mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-19 16:21:17 +00:00
directsoundsrc: Implement volume and mute
Using the MixerAPI as IDirectSoundCaptureBuffer doesn't implement volume control. https://bugzilla.gnome.org/show_bug.cgi?id=744383
This commit is contained in:
parent
4504356dda
commit
1b564bfb8b
4 changed files with 279 additions and 5 deletions
|
@ -1397,12 +1397,13 @@ AG_GST_CHECK_FEATURE(DIRECTSOUND, [DirectSound], directsoundsrc, [
|
||||||
save_LIBS="$LIBS"
|
save_LIBS="$LIBS"
|
||||||
CFLAGS="$CFLAGS $DIRECTX_CFLAGS"
|
CFLAGS="$CFLAGS $DIRECTX_CFLAGS"
|
||||||
LDFLAGS="$LDFLAGS $DIRECTX_LDFLAGS"
|
LDFLAGS="$LDFLAGS $DIRECTX_LDFLAGS"
|
||||||
LIBS="$LIBS -ldsound -ldxerr9 -luser32"
|
LIBS="$LIBS -lwinmm -ldsound -ldxerr9 -luser32"
|
||||||
AC_MSG_CHECKING(for DirectSound LDFLAGS)
|
AC_MSG_CHECKING(for DirectSound LDFLAGS)
|
||||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <dxerr9.h>
|
#include <dxerr9.h>
|
||||||
#include <dsound.h>
|
#include <dsound.h>
|
||||||
|
#include <mmsystem.h>
|
||||||
]], [[
|
]], [[
|
||||||
DXGetErrorString9 (0);
|
DXGetErrorString9 (0);
|
||||||
DirectSoundCreate(NULL, NULL, NULL);
|
DirectSoundCreate(NULL, NULL, NULL);
|
||||||
|
@ -1416,7 +1417,7 @@ AG_GST_CHECK_FEATURE(DIRECTSOUND, [DirectSound], directsoundsrc, [
|
||||||
|
|
||||||
if test "x$HAVE_DIRECTSOUND" = "xyes"; then
|
if test "x$HAVE_DIRECTSOUND" = "xyes"; then
|
||||||
dnl this is much more than we want
|
dnl this is much more than we want
|
||||||
DIRECTSOUND_LIBS="-ldsound -ldxerr9 -luser32"
|
DIRECTSOUND_LIBS="-lwinmm -ldsound -ldxerr9 -luser32"
|
||||||
AC_SUBST(DIRECTX_CFLAGS)
|
AC_SUBST(DIRECTX_CFLAGS)
|
||||||
AC_SUBST(DIRECTX_LDFLAGS)
|
AC_SUBST(DIRECTX_LDFLAGS)
|
||||||
AC_SUBST(DIRECTSOUND_LIBS)
|
AC_SUBST(DIRECTSOUND_LIBS)
|
||||||
|
|
|
@ -5,7 +5,7 @@ libgstdirectsoundsrc_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) \
|
||||||
$(GST_PLUGINS_BASE_CFLAGS) $(DIRECTX_CFLAGS)
|
$(GST_PLUGINS_BASE_CFLAGS) $(DIRECTX_CFLAGS)
|
||||||
libgstdirectsoundsrc_la_LIBADD = \
|
libgstdirectsoundsrc_la_LIBADD = \
|
||||||
$(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_API_VERSION) \
|
$(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_API_VERSION) \
|
||||||
$(DIRECTX_LDFLAGS) -ldsound
|
$(DIRECTX_LDFLAGS) $(DIRECTSOUND_LIBS)
|
||||||
libgstdirectsoundsrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
libgstdirectsoundsrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||||
libgstdirectsoundsrc_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
|
libgstdirectsoundsrc_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
|
||||||
|
|
||||||
|
|
|
@ -73,18 +73,22 @@
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <dsound.h>
|
#include <dsound.h>
|
||||||
|
#include <mmsystem.h>
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (directsoundsrc_debug);
|
GST_DEBUG_CATEGORY_STATIC (directsoundsrc_debug);
|
||||||
#define GST_CAT_DEFAULT directsoundsrc_debug
|
#define GST_CAT_DEFAULT directsoundsrc_debug
|
||||||
|
|
||||||
/* defaults here */
|
/* defaults here */
|
||||||
#define DEFAULT_DEVICE 0
|
#define DEFAULT_DEVICE 0
|
||||||
|
#define DEFAULT_MUTE FALSE
|
||||||
|
|
||||||
/* properties */
|
/* properties */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_DEVICE_NAME
|
PROP_DEVICE_NAME,
|
||||||
|
PROP_VOLUME,
|
||||||
|
PROP_MUTE
|
||||||
};
|
};
|
||||||
|
|
||||||
static HRESULT (WINAPI * pDSoundCaptureCreate) (LPGUID,
|
static HRESULT (WINAPI * pDSoundCaptureCreate) (LPGUID,
|
||||||
|
@ -114,6 +118,18 @@ static void gst_directsound_src_dispose (GObject * object);
|
||||||
|
|
||||||
static guint gst_directsound_src_delay (GstAudioSrc * asrc);
|
static guint gst_directsound_src_delay (GstAudioSrc * asrc);
|
||||||
|
|
||||||
|
static gboolean gst_directsound_src_mixer_find (GstDirectSoundSrc * dsoundsrc,
|
||||||
|
MIXERCAPS * mixer_caps);
|
||||||
|
static void gst_directsound_src_mixer_init (GstDirectSoundSrc * dsoundsrc);
|
||||||
|
|
||||||
|
static gdouble gst_directsound_src_get_volume (GstDirectSoundSrc * dsoundsrc);
|
||||||
|
static void gst_directsound_src_set_volume (GstDirectSoundSrc * dsoundsrc,
|
||||||
|
gdouble volume);
|
||||||
|
|
||||||
|
static gboolean gst_directsound_src_get_mute (GstDirectSoundSrc * dsoundsrc);
|
||||||
|
static void gst_directsound_src_set_mute (GstDirectSoundSrc * dsoundsrc,
|
||||||
|
gboolean mute);
|
||||||
|
|
||||||
static GstStaticPadTemplate directsound_src_src_factory =
|
static GstStaticPadTemplate directsound_src_src_factory =
|
||||||
GST_STATIC_PAD_TEMPLATE ("src",
|
GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_PAD_SRC,
|
GST_PAD_SRC,
|
||||||
|
@ -124,7 +140,9 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
"rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]"));
|
"rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]"));
|
||||||
|
|
||||||
#define gst_directsound_src_parent_class parent_class
|
#define gst_directsound_src_parent_class parent_class
|
||||||
G_DEFINE_TYPE (GstDirectSoundSrc, gst_directsound_src, GST_TYPE_AUDIO_SRC);
|
G_DEFINE_TYPE_WITH_CODE (GstDirectSoundSrc, gst_directsound_src,
|
||||||
|
GST_TYPE_AUDIO_SRC, G_IMPLEMENT_INTERFACE (GST_TYPE_STREAM_VOLUME, NULL)
|
||||||
|
);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_directsound_src_dispose (GObject * object)
|
gst_directsound_src_dispose (GObject * object)
|
||||||
|
@ -193,6 +211,18 @@ gst_directsound_src_class_init (GstDirectSoundSrcClass * klass)
|
||||||
(gobject_class, PROP_DEVICE_NAME,
|
(gobject_class, PROP_DEVICE_NAME,
|
||||||
g_param_spec_string ("device-name", "Device name",
|
g_param_spec_string ("device-name", "Device name",
|
||||||
"Human-readable name of the sound device", NULL, G_PARAM_READWRITE));
|
"Human-readable name of the sound device", NULL, G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
g_object_class_install_property
|
||||||
|
(gobject_class, PROP_VOLUME,
|
||||||
|
g_param_spec_double ("volume", "Volume",
|
||||||
|
"Volume of this stream", 0.0, 1.0, 1.0,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
g_object_class_install_property
|
||||||
|
(gobject_class, PROP_MUTE,
|
||||||
|
g_param_spec_boolean ("mute", "Mute",
|
||||||
|
"Mute state of this stream", DEFAULT_MUTE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
|
@ -222,6 +252,12 @@ gst_directsound_src_set_property (GObject * object, guint prop_id,
|
||||||
src->device_name = g_strdup (g_value_get_string (value));
|
src->device_name = g_strdup (g_value_get_string (value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case PROP_VOLUME:
|
||||||
|
gst_directsound_src_set_volume (src, g_value_get_double (value));
|
||||||
|
break;
|
||||||
|
case PROP_MUTE:
|
||||||
|
gst_directsound_src_set_mute (src, g_value_get_boolean (value));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
@ -241,6 +277,12 @@ gst_directsound_src_get_property (GObject * object, guint prop_id,
|
||||||
case PROP_DEVICE_NAME:
|
case PROP_DEVICE_NAME:
|
||||||
g_value_set_string (value, src->device_name);
|
g_value_set_string (value, src->device_name);
|
||||||
break;
|
break;
|
||||||
|
case PROP_VOLUME:
|
||||||
|
g_value_set_double (value, gst_directsound_src_get_volume (src));
|
||||||
|
break;
|
||||||
|
case PROP_MUTE:
|
||||||
|
g_value_set_boolean (value, gst_directsound_src_get_mute (src));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -260,6 +302,11 @@ gst_directsound_src_init (GstDirectSoundSrc * src)
|
||||||
g_mutex_init (&src->dsound_lock);
|
g_mutex_init (&src->dsound_lock);
|
||||||
src->device_guid = NULL;
|
src->device_guid = NULL;
|
||||||
src->device_name = NULL;
|
src->device_name = NULL;
|
||||||
|
src->mixer = NULL;
|
||||||
|
src->control_id_mute = -1;
|
||||||
|
src->control_id_volume = -1;
|
||||||
|
src->volume = 100;
|
||||||
|
src->mute = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -326,6 +373,7 @@ gst_directsound_src_open (GstAudioSrc * asrc)
|
||||||
goto capture_object;
|
goto capture_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gst_directsound_src_mixer_init (dsoundsrc);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
capture_function:
|
capture_function:
|
||||||
|
@ -374,6 +422,9 @@ gst_directsound_src_close (GstAudioSrc * asrc)
|
||||||
/* Close library */
|
/* Close library */
|
||||||
FreeLibrary (dsoundsrc->DSoundDLL);
|
FreeLibrary (dsoundsrc->DSoundDLL);
|
||||||
|
|
||||||
|
if (dsoundsrc->mixer)
|
||||||
|
mixerClose (dsoundsrc->mixer);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -661,3 +712,215 @@ gst_directsound_src_reset (GstAudioSrc * asrc)
|
||||||
|
|
||||||
GST_DSOUND_UNLOCK (dsoundsrc);
|
GST_DSOUND_UNLOCK (dsoundsrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the PROP_DEVICE_NAME is set, find the mixer related to device;
|
||||||
|
* otherwise we get the default input mixer. */
|
||||||
|
static gboolean
|
||||||
|
gst_directsound_src_mixer_find (GstDirectSoundSrc * dsoundsrc,
|
||||||
|
MIXERCAPS * mixer_caps)
|
||||||
|
{
|
||||||
|
MMRESULT mmres;
|
||||||
|
guint i, num_mixers;
|
||||||
|
|
||||||
|
num_mixers = mixerGetNumDevs ();
|
||||||
|
for (i = 0; i < num_mixers; i++) {
|
||||||
|
mmres = mixerOpen (&dsoundsrc->mixer, i, 0L, 0L,
|
||||||
|
MIXER_OBJECTF_MIXER | MIXER_OBJECTF_WAVEIN);
|
||||||
|
|
||||||
|
if (mmres != MMSYSERR_NOERROR)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
mmres = mixerGetDevCaps ((UINT) dsoundsrc->mixer,
|
||||||
|
mixer_caps, sizeof (MIXERCAPS));
|
||||||
|
|
||||||
|
if (mmres != MMSYSERR_NOERROR) {
|
||||||
|
mixerClose (dsoundsrc->mixer);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get default mixer */
|
||||||
|
if (dsoundsrc->device_name == NULL) {
|
||||||
|
GST_DEBUG ("Got default input mixer: %s", mixer_caps->szPname);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_strstr_len (dsoundsrc->device_name, -1, mixer_caps->szPname) != NULL) {
|
||||||
|
GST_DEBUG ("Got requested input mixer: %s", mixer_caps->szPname);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wrong mixer */
|
||||||
|
mixerClose (dsoundsrc->mixer);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEBUG ("Can't find input mixer");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_directsound_src_mixer_init (GstDirectSoundSrc * dsoundsrc)
|
||||||
|
{
|
||||||
|
gint i, k;
|
||||||
|
gboolean found_mic;
|
||||||
|
MMRESULT mmres;
|
||||||
|
MIXERCAPS mixer_caps;
|
||||||
|
MIXERLINE mixer_line;
|
||||||
|
MIXERLINECONTROLS ml_ctrl;
|
||||||
|
PMIXERCONTROL pamixer_ctrls;
|
||||||
|
|
||||||
|
if (!gst_directsound_src_mixer_find (dsoundsrc, &mixer_caps))
|
||||||
|
goto mixer_init_fail;
|
||||||
|
|
||||||
|
/* Find the MIXERLINE related to MICROPHONE */
|
||||||
|
found_mic = FALSE;
|
||||||
|
for (i = 0; i < mixer_caps.cDestinations && !found_mic; i++) {
|
||||||
|
gint j, num_connections;
|
||||||
|
|
||||||
|
mixer_line.cbStruct = sizeof (mixer_line);
|
||||||
|
mixer_line.dwDestination = i;
|
||||||
|
mmres = mixerGetLineInfo ((HMIXEROBJ) dsoundsrc->mixer,
|
||||||
|
&mixer_line, MIXER_GETLINEINFOF_DESTINATION);
|
||||||
|
|
||||||
|
if (mmres != MMSYSERR_NOERROR)
|
||||||
|
goto mixer_init_fail;
|
||||||
|
|
||||||
|
num_connections = mixer_line.cConnections;
|
||||||
|
for (j = 0; j < num_connections && !found_mic; j++) {
|
||||||
|
mixer_line.cbStruct = sizeof (mixer_line);
|
||||||
|
mixer_line.dwDestination = i;
|
||||||
|
mixer_line.dwSource = j;
|
||||||
|
mmres = mixerGetLineInfo ((HMIXEROBJ) dsoundsrc->mixer,
|
||||||
|
&mixer_line, MIXER_GETLINEINFOF_SOURCE);
|
||||||
|
|
||||||
|
if (mmres != MMSYSERR_NOERROR)
|
||||||
|
goto mixer_init_fail;
|
||||||
|
|
||||||
|
if (mixer_line.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE
|
||||||
|
|| mixer_line.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_LINE)
|
||||||
|
found_mic = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_mic == FALSE) {
|
||||||
|
GST_DEBUG ("Can't find mixer line related to input");
|
||||||
|
goto mixer_init_fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get control associated with microphone audio line */
|
||||||
|
pamixer_ctrls = g_malloc (sizeof (MIXERCONTROL) * mixer_line.cControls);
|
||||||
|
ml_ctrl.cbStruct = sizeof (ml_ctrl);
|
||||||
|
ml_ctrl.dwLineID = mixer_line.dwLineID;
|
||||||
|
ml_ctrl.cControls = mixer_line.cControls;
|
||||||
|
ml_ctrl.cbmxctrl = sizeof (MIXERCONTROL);
|
||||||
|
ml_ctrl.pamxctrl = pamixer_ctrls;
|
||||||
|
mmres = mixerGetLineControls ((HMIXEROBJ) dsoundsrc->mixer,
|
||||||
|
&ml_ctrl, MIXER_GETLINECONTROLSF_ALL);
|
||||||
|
|
||||||
|
/* Find control associated with volume and mute */
|
||||||
|
for (k = 0; k < mixer_line.cControls; k++) {
|
||||||
|
if (strstr (pamixer_ctrls[k].szName, "Volume") != NULL) {
|
||||||
|
dsoundsrc->control_id_volume = pamixer_ctrls[k].dwControlID;
|
||||||
|
dsoundsrc->dw_vol_max = pamixer_ctrls[k].Bounds.dwMaximum;
|
||||||
|
dsoundsrc->dw_vol_min = pamixer_ctrls[k].Bounds.dwMinimum;
|
||||||
|
} else if (strstr (pamixer_ctrls[k].szName, "Mute") != NULL) {
|
||||||
|
dsoundsrc->control_id_mute = pamixer_ctrls[k].dwControlID;
|
||||||
|
} else {
|
||||||
|
GST_DEBUG ("Control not handled: %s", pamixer_ctrls[k].szName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_free (pamixer_ctrls);
|
||||||
|
|
||||||
|
if (dsoundsrc->control_id_volume < 0 && dsoundsrc->control_id_mute < 0)
|
||||||
|
goto mixer_init_fail;
|
||||||
|
|
||||||
|
/* Save cChannels information to properly changes in volume */
|
||||||
|
dsoundsrc->mixerline_cchannels = mixer_line.cChannels;
|
||||||
|
return;
|
||||||
|
|
||||||
|
mixer_init_fail:
|
||||||
|
GST_WARNING ("Failed to get Volume and Mute controls");
|
||||||
|
if (dsoundsrc->mixer != NULL) {
|
||||||
|
mixerClose (dsoundsrc->mixer);
|
||||||
|
dsoundsrc->mixer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gdouble
|
||||||
|
gst_directsound_src_get_volume (GstDirectSoundSrc * dsoundsrc)
|
||||||
|
{
|
||||||
|
return (gdouble) dsoundsrc->volume / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_directsound_src_get_mute (GstDirectSoundSrc * dsoundsrc)
|
||||||
|
{
|
||||||
|
return dsoundsrc->mute;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_directsound_src_set_volume (GstDirectSoundSrc * dsoundsrc, gdouble volume)
|
||||||
|
{
|
||||||
|
MMRESULT mmres;
|
||||||
|
MIXERCONTROLDETAILS details;
|
||||||
|
MIXERCONTROLDETAILS_UNSIGNED details_unsigned;
|
||||||
|
glong dwvolume;
|
||||||
|
|
||||||
|
if (dsoundsrc->mixer == NULL || dsoundsrc->control_id_volume < 0) {
|
||||||
|
GST_WARNING ("mixer not initialized");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dwvolume = volume * dsoundsrc->dw_vol_max;
|
||||||
|
dwvolume = CLAMP (dwvolume, dsoundsrc->dw_vol_min, dsoundsrc->dw_vol_max);
|
||||||
|
|
||||||
|
GST_DEBUG ("max volume %ld | min volume %ld",
|
||||||
|
dsoundsrc->dw_vol_max, dsoundsrc->dw_vol_min);
|
||||||
|
GST_DEBUG ("set volume to %f (%ld)", volume, dwvolume);
|
||||||
|
|
||||||
|
details.cbStruct = sizeof (details);
|
||||||
|
details.dwControlID = dsoundsrc->control_id_volume;
|
||||||
|
details.cChannels = dsoundsrc->mixerline_cchannels;
|
||||||
|
details.cMultipleItems = 0;
|
||||||
|
|
||||||
|
details_unsigned.dwValue = dwvolume;
|
||||||
|
details.cbDetails = sizeof (MIXERCONTROLDETAILS_UNSIGNED);
|
||||||
|
details.paDetails = &details_unsigned;
|
||||||
|
|
||||||
|
mmres = mixerSetControlDetails ((HMIXEROBJ) dsoundsrc->mixer,
|
||||||
|
&details, MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE);
|
||||||
|
|
||||||
|
if (mmres != MMSYSERR_NOERROR)
|
||||||
|
GST_WARNING ("Failed to set volume");
|
||||||
|
else
|
||||||
|
dsoundsrc->volume = volume * 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_directsound_src_set_mute (GstDirectSoundSrc * dsoundsrc, gboolean mute)
|
||||||
|
{
|
||||||
|
MMRESULT mmres;
|
||||||
|
MIXERCONTROLDETAILS details;
|
||||||
|
MIXERCONTROLDETAILS_BOOLEAN details_boolean;
|
||||||
|
|
||||||
|
if (dsoundsrc->mixer == NULL || dsoundsrc->control_id_mute < 0) {
|
||||||
|
GST_WARNING ("mixer not initialized");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
details.cbStruct = sizeof (details);
|
||||||
|
details.dwControlID = dsoundsrc->control_id_mute;
|
||||||
|
details.cChannels = dsoundsrc->mixerline_cchannels;
|
||||||
|
details.cMultipleItems = 0;
|
||||||
|
|
||||||
|
details_boolean.fValue = mute;
|
||||||
|
details.cbDetails = sizeof (MIXERCONTROLDETAILS_BOOLEAN);
|
||||||
|
details.paDetails = &details_boolean;
|
||||||
|
|
||||||
|
mmres = mixerSetControlDetails ((HMIXEROBJ) dsoundsrc->mixer,
|
||||||
|
&details, MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE);
|
||||||
|
|
||||||
|
if (mmres != MMSYSERR_NOERROR)
|
||||||
|
GST_WARNING ("Failed to set mute");
|
||||||
|
else
|
||||||
|
dsoundsrc->mute = mute;
|
||||||
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
#include <gst/audio/gstaudiosrc.h>
|
#include <gst/audio/gstaudiosrc.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <dsound.h>
|
#include <dsound.h>
|
||||||
|
#include <mmsystem.h>
|
||||||
|
|
||||||
/* add here some headers if needed */
|
/* add here some headers if needed */
|
||||||
|
|
||||||
|
@ -91,6 +92,15 @@ struct _GstDirectSoundSrc
|
||||||
guint buffer_time;
|
guint buffer_time;
|
||||||
guint latency_time;
|
guint latency_time;
|
||||||
|
|
||||||
|
HMIXER mixer;
|
||||||
|
DWORD mixerline_cchannels;
|
||||||
|
gint control_id_volume;
|
||||||
|
gint control_id_mute;
|
||||||
|
glong dw_vol_max;
|
||||||
|
glong dw_vol_min;
|
||||||
|
|
||||||
|
glong volume;
|
||||||
|
gboolean mute;
|
||||||
|
|
||||||
GUID *device_guid;
|
GUID *device_guid;
|
||||||
char *device_name;
|
char *device_name;
|
||||||
|
|
Loading…
Reference in a new issue