找回密码
 注册
搜索
查看: 4501|回复: 0

利用MIXER获取麦克风录音音量

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/
# N: S/ C3 w* J$ I( S9 k; m6 g* j; d2 X
参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
! h/ S& r# h1 ^! i* y, s
) x/ ^; d  y) U0 P1 c
/ D+ N: h% K3 B' A/ S. Kint DeviceManager::getAudioInputVolumn( const std::string &deviceName )% z( a# T% V0 p% e* X1 D
{
1 i8 u/ w8 v1 i# G& Q
8 ~3 L, g4 w5 D# G* H) s. w( y" k: Q% `$ N0 m* q! G
        MMRESULT          rc;     // 多媒体函数返回结果变量& C. t5 j5 D. S$ ?1 U* ]8 q
        HMIXER            hMixer; // 混合器设备句柄
, ^1 O2 G3 x. h% u! L        MIXERLINE         mxl;    // 音频线路标准状态信息结构体" l* k. a* j; V; Z! O
        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体- u. F8 v9 |3 }; I4 @  Q
        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
1 Y/ S5 x0 M; V, t- U- M9 y1 ~- C$ j% e% }% w0 X
2 x1 `3 I; j/ L9 `8 g, X+ X: X
        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即) ^& z# }+ ^. E/ h) X: E
        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,6 E- N" u  g/ D4 @, @4 v: b3 ?1 Z% B" E
       //可能还是跟声卡驱动有关。( @1 V, m3 \3 h. i  G
        for( int deviceID =0 ; true ; deviceID++ )! S5 z0 R% ~5 B9 _0 ?5 A. A4 T2 V
        {9 K/ c$ Z, P6 J% X9 v! q
                // 打开混合器设备4 i! u# c9 _4 H
                rc = mixerOpen(&hMixer, // 返回的设备句柄4 G8 [7 p- ^4 U) A
                        deviceID,       // 单声卡的设备ID为零
9 q, B3 S" m  c( x- x* B" o                        0,       // 不使用回调机制
' o2 @; e1 N, ]' r9 j7 p                        0,       // 回调函数参数. _% o# }8 A5 d* l5 k  ]
                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID
4 P8 R  j, F& V& W9 V                if( MMSYSERR_NOERROR!=rc )# Q! n1 V/ e( p9 h& h5 s) y8 N
                {
+ U, _& ]5 B1 h8 |1 ^( A                        //跳出循环' Q1 u( r; |( Q! X
                        break;
& G, m2 `" J8 `! ~8 m( L8 q& l                }. ^. |( S6 F+ {) P+ d* J& K- ^
                // 打开混合器设备无错的话,则, c% U% s7 [4 l! G

. u8 Z' @  f: P! c
! T& F( B5 j% X/ G' l( N. N                // MIXERLINE 结构体变量清零
! l3 \4 l( W0 K: c: p+ T                ZeroMemory(&mxl, sizeof(MIXERLINE));
; O) e" U* ~1 N  f: b4 j! Y7 {
0 T# {" u! x* D( Q6 [$ m% p$ t% a* N- S) e
                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本3 P# I# U0 p9 L, m1 ^
                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
+ I( C& Z$ v& S' y/ o6 j0 P$ Z                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
/ p$ Z, M: p; {6 D4 Y1 [; X- c' p
6 ~+ w: P$ }5 z0 d0 ^' F# e3 T+ L. I6 G: u
                // 取得混合器设备的指定线路信息
" H  Q/ h/ {9 |8 g0 V7 ]. `                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,
! @; m+ e& z2 |: q4 v                        &mxl,
! N) ?0 z! y3 R3 B1 S                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息) t8 B" J1 J# H* c+ _
                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);( p4 _1 O' e- j! K- j) a7 u
                if( rc!=MMSYSERR_NOERROR )
* y( U2 A5 F" ^5 k) N                {
- d. o4 Q+ U4 j                        //无法获取声音输入线路,尝试其他声卡' Z" \  i" k+ F$ s6 n! M
                        continue;
3 ?, p0 v6 l) z! p4 }                }! E  H/ P* O( b+ h7 U+ c5 R. c' O
/ H1 J5 z" I" D8 @) ?3 o
# y' S) y3 I6 U" Q% Z% @& z7 B
                // 取得混合器设备的指定线路信息成功的话,则: k# k$ ]6 {$ @! {

8 f9 }( r- ?3 R6 q0 K/ l, L# x4 p+ J( l) n0 r# e' t0 O$ w
                // 将连接数保存
' b6 V3 J, k, _* G: p0 w                DWORD   dwConnections   =   mxl.cConnections; 1 w. \1 s8 L1 V* _; l6 N9 P! n# c1 o
                // 准备获取麦克风设备的ID
! V$ \6 s% U  m                DWORD   dwLineID = -1; 8 J7 e" f! e2 |" g$ U6 i, L
                for( DWORD i=0 ; i<dwConnections; i++ )
2 M' A. d" `! Q( R) u* K                { 8 V& N( R# B4 v& D5 [/ `
                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
) }3 Z- _# o, w2 x. q) q                        mxl.dwSource = i;
" z6 G/ l2 r3 V  \                        // 根据SourceID获得连接的信息
5 r5 s) F1 K. v: P; s( r5 L" r                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl,   R0 e% \/ @9 r. z5 X1 |9 _6 ~- h$ u! r
                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); ! b& G" ^5 h0 W: K( p  ~  T6 [
                        // 判断函数执行错误
