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

📄 tplaywaveunit.~pas

📁 语音与识别技术包含很多C语言处理模块系统
💻 ~PAS
📖 第 1 页 / 共 5 页
字号:
//***********************************************************************//
//                                                                       //
//   放音单元                                                            //
//   单元名: TPlayWaveUnit                                               //
//   功能: 放音、对音频进行编辑操作                                      //
//   实现方法: 采用音频底层操作                                          //
//   特点: 放音的同时显示波形并可对音频数据进行编辑                      //
//   日期: 2003 年 1月 13日                                              //
//                                                                       //
//***********************************************************************//

unit TPlayWaveUnit;          

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, MMSystem, ExtCtrls,
  Forms, Dialogs, TCMWaveType, ComCtrls;

Type
  TCMPlayWave = Class
  private
    { Private declarations }
    FFileName: PChar;
    hio: HMMIO;                   //当前打开的音频文件句柄
    hwo: HWAVEOUT;                //设备句柄
    MODInt: LongInt;              //最后的( 少于指定长度 )数据长度
    PlaySize: LongInt;            //要播放的数据的长度
    pFormat: PWAVEFORMATEX;       //波形格式结构
    hFormat: THANDLE;             //波形格式结构句柄
    PlayLoop: Integer;            //分段播放的总段数
    DataLength: DWORD;            //音频数据的总长度
    GotoPosition: DWORD;          //从指定位置开始播放
    FirstData: PChar;             //双缓存数据指针
    NextData: PChar;              //双缓存数据指针
    SetMemTime: TTimer;           //用于读取数据
    PlayDataLength: DWORD;        //要播放的音频数据的总长度
    PasteDataLength: LongInt;     //可用于粘贴的数据的长度
    CopyDataFileName: String;     //保存可用于粘贴的数据的临时文件
    CopyBackFileName: String;     //进行音频编辑时, 用于保存临时数据的文件
    UndoBackFileName: String;     //用于保存最后一次编辑前的音频数据的临时文件
    BackFileName: String;         //打开一个音频文件后, 用于放音的临时文件
    FNowPlay: TCMPlaying;         //当前处于何种操作状态下
    FDesBMP: TBitMap;             //画波形用的源位图对像
    FDrawWave: TPaintBox;         //用于显示波形的目标画布对像
    WaveMin, WaveMax: LongInt;    //波形的最小与最大数据值
    FDetachLength: LongInt;       //句子个数
    FPosition: DWORD;             //当前播放位置
    FCanUndo: Boolean;            //当前能否进行撤消操作
    FShowDrawWave: Boolean;       //是否显示波形
    FShowMessageParBar: TProgressBar;  //用于显示进度的进度条
    FDrawBackColor: TColor;       //波形背景色
    FDrawLineColor: TColor;       //波形颜色
    FWaveLoop: TWaveLoopNotifyEvent;
    FWavePlayKM: byte;
    procedure PlayWave;           //放音子过程
    procedure SetFileName(const Value: String); 
    function GetFileName: String;
    function OpenFileName(Name: PChar; Draw: Boolean = TRUE): Boolean;
    procedure SetDesBMP(const Value: TBitMap);
    procedure SetDrawWave(const Value: TPaintBox);
    procedure SetPlayMem(Sender: TObject);
    procedure SDTime(Sender: TObject);
    procedure WriteWaveData(Dhio: HMMIO; Length: Integer);      //读取数据过程
    procedure CloseWaveFile;
    function GetCanPaste: Boolean;
    function GetMaxVal: Longint;
    procedure SetShowDrawWave(const Value: Boolean);
    procedure SetShowMessageParBar(const Value: TProgressBar);
    procedure SetDrawBackColor(const Value: TColor);
    procedure SetDrawLineColor(const Value: TColor);
    procedure SetWaveLoop(const Value: TWaveLoopNotifyEvent);
    procedure ShowPoistrator(WaveEvent: TWaveLoopEventType; Max, Min, Position: DWORD);
    procedure SetWavePlayKM(const Value: byte);
  public
    { Public declarations }
    constructor Create; overload;  //构造器
    destructor Destroy; override;  //析构器
    procedure Free;                //释放
    procedure New;     
    procedure Play(const Start: DWORD = 0; const Length: DWORD = 0);
    procedure Stop;
    procedure Pause;
    procedure Restart;
    procedure CloseWave;
    procedure DrawShowWave;
    procedure Save(const NewFileName: String; const StartPoi: LongInt = 0;
              const SaveLength: LongInt = 0);
    procedure Copy(const StartPoi, Length: LongInt);
    procedure Cut(const StartPoi, Length: LongInt);
    procedure Paste(const StartPoi, Length: LongInt; DrawData: Boolean = TRUE);
    procedure Delete(const StartPoi, Length: LongInt; DrawData: Boolean = TRUE);
    procedure Undo(DrawData: Boolean = TRUE);
    property FileName: String read GetFileName write SetFileName;
    property NowPlay: TCMPlaying read FNowPlay;
    function IntToWaveLength(const Position: Integer): LongInt;
    procedure SetMinMaxData;
    procedure SetWaveFile(const Value: String);
    procedure IntToWaveTime(const Length: LongInt; var Time: TCM_Wave_Time);
    property DrawWave: TPaintBox read FDrawWave write SetDrawWave;
    property DesBMP: TBitMap read FDesBMP write SetDesBMP;
    property Position: DWORD read FPosition;
    property WaveLength: DWORD read DataLength;
    property CanUndo: Boolean read FCanUndo;
    property CanPaste: Boolean read GetCanPaste;
    property MaxVal: LongInt read GetMaxVal;
    property ShowDrawWave: Boolean read FShowDrawWave write SetShowDrawWave default TRUE;
    property ShowMessageParBar: TProgressBar read FShowMessageParBar write SetShowMessageParBar;
    property DrawLineColor: TColor read FDrawLineColor write SetDrawLineColor;
    property DrawBackColor: TColor read FDrawBackColor write SetDrawBackColor;
    property WaveLoopEvent: TWaveLoopNotifyEvent read FWaveLoop write SetWaveLoop;
    property WavePlayKM: byte read FWavePlayKM write SetWavePlayKM default 100;
  end;

