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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/
9 p' ~, w1 q0 g
- X7 a# m9 F9 p2 l$ m参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
" n2 o* u4 r( N; Z2 U0 N; t6 i9 ]7 m% Y5 Z
( H0 P/ k$ [1 n) c4 N8 {
int DeviceManager::getAudioInputVolumn( const std::string &deviceName )  I' `7 t" T5 e5 T; K- v& Z
{& K0 }, w# x8 p9 M# d
5 x3 h7 X- s  a5 G3 o% A: {- s
8 t& N4 W- k$ S/ b5 A! k
        MMRESULT          rc;     // 多媒体函数返回结果变量
1 r, G& b" W7 Y2 i" z, a        HMIXER            hMixer; // 混合器设备句柄
6 R! z- `6 f, U4 m' a% ~- ]        MIXERLINE         mxl;    // 音频线路标准状态信息结构体
6 j# i  M# A+ ~        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体3 R7 N0 L; e: S
        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
8 N/ I/ W. a% m0 s; E- \, U5 K% m* ]9 O: v7 {) e# ^9 P8 M5 p

5 s- L9 n! |& [! n* [/ G6 u! ]        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即& e% K' ^: P, O) A/ ?. B4 p
        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,8 |  d& J3 s$ n5 R$ D( Z4 o% k( h2 e
       //可能还是跟声卡驱动有关。+ x$ u- E5 B" M
        for( int deviceID =0 ; true ; deviceID++ )* }9 l5 p: {! ~, b0 d
        {
$ @' `! B, b. O+ ^# X" C* P" |                // 打开混合器设备
7 H% B' U- {4 B8 C0 _                rc = mixerOpen(&hMixer, // 返回的设备句柄
0 {% ^( d2 ~9 s6 i: B. w/ i2 G/ }                        deviceID,       // 单声卡的设备ID为零
" q! F2 i7 t9 t  u+ u                        0,       // 不使用回调机制* P) R9 q/ C+ R# u. ]. _8 X
                        0,       // 回调函数参数  y- @+ E7 h- d3 a, X% L
                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID
- O: N& X; r3 ?$ c' G6 e( a" K                if( MMSYSERR_NOERROR!=rc )0 R) ?! P" T* r3 _
                {
6 W5 i" O  t' G' Q                        //跳出循环8 `6 H; m1 j* {# `
                        break;
0 \) M' B; o+ B7 W                }7 D: l, f3 v& e6 O, `6 u
                // 打开混合器设备无错的话,则
3 }4 e' M1 h* z  \+ ?
6 `  V2 {+ H! T. t- K7 v6 W: Y9 S
                // MIXERLINE 结构体变量清零+ v8 J+ q# x( G: }% e# k8 b7 k
                ZeroMemory(&mxl, sizeof(MIXERLINE));& m: j* M8 [3 }7 h$ O1 c

; Q5 W2 }* [/ t1 U( J" f8 M! e, o
5 N5 F8 }. f) d4 F                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本
6 m2 ~6 k$ ~, S+ g                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS$ ?$ D; s" H) A( ~. X( {
                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;% u$ M* W% N0 \6 F: ~
0 ]6 [; I. q, Y/ [

% Q( a2 p" x8 Q6 B- b2 K8 N, ]0 R8 _                // 取得混合器设备的指定线路信息
: H) P9 Y* w4 i1 f/ j+ J4 i, A                rc = mixerGetLineInfo((HMIXEROBJ)hMixer," c4 C" _3 h% x- S" Q  o# J
                        &mxl,) B( }. z; j% I6 D% ?- v
                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息  e) Y' Q% E# G
                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);/ [7 e6 \+ x8 C9 v( \
                if( rc!=MMSYSERR_NOERROR )6 r4 d4 i8 {$ u  A  s9 d! s. M
                {% h7 J5 `/ A: I1 E7 z$ x( a% s/ w/ Q
                        //无法获取声音输入线路,尝试其他声卡
6 [2 @0 S8 W+ U! E6 s                        continue;/ `, `: p/ c; ~8 S" n0 X5 P
                }
* q) I2 T  c% I& ^$ h) t( X9 S# n) J, G! u
, i5 }$ w: g8 v( E
                // 取得混合器设备的指定线路信息成功的话,则8 z0 E2 h/ Y8 K! ]0 H

) }; `- K0 m1 g# e: N0 P& L, k
# ]: L9 W) p6 w& T( d) g                // 将连接数保存 : F9 S2 A" s. u. F0 U3 d/ Z( u9 h
                DWORD   dwConnections   =   mxl.cConnections;
+ K$ k" p+ F+ {3 F6 t                // 准备获取麦克风设备的ID
( v9 ]$ w7 X' q; I, P& D                DWORD   dwLineID = -1;
& Z5 E5 r' _/ B5 k! I5 W                for( DWORD i=0 ; i<dwConnections; i++ )* ?* D5 s% ~% }4 l$ c/ h
                { " L" k" }3 @/ y  M" S
                        // 枚举每一个设备,当Source的ID等于当前的迭代记数 / `% U! n" `6 w/ H* z; j; T* V
                        mxl.dwSource = i;% q" _1 K: b/ X
                        // 根据SourceID获得连接的信息
5 T  l8 h9 H: E% |+ }                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl, + N: H- O* N+ A1 `1 n' }) v
                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); 2 J% T" P& _+ ?# q) ~
                        // 判断函数执行错误
. Y* H  ^9 P+ c1 F                        if( MMSYSERR_NOERROR==rc )
7 ]1 M; h* `1 M; B                        {
3 h4 `3 b; v, n2 I, j) @8 P0 {                                // 如果当前设备类型是麦克风,则跳出循环。
: [' E! @, H, h4 B& z  P# }                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )7 s: l& V' Z5 X3 `: K
                                {
; x0 Y3 e6 y2 ?( ?                                        dwLineID = mxl.dwLineID; ; G7 {0 |3 w# T0 r0 @5 V: R6 I
                                        break;
$ C1 y* L4 g; n% }  B% o8 b/ b                                }
, M, j/ f$ @7 w1 \7 C+ d                        }
$ ]& j( `' K0 `' R' L% A7 m                }
# j: X) v* b. ^! g& K' R" V                // 如果没有找到,返回失败。 0 j- O6 X& D! L- E! x) ^
                if( dwLineID==-1 )
