如何自动控制音量,让每首歌在听的时候音量都一样 ( 积分: 200 )

  • 主题发起人 主题发起人 dali2000
  • 开始时间 开始时间
D

dali2000

Unregistered / Unconfirmed
GUEST, unregistred user!
我是想知道硬盘里存的每首MP3的电平,这样就可以在我软件中自动控制音量,让每首歌在听的时候音量都一样,免得在放歌时有些歌的音量大有些歌小.
 
我是想知道硬盘里存的每首MP3的电平,这样就可以在我软件中自动控制音量,让每首歌在听的时候音量都一样,免得在放歌时有些歌的音量大有些歌小.
 
不可能,因每首歌的录制音量皆不同。
 
就是因为每首歌的录制音量皆不同,放歌时有些歌音量大.方法应是有的,我见过一个点歌系统有过这功能,不知是如何实现的
 
点歌系统是不是他本身就有一个数据库
数据库存有
歌曲名 歌曲路径 歌曲音量
通过人来听每一首歌的音量,再在数据库里设定,
播放时就通过设定的播放呢
 
.................
 
bjaman你没有理解到房主的意思,是要让所以的歌的音量都差不多高,
照你的方法,只能是把高音的歌调低,但是不能把低间的歌调高哈
 
.................
 
我也很想知道,UP一下!
 
学习一下
 
//音量控制
procedure TForm1.TrackBar1Change(Sender: TObject);
var
t,v:Longint;
begin

// if a=0 then
Exit;
t:=TrackBar1.Position;
v:=(t shl 8)or(t shl 24);
waveOutSetVolume(0,v);
end;


procedure tform1.trackbar1changer (sender:tobject);//左声道
var t,v:longint;
begin

t:=trackbar1.postion;
wavoutgetvolume(0,@v);
v:=v and $ffff0000 or (t shl 8);
wavoutsetvolume(0,v);
end;


procedure tform1.trackbar2changer (sender:tobject);//右声道
var t,v:longint;
begin

t:=trackbar2.postion;
wavoutgetvolume(0,@v);
v:=v and $0000ffff or (t shl 24);
wavoutsetvolume(0,v);
end;


//获得当前音量值
procedure TForm1.FormCreate(Sender: TObject);
var
v:longint;
begin

waveOutGetVolume(0,@v);
TrackBar2.Position:=hi(v);
TrackBar3.Position:=hi(v shr 16);
if hi(v)>hi(v shr 16) then

TrackBar1.Position:=hi(v)
else

TrackBar1.Position:=hi(v shr 16);
end;


end.



函数说明:

uses MMSystem;

waveOutSetVolume
第一个参数是波形文件输出设备标识符;
第二个参娄是音量大小。这是一个32位的整数,低16位表示左声道的音量,
高16位表示右声道的音量。

waveOutGetVolume
第一个参数是波形文件输出设备标识符;
第二个参数是一个32位整数的指针。


可以用auxoutsetvolume(id:integer,volume:dword);具体使用方法请查阅DELPHI帮助,WIN32SDK.HLP。 其中ID是设备代号,我在实际编程中发现ID随着机器的不同而不同,但是他可以直接控制各种设备的音量,你可以用不同的ID试一试(ID一般在1~8之间),音量设置方法wjiachun好象没错

