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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/, u, F- W& c9 o( k( t1 Q# v1 m% a

& Y. y% I6 f( X8 X4 N参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
; b7 V* t, u5 |! J# {- h+ x4 H! g7 Z# ]+ i
& O  D2 r% B* P
int DeviceManager::getAudioInputVolumn( const std::string &deviceName )
* K$ G1 c! P* u5 |. v/ y  t{8 \5 F% I$ j% ^, X& J$ s% k
1 _: i, I5 o3 h5 O4 Z
% H& |# W! K* A
        MMRESULT          rc;     // 多媒体函数返回结果变量0 G; c0 A5 z1 S6 u9 b9 T" S  q% _; ~
        HMIXER            hMixer; // 混合器设备句柄% ~9 G( e* i4 A& \# N+ o7 f
        MIXERLINE         mxl;    // 音频线路标准状态信息结构体
9 t) ^. l$ O6 ^& }! `5 c        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体
$ c. S) D5 k+ x& v        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体6 {6 b1 W; i5 {* }

) q# h+ l; ]$ l9 W2 b% t
  d; }: o: w' Y* Z$ ?        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即
" G) z- k! v2 }+ y        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,$ M9 J' z' x% ?7 A8 `( i
       //可能还是跟声卡驱动有关。" a. q8 S8 B/ Z/ n
        for( int deviceID =0 ; true ; deviceID++ )0 a0 q0 g: a8 a0 E5 t
        {
% W( X8 a; g/ m  w+ M/ R3 ^0 v2 j5 O                // 打开混合器设备
7 c* M& |, N; K" S* p3 C1 f1 {                rc = mixerOpen(&hMixer, // 返回的设备句柄- x; w6 b2 J9 `7 W
                        deviceID,       // 单声卡的设备ID为零
  e, w0 d% H2 {: N9 \( Y                        0,       // 不使用回调机制# r" k7 B4 W/ P2 S
                        0,       // 回调函数参数
8 b; ^, F6 _) [: z2 |                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID' P  }$ c- E3 d# Z1 `$ z
                if( MMSYSERR_NOERROR!=rc )
/ ^2 n( f! i9 I7 e1 L% p                {8 a7 e; ]9 r* I
                        //跳出循环9 Z9 I6 d: p7 R0 ~# z
                        break;# a( W9 l0 k0 a4 f0 j  X$ f
                }' c# i3 Z# ^. I6 x/ X( v
                // 打开混合器设备无错的话,则4 J! R: W  p9 p! P
% }% g  X3 p# y0 l
& q* Q- a' W* w8 x3 s- W
                // MIXERLINE 结构体变量清零
# c9 A8 A- `; W4 o                ZeroMemory(&mxl, sizeof(MIXERLINE));
" ^4 ]% p* s9 G
4 n* O6 F6 [$ `8 l& D
  p( S5 t7 v4 x$ s                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本, O6 }& y: O! u5 H, i
                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS* W! n% v5 v+ e
                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;0 B+ Z" q6 B2 |9 R6 n

! Q' D+ L2 B$ w5 B$ O# G" }/ B9 v( X$ y8 T
                // 取得混合器设备的指定线路信息
3 {0 c6 x' Q$ s& y, E  [                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,
9 \. U& O% ~1 f- X                        &mxl,: ~2 K0 d3 g# C; m  ?6 @
                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息
+ x6 S3 U5 v6 I! l% _6 Z3 i                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
% C9 Z* b8 d$ ?! W/ n2 J3 i                if( rc!=MMSYSERR_NOERROR )
' U5 ^6 X/ h$ O3 w" F* @                {
$ n. C) q& p7 p; y2 r, y" v. j! a2 K                        //无法获取声音输入线路,尝试其他声卡3 C1 S, @" l' N; v' Z
                        continue;3 b" ?- A& h9 L. F/ I
                }
( `4 p/ U% x- Y" O  s/ v! i$ t4 p

# K' i) n' A, m' b7 `                // 取得混合器设备的指定线路信息成功的话,则0 H1 K% w3 N3 q' p* D
* R4 H! T, ^( P) ?3 \% i( I

- ~5 m* `% n9 m3 j& i                // 将连接数保存 1 f: T7 y4 s7 F6 p3 ?
                DWORD   dwConnections   =   mxl.cConnections; & A) _: q3 F5 i) \
                // 准备获取麦克风设备的ID 6 q- [. _& e0 d2 s4 M8 V7 ]. h  @( H
                DWORD   dwLineID = -1;
- M% _0 P4 y) \) G                for( DWORD i=0 ; i<dwConnections; i++ ), b! n# N, Q' m+ B
                { : S$ r: ?, i& @, X2 N4 J% U1 T
                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
: ]2 v& V) d9 C2 e9 @$ K                        mxl.dwSource = i;7 D" I, m/ d0 ^  W) ?) ~* a
                        // 根据SourceID获得连接的信息 % ?, j. K5 Z- o( F+ P7 F
                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl,
8 y8 s; k* X# h# p                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); * }& T2 _8 M- h( I- z+ L5 i5 {; b5 n; J
                        // 判断函数执行错误 . h) {% L& Z+ H7 l& h7 a
                        if( MMSYSERR_NOERROR==rc )
: r1 n/ w4 @9 ?- [4 R: Z                        { ) _$ w! l$ ~2 u9 Q# F
                                // 如果当前设备类型是麦克风,则跳出循环。
7 L; M3 H7 c- r7 u' [, T                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
$ L  z% R/ F' a! c" E                                {
5 n! v2 Z! M8 b2 N, K                                        dwLineID = mxl.dwLineID;
+ q' ?4 f6 W3 |1 _7 Y                                        break;
/ C) n# i8 U( C% ]0 Q                                }( Q( f! \6 d! l
                        }3 U! o* ~0 v3 N: }* Q
                }
2 I5 O" T! I' w  K) }$ f                // 如果没有找到,返回失败。 : O3 w8 s1 H+ @9 Y3 p
                if( dwLineID==-1 )
/ k) w# Q  u, w% ]( ^& b3 d) \                {
0 L' Y, }; ]# C: R+ |; v  r* `$ m3 y/ d                        //尝试其他声卡; D. W2 G) q; }1 @
                        continue;: J6 }5 i! e+ Z0 X
                }
  e3 X: x! J9 l: n8 ~3 p
$ y9 J$ M3 O3 _2 y3 W; s
9 u# d) B# S/ I$ |2 P0 J! h9 z                // MIXERCONTROL 结构体变量清零8 P4 a" ]' z) D7 U2 o* m# S
                ZeroMemory(&mxc, sizeof(MIXERCONTROL));
) S7 G: ]- n3 c9 l
. s& Z- W3 t9 I" i2 I' y; W
* C+ B2 J4 L$ X' x: `                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本( B! |, i) u" n/ E5 r( I
* y+ d8 [) O2 q! Y2 k7 T# ?. c
5 {& _, d* A. q; G$ S3 q: a5 [
                // MIXERLINECONTROLS 结构体变量清零
6 T6 D: L1 L1 \, a0 W                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));# i$ {( u( o7 E! ^( B
! F, ]2 [. A5 L! S- X2 r2 o
' ~7 J, ~) E. u& ]
                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本
5 H2 \# F* \5 Z9 g' E' K+ ?) _: e/ o2 I: y5 |' `' P) Z
# i1 V2 ]  ~- D' q* R: ^+ {
                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识
. `" I& M1 f* M                // 控制类型为控制音量
( h6 h, S% E! [/ Q% W* s                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
! e) a9 q6 J/ ^/ c                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数8 M- U9 K. |3 O! v& I6 {, i. f! p
                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针
. P0 k) I9 C5 f6 n) _# f; `                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小
1 N9 l7 `; s/ j' G2 g
/ U+ c& \! J) [) ~: m) F$ _2 m; ?0 m+ T+ `- w* J
                // 取得控制器信息7 Z' f) j% O6 j; E4 a4 P7 ]3 @
                rc = mixerGetLineControls((HMIXEROBJ)hMixer,
8 {5 j6 \* Z7 ^; n& H. R/ _" X2 s                        &mxlc,
: }: [6 e5 u  _& i                        MIXER_GETLINECONTROLSF_ONEBYTYPE);- ?- O: B' e" X, m. t- y
" ?- {4 L& R, S3 E8 _
0 G+ |  u: a& T3 x" |8 R% ?2 E
                // 取得控制器信息成功的话,则+ v0 E. f6 r3 O! b% }, Z- O! f3 H
                if (MMSYSERR_NOERROR == rc)  T) @8 K; E# V7 w6 @# K
                {0 W: M# S4 o- a) O
                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.4 v" }7 Y. C( D6 ^' d; C4 D5 [
                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
: W/ g  ^0 s. k0 K                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)
& |' |7 b7 ^6 F' h9 S# i* T
' ^+ D, F4 I2 _3 i% ]7 K, |7 {% i, s+ f, `0 \& }4 r+ N% c4 b
                        // MIXERCONTROLDETAILS 结构体变量清零
2 n4 _4 F" }6 k& s                        ZeroMemory(&mxcd, sizeof(mxcd));
, \9 m8 j; C1 A2 O+ X0 z
9 S& z% {8 D, H3 \1 b+ R8 ^" J0 E/ {9 k8 x, D7 _
                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本4 q3 W. [! o1 b4 m
                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识+ ~0 x6 ?: p" v8 C* _. u( l+ G2 }
                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针
" i: P7 l: J5 @" N; \: W. B" C4 R! ^                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
! x9 }% i0 C6 V) H& p/ a                        mxcd.cChannels = 1;                 // 取得或设置全部通道
% |0 K, K. G- ]9 J$ l
6 H5 Z, j) |1 v/ e' L
3 g8 [' V  T+ w" z" e1 `                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
" c& d1 f) D/ |4 c9 Z
+ U" s! M& n  s. J' q; \1 v8 m; j
                        // 获得音量值
7 m3 s- l4 Z8 \; C. I2 Q                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,
6 Y* q7 R8 [( `                                &mxcd,
  p' y+ X" q8 Q! h( a                                MIXER_GETCONTROLDETAILSF_VALUE);
: z; u+ x+ z  Q9 @% C
, S# d8 W5 H  f1 x* P
2 m2 ?4 Z7 y1 ~1 \- W0 r9 R1 E                        if (MMSYSERR_NOERROR == rc)$ W" @( ^$ ?; \: H! S
                        {  d$ F1 [  z, D8 m$ Z' X
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;
2 Y( L" {" E% K! [9 H" q! m) A/ h
/ Q% w4 B: ^" z5 F0 A/ Y- F) V% P
5 V2 t( y" m7 \$ Y                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;' h' Q& |7 }4 `0 p0 l( O
                                printf("音量:%X", volStruct.lValue);0 D7 o8 i. T; V% |0 w8 b6 N
                                return index;$ w+ W; i6 x; x8 S
                        }2 t1 a" F$ \/ C% F; r& n* e
                }; s* u) o$ k; Y! y1 [: D  I8 V
        }( o% S4 u3 J$ K) D8 e  |5 f

2 c1 n, S* \. B5 e, S$ K$ S# W6 u3 N3 M( G6 J; q& c
        return -1;
3 t! i# o' L8 j4 G) B0 |}& g& B  i+ b5 `- r& K+ m4 s* e
) m. ]. }+ D8 J1 n
        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html
2 E0 N. q5 r9 Y& H/ J- l                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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