⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tplaywaveunit.~pas

📁 语音与识别技术包含很多C语言处理模块系统
💻 ~PAS
📖 第 1 页 / 共 5 页
字号:
    ck.ckid := mmioStringToFOURCC('fmt', 0);;          //创建 fmt 块
    if Self.pFormat^.wFormatTag = WAVE_FORMAT_PCM then
      ck.cksize := SizeOf(Self.pFormat^) - 2           //fmt 块的大小
    else
      ck.cksize := SizeOf(Self.pFormat^) + Self.pFormat^.cbSize;

    if 0 <> mmioCreateChunk(Dhio, @ck, 0) then         //创建
       raise EMMIO.Create('粘贴数据错');
    mmioWrite(Dhio, PChar(Self.pFormat), ck.cksize);

    ck.ckid := mmioStringToFOURCC('data', 0);         //创建 data 数据块
    ck.cksize := LongInt(Self.DataLength) + EditLength;
    if 0 <> mmioCreateChunk(Dhio, @ck, 0) then
       raise EMMIO.Create('粘贴数据错');

    SendMessage(Application.MainForm.Handle, CM_EDITPOI, 1, 0);

    //移到音频数据开始处
    mmioSeek(Self.hio, Self.DataLength, SEEK_END);

    Try
      Self.WriteWaveData(Dhio, StartPoi);       //写入数据
    Except
      mmioClose(Dhio, 0);
      raise EMMIO.Create('粘贴数据错');
      Exit;
    end;

    //打开剪切板数据文件
    TempFile := FileOpen(Self.CopyDataFileName, fmOpenRead);
    if TempFile = 0 then
       raise EMMIO.Create('粘贴数据错');

    //把剪切板文件中的数据写入音频文件中
    LoopMod := LoadMemSize;
    LoopData := EditLength DIV LoadMemSize;
    if (EditLength MOD LoadMemSize) <> 0 then
    begin
       LoopMod := EditLength MOD LoadMemSize;
       LoopData := LoopData + 1;
    end;

    Try
      Buf := PChar(GlobalAllocPtr(GMEM_MOVEABLE or GMEM_SHARE, LoadMemSize));
      if Buf = NIL then
         EMMIO.Create('不能分配内存');
      Try
        for i := 1 to LoopData - 1 do
        begin
          FileRead(TempFile, Buf^, LoadMemSize);        //读指定大小的数据
          if mmioWrite(Dhio, Buf, LoadMemSize) <> LoadMemSize then
             raise EMMIO.Create('粘贴数据错');
          SendMessage(Application.MainForm.Handle, CM_EDITPOI, 0, 1);
        end;
      Finally
        GloBalFreePtr(Buf);
      end;
      if LoopMod > 0 then
      begin
         Buf := PChar(GlobalAllocPtr(GMEM_MOVEABLE or GMEM_SHARE, LoopMod));
         if Buf = NIL then
            EMMIO.Create('不能分配内存');
         Try
           FileRead(TempFile, Buf^, LoopMod);
           //写入到音频文件中
           if mmioWrite(Dhio, Buf, LoopMod) <> LoopMod then
              raise EMMIO.Create('粘贴数据错');
           SendMessage(Application.MainForm.Handle, CM_EDITPOI, 0, 1);
         Finally
           GloBalFreePtr(Buf);
         end;
      end;
    Finally
      FileClose(TempFile);                  //关闭文件
    end;
     
    Try //把余下的数据写入到音频文件中
      Self.WriteWaveData(Dhio, LongInt(Self.DataLength) - StartPoi);
    Except
      mmioClose(Dhio, 0);
      raise EMMIO.Create('粘贴数据错');
      Exit;
    end;
  Finally
    mmioClose(Dhio, 0);
  end;

  Self.Stop;
  Self.CloseWaveFile;   //关闭音频文件

  if Length > 0 then
  begin
     if FileExists(Self.UndoBackFileName) then
        DeleteFile(Self.UndoBackFileName);      //删除用于撤消的备份文件

     //把当前的音频文件复制成用于撤消的备份文件
     CopyFile(PChar(Self.BackFileName), PChar(Self.UndoBackFileName), TRUE);
  end;

  //删除备份文件
  DeleteFile(Self.BackFileName);

  //把处理后的文件复制成备份文件
  CopyFile(PChar(Self.CopyBackFileName), PChar(Self.BackFileName), TRUE);

  SendMessage(Application.MainForm.Handle, CM_EDITPOI, 0, 1);

  //打开备份文件
  if Self.OpenFileName(PChar(Self.BackFileName), DrawData) then
     Self.FNowPlay := CPSTOPING;
  Self.FCanUndo := TRUE;        //可以撤消
  SendMessage(Application.MainForm.Handle, CM_EDIEND, 0, 0);
