From 182ac7e012b5bcda1416e5edac4e2dff83cf6cbd Mon Sep 17 00:00:00 2001 From: aymeric <aymeric@3f6dc0c8-ddfe-455d-9043-3cd528dc4637> Date: Tue, 28 Apr 2009 14:35:25 +0000 Subject: [PATCH] Add mute/unmute support in mediastreamer2 and winsnd2 filter git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@445 3f6dc0c8-ddfe-455d-9043-3cd528dc4637 --- .../build/win32-novideo/mediastreamer2.def | 2 + .../build/win32native/mediastreamer2.def | 2 + .../include/mediastreamer2/mssndcard.h | 52 ++- linphone/mediastreamer2/src/mssndcard.c | 21 +- linphone/mediastreamer2/src/winsnd2.c | 323 +++++++++++++----- 5 files changed, 314 insertions(+), 86 deletions(-) diff --git a/linphone/mediastreamer2/build/win32-novideo/mediastreamer2.def b/linphone/mediastreamer2/build/win32-novideo/mediastreamer2.def index 89f7c3797f..f8c592e131 100755 --- a/linphone/mediastreamer2/build/win32-novideo/mediastreamer2.def +++ b/linphone/mediastreamer2/build/win32-novideo/mediastreamer2.def @@ -40,6 +40,8 @@ EXPORTS ms_snd_card_set_level ms_snd_card_get_level ms_snd_card_set_capture + ms_snd_card_set_control + ms_snd_card_get_control ms_ticker_new ms_ticker_set_name diff --git a/linphone/mediastreamer2/build/win32native/mediastreamer2.def b/linphone/mediastreamer2/build/win32native/mediastreamer2.def index 21693b2174..f880c1bf77 100755 --- a/linphone/mediastreamer2/build/win32native/mediastreamer2.def +++ b/linphone/mediastreamer2/build/win32native/mediastreamer2.def @@ -40,6 +40,8 @@ EXPORTS ms_snd_card_set_level ms_snd_card_get_level ms_snd_card_set_capture + ms_snd_card_set_control + ms_snd_card_get_control ms_ticker_new ms_ticker_set_name diff --git a/linphone/mediastreamer2/include/mediastreamer2/mssndcard.h b/linphone/mediastreamer2/include/mediastreamer2/mssndcard.h index 0561cd12c8..b4aa9f2f76 100644 --- a/linphone/mediastreamer2/include/mediastreamer2/mssndcard.h +++ b/linphone/mediastreamer2/include/mediastreamer2/mssndcard.h @@ -65,6 +65,18 @@ enum _MSSndCardCapture { MS_SND_CARD_LINE }; +/** + * Structure for sound card mixer values. + * @var MSSndCardMixerElem + */ +typedef enum _MSSndCardControlElem MSSndCardControlElem; + +enum _MSSndCardControlElem { + MS_SND_CARD_MASTER_MUTE, + MS_SND_CARD_PLAYBACK_MUTE, + MS_SND_CARD_CAPTURE_MUTE +}; + /** * Structure for sound card capture source values. * @var MSSndCardCapture @@ -79,6 +91,8 @@ typedef void (*MSSndCardUninitFunc)(struct _MSSndCard *obj); typedef void (*MSSndCardSetLevelFunc)(struct _MSSndCard *obj, MSSndCardMixerElem e, int percent); typedef void (*MSSndCardSetCaptureFunc)(struct _MSSndCard *obj, MSSndCardCapture e); typedef int (*MSSndCardGetLevelFunc)(struct _MSSndCard *obj, MSSndCardMixerElem e); +typedef void (*MSSndCardSetControlFunc)(struct _MSSndCard *obj, MSSndCardControlElem e, int val); +typedef int (*MSSndCardGetControlFunc)(struct _MSSndCard *obj, MSSndCardControlElem e); typedef struct _MSFilter * (*MSSndCardCreateReaderFunc)(struct _MSSndCard *obj); typedef struct _MSFilter * (*MSSndCardCreateWriterFunc)(struct _MSSndCard *obj); typedef struct _MSSndCard * (*MSSndCardDuplicateFunc)(struct _MSSndCard *obj); @@ -90,6 +104,8 @@ struct _MSSndCardDesc{ MSSndCardSetLevelFunc set_level; MSSndCardGetLevelFunc get_level; MSSndCardSetCaptureFunc set_capture; + MSSndCardSetControlFunc set_control; + MSSndCardGetControlFunc get_control; MSSndCardCreateReaderFunc create_reader; MSSndCardCreateWriterFunc create_writer; MSSndCardUninitFunc uninit; @@ -342,7 +358,7 @@ void ms_snd_card_set_level(MSSndCard *obj, MSSndCardMixerElem e, int percent); * @param obj A sound card object. * @param e A sound card mixer object. * - * Returns: A int if successfull, 0 otherwise. + * Returns: A int if successfull, <0 otherwise. */ int ms_snd_card_get_level(MSSndCard *obj, MSSndCardMixerElem e); @@ -362,6 +378,40 @@ int ms_snd_card_get_level(MSSndCard *obj, MSSndCardMixerElem e); */ void ms_snd_card_set_capture(MSSndCard *obj, MSSndCardCapture c); +/** + * Set some mixer control. + * + * <PRE> + * MS_SND_CARD_MASTER_MUTE, -> 0: unmute, 1: mute + * MS_SND_CARD_PLAYBACK_MUTE, -> 0: unmute, 1: mute + * MS_SND_CARD_CAPTURE_MUTE -> 0: unmute, 1: mute + * </PRE> + * Note: not implemented on all sound card filters. + * + * @param obj A sound card object. + * @param e A sound card control object. + * @param percent A value for control. + * + */ +void ms_snd_card_set_control(MSSndCard *obj, MSSndCardControlElem e, int val); + +/** + * Get some mixer control. + * + * <PRE> + * MS_SND_CARD_MASTER_MUTE, -> return 0: unmute, 1: mute + * MS_SND_CARD_PLAYBACK_MUTE, -> return 0: unmute, 1: mute + * MS_SND_CARD_CAPTURE_MUTE -> return 0: unmute, 1: mute + * </PRE> + * Note: not implemented on all sound card filters. + * + * @param obj A sound card object. + * @param e A sound card mixer object. + * + * Returns: A int if successfull, <0 otherwise. + */ +int ms_snd_card_get_control(MSSndCard *obj, MSSndCardControlElem e); + /** * Create a alsa card with user supplied pcm name and mixer name. * @param pcmdev The pcm device name following alsa conventions (ex: plughw:0) diff --git a/linphone/mediastreamer2/src/mssndcard.c b/linphone/mediastreamer2/src/mssndcard.c index 2313b85dc4..e8de161430 100644 --- a/linphone/mediastreamer2/src/mssndcard.c +++ b/linphone/mediastreamer2/src/mssndcard.c @@ -156,14 +156,14 @@ const char *ms_snd_card_get_string_id(MSSndCard *obj){ void ms_snd_card_set_level(MSSndCard *obj, MSSndCardMixerElem e, int percent){ if (obj->desc->set_level!=NULL) obj->desc->set_level(obj,e,percent); - else ms_warning("ms_snd_card_set_capture: unimplemented by %s wrapper",obj->desc->driver_type); + else ms_warning("ms_snd_card_set_level: unimplemented by %s wrapper",obj->desc->driver_type); } int ms_snd_card_get_level(MSSndCard *obj, MSSndCardMixerElem e){ if (obj->desc->get_level!=NULL) return obj->desc->get_level(obj,e); else { - ms_warning("ms_snd_card_set_capture: unimplemented by %s wrapper",obj->desc->driver_type); + ms_warning("ms_snd_card_get_level: unimplemented by %s wrapper",obj->desc->driver_type); return -1; } } @@ -174,6 +174,23 @@ void ms_snd_card_set_capture(MSSndCard *obj, MSSndCardCapture c){ else ms_warning("ms_snd_card_set_capture: unimplemented by %s wrapper",obj->desc->driver_type); } +void ms_snd_card_set_control(MSSndCard *obj, MSSndCardControlElem e, int val) +{ + if (obj->desc->set_control!=NULL) + obj->desc->set_control(obj,e,val); + else ms_warning("ms_snd_card_set_control: unimplemented by %s wrapper",obj->desc->driver_type); +} + +int ms_snd_card_get_control(MSSndCard *obj, MSSndCardControlElem e) +{ + if (obj->desc->get_control!=NULL) + return obj->desc->get_control(obj,e); + else { + ms_warning("ms_snd_card_get_control: unimplemented by %s wrapper",obj->desc->driver_type); + return -1; + } +} + struct _MSFilter * ms_snd_card_create_reader(MSSndCard *obj){ if (obj->desc->create_reader!=NULL) return obj->desc->create_reader(obj); diff --git a/linphone/mediastreamer2/src/winsnd2.c b/linphone/mediastreamer2/src/winsnd2.c index 933ebf5fbd..f45973f44d 100755 --- a/linphone/mediastreamer2/src/winsnd2.c +++ b/linphone/mediastreamer2/src/winsnd2.c @@ -76,7 +76,7 @@ static void winsndcard_set_level(MSSndCard *card, MSSndCardMixerElem e, int perc mr = waveOutSetVolume((HWAVEOUT)d->out_devid, dwNewVol); if (mr != MMSYSERR_NOERROR) { - ms_warning("Failed to set master volume. (waveOutSetVolume:0x%i)", mr); + ms_error("winsndcard_set_level: waveOutSetVolume failed. (0x%x)", mr); return; } break; @@ -84,14 +84,14 @@ static void winsndcard_set_level(MSSndCard *card, MSSndCardMixerElem e, int perc mr = mixerGetID( (HMIXEROBJ)d->in_devid, &uMixerID, MIXER_OBJECTF_WAVEIN ); if ( mr != MMSYSERR_NOERROR ) { - ms_error("winsndcard_set_level: mixerGetID failed. mr=%d\n", mr ); + ms_error("winsndcard_set_level: mixerGetID failed. (0x%x)", mr); return; } mr = mixerOpen( (LPHMIXER)&dwMixerHandle, uMixerID, 0L, 0L, 0L ); if ( mr != MMSYSERR_NOERROR ) { mixerClose( (HMIXER)dwMixerHandle ); - ms_error("winsndcard_set_level: Could not open Mixer. mr=%d\n", mr ); + ms_error("winsndcard_set_level: mixerGetLineInfo failed. (0x%x)", mr); return; } memset( &MixerLine, 0, sizeof(MIXERLINE) ); @@ -101,12 +101,12 @@ static void winsndcard_set_level(MSSndCard *card, MSSndCardMixerElem e, int perc if ( mr != MMSYSERR_NOERROR ) { mixerClose( (HMIXER)dwMixerHandle ); - ms_error("winsndcard_set_level: Could not get WaveIn Destination Line for the requested source while enumerating. mr=%d\n", mr ); + ms_error("winsndcard_set_level: mixerGetLineInfo failed. (0x%x)", mr); return; } - ms_message("Name: %s\n", MixerLine.szName); - ms_message("Source Line: %d\n", MixerLine.dwSource); - ms_message("ComponentType: %d\n", MixerLine.dwComponentType); + /* ms_message("Name: %s\n", MixerLine.szName); */ + /* ms_message("Source Line: %d\n", MixerLine.dwSource); */ + /* ms_message("ComponentType: %d\n", MixerLine.dwComponentType); */ for (uLineIndex = 0; uLineIndex < MixerLine.cConnections; uLineIndex++) { @@ -118,16 +118,15 @@ static void winsndcard_set_level(MSSndCard *card, MSSndCardMixerElem e, int perc if ( mr != MMSYSERR_NOERROR ) { mixerClose( (HMIXER)dwMixerHandle ); - ms_error("winsndcard_set_level: Could not get the interated Source Line while enumerating. mr=%d\n", mr ); + ms_error("winsndcard_set_level: mixerGetLineInfo failed. (0x%x)", mr); return; } - else - { - ms_message("Name: %s\n", MixerLine.szName); - ms_message("Source Line: %d\n", MixerLine.dwSource); - ms_message("LineID: %d\n", MixerLine.dwLineID); - ms_message("ComponentType: %d\n", MixerLine.dwComponentType); - } + + /* ms_message("Name: %s\n", MixerLine.szName); */ + /* ms_message("Source Line: %d\n", MixerLine.dwSource); */ + /* ms_message("LineID: %d\n", MixerLine.dwLineID); */ + /* ms_message("ComponentType: %d\n", MixerLine.dwComponentType); */ + memset( &Line, 0, sizeof(MIXERLINE) ); Line.cbStruct = sizeof(MIXERLINE); Line.dwDestination = MixerLine.dwDestination; @@ -136,52 +135,14 @@ static void winsndcard_set_level(MSSndCard *card, MSSndCardMixerElem e, int perc if ( mr != MMSYSERR_NOERROR ) { mixerClose( (HMIXER)dwMixerHandle ); - ms_error("winsndcard_set_level: Could not get the interated Source Line while enumerating. mr=%d\n", mr ); + ms_error("winsndcard_set_level: mixerGetLineInfo failed. (0x%x)", mr); return; } - else - { - ms_message("Name: %s\n", MixerLine.szName); - ms_message("Source Line: %d\n", MixerLine.dwSource); - ms_message("LineID: %d\n", MixerLine.dwLineID); - ms_message("ComponentType: %d\n", MixerLine.dwComponentType); - } - if (MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE == Line.dwComponentType) - { - /* unmute */ - /* Find a mute control, if any, of the microphone line */ - LPMIXERCONTROL pmxctrl = (LPMIXERCONTROL)malloc(sizeof(MIXERCONTROL)); - MIXERLINECONTROLS mxlctrl = {sizeof mxlctrl, Line.dwLineID, MIXERCONTROL_CONTROLTYPE_MUTE, 1, sizeof(MIXERCONTROL), pmxctrl}; - if(!mixerGetLineControls((HMIXEROBJ)dwMixerHandle, &mxlctrl, MIXER_GETLINECONTROLSF_ONEBYTYPE)){ - DWORD cChannels = Line.cChannels; - LPMIXERCONTROLDETAILS_BOOLEAN pbool; - MIXERCONTROLDETAILS mxcd; - - if (MIXERCONTROL_CONTROLF_UNIFORM & pmxctrl->fdwControl) - cChannels = 1; - pbool = (LPMIXERCONTROLDETAILS_BOOLEAN) malloc(cChannels * sizeof( - MIXERCONTROLDETAILS_BOOLEAN)); - - mxcd.cbStruct = sizeof(mxcd); - mxcd.dwControlID = pmxctrl->dwControlID; - mxcd.cChannels = cChannels; - mxcd.hwndOwner = (HWND)0; - mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN); - mxcd.paDetails = (LPVOID) pbool; - - mixerGetControlDetails((HMIXEROBJ)dwMixerHandle, &mxcd, - MIXER_SETCONTROLDETAILSF_VALUE); - /* Unmute the microphone line (for both channels) */ - pbool[0].fValue = pbool[cChannels - 1].fValue = 0; /* 0 -> unmute; */ - mixerSetControlDetails((HMIXEROBJ)dwMixerHandle, &mxcd, - MIXER_SETCONTROLDETAILSF_VALUE); - free(pmxctrl); - free(pbool); - } - else - free(pmxctrl); - } + /* ms_message("Name: %s\n", MixerLine.szName); */ + /* ms_message("Source Line: %d\n", MixerLine.dwSource); */ + /* ms_message("LineID: %d\n", MixerLine.dwLineID); */ + /* ms_message("ComponentType: %d\n", MixerLine.dwComponentType); */ if (MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE == Line.dwComponentType) { @@ -221,7 +182,7 @@ static void winsndcard_set_level(MSSndCard *card, MSSndCardMixerElem e, int perc mixerClose( (HMIXER)dwMixerHandle ); if (mr != MMSYSERR_NOERROR) { - ms_warning("Failed to set capture volume. (mixerClose:0x%i)", mr); + ms_error("winsndcard_set_level: mixerClose failed. (0x%x)", mr); return; } break; @@ -235,14 +196,14 @@ static void winsndcard_set_level(MSSndCard *card, MSSndCardMixerElem e, int perc mr = mixerGetID( (HMIXEROBJ)d->out_devid, &uMixerID, MIXER_OBJECTF_WAVEOUT ); if ( mr != MMSYSERR_NOERROR ) { - ms_error("winsndcard_set_level: mixerGetID failed. mr=%d\n", mr ); + ms_error("winsndcard_set_level: mixerGetID failed. (0x%x)", mr); return; } mr = mixerOpen( (LPHMIXER)&dwMixerHandle, uMixerID, 0L, 0L, 0L ); if ( mr != MMSYSERR_NOERROR ) { mixerClose( (HMIXER)dwMixerHandle ); - ms_error("winsndcard_set_level: Could not open Mixer. mr=%d\n", mr ); + ms_error("winsndcard_set_level: mixerOpen failed. (0x%x)", mr); return; } memset( &MixerLine, 0, sizeof(MIXERLINE) ); @@ -252,12 +213,13 @@ static void winsndcard_set_level(MSSndCard *card, MSSndCardMixerElem e, int perc if ( mr != MMSYSERR_NOERROR ) { mixerClose( (HMIXER)dwMixerHandle ); - ms_error("winsndcard_set_level: Could not get WaveIn Destination Line for the requested source while enumerating. mr=%d\n", mr ); + ms_error("winsndcard_set_level: mixerGetLineInfo failed. (0x%x)", mr); return; } - ms_message("Name: %s\n", MixerLine.szName); - ms_message("Source Line: %d\n", MixerLine.dwSource); - ms_message("ComponentType: %d\n", MixerLine.dwComponentType); + + /* ms_message("Name: %s\n", MixerLine.szName); */ + /* ms_message("Source Line: %d\n", MixerLine.dwSource); */ + /* ms_message("ComponentType: %d\n", MixerLine.dwComponentType); */ mlc.cbStruct = sizeof(MIXERLINECONTROLS); mlc.dwLineID = MixerLine.dwLineID; @@ -282,7 +244,7 @@ static void winsndcard_set_level(MSSndCard *card, MSSndCardMixerElem e, int perc if (mr != MMSYSERR_NOERROR) { - ms_warning("Failed to set playback volume. (waveOutSetVolume:0x%i)", mr); + ms_error("winsndcard_set_level: mixerSetControlDetails failed. (0x%x)", mr); return; } } @@ -340,9 +302,10 @@ static int winsndcard_get_level(MSSndCard *card, MSSndCardMixerElem e){ ms_error("winsndcard_set_level: Could not get WaveIn Destination Line for the requested source while enumerating. mr=%d\n", mr ); return -1; } - ms_message("Name: %s\n", MixerLine.szName); - ms_message("Source Line: %d\n", MixerLine.dwSource); - ms_message("ComponentType: %d\n", MixerLine.dwComponentType); + + /* ms_message("Name: %s\n", MixerLine.szName); */ + /* ms_message("Source Line: %d\n", MixerLine.dwSource); */ + /* ms_message("ComponentType: %d\n", MixerLine.dwComponentType); */ for (uLineIndex = 0; uLineIndex < MixerLine.cConnections; uLineIndex++) { @@ -357,13 +320,12 @@ static int winsndcard_get_level(MSSndCard *card, MSSndCardMixerElem e){ ms_error("winsndcard_set_level: Could not get the interated Source Line while enumerating. mr=%d\n", mr ); return -1; } - else - { - ms_message("Name: %s\n", MixerLine.szName); - ms_message("Source Line: %d\n", MixerLine.dwSource); - ms_message("LineID: %d\n", MixerLine.dwLineID); - ms_message("ComponentType: %d\n", MixerLine.dwComponentType); - } + + /* ms_message("Name: %s\n", MixerLine.szName); */ + /* ms_message("Source Line: %d\n", MixerLine.dwSource); */ + /* ms_message("LineID: %d\n", MixerLine.dwLineID); */ + /* ms_message("ComponentType: %d\n", MixerLine.dwComponentType); */ + memset( &Line, 0, sizeof(MIXERLINE) ); Line.cbStruct = sizeof(MIXERLINE); Line.dwDestination = MixerLine.dwDestination; @@ -375,13 +337,11 @@ static int winsndcard_get_level(MSSndCard *card, MSSndCardMixerElem e){ ms_error("winsndcard_set_level: Could not get the interated Source Line while enumerating. mr=%d\n", mr ); return -1; } - else - { - ms_message("Name: %s\n", MixerLine.szName); - ms_message("Source Line: %d\n", MixerLine.dwSource); - ms_message("LineID: %d\n", MixerLine.dwLineID); - ms_message("ComponentType: %d\n", MixerLine.dwComponentType); - } + + /* ms_message("Name: %s\n", MixerLine.szName); */ + /* ms_message("Source Line: %d\n", MixerLine.dwSource); */ + /* ms_message("LineID: %d\n", MixerLine.dwLineID); */ + /* ms_message("ComponentType: %d\n", MixerLine.dwComponentType); */ if (MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE == Line.dwComponentType) { @@ -440,6 +400,201 @@ static void winsndcard_set_source(MSSndCard *card, MSSndCardCapture source){ } } +static void winsndcard_set_control(MSSndCard *card, MSSndCardControlElem e, int val){ + WinSndCard *d=(WinSndCard*)card->data; + + UINT uMixerID; + DWORD dwMixerHandle; + MIXERLINE MixerLine; + MIXERLINE Line; + UINT uLineIndex; + + MMRESULT mr = MMSYSERR_NOERROR; + + switch(e){ + case MS_SND_CARD_CAPTURE_MUTE: + + mr = mixerGetID( (HMIXEROBJ)d->in_devid, &uMixerID, MIXER_OBJECTF_WAVEIN ); + if ( mr != MMSYSERR_NOERROR ) + { + ms_error("winsndcard_set_control: mixerGetID failed. (0x%x)", mr); + return; + } + mr = mixerOpen( (LPHMIXER)&dwMixerHandle, uMixerID, 0L, 0L, 0L ); + if ( mr != MMSYSERR_NOERROR ) + { + mixerClose( (HMIXER)dwMixerHandle ); + ms_error("winsndcard_set_control: mixerOpen failed. (0x%x)", mr); + return; + } + memset( &MixerLine, 0, sizeof(MIXERLINE) ); + MixerLine.cbStruct = sizeof(MIXERLINE); + MixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN; + mr = mixerGetLineInfo( (HMIXEROBJ)dwMixerHandle, &MixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE ); + if ( mr != MMSYSERR_NOERROR ) + { + mixerClose( (HMIXER)dwMixerHandle ); + ms_error("winsndcard_set_control: mixerGetLineInfo failed. (0x%x)", mr); + return; + } + /* ms_message("Name: %s\n", MixerLine.szName); */ + /* ms_message("Source Line: %d\n", MixerLine.dwSource); */ + /* ms_message("ComponentType: %d\n", MixerLine.dwComponentType); */ + + for (uLineIndex = 0; uLineIndex < MixerLine.cConnections; uLineIndex++) + { + memset( &Line, 0, sizeof(MIXERLINE) ); + Line.cbStruct = sizeof(MIXERLINE); + Line.dwDestination = MixerLine.dwDestination; + Line.dwSource = uLineIndex; + mr = mixerGetLineInfo( (HMIXEROBJ)dwMixerHandle, &Line, MIXER_GETLINEINFOF_LINEID); + if ( mr != MMSYSERR_NOERROR ) + { + mixerClose( (HMIXER)dwMixerHandle ); + ms_error("winsndcard_set_control: mixerGetLineInfo failed. (0x%x)", mr); + return; + } + + /* ms_message("Name: %s\n", MixerLine.szName); */ + /* ms_message("Source Line: %d\n", MixerLine.dwSource); */ + /* ms_message("LineID: %d\n", MixerLine.dwLineID); */ + /* ms_message("ComponentType: %d\n", MixerLine.dwComponentType); */ + + memset( &Line, 0, sizeof(MIXERLINE) ); + Line.cbStruct = sizeof(MIXERLINE); + Line.dwDestination = MixerLine.dwDestination; + Line.dwSource = uLineIndex; + mr = mixerGetLineInfo( (HMIXEROBJ)dwMixerHandle, &Line, MIXER_GETLINEINFOF_SOURCE); + if ( mr != MMSYSERR_NOERROR ) + { + mixerClose( (HMIXER)dwMixerHandle ); + ms_error("winsndcard_set_control: mixerGetLineInfo failed. (0x%x)", mr); + return; + } + + /* ms_message("Name: %s\n", MixerLine.szName); */ + /* ms_message("Source Line: %d\n", MixerLine.dwSource); */ + /* ms_message("LineID: %d\n", MixerLine.dwLineID); */ + /* ms_message("ComponentType: %d\n", MixerLine.dwComponentType); */ + + if (MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE == Line.dwComponentType) + { + /* unmute */ + /* Find a mute control, if any, of the microphone line */ + + LPMIXERCONTROL pmxctrl = (LPMIXERCONTROL)malloc(sizeof(MIXERCONTROL)); + MIXERLINECONTROLS mxlctrl = {sizeof(mxlctrl), Line.dwLineID, MIXERCONTROL_CONTROLTYPE_MUTE, 1, sizeof(MIXERCONTROL), pmxctrl}; + if(!mixerGetLineControls((HMIXEROBJ)dwMixerHandle, &mxlctrl, MIXER_GETLINECONTROLSF_ONEBYTYPE)){ + DWORD cChannels = Line.cChannels; + LPMIXERCONTROLDETAILS_BOOLEAN pbool; + MIXERCONTROLDETAILS mxcd; + + if (MIXERCONTROL_CONTROLF_UNIFORM & pmxctrl->fdwControl) + cChannels = 1; + pbool = (LPMIXERCONTROLDETAILS_BOOLEAN) malloc(cChannels * sizeof( + MIXERCONTROLDETAILS_BOOLEAN)); + + mxcd.cbStruct = sizeof(mxcd); + mxcd.dwControlID = pmxctrl->dwControlID; + mxcd.cChannels = cChannels; + mxcd.hwndOwner = (HWND)0; + mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN); + mxcd.paDetails = (LPVOID) pbool; + + mixerGetControlDetails((HMIXEROBJ)dwMixerHandle, &mxcd, + MIXER_SETCONTROLDETAILSF_VALUE); + /* Unmute the microphone line (for both channels) */ + pbool[0].fValue = pbool[cChannels - 1].fValue = val; /* 0 -> unmute; */ + mixerSetControlDetails((HMIXEROBJ)dwMixerHandle, &mxcd, + MIXER_SETCONTROLDETAILSF_VALUE); + free(pmxctrl); + free(pbool); + } + else + free(pmxctrl); + } + } + mixerClose( (HMIXER)dwMixerHandle ); + if (mr != MMSYSERR_NOERROR) + { + ms_error("winsndcard_set_control: mixerClose failed. (0x%x)", mr); + return; + } + break; + + case MS_SND_CARD_MASTER_MUTE: + case MS_SND_CARD_PLAYBACK_MUTE: + { + MIXERLINECONTROLS mlc = {0}; + MIXERCONTROL mc = {0}; + MIXERCONTROLDETAILS mcd = {0}; + MIXERCONTROLDETAILS_BOOLEAN bMute; + + bMute.fValue = (val>0); + + mr = mixerGetID( (HMIXEROBJ)d->out_devid, &uMixerID, MIXER_OBJECTF_WAVEOUT ); + if ( mr != MMSYSERR_NOERROR ) + { + ms_error("winsndcard_set_control: mixerGetID failed. (0x%x)", mr); + return; + } + mr = mixerOpen( (LPHMIXER)&dwMixerHandle, uMixerID, 0L, 0L, 0L ); + if ( mr != MMSYSERR_NOERROR ) + { + mixerClose( (HMIXER)dwMixerHandle ); + ms_error("winsndcard_set_control: mixerOpen failed. (0x%x)", mr); + return; + } + memset( &MixerLine, 0, sizeof(MIXERLINE) ); + MixerLine.cbStruct = sizeof(MIXERLINE); + MixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; + mr = mixerGetLineInfo( (HMIXEROBJ)dwMixerHandle, &MixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE ); + if ( mr != MMSYSERR_NOERROR ) + { + mixerClose( (HMIXER)dwMixerHandle ); + ms_error("winsndcard_set_control: mixerSetControlDetails failed. (0x%x)", mr); + return; + } + + /* ms_message("Name: %s\n", MixerLine.szName); */ + /* ms_message("Source Line: %d\n", MixerLine.dwSource); */ + /* ms_message("ComponentType: %d\n", MixerLine.dwComponentType); */ + + mlc.cbStruct = sizeof(MIXERLINECONTROLS); + mlc.dwLineID = MixerLine.dwLineID; + mlc.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE; //MIXERCONTROL_CONTROLTYPE_VOLUME; + mlc.cControls = 1; + mlc.pamxctrl = &mc; + mlc.cbmxctrl = sizeof(MIXERCONTROL); + mr = mixerGetLineControls((HMIXEROBJ)dwMixerHandle, + &mlc, MIXER_GETLINECONTROLSF_ONEBYTYPE); + + mcd.cbStruct = sizeof(MIXERCONTROLDETAILS); + mcd.hwndOwner = 0; + mcd.dwControlID = mc.dwControlID; + mcd.paDetails = &bMute; + mcd.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN); + mcd.cChannels = 1; + mr = mixerSetControlDetails((HMIXEROBJ)dwMixerHandle, + &mcd, MIXER_SETCONTROLDETAILSF_VALUE); + + if (mr != MMSYSERR_NOERROR) + { + ms_error("winsndcard_set_control: mixerSetControlDetails failed. (0x%x)", mr); + return; + } + } + break; + default: + ms_warning("winsndcard_set_control: unsupported command."); + } +} + +static int winsndcard_get_control(MSSndCard *card, MSSndCardControlElem e){ + WinSndCard *d=(WinSndCard*)card->data; + return -1; +} + static void winsndcard_init(MSSndCard *card){ WinSndCard *c=(WinSndCard *)ms_new(WinSndCard,1); card->data=c; @@ -459,6 +614,8 @@ MSSndCardDesc winsnd_card_desc={ winsndcard_set_level, winsndcard_get_level, winsndcard_set_source, + winsndcard_set_control, + winsndcard_get_control, ms_winsnd_read_new, ms_winsnd_write_new, winsndcard_uninit, -- GitLab