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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/. p, m1 l( x1 F' C: m/ e" B2 }
% R+ m/ _; I# K# z/ T6 o# I3 q% m
参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
5 @4 C, D! z9 B9 Y$ T2 s* o0 C6 j: E% V& D0 K# ~" e$ K
5 s+ l) f1 ^) B) H
int DeviceManager::getAudioInputVolumn( const std::string &deviceName )) X  y% ]3 [! ^# g% c
{. ^) c" G: L4 j# o3 G6 ], e* ?

  q6 N  Q2 J& f2 s& I, H- [0 y, b: P4 M. ?+ ^
        MMRESULT          rc;     // 多媒体函数返回结果变量
5 C6 D! }$ k3 \- o        HMIXER            hMixer; // 混合器设备句柄. L! E5 z7 \$ J6 v$ |' u0 y) G
        MIXERLINE         mxl;    // 音频线路标准状态信息结构体1 G& q: k1 Z' _& L% w2 I1 B' z
        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体
# p0 K4 S1 v9 o; d$ T        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体4 o5 V" U7 U4 B: v& D! F  D

% T% f5 y* c0 y: D. V; L* L3 B$ N& ^2 P& ?  X4 ?
        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即8 t. l2 S- g" R9 K
        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
. p$ U6 W5 G/ }       //可能还是跟声卡驱动有关。6 }9 b( G& f0 j, A$ ~
        for( int deviceID =0 ; true ; deviceID++ )
4 K) Y0 O2 ]7 D$ g* t. |        {% ]0 p1 v/ w  P
                // 打开混合器设备
6 y. R7 Y, }% ]. X* i/ {                rc = mixerOpen(&hMixer, // 返回的设备句柄9 S" T7 S$ ]  E# }- a/ R
                        deviceID,       // 单声卡的设备ID为零' ]/ A+ `% \7 r+ x: G7 i
                        0,       // 不使用回调机制
/ t8 [5 G6 \. b0 R7 q6 e                        0,       // 回调函数参数2 a6 s7 c+ b( X1 p+ u% q9 L9 Z  K
                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID
! j1 n" z% k: b$ F: c                if( MMSYSERR_NOERROR!=rc ): N; X/ Y* l+ F# A' C
                {, U) b+ F  c- ]# G
                        //跳出循环5 e! h( N" E1 x" u' ?4 w) I4 z
                        break;( Z8 X' `: l. H0 m  S- Y( ?
                }; f7 e0 ]0 S! ?: t! d: ^- o4 c: W; T
                // 打开混合器设备无错的话,则
) H# X+ x% U# k/ G8 Y
" Q$ [- a" }9 E) _8 r
& k- ]7 [6 p0 g1 `8 g5 {+ e                // MIXERLINE 结构体变量清零) {. ~# Y' I5 S9 N
                ZeroMemory(&mxl, sizeof(MIXERLINE));2 A8 G- z, E9 x0 C

( O, u! O2 [/ M( c8 K7 A0 a7 B" l, Q" y
                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本' ^' @& u/ e0 A8 f6 _* X/ G0 U' N
                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS8 C4 ?  l; g& B9 r/ [6 o4 t
                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;8 ~4 P( N1 s  y3 U7 ]- j
: K, h5 ]# G5 u) [

& c$ }3 q6 Z( [  M/ k                // 取得混合器设备的指定线路信息
; L  I: z8 v/ c+ W                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,# P8 y7 ^$ I$ o5 P5 [5 T$ t7 {
                        &mxl,
# X+ L+ k! T6 q6 s                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息4 @2 I5 S, }  x5 M" j/ b
                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);8 K/ Q. ^( @* J6 K! x
                if( rc!=MMSYSERR_NOERROR )
& v+ P+ i8 A2 z  I                {3 A$ e5 S& J; x4 I1 x  ^
                        //无法获取声音输入线路,尝试其他声卡
7 H. @  b, E* n: ?5 ?                        continue;
8 S6 U% ~' b, y! A                }
/ I3 @6 R# M. p4 V. H
. U% n$ e- |5 v4 I$ B+ I% s& O, m' d
                // 取得混合器设备的指定线路信息成功的话,则
6 b' r* C3 R* A
  l6 Z: v' c* \: p, t& h/ J; z# I7 w& C2 v+ l; n% M
                // 将连接数保存
  Y5 h& m# ]# B8 D                DWORD   dwConnections   =   mxl.cConnections; 3 e' O, J8 P$ ?' a- a2 x
                // 准备获取麦克风设备的ID 4 i) ]6 Z) ^. y
                DWORD   dwLineID = -1;
( |+ Q7 e( S* t" W1 w: o3 L9 }8 a                for( DWORD i=0 ; i<dwConnections; i++ )
3 v+ P+ m% k% g% J9 f9 R                {
  V0 o8 a7 M3 S& O' U                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
+ O+ g; [3 ?3 V" [' W3 b                        mxl.dwSource = i;, P6 J  d# W* C' O5 E8 |, i
                        // 根据SourceID获得连接的信息 / S3 a$ {! H% B8 U# L
                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl,
% E$ o8 U3 S% B8 k- h: U# A                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   );
, `+ x0 ]) J; d, t" {- F                        // 判断函数执行错误
0 S8 d) K1 f+ X8 B5 H                        if( MMSYSERR_NOERROR==rc )# K& z" I; S% y: I: f
                        {
4 x+ o0 F' g: i, `3 c: k! o, n                                // 如果当前设备类型是麦克风,则跳出循环。 , _% l: Z, z9 `9 Q( [: J
                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
; J! A& K5 J5 w' Y. \                                {
7 E$ V) d% _7 M" s+ \/ ?! p6 S                                        dwLineID = mxl.dwLineID;
- L1 x& l% c- p+ i& S                                        break;
) r! m3 M4 @" k. ^( _; [                                }, K1 N6 V# m7 c; \2 u5 N% `
                        }