end;

//***********************************************************************//
//                                                                       //
//   撤消编辑操作                                                        //
//   参数:                                                               //
//        DrawData    : 是否画波形                                       //
//   返回值:  无                                                         //
//                                                                       //
//***********************************************************************//
procedure TCMPlayWave.Undo(DrawData: Boolean);
begin
  if (NOT Self.FCanUndo) OR (Self.NowPlay <> CPSTOPING) then
     Exit;
  SendMessage(Application.MainForm.Handle, CM_BEGINUNDO, 0, 0);
  SendMessage(Application.MainForm.Handle, CM_EDITLENGTH, 3, 0);
  Self.Stop;
  Self.CloseWaveFile;           //关闭音频文件

  SendMessage(Application.MainForm.Handle, CM_EDITPOI, 0, 1);

  if FileExists(Self.BackFileName) then                
     DeleteFile(Self.BackFileName);     //删除备份文件

  SendMessage(Application.MainForm.Handle, CM_EDITPOI, 0, 1);

  //把用于撤消操作的文件复制成备份文件
  CopyFile(PChar(Self.UndoBackFileName), PChar(Self.BackFileName), TRUE);

  SendMessage(Application.MainForm.Handle, CM_EDITPOI, 0, 1);

  //打开备份文件
  if Self.OpenFileName(PChar(Self.BackFileName), DrawData) then
     Self.FNowPlay := CPSTOPING;
  if FileExists(Self.UndoBackFileName) then
     DeleteFile(Self.UndoBackFileName); //删除撤消文件
  SendMessage(Application.MainForm.Handle, CM_EDITPOI, 0, 1);
  Self.FCanUndo := False;
  SendMessage(Application.MainForm.Handle, CM_EDIEND, 0, 0);
end;

//***********************************************************************//
//                                                                       //
//   关闭打开的音频文件                                                  //
//   参数:    无                                                         //
//   返回值:  无                                                         //
//                                                                       //
//***********************************************************************//
procedure TCMPlayWave.CloseWaveFile;
begin
  if NowPlay <> CPSTOPING then  //不是停止状态
     Exit;
  LocalUnlock(hFormat);  //解锁内存
  LocalFree(hFormat);    //释放音频信息头
  mmioClose(hio, 0);     //半闭音频输出设备
  Self.hio := 0;
  Self.DataLength := 0;
  FNowPlay := CPNONE;    //当前没有状态
end;

//***********************************************************************//
//                                                                       //
//   关闭音频                                                            //
//   参数:    无                                                         //
//   返回值:  无                                                         //
//                                                                       //
//***********************************************************************//
procedure TCMPlayWave.CloseWave;
begin
  if Self.FFileName = NIL then
     Exit;
  Self.Stop;    //停止播放
  Self.CloseWaveFile;   //关闭打开的音频文件
  Self.DataLength := 0;
  Self.FFileName := NIL;
  Self.FCanUndo := False;
end;

//***********************************************************************//
//                                                                       //
//   返回当前能否进行粘贴操作                                            //
//   参数:    无                                                         //
//   返回值:                                                             //
//            当前能否进行撤消操作                                       //
//                                                                       //
//***********************************************************************//
function TCMPlayWave.GetCanPaste: Boolean;
begin
  //剪切板中的数据的长度大于 0 并且剪切板文件存在
  Result := ((Self.PasteDataLength > 0) AND (FileExists(Self.CopyDataFileName)));
