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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/
3 ]  d5 {! o' S: h& r" i
- G; m; y0 e% l' g( v5 {; {参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
" e# C! D% y4 h: v9 o/ M% Q: {2 W" t" ^8 K# w" @* ?1 ~

3 N# P) D  R4 m( e' G' ^5 Lint DeviceManager::getAudioInputVolumn( const std::string &deviceName )
9 H8 p" t% b) H7 n& m{' `, p6 ^! `. @- ^# w* h7 r
3 q/ J  g; V, G$ o+ `6 i- d) v
( w% p+ i# A* g8 G
        MMRESULT          rc;     // 多媒体函数返回结果变量% B3 e/ X5 P2 y
        HMIXER            hMixer; // 混合器设备句柄
0 X7 F* U1 u7 I        MIXERLINE         mxl;    // 音频线路标准状态信息结构体
$ r. `0 ]/ P7 Y% m. m        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体  S) t! b4 b- W, S6 e) k; x/ q
        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体% E: P, B" W4 x% w

2 p" r& h3 B9 E9 F3 t$ c! C- N3 ^6 k
        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即0 v% r! R/ q+ ]+ y7 K' ~
        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
3 s# C( I0 p# B5 h2 o       //可能还是跟声卡驱动有关。
  J# T4 I; g5 L        for( int deviceID =0 ; true ; deviceID++ )1 P7 ^; a, P: i9 I% U9 y& \
        {
7 Y3 v5 Z, \  V; \                // 打开混合器设备
- C1 O7 I9 ~" Z" ~6 C# h                rc = mixerOpen(&hMixer, // 返回的设备句柄
8 M; a- g; {( t# I! I                        deviceID,       // 单声卡的设备ID为零
9 x$ J% E, {# U3 ]                        0,       // 不使用回调机制3 ~6 F1 a+ T; a  W& E
                        0,       // 回调函数参数
) t3 ]) U3 q1 [, X' a& |                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID
; ~( _0 B3 @; A* p: ^                if( MMSYSERR_NOERROR!=rc )* }1 ?; k3 F2 _
                {, c- h8 ?7 g4 R0 i6 v
                        //跳出循环
/ B+ n: p9 g1 I% J+ Y                        break;$ ~' h/ l" T* @
                }
  B+ S  r" Q( L( I8 X$ P                // 打开混合器设备无错的话,则$ q7 ~; Z5 R& h1 G) \0 g4 _+ i
2 n3 o7 d! N: Y3 f! H

$ H# \: \8 A7 z+ ?; Z                // MIXERLINE 结构体变量清零& y1 d  \! w  z( D7 L  z- ~$ L3 B
                ZeroMemory(&mxl, sizeof(MIXERLINE));
# o  P3 b) M2 P9 Z  m0 b8 f, Q2 C  {  H/ W# e
7 M; i7 {! x" V. A% R
                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本( Y, ?; t- u3 }: _( X. N" I3 `
                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS. T8 g6 Q/ G4 [# j1 B$ y/ C) ^$ w
                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
5 B! U: ^$ U1 y& a" }
) S8 @  ^2 l' n* K
6 I# d+ s  c+ X9 J* I9 N                // 取得混合器设备的指定线路信息% r( c- p5 ?8 V
                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,
' b: d# o* d1 P+ `- K+ z. b9 x: T                        &mxl,
, i  z! M" j5 B) X2 n& c( w" l                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息
; l8 _2 K- h9 o' k0 ^' |, T                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);; Q; Z2 B9 ^+ S; S- r! S0 E2 p' w
                if( rc!=MMSYSERR_NOERROR )
6 w- F) i2 d4 `/ S' E$ @2 T                {
' U3 A, v+ u. X5 o, l3 |7 T- _                        //无法获取声音输入线路,尝试其他声卡5 F3 ~* d: A2 m) g
                        continue;
' f5 V$ t8 I( m/ `6 S/ _, j; l/ {                }
; {6 g" z" b8 i7 N' E* M4 C& A
. \& N, F& F! T' [* D
                // 取得混合器设备的指定线路信息成功的话,则# l/ e# V' ~- T9 r1 q) F5 k
% Z+ U0 J7 N& L) K
5 H9 U4 k: i% x4 p
                // 将连接数保存
3 {5 V: D, T8 O4 {! e7 Y6 T                DWORD   dwConnections   =   mxl.cConnections;
* z7 n! W* C0 J! |! U& J                // 准备获取麦克风设备的ID 4 e& w! t$ p! d/ m1 `$ d& C
                DWORD   dwLineID = -1; # _- n" u( u7 R6 d" U8 i
                for( DWORD i=0 ; i<dwConnections; i++ )
% h/ Z: `& {  k* L6 k                {
# O& d  l$ N* I4 J( D3 Z1 N                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
2 m0 Y- v8 q8 z$ q6 }0 |                        mxl.dwSource = i;
0 `/ O) W! i& f9 j1 N" ]$ K6 \                        // 根据SourceID获得连接的信息
. R% P6 p+ Y% H# H! S                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl,
( z! @9 Q+ _  z/ y4 D2 A                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   );
1 Z4 q+ A) `/ ^- f                        // 判断函数执行错误
" l6 k& I- T% K: j7 [, p                        if( MMSYSERR_NOERROR==rc )( f; ~' ]; N# r: @
                        { 3 g3 O7 Z  H' n+ q# R4 A
                                // 如果当前设备类型是麦克风,则跳出循环。 8 Z; ?3 Q8 R! w
                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )( W& ^; E! M- c$ @9 {
                                {
# Z) Z$ I4 s9 H                                        dwLineID = mxl.dwLineID; 6 G5 L+ v) A# u3 H
                                        break; : `! B: D1 {) b$ T7 @5 j
                                }3 R5 A% U( L: u& C$ D9 i3 d" b  j
                        }
9 J% I' {' ^, W                }, ]& B2 o8 a! H2 I& y
                // 如果没有找到,返回失败。