$ g3 C7 A4 r, c% f) B- c                }; ?: `+ V# l8 R7 Y
                // 如果没有找到,返回失败。
) |/ _) G6 O$ J# h                if( dwLineID==-1 )0 x  `, O5 p5 h9 {9 h% u) M* _
                { ! p. m+ [) \1 q" J& t
                        //尝试其他声卡0 j) H4 b8 e2 L
                        continue;6 l2 f0 Y0 o1 F3 A% L$ K
                }; Q6 H  x: w) G/ f
1 S5 \% q  F) n2 l" ?' h
5 X/ P7 A& K+ S. Q
                // MIXERCONTROL 结构体变量清零6 ~& W5 C* }+ v) j1 `# X/ s; ^
                ZeroMemory(&mxc, sizeof(MIXERCONTROL));4 N# k/ p" q- ~6 y' I9 f4 q) r6 F

! s* u9 k3 t5 L7 _9 v5 ?3 y/ O* W3 Q
                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本5 A. o6 [, f) Y9 e
  t$ ^! g8 A/ w2 {- X
- e- y; z! h8 `' M* _# [/ `( K. o
                // MIXERLINECONTROLS 结构体变量清零) v7 ?' ?8 g% O% h) c$ z3 V
                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));# D2 [7 {7 Y: j7 J8 _

; P" ?& r1 Y/ J# \/ ^% r( s
' k2 l1 H; z2 w                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本
/ @7 ]) h% L% z/ A* d+ b$ q% M2 b  M0 u- r9 |' N

, Q; B- y  H0 b) _                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识; \) k6 y7 H: v0 S1 j- b
                // 控制类型为控制音量% x2 Q5 K+ z6 ~# N: z  v3 D
                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
