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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/
+ q4 H8 l2 C1 r4 |4 w- C( o( J, h! }+ X" C! l" ~0 F' p
参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
7 v5 ^% q+ |4 G. O- T5 N
' p; k& G* d+ x- X. i" Q
1 u( o' V2 Z" Iint DeviceManager::getAudioInputVolumn( const std::string &deviceName ): i4 e1 c+ j; S/ H+ I, t- k# U
{' J+ M' ~. n6 B6 Y* [/ h6 o4 N
- I% p% M# E% ]8 H
0 J' [6 W/ V- {8 a9 v
        MMRESULT          rc;     // 多媒体函数返回结果变量
' o  Q4 W9 C& A! O3 T5 S% u: h        HMIXER            hMixer; // 混合器设备句柄
2 P- _# P3 y7 K( d" w        MIXERLINE         mxl;    // 音频线路标准状态信息结构体
1 P7 k: z) X% d6 c8 P        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体) _. Z! s: R; T( o8 g. c7 K
        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
- T$ j/ o2 v( o" g
- _, x7 p( |: }! o
& W! N3 d7 a1 T% [+ B        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即3 A) ^& E( x& ]3 |
        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
; |$ V  f; r: c9 k0 \2 l& [) y4 V  K       //可能还是跟声卡驱动有关。
; P8 v2 B+ k; N% a7 a. @        for( int deviceID =0 ; true ; deviceID++ )! c8 N" p' z- C' G2 N5 q
        {
5 ~" L5 f' ^' Y8 W9 w7 ]& v                // 打开混合器设备
3 I4 Y, W! j. T3 P# w- t$ r                rc = mixerOpen(&hMixer, // 返回的设备句柄
" b# F3 d) S8 w1 c                        deviceID,       // 单声卡的设备ID为零
: @/ Y" t8 l$ S& ^  O                        0,       // 不使用回调机制
, D- d+ G3 _9 j7 l- Q                        0,       // 回调函数参数
4 ?' I$ i4 E3 ?                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID
0 \, n# l; X' a) v2 x, t6 Q                if( MMSYSERR_NOERROR!=rc )( ]( f8 h/ @- `" e
                {9 O9 p# T2 b+ @5 Z- c( t  |  @
                        //跳出循环# L; ]* \" l1 q2 C7 [0 E5 E
                        break;
* j4 K! |  t9 m* A( A                }" n$ s+ G" _% ^
                // 打开混合器设备无错的话,则
* ]; E4 ^/ f1 F/ J% E$ ~( @/ W; l/ e+ t6 R. k8 C. e

8 h7 ?3 Z7 `; M8 \! e8 e                // MIXERLINE 结构体变量清零
/ |: h9 [- ^, P% Z* V/ B3 ]                ZeroMemory(&mxl, sizeof(MIXERLINE));: H# G, h2 V9 r0 ?
) C; `$ _( S) w
+ @$ _& s6 |" X% a" v- T) O* k
                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本/ X' T. w% o7 k1 ?- F; X* k# C0 E2 Q
                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS7 N5 d! i) L2 M$ j$ E
                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;# B5 j3 q( ]& E. H

7 g& `9 ?6 U6 _3 r
4 }' Q# K; n+ j                // 取得混合器设备的指定线路信息
4 Y2 B. V  J- W6 b0 j" G8 [                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,1 w! R. U4 U, ?! ]0 \- H- I. W7 X
                        &mxl,
/ W$ z: v0 j" B, U) d7 H                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息: r$ C' [  m$ M3 |
                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
& L* s" D6 ?. i: g- X                if( rc!=MMSYSERR_NOERROR )3 Y. p& W' c. ~( W
                {1 a) J: v, I  d
                        //无法获取声音输入线路,尝试其他声卡
5 u- {  U9 Y3 ~% H4 w                        continue;
: O  x2 t/ X% l1 g( b4 j                }' ~0 X' x; F6 Q

  V  ~. g# F5 M! M' R3 w1 p# U$ V
/ ]- T9 w9 K: U- p# }& @7 O                // 取得混合器设备的指定线路信息成功的话,则  Q$ h/ y6 X% s: \

1 Q3 a  m0 a% K) ~7 n% R% B" g2 b
) U, m) d( b$ d- w' f' e7 s                // 将连接数保存 9 r' {+ u  K2 [1 P: v
                DWORD   dwConnections   =   mxl.cConnections;
/ h% W) U* E7 `1 h" ?                // 准备获取麦克风设备的ID
/ o0 B( Q; g- W1 e. q                DWORD   dwLineID = -1;
! F, r7 q9 y0 L6 Q$ A                for( DWORD i=0 ; i<dwConnections; i++ )8 h, A- w+ z  N
                {
+ |1 k1 b2 @' _5 b9 v                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
! k0 N  h7 @9 w* V                        mxl.dwSource = i;4 p, G) H! u- V4 O  }/ q, V
                        // 根据SourceID获得连接的信息 $ e" Q# y; f9 S- g  M9 e
                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl, 4 f3 Z8 c+ ?' P6 y
                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); 7 F: w, {: D/ e" g1 C4 u' c0 \- A
                        // 判断函数执行错误 $ n- n8 G& p. ~4 s
                        if( MMSYSERR_NOERROR==rc )+ W) _% T/ v8 ~2 z3 @9 r1 u
                        { " _, ~; R7 n' w3 H' E
                                // 如果当前设备类型是麦克风,则跳出循环。 , f! A6 B& E& q7 m) o
                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
' T$ E2 `2 V/ D                                {
  r* d- o) L+ n0 x! U  `+ K( o                                        dwLineID = mxl.dwLineID;
8 T( g4 m+ l4 E9 k                                        break;
* u; }* |4 P) s8 L7 N5 b* l                                }2 _3 S5 `; L- ~/ t* c8 T- N  r6 D- y
                        }
! g4 U, E, m9 g5 S' f8 v6 H6 d' N$ B                }
. e6 f# \4 H* C# `- Z( }% l3 L8 p                // 如果没有找到,返回失败。
. t8 d) l5 H# w1 X8 j3 C" P; P6 e                if( dwLineID==-1 )8 C$ E3 G1 ?/ f+ D' C; U- N1 j
                { ! B, J/ n! E) r; E/ E
                        //尝试其他声卡
