/* * Test mixer * * Copyright (c) 2004 Robert Reif * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * To Do: * examine and update control details * add interactive tests */ #include #include #include #include #define NONAMELESSSTRUCT #define NONAMELESSUNION #include "wine/test.h" #include "windef.h" #include "winbase.h" #include "winnls.h" #include "mmsystem.h" #include "mmddk.h" #include "winmm_test.h" static const char * line_flags(DWORD fdwLine) { static char flags[100]; BOOL first=TRUE; flags[0]=0; if (fdwLine&MIXERLINE_LINEF_ACTIVE) { strcat(flags,"MIXERLINE_LINEF_ACTIVE"); first=FALSE; } if (fdwLine&MIXERLINE_LINEF_DISCONNECTED) { if (!first) strcat(flags, "|"); strcat(flags,"MIXERLINE_LINEF_DISCONNECTED"); first=FALSE; } if (fdwLine&MIXERLINE_LINEF_SOURCE) { if (!first) strcat(flags, "|"); strcat(flags,"MIXERLINE_LINEF_SOURCE"); } return flags; } static const char * component_type(DWORD dwComponentType) { #define TYPE_TO_STR(x) case x: return #x switch (dwComponentType) { TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_UNDEFINED); TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_DIGITAL); TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_LINE); TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_MONITOR); TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS); TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_HEADPHONES); TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_TELEPHONE); TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_WAVEIN); TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_VOICEIN); TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED); TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_DIGITAL); TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_LINE); TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE); TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER); TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC); TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE); TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER); TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT); TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY); TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_ANALOG); } #undef TYPE_TO_STR return "UNKNOWN"; } static const char * target_type(DWORD dwType) { #define TYPE_TO_STR(x) case x: return #x switch (dwType) { TYPE_TO_STR(MIXERLINE_TARGETTYPE_UNDEFINED); TYPE_TO_STR(MIXERLINE_TARGETTYPE_WAVEOUT); TYPE_TO_STR(MIXERLINE_TARGETTYPE_WAVEIN); TYPE_TO_STR(MIXERLINE_TARGETTYPE_MIDIOUT); TYPE_TO_STR(MIXERLINE_TARGETTYPE_MIDIIN); TYPE_TO_STR(MIXERLINE_TARGETTYPE_AUX); } #undef TYPE_TO_STR return "UNKNOWN"; } static const char * control_type(DWORD dwControlType) { #define TYPE_TO_STR(x) case x: return #x switch (dwControlType) { TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_CUSTOM); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BOOLEANMETER); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SIGNEDMETER); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_PEAKMETER); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BOOLEAN); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_ONOFF); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MUTE); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MONO); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_LOUDNESS); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_STEREOENH); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BASS_BOOST); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BUTTON); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_DECIBELS); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SIGNED); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_UNSIGNED); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_PERCENT); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SLIDER); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_PAN); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_QSOUNDPAN); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_FADER); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_VOLUME); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BASS); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_TREBLE); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_EQUALIZER); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SINGLESELECT); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MUX); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MIXER); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MICROTIME); TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MILLITIME); } #undef TYPE_TO_STR return "UNKNOWN"; } static const char * control_flags(DWORD fdwControl) { static char flags[100]; BOOL first=TRUE; flags[0]=0; if (fdwControl&MIXERCONTROL_CONTROLF_UNIFORM) { strcat(flags,"MIXERCONTROL_CONTROLF_UNIFORM"); first=FALSE; } if (fdwControl&MIXERCONTROL_CONTROLF_MULTIPLE) { if (!first) strcat(flags, "|"); strcat(flags,"MIXERCONTROL_CONTROLF_MULTIPLE"); first=FALSE; } if (fdwControl&MIXERCONTROL_CONTROLF_DISABLED) { if (!first) strcat(flags, "|"); strcat(flags,"MIXERCONTROL_CONTROLF_DISABLED"); } return flags; } void mixer_test_deviceA(int device) { MIXERCAPSA capsA; HMIXER mix; MMRESULT rc; DWORD d,s,ns,nc; rc=mixerGetDevCapsA(device,0,sizeof(capsA)); ok(rc==MMSYSERR_INVALPARAM, "mixerGetDevCapsA: MMSYSERR_INVALPARAM expected, got %s\n", mmsys_error(rc)); rc=mixerGetDevCapsA(device,&capsA,4); ok(rc==MMSYSERR_NOERROR, "mixerGetDevCapsA: MMSYSERR_NOERROR expected, got %s\n", mmsys_error(rc)); rc=mixerGetDevCapsA(device,&capsA,sizeof(capsA)); ok(rc==MMSYSERR_NOERROR, "mixerGetDevCapsA: MMSYSERR_NOERROR expected, got %s\n", mmsys_error(rc)); if (winetest_interactive) { trace(" %d: \"%s\" %d.%d (%d:%d) destinations=%ld\n", device, capsA.szPname, capsA.vDriverVersion >> 8, capsA.vDriverVersion & 0xff,capsA.wMid,capsA.wPid, capsA.cDestinations); } rc=mixerOpen(&mix, device, 0, 0, 0); ok(rc==MMSYSERR_NOERROR, "mixerOpen: MMSYSERR_BADDEVICEID expected, got %s\n",mmsys_error(rc)); if (rc==MMSYSERR_NOERROR) { for (d=0;d> 8, mixerlineA.Target.vDriverVersion & 0xff, mixerlineA.Target.wMid, mixerlineA.Target.wPid); } ns=mixerlineA.cConnections; for(s=0;s> 8, mixerlineA.Target.vDriverVersion & 0xff, mixerlineA.Target.wMid, mixerlineA.Target.wPid); } if (mixerlineA.cControls) { array=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, mixerlineA.cControls*sizeof(MIXERCONTROLA)); if (array) { rc=mixerGetLineControlsA((HMIXEROBJ)mix,0, MIXER_GETLINECONTROLSF_ALL); ok(rc==MMSYSERR_INVALPARAM, "mixerGetLineControlsA(MIXER_GETLINECONTROLSF_ALL): " "MMSYSERR_INVALPARAM expected, got %s\n", mmsys_error(rc)); rc=mixerGetLineControlsA((HMIXEROBJ)mix,&controls,-1); ok(rc==MMSYSERR_INVALFLAG||rc==MMSYSERR_INVALPARAM, "mixerGetLineControlsA(-1): " "MMSYSERR_INVALFLAG or MMSYSERR_INVALPARAM expected, got %s\n", mmsys_error(rc)); controls.cbStruct = sizeof(MIXERLINECONTROLSA); controls.cControls = mixerlineA.cControls; controls.dwLineID = mixerlineA.dwLineID; controls.pamxctrl = array; controls.cbmxctrl = sizeof(MIXERCONTROLA); /* FIXME: do MIXER_GETLINECONTROLSF_ONEBYID * and MIXER_GETLINECONTROLSF_ONEBYTYPE */ rc=mixerGetLineControlsA((HMIXEROBJ)mix,&controls, MIXER_GETLINECONTROLSF_ALL); ok(rc==MMSYSERR_NOERROR, "mixerGetLineControlsA(MIXER_GETLINECONTROLSF_ALL): " "MMSYSERR_NOERROR expected, got %s\n", mmsys_error(rc)); if (rc==MMSYSERR_NOERROR) { for(nc=0;nc> 8, capsW.vDriverVersion & 0xff,capsW.wMid,capsW.wPid, capsW.cDestinations); } rc=mixerOpen(&mix, device, 0, 0, 0); ok(rc==MMSYSERR_NOERROR, "mixerOpen: MMSYSERR_BADDEVICEID expected, got %s\n",mmsys_error(rc)); if (rc==MMSYSERR_NOERROR) { for (d=0;d> 8, mixerlineW.Target.vDriverVersion & 0xff, mixerlineW.Target.wMid, mixerlineW.Target.wPid); } ns=mixerlineW.cConnections; for(s=0;s> 8, mixerlineW.Target.vDriverVersion & 0xff, mixerlineW.Target.wMid, mixerlineW.Target.wPid); } if (mixerlineW.cControls) { array=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, mixerlineW.cControls*sizeof(MIXERCONTROLW)); if (array) { rc=mixerGetLineControlsW((HMIXEROBJ)mix,0, MIXER_GETLINECONTROLSF_ALL); ok(rc==MMSYSERR_INVALPARAM, "mixerGetLineControlsW(MIXER_GETLINECONTROLSF_ALL): " "MMSYSERR_INVALPARAM expected, got %s\n", mmsys_error(rc)); rc=mixerGetLineControlsW((HMIXEROBJ)mix,&controls, -1); ok(rc==MMSYSERR_INVALFLAG||rc==MMSYSERR_INVALPARAM, "mixerGetLineControlsA(-1): " "MMSYSERR_INVALFLAG or MMSYSERR_INVALPARAM expected, got %s\n", mmsys_error(rc)); controls.cbStruct = sizeof(MIXERLINECONTROLSW); controls.cControls = mixerlineW.cControls; controls.dwLineID = mixerlineW.dwLineID; controls.pamxctrl = array; controls.cbmxctrl = sizeof(MIXERCONTROLW); /* FIXME: do MIXER_GETLINECONTROLSF_ONEBYID * and MIXER_GETLINECONTROLSF_ONEBYTYPE */ rc=mixerGetLineControlsW((HMIXEROBJ)mix,&controls, MIXER_GETLINECONTROLSF_ALL); ok(rc==MMSYSERR_NOERROR, "mixerGetLineControlsW(MIXER_GETLINECONTROLSF_ALL): " "MMSYSERR_NOERROR expected, got %s\n", mmsys_error(rc)); if (rc==MMSYSERR_NOERROR) { for(nc=0;nc