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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/
( x: d% A4 c6 N3 K, l; c4 y" ?$ \
参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:: Q0 B. `' P8 n' P" K; j

; e  Y; o6 H- |9 Q+ w3 r
0 K9 @( W4 L  l5 Cint DeviceManager::getAudioInputVolumn( const std::string &deviceName )
4 U; K" f# W1 u; M) o{
, b) i- j* _1 q" k) Z: [3 r8 l1 w. N2 z% S+ i; y5 c7 Q# \( J
( f8 X8 I  N8 H0 U! M- u
        MMRESULT          rc;     // 多媒体函数返回结果变量' R8 B+ f# ?  z- ^, T5 D9 V' j
        HMIXER            hMixer; // 混合器设备句柄
  G+ {$ k3 s! K* P/ A0 P: i3 q8 w        MIXERLINE         mxl;    // 音频线路标准状态信息结构体
; e7 J  {2 ^( ~$ |2 \' P" f        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体
1 P+ [6 l' V2 B0 a# t  C  X        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体9 X- k: X1 f) z% M

$ b# u0 T& Z( u: u+ W0 ]# q  k$ ~- ?/ J1 g, M$ F
        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即2 N7 D3 [8 ]8 k: ?5 l2 `# G
        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
( i5 ]0 j* Y8 X8 e/ w" t5 w: c( w       //可能还是跟声卡驱动有关。* |! Z4 l6 X7 @- h/ H2 |2 {
        for( int deviceID =0 ; true ; deviceID++ )
+ {  d. ]8 e' M& {2 V1 o& ^" z/ C        {1 a8 v" @" n4 q7 [+ b7 H' N8 G
                // 打开混合器设备
3 Z# v  ]* H0 ]$ O4 n3 m8 d                rc = mixerOpen(&hMixer, // 返回的设备句柄
( e+ L' G( [! a! G5 U/ D                        deviceID,       // 单声卡的设备ID为零. Y' e: v/ {/ i5 o& C
                        0,       // 不使用回调机制6 c! v& X7 y# m6 U1 K" \
                        0,       // 回调函数参数6 J$ t  l: O1 v0 u+ m# e
                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID
3 g' ]4 @2 D' `# D" ]0 u/ Q: Q- c                if( MMSYSERR_NOERROR!=rc )
, e/ o+ I6 v  {4 l2 Z% S( T                {! ^2 {' O$ c) _3 I, i' s
                        //跳出循环
' T, M" M1 j3 C+ ]9 r                        break;
; n4 a4 y' f9 D' L% s4 C- b                }
1 J* {" V" ?8 e; Z: c5 T: U                // 打开混合器设备无错的话,则
0 D, z2 {0 l3 t3 F
3 P. p" |- O5 c4 d: {7 H/ s+ l2 ^4 {9 o' m% f& c+ C
                // MIXERLINE 结构体变量清零
  v; f9 N& @  L) J/ S2 [: S                ZeroMemory(&mxl, sizeof(MIXERLINE));* d8 R; }/ a! G1 D; {( Z- k  y4 e

6 {+ d# N$ o9 v& Y
3 b4 g/ Q* T, u: W- t  u; _# k9 B                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本6 o# b% j" u4 M, H
                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS$ e2 O- _$ U/ w$ u, U
                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
( B/ }! g& U/ _! u! x& O" a' o
  f. w7 t, Z+ U2 P! ^" j: H; K0 u- q
                // 取得混合器设备的指定线路信息8 i6 k4 a( v3 H0 x. y
                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,' |- o2 z. U' O& U1 }- K
                        &mxl,
" v: h3 G, J2 ]9 i+ N5 w2 _. A* o! e                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息
- O; w4 R  U6 R1 r" S                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);/ m2 B, \0 J# [9 s. v
                if( rc!=MMSYSERR_NOERROR )4 L6 j6 I7 F* |/ H5 x: S1 |, l
                {
* t7 ~3 p- [1 o  t7 Q. g                        //无法获取声音输入线路,尝试其他声卡
4 C( h- a& H8 T+ a& t# ]9 n7 ]                        continue;0 Q1 p$ @: z: b2 s; u
                }
, e) M6 D1 F# Z1 M/ W7 E. O; l
0 o% u7 P& x- q- ^1 D
                // 取得混合器设备的指定线路信息成功的话,则6 f! \' A/ F9 \) s: x: [  S
/ ^/ {9 u; |9 S$ \3 h4 j
5 y( l) s2 p; Q! a  ~, Y0 Y5 B
                // 将连接数保存 & B; n- @: ?4 b  p% O
                DWORD   dwConnections   =   mxl.cConnections; 7 B8 l( }6 T# ]2 I' U1 F
                // 准备获取麦克风设备的ID . b, d7 \9 e: s0 ]' i- l
                DWORD   dwLineID = -1; ! Z/ l& E- T2 L- }  I0 \* Q
                for( DWORD i=0 ; i<dwConnections; i++ )
3 H* i, Q8 L+ m) `+ Z$ Q                {   X9 c% z; q9 T' b4 a4 z7 T& T
                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
, G- Z. u* C3 N+ V$ ^# W1 R2 s3 {                        mxl.dwSource = i;
8 N% m1 j- f) Q. U0 |$ \* A                        // 根据SourceID获得连接的信息 - o9 u$ I( A5 c& X( M, y
                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl,
% e0 k  q  S% [3 ~3 r( k  l' F& z: l, L1 h                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); 9 u5 t5 N! e: u* b2 {1 `* @" |
                        // 判断函数执行错误
5 k" Q6 |$ ~6 y* C- B                        if( MMSYSERR_NOERROR==rc )6 ^. N3 O' ]" U) \2 _
                        { % p- A5 W* ~6 ]: A, A: t
                                // 如果当前设备类型是麦克风,则跳出循环。 ' u/ ~& ~+ A% G: I. X) K' W8 h
                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )3 I9 ]( v1 D; z2 q* ]) l2 P
                                { ; G% h8 i2 Y0 i; d$ M7 o+ ~; ~+ O! |
                                        dwLineID = mxl.dwLineID; ' e2 {/ @# f$ x0 J5 K; X# c3 J
                                        break; 2 G- G& H7 C6 C- U+ ^* ^/ O
                                }% G8 N; B0 S- ^7 W
                        }! R. p" {2 l5 k
                }
( J# @9 E/ {% u# }2 `. i                // 如果没有找到,返回失败。
% I" \5 B6 n5 y7 E, G                if( dwLineID==-1 )
, o+ C0 z# q- G5 }: y! n1 ^$ L                {
& r8 H3 M1 `, m2 R2 f* P' Q                        //尝试其他声卡9 U6 E9 m: W$ P; N2 f- q# X( O  q. T
                        continue;
9 K! I$ i& v6 h$ E                }. ?: r/ |( n' X2 C7 s  `/ f* f
# C) w* k, A( N0 Q  [4 H
9 [% c' W& b, U& h$ V* h. G" h; c
                // MIXERCONTROL 结构体变量清零
) t/ L2 r* g: g% ?$ F' }% [) d6 S                ZeroMemory(&mxc, sizeof(MIXERCONTROL));
: V! V4 A& M" t8 ^5 I2 Z8 W/ n! X& G9 R: q$ H

& u! d, _) g* j- E                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本# g4 Q! m) L! y$ Y2 l

; G5 S' R" X2 @; R
0 }' o3 D" c; F" B! t/ M                // MIXERLINECONTROLS 结构体变量清零
  M) w4 n9 O0 o9 G3 D" B, R$ T+ W* B                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));3 I( B" B$ e, {8 z
1 N# e. L$ `: }3 k) _+ I! K  n
- E% D; [, q! h/ i& \" S
                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本/ ~; z) u6 E' i( I% b' ~3 Y
& @* P2 j$ W0 v! r" m; L
3 M" h& U" q8 i4 B' x. x2 v
                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识
0 a9 }6 L9 u8 q* H$ T* G                // 控制类型为控制音量
' M2 T! o' F$ z5 b$ q/ a9 C                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
( t0 X- ^+ |2 ^3 A                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数
  u- F  ^/ T, l: s                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针
. d9 B; V' T0 C( G) E                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小  R! g# p# S: x( u
* i3 [2 q, Q( M( Y5 D7 O
) Y8 B# D+ @$ Z5 ~. }: Q
                // 取得控制器信息
0 I& p: B2 t$ l                rc = mixerGetLineControls((HMIXEROBJ)hMixer," B4 K4 W6 K# P0 J' e
                        &mxlc,( P) g. b5 J, A8 E3 {
                        MIXER_GETLINECONTROLSF_ONEBYTYPE);2 A: s. m0 I/ \# W
& ?$ i; o! r8 S! k

2 y% P! P/ @  ^3 y. j) A$ f3 J  @                // 取得控制器信息成功的话,则
+ |. P* o9 X- c: w: Q# N                if (MMSYSERR_NOERROR == rc)
! X1 d. T7 K. u) g                {
7 m) s; |( F. B                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.  G# W  q7 J$ N2 G8 o9 B
                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
0 u3 W: |, v' b9 H* D) q                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)
1 s% j) M& S6 m4 R0 t; N) a% f( h1 M  n3 l1 k3 Z$ u/ |

- q: @* \/ _! V, t: ~                        // MIXERCONTROLDETAILS 结构体变量清零
" M! W% ^8 A% F                        ZeroMemory(&mxcd, sizeof(mxcd));, g$ E! p2 ?2 C4 g2 y: B

" o4 K) l6 \! I0 q" n! s9 k/ q1 e: R
                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本
" q2 O+ C9 M% p2 h  y! ]                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识. ?7 F( o3 B% ?) O! h
                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针
+ c- ?, P$ w, p4 {, q* I                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
! p1 a6 i2 x) k4 W# ]4 J                        mxcd.cChannels = 1;                 // 取得或设置全部通道
8 z) d8 \4 y# Z/ @* |) s2 r8 }, ~0 f9 w4 [: Y& [1 V& i0 k$ j3 `
5 ~6 @. p7 ?# j  B1 }8 ^, g) d# u
                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
2 i. j4 o2 T* d7 ?! K
; F( R) E, O3 a+ @9 T1 H. i3 x1 R/ o8 z' d# e5 Y9 y
                        // 获得音量值
9 R- U% L' V4 g$ ]) L! F; s                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,
. V' @2 E1 |' X% g9 Q, ~                                &mxcd,6 I) T) v) D2 G3 _! G8 k' `
                                MIXER_GETCONTROLDETAILSF_VALUE);3 t* B5 U: }& M
! g0 i# y1 h6 Z  D( ]3 J

  ^- Z' L5 i* K, ?6 i                        if (MMSYSERR_NOERROR == rc)
; d: W! W1 f. H- |9 @) H                        {) \+ \" p) ^. t7 Y
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;5 v" L. S1 Y  m1 Q

& M; L# c5 ~# a$ B( w7 B: j- t" T% J1 ~, y  m6 p. R7 u
                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;- k. {& _( w. b2 L
                                printf("音量:%X", volStruct.lValue);
6 N9 |$ ]) O; Q( e4 g% `2 j                                return index;7 A9 j& W: [2 c0 E0 t+ o
                        }/ d& J7 N) w/ U1 d; d5 `
                }
) ]1 `0 |; x/ Q% g0 {1 N. |5 k        }/ \$ a7 j  ~2 e4 T$ X4 d

. c' m4 u6 V' d! ]/ C
2 D) O% x- U5 U7 @0 S        return -1;* k5 V: U! R3 n# X' m$ Y
}, S8 _8 i9 x  ]$ d* M) L) A4 Z6 ^
7 G0 M) s9 R- m  e1 a+ V
        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html
# w' C4 P5 E6 P3 Y                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-18 04:57 , Processed in 0.019807 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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