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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/  \5 b& Q' D; s- r8 I- T! C
5 c- D6 y0 B5 p9 `0 V" E. G# W1 ]
参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:  R9 T  ?5 e! j* r. T
( d5 ^1 V0 I9 G; n: _3 ~
! O, S; T8 q) W7 R* J+ Z: g/ g
int DeviceManager::getAudioInputVolumn( const std::string &deviceName )
, M7 l# E  }& e! d{4 J2 C% P% D& {! a/ w

0 e/ r. W% h/ X. d0 V/ i; _
6 P3 w5 L8 d. ]3 U5 N/ z! e! `$ @        MMRESULT          rc;     // 多媒体函数返回结果变量
/ u8 z* n; N! F+ l6 p  @+ R7 w( K        HMIXER            hMixer; // 混合器设备句柄+ x7 _/ d! @$ A2 Z
        MIXERLINE         mxl;    // 音频线路标准状态信息结构体
! z$ E( ]7 t5 ]# N  E# X        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体6 X& B0 u0 e( ]% ~# x2 `
        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
5 A  s* M- `0 j; n/ m
" p4 i4 W1 [9 h, j# `# L% q: V+ f5 P8 s9 ]; B
        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即4 m! {5 j2 l3 d7 N' i# R- J
        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,5 A; `2 O/ S  j! P- C9 P
       //可能还是跟声卡驱动有关。
0 O2 V' d0 Q6 r% \# J        for( int deviceID =0 ; true ; deviceID++ ): g3 a- ]+ y" i# Q
        {
' M8 K  ^5 K* `2 q1 D                // 打开混合器设备) z* {6 d7 J' }) F
                rc = mixerOpen(&hMixer, // 返回的设备句柄
' i& ^' H1 L# d" T5 ^" h                        deviceID,       // 单声卡的设备ID为零5 v: R" r8 h) H2 N. n
                        0,       // 不使用回调机制
+ V3 K# n' R) M6 B( p/ w                        0,       // 回调函数参数- Z% N3 t) H7 T' |& k0 @2 a6 Z
                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID, R8 E8 k" y- [% |
                if( MMSYSERR_NOERROR!=rc )
7 J! C- L8 [: t( A# D                {  o/ F4 ~6 U( _; i- z
                        //跳出循环
' c% C; I/ R2 D. G- b5 Z# Y                        break;
( k* w! a( k2 f1 g3 B) W; z                }
8 r3 y/ b2 l3 N4 U- b5 i                // 打开混合器设备无错的话,则
+ p3 U2 V  R6 X6 \, ^" V# z# W
8 r' e8 C# v9 ?) e# ?* K) s2 [; U! p8 |3 O# x. S" _/ ]
                // MIXERLINE 结构体变量清零+ {9 a6 k" M% p  s' M1 M- O
                ZeroMemory(&mxl, sizeof(MIXERLINE));
* a- q4 j. ^$ j( Q1 T, I
9 i4 Z( C6 V1 a" K. G3 N
5 g! r) P  O1 u& X3 b' |4 M                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本
0 l) r( b1 S# Y                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS6 r! @" l; Q- E
                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
: O$ j" T( @$ a$ F4 z, l
& Z1 r4 x0 h0 |  a' ?* k6 j: A
, x( p; o3 i4 [! W8 T! ^                // 取得混合器设备的指定线路信息
  P; Z. e' F9 z7 Z                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,0 m9 [/ I5 `; F3 f/ n
                        &mxl,7 ]3 `7 m3 s4 ]6 C5 R
                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息" r- w2 Y5 q/ U* @2 o; J% I
                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);* _# \( k1 z3 J5 K, u, X+ G: b& Y
                if( rc!=MMSYSERR_NOERROR )5 P, T5 f4 t: i- b3 N
                {& v* t* Z- q( E
                        //无法获取声音输入线路,尝试其他声卡
2 [0 K  G8 [( O8 ?" D8 v9 \                        continue;
$ {7 N" I% O6 A+ T# l2 x: M3 w                }. r2 }5 h; ]8 k

( r1 h: `2 Z, @- I' _- x0 ]: f/ W
; p9 d7 H  @$ u+ b                // 取得混合器设备的指定线路信息成功的话,则
1 u  D8 v2 R& X
+ r# H, X4 B+ ?# D" `' A
/ ~9 Q' P. f2 E( r. N- h                // 将连接数保存
, }2 [7 X$ U! S& m& I                DWORD   dwConnections   =   mxl.cConnections; % a8 {% |) W* f* e
                // 准备获取麦克风设备的ID $ d) Q: \5 x8 p# f+ k1 w
                DWORD   dwLineID = -1;
' m* N+ a/ j1 z! {0 A" ^3 B                for( DWORD i=0 ; i<dwConnections; i++ )3 A+ b( E) Z$ w* l- N
                { 4 Y* \' F7 a8 n# {3 n
                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
3 X- R/ f  ]5 {: x* \% i                        mxl.dwSource = i;( X' i* R  S$ I4 d* n
                        // 根据SourceID获得连接的信息 1 F8 e1 j+ ^# g( J
                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl, " q9 U( q+ y$ c; c- _9 T0 O3 u
                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); " C, ?& x( S$ D+ `/ @- Q3 [! E
                        // 判断函数执行错误
: e1 A6 K/ V- K5 D$ B+ b                        if( MMSYSERR_NOERROR==rc )
" ~/ Y  `# Q+ m& r) S                        { % R" H$ v* _  S9 J$ ]3 b/ O
                                // 如果当前设备类型是麦克风,则跳出循环。 0 x* J0 @. G/ f: u/ `
                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )# ~' K" T7 n8 C7 _1 {/ j& j
                                { 6 t7 i0 S- |+ I  T' a) ~. S
                                        dwLineID = mxl.dwLineID;
- a- @5 n0 w3 \: I, a, w/ B                                        break;
6 V$ e' u, L4 G  b4 `, v                                }
3 m* E5 p! H! R3 I1 i* ]# \$ h" C                        }( X- C+ e  v0 n$ D( K6 o* B# d
                }! l+ s: h; G+ Z
                // 如果没有找到,返回失败。 / y. d4 ^( z* T
                if( dwLineID==-1 )
! {6 ]2 ?4 }+ q/ W                {
# Z& S, m: u7 `2 {' _; U" U                        //尝试其他声卡
" \. z% a  f8 \                        continue;
& l2 @" q4 D5 {8 p- r4 q  E2 p& _                }  D: j& V( n# o9 I/ y( @/ M+ [# D
% l& U  q$ _8 W- N) V

- H; `( i; U9 Z) o3 Z" _                // MIXERCONTROL 结构体变量清零" n. `  w7 b  Y6 G& K( Z
                ZeroMemory(&mxc, sizeof(MIXERCONTROL));
# P+ j' \' \) e6 E, Y# b% s
: S: K$ |0 u1 U+ Y! S3 {0 W4 n' f$ ^4 L- v5 q' W- D- K
                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本1 K" t# W6 K3 {
. M8 d- A. C# T7 d5 v
' e7 B. ]! N4 x  }1 E$ ^3 q* }1 r
                // MIXERLINECONTROLS 结构体变量清零
  H  q9 h0 i. q3 g6 Y- s( M. L$ x6 v                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));9 j  l6 ]* O1 X7 G
+ K9 v5 K6 Z: O2 V
: w/ s! s$ p1 X# S) ^
                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本9 ~4 p* H- d7 M1 I3 v! v; C5 W, m
& H& \; u  _/ W4 Q6 t
/ m- K* R' L0 Z( W# B2 X
                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识" \4 B4 J% {9 j1 U" u
                // 控制类型为控制音量
: o% Z1 Z, F4 u                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;) [5 r$ ?0 m  a
                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数8 P- M+ K* `/ [+ m
                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针( _: C9 N" P2 m/ z; c
                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小+ l, B4 o: H9 i# d! n" n

3 W& T1 g1 \, D! p' j6 h
: I( i: b& p4 G5 X+ U  p9 r+ A                // 取得控制器信息8 |& {( M; l+ t
                rc = mixerGetLineControls((HMIXEROBJ)hMixer,. s1 A- m  E9 c+ O" N- q
                        &mxlc,
( q2 k  R0 M' I                        MIXER_GETLINECONTROLSF_ONEBYTYPE);. n8 e. ^  E: N2 {& K
, Y) U5 Q5 P4 P
/ K! r* Q. s; z, n$ y0 x
                // 取得控制器信息成功的话,则
- v& L+ D/ m4 B' n6 Z) ^+ o                if (MMSYSERR_NOERROR == rc)% R/ _$ Q/ v9 P6 H) T8 v! W. w
                {
, J& R3 N; i6 d) R1 n* s                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.9 o6 M: C0 E4 n% [" ~
                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
% R( ^4 C; Q5 U8 I8 h& {                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)) z; s+ `6 B" O0 E0 {) f

) @$ s* \: a# h
! G1 w5 O) J* u; v" M                        // MIXERCONTROLDETAILS 结构体变量清零
" @# W" f8 Y5 Q" L0 h$ e* U+ f                        ZeroMemory(&mxcd, sizeof(mxcd));
3 r/ _' ]; ^' W2 E7 H0 O! w3 ?+ W  J$ c8 ]4 @
+ n) g! t* Y& w) D8 `
                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本
% w9 M" U$ m3 o4 C$ U                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识5 S% v4 K/ B3 k6 t' O( i
                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针% S8 N; @; Y5 I
                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
9 N; r7 t1 a5 Q  O# \- j9 K8 _                        mxcd.cChannels = 1;                 // 取得或设置全部通道' m4 ~4 y3 y2 S
/ O. n( z, \' F. y% T; c

2 Z4 W, T) J9 h- n! D  d                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
7 b) M7 T' G; P7 d: `" T0 H! y" g0 S; B) H/ p# Z
5 j8 h5 x: F4 }/ j* b3 R
                        // 获得音量值" ^% f+ \2 Z6 N* \  X
                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,
