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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/- a. j2 w" @1 z  Y

( S2 j% t$ }7 ]* Q: P) _参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
3 O1 ^2 {0 q1 t: E7 U2 l" s
" f1 B0 D0 j. n4 f# O- t# b4 @& e& i( W& T/ i5 \2 [
int DeviceManager::getAudioInputVolumn( const std::string &deviceName )
6 @/ `, E2 t# b. j, V* Q{4 D1 D( F! g  E  C

+ T- ~4 D  f$ j# L/ D9 b( `2 M# G5 n% T; q
        MMRESULT          rc;     // 多媒体函数返回结果变量. z$ [7 E1 {  n7 f- c* G9 f$ C
        HMIXER            hMixer; // 混合器设备句柄
0 d. L( H6 u) m) |0 ~2 B* [) N        MIXERLINE         mxl;    // 音频线路标准状态信息结构体% u0 W' H: u1 W; ?1 {6 c* f9 f
        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体
7 w* @$ m1 N+ `) Q0 i2 L% a! g        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
+ R5 M- Y" U! T& B$ i( z8 f7 ?# X2 J0 o5 f/ ]

+ K3 C/ }. E6 P) U        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即* r! Y2 B2 i- h( ], V6 R
        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
' k' j% p8 H* E. |4 ]       //可能还是跟声卡驱动有关。
( \3 B* q9 w: @5 Y6 a. G2 k6 E9 j        for( int deviceID =0 ; true ; deviceID++ ), e& w4 A: g& \
        {
0 ?; [; b* m6 N; l: N                // 打开混合器设备
2 o6 e: K# g6 V5 t4 v% j  ?                rc = mixerOpen(&hMixer, // 返回的设备句柄
) G3 E4 e- s# x7 e8 N! K  C                        deviceID,       // 单声卡的设备ID为零" `5 S' u& {5 p- c: `  i. l
                        0,       // 不使用回调机制
6 J; _! m" x8 E: T4 b( _                        0,       // 回调函数参数1 ]  E; G6 |& e4 }) F  d* T$ ~, R
                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID; h0 s7 Y* D) \& F2 r, i0 X- C) X
                if( MMSYSERR_NOERROR!=rc )
