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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/* \; z' e. L3 R" q7 K! }- n0 [- J9 E

; ]3 f7 @( A( R0 ?' {& b参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:3 M" z( Z" t; x/ ?2 F' l0 y; q

% f+ L( C# R' T$ E4 Y& k1 x/ I. u7 e; `  f, v- F) J7 }
int DeviceManager::getAudioInputVolumn( const std::string &deviceName )
: Q9 O  Q. F3 ?" y{
+ z) C6 C$ f. @& T0 C7 F  r  t6 H( r3 B

! h& X( S. T; {8 o- z( S/ X        MMRESULT          rc;     // 多媒体函数返回结果变量
9 F1 C2 {3 Y% e. f% X7 R" |3 C        HMIXER            hMixer; // 混合器设备句柄
6 K6 O* h! D; j+ m# i        MIXERLINE         mxl;    // 音频线路标准状态信息结构体3 h  B& H7 |; ?# g9 U7 u
        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体
  |$ p( W* J0 N. Q8 C! f        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体( J  X- u$ Y, s9 T* z7 _+ s
/ c" B3 Q' @7 f, B: q! J
8 u0 ?1 W; l: i1 Z4 R- ]4 G
        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即% L, F( L% ^  N3 S
        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
/ J1 ?0 O' _$ }3 ]% r       //可能还是跟声卡驱动有关。
( A* F& U+ h' T        for( int deviceID =0 ; true ; deviceID++ )
- `# [7 n/ @( W" A$ ]4 h        {
! }5 T7 u5 x* ?& h3 B' P                // 打开混合器设备5 U! U9 N- L3 }5 P1 H
                rc = mixerOpen(&hMixer, // 返回的设备句柄0 J  D! o+ N, k/ }( ~
                        deviceID,       // 单声卡的设备ID为零5 P1 X9 k9 v. W9 X% [
                        0,       // 不使用回调机制# x6 A# I6 H' m* R" U* s. t
                        0,       // 回调函数参数
  \% }) y: }+ q# F" [                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID& O  ^* `0 r$ x3 Z' i# [) |) V
                if( MMSYSERR_NOERROR!=rc )4 P& X3 s+ L3 c& a$ A
                {" M0 m  v1 [8 z1 s
                        //跳出循环& W1 B$ r! r7 n6 n. B# O
                        break;
; Y9 r/ q& x7 x. b1 g0 g                }2 m5 s1 j3 S  D4 i- Z5 ]1 R+ a: i
                // 打开混合器设备无错的话,则; S- M9 B7 _& O1 Z
6 \3 l, R' t% d! g. \9 g6 Q
+ b7 [9 S+ a: M" s$ q1 N
                // MIXERLINE 结构体变量清零$ e: o$ p. Z3 c1 \( e
                ZeroMemory(&mxl, sizeof(MIXERLINE));
2 T6 E- x1 O+ r$ `6 o. P: `# x& X/ D1 m

& N" z) x/ E$ W2 ]% I  _                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本
+ w8 I  p6 g& I* n% g+ R( w. O                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
8 L+ ~% |+ }# {( g8 h' |                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;  b, y9 z7 \8 Q5 Z6 w3 s* i
" ~& L' l1 n+ ?) q! Q$ k7 s

0 W$ U! k1 S# Y% Q                // 取得混合器设备的指定线路信息1 a/ O% i6 ~( D) v6 R; H
                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,
: a5 `& V3 x" k                        &mxl,
/ {1 E$ D& d- L) R7 P                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息7 ~" I7 K+ t( w! s4 r
                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);) \+ X! R: _, @4 C# ]. q1 H
                if( rc!=MMSYSERR_NOERROR )  W, B! R$ c' w' X1 t  S
                {
. ?' S- b# Y: r  j                        //无法获取声音输入线路,尝试其他声卡6 }2 _$ `1 \1 ]1 ]# P5 p5 l
                        continue;( g* }( {1 l' t
                }9 \' A6 I0 Z2 f: q

4 }. I4 B) {* r+ r3 B4 \
. k! t" C; Z0 T9 h1 A! j                // 取得混合器设备的指定线路信息成功的话,则
( z  a3 y7 k  A* w$ m; p, n1 P9 I5 j: M! h! u. t3 H0 X# A  A7 R' d
# j5 f' i. z9 q
                // 将连接数保存 ! T, B. k' b& d  e; R4 O
                DWORD   dwConnections   =   mxl.cConnections; + t) W$ |3 `- S8 j
                // 准备获取麦克风设备的ID ' ]4 {+ E6 G! z6 _% E1 n; b4 M, K
                DWORD   dwLineID = -1; - G% Y, m# J& v2 E6 D5 D
                for( DWORD i=0 ; i<dwConnections; i++ )
5 B+ w9 @0 s0 Z  Y8 e8 s                { $ o  Z6 T% h; A( O6 U9 g& T* Q) e
                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
3 l- r' T$ l4 W' m% h                        mxl.dwSource = i;- p* g3 w$ T/ R7 Z
                        // 根据SourceID获得连接的信息
$ n  x6 t/ h3 A0 c. P                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl,
8 E  L5 l! n6 @- B- ?, ^$ d+ }                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); + M' r- L! @) y! _% ~5 B" N
                        // 判断函数执行错误 % x1 I  i) e* a1 D/ a# R) L
                        if( MMSYSERR_NOERROR==rc )
, R  g7 L4 ^( S$ y5 y* J7 @0 _. d                        { ' `. c* S& j* G; E) v4 u
                                // 如果当前设备类型是麦克风,则跳出循环。
; k; T. D' n! U$ N                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE ): t8 T1 n. O. v; @2 M( R! X
                                { ' `/ G& X8 o' `* [; P3 J; F- r
                                        dwLineID = mxl.dwLineID; 8 M: r. ?* S1 n4 [
                                        break; 2 \' W4 o* f9 m! E+ g( E/ ^
                                }; x8 {5 I* M5 a, n$ w+ O, T
                        }
- D# [) v, l  Z& Z! ]                }
  z& C. A3 L' ~6 w2 g) @- J( }                // 如果没有找到,返回失败。 , V8 ]+ S, @1 D7 N) u% g
                if( dwLineID==-1 )" Y5 N9 S5 e6 x( G& t! {0 n
                { 7 R( b) d, Q: o* u7 h5 Q7 @
                        //尝试其他声卡; S  X) r+ [) \# B2 N3 F; E, I9 A
                        continue;" ^2 K+ u$ s! |/ m
                }+ z' k* A1 I3 z1 E8 p; D* S
& y2 {+ k2 y! s( t/ y

1 g4 v, H, g( m. `! p' j: ~& d                // MIXERCONTROL 结构体变量清零3 P* l( ^6 d6 H* ^0 k
                ZeroMemory(&mxc, sizeof(MIXERCONTROL));- Y' _) r1 ~3 l" X- x
% R' c( b$ _8 Y$ r, v+ s; [6 p
3 \  l1 {0 x: o, w8 y+ U
                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本
/ o# p1 L  m( M* `* U0 C8 f/ }/ L2 E9 d; S
$ C0 q$ \! D& M' y% g6 y
                // MIXERLINECONTROLS 结构体变量清零. e# {+ Y8 h% c4 P+ K# q+ S
                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));1 T7 V2 x2 z* g
. o7 S/ c. L; t! n3 J
. q1 V. G+ R0 J. ~# L
                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本
+ _( |1 K6 L# z& C2 R2 S
' {/ f: h$ d# y& V
1 V0 P3 [4 _7 H9 ?9 m0 y! l  L                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识
  p8 X0 M; z# ]                // 控制类型为控制音量
6 |: U- \" ]7 t% G                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;- w$ k0 F- `9 l8 V+ |
                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数" b5 k: e! U7 i0 \) k
                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针
, w  j2 s& d0 K: m3 ^) i0 S  J                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小
/ \) P- x4 y8 ]! `
4 w5 a/ T2 \$ L( N6 h& i- t- M) y8 Y8 r$ x/ x+ w
                // 取得控制器信息- N" ~! O5 K8 {6 p! q- U
                rc = mixerGetLineControls((HMIXEROBJ)hMixer,4 M/ m3 x4 y. I) W! F3 Z5 r) z
                        &mxlc," r% e& f" c* `; c1 X
                        MIXER_GETLINECONTROLSF_ONEBYTYPE);
0 \. r6 g% Q, N: e9 P
" b9 A( M+ F: h9 k+ p6 ^
1 ?0 |( d. b" W# F                // 取得控制器信息成功的话,则
/ h  }! A! X3 j: p7 U                if (MMSYSERR_NOERROR == rc)
0 C' h0 f$ P" d/ z) h                {
7 O# u* _% M& m$ t                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.( n1 A' X. }( l; @& _7 c- @
                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
+ b$ G! d3 }& `                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量). n8 p; Z0 t) c* e* K

. G, H0 _: A6 ?. {3 T
8 _% V7 Z& V. I2 m7 V                        // MIXERCONTROLDETAILS 结构体变量清零
/ ]3 k( p6 {% y5 _1 H                        ZeroMemory(&mxcd, sizeof(mxcd));
1 I! j- s1 |: j, l9 L9 c0 v0 H. c/ d6 g* B6 l& ]! X2 K

4 k- N, N6 ?  e- `, [7 C                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本
$ p5 l/ a6 J& a' b                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识3 a( y  T' M! h# ~% A
                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针) j5 F& a0 F; e' n# r
                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
+ i8 ]  g9 G+ @# Q                        mxcd.cChannels = 1;                 // 取得或设置全部通道6 y1 E6 m7 h4 {$ L( X8 ~  K' v2 p
  ~% n" `8 Q' n2 r$ x

- {# z2 k# f# U1 y0 I7 K1 N                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
% Q9 U) q" F% o% t4 v0 l
% X( V# Q) T* ?  K. J$ o, @* t' G+ u( M
                        // 获得音量值
! l+ [; W7 Y; z) ]* s# @                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,) I& e' Y2 x; a$ j4 E! p
                                &mxcd,
* T7 l5 q/ b- H4 N1 r! x                                MIXER_GETCONTROLDETAILSF_VALUE);9 g& ~# k# G0 i+ A4 ?

7 i6 m$ j0 a9 W6 h# ?/ S& T4 O! J( w+ h- T
                        if (MMSYSERR_NOERROR == rc)0 D1 Q; q6 W3 K( U% W( R5 h
                        {
( A9 ?8 q; d  e( B* j                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;
+ N0 i, d# c# Y  c/ r, _7 V) d
+ O8 `$ C& @' ], T, W. {
5 b, O9 ~; m: [2 n                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;. O" W* `" n* n% m  |
                                printf("音量:%X", volStruct.lValue);
/ E% m1 [7 K0 B9 M3 V  L* O                                return index;& t; u4 `, [9 R* \2 ^' f. G, B
                        }- d- j7 Q. H: t+ w
                }6 D# a. `3 `. H) n3 M, Y
        }  d* E6 K1 J5 u0 [, G0 _

: _+ W6 E$ D* d* b) {  h7 G
9 T5 s, M; r- @$ t6 r- u        return -1;1 W+ r6 z) L1 X. m1 T, _  E
}, D. n, {$ q. [
* a4 t7 b& N! {
        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html$ c5 Y6 w' }3 `" i+ V
                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 07:38 , Processed in 0.017351 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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