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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/: ~* L$ B2 t" r. h$ O- v+ |' I
; C! t2 j% O7 ^% ]% z$ Y/ u; I, V
参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:4 x1 O2 I2 P$ k

( ]& S4 ^8 v" X' u7 I
" H7 _3 }; u6 _: h4 r+ M. ^int DeviceManager::getAudioInputVolumn( const std::string &deviceName ), Y& i; [7 Z; Z/ S4 E
{" q2 g3 y+ ?6 G7 l9 _) S
1 }% H. C+ E: W0 ?9 F$ {
- g# L, B0 g( I: X2 }
        MMRESULT          rc;     // 多媒体函数返回结果变量
% h1 Q/ _2 r" {6 V2 [5 Z: n$ m1 j        HMIXER            hMixer; // 混合器设备句柄- E: }$ i+ i. \+ d4 b8 p) K0 y
        MIXERLINE         mxl;    // 音频线路标准状态信息结构体5 u( R9 S# i2 `! X, m2 Q3 ]
        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体
6 i) V! w( R, S/ ^' u% m3 S( ]        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
9 u/ i5 P: L1 Y, g* q" T& [  h3 p4 o" j& n  y) a3 ^, l

& j$ _9 V$ ~" p9 L! c        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即9 W5 F# d4 y9 ?- ]# b8 a3 u
        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
( r  z, ~! _/ M9 Q       //可能还是跟声卡驱动有关。" ^8 [5 W/ Y7 L1 i
        for( int deviceID =0 ; true ; deviceID++ )
: A; m5 q) m" K        {( ?- j* R7 T! I
                // 打开混合器设备
" }- h* ]0 U1 G8 B) J4 n7 y( |8 s                rc = mixerOpen(&hMixer, // 返回的设备句柄
9 l7 \0 \  Q0 n6 ]) R                        deviceID,       // 单声卡的设备ID为零" _. S9 i. G6 u7 N0 D
                        0,       // 不使用回调机制4 k; n+ ~# q+ _- ^: T  ^
                        0,       // 回调函数参数8 W3 h% y1 o% y4 V* I+ [
                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID& X/ ~$ C" @$ q: s
                if( MMSYSERR_NOERROR!=rc )
% }* y% J7 i+ c4 h8 R                {
& w) B8 p5 {& u7 A& ^7 S5 R, u1 \                        //跳出循环
0 ^- B& n8 ]- U" r6 m1 {: u" Q                        break;
5 R' K( A' }3 G. ~                }; H! X  S: U7 Z6 i
                // 打开混合器设备无错的话,则& J# ]; s% Y# O/ [. O
7 m8 e. n$ Q$ A: X) p: g* T
2 |3 B1 A+ G- a
                // MIXERLINE 结构体变量清零. p  Z, q/ _- B% r- h" q4 z
                ZeroMemory(&mxl, sizeof(MIXERLINE));: a; I- O% ^2 L
5 {+ r- m) T% A" q, U( e

/ I7 ]1 R# s# s2 F% v1 y) _6 V9 b                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本( j: [3 V4 Z; p& Q. |; h
                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS5 N; K& r9 O6 _) a, g
                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