1 f! V- B; H& c0 a1 W                        if( MMSYSERR_NOERROR==rc )7 X3 i: C& W0 }- P( E: l  ~
                        {
2 _/ r. b1 L& g; l                                // 如果当前设备类型是麦克风,则跳出循环。 + ~; [% m9 @7 [  [, |' ^
                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
( d, p7 f9 i4 a- g6 K                                { 0 T3 U& u5 C5 ?
                                        dwLineID = mxl.dwLineID;
- W4 r" L1 T* B7 Y                                        break; ( `4 g: q& o) `5 v1 o
                                }1 `, I0 m$ M  N+ m- G% W
                        }
" g; y+ i) `: B' |9 ~                }! e/ i0 `$ X) y! U0 M9 G; R
                // 如果没有找到,返回失败。
: J7 s4 U! D9 L) S; F                if( dwLineID==-1 )  i( Y, U3 s: H
                { ( b1 \$ J8 C; J! l+ C
                        //尝试其他声卡
2 C) @6 ^  K" j                        continue;* }/ k" c5 H1 V3 |
                }- k- I4 w6 T! [

- K' f! S2 @$ H4 N9 A# {3 h2 D" N% W8 f
                // MIXERCONTROL 结构体变量清零
9 s9 G, [- y/ f2 L  p                ZeroMemory(&mxc, sizeof(MIXERCONTROL));; I0 ]' R7 \, b* @9 ]% I% p
' R! K" r& C1 M. C
& y  k+ E% c( u; u* w# ~5 A
                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本! Y: M7 [4 C7 I# U! S

1 c4 a" i. n  h0 E- ]- V$ S$ q- [4 w( N8 b  @6 k% y0 e
                // MIXERLINECONTROLS 结构体变量清零) g' H, w- i3 w. I
                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));/ s7 ]0 M, w4 W& p
. H. q3 Y& c6 S8 e
( S) s! y" ]/ }3 E! k
                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本
* Y4 i# C: X2 b
6 a) X5 e, K1 v8 Z% Y
: K0 S' ]& b, L! u/ H                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识& y! }( z4 @" f0 Q' v% k* y6 }  r; w
                // 控制类型为控制音量
* L7 p+ h( ~1 T3 W7 d* i$ \                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
$ c. n( X. w( K8 w0 M! w& L                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数2 s5 p+ I9 y" w) s8 M% b/ ~0 I
                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针
- a' [: I! W$ H; x7 Q                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小
/ S! E* o9 e6 h) s8 i+ P4 x5 l: o% g4 W- p

( l$ G: E5 ?) O7 ]/ J                // 取得控制器信息
! ?1 _& J3 V/ w& T1 O1 u                rc = mixerGetLineControls((HMIXEROBJ)hMixer,& Y' ?* x  s( ]/ L, ?
                        &mxlc,
4 X- Z- T$ L3 g2 M. V4 v7 B! H& R4 ?                        MIXER_GETLINECONTROLSF_ONEBYTYPE);. Q  W6 @( H4 g

0 c0 p9 I7 Q3 i6 q- o0 w9 B. V. N- u3 B: I, u" K
                // 取得控制器信息成功的话,则
# \( L& v0 E: g  f5 m                if (MMSYSERR_NOERROR == rc)7 W6 {' f+ m) w# u' X. |4 x) x
                {
+ K7 U% r& M+ _& \  E: B5 v                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
, t8 U% `& ^, t( Z" Q- S                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
% \1 R% P& t6 }  ]( K                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)  n  ?) l/ O0 t$ X

; [9 S* N( X2 m1 e+ n) c; f6 t+ J! ^9 s. Z# u$ b# Y- z/ g
                        // MIXERCONTROLDETAILS 结构体变量清零
0 f, n. M, M) }/ ?2 x: v- }, G                        ZeroMemory(&mxcd, sizeof(mxcd));
0 \! m5 h: t8 N2 N) r5 z! x+ c6 U% Q* S
; w  x* b8 Q9 Q/ g. f  p2 K
                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本
5 V# M" ], \1 h# k1 |6 L                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识
$ \/ l0 {) [  S) T7 s                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针
- p( E; m& ?" m; g8 V/ Z3 A                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小6 }" Y7 H' e- O! n# a
                        mxcd.cChannels = 1;                 // 取得或设置全部通道
0 @4 ^5 |  M- Q$ C/ Z. l
& E1 m, Q6 r, ~! H; f
4 O) ~+ u+ d0 W. w                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum. " P" s  m/ U. G
- V8 g! m! ?# P" V9 t
) i5 b1 j  y0 e
                        // 获得音量值
4 r1 e, \1 R' ?                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,
' U7 M8 ^( s+ l! W; a                                &mxcd,
# i6 a: \" Z$ t9 g                                MIXER_GETCONTROLDETAILSF_VALUE);0 S7 v5 k# q! l/ P$ b& Q7 t: t
; v2 |4 y8 s+ T3 j1 g+ T* l
. u' u" E- \- W; d
                        if (MMSYSERR_NOERROR == rc)
$ @+ K1 F3 a5 I4 ~8 V                        {  ^0 ]! Q- R6 d7 g2 r, O
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;* g: D' a) K8 \' m

6 v4 a& l# K& Z) H8 l" Y  \. _1 M& P- z
                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;
, ?- t, w; L0 e1 c                                printf("音量:%X", volStruct.lValue);5 I1 N5 o2 t" u9 {8 k
                                return index;0 o2 F- T1 h' B( j! _/ T
                        }
) ?! _# R' C. N5 i: n& m                }, E/ l. o7 F" m: u" I
        }% M+ h% M8 r( D/ a

. F3 L& O* h. t9 L3 y+ o! c* k3 F4 d2 e
        return -1;  V) b/ j, j( h5 F( C# |
}
2 }: P/ N3 X! d! z
) h/ {1 R& L0 L+ K, n8 E        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html6 N" t. N( ^, P4 C9 p. f
                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|宁德市腾云网络科技有限公司 ( 闽ICP备2022007940号-5|闽公网安备 35092202000206号 )

GMT+8, 2025-9-30 08:57 , Processed in 0.034004 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表