0 Y1 q( b  h1 y' x8 L$ N                {
% Y/ u7 a' f" J, t- j- l7 P; n; `                        //跳出循环; T& \0 [$ F' n' n% d4 ?7 Y
                        break;& r% {7 s* v& y' J
                }( p  y$ b" L/ I
                // 打开混合器设备无错的话,则5 @, R" H- |! e

: t5 y+ A/ Z6 R( C( C7 h  i& @, V- |: m( g& V
                // MIXERLINE 结构体变量清零
- D* C; `- j& P+ V                ZeroMemory(&mxl, sizeof(MIXERLINE));
1 B" s3 ?" Q4 a4 z- {# |) F2 B0 N; @) y  Y! b4 r( @. v4 V. z" H
* @! ]# ]# u; g5 N; t
                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本) C( }- P. b  \/ e( \; S' V5 T% ?
                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
: T# x* {. R# M# E0 ^( j                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
) ^) Y- O& t* c" e+ \7 w* y* L
  W9 w9 a7 Q" n1 r- j) c0 R$ a" s) [6 G" H0 h( o; B* f
                // 取得混合器设备的指定线路信息
% i; ]( h0 B5 S" _$ j- {$ t                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,
% O  I7 V2 N2 w3 ]+ b                        &mxl,
! @* o5 F5 b- J( A/ K2 t                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息
# G: Q' i; H# J  _- e+ |  Y                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
+ ?: N3 |8 i5 h  j                if( rc!=MMSYSERR_NOERROR ). u9 T/ O0 m- \; I
                {
% n6 j: x7 q) K4 M+ q9 _                        //无法获取声音输入线路,尝试其他声卡
2 N' Y6 R( n+ W) m3 s. w                        continue;& h: s$ L$ P! S5 b
                }
! c; A0 R# b2 c- i) N* @1 @# b( j+ `3 J
( J0 o' F5 {% W  {5 n' `
                // 取得混合器设备的指定线路信息成功的话,则2 k( x* D) X5 x
7 S7 Y2 r) }: N+ b, Y

! f0 U" k4 a+ K/ q                // 将连接数保存
8 L1 L) m, E( a5 N1 t- v                DWORD   dwConnections   =   mxl.cConnections;
. h. b; r6 t& n8 C4 P* V- D                // 准备获取麦克风设备的ID 3 q2 H" H; i0 ~  }+ Q5 Q1 h& \
                DWORD   dwLineID = -1; + W' t% N9 @# f
                for( DWORD i=0 ; i<dwConnections; i++ )+ R" v! L% [. k8 u5 B- t. p# G. B
                {
+ ^8 ?. f" {. O9 ]) v* V                        // 枚举每一个设备,当Source的ID等于当前的迭代记数 & a5 X  D" t! C# u
                        mxl.dwSource = i;: K+ X9 t- P1 M0 K* q  L4 o% e+ N
                        // 根据SourceID获得连接的信息
, e) G' ^0 V3 {5 ]* t                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl,
1 u4 p. H# c1 h. C                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); ( m3 P8 h; F. W. }8 D3 |
                        // 判断函数执行错误 & e7 [& y2 U5 K  Y% I
                        if( MMSYSERR_NOERROR==rc )
9 e5 l  _$ x: R                        { ) l! K1 C6 V# O+ d1 l
                                // 如果当前设备类型是麦克风,则跳出循环。 8 C+ ^' V, A( O- _/ b) T$ W1 i
                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
& N/ a& [! F  L  n3 Y1 i( y% V8 Q                                {
% B7 ?2 `5 j8 `# J/ J8 i- u) S' K6 @                                        dwLineID = mxl.dwLineID;
) x) C, v! [8 {* U4 \% p) ]                                        break; 8 e3 W) c( ]' P2 P, D: {
                                }
% S  v" s7 y7 Q3 d6 }  l                        }. E/ p* {* I+ S) a: [3 d7 T
                }+ Y" y- s; i, f
                // 如果没有找到,返回失败。 ) a/ V. x1 \- M. r9 ]) U
                if( dwLineID==-1 )6 K+ B5 X2 `0 ~
                {
+ p. v( B2 r8 H# c/ o2 ?                        //尝试其他声卡4 w) ]7 G7 j9 Y+ a
                        continue;
' y6 b; R$ o& j  R- ?0 P9 z                }
) _% H; g/ ^0 n! ]5 U
$ h2 F* e: V+ X  u3 M: U
3 X' _, J" t& v2 P: g! Q7 X1 J& g                // MIXERCONTROL 结构体变量清零  u$ {- v9 _& T6 G4 c8 D8 B
                ZeroMemory(&mxc, sizeof(MIXERCONTROL));; u! A+ T4 I) c2 E( w, ~5 G

, q+ s4 ~% B4 r: y$ i5 O1 \; |: k1 U# p
                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本
) x) s; [  D9 m) b+ c: H# x$ D
2 R. J7 Z# R$ N, C# [/ S. K% A$ |; X2 {8 J$ x' ]) M
                // MIXERLINECONTROLS 结构体变量清零
7 k) F/ P9 g8 Y( W. _+ [1 u) E                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
8 z' f( u' B9 C! F3 i* d, }8 u: N# g& {0 B

7 S- [# _" r7 K' f$ a' R9 d  w                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本0 y6 @" V. e" q
# U1 j& G! @  H7 ~& [: b: }
6 u" O* m6 \5 \- `
                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识+ l) E7 Q: c/ d
                // 控制类型为控制音量
; l; q* i, G6 O$ }' y) P" v' H% L                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
$ ]0 ~: Z: J8 N3 v                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数; t/ T9 T3 c" j( |
                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针) j1 y" J' a6 X8 s; G6 @* M
                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小