' B" N, E) w/ l
- L+ \+ u$ {; |# [% G) ?& ]0 O* d1 J" }' q% m& p
                // 取得混合器设备的指定线路信息8 c: q1 I% S( K8 x; d; n5 r0 ~% t% V% S
                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,7 ]' p9 t# a7 _  ]/ @+ u2 D
                        &mxl,! T3 y* v; w9 P" F" r) [. S& g
                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息; f' c7 r/ }+ U& U
                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);5 J: o3 Y! {. k5 {6 G6 i4 H
                if( rc!=MMSYSERR_NOERROR )
& M, e1 g8 J! v, f( t# ^- s                {+ C- h+ a: ~$ ~% a
                        //无法获取声音输入线路,尝试其他声卡  `$ a- V+ ]3 j( |4 v) l) A
                        continue;; J; L4 n0 `7 F1 h0 f( K
                }
5 t. z/ W  @% n* b3 O" t7 Z4 z$ p4 M9 ]% h) v2 g1 }% N

3 ?, x* L: x( ]' I                // 取得混合器设备的指定线路信息成功的话,则- c* b4 ]  ~/ H. g

$ Y4 a, @. [" V, B
% U1 V( j7 L- q                // 将连接数保存 6 v; L, B, e  A) Z* w
                DWORD   dwConnections   =   mxl.cConnections; + B6 G' H5 ~" m0 D0 q! }  _
                // 准备获取麦克风设备的ID
/ T- ]4 l9 q! n0 c7 p2 a                DWORD   dwLineID = -1;
' i' w  N. k7 ?                for( DWORD i=0 ; i<dwConnections; i++ )
# r9 A: o0 A" f) L! f                {
, y+ w8 N; ]- }+ w                        // 枚举每一个设备,当Source的ID等于当前的迭代记数 # r1 f4 ]! a* {$ V/ u% H- ]
                        mxl.dwSource = i;
8 C( F% s" }' J                        // 根据SourceID获得连接的信息
- c6 F; s$ G- P8 p% y5 T                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl, 3 m% b5 J+ g% L% C
                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   );
1 e1 M- I2 q. R$ d* P6 `                        // 判断函数执行错误
% Q4 S$ l$ M2 b" a- T: V                        if( MMSYSERR_NOERROR==rc )
3 i: S0 u: l$ X; H) n1 Q                        { 2 ?; q; S/ [/ _- C: L9 U/ A0 J2 E
                                // 如果当前设备类型是麦克风,则跳出循环。
4 M. S" T4 @& B) e) f" U2 U                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE ): t  {* Q) f2 P: }3 g5 c
                                { ; p/ ~1 H4 I9 B# a+ c
                                        dwLineID = mxl.dwLineID; ; [3 }+ G( o+ S# j$ S: H$ A1 l1 U
                                        break; ; @7 P6 L, m: ?0 z
                                }) k1 C( M1 G, u8 f' I
                        }
8 W+ s4 \! M, T                }
/ P! j! E4 u$ u% N* f                // 如果没有找到,返回失败。 . w( j8 A+ D0 t% s& {% G" T
                if( dwLineID==-1 )$ {# g; [0 X$ {6 h
                {
  h( `$ a4 H; I, @                        //尝试其他声卡( n1 i* u& m/ T3 c2 a
                        continue;
0 h, i. E9 M. O$ R, g                }0 D) ~6 V  C# h/ `! e
0 B+ N7 _5 h. f. t5 O
0 i4 p% o& v; I( U; h. Z% J
                // MIXERCONTROL 结构体变量清零- H! }2 R# `& [! B* U+ ^
                ZeroMemory(&mxc, sizeof(MIXERCONTROL));
3 f/ t* h- G3 }9 c1 N' ?6 y/ a* i, K0 R/ |4 T% a, x

4 ~* w/ u* _% p- |  P1 r                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本8 O2 f! v" _8 o7 C

# k' Q6 T. f. a! d& U; ?) Q% Z9 W, S' ]: j) }& U
                // MIXERLINECONTROLS 结构体变量清零
. |% T$ U9 D0 f/ s9 S: R                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));9 u+ {: u5 ~  v( z' z4 M9 o0 s2 d) A4 I
1 V' }3 s9 a# u4 H+ \3 }

  j3 l9 h- e+ n, w% U" D                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本+ R5 _' A$ B  W
/ H. [4 C: `6 k) q9 G# a
5 q  T  z( i. ^( B7 w- J
                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识+ a8 `' }$ _5 M0 }9 c% @
                // 控制类型为控制音量
/ X) H" d0 h/ E# J' E0 I7 L                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
: u9 H( W; _. [8 ]: q                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数
; z# n! a6 V. z: K                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针2 O: P- Q4 Z( l6 M
                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小
% s. I" x$ {! F6 ~9 N  h
* J4 q6 l% s1 K( _# p
" n! @( m5 k5 ]9 t5 |2 ~, B( o- L                // 取得控制器信息
/ I: F1 C- H6 x- Z9 s                rc = mixerGetLineControls((HMIXEROBJ)hMixer,+ C5 q( Y5 B9 ^" T
                        &mxlc,
6 q" e8 E' H6 [8 G+ C( D5 h                        MIXER_GETLINECONTROLSF_ONEBYTYPE);
3 C  L' c! w, ~/ S! u- \1 z
  y5 R  A& v1 S1 M7 c$ [  q/ A$ w
3 J/ i$ q# o/ q. ?! X) I                // 取得控制器信息成功的话,则" f( O* [- K9 t! m
                if (MMSYSERR_NOERROR == rc)# r; S; G' [! W( T; v- H5 G
                {4 o1 i8 H+ J9 h
                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum./ ^  I- a" ^8 \( s' n: D9 k; [
                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息- i- v5 r) a2 |4 }" |1 l% q
                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)
& P, P" ]. @4 X7 d0 `
( C* @  p: l8 Z3 ~* w! w( y: V/ n: [  ^) l% j4 E0 q
                        // MIXERCONTROLDETAILS 结构体变量清零
6 l) F( _! I) [( L( E6 H, s                        ZeroMemory(&mxcd, sizeof(mxcd));7 u2 d7 m+ @* o! C' Y  C
2 U4 ?; O% I6 A1 C  s# R7 X$ ]7 E

7 ]& |5 _5 g& Q3 r+ J. |0 G                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本9 H- Y6 e3 L( [$ x: I( s
                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识7 A' _2 b$ R2 x& n* n% v# M1 N
                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针; I, i  o% D1 x9 c
                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
' C: R! ]/ t& y                        mxcd.cChannels = 1;                 // 取得或设置全部通道
4 t6 P# M  }  e: [& v" J" U6 ?; ?, i) }- R
) [" S/ n8 z, w0 p+ ]
                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum. + C6 H! }5 ~* p: u* ~

# }, F$ \( i& g+ l' b5 U7 S
/ d: N0 I, A+ w  j& b                        // 获得音量值$ m2 S2 z& j( d/ k  `% w% M$ p1 z( q
                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,' O( _1 i5 ?0 Z# t
                                &mxcd,
( ?! b# s; X- P, @                                MIXER_GETCONTROLDETAILSF_VALUE);
. J8 E3 g, ~6 k# o% G) [$ b
  G2 r6 K. x! j8 Y, l
+ V+ _3 e; T* @9 j0 j$ y                        if (MMSYSERR_NOERROR == rc)
, o! d& x5 {  R2 T                        {3 q( A* I2 q) n1 a/ i
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;+ x/ _+ u6 f' D& i& ?0 f( N0 N

5 _7 q2 J1 i4 R" @- |+ B# o  C, [8 ]/ |9 M& D8 K5 v+ p
                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;8 D# q+ r1 J. r' g
                                printf("音量:%X", volStruct.lValue);
: U. ^, Q0 M# W, g2 Y5 H1 J, O                                return index;, ~- @2 n, k; \  n- k/ J& q# h
                        }
0 `  c1 H, f% v' c" e  q- y                }8 _: s" W3 y6 K- v% ^
        }
) T$ i! @# i5 S$ v9 K; a/ j4 X
4 F' `  z$ ]( y5 a  `$ U. W
% e# H+ K$ ^$ z" R4 k        return -1;" W. S, ^% G; u2 C6 T7 ?
}# P5 ?7 ~$ O* @# d) ^

# A0 I/ I" ^0 K% k- c1 d        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html
+ [9 A' E  g5 M8 m                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-8-8 20:20 , Processed in 0.034703 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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