source: trunk/src/winmm/mixer.cpp@ 6496

Last change on this file since 6496 was 5926, checked in by sandervl, 24 years ago

compile fix for vac 3.6.5

File size: 18.4 KB
Line 
1/* $Id: mixer.cpp,v 1.10 2001-06-07 12:47:39 sandervl Exp $ */
2
3/*
4 * Mixer stubs
5 *
6 * Copyright 1998 Joel Troster
7 *
8 * TODO: This is just a hack to fool apps into thinking a mixer exists
9 * Must be redesigned
10 *
11 * Based on Wine code (dlls\winmm\wineoss\mixer.c)
12 * Copyright 1997 Marcus Meissner
13 * 1999 Eric Pouech
14 *
15 *
16 * Project Odin Software License can be found in LICENSE.TXT
17 *
18 */
19
20/****************************************************************************
21 * Includes *
22 ****************************************************************************/
23
24#define NONAMELESSUNION
25#define NONAMELESSSTRUCT
26
27#include <os2win.h>
28#include <string.h>
29#include <mmsystem.h>
30#include <odinwrap.h>
31#include <misc.h>
32
33#include "waveoutdart.h"
34#include "winmm.h"
35
36#define DBG_LOCALLOG DBG_mixer
37#include "dbglocal.h"
38
39
40ODINDEBUGCHANNEL(WINMM-MIXER)
41
42#define WINMM_MIXERSTRING_A "OS/2 WINMM Mixer"
43#define WINMM_MIXERSTRING_W (LPWSTR)L"OS/2 WINMM Mixer"
44
45#define WINMM_SHORTNAME_WAVEOUT_A "Wave Out"
46#define WINMM_SHORTNAME_WAVEOUT_W (LPWSTR)L"Wave Out"
47#define WINMM_SHORTNAME_LINEOUT_A "Line Out"
48#define WINMM_SHORTNAME_LINEOUT_W (LPWSTR)L"Line Out"
49
50#define SOUND_MIXER_LINEOUT 0
51#define SOUND_MIXER_WAVEOUT 1
52#define SOUND_MIXER_MAXID 2
53
54DWORD MIX_Volume[SOUND_MIXER_MAXID] = { 0x80008000, 0x80008000};
55DWORD MIX_Mute[SOUND_MIXER_MAXID] = { 0, 0};
56
57//
58// All Stubs
59//
60
61/**************************************************************************
62 * MIX_SplitControlID [internal]
63 */
64static BOOL MIX_SplitControlID(DWORD controlID, LPDWORD lineID, LPDWORD controlType)
65{
66 *lineID = controlID / 2;
67 *controlType = (controlID & 1) ?
68 MIXERCONTROL_CONTROLTYPE_MUTE : MIXERCONTROL_CONTROLTYPE_VOLUME;
69
70 return *lineID < SOUND_MIXER_MAXID;
71}
72/**************************************************************************
73 * MIX_MakeControlID [internal]
74 */
75static DWORD MIX_MakeControlID(DWORD lineID, DWORD controlType)
76{
77 switch (controlType) {
78 case MIXERCONTROL_CONTROLTYPE_VOLUME:
79 return 2 * lineID + 0;
80 case MIXERCONTROL_CONTROLTYPE_MUTE:
81 return 2 * lineID + 1;
82 }
83 dprintf(("MIX_MakeControlID: Internal error"));
84 return 0x00FADE00;
85}
86/**************************************************************************
87 * MIX_DoGetLineControls [internal]
88 */
89static void MIX_DoGetLineControls(LPMIXERCONTROLA mc, DWORD lineID, DWORD dwType)
90{
91 mc->cbStruct = sizeof(MIXERCONTROLA);
92
93 switch (dwType) {
94 case MIXERCONTROL_CONTROLTYPE_VOLUME:
95 mc->dwControlID = MIX_MakeControlID(lineID, dwType);
96 mc->dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
97 mc->fdwControl = 0;
98 mc->cMultipleItems = 0;
99 lstrcpynA(mc->szShortName, "Vol", MIXER_SHORT_NAME_CHARS);
100 lstrcpynA(mc->szName, "Volume", MIXER_LONG_NAME_CHARS);
101 memset(&mc->Bounds, 0, sizeof(mc->Bounds));
102 mc->Bounds.s1.dwMinimum = 0;
103 mc->Bounds.s1.dwMaximum = 65535;
104 memset(&mc->Metrics, 0, sizeof(mc->Metrics));
105 break;
106 case MIXERCONTROL_CONTROLTYPE_MUTE:
107 mc->dwControlID = MIX_MakeControlID(lineID, dwType);
108 mc->dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE;
109 mc->fdwControl = 0;
110 mc->cMultipleItems = 0;
111 lstrcpynA(mc->szShortName, "Mute", MIXER_SHORT_NAME_CHARS);
112 lstrcpynA(mc->szName, "Mute", MIXER_LONG_NAME_CHARS);
113 memset(&mc->Bounds, 0, sizeof(mc->Bounds));
114 memset(&mc->Metrics, 0, sizeof(mc->Metrics));
115 break;
116 default:
117 dprintf(("MIX_DoGetLineControls: Internal error: unknown type: %08lx\n", dwType));
118 }
119}
120/******************************************************************************/
121/******************************************************************************/
122ODINFUNCTION3(MMRESULT, mixerGetControlDetailsA,
123 HMIXEROBJ, hmxobj,
124 LPMIXERCONTROLDETAILS, lpmcd,
125 DWORD, fdwDetails)
126{
127 DWORD ret = MMSYSERR_NOTSUPPORTED;
128 DWORD lineID, controlType;
129
130 if (lpmcd == NULL) return MMSYSERR_INVALPARAM;
131
132 switch (fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK) {
133 case MIXER_GETCONTROLDETAILSF_VALUE:
134 if(MIX_SplitControlID(lpmcd->dwControlID, &lineID, &controlType)) {
135 switch (controlType)
136 {
137 case MIXERCONTROL_CONTROLTYPE_VOLUME:
138 {
139 LPMIXERCONTROLDETAILS_UNSIGNED mcdu;
140 int val;
141
142 /* return value is 00RL (4 bytes)... */
143 val = MIX_Volume[lineID];
144
145 switch (lpmcd->cChannels) {
146 case 1:
147 /* mono... so R = L */
148 mcdu = (LPMIXERCONTROLDETAILS_UNSIGNED)lpmcd->paDetails;
149 mcdu->dwValue = LOWORD(val);
150 break;
151 case 2:
152 /* stereo, left is paDetails[0] */
153 mcdu = (LPMIXERCONTROLDETAILS_UNSIGNED)((char*)lpmcd->paDetails + 0 * lpmcd->cbDetails);
154 mcdu->dwValue = LOWORD(val);
155 mcdu = (LPMIXERCONTROLDETAILS_UNSIGNED)((char*)lpmcd->paDetails + 1 * lpmcd->cbDetails);
156 mcdu->dwValue = HIWORD(val);
157 break;
158 default:
159 dprintf(("Unknown cChannels (%ld)\n", lpmcd->cChannels));
160 return MMSYSERR_INVALPARAM;
161 }
162 }
163 break;
164 case MIXERCONTROL_CONTROLTYPE_MUTE:
165 {
166 LPMIXERCONTROLDETAILS_BOOLEAN mcdb;
167
168 /* we mute both channels at the same time */
169 mcdb = (LPMIXERCONTROLDETAILS_BOOLEAN)lpmcd->paDetails;
170 mcdb->fValue = MIX_Mute[lineID];
171 }
172 break;
173 }
174 ret = MMSYSERR_NOERROR;
175 } else {
176 ret = MMSYSERR_INVALPARAM;
177 }
178 break;
179 case MIXER_GETCONTROLDETAILSF_LISTTEXT:
180 dprintf(("mixerGetControlDetailsA: NIY\n"));
181 break;
182 default:
183 dprintf(("Unknown flag (%08lx)\n", fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK));
184 }
185 return ret;
186}
187/******************************************************************************/
188/******************************************************************************/
189ODINFUNCTION3(MMRESULT, mixerGetControlDetailsW,
190 HMIXEROBJ, hmxobj,
191 LPMIXERCONTROLDETAILS, pmxcd,
192 DWORD, fdwDetails)
193{
194 dprintf(("WINMM:mixerGetControlDetailsW - stub\n" ));
195 return MIXERR_INVALCONTROL;
196}
197/******************************************************************************/
198/******************************************************************************/
199ODINFUNCTION3(MMRESULT, mixerSetControlDetails,
200 HMIXEROBJ, hmxobj,
201 LPMIXERCONTROLDETAILS, lpmcd,
202 DWORD, fdwDetails)
203{
204 DWORD ret = MMSYSERR_NOTSUPPORTED;
205 DWORD lineID, controlType;
206 int val;
207
208 if (lpmcd == NULL) return MMSYSERR_INVALPARAM;
209
210 switch (fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK) {
211 case MIXER_GETCONTROLDETAILSF_VALUE:
212 if (MIX_SplitControlID(lpmcd->dwControlID, &lineID, &controlType)) {
213 switch (controlType) {
214 case MIXERCONTROL_CONTROLTYPE_VOLUME:
215 {
216 LPMIXERCONTROLDETAILS_UNSIGNED mcdu;
217
218 /* val should contain 00RL */
219 switch (lpmcd->cChannels) {
220 case 1:
221 /* mono... so R = L */
222 mcdu = (LPMIXERCONTROLDETAILS_UNSIGNED)lpmcd->paDetails;
223 val = mcdu->dwValue;
224 break;
225 case 2:
226 /* stereo, left is paDetails[0] */
227 mcdu = (LPMIXERCONTROLDETAILS_UNSIGNED)((char*)lpmcd->paDetails + 0 * lpmcd->cbDetails);
228 val = mcdu->dwValue;
229 mcdu = (LPMIXERCONTROLDETAILS_UNSIGNED)((char*)lpmcd->paDetails + 1 * lpmcd->cbDetails);
230 val += (mcdu->dwValue) << 16;
231 break;
232 default:
233 dprintf(("Unknown cChannels (%ld)\n", lpmcd->cChannels));
234 return MMSYSERR_INVALPARAM;
235 }
236
237 MIX_Volume[lineID] = val;
238 }
239 ret = MMSYSERR_NOERROR;
240 break;
241 case MIXERCONTROL_CONTROLTYPE_MUTE:
242 {
243 LPMIXERCONTROLDETAILS_BOOLEAN mcdb;
244
245 mcdb = (LPMIXERCONTROLDETAILS_BOOLEAN)lpmcd->paDetails;
246 MIX_Mute[lineID] = mcdb->fValue;
247 }
248 ret = MMSYSERR_NOERROR;
249 break;
250 }
251 }
252 break;
253 case MIXER_GETCONTROLDETAILSF_LISTTEXT:
254 dprintf(("mixerSetControlDetails: NIY\n"));
255 break;
256 default:
257 dprintf(("Unknown flag (%08lx)\n", fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK));
258 }
259 return MMSYSERR_NOTSUPPORTED;
260}
261/******************************************************************************/
262/******************************************************************************/
263ODINFUNCTION3(MMRESULT, mixerGetLineControlsA,
264 HMIXEROBJ, hmxobj,
265 LPMIXERLINECONTROLSA, lpMlc,
266 DWORD, fdwControls)
267{
268 DWORD dwRet = MMSYSERR_NOERROR;
269 DWORD lineID, controlType;
270
271 if (lpMlc == NULL) return MMSYSERR_INVALPARAM;
272 if (lpMlc->cbStruct < sizeof(*lpMlc) ||
273 lpMlc->cbmxctrl < sizeof(MIXERCONTROLA))
274 return MMSYSERR_INVALPARAM;
275
276 switch(fdwControls & MIXER_GETLINECONTROLSF_QUERYMASK)
277 {
278 case MIXER_GETLINECONTROLSF_ALL:
279 if (lpMlc->cControls != 2) {
280 dwRet = MMSYSERR_INVALPARAM;
281 }
282 else {
283 MIX_DoGetLineControls(&lpMlc->pamxctrl[0], lpMlc->dwLineID, MIXERCONTROL_CONTROLTYPE_VOLUME);
284 MIX_DoGetLineControls(&lpMlc->pamxctrl[1], lpMlc->dwLineID, MIXERCONTROL_CONTROLTYPE_MUTE);
285 }
286 break;
287 case MIXER_GETLINECONTROLSF_ONEBYID:
288 if (MIX_SplitControlID(lpMlc->u.dwControlID, &lineID, &controlType))
289 MIX_DoGetLineControls(&lpMlc->pamxctrl[0], lineID, controlType);
290 else
291 dwRet = MMSYSERR_INVALPARAM;
292 break;
293 case MIXER_GETLINECONTROLSF_ONEBYTYPE:
294 switch (lpMlc->u.dwControlType & MIXERCONTROL_CT_CLASS_MASK) {
295 case MIXERCONTROL_CT_CLASS_FADER:
296 MIX_DoGetLineControls(&lpMlc->pamxctrl[0], lpMlc->dwLineID, MIXERCONTROL_CONTROLTYPE_VOLUME);
297 break;
298 case MIXERCONTROL_CT_CLASS_SWITCH:
299 MIX_DoGetLineControls(&lpMlc->pamxctrl[0], lpMlc->dwLineID, MIXERCONTROL_CONTROLTYPE_MUTE);
300 break;
301 default:
302 dwRet = MMSYSERR_INVALPARAM;
303 }
304 break;
305 default:
306 dprintf(("Unknown flag %08lx\n", fdwControls & MIXER_GETLINECONTROLSF_QUERYMASK));
307 dwRet = MMSYSERR_INVALPARAM;
308 }
309
310 return dwRet;
311}
312/******************************************************************************/
313/******************************************************************************/
314ODINFUNCTION3(MMRESULT, mixerGetLineControlsW,
315 HMIXEROBJ, hmxobj,
316 LPMIXERLINECONTROLSW, pmxlc,
317 DWORD, fdwControls)
318{
319 dprintf(("WINMM:mixerGetGetLineControlsW - stub\n" ));
320 return MIXERR_INVALLINE;
321}
322/******************************************************************************/
323/******************************************************************************/
324ODINFUNCTION3(MMRESULT, mixerGetDevCapsA,
325 UINT, uMxId,
326 LPMIXERCAPSA, pmxcaps,
327 UINT, cbmxcaps)
328{
329 if(DartWaveOut::getNumDevices() == 0) {
330 memset(pmxcaps, 0, sizeof(*pmxcaps));
331 return MMSYSERR_NODRIVER;
332 }
333
334 // we have to fill in this thing
335 pmxcaps->wMid = 0; /* manufacturer ID */
336 pmxcaps->wPid = 0; /* product ID */
337 pmxcaps->vDriverVersion = 0x0001; /* version of the driver */
338 strcpy( pmxcaps->szPname, WINMM_MIXERSTRING_A); /* product name */
339
340 pmxcaps->fdwSupport = 0;
341 pmxcaps->cDestinations = 1;
342
343 return MMSYSERR_NOERROR;
344}
345/******************************************************************************/
346/******************************************************************************/
347ODINFUNCTION3(MMRESULT, mixerGetDevCapsW,
348 UINT, uMxId,
349 LPMIXERCAPSW, pmxcaps,
350 UINT, cbmxcaps)
351{
352 if(DartWaveOut::getNumDevices() == 0) {
353 memset(pmxcaps, 0, sizeof(*pmxcaps));
354 return MMSYSERR_NODRIVER;
355 }
356
357 // we have to fill in this thing
358 pmxcaps->wMid = 0; /* manufacturer ID */
359 pmxcaps->wPid = 0; /* product ID */
360 pmxcaps->vDriverVersion = 0x0001; /* version of the driver */
361 lstrcpyW( pmxcaps->szPname, WINMM_MIXERSTRING_W ); /* product name */
362
363 pmxcaps->fdwSupport = 0;
364 pmxcaps->cDestinations = 1;
365
366 return MMSYSERR_NOERROR;
367}
368/******************************************************************************/
369/******************************************************************************/
370ODINFUNCTION3(MMRESULT, mixerGetID,
371 HMIXEROBJ, hmxobj,
372 UINT *, puMxId,
373 DWORD, fdwId)
374{
375 DEVICE_STRUCT *pMixInfo = (DEVICE_STRUCT *)hmxobj;
376
377 if(pMixInfo && puMxId) {
378 *puMxId = pMixInfo->uDeviceID;
379 }
380 else *puMxId = 0;
381 return MMSYSERR_NOERROR;
382}
383/******************************************************************************/
384/******************************************************************************/
385ODINFUNCTION3(MMRESULT, mixerGetLineInfoA,
386 HMIXEROBJ, hmxobj,
387 LPMIXERLINEA, lpMl,
388 DWORD, fdwInfo)
389{
390 if (lpMl == NULL || lpMl->cbStruct != sizeof(*lpMl))
391 return MMSYSERR_INVALPARAM;
392
393 /* FIXME: set all the variables correctly... the lines below
394 * are very wrong...
395 */
396 lpMl->fdwLine = MIXERLINE_LINEF_ACTIVE;
397 lpMl->cChannels = 1;
398 lpMl->dwUser = 0;
399 lpMl->cControls = 2;
400
401 switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK)
402 {
403 case MIXER_GETLINEINFOF_DESTINATION:
404 /* FIXME: Linux doesn't seem to support multiple outputs?
405 * So we have only one output type: Speaker.
406 */
407 lpMl->dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
408 lpMl->dwSource = 0xFFFFFFFF;
409 lpMl->dwLineID = SOUND_MIXER_LINEOUT;
410 lstrcpynA(lpMl->szShortName, WINMM_SHORTNAME_LINEOUT_A, MIXER_SHORT_NAME_CHARS);
411 lstrcpynA(lpMl->szName, WINMM_SHORTNAME_LINEOUT_A, MIXER_LONG_NAME_CHARS);
412
413 /* we have all connections found in the MIX_DevMask */
414 lpMl->cConnections = 1; //waveout
415 lpMl->cControls = 1;
416 lpMl->cChannels = 2;
417 break;
418
419 case MIXER_GETLINEINFOF_LINEID:
420 if(lpMl->dwLineID >= SOUND_MIXER_MAXID)
421 return MIXERR_INVALLINE;
422
423 lpMl->cChannels = 2;
424 lpMl->dwDestination = 0; /* index for speakers */
425 if(lpMl->dwLineID == SOUND_MIXER_WAVEOUT) {
426 lpMl->dwLineID = SOUND_MIXER_WAVEOUT;
427 lstrcpynA(lpMl->szShortName, WINMM_SHORTNAME_WAVEOUT_A, MIXER_SHORT_NAME_CHARS);
428 lstrcpynA(lpMl->szName, WINMM_SHORTNAME_WAVEOUT_A, MIXER_LONG_NAME_CHARS);
429 lpMl->cConnections = 0;
430 lpMl->cControls = 1;
431 lpMl->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
432 lpMl->fdwLine |= MIXERLINE_LINEF_SOURCE;
433 }
434 else {
435 lpMl->dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
436 lpMl->dwSource = 0xFFFFFFFF;
437 lpMl->dwLineID = SOUND_MIXER_LINEOUT;
438 lstrcpynA(lpMl->szShortName, WINMM_SHORTNAME_LINEOUT_A, MIXER_SHORT_NAME_CHARS);
439 lstrcpynA(lpMl->szName, WINMM_SHORTNAME_LINEOUT_A, MIXER_LONG_NAME_CHARS);
440 lpMl->cConnections = 1;
441 lpMl->cControls = 1;
442 }
443 break;
444
445 case MIXER_GETLINEINFOF_SOURCE:
446 if(lpMl->dwSource != SOUND_MIXER_WAVEOUT)
447 return MIXERR_INVALLINE;
448
449 lpMl->dwLineID = SOUND_MIXER_WAVEOUT;
450 lstrcpynA(lpMl->szShortName, WINMM_SHORTNAME_WAVEOUT_A, MIXER_SHORT_NAME_CHARS);
451 lstrcpynA(lpMl->szName, WINMM_SHORTNAME_WAVEOUT_A, MIXER_LONG_NAME_CHARS);
452 lpMl->cConnections = 0;
453 lpMl->cControls = 1;
454 lpMl->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
455 lpMl->fdwLine |= MIXERLINE_LINEF_SOURCE;
456 lpMl->cChannels = 2;
457 lpMl->dwLineID = SOUND_MIXER_WAVEOUT;
458 lpMl->dwDestination = 0; /* index for speakers */
459 break;
460
461 case MIXER_GETLINEINFOF_COMPONENTTYPE:
462 switch (lpMl->dwComponentType)
463 {
464 case MIXERLINE_COMPONENTTYPE_DST_SPEAKERS:
465 lpMl->dwDestination = 0;
466 lpMl->dwSource = 0xFFFFFFFF;
467 lpMl->dwLineID = SOUND_MIXER_LINEOUT;
468 lstrcpynA(lpMl->szShortName, WINMM_SHORTNAME_LINEOUT_A, MIXER_SHORT_NAME_CHARS);
469 lstrcpynA(lpMl->szName, WINMM_SHORTNAME_LINEOUT_A, MIXER_LONG_NAME_CHARS);
470 break;
471 case MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT:
472 lpMl->dwLineID = SOUND_MIXER_WAVEOUT;
473 lpMl->fdwLine |= MIXERLINE_LINEF_SOURCE;
474 lstrcpynA(lpMl->szShortName, WINMM_SHORTNAME_WAVEOUT_A, MIXER_SHORT_NAME_CHARS);
475 lstrcpynA(lpMl->szName, WINMM_SHORTNAME_WAVEOUT_A, MIXER_LONG_NAME_CHARS);
476 break;
477 default:
478 dprintf(("Unhandled component type (%08lx)\n", lpMl->dwComponentType));
479 return MMSYSERR_INVALPARAM;
480 }
481 lpMl->cConnections = 0;
482 lpMl->cControls = 1;
483 lpMl->cChannels = 2;
484 break;
485
486 case MIXER_GETLINEINFOF_TARGETTYPE:
487 dprintf(("_TARGETTYPE not implemented yet.\n"));
488 break;
489 default:
490 dprintf(("Unknown flag (%08lx)\n", fdwInfo & MIXER_GETLINEINFOF_QUERYMASK));
491 break;
492 }
493
494 lpMl->Target.dwType = MIXERLINE_TARGETTYPE_AUX;
495 lpMl->Target.dwDeviceID = 0xFFFFFFFF;
496 lpMl->Target.wMid = 0;
497 lpMl->Target.wPid = 0;
498 lpMl->Target.vDriverVersion = 1;
499 lstrcpyA(lpMl->Target.szPname, WINMM_MIXERSTRING_A);
500
501 return MMSYSERR_NOERROR;
502}
503
504/******************************************************************************/
505ODINFUNCTION3(MMRESULT, mixerGetLineInfoW,
506 HMIXEROBJ, hmxobj,
507 LPMIXERLINEW, pmxl,
508 DWORD, fdwInfo)
509{
510 dprintf(("WINMM:mixerGetLineInfoW - stub\n" ));
511 return MIXERR_INVALLINE;
512}
513/******************************************************************************/
514/******************************************************************************/
515ODINFUNCTION4(MMRESULT, mixerMessage,
516 HMIXER, hmx,
517 UINT, uMsg,
518 DWORD, dwParam1,
519 DWORD, dwParam2)
520{
521 dprintf(("WINMM:mixerMessage - stub\n" ));
522 return 0;
523}
524
525/******************************************************************************/
526ODINFUNCTION0(UINT, mixerGetNumDevs)
527{
528 if(DartWaveOut::getNumDevices() == 0) {
529 return 0;
530 }
531 return 1;
532}
533/******************************************************************************/
534/******************************************************************************/
535ODINFUNCTION5(MMRESULT, mixerOpen,
536 LPHMIXER, phmx,
537 UINT, uMxId,
538 DWORD, dwCallback,
539 DWORD, dwInstance,
540 DWORD, fdwOpen)
541{
542 DEVICE_STRUCT *pMixInfo;
543
544 if(DartWaveOut::getNumDevices() == 0) {
545 if(phmx) *phmx = 0;
546 return MMSYSERR_NODRIVER;
547 }
548 pMixInfo = (DEVICE_STRUCT *)malloc(sizeof(DEVICE_STRUCT));
549 if(pMixInfo == NULL) {
550 return MMSYSERR_NODRIVER;
551 }
552 pMixInfo->dwCallback = dwCallback;
553 pMixInfo->dwDriverInstance = dwInstance;
554 pMixInfo->dwFlags = fdwOpen;
555 pMixInfo->uDeviceID = uMxId;
556 pMixInfo->type = WINMM_MIXER;
557 if(phmx)
558 *phmx = (HMIXER)pMixInfo;
559 return MMSYSERR_NOERROR;
560}
561/******************************************************************************/
562/******************************************************************************/
563ODINFUNCTION1(MMRESULT, mixerClose,
564 HMIXER, hmx)
565{
566 if(hmx) {
567 free((void *)hmx);
568 }
569 return MMSYSERR_NOERROR;
570}
571/******************************************************************************/
572/******************************************************************************/
573
574
Note: See TracBrowser for help on using the repository browser.