' d9 y! I: h% _/ W9 ]' v; T. c, }9 d6 |# S( ]$ d
* h) e. ~3 ?0 _
                // 取得控制器信息
$ T: a4 `0 u9 R5 i- W7 m                rc = mixerGetLineControls((HMIXEROBJ)hMixer,3 Y8 L- Z& t1 t% @* ]0 O5 {. u
                        &mxlc,7 v/ y9 b7 ^/ u1 k* I1 F. z
                        MIXER_GETLINECONTROLSF_ONEBYTYPE);! M. D% m0 Y0 c3 ^- p. J$ Y

5 z3 P. V% x/ e& \. ?; J/ m8 x4 P& r
                // 取得控制器信息成功的话,则
, o" k# y8 m& j( c; m0 W- B' a7 \* h                if (MMSYSERR_NOERROR == rc)& r: @. a/ t: s7 p; L
                {
0 c' l6 c; q- {$ n, E                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
) {# H* L3 \( m0 ?                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
) f7 K& e, s& [* a                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量): P3 D  B% d9 ~- L: V
4 G* q9 e7 P$ ]* t' |2 o* C8 Z4 Y
) h- B2 i& {" j! U  w+ J  I& P
                        // MIXERCONTROLDETAILS 结构体变量清零& M. }3 s8 R  P. [6 t
                        ZeroMemory(&mxcd, sizeof(mxcd));
. ?' y5 h4 G# @% y) i0 R- ]: Q3 W$ t
9 _7 X4 g6 G7 A# p% C/ v
0 C8 F+ I, }7 w1 I/ m. p                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本
% _5 \) o. t9 ^- f. P+ [                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识8 ?  r% Z0 g4 j0 h
                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针
  ~6 z# l! d) K                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
3 T& x6 M: a, C! U5 g                        mxcd.cChannels = 1;                 // 取得或设置全部通道' N& X4 y" T+ A8 f6 Q! {1 B4 {
, E. Z( ^# Z. h% Q3 m+ k; G

& o4 }3 G0 _; s3 S5 L  V% z                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum. . w5 d3 t' E" }) n2 T, b& P
- U3 ^% X( O; h7 S2 k# U* n
$ c9 c# D: S. T, ]8 T/ Y. V/ W
                        // 获得音量值
( R# }( ], @6 D( Y4 e                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,
* Y8 v: R0 b* B2 G* q  Y                                &mxcd,
% }/ L& p" H0 j5 T  @) a                                MIXER_GETCONTROLDETAILSF_VALUE);! Z) s* |9 L. B
( {. j; D7 C0 T( t/ M' y

0 r$ H: X- J5 ]                        if (MMSYSERR_NOERROR == rc)1 }' Z- {# W$ f6 n1 w5 F  q, y) M
                        {0 S1 I' i7 @" c) N
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;
' R9 t/ V( e" n1 X/ e% w% m/ @' H. @
& j; @* q- q4 _
                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;
+ C. s% [. p5 p, S! f0 @3 F2 s8 `2 I                                printf("音量:%X", volStruct.lValue);
* ]6 \- k& h( I% L2 M+ y9 e                                return index;6 W+ x% \+ s( A1 F& n( ?
                        }* Q2 u! a& e# n0 d! N4 B- n/ A
                }/ f$ s/ ~/ r9 |3 {  A$ H
        }
, N; A) L  I; \7 S7 i- v3 \/ ^% ]/ s5 Y, Z5 |) P" ^

; A- M) e1 {4 y( p* q" a        return -1;2 S* m' @8 z! i7 D5 o8 ~
}
$ ?5 i! A& q# o. {
& H4 K5 Q4 y4 r& w2 d6 P        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html* n. O3 z3 [) d( Y( t
                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-18 10:44 , Processed in 0.019166 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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