TNB Library
TnbMixerVolume.h
[詳解]
1#pragma once
11#include "TnbDef.h"
12#include <mmsystem.h>
13
14
15
16//TNB Library
17namespace TNB
18{
19
20
21
36{
37public:
38
40 CMixerVolume(void) : m_hMix(NULL), m_result(MMSYSERR_NOERROR)
41 {
42 }
43
46 {
47 Close();
48 }
49
53 void Close(void)
54 {
55 if ( m_hMix != NULL )
56 {
57 HMIXER h = reinterpret_cast<HMIXER>(m_hMix);
58 ::mixerClose(h);
59 m_hMix = NULL;
60 }
61 }
62
70 bool Open(UINT mxid = 0, HWND hCallbackWnd = NULL)
71 {
72 Close();
73 HMIXER h = NULL;
74 DWORD dwCallback = reinterpret_cast<DWORD>(hCallbackWnd);
75 DWORD dwFlag = MIXER_OBJECTF_MIXER;
76 if ( dwCallback != 0 )
77 {
78 dwFlag |= CALLBACK_WINDOW;
79 }
80 if ( m_res(::mixerOpen(&h, mxid, dwCallback, 0, dwFlag)) )
81 {
82 m_hMix = reinterpret_cast<HMIXEROBJ>(h);
83 Zero(m_mixerLine);
84 m_mixerLine.cbStruct = sizeof(MIXERLINE);
85 if ( m_res(::mixerGetLineInfo(m_hMix, &m_mixerLine, MIXER_GETLINEINFOF_DESTINATION | MIXER_OBJECTF_HMIXER)) )
86 {
87 return true;
88 }
89 }
90 Close();
91 return false;
92 }
93
99 LPCTSTR GetDeviceName(void)
100 {
101 return (m_hMix == NULL) ? NULL : m_mixerLine.Target.szPname;
102 }
103
108 size_t GetLinesNumber(void) const
109 {
110 return (m_hMix == NULL) ? 0 : m_mixerLine.cConnections;
111 }
112
127 struct TParam
128 {
129 TCHAR szLineName[MIXER_LONG_NAME_CHARS];
131 TCHAR szVolumeName[MIXER_LONG_NAME_CHARS];
132 DWORD left;
133 DWORD right;
134 DWORD minimum;
135 DWORD maximum;
136 TCHAR szMuteName[MIXER_LONG_NAME_CHARS];
137 bool isMute;
138 };
139
147 bool GetMasterVolume(TParam& _prm) const
148 {
149 return GetComponentTypeVolume(_prm, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS);
150 }
151
160 bool GetLineVolume(TParam& _prm, size_t line) const
161 {
162 if ( line == INVALID_INDEX ) { return GetMasterVolume(_prm); }
163 Zero(_prm);
164 return m_LineParam(_prm, line, 0, true);
165 }
166
175 bool GetComponentTypeVolume(TParam& _prm, DWORD componentType) const
176 {
177 Zero(_prm);
178 return m_LineParam(_prm, 0, componentType, true);
179 }
180
191 bool SetMasterVolume(DWORD left, DWORD right, bool isMute = false)
192 {
193 return SetComponentTypeVolume(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, left, right, isMute);
194 }
195
207 bool SetLineVolume(size_t line, DWORD left, DWORD right, bool isMute = false)
208 {
209 if ( line == INVALID_INDEX ) { return SetMasterVolume(left, right, isMute); }
210 TParam p = { 0 };
211 p.left = left;
212 p.right = right;
213 p.isMute = isMute;
214 return m_LineParam(p, line, 0, false);
215 }
216
228 bool SetComponentTypeVolume(DWORD componentType, DWORD left, DWORD right, bool isMute = false)
229 {
230 TParam p = { 0 };
231 p.left = left;
232 p.right = right;
233 p.isMute = isMute;
234 return m_LineParam(p, 0, componentType, false);
235 }
236
241 MMRESULT GetLastError(void) const
242 {
243 return m_result;
244 }
245
250 static size_t GetDevicesNumber(void)
251 {
252 return ::mixerGetNumDevs();
253 }
254
255private:
256
266 bool m_LineParam(TParam& _prm, size_t line, DWORD compType, bool isGet) const
267 {
268 if ( m_hMix == NULL )
269 {
270 m_res(MMSYSERR_ERROR);
271 return false;
272 }
273 MIXERLINE ml = { 0 };
274 ml.cbStruct = sizeof(MIXERLINE);
275 DWORD info = MIXER_OBJECTF_HMIXER;
276 if ( compType != 0 )
277 {
278 ml.dwComponentType = compType;
279 info |= MIXER_GETLINEINFOF_COMPONENTTYPE;
280 }
281 else
282 {
283 ml.dwSource = line;
284 info |= MIXER_GETLINEINFOF_SOURCE;
285 }
286 if ( ! m_res(::mixerGetLineInfo(m_hMix, &ml, info)) )
287 {
288 return false;
289 }
290 MemCopy(_prm.szLineName, ml.szName, MIXER_LONG_NAME_CHARS);
291 _prm.componentType = ml.dwComponentType;
292 CWorkMemT<MIXERCONTROL> amc(ml.cControls);
293 loop ( i, ml.cControls )
294 {
295 amc[i].cbStruct = sizeof(MIXERCONTROL);
296 }
297 MIXERLINECONTROLS mlc = { 0 };
298 mlc.cbStruct = sizeof(mlc);
299 mlc.dwLineID = ml.dwLineID;
300 mlc.cControls = ml.cControls;
301 mlc.cbmxctrl = sizeof(MIXERCONTROL);
302 mlc.pamxctrl = amc;
303 if ( ! m_res(::mixerGetLineControls(m_hMix, &mlc, MIXER_GETLINECONTROLSF_ALL | MIXER_OBJECTF_HMIXER)) )
304 {
305 return false;
306 }
307 loop ( i, ml.cControls )
308 {
309 MIXERCONTROL* P = &amc[i];
310 MIXERCONTROLDETAILS mcd = { 0 };
311 mcd.cMultipleItems = P->cMultipleItems;
312 if ( (P->fdwControl & MIXERCONTROL_CONTROLF_MULTIPLE) == 0 )
313 {
314 mcd.cMultipleItems = 0;
315 }
316 mcd.cChannels = ml.cChannels;
317 if ( (P->fdwControl & MIXERCONTROL_CONTROLF_UNIFORM) != 0 )
318 {
319 mcd.cChannels = 1;
320 }
321 MIXERCONTROLDETAILS_BOOLEAN bn = { 0 };
322 MIXERCONTROLDETAILS_UNSIGNED us[2] = { 0 };
323 if ( P->dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME )
324 {
325 mcd.paDetails = us;
326 mcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
327 us[0].dwValue = _prm.left;
328 us[1].dwValue = _prm.right;
329 }
330 else if ( P->dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE )
331 {
332 mcd.paDetails = &bn;
333 mcd.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
334 mcd.cChannels = 1;
335 bn.fValue = _prm.isMute;
336 }
337 else
338 {
339 continue;
340 }
341 mcd.dwControlID = P->dwControlID;
342 mcd.cbStruct = sizeof(mcd);
343 //
344 if ( isGet )
345 {
346 if ( ! m_res(::mixerGetControlDetails(m_hMix, &mcd, MIXER_GETCONTROLDETAILSF_VALUE | MIXER_OBJECTF_HMIXER)) )
347 {
348 return false;
349 }
350 if ( P->dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME )
351 {
352 MemCopy(_prm.szVolumeName, P->szName, MIXER_LONG_NAME_CHARS);
353 _prm.left = us[0].dwValue;
354 _prm.right = us[1].dwValue;
355 if ( ml.cChannels == 1 )
356 {
357 _prm.right = DWORD_MAX;
358 }
359 _prm.minimum = P->Bounds.dwMinimum;
360 _prm.maximum = P->Bounds.dwMaximum;
361 }
362 else if ( P->dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE )
363 {
364 MemCopy(_prm.szMuteName, P->szName, MIXER_LONG_NAME_CHARS);
365 _prm.isMute = !! bn.fValue;
366 }
367 }
368 else
369 {
370 if ( ! m_res(::mixerSetControlDetails(m_hMix, &mcd, MIXER_SETCONTROLDETAILSF_VALUE | MIXER_OBJECTF_HMIXER)) )
371 {
372 return false;
373 }
374 }
375 }
376 return true;
377 }
379 bool m_res(MMRESULT r) const
380 {
381 m_result = r;
382 return r == MMSYSERR_NOERROR;
383 }
384 HMIXEROBJ m_hMix;
385 mutable MMRESULT m_result;
386 MIXERLINE m_mixerLine;
387};
388
389
390
391}; // TNB
392
TNBライブラリの定義ヘッダ
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
[ETC] コピー不可能スーパークラス.
Definition: TnbDef.h:599
ミキサーボリュームクラス
static size_t GetDevicesNumber(void)
[取得] デバイス数取得
size_t GetLinesNumber(void) const
[取得] ライン数取得
MMRESULT GetLastError(void) const
[取得] エラーコード取得.
bool GetLineVolume(TParam &_prm, size_t line) const
[取得] ラインボリューム取得.
CMixerVolume(void)
コンストラクタ
void Close(void)
[設定] クローズ
bool Open(UINT mxid=0, HWND hCallbackWnd=NULL)
[設定] オープン
bool GetMasterVolume(TParam &_prm) const
[取得] マスターボリューム取得.
bool SetMasterVolume(DWORD left, DWORD right, bool isMute=false)
[設定] マスターボリューム設定.
~CMixerVolume(void)
デストラクタ
LPCTSTR GetDeviceName(void)
[取得] デバイス名取得.
bool SetLineVolume(size_t line, DWORD left, DWORD right, bool isMute=false)
[設定] ラインボリューム設定.
bool SetComponentTypeVolume(DWORD componentType, DWORD left, DWORD right, bool isMute=false)
[設定] コンポーネントタイプボリューム設定.
bool GetComponentTypeVolume(TParam &_prm, DWORD componentType) const
[取得] コンポーネントタイプボリューム取得.
ワークメモリテンプレート.
Definition: TnbDef.h:633
void Zero(V &value)
[設定] ゼロクリア.
Definition: TnbDef.h:399
TNB Library
Definition: TnbDoxyTitle.txt:2
void MemCopy(T *_pDst, const void *pSrc, size_t len)
[複製] メモリコピー
Definition: TnbDef.h:376
ボリュームパラメータ型
TCHAR szMuteName[MIXER_LONG_NAME_CHARS]
ミュート名
DWORD right
右ボリューム値
DWORD left
左ボリューム値
DWORD maximum
ボリューム値最大
DWORD componentType
コンポーネントタイプ
TCHAR szVolumeName[MIXER_LONG_NAME_CHARS]
ボリューム名
DWORD minimum
ボリューム値最小
TCHAR szLineName[MIXER_LONG_NAME_CHARS]
ライン名