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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/
7 p) ~, R$ ?/ l' @( A2 Q9 [
3 d5 x$ k5 _0 Y" l1 S: t参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
3 ~/ ~, O* T  ]6 N1 I9 }
, \( u# U# h, z( u! n% G: c+ Q$ [) s4 D/ d6 P0 Y
int DeviceManager::getAudioInputVolumn( const std::string &deviceName )
7 k; A: i: b/ O7 @+ ^{
# S( L/ ]* Q( k  j. v9 Z, {8 {, i/ L8 q
# G& X+ Y$ e) i3 t8 l0 Q$ C, r
        MMRESULT          rc;     // 多媒体函数返回结果变量  k+ t+ x3 T9 H
        HMIXER            hMixer; // 混合器设备句柄. |8 ^; Y  K0 h9 Q' O" N( {
        MIXERLINE         mxl;    // 音频线路标准状态信息结构体, H! m9 r7 i! F3 M8 g& }, M- c- I
        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体6 D+ ]! A- s$ Z2 l
        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体, i2 g. _3 L. X- ]# m7 N

- p: p) I$ T! s6 Y; e, Y
0 R  C( x* a* k, p* @2 r        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即
7 s# N6 n; ?. B. y8 j8 G; P8 ?        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
& j2 `) i, D  ]       //可能还是跟声卡驱动有关。
. g& h, J) c6 |+ R        for( int deviceID =0 ; true ; deviceID++ )
5 X4 u" E) o1 `6 u% ]: @0 n        {- N; f9 B  C) P5 A) ?# J
                // 打开混合器设备
& J9 C3 g: f# h7 d                rc = mixerOpen(&hMixer, // 返回的设备句柄* x( h2 o, m& W2 m* t5 t% b' q
                        deviceID,       // 单声卡的设备ID为零) E  _  m; z& D+ i& k' I& i
                        0,       // 不使用回调机制
$ q- {1 W8 V- @, I' h                        0,       // 回调函数参数. u' N- P9 m+ }# ]( @/ M4 d" F
                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID
* |6 \2 _4 \5 D( L4 ?+ G                if( MMSYSERR_NOERROR!=rc )  v& ~: g0 T- h7 T0 E: J) g! B
                {, t  {) Y9 {% D0 M4 n  n0 U- u- R
                        //跳出循环! E1 {8 S! N7 E( u
                        break;
& k& k' l2 m: `6 U' a                }
- K" q4 }9 B5 @4 ~2 ~                // 打开混合器设备无错的话,则
, t  q: v- O5 J/ ?
# M3 n2 e; X6 i1 J" p0 a1 N$ C  d( d2 X7 v4 g
                // MIXERLINE 结构体变量清零( c! A: _# s! H  M2 Y$ s9 Q5 `
                ZeroMemory(&mxl, sizeof(MIXERLINE));
" |& C4 Z* _* ^( G
: g! l8 g5 W) E4 }' |5 B+ L8 t
& C' ^9 N7 H, _; K6 E* q                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本
. u! T: ]* r# z0 i: `- \                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
+ x" w0 C( `' h% G  r6 Y                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;- J. G! O  a# r7 ~5 `) W

5 r/ f* u" @1 P% R; c
4 _# D, N% j9 ?4 L# b% G                // 取得混合器设备的指定线路信息  |. u$ Q' Q8 x. s- N" @
                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,+ ?- B( J/ v- ^0 s6 h
                        &mxl,5 m7 t* Q+ _" a
                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息" {1 O( k1 B$ z9 u) W5 T
                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);# J6 U$ D! N. }) X2 f  n: x
                if( rc!=MMSYSERR_NOERROR )
2 s5 q4 @/ H9 R! V                {
% y8 h) k/ x2 d  x                        //无法获取声音输入线路,尝试其他声卡0 m7 X+ Z( V1 x: d9 H6 Z. N
                        continue;* y+ @9 U4 a/ s+ C) X6 H6 T
                }
9 S8 q3 P2 v9 R/ U
1 ]8 D6 @+ w0 }0 W; A$ p+ B% }$ h. D, b2 i+ W
                // 取得混合器设备的指定线路信息成功的话,则* g) E" _4 f0 L+ P1 S. g
* S0 c5 @- {. v/ E: V' J$ H

9 A* p, a  o. b+ Q4 J5 D& P. H$ e! V* @                // 将连接数保存 0 A4 |; l  |$ v: D4 q: o1 O
                DWORD   dwConnections   =   mxl.cConnections; 6 ?0 j* s0 g$ T% {- ]; F0 b
                // 准备获取麦克风设备的ID 6 U4 Z) r+ q" p5 p
                DWORD   dwLineID = -1;
2 E, Q* h: I6 G; X% x5 ?+ A                for( DWORD i=0 ; i<dwConnections; i++ )
3 n$ l; n8 e' n" M. ]                {
" M5 ?. `0 R% j4 |: \                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
/ Q' i9 g# e9 H  k% ]8 Y* m1 i& s                        mxl.dwSource = i;
3 `4 Y2 ^0 c/ F* m2 ~5 I0 t                        // 根据SourceID获得连接的信息 ( n! A6 `4 o+ y  o& S6 Q
                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl,
( O) `' K9 W- O- h                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); ; G8 z/ b$ L6 g* A$ K- h( c6 _: {
                        // 判断函数执行错误
* x; `' ?% P8 w& d4 ^                        if( MMSYSERR_NOERROR==rc )' d8 W, z- }3 L6 t, [
                        {
4 T$ \5 z9 E2 j8 ~+ G. ]# T9 H. {- s                                // 如果当前设备类型是麦克风,则跳出循环。 9 A* k( _* P, M9 r
                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )3 c3 E/ C3 Y- ~
                                { 4 F9 X' K: a( b5 z
                                        dwLineID = mxl.dwLineID;
, F% ?: X) k3 h5 [" K                                        break; 6 T1 h$ K* M1 b0 W
                                }
