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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/& i6 d& j3 s, b% z/ U! y
, d: \, p. [3 }
参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:. e8 s# w9 `* k. w8 y# d  |
' ]* W3 F6 I4 }0 N4 t: y

3 ~/ [' j* n- k; aint DeviceManager::getAudioInputVolumn( const std::string &deviceName )
) z2 M+ a6 m8 ~- p) p  [. g{. u4 }( Q2 v1 N" z
% i/ J) x% o! r) l$ w& ^  J$ S/ J
" ^2 I1 n( U( Z3 Q7 R
        MMRESULT          rc;     // 多媒体函数返回结果变量0 F% p6 L& D& x% V- P8 ^
        HMIXER            hMixer; // 混合器设备句柄
; L1 O5 W) l$ y' @3 h. x8 S        MIXERLINE         mxl;    // 音频线路标准状态信息结构体* V3 G1 @- w! e9 Z; ^/ V
        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体
, i4 q. ~0 X/ `- X* e# o+ n        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
7 N$ R6 X" I3 E# c! r% h0 A: H/ [' Y$ O$ h; ?% `" s

3 _* ~2 m9 c: y. U2 O( g        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即
4 ]" s) I  |$ F3 @! [) i7 P) `, d        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,# {7 [$ B+ s( m! j- j0 C+ {
       //可能还是跟声卡驱动有关。