! ?. E7 {& q; r/ w' c; v, j                {
# ^$ W% s! {$ A; ?: l# f# j' U2 F- Q$ B                        //尝试其他声卡) i, v; B; m/ W; f7 u/ D
                        continue;2 C! B! \' H2 T* s; X5 T# _
                }
6 h, n  A. W# q( a& D$ t% U8 i" V- H1 u. x- s- f/ g
$ E! o9 f6 D  i* h, t+ l5 O0 k
                // MIXERCONTROL 结构体变量清零
+ Y% N' N. E/ k% D2 ^' N* V8 o, O8 b                ZeroMemory(&mxc, sizeof(MIXERCONTROL));
; s% z/ l+ n0 R, K# t  e1 o  D2 [7 n  _& g" ]3 G+ C! D
: h3 e' U0 u+ y9 t$ z) P5 |
                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本& `/ n8 Y6 O  G: i* x( \

5 }+ `0 U9 q( U# q/ e* j; ~! v1 E# d2 w+ ]( d; C
                // MIXERLINECONTROLS 结构体变量清零
3 B" z+ e! p3 v! w0 _5 b                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
. j9 q% e' z* }" X9 }# P
6 g5 }2 `' \; j/ F8 q$ O% S; ?
) ?; ^. q' N3 _: ?                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本
& v" \* ~, i& {) Z  W, K
& B: J2 j( `' Z$ \
$ Q9 [! Y' G- T, Z# `( H                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识
1 E! I1 M& r5 I: w% x6 L: C& Z, K                // 控制类型为控制音量+ _! B3 _! o* z4 K& c! c7 ^
                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;0 x  c, n% o: M. }4 B
                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数* U3 e, ?* n+ n- B
                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针
