音量控制的问题 ( 积分: 100 )

  • 主题发起人 主题发起人 HuangRenGX
  • 开始时间 开始时间
H

HuangRenGX

Unregistered / Unconfirmed
GUEST, unregistred user!
据我所知,系统音量应是个独占性资源,但我发现 Windows Media Player 修改音量,并不影响系统的音量,或其它程序的音量,有哪位大虾知道它是如何实现的?
 
据我所知,系统音量应是个独占性资源,但我发现 Windows Media Player 修改音量,并不影响系统的音量,或其它程序的音量,有哪位大虾知道它是如何实现的?
 
我也很好奇,出名点的播放器都有这功能!如winamp,realplayer/千千静音...
 
可能 DX 类吧
 
winamp 好像没这个功能
 
理论上可以实现
如果你在输出音频数据之前,首先对输出音频数据进行调幅,那么完全可以实现如 Windows Media Player 的效果。
 
觉得 abookdog 讲的无道理:
为什么 winamp 和 Windows Media Player 同时播放, winamp 用的是系统音量,而 Windows Media Player 可以使用其自己设定的音量。
 
操作系统的音量是分很多种的!!
主音量控制,波形,SW同步,CD唱机,麦克风,。。。。。。。
给你一些猛料吧。
unit funVolume;

interface

uses MMSystem, Dialogs, windows;

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

function GetVolume(DN:TDeviceName) : DWord ;
procedure SetVolume(DN:TDeviceName;
Value:Word);
function GetVolumeMute(DN:TDeviceName) : Boolean;
procedure SetVolumeMute(DN:TDeviceName;
Value:Boolean);

implementation

//获取音量
function GetVolume(DN:TDeviceName) : DWord;
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
dnMaster : 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
dnMaster : 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
dnMaster : 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
dnMaster : 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.

{

http://www.csdn.net/develop/article/17/17257.shtm

标题 音量调节及静音 Haofei(原作)
关键字 音量调节,静音

在进行多媒体软件开发时,经常要调整各种设备的音量和设置静音,本
人编写了一个单元,四个函数,分别用于获取音量(GetVolume(DN))、
设置音量(SetVolume(DN,Value))、获取静音(GetVolumeMute(DN))
及设置静音(SetVolumeMute(DN,Value))。

}

如果你还不明白我就没办法了。
 
to 张辉明:
谢谢您的热情,我不是不知道如果获取、修改音量,而是如何不独占音量资源:
你可以试试看,用您的代码或别的软件,如 winamp、realplayer、超级解霸等,当修改音量时,打开的音量控制器是否变化,而在 Windows Media Player 中修改音量时,音量控制器又是否变化,就知道了,谢谢继续赐教!
 
控件本身提供啊
比如Dspack就提供了这么个属性。。。
 
这些规格全由微软定的啊,就像现在为什么asp.net跟php争地位,vc++跟delphi争地位一样了
 
解决了,谢谢 Genl
 
后退
顶部