12.
{  已经有很多文章介绍过控制总音量的方法,但控制左右声道音量的方法却很少有文章介绍,本人介绍一种用Delphi实现控制左右声道音量的妙法,希望能给你的程序添彩。
  一、调节全部音量
  1.先在窗体中添加一个trackbar控件,可通过改变它的位置来调节音量,在trackbar1的属性中,我们把Max属性修改成255,改成这个值是为了便于进行二进制的音量调节操作。
  2.为了调用一个Windows函数,在uses子句里加上Mmsystem。
  3.为trackbar1的Onchange事件编写如下代码:
  procedure Tform1.TrackBar1change(Sender:Tobject);
  var t,v:longint;// t的最大值为8位的二进制:11111111;用v来表示音量的大小,这是个32位的整数,高16位表示右声道的音量,低16位表示左声道的音量
  begin

  t:=trackbar1.Position;//得到Trackbar的位置,可用这个值来表示音量的大小
  v:=(t shl 8) or (t shl 24);//将t左移8位、24位
  waveoutsetvolume(0,v);//设置音量
  end;
  二、分别控制两个声道的方法
  1.控制左声道
  procedure Tform1.TrackBar1change(Sender:Tobject);
  var t,v:longint;
  begin

  t:=trackbar1.Position;
  waveoutgetvolume(0,@v);//@表示指向变量v的指针(32位),调用此函数的用意就是得到右声道的值,做到在调节左声道的时候,不改变右声道
  v:=v and $ffff0000 or (t shl 8);//数字前面加$表示是十六进制数字
  waveoutsetvolume(0,v);
  end;
  2.控制右声道
  procedure Tform1.TrackBar2change(Sender:Tobject);
  var t,v:longint;//它的原理同上
  begin

  t:=trackbar2.Position;
  waveoutgetvolume(0,@v);
  v:=v and $0000ffff or (t shl 24);
  waveoutsetvolume(0,v);
  end;
  三、设置滑块的初始位置
  1.程序开始执行时,缺省情况下,Trackbar的位置在0,但我们希望程序开始执行时,这两个滑块能自动得到当前的音量,而处在相应的位置。
  procedure TForm1.FormCreate(Sender: TObject);
  var v:longint;
  begin

  waveoutgetvolume(0,@v);//得到现在音量
  trackbar1.Position:=hi(v);//设置左滑块的正确位置
  trackbar2.Position:=hi(v shr 16);//设置右声道滑块的正确位置
  end;
  注:函数hi(v)的作用为:返回一个16位无符号整数的高8位值。如果v为32位,则高16位自动被忽略了。
  2.只使用高8位时,可使调节效果更明显。
  3.对波形文件可以用waveoutgetvolume函数,对cd文件可以用auxgetvolume函数。
  注:以上程序均在Delphi 5.0,Windows 98SE下调试通过。}
 
调节音量的方法我已查出,不是采用楼上的这些方法,楼上的方法我感觉不是很好.我感觉比较好的方法如下(可以控制Master, Microphone, WaveOut, Synth):
//在进行多媒体软件开发时,经常要调整各种设备的音量和设置静音,有人编写了一个单元,四个函数,分别用于获取音量(GetVolume(DN))、设置音量(SetVolume(DN,Value))、获取静音(GetVolumeMute(DN))及设置静音(SetVolumeMute(DN,Value))。

unit funVolume;

interface

uses MMSystem, Dialogs;

Type TDeviceName = (Master, Microphone, WaveOut, Synth);

function GetVolume(DN:TDeviceName) : Word ;
//获取音量 (0~65535)
procedure SetVolume(DN:TDeviceName;
Value:Word);
//设置音量
function GetVolumeMute(DN:TDeviceName) : Boolean;
//获取静音
procedure SetVolumeMute(DN:TDeviceName;
Value:Boolean);
//设置静音

implementation

//获取音量
function GetVolume(DN:TDeviceName) : Word;
var
hMix: HMIXER;
mxlc: MIXERLINECONTROLS;
mxcd: TMIXERCONTROLDETAILS;
vol: TMIXERCONTROLDETAILS_UNSIGNED;
mxc: MIXERCONTROL;
mxl: TMixerLine;
intRet: Integer;
nMixerDevs: Integer;
begin

// Check if Mixer is available
nMixerDevs := mixerGetNumDevs();
if (nMixerDevs < 1) then

begin

Exit;
end;


// open the mixer
intRet := mixerOpen(@hMix, 0, 0, 0, 0);
if intRet = MMSYSERR_NOERROR then

begin

case DN of
Master : mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
Microphone :
mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
WaveOut : mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
Synth : mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER;
end;

mxl.cbStruct := SizeOf(mxl);

// get line info
intRet := mixerGetLineInfo(hMix, @mxl, MIXER_GETLINEINFOF_COMPONENTTYPE);

if intRet = MMSYSERR_NOERROR then

begin

FillChar(mxlc, SizeOf(mxlc),0);
mxlc.cbStruct := SizeOf(mxlc);
mxlc.dwLineID := mxl.dwLineID;
mxlc.dwControlType := MIXERCONTROL_CONTROLTYPE_VOLUME;
mxlc.cControls := 1;
mxlc.cbmxctrl := SizeOf(mxc);

mxlc.pamxctrl := @mxc;
intRet := mixerGetLineControls(hMix, @mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE);

if intRet = MMSYSERR_NOERROR then

begin

FillChar(mxcd, SizeOf(mxcd),0);
mxcd.dwControlID := mxc.dwControlID;
mxcd.cbStruct := SizeOf(mxcd);
mxcd.cMultipleItems := 0;
mxcd.cbDetails := SizeOf(Vol);
mxcd.paDetails := @vol;
mxcd.cChannels := 1;

