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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/6 n! m9 q5 h, t1 n0 H
  a9 r9 R5 X( v
参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
4 u4 F$ W& |* c1 p1 X+ J# g4 z. [
+ l1 H' u- \2 o
! S# n# N. k* p! Rint DeviceManager::getAudioInputVolumn( const std::string &deviceName )! M& q2 r, l# P6 e/ Y% o
{: U. P( I9 u8 ]
/ p9 n) t& T$ W% a. v
' A* D# w4 x0 B( E- [; ?, P6 C
        MMRESULT          rc;     // 多媒体函数返回结果变量
+ n4 Z! s6 C6 X5 }' [: l& ]        HMIXER            hMixer; // 混合器设备句柄
  g, ^) z0 B9 G$ |) j1 Y4 }+ ~        MIXERLINE         mxl;    // 音频线路标准状态信息结构体% |! Q+ v7 x2 C8 U
        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体
" z5 o4 l  l- k( q        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体9 E" v7 Z  x1 l5 K+ R

2 }3 Z2 }" ^. W# ?6 L2 s
) m) |8 M" f: [4 d1 w4 }" C7 b. {        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即
0 @. c$ ]3 |7 Q* r% c9 x        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,7 D1 t% ~+ A2 ~( t- _  {* q
       //可能还是跟声卡驱动有关。1 ]0 m+ H! p, H7 a1 [
        for( int deviceID =0 ; true ; deviceID++ ); \0 O  G' u- Q( V
        {1 i- a7 v4 C% E% U$ c
                // 打开混合器设备4 E$ j  w8 t7 t9 ~% p
                rc = mixerOpen(&hMixer, // 返回的设备句柄
+ _9 K1 i: \  a! W                        deviceID,       // 单声卡的设备ID为零+ h$ c" u/ ?0 O
                        0,       // 不使用回调机制) M0 ?6 B; D, I7 m( ~2 ~
                        0,       // 回调函数参数9 ?( C0 g! e5 J/ V- o6 Y
                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID
7 o2 T& M1 H% R" g) v                if( MMSYSERR_NOERROR!=rc )
. T7 H8 G" j: b. l; }* I                {
0 ]: w# t2 O1 D' t9 o8 W  x' Z                        //跳出循环4 w6 C, l; }& m4 ~) }
                        break;  A9 \) S, ]# o3 o/ B8 T/ N2 k
                }
" S  N/ E2 y! Y" r" q. H" r                // 打开混合器设备无错的话,则' O' B/ U1 q6 }. q: \! H5 K

/ l4 ?9 Z* @* ]7 G" o' O3 ~
0 R: t; _# |; l5 ?3 g                // MIXERLINE 结构体变量清零
9 V# R- q4 j' H; v: F) z                ZeroMemory(&mxl, sizeof(MIXERLINE));4 w& O8 G1 p; A6 Y* ?8 R

* d5 l! }6 H* t0 c! {* N2 z7 ]5 L. Q* L3 i7 {, E
                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本
/ D# i8 Y! A! h9 o6 V* f                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
" d9 D) k( R, y6 Q2 I" I7 c                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
$ G* X+ k7 @* Q* g& o
- e+ K) I6 B  U  w, j( x! E$ L3 h% }% v& K
                // 取得混合器设备的指定线路信息
