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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/1 Q% l' P6 a2 W# T  K

# A9 e0 {  Q* {参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:. g$ X+ k+ K+ @& ~; Y! w. D# N4 v# w

/ V3 _# U. E: E
4 ~8 ]6 B% c; N$ R% g" Aint DeviceManager::getAudioInputVolumn( const std::string &deviceName )
5 {- q% ~) p6 Y* T4 f  ~{& w  e8 C( B$ L

0 M# @/ B& B1 H3 w# e* ?
/ y7 T' s5 I6 Z6 f( h: n. D" ^) e4 Q        MMRESULT          rc;     // 多媒体函数返回结果变量
) U- t$ X& S0 h" J$ G2 P0 x        HMIXER            hMixer; // 混合器设备句柄5 v$ _) R6 G# {2 r0 l8 {
        MIXERLINE         mxl;    // 音频线路标准状态信息结构体  S8 \  W# Z; L/ M1 f5 ]9 P3 ]
        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体
5 |8 Q, P) O  l* ]8 J2 S/ v        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
, |8 i- ?$ `& a" E: V% c# T# t5 e
5 _% M: X) \- O) g% J$ ]
1 u9 m& s* A. G        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即
. s7 x$ h2 J7 P- j+ F+ X& D        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
# P( Y+ G( n  A+ b       //可能还是跟声卡驱动有关。- f, @: M7 S1 Z1 v
        for( int deviceID =0 ; true ; deviceID++ ); O* X  o, m$ H% d
        {
5 T/ L( @7 o) p; b! i                // 打开混合器设备
0 l- B0 E% O) Z4 s& @7 U* U                rc = mixerOpen(&hMixer, // 返回的设备句柄
$ ?6 F" i* I: U6 W# z                        deviceID,       // 单声卡的设备ID为零( V) {. i2 D& p+ M
                        0,       // 不使用回调机制; E2 w( Q7 F! j+ N# K, U% [  u
                        0,       // 回调函数参数5 }2 q. H' X: w4 H; K% R" V: K% w
                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID! a# p, L6 ~1 m8 G( |
                if( MMSYSERR_NOERROR!=rc )& I2 r7 U4 u7 D# K. n7 u
                {+ B( d8 V# I' E* ^3 R
                        //跳出循环( V( s% N$ |6 B6 h- S
                        break;8 F  V" G9 n/ y, E
                }
* f. @5 d9 }  _' s                // 打开混合器设备无错的话,则
& k( m* h3 P; U& Z( T, I
& h0 S, h5 }) C2 [  l- R
* f& X& j( _& f/ C                // MIXERLINE 结构体变量清零2 U, Q+ d5 x/ p& ^
                ZeroMemory(&mxl, sizeof(MIXERLINE));
. `, h+ T) ]+ _5 V" R0 d
8 Z  ~# [8 Z1 Z
$ l2 N, q7 g  P& [; Y4 E( Q8 y) \                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本
* J- D/ c2 ?1 ]9 ?) d+ h( b  {& [                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS1 a8 R2 M& d% b
                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
9 D4 m6 t0 F* G: x/ C* p9 A3 o2 k$ U& Q8 c. p/ q. s& F. z

* y  v. }0 ~* T2 W& L                // 取得混合器设备的指定线路信息
# y, Z$ ?) M. W# p' g! u                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,5 Y- @" o* C' X" T  S2 R  z% n
                        &mxl,- s; f# f, ^) W; ]5 l( t+ U  \" C3 r
                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息
0 |. b6 ]% V) u: l3 Y                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);' K% W. A3 `( G5 {5 {, A! O6 x
                if( rc!=MMSYSERR_NOERROR )- v( c0 E9 ]) f; o! H
                {
: {# z" ~; u9 K                        //无法获取声音输入线路,尝试其他声卡8 p% {# @7 i' a  t( P- E8 I: A
                        continue;% h4 c" w& p3 d5 b, Q
                }
/ z  n' B6 s- P* q. b0 Y$ }% P) P4 H; u( `3 U  p( n

) T. w5 e$ t) d. x$ d) a" F3 h                // 取得混合器设备的指定线路信息成功的话,则6 X% T; t9 r; n
6 f  f+ s- X  H; q

