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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/
3 O( D6 w3 m5 l  ^# X
7 @, z" Q& s0 T* D: x( h* T) t4 ?; D参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:- S4 w: M! b* z( m5 F8 C: f
7 f1 W0 A+ s& t2 h

$ F  Z3 p$ ^- S! [; D" [; Oint DeviceManager::getAudioInputVolumn( const std::string &deviceName )/ G8 V' a* G$ `! p
{* Z, _7 L2 N8 h, K

& U( H* h+ x3 N+ p
4 l9 k0 i# n0 D7 ^* S! I* u        MMRESULT          rc;     // 多媒体函数返回结果变量
6 z, r2 U$ w, Y- e        HMIXER            hMixer; // 混合器设备句柄
  r# q5 Y7 |3 L/ d        MIXERLINE         mxl;    // 音频线路标准状态信息结构体5 a4 `- o# |0 O6 r8 l
        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体) Y0 d1 ?$ d# H! p
        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
: B  M: E" d& k. c& o9 z  ^: U# z/ _
8 C5 Y% Z6 v" r0 t- k0 ]1 X6 i9 L
        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即
* |  e. k, b( o$ C- _' _        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
  J! l% k$ Q1 t4 O" T       //可能还是跟声卡驱动有关。' g. M& n: \3 g7 m4 s* U; w
        for( int deviceID =0 ; true ; deviceID++ )* t6 v6 W+ ~% a7 X
        {
3 K# ^* _; U3 j9 a' y8 {( d) d% ^, Z                // 打开混合器设备
; I/ M$ k& Z' _. U) f. ]                rc = mixerOpen(&hMixer, // 返回的设备句柄
4 F' Z9 x6 \7 _& M2 J                        deviceID,       // 单声卡的设备ID为零9 d, A- u  ?1 S
                        0,       // 不使用回调机制
* J" u) I8 r; m# n1 l                        0,       // 回调函数参数
6 r& M, R+ A0 d  j3 W                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID
! d! r9 ?# o: X! {                if( MMSYSERR_NOERROR!=rc )4 v' [: [8 X! T/ ^; A+ o
                {
- T5 j  n/ G- n0 \                        //跳出循环
' |. r2 T2 c7 c- m- q$ R3 B" F                        break;5 S, r8 Z: p! ]/ [& }
                }' T% S) r  {' A5 K# I% l
                // 打开混合器设备无错的话,则- f( |- q2 x- p; l

: p8 H) T: Q" M1 P5 Q4 u5 V! c% B$ j/ z; U5 Y# C" V
                // MIXERLINE 结构体变量清零
  T( k# d# \1 S' t                ZeroMemory(&mxl, sizeof(MIXERLINE));
4 t4 h7 c" E) ?: |
2 |% l% j: ~. T) @0 M$ L# f& K
) v$ X6 }8 a) q' J1 S                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本+ N2 E* Y; z# d
                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS4 n5 A+ }' n: q3 H8 B% u5 W
                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
# O. `3 @& R, ?2 M7 }
4 D3 @# y6 F) i2 ^6 F4 p, U
* E, F" Y1 ?3 ~! F                // 取得混合器设备的指定线路信息
; a$ S% a+ B9 o                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,) @0 g) _! s) c! B# K9 u) n
                        &mxl,/ v; s- I6 L: N2 P* S
                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息( a: u7 C0 I( a* U7 K
                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);: ^5 s' n# i" |: O& @; M
                if( rc!=MMSYSERR_NOERROR )# \, c2 A, ^2 `$ T
                {% E3 e5 L+ }, Q6 Q& R2 h* T: Y
                        //无法获取声音输入线路,尝试其他声卡/ h. c  ]$ F9 G, W4 t" G
                        continue;
1 h. h# X6 y: \2 Q' {  U9 F2 a                }5 b- A0 K* `* W! `

3 p: \( s7 b* {/ f6 J
/ ]9 q3 u( [2 V9 f( w0 T                // 取得混合器设备的指定线路信息成功的话,则" {. u& T5 ?% x- j

; b$ _$ H" j* m7 ^  K" @: o' P1 e& m7 l+ z. T2 O* r
                // 将连接数保存
9 u5 K0 P! g4 P) f9 Y: M$ i+ J1 q4 Z" D                DWORD   dwConnections   =   mxl.cConnections;
7 o$ r( l; i/ i$ j! l                // 准备获取麦克风设备的ID
+ x1 ^1 Y! A2 d                DWORD   dwLineID = -1; ' I( t+ }! M7 Y" w' g: c
                for( DWORD i=0 ; i<dwConnections; i++ )& s( p5 M1 k7 ^8 `4 G# u
                {
5 t' ]+ N7 V! w0 J% j$ p3 q+ [6 L                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
( [+ q2 M$ G! U$ g0 B" y/ `0 j! L( l                        mxl.dwSource = i;! \) Y  b7 Y+ I6 U- |4 b2 P" c
                        // 根据SourceID获得连接的信息 # y# w: b/ l' P( ^$ y, n
                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl, 3 d9 p$ @1 g, r6 F; `; r5 c
                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   );
- X. D2 t/ W- m& J1 M& o                        // 判断函数执行错误 . P" o4 {) }0 ?0 f! E- j
                        if( MMSYSERR_NOERROR==rc )
. M  W7 j1 n0 e  H0 I% r& V                        {
0 \: c; Z( O/ p                                // 如果当前设备类型是麦克风,则跳出循环。 7 ?+ f: k& A, m7 G/ O9 F
                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
* w6 J1 j$ c5 F4 E( \2 d                                {
- D7 V8 ]5 n6 Q0 |0 h. H# {# E                                        dwLineID = mxl.dwLineID;
/ _$ F6 z) V, ?( z/ M& ^# B9 E' E                                        break;   s+ k) F1 Q! |6 `
                                }
# u# z9 Q/ x8 K% U8 q" M' ^                        }
5 R3 D- u3 @% B$ f0 V$ L9 ^3 i6 f                }+ j& L" ]: u- K: Q! B7 o7 ^
                // 如果没有找到,返回失败。
0 W" U2 t: X1 Y! |( q                if( dwLineID==-1 )
- ^% v* s  q# b2 ^( A: P                { % P3 V- y2 S( ^2 \
                        //尝试其他声卡. C7 f, }$ A7 \6 O# n2 q& |, |" n
                        continue;
  g5 U$ W( q7 m4 ]                }" p# F; n1 f0 @2 e( U) `" }; j

1 \8 H0 K/ r2 ^  G7 M
  k9 W& e3 K% n7 p2 V( G  v                // MIXERCONTROL 结构体变量清零
) I) u! }# ?% m" w                ZeroMemory(&mxc, sizeof(MIXERCONTROL));+ V0 _/ P: U' e: Z8 p4 h7 l

