zoukankan      html  css  js  c++  java
  • Delphi利用Bass.dll播放音频

    正好要做一个能够播放音频的模块,看到万一的博客中关于用BASS做音频处理的一些例子,正好满足我的需求。

    http://www.un4seen.com下载BASS 2.4.8,解压包后要设置Bass.dll路径和导入Bass.pas

    Delphi 中使用前, 有三步工作要做:
    1
    、复制 Bass.dll 到系统可以识别的文件夹, 譬如: Windows\System32WindowsWindows\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.



  • 相关阅读:
    增强for循环
    java魔性的类型
    回溯算法
    UE4报错cmd.exe failed with args /c
    C#中GetHashCode的各类实现
    Unity3D中的meta文件笔记
    数值分析笔记(3)——数值计算中的原则
    数值分析笔记(2)——有效数字
    数值分析笔记(1)——误差的来源和分类
    数值分析笔记(0)——数值分析研究的对象和内容
  • 原文地址:https://www.cnblogs.com/skybdemq/p/2184374.html
Copyright © 2011-2022 走看看