正好要做一个能够播放音频的模块,看到万一的博客中关于用BASS做音频处理的一些例子,正好满足我的需求。
在http://www.un4seen.com下载BASS 2.4.8,解压包后要设置Bass.dll路径和导入Bass.pas。
Delphi 中使用前,
有三步工作要做:
1、复制 Bass.dll 到系统可以识别的文件夹, 譬如:
Windows\System32、Windows、Windows\System,
也可以是系统或用户的环境变量 Path 指定的任何目录, 还可以在做程序时放在当前目录, 随便放一个文件夹然后在程序中指定路径也可以.
2、把专为 Delphi 写的头文件 bass.pas 放在某个目录(譬如:
C:\Program Files\CodeGear\RAD Studio\6.0\Imports\Bass24).
3、然后从 Delphi 菜单 -> Tools -> Options
-> Library-Win32 -> Library path -> 然后 Add 这个目录
下面几个函数是从万一那copy来的,记在这里方便自己查阅。
function BASS_StreamCreateFile(
mem: BOOL; {从文件载入这里是 False; 从内存载入这里是 True}
f: Pointer; {文件名或内存流的指针}
offset: QWORD; {播放起始点, 单位是 1/10 毫米; 只在参数 1: mem = False 时有效; 默认是 0}
length: QWORD; {播放终止点, 单位是 1/10 毫米; 只在参数 1: mem = False 时有效; 默认是 0}
flags: DWORD {BASS_SAMPLE_3D 等参数的组合; 控制播放效果、反复和解码等等}
): HSTREAM; stdcall; external bassdll;
//获取文件流的长度, 单位是字节
function BASS_ChannelGetLength(
handle: DWORD; {流句柄}
mode: DWORD {获取模式; 有两种选择, 但对 HSTREAM 流只能使用 BASS_POS_BYTE}
): QWORD; stdcall; external bassdll;
//获取流的当前指针位置, 单位是字节
function BASS_ChannelGetPosition(
handle: DWORD; {流句柄}
mode: DWORD {获取模式; 有两种选择, 但对 HSTREAM 流只能使用 BASS_POS_BYTE}
): QWORD; stdcall; external bassdll;
//根据流的指针位置来获取时间点, 单位是秒, 是非常精确的浮点数
function BASS_ChannelBytes2Seconds(
handle: DWORD; {流句柄}
pos: QWORD {流的指针位置, 单位是字节, QWORD = Int64}
): Double; stdcall;external bassdll;
//和 BASS_ChannelBytes2Seconds 相反, BASS_ChannelSeconds2Bytes 可以通过时间获取流的指针位置.
function BASS_ChannelSeconds2Bytes(
handle: DWORD;
pos: Double
): QWORD; stdcall;external bassdll;
//和 BASS_ChannelGetPosition 相反, BASS_ChannelSetPosition 可以设置流的指针位置.
function BASS_ChannelSetPosition(
handle: DWORD;
pos: QWORD;
mode: DWORD
): BOOL; stdcall; external bassdll;
好了,环境设置好后,动手做一个程序先
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) btnOpen: TButton; btnPlay: TButton; btnPause: TButton; edt1: TEdit; dlgOpen1: TOpenDialog; lbl1: TLabel; chkLoop: TCheckBox; btnDelete: TButton; procedure FormCreate(Sender: TObject); procedure btnOpenClick(Sender: TObject); procedure btnPlayClick(Sender: TObject); procedure btnPauseClick(Sender: TObject); procedure chkLoopClick(Sender: TObject); procedure btnDeleteClick(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form1: TForm1; implementation {$R *.dfm} uses bass; var hs:HSTREAM; //流句柄 //Open procedure TForm1.btnOpenClick(Sender: TObject); var soundPath:AnsiString; str:string; time:Double; timeStr:String; hour:Integer; minute:Integer; second:Integer; begin dlgOpen1.Filter:='Mp3 File(*.mp3)|*.mp3|Wav File(*.wav)|*wav' ; if dlgOpen1.Execute then soundPath:=AnsiString(dlgOpen1.FileName); BASS_StreamFree(hs); hs:=BASS_StreamCreateFile(False,PAnsiChar(soundPath),0,0,0); //创建播放流,第一个参数False为从文件载入,true从内存载入。第二个参数为文件名或内存流的指针 edt1.Text:=ExtractFileName(soundPath);//edt1用来显示读取的文件名 if hs < BASS_ERROR_ENDED then //判断打开是否失败 begin ShowMessage('Open '+soundPath+' fail!'); Exit; end; time:=BASS_ChannelBytes2Seconds(hs,BASS_ChannelGetLength(hs,BASS_POS_BYTE)); //获取音频的总时间,BAss_Channel2Seconds根据流的指针位置来获取时间点, 单位是秒, //BASS_ChannelGetLength是获取文件流的长度,BASS_ChannelGetPosition是获得指针的位置 hour:=Trunc(time/3600); time:=time-hour*3600; minute:=Trunc(time/60); time:=time-minute*60; second:=Trunc(time); timeStr:=Format('%.2d',[hour])+':'+Format('%.2d',[minute])+':'+Format('%.2d',[second]); lbl1.Caption:='Total Time: '+timeStr; end; //Play procedure TForm1.btnPlayClick(Sender: TObject); begin BASS_ChannelPlay(hs,False); end; //Pause procedure TForm1.btnPauseClick(Sender: TObject); begin BASS_ChannelPause(hs); end;
procedure TForm1.btnDeleteClick(Sender: TObject); begin BASS_StreamFree(hs); //释放流 edt1.Text:='No Audio'; end;
procedure TForm1.chkLoopClick(Sender: TObject); begin if chkLoop.Checked then BASS_ChannelFlags(hs, BASS_SAMPLE_LOOP, BASS_SAMPLE_LOOP) else BASS_ChannelFlags(hs, 0, BASS_SAMPLE_LOOP); end;
//IS Loop procedure TForm1.FormCreate(Sender: TObject); var i:Integer; info: BASS_DEVICEINFO;
begin edt1.Text:='No Audio'; if HiWord(BASS_GetVersion) <> BASSVERSION then ShowMessage('The Bass.dll version is not available'); if not BASS_Init(-1, 44100, 0, 0, nil) then ShowMessage('Initial Error!'); end;
end.
|
请发表评论