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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/) x6 ^: W5 I  d* I4 ?0 P
/ X/ x" ^, P) y( B5 V8 }# M
参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:1 ], L- v+ V/ g& @
% j! U/ D$ {( @& q6 `6 {7 E, v  T

+ X$ e; g/ _5 i& P8 p; oint DeviceManager::getAudioInputVolumn( const std::string &deviceName )
3 |) G7 I7 D& _8 G+ O" l{- G* u0 ]/ i, D% ?6 V& p; B

+ `/ M9 T. ?7 ^) v% O5 r
& [  h1 f( i; R0 R# l7 F' k8 E        MMRESULT          rc;     // 多媒体函数返回结果变量
8 I; e, |; x& \2 R, ~; m        HMIXER            hMixer; // 混合器设备句柄" n6 d, @1 q6 j6 c2 ^
        MIXERLINE         mxl;    // 音频线路标准状态信息结构体1 S) G: x) E: X3 W. O  C
        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体9 |+ C! v( H! q4 _* u; Y, O
        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
9 v/ S3 l; r0 E4 b
* f/ e& h4 p; N$ M) l% E* R% m3 J, r! j) k5 M
        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即
' n1 ~; F6 Q5 I1 D% U: U* S: |& ^        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,( C4 g3 U5 @# ]1 b& `7 k1 |
       //可能还是跟声卡驱动有关。
) [' M. [1 @9 c        for( int deviceID =0 ; true ; deviceID++ )
+ t% R; W9 V, x" y0 Z+ E- @4 p( n1 g        {9 \+ R  V# L/ x/ O) X9 d- ~" m- x9 j
                // 打开混合器设备3 F: a0 e2 P+ d8 f
                rc = mixerOpen(&hMixer, // 返回的设备句柄5 n5 v0 H4 Q5 ]" s/ s8 y
                        deviceID,       // 单声卡的设备ID为零6 o1 v1 K" _/ g! M4 X9 H
                        0,       // 不使用回调机制& k& S# Z1 [9 Q9 ~1 ^
                        0,       // 回调函数参数9 h4 S; c$ n: i7 x6 Y
                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID
/ b" A: g8 G! J7 l2 p# ?                if( MMSYSERR_NOERROR!=rc )
# [' _+ `, @7 f6 P5 P                {/ a# |4 j' ^% |  F6 w5 W
                        //跳出循环
) T" M" l0 r' e7 I                        break;
, `: x' B1 H6 [9 ]2 Q+ E. ]0 D                }, U$ q& Y9 ~/ h# F" C
                // 打开混合器设备无错的话,则
7 i& ^5 c: w3 w7 S# w4 O: D  ~4 i1 e/ W! a

% C! M7 A: U! f                // MIXERLINE 结构体变量清零: M, ?! d2 E0 f5 r/ Q
                ZeroMemory(&mxl, sizeof(MIXERLINE));
# Y  k! O% _, m" e  D
+ E9 M4 x4 A& |$ Y, Y" l
/ J& x% F9 J1 w                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本
4 C! J5 q" f8 H( B( U& U& H/ ]                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS# V. `( j. k6 M- i. C* a7 F! i# E
                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
3 T$ D  H; S+ j
* f% B4 m; G; C% e' b: S! j. I2 x: Y0 R
                // 取得混合器设备的指定线路信息( L# G  F( `+ C0 J3 a( U
                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,
0 z3 Q# {$ W2 ]& g. O7 C0 E: w6 B& s                        &mxl,
4 ^& D/ h5 L" l) I5 N                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息
9 {5 ^+ d; ^0 X7 y                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
8 q1 X* c+ X3 X1 Z1 |  f                if( rc!=MMSYSERR_NOERROR )) E7 I$ `" a& M
                {
4 L) D) y" A5 b; E  ]# `7 G                        //无法获取声音输入线路,尝试其他声卡3 {$ l8 r& U7 @' ?+ V
                        continue;0 S, V6 T  n2 N$ Q* r: W
                }
9 X% ~- q/ s' _. s: T" ?" v3 f$ b+ F
0 y- d. M+ G5 t
+ X' [# c9 s' P( y" m, x& p! v5 `                // 取得混合器设备的指定线路信息成功的话,则; D2 o/ f2 Z  ?; G! U* ?0 S

0 {" \+ p. N' n7 P6 r+ c
9 t0 H  B. e8 y5 H                // 将连接数保存 + e4 F  Z  i, S& s, R
                DWORD   dwConnections   =   mxl.cConnections;   [( U; {; x: K
                // 准备获取麦克风设备的ID " A8 N8 ]0 K" X6 t( n5 P
                DWORD   dwLineID = -1; / x- p( a- s3 |0 M. k, {
                for( DWORD i=0 ; i<dwConnections; i++ )
2 `( y  B2 R  v                {
7 ]( ?4 v/ u0 a3 \                        // 枚举每一个设备,当Source的ID等于当前的迭代记数 2 ~6 \% o5 @% T5 X
                        mxl.dwSource = i;7 K4 V! I) P" ]5 t
                        // 根据SourceID获得连接的信息 - `1 J% R6 c$ u
                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl, ' i( Q1 y" H6 O4 ]: Y' Z
                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); 9 |) L9 Z# P( |+ d' c; M
                        // 判断函数执行错误 ' o  j$ g0 f, K2 G1 K
                        if( MMSYSERR_NOERROR==rc )  `& U7 j$ z3 k7 Y
                        { $ p5 b/ X- ?4 P* E( C9 w+ g
                                // 如果当前设备类型是麦克风,则跳出循环。
7 B' b  U* X( G* N0 R0 M8 [                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
5 g/ _" Y) Z" x                                { * ?; \+ h- X% @# E2 [- @5 b: W
                                        dwLineID = mxl.dwLineID;
  N% z+ q' x. E$ g                                        break; ! L( N9 \  a0 `$ ~0 Z% a
                                }
- V9 a5 y+ V6 A. b- T                        }
/ ~+ v' B$ h) G9 ]+ W% i/ @                }4 C$ P( \; k. R
                // 如果没有找到,返回失败。 8 v% W$ ?7 g7 f; w* K3 U
                if( dwLineID==-1 ). E) [+ {. o3 K) g) `
                {
' j; I) W* k! |6 Z  [7 a+ k: ^. {# s                        //尝试其他声卡
3 O) B! Z/ Z5 o: v                        continue;
; U; K, F) Y8 o8 ~                }
5 _8 u" [- f2 t, ~& J2 C0 g4 \  K
- o5 d; D7 _- Q; U/ k" [
) @- v4 X$ W" C/ K& {: Q/ N                // MIXERCONTROL 结构体变量清零
6 V. x- C  |* M5 N+ `                ZeroMemory(&mxc, sizeof(MIXERCONTROL));& I: ]+ m- t6 R9 O. N

7 ~0 A8 P" l( q9 n, k% R* h, m6 j; M* s2 ?2 ]( D
                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本
7 w% i5 W; P' o4 _; D% ^' p
' A7 P2 m7 r0 g, x2 Z- l! e8 [  g" ~  a) l5 F9 z% u0 V8 k
                // MIXERLINECONTROLS 结构体变量清零
0 }# A) j2 D3 o$ Q( l, G( o                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));  w" O7 d6 ?4 M3 m$ Q2 W9 h
3 V5 m8 m4 U9 k* o* V

1 q: _9 R7 [) n                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本& X7 Z  z# ?4 I3 Z
( [* P% K# ^  d/ B. ?- S

- \/ z: ]$ Q$ C: O                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识
; R) a1 o4 a; y3 a( F                // 控制类型为控制音量" W% o' k9 E. I7 ?2 \
                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;/ X/ l. U  D: x
                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数
* c1 P2 v8 L2 N1 C) J) y                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针3 [/ l+ x# j) b, [9 S9 [& b0 [4 S
                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小
5 v6 ~- y( x' j& }1 i) X/ e  R$ }6 Q: F  H- N6 K/ g4 ?; v
' \) k# }9 @3 m
                // 取得控制器信息! x' [0 ?) e. L0 i4 a0 s
                rc = mixerGetLineControls((HMIXEROBJ)hMixer,4 s3 Z0 @/ B" w' Q# a) q$ f
                        &mxlc,) E0 p7 }8 R+ ]5 `' {
                        MIXER_GETLINECONTROLSF_ONEBYTYPE);; ^. V+ y9 @# m
3 E7 q( r/ i4 y7 n( b6 {' i
9 X& a9 w% y% L; N
                // 取得控制器信息成功的话,则
/ m) z2 M" w2 K                if (MMSYSERR_NOERROR == rc)
# [2 u/ {* J" N  H# @                {' R& d4 z" {8 x+ r$ L: u$ S6 P
                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.9 F% O7 m# W: D) T2 N
                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息
) i( [, W8 H- Y6 o3 M4 `                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)1 D1 Z* M6 [& B/ X. j8 F8 t- E: k
; v7 u. R2 V/ e; B
* K6 \) u% w" H. ?
                        // MIXERCONTROLDETAILS 结构体变量清零
