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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/
# ?9 e4 j& B+ t; r+ y4 S) q$ a
6 S: B9 T* c1 p参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
/ ]9 L- E' B" m* X% J* @6 [( Z1 B5 V: r/ }

4 D. ?/ x, w) R9 _) s8 Xint DeviceManager::getAudioInputVolumn( const std::string &deviceName )9 m, M  u$ |8 c' J1 a% f
{
% y0 m- g5 x. E' v# U: a) }4 z$ @/ p1 w9 K  z) x3 q. x9 [3 g2 _

  a  N7 I3 K% @4 b' ^% X$ L        MMRESULT          rc;     // 多媒体函数返回结果变量
  y* d1 z# R7 W6 u9 Q        HMIXER            hMixer; // 混合器设备句柄
0 T% t# }- `; E1 ^        MIXERLINE         mxl;    // 音频线路标准状态信息结构体
& t1 r2 q: c7 [: X* g        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体
/ V, t+ Y( ]' ]( L# `        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体! {; f& b0 L; J8 y, }6 b( Y' M

( y# j; D9 v0 h
2 O. Q# |/ }( ^/ a        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即
  B) D" @9 ~5 V6 L0 w        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,9 w/ f7 E' d  U$ q" q
       //可能还是跟声卡驱动有关。
0 M( X6 a3 U: Q9 ?) D7 _        for( int deviceID =0 ; true ; deviceID++ )3 i7 p$ u+ G5 f
        {! a: u  A5 Z* ^3 u5 _# ~  i: s
                // 打开混合器设备
+ t/ L7 r! d: ]( s) p; b- b' {/ K0 L                rc = mixerOpen(&hMixer, // 返回的设备句柄, W+ l4 A* ^3 B6 p
                        deviceID,       // 单声卡的设备ID为零: Z4 Y3 A' A' ]$ `
                        0,       // 不使用回调机制
+ _% `$ S$ o6 w* e                        0,       // 回调函数参数7 q( {! y7 l# P# u/ ]$ E" f% _( s
                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID
% g7 R* A/ G# f* q" i                if( MMSYSERR_NOERROR!=rc )" t" R) A8 {+ x. {5 Y
                {
- z/ T5 C2 D. E  q7 M6 b5 S9 n                        //跳出循环
& ^$ H) o& M* i2 {" A! _                        break;/ c- g* K4 T5 T7 |6 H
                }
) H. h2 g! S, r8 Q7 n' e                // 打开混合器设备无错的话,则
0 J3 O" [3 j8 _4 P* Q7 f# {6 k
1 d/ @- U- X( s3 O, H) H8 `) I0 \5 x4 U+ i! f
                // MIXERLINE 结构体变量清零
4 b& r! [3 w* G7 A                ZeroMemory(&mxl, sizeof(MIXERLINE));
9 F2 b& p7 u/ ^- Y$ u3 U+ J
( B5 J5 ^1 i2 E9 M
2 H% O4 A% j, v- a& x: Y                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本
: w- a! T; D3 r6 M, S                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
5 A4 Z; l: T! T6 |: c- n                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;# H! E4 J7 l' i8 D- d/ W$ m  ^3 a
1 X% \: z9 b8 t3 G

  k- D2 A* b8 E                // 取得混合器设备的指定线路信息2 w( ^" [* k. G/ Z# r
                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,0 O" V: V! A$ \
                        &mxl,* n+ Z4 o. l9 t0 }( U% _: Z
                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息3 ]: Z# C) s3 V8 S2 ]
                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
9 r9 t( a: h3 G2 e: q+ i& F  k                if( rc!=MMSYSERR_NOERROR )
# P4 M! C9 p4 O( N; R0 D* {                {$ L# j1 ]+ `# ?- T4 y/ S* i
                        //无法获取声音输入线路,尝试其他声卡0 \. Q! ^$ A  r
                        continue;% A% W, o2 H% f* U: w
                }, h3 d/ E+ \$ j) E. _+ \
% d) Q8 l* z7 H, D6 g

