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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/
4 ^7 }% z2 l2 {5 F
! G- N( b( B9 L6 K, r5 J参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
2 v% A. [, z  _8 n/ v% J
, N3 ?8 {/ q* \- j
, G& z$ @" `3 x$ Fint DeviceManager::getAudioInputVolumn( const std::string &deviceName )
; ~! k% l! R/ l# `5 M{! \; I1 @; T5 a2 d

( P: z0 t4 ]4 k. Y' t- w( M# w/ X" |8 p. G6 J
        MMRESULT          rc;     // 多媒体函数返回结果变量! i* k- t% l+ ~4 P7 H9 o; f9 J
        HMIXER            hMixer; // 混合器设备句柄
; }+ s. ~5 j8 T. W! o- W/ M7 i        MIXERLINE         mxl;    // 音频线路标准状态信息结构体" F" _. ^9 ?( U% @& Z- u9 v4 {
        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体5 {5 o$ U, M4 K/ M( h% e$ X$ A
        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
4 B8 M2 \' ?8 h6 j6 b$ a. M8 ~8 N7 a: q3 Y0 s
/ O& h) a& |* n6 t; ^4 R1 U2 K
        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即
; D* ]; ^. c) K5 d8 y9 F& J        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,! X5 Y$ ?- F' E
       //可能还是跟声卡驱动有关。
$ l- k. K/ b7 |$ f# U& \' J7 m        for( int deviceID =0 ; true ; deviceID++ )- n$ A) P- L5 I9 S5 f3 Y
        {+ `: X& ~0 ^- a8 H  s- w
                // 打开混合器设备  R, _4 a4 A* p
                rc = mixerOpen(&hMixer, // 返回的设备句柄
4 |7 e/ w# ?5 X, ^5 q                        deviceID,       // 单声卡的设备ID为零# X  g! d0 T' v, E) w
                        0,       // 不使用回调机制
0 H( H# e) {* N. g                        0,       // 回调函数参数! z. l) T) Z( }5 W
                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID$ w- d* _0 o* v2 k* }* C6 b
                if( MMSYSERR_NOERROR!=rc )( r& `, W( l# F6 w
                {
. n* M  F% S/ N9 z8 N7 A                        //跳出循环4 A3 K+ T% j2 ], }) B, E- t9 @1 z
                        break;
. o  k( r# a( e4 |3 Y- y8 _                }% t& [" t/ _1 Z
                // 打开混合器设备无错的话,则
1 B! u) c2 o% W- h8 I/ C: w1 @2 ^  S2 z& G, I
7 p% F9 T  x/ M* d6 ]# `
                // MIXERLINE 结构体变量清零
; C3 r8 ?! W. r8 ~2 z) Y                ZeroMemory(&mxl, sizeof(MIXERLINE));9 x& s; W; B& w

& y4 ?- F0 Q. Z  G! E2 I4 V% _3 Q4 d4 |! B* \: [
                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本3 ]' {# i& v1 t) m) I
                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS. w" C8 S- U8 K/ E! _. s
                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
/ d0 T& h% r/ V% c+ V( M  D
0 G0 W  M7 \. U. M( k$ A1 g" x7 S, C4 I
                // 取得混合器设备的指定线路信息
0 z" I- O% Z3 E) I* V                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,
) m/ E6 }4 d. |  F! ?" J* w5 t                        &mxl,+ b* b  {( e3 p: c
                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息$ p$ A, E+ e! U+ k5 a( v7 o) R
                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
, T. |3 }7 ]" C                if( rc!=MMSYSERR_NOERROR )" ]/ Z$ V  A/ F- u9 m3 }
                {
  T+ D7 y0 l* r6 v( {: ?6 ^                        //无法获取声音输入线路,尝试其他声卡
3 }8 X+ c9 y. C8 Y* e% i3 p# R                        continue;
( d5 K% B# z6 W  L2 X                }
/ X( h6 c$ m0 U6 [
+ D! l* D% \1 H
6 Q$ Q/ O: f/ A; O2 J                // 取得混合器设备的指定线路信息成功的话,则4 f. z. p8 a: E# ?: d  r3 T
* r) Z7 u# t1 o/ C

* j- z" R0 T7 _/ y+ @% z4 b# z                // 将连接数保存 . n! q* P/ Y2 F
                DWORD   dwConnections   =   mxl.cConnections;
! Q+ B- v6 x1 y                // 准备获取麦克风设备的ID & R) ?: r* @1 O4 h) Q) D( Q
                DWORD   dwLineID = -1; - Z: p" a: n  i; k. R: u9 ~
                for( DWORD i=0 ; i<dwConnections; i++ )4 p% u2 r! X* P5 E0 }. B
                {
, _* w0 }/ M7 G# U3 |( E4 j                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
$ o& i* Y) n- k3 Y7 E6 {                        mxl.dwSource = i;% a3 L1 @" T4 Y7 K
                        // 根据SourceID获得连接的信息
  @) k. j0 e. @0 Z. N3 w                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl,
0 T% r3 \0 R( Q* n9 l: Z; d4 [+ ?                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   );
" k  c  E+ B( K4 M$ |& `                        // 判断函数执行错误 - D0 _" M: a7 }3 E' D0 z
                        if( MMSYSERR_NOERROR==rc )
! O" L' `7 N) O% S, ?( \/ |5 q                        { ) @0 i1 n% F: ~2 P: @7 }
                                // 如果当前设备类型是麦克风,则跳出循环。   l/ Y4 q  M! ]
                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
+ e" U" H' B3 W, I8 V                                {
" h5 o6 x1 F$ C' D                                        dwLineID = mxl.dwLineID;
6 p0 O# t; v" P, F; r, X; Z  H                                        break; / d% C# L; A5 f% f% S
                                }7 \! o4 l- y* ?- ]9 U/ m+ K( o
                        }! M: U, b- F( ^/ |& P3 ~% @$ A* L
                }