! \# v2 }6 P6 g; Q, [1 ^                        ZeroMemory(&mxcd, sizeof(mxcd));
' t. r3 K$ x1 N( N5 o$ z! |
- T& v; k! n- R  w
, Y: d5 z) l& C* t+ |                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本
8 O- v) w  y7 |, i/ q* P. s                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识1 o) c% O$ v1 {! Y
                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针
1 @% x% m& p( i, h1 g- U                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小
) X/ Y' s. L$ n, v4 q                        mxcd.cChannels = 1;                 // 取得或设置全部通道
5 n# }3 b9 S* o& ]4 p9 e3 a0 ]7 A* A4 H
4 F1 v& l3 T/ K! M0 c' k- T
                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum. 4 ], t9 K( d9 d" o" w- N* K: R/ O9 O
" R. K0 g8 J( Q3 u" A! Q

/ j  G3 r' r" w' L4 `                        // 获得音量值
& X- @- J# g' D6 [, e* c5 b                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,$ g: V: G: q1 G$ q! c# ]" r
                                &mxcd,
, q0 ?/ c& w$ n" G( s                                MIXER_GETCONTROLDETAILSF_VALUE);! P2 Z% a1 @/ P5 t
' n7 T# ?/ x  S3 n
6 q  j! l4 l4 t$ X( G8 d: s
                        if (MMSYSERR_NOERROR == rc)3 |! J" T: L. q5 a
                        {7 w9 @8 L8 [4 f( D* V" I: s
                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;1 g4 Y4 R2 f9 J2 z6 o" y0 ?

/ M9 k; w& ]- |4 B
4 |" e: _; N, [! x* F$ H9 o  e                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;. u3 h) Y, u3 P0 B& H0 V; X
                                printf("音量:%X", volStruct.lValue);
4 C7 `+ I$ P. @3 W                                return index;
  b! y# s. \- c7 H% |  c) r                        }* l9 v4 U' O3 q8 g& P6 {
                }
& k* @; G8 W) R+ g+ o) u- K        }
; r/ J8 R1 n6 Q, y5 @$ O
5 h* @% c* z, s2 A' O) x
- S- X1 Q3 G  U% E% D6 E        return -1;
8 u0 V% g0 {" e5 Q3 G}5 w8 B) ^+ o5 d3 ~9 E7 l

. [6 P. M: }+ p1 h- o5 a+ U        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html: b: J! I$ p7 b4 \7 T5 x- A
                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-8-9 04:15 , Processed in 0.035056 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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