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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/2 w  F/ J, p2 n. _% {
7 I6 R7 V6 X  D9 a7 z; x
参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
) L$ @  f3 n8 I8 h. w
# ^/ ~$ s- }5 s$ ~. g! ]# X5 j8 h! A
int DeviceManager::getAudioInputVolumn( const std::string &deviceName )
- e. a* }- D$ g4 O' g{
  R: ~8 [" o" \* s
8 i, k& G2 v- h( A& J# H' `& {- ^4 |
        MMRESULT          rc;     // 多媒体函数返回结果变量" r" j. N% @6 y% a& F
        HMIXER            hMixer; // 混合器设备句柄
% ]2 g) d! P# ~4 ^$ S        MIXERLINE         mxl;    // 音频线路标准状态信息结构体- a9 |8 a( o3 E- A
        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体
' x/ Y6 ]4 u% a% v$ Z4 L/ A        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
9 ]; o6 `& |* n
1 f6 A) t4 {% d; M' c: p& U  T$ N! p9 E3 v' L4 E! I/ A
        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即
5 i0 b7 C% L% n        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,. @& b6 T& F* B+ q  p5 G% e& ]
       //可能还是跟声卡驱动有关。8 b( @3 V5 t% i8 ~' P
        for( int deviceID =0 ; true ; deviceID++ )
' `, U7 L5 _1 c: c9 k+ k; h        {
6 L4 r2 v: }, d5 d4 G0 ~8 Y+ ~                // 打开混合器设备
  [2 l6 R( z5 S" J( B. q                rc = mixerOpen(&hMixer, // 返回的设备句柄
( x1 l" t% @1 Q                        deviceID,       // 单声卡的设备ID为零7 Z5 v5 F7 h1 G* b" C6 l8 s8 t
                        0,       // 不使用回调机制
; e  j( E, N" G; L5 \% t  G                        0,       // 回调函数参数
  ^& X+ E& s- g7 f" M0 e                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID* A7 r; X8 \& D6 I
                if( MMSYSERR_NOERROR!=rc )
% m" W" h6 y0 a4 ^: e' ^                {
5 @* B) X9 y$ o, k- s% M" `                        //跳出循环
2 S! J4 J* S4 n4 n; ?3 [                        break;4 _, M- T7 P& K8 n
                }& I- _: ?' F# Q2 N  {+ g8 F# p
                // 打开混合器设备无错的话,则" R8 J7 X) l- f" |2 p
* ~; `3 [/ L; U1 ^6 G- b

# C% \' x1 u7 p* `& Z3 L                // MIXERLINE 结构体变量清零
( T# U2 s. Y$ |' g8 a                ZeroMemory(&mxl, sizeof(MIXERLINE));7 V  Z: v# O; b- P6 o4 I9 W# Y

/ _6 U: l/ |" O$ S
% r# _& T, O0 {                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本
. |- D8 ]& Z8 s! [/ X# _0 B; A% z                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
- w3 S5 m. I* _0 k) j1 a% F                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;4 |( v9 \3 d( t2 y
9 J8 ^! \6 I# o/ {9 ?4 n1 F5 ]
! Q1 I% v8 C+ O/ @% f3 x
                // 取得混合器设备的指定线路信息
" h6 o. A" S  `5 n                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,! \$ @: z6 B( B! L7 G
                        &mxl,
$ _; I' W( b, `0 d; c" ^                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息$ L, X+ A. H+ ^/ p1 d- h  e
                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
  g7 G4 e- \: ?$ y1 E! O                if( rc!=MMSYSERR_NOERROR )
0 U1 `, F6 w: ]% z5 I                {
$ c4 X* G* T5 S. ^. ]                        //无法获取声音输入线路,尝试其他声卡: b4 M+ Q9 O5 F! d0 \' f% D
                        continue;
3 l0 w; N& y8 q- H( q: a% Y                }6 g0 `4 J/ X! I5 _+ }, f, u! C
. b  J2 ]+ _* G4 l& T, x# f

/ u5 J! U5 b5 X2 D                // 取得混合器设备的指定线路信息成功的话,则# ?% c/ b  A# X: L

/ m% J7 D9 n9 J: v+ d9 ^8 e
; t! f5 G6 x: s                // 将连接数保存
' C! A% l" _0 J5 Y( `' a$ Y                DWORD   dwConnections   =   mxl.cConnections;
) l; C! [$ k( Y8 E& S$ M& C8 O                // 准备获取麦克风设备的ID
9 H; T0 L# ?9 F6 p                DWORD   dwLineID = -1; 2 R* |8 n" {9 v& E& U# A$ O
                for( DWORD i=0 ; i<dwConnections; i++ )
" w, m+ f% V- T3 l- y# |7 Q3 `1 X                { ' A" G* B4 a/ T% k) t  D
                        // 枚举每一个设备,当Source的ID等于当前的迭代记数 5 ]7 J1 p2 u$ ]# I3 @$ ~  U
                        mxl.dwSource = i;
9 F1 A9 w0 @. U                        // 根据SourceID获得连接的信息 $ N/ R# n0 ?% L# T! ?# _; W( n
                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl,
8 `7 j4 Z3 w5 a  D6 X: i                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); 9 Y7 ~7 A7 I- u; Y. Y. o
                        // 判断函数执行错误 + k$ _7 r0 N4 `# i" \" O9 {
                        if( MMSYSERR_NOERROR==rc )& G6 \* i+ F8 u, ]
                        { * {6 z8 g( X  f5 `- `8 T, q- i
                                // 如果当前设备类型是麦克风,则跳出循环。
: e0 q2 G; U0 D6 K! Q; K, E                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
& Q0 t( H% _) A2 p' ^" o+ m/ {4 w9 T                                {
4 R  K. N1 h! D! ?7 O                                        dwLineID = mxl.dwLineID;
! W1 E. U% A8 E( Y5 k                                        break;
/ q5 u+ `1 K* C! Z" s                                }
8 X; i- ]# h0 U$ ^3 F) k/ R                        }
  H8 `: Y6 h) t* e0 n* h  F                }
/ @8 C) l( j4 z/ u. y2 E0 m8 O                // 如果没有找到,返回失败。
( t, I+ M9 H2 M5 t& u+ {                if( dwLineID==-1 )
3 B% R0 H* @$ h" o                {
; A" u1 t/ L( Z                        //尝试其他声卡
5 `) l% \4 Q1 }& ?+ m                        continue;! @. ^3 C; s& E; l% y
                }5 s6 _! _$ R) A: k+ ^' [/ e0 ?

5 f: h4 O" C! V" b
% s# h) S' v! i1 U                // MIXERCONTROL 结构体变量清零
8 H7 T  j& m; g/ A                ZeroMemory(&mxc, sizeof(MIXERCONTROL));
5 T7 D: {- \4 n5 z6 P( l7 B5 u( _: v. k' l; J2 e, |! R

; m. M7 ], h) }4 E. q6 x2 h7 b                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本
! F- [" o# E: t) J( g
/ r3 W) r5 S" v! i( N$ G0 N
2 D  O  V9 S4 H. }) h  w                // MIXERLINECONTROLS 结构体变量清零# `! Z; m% Y: D1 y  c
                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
) z9 _- O0 X- M; M5 v3 q5 h5 [- X+ ^$ K2 j" O4 s
) D) \8 R6 P. B& P. N+ n2 K
                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本3 f) O& G. T% W- K1 @
3 Q4 H* ^! b/ T7 u# ~8 n
5 f* a6 j% D' W# ?% R
                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识
; T3 z2 W: p) }5 w9 h                // 控制类型为控制音量  F  C4 A% S4 g% A: ?" B: g
                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;$ i5 ]9 M# ^( P6 l3 H4 y3 P* W
                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数
