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

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

[复制链接]
发表于 2011-5-7 21:31:51 | 显示全部楼层 |阅读模式
原文:http://sunerok.blog.163.com/blog/static/231096422010112815525949/, h3 v' D; l, ?% w: j7 x% L; q
) F. C+ A+ @8 S3 l2 q6 z4 q
参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:$ o; g) q5 u9 i* d; Z; v

, I1 A* _1 t8 k5 F6 a
# Z( D: m2 `9 ]+ B3 oint DeviceManager::getAudioInputVolumn( const std::string &deviceName ). W9 M, Z) }+ N- Q* s' k
{
6 D7 J$ m6 V# N; B- ?* p) C2 ?' |1 C( U: w& R0 p1 v

/ Z' W( k- `' M4 V  ?9 y        MMRESULT          rc;     // 多媒体函数返回结果变量% k' G; ^: I) q5 K
        HMIXER            hMixer; // 混合器设备句柄, e' d% j# V$ E7 R* ]6 t1 Y; k# p
        MIXERLINE         mxl;    // 音频线路标准状态信息结构体
: S5 R% [$ ]9 x: U7 o& `        MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体( n9 ^: L* x+ ^
        MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体: t/ J! v- x2 }/ d: |

4 T- ^9 E) c$ n/ L  ?! p5 f0 k
- Q2 F# e9 \0 g        //枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即
$ b9 |, w8 i; |  a1 }; n4 p, }, s; H        //mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
' ~2 C% W( g6 v       //可能还是跟声卡驱动有关。) r3 f% l5 h% x- @( z$ j# Q
        for( int deviceID =0 ; true ; deviceID++ )" Q4 b3 r2 R$ e3 a+ N" N
        {
0 E& }& N% p* _# E                // 打开混合器设备2 W! j; H& |# C* Q% G+ W/ c
                rc = mixerOpen(&hMixer, // 返回的设备句柄
, x% q1 V2 E( d                        deviceID,       // 单声卡的设备ID为零
1 |8 C# R" f, r5 Q                        0,       // 不使用回调机制% A3 v/ `; M% ^# ]. i9 S
                        0,       // 回调函数参数
$ t0 l  K5 A) d1 }4 \0 ^! C0 e: O                        MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID
" E4 p  ]% N% |- V6 r! I! j5 D                if( MMSYSERR_NOERROR!=rc )7 u# B+ M1 F' O
                {
! }4 k; S7 c& w5 l' }                        //跳出循环
% y2 {4 E& ^( a7 |2 w                        break;% R, R- w. _3 j  i3 `3 o  B
                }
, X# q' k5 u5 w; a# E                // 打开混合器设备无错的话,则
- O4 r. |1 V8 q. H7 m+ P, o
. j* w2 O1 a( S) [1 [
( u# h4 ?+ x# x3 N5 J+ U$ M% m                // MIXERLINE 结构体变量清零
  U& y& K# I1 [5 g# Q3 H                ZeroMemory(&mxl, sizeof(MIXERLINE));: D# h$ p" L  i0 _' `+ P

5 k; r# j1 z- S; v9 L
3 n. ]  I6 {) h$ _+ l. U                mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本
9 s% D# [( h0 O. ?& P; ?( e3 [& C                // 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
0 q- @8 F6 D/ e                mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
( W% Y" B* _6 g' n' c0 c% ^: }
. _. s) y( C+ G1 Q7 c) G: O
. `9 h/ v5 n+ D2 a  p" `4 Q- V0 @3 o                // 取得混合器设备的指定线路信息
& J/ l( j# F! W% q8 c                rc = mixerGetLineInfo((HMIXEROBJ)hMixer,8 ~2 a$ z& n5 G0 G
                        &mxl,: x1 Z6 \$ b/ l/ t* }% o* q4 o
                        // 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息+ U" n% A) y5 r1 w0 g$ |& ~' A9 Y
                        MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);; i. H% h7 \1 x% E' h, s
                if( rc!=MMSYSERR_NOERROR )