intRet := mixerGetControlDetails(hMix, @mxcd,MIXER_SETCONTROLDETAILSF_VALUE);

Result := vol.dwValue ;

if intRet <> MMSYSERR_NOERROR then

ShowMessage('GetControlDetails Error');
end
else

ShowMessage('GetLineInfo Error');
end;

intRet := mixerClose(hMix);
end;

end;


//设置音量
procedure setVolume(DN:TDeviceName;
Value : Word);
var
hMix: HMIXER;
mxlc: MIXERLINECONTROLS;
mxcd: TMIXERCONTROLDETAILS;
vol: TMIXERCONTROLDETAILS_UNSIGNED;
mxc: MIXERCONTROL;
mxl: TMixerLine;
intRet: Integer;
nMixerDevs: Integer;
begin

// Check if Mixer is available
nMixerDevs := mixerGetNumDevs();
if (nMixerDevs < 1) then

begin

Exit;
end;


// open the mixer
intRet := mixerOpen(@hMix, 0, 0, 0, 0);
if intRet = MMSYSERR_NOERROR then

begin

case DN of
Master : mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
Microphone :
mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
WaveOut : mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
Synth : mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER;
end;

mxl.cbStruct := SizeOf(mxl);

// get line info
intRet := mixerGetLineInfo(hMix, @mxl, MIXER_GETLINEINFOF_COMPONENTTYPE);

if intRet = MMSYSERR_NOERROR then

begin

FillChar(mxlc, SizeOf(mxlc),0);
mxlc.cbStruct := SizeOf(mxlc);
mxlc.dwLineID := mxl.dwLineID;
mxlc.dwControlType := MIXERCONTROL_CONTROLTYPE_VOLUME;
mxlc.cControls := 1;
mxlc.cbmxctrl := SizeOf(mxc);

mxlc.pamxctrl := @mxc;
intRet := mixerGetLineControls(hMix, @mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE);

if intRet = MMSYSERR_NOERROR then

begin

FillChar(mxcd, SizeOf(mxcd),0);
mxcd.dwControlID := mxc.dwControlID;
mxcd.cbStruct := SizeOf(mxcd);
mxcd.cMultipleItems := 0;
mxcd.cbDetails := SizeOf(Vol);
mxcd.paDetails := @vol;
mxcd.cChannels := 1;

vol.dwValue := Value;

intRet := mixerSetControlDetails(hMix, @mxcd,MIXER_SETCONTROLDETAILSF_VALUE);

if intRet <> MMSYSERR_NOERROR then

ShowMessage('SetControlDetails Error');
end
else

ShowMessage('GetLineInfo Error');
end;

intRet := mixerClose(hMix);
end;

end;


//获取静音
function GetVolumeMute(DN:TDeviceName) : Boolean;
var
hMix: HMIXER;
mxlc: MIXERLINECONTROLS;
mxcd: TMIXERCONTROLDETAILS;
vol: TMIXERCONTROLDETAILS_UNSIGNED;
mxc: MIXERCONTROL;
mxl: TMixerLine;
intRet: Integer;
nMixerDevs: Integer;
mcdMute: MIXERCONTROLDETAILS_BOOLEAN;
begin

// Check if Mixer is available
nMixerDevs := mixerGetNumDevs();
if (nMixerDevs < 1) then

begin

Exit;
end;


// open the mixer
intRet := mixerOpen(@hMix, 0, 0, 0, 0);
if intRet = MMSYSERR_NOERROR then

begin

case DN of
Master : mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
Microphone :
mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
WaveOut : mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
Synth : mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER;
end;

mxl.cbStruct := SizeOf(mxl);

// mixerline info
intRet := mixerGetLineInfo(hMix, @mxl, MIXER_GETLINEINFOF_COMPONENTTYPE);

if intRet = MMSYSERR_NOERROR then

begin

FillChar(mxlc, SizeOf(mxlc),0);
mxlc.cbStruct := SizeOf(mxlc);
mxlc.dwLineID := mxl.dwLineID;
mxlc.dwControlType := MIXERCONTROL_CONTROLTYPE_MUTE;
mxlc.cControls := 1;
mxlc.cbmxctrl := SizeOf(mxc);
mxlc.pamxctrl := @mxc;

// Get the mute control
intRet := mixerGetLineControls(hMix, @mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE);

if intRet = MMSYSERR_NOERROR then

begin