$ o8 R6 Z) f- ?2 j. p# p                        continue;1 Y( H# Z" `# k+ K" q
                }
+ ^( {  m, u8 S" n6 E" {. a- L9 O6 V# L! F1 x% _2 L( J2 S8 _
& T3 V' _2 e. m6 D" R, H
                // MIXERCONTROL 结构体变量清零5 c4 u- G0 l: A. x3 m2 K
                ZeroMemory(&mxc, sizeof(MIXERCONTROL));/ b' p! j$ m# t4 O3 i* U
1 y; F7 r& w  u' ^) \5 W

' M: H% w/ s: ^1 m( G4 T; b                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本
- w, Z( g# C; d* i7 l
; i. a$ s. n! t/ J8 x' ?- c4 c$ ?- T
                // MIXERLINECONTROLS 结构体变量清零' K7 _/ D' P/ U
                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));' @1 i! ^4 ?3 O" h: k5 k) P
1 \; P* s3 v$ N, E) X7 m3 S6 x

( N) H& z. [0 o5 h. q; J- _- n" _                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本
  u* r9 L5 u$ {! W
1 M$ k9 ^* @% _9 K9 c
# g5 h+ S8 q1 w' x) @+ Y3 Q) _                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识
, r8 J7 }" i' Q1 M* A" F$ Q                // 控制类型为控制音量, {: [8 F4 l+ X% Z7 _" V/ y0 X* ?0 M
                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
& R$ g# m& H8 \% K* t                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数! \* t* U& j! ]# y7 Q# U
                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针7 ^% X4 e, v. P; B
                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小( h, \! J1 \1 J$ z% [6 t3 r
1 ^+ h: Q9 x% y& S0 s* X
2 C! G* u2 L' @& p
                // 取得控制器信息
" [/ o& e  r, \                rc = mixerGetLineControls((HMIXEROBJ)hMixer,
2 Y! ^( t) m; ~7 J' a. @+ B                        &mxlc,
) J5 d: P7 f) z# `/ b9 K                        MIXER_GETLINECONTROLSF_ONEBYTYPE);
) \* u/ y! ~. D% I2 Q/ s' W& T
: {& [, g: ?/ ^2 X  }' ^) [9 L0 H, y& w4 g* e1 h4 o
                // 取得控制器信息成功的话,则
& y, \. c, [* m& r                if (MMSYSERR_NOERROR == rc); {: D# P# K3 E4 G) S7 R; b
                {$ P6 j) y0 M- |+ }$ ^& ]
                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.& P, A  s3 \1 Y5 r0 }
                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
3 Y( l  J) J8 g3 |1 M                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)- [$ e/ C% b  R) C' J0 j
3 V* t$ }  y" t" ?. f7 m; o