( _- J+ z1 N8 w& S+ p6 i' I, O                {
. I. a& {! ~1 q3 V                        //无法获取声音输入线路,尝试其他声卡
- z9 z4 v( h0 @1 N. r6 P% P/ x; q2 |                        continue;+ H# w6 [) ]9 B- U' U( k/ |  _! V
                }+ M1 C: B; A  K  S
1 v0 h. g5 n! a

/ A( y8 D. _9 T! f                // 取得混合器设备的指定线路信息成功的话,则$ V; e/ H6 w# P/ u! K

: @) p+ Q) N) C- u( y
8 \2 r. V: {- h4 N0 l8 ^! B7 C4 Y                // 将连接数保存 3 t- w2 A1 A- Y/ |$ ]/ N
                DWORD   dwConnections   =   mxl.cConnections; $ M% _' \* R- M
                // 准备获取麦克风设备的ID , u* I! G$ Z1 X
                DWORD   dwLineID = -1;
, K9 E3 [4 R! x  P) k8 r                for( DWORD i=0 ; i<dwConnections; i++ )
5 O6 a# D1 v( u; N% |' C& R                { # A; f5 a- P! Y5 Y% z+ Q6 _7 ^
                        // 枚举每一个设备,当Source的ID等于当前的迭代记数 3 O; ]2 [. @1 O) T  F) H
                        mxl.dwSource = i;* _5 H1 S  {! z
                        // 根据SourceID获得连接的信息
/ H1 n0 X1 q4 F5 X% s% ?                        rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl, ( C5 w( Q$ h! _$ o5 I: I/ d
                                MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); 0 @7 L' v1 W3 m; ^5 f
                        // 判断函数执行错误
6 ^% T+ V$ }' x6 M8 K8 ]                        if( MMSYSERR_NOERROR==rc ): ~5 r+ f- y& ?* l) k$ P
                        {
8 u) c5 w+ P# v                                // 如果当前设备类型是麦克风,则跳出循环。 3 n( L5 E- D' T+ ~4 }
                                if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
9 s9 P1 w! N2 N3 v- F                                {   J) R, V) {) }) C* v4 A2 n
                                        dwLineID = mxl.dwLineID; ! M0 i: k( ?7 v
                                        break;
/ E8 N. u* A7 o& X0 z' |! D) ]- j% t                                }
  `! b) `2 g! v; _6 b                        }
; C. `0 K7 P' F; }                }/ o$ V+ Y# `1 e# G/ M
                // 如果没有找到,返回失败。 # n- T! N$ x9 I0 ]; j/ ]
                if( dwLineID==-1 )# B: j8 e" s. ^6 e  }
                {
2 v! b. ^+ S5 g& y1 @1 y4 Q                        //尝试其他声卡5 m2 b/ O4 M& R7 `( x
                        continue;
) Q; |6 Q/ s9 h) B                }
' t' Z2 z- v% z0 P1 ]* n, w# S3 S* T5 k  w+ ]

/ K/ A7 w  T. L* A) K& m/ c! x2 o                // MIXERCONTROL 结构体变量清零
8 n* u* e; L; r/ f/ o                ZeroMemory(&mxc, sizeof(MIXERCONTROL));3 T1 f$ `0 j3 e* M0 \4 Y' J  _
" T# K; h0 s: o) r8 R

1 U. w1 Y2 i$ j* I" e2 \: x, x                mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本
2 N! |4 N- |% [- U: g4 x2 R- h. V
9 [6 I" g, I& k6 u# h8 o7 [6 e3 i
                // MIXERLINECONTROLS 结构体变量清零5 P7 `' E2 C' ?# y: q& ?
                ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));  ?% ?- F5 U" Z& P% g

% Z) J' v+ I4 n' F$ x2 f1 p; P+ N9 j5 G8 ?
                mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本
4 X/ ^0 F9 w8 ^
2 N, {, n0 s- t  y% }3 }1 D& E
! Y& _6 D' A/ h5 F/ i- K. e* [, U& ]                mxlc.dwLineID = dwLineID; // 上面取得的声卡音频输入线路标识; g  F# Z' I: r# A& K* \$ n4 D4 q
                // 控制类型为控制音量
