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

📄 tplaywaveunit.~pas

📁 语音与识别技术包含很多C语言处理模块系统
💻 ~PAS
📖 第 1 页 / 共 5 页
字号:
  //发送暂停消息
  SendMessage(Application.MainForm.Handle, CM_PLAYPAUSE, 0, 0);
  WaveOutPause(hwo);            //暂停播放
  Self.FNowPlay := CPPAUSEING;  //设置播放状态
end;

//***********************************************************************//
//                                                                       //
//   恢复播放                                                            //
//   参数: 无                                                            //
//   返回值:  无                                                         //
//                                                                       //
//***********************************************************************//
procedure TCMPlayWave.Restart;
begin
  if Self.NowPlay <> CPPAUSEING then    //如果不是暂停状态下
     Exit;
  WaveOutRestart(hwo);          //恢复播放
  FNowPlay := CPPLAYING;        //设置播放状态
  //发送恢复播放的消息
  SendMessage(Application.MainForm.Handle, CM_PLAYREST, 0, 0);
end;

//***********************************************************************//
//                                                                       //
//   停止播放                                                            //
//   参数: 无                                                            //
//   返回值:  无                                                         //
//                                                                       //
//***********************************************************************//
procedure TCMPlayWave.Stop;
begin
  if Self.FNowPlay = CPNONE then        //没有任何状态
     Exit;
  if Self.FNowPlay = CPPLAYING then
     WaveOutReset(Self.hwo);            //停止播放
  Self.FNowPlay := CPSTOPING;           //设置状态
end;

//***********************************************************************//
//                                                                       //
//   设置画波形用的源位图对像                                            //
//   参数:                                                               //
//        Value : 源位图对像                                             //
//   返回值:  无                                                         //
//                                                                       //
//***********************************************************************//
procedure TCMPlayWave.SetDesBMP(const Value: TBitMap);
begin
  FDesBMP := Value;
end;

//***********************************************************************//
//                                                                       //
//   设置用于显示波形的目标画布对像                                      //
//   参数:                                                               //
//        Value : 目标画布对像                                           //
//   返回值:  无                                                         //
//                                                                       //
//***********************************************************************//
procedure TCMPlayWave.SetDrawWave(const Value: TPaintBox);
begin
  FDrawWave := Value;
end;

//***********************************************************************//
//                                                                       //
//   把从指定位置开始,指定长度的音频数据保存到指定文件中                //
//   参数:                                                               //
//        NewFileName : 要保存的目标文件                                 //
//        StartPoi    : 要保存的音频数据的起始位置                       //
//        SaveLength  : 要保存的音频数据的长度 ( 0 为全部保存 )        //
//   返回值:  无                                                         //
//                                                                       //
//***********************************************************************//
procedure TCMPlayWave.Save(const NewFileName: String; const StartPoi,
  SaveLength: Integer);
var
  TRecordHdr: TWAVEFORMATEX;    //波形格式
begin
  if (Self.NowPlay <> CPSTOPING) OR (hio = 0) OR (NewFileName = '') then
     Exit;
  //保存到文件
  if Self.DataLength = 0 then
  begin
     //设置音频文件头
     TRecordHdr.wFormatTag := WAVE_FORMAT_PCM;        //格式类型
     TRecordHdr.nChannels := 1;                       //声道数据
     TRecordHdr.nSamplesPerSec := 22050;              //采样频率
     TRecordHdr.nAvgBytesPerSec := 44100;             //平均数据传输率
     TRecordHdr.wBitsPerSample := 16;                 //采样数据的大小
     TRecordHdr.nBlockAlign := 2;                     //块对齐方式
     TRecordHdr.cbSize := 0;                          //加在本结构后的格式数据的大小
     Wave_SaveFile(NewFileName, '', 0, TRecordHdr, 0, CS_SAVE_NEW);
  end else
     Wave_SaveFile(NewFileName, '', DataLength, pFormat^, hio, CS_SAVE_PLAY, StartPoi, SaveLength);
end;

