混音器原理及Mixer API函数介绍3

获取,设置某个控件的值

想要获取或设置某个控件的值,你必须知道此控件的ID。可以通过mixerGetControlDetails()获取其当前值,通过mixerSetControlDetails()设置为某个特定的值。这些函数都使用一个类型为MIXERCONTROLDETAILS的结构体。你可以初始化其中的部分域来告诉

mixerGetControlDetails()/mixerSetControlDetails()你想设置/获取哪个控件的值。你同时还得提供另外一个即将存放值的结构。

例如,我们获取线路Speaker Out的音量滑动器控件的当前值,到目前位置,我们已知道了怎样获取这个控件的信息(例如,这个控件的ID)。为了获取控件的值,我们需要提供一个特殊的结构体来存放返回值。

我们需要使用什么样的结构?哦,这要看控件的类型了。音量滑动器控件的类型为

MIXERCONTROL_CONTROLTYPE_VOLUME,如果你回头看一下chart about the fader class of controls,就知道了这个值将使用一个类型为MIXERCONTROLDETAILS_UNSIGNED的结构。这个结构只有一个域dwValue,用于存放返回值。因此我们提供一个MIXERCONTROLDETAILS_UNSIGNED类型的结构给mixerGetControlDetails()(通过MIXERCONTROLDETAILS结构),如下是一个样例程序,获取并输出Speaker Out线路中音量滑动器控件的当前值。

 
 

若要设置一个控件的值,你只需填充此结构,然后将其传递给mixerSetControlDetails()。你同时还要指定MIXER_SETCONTROLDETAILSF_VALUE结构。这里是一个样例程序,其将线路 Speaker Out的音量滑动器控件的值设置为31

 

 
 

多声道控件

前面已说过,当将设置了控件的MIXERCONTROL_CONTROLF_UNIFORM标志时,所有声道都共享同一个值。例如,对于Speaker Out线路,它是立体声线路,但是其左右声道并没有独立的值。

但是,若一个控件的MIXERCONTROL_CONTROLF_UNIFORM值没有设置,并且此控件有一个以上的声道,那么每个声道都有一个独立的值。因为这个原因,当你设置/获取某个控件的值时,你必须提供多个特殊的结构。例如,假设Speaker Out线路的音量滑动器控件没有设置

MIXERCONTROL_CONTROLF_UNIFORM标志。因为此线路有两个声道,所以我们必须提供两个MIXERCONTROLDETAILS_UNSIGNED结构来存放获取/设置其左右声道的值,

我们需要使用一个类型为MIXERCONTROLDETAILS_UNSIGNED数组。第一个MIXERCONTROLDETAILS_UNSIGNED结构将存放第一个声道的值,第二个结构将存放第二个声道的值。如下是一个样例程序,获取我们的Speaker Out线路的音量滑动器控件的左右声道的值:

 
 

To set the values of both channels, you fill in the values of both MIXERCONTROLDETAILS_UNSIGNED structs. Here is an example of setting the left channel's volume to 31 and the right channel's volume to 0.

 
 

当然,一个控件或许有2个以上的控件。对一个给定的控件,你必须提供足够大的结构来容纳所有的声道的值。因此,你必须根据需要来开辟数组空间。

一次存取一个控件中的某几个声道是非法的。例如,一个控件有8个声道,但是你只取其前2个声道的值,这是不允许的。你必须同时存取一个控件的所有声道才可以。但是这里有一条有关设置一个值的规则:如果你仅仅设置第一个声道的值,那么

mixerSetControlDetails()自动将控件设置MIXERCONTROL_CONTROLF_UNIFORM标志。最终结果是此控件的所有声道都被设置为这个值。因此,你可以通过仅仅设置第一个声道的值来达到将所有的声道设置为同一个值的目的。

多条目控件

你不会经常碰到“多条目”控件。一个多条目控件就是那种一个声道关联着多个值的控件。

下面是一个图形均衡器控件。让我们简单的学习一下这个样例。假设一个声卡中有以下3个图形均衡器。

                                   

混音器原理及Mixer API函数介绍3 - 我,猪八戒 - 我,猪八戒的博客

这个控件有3个值与其关联与“低通道”关联的值、与“中通道”关联的值、与“高通道”关联的值。(注:假设每个通道都能设置为不同的值,否则它就是一个无用的图形均衡器了)。这样表现出来的就是一个多条目控件,它有3个值与其关联。

我们再进一步假设这个控件属于Speaker Out线路。

我们来看一下MIXERCONTROL结构体。一个多条目控件的MIXERCONTROL的域dwControlType值会有MIXERCONTROL_CONTROLF_MULTIPLE位标志设置。MIXERCONTROL  cMultipleItems域同时会告诉你每个声道有几个条目。

 
 

首先,注意控件ID不同于此混音器中其它控件的ID。同样要注意的是,还设置了MIXERCONTROL_CONTROLF_MULTIPLE位标志。cMultipleItems被设置为3,表明每个声道有3个条目。(但是我已将此控件设置了MIXERCONTROL_CONTROLF_UNIFORM标志,因此总共只有3个值,即使线路Speaker Out是立体声的。换句话说,每个通道的值同时影响着所有声道)