* K( k: w- N  p+ M8 H                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针2 Q: Y" C* C+ j
                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小4 b, T. t* h, N
5 V) ~# _1 Z8 a: A1 F" U

. q& t+ t* h8 z! B" z( g' J& B                // 取得控制器信息2 B& U. }, {% B* t# l5 ?3 t6 I
                rc = mixerGetLineControls((HMIXEROBJ)hMixer,
& a& S% I9 S1 \# O                        &mxlc,2 e/ ]! z+ }4 f
                        MIXER_GETLINECONTROLSF_ONEBYTYPE);8 c$ p+ z  V( L8 y: `/ }

& G7 F# o" Y8 f& L7 m1 Z+ o% W' L5 }$ P- u# U9 s7 T% B8 e, ?0 N
                // 取得控制器信息成功的话,则5 q1 ]! s! {9 P! z
                if (MMSYSERR_NOERROR == rc)! ]" k) p- C! u. W2 p7 R
                {! q( U7 c8 e& `! }
                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.7 f" M' T5 A9 P1 q
                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
4 @0 g! l) i1 l5 X3 Z                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)
! ^' i2 ^6 c* V2 T: c6 U# X* c6 A3 m5 n# |9 w' V
* b' R4 m- h  ]9 i; o4 z
                        // MIXERCONTROLDETAILS 结构体变量清零+ @: c7 d, H. N8 d
                        ZeroMemory(&mxcd, sizeof(mxcd));