implementation

//***********************************************************************//
//                                                                       //
//   TCMPlayWave 的实现部分                                              //
//                                                                       //
//***********************************************************************//
{ TCMPlayWave }

//***********************************************************************//
//                                                                       //
//   构造器                                                              //
//                                                                       //
//***********************************************************************//
constructor TCMPlayWave.Create;
  function FindTempFile(const FindFileName: String): String;
  var
    i: Integer;
    TempStr: String;
  begin
    i := 0;
    While TRUE do
    begin //查找文件
       if Not FileExists(FindFileName + IntToStr(i) + '.tmp') then
       begin
          TempStr := FindFileName + IntToStr(i) + '.tmp';
          break;
       end;
       INC(i);
    end;
    Result := TempStr
  end;
var
  TempDir: array[0..255] of Char;       //Windows 操作系统的临时路径
  Tem: Integer;
const
  CopyDataTempFile = 'CMCopyDataWave';
  CopyBackTempFile = 'CMCopyBackWave';
  BackTempFile     = 'CMBackWave';
  UndoTempFile     = 'CMUndoBackWave';
begin
  if WaveOutGetNumDevs() = 0 then
     raise EMMIO.Create('找不到音频设备!');
  inherited Create;

  GetTempPath(255, @TempDir);           //取得操作系统的临时目录
  //可用于粘贴的数据
  Self.CopyDataFileName := FindTempFile(StrPas(TempDir) + CopyDataTempFile);
  //用于编辑操作的临时文件
  Self.CopyBackFileName := FindTempFile(StrPas(TempDir) + CopyBackTempFile);
  //备份文件,用于编辑、播放等操作
  Self.BackFileName     := FindTempFile(StrPas(TempDir) + BackTempFile);
  //编辑操作前的文件的备份
  Self.UndoBackFileName := FindTempFile(StrPas(TempDir) + UndoTempFile);

  //创建文件
  Tem := FileCreate(Self.CopyDataFileName);
  FileClose(Tem);

  Tem := FileCreate(Self.CopyBackFileName);
  FileClose(Tem);

  Tem := FileCreate(Self.BackFileName);
  FileClose(Tem);

  Tem := FileCreate(Self.UndoBackFileName);
  FileClose(Tem);

  Self.FFileName := NIL;

  //用于控制播放时显示波形的周期
  Self.SetMemTime := TTimer.Create(Application);
  Self.SetMemTime.Enabled := False;
  Self.SetMemTime.Interval := 1;
  Self.SetMemTime.Tag := 1;
  Self.SetMemTime.OnTimer := Self.SetPlayMem;

  Self.FCanUndo := False;
  Self.FNowPlay := CPNONE;
  Self.FShowDrawWave := True;

  Self.PasteDataLength := 0;    //可用于粘贴的数据的长度
  Self.DataLength := 0;
  Self.FDetachLength := 0;

  Self.FDrawBackColor := clWhite;       //波形背景颜色
  Self.FDrawLineColor := clBlue;        //波形颜色

  Self.FirstData := NIL;                
  Self.NextData := NIL;

  Self.FDesBMP := NIL;
  Self.FDrawWave := NIL;