3 q' c$ B% ^% Q+ b" E6 d/ d                // 取得混合器设备的指定线路信息成功的话,则) X0 @/ q, |1 P2 n5 N; |8 Y
) v% Q& N7 ~8 d) f' f$ m3 P! e* Y
9 G% P( o) E0 x# T1 r$ ^$ C0 x$ s6 E
                // 将连接数保存 0 }% o, \" H* y$ T0 C) S; I- X
                DWORD   dwConnections   =   mxl.cConnections;
$ v. B; m3 A9 x8 P- b) q+ K- {4 X                // 准备获取麦克风设备的ID ) |7 M7 `' ]0 Y
                DWORD   dwLineID = -1;
& {( Q- P5 S3 x2 ?  i8 l) D* N                for( DWORD i=0 ; i<dwConnections; i++ )7 ?# Y- b: s( Z' T! ]0 h! N
                {
8 N2 X. Z0 [& ]+ ?                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
$ `1 h( ^5 T* a* T. B% n6 ^) j                        mxl.dwSource = i;' D) k0 A, [+ h. V& ]3 l- h
                        // 根据SourceID获得连接的信息 , {1 y" @8 w' d2 @
                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl, 7 c! B2 G) F9 \3 `( Z3 E& }( L5 ]
                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); + T6 o5 q  A: o3 M, \# X6 |
                        // 判断函数执行错误 # {# x6 l/ Z0 }) ~% z3 X
                        if( MMSYSERR_NOERROR==rc )
# R" E3 g& p$ g/ K7 n" R                        {
7 f( m/ B- n4 V1 F8 t# J                                // 如果当前设备类型是麦克风,则跳出循环。 ( [8 p9 y( i' L. U# P+ a
                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
! w9 k& Z2 G2 W/ G                                { 2 o- i7 L1 u0 t3 v2 N
                                        dwLineID = mxl.dwLineID;
: U1 Q* B: @& i4 [. k$ p3 f                                        break;
8 {* {: G, o, c" y5 C' ?9 y  [                                }1 s& n" h3 J% Q6 p* F& n
                        }* c8 j# Y( G' G) {
                }9 z' g4 i( P( W: C$ y9 K6 q
                // 如果没有找到,返回失败。 6 J. ]5 P/ A% @5 J; Z( N: c& H7 \
                if( dwLineID==-1 )( K1 M9 U+ E& m0 F1 s9 d; L
                { 3 v9 _* A) C% w6 @; a' o% o
                        //尝试其他声卡4 T. Y9 y( d* H9 w
                        continue;
1 P" z5 h6 ~0 O3 Q: _: ]                }* t; I  x* v; j  T5 Y
3 A, E- [1 U0 t( P

6 X+ T1 G0 U$ S! G6 I' ^                // MIXERCONTROL 结构体变量清零5 }% o7 K0 N* r3 e
                ZeroMemory(&mxc, sizeof(MIXERCONTROL));
! B+ s9 [& A0 Z* c' L7 ^
- `/ Y" u  l0 P# s
+ @+ c% n' T, E: |# v0 H. W                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本
4 ?2 |4 c4 w! e1 B# q7 T, s* _' v
9 G! ]/ Y6 F6 s. ]: \. E& i% N
6 j; A( Z5 T3 J; w2 \6 f                // MIXERLINECONTROLS 结构体变量清零" q' e0 w% v, x6 M9 L/ M4 N! z
                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
! w8 F) n# d" Q( F9 Q0 Z
9 Q4 @9 V7 ]- I, P+ T! ]( D& h0 j
7 j! r) o- S: A                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本
" @- R8 h4 {5 I8 [: ?5 P3 b- ~; W( W! t& b  V) ^
. j- U; L" j. ]2 Z9 `7 v4 v
                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识7 ?5 y/ s3 y: D
                // 控制类型为控制音量
7 B( V9 s6 P5 h0 M                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;: r# W9 ]; ~; V# G
                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数
- }+ W; ~. I  B; t5 Z                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针. h" U- e4 Z; q  ]1 M
                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小
' h, z9 W" f* h3 I4 H
+ {) J- z( U4 \6 X0 J
7 R+ }# D/ X2 m; K& T% n: ], Q                // 取得控制器信息( i/ y4 X) r' `, o+ s
                rc = mixerGetLineControls((HMIXEROBJ)hMixer,
- \4 w$ p& w( g  I% O( p                        &mxlc,
; F( U- `( P5 Q+ k                        MIXER_GETLINECONTROLSF_ONEBYTYPE);& c1 R# l. T" L" E1 u
) y2 s( t6 m/ y) R2 H8 Y' S* t

0 V2 l% S% X1 K8 G/ \9 Q3 z9 G! B                // 取得控制器信息成功的话,则% e# [6 f9 S; q7 F" v* f) r
                if (MMSYSERR_NOERROR == rc)
; h: l  H3 W( r* f- l' R# d" z                {7 f- o6 y% [! Y( j. n4 S
                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
7 U( X; g( G3 z) T                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息9 H) v9 S( h/ t/ ]; l; |
                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)
/ y) m( `/ f6 [: M7 g3 X+ F( A+ w
& T$ ^9 b) z2 r" J* l3 }
" E/ b7 `9 w8 p5 Z, X6 [                        // MIXERCONTROLDETAILS 结构体变量清零
  L0 q" f& G0 L* g1 _9 X0 k" p- d                        ZeroMemory(&mxcd, sizeof(mxcd));* `2 I+ k* j) T& ~  d

4 g# b0 w0 f& i. r5 h$ f+ e: U8 K/ D; a
                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本$ y$ q) o$ k! g. S/ c. w' D  W
                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识
5 p) Z# A8 R/ M6 y( d4 p. r                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针
; O4 T# `; m4 {+ j& g  K                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
0 E; }2 e* D  r1 w% j/ m  C  ]                        mxcd.cChannels = 1;                 // 取得或设置全部通道! g; a* ?0 S* H) C* D& V
: J0 W% M8 X. q2 d+ n

* g' ~7 r$ E* Y& x: h+ u1 {5 I                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
9 f5 Z3 c% o$ ~4 f8 K5 b
9 E7 [( m3 N0 c- m5 R7 R. A
2 k, k0 ]* L: x2 J9 f5 o0 H                        // 获得音量值
9 I7 m  W0 g9 \. V& U- e                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,
$ j9 h/ P/ q- W                                &mxcd,+ b& M* O( k9 B; Q2 w! t, G0 {
                                MIXER_GETCONTROLDETAILSF_VALUE);
7 s, S; {6 T: z
1 I6 y4 E1 ~7 b% E9 T0 q& z
& i  D, _) y9 K- B- d                        if (MMSYSERR_NOERROR == rc): s7 z9 o+ U# ?- f
                        {/ U/ S: T6 g' y4 H
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;
1 O& t6 @( O) s8 a6 f1 D0 s# |2 m/ D9 V  }* C; W

8 e! R$ O' G$ V: d. m" E                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;
6 \0 u0 M5 c; ^                                printf("音量:%X", volStruct.lValue);
: j) a+ {' r7 A# M, E7 j  n                                return index;) a( c8 O) [- i8 N. z2 L! ]
                        }
5 B/ X( g8 t2 `( `$ t6 C                }
  }8 i8 v$ ^' a# ~4 L4 R' j, Z        }
9 P0 F7 D( u0 d1 S
6 a; P+ m+ K2 Z. V2 B; r; [# m7 n5 c2 d) `
        return -1;
7 u* V1 U/ c; l. Q% c8 J}7 I6 }6 c/ J3 A- s6 o
) I+ L6 M, y) p. x  q' G* x1 F
        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html
. T: l. p5 J( q/ w& ]                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-8-13 19:01 , Processed in 0.019119 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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