4 b9 o) {* t9 }0 X4 ]                // 如果没有找到,返回失败。 - Y! G0 s7 C5 m( [
                if( dwLineID==-1 )
$ ], K% C  v3 d7 q: l/ H. T9 s                { ' I+ C7 b: i) ]; t, W' R% k
                        //尝试其他声卡/ F9 d( L. b) U8 V7 U3 p: N: F: I8 R
                        continue;
+ v% ?# i4 q6 s. t  ^- _                }
; M. @% E$ S5 V, z# r0 A, X/ p
  H( D0 N/ a. w2 t. h) l) v# N# z$ {. C  n2 D
                // MIXERCONTROL 结构体变量清零
) _$ c# T5 s7 f                ZeroMemory(&mxc, sizeof(MIXERCONTROL));( ]# v" R5 X7 l$ Z; w

8 o8 }; ]3 @3 v  m
9 g# k- S9 ?' ?                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本
8 Y2 h1 s1 }1 f& N# t
, ]* s1 ?- [* J, z
$ \0 y5 {5 i9 x- f                // MIXERLINECONTROLS 结构体变量清零
# w, p& Z2 n# J0 `% J                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
9 b  u" p8 e% C
4 q; L9 ]" j6 Y& n6 c, w1 k# D( P; G8 K" n  ?# [
                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本8 G9 |- b* V& X4 P( w  T8 i3 ^' U3 V
5 O1 V5 u2 O, T2 I# D

( F# S" o2 @1 t/ _% U                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识6 ]  V0 g- L% }0 M  v, {5 q
                // 控制类型为控制音量! o+ y, h, V- O& b# h3 P
                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
6 j: }0 E& m: m4 ?                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数
: F/ _) O+ V9 w5 O) O, s                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针
9 b" C' Z8 T2 x  U                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小$ T% i; ^( m$ c+ ~2 p: [4 l7 n