end;

//***********************************************************************//
//                                                                       //
//   析构器                                                              //
//                                                                       //
//***********************************************************************//
destructor TCMPlayWave.Destroy;
begin
  Self.Stop;            //停目播放
  Self.CloseWave;       //关闭文件
  //删除临时文件
  if FileExists(Self.CopyDataFileName) then
     DeleteFile(Self.CopyDataFileName);
  if FileExists(Self.CopyBackFileName) then
     DeleteFile(Self.CopyBackFileName);
  if FileExists(Self.UndoBackFileName) then
     DeleteFile(Self.UndoBackFileName);
  if FileExists(Self.BackFileName) then
     DeleteFile(Self.BackFileName);
  inherited;
end;

//***********************************************************************//
//                                                                       //
//   释放                                                                //
//   参数: 无                                                            //
//   返回值: 无                                                          //
//                                                                       //
//***********************************************************************//
procedure TCMPlayWave.Free;
begin
  if Self <> NIL then
     Self.Destroy;
end;

//***********************************************************************//
//                                                                       //
//   取当前音频文件名                                                    //
//   参数:    无                                                         //
//   返回值:                                                             //
//           当前音频文件名                                              //
//                                                                       //
//***********************************************************************//
function TCMPlayWave.GetFileName: String;
begin
  Result := String(Self.FFileName);
end;

//***********************************************************************//
//                                                                       //
//   设置当前音频文件名                                                  //
//   参数:                                                               //
//        Value : 文件名                                                 //
//   返回值:  无                                                         //
//                                                                       //
//***********************************************************************//
procedure TCMPlayWave.SetFileName(const Value: String);
var
  WaveFmt: TWAVEFORMATEX;
begin
  if NOT FileExists(Value) then
     raise EMMIO.Create('找不到文件');
  Self.Stop;
  Self.CloseWave;

  //设置进度
  if Assigned(Self.WaveLoopEvent) then
     Self.WaveLoopEvent(WA_EN_OPENFILE, 100, 0, 0);

  if Self.ShowMessageParBar <> NIL then
  begin
     Self.ShowMessageParBar.Max := 100;
     Self.ShowMessageParBar.Position := 10;
  end;

  if Assigned(Self.WaveLoopEvent) then
     Self.WaveLoopEvent(WA_EN_OPENFILE, 100, 0, 10);

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

  if Self.ShowMessageParBar <> NIL then
  begin
     Self.ShowMessageParBar.Position := 20;
  end;

  if Assigned(Self.WaveLoopEvent) then
     Self.WaveLoopEvent(WA_EN_OPENFILE, 100, 0, 20);

  if Self.OpenFileName(PChar(Value), False) then
  begin
     WaveFmt := Self.pFormat^;
     WaveFmt.nChannels := 1;            //单声道

⌨️ 快捷键说明

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