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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/: p$ V+ q( e# V; Q6 u

! m2 I0 P  A. O参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:" q0 |0 A9 X, y: J0 H
  @, g  j8 F) C* f
7 L) l& Y; ^) v# i6 @+ h9 O: }
int DeviceManager::getAudioInputVolumn( const std::string &deviceName )
& C2 y) ~( A$ [( e# h: }) |{
% T% j! H6 S) J! H/ \/ {. I0 c3 t( ?1 s- a# n

! l& f! e8 b5 a0 V8 R. s( W        MMRESULT          rc;     // 多媒体函数返回结果变量
& U- A& t$ L9 }' B6 A. x+ ^        HMIXER            hMixer; // 混合器设备句柄7 p9 \5 g9 R$ l& |3 `& O! F
        MIXERLINE         mxl;    // 音频线路标准状态信息结构体
& f- y; c; f8 }+ L1 b" P% U        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体
6 C0 i5 Z6 q: P6 i0 [  M; {# y        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
" F2 c+ q$ R9 T2 _6 ~! \$ d% ?& f: s* f2 `. L8 Z/ B" }3 n
! z. g, L- h* _; Y) @# m* U4 G% V
        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即
+ F+ v8 |$ l  R& ^        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
7 r0 r: S  q4 m$ U       //可能还是跟声卡驱动有关。
) G6 s; d. U6 @1 _        for( int deviceID =0 ; true ; deviceID++ )
9 x& L) {. |7 H  Z. \  V% [9 X: ?, E        {5 ^* S" R+ l9 f* `: u) v& J
                // 打开混合器设备# E. D3 t# L) A" r) s- r/ v
                rc = mixerOpen(&hMixer, // 返回的设备句柄9 T9 d6 _4 ~7 o5 O2 W2 x- {
                        deviceID,       // 单声卡的设备ID为零
2 I* p  I/ U, O/ q) g                        0,       // 不使用回调机制
0 a/ p3 e: U5 S                        0,       // 回调函数参数
. x4 a% q* A& o% M% ?  j2 h                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID: ^; x$ u  n7 w% P0 f4 Z
                if( MMSYSERR_NOERROR!=rc )
1 X; ?% Q1 R( Q$ ?# q                {" j- L/ {- {- [$ v
                        //跳出循环
8 f3 c0 S- ]* S& W) E" ~* c                        break;/ r0 X! u& P7 i: F0 Y' Q' f
                }
" }6 V# d& @3 ]; [' r                // 打开混合器设备无错的话,则6 ^3 q* s' y+ I3 p6 o2 [/ U

1 T0 i( e7 L, @3 N
6 {9 p8 w9 J+ _. s                // MIXERLINE 结构体变量清零4 |4 O+ J8 W* t( F
                ZeroMemory(&mxl, sizeof(MIXERLINE));
2 O. t6 y6 [( @( ]( r
& S. M& L  b$ b) ~/ i2 n
0 m/ w+ B0 i$ K                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本3 p; v) j; C' u! @7 S
                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS: h$ ]( Z6 w! ~% s* F
                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
" a& O* \# {( `; K' H6 e9 u' K1 v$ g% @( M$ ^( ]- ~: H/ K
' b8 X6 g- ]! r; t( l* q$ C! x+ A% y
                // 取得混合器设备的指定线路信息* V. M+ S1 o) t) @; g
                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,! t4 K, m/ d' K: E' x; a
                        &mxl,
# Z" C; ~5 p0 P8 }3 F! V7 V; ~                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息
  z5 v9 S' a" K0 N' O' M                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
" \6 t7 s, M* t7 V; e* i. M                if( rc!=MMSYSERR_NOERROR )
2 E3 C8 Q% i4 C7 N4 w                {
. C1 @- }2 h6 U) X! M* W                        //无法获取声音输入线路,尝试其他声卡3 z3 ~# D# e" A
                        continue;0 L$ U0 r) U8 O, v0 A  f. O
                }; g- v3 J3 @# f! N4 U6 H! S. N' V

+ i0 p* R  I; B' j& g$ h. P$ H3 I( ]& ~, V& S% w5 e# R2 [9 I
                // 取得混合器设备的指定线路信息成功的话,则
9 G& i0 U0 p/ _4 p# S( `/ |  N
" }% j9 `/ Q5 R) `5 F! Q
4 Q0 v3 \1 y" `2 Z* f" v# q                // 将连接数保存
6 j: K+ ~1 D) n6 N# R9 w7 M                DWORD   dwConnections   =   mxl.cConnections;
. V% Y/ t* w+ `                // 准备获取麦克风设备的ID & z; u7 q& q: W) O9 ~0 m- U
                DWORD   dwLineID = -1; $ Y. x+ A! z, U+ R
                for( DWORD i=0 ; i<dwConnections; i++ )" |7 r. ~; B$ \: M+ _
                {
" v. `8 q" z7 M6 J8 G" p5 B9 D                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
6 }8 G- h5 _( w) Z3 d                        mxl.dwSource = i;
% c) a+ \1 |6 x( |  r0 x2 |                        // 根据SourceID获得连接的信息 % U* S$ A2 s# ^% x! X
                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl,
7 U2 o! L: _( }1 f/ H6 g- B. [                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   );
1 K& f; N$ O: @2 N! W                        // 判断函数执行错误
. p5 S8 P  D" ?* K. `0 M. F                        if( MMSYSERR_NOERROR==rc )
5 Z3 S- n; S- R( Y                        { / k6 c. X0 M* K9 H# ^/ w
                                // 如果当前设备类型是麦克风,则跳出循环。
0 u) l7 e/ G" D$ P                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
  ^3 L* v& u7 i: \                                {
. f) t2 w. ~  V8 a, T% d                                        dwLineID = mxl.dwLineID; # H: y3 H, Z$ B( A: _) R  g5 M
                                        break;
1 c' {$ W2 U% ~6 `* p3 X& _                                }
0 h9 @" N9 f( U                        }% k3 }" v8 P' q& L" ]. ~" y
                }
" ?" H+ P6 J+ Z* E6 V5 r                // 如果没有找到,返回失败。
4 ]( j) u& a+ ?/ `3 s' n0 n                if( dwLineID==-1 )
0 m' Y3 x, V: K- s                { 2 G3 G, P. l; T7 X9 |; S
                        //尝试其他声卡4 o/ Q+ d/ j4 p- m9 e9 D: X1 N
                        continue;
4 j% \# |: C, a                }' d1 C2 I+ p$ b$ o5 Q, L

: v1 M: ~/ w; T8 b
: M/ u: e! G: Y9 z( t8 m                // MIXERCONTROL 结构体变量清零
* d# e: R! s6 P3 o( F                ZeroMemory(&mxc, sizeof(MIXERCONTROL));5 K9 e0 m. B$ m7 A# f& q
( v  e0 V- P2 l
" o! D: }, @1 K8 L; k, l( \
                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本
+ {( i& M8 J7 e" \7 i8 G- X: e- e1 a+ N

& F5 _0 U8 o' u) E                // MIXERLINECONTROLS 结构体变量清零
, f9 a( E& z; J3 N: Y( @                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));% n# p/ [* V: N9 d, q/ P" b

3 }' D& [* O" e/ ]/ X% A3 A& m0 S/ J( k- ?
                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本
8 `% p$ d3 }/ x9 d! V- l
/ S* H5 S7 q" _' l$ A/ g! a2 ^: z. }2 K" a; q+ m) n3 u
                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识
