source: trunk/src/winmm/mixeros2.cpp@ 8485

Last change on this file since 8485 was 8485, checked in by sandervl, 23 years ago

more mixer updates

File size: 12.4 KB
Line 
1/* $Id: mixeros2.cpp,v 1.3 2002-05-24 18:02:48 sandervl Exp $ */
2
3/*
4 * OS/2 Mixer multimedia
5 *
6 * Copyright 2002 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12
13#define INCL_BASE
14#define INCL_DOSERRORS
15#define INCL_DOSDEVIOCTL
16#define INCL_DOSFILEMGR
17#define INCL_OS2MM
18#include <os2wrap.h>
19#include <os2mewrap.h>
20#include <stdlib.h>
21#include <string.h>
22#include <dbglog.h>
23#include <ioctl90.h>
24
25#include "initwinmm.h"
26#include "mixeros2.h"
27
28static BOOL GetAudioPDDName (char *pszPDDName);
29static HFILE DevOpen (char *ddName);
30static BOOL mixerapiIOCTL90 (HFILE hPdd, ULONG ulFunc, PVOID pData, ULONG cbDataSize);
31
32static HFILE hPDDMix = 0;
33static char mixerApiMap[256] = {0};
34
35/******************************************************************************/
36/******************************************************************************/
37BOOL OSLibMixerOpen()
38{
39 char szPDDName[128] = "\\DEV\\";
40
41 if(GetAudioPDDName(&szPDDName[5]) == FALSE) {
42 return FALSE;
43 }
44
45 dprintf(("OSLibMixerOpen: PDD name %s", szPDDName));
46
47 hPDDMix = DevOpen(szPDDName);
48 if(hPDDMix == 0) {
49 dprintf(("Unable to open PDD %s", szPDDName));
50 return FALSE;
51 }
52 if(mixerapiIOCTL90(hPDDMix, GETAPIMAP, mixerApiMap, sizeof(mixerApiMap)) == FALSE) {
53 dprintf(("GETAPIMAP failed!!"));
54 DosClose(hPDDMix);
55 return FALSE;
56 }
57
58 return TRUE;
59}
60/******************************************************************************/
61/******************************************************************************/
62void OSLibMixerClose()
63{
64 if(hPDDMix) {
65 DosClose(hPDDMix);
66 }
67}
68/******************************************************************************/
69/******************************************************************************/
70static DWORD OSLibMixGetIndex(DWORD dwControl)
71{
72 DWORD idx;
73
74 switch(dwControl) {
75 case MIX_CTRL_VOL_IN_L_MONO:
76 case MIX_CTRL_MUTE_IN_L_MONO:
77 idx = MONOINSET;
78 break;
79 case MIX_CTRL_VOL_IN_L_PHONE:
80 case MIX_CTRL_MUTE_IN_L_PHONE:
81 idx = PHONESET;
82 break;
83 case MIX_CTRL_VOL_IN_L_MIC:
84 case MIX_CTRL_MUTE_IN_L_MIC:
85 idx = MICSET;
86 break;
87 case MIX_CTRL_VOL_IN_L_LINE:
88 case MIX_CTRL_MUTE_IN_L_LINE:
89 idx = LINESET;
90 break;
91 case MIX_CTRL_VOL_IN_L_CD:
92 case MIX_CTRL_MUTE_IN_L_CD:
93 idx = CDSET;
94 break;
95 case MIX_CTRL_VOL_IN_L_VIDEO:
96 case MIX_CTRL_MUTE_IN_L_VIDEO:
97 idx = VIDEOSET;
98 break;
99 case MIX_CTRL_VOL_IN_L_AUX:
100 case MIX_CTRL_MUTE_IN_L_AUX:
101 idx = AUXSET;
102 break;
103 case MIX_CTRL_OUT_L_BASS:
104 case MIX_CTRL_OUT_L_TREBLE:
105 idx = BASSTREBLESET;
106 break;
107 case MIX_CTRL_OUT_L_3DCENTER:
108 case MIX_CTRL_OUT_L_3DDEPTH:
109 idx = THREEDSET;
110 break;
111 case MIX_CTRL_VOL_IN_L_PCM:
112 case MIX_CTRL_MUTE_IN_L_PCM:
113 idx = STREAMVOLSET;
114 break;
115 case MIX_CTRL_MUX_IN_W_SRC:
116 idx = RECORDSRCSET;
117 break;
118 default:
119 return -1;
120 }
121 return idx & 0xF;
122}
123/******************************************************************************/
124/******************************************************************************/
125BOOL OSLibMixIsControlPresent(DWORD dwControl)
126{
127 DWORD idx;
128
129 idx = OSLibMixGetIndex(dwControl);
130 if(idx == -1) {
131 return FALSE;
132 }
133 idx += MONOINSET;
134 return mixerApiMap[idx] != 0;
135}
136/******************************************************************************/
137/******************************************************************************/
138BOOL OSLibMixSetVolume(DWORD dwControl, BOOL fMute, DWORD dwVolLeft, DWORD dwVolRight)
139{
140 DWORD dwFunc;
141 MIXSTRUCT mixstruct;
142
143 dwFunc = OSLibMixGetIndex(dwControl);
144 if(dwFunc == -1) {
145 return FALSE;
146 }
147 dwFunc += MONOINSET;
148
149 if(dwVolLeft > MIXER_MAX_VOLUME || dwVolRight > MIXER_MAX_VOLUME) {
150 dprintf(("OSLibMixSetVolume: Volume (%d,%d) out of RANGE!!", dwVolLeft, dwVolRight));
151 return FALSE;
152 }
153 mixstruct.Mute = fMute;
154 mixstruct.VolumeL = dwVolLeft;
155 mixstruct.VolumeR = dwVolRight;
156
157 if(mixerapiIOCTL90(hPDDMix, dwFunc, &mixstruct, sizeof(mixstruct)) == TRUE) {
158 return TRUE;
159 }
160 dprintf(("OSLibMixSetVolume: mixerapiIOCTL90 %d failed!!", dwFunc));
161 return FALSE;
162}
163/******************************************************************************/
164/******************************************************************************/
165BOOL OSLibMixGetVolume(DWORD dwControl, BOOL *pfMute, DWORD *pdwVolLeft, DWORD *pdwVolRight)
166{
167 DWORD dwFunc;
168 MIXSTRUCT mixstruct;
169
170 dwFunc = OSLibMixGetIndex(dwControl);
171 if(dwFunc == -1) {
172 return FALSE;
173 }
174 dwFunc += MONOINQUERY;
175
176 if(mixerapiIOCTL90(hPDDMix, dwFunc, &mixstruct, sizeof(mixstruct)) == FALSE) {
177 return FALSE;
178 }
179 if(pfMute) *pfMute = mixstruct.Mute;
180 if(pdwVolLeft) *pdwVolLeft = mixstruct.VolumeL;
181 if(pdwVolRight) *pdwVolRight = mixstruct.VolumeR;
182
183 if(mixstruct.VolumeL > MIXER_MAX_VOLUME || mixstruct.VolumeR > MIXER_MAX_VOLUME) {
184 dprintf(("OSLibMixGetVolume: Volume (%d,%d) out of RANGE!!", mixstruct.VolumeL, mixstruct.VolumeR));
185 return FALSE;
186 }
187 return TRUE;
188}
189/******************************************************************************/
190/******************************************************************************/
191BOOL OSLibMixIsRecSourcePresent(DWORD dwRecSrc)
192{
193 DWORD dwOldRecSrc, dwVolL, dwVolR;
194
195 if(OSLibMixGetRecSource(&dwOldRecSrc, &dwVolL, &dwVolR) == FALSE) {
196 return FALSE;
197 }
198 if(OSLibMixSetRecSource(dwRecSrc, dwVolL, dwVolR) == FALSE) {
199 return FALSE;
200 }
201 OSLibMixSetRecSource(dwOldRecSrc, dwVolL, dwVolR);
202 return TRUE;
203}
204/******************************************************************************/
205/******************************************************************************/
206BOOL OSLibMixSetRecSource(DWORD dwRecSrc, DWORD dwVolL, DWORD dwVolR)
207{
208 DWORD idx;
209 MIXSTRUCT mixstruct;
210
211 switch(dwRecSrc) {
212 case MIX_CTRL_VOL_IN_W_MIC:
213 idx = I90SRC_MIC;
214 break;
215 case MIX_CTRL_VOL_IN_W_CD:
216 idx = I90SRC_CD;
217 break;
218 case MIX_CTRL_VOL_IN_W_VIDEO:
219 idx = I90SRC_VIDEO;
220 break;
221 case MIX_CTRL_VOL_IN_W_AUX:
222 idx = I90SRC_AUX;
223 break;
224 case MIX_CTRL_VOL_IN_W_LINE:
225 idx = I90SRC_LINE;
226 break;
227 case MIX_CTRL_VOL_IN_W_PHONE:
228 idx = I90SRC_PHONE;
229 break;
230 default:
231 return FALSE;
232 }
233 mixstruct.Mute = 0;
234 mixstruct.VolumeL = idx;
235
236 if(mixerapiIOCTL90(hPDDMix, RECORDSRCSET, &mixstruct, sizeof(mixstruct)) == FALSE) {
237 dprintf(("OSLibMixSetRecSource: mixerapiIOCTL90 RECORDSRCSET failed!!"));
238 return FALSE;
239 }
240
241 mixstruct.Mute = 0;
242 mixstruct.VolumeL = dwVolL;
243 mixstruct.VolumeR = dwVolR;
244 if(mixerapiIOCTL90(hPDDMix, RECORDGAINSET, &mixstruct, sizeof(mixstruct)) == FALSE) {
245 dprintf(("OSLibMixSetRecSource: mixerapiIOCTL90 RECORDGAINSET failed!!"));
246 return FALSE;
247 }
248 return TRUE;
249}
250/******************************************************************************/
251/******************************************************************************/
252BOOL OSLibMixGetRecSource(DWORD *pdwRecSrc, DWORD *pdwVolL, DWORD *pdwVolR)
253{
254 DWORD idx;
255 MIXSTRUCT mixstruct;
256
257 if(mixerapiIOCTL90(hPDDMix, RECORDSRCQUERY, &mixstruct, sizeof(mixstruct)) == FALSE) {
258 dprintf(("OSLibMixSetRecSource: mixerapiIOCTL90 RECORDSRCGET failed!!"));
259 return FALSE;
260 }
261 switch(mixstruct.VolumeL) {
262 case I90SRC_MIC:
263 idx = MIX_CTRL_VOL_IN_W_MIC;
264 break;
265 case I90SRC_CD:
266 idx = MIX_CTRL_VOL_IN_W_CD;
267 break;
268 case I90SRC_VIDEO:
269 idx = MIX_CTRL_VOL_IN_W_VIDEO;
270 break;
271 case I90SRC_AUX:
272 idx = MIX_CTRL_VOL_IN_W_AUX;
273 break;
274 case I90SRC_LINE:
275 idx = MIX_CTRL_VOL_IN_W_LINE;
276 break;
277 case I90SRC_PHONE:
278 idx = MIX_CTRL_VOL_IN_W_PHONE;
279 break;
280 default:
281 DebugInt3();
282 return FALSE;
283 }
284 if(pdwRecSrc) {
285 *pdwRecSrc = idx;
286 }
287 if(mixerapiIOCTL90(hPDDMix, RECORDGAINQUERY, &mixstruct, sizeof(mixstruct)) == FALSE) {
288 dprintf(("OSLibMixSetRecSource: mixerapiIOCTL90 RECORDGAINQUERY failed!!"));
289 return FALSE;
290 }
291 if(pdwVolL) {
292 *pdwVolL = mixstruct.VolumeL;
293 }
294 if(pdwVolR) {
295 *pdwVolR = mixstruct.VolumeR;
296 }
297 return TRUE;
298}
299/******************************************************************************/
300// OS/2 32-bit program to query the Physical Device Driver name
301// for the default MMPM/2 WaveAudio device. Joe Nord 10-Mar-1999
302/******************************************************************************/
303static HFILE DevOpen (char *ddName)
304{
305 ULONG ulRC;
306 ULONG OpenFlags;
307 ULONG OpenMode;
308 ULONG ulFileSize = 0;
309 ULONG ulFileAttribute = 0;
310 ULONG ulActionTaken = 0;
311 HFILE hPdd = NULL;
312
313 OpenFlags = OPEN_ACTION_OPEN_IF_EXISTS; // Do not create file
314
315 OpenMode = OPEN_ACCESS_READWRITE + // Read/Write file
316 OPEN_SHARE_DENYNONE + // Non-exclusive access
317 OPEN_FLAGS_FAIL_ON_ERROR; // No system popups on errors
318
319 ulRC = DosOpen (ddName, // in
320 &hPdd, // out (handle)
321 &ulActionTaken, // out
322 ulFileSize, // in
323 ulFileAttribute, // in
324 OpenFlags, // in
325 OpenMode, // in
326 NULL); // in
327
328 if (ulRC != 0)
329 hPdd = NULL;
330
331 return (hPdd);
332}
333/******************************************************************************/
334/******************************************************************************/
335static BOOL mixerapiIOCTL90 (HFILE hPdd, ULONG ulFunc, PVOID pData, ULONG cbDataSize)
336{
337 ULONG ulRC;
338
339 ulRC = DosDevIOCtl
340 (hPdd, // Device Handle
341 0x90, // Category (user defined >= 0x80)
342 ulFunc, // Function Use defines in .H file
343 NULL, // in Address of parm data (not used)
344 0, // in Max size of parm data structure
345 NULL, // in out Actual size of parm data structure
346 pData, // in Address of command data
347 cbDataSize, // in Maximum size of command data
348 &cbDataSize); // in out Size of command data
349
350 return ulRC == NO_ERROR;
351}
352/******************************************************************************/
353// OS/2 32-bit program to query the Physical Device Driver name
354// for the default MMPM/2 WaveAudio device. Joe Nord 10-Mar-1999
355/******************************************************************************/
356static BOOL GetAudioPDDName (char *pszPDDName)
357{
358 ULONG ulRC;
359 char szAmpMix[9] = "AMPMIX01";
360
361 MCI_SYSINFO_PARMS SysInfo;
362 MCI_SYSINFO_LOGDEVICE SysInfoParm;
363 MCI_SYSINFO_QUERY_NAME QueryNameParm;
364
365 memset (&SysInfo, '\0', sizeof(SysInfo));
366 memset (&SysInfoParm, '\0', sizeof(SysInfoParm));
367 memset (&QueryNameParm, '\0', sizeof(QueryNameParm));
368
369 SysInfo.ulItem = MCI_SYSINFO_QUERY_NAMES;
370 SysInfo.usDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;
371 SysInfo.pSysInfoParm = &QueryNameParm;
372
373 strcpy (QueryNameParm.szLogicalName, szAmpMix);
374
375 ulRC = mymciSendCommand (0,
376 MCI_SYSINFO,
377 MCI_SYSINFO_ITEM | MCI_WAIT,
378 (PVOID) &SysInfo,
379 0);
380 if (ulRC != 0) return FALSE;
381
382 // Get PDD associated with our AmpMixer
383 // Device name is in pSysInfoParm->szPDDName
384
385 SysInfo.ulItem = MCI_SYSINFO_QUERY_DRIVER;
386 SysInfo.usDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;
387 SysInfo.pSysInfoParm = &SysInfoParm;
388
389 strcpy (SysInfoParm.szInstallName, QueryNameParm.szInstallName);
390
391 ulRC = mymciSendCommand (0,
392 MCI_SYSINFO,
393 MCI_SYSINFO_ITEM | MCI_WAIT,
394 (PVOID) &SysInfo,
395 0);
396 if (ulRC != 0) return FALSE;
397
398 strcpy (pszPDDName, SysInfoParm.szPDDName);
399
400 return TRUE;
401}
402/******************************************************************************/
403/******************************************************************************/
404
Note: See TracBrowser for help on using the repository browser.