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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/, \/ A3 [! |  ^, K
  k! F) P7 d6 a3 |6 D
参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
* J1 ^. j+ T% z( T9 {! Z) j/ ?& g7 c6 y

8 M& x1 w* d; \8 V% G' U* dint DeviceManager::getAudioInputVolumn( const std::string &deviceName )2 P9 u" E0 L$ h& E; N1 U) q
{( A5 r$ K( l+ c1 j! d' X! C7 w6 e
- C" k+ a: a5 g: s+ k4 D

3 m' i2 q' N# u1 I: E        MMRESULT          rc;     // 多媒体函数返回结果变量
, X- n# n1 G# b/ n: h' h9 s        HMIXER            hMixer; // 混合器设备句柄
* z. c% \  s5 p* t        MIXERLINE         mxl;    // 音频线路标准状态信息结构体
- \, O  |1 y( y$ H        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体) @8 |9 y! |2 {
        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
5 a3 D" j$ S& `3 p, i0 e
" `/ C% P% L- ?& W6 t9 E) d3 [, ^$ F8 v8 _' K4 j! a9 ^. D2 V8 `# O
        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即
: i# X; T$ p5 z% w- ]* r        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,3 y  V4 n# Y0 I1 @
       //可能还是跟声卡驱动有关。
) T5 h  ?1 ~3 t: F% b        for( int deviceID =0 ; true ; deviceID++ )
5 I5 r& v7 {5 E) M        {
2 }, V, m" Z( Z+ i/ m7 W& V, |                // 打开混合器设备: i( @, ~2 R, Z, u) g! j9 Q. M
                rc = mixerOpen(&hMixer, // 返回的设备句柄3 `# B: N4 Z8 l# f: g
                        deviceID,       // 单声卡的设备ID为零
0 x& _" O5 B) q, ]$ w! G* Q; m                        0,       // 不使用回调机制
" [: V2 O. T( m' p                        0,       // 回调函数参数
+ n9 r# p+ I! p2 {7 F% w                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID
1 A8 Q) L% ]' O; J) z- ]9 n$ O+ m                if( MMSYSERR_NOERROR!=rc )
$ i; i7 n- v# [$ a: K+ k                {
+ C& h- _# u, ^# |( c; W! ?. P3 T                        //跳出循环
! r0 @/ `  A( S                        break;2 N: m( d/ `, @% f
                }% O% n8 p: k) Z2 T; z) y
                // 打开混合器设备无错的话,则
' \- F- V! O1 s/ O1 m' C. k0 }9 _4 z/ U& S" C, Z+ s