2 R+ E. d5 w/ \$ Q' Y" b                // 将连接数保存 8 _* G# D" a; f2 n; @8 u& f
                DWORD   dwConnections   =   mxl.cConnections; 5 {- s6 x, h$ K: G1 U2 M
                // 准备获取麦克风设备的ID , P( |5 E* K) j; S
                DWORD   dwLineID = -1; " m$ w  w4 u9 R9 c- s- ^
                for( DWORD i=0 ; i<dwConnections; i++ ). a6 L& ]0 E* {' W2 Y5 q* B
                {
+ k9 e2 X3 t7 x! M7 ?" |* Q                        // 枚举每一个设备,当Source的ID等于当前的迭代记数 8 I3 w0 U& h; K& j( L
                        mxl.dwSource = i;2 P" K5 K: _* p$ f; h
                        // 根据SourceID获得连接的信息 , n( c3 f+ B3 k3 j
                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl,
* a3 y' k) s" G7 U$ {9 Z6 s                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); / T9 ?8 O4 I$ l; f2 K+ }
                        // 判断函数执行错误
  ?! O0 x5 D4 D' G" E" N                        if( MMSYSERR_NOERROR==rc )
& A! |: h7 J; P" Y) c                        { 2 x; W' T4 L' ^2 j( p
                                // 如果当前设备类型是麦克风,则跳出循环。
8 M0 d9 j0 G0 N4 V: s% h" {! X; l                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
3 {5 D9 {8 u* C! ~) D% c7 _                                { 6 L$ D; m2 g/ r+ l& Y
                                        dwLineID = mxl.dwLineID;
$ J1 ?$ R9 w9 L$ b6 K2 j9 {                                        break;
- M4 Y5 ^7 @, Q$ A. P9 Y                                }+ y. f3 c; |% P& T# Q8 ~+ N2 ?9 b& C
                        }) |9 o+ h; [3 B0 ^- z" {3 A
                }
$ c( \. q% x, E& Z* x                // 如果没有找到,返回失败。 $ k! M3 N: W& L4 o  x4 n& s, G
                if( dwLineID==-1 )  }+ n0 _/ \* L) u* A& I( ^
                { 6 m7 _- \6 g5 V' _' ?8 \
                        //尝试其他声卡
9 H8 t  X5 k9 H                        continue;# [# v  o- r) s! T
                }
: B( p- y3 ]9 c/ Z
" @7 a3 S7 D. ^+ i- n4 |: l3 v
2 Q! i$ Z9 r/ z1 _. ]                // MIXERCONTROL 结构体变量清零9 w9 }" `# x0 ~4 R6 |
                ZeroMemory(&mxc, sizeof(MIXERCONTROL));
9 ]; Q: B& l4 @7 s) }, l  }, G7 _$ m, ~! y" `

# I  c% x( q1 M9 T# B                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本
4 p* w  r8 P  ^9 r, q  |' d9 b
7 }; J3 p3 ]; `! x  j: ~8 u; }- Y# _1 ]; b# [. @
                // MIXERLINECONTROLS 结构体变量清零
7 Y' F; G% f) v( g( H                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
, I$ e4 J! a+ L5 R* {! E) i6 a* ~, Z' ]5 h, Q+ `

$ E7 F# M) h0 Q/ _/ q                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本7 j7 [! l1 |- o( U/ B