* p6 W0 Q/ U/ N                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小2 Y3 E7 a7 c3 N- V; @0 j" v0 j

% j) M# K  a- e2 B1 o: R6 @
! Q$ \/ r6 ~* P" a                // 取得控制器信息2 B$ M  y; T' q% ]
                rc = mixerGetLineControls((HMIXEROBJ)hMixer,
; V: ^# c% L7 n3 C% Y$ d                        &mxlc,
$ b6 m! C1 }( R' }: m" w                        MIXER_GETLINECONTROLSF_ONEBYTYPE);
$ M- ~# ^' d; z1 a/ Y* J3 m  l) Q
' l. @  q7 |+ g" @) S% O0 z5 P  S1 d+ q
5 R# _$ Q" M( G" Y                // 取得控制器信息成功的话,则
* z$ Y8 U2 |2 p5 x                if (MMSYSERR_NOERROR == rc)
; u% L( C* H4 Y1 n                {5 X7 I8 P* L+ E3 z
                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
" |+ @7 X$ ]1 J( k& m. z- ~                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
2 m# f, B) u) W- \% G! m* v                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)
- |" `* ^* I6 r5 u% k3 ^+ ~
; [6 t; z0 N0 x  e
6 W; ^& R: D- P+ Y8 m) G                        // MIXERCONTROLDETAILS 结构体变量清零5 g" z* C7 \* R. o7 {
                        ZeroMemory(&mxcd, sizeof(mxcd));
- Q6 @" I" G" I4 o
0 S5 s; G# d1 |0 R, [3 ]# F. q; T- i2 @3 Z& a. o
                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本7 z% Y& r( G! ~2 ~9 m  \  ]) g" S
                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识7 H0 o0 k3 d8 J+ {- _( x# K3 m9 }0 q" j
                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针0 B) Z; `# V. F2 n" A
                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
; k; F( F* C6 d, G/ n; q                        mxcd.cChannels = 1;                 // 取得或设置全部通道
) M2 J: y$ d( h' s) I) H$ D; x+ x- E0 q- [3 X2 G

2 |4 R2 Q! J+ t) p                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
3 }: w8 h/ Q8 B+ H3 x5 w+ O: H9 E& A% e, B
; `. D, q) z5 C; ~; L8 O9 p0 [
                        // 获得音量值, |) Q* @' n. B! F% f7 i9 \' D
                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,1 k1 p( J' c( p3 b
                                &mxcd,
) ]8 B8 e3 ~4 i' h                                MIXER_GETCONTROLDETAILSF_VALUE);
; s' ]1 i! v$ ?( p1 x
' w; |4 M, c# l4 W9 e) x: X8 a7 A+ U/ g8 }8 x
                        if (MMSYSERR_NOERROR == rc)
( c; h/ W  Z- U" a                        {8 c' M1 V$ i, D  F* Q
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;$ v% d' X# x; e2 v* \; h
2 `4 V, r) K& l0 K6 }6 ]
( k$ K5 f+ S. q4 ?
                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;! h4 C% L9 ]: }7 o$ i3 B$ w; ?5 x2 h- f
                                printf("音量:%X", volStruct.lValue);8 Y& P9 w" {* O# I
                                return index;
3 S- s9 R' v; H                        }* P/ h6 ?# X0 S# E
                }
) s+ D8 i4 ?- P5 K9 O8 C& p0 w3 C        }
9 m) B: `- Z% B# [
0 c9 E/ {% O+ Y- \
% s* p% l: `/ C' z, ?/ k. F& h        return -1;
0 c, h& \1 O! p. |& q6 i2 l- Y6 o/ P}
- ?3 {+ D# }3 \0 J: M* h; Q, k& A( h) e% R9 d8 Z  _! H  _( A
        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html4 q! V- L- e' @+ s
                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-9-30 06:30 , Processed in 0.035517 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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