/ P* Z. W! {0 ?* f0 B0 z, C, j" n, z                // MIXERLINE 结构体变量清零
' j5 R, k$ s$ L2 R                ZeroMemory(&mxl, sizeof(MIXERLINE));
* T* @4 r4 S1 T* H" F
- C. E4 _4 w( s$ g1 Z9 V0 w! _9 y2 T% {* w
                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本0 I& x% ~7 [1 Z& a8 ~# x" @9 _
                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS  \3 b- q" Z) \. V2 g9 L
                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;8 z: i  T" E% _$ }: g) x$ M$ C

4 X8 l- d& L; E* ~6 `
  k3 i' C+ x! n& d* ^* }7 o8 e9 H3 q                // 取得混合器设备的指定线路信息
% H! p; \& `* y6 O4 [* ?. `                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,: @& q( V: z& b. n4 D
                        &mxl," ]4 S, m+ W/ v
                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息
+ x" q5 A; j6 E. D                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
- k* @+ @% Y( X3 ~                if( rc!=MMSYSERR_NOERROR )
, F1 \( i% s# B( {  @* L                {
8 c0 v/ I+ r2 [  d: @- V                        //无法获取声音输入线路,尝试其他声卡4 M- k7 d* H8 z: a, f9 }. ^( n  P
                        continue;
) G+ N4 T; R& h1 g                }) D  l- I* C1 d# R1 L  v/ [; N+ ]1 K

7 F: ?- K) h+ u4 B
* {, i5 Z: k& j' x, [                // 取得混合器设备的指定线路信息成功的话,则
3 b8 ~% Y" L# ]3 x* F2 `
) Y3 F* D1 |$ ^8 j2 X0 h
# j( q+ M0 E" J. \; G# i                // 将连接数保存
. f1 {: Q& c0 @& M% l" }3 S                DWORD   dwConnections   =   mxl.cConnections; & _3 ?& O  e' f. o
                // 准备获取麦克风设备的ID 0 W+ k+ e% i: q6 c6 A5 n
                DWORD   dwLineID = -1;
0 J) |1 U6 D# Y                for( DWORD i=0 ; i<dwConnections; i++ )
5 p  e" R, z: J" Q' z) A- I+ M                { 3 I! v- T8 F5 U+ [1 P; M
                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
* y. `* t, B, F6 c" E% d4 z8 r                        mxl.dwSource = i;5 g( M- \. I# I- G; ^
                        // 根据SourceID获得连接的信息
( L" E% e( l7 ~0 K1 }- e; q                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl,
7 j" M8 S  }5 x: C# {2 q0 e  V                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   );
8 S) e) g+ n7 s& y! H                        // 判断函数执行错误 ; F; k) ?+ I0 [) ]. ]& g, M# ]) X
                        if( MMSYSERR_NOERROR==rc )
0 J9 L2 G1 I$ Z- x2 N1 v                        {
) A) t9 r) m& L* j( Y+ \                                // 如果当前设备类型是麦克风,则跳出循环。
( J/ r6 l+ v4 ^4 V$ k- p( }                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )& p) t; C/ E9 ~1 m/ g  P& R
                                { 0 v" ^" S3 x- d; {! G4 y  A
                                        dwLineID = mxl.dwLineID; % E& x2 @5 U+ \2 Z7 ^
                                        break; 9 ^! x' H. x( O9 y/ ?, i
                                }
2 g6 R% |  l0 H! R1 T                        }) x. }$ ~4 |# F4 P5 m' B
                }6 E/ {) i& _* d
                // 如果没有找到,返回失败。 4 q3 q* W* J8 o) i  p
                if( dwLineID==-1 )1 G+ \" X( o5 z. i9 c0 y, U
                {
5 n7 Q' `1 K& o: @                        //尝试其他声卡: Q. w6 n$ E/ _& m; s
                        continue;
7 {' ~6 j6 U" B: r. p/ e  S$ u0 J                }! f) N+ w0 s7 S" s/ h. l' D5 T
% b/ u2 L  t  i8 {# N3 M) N# g, x

' D* T7 N# f# ~' n                // MIXERCONTROL 结构体变量清零' w, {: o+ Y1 L
                ZeroMemory(&mxc, sizeof(MIXERCONTROL));
/ K9 |9 X% U' Q: B7 n7 E) W; X
. d: M) x3 c4 [+ \
: e/ G+ d+ k6 `( f9 S                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本
; L  \* e2 v0 e6 p! o
  u' f* F: Y4 K6 g1 `; w
+ Y8 k$ F" g. _1 d# H                // MIXERLINECONTROLS 结构体变量清零/ y+ M3 }9 Q6 Y& A5 `9 f
                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));4 L# p& E' K5 H% M/ x! R, O

6 B1 z- N# k0 W4 U  f
! p$ m1 y( C* x6 P' p/ d                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本4 C! _' K( b7 q' }$ ?  U0 m4 A3 x. Z

  N; d( Q' A! x0 A: t  @1 v7 c6 L  T/ \: {
                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识9 ]& O1 ~& |2 u9 T! @3 B5 H( ^3 Q
                // 控制类型为控制音量1 d0 @2 H# U$ d! N9 j
                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
( _) d8 O$ N4 K4 j7 K9 l* p                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数, a' v  t* A) K5 o8 W: R9 T; f
                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针: K4 \5 K# J$ L4 U7 o9 W9 w
                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小
/ g0 d9 h  w; V0 O1 S0 u9 W- q: q- G+ K$ v/ |
! X! A+ b/ b% b7 T- F$ N( }
                // 取得控制器信息) a$ Y9 E1 E( P( x1 B
                rc = mixerGetLineControls((HMIXEROBJ)hMixer,* n- X- g. C& X7 q2 G. P
                        &mxlc,3 N& s6 p& X7 L2 @' z. e/ c; Y1 w
                        MIXER_GETLINECONTROLSF_ONEBYTYPE);1 E. u5 K3 \2 P! j6 V) ^+ |& `
* y# {# i; F7 G3 |# N
$ a: {1 C* a) t. ^$ ^# ]# @$ Y
                // 取得控制器信息成功的话,则* c' Q4 F& k' V" l, _# Z: V3 t! A
                if (MMSYSERR_NOERROR == rc)
/ {/ ^% V/ T) c: j                {# {# t. |$ V% l/ ?' G$ Z3 n
                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
+ |4 `8 P; H* O% I2 I3 B                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
' j, @8 @8 i3 g" q                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)" k3 f0 [# n: k0 k* n6 f

  H+ ?) M1 n  N- M9 i1 m  L. o4 Y- l* J: P5 r9 k7 q
                        // MIXERCONTROLDETAILS 结构体变量清零" t, c# _! `& O4 t4 z- x+ y. v
                        ZeroMemory(&mxcd, sizeof(mxcd));
, d2 i; U6 c' W! O9 t
* k/ ~* F3 `! G* Q6 R7 [9 j; w8 X, i5 z' j* ?. v9 J3 a0 g& X) _, p- j
                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本. H* d  o# V4 A( [( ?% n* h) {
                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识# F/ ?, w6 S  P! l4 Q8 N
                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针( S2 r. C& l* c
                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小, D. C3 o) ?; C: e
                        mxcd.cChannels = 1;                 // 取得或设置全部通道
1 P4 x1 [4 s' a8 i! L) k
8 ~6 D9 x9 U9 c0 w. I' ?7 t6 [, v1 X1 S  g$ K+ ~! ]& n
                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum. 0 P: t$ j5 {1 _& A
! G3 [% N5 M, }( ~% \  {

2 U6 W( s0 }* |/ Y6 D! p                        // 获得音量值
  q6 J9 |8 A" l* g( j! q) S                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,2 K) E8 c2 S3 J. A' w+ M% x) _
                                &mxcd,
8 `( F( C6 s5 n2 d                                MIXER_GETCONTROLDETAILSF_VALUE);, R+ V0 W/ n  Z4 Z5 q. \

  @$ G7 j+ d0 O: {- {, F
9 x% k* q4 K! C1 v7 D/ w                        if (MMSYSERR_NOERROR == rc)2 ~7 q5 h- V* Y
                        {
0 h4 c: c* L4 \6 c. ?4 {1 ]                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;
1 r( D" f# i* T. _5 q# x7 ~2 i* j0 G! d* D

$ S! ~0 Y  ^# H                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;7 C3 f7 O& {0 b& V
                                printf("音量:%X", volStruct.lValue);
3 t: p( u' K$ D& r8 R                                return index;' M% P$ B1 D! D. z% S. f0 a( R) J
                        }
- F- g4 j3 i# _& A% l                }
; y- J. }! L& [& I% W% R        }, C5 }7 X; m9 |- w

! i/ R, `9 J! v* b; w
2 }, i# |6 ?' \: q. F+ R' [        return -1;( p$ Y  H: d4 _, O3 {
}& R1 V5 ]6 X" ^- P. \0 `5 x
/ B8 S# B  r5 R. ^7 m3 T
        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html
# t7 t, O' o/ M                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-9-30 12:36 , Processed in 0.035862 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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