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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/
* d$ [- \; s0 f& M1 k! }  K" f4 q, R5 S+ n* W( w
参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:
7 x/ ~6 Y2 W7 H' m; H6 \8 L, p" y9 {' w/ f8 [$ v, E2 v1 \' |
' E* a- k% d( X2 Q3 S
int DeviceManager::getAudioInputVolumn( const std::string &deviceName )& |2 }2 O% b, e  ?7 F; v
{
8 S8 ~* |' v7 z2 s, J! Q7 U
, U' I/ k) s3 ~& b4 e1 C( T. g; E0 m) [2 [, c8 D
        MMRESULT          rc;     // 多媒体函数返回结果变量
$ l0 @1 u7 c! K        HMIXER            hMixer; // 混合器设备句柄
( W9 O' o; Z0 K& Y0 `. G) c6 y        MIXERLINE         mxl;    // 音频线路标准状态信息结构体
2 r( k7 y9 }& K& [5 a. R' u% U        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体; E# d7 p% t/ Z. M, P: `
        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
( \% |* T  u% f
6 @2 m" _, }! h% p( c  [  m- J6 K; Z9 H( o
        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即0 |- g% U/ n/ {# l* ~# F
        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
3 |* Z; d6 a" T2 h+ U: Y6 m       //可能还是跟声卡驱动有关。
& n2 g6 `5 |1 W0 d1 A- ^# h' N        for( int deviceID =0 ; true ; deviceID++ )( M2 p1 x4 L1 a/ N# Z/ Y+ n
        {& D4 Y  ?) t: H  @- R
                // 打开混合器设备! W6 ]5 A4 z$ M
                rc = mixerOpen(&hMixer, // 返回的设备句柄1 v, q; V% q0 S3 P1 p$ f; M' @' ?
                        deviceID,       // 单声卡的设备ID为零' q  Y( p; A2 R; M4 N9 I" M
                        0,       // 不使用回调机制! I) y% k% ^2 z; h8 Q* h) x% W9 d
                        0,       // 回调函数参数
4 {8 b1 ?, ]) P  H( E; Y% M                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID( U  Z) \) H" h- S! j$ w# E7 O
                if( MMSYSERR_NOERROR!=rc )
6 _$ }- d2 g! g                {
4 I: n& q9 W) j1 P9 B% X                        //跳出循环: m, K1 K, t$ H% m( a* |4 c; d
                        break;3 o, R  x+ w- S% Y2 W/ T& k7 B
                }
% U/ y! S: x, |5 O' `+ t                // 打开混合器设备无错的话,则
1 A# l0 T+ c! J5 j$ p4 S: ^- [+ e# L/ W$ M, R- y* q
1 W9 r2 V# D0 o9 M1 I) J. D) `
                // MIXERLINE 结构体变量清零0 L5 C  i, l( j9 A: v) r
                ZeroMemory(&mxl, sizeof(MIXERLINE));# P- F' ~  t' c2 m/ r7 d
; Z. ^# h- y* T+ h" j" \+ i8 y# S
8 e' x& @6 P/ j! f9 @- c% \
                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本
: W$ k6 b. T* ^& A" e. s                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
6 a+ I4 D1 _2 D5 R( y, w8 k                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
9 b" S7 @( `8 o. M0 v: y" k8 R
: }/ o* X% |7 r0 ?% \9 n/ Q8 a5 k% F
                // 取得混合器设备的指定线路信息
# G) d; c  @4 r; B) i( x: N3 i. \' O- M! b$ D                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,- X8 G8 b4 M; u4 v' l- f
                        &mxl,
5 @( q8 D$ o) i8 O5 w                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息
3 E$ a8 J5 k0 S                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);8 Y6 f5 u/ b6 z, T5 W% C, L
                if( rc!=MMSYSERR_NOERROR )( T+ {  v3 |' J: L& @" ]( `
                {
0 d- {! }; O7 n  Q0 ^6 @$ ?/ z8 y9 s  `                        //无法获取声音输入线路,尝试其他声卡# ~, z( L8 i% S  y7 V+ K
                        continue;
$ X; @6 ~# Q8 {                }
9 I- Q/ z! A0 L, T* G" I1 c  G4 `% y

9 d; P7 I; N. I) ~0 R                // 取得混合器设备的指定线路信息成功的话,则! x0 C( `# I/ w$ p, i% k
) s( y9 b8 f1 N' n9 l/ N" n; `/ j
: Q4 k, T+ B5 Q4 V8 Q# z! G6 t# V
                // 将连接数保存
6 T# {  ?6 w! _1 ~                DWORD   dwConnections   =   mxl.cConnections;
' u9 }; @6 u; q+ J( J( E                // 准备获取麦克风设备的ID
; r4 E5 a% a7 N5 C- ]+ L                DWORD   dwLineID = -1;
, |: J/ @; J  P5 [5 L                for( DWORD i=0 ; i<dwConnections; i++ )- v' ^4 l# p4 a% K) M/ e$ p1 K7 b; e
                {
- n  z; N' ~3 k- X                        // 枚举每一个设备,当Source的ID等于当前的迭代记数 / u0 e) V9 b. y
                        mxl.dwSource = i;4 ]# Z* p' S, C- z2 X
                        // 根据SourceID获得连接的信息
7 ]: N& |6 `0 q0 l                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl, : Y8 J' J. D2 z9 P. b( j; {
                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); ) v+ x" y/ j; Z7 ^6 M' n
                        // 判断函数执行错误
! Q& z# j& h6 @# H' `- v3 k                        if( MMSYSERR_NOERROR==rc )
/ }0 [2 O2 H  Z3 G1 `                        {
: u& ^4 {. O4 H1 h# ~                                // 如果当前设备类型是麦克风,则跳出循环。 6 f. g5 Y5 r6 i5 @$ \# p
                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
; i7 K$ r) B% o* s' V. S                                { 7 v1 z* a' z* ~( ]+ A
                                        dwLineID = mxl.dwLineID;
; O* f* {% V: a                                        break;
* X4 u& `8 y& V7 P: D, [1 T                                }
# B& {+ t) l5 c7 j& ^. ~5 g* P. i                        }
4 [3 S2 e: i) m6 [9 k                }5 ^1 W% c$ @+ L& L% @  ^! j* g
                // 如果没有找到,返回失败。
' C; W6 J0 V+ M* w# m                if( dwLineID==-1 )/ o( J# B! D+ [: v  _
                {
  U, B  g" e$ ?                        //尝试其他声卡9 R/ a$ T2 l  C2 u0 v3 S# P
                        continue;5 ]7 C! m/ b0 H$ e% k" o0 ]
                }! h" [1 X6 `: _' g3 g
, |! v- s+ C% D9 H2 F1 y7 r/ C

6 A# z' d0 D* G2 S1 v6 R- G( T8 p                // MIXERCONTROL 结构体变量清零5 }4 B4 }( [0 d3 N2 w
                ZeroMemory(&mxc, sizeof(MIXERCONTROL));
  a5 a8 U& ~- N2 s5 u1 I
2 f7 S, F- U! h" q# k5 u% k
' r% ?5 g  I+ }) l( v7 T' p+ K                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本
- k0 n) N7 N3 h( Y/ C, ~5 e4 I
: n0 D2 X- e# a# G& W
( z- f1 ^! ]. w$ u% ~                // MIXERLINECONTROLS 结构体变量清零, m! v) I/ }: H& x& G: G# t
                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));* z$ {) q0 K, p. ?3 F) U
6 g' K$ Z. n  L& H

+ I8 T$ r" {2 a                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本
- J. ]- `; c+ u: p' b1 R4 e+ f1 s$ H" l3 ]7 P! [' k

  `- r4 O: ^. c  c% O+ g* ^                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识: Z* b3 O* O! F: M6 @* N
                // 控制类型为控制音量5 C# y' N  `" l+ A! u$ M
                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