& o5 I4 e# j3 H( k                // 控制类型为控制音量
- U& h! |/ T" F; ]                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;$ Z- W- F; ~- r
                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数
% r0 `# v) f) n! v# G) B                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针$ y; a+ k6 _; z4 ^8 d6 T! d
                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小
+ s7 l- C4 N- \, k/ p
4 E- q$ Z: [$ L9 T6 B
' K- O; T7 H) N                // 取得控制器信息
2 Y' O, M: y, F( M5 \                rc = mixerGetLineControls((HMIXEROBJ)hMixer,
5 |: R1 S8 t( b8 p                        &mxlc,
# p$ F# n% \3 u                        MIXER_GETLINECONTROLSF_ONEBYTYPE);! F+ P3 D5 l+ r1 J8 j! ]
6 b: ?) T# u/ I

6 l' ^% C& P7 [0 t                // 取得控制器信息成功的话,则
& }& ?) ]- S# a3 m9 p$ R                if (MMSYSERR_NOERROR == rc)4 m5 A/ S& f* H* H% z
                {
1 i! x0 Y4 Q$ b+ d  k' ^# R: {' ^                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
" ]; W: ]9 \' v2 q! n                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
  @5 O9 f% X4 b) j9 D                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)
% b! e* |* N# Y8 @5 w- T
) u4 i& u) h& i! t
: i' A! i/ E2 n7 f! o2 u                        // MIXERCONTROLDETAILS 结构体变量清零
3 ~: h' ]+ e- R* V) f                        ZeroMemory(&mxcd, sizeof(mxcd));( w0 J( G0 q: t5 V0 \& d: p: u

: t1 F) |- y+ R$ `4 V0 W- `8 U# t0 C% n2 e7 l3 j& P; q, k
                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本$ v& K3 o* Y0 ^- P$ j( w9 `7 z; D1 g
                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识7 b+ r! ~* k+ b/ }3 h2 m
                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针
# M; y$ f% C- n) Y                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
6 r7 }8 [" X7 P* }; n( t                        mxcd.cChannels = 1;                 // 取得或设置全部通道' y- H! y" T: x3 X7 v( K
. S' i0 _. Y5 _" E* P& P

% m3 Z1 N: U! W# a3 A; W5 Y$ _3 @  I                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
, M. @3 f3 N  }7 ^, ~, B, H( l+ t7 K. U5 C8 @9 z- ?

4 c6 ~  A$ n9 l5 w0 p! Z                        // 获得音量值
2 W, t7 n  K; W* z* G                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,9 Q+ r3 Y( `! @' o: B+ D
                                &mxcd,( [5 C  `& B) B9 a( [
                                MIXER_GETCONTROLDETAILSF_VALUE);
" P8 l+ A: a7 l4 _/ E( i9 J( i* f  ~3 L  f

% S( I5 T/ y7 ^                        if (MMSYSERR_NOERROR == rc)
& A7 f5 G) R8 a: l) [. a' h  o                        {' L7 S3 x4 |% t' ~& c
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;
2 m, |: ]( [. }, t) Z( Z+ p  `! K$ \. S7 P6 H- g, w
9 L* X6 {7 Y6 p7 y6 v; x9 j+ [
                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;
7 |0 C/ u7 G7 x: i$ `2 h9 n                                printf("音量:%X", volStruct.lValue);
% c/ e6 p" ~8 d% G0 e6 J$ `( \                                return index;8 |* x1 m8 d) f7 r( v4 e; Z
                        }  k/ Y2 i: K: _1 E4 n! d( Y. q" U
                }" d& l# a, }4 M# Q) w* r$ {* C+ z4 l
        }3 q5 a% z5 ]4 ~  E+ Y( w
* S9 a8 R5 |  A4 d

$ Q* B# v; [7 m5 w        return -1;7 @0 k& S# ^/ {
}
: |: ?# O8 }0 D9 F5 v
- F2 ~  u; C9 B        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html8 A, q; Q/ i* o
                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 07:41 , Processed in 0.019724 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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