/ G2 O; y, ~9 j3 ^( j5 G6 m% I        for( int deviceID =0 ; true ; deviceID++ )7 Z2 [1 y4 n/ c8 Q0 u& s& a
        {- v! f& O* S* N0 N: `6 k  ]+ C; ?
                // 打开混合器设备
( f/ r8 U: P6 k7 y                rc = mixerOpen(&hMixer, // 返回的设备句柄- @5 j6 z. O, o( ^. m7 i
                        deviceID,       // 单声卡的设备ID为零  @6 x7 C5 r' u7 ~6 V" w# z
                        0,       // 不使用回调机制2 E7 f: v2 o6 o- o* }
                        0,       // 回调函数参数$ [! v# E2 v% g. A
                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID- p, A- R" s3 `/ B
                if( MMSYSERR_NOERROR!=rc )
3 P" [9 S7 Y+ |8 P                {& S9 x* T1 H7 w: D) R6 l6 q
                        //跳出循环
& v! y% H/ o( q' I: U                        break;
' V6 M1 g# E, U                }
9 U( Z0 D* c  O2 D0 o& C2 ]                // 打开混合器设备无错的话,则
! A" E& c  F8 r# ?, v( U. _* Q' p0 H3 Y& c) U# v
& j* C2 B$ j5 n0 Y4 q2 |1 E
                // MIXERLINE 结构体变量清零# P6 l6 }( L$ w4 x* S
                ZeroMemory(&mxl, sizeof(MIXERLINE));7 `- \- q- c" s5 L: A
$ d2 e- I6 c: i; v

) M) Q2 V2 ^( {9 Q& T1 y" ]- f8 V                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本
1 l5 c) I& W) Z$ k& [                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS4 R! U8 p- C0 g7 j" w
                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;! |) j0 ~/ b+ T4 s& J+ m
' {2 u2 X" G* t. R+ }

& v/ I- i# L( ~8 ~; |. K                // 取得混合器设备的指定线路信息3 M" [4 }# [  T
                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,7 T) V* [: V; d* Z
                        &mxl,
4 j, t& g/ L- ]/ |( J                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息0 |8 g  g4 X6 a4 `
                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
. [0 A4 ]& S: y5 c/ e/ m                if( rc!=MMSYSERR_NOERROR )( R- ~& y# ]; g2 x6 v* L: {# Y* l
                {
) o! w! e* ^; X; ]                        //无法获取声音输入线路,尝试其他声卡
7 M  B/ g( Q5 ?" _                        continue;
& d3 l7 h* n9 r5 X6 E; Z; e                }
0 h9 u) {# h$ ~3 N5 m3 {; h
9 P, I5 g: l0 F5 q; \& {6 T+ b% N
                // 取得混合器设备的指定线路信息成功的话,则
' W3 E' @& Z4 s0 ]
& W2 w+ A+ j7 ]# r" y! w) T2 f$ S7 w, g8 V' q% p8 P3 _
                // 将连接数保存 4 N) `- }' [0 H0 L; u
                DWORD   dwConnections   =   mxl.cConnections; 3 e  M/ ~2 F6 c
                // 准备获取麦克风设备的ID 3 G: R' y* U* l9 E- Y6 |
                DWORD   dwLineID = -1;
7 W; Z. s2 u5 ?                for( DWORD i=0 ; i<dwConnections; i++ )3 d* J2 }1 T! x$ M/ F5 E& P
                { & r7 v+ X% [4 Z" v5 v
                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
9 x; V! D0 f3 I* q/ w                        mxl.dwSource = i;
9 q9 @( S8 m1 B) Z2 ~- U                        // 根据SourceID获得连接的信息
( H+ m, C7 H  i  w, |2 V                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl, 4 F4 U. h) r' e" }
                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   );
( u% Q2 m7 s, ?; D! T# s0 O                        // 判断函数执行错误
3 \7 U1 _2 l& _                        if( MMSYSERR_NOERROR==rc )4 }, z; }" M. X( Z
                        {
% h5 y4 h% D. A+ Y$ |: o                                // 如果当前设备类型是麦克风,则跳出循环。
9 L. H& D( ~, C/ a# m                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
# @- _* X* v  z! h- Q* o                                {
8 r1 {9 p; t; h! |' G                                        dwLineID = mxl.dwLineID;
9 a: m: U8 s- @2 ~7 H5 c+ f3 a                                        break;
4 b0 n8 O. g! _" @( p  n                                }
+ J; q. G  m( S7 `; g/ p& F0 y" o                        }
* K1 A) X* o' _) W, a" ~: l                }
1 q- L8 p$ @; z/ }# P6 T& }                // 如果没有找到,返回失败。
* [9 t* C7 Z+ V* _                if( dwLineID==-1 )
* ^- {6 x; |0 I2 K, B. R+ u# E4 h                { - V$ N9 q1 s, i) |) |
                        //尝试其他声卡
2 l3 Z4 _' C4 _) h                        continue;: ]2 c' I  u6 h; i
                }9 j8 r4 D" }$ u+ W% s
- V& y, s9 @1 ~- f1 s

+ L( i7 V6 O' {' V. d                // MIXERCONTROL 结构体变量清零; k& i  x: q# `5 }
                ZeroMemory(&mxc, sizeof(MIXERCONTROL));
# v! q( y* R4 }  E  i. U( X2 B; B
, i: g9 Y6 M7 C
( p1 ^& A1 q6 [8 T                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本
. }' [; C* ?/ D+ M% `; ]9 v% d; I( j% ?3 \( y

  \5 t7 o! Z5 z/ L2 U8 |/ |$ Z4 J                // MIXERLINECONTROLS 结构体变量清零8 C* T1 t2 V# s" U2 F
                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));* B, U3 k5 m; {5 I0 n0 o* o  ~6 }

+ x2 G: a6 V3 P/ ^* L- c. m' j3 H( k8 A# q2 x$ p) q& N' M
                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本
/ X+ E4 }& x% \9 Y4 h4 c/ r
9 o( m" |, U$ U. `9 f: J6 z" E% Z5 S' q5 J9 Q
                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识! |4 v- I$ i, k  M8 a, {
                // 控制类型为控制音量
. A0 g8 [2 e; H& ^                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;' s, {9 C' N4 N) I2 \# _
                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数: H2 ~5 h4 Q" P  ?
                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针7 Q4 |2 M( E* E
                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小
- q- Z# l5 ]* T0 R$ @6 v
3 [4 f: o; H, s- T8 U# D; p; w" m, W; j0 e0 e2 |
                // 取得控制器信息) x0 G* E* f' B, Q
                rc = mixerGetLineControls((HMIXEROBJ)hMixer,
) J' D- }) g4 f0 z. I+ z                        &mxlc,
2 f) O2 ]0 i1 r8 ?  Z; k                        MIXER_GETLINECONTROLSF_ONEBYTYPE);
/ O) W- P1 x3 ^6 l! x; ^* [2 P6 D( w' c. Y2 S* ~

8 N. y/ Z: x% ?! f                // 取得控制器信息成功的话,则. @0 f7 u9 m& w7 j6 p5 v- E% G4 R
                if (MMSYSERR_NOERROR == rc)& _: D) Y6 X) i- L# z
                {
' h- I+ i( v3 D5 S2 z5 i                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
: I% U8 N+ Z4 j" a                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
& t4 s+ z: U! H4 _                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)9 d' Z: b; j3 f4 I
2 P% V$ K; s5 }$ Y* \  C
" ^4 N; G! H: m- O8 a* u
                        // MIXERCONTROLDETAILS 结构体变量清零
9 `& {- C  X: Z& x                        ZeroMemory(&mxcd, sizeof(mxcd));
* n, a& P3 k9 e8 u" s4 ^: [0 s
- g% m8 F5 F* w2 z/ h9 _# I
0 Z& n1 K; J3 V$ I6 M: W$ q6 B                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本
$ i0 X% N2 l/ T2 S6 ~! P6 [+ p                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识2 O9 c, O+ `! F% ~1 j
                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针
& C  _0 y0 a  k; I5 q- v& }( _                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
' O& _5 J, k6 d9 w                        mxcd.cChannels = 1;                 // 取得或设置全部通道
6 V: V9 H: V, @2 F8 c, m. R( L; D3 h8 B( |# D/ s6 V  F9 E6 R
0 w' i5 T. Z6 _8 n$ ^  ~$ k9 ^3 P
                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum. ! N5 Y; H0 E! _# S

; h  ?3 B) T' Z3 ~
, i5 R; A6 l  O1 r) F                        // 获得音量值, P; r8 U' i* F
                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,5 m# X* J' {5 M3 V% d
                                &mxcd,! D2 s# F) g" p( |; x9 p6 e7 A# x" O
                                MIXER_GETCONTROLDETAILSF_VALUE);
* I  U$ ^7 |. {" A' Q0 H/ b0 b( _' Z' f+ g. E: B' E3 f

1 y8 a7 F9 E- l: ~; v                        if (MMSYSERR_NOERROR == rc)( u- L$ ^( V$ S. I- {( D
                        {( `2 y; k# p+ o6 o8 M  J$ O
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;
/ q$ l0 g" x( a; q) C, O7 u3 W) Y
* u% B3 `) M3 G
                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;6 F, P0 B  H6 ?6 ?9 D8 U
                                printf("音量:%X", volStruct.lValue);5 p; z; j& s- f# T& J
                                return index;! ]/ s4 k8 B; T$ Q8 R
                        }
/ K3 r& J$ M. }' ?- F                }  c: n$ Y; b/ ^+ ~4 m; p0 ]
        }& ]* H/ P- Y' o9 [  `/ A

; \- g1 G$ H0 Y2 r4 _- Q: o2 b
        return -1;
9 `, }# T. ?) k, V' d/ C/ f& e4 U}
: f- c; |7 R2 Z2 E* \+ Z; B) @
5 ^- F$ N) N, t$ [6 }6 y5 u1 u  `        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html& I! d! e8 _+ b
                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-6-19 11:10 , Processed in 0.015447 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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