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

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

mixer updates

File size: 36.5 KB
Line 
1/* $Id: mixer.cpp,v 1.13 2002-05-23 13:50:15 sandervl Exp $ */
2
3/*
4 * Mixer functions
5 *
6 * Copyright 2002 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 * TODO: Mixer notification
9 *
10 * NOTE: Not really flexible (capabilities, > 1 audio card)
11 *
12 * Project Odin Software License can be found in LICENSE.TXT
13 *
14 */
15
16/****************************************************************************
17 * Includes *
18 ****************************************************************************/
19
20#define NONAMELESSUNION
21#define NONAMELESSSTRUCT
22
23#include <os2win.h>
24#include <string.h>
25#include <dbglog.h>
26#include <mmsystem.h>
27#include <winnls.h>
28
29#include "waveoutdart.h"
30#include "winmm.h"
31#include "initwinmm.h"
32#include "mixer.h"
33#include "mixeros2.h"
34
35#define DBG_LOCALLOG DBG_mixer
36#include "dbglocal.h"
37
38static BOOL mixerAddControl(DWORD dwControl);
39static BOOL mixerAddSource(DWORD dwDest);
40static BOOL mixerAddDestination(DWORD dwSource);
41
42static MIXERLINEA mixerDest[MAX_MIXER_DESTINATIONS] = {0};
43static MIXERLINEA mixerSource[MAX_MIXER_SOURCES] = {0};
44static MIXERCONTROLA mixerControls[MAX_MIXER_CONTROLS] = {0};
45static int nrDestinations = 0;
46static int nrSources = 0;
47static int nrControls = 0;
48static int nrLineOutInputs = 0;
49static int nrLineOutControls = 0;
50static int nrWaveInInputs = 0;
51static int nrWaveInControls = 0;
52static int nrSPDIFInputs = 0;
53static int nrSPDIFControls = 0;
54
55/******************************************************************************/
56/******************************************************************************/
57MMRESULT WINAPI mixerGetControlDetailsA(HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS lpmcd, DWORD fdwDetails)
58{
59 DWORD lineID, controlType;
60
61 if (lpmcd == NULL) return MMSYSERR_INVALPARAM;
62
63 switch (fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK) {
64 case MIXER_GETCONTROLDETAILSF_VALUE:
65 break;
66 case MIXER_GETCONTROLDETAILSF_LISTTEXT:
67 dprintf(("mixerGetControlDetailsA: NIY\n"));
68 break;
69 default:
70 dprintf(("Unknown flag (%08lx)\n", fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK));
71 break;
72 }
73 return MMSYSERR_NOERROR;
74}
75/******************************************************************************/
76/******************************************************************************/
77MMRESULT WINAPI mixerGetControlDetailsW(HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails)
78{
79 dprintf(("WINMM:mixerGetControlDetailsW - stub\n" ));
80 return MIXERR_INVALCONTROL;
81}
82/******************************************************************************/
83/******************************************************************************/
84MMRESULT WINAPI mixerSetControlDetails(HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS lpmcd, DWORD fdwDetails)
85{
86 DWORD ret = MMSYSERR_NOTSUPPORTED;
87 DWORD lineID, controlType;
88 int val;
89
90 if (lpmcd == NULL) return MMSYSERR_INVALPARAM;
91
92 switch (fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK) {
93 case MIXER_GETCONTROLDETAILSF_VALUE:
94 break;
95 case MIXER_GETCONTROLDETAILSF_LISTTEXT:
96 dprintf(("mixerSetControlDetails: NIY\n"));
97 break;
98 default:
99 dprintf(("Unknown flag (%08lx)\n", fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK));
100 break;
101 }
102 return MMSYSERR_NOTSUPPORTED;
103}
104/******************************************************************************/
105/******************************************************************************/
106MMRESULT WINAPI mixerGetLineControlsA(HMIXEROBJ hmxobj, LPMIXERLINECONTROLSA lpMlc, DWORD fdwControls)
107{
108 DWORD dwRet = MMSYSERR_NOERROR;
109 DWORD lineID, controlType;
110 DEVICE_STRUCT *pMixInfo = (DEVICE_STRUCT *)hmxobj;
111
112 if(!pMixInfo) {
113 return MMSYSERR_INVALHANDLE;
114 }
115
116 if (lpMlc == NULL) return MMSYSERR_INVALPARAM;
117
118 if (lpMlc->cbStruct < sizeof(*lpMlc) || lpMlc->cbmxctrl < sizeof(MIXERCONTROLA))
119 return MMSYSERR_INVALPARAM;
120
121 switch(fdwControls & MIXER_GETLINECONTROLSF_QUERYMASK)
122 {
123 case MIXER_GETLINECONTROLSF_ALL:
124 if (lpMlc->cControls != 2) {
125 dwRet = MMSYSERR_INVALPARAM;
126 }
127 else {
128 }
129 break;
130 case MIXER_GETLINECONTROLSF_ONEBYID:
131 break;
132
133 case MIXER_GETLINECONTROLSF_ONEBYTYPE:
134 switch (lpMlc->u.dwControlType & MIXERCONTROL_CT_CLASS_MASK) {
135 case MIXERCONTROL_CT_CLASS_FADER:
136 break;
137 case MIXERCONTROL_CT_CLASS_SWITCH:
138 break;
139 default:
140 dwRet = MMSYSERR_INVALPARAM;
141 }
142 break;
143
144 default:
145 dprintf(("Unknown flag %08lx\n", fdwControls & MIXER_GETLINECONTROLSF_QUERYMASK));
146 dwRet = MMSYSERR_INVALPARAM;
147 }
148
149 return dwRet;
150}
151/******************************************************************************/
152/******************************************************************************/
153MMRESULT WINAPI mixerGetLineControlsW(HMIXEROBJ hmxobj, LPMIXERLINECONTROLSW pmxlc, DWORD fdwControls)
154{
155 DEVICE_STRUCT *pMixInfo = (DEVICE_STRUCT *)hmxobj;
156
157 if(!pMixInfo) {
158 return MMSYSERR_INVALHANDLE;
159 }
160
161 dprintf(("WINMM:mixerGetGetLineControlsW - stub\n" ));
162 return MIXERR_INVALLINE;
163}
164/******************************************************************************/
165/******************************************************************************/
166MMRESULT WINAPI mixerGetLineInfoA(HMIXEROBJ hmxobj, LPMIXERLINEA lpMl, DWORD fdwInfo)
167{
168 DEVICE_STRUCT *pMixInfo = (DEVICE_STRUCT *)hmxobj;
169
170 if(!pMixInfo) {
171 return MMSYSERR_INVALHANDLE;
172 }
173
174 if (lpMl == NULL || lpMl->cbStruct != sizeof(*lpMl)) {
175 dprintf(("ERROR: mixerGetLineInfoA: invalid paramter!!"));
176 return MMSYSERR_INVALPARAM;
177 }
178
179 switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK)
180 {
181 case MIXER_GETLINEINFOF_DESTINATION:
182 dprintf(("MIXER_GETLINEINFOF_DESTINATION"));
183 if(lpMl->dwDestination >= nrDestinations) {
184 dprintf(("ERROR: Invalid desitnation %d", lpMl->dwDestination));
185 return MMSYSERR_INVALPARAM;
186 }
187 memcpy(lpMl, &mixerDest[lpMl->dwDestination], sizeof(MIXERLINEA));
188 break;
189
190 case MIXER_GETLINEINFOF_LINEID:
191 dprintf(("MIXER_GETLINEINFOF_LINEID"));
192 break;
193
194 case MIXER_GETLINEINFOF_SOURCE:
195 dprintf(("MIXER_GETLINEINFOF_SOURCE"));
196 if(lpMl->dwDestination >= nrDestinations) {
197 dprintf(("ERROR: Invalid desitnation %d", lpMl->dwDestination));
198 return MMSYSERR_INVALPARAM;
199 }
200 break;
201
202 case MIXER_GETLINEINFOF_COMPONENTTYPE:
203 dprintf(("MIXER_GETLINEINFOF_COMPONENTTYPE"));
204 switch (lpMl->dwComponentType)
205 {
206 case MIXERLINE_COMPONENTTYPE_DST_SPEAKERS:
207 break;
208 case MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT:
209 break;
210 default:
211 dprintf(("Unhandled component type (%08lx)\n", lpMl->dwComponentType));
212 return MMSYSERR_INVALPARAM;
213 }
214 break;
215
216 case MIXER_GETLINEINFOF_TARGETTYPE:
217 dprintf(("_TARGETTYPE not implemented yet.\n"));
218 break;
219 default:
220 dprintf(("Unknown flag (%08lx)\n", fdwInfo & MIXER_GETLINEINFOF_QUERYMASK));
221 break;
222 }
223 return MMSYSERR_NOERROR;
224}
225/******************************************************************************/
226/******************************************************************************/
227MMRESULT WINAPI mixerGetLineInfoW(HMIXEROBJ hmxobj, LPMIXERLINEW pmxl, DWORD fdwInfo)
228{
229 DEVICE_STRUCT *pMixInfo = (DEVICE_STRUCT *)hmxobj;
230 MIXERLINEA line;
231 MMRESULT result;
232
233 if(!pMixInfo) {
234 return MMSYSERR_INVALHANDLE;
235 }
236 line.cbStruct = sizeof(MIXERLINEA);
237 line.cChannels = pmxl->cChannels;
238 line.cConnections = pmxl->cConnections;
239 line.dwComponentType = pmxl->dwComponentType;
240 line.dwDestination = pmxl->dwDestination;
241 line.dwLineID = pmxl->dwLineID;
242 line.dwSource = pmxl->dwSource;
243 line.dwUser = pmxl->dwUser;
244 line.fdwLine = pmxl->fdwLine;
245 line.szName[0] = 0;
246 line.szShortName[0] = 0;
247 line.Target.dwDeviceID = pmxl->Target.dwDeviceID;
248 line.Target.dwType = pmxl->Target.dwType;
249 line.Target.vDriverVersion = pmxl->Target.vDriverVersion;
250 line.Target.wMid = pmxl->Target.wMid;
251 line.Target.wPid = pmxl->Target.wPid;
252 line.Target.szPname[0] = 0;
253
254 result = mixerGetLineInfoA(hmxobj, &line, fdwInfo);
255 if(result != MMSYSERR_NOERROR) {
256 return result;
257 }
258 pmxl->cbStruct = sizeof(MIXERLINEA);
259 pmxl->cChannels = line.cChannels;
260 pmxl->cConnections = line.cConnections;
261 pmxl->dwComponentType = line.dwComponentType;
262 pmxl->dwDestination = line.dwDestination;
263 pmxl->dwLineID = line.dwLineID;
264 pmxl->dwSource = line.dwSource;
265 pmxl->dwUser = line.dwUser;
266 pmxl->fdwLine = line.fdwLine;
267 MultiByteToWideChar(CP_ACP, 0, line.szName, -1, pmxl->szName, sizeof(line.szName));
268 MultiByteToWideChar(CP_ACP, 0, line.szShortName, -1, pmxl->szShortName, sizeof(line.szShortName));
269 pmxl->Target.dwDeviceID = line.Target.dwDeviceID;
270 pmxl->Target.dwType = line.Target.dwType;
271 pmxl->Target.vDriverVersion = line.Target.vDriverVersion;
272 pmxl->Target.wMid = line.Target.wMid;
273 pmxl->Target.wPid = line.Target.wPid;
274 pmxl->Target.szPname[0] = 0;
275 MultiByteToWideChar(CP_ACP, 0, line.Target.szPname, -1, pmxl->Target.szPname, sizeof(line.Target.szPname));
276 return MMSYSERR_NOERROR;
277}
278/******************************************************************************/
279/******************************************************************************/
280MMRESULT WINAPI mixerMessage(HMIXER hmx, UINT uMsg, DWORD dwParam1, DWORD dwParam2)
281{
282 dprintf(("WINMM:mixerMessage - stub\n" ));
283 return 0;
284}
285/******************************************************************************/
286/******************************************************************************/
287UINT WINAPI mixerGetNumDevs()
288{
289 if(fMMPMAvailable == FALSE || DartWaveOut::getNumDevices() == 0) {
290 return 0;
291 }
292 return 1;
293}
294/******************************************************************************/
295/******************************************************************************/
296MMRESULT WINAPI mixerGetDevCapsA(UINT uMxId, LPMIXERCAPSA pmxcaps, UINT cbmxcaps)
297{
298 if(fMMPMAvailable == FALSE || DartWaveOut::getNumDevices() == 0) {
299 return MMSYSERR_BADDEVICEID;
300 }
301
302 if(uMxId > 0) {
303 return MMSYSERR_BADDEVICEID;
304 }
305
306 //According to MSDN, nothing is copied when cbmxcaps is zero
307 if(cbmxcaps >= sizeof(MIXERCAPSA)) {
308 // we have to fill in this thing
309 pmxcaps->wMid = 0; /* manufacturer ID */
310 pmxcaps->wPid = 0; /* product ID */
311 pmxcaps->vDriverVersion = 0x0001; /* version of the driver */
312 strcpy( pmxcaps->szPname, WINMM_MIXERSTRING_A); /* product name */
313
314 pmxcaps->fdwSupport = 0; //no mixer flags exist
315 pmxcaps->cDestinations = nrDestinations;
316 }
317
318 return MMSYSERR_NOERROR;
319}
320/******************************************************************************/
321/******************************************************************************/
322MMRESULT WINAPI mixerGetDevCapsW(UINT uMxId, LPMIXERCAPSW pmxcaps, UINT cbmxcaps)
323{
324 if(fMMPMAvailable == FALSE || DartWaveOut::getNumDevices() == 0) {
325 return MMSYSERR_BADDEVICEID;
326 }
327
328 if(uMxId > 0) {
329 return MMSYSERR_BADDEVICEID;
330 }
331
332 //According to MSDN, nothing is copied when cbmxcaps is zero
333 if(cbmxcaps >= sizeof(MIXERCAPSW)) {
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 lstrcpyW( pmxcaps->szPname, WINMM_MIXERSTRING_W ); /* product name */
339
340 pmxcaps->fdwSupport = 0; //no mixer flags exist
341 pmxcaps->cDestinations = nrDestinations;
342 }
343
344 return MMSYSERR_NOERROR;
345}
346/******************************************************************************/
347/******************************************************************************/
348MMRESULT WINAPI mixerGetID(HMIXEROBJ hmxobj, UINT * puMxId, DWORD fdwId)
349{
350 switch(fdwId) {
351 case MIXER_OBJECTF_MIXER:
352 {
353 DEVICE_STRUCT *pMixInfo = (DEVICE_STRUCT *)hmxobj;
354 if(!pMixInfo) {
355 if(puMxId) {
356 *puMxId = -1;
357 }
358 return MMSYSERR_INVALHANDLE;
359 }
360 if(puMxId) {
361 *puMxId = pMixInfo->uDeviceID;
362 }
363 break;
364 }
365
366 case MIXER_OBJECTF_HMIXER:
367 case MIXER_OBJECTF_WAVEOUT:
368 case MIXER_OBJECTF_HWAVEOUT:
369 case MIXER_OBJECTF_WAVEIN:
370 case MIXER_OBJECTF_HWAVEIN:
371 case MIXER_OBJECTF_MIDIOUT:
372 case MIXER_OBJECTF_HMIDIOUT:
373 case MIXER_OBJECTF_MIDIIN:
374 case MIXER_OBJECTF_HMIDIIN:
375 case MIXER_OBJECTF_AUX:
376 //TODO: assume default mixer
377 if(puMxId) {
378 *puMxId = 0;
379 }
380 break;
381 default:
382 if(puMxId) {
383 *puMxId = -1;
384 }
385 return MMSYSERR_INVALPARAM;
386 }
387 return MMSYSERR_NOERROR;
388}
389/******************************************************************************/
390/******************************************************************************/
391MMRESULT WINAPI mixerOpen(LPHMIXER phmx, UINT uMxId, DWORD dwCallback, DWORD dwInstance,
392 DWORD fdwOpen)
393{
394 DEVICE_STRUCT *pMixInfo;
395
396 if(DartWaveOut::getNumDevices() == 0) {
397 if(phmx) *phmx = 0;
398 return MMSYSERR_NODRIVER;
399 }
400 pMixInfo = (DEVICE_STRUCT *)malloc(sizeof(DEVICE_STRUCT));
401 if(pMixInfo == NULL) {
402 return MMSYSERR_NODRIVER;
403 }
404 pMixInfo->dwCallback = dwCallback;
405 pMixInfo->dwDriverInstance = dwInstance;
406 pMixInfo->dwFlags = fdwOpen;
407 pMixInfo->uDeviceID = uMxId;
408 pMixInfo->type = WINMM_MIXER;
409 if(phmx)
410 *phmx = (HMIXER)pMixInfo;
411
412 return MMSYSERR_NOERROR;
413}
414/******************************************************************************/
415/******************************************************************************/
416MMRESULT WINAPI mixerClose(HMIXER hmx)
417{
418 if(hmx) {
419 free((void *)hmx);
420 }
421 return MMSYSERR_NOERROR;
422}
423/******************************************************************************/
424/******************************************************************************/
425BOOL mixerInit()
426{
427 if(!fMMPMAvailable) return TRUE;
428
429 if(OSLibMixerOpen() == FALSE) {
430 //Line out destination
431 mixerAddControl(MIX_CTRL_VOL_OUT_LINE);
432 mixerAddControl(MIX_CTRL_MUTE_OUT_LINE);
433 //muast add after all controls (for counting controls & inputs)
434 mixerAddDestination(MIXER_DEST_LINEOUT);
435
436 //WaveIn destination
437 mixerAddControl(MIX_CTRL_VOL_IN_W_MIC);
438 mixerAddControl(MIX_CTRL_VOL_IN_W_LINE);
439 //must add after all recording inputs (to count them)
440 mixerAddControl(MIX_CTRL_MUX_IN_W_SRC);
441 //muast add after all wave in controls (for counting controls & inputs)
442 mixerAddDestination(MIXER_DEST_WAVEIN);
443 return TRUE;
444 }
445 //Line out destination
446 mixerAddControl(MIX_CTRL_VOL_OUT_LINE);
447 mixerAddControl(MIX_CTRL_MUTE_OUT_LINE);
448
449 if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_SPDIF)) {
450 mixerAddSource(MIXER_SRC_SPDIF);
451 mixerAddControl(MIX_CTRL_VOL_IN_L_SPDIF);
452 mixerAddControl(MIX_CTRL_MUTE_IN_L_SPDIF);
453 }
454
455 if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_MONO)) {
456 mixerAddSource(MIXER_SRC_MONOIN);
457 mixerAddControl(MIX_CTRL_VOL_IN_L_MONO);
458 mixerAddControl(MIX_CTRL_MUTE_IN_L_MONO);
459 }
460 if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_PHONE)) {
461 mixerAddSource(MIXER_SRC_PHONE);
462 mixerAddControl(MIX_CTRL_VOL_IN_L_PHONE);
463 mixerAddControl(MIX_CTRL_MUTE_IN_L_PHONE);
464 }
465 if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_MIC)) {
466 mixerAddSource(MIXER_SRC_MIC);
467 mixerAddControl(MIX_CTRL_VOL_IN_L_MIC);
468 mixerAddControl(MIX_CTRL_MUTE_IN_L_MIC);
469 if(OSLibMixIsControlPresent(MIX_CTRL_BOOST_IN_L_MIC)) {
470 mixerAddControl(MIX_CTRL_BOOST_IN_L_MIC);
471 }
472 }
473 if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_LINE)) {
474 mixerAddSource(MIXER_SRC_LINE);
475 mixerAddControl(MIX_CTRL_VOL_IN_L_LINE);
476 mixerAddControl(MIX_CTRL_MUTE_IN_L_LINE);
477 }
478 if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_CD)) {
479 mixerAddSource(MIXER_SRC_CD);
480 mixerAddControl(MIX_CTRL_VOL_IN_L_CD);
481 mixerAddControl(MIX_CTRL_MUTE_IN_L_CD);
482 }
483 if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_VIDEO)) {
484 mixerAddSource(MIXER_SRC_VIDEO);
485 mixerAddControl(MIX_CTRL_VOL_IN_L_VIDEO);
486 mixerAddControl(MIX_CTRL_MUTE_IN_L_VIDEO);
487 }
488 if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_AUX)) {
489 mixerAddSource(MIXER_SRC_AUX);
490 mixerAddControl(MIX_CTRL_VOL_IN_L_AUX);
491 mixerAddControl(MIX_CTRL_MUTE_IN_L_AUX);
492 }
493 if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_PCM)) {
494 mixerAddSource(MIXER_SRC_PCM);
495 mixerAddControl(MIX_CTRL_VOL_IN_L_PCM);
496 mixerAddControl(MIX_CTRL_MUTE_IN_L_PCM);
497 }
498 if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_WAVETABLE)) {
499 mixerAddSource(MIXER_SRC_WAVETABLE);
500 mixerAddControl(MIX_CTRL_VOL_IN_L_WAVETABLE);
501 mixerAddControl(MIX_CTRL_MUTE_IN_L_WAVETABLE);
502 }
503 if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_MIDI)) {
504 mixerAddSource(MIXER_SRC_MIDI);
505 mixerAddControl(MIX_CTRL_VOL_IN_L_MIDI);
506 mixerAddControl(MIX_CTRL_MUTE_IN_L_MIDI);
507 }
508 if(OSLibMixIsControlPresent(MIX_CTRL_OUT_L_3DCENTER)) {
509 mixerAddControl(MIX_CTRL_OUT_L_3DCENTER);
510 }
511 if(OSLibMixIsControlPresent(MIX_CTRL_OUT_L_3DDEPTH)) {
512 mixerAddControl(MIX_CTRL_OUT_L_3DDEPTH);
513 }
514 if(OSLibMixIsControlPresent(MIX_CTRL_OUT_L_TREBLE)) {
515 mixerAddControl(MIX_CTRL_OUT_L_TREBLE);
516 }
517 if(OSLibMixIsControlPresent(MIX_CTRL_OUT_L_BASS)) {
518 mixerAddControl(MIX_CTRL_OUT_L_BASS);
519 }
520 //muast add after all controls (for counting controls & inputs)
521 mixerAddDestination(MIXER_DEST_LINEOUT);
522
523 //Wave In Destination
524 if(OSLibMixIsControlPresent(MIX_CTRL_MUX_IN_W_SRC)) {
525 if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_MONO)) {
526 mixerAddControl(MIX_CTRL_VOL_IN_W_MONO);
527 }
528 if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_PHONE)) {
529 mixerAddControl(MIX_CTRL_VOL_IN_W_PHONE);
530 }
531 if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_MIC)) {
532 mixerAddControl(MIX_CTRL_VOL_IN_W_MIC);
533 }
534 if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_LINE)) {
535 mixerAddControl(MIX_CTRL_VOL_IN_W_LINE);
536 }
537 if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_CD)) {
538 mixerAddControl(MIX_CTRL_VOL_IN_W_CD);
539 }
540 if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_SPDIF)) {
541 mixerAddControl(MIX_CTRL_VOL_IN_W_SPDIF);
542 }
543 if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_VIDEO)) {
544 mixerAddControl(MIX_CTRL_VOL_IN_W_VIDEO);
545 }
546 if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_AUX)) {
547 mixerAddControl(MIX_CTRL_VOL_IN_W_AUX);
548 }
549 if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_PCM)) {
550 mixerAddControl(MIX_CTRL_VOL_IN_W_PCM);
551 }
552 if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_WAVETABLE)) {
553 mixerAddControl(MIX_CTRL_VOL_IN_W_WAVETABLE);
554 }
555 if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_MIDI)) {
556 mixerAddControl(MIX_CTRL_VOL_IN_W_MIDI);
557 }
558 //must add after all recording inputs (to count them)
559 mixerAddControl(MIX_CTRL_MUX_IN_W_SRC);
560 //muast add after all wave in controls (for counting controls & inputs)
561 mixerAddDestination(MIXER_DEST_WAVEIN);
562 }
563
564 //SPDIF destination
565 if(OSLibMixIsControlPresent(MIX_CTRL_VOL_OUT_SPDIF)) {
566 mixerAddControl(MIX_CTRL_VOL_OUT_SPDIF);
567 mixerAddControl(MIX_CTRL_MUTE_OUT_SPDIF);
568 mixerAddDestination(MIXER_DEST_SPDIFOUT);
569 }
570
571 return TRUE;
572}
573/******************************************************************************/
574/******************************************************************************/
575void mixerExit()
576{
577 OSLibMixerClose();
578}
579/******************************************************************************/
580/******************************************************************************/
581static BOOL mixerAddSource(DWORD dwSource)
582{
583 MIXERLINEA *pline = &mixerSource[nrSources];
584
585 if(nrSources >= MAX_MIXER_SOURCES) {
586 dprintf(("ERROR: mixerAddSource: out of room!!!"));
587 DebugInt3();
588 return FALSE;
589 }
590
591 pline->cbStruct = sizeof(MIXERLINEA);
592 memset(pline, 0, sizeof(MIXERLINEA));
593
594 switch(dwSource) {
595 case MIXER_SRC_MONOIN:
596 case MIXER_SRC_PHONE:
597 pline->dwSource = nrSources;
598 pline->cChannels = 1;
599 pline->cConnections = 0;
600 pline->cControls = 0;
601 pline->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE;
602 pline->dwDestination = 0;
603 pline->dwLineID = (DWORD)-1;
604 pline->fdwLine = MIXERLINE_LINEF_SOURCE;
605 pline->Target.dwType = MIXERLINE_TARGETTYPE_UNDEFINED;
606 nrLineOutInputs++;
607 break;
608
609 case MIXER_SRC_MIC:
610 pline->dwSource = nrSources;
611 pline->cChannels = 1;
612 pline->cConnections = 0;
613 pline->cControls = 0;
614 pline->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
615 pline->dwDestination = 0;
616 pline->dwLineID = (DWORD)-1;
617 pline->fdwLine = MIXERLINE_LINEF_SOURCE;
618 pline->Target.dwType = MIXERLINE_TARGETTYPE_UNDEFINED;
619 nrLineOutInputs++;
620 break;
621
622 case MIXER_SRC_LINE:
623 pline->dwSource = nrSources;
624 pline->cChannels = 2;
625 pline->cConnections = 0;
626 pline->cControls = 0;
627 pline->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_LINE;
628 pline->dwDestination = 0;
629 pline->dwLineID = (DWORD)-1;
630 pline->fdwLine = MIXERLINE_LINEF_SOURCE;
631 pline->Target.dwType = MIXERLINE_TARGETTYPE_UNDEFINED;
632 nrLineOutInputs++;
633 break;
634
635 case MIXER_SRC_CD:
636 pline->dwSource = nrSources;
637 pline->cChannels = 2;
638 pline->cConnections = 0;
639 pline->cControls = 0;
640 pline->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC;
641 pline->dwDestination = 0;
642 pline->dwLineID = (DWORD)-1;
643 pline->fdwLine = MIXERLINE_LINEF_SOURCE;
644 pline->Target.dwType = MIXERLINE_TARGETTYPE_UNDEFINED;
645 nrLineOutInputs++;
646 break;
647
648 case MIXER_SRC_SPDIF:
649 pline->dwSource = nrSources;
650 pline->cChannels = 2;
651 pline->cConnections = 0;
652 pline->cControls = 0;
653 pline->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_DIGITAL;
654 pline->dwDestination = 0;
655 pline->dwLineID = (DWORD)-1;
656 pline->fdwLine = MIXERLINE_LINEF_SOURCE;
657 pline->Target.dwType = MIXERLINE_TARGETTYPE_UNDEFINED;
658 nrLineOutInputs++;
659 break;
660
661 case MIXER_SRC_VIDEO:
662 pline->dwSource = nrSources;
663 pline->cChannels = 2;
664 pline->cConnections = 0;
665 pline->cControls = 0;
666 pline->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED;
667 pline->dwDestination = 0;
668 pline->dwLineID = (DWORD)-1;
669 pline->fdwLine = MIXERLINE_LINEF_SOURCE;
670 pline->Target.dwType = MIXERLINE_TARGETTYPE_UNDEFINED;
671 nrLineOutInputs++;
672 break;
673
674 case MIXER_SRC_AUX:
675 pline->dwSource = nrSources;
676 pline->cChannels = 2;
677 pline->cConnections = 0;
678 pline->cControls = 0;
679 pline->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY;
680 pline->dwDestination = 0;
681 pline->dwLineID = (DWORD)-1;
682 pline->fdwLine = MIXERLINE_LINEF_SOURCE;
683 pline->Target.dwType = MIXERLINE_TARGETTYPE_AUX;
684 nrLineOutInputs++;
685 break;
686
687 case MIXER_SRC_PCM:
688 pline->dwSource = nrSources;
689 pline->cChannels = 2;
690 pline->cConnections = 0;
691 pline->cControls = 0;
692 pline->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
693 pline->dwDestination = 0;
694 pline->dwLineID = (DWORD)-1;
695 pline->fdwLine = MIXERLINE_LINEF_SOURCE;
696 pline->Target.dwType = MIXERLINE_TARGETTYPE_WAVEOUT;
697 nrLineOutInputs++;
698 break;
699
700 case MIXER_SRC_WAVETABLE:
701 case MIXER_SRC_MIDI:
702 pline->dwSource = nrSources;
703 pline->cChannels = 2;
704 pline->cConnections = 0;
705 pline->cControls = 0;
706 pline->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER;
707 pline->dwDestination = 0;
708 pline->dwLineID = (DWORD)-1;
709 pline->fdwLine = MIXERLINE_LINEF_SOURCE;
710 pline->Target.dwType = MIXERLINE_TARGETTYPE_MIDIOUT;
711 nrLineOutInputs++;
712 break;
713
714 default:
715 DebugInt3();
716 return FALSE;
717 }
718 strncpy(pline->szShortName, szSourceName[dwSource][0], sizeof(pline->szShortName));
719 strncpy(pline->szName, szSourceName[dwSource][1], sizeof(pline->szName));
720
721 dprintf(("Adding Source %s (%s)", pline->szName, pline->szShortName));
722
723 nrSources++;
724 return TRUE;
725}
726/******************************************************************************/
727/******************************************************************************/
728static BOOL mixerAddDestination(DWORD dwDest)
729{
730 MIXERLINEA *pline = &mixerDest[nrDestinations];
731
732 if(nrDestinations >= MAX_MIXER_DESTINATIONS) {
733 dprintf(("ERROR: mixerAddDestination: out of room!!!"));
734 DebugInt3();
735 return FALSE;
736 }
737 pline->cbStruct = sizeof(MIXERLINEA);
738 memset(pline, 0, sizeof(MIXERLINEA));
739
740 switch(dwDest) {
741 case MIXER_DEST_LINEOUT:
742 pline->dwDestination = nrDestinations;
743 pline->cChannels = 2;
744 pline->cConnections = nrLineOutInputs;
745 pline->cControls = nrLineOutControls;
746 pline->dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
747 pline->dwSource = 0;
748 pline->dwLineID = (DWORD)-1;
749 pline->fdwLine = MIXERLINE_LINEF_ACTIVE;
750 pline->Target.dwType = MIXERLINE_TARGETTYPE_UNDEFINED;
751 break;
752
753 case MIXER_DEST_SPDIFOUT:
754 pline->dwDestination = nrDestinations;
755 pline->cChannels = 2;
756 pline->cConnections = nrSPDIFInputs;
757 pline->cControls = nrSPDIFControls;
758 pline->dwComponentType = MIXERLINE_COMPONENTTYPE_DST_DIGITAL;
759 pline->dwSource = 0;
760 pline->dwLineID = (DWORD)-1;
761 pline->fdwLine = 0;
762 pline->Target.dwType = MIXERLINE_TARGETTYPE_UNDEFINED;
763 break;
764
765 case MIXER_DEST_WAVEIN:
766 pline->dwSource = nrSources;
767 pline->cChannels = 2;
768 pline->cConnections = nrWaveInInputs;
769 pline->cControls = nrWaveInControls;
770 pline->dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
771 pline->dwDestination = 0;
772 pline->dwLineID = (DWORD)-1;
773 pline->fdwLine = MIXERLINE_LINEF_SOURCE;
774 pline->Target.dwType = MIXERLINE_TARGETTYPE_UNDEFINED;
775 break;
776
777 default:
778 DebugInt3();
779 return FALSE;
780 }
781 strncpy(pline->szShortName, szDestName[dwDest][0], sizeof(pline->szShortName));
782 strncpy(pline->szName, szDestName[dwDest][1], sizeof(pline->szName));
783 dprintf(("Adding destination %s (%s)", pline->szName, pline->szShortName));
784 nrDestinations++;
785 return TRUE;
786}
787/******************************************************************************/
788/******************************************************************************/
789static BOOL mixerAddControl(DWORD dwControl)
790{
791 MIXERCONTROLA *pctrl = &mixerControls[nrControls];
792
793 if(nrControls >= MAX_MIXER_CONTROLS) {
794 dprintf(("ERROR: mixerAddControl: out of room!!!"));
795 DebugInt3();
796 return FALSE;
797 }
798
799 pctrl->cbStruct = sizeof(MIXERCONTROLA);
800 memset(pctrl, 0, sizeof(MIXERCONTROLA));
801
802 switch(dwControl) {
803 case MIX_CTRL_VOL_OUT_LINE:
804 case MIX_CTRL_VOL_IN_L_MONO:
805 case MIX_CTRL_VOL_IN_L_PHONE:
806 case MIX_CTRL_VOL_IN_L_MIC:
807 case MIX_CTRL_VOL_IN_L_LINE:
808 case MIX_CTRL_VOL_IN_L_CD:
809 case MIX_CTRL_VOL_IN_L_SPDIF:
810 case MIX_CTRL_VOL_IN_L_VIDEO:
811 case MIX_CTRL_VOL_IN_L_AUX:
812 case MIX_CTRL_VOL_IN_L_PCM:
813 case MIX_CTRL_VOL_IN_L_WAVETABLE:
814 case MIX_CTRL_VOL_IN_L_MIDI:
815 pctrl->cMultipleItems = 0;
816 pctrl->fdwControl = 0;
817 pctrl->dwControlID = nrControls;
818 pctrl->dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
819 strncpy(pctrl->szShortName, szCtrlName[dwControl][0], sizeof(pctrl->szShortName));
820 strncpy(pctrl->szName, szCtrlName[dwControl][1], sizeof(pctrl->szName));
821 pctrl->Bounds.s.lMinimum = 0;
822 pctrl->Bounds.s.lMaximum = 100;
823 pctrl->Metrics.cSteps = 1;
824 nrControls++;
825 nrLineOutControls++;
826 break;
827
828 case MIX_CTRL_VOL_IN_W_MONO:
829 case MIX_CTRL_VOL_IN_W_PHONE:
830 case MIX_CTRL_VOL_IN_W_MIC:
831 case MIX_CTRL_VOL_IN_W_LINE:
832 case MIX_CTRL_VOL_IN_W_CD:
833 case MIX_CTRL_VOL_IN_W_SPDIF:
834 case MIX_CTRL_VOL_IN_W_VIDEO:
835 case MIX_CTRL_VOL_IN_W_AUX:
836 case MIX_CTRL_VOL_IN_W_PCM:
837 case MIX_CTRL_VOL_IN_W_WAVETABLE:
838 case MIX_CTRL_VOL_IN_W_MIDI:
839 pctrl->cMultipleItems = 0;
840 pctrl->fdwControl = 0;
841 pctrl->dwControlID = nrControls;
842 pctrl->dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
843 strncpy(pctrl->szShortName, szCtrlName[dwControl][0], sizeof(pctrl->szShortName));
844 strncpy(pctrl->szName, szCtrlName[dwControl][1], sizeof(pctrl->szName));
845 pctrl->Bounds.s.lMinimum = 0;
846 pctrl->Bounds.s.lMaximum = 100;
847 pctrl->Metrics.cSteps = 1;
848 nrControls++;
849 nrWaveInControls++;
850 nrWaveInInputs++;
851 break;
852
853 case MIX_CTRL_MUTE_OUT_LINE:
854 case MIX_CTRL_MUTE_IN_L_MONO:
855 case MIX_CTRL_MUTE_IN_L_PHONE:
856 case MIX_CTRL_MUTE_IN_L_MIC:
857 case MIX_CTRL_MUTE_IN_L_LINE:
858 case MIX_CTRL_MUTE_IN_L_CD:
859 case MIX_CTRL_MUTE_IN_L_SPDIF:
860 case MIX_CTRL_MUTE_IN_L_VIDEO:
861 case MIX_CTRL_MUTE_IN_L_AUX:
862 case MIX_CTRL_MUTE_IN_L_PCM:
863 pctrl->cMultipleItems = 0;
864 pctrl->fdwControl = MIXERCONTROL_CONTROLF_UNIFORM;
865 pctrl->dwControlID = nrControls;
866 pctrl->dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE;
867 strncpy(pctrl->szShortName, szCtrlName[dwControl][0], sizeof(pctrl->szShortName));
868 strncpy(pctrl->szName, szCtrlName[dwControl][1], sizeof(pctrl->szName));
869 pctrl->Bounds.s.lMinimum = 0;
870 pctrl->Bounds.s.lMaximum = 1;
871 pctrl->Metrics.cSteps = 0;
872 nrControls++;
873 nrLineOutControls++;
874 break;
875
876 case MIX_CTRL_VOL_OUT_SPDIF:
877 pctrl->cMultipleItems = 0;
878 pctrl->fdwControl = 0;
879 pctrl->dwControlID = nrControls;
880 pctrl->dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
881 strncpy(pctrl->szShortName, szCtrlName[MIX_CTRL_VOL_OUT_SPDIF][0], sizeof(pctrl->szShortName));
882 strncpy(pctrl->szName, szCtrlName[MIX_CTRL_VOL_OUT_SPDIF][1], sizeof(pctrl->szName));
883 pctrl->Bounds.s.lMinimum = 0;
884 pctrl->Bounds.s.lMaximum = 100;
885 pctrl->Metrics.cSteps = 1;
886 nrControls++;
887 nrSPDIFControls++;
888 break;
889
890 case MIX_CTRL_MUTE_OUT_SPDIF:
891 pctrl->cMultipleItems = 0;
892 pctrl->fdwControl = MIXERCONTROL_CONTROLF_UNIFORM;
893 pctrl->dwControlID = nrControls;
894 pctrl->dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE;
895 strncpy(pctrl->szShortName, szCtrlName[MIX_CTRL_MUTE_OUT_SPDIF][0], sizeof(pctrl->szShortName));
896 strncpy(pctrl->szName, szCtrlName[MIX_CTRL_MUTE_OUT_SPDIF][1], sizeof(pctrl->szName));
897 pctrl->Bounds.s.lMinimum = 0;
898 pctrl->Bounds.s.lMaximum = 1;
899 pctrl->Metrics.cSteps = 0;
900 nrControls++;
901 nrSPDIFControls++;
902 break;
903
904 case MIX_CTRL_BOOST_IN_L_MIC:
905 pctrl->cMultipleItems = 0;
906 pctrl->fdwControl = MIXERCONTROL_CONTROLF_UNIFORM;
907 pctrl->dwControlID = nrControls;
908 pctrl->dwControlType = MIXERCONTROL_CONTROLTYPE_ONOFF;
909 strncpy(pctrl->szShortName, szCtrlName[MIX_CTRL_BOOST_IN_L_MIC][0], sizeof(pctrl->szShortName));
910 strncpy(pctrl->szName, szCtrlName[MIX_CTRL_BOOST_IN_L_MIC][1], sizeof(pctrl->szName));
911 pctrl->Bounds.s.lMinimum = 0;
912 pctrl->Bounds.s.lMaximum = 1;
913 pctrl->Metrics.cSteps = 0;
914 nrControls++;
915 nrLineOutControls++;
916 break;
917
918 case MIX_CTRL_OUT_L_3DDEPTH:
919 pctrl->cMultipleItems = 0;
920 pctrl->fdwControl = MIXERCONTROL_CONTROLF_UNIFORM;
921 pctrl->dwControlID = nrControls;
922 pctrl->dwControlType = MIXERCONTROL_CONTROLTYPE_FADER;
923 strncpy(pctrl->szShortName, szCtrlName[MIX_CTRL_OUT_L_3DDEPTH][0], sizeof(pctrl->szShortName));
924 strncpy(pctrl->szName, szCtrlName[MIX_CTRL_OUT_L_3DDEPTH][1], sizeof(pctrl->szName));
925 pctrl->Bounds.s.lMinimum = 0;
926 pctrl->Bounds.s.lMaximum = 100;
927 pctrl->Metrics.cSteps = 1;
928 nrControls++;
929 nrLineOutControls++;
930 break;
931
932 case MIX_CTRL_OUT_L_3DCENTER:
933 pctrl->cMultipleItems = 0;
934 pctrl->fdwControl = MIXERCONTROL_CONTROLF_UNIFORM;
935 pctrl->dwControlID = nrControls;
936 pctrl->dwControlType = MIXERCONTROL_CONTROLTYPE_FADER;
937 strncpy(pctrl->szShortName, szCtrlName[MIX_CTRL_OUT_L_3DCENTER][0], sizeof(pctrl->szShortName));
938 strncpy(pctrl->szName, szCtrlName[MIX_CTRL_OUT_L_3DCENTER][1], sizeof(pctrl->szName));
939 pctrl->Bounds.s.lMinimum = 0;
940 pctrl->Bounds.s.lMaximum = 100;
941 pctrl->Metrics.cSteps = 1;
942 nrControls++;
943 nrLineOutControls++;
944 break;
945
946 case MIX_CTRL_MUX_IN_W_SRC:
947 pctrl->cMultipleItems = nrWaveInControls;
948 pctrl->fdwControl = MIXERCONTROL_CONTROLF_MULTIPLE | MIXERCONTROL_CONTROLF_UNIFORM;
949 pctrl->dwControlID = nrControls;
950 pctrl->dwControlType = MIXERCONTROL_CONTROLTYPE_MUX;
951 strncpy(pctrl->szShortName, szCtrlName[MIX_CTRL_MUX_IN_W_SRC][0], sizeof(pctrl->szShortName));
952 strncpy(pctrl->szName, szCtrlName[MIX_CTRL_MUX_IN_W_SRC][1], sizeof(pctrl->szName));
953 pctrl->Bounds.s.lMinimum = 0;
954 pctrl->Bounds.s.lMaximum = 1;
955 pctrl->Metrics.cSteps = 1;
956 nrControls++;
957 nrWaveInControls++;
958 break;
959
960 case MIX_CTRL_OUT_L_TREBLE:
961 pctrl->cMultipleItems = 0;
962 pctrl->fdwControl = 0;
963 pctrl->dwControlID = nrControls;
964 pctrl->dwControlType = MIXERCONTROL_CONTROLTYPE_TREBLE;
965 strncpy(pctrl->szShortName, szCtrlName[MIX_CTRL_OUT_L_TREBLE][0], sizeof(pctrl->szShortName));
966 strncpy(pctrl->szName, szCtrlName[MIX_CTRL_OUT_L_TREBLE][1], sizeof(pctrl->szName));
967 pctrl->Bounds.s.lMinimum = 0;
968 pctrl->Bounds.s.lMaximum = 100;
969 pctrl->Metrics.cSteps = 1;
970 nrControls++;
971 nrLineOutControls++;
972 break;
973
974 case MIX_CTRL_OUT_L_BASS:
975 pctrl->cMultipleItems = 0;
976 pctrl->fdwControl = 0;
977 pctrl->dwControlID = nrControls;
978 pctrl->dwControlType = MIXERCONTROL_CONTROLTYPE_BASS;
979 strncpy(pctrl->szShortName, szCtrlName[MIX_CTRL_OUT_L_BASS][0], sizeof(pctrl->szShortName));
980 strncpy(pctrl->szName, szCtrlName[MIX_CTRL_OUT_L_BASS][1], sizeof(pctrl->szName));
981 pctrl->Bounds.s.lMinimum = 0;
982 pctrl->Bounds.s.lMaximum = 100;
983 pctrl->Metrics.cSteps = 1;
984 nrControls++;
985 nrLineOutControls++;
986 break;
987
988 default:
989 DebugInt3();
990 return FALSE;
991 }
992 dprintf(("Adding control %s (%s)", pctrl->szName, pctrl->szShortName));
993 return TRUE;
994}
995/******************************************************************************/
996/******************************************************************************/
997
Note: See TracBrowser for help on using the repository browser.