9 a* H) c( [& D( L4 }* p& m                                &mxcd,3 W, O# p8 F" h( |* n
                                MIXER_GETCONTROLDETAILSF_VALUE);. Q. ^8 `7 A6 b* o' \7 I% P
; G6 o6 w4 w& k4 G, Y" Y# j

( ~, G- u/ A" G/ w% }. K- s                        if (MMSYSERR_NOERROR == rc)
4 C/ }# v* n8 x5 s7 M% m* h                        {/ E' Z# T4 C6 j6 V# g
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;- H; c, y# N2 b8 J: d% ]* N8 o

; ?8 g: v3 O: s* e1 g* L! Q% |0 B' {) I2 B2 e+ D2 D0 U* T4 _6 I
                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;
9 u  U/ A  O' O/ ]% M( e+ Y/ n                                printf("音量:%X", volStruct.lValue);  A3 F6 J$ @5 h# C
                                return index;8 d% y* j1 E' w# W- v  @9 B
                        }" {* p5 Y- g) `& I/ r7 m, k. C4 J
                }; }! D  X( p* ^! C0 R1 e
        }
2 _1 v3 \9 v. A2 d* q1 w" c  G8 q+ w( o; V' ?" g5 [  J4 X

9 C2 p5 y5 b. ^% l; S" Y        return -1;; M) F! j( r$ }( l' i
}0 n# {3 H4 }- r4 g
# ?2 d: b/ W: @! [$ W
        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html. R' A2 I6 {" ~
                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 11:50 , Processed in 0.019831 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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