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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/7 U& `! h& F+ V$ K+ ^9 @

1 h  {: T; [- t5 W: s参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
' P3 V& y2 `$ t
+ F8 e# k3 J3 t7 d, M
( o2 K' Y* V' n; T2 Yint DeviceManager::getAudioInputVolumn( const std::string &deviceName )- p7 ~% x1 W5 U- r, E! y) C3 f1 A
{
  X! t+ ^5 I) _% g. o1 @+ s
0 e% R" t0 E+ B' h0 M' e) B$ n& g) ^
6 b5 J) @! a! Q" A1 k" g/ `2 @, C        MMRESULT          rc;     // 多媒体函数返回结果变量
: ~0 V+ g8 ?. i0 w! P( T        HMIXER            hMixer; // 混合器设备句柄, a4 _0 j0 ]9 [  y. o3 v2 ^0 z
        MIXERLINE         mxl;    // 音频线路标准状态信息结构体$ C, ^. c0 S, ]' e( ?
        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体
5 I) Z4 m2 f4 S' p+ L# _- M: `, w. ^        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
% o* N9 w* U2 o- o' h% R1 j% E$ S) ?9 F* ^

9 E) r) R# j) x3 [0 R        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即$ X8 e; e6 M0 X, A; C
        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
" V8 m% f0 I9 z, T/ p9 X' ]       //可能还是跟声卡驱动有关。7 Z, }) y+ M# I" }  l
        for( int deviceID =0 ; true ; deviceID++ )1 u% V2 w6 A/ G  V- M
        {
( e% g  d/ d7 G: X4 I; D                // 打开混合器设备
* N' Y$ R1 i- S: ]  H' [                rc = mixerOpen(&hMixer, // 返回的设备句柄, Q3 g& {! G4 J
                        deviceID,       // 单声卡的设备ID为零
% i( a6 \; _; j3 {8 [( n5 q                        0,       // 不使用回调机制2 L" h' }: `. F; ]4 c. O
                        0,       // 回调函数参数
5 }) C& o: }5 I5 j  E                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID- a' ~2 b% }1 G( m7 L
                if( MMSYSERR_NOERROR!=rc )
  \4 ?7 a# B& F) z; t# ~; E                {* R# G! ?2 s" _( W
                        //跳出循环
; Z* w5 \3 b/ Z% h2 _                        break;
0 S; ]& U! K* J4 `$ Z6 H$ h1 R! Q                }
; j0 I* ^4 j. |: x. P8 s3 n                // 打开混合器设备无错的话,则
7 m% |) Z9 g8 H8 U3 B; l
+ W8 H9 Q0 q* m9 ~* j$ q& T) |$ b" q9 e
                // MIXERLINE 结构体变量清零% i0 A0 j1 }& [' C! c
                ZeroMemory(&mxl, sizeof(MIXERLINE));
9 F- l9 c2 R" w9 \& u& B. {$ U5 i$ z# V, {: R! L

1 I4 U8 X! i* Z. M, e                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本  _9 D6 I1 O; ~( a  a. i3 I0 ^
                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
7 r/ n3 N% x; K" i! H                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;2 k: m7 n; ~4 M6 i* x  Z

, M; ]2 A9 m' g# x- y1 J4 x6 M/ e* I. n. `' H: b
                // 取得混合器设备的指定线路信息" {8 d7 e0 B9 p" O+ }
                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,8 ]0 D! _# ?1 [" q
                        &mxl,! S' @3 N. G3 y
                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息
& b+ i1 ?0 u% D' J- s+ B+ X                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
! P" D* K& U! `1 j2 F                if( rc!=MMSYSERR_NOERROR )
' ]. |* ?8 b" L7 R                {9 u8 H2 l1 i6 M- z
                        //无法获取声音输入线路,尝试其他声卡
% [2 L8 [' E, V                        continue;8 a# B9 M0 D6 E/ ~
                }
4 o( T0 u' v/ s" U2 G9 V) L* G9 G( @' [. R1 a( A4 B

6 k) {5 [/ }: N# X7 Z" v& S2 e& C/ E1 D                // 取得混合器设备的指定线路信息成功的话,则4 b3 G3 G& s. q2 Z, T* [' f
1 ~6 Y/ k, |* T1 ~; ]8 Z, F

( G; v2 {0 ?- U/ F                // 将连接数保存
4 q; _" G/ y: o" m7 a! U+ c* e) q3 o* A                DWORD   dwConnections   =   mxl.cConnections;
# v& D1 }. o) m                // 准备获取麦克风设备的ID 0 U" j$ g; R/ @
                DWORD   dwLineID = -1;
5 U& _; |, J$ i4 S1 [                for( DWORD i=0 ; i<dwConnections; i++ )4 b! M0 e$ P# `
                { 2 S7 u, n* m% S
                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
. |% t5 }' n$ R! f0 P: J$ I7 c% y# D                        mxl.dwSource = i;, y; p! O8 s( [
                        // 根据SourceID获得连接的信息
5 q: y; e+ |7 n3 p" w" R                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl, - p7 d" m5 e( Z- S- [  G& I8 k3 y  e& w
                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); 5 d1 b1 F" v' _& J
                        // 判断函数执行错误
4 [1 |4 F: ^/ w5 ?                        if( MMSYSERR_NOERROR==rc )) E5 b/ O( O" x: v. p1 l( t7 v& \
                        { % ^$ u& e8 a9 }* t) M
                                // 如果当前设备类型是麦克风,则跳出循环。 2 U# C" N: N0 U. [! \& T0 e  m
                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
0 r, I) \3 ^: }8 E# c7 g# x1 t                                { ' A9 u6 [8 a7 t' D& v
                                        dwLineID = mxl.dwLineID;
& s- H, @) T! X1 f                                        break;
' |& y* W4 C) h& M- \1 c+ ^& P                                }
  w- h9 q' I9 r' O2 }                        }
" L, T' @/ N, O2 {( r' M# b! p                }
- Z0 A* d! P, f: l. E  w6 H                // 如果没有找到,返回失败。
+ X& {0 E& e# _: E$ T                if( dwLineID==-1 )
. k+ X1 q- {8 s, G  q                {
$ `0 y8 s& b4 |, u# E0 A; ]                        //尝试其他声卡
% T7 q1 p& e: Q                        continue;+ @' D5 P- G3 g  {& B
                }& f1 c% \# ~  t) i

5 ]* a/ H7 `$ h0 A0 d9 `
0 x7 O' O- x- ~/ `7 ^7 M. T                // MIXERCONTROL 结构体变量清零# _) J4 O2 o0 T8 |: e# I. s( D1 ?  w
                ZeroMemory(&mxc, sizeof(MIXERCONTROL));
' H' ?: L) k- ]" U0 K
7 a* Q7 o. [3 H  t
2 _1 ^5 [( Z5 i# O% f# C; z6 Q                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本  l$ i! H* w" U& w4 E* g# t

0 v, B$ L. t, t; f: T
4 s, h9 f1 U2 i$ N* r                // MIXERLINECONTROLS 结构体变量清零+ D3 T& I* r. ]- g8 d
                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));" u# g3 \1 M$ ?2 a3 H

( F  a1 u& D' [; M  }9 s7 E" ?$ c8 [2 }3 n  K+ y( p
                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本8 J. X& K- ]5 w3 Y, l1 f

' K" n8 E% X! C; k
- I$ @/ v5 Q# c7 B4 P                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识* p4 w  |6 G+ o" Z+ ~7 @- d" B
                // 控制类型为控制音量
% C( B% C+ P) e) H$ m                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
  f0 c  D' Y0 \6 Z                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数
7 }: V8 a0 l4 q8 g3 ~                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针( L7 ?) ^9 W% Y
                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小
4 n$ T* I6 j4 y7 q9 w! i+ J0 R$ \# d3 Z

0 i4 A- e; h# O+ H6 b, H9 n                // 取得控制器信息  ]) M' B) R; l6 Y
                rc = mixerGetLineControls((HMIXEROBJ)hMixer,3 x2 f) O. ~! q* e5 I
                        &mxlc,9 n; J0 d' D, I8 E! f! x. H1 \+ R
                        MIXER_GETLINECONTROLSF_ONEBYTYPE);6 R7 T' V" n8 y
0 S$ b& N& |% ^# H  B' z

6 G4 R3 f) _$ z- D2 U. L6 ]                // 取得控制器信息成功的话,则6 s* K, r0 H/ [
                if (MMSYSERR_NOERROR == rc)