/ p* O. L7 d+ C( b% w% I" @                mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;: t6 q" ?. m, U. a: R' B
                mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数( ?" e! C/ m! ?7 ~
                mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针
6 S: S1 g8 a; B6 I. V5 M, z1 D9 K# ~                mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小" ^+ F% R: G6 a' {

, {6 v  K4 N8 H4 |: _8 |  P4 y
/ v$ |3 p8 i  G                // 取得控制器信息, ^, W" p7 e# W5 o0 E% h
                rc = mixerGetLineControls((HMIXEROBJ)hMixer,) M! ^+ W+ W: V  b; q
                        &mxlc,, D- o4 V% Z* o' B7 E- l0 H
                        MIXER_GETLINECONTROLSF_ONEBYTYPE);
! G* f6 i' U8 V8 i' r
5 M. L. F2 K9 ]( V0 S$ Z& J  C4 w4 q1 Z' T3 P! M
                // 取得控制器信息成功的话,则. n% s' L% S3 W/ c- `1 p
                if (MMSYSERR_NOERROR == rc)0 m( L. C  V! F
                {, n) c3 `! I* }9 b5 \
                        // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
, X9 L) B* |" E0 H                        MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息' V  j9 W9 V- }# ~# c& P+ f
                        MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)
  r% H$ u4 n' @' p7 }9 K( C/ p+ A/ K6 g/ s
0 |  P& _( P8 g- s! N# [
                        // MIXERCONTROLDETAILS 结构体变量清零9 Y7 u  E# C" d+ N$ Q2 h
                        ZeroMemory(&mxcd, sizeof(mxcd));
8 ^1 o& J5 A( a: K1 X5 P1 ^6 x3 a9 l0 d# f
/ A- c1 }6 z$ S4 _! U6 y2 n& U
                        mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本
9 M/ L" k3 c  }                        mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识2 y+ Z2 [8 s  `3 a0 J( R9 R) r
                        mxcd.paDetails = &volStruct;        // 音量结构体变量指针
3 Z( d( x) K, Q8 c$ M9 ~                        mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小) J* G! p+ V; x0 j2 v# s
                        mxcd.cChannels = 1;                 // 取得或设置全部通道0 h; W& ?  [4 ^' u9 L; G& m
# r$ q% J1 f1 k" x
& o! ^0 a7 O  G2 X# x
                        //  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum. + C9 T4 I. Y6 u" t; m  }8 j
% @1 M& {& P6 q2 L7 y/ h6 W
; u+ M  e+ m# g& E$ t* E
                        // 获得音量值0 L6 y3 ~- H( y, G  U5 B. Z
                        rc = mixerGetControlDetails((HMIXEROBJ)hMixer,
1 b: b1 R4 {* l- o3 C+ o. P; U8 [8 L                                &mxcd,1 i3 h  T! g7 e/ d$ t, B6 e
                                MIXER_GETCONTROLDETAILSF_VALUE);. M5 [" _6 m5 B: n  F6 a
2 C. ^+ d8 z5 w- `2 l

8 K4 `0 C; N9 }4 b- I6 n                        if (MMSYSERR_NOERROR == rc)
5 h% n% s8 `4 C6 X% O# {                        {
" C! h/ J2 b+ L5 b9 d, _6 X                                long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;7 M2 e) `& V( P. Z. S( E  R# y
& d" S( |! [6 G1 x

% E; b; q) B1 [% z* A                                int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;
* L! |. q5 B1 `6 x  t( g1 |                                printf("音量:%X", volStruct.lValue);. l, J, @  c2 @, w1 @
                                return index;# L3 ~! o2 Z5 t: \* T
                        }
+ _! z9 q  v* }                }
, V/ ^: m* M2 j0 b: }        }
% I/ Q+ a6 Y( n* `- O, e, |: t- f3 W; u- ^0 X1 P9 ^2 _

4 M5 z" c# _+ c/ }! ~- r1 \        return -1;
1 d5 M7 _. U, J7 B- [% v}
- y# p! l0 A3 }' g* I; A; q3 ~9 {9 F* {; F. ~: @' e# C* }% _6 G3 `( ^
        相关网址:http://topic.csdn.net/t/20050606/10/4062001.html7 |; ]* x! R7 q# Q9 _9 r0 G1 x
                        http://blog.csdn.net/tangaowen/archive/2010/07/28/5771149.aspx
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-11-14 14:44 , Processed in 0.019011 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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