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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/
0 U! m, ]8 l0 Q" P
2 ?! R- K. J$ l7 I" f参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
4 ]3 D  [% P' X( \
* W* w4 D3 Y. w' p7 m: s+ S% O* M0 b6 J
int DeviceManager::getAudioInputVolumn( const std::string &deviceName )
$ x8 L8 m0 s- L4 {6 K, D{
4 J9 a" q6 [  c' x$ _# ^! M! G' Z' I* v+ T
1 h3 ?3 R1 x2 _* v* @7 N
        MMRESULT          rc;     // 多媒体函数返回结果变量
  J2 S' |- R, G7 {% F; q0 ^* [        HMIXER            hMixer; // 混合器设备句柄
- y" U3 B% K! S' }5 U        MIXERLINE         mxl;    // 音频线路标准状态信息结构体
7 E, w8 y1 G0 I- \% K        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体
9 E. X0 |; U4 y. K  S. Z5 ^( B        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
& b4 ?3 w0 `  L$ M
3 ]. c+ m1 y: _9 k$ D; _9 Q! @) c  h- i- {& @  M! [
        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即/ O6 X- X! G2 n) M1 @
        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
" Q; J& M' t0 S1 w% @       //可能还是跟声卡驱动有关。
0 ~0 y' c5 a& g# ^% F: a        for( int deviceID =0 ; true ; deviceID++ )
. f" }' P6 ^  g6 U( A        {& o0 r- Q- `7 W9 w: |
                // 打开混合器设备2 o5 L" `. b3 J. q- n  s( M* v
                rc = mixerOpen(&hMixer, // 返回的设备句柄7 u, y% o9 ^3 N7 E/ Z9 |1 S
                        deviceID,       // 单声卡的设备ID为零
- ~- o" a6 F1 k7 i1 r6 R                        0,       // 不使用回调机制5 p- d7 n: J  L( i) f' _
                        0,       // 回调函数参数
$ y0 P% ]. `6 ^& ~, k- y7 r# z                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID
6 z( J# M0 L! R5 T- J& {9 A1 h; |                if( MMSYSERR_NOERROR!=rc )$ z* T8 O! l& v* g
                {# D  x) b; M2 C! f
                        //跳出循环1 j$ @6 ]# g& f
                        break;4 i  z* h( n6 n, q6 d
                }
3 l8 L  p' O( m, Q' F6 `& m                // 打开混合器设备无错的话,则2 m# H; O& Y, i. x

% X6 O: h' m5 Z# `& f$ E1 B8 I% L3 h: b( s3 v2 y: i1 R; [7 C
                // MIXERLINE 结构体变量清零3 T# w) l$ D. S% o
                ZeroMemory(&mxl, sizeof(MIXERLINE));
) _( A, q" p2 n5 s3 M4 m
( B/ g+ G) ], ], L8 x: V. B$ ~* Z$ c2 f7 a5 A7 W) j( t# \
                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本
6 a$ v! f& e5 j% _+ h8 T                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
$ v7 |. O' H  G# `+ m9 w( l                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;7 I0 F2 ?8 I: R6 s- V; k& k
/ }; b9 d. p/ U
9 i: I9 v$ L# y' f
                // 取得混合器设备的指定线路信息  o" S9 C; v" Q; u/ P9 Z9 q
                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,$ W# @5 F- ~# w; s) S
                        &mxl,
2 @: u* ^: a2 e4 G' T: E                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息
- n6 d/ m1 ?) J4 H2 A  {% W                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
3 [6 k6 ^8 }2 z+ M+ `" a. u                if( rc!=MMSYSERR_NOERROR )# U& q) Z6 ]8 V, ]; Y
                {
" v. ]4 h5 M, S) w; |' i: {) Y                        //无法获取声音输入线路,尝试其他声卡
& S: _5 [4 s0 b9 J                        continue;
1 _  }. D* K/ V  }0 J                }2 x+ @, X& E" Q0 b7 W4 V+ C* T* |
( C+ G7 U* p; u0 j* s2 V
$ Y1 J5 A. q. T% j. ^; A$ [
                // 取得混合器设备的指定线路信息成功的话,则6 @2 N5 X* V- T1 V3 b
5 H- K! V1 }8 X1 o8 I

2 V% `$ u% q2 O' j( h2 o                // 将连接数保存 1 o  Q4 w& |8 ^
                DWORD   dwConnections   =   mxl.cConnections;
0 Z- K5 b# Z8 c9 W! B                // 准备获取麦克风设备的ID
7 q( P' }- a+ i0 `                DWORD   dwLineID = -1;
" \  R9 [# o2 |                for( DWORD i=0 ; i<dwConnections; i++ )
2 }  x0 b' ?& b                {
5 N' A$ Y% O( \. S# E                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
7 c) d/ s0 j) S; D- v& t                        mxl.dwSource = i;! W  B/ |3 m! [) C0 T# v. N! t
                        // 根据SourceID获得连接的信息
4 M& ^2 _. R' z9 j                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl,
( v) w2 a/ J$ ~' g7 L5 Z                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   );
9 }  `4 }4 J* b2 L$ S                        // 判断函数执行错误
1 L. h$ x' C) o) u0 z                        if( MMSYSERR_NOERROR==rc )( @# O5 O6 v3 T' A
                        { ) w% M1 `  v# ~. Y+ K
                                // 如果当前设备类型是麦克风,则跳出循环。
7 R  V- W8 K! A# \+ M" p, F                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
6 ~0 Y' O1 k+ {                                {
4 R  }0 f# Q/ f1 a4 i                                        dwLineID = mxl.dwLineID;
. B9 A% P9 I6 X9 [  w* _                                        break; 2 Y. N3 f% k$ j& m
                                }5 R; L+ J  c0 ]
                        }
, E8 N! o  T- ?; E& x3 r2 C0 Z                }
2 Q$ k- t0 w% h, s                // 如果没有找到,返回失败。 6 f4 n; B0 p$ P4 O% k1 ]7 A
                if( dwLineID==-1 )
$ U8 ?6 S- p% ^' @7 @( T; L2 e% P# }                { 3 p7 a- [$ z  H, D
                        //尝试其他声卡
; A1 G- Y2 \; W+ p' I$ u# g- c                        continue;
+ d. {. C, M. R  D# _' i                }
& \5 L, G1 x8 E- H5 @4 r/ j9 [3 F9 n7 u

# r# s! ?/ d. L                // MIXERCONTROL 结构体变量清零  G# u9 o( \! [& K
                ZeroMemory(&mxc, sizeof(MIXERCONTROL));% z5 C1 Z2 S* _& @2 b
# V* _- x7 Q" I5 l% g

% O5 ]* G( R9 b6 h! o( |7 V4 Q                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本
" ]( Z  B6 b' D) e
9 K2 n; r/ N; ~, X
. e" F, o+ K/ x) T' B( F9 t- |                // MIXERLINECONTROLS 结构体变量清零( S1 O. S: x5 a" G3 A: F6 f
                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
, w$ K5 Z6 v; \
! H' s# ~! V2 R
, _7 ?; U3 [! z7 E# h! @                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本! a3 r. i/ x) ~7 Z

7 _0 @6 c7 S8 u0 d) k# W
+ T4 b- w- U- h+ I. x* J                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识. @& M" e; N8 `3 v
                // 控制类型为控制音量" y* I& J$ N4 n1 ~$ t. u
                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
1 F, o5 Q+ i2 C4 |7 `2 O" r3 l                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数# P! Z; O6 K3 T$ D& |( X1 P
                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针* R) p, i" o/ a' O
                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小( @4 V/ @. o4 p3 n9 D
2 p7 z1 h+ f: M
1 J9 A3 T* v6 f
                // 取得控制器信息
4 R& T6 Z: |- S7 L- h                rc = mixerGetLineControls((HMIXEROBJ)hMixer,+ {/ L& ^. r: P2 o$ t
                        &mxlc,
, a4 M- |. {5 S                        MIXER_GETLINECONTROLSF_ONEBYTYPE);: N" J4 t8 M: O* Q' m, P

, e3 o# f8 T+ L6 Q/ q+ ^
, M* A0 d  y7 A                // 取得控制器信息成功的话,则) P  |- i5 M2 ?- D2 k& V4 R, F
                if (MMSYSERR_NOERROR == rc)
$ z+ @1 x, _9 Q                {
/ ], w6 T6 U+ `( B. z( t                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.$ P( T. N; I7 _
                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
6 Y$ Y/ u0 K" e                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)
) v$ K9 k: H5 U/ m% F
. P1 j# Q* x* p+ Z' ]; {$ p) b4 [- m2 _: R
                        // MIXERCONTROLDETAILS 结构体变量清零/ x' |; \' k& D8 i$ E
                        ZeroMemory(&mxcd, sizeof(mxcd));
5 n1 U5 {# E' \+ M, G& O  c! K8 Q  m+ b( _

1 ^& i( c& k- V5 T                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本
! [& d4 v% z" [; T0 c: [/ _1 m$ ]5 N* Q                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识
# P3 V2 g; J, j( Q( R                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针
* O! N) [, @3 g# B/ j                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小6 [# ]/ R8 J8 \2 G* n5 ]; w
                        mxcd.cChannels = 1;                 // 取得或设置全部通道8 @% O* y+ t$ a; J" o% o3 n+ T4 r$ F

4 y4 X+ D$ c5 _8 t, Q; O$ N& r7 Y1 R7 e3 `: s% [
                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
; C/ t# H, I% i
- `8 b& C5 \% I* ?* J; B  I. ]2 u6 E; v# u9 Y5 o
                        // 获得音量值
: h1 ~0 M/ }  b' C                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,  ^) z( ?- M: O. ?
                                &mxcd,2 C5 v" z- ^* q" P
                                MIXER_GETCONTROLDETAILSF_VALUE);+ U( {2 s- U- l5 ]

( e4 e" C1 H# }2 Z
9 t5 N: @3 v; _                        if (MMSYSERR_NOERROR == rc)
3 _+ Y! X- J, G9 j                        {$ x# X% A, l3 J& ]$ a
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;
% r% q$ Q' c$ c. \- P; M' K  S6 c" d& J9 m0 d2 w6 m2 r

' \7 ^3 Q( S5 j$ a' i# f! ?                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;2 L" q2 A! c" A9 V0 ^
                                printf("音量:%X", volStruct.lValue);
2 w$ i+ r  F( {1 f                                return index;
& Q4 u. I% ?2 m( X0 \& a/ X7 B$ [                        }; ~$ F9 V4 o6 j
                }
8 p* Y8 @  d+ Z        }
+ v- J4 w! L  ?, _! \3 j
5 R" g& ]5 `4 u/ t6 W# X& m5 a/ F  T+ @) H4 J9 Q% `1 v3 J$ B
        return -1;
% }1 b' A4 \; a}
6 ~$ X! t1 Q" J5 h  s0 [9 I' J# x3 M4 ]: p
        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html
: t& {# |& X3 R3 T7 V% n: g                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-10-2 08:40 , Processed in 0.017079 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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