end;

//***********************************************************************//
//                                                                       //
//   新建一个空的音频文件                                                //
//   参数:    无                                                         //
//   返回值:  无                                                         //
//                                                                       //
//***********************************************************************//
procedure TCMPlayWave.New;
var
  TRecordHdr: TWAVEFORMATEX;    //波形格式
begin
   if Self.NowPlay <> CPNONE then
      Exit;
  //设置音频文件头
  TRecordHdr.wFormatTag := WAVE_FORMAT_PCM;        //格式类型
  TRecordHdr.nChannels := 1;                       //声道数据
  TRecordHdr.nSamplesPerSec := 8000;               //采样频率
  TRecordHdr.nAvgBytesPerSec := 16000;             //平均数据传输率
  TRecordHdr.wBitsPerSample := 16;                 //采样数据的大小
  TRecordHdr.nBlockAlign := 2;                     //块对齐方式
  TRecordHdr.cbSize := 0;                          //加在本结构后的格式数据的大小

  Wave_SaveFile(Self.BackFileName, '', 0, TRecordHdr, 0, CS_SAVE_NEW);
end;

//***********************************************************************//
//                                                                       //
//   把一个整数转换成时间格式                                            //
//   参数:                                                               //
//         Length     : 指定的整数                                       //
//         Time       : 用于返回的时间格式                               //
//   返回值:  无                                                         //
//                                                                       //
//***********************************************************************//
procedure TCMPlayWave.IntToWaveTime(const Length: LongInt; var Time: TCM_Wave_Time);
var
  i: LongInt;
begin
  Time.Hour := 0;       //小时
  Time.Minute := 0;     //分
  Time.Second := 0;     //秒
  Time.Heroism := 0;    //毫秒
  Try
    if Self.pFormat = NIL then
       Exit;
    Time.Heroism := Length MOD LongInt(Self.pFormat^.nAvgBytesPerSec);
    i := Length DIV LongInt(Self.pFormat^.nAvgBytesPerSec);
    Time.Second := i MOD 60;
    Time.Minute := i DIV 60;
    Time.Hour := Time.Minute DIV 60;
    Time.Minute := Time.Minute MOD 60;
    Time.Heroism := (Time.Heroism * 100) DIV Self.pFormat^.nAvgBytesPerSec;
  Except
    Time.Hour := 0;
    Time.Minute := 0;
    Time.Second := 0;
    Time.Heroism := 0;
    Application.MessageBox('时间格式转换错误!', '系统错误', MB_OK + MB_ICONERROR);
  end;
end;

//***********************************************************************//
//                                                                       //
//   取音频数据的最大振幅                                                //
//   参数:    无                                                         //
//   返回值:                                                             //
//            音频数据的最大振幅                                         //
//                                                                       //
//***********************************************************************//
function TCMPlayWave.GetMaxVal: Longint;
begin
  Result := ABS(Self.WaveMax - Self.WaveMin);
end;

//***********************************************************************//
//                                                                       //
//   显示波形                                                            //
//   参数:    无                                                         //
//   返回值:  无                                                         //
//                                                                       //
//***********************************************************************//
procedure TCMPlayWave.DrawShowWave;
var
  DrawAll: TDrawWave_Type;
begin
  if (Self.FDrawWave <> NIL) AND (Self.FDesBMP <> NIL) then
  begin
    DrawAll.FileType := CS_SAVE_PLAY;
    DrawAll.hio := Self.hio;
    DrawAll.Flag := Integer(Self.DataLength) DIV 2 DIV Self.FDrawWave.ClientWidth + 1;
    if DrawAll.Flag <= 0 then DrawAll.Flag := 1;
    DrawAll.FileName := '';
    DrawAll.Length := Self.DataLength;
    DrawAll.Des

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -