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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/( p$ _) a6 ?7 K& U) \
/ g. S8 \5 _3 H" s) u
参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
5 z% r# ~# l9 C* Z# N4 b: n+ G1 U  _) e$ y
/ I8 }9 K8 O( L3 U
int DeviceManager::getAudioInputVolumn( const std::string &deviceName )7 J# }5 s6 x% f0 r& o2 j5 B& V  k
{
0 N" v5 ]! e% g9 w% n9 P  o- q/ P# ]% F- y% ~8 [3 I

# U5 `2 u% w" x6 |& T        MMRESULT          rc;     // 多媒体函数返回结果变量
6 f2 g1 g2 R4 A. b        HMIXER            hMixer; // 混合器设备句柄" e4 y' ^; R8 t: d5 D& w9 E- T
        MIXERLINE         mxl;    // 音频线路标准状态信息结构体
' J9 v& e, G& N: E+ j& E. x& C        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体
( Q- ?( W. I4 Z9 |        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
& f0 r! X. G# M
% i5 A5 _( t; K  X4 q4 C$ N2 g: v1 {0 r2 b  Y$ a3 x
        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即# J- h' ]' ~7 _- }2 U. H( x
        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
& Z! r* I6 p5 m* ?, t       //可能还是跟声卡驱动有关。
. [, \% G: B6 n' m) p6 s        for( int deviceID =0 ; true ; deviceID++ )
3 l! |3 _: [% ^$ x! [0 k        {
3 t6 E3 u5 y6 W4 |  d# c/ e5 n                // 打开混合器设备, j& D3 P1 S7 E, K* ~
                rc = mixerOpen(&hMixer, // 返回的设备句柄" ~9 z5 y. x' c% U
                        deviceID,       // 单声卡的设备ID为零7 I  h+ E% p' J9 R3 U2 H
                        0,       // 不使用回调机制
+ q, ?  R0 J3 z1 P* s/ V. l, N" B                        0,       // 回调函数参数
1 J; ^( ?# C3 N, o9 w( U                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID6 t; ]3 W$ o7 i& Y
                if( MMSYSERR_NOERROR!=rc )
9 F% Z& d0 G. Q; P9 w                {) O+ h; W! R: {5 F4 L3 S: A% B
                        //跳出循环. e5 Y. D" K, C/ f( L% `
                        break;
# d5 `1 P# h% y6 R                }
( f# P: Z% x- ^0 Z/ O                // 打开混合器设备无错的话,则
! ^$ t5 h" x% k8 ]4 N
3 q: K+ {# B$ o: e' [" P! k" }: {
                // MIXERLINE 结构体变量清零
' J2 m) W& L" j! u2 h5 e                ZeroMemory(&mxl, sizeof(MIXERLINE));& \$ ~7 _  N" ^3 y

9 N* W+ ?2 c/ v! j+ |; B1 ~2 E* n% \+ Q& C& G9 U1 z
                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本8 c: z1 M4 t/ [: e& U1 }7 y
                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS1 D$ k2 m3 ]3 I  b2 g
                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;% e- t  D8 Y, B
1 E2 f! }! [% w! b

- \/ z% F7 M1 K9 t                // 取得混合器设备的指定线路信息
/ x- X* L7 h7 r                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,
- ?3 X7 q! y' v! V                        &mxl,8 ^/ `0 b# g! ^6 z3 _. _
                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息+ E* Y4 J3 [* M4 i- L
                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
2 J4 i4 y" v& ^2 g, y8 ~* s                if( rc!=MMSYSERR_NOERROR )2 r7 m, W& s) m. l
                {! w, E) ^5 }8 B
                        //无法获取声音输入线路,尝试其他声卡, z, \% {. o8 d+ q+ e
                        continue;
, k8 E) \% o* c% K  T7 j( b3 l                }# v$ a2 v1 W2 {

% L2 y/ D3 }: L+ j- X" R" ~5 N
; b2 U( w1 V. m                // 取得混合器设备的指定线路信息成功的话,则' Y, |/ N- Y- V9 H5 a8 d5 z* ^( ?

0 x" c! n  V9 s; ~( l; |0 e" a- L. l$ z) r
                // 将连接数保存
) z4 W0 v- S9 `4 u8 g" }$ W) f                DWORD   dwConnections   =   mxl.cConnections;
3 Q7 T! ~$ J* F& q# j0 h! w4 \                // 准备获取麦克风设备的ID 7 |. m+ |7 R) r
                DWORD   dwLineID = -1;
" y9 S: ?& ?* I9 _  A                for( DWORD i=0 ; i<dwConnections; i++ )
  w  y* y# {0 F* x, \  O7 ?% w2 J                { + k9 ^7 e, J4 ?
                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
. d' m' ~5 y, \# _  U* w                        mxl.dwSource = i;1 l+ o; |! ]% M/ @
                        // 根据SourceID获得连接的信息 ! G% e/ h( k% H4 Z; h9 A$ Z
                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl,
; l1 b# q. k: G8 o1 c                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   );
& O5 y9 {' f" Y# s1 |                        // 判断函数执行错误 1 S! O  E  |5 X0 o0 ]7 C
                        if( MMSYSERR_NOERROR==rc )
0 q7 I, `. B5 Q/ D5 O8 F                        {
! w' z& @1 n- a" M/ w0 v                                // 如果当前设备类型是麦克风,则跳出循环。
" {2 t4 _1 g& Q0 P% }                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
1 `: h! K: }; B$ }, D% `                                {
4 x5 A% x! `, S0 B: {, h                                        dwLineID = mxl.dwLineID;
) S. k! d; n) n2 U2 J3 A                                        break; ! ~5 J0 |2 |5 b: p: L
                                }
; Z) C: g& ^6 P5 b% R& b' |                        }) p, S. _2 W- i: B% I! }. ^* Z
                }( ]4 [3 Z% }5 C/ ?; K' I- ^
                // 如果没有找到,返回失败。 ( e. ^; I3 m. E8 z
                if( dwLineID==-1 )
# t) G6 t: X, }5 P                { 0 d+ r6 _& Y5 h% Y" C" X( N+ u
                        //尝试其他声卡
; ?9 P& ~' P7 l1 N5 E                        continue;1 V) N7 h) m" Z# Y5 }
                }1 p# U5 Q$ e* F! ^8 T

, Z; f6 k, u' D0 R2 }9 I' J  e8 Q; f$ ~9 T2 s5 e! {
                // MIXERCONTROL 结构体变量清零
0 l% W2 Y2 H# i. `                ZeroMemory(&mxc, sizeof(MIXERCONTROL));& D0 r1 `" I! [% g2 U" f

9 B2 |6 r2 H. w% Y0 ^  y! |. ^& n4 n- T% S- |* i
                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本+ _  ?: F0 ?: S* {* J; _7 O

0 i6 [$ o, [* w, [) @9 c& m+ E7 j) K9 t6 M, O
                // MIXERLINECONTROLS 结构体变量清零
% r+ B# j5 r- ]0 U6 _                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
0 ~+ r) P6 l/ C. j0 B5 G3 G& y# \0 U1 i9 I* p. g0 y! A: K( o
% ]  P' z1 j5 w  ]
                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本% w% W% ?& l; S$ }8 B3 ^, o- u

8 b, [. g+ |$ J# ?: O7 t/ h' I0 \
                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识* V2 P! d1 d' X5 y; [) m7 C
                // 控制类型为控制音量0 j  |0 s  j& x$ u8 e+ e1 o$ {
                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
7 q0 O# S# Q: ^+ D' ^                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数; k7 D0 U6 G' r7 B; H- Z
                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针
( ]; U' D$ a# X, Q+ W6 l                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小9 {* f; ]( c3 e! l. D, S
2 [  ]9 T6 u8 l7 W

& A% ~4 x4 U: p9 }, [+ S& z4 T                // 取得控制器信息  r6 V; _; t& ?2 l
                rc = mixerGetLineControls((HMIXEROBJ)hMixer,5 ~6 M$ z4 l) m" N+ F; g, p
                        &mxlc,
+ \8 {, _, \  y: x' L                        MIXER_GETLINECONTROLSF_ONEBYTYPE);
1 E& a8 ^8 m. r8 m+ Y
$ n; m& D6 b# C) ]: J$ P# l
; ]7 ^. Z9 J) @- `% d. e2 M2 e' E                // 取得控制器信息成功的话,则! ~, u" {, K# {. F
                if (MMSYSERR_NOERROR == rc), V0 D* L7 X5 g$ {/ j# Q9 ~
                {. w) E) |" z) N- p# A- D
                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
9 K: D$ `9 r. C/ z                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息! U% o% Y5 \  F# a
                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)3 b" K( A3 d1 d; N  g, {0 f
! W# o9 W) l( S: x. P% B3 K

1 k: M. w; a) K! d& |; V                        // MIXERCONTROLDETAILS 结构体变量清零2 O, y1 ?. A) K" u  f
                        ZeroMemory(&mxcd, sizeof(mxcd));
7 t- N# ]6 a5 Y
. q) n+ D' ?0 l  C, g
: |5 {% ]" o* j7 ~3 r6 k                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本* J. D" P" f% X* y$ F
                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识3 X1 |9 H% L: \4 G$ M6 N- `! h
                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针; G* {$ D* h' c5 n- j6 m: |
                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
. B* {  ~/ A0 r* q                        mxcd.cChannels = 1;                 // 取得或设置全部通道; c% O8 S2 d' v/ a" \1 {" I
( J! x+ `  O( G

4 F) Q* o3 `2 P' p% D: B: r                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum. ( [! g/ l$ S# N0 T6 w& ~
/ R! F! t% z- f5 S

( q1 m$ s5 {- J/ W6 }                        // 获得音量值+ G3 g- F# j# L5 k/ Z. X
                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,
2 v7 z$ T; }9 k1 r; `                                &mxcd,: m" }3 u4 Y$ l; y3 O
                                MIXER_GETCONTROLDETAILSF_VALUE);; e7 A/ ~% E" }, X: B, ]0 h* Z

1 l: r, E/ }" j9 T: V1 X) L& ~* G0 p3 M8 ~& W
                        if (MMSYSERR_NOERROR == rc)
  V3 i+ L* P% x) P* ^                        {6 ?. V$ _$ Y2 V! z" h
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;' w: l0 U$ _7 {9 b% I

0 e3 [! ]3 t5 x) t' i% p7 s
% D9 w% {9 [: c+ n7 }                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;
- K8 o/ E! _$ K/ v( m$ K                                printf("音量:%X", volStruct.lValue);0 g3 w& R2 b  d. T/ }* H4 w$ Q
                                return index;
1 u  Y. Z8 R  Z4 Z# Y& K4 ?; ]: C3 z                        }4 ]# e  V8 o4 O5 v* s$ j+ Z
                }
! _. G4 j: S5 g3 c. }        }- a2 B8 I: T( |* _- X  }
" Z3 H) {% F+ N, }
$ r" y: D' \! K: E; W% G
        return -1;6 d2 w7 ^# s- w2 K" b: T$ |
}: g/ t2 w# L$ o. J- }

+ c3 n2 |9 B" G0 w        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html
+ u  K* A+ @: G                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-18 06:53 , Processed in 0.020958 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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