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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/
2 f2 V; F& x5 R' \! x  S
7 f( M$ |: L2 }参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:. B1 z. r' F* S  d1 {9 Y; r' c

* B. T, v" R: x5 [
. b+ A5 I2 R0 ]$ mint DeviceManager::getAudioInputVolumn( const std::string &deviceName )
! P  V5 {/ P5 y  ?8 a$ u" h' i& `3 @& ^{
+ E7 d2 B" ?' o9 |, R3 l$ i
) w; j( U8 j, ^9 o3 @" @" C- v5 w, F& z  W) f; g% m4 T; f
        MMRESULT          rc;     // 多媒体函数返回结果变量! [8 {4 ?6 V% y" x% @% N; e
        HMIXER            hMixer; // 混合器设备句柄. g! {( e' r: S/ @- a5 N2 D& l
        MIXERLINE         mxl;    // 音频线路标准状态信息结构体; ^6 R% [  D, {  }3 g
        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体" [+ N' Q, z! O' y: H
        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体! g1 e' ^! t" s/ f+ ~6 |

+ o7 e5 ^$ w, r7 O5 z0 \4 f: f6 a7 t- _  ^  S& O  {
        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即
; C0 M, ?. H2 I3 V" J* P        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
8 r- y( g# S( O% R' _       //可能还是跟声卡驱动有关。
; g0 q+ q' m, j4 Y% _3 Y* l& [2 Q        for( int deviceID =0 ; true ; deviceID++ )4 |1 }$ A  ], F' f
        {
( l6 {8 i, u0 D8 ^" ^4 ^9 b                // 打开混合器设备
6 s8 Z6 Z8 K8 T( u* O% ~0 d+ L1 Z                rc = mixerOpen(&hMixer, // 返回的设备句柄( v2 V* c. G2 p: T7 ~
                        deviceID,       // 单声卡的设备ID为零
" G4 ?: Q. F  x4 @                        0,       // 不使用回调机制4 Q, y7 j' w! \) R3 @
                        0,       // 回调函数参数) S0 P: z% Z) i0 D
                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID
4 ]+ C: O4 L7 w                if( MMSYSERR_NOERROR!=rc )7 V' C5 \: o  a$ Z: _6 d
                {
/ M7 }2 K+ ^' q9 @* K" c                        //跳出循环- d# h9 W' [% B) B, T
                        break;
6 Q. m: s  w4 V7 B, U                }
! G% i5 E. X' p                // 打开混合器设备无错的话,则6 P! {+ {1 |% |9 @/ s
' L* F" l1 p; m
- L+ ]- y8 r5 C! g4 d3 Y* W
                // MIXERLINE 结构体变量清零' P: i" _% Q5 s) J" |. d1 n
                ZeroMemory(&mxl, sizeof(MIXERLINE));1 {0 D, u4 d. M( H" s
' i( S2 F9 n% e
) T. J7 Z, R: r0 s
                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本
* `4 e" s/ N* J3 d* @2 A                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS7 |# h1 F# ?4 N) _
                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
7 J4 L- D- Q2 d/ g' o$ E& Z6 {3 N: F& N9 s& P/ P& q
  H" u. s; |, ?# @0 u6 d# Q& ~
                // 取得混合器设备的指定线路信息
3 M3 h* x/ t- w! k                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,5 s. F, v' h1 {4 C
                        &mxl,
# n, C2 @, M$ X7 R! G0 O7 b                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息: l4 ~3 [% P$ V& U6 n( b* e
                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
5 }# m! m) }- i                if( rc!=MMSYSERR_NOERROR )) X7 o" }" J' k6 @3 t8 Z& c( T% `
                {/ h9 @0 s' F6 ]3 C; f, I0 I) i* _
                        //无法获取声音输入线路,尝试其他声卡# {2 a6 |: l+ D' G* P+ h6 r+ B
                        continue;
  ]( A2 o" h  @+ p7 Z  v( G& z                }
+ I* s/ z% F1 b" W0 c
* A1 y8 D/ q. j$ P5 G
* q- K5 a8 W3 [5 m  X' T                // 取得混合器设备的指定线路信息成功的话,则
+ n/ F; S. }" {0 d( q5 W5 Q1 A7 I; w; Y/ I4 e9 {' g8 h4 G: d

1 E$ i, h- ^; g8 k* n! z! x                // 将连接数保存 * I- e& a0 w* j
                DWORD   dwConnections   =   mxl.cConnections;
6 h" W% u7 k6 a5 D2 c; h' `4 n                // 准备获取麦克风设备的ID * l8 i" j5 ]; E  _$ H9 p
                DWORD   dwLineID = -1; # Z) X* z) x& P/ Z5 F) c
                for( DWORD i=0 ; i<dwConnections; i++ )
+ U+ M7 F/ t4 q! P0 W8 C                {
% h* {6 \1 ?3 k                        // 枚举每一个设备,当Source的ID等于当前的迭代记数
: n5 Q* C2 g: ~                        mxl.dwSource = i;
! k4 T  O8 |0 o! T2 x9 G0 V                        // 根据SourceID获得连接的信息 2 H- p  n% J$ Q) s
                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl, ( L$ M0 A' ~6 h* \9 d. s+ `
                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); 2 R! s" E6 y3 M  @/ d
                        // 判断函数执行错误 7 M0 x$ b- B/ V
                        if( MMSYSERR_NOERROR==rc )% H: T% ?0 J8 o; f. V, j; \
                        {
$ w4 Y: S- {  O. f' B5 D; S                                // 如果当前设备类型是麦克风,则跳出循环。 7 }# h* u$ ?/ b) l$ D2 }
                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
( D; y; d* z9 x# Z+ ^                                {
" a. A9 u# `9 j* i) X! u) I2 e                                        dwLineID = mxl.dwLineID;
: L5 l8 t9 Z4 i7 ]: X3 x4 q                                        break;
# b6 v8 Y7 ?, `0 F                                }
5 m! Q+ a- S7 S! y/ \8 h                        }5 Y. }+ Z- Y3 k. x9 x9 G; R* P
                }, ~+ i$ o* x$ m3 u* y9 c% C2 m, E
                // 如果没有找到,返回失败。 * l1 Y. i+ a1 b/ M) G; \# b
                if( dwLineID==-1 ), r7 I" k5 r- Q% A' X
                {
, S0 X9 A/ c8 t& B) L7 t                        //尝试其他声卡; j/ i/ |& h& Z% ~% A4 b
                        continue;
5 a0 V" K) c" W7 {' u1 K& O0 X0 ]' s                }& \6 k" R3 G* Z1 E) a

- P9 O0 v- X. y& C2 f9 o. F% I' I) Y" D! ^9 b6 J, T5 K
                // MIXERCONTROL 结构体变量清零
9 ]1 {4 j; z/ v& U1 S: m: J+ V                ZeroMemory(&mxc, sizeof(MIXERCONTROL));
. z: {" S5 ^6 k  n  X& A* f! w5 T2 X- D9 y! M% k. L
9 c% v$ M( |* t- {: F5 F
                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本
% `# e- j  o6 v, D" b
+ x3 G- W+ l% E6 e) H& T! a  i, k# l6 T
                // MIXERLINECONTROLS 结构体变量清零* s& {; U% E, w. B+ K- w. e
                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
) l9 V7 m: Q. O% h% U- T
7 Z7 k8 x# Z* J2 k$ `' F$ `( N% M% J$ Y: e0 B
                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本
4 y+ ]% n) L- T; n
* j0 ]3 q5 d8 W, w7 o1 W; O* w. ~; P5 a& L+ P6 ^' ]
                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识8 I$ g* v6 k' ^# O6 t2 C# V
                // 控制类型为控制音量
& u" n% S4 {( s2 z5 I                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
" j7 o5 U; `; _3 [: n% e3 f                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数
7 R. W& S- K, P! P+ B& c: M  f                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针
1 s0 l* f% U7 }) i( v8 d6 Q# m                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小
. T5 S. `1 v% O9 _  W
9 h+ w( Z) @: a2 U  U8 W( L) W$ C0 x6 a, J+ H+ V
                // 取得控制器信息
* {% }# X/ c$ r$ \                rc = mixerGetLineControls((HMIXEROBJ)hMixer,
7 e) L6 w9 o0 U$ N                        &mxlc,
: J/ a! _* y0 A                        MIXER_GETLINECONTROLSF_ONEBYTYPE);
/ P3 d' j5 n& G9 B' B
# t) D1 g! }. p. x, j0 p" Z# {* D$ J, |0 P5 j
                // 取得控制器信息成功的话,则
" Q4 \, O9 X' R; w3 e                if (MMSYSERR_NOERROR == rc)
, S) ^4 k+ `# I: j* L, `$ F) G: `                {
+ q/ v# J5 {+ t; ]4 E                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
6 x' U, x  |' v! n                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息; M& H! j/ {/ Z% S4 v8 v
                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)( _3 G) K- w" V( @. t4 C2 u

$ S0 v" W: F- x1 c' E* u; b2 J4 ^9 O* h! P+ c6 F* E
                        // MIXERCONTROLDETAILS 结构体变量清零$ p! u4 n4 H4 F! r& g, K; d; q
                        ZeroMemory(&mxcd, sizeof(mxcd));
- g/ D* r+ w$ C# x( l* \! m% T/ h
9 U1 F; K+ h2 z& Y+ l* @2 N" J4 B9 p6 ?
                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本
/ T8 k. n+ d1 Z- ~                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识- ^6 o/ y  r) P1 S; ^: @
                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针2 J  F* p5 e; D3 t4 D0 I
                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小: t; \% R# @+ D4 S6 t! u8 v. k
                        mxcd.cChannels = 1;                 // 取得或设置全部通道6 I* b4 M# v: r6 v+ }  H
' g" C; g) j# o4 K) W' r+ q1 f
! }! d# H6 h# e9 f; e: K
                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
$ z4 q5 Z' C$ |, x0 H# g
* \; K/ N# j. X; P
* [& b5 p0 Z4 @. d) d" q! j                        // 获得音量值# o: i1 Q, E! v6 b7 N3 h
                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,# @8 n/ g$ }+ f4 P3 z/ V. ?
                                &mxcd,
( H/ w( O  \- V  z7 U! |: q                                MIXER_GETCONTROLDETAILSF_VALUE);: j: I; |- x% @7 E) G1 `
+ R4 S0 X% O% u4 ~8 _  g& [* i5 ~, }
5 W3 s3 R/ h3 i& n
                        if (MMSYSERR_NOERROR == rc)7 W8 H# u1 A( h# V
                        {
; C+ r& a8 l; e                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;
& U2 I+ ^- D9 e5 e# ^: b9 I" C* q: \
: ?! K+ U  t/ r8 L5 Z$ ^) s# }  q
                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;+ }9 c4 g7 a0 _1 [8 V
                                printf("音量:%X", volStruct.lValue);
6 V& v# W/ T0 [$ v0 g. J                                return index;
6 S8 V0 v7 k/ Y  q( D$ ^                        }* C2 w. T# t3 A: [% _% Q
                }
8 A6 c" U0 x  D/ O+ T        }; [4 P; _. I5 E3 T; \
/ c. w& Q: `- ?
; l8 H9 ?! u: E& l: t9 e
        return -1;
+ [% z' {4 ?1 _2 B0 w/ x1 s}
/ h! Q) n, _* l
: {! W/ z# c' u        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html7 ~4 d" H- r" P0 A- C+ D
                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 08:53 , Processed in 0.018048 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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