找回密码
 注册
查看: 5090|回复: 0

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/
) C* i0 G" R; S- E
, d5 R& T9 z3 D  |6 F* \9 [5 A参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
* {5 n; ~: Z" W9 j% C5 Z9 O
# m& W: ]7 j& m. d( w
. G0 {; t% J! F) Sint DeviceManager::getAudioInputVolumn( const std::string &deviceName )  G- m) C! e: @1 }1 g! {
{
. O' _0 T$ Q  f" O% V8 c6 ~, ?1 d1 `5 `- X
8 c, w" y5 w- m/ a# y
        MMRESULT          rc;     // 多媒体函数返回结果变量
/ f  g4 m% O' c0 u* t4 Q& n        HMIXER            hMixer; // 混合器设备句柄
/ S7 Y8 M+ S1 h/ f: F( g% c        MIXERLINE         mxl;    // 音频线路标准状态信息结构体9 c7 g! h3 l6 O# K+ ^
        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体* S( Y/ c4 r  v! X# y
        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体9 s2 `+ r7 f" k3 E) B" F

" d- f8 R& }& _4 K, B
& i! T$ Y3 v, K7 [- B/ d5 u        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即
1 ?4 |6 \$ M. X6 j6 v' l5 Y4 \        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
4 q1 |! V8 \4 T; i! j       //可能还是跟声卡驱动有关。. t- u" j. \, {* y# [) w! [! U
        for( int deviceID =0 ; true ; deviceID++ )4 x* j* y' o- v
        {
4 I5 s; L8 E8 Z  X9 o3 B: o6 ~) M6 C                // 打开混合器设备* k, Q% F7 w: ]4 X
                rc = mixerOpen(&hMixer, // 返回的设备句柄8 A& a% W4 k; R* X4 H3 J! T# n
                        deviceID,       // 单声卡的设备ID为零
' _0 D: d+ {2 t* r; Y                        0,       // 不使用回调机制
( |0 @5 Y, U1 ]! o, a4 e1 `: q                        0,       // 回调函数参数
! L% K* [9 p) E0 ^: A2 \; G                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID' T/ ?, u8 w. K5 L
                if( MMSYSERR_NOERROR!=rc ): U! M2 W/ y/ N) C( X$ ~& p
                {
( I$ u3 V8 X' x0 c2 v                        //跳出循环1 A1 L+ T/ N! b, h( w( u
                        break;8 ?; I& [/ ?$ B0 [4 Q& N+ g
                }
: }& g; s/ u" k                // 打开混合器设备无错的话,则
) U, ~2 {: W1 y. t& M9 y/ v% t+ B+ |/ O/ h# K- R2 m
3 f. o) M$ h) N3 ~5 n; C
                // MIXERLINE 结构体变量清零
! |# h7 O" j& J  x/ D4 B                ZeroMemory(&mxl, sizeof(MIXERLINE));  Q5 Y  Y' u; z9 d7 M2 w

: E6 ~, [* V: g4 t4 z
* E9 z& ]% x) K1 Y1 J7 M  Y" B2 ?, p                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本
. n5 |) M! O5 A5 O, q* T                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
5 q3 U: T- A( S, ~& P, E" o5 `" s                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;7 c, u" U  Q$ B4 H  e- m
- o8 A' X) k! N3 W4 j% c

% _- v( U# {0 Q                // 取得混合器设备的指定线路信息
$ b, U  W! ~  `& W0 J                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,8 Z( g: ^7 k0 w' b/ B
                        &mxl,, ]& V/ m: I0 w7 P) Z- ]+ c1 a
                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息2 b: l5 V7 V; a( ~
                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
. X5 O8 w4 n1 d, m                if( rc!=MMSYSERR_NOERROR )
! L5 B* B, a) R" i3 g) A8 ^                {( D" h9 }. j9 W
                        //无法获取声音输入线路,尝试其他声卡
; V2 v! t  q$ r9 h1 o6 @# H                        continue;2 h; R# w% t7 r2 z$ P/ L/ m
                }: B& s. Y! a+ f- l

2 _1 u; U# F& g+ i) h3 M) d0 S/ q' n$ D1 J1 b$ O5 G$ f
                // 取得混合器设备的指定线路信息成功的话,则
! m4 P% V& {' C) r; c& u, Y2 U! l. d8 Z9 y
+ X( M0 m3 k& F' `
                // 将连接数保存
9 G$ A/ e5 ]% J/ U* D+ c5 q                DWORD   dwConnections   =   mxl.cConnections;
0 |5 m( z7 e6 ?; |& C7 J6 N                // 准备获取麦克风设备的ID
( x' ?) w1 J" z3 [9 r                DWORD   dwLineID = -1;
' `! \0 ?: _6 |: Q" b                for( DWORD i=0 ; i<dwConnections; i++ )
& G; |: Q' D4 {* ]( z                { 1 ^$ g) |/ H; m- P  w1 F! K/ ^* N
                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
, B' {2 [  |/ h                        mxl.dwSource = i;
  u$ o; i  @2 c6 ^' I2 B                        // 根据SourceID获得连接的信息
4 ?3 [$ g" X9 s0 _6 a8 _. A3 Z3 A                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl, # }' K; Z3 M+ w8 @% _# P: p, d; s
                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); . R) T1 Q: }% u; W, ?* E
                        // 判断函数执行错误 ; T7 D; W) |1 M: z. J
                        if( MMSYSERR_NOERROR==rc )' X# t- O# A  W. @
                        { : K4 ]0 R( \/ H' @) ^
                                // 如果当前设备类型是麦克风,则跳出循环。
0 p1 K" L5 t3 e8 s                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
% B: @. t4 S  w1 V0 p) M6 O1 J                                {
- s+ f  R; w8 J9 p7 Y                                        dwLineID = mxl.dwLineID; - T( H8 ?- j/ A
                                        break; ( E! `; A* @: ]
                                }
/ C9 A0 _, Z* g1 Q. V: I                        }, I% n' G" y. S1 k( u6 D: G
                }. u6 x; b4 p! o
                // 如果没有找到,返回失败。 # V4 x4 T& g( V4 i( Z
                if( dwLineID==-1 )
0 q: c1 J( d" l) B2 ^                { 5 G1 `& W0 F, q. w4 p
                        //尝试其他声卡
6 O  u* H( A' G. ]4 s; S: \                        continue;1 U2 C3 g) \& ^! u7 s! f9 k
                }( D! p4 |$ \. e4 |. w5 p; I1 Z

3 X( z2 [: S( L, _9 Q/ A6 N: Y% |, z  {( D. S0 F6 Q
                // MIXERCONTROL 结构体变量清零  D) A# I- J, t! p- J' k
                ZeroMemory(&mxc, sizeof(MIXERCONTROL));
) d1 i6 j1 Q/ @# Q7 d9 v  ^% ~4 t/ O) V
. s  p5 I5 ~- H" j
                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本" Q4 I' d9 S6 S6 t) k! }! P& D

& G% R) S. u4 G9 g4 D/ F1 H3 o2 _
                // MIXERLINECONTROLS 结构体变量清零: v- X+ _" ~+ h9 u0 H7 f
                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
* k$ |* R, K+ i7 Y2 C7 F, V) g1 Z4 ]/ X5 M& i+ h, q% _
3 F# ~2 r/ w: \/ G/ V: R( q- y
                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本
$ @# q$ B% J( h9 N( P! k; L* C: [! a* c  Y  j3 V/ b+ a

' l8 Y: H6 M  p' M* D8 a+ ~                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识
* S6 l% n# |' s  _8 O( t                // 控制类型为控制音量
) T' @3 P8 X$ ?0 z# K% f                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;: P7 m; ?! B+ I$ z
                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数
) O2 j: G4 v$ I5 F* {                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针
- w- I1 k% n3 j: w5 t9 i- L                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小% w: P$ x0 c' A% ], z9 E3 q

3 @9 S; j- A& b& g, G. V$ ^* u5 x0 p/ ~! e
                // 取得控制器信息: x2 t0 ]! C% q5 O7 z( {5 n9 A
                rc = mixerGetLineControls((HMIXEROBJ)hMixer,# u4 ]* z1 {2 n: P
                        &mxlc,; E& K; {4 E9 k6 n
                        MIXER_GETLINECONTROLSF_ONEBYTYPE);
/ [+ k' |8 H" Q9 M  U+ [2 S
. K9 y2 U3 k) s0 [
* p% e3 O. P5 l7 P9 o, K' j/ R                // 取得控制器信息成功的话,则
3 W4 v4 G! E! o% _1 T/ t0 v                if (MMSYSERR_NOERROR == rc)
+ H' `+ R% j2 m3 e                {6 t2 b2 O( ]. S' o9 q
                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.! J% y7 }" D0 R& h3 u" o; @
                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
; f  ?' _( k- Y                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)
+ M9 a/ V8 V, q4 y/ a6 m
- `5 X) g* e0 O  {2 B3 h
' k- S( S" {7 _+ H3 \1 ^                        // MIXERCONTROLDETAILS 结构体变量清零
8 ~& l3 f( a: u. w                        ZeroMemory(&mxcd, sizeof(mxcd));
% Q1 z/ S! x: ^' ~1 T: b' u+ z; j
/ B3 O( ~$ T' B3 k9 g, x% Q: x
/ _) N9 a* h7 s; P& q7 V                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本
) J. i6 j+ t* z) l# f                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识
0 S$ q4 a7 w! c4 V                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针
( R1 E1 w: i2 W* L, p& |! m$ m0 w                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小3 p/ v/ x+ `' s  o& S9 S( O: V
                        mxcd.cChannels = 1;                 // 取得或设置全部通道7 \2 R& C. y0 w# {4 x

* O2 b4 g3 b8 x& R$ X2 r1 Q) ]& ?9 S6 M7 z9 p5 @, J& R; s
                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum. ) Q' F% N7 [2 F

( V  {: H" e/ i9 T' @' Q! C" f- x/ y1 [( }% F
                        // 获得音量值; m4 v, a+ {: U4 x, {- L
                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,
" s: t  n4 I; |+ w( U( y                                &mxcd,
4 p3 v1 c9 t  n" o! ^3 n( F7 b                                MIXER_GETCONTROLDETAILSF_VALUE);
+ O4 _5 P- K* J: j8 S+ @  S; N. ?  w( H" y1 m* E

' W8 [* B# D2 c1 n                        if (MMSYSERR_NOERROR == rc)& }) Y! |: Z& V7 i& O/ e& K& |
                        {
* \% D% g1 q9 y+ i                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;
1 E4 `. |8 ?( J% P* T
( y9 ^! `& z. n3 q8 m: _/ k0 N, X5 N2 F3 \' G7 n) l$ l- a
                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;9 r$ D2 H; z( l
                                printf("音量:%X", volStruct.lValue);$ B6 {: C% a& |; Q
                                return index;. @0 ~) N$ ]  Y4 T
                        }+ X# B% j7 G) f
                }
( y" _8 O' t0 x# O) Z        }7 Y5 b5 Y: F  y4 g" b# d2 k

; O9 M9 U# `: S! r1 I/ I$ H5 I  Z" o
        return -1;& r- e6 v9 X7 Q
}
6 ~. ^- s, v8 O& I6 ]; Z3 f# b% C& z0 v
        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html! i' a) B' T$ v$ _( w
                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-10-1 23:52 , Processed in 0.017125 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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