: K( p7 c: ?/ l0 L                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,
) |1 f. m: c  L8 R) Y7 A6 c( ~                        &mxl,( o& w  I: G( l
                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息+ f& d' |5 F; f" \0 A2 \; @4 s
                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);* e. U! s6 z; ?5 h) o& C
                if( rc!=MMSYSERR_NOERROR )
+ ~  K; C8 Y$ H5 \                {
9 L4 a' ]+ s* z% ]                        //无法获取声音输入线路,尝试其他声卡
1 D% V5 o; A, s/ @                        continue;
6 T, P: s0 R- C. b. K% }                }; r, a. S0 V9 D  v7 `+ E5 f

" n, {9 H! w7 _- n; n3 L8 I* A$ [1 Z, V3 o; k/ U# ~9 M3 D
                // 取得混合器设备的指定线路信息成功的话,则( ?, y: @+ O( o% w) f

+ y8 G, S. s4 x) W4 }# z; I$ t9 ~! r1 h
                // 将连接数保存 $ A" v: u6 j; V; g" @
                DWORD   dwConnections   =   mxl.cConnections;
  a; c7 h$ C6 \9 \$ H- v                // 准备获取麦克风设备的ID
& O7 U+ T. h: h/ m' B+ Z                DWORD   dwLineID = -1; $ p$ z6 B0 p0 ]& d+ t
                for( DWORD i=0 ; i<dwConnections; i++ )
6 ~4 ~; [' C% y& y. C5 N" R+ q2 N8 h                { 1 I& G+ n; s5 _/ ]2 O4 c3 Y
                        // 枚举每一个设备,当Source的ID等于当前的迭代记数 ! U- ]: X( X- i& u( |  U' g
                        mxl.dwSource = i;
: @2 Y/ ?+ D/ ?- k! M6 N) d# J3 P6 \                        // 根据SourceID获得连接的信息
0 D, p% G. C; w1 N/ m/ C; K6 Z                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl, 9 |8 j% H1 c( d& Q8 J' y5 n
                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   );
8 W$ B: R3 V( n$ _                        // 判断函数执行错误
/ M# V) Y% Y4 k9 n) @                        if( MMSYSERR_NOERROR==rc )8 h0 M# n, z1 `, t
                        {
9 Q! v) K2 u8 g1 U1 O                                // 如果当前设备类型是麦克风,则跳出循环。 " V6 Q$ A6 F: g: s2 |4 i& A0 b. D
                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )4 V$ h, `/ `% b3 y+ i5 z, f
                                {
" ]1 L5 q# [2 L+ a                                        dwLineID = mxl.dwLineID;
* j4 v: b! k- H1 I" U                                        break;
. a4 h# j) Z, Q+ ^$ p9 U                                }0 o; V3 Q( g3 M. _) @
                        }; j' ~% Q' U! P" r0 u
                }
: w; q. a2 j" l                // 如果没有找到,返回失败。
+ }0 D4 b% @3 R( X6 S4 D! g                if( dwLineID==-1 )7 Q- k- E2 B  D& t; ?
                {
0 `* I% g# ]) H- c, P# K                        //尝试其他声卡( `1 |, L0 J5 u, m2 w/ L- ^
                        continue;5 h/ s$ C2 L/ Z+ _3 C) Z1 U7 V% [+ l
                }
+ T5 C: X( z) v4 C- ?* _6 b( q3 x3 H/ h0 P
  f, s* g$ ~: \) V  y# D& c
                // MIXERCONTROL 结构体变量清零* Y& k8 q0 P" V
                ZeroMemory(&mxc, sizeof(MIXERCONTROL));7 W; |- ~# e& z
5 t' g" R6 h# e5 [* G) R( c: S

& }" I) F: C) h: D; k& x                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本
4 h0 ~1 h$ Q" S5 c$ h9 j
  q8 `. K1 T' m, p  F) J3 _0 ?6 [4 z8 X0 U. e" f
                // MIXERLINECONTROLS 结构体变量清零) u; d& Z# q4 W+ |- Z. s  M
                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
+ _$ W' Q  A8 m6 K! q. f) t6 d3 n$ N& I8 T

3 o9 t: w. V3 d2 `                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本( n  p! T0 f+ c: f. V& g. x0 u
  ]  m8 D1 W) h+ k5 g