( O3 q. N5 Q/ }& b# Y. E! c                {
4 s1 k( Y- s6 ?+ w                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
. q5 J, c/ z  w* Z4 y+ K                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息5 T( g" Y% W+ r4 A
                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)4 a3 O( M3 K* F$ w' m0 z3 }
9 w7 |, v* W% E3 G# Z* f! f. x
# a! n9 [( R( p  K. ?- `
                        // MIXERCONTROLDETAILS 结构体变量清零7 q+ O! Z9 _; r9 ^- |. I
                        ZeroMemory(&mxcd, sizeof(mxcd));) y! c) `# l) d0 D; S! G3 o
; s# ~" R* f& ^0 ^. W

8 i$ H$ i# p) y! \+ r6 j, y! m                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本0 [9 G, L$ L6 }% L# N
                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识
7 }% u- J8 B) m                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针
0 r' I+ L& d5 N6 A+ b& ~                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
: _+ e4 ^' @4 _0 s                        mxcd.cChannels = 1;                 // 取得或设置全部通道
. M0 O' N. s% e  U4 a! H( w1 Q
4 |$ M( S! _; H+ ~- P9 a: r. z: j
                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
% Q* i) o7 }, d% Z5 v" K# h3 }1 d' n. m/ o% d. y; n' I: i
& l1 m4 r" y" Y% y( h2 g. G: U
                        // 获得音量值
3 V# a1 X) @6 ?& d1 q2 ]                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,
) r( U( ~  \) O4 r5 j                                &mxcd,
1 A' M9 y) L4 P! l                                MIXER_GETCONTROLDETAILSF_VALUE);. L8 g8 l2 v" @7 S  A% U% ]% A$ ^

$ G: j) O$ m4 J% l9 _- D+ [; r7 ]8 n) Z9 r' V% R! I3 p7 u
                        if (MMSYSERR_NOERROR == rc)8 y; D& O2 U; S1 o# r" c$ O
                        {
+ s# s# A. V/ f# b  s' J( d& ~                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;" }+ J: x1 _5 Q% |1 u

7 w( ^2 C# @. W; f5 u8 r
! e1 o9 Z2 R# s# O% J- U8 `, C                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;( Y  S* L; {5 }5 h; m
                                printf("音量:%X", volStruct.lValue);
- Y) N9 Q$ P4 A1 r# r& M                                return index;5 J9 e! M1 K1 F% h) u# |% r
                        }# B# w$ b1 X0 J
                }
( ]& c8 |( l4 A) c, G$ ~) X        }
; R* q* p2 r& [  o  g2 Q+ ]0 D3 n& O& K
* W4 N* k( n* }+ S7 o0 D
        return -1;: X3 E  d! K' I1 t1 B+ z6 I
}/ W; N' v7 A) ^4 U$ p2 g( I
0 z5 y: `0 H: c% }) s( y
        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html
3 j) b7 [* A! O+ H0 }: l                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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