/ }6 C) `( Z8 D" q6 u! S( v                        }# d% m! ?0 o# Y5 _$ f, F, Z
                }2 S! f& W. N+ R1 F  c
                // 如果没有找到,返回失败。
/ T2 L; z1 W  O, D8 t; s- I                if( dwLineID==-1 )7 d4 B6 A9 W/ Y. v! t
                { " Z* W+ R+ P: T( @7 {4 y* R
                        //尝试其他声卡
" U8 O! h0 x% u4 C6 A% L: r                        continue;$ f  G$ D. f. l
                }& ^& s+ |+ l( n2 u1 w5 k
# c8 U. P( f3 N7 @2 G4 P: n! b: E9 W
( M$ P) R$ G' P0 s5 J3 W* ?
                // MIXERCONTROL 结构体变量清零" L9 [5 C# p! F) r
                ZeroMemory(&mxc, sizeof(MIXERCONTROL));
% w8 [( `0 v; C+ J" D6 b
1 ~6 X+ Y/ W2 J& B3 u. a
2 u7 F# K* J- b: Z$ a% S" @' R                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本1 N9 ]) R4 s3 ]! ]

' a0 p3 |9 {! f
/ D* j) h0 S, q) X3 x  K5 K1 T                // MIXERLINECONTROLS 结构体变量清零( i) f9 d4 S6 K5 U  q
                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
9 D5 q) S0 m4 q1 z7 \. c3 H9 Y
" Q( g9 R, w: t2 u. s$ o5 C
8 ^: g! U9 e: D0 |; s+ j! X% N! F2 }                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本
5 s' y" u" B2 |
* g  }; ^: ^1 b& t2 W8 K2 x1 H! I
1 C0 J9 D1 ~/ n& e4 ?                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识
3 S) n6 w" r2 O9 h4 ], ]                // 控制类型为控制音量6 L) L  i/ T: z) l" W+ M1 n
                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;: M. L6 Q1 U" f" c0 v1 t
                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数
1 q( b9 Y& ?0 j, y! r1 k3 M                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针4 [! J" V" _! l: d: Y0 R
                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小) p1 X: E& M# z

6 P( q( r( j/ v! t2 w  B+ K* j& d+ L9 r
                // 取得控制器信息
6 u3 m# p, M" `7 E                rc = mixerGetLineControls((HMIXEROBJ)hMixer,5 q. H& U. |% I1 R
                        &mxlc,
) K' n" u6 K5 n& |                        MIXER_GETLINECONTROLSF_ONEBYTYPE);
8 t1 z1 J  {; y
; S& I: I/ t( e: t, H' f% m1 e1 a+ e% M  }
                // 取得控制器信息成功的话,则3 z1 B  [- F& H# d3 \- c
                if (MMSYSERR_NOERROR == rc)
- f4 Y) @6 |  ?& `0 Y/ P                {2 f1 I6 F9 ^! S4 |4 ]; T
                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.1 ]) [1 E2 Q3 u- r: [  j
                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
( {+ }  u" E. T2 g                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)8 Q" d+ x* M' g- s0 y

1 N8 g, c( g: C" G: Z2 ?9 d6 I( L# E# `+ L: ]
                        // MIXERCONTROLDETAILS 结构体变量清零
( k2 x( X7 s: j0 Y. |2 F" f( K                        ZeroMemory(&mxcd, sizeof(mxcd));
' x; ?. G) k: k- L
4 G6 q2 |$ r* K( z6 h1 L2 M& @
; l9 Q5 t: s) K                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本
0 u8 t7 M; p; Z  B                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识/ G# \8 O4 t- K, G, o- U
                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针
$ _9 _8 r3 J6 B" N' c) y7 i8 G7 Y* a                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
1 n0 A7 A; E) a$ D' ]  _                        mxcd.cChannels = 1;                 // 取得或设置全部通道
1 Y! z4 `4 V0 E
2 ?# \/ b+ X, t5 g; m( J2 Q# E0 k3 W, Z% F$ N# }
                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
& t( b" K& I5 c
  x& T. z: V3 |; `% l* t! M, [+ m0 l! h. _0 A; y, }
                        // 获得音量值8 F" L" d- {5 t
                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,  [: ?0 g$ ]& s
                                &mxcd,7 j" a0 `8 q4 B% U& w
                                MIXER_GETCONTROLDETAILSF_VALUE);) H; u+ R- F' C

+ }) N' T2 a# c  v6 x, ~! G2 u- H, E% V! }
                        if (MMSYSERR_NOERROR == rc)+ B1 e5 @) x$ A% t, a
                        {0 F, y1 y0 ]+ p" a5 k
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;: Z, ^' f  Z! O% G3 T) T9 \
' u2 x, J5 N% Q; O# e0 |& n7 w
! A! D7 R0 z+ F0 a; \5 v
                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;/ g" Y4 c5 t0 l' h! l
                                printf("音量:%X", volStruct.lValue);, i$ d* H% }/ Q+ u) s
                                return index;
: L& H9 g( e; x                        }- ~) U, p! K  R0 f0 T
                }
% z/ e! m0 k9 g# G' m        }7 p- h  A0 M( p, I, t' `  j
7 M; h: @+ v& s, J
+ _1 z. t( M/ @; J9 R6 h. L' e- }
        return -1;+ Y( i3 H) X( G6 G: s
}/ k1 z* X" O2 z

5 G4 h% A9 |; L, z2 x4 C$ b        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html2 U2 K" q, r. X2 w
                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-8-13 20:16 , Processed in 0.021564 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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