2013年3月14日星期四

【转】在Delphi中实现音量的控制

   多媒体的应用,往往离不开音频文件,DELPHI偏偏不带音量控制的控件,虽然可以安装第三方的音量控制控件,不过对于我们这些编程的超级菜鸟来说,自己动手才是丰脑之道,这里,我利用API函数就实现了WAVE文件的总音量控制及左右声道音量分别控制。

    为了调用Windows函数,先在Uses中加上MMSystem,Delphi提供了调用WaveOutSetVolume 函数的Pascal语言的接口,不信看看MMSystem.pas文件*&^@*<。

    我编了演示程序,界面如下: 
    加入三个TrackBar,分别命名为TB_vol,TB_l,TB_r,将Max值设为255(即8位二进制数的最大值),Frequency的值设为10。

    先看看总音量控制的实现:  

procedure TForm1.TB_volChange(Sender: TObject);
var
  pos,vol:longint;
begin
  pos:=TB_vol.Position;
  vol:=(pos shl 8)or(pos shl 24);
  waveoutsetvolume(0,vol);
end;

    首先我们得到TrackBar的位置,用这个值来记录音量的大小,第二句转换Windows函数中对应的正确形式,末一句设置音量。
    WaveOutSetVolume函数有两个参数:
    第一个参数为波形文件输出设备的标识符,这里的标识符为0。
    第二个参数为音量的大小,他是一个32位的整数,低16位表示左声道的音量,高16位表示右声道的音量。
    由于TrackBar只用8位二进制数表示音量,因而先把得到的8位音量值pos左移8位,变成左声到16为中的高8位,然后将pos右移24位,变成右声到16为中的高8位,将两个值进行or运算赋给vol,将vol加给WaveOutSetVolume函数的第二个参数,这样就可以实现同时改变两个声道的音量了。

    理解上述方法后,分别控制左右声道就不难了,看看左声道的实现:
 
procedure TForm1.TB_lChange(Sender: TObject);
var
  pos,vol:longint;
begin
  pos:=TB_l.Position;
  waveoutgetvolume(0,@vol);
  vol:=vol and $ffff0000 or (pos shl 8);
  waveoutsetvolume(0,vol);
end;
   
    由于只修改左声道的值,为了保存右声道的音量,即保存得到音量值pos的高16位,我们将vol和$ffff0000(16进制数)进行or运算,这样,vol的低16位被清零,高16位保持不变,再将低16位左移8位表示新的左声道的音量。

    右声道同理实现   
procedure TForm1.TB_rChange(Sender: TObject);
var
  pos,vol:longint;
begin
  pos:=TB_r.Position;
  waveoutgetvolume(0,@vol);
  vol:=vol and $0000ffff or (pos shl 24);
  waveoutsetvolume(0,vol);
end;
   
    同时,我们为了程序一运行滑块就能到当前的音量(完善完善嘛),需要在Form的Create事件中加入以下语句:

procedure TForm1.FormCreate(Sender: TObject);
var
  vol:longint;
begin
  waveoutgetvolume(0,@vol);
  TB_l.Position :=hi(vol); {设置左声道音量}
  TB_r.Position :=hi(vol shr 16); {设置右声道音量}
end;
   
    到此,一个控制音量的程序就OK了,以上在Delphi5.2中调试通过。

没有评论: