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

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

mixer updates

File size: 12.4 KB
Line 
1/* $Id: mixeros2.cpp,v 1.2 2002-05-23 13:50:15 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)) == TRUE) {
177 return TRUE;
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
188 dprintf(("OSLibMixGetVolume: mixerapiIOCTL90 %d failed!!", dwFunc));
189 return FALSE;
190}
191/******************************************************************************/
192/******************************************************************************/
193BOOL OSLibMixIsRecSourcePresent(DWORD dwRecSrc)
194{
195 DWORD dwOldRecSrc, dwVolL, dwVolR;
196
197 if(OSLibMixGetRecSource(&dwOldRecSrc, &dwVolL, &dwVolR) == FALSE) {
198 return FALSE;
199 }
200 if(OSLibMixSetRecSource(dwRecSrc, dwVolL, dwVolR) == FALSE) {
201 return FALSE;
202 }
203 OSLibMixSetRecSource(dwOldRecSrc, dwVolL, dwVolR);
204 return TRUE;
205}
206/******************************************************************************/
207/******************************************************************************/
208BOOL OSLibMixSetRecSource(DWORD dwRecSrc, DWORD dwVolL, DWORD dwVolR)
209{
210 DWORD idx;
211 MIXSTRUCT mixstruct;
212
213 switch(dwRecSrc) {
214 case MIX_CTRL_VOL_IN_W_MIC:
215 idx = I90SRC_MIC;
216 break;
217 case MIX_CTRL_VOL_IN_W_CD:
218 idx = I90SRC_CD;
219 break;
220 case MIX_CTRL_VOL_IN_W_VIDEO:
221 idx = I90SRC_VIDEO;
222 break;
223 case MIX_CTRL_VOL_IN_W_AUX:
224 idx = I90SRC_AUX;
225 break;
226 case MIX_CTRL_VOL_IN_W_LINE:
227 idx = I90SRC_LINE;
228 break;
229 case MIX_CTRL_VOL_IN_W_PHONE:
230 idx = I90SRC_PHONE;
231 break;
232 default:
233 return FALSE;
234 }
235 mixstruct.Mute = 0;
236 mixstruct.VolumeL = idx;
237
238 if(mixerapiIOCTL90(hPDDMix, RECORDSRCSET, &mixstruct, sizeof(mixstruct)) == FALSE) {
239 dprintf(("OSLibMixSetRecSource: mixerapiIOCTL90 RECORDSRCSET failed!!"));
240 return FALSE;
241 }
242
243 mixstruct.Mute = 0;
244 mixstruct.VolumeL = dwVolL;
245 mixstruct.VolumeR = dwVolR;
246 if(mixerapiIOCTL90(hPDDMix, RECORDGAINSET, &mixstruct, sizeof(mixstruct)) == FALSE) {
247 dprintf(("OSLibMixSetRecSource: mixerapiIOCTL90 RECORDGAINSET failed!!"));
248 return FALSE;
249 }
250 return TRUE;
251}
252/******************************************************************************/
253/******************************************************************************/
254BOOL OSLibMixGetRecSource(DWORD *pdwRecSrc, DWORD *pdwVolL, DWORD *pdwVolR)
255{
256 DWORD idx;
257 MIXSTRUCT mixstruct;
258
259 if(mixerapiIOCTL90(hPDDMix, RECORDSRCQUERY, &mixstruct, sizeof(mixstruct)) == FALSE) {
260 dprintf(("OSLibMixSetRecSource: mixerapiIOCTL90 RECORDSRCGET failed!!"));
261 return FALSE;
262 }
263 switch(mixstruct.VolumeL) {
264 case I90SRC_MIC:
265 idx = MIX_CTRL_VOL_IN_W_MIC;
266 break;
267 case I90SRC_CD:
268 idx = MIX_CTRL_VOL_IN_W_CD;
269 break;
270 case I90SRC_VIDEO:
271 idx = MIX_CTRL_VOL_IN_W_VIDEO;
272 break;
273 case I90SRC_AUX:
274 idx = MIX_CTRL_VOL_IN_W_AUX;
275 break;
276 case I90SRC_LINE:
277 idx = MIX_CTRL_VOL_IN_W_LINE;
278 break;
279 case I90SRC_PHONE:
280 idx = MIX_CTRL_VOL_IN_W_PHONE;
281 break;
282 default:
283 DebugInt3();
284 return FALSE;
285 }
286 if(pdwRecSrc) {
287 *pdwRecSrc = idx;
288 }
289 if(mixerapiIOCTL90(hPDDMix, RECORDGAINQUERY, &mixstruct, sizeof(mixstruct)) == FALSE) {
290 dprintf(("OSLibMixSetRecSource: mixerapiIOCTL90 RECORDGAINQUERY failed!!"));
291 return FALSE;
292 }
293 if(pdwVolL) {
294 *pdwVolL = mixstruct.VolumeL;
295 }
296 if(pdwVolR) {
297 *pdwVolR = mixstruct.VolumeR;
298 }
299 return TRUE;
300}
301/******************************************************************************/
302// OS/2 32-bit program to query the Physical Device Driver name
303// for the default MMPM/2 WaveAudio device. Joe Nord 10-Mar-1999
304/******************************************************************************/
305static HFILE DevOpen (char *ddName)
306{
307 ULONG ulRC;
308 ULONG OpenFlags;
309 ULONG OpenMode;
310 ULONG ulFileSize = 0;
311 ULONG ulFileAttribute = 0;
312 ULONG ulActionTaken = 0;
313 HFILE hPdd = NULL;
314
315 OpenFlags = OPEN_ACTION_OPEN_IF_EXISTS; // Do not create file
316
317 OpenMode = OPEN_ACCESS_READWRITE + // Read/Write file
318 OPEN_SHARE_DENYNONE + // Non-exclusive access
319 OPEN_FLAGS_FAIL_ON_ERROR; // No system popups on errors
320
321 ulRC = DosOpen (ddName, // in
322 &hPdd, // out (handle)
323 &ulActionTaken, // out
324 ulFileSize, // in
325 ulFileAttribute, // in
326 OpenFlags, // in
327 OpenMode, // in
328 NULL); // in
329
330 if (ulRC != 0)
331 hPdd = NULL;
332
333 return (hPdd);
334}
335/******************************************************************************/
336/******************************************************************************/
337static BOOL mixerapiIOCTL90 (HFILE hPdd, ULONG ulFunc, PVOID pData, ULONG cbDataSize)
338{
339 ULONG ulRC;
340
341 ulRC = DosDevIOCtl
342 (hPdd, // Device Handle
343 0x90, // Category (user defined >= 0x80)
344 ulFunc, // Function Use defines in .H file
345 NULL, // in Address of parm data (not used)
346 0, // in Max size of parm data structure
347 NULL, // in out Actual size of parm data structure
348 pData, // in Address of command data
349 cbDataSize, // in Maximum size of command data
350 &cbDataSize); // in out Size of command data
351
352 return ulRC == NO_ERROR;
353}
354/******************************************************************************/
355// OS/2 32-bit program to query the Physical Device Driver name
356// for the default MMPM/2 WaveAudio device. Joe Nord 10-Mar-1999
357/******************************************************************************/
358static BOOL GetAudioPDDName (char *pszPDDName)
359{
360 ULONG ulRC;
361 char szAmpMix[9] = "AMPMIX01";
362
363 MCI_SYSINFO_PARMS SysInfo;
364 MCI_SYSINFO_LOGDEVICE SysInfoParm;
365 MCI_SYSINFO_QUERY_NAME QueryNameParm;
366
367 memset (&SysInfo, '\0', sizeof(SysInfo));
368 memset (&SysInfoParm, '\0', sizeof(SysInfoParm));
369 memset (&QueryNameParm, '\0', sizeof(QueryNameParm));
370
371 SysInfo.ulItem = MCI_SYSINFO_QUERY_NAMES;
372 SysInfo.usDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;
373 SysInfo.pSysInfoParm = &QueryNameParm;
374
375 strcpy (QueryNameParm.szLogicalName, szAmpMix);
376
377 ulRC = mymciSendCommand (0,
378 MCI_SYSINFO,
379 MCI_SYSINFO_ITEM | MCI_WAIT,
380 (PVOID) &SysInfo,
381 0);
382 if (ulRC != 0) return FALSE;
383
384 // Get PDD associated with our AmpMixer
385 // Device name is in pSysInfoParm->szPDDName
386
387 SysInfo.ulItem = MCI_SYSINFO_QUERY_DRIVER;
388 SysInfo.usDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;
389 SysInfo.pSysInfoParm = &SysInfoParm;
390
391 strcpy (SysInfoParm.szInstallName, QueryNameParm.szInstallName);
392
393 ulRC = mymciSendCommand (0,
394 MCI_SYSINFO,
395 MCI_SYSINFO_ITEM | MCI_WAIT,
396 (PVOID) &SysInfo,
397 0);
398 if (ulRC != 0) return FALSE;
399
400 strcpy (pszPDDName, SysInfoParm.szPDDName);
401
402 return TRUE;
403}
404/******************************************************************************/
405/******************************************************************************/
406
Note: See TracBrowser for help on using the repository browser.