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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/
+ r# h% ?8 S. ?+ O! x
& j9 |3 _3 D: L- S4 m7 K7 }  {参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
4 r! N) j$ V% C) q
: \. ^6 s4 i0 a( g1 H; W- x0 A" m2 G
int DeviceManager::getAudioInputVolumn( const std::string &deviceName )9 C6 J# a/ R. i+ ~& D3 [7 W3 d, c3 U
{
2 \$ A4 t& u' S  O  e0 s
$ U( n8 k3 O5 m* X  ?* \, \, ^+ Z$ C# p: ]
        MMRESULT          rc;     // 多媒体函数返回结果变量9 |+ v* ?8 I9 K2 J/ P
        HMIXER            hMixer; // 混合器设备句柄( b( J& L  Q, L+ Z3 M, ~! y2 V  V
        MIXERLINE         mxl;    // 音频线路标准状态信息结构体& }4 A8 w3 |! F
        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体
8 j3 N) [" S9 \; m4 M$ N: k        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
; z' x% L; Q! ^) a) w7 N5 Y' R+ d' y% s/ w" q

: M: t. a! q/ m5 D8 H5 t        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即7 T1 g" g$ d  y$ J( d
        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,. u9 z" K3 F; _' y5 \7 N2 _! k
       //可能还是跟声卡驱动有关。3 h( u" J/ v3 R! w7 U8 |) D
        for( int deviceID =0 ; true ; deviceID++ )& V; A# F* T! l
        {0 e; Y0 q. g6 ?4 Q, x
                // 打开混合器设备7 f% C% w% `. j8 B! e
                rc = mixerOpen(&hMixer, // 返回的设备句柄$ `& d7 W! {1 A$ B; |
                        deviceID,       // 单声卡的设备ID为零
+ p% W& B. r: T/ ~  z$ H. L# ^7 g                        0,       // 不使用回调机制
/ [& ~. v4 p) ]* p  H% Y$ M                        0,       // 回调函数参数8 `2 J6 Q  ?+ I; N3 t4 W5 [: J
                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID
! L  x7 [2 f' a+ L! g# P- Z9 `                if( MMSYSERR_NOERROR!=rc )4 r, Q$ D0 {  ], k8 ?) a
                {
4 k$ e: F* o' v% u8 K& G+ T; z                        //跳出循环
2 X4 Y# K- V% v' J) w) S                        break;3 H7 Y/ e- A3 R) l' R+ Q5 S
                }# M+ ^+ F+ E: ?0 k# B8 ^5 [/ L
                // 打开混合器设备无错的话,则
) b+ H& R4 V3 W; Y9 L: }5 c, k8 f$ }8 {) Q& G+ Y; D

* i4 j. A7 Q/ a                // MIXERLINE 结构体变量清零' o& A' ]# {3 ?! N* j8 K5 r
                ZeroMemory(&mxl, sizeof(MIXERLINE));4 G/ J: [' I# _0 W% F2 v
6 r' N' m: N, ~) C4 }
6 R$ F5 ]  o2 f& d% k1 ^9 ^$ S
                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本1 [; ^. |; b  {9 p8 |- |
                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
8 S$ `8 B$ t$ O- M                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
( G; ~. g4 R3 Y" D. F/ w) n8 x. g4 F7 M4 H
4 @0 B3 W1 x" I: C/ a
                // 取得混合器设备的指定线路信息4 y$ R+ v0 i  `# ^/ r
                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,
$ ]: d2 W7 k$ D0 t: C0 o( _                        &mxl,
: }% n/ e$ E7 Y) v$ A9 a                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息6 N0 o% l0 ^( k& I
                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);! p2 K. ~) S0 Y  f3 U
                if( rc!=MMSYSERR_NOERROR )  {$ J5 |. {" |) A8 ^4 }1 b
                {  d: ^# e! C* I; {4 A
                        //无法获取声音输入线路,尝试其他声卡! B7 G" M) g8 I5 h1 F
                        continue;- D; X9 A" i2 {3 [9 Q& g
                }9 o% _4 O2 s+ D9 Y/ Y

0 L- {  x* n" [; z, w. F
/ j. M! A& V- j: `; q& R* W: q                // 取得混合器设备的指定线路信息成功的话,则
+ d4 n& Y" t8 Q8 A+ ?
& ]5 I: ?7 b5 x# m
* \+ Z- G0 c/ Q* ?. K$ f( Q                // 将连接数保存
  B0 ~% s3 c. ^( v2 V                DWORD   dwConnections   =   mxl.cConnections; * n; b. Z5 q: {* F( b
                // 准备获取麦克风设备的ID   E0 d; U+ N; ~' Y
                DWORD   dwLineID = -1;
0 T* _! n% j# }- h6 G                for( DWORD i=0 ; i<dwConnections; i++ )
; o5 s$ m, s4 j, I* ~! L' F7 C$ v                { * i' D. K: T) {6 u
                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
1 N: z) ]  g- z4 M. p4 w, S$ R                        mxl.dwSource = i;
6 r# u% h7 }  ~0 w, L                        // 根据SourceID获得连接的信息
7 O+ Q6 k+ P% {                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl, 2 Y+ x4 g2 J8 E
                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); ! a6 g' {0 Y% O& L+ X
                        // 判断函数执行错误
( f( t( @2 m( u2 K. t, R" c4 X( A                        if( MMSYSERR_NOERROR==rc )9 D& ^2 Y+ H+ D0 c4 k
                        { , ^2 ?: m1 l( p- Y
                                // 如果当前设备类型是麦克风,则跳出循环。
/ n% x- d- I7 P                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
0 r! J1 ^+ h# j# ?- H) J                                {
# c0 u3 n5 ?& }' }7 ~8 E# _                                        dwLineID = mxl.dwLineID;
7 o1 @& z+ {$ d  `. N' B- d                                        break; 6 O$ t% |' u! ]) q
                                }