3 g/ }1 D: v8 d5 C4 e6 t1 G
9 c3 a7 h% p+ S- x+ e                // 取得控制器信息
! }' ?& \% Y) d$ o0 D9 @0 [                rc = mixerGetLineControls((HMIXEROBJ)hMixer,
+ m9 a/ F% t* J  J' \                        &mxlc,3 {+ c' f& I- w4 t7 N
                        MIXER_GETLINECONTROLSF_ONEBYTYPE);/ b% O( H0 r& y/ ]' E
% s7 w' I/ W& n

  E1 z' R  `! e& C5 v3 Y                // 取得控制器信息成功的话,则
. C+ S( s6 F5 C1 ^5 T6 P  o! u5 A                if (MMSYSERR_NOERROR == rc)$ ], a1 {2 b' p
                {: Y- e& N! x/ A/ Q+ [" G" z, B
                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.6 B" G4 u3 C( O) n) C1 N& b4 c
                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息5 {( r; j5 _5 D# n; S
                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)
2 D0 J& K- ]& t0 A
( q$ e* k) J  G9 a: Z$ L/ o. n+ ]9 J+ I
                        // MIXERCONTROLDETAILS 结构体变量清零6 I% Q' K6 ~% ~1 J9 T3 A. n
                        ZeroMemory(&mxcd, sizeof(mxcd));
9 ?& D/ ~+ \3 i/ R' ?+ Q) B" D1 W# {; x" l
9 B7 q+ W5 W8 `$ h2 r6 K) T% ?/ S9 D
                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本
, M" u/ x! {( M2 q                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识
5 N# b9 G4 w- D- h/ B# }  T1 ?                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针& H/ N- d5 C/ p' K' V
                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小& j* V6 c1 ?$ w! f. y
                        mxcd.cChannels = 1;                 // 取得或设置全部通道* s9 d, }1 @6 I& t; r

5 o2 Q  F3 C/ \  w6 @% \5 G- v" p3 m: ~
                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
. F. c! K/ e: N4 w+ Z) ?5 F0 E9 h9 M  \

' `0 e' k* M  j5 v+ Y' a/ |                        // 获得音量值
; F% v: q; m6 c( G                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,3 u4 f! ~# A- V2 {1 Y/ t
                                &mxcd,
2 ^9 B  N( s# w: l/ y, M                                MIXER_GETCONTROLDETAILSF_VALUE);) I* H( d" Y" [- Y8 t" U4 J

) Y  V' J  E8 S. f9 b! V; s, }; m. `* Y0 x; g( [- I$ B
                        if (MMSYSERR_NOERROR == rc)
; k& w6 Z! z( Z- T9 i                        {, b; D2 ]' X, i# {1 Z5 N8 l
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;: z7 ~6 O" ^& `; _/ v2 F# k0 }+ u
6 L# a7 a1 f; M& j( L4 A  I7 ~
8 R/ E: o+ v7 T5 ]+ S
                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;8 k* ~2 I" o/ Z3 n  c
                                printf("音量:%X", volStruct.lValue);
, \8 b6 g- F# @) h- r                                return index;$ M9 W  [. ~7 y8 ?0 s6 B
                        }
, E% k; H' ~5 }: P, ~' u% P* Z$ |) s                }; j; t; P/ R' z( v3 L
        }: p+ O+ [3 l% [2 F: `- N/ X8 Q
0 p/ s4 y$ ^% b/ M% g' d+ H
+ L, s1 d! |7 v: i2 Z
        return -1;
- r3 }9 }# ~+ \$ ]/ @; c+ m5 x}
7 Q& o$ v; Y2 t2 b* b9 e  O. y* H0 l+ k# J. ?, q- v
        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html
3 v2 M& E" o7 g/ I                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-8-9 06:27 , Processed in 0.036150 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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