- Q+ A! _* J( `8 ^6 o, E. |$ C                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识6 p8 q$ i" [( s+ Z
                // 控制类型为控制音量
. E. `# ^) t# l' |                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
7 s1 f- X1 J4 p                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数
4 D& V' V  t' b! G$ E1 Q                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针" _- c+ N& u1 C/ r
                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小
6 Y) H7 e! t$ r' n4 G# x6 I0 ]7 K! S' \7 H% z2 _- u

3 \0 C* S: _- \3 h0 E: _                // 取得控制器信息" d, L2 h$ ?, s$ k4 |; h8 N7 ]# \
                rc = mixerGetLineControls((HMIXEROBJ)hMixer,  B$ K5 T. v9 [& c
                        &mxlc,; t2 E- T3 \3 L- |! [- N6 b
                        MIXER_GETLINECONTROLSF_ONEBYTYPE);
6 n* ^: x7 C& l* k
2 }$ ]" V1 T0 A$ W& ^4 o0 z7 d: s! \4 y( ?  j0 V
                // 取得控制器信息成功的话,则+ w" |- L) c5 J# m! d, H. z6 ]# u
                if (MMSYSERR_NOERROR == rc)
% \" |- H! `4 p; I                {1 x. p" C* F* |9 ^: I
                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.5 _; s4 p* n. o+ T1 I
                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
+ t( P3 `( p! a/ q                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)' ~/ E( ~- X! x2 [. i) I6 I

' u5 N9 _% u+ q: {) M5 `1 G& {* n! ?% A" e' t
                        // MIXERCONTROLDETAILS 结构体变量清零- Y, H+ x9 h8 T+ s+ D
                        ZeroMemory(&mxcd, sizeof(mxcd));
, y& h* A5 e, x8 |" u& A2 M5 M; K( W3 Q# J* l# o4 w! \
8 e& `' W+ C! |: |
                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本0 O/ H9 k6 j3 F; |" a
                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识
% [3 g* {0 }' y7 c# U: o  v                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针
# k, m* e6 o4 q0 U4 D                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小. T* [1 b5 ^: Q7 o" |
                        mxcd.cChannels = 1;                 // 取得或设置全部通道
' G% n  ~( x+ P
) F7 N$ ]; K: M/ O9 z
& [& ^( ?3 E/ t: T/ s7 y3 S+ w                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum. 5 m! p7 B3 s. T- u/ t
- L( F% c& t' M' X
7 P4 \& S  T5 b# F' J) A
                        // 获得音量值
7 Q4 y. J( y1 D/ M# }6 L- J                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer," Q9 F9 p: V4 e: \/ y( K6 H# u2 F4 ^
                                &mxcd,
4 z7 T& V  @7 v( o! x: Y. J                                MIXER_GETCONTROLDETAILSF_VALUE);" K3 T" g" v7 u

" U9 L7 m6 j+ e3 N# f7 }$ `! ?) X; f. e7 {
                        if (MMSYSERR_NOERROR == rc)& @" E7 x7 V) @+ w: t% P
                        {- l! K/ K% w6 W! w) L1 \7 J! z
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;- d. j& p/ P- e; h

1 A# p) ?. m9 Z0 U, y" D5 `( X* N) S6 P2 d
                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;
! b; @$ F( N4 Y5 N9 D' w$ V                                printf("音量:%X", volStruct.lValue);
4 `% o+ p. }* m+ I6 ?5 q                                return index;
8 `8 S. E* @. R4 j/ O3 X                        }
. v# ]) r! f$ o5 n& Y7 ?                }
( F1 n# X! E0 _. P+ a5 H        }
6 j# ?) K2 p$ ~$ h* \5 Y! [$ b. A9 x' T6 T7 A

" N. |% r0 U1 K/ Z9 L1 t        return -1;
$ p* f/ f9 O5 J3 \}
0 \7 ^* V& ?( e" t4 b& e8 w$ {2 {4 z8 @. V8 C5 ^  _6 |* R$ }
        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html( v$ o) D) Q4 }6 p
                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-10-2 05:02 , Processed in 0.015214 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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