7 @+ {) h( Z) R+ b* f! H                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数
& Q2 e0 a# n. E- p                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针
- ^- U% {7 r$ t+ d! q4 W* |                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小2 |1 A/ h/ \, w9 e. k7 Q

5 g% Z' D; n& L9 x8 d
) t: h* ]# [+ }& e                // 取得控制器信息
8 O; ]+ p% t* J6 _                rc = mixerGetLineControls((HMIXEROBJ)hMixer,% Y* Y' y6 Z4 [9 S# ~/ t* u
                        &mxlc,6 }. `7 ?$ s( C6 i/ D3 J4 i0 V
                        MIXER_GETLINECONTROLSF_ONEBYTYPE);. G2 _! \3 v; U  ]5 L; J% u
1 i8 V% @' j# q" Q% s8 N4 e6 w6 D

( `3 ~3 x+ n2 ~" ~! `0 r& `- R8 @) r( c                // 取得控制器信息成功的话,则5 N- `. T6 w& @# j9 U
                if (MMSYSERR_NOERROR == rc)7 H1 d  t- N) {+ w
                {
" ?2 e7 s' @- x+ c                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.2 u, Q) d! Z+ c. `% K6 i/ u
                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
8 Q" q. ]4 G( L( C9 ^) [$ J. A' j                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)
% G! j! _5 i! W7 j9 n  \% w. @8 g0 u2 L7 D/ b) P

6 g( \* r; O! G. s6 e, ^" L( L                        // MIXERCONTROLDETAILS 结构体变量清零+ F9 v+ f! Y4 h' x- M
                        ZeroMemory(&mxcd, sizeof(mxcd));1 e& S/ O3 i; S- G& l
4 [* @- p. f% f: `; R6 X

8 f" M  e3 j' F: X' @  W                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本# g6 M4 }. y! T8 ^
                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识
; P  e; M' ?" K1 C8 R5 V                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针$ }+ l/ r( w( }: g6 Q
                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
' W$ t$ T; Z  F1 I" `                        mxcd.cChannels = 1;                 // 取得或设置全部通道3 x& e, r* E, p5 m

, F' T0 N3 m: s* K3 {1 A' {6 i7 U. n0 a1 Q6 |, k3 N
                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum. / u. {- O. a, p& z7 M7 t9 Q
" i' U$ m! J/ R$ v- _4 ~

$ C3 a6 F0 N* T/ w, M) z                        // 获得音量值
) s8 S3 h0 w" e, [                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,
" B* X0 L9 k2 _7 L. s( L9 |1 L                                &mxcd,
: y8 c6 ~8 s/ K% G7 P& T) W' h                                MIXER_GETCONTROLDETAILSF_VALUE);
! l+ c+ j4 G! y+ y- \& Y- X! ]& T3 N( v" G/ {% \

* T  f/ d1 g/ {& K0 ]4 C" a                        if (MMSYSERR_NOERROR == rc)
2 `8 k% ?# |( b) i                        {
0 ^/ L* j, ^* ]4 q                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;0 |+ y0 r, F4 H, i+ j
5 e- l. R% d, o5 H  c# A

# d- ^% Y  D- _" S% Y' D0 f                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;: f: [- t/ `* M9 k5 s5 P' F! f
                                printf("音量:%X", volStruct.lValue);
$ F9 _$ w, Y  H* Y8 t# F                                return index;
- ]+ t2 c" M. ~* g2 A$ j2 W                        }# l6 r8 u; f4 \0 [
                }$ [0 A$ q5 R, o5 B! B* k! ^
        }$ C" O$ w6 T' a" N

( ?' {' l/ D' ?$ I: ^+ }$ y+ p+ e, s7 K# }
        return -1;
) j2 U. \% |! {}# a' [% l- p8 M* t& W9 h

! P6 \1 |+ [. O8 X  q1 P, W        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html
1 n$ l6 m) k0 Z8 T  q. x% w                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-12-30 02:12 , Processed in 0.020938 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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