/ z4 \" _' I. i                        }
" a- T" L4 G" W* V/ u/ K0 d                }& c2 a, n; ~; [0 e
                // 如果没有找到,返回失败。 5 }9 _" l4 p4 i3 _7 Z6 E
                if( dwLineID==-1 )# \0 Y0 {/ i! R8 q% z/ n
                {
  ^# j- G+ y9 K) W                        //尝试其他声卡
7 o' M: u; {2 q, f5 B) A                        continue;# ^+ b8 G9 e, @$ V% T9 z1 @" g
                }1 |' Q, J9 {) K+ L5 p

; S* a5 `) e# b* f) }1 l' Q0 w0 c1 L
                // MIXERCONTROL 结构体变量清零
/ B% o$ ]3 g( _+ k, ^                ZeroMemory(&mxc, sizeof(MIXERCONTROL));
) I4 ^+ C( P+ s8 I) U5 g# d
, G$ f7 ~- f* ~( H; F9 @; M6 D. r, @0 W
                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本, p5 J$ A1 ^$ ?, U& g8 d

) K9 z2 V8 x9 W& Z8 K
0 |  e, ~5 d5 Y; C                // MIXERLINECONTROLS 结构体变量清零
' B+ i& H* t8 n0 J+ R5 F                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));$ C' Y6 @, |6 n  O5 |) u

# `& i. q) f: f: m! E& k( }
! Z/ L  g; g3 r# ]                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本
4 K$ y% [/ p$ K0 {6 P/ e7 x: g: o/ `( o9 Y: q9 `* m% F' c
  P3 w% K9 j" ?3 e/ e6 C
                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识3 Y: L7 U1 W1 D! P5 W* F. u
                // 控制类型为控制音量
: Q# g9 A% t' n2 Z                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
% @( [1 Z" ~/ y                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数  P+ i0 s% y8 F* q3 u" v* K' O
                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针0 V! y5 `0 n: C% r+ o' O( z
                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小- I8 G* z  s% c, I1 Z0 C

. n% _6 Y* K$ k# y/ r
$ N! y- A& \. f( O" ?% y                // 取得控制器信息
5 e: Y+ S, y/ t. B; |                rc = mixerGetLineControls((HMIXEROBJ)hMixer,8 E$ X* A! Y  l6 m7 y/ [, s# _
                        &mxlc,/ d4 D& w6 U" f* F
                        MIXER_GETLINECONTROLSF_ONEBYTYPE);
* d2 f6 F+ n: f
3 m. C& o: O4 @' [; b( `8 n" g- P% a+ S' Z: Q3 }
                // 取得控制器信息成功的话,则( l3 c" o' p$ l: N$ w$ N8 d
                if (MMSYSERR_NOERROR == rc)1 O8 B: V+ b( r
                {3 e  v9 E8 o4 c) \0 q3 b
                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
1 B. ?; A$ s5 E# ~# Q                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
, M% X1 t& p8 l5 m, M, W7 I                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)6 o) O6 d& x* p( e) q" V

" r9 Y% R; \0 k. {+ v9 b1 L- B: [7 F5 ]" B9 d8 T7 b9 r" b
                        // MIXERCONTROLDETAILS 结构体变量清零
. Y/ a9 J, D4 }' l6 s                        ZeroMemory(&mxcd, sizeof(mxcd));) x6 b- P9 u; @5 @5 V1 ]
' `9 S; F* C) O
- J+ e% x7 t0 p1 A  d& h
                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本5 s) {' G* i- d/ M# M& q
                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识
, N' K# v! s; g# M( N3 c0 l  r6 m. Q                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针
& R. ?4 V6 B2 J6 ~# \+ w                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
% o+ g9 m( n- s- K% y                        mxcd.cChannels = 1;                 // 取得或设置全部通道% J1 m6 d8 ]5 B" i

9 U% f+ a: B9 Z9 z, f( x( D. j# z# O% K$ E$ t& y
                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum. 4 p9 B/ Q4 V# y

2 Y* ?* u3 X( T+ Y: B5 E& m- P
) y7 X2 P* z$ W* I( w6 {1 @( S+ z                        // 获得音量值: m9 H& J0 A0 }9 q& G
                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,
9 P) y, n- n) j2 }                                &mxcd,! q% \9 z3 q7 R  e6 e8 D  y5 ]
                                MIXER_GETCONTROLDETAILSF_VALUE);
$ Y* N0 P' {) O- B; e# n% z/ ~7 j  P8 {0 C
. r2 z: C5 j2 ~, w4 k. ]& ^7 C
                        if (MMSYSERR_NOERROR == rc)- E+ c' }" s2 S. _" O" u0 z
                        {0 G, q& F! s: a) w! y# }
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;7 w( q6 p, \8 b7 i
8 G8 C8 \( w/ `- X

$ {3 @( S' M% i$ S: l8 A                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;" \" ?* U8 v. L; p% _( F3 W
                                printf("音量:%X", volStruct.lValue);" }! z: ]( a' ~+ g7 b
                                return index;
* l! F! ~: i9 B% T5 e                        }$ i* w" c" J" w1 a+ b& r
                }
; n1 Q0 p- U! c2 g; F        }# d+ ]' l1 l8 i  e
' S; ^: m# k9 l; o# @$ t

0 X3 l, ]1 D0 p0 m        return -1;0 |% f, f4 F9 O" o# C! b8 n6 y, X7 F
}$ R) O( U4 t1 j5 L0 r
5 p" @6 D# i- f. l
        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html4 b! g, \/ v  C  q/ N2 y+ D8 S
                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-5-5 03:25 , Processed in 0.015015 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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