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

Last change on this file since 5090 was 5090, checked in by sandervl, 25 years ago

Update for VAC 3.6.5

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