5 T0 K, h& j% R9 ~7 b' R                        // MIXERCONTROLDETAILS 结构体变量清零% F' P2 X6 b/ J$ |, a
                        ZeroMemory(&mxcd, sizeof(mxcd));
0 g, M, @0 o" i  d2 e: ~
: p4 r* ]2 `3 e+ n
& c2 Q+ n! @8 s: D8 B                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本
" Z/ C/ [6 g) x                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识( S3 J7 X+ ~! B% Z& u  p6 R  X. U
                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针
' B' K4 W, [- y                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
- m' r! C  h" Q  I: w/ Y                        mxcd.cChannels = 1;                 // 取得或设置全部通道4 q/ a8 g& l5 V2 y; i8 k/ X" ~1 f
6 q5 N. n4 p. d% M6 f* ]: y! j  t0 F
, v8 e7 n( ]/ r3 a( J  Q. Y
                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum. : J6 p: u$ Q( d' h6 w  p

8 \" @$ v* C# e1 Y9 X. d4 O( V) W! I' n" G- H; F& l2 M- B# Y
                        // 获得音量值+ X4 r& `* `' R
                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,; O  D6 ^' o' Q" C* i
                                &mxcd,7 B" q" y% }% o7 B' W
                                MIXER_GETCONTROLDETAILSF_VALUE);
0 Z0 G! }9 v5 B7 t/ s8 q# j$ |9 `# r0 j0 z3 y3 ?* Y$ `5 R
  B  V, ^, o3 {- C8 Q5 V
                        if (MMSYSERR_NOERROR == rc)
, O5 C( v+ P- v! j6 G% @                        {; Y! Q& E: c5 K9 a3 p
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;" d4 X* K& p" m& R: I" n& |# s1 S

; J  ^0 K9 o' l7 H9 Y- O8 B2 x1 c$ a
/ N4 ^  E% v+ L! S                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;
7 Q* W& u$ s6 \; j4 P                                printf("音量:%X", volStruct.lValue);; y, b! B3 {0 B0 l" b: r* Y. E4 |% @
                                return index;
' Q4 Z$ S( E+ R" {/ J; y                        }. b- M9 h7 E3 @, L- E4 @2 d
                }1 Y( |' a3 P6 z+ e6 N& l  z
        }) B1 F; e- N' f+ i6 }) D
) H- c/ M! @8 s! M/ A) k) h4 V
: H- n/ d( k1 i5 E0 c
        return -1;
; j0 d- ]) m+ D}
5 v6 f# Z0 `4 T/ l5 g- b3 t- U) T8 ~  ?
        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html
" F0 O: R5 H6 k' A                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-6-19 07:25 , Processed in 0.014798 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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