为了获取3个通道的值,我们需要一个包含3个结构的数组。需要什么类型的结构呢?哦,类型为MIXERCONTROL_CONTROLTYPE_EQUALIZER的控件的种类是fader,因此你会想起此种类的值都使用MIXERCONTROLDETAILS_UNSIGNED类型的结构。如下展示了怎样获取3个通道的值。

 
 

To set the values of all 3 bands, you fill in the values of the MIXERCONTROLDETAILS_UNSIGNED structs. Here is an example of setting the Low band to 31, the Mid band to 0, and the High band to 62.

 
 

现在我们将控件的MIXERCONTROL_CONTROLF_UNIFORM标志去掉。因此,每个声道的每个条目都有其自己的值。因为Speaker Out 有两个声道,那意味着我们需要总计为2 (声道) * 3 (条目)个结构,也就是6个值。我们的图形均衡器如下图所示:  

 

混音器原理及Mixer API函数介绍3 - 我,猪八戒 - 我,猪八戒的博客混音器原理及Mixer API函数介绍3 - 我,猪八戒 - 我,猪八戒的博客
Left ChannelRight Channel

我们需要6个类型为MIXERCONTROLDETAILS_UNSIGNED的结构来存放所有声道的所有条目的值。哦,在前面的样例程序中,我都将这些条目的标签设置过了。如果你希望将他们输出,你就应该向混音器询问这些值。为了达到这个目标,你必须提供一个类型为MIXERCONTROLDETAILS_LISTTEXT结构的数组,就像你提供一组类型为MIXERCONTROLDETAILS_UNSIGNED的结构来获取所有声道的所有条目的值一样。

 
 

一次获取或设置控件中几个条目的值是不行的。例如,若一个控件有8个条目,你仅仅获取其前2个条目的控件是不允许的。你必须同时设置/获取所有的声道的所有条目的值。关于设置条目的值,这里有一个规则:如果你仅仅设置第一个声道的条目的值,那么mixerSetControlDetails()会自动将控件设置MIXERCONTROL_CONTROLF_UNIFORM标记。最终结果就是所有声道的所条目的值都和第一个声道的条目的值相同。因此,你可以通过只设置第一个声道的条目的值达到将所有的声道的条目的值设为相同值的目的。

改变通知

在上面的样例程序中,我已展示了通过mixerOpen()函数打开混音器然后将其返回值用作其它函数。不一定非得这样做。实际上,Mixer API被设计为可以按以下方式使用:取代将打开的混音器句柄作为混音器函数的某个参数的一种方式是,你可以传递混音器ID。因此,你不必显式的打开混音器。

但是如果你想做某些操作,显式的打开混音器设备(通过mixerOpen()函数)会有一些优点。

首先,这会防止混音器被卸载(大概是声卡的驱动所为)。其次,在你打开了一个混音器后,当此混音器的任何线路的状态发生改变时(比如线路被设置为静音),或者某个控件的值改变时,你可以命令windows系统发送一个消息(到你自定义的窗口程序)通知你。你不仅仅在你改变某个线路的状态或某个控件的值时获得这些消息,而且当其它程序打开混音器(注:多个程序可以同时打开一个混音器)并改变某个线路的状态或某个控件的值时也能获取这些消息。因此,当其它程序对混音器做改变时,你可以使你的程序与混音器的状态保持同步。

当你调用mixerOpen()时,你应该将接受通知消息的窗口句柄作为地上那个参数传递给此函数,并将CALLBACK_WINDOW传递给最后一个参数。

这里有2个特殊的“混音器消息”。

MM_MIXM_LINE_CHANGE:当混音器的任何一个线路的状态发生改变时,系统会发送此消息到你的窗口处理程序。

    MM_MIXM_CONTROL_CHANGE:当混音器中的任何一个控件的值发生改变时,系统会发送此消息到你的窗口处理程序。

    对于MM_MIXM_LINE_CHANGEWPARAM参数表示发生改变的线路所属的混音器句柄,LPARAM参数表示此线路的ID

    对于MM_MIXM_CONTROL_CHANGEWPARAM参数表示发生改变的线路所属的混音器句柄,LPARAM参数表示值发生改变的控件的ID

总结

Mixer APIwindows多媒体中最复杂的一组API。你需要一点时间来读懂这篇教程然后将它应用于你的程序中。但是Mixer API使得你可以操作任何已安装的声卡,而不必对某个特定的声卡编写特定的程序。

想获取更多关于混音器结构和API的信息,请参考Microsoft Developer Network's reference upon audio mixers 

微软提供了一个免费下载的关于使用Mixer API的样例程序。但是我发现此代码的注释太简单了,同时有很多和Mixer API无关并且是不必要的代码。我已将此样例程序精简,使得其都是展示如何使用Mixer API的关键代码,并添加了很多注释。你可以下载我修改的版本Microsoft's Mixer Device Example,它将展示了如何显示所有的混音器设备和它们的线路/控件,以及调整控件的值。这个工程是基于Visual C++4.0的,因为它是一个普通的用C语言编写的windows应用程序,因此任何windowsC语言编译器应该都可以编译它。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值