6 y. ^( C) w+ k( |                if( dwLineID==-1 )
5 x1 y8 a* D# M# K                {
4 D3 A6 w& c# a# m! D  f7 a0 }                        //尝试其他声卡
, J% h- v4 C6 g* V                        continue;
/ x7 o+ @4 }0 ^* ?" X- {                }
) k5 M8 J' N7 q1 M4 ?) B; b  Q0 {" a0 K; I

2 _* ]+ n- U/ n% _4 ]                // MIXERCONTROL 结构体变量清零, e5 V) F. W2 L; t
                ZeroMemory(&mxc, sizeof(MIXERCONTROL));8 d, u$ P( x9 C. y' I9 O6 n2 ?
! |8 J% t& T7 y$ M% K6 P8 z

# \. p2 a" N% C& O  @$ `, a2 q% ~. r                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本
$ d' I7 {0 j) j3 B$ j
2 ?) |3 K1 J" `0 K2 K- l2 t) R/ z4 i# e# Z0 r0 [
                // MIXERLINECONTROLS 结构体变量清零
# x; [- @* e8 p' [0 h5 [1 c                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));/ Q/ U, B/ s( q* s. x" Q
0 o$ d3 c4 W  w' [

5 z: J3 a) \" L7 y% W3 m3 g) a7 P6 s                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本
! k- U+ c/ u' t. m  I
9 ?  M* p0 v- H2 i2 R$ g4 ?( c( V$ {) V9 w4 q
                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识
9 f1 w3 V4 W4 ~                // 控制类型为控制音量
1 Z- e3 K, U% D7 i/ P& V5 B# J                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
7 I8 p: m7 N9 g: ^8 B" z8 G2 ~                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数1 Z+ z# R/ R4 P0 s/ l
                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针' \8 M0 o. d& R+ s! j& ^) U
                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小6 k9 \4 I; P7 L. f$ z# d

& l+ |' [, e# F% `/ ?4 P$ R: U- ]  M0 Q6 E( F! U8 e" [* k
                // 取得控制器信息5 ?5 o2 j; u3 _, P# t* v$ `9 ]! H
                rc = mixerGetLineControls((HMIXEROBJ)hMixer,& O5 H9 S$ \4 T6 O. d+ K
                        &mxlc,
) Y( a1 [% N2 K) ?' i" e' X                        MIXER_GETLINECONTROLSF_ONEBYTYPE);3 A' ~8 f  l2 ?* e* F

# \% E( h, S7 x
7 k. e; t& f: B# F8 R' w1 w                // 取得控制器信息成功的话,则
# K3 V- k2 J: s; e                if (MMSYSERR_NOERROR == rc)
/ H6 o1 ]$ x3 L                {, i# j2 G! J) V: `# o
                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
/ Z  b# a8 [; w$ m- b% p! G                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
& k' j$ j3 s( y- H! G+ I                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)
1 e) ^$ `+ h- I! s4 M, i+ d
2 P: |; i9 l9 b5 n9 P, a' b" E8 Q( k6 x2 ]) q' r; ^8 O3 ~
                        // MIXERCONTROLDETAILS 结构体变量清零
8 K5 i+ c, ?4 o                        ZeroMemory(&mxcd, sizeof(mxcd));! u4 }; V1 k) ?

1 Y4 u& n  M# M9 t  M6 f3 B
2 G8 t, M' _& _& ?& u# T4 W4 O                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本* @3 e/ i! [/ y+ a- n# ^( C6 C9 o4 T
                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识' }( D' A8 |3 z  V& U
                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针
- @) Y7 M" k7 j4 ^                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
# i; ^( h4 e6 a: h2 h                        mxcd.cChannels = 1;                 // 取得或设置全部通道
( Z9 }& p' u5 p' n& C9 V0 x2 z
' p8 c5 `. d" R0 C. }$ e( O4 \+ [) F
                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum. ; h# P$ y' c2 p' T# Q7 g
/ z2 u% z$ I7 ?* E1 H
( S) K) ^& F/ d+ J8 R
                        // 获得音量值
- M4 T+ H9 ?2 f6 a7 O                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,
+ p" L* a. y' Z1 _+ V                                &mxcd,$ l8 [5 i: {- i) k2 X$ M' ^+ V
                                MIXER_GETCONTROLDETAILSF_VALUE);
2 |$ K* k* F! e' ~  n' ?1 Q+ N) K& [8 V

4 M: G0 G! g; H                        if (MMSYSERR_NOERROR == rc)2 z& C' [7 h, U2 @" E
                        {
: n% j, Z( l: r  ]- x* [                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;
7 p) b6 @' C/ K1 f% L' V+ h& w- V9 f% \$ z) w( ]# ]! l

8 ]; r* ^' X6 P% a                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;$ j( q9 B4 }; M
                                printf("音量:%X", volStruct.lValue);- |1 A3 t1 ^0 ]* C& p8 o
                                return index;
$ m9 G6 K+ i4 P0 h& |+ _                        }* e. t0 U9 P- O% S. S) G1 m
                }
4 x  b# k  ]8 J8 D, r        }) F4 c+ J8 g- s* H5 f

" p; Q. s' i! V" |- C) n* Q$ {. _
2 F2 p) s# i6 o' n        return -1;
1 Z4 v9 T7 [) _# W' ^7 w: \}; Y& p3 E& f, w+ v# I& J2 T4 m
& q+ I" |2 h' @. ?
        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html
4 \4 `! A$ p9 O                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-11-14 20:02 , Processed in 0.018427 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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