3 f- J- t5 p4 t2 P  m, g3 h9 s" C1 h% [$ S2 x
                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本) h) L6 m% \3 h$ F

7 I+ h8 ^" Y7 G) B) B1 F" ?% Z" z7 D! _  Y: w
                // MIXERLINECONTROLS 结构体变量清零
7 B  j# F" E+ D. v) {                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
0 p6 g1 _$ U* S/ E( M( W, C+ f7 w
3 ^& |  C! P( L4 m  \
+ |" X9 V7 t! V8 r6 q" ~                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本
8 P  k/ i1 V+ ^- o5 s# c" l5 V! X1 n

% G& j% P+ N4 x0 z3 W  m                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识* Z9 o5 p4 h' @0 \- w
                // 控制类型为控制音量; ]* p. }2 [2 N
                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
: n  u# \' i. @7 N  u  y. }                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数! V& T$ u- W% q
                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针
/ A% ?% |1 i8 I7 T4 x' F                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小
' O9 F! X: X# y- l# s9 s8 D  N* B  `# S6 W3 i/ l
1 g; e! N# k5 ]& X1 S) \. N
                // 取得控制器信息
$ X( O* ~! e' @$ `# _                rc = mixerGetLineControls((HMIXEROBJ)hMixer,
9 f' i5 q, E; v; ?$ `' h                        &mxlc,
) g" G0 D' A- T                        MIXER_GETLINECONTROLSF_ONEBYTYPE);
8 `. y3 `& q; u2 ^1 ]- l  P
) t  l/ L+ Y1 L
" L# Q3 D. }  w. Y                // 取得控制器信息成功的话,则: O9 o5 J0 c4 ^
                if (MMSYSERR_NOERROR == rc). u) W3 n* y% Q! L$ A8 h; `& d3 j
                {
0 r) H+ W. `1 o; |. h8 [: C                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
' a( I, n6 `! w                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
- P( k( q, U" {. b# q; L0 w* N- v                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)# Z' S! _9 x6 y( f# Z$ G* T& K  ]3 ~
6 o5 ^) s) F- |9 [1 ?! {
: N2 C, @5 S$ k0 o. \; b0 c. x
                        // MIXERCONTROLDETAILS 结构体变量清零
& T3 v0 a5 [" I; m7 l                        ZeroMemory(&mxcd, sizeof(mxcd));
  I' Y( C& Y+ F# r; Q+ M1 x& T7 r
- o# d; U; _* X' ]- ?/ X/ J' Q) O
: r. k4 ?) U- T& P                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本
" N* q. `; L* C/ B                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识, L; _& s; R6 W( `7 p) [
                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针
, ?- a; J3 b4 q4 P4 J. z                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
( T2 x2 C& y; R                        mxcd.cChannels = 1;                 // 取得或设置全部通道# B# x; A* W9 e: m: z; F
  E1 E/ H8 ?! M( K

4 p3 o0 ^# g: Y                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum. 1 ~7 J/ g+ K" _0 i* T/ M7 w
- R- U# [% ]  g" ?8 h1 m/ C0 f5 r
6 m2 j8 G8 |$ O& K5 `
                        // 获得音量值
5 j& j8 n9 h" m5 C0 W/ d  x                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,
* x- U2 |, X' ~/ ?! K, u8 p; Z/ u                                &mxcd,
" O  u, X/ O: A6 n. R8 N1 C0 ~+ e6 L                                MIXER_GETCONTROLDETAILSF_VALUE);
& Y2 S; d- Q! d8 Q5 M( g4 P# _4 g2 Q, T" o

9 B% P" d0 e1 f3 Z2 j                        if (MMSYSERR_NOERROR == rc)6 Z5 \6 Z) a0 ]( }0 B6 i7 R# X- r% C( l
                        {2 ]+ c$ u8 s5 @
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;
  `" W5 E6 w" F5 Q8 S5 E+ J% h, o6 A. z* }0 a
3 ?5 }* M+ |" _/ p2 _- T! Q
                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;/ p: ~+ ?6 P; `) s& ^
                                printf("音量:%X", volStruct.lValue);
$ T  b" @9 v$ x6 G5 M: x                                return index;
2 x& z2 @: a+ g6 y7 h: T                        }- j1 n; I* {4 H0 k
                }: d1 P. @; N4 X
        }1 F0 u% {0 Y; N
( p" ?8 W5 n& q" N$ j2 L
" F; n% ]9 e7 E
        return -1;
1 |* P( D1 i" [$ L# H}
( T; e1 O+ n& P1 y" R4 M
- x% C2 r$ ^( v0 @        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html
5 L" O/ t- I" n$ k7 {& @$ h! F                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-18 06:05 , Processed in 0.019883 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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