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

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

fixed mixerGetID

File size: 18.3 KB
Line 
1/* $Id: mixer.cpp,v 1.7 2000-09-02 08:32:03 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 else *puMxId = 0;
378 return MMSYSERR_NOERROR;
379}
380/******************************************************************************/
381/******************************************************************************/
382ODINFUNCTION3(MMRESULT, mixerGetLineInfoA,
383 HMIXEROBJ, hmxobj,
384 LPMIXERLINEA, lpMl,
385 DWORD, fdwInfo)
386{
387 if (lpMl == NULL || lpMl->cbStruct != sizeof(*lpMl))
388 return MMSYSERR_INVALPARAM;
389
390 /* FIXME: set all the variables correctly... the lines below
391 * are very wrong...
392 */
393 lpMl->fdwLine = MIXERLINE_LINEF_ACTIVE;
394 lpMl->cChannels = 1;
395 lpMl->dwUser = 0;
396 lpMl->cControls = 2;
397
398 switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK)
399 {
400 case MIXER_GETLINEINFOF_DESTINATION:
401 /* FIXME: Linux doesn't seem to support multiple outputs?
402 * So we have only one output type: Speaker.
403 */
404 lpMl->dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
405 lpMl->dwSource = 0xFFFFFFFF;
406 lpMl->dwLineID = SOUND_MIXER_LINEOUT;
407 lstrcpynA(lpMl->szShortName, WINMM_SHORTNAME_LINEOUT_A, MIXER_SHORT_NAME_CHARS);
408 lstrcpynA(lpMl->szName, WINMM_SHORTNAME_LINEOUT_A, MIXER_LONG_NAME_CHARS);
409
410 /* we have all connections found in the MIX_DevMask */
411 lpMl->cConnections = 1; //waveout
412 lpMl->cControls = 1;
413 lpMl->cChannels = 2;
414 break;
415
416 case MIXER_GETLINEINFOF_LINEID:
417 if(lpMl->dwLineID >= SOUND_MIXER_MAXID)
418 return MIXERR_INVALLINE;
419
420 lpMl->cChannels = 2;
421 lpMl->dwDestination = 0; /* index for speakers */
422 if(lpMl->dwLineID == SOUND_MIXER_WAVEOUT) {
423 lpMl->dwLineID = SOUND_MIXER_WAVEOUT;
424 lstrcpynA(lpMl->szShortName, WINMM_SHORTNAME_WAVEOUT_A, MIXER_SHORT_NAME_CHARS);
425 lstrcpynA(lpMl->szName, WINMM_SHORTNAME_WAVEOUT_A, MIXER_LONG_NAME_CHARS);
426 lpMl->cConnections = 0;
427 lpMl->cControls = 1;
428 lpMl->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
429 lpMl->fdwLine |= MIXERLINE_LINEF_SOURCE;
430 }
431 else {
432 lpMl->dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
433 lpMl->dwSource = 0xFFFFFFFF;
434 lpMl->dwLineID = SOUND_MIXER_LINEOUT;
435 lstrcpynA(lpMl->szShortName, WINMM_SHORTNAME_LINEOUT_A, MIXER_SHORT_NAME_CHARS);
436 lstrcpynA(lpMl->szName, WINMM_SHORTNAME_LINEOUT_A, MIXER_LONG_NAME_CHARS);
437 lpMl->cConnections = 1;
438 lpMl->cControls = 1;
439 }
440 break;
441
442 case MIXER_GETLINEINFOF_SOURCE:
443 if(lpMl->dwSource != SOUND_MIXER_WAVEOUT)
444 return MIXERR_INVALLINE;
445
446 lpMl->dwLineID = SOUND_MIXER_WAVEOUT;
447 lstrcpynA(lpMl->szShortName, WINMM_SHORTNAME_WAVEOUT_A, MIXER_SHORT_NAME_CHARS);
448 lstrcpynA(lpMl->szName, WINMM_SHORTNAME_WAVEOUT_A, MIXER_LONG_NAME_CHARS);
449 lpMl->cConnections = 0;
450 lpMl->cControls = 1;
451 lpMl->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
452 lpMl->fdwLine |= MIXERLINE_LINEF_SOURCE;
453 lpMl->cChannels = 2;
454 lpMl->dwLineID = SOUND_MIXER_WAVEOUT;
455 lpMl->dwDestination = 0; /* index for speakers */
456 break;
457
458 case MIXER_GETLINEINFOF_COMPONENTTYPE:
459 switch (lpMl->dwComponentType)
460 {
461 case MIXERLINE_COMPONENTTYPE_DST_SPEAKERS:
462 lpMl->dwDestination = 0;
463 lpMl->dwSource = 0xFFFFFFFF;
464 lpMl->dwLineID = SOUND_MIXER_LINEOUT;
465 lstrcpynA(lpMl->szShortName, WINMM_SHORTNAME_LINEOUT_A, MIXER_SHORT_NAME_CHARS);
466 lstrcpynA(lpMl->szName, WINMM_SHORTNAME_LINEOUT_A, MIXER_LONG_NAME_CHARS);
467 break;
468 case MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT:
469 lpMl->dwLineID = SOUND_MIXER_WAVEOUT;
470 lpMl->fdwLine |= MIXERLINE_LINEF_SOURCE;
471 lstrcpynA(lpMl->szShortName, WINMM_SHORTNAME_WAVEOUT_A, MIXER_SHORT_NAME_CHARS);
472 lstrcpynA(lpMl->szName, WINMM_SHORTNAME_WAVEOUT_A, MIXER_LONG_NAME_CHARS);
473 break;
474 default:
475 dprintf(("Unhandled component type (%08lx)\n", lpMl->dwComponentType));
476 return MMSYSERR_INVALPARAM;
477 }
478 lpMl->cConnections = 0;
479 lpMl->cControls = 1;
480 lpMl->cChannels = 2;
481 break;
482
483 case MIXER_GETLINEINFOF_TARGETTYPE:
484 dprintf(("_TARGETTYPE not implemented yet.\n"));
485 break;
486 default:
487 dprintf(("Unknown flag (%08lx)\n", fdwInfo & MIXER_GETLINEINFOF_QUERYMASK));
488 break;
489 }
490
491 lpMl->Target.dwType = MIXERLINE_TARGETTYPE_AUX;
492 lpMl->Target.dwDeviceID = 0xFFFFFFFF;
493 lpMl->Target.wMid = 0;
494 lpMl->Target.wPid = 0;
495 lpMl->Target.vDriverVersion = 1;
496 lstrcpyA(lpMl->Target.szPname, WINMM_MIXERSTRING_A);
497
498 return MMSYSERR_NOERROR;
499}
500
501/******************************************************************************/
502ODINFUNCTION3(MMRESULT, mixerGetLineInfoW,
503 HMIXEROBJ, hmxobj,
504 LPMIXERLINEW, pmxl,
505 DWORD, fdwInfo)
506{
507 dprintf(("WINMM:mixerGetLineInfoW - stub\n" ));
508 return MIXERR_INVALLINE;
509}
510/******************************************************************************/
511/******************************************************************************/
512ODINFUNCTION4(MMRESULT, mixerMessage,
513 HMIXER, hmx,
514 UINT, uMsg,
515 DWORD, dwParam1,
516 DWORD, dwParam2)
517{
518 dprintf(("WINMM:mixerMessage - stub\n" ));
519 return 0;
520}
521
522/******************************************************************************/
523ODINFUNCTION0(UINT, mixerGetNumDevs)
524{
525 if(DartWaveOut::getNumDevices() == 0) {
526 return 0;
527 }
528 return 1;
529}
530/******************************************************************************/
531/******************************************************************************/
532ODINFUNCTION5(MMRESULT, mixerOpen,
533 LPHMIXER, phmx,
534 UINT, uMxId,
535 DWORD, dwCallback,
536 DWORD, dwInstance,
537 DWORD, fdwOpen)
538{
539 DEVICE_STRUCT *pMixInfo;
540
541 if(DartWaveOut::getNumDevices() == 0) {
542 if(phmx) *phmx = 0;
543 return MMSYSERR_NODRIVER;
544 }
545 pMixInfo = (DEVICE_STRUCT *)malloc(sizeof(DEVICE_STRUCT));
546 if(pMixInfo == NULL) {
547 return MMSYSERR_NODRIVER;
548 }
549 pMixInfo->dwCallback = dwCallback;
550 pMixInfo->dwDriverInstance = dwInstance;
551 pMixInfo->dwFlags = fdwOpen;
552 pMixInfo->uDeviceID = uMxId;
553 pMixInfo->type = WINMM_MIXER;
554 if(phmx)
555 *phmx = (HMIXER)pMixInfo;
556 return MMSYSERR_NOERROR;
557}
558/******************************************************************************/
559/******************************************************************************/
560ODINFUNCTION1(MMRESULT, mixerClose,
561 HMIXER, hmx)
562{
563 if(hmx) {
564 free((void *)hmx);
565 }
566 return MMSYSERR_NOERROR;
567}
568/******************************************************************************/
569/******************************************************************************/
570
571
Note: See TracBrowser for help on using the repository browser.