7 q1 q4 l) F  y! I7 `, k' \1 B" [# J) P: c; x& V8 m* I$ i

1 P3 K* V3 P$ I) \                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本
: n+ V2 Y) g9 k. i! a                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识/ c* t4 g& T$ V3 G  E
                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针; R  A* d7 p- C# t! X
                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
- O! w3 `9 U( E4 k' n2 r4 ?                        mxcd.cChannels = 1;                 // 取得或设置全部通道
# r0 Q* O, p0 b" q
: B' X8 ?1 f5 |
% g* l4 S) W% |& T8 l& b& m! r                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
: F' c. R' }- u3 Z  G
; v1 F, r1 c' \0 R  m3 ^  X0 u% P* _# h+ Y/ d* _- z* k
                        // 获得音量值
/ ?; z: k+ r9 m  p0 p* U0 K                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,
/ @' T& c/ |/ s+ V7 t1 \                                &mxcd,. c) k! Z3 A4 F7 s2 t
                                MIXER_GETCONTROLDETAILSF_VALUE);
' ]: \9 p" i1 A( W$ W) z! F. a
8 m9 X  }6 Y! j$ V- p0 E
/ X$ f  q4 A3 ^6 B- `: D: G! B                        if (MMSYSERR_NOERROR == rc)
' I6 |4 j! ]# j0 S) f% o% V                        {8 E: j0 x! T+ h. \+ ~: N
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;
0 D3 F6 o) ]8 c" x# I5 P
: G8 N: {+ {/ d% j( T  R- [9 f$ h( f' `: \" G# O4 W
                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;) ~1 x- i6 V+ ^* ^. ^
                                printf("音量:%X", volStruct.lValue);  ?2 ^0 U' H1 p6 g4 }- A! o( w" `0 u3 J
                                return index;
# M# \1 V% A/ \% X1 p  c; d; S                        }
( D7 Q0 G5 v$ y8 l  q& W6 Q8 u. W                }/ B8 U7 s0 S+ B0 w
        }* v+ U$ E$ }1 s. j0 ~+ e

; y# E; G, [$ u  y& r( B2 b+ y' g( E- h8 u' z1 e, V; L4 n0 \
        return -1;3 p' ?" d: x% ]
}$ I5 z& o( k. C% s

# r. S, p$ f% h* J% e3 X! ?9 Q        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html
0 n) p- r6 S; u% v- q                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-6-19 04:05 , Processed in 0.015540 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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