ReactOS 0.4.16-dev-197-g92996da
audio.c
Go to the documentation of this file.
1/*
2 *
3 * PROJECT: ReactOS Multimedia Control Panel
4 * FILE: dll/cpl/mmsys/audio.c
5 * PURPOSE: ReactOS Multimedia Control Panel
6 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
7 * Johannes Anderwald <janderwald@reactos.com>
8 * Dmitry Chapyshev <dmitry@reactos.org>
9 */
10
11#include "mmsys.h"
12
13typedef struct _GLOBAL_DATA
14{
18
22
24
25VOID
27{
28 WAVEOUTCAPSW waveOutputPaps;
29 WAVEINCAPSW waveInputPaps;
30 MIDIOUTCAPSW midiOutCaps;
31 WCHAR szNoDevices[256];
32 UINT DevsNum;
33 UINT uIndex;
34 HWND hCB;
35 LRESULT Res;
36
37 LoadStringW(hApplet, IDS_NO_DEVICES, szNoDevices, _countof(szNoDevices));
38
39 // Init sound playback devices list
41
42 DevsNum = waveOutGetNumDevs();
43 if (DevsNum < 1)
44 {
45 Res = SendMessageW(hCB, CB_ADDSTRING, 0, (LPARAM)szNoDevices);
46 SendMessageW(hCB, CB_SETCURSEL, (WPARAM)Res, 0);
47 pGlobalData->bNoAudioOut = TRUE;
48 }
49 else
50 {
51 WCHAR DefaultDevice[MAX_PATH] = {0};
52 HKEY hKey;
53 DWORD dwSize = sizeof(DefaultDevice);
54 UINT DefaultIndex = 0;
55
56 if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Multimedia\\Sound Mapper", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
57 {
58 RegQueryValueExW(hKey, L"Playback", NULL, NULL, (LPBYTE)DefaultDevice, &dwSize);
59 DefaultDevice[_countof(DefaultDevice) - 1] = UNICODE_NULL;
61 }
62
63 for (uIndex = 0; uIndex < DevsNum; uIndex++)
64 {
65 if (waveOutGetDevCapsW(uIndex, &waveOutputPaps, sizeof(waveOutputPaps)))
66 continue;
67
68 Res = SendMessageW(hCB, CB_ADDSTRING, 0, (LPARAM)waveOutputPaps.szPname);
69
70 if (CB_ERR != Res)
71 {
72 SendMessageW(hCB, CB_SETITEMDATA, Res, (LPARAM)uIndex);
73 if (!_wcsicmp(waveOutputPaps.szPname, DefaultDevice))
74 DefaultIndex = Res;
75 }
76 }
77 SendMessageW(hCB, CB_SETCURSEL, (WPARAM)DefaultIndex, 0);
78 }
79
80 // Init sound recording devices list
82
83 DevsNum = waveInGetNumDevs();
84 if (DevsNum < 1)
85 {
86 Res = SendMessageW(hCB, CB_ADDSTRING, 0, (LPARAM)szNoDevices);
87 SendMessageW(hCB, CB_SETCURSEL, (WPARAM)Res, 0);
88 pGlobalData->bNoAudioIn = TRUE;
89 }
90 else
91 {
92 WCHAR DefaultDevice[MAX_PATH] = {0};
93 HKEY hKey;
94 DWORD dwSize = sizeof(DefaultDevice);
95 UINT DefaultIndex = 0;
96
97 if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Multimedia\\Sound Mapper", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
98 {
99 RegQueryValueExW(hKey, L"Record", NULL, NULL, (LPBYTE)DefaultDevice, &dwSize);
100 DefaultDevice[_countof(DefaultDevice) - 1] = UNICODE_NULL;
102 }
103
104
105 for (uIndex = 0; uIndex < DevsNum; uIndex++)
106 {
107 if (waveInGetDevCapsW(uIndex, &waveInputPaps, sizeof(waveInputPaps)))
108 continue;
109
110 Res = SendMessageW(hCB, CB_ADDSTRING, 0, (LPARAM)waveInputPaps.szPname);
111
112 if (CB_ERR != Res)
113 {
114 SendMessageW(hCB, CB_SETITEMDATA, Res, (LPARAM)uIndex);
115 if (!_wcsicmp(waveInputPaps.szPname, DefaultDevice))
116 DefaultIndex = Res;
117 }
118 }
119 SendMessageW(hCB, CB_SETCURSEL, (WPARAM)DefaultIndex, 0);
120 }
121
122 // Init MIDI devices list
124
125 DevsNum = midiOutGetNumDevs();
126 if (DevsNum < 1)
127 {
128 Res = SendMessageW(hCB, CB_ADDSTRING, 0, (LPARAM)szNoDevices);
129 SendMessageW(hCB, CB_SETCURSEL, (WPARAM)Res, 0);
130 pGlobalData->bNoMIDIOut = TRUE;
131 }
132 else
133 {
134 WCHAR DefaultDevice[MAX_PATH] = {0};
135 HKEY hKey;
136 DWORD dwSize = sizeof(DefaultDevice);
137 UINT DefaultIndex = 0;
138
139 if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Multimedia\\MIDIMap", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
140 {
141 RegQueryValueExW(hKey, L"szPname", NULL, NULL, (LPBYTE)DefaultDevice, &dwSize);
142 DefaultDevice[_countof(DefaultDevice) - 1] = UNICODE_NULL;
144 }
145
146 for (uIndex = 0; uIndex < DevsNum; uIndex++)
147 {
148 if (midiOutGetDevCapsW(uIndex, &midiOutCaps, sizeof(midiOutCaps)))
149 continue;
150
151 Res = SendMessageW(hCB, CB_ADDSTRING, 0, (LPARAM)midiOutCaps.szPname);
152
153 if (CB_ERR != Res)
154 {
155 SendMessageW(hCB, CB_SETITEMDATA, Res, (LPARAM)uIndex);
156 if (!_wcsicmp(midiOutCaps.szPname, DefaultDevice))
157 DefaultIndex = Res;
158 }
159 }
160 SendMessageW(hCB, CB_SETCURSEL, (WPARAM)DefaultIndex, 0);
161 }
162}
163
164VOID
166{
167 HWND hwndCombo = GetDlgItem(hwnd, ctrl);
168 INT CurSel = SendMessageW(hwndCombo, CB_GETCURSEL, 0, 0);
169 UINT TextLen;
170 WCHAR SelectedDevice[MAX_PATH] = {0};
171 HKEY hKey;
172
173 if (CurSel == CB_ERR)
174 return;
175
176 TextLen = SendMessageW(hwndCombo, CB_GETLBTEXTLEN, CurSel, 0) + 1;
177
178 if (TextLen > _countof(SelectedDevice))
179 return;
180
181 SendMessageW(hwndCombo, CB_GETLBTEXT, CurSel, (LPARAM)SelectedDevice);
182
184 return;
185
186 RegSetValueExW(hKey, value, 0, REG_SZ, (BYTE*)SelectedDevice, (wcslen(SelectedDevice) + 1) * sizeof(WCHAR));
188}
189
190VOID
192{
193 if (pGlobalData->bAudioOutChanged)
194 {
197 L"Software\\Microsoft\\Multimedia\\Sound Mapper",
198 L"Playback");
199 }
200
201 if (pGlobalData->bAudioInChanged)
202 {
205 L"Software\\Microsoft\\Multimedia\\Sound Mapper",
206 L"Record");
207 }
208
209 if (pGlobalData->bMIDIOutChanged)
210 {
213 L"Software\\Microsoft\\Windows\\CurrentVersion\\Multimedia\\MIDIMap",
214 L"szPname");
215 }
216}
217
218static UINT
220{
221 int iCurSel;
222 UINT DevNum;
223
224 iCurSel = SendMessageW(hControl, CB_GETCURSEL, 0, 0);
225
226 if (iCurSel == CB_ERR)
227 return 0;
228
229 DevNum = (UINT)SendMessageW(hControl, CB_GETITEMDATA, iCurSel, 0);
230 if (DevNum == (UINT) CB_ERR)
231 return 0;
232
233 if (mixerGetID((HMIXEROBJ)IntToPtr(DevNum), &DevNum, Id) != MMSYSERR_NOERROR)
234 return 0;
235
236 return DevNum;
237}
238
239/* Audio property page dialog callback */
242 UINT uMsg,
245{
246 PGLOBAL_DATA pGlobalData;
247
248 pGlobalData = (PGLOBAL_DATA)GetWindowLongPtrW(hwndDlg, DWLP_USER);
249
250 switch (uMsg)
251 {
252 case WM_INITDIALOG:
253 {
254 UINT NumWavOut = waveOutGetNumDevs();
255
256 pGlobalData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLOBAL_DATA));
257 SetWindowLongPtrW(hwndDlg, DWLP_USER, (LONG_PTR)pGlobalData);
258
259 if (!pGlobalData)
260 break;
261
262 InitAudioDlg(hwndDlg, pGlobalData);
263
264 if (!NumWavOut)
265 {
276 }
277
278 if (pGlobalData->bNoAudioOut)
279 {
283 }
284
285 if (pGlobalData->bNoAudioIn)
286 {
290 }
291
292 if (pGlobalData->bNoMIDIOut)
293 {
297 }
298 }
299 break;
300
301 case WM_COMMAND:
302 {
303 STARTUPINFOW si;
306
307 if (!pGlobalData)
308 break;
309
310 switch (LOWORD(wParam))
311 {
312 case IDC_VOLUME1_BTN:
313 {
314 StringCchPrintfW(szPath, _countof(szPath), L"sndvol32.exe -d %d",
316
317 ZeroMemory(&si, sizeof(si));
318 si.cb = sizeof(si);
320 si.wShowWindow = SW_SHOW;
321
322 if (CreateProcessW(NULL, szPath, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
323 {
324 CloseHandle(pi.hProcess);
325 CloseHandle(pi.hThread);
326 }
327 }
328 break;
329
330 case IDC_ADV2_BTN:
331 {
332
333 }
334 break;
335
336 case IDC_VOLUME2_BTN:
337 {
338 StringCchPrintfW(szPath, _countof(szPath), L"sndvol32.exe -r -d %d",
340
341 ZeroMemory(&si, sizeof(si));
342 si.cb = sizeof(si);
344 si.wShowWindow = SW_SHOW;
345
346 if (CreateProcessW(NULL, szPath, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
347 {
348 CloseHandle(pi.hProcess);
349 CloseHandle(pi.hThread);
350 }
351 }
352 break;
353
354 case IDC_ADV1_BTN:
355 {
356
357 }
358 break;
359
360 case IDC_VOLUME3_BTN:
361 {
362 StringCchPrintfW(szPath, _countof(szPath), L"sndvol32.exe -d %d",
364
365 ZeroMemory(&si, sizeof(si));
366 si.cb = sizeof(si);
368 si.wShowWindow = SW_SHOW;
369
370 if (CreateProcessW(NULL, szPath, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
371 {
372 CloseHandle(pi.hProcess);
373 CloseHandle(pi.hThread);
374 }
375 }
376 break;
377
378 case IDC_ADV3_BTN:
379 {
380
381 }
382 break;
383
385 {
387 {
388 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
389 pGlobalData->bAudioOutChanged = TRUE;
390 }
391 }
392 break;
393
395 {
397 {
398 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
399 pGlobalData->bAudioInChanged = TRUE;
400 }
401 }
402
404 {
406 {
407 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
408 pGlobalData->bMIDIOutChanged = TRUE;
409 }
410 }
411 break;
412 }
413 }
414 break;
415
416 case WM_DESTROY:
417 if (!pGlobalData)
418 break;
419
420 HeapFree(GetProcessHeap(), 0, pGlobalData);
421 break;
422
423 case WM_NOTIFY:
424 if (!pGlobalData)
425 break;
426
427 if (((LPNMHDR)lParam)->code == (UINT)PSN_APPLY)
428 {
429 SaveAudioDlg(hwndDlg, pGlobalData);
430 }
431 return TRUE;
432 }
433
434 return FALSE;
435}
DWORD Id
#define IntToPtr(i)
Definition: basetsd.h:89
#define RegCloseKey(hKey)
Definition: registry.h:49
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HINSTANCE hApplet
Definition: access.c:17
struct _GLOBAL_DATA GLOBAL_DATA
VOID UpdateRegistryString(HWND hwnd, INT ctrl, LPCWSTR key, LPCWSTR value)
Definition: audio.c:165
VOID InitAudioDlg(HWND hwnd, PGLOBAL_DATA pGlobalData)
Definition: audio.c:26
static UINT GetDevNum(HWND hControl, DWORD Id)
Definition: audio.c:219
struct _GLOBAL_DATA * PGLOBAL_DATA
INT_PTR CALLBACK AudioDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: audio.c:241
VOID SaveAudioDlg(HWND hwnd, PGLOBAL_DATA pGlobalData)
Definition: audio.c:191
#define IDC_VOLUME1_BTN
Definition: resource.h:55
#define IDC_DEFAULT_DEV_CHECKBOX
Definition: resource.h:41
#define IDC_DEVICE_MIDI_LIST
Definition: resource.h:44
#define IDC_DEVICE_REC_LIST
Definition: resource.h:43
#define IDC_VOLUME3_BTN
Definition: resource.h:59
#define IDC_ADV2_BTN
Definition: resource.h:56
#define IDC_VOLUME2_BTN
Definition: resource.h:57
#define IDC_ADV3_BTN
Definition: resource.h:60
#define IDC_DEVICE_PLAY_LIST
Definition: resource.h:42
#define IDS_NO_DEVICES
Definition: resource.h:91
#define IDC_ADV1_BTN
Definition: resource.h:58
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4598
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define REG_SZ
Definition: layer.c:22
#define MIXER_OBJECTF_MIDIOUT
Definition: mmsystem.h:306
#define MIXER_OBJECTF_WAVEOUT
Definition: mmsystem.h:302
#define MIXER_OBJECTF_WAVEIN
Definition: mmsystem.h:304
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
LPCWSTR szPath
Definition: env.c:37
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static refpint_t pi[]
Definition: server.c:96
#define ctrl
Definition: input.c:1756
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
#define KEY_READ
Definition: nt_native.h:1023
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WRITE
Definition: nt_native.h:1031
#define UNICODE_NULL
#define L(x)
Definition: ntvdm.h:50
#define LOWORD(l)
Definition: pedump.c:82
#define PropSheet_Changed(d, w)
Definition: prsht.h:344
#define PSN_APPLY
Definition: prsht.h:117
#define WM_NOTIFY
Definition: richedit.h:61
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define _countof(array)
Definition: sndvol32.h:70
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
BOOL bMIDIOutChanged
Definition: audio.c:21
BOOL bAudioOutChanged
Definition: audio.c:19
BOOL bNoAudioIn
Definition: audio.c:16
BOOL bAudioInChanged
Definition: audio.c:20
BOOL bNoAudioOut
Definition: audio.c:15
BOOL bNoMIDIOut
Definition: audio.c:17
DWORD cb
Definition: winbase.h:876
DWORD dwFlags
Definition: winbase.h:887
WORD wShowWindow
Definition: winbase.h:888
Definition: inflate.c:139
Definition: copy.c:22
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1126
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1060
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1039
int32_t INT_PTR
Definition: typedefs.h:64
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t INT
Definition: typedefs.h:58
#define HIWORD(l)
Definition: typedefs.h:247
Definition: pdh_main.c:94
#define ZeroMemory
Definition: winbase.h:1736
#define STARTF_USESHOWWINDOW
Definition: winbase.h:516
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
UINT WINAPI midiOutGetNumDevs(void)
Definition: winmm.c:806
UINT WINAPI waveOutGetNumDevs(void)
Definition: winmm.c:2137
UINT WINAPI waveOutGetDevCapsW(UINT_PTR uDeviceID, LPWAVEOUTCAPSW lpCaps, UINT uSize)
Definition: winmm.c:2173
UINT WINAPI mixerGetID(HMIXEROBJ hmix, LPUINT lpid, DWORD fdwID)
Definition: winmm.c:404
UINT WINAPI waveInGetNumDevs(void)
Definition: winmm.c:2565
UINT WINAPI midiOutGetDevCapsW(UINT_PTR uDeviceID, LPMIDIOUTCAPSW lpCaps, UINT uSize)
Definition: winmm.c:814
UINT WINAPI waveInGetDevCapsW(UINT_PTR uDeviceID, LPWAVEINCAPSW lpCaps, UINT uSize)
Definition: winmm.c:2573
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define CB_SETITEMDATA
Definition: winuser.h:1969
#define CB_GETLBTEXTLEN
Definition: winuser.h:1956
#define DWLP_USER
Definition: winuser.h:875
#define GetWindowLongPtrW
Definition: winuser.h:4832
#define CB_GETLBTEXT
Definition: winuser.h:1955
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define WM_COMMAND
Definition: winuser.h:1743
#define CB_ERR
Definition: winuser.h:2438
#define CB_SETCURSEL
Definition: winuser.h:1964
#define WM_INITDIALOG
Definition: winuser.h:1742
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
#define CBN_SELCHANGE
Definition: winuser.h:1982
#define CB_ADDSTRING
Definition: winuser.h:1939
#define CB_GETITEMDATA
Definition: winuser.h:1953
BOOL WINAPI EnableWindow(_In_ HWND, _In_ BOOL)
HWND WINAPI GetParent(_In_ HWND)
#define SW_SHOW
Definition: winuser.h:778
#define WM_DESTROY
Definition: winuser.h:1612
#define CB_GETCURSEL
Definition: winuser.h:1946
#define SetWindowLongPtrW
Definition: winuser.h:5358
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193