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

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

faked mixer apis

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