, ~4 y9 {' A" z                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数6 t( o: G9 I. v" Q+ G8 N
                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针5 Y3 ~; i/ i$ r1 N3 `/ J. [! y
                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小. J3 c" p" ?' F1 p9 Y( x
' I# C8 A+ ~8 \0 F
# t# G# x, G( T6 Y
                // 取得控制器信息- O! r) H& n; @' D1 }
                rc = mixerGetLineControls((HMIXEROBJ)hMixer,9 A' M; _4 [( @* l5 }% w+ p  D
                        &mxlc,
9 K; B+ d( K# H8 l9 ?                        MIXER_GETLINECONTROLSF_ONEBYTYPE);2 m4 Z2 D6 M1 X) V7 U5 x
% B# A* y) d+ k6 b1 _
. i% ?. n: F# d  W" E) z0 N( P
                // 取得控制器信息成功的话,则
+ C; W+ H3 |9 G$ y2 A' L                if (MMSYSERR_NOERROR == rc)
- \5 B) D3 ?/ i4 M6 i' l3 L0 q                {
2 p# Y: s: g& S& y                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
5 i- K% e2 x7 G% V                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
1 D' S' e" Z& L% D+ B3 l                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)
' M0 [; M' E# ]2 G0 c7 ]& V
2 M) ]0 e8 o. y% Y) i$ o% }) R5 @( n7 u- P4 h1 x( w+ x- i
                        // MIXERCONTROLDETAILS 结构体变量清零3 T" M5 C2 [1 a: b$ G% Q
                        ZeroMemory(&mxcd, sizeof(mxcd));
" ?+ E. [, e# t
/ }9 p5 n9 M! |' c: w9 {7 A: _( C6 I% Q2 Q
                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本
4 ?7 A4 Z4 S4 H                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识
; H  V  L0 Z3 V4 ]% z# h3 w9 X2 i                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针9 i5 w, o) j" S3 ]. V: z3 z' W
                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小6 j2 `" ]4 ^; k$ H" d* k) v9 s" N
                        mxcd.cChannels = 1;                 // 取得或设置全部通道  t/ D' i3 D  ~* N0 r; u
7 W3 [9 ?3 N) s& p3 K; N

# ^6 L0 e4 x, O7 G5 @4 B9 t0 H$ f& r                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum. 2 _, S, a* V- C( Q* U

8 A' R; y# n" A/ Y$ e# s+ U3 P7 O, j8 Y  q: Q- {
                        // 获得音量值
- U8 }( n- y: O! x4 T. m3 Y! `                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,' ]; _; s5 B4 Y
                                &mxcd,* C+ o+ M  ~, e! m& u: L3 p' m$ q
                                MIXER_GETCONTROLDETAILSF_VALUE);
, x6 V6 V& ^+ y" u* U0 ]
# |1 y& l9 \* _& o& W2 O! K1 E' u; p0 U" V
                        if (MMSYSERR_NOERROR == rc)
0 T1 y2 b! D/ W; r4 C                        {
" }8 s9 S2 H  e& W) F) f                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;
' Y" b  ]7 K' ~2 t" Y
- k1 L  n" X, ^3 Q% x  Q4 I9 i0 G1 N* h3 n9 A4 O
                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;
3 h' O/ i' d1 v% N( q                                printf("音量:%X", volStruct.lValue);
  L2 e# n9 z) ?3 U% T% k                                return index;
) {2 i! R2 |# n- S                        }" p) B  s3 w6 a  Z$ ~' _) h2 @
                }
. Y, j! L: a1 B6 c        }
* w) E( [- h# q$ J: B/ B- k; [1 P" `9 `, Y) y# E
+ s) U- w# w  E8 r. }/ l
        return -1;; h: Y4 C5 W; }( y  ^2 P, Z
}% K4 U* S2 v5 T/ u! ~

. x8 C8 H4 n! k$ a' V4 H3 J" W, h        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html6 Q/ P( E" N2 P" B# Z' D
                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-11-14 14:43 , Processed in 0.018582 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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