FillChar(mxcd, SizeOf(mxcd),0);
mxcd.cbStruct := SizeOf(TMIXERCONTROLDETAILS);
mxcd.dwControlID := mxc.dwControlID;
mxcd.cChannels := 1;
mxcd.cbDetails := SizeOf(MIXERCONTROLDETAILS_BOOLEAN);
mxcd.paDetails := @mcdMute;

// Get mute
intRet := mixerGetControlDetails(hMix, @mxcd, MIXER_SETCONTROLDETAILSF_VALUE);

if mcdMute.fValue = 0 then
Result:=false
else
Result := True;

if intRet <> MMSYSERR_NOERROR then

ShowMessage('SetControlDetails Error');
end
else

ShowMessage('GetLineInfo Error');
end;


intRet := mixerClose(hMix);
end;

end;


//设置静音
procedure SetVolumeMute(DN:TDeviceName;
Value:Boolean);
var
hMix: HMIXER;
mxlc: MIXERLINECONTROLS;
mxcd: TMIXERCONTROLDETAILS;
vol: TMIXERCONTROLDETAILS_UNSIGNED;
mxc: MIXERCONTROL;
mxl: TMixerLine;
intRet: Integer;
nMixerDevs: Integer;
mcdMute: MIXERCONTROLDETAILS_BOOLEAN;
begin

// Check if Mixer is available
nMixerDevs := mixerGetNumDevs();
if (nMixerDevs < 1) then

begin

Exit;
end;


// open the mixer
intRet := mixerOpen(@hMix, 0, 0, 0, 0);
if intRet = MMSYSERR_NOERROR then

begin

case DN of
Master : mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
Microphone :
mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
WaveOut : mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
Synth : mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER;
end;

mxl.cbStruct := SizeOf(mxl);

// mixerline info
intRet := mixerGetLineInfo(hMix, @mxl, MIXER_GETLINEINFOF_COMPONENTTYPE);

if intRet = MMSYSERR_NOERROR then

begin

FillChar(mxlc, SizeOf(mxlc),0);
mxlc.cbStruct := SizeOf(mxlc);
mxlc.dwLineID := mxl.dwLineID;
mxlc.dwControlType := MIXERCONTROL_CONTROLTYPE_MUTE;
mxlc.cControls := 1;
mxlc.cbmxctrl := SizeOf(mxc);
mxlc.pamxctrl := @mxc;

// Get the mute control
intRet := mixerGetLineControls(hMix, @mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE);

if intRet = MMSYSERR_NOERROR then

begin

FillChar(mxcd, SizeOf(mxcd),0);
mxcd.cbStruct := SizeOf(TMIXERCONTROLDETAILS);
mxcd.dwControlID := mxc.dwControlID;
mxcd.cChannels := 1;
mxcd.cbDetails := SizeOf(MIXERCONTROLDETAILS_BOOLEAN);
mxcd.paDetails := @mcdMute;

// Set and UnSet mute
mcdMute.fValue := Ord(Value);
intRet := mixerSetControlDetails(hMix, @mxcd, MIXER_SETCONTROLDETAILSF_VALUE);

if intRet <> MMSYSERR_NOERROR then

ShowMessage('SetControlDetails Error');
end
else

ShowMessage('GetLineInfo Error');
end;


intRet := mixerClose(hMix);
end;

end;

end.
 
的问题是如何得到MP3歌曲的音量,以便进行调节.
就如有个软件(MP3Gain)可以将MP3歌曲的音量分析并调整到相同大小的软件.
 
winamp的插件就可以实现这个功能,难道非要自己搞吗?楼主提的问题也不算创新。
 
音量就是通过人来听的,先找一首歌为标准,其他的歌听出来把音量和这首歌调成差不多大小,然后把音量写进数据库里面,只有这样才行,点歌系统就是这么搞的:(
 
可能也有硬件直接调整音高什么的,不过现阶段没有看到有软件这样做的
 
WAV文件记录的数据是音量吧。。。。。。。
遍历整个文件 找到音量的最大值。。。假如是8位的声音。。。
假如找到最大值是255。。。说明这个音乐已经最大了。。。
比如找到最大值是200。。。那么就将数据/200*255计算放大。。。。

如果用DirectShow作的播放器 那么无论什么音频(MiDi除外)最后一定是变成WAV(PCM)
输出的 加个Filter就可以做以上处理
实际上8位声音好像情况不多 16位 24位比较常见
 
不好办吧,我研究过,最大值可能是个“听不到”的峰值,最小值也可能是瞬间的0,
求n个最大值的平均值可能好些
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部