//***********************************************************************//
//                                                                       //
//   把指定整数转换从在音频中的位置                                      //
//   参数:                                                               //
//        Position    : 要转换的整数                                     //
//   返回值:                                                             //
//           在音频中的位置                                              //
//                                                                       //
//***********************************************************************//
function TCMPlayWave.IntToWaveLength(const Position: Integer): LongInt;
var
  Flag: Integer;
begin
  //音频显示周期
  Flag := Integer(Self.DataLength) DIV 2 DIV Self.DrawWave.ClientWidth + 1;
  if Flag <= 0 then Flag := 1;
  Result := Position * Flag * 2;        //返回长度
end;

//***********************************************************************//
//                                                                       //
//   打开指定的音频文件 ( 载入内存 )                                   //
//   参数:                                                               //
//        Name        : 要打开的文件名                                   //
//        Draw        : 是否画波形                                       //
//   返回值:                                                             //
//           是否打开成功                                                //
//                                                                       //
//***********************************************************************//
function TCMPlayWave.OpenFileName(Name: PChar; Draw: Boolean): Boolean;
var
  mmckinfoParent, mmckinfoSubchunk: MMCKINFO;//音频信息头
  dwfmtSize: DWORD;
  DrawAll: TDrawWave_Type;      //波形结构体
begin
  Self.MODInt := 0;
  Self.PlaySize := 0;

  //打开音频文件                  只读       以缓冲区方式打开
  Self.hio := mmioOpen(Name, NIL, MMIO_READ or MMIO_ALLOCBUF);
  if Self.hio = 0 then
     raise EMMIO.Create('打不开文件或文件不存在!');

  Try
    //寻找 RIFF 块的类型标志,以确定是 WAV 文件
    mmckinfoParent.fccType := mmioStringToFOURCC('WAVE', 0);
    if mmioDescend(Self.hio, @mmckinfoParent, NIL, MMIO_FINDRIFF) <> 0 then
       raise EMMIO.Create('不是WAVE文件!');

    //寻找 fmt 子块,以确定是 WAV 文件并找出一些音频文件的数据
    mmckinfoSubchunk.ckid := mmioStringToFOURCC('fmt', 0);
    if mmioDescend(Self.hio, @mmckinfoSubchunk, @mmckinfoParent, MMIO_FINDCHUNK) <> 0 then
       raise EMMIO.Create('不是WAVE文件!');

    //音频信息头的大小
    dwFmtSize := mmckinfoSubchunk.cksize;
    //锁定内存
    Self.hFormat := LocalAlloc(LMEM_MOVEABLE, LOWORD(dwFmtSize));
    if Self.hFormat = 0 then
       raise EMMIO.Create('不能分配内存!');

    try               //开辟内存
      Self.pFormat := PWAVEFORMATEX(LocalLock(Self.hFormat));
      if Self.pFormat = NIL then
         raise EMMIO.Create('不能锁定内存!');

      //读取音频信息头( 音频格式 )
      if mmioRead(Self.hio, PChar(Self.pFormat), dwFmtSize) <> LongInt(dwFmtSize) then
         raise EMMIO.Create('读格式错!');

      //确定是否为指定格式类型
      if Self.pFormat^.wFormatTag <> WAVE_FORMAT_PCM then
         raise EMMIO.Create('波形音频不是PCM格式音频!');

      //打开音频输出设备
      if WaveOutOpen(@Self.hwo, WAVE_MAPPER, Self.pFormat, 0, 0, WAVE_FORMAT_QUERY) <> 0 then
         raise EMMIO.Create('波形音频输出设备不支持该格式!');

      //把文件指针移到 data 数据块的开始处
      mmioAscend(Self.hio, @mmckinfoSubchunk, 0);

      //查找 data 数据块
      mmckinfoSubchunk.ckid := mmioStringToFOURCC('data', 0);
      if mmioDescend(Self.hio, @mmckinfoSubchunk, @mmckinfoParent, MMIO_FINDCHUNK) <> 0 then
         raise EMMIO.Create('找不到数据块!');

      //音频数据的长度
      Self.DataLength := mmckinfoSubchunk.cksize;

      if Self.DataLength = 0 then
      begin             //音频数据的长度为0
         LocalUnlock(Self.hFormat);     //解锁内存块
         LocalFree(Self.hFormat);       //释放内存块
         mmioClose(Self.hio, 0);        //关闭文件
      end;
    Finally
    end;
  Finally
  end;

  if Self.DataLength = 0 then
  begin
     with Self.FDesBMP do
     begin
        Canvas.Brush.Color := Self.DrawBackColor;
        Canvas.Brush.Style := bsSolid;
        Canvas.Pen.Color := Self.DrawLineColor;
        Canvas.Pen.Mode := pmCopy;
        Canvas.FillRect(Rect(0, 0, Self.FDrawWave.ClientWidth, Self.FDrawWave.ClientHeight));
     end;
     BitBlt(Self.FDrawWave.Canvas.Handle, 0, 0, Self.FDrawWave.ClientWidth,
            Self.FDrawWave.ClientHeight, Self.FDesBMP.Canvas.Handle, 0, 0, SRCCOPY);
     Application.MessageBox('文件长度为零!', '提示', MB_OK + MB_ICONINFORMATION);
     SendMessage(Application.MainForm.Handle, CM_ENDDRAW, 0, 0);
  end;

  if (Self.FDrawWave <> NIL) AND (Self.FDesBMP <> NIL) AND Draw AND Self.FShowDrawWave
     and (Self.DataLength <> 0) 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.DesCanvas := Self.FDrawWave.Canvas;
    DrawAll.DH := Self.FDrawWave.ClientHeight;
    DrawAll.DW := Self.FDrawWave.ClientWidth;
    DrawAll.DesBitMap := Self.FDesBMP;
    DrawAllWave(DrawAll, Self.WaveMin, Self.WaveMax, Self.FDrawLineColor, Self.FDrawBackColor);
  end;

  Self.FCanUndo := False;       //不能进行撤消操作
  Result := True;               //打开成功
end;

//***********************************************************************//
//                                                                       //
//   向指定的音频文件写入指定长度的音频数据                              //
//   参数:                                                               //
//        Dhio        : 音频文件的句柄                                   //
//        Length      : 音频数据的长度                                   //
//   返回值:  无                                                         //
//                                                                       //
//***********************************************************************//
procedure TCMPlayWave.WriteWaveData(Dhio: HMMIO; Length: LongInt);
var
  LoopData, i: Integer;
  LoopMod: LongInt;
  Buf: PChar;
begin
  if Length <= 0 then
     Exit;
  LoopMod := LoadMemSize;
  LoopData := Length DIV LoadMemSize;
  if (Length MOD LoadMemSize) <> 0 then
  begin
     LoopMod := Length MOD LoadMemSize;
     LoopData := LoopData + 1;
  end;

  //分配内存块
  Buf := PChar(GlobalAllocPtr(GMEM_MOVEABLE or GMEM_SHARE, LoadMemSize));
  if Buf = NIL then
     EMMIO.Create('数据错');
  Try
    for i := 1 to LoopData - 1 do
    begin  //从当前打开的音频文件读取音频数据
        if mmioRead(Self.hio, Buf, LoadMemSize) <> LoadMemSize then
           raise EMMIO.Create('数据错');
        //写入到指定的音频文件中
        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
       if mmioRead(Self.hio, Buf, LoopMod) <> LoopMod then
          raise EMMIO.Create('数据错');
       if mmioWrite(Dhio, Buf, LoopMod) <> LoopMod then
          raise EMMIO.Create('数据错');
       SendMessage(Application.MainForm.Handle, CM_EDITPOI, 0, 1);
     Finally
       GloBalFreePtr(Buf);
     end;
  end;
end;

//***********************************************************************//
//                                                                       //
//   从指定位置复制指定长度的音频数据到剪贴板                            //
//   参数:                                                               //
//        StartPoi    : 复制音频数据的起始位置                           //
//        Length      : 音频数据的长度                                   //
//   返回值:  无                                                         //
//                                                                       //

⌨️ 快捷键说明

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