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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/
! x! u; N. ~% Q7 G3 Q" Z( s
. q2 [9 _- |+ Y1 ~参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:# n. W% o  M2 X/ C! F; X

4 f: p+ P' p7 |( N$ p
5 z( W/ g* h5 D, {int DeviceManager::getAudioInputVolumn( const std::string &deviceName )
% M: Z1 J: W0 K- A" k# v; G8 }{# ~) a" S4 L( Y) p0 h, {0 p
8 O! i9 c% g8 o8 ^
1 r% M6 M! ?! a5 D2 R$ p# h
        MMRESULT          rc;     // 多媒体函数返回结果变量7 f9 q" T2 D; ~* M3 H  a3 W( v# e
        HMIXER            hMixer; // 混合器设备句柄( w- h' ^0 U. q$ }/ s0 ^' R
        MIXERLINE         mxl;    // 音频线路标准状态信息结构体
- J2 v7 J6 p% g        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体
  `1 }: x4 N( {- H# K# K7 W4 D        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
# }7 i9 q: Z9 h( D: B! {
+ e9 r2 A6 k2 H% U* d1 V
4 K/ {; F: J! [5 k+ @$ T1 n) {        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即1 Y8 J" I1 j& J2 d! @
        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
/ \* }$ d( |6 U' P0 B- n1 b3 h       //可能还是跟声卡驱动有关。# x# l& a8 l5 f, p  M4 T
        for( int deviceID =0 ; true ; deviceID++ )0 D9 I. S) A- I  C+ s( P
        {! b4 [! e0 s: Y6 `5 P9 z' s! t
                // 打开混合器设备; O7 F, R: B1 W6 z8 t# x2 a
                rc = mixerOpen(&hMixer, // 返回的设备句柄
8 K% ?6 E/ \9 u2 Q6 G8 \                        deviceID,       // 单声卡的设备ID为零
2 ^5 z7 Q4 ~6 y6 }7 A% N, E                        0,       // 不使用回调机制
$ }1 f/ }2 h7 u                        0,       // 回调函数参数
0 k8 q0 G1 H2 j: T                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID
6 C3 Z+ e' y1 l: ^% t$ r6 j                if( MMSYSERR_NOERROR!=rc )
6 _8 f9 t: Y# E* G' b( P                {9 A( {2 n& y2 j% Q" a3 t- K4 F! D' j" a
                        //跳出循环
. K1 T% Q5 [+ \; [7 y                        break;
' g; o: \& Y6 ~7 r9 T: H8 \                }
0 x# B* b7 c! G, b  o                // 打开混合器设备无错的话,则
* p+ T9 R0 e8 {1 P: z2 A% M8 h# a6 `: m2 k
7 {" Y7 I+ b! U2 A- P$ G
                // MIXERLINE 结构体变量清零2 q" g# a2 q6 W$ }9 Q! h
                ZeroMemory(&mxl, sizeof(MIXERLINE));
3 M: a1 Z: Z" F$ t% Y8 ^
; V9 b1 \/ n5 Q5 b% L2 d8 h% a0 G4 q$ K% ~: S8 X" x
                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本' y7 g% r6 o$ K6 K5 q
                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS. e$ S/ j; {. I" n4 C, R
                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
3 |2 J) }3 u  H* T+ L2 T; Z$ I& N: v; v3 [% x9 t
2 l5 L9 S4 \# V3 Y+ c/ X
                // 取得混合器设备的指定线路信息/ {. @/ \* G) Z7 T3 `
                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,7 X% p+ \# R' D- p/ B; t- B4 G# d
                        &mxl,
9 ?5 G8 Y/ W6 e$ f: v+ D                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息
+ U, A+ R( n# `- c0 C) m- t  l, P. g                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
$ N1 k' T6 W% \! N                if( rc!=MMSYSERR_NOERROR )
. m, [9 |* o# A2 J. {                {
9 o- {* f2 w$ b2 C# F                        //无法获取声音输入线路,尝试其他声卡
+ g1 l7 H* w) J/ p9 Y% M" V                        continue;6 V9 N* _: U# k+ m
                }' B: \% |. A) C

7 t3 v& ]2 M! d- e4 K/ L3 F/ e0 G, B& w! l
                // 取得混合器设备的指定线路信息成功的话,则
; B6 V* O  x" v* a6 M& o7 u" W9 V: U# A) U2 }0 k

7 P2 V% h& }( X- T                // 将连接数保存 : ^9 P& v+ G& z! s
                DWORD   dwConnections   =   mxl.cConnections;
: p6 V1 B4 P; G+ p! M                // 准备获取麦克风设备的ID : D2 S! e6 f2 c3 a# c# A9 v0 b0 U
                DWORD   dwLineID = -1; 1 h* g( X: _! }9 Z3 I
                for( DWORD i=0 ; i<dwConnections; i++ )
6 T; _- l% @8 q3 |7 x6 ]; j, k                { ! H1 ^$ X/ r( O  s1 k7 B9 x: Q& q
                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
/ \' d) D4 n; @9 L. t                        mxl.dwSource = i;
) I  z% J; _) g5 q: J                        // 根据SourceID获得连接的信息 & S* H$ y9 C. B( R2 R
                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl,
2 V* x( B4 t3 @# k/ u5 Q                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); + u# n+ \+ x$ k( [: B# h
                        // 判断函数执行错误
+ t0 M% x9 V1 Z                        if( MMSYSERR_NOERROR==rc )- E9 [1 D! }$ ^
                        {
2 G' h2 ?) l" O/ @& v: h                                // 如果当前设备类型是麦克风,则跳出循环。
* a' Z6 H4 g( ^! v3 p                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )! I0 \2 y) a# L3 X6 Z
                                { * c, {+ b6 @) K  ~  K) }5 i3 m
                                        dwLineID = mxl.dwLineID;
4 |8 V/ J3 _7 [& n1 i                                        break;
$ h9 k8 E- J! y                                }
: R2 u  u! Q' E) Z                        }
5 `, G* R8 s, w: x/ [$ T                }3 V0 k0 P/ c# ~  p/ l
                // 如果没有找到,返回失败。 9 \$ i5 I% M7 T0 b# }5 d
                if( dwLineID==-1 )
+ U/ d/ H- d% A3 y8 y                {
& d5 K* s' j: r9 D% ]# m. S                        //尝试其他声卡1 [) H% ~  [1 C, g( P
                        continue;
/ E+ ^7 x4 ^) D1 M6 n. A                }
3 ?) v6 i& y& o' z" ?
, A# C" q/ z5 k  ^( L
3 F3 B6 h- s( {+ F                // MIXERCONTROL 结构体变量清零/ V- v( g+ j7 Z3 S
                ZeroMemory(&mxc, sizeof(MIXERCONTROL));7 T1 o2 {8 G$ ^) E$ `
' n, i. z  L6 I) }

7 w8 }* G7 E7 o  F( P; t1 k                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本8 E! c- T* Q2 ^# j" I  ?
6 c0 q1 Q9 a9 ~8 G& E% W+ _
4 n$ X2 \3 @9 W$ q
                // MIXERLINECONTROLS 结构体变量清零
% t, {; o1 A: C                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
- [. T# n7 k& o& l" y- }! z, H  P+ `3 x0 H( H7 q
- H2 ~/ f; X8 E/ S& V  ^
                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本2 F1 s5 E& W8 t: [( u

( |1 l* A, l7 B8 V3 Y
' s, n1 e% i5 [5 r                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识
# j" V/ \1 o& ]( v                // 控制类型为控制音量
  q. o# U* F* u) C                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;5 H. c' \1 H) @4 E) l3 N
                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数1 t" ^- Z. O. M9 a
                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针
5 _# p+ R9 u0 v6 f$ i                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小5 S0 Q/ L  V' Y* X( n

7 e  W$ ^  ?3 ^8 m7 h# c; |7 s+ P) K+ P" Q0 y
                // 取得控制器信息2 l8 U- F5 e1 g% a  s' r/ `
                rc = mixerGetLineControls((HMIXEROBJ)hMixer,
1 [0 c5 E& N# t& e) }8 m                        &mxlc,0 M- _1 c& g  w$ y% I4 }$ Z
                        MIXER_GETLINECONTROLSF_ONEBYTYPE);
, v  K8 b/ Y: s3 q5 B
4 o' m  A( _2 W0 U: B! s+ G6 K) _
. d2 A/ O( P( [" A  y! M                // 取得控制器信息成功的话,则7 @9 Q5 G1 _8 C# ^! V8 a( N
                if (MMSYSERR_NOERROR == rc)0 J6 `4 [1 H( O0 E! Z' j
                {
/ C  `: O6 d* c7 \$ G8 f4 Y" b                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.+ L8 V; v/ c# a
                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息+ u- |" k' g. R9 N. X: @
                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)
2 v8 C' c! Q+ f9 t6 n% Y( c2 z% Y; |1 y9 i! A

7 _; S3 H. @, B3 c9 i( s) i                        // MIXERCONTROLDETAILS 结构体变量清零
2 D) X0 I/ v+ W8 j+ |: c1 }                        ZeroMemory(&mxcd, sizeof(mxcd));' |9 _5 F, B5 Z+ Z

7 U' N0 {8 w5 |% J) {5 i& b6 y7 Z5 ^9 L- j) O6 V3 X
                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本  U! u) a! C; e
                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识
! G7 C& |9 `9 x/ `  \9 I                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针* y+ y1 H8 }9 W# O
                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
2 j3 Q7 L* D4 ?" \! _* p) _' l, o* A                        mxcd.cChannels = 1;                 // 取得或设置全部通道& z2 i) R, t& \3 B

- T/ m5 E* P  t- S6 S$ W: Y$ ~6 S# K
                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
8 P+ g. Y- Q. J( J0 ^; F. h! C) {
& F8 d& M3 v4 W# f- R4 @/ z
! r  ~& V2 ?" q, L) j' h  ]% n                        // 获得音量值9 p2 h9 [2 c2 T; o' }  E9 R
                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,) U+ R0 o2 [! e+ p' [0 l8 s
                                &mxcd,2 n; k8 |# [  G& U
                                MIXER_GETCONTROLDETAILSF_VALUE);4 l6 N; r, z" E# [: ]2 j
- y3 _; {2 @7 p# J/ d: a) A

2 O% @1 H9 e# H% e* e% P                        if (MMSYSERR_NOERROR == rc)
' i5 y* z# N# G6 W9 k  ]                        {5 b. n2 M- h8 q/ r
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;
. @4 C$ l. j6 _% z$ H0 ^+ `* J& P
4 v  O9 ?  }9 ~# h, m" _' ^
, S( r! Q/ K# J0 F! d  E9 R                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;
5 B) T5 L* ^# g( j. ]% ?                                printf("音量:%X", volStruct.lValue);
  }- j+ ~* Z& Y4 H1 ]9 v5 L                                return index;# _8 O$ v4 m# Z5 Q' q; K) ?6 L$ K
                        }4 G0 i$ n/ M# k, j* Y! c
                }& g7 k: N' ^4 ?& `1 ^
        }
% ?$ r5 s( t3 x2 Z5 {* E, P' e' H$ q4 U/ W0 H% Q
: ]$ G& G& f- b7 G1 `+ o) Y; |
        return -1;
# O: B& P* f: f1 A3 ]7 W}6 n1 R9 D/ \" b7 Q$ `) E" \
( V8 ~$ Z, ~5 m. `
        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html8 u! q2 y5 ~% a) E* L
                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-5-4 23:11 , Processed in 0.015668 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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