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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/4 S" \0 U/ [+ H$ {' |$ _
/ c; r# n& N# K7 f8 b8 X0 @
参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
, E  N9 H; y: i4 e1 S# x. m& p- X" Z  ]( b! }
  U- E  [9 m5 T6 T
int DeviceManager::getAudioInputVolumn( const std::string &deviceName )
) Q- s, n* y& G6 E* e4 ^{' ?/ ~; ?  W, M- ^8 @! Z
3 K% e$ Q: ^/ e9 l: T

1 U+ w/ G  F5 I) ~        MMRESULT          rc;     // 多媒体函数返回结果变量
$ u$ c/ o5 f- d* l! R        HMIXER            hMixer; // 混合器设备句柄5 k3 H: b' Y. X/ N
        MIXERLINE         mxl;    // 音频线路标准状态信息结构体
3 O7 J: ?( o& k; r6 p4 r- R        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体  r* h% h. }$ r- o* ^
        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体$ M! H/ q; `1 |! {( r2 ?; w8 F

4 B4 ^4 y; ~& z+ w* Z' p3 \) _! b' R9 E6 m# q
        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即0 V& }1 P4 G8 b2 `; E
        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,1 ]( G0 f4 E( C8 l
       //可能还是跟声卡驱动有关。
7 y2 Z% Y  i; z3 G% ^/ S/ n! C        for( int deviceID =0 ; true ; deviceID++ )- j- E! Q& B! P& H
        {
' B- {; I5 s: i6 W+ u                // 打开混合器设备7 C% D1 P" ]' l  E! `8 Z$ T" ?
                rc = mixerOpen(&hMixer, // 返回的设备句柄
8 Q$ q/ ?% o- K. m, P5 x& U2 Z) R                        deviceID,       // 单声卡的设备ID为零/ ]- y+ s0 U# W9 r7 a
                        0,       // 不使用回调机制3 n1 [6 [2 h* m) p" {4 a$ h0 S
                        0,       // 回调函数参数
8 {/ l; h4 L6 {# Z! V0 j                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID
3 r8 V4 P* j4 G5 }% j                if( MMSYSERR_NOERROR!=rc )
; {5 j, O: ^  C                {5 |8 L# N6 z8 k
                        //跳出循环
; @5 r" K" G6 O, x2 ^* E" m                        break;
1 N: S# d5 e2 t7 p2 x                }% b+ O& k1 I% m8 F* _3 S
                // 打开混合器设备无错的话,则
( m$ P% M' u, I- x3 V8 m. f
& J5 h6 w0 F& Z) f* T( ^
- R+ p. P- ?" Q; G. c                // MIXERLINE 结构体变量清零
0 r0 x' B5 D2 x- a                ZeroMemory(&mxl, sizeof(MIXERLINE));
9 r' ^- c$ D- v$ x7 p* b! [4 W: r# _2 ~6 |
0 s6 q3 `. ?" x& R5 l. n9 [0 ?
                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本
4 d( e2 g" V8 Q: T7 w/ m& d* v; p                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS! E* ]9 l) A- N
                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;3 b, K- [9 f" n; M: Q2 c

3 V0 v$ k/ k; j- n
0 r! I. d. @: R/ g) S  k7 t8 o' F                // 取得混合器设备的指定线路信息. c8 u# s4 f9 B$ I. S* s! f
                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,
! f# t9 S7 O  n- {4 P  I                        &mxl,0 Y! g; L3 L- i& S( m4 m. v+ e
                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息
* p8 E! A8 u6 q                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);( @. U/ w$ j7 ?2 {! G
                if( rc!=MMSYSERR_NOERROR )4 A' [) w3 m" |% x6 A1 g5 v
                {" F) f8 O  g! W9 k6 q
                        //无法获取声音输入线路,尝试其他声卡
* R) S" x& M% a9 K                        continue;
) E  I% b7 p1 ]( n: G5 B                }5 Q) N9 o( L4 R/ C  M6 a) i
7 r" D& h4 h. t7 c

( e7 O5 i  W, Y% C1 x+ u                // 取得混合器设备的指定线路信息成功的话,则- c5 C1 J; x- @0 F

% J6 h: t) l9 |2 |& m0 e( |  V+ s/ B+ A7 G% L) O7 l
                // 将连接数保存
* D7 j6 o" w* S" c                DWORD   dwConnections   =   mxl.cConnections; " ~% g1 @7 S1 y# g; Q2 w
                // 准备获取麦克风设备的ID 9 R; @& q. V" E! }/ k
                DWORD   dwLineID = -1;
& x" d- v2 ?  n7 m- I( M                for( DWORD i=0 ; i<dwConnections; i++ )
- x2 n* N0 Q; ~9 ^' ]                {
4 B7 Q+ l, O. V7 w                        // 枚举每一个设备,当Source的ID等于当前的迭代记数 . Z; J$ ?: u& z, X' v
                        mxl.dwSource = i;
& Q6 ]1 Z9 T" y                        // 根据SourceID获得连接的信息 6 ^6 J3 o2 v) d% u2 C$ H: h' S
                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl,
0 k$ P" t- `. h( ~0 i                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); - N& i) v" \9 @0 l* ?' k2 ~" ]& @
                        // 判断函数执行错误 , C& a1 N7 q3 a. Y
                        if( MMSYSERR_NOERROR==rc )/ O1 D( I- p% x- M, v& S6 l
                        {
8 I! f6 y( y: U                                // 如果当前设备类型是麦克风,则跳出循环。
3 T; w* F& C6 a5 J  c) C                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
! B( k# v9 a" W. x: Y                                {
% ^7 W5 k2 x* M( K7 h8 n" e/ G                                        dwLineID = mxl.dwLineID; * z. V/ L9 q9 M! T  u' V
                                        break; + P1 L% N, `9 N7 z2 ~) g
                                }( M: W# J* o% N$ Y9 c! ^
                        }
9 l/ {7 e; a! B0 o( h. Z. Y. O                }& h. r3 Z5 `0 g) U0 }. v3 Z
                // 如果没有找到,返回失败。
" c. Q/ G* @6 R" H3 \( [                if( dwLineID==-1 )
: _1 ^& d- L' f                { 9 D6 m8 h, Z# A* g/ F0 \
                        //尝试其他声卡; ^( c' {. X0 v! I( x) N0 @3 P
                        continue;
' l$ j8 Z# r( d- [                }- Z; {, y4 u6 [7 _

' f) q# n& W2 s) r6 ^. g% t; |3 V: b6 X  L) H$ @7 {
                // MIXERCONTROL 结构体变量清零
7 G3 r$ e& R! q! k                ZeroMemory(&mxc, sizeof(MIXERCONTROL));
5 c, H% c1 ~4 X1 u9 U" w
! b& K& T1 E+ O8 D9 h; V, C, A2 @: b8 p) C, K
                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本8 u# f7 P/ [: k# p: G7 S

" d3 S1 q% O  d; R4 V2 j1 ?8 l+ b% W% a/ w  Y; T: m
                // MIXERLINECONTROLS 结构体变量清零
5 w6 @% l6 y: y! P                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
3 R1 e4 @  k; w8 x# `. |' a* i' Y, D$ Q/ p  _

! R( y5 ?, ?8 x+ k' L% l  |2 Z                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本5 _# M1 n  w; p/ n  h' r! Z

7 ~+ y1 M$ _% }" |8 r+ H% A5 C/ h  g' G6 s
                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识
& C% v$ @" R7 `7 `                // 控制类型为控制音量) {, d. m, n$ b+ n* d
                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
4 [, x, n6 C1 d                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数
  I* l( L+ h' g) P( a) D8 ~: Y7 K4 k                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针
6 n1 n) I  r4 u4 Z3 t                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小6 s" p& d9 X; {* t2 l: i0 t7 Q: C
$ h& q3 d, r* k+ X/ q

) J# T6 y) N& J8 f" c                // 取得控制器信息
1 ]6 ]* t; T( T6 O! o                rc = mixerGetLineControls((HMIXEROBJ)hMixer,
; G+ b$ C3 l1 k2 P                        &mxlc,# i* W+ S0 W# r( n
                        MIXER_GETLINECONTROLSF_ONEBYTYPE);
) g- ?, l, K3 q: \
8 U: v3 A9 k) U. N9 [. t+ u. W0 C6 X! H2 D
                // 取得控制器信息成功的话,则
3 {( w0 N; ?% F5 k; u' B3 Y1 z* z                if (MMSYSERR_NOERROR == rc)% {# O# i# {% l
                {
6 I( \# b1 X/ R& L* X. F" Z                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
4 ?- |* y' w( s2 s4 v                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息8 D* I7 `6 _4 A& J
                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)
& I" {0 T" \4 f" k; a9 F; Q9 z7 _7 l9 @/ c8 V$ h0 E

' L8 ?% N; e4 P5 c. e                        // MIXERCONTROLDETAILS 结构体变量清零
  w& d$ q0 \6 @9 {4 g: g' n                        ZeroMemory(&mxcd, sizeof(mxcd));: T2 _. h8 Z+ ^' X

" ]& T- o$ `' l: _8 |6 P4 M# H: S
                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本
7 s. ]/ Z3 e) q; u( N$ u                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识
" z# c/ i8 o/ P% f1 }' H; D                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针4 I$ _4 J- i# w; k" `7 D
                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小( G( P5 ?1 |- ^( f
                        mxcd.cChannels = 1;                 // 取得或设置全部通道# J5 t0 J: y/ h* D& O# m+ O
+ [0 _5 M4 j' z! Z; q. N4 e& ^
0 @& d3 _( M  m+ t* v
                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum. + K. z. }# y. S  T

4 v: h. O& w1 Y. p
& c+ j0 m5 ?9 B                        // 获得音量值
- Q6 ]" a5 Y7 U+ U5 a                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,3 x0 g' L3 @% J4 @+ E: P; f
                                &mxcd," ^, m$ }+ s" v5 u# S2 c7 `  O
                                MIXER_GETCONTROLDETAILSF_VALUE);6 T1 V( j* @% [. |

& r, d8 e( [3 E; C( j" f, J. U
8 \/ v. |' I- b" O* B8 Z$ }                        if (MMSYSERR_NOERROR == rc)& N  M/ q) X* G" x; p. u0 E" L
                        {" x$ G- o/ R6 ]8 o& {/ _
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;' E' i5 |+ o( c7 O% U& |2 w

! [* l: V8 x3 J* N
: a" l* H4 L; w" v5 y                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;
% X2 l; G4 U$ Y" s2 v1 _                                printf("音量:%X", volStruct.lValue);
9 a6 u. `! {2 H- b! W3 u0 }, H                                return index;8 V# P9 z# v: K9 E5 l
                        }
" w, {3 z. u( P/ s) d* h8 v2 y                }
& o0 o" \5 e( n; C2 Q8 X+ i        }% s+ D0 N" d4 W% z! H

: P3 i0 h* f0 I( I4 @( ?$ s5 o5 s
8 a7 t, w% j3 y0 h7 P! G" B# M        return -1;' p( h+ A) U4 Z
}- t& K# \- X4 K

. B5 e/ t3 m& P* u/ s/ ]        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html: x! o& r! w& p! W
                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-6-19 03:23 , Processed in 0.016454 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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