" T* b: B5 F& s  o* Q+ D8 \
1 @. g0 I$ s- a& B4 V1 g                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识
# q3 t. s$ o( c' B% ^, p                // 控制类型为控制音量
$ C9 `5 V) a( G# o' N                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;1 d$ \+ a& }" ~- v
                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数3 T) Y, k: B+ w  E  M( V, [
                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针
7 P1 g) u1 y( t* ]8 \                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小
' h+ B, |2 U6 ?; W6 W1 k$ [6 b2 k3 w& s) S* B
9 F3 q& e# k; B  L3 Z; z. I
                // 取得控制器信息5 W- u' T7 f4 X2 c9 q3 j" U
                rc = mixerGetLineControls((HMIXEROBJ)hMixer,
3 W+ r/ |* j3 o5 ]                        &mxlc,( q3 n( H6 Y; w7 l: y$ d# a
                        MIXER_GETLINECONTROLSF_ONEBYTYPE);
" A8 q0 B+ d6 j$ W0 ?$ k+ W
% G% w& x5 f! K  @  z, [! X$ [. X2 R9 k0 T8 i" n4 _: t8 v
                // 取得控制器信息成功的话,则
2 N" j+ Y* L' z                if (MMSYSERR_NOERROR == rc)
, m- c- N* d* r6 K/ x; C/ o0 o                {! |0 G7 K. W/ W3 `
                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum./ g: I" o) u4 I9 v7 A0 K
                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
+ v' g7 E; k  j( X. l                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)6 g. p9 `% `& b8 V, @
$ ]' r( V, }2 W3 w4 d3 |+ A

, m4 Z- q# O. }+ h. B  Y2 }2 l                        // MIXERCONTROLDETAILS 结构体变量清零. M% E" |4 z1 T& t
                        ZeroMemory(&mxcd, sizeof(mxcd));
: H' W* d5 m" t3 v
# Y6 f8 a8 H0 ^$ j6 f8 l) r  G: t7 `1 U$ k; c. g& z8 a' x
                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本
0 l4 ^* z$ ~. W5 g7 w                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识
. x& i, Z, G5 y3 |, k6 ]+ t% b) o                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针
3 Z& _4 r/ m; j' B% B# v$ a8 C                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
7 U+ r$ p1 l, Z; ?                        mxcd.cChannels = 1;                 // 取得或设置全部通道, Q* T9 w# @- C. j$ V, d& S
$ @5 i. A2 @: J
7 R; c# s) K) g) H' k
                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
. N8 i9 K! D9 @0 Q+ o: u
9 v3 `% I" S3 b! `3 G/ W  \/ ^& _! }' v4 Z* g  g
                        // 获得音量值5 S# \: [7 G1 H6 [* u1 r
                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,  j! }! b* K5 y- T! \9 C6 ]$ l
                                &mxcd,
5 p/ c3 X1 Y% q* n                                MIXER_GETCONTROLDETAILSF_VALUE);" u$ C( N' S" N" {3 N) [

; d( i, U, Y/ D# i6 Q" [' p+ d
$ b' k! I/ W+ h/ u! |                        if (MMSYSERR_NOERROR == rc)! o5 h& a3 W% h2 B& w& V0 e4 g  k
                        {
6 W5 T+ S' @+ i" O                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;$ _/ [* ~. F+ R( Z( B7 H/ }

3 v' d% s* |) V9 _$ P) Y
. ~0 R$ q7 O1 H0 r6 g) r5 V* j; ~3 @                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;4 ]! c+ i4 T: |  m* `. L  A
                                printf("音量:%X", volStruct.lValue);
" U; [) D/ q, u$ ^' r                                return index;
0 Q2 n6 w( }! k" y6 x& W                        }
/ ]6 a9 \, ]' Y                }, a6 o, c% H  O5 _3 F
        }
0 p; ?. n  n, e0 C* X* u
- s! {& p2 F- [  Z5 N, w+ M$ t7 N# i* h/ i  R, J% w3 x5 `. t
        return -1;; x- S; `: ^9 P) D
}
; T0 X: f% T  P5 j+ D, k
& s. R" Q* E" _1 H) ?* o        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html
0 I/ ]* k* z9 \5 p0 F                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-8-8 20:15 , Processed in 0.036922 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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