summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/directsound/gstdirectsoundsink.c197
-rw-r--r--sys/directsound/gstdirectsoundsink.h14
-rw-r--r--win32/vs6/libgstdirectsound.dsp4
3 files changed, 135 insertions, 80 deletions
diff --git a/sys/directsound/gstdirectsoundsink.c b/sys/directsound/gstdirectsoundsink.c
index e0b262ed..97127bdb 100644
--- a/sys/directsound/gstdirectsoundsink.c
+++ b/sys/directsound/gstdirectsoundsink.c
@@ -76,13 +76,8 @@ static void gst_directsound_sink_class_init (GstDirectSoundSinkClass * klass);
static void gst_directsound_sink_init (GstDirectSoundSink * dsoundsink,
GstDirectSoundSinkClass * g_class);
static void gst_directsound_sink_finalise (GObject * object);
-static void gst_directsound_sink_set_property (GObject * object,
- guint prop_id, const GValue * value, GParamSpec * pspec);
-static void gst_directsound_sink_get_property (GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec);
static GstCaps *gst_directsound_sink_getcaps (GstBaseSink * bsink);
-
static gboolean gst_directsound_sink_prepare (GstAudioSink * asink,
GstRingBufferSpec * spec);
static gboolean gst_directsound_sink_unprepare (GstAudioSink * asink);
@@ -94,6 +89,12 @@ static guint gst_directsound_sink_write (GstAudioSink * asink, gpointer data,
static guint gst_directsound_sink_delay (GstAudioSink * asink);
static void gst_directsound_sink_reset (GstAudioSink * asink);
+/* interfaces */
+static void gst_directsound_sink_interfaces_init (GType type);
+static void
+gst_directsound_sink_implements_interface_init (GstImplementsInterfaceClass *
+ iface);
+static void gst_directsound_sink_mixer_interface_init (GstMixerClass * iface);
static GstStaticPadTemplate directsoundsink_sink_factory =
GST_STATIC_PAD_TEMPLATE ("sink",
@@ -110,22 +111,108 @@ static GstStaticPadTemplate directsoundsink_sink_factory =
"depth = (int) 8, "
"rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]"));
-enum
+GST_BOILERPLATE_FULL (GstDirectSoundSink, gst_directsound_sink, GstAudioSink,
+ GST_TYPE_AUDIO_SINK, gst_directsound_sink_interfaces_init);
+
+/* interfaces stuff */
+static void
+gst_directsound_sink_interfaces_init (GType type)
+{
+ static const GInterfaceInfo implements_interface_info = {
+ (GInterfaceInitFunc) gst_directsound_sink_implements_interface_init,
+ NULL,
+ NULL,
+ };
+
+ static const GInterfaceInfo mixer_interface_info = {
+ (GInterfaceInitFunc) gst_directsound_sink_mixer_interface_init,
+ NULL,
+ NULL,
+ };
+
+ g_type_add_interface_static (type,
+ GST_TYPE_IMPLEMENTS_INTERFACE, &implements_interface_info);
+ g_type_add_interface_static (type, GST_TYPE_MIXER, &mixer_interface_info);
+}
+
+static gboolean
+gst_directsound_sink_interface_supported (GstImplementsInterface * iface,
+ GType iface_type)
{
- PROP_0,
- PROP_ATTENUATION
-};
+ g_return_val_if_fail (iface_type == GST_TYPE_MIXER, FALSE);
+
+ /* for the sake of this example, we'll always support it. However, normally,
+ * you would check whether the device you've opened supports mixers. */
+ return TRUE;
+}
static void
-_do_init (GType directsoundsink_type)
+gst_directsound_sink_implements_interface_init (GstImplementsInterfaceClass *
+ iface)
{
- GST_DEBUG_CATEGORY_INIT (directsoundsink_debug, "directsoundsink", 0,
- "DirectSound sink");
+ iface->supported = gst_directsound_sink_interface_supported;
}
-GST_BOILERPLATE_FULL (GstDirectSoundSink, gst_directsound_sink, GstAudioSink,
- GST_TYPE_AUDIO_SINK, _do_init);
+/*
+ * This function returns the list of support tracks (inputs, outputs)
+ * on this element instance. Elements usually build this list during
+ * _init () or when going from NULL to READY.
+ */
+
+static const GList *
+gst_directsound_sink_mixer_list_tracks (GstMixer * mixer)
+{
+ GstDirectSoundSink *dsoundsink = GST_DIRECTSOUND_SINK (mixer);
+ return dsoundsink->tracks;
+}
+
+/*
+ * Set volume. volumes is an array of size track->num_channels, and
+ * each value in the array gives the wanted volume for one channel
+ * on the track.
+ */
+
+static void
+gst_directsound_sink_mixer_set_volume (GstMixer * mixer,
+ GstMixerTrack * track, gint * volumes)
+{
+ GstDirectSoundSink *dsoundsink = GST_DIRECTSOUND_SINK (mixer);
+
+ if (volumes[0] != dsoundsink->volume) {
+ dsoundsink->volume = volumes[0];
+
+ if (dsoundsink->pDSBSecondary) {
+ /* DirectSound is using attenuation in the following range
+ * (DSBVOLUME_MIN=-10000, DSBVOLUME_MAX=0) */
+ glong ds_attenuation = DSBVOLUME_MIN + (dsoundsink->volume * 100);
+
+ IDirectSoundBuffer_SetVolume (dsoundsink->pDSBSecondary, ds_attenuation);
+ }
+ }
+}
+
+static void
+gst_directsound_sink_mixer_get_volume (GstMixer * mixer,
+ GstMixerTrack * track, gint * volumes)
+{
+ GstDirectSoundSink *dsoundsink = GST_DIRECTSOUND_SINK (mixer);
+
+ volumes[0] = dsoundsink->volume;
+}
+
+static void
+gst_directsound_sink_mixer_interface_init (GstMixerClass * iface)
+{
+ /* the mixer interface requires a definition of the mixer type:
+ * hardware or software? */
+ GST_MIXER_TYPE (iface) = GST_MIXER_SOFTWARE;
+
+ /* virtual function pointers */
+ iface->list_tracks = gst_directsound_sink_mixer_list_tracks;
+ iface->set_volume = gst_directsound_sink_mixer_set_volume;
+ iface->get_volume = gst_directsound_sink_mixer_get_volume;
+}
static void
gst_directsound_sink_finalise (GObject * object)
@@ -134,6 +221,12 @@ gst_directsound_sink_finalise (GObject * object)
g_mutex_free (dsoundsink->dsound_lock);
+ if (dsoundsink->tracks) {
+ g_list_foreach (dsoundsink->tracks, (GFunc) g_object_unref, NULL);
+ g_list_free (dsoundsink->tracks);
+ dsoundsink->tracks = NULL;
+ }
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -162,13 +255,12 @@ gst_directsound_sink_class_init (GstDirectSoundSinkClass * klass)
gstbaseaudiosink_class = (GstBaseAudioSinkClass *) klass;
gstaudiosink_class = (GstAudioSinkClass *) klass;
+ GST_DEBUG_CATEGORY_INIT (directsoundsink_debug, "directsoundsink", 0,
+ "DirectSound sink");
+
parent_class = g_type_class_peek_parent (klass);
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_directsound_sink_finalise);
- gobject_class->get_property =
- GST_DEBUG_FUNCPTR (gst_directsound_sink_get_property);
- gobject_class->set_property =
- GST_DEBUG_FUNCPTR (gst_directsound_sink_set_property);
gstbasesink_class->get_caps =
GST_DEBUG_FUNCPTR (gst_directsound_sink_getcaps);
@@ -182,69 +274,28 @@ gst_directsound_sink_class_init (GstDirectSoundSinkClass * klass)
gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_directsound_sink_write);
gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_directsound_sink_delay);
gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_directsound_sink_reset);
-
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_ATTENUATION,
- g_param_spec_long ("attenuation", "Attenuation of the sound",
- "The attenuation for the directsound buffer (default is 0 so the directsound buffer will not be attenuated)",
- -10000, 0, 0, G_PARAM_READWRITE));
-}
-
-static void
-gst_directsound_sink_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstDirectSoundSink *dsoundsink;
-
- dsoundsink = GST_DIRECTSOUND_SINK (object);
-
- switch (prop_id) {
- case PROP_ATTENUATION:
- {
- glong attenuation = g_value_get_long (value);
-
- if (attenuation != dsoundsink->attenuation) {
- dsoundsink->attenuation = attenuation;
-
- if (dsoundsink->pDSBSecondary)
- IDirectSoundBuffer_SetVolume (dsoundsink->pDSBSecondary,
- dsoundsink->attenuation);
- }
-
- break;
- }
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_directsound_sink_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstDirectSoundSink *dsoundsink;
-
- dsoundsink = GST_DIRECTSOUND_SINK (object);
-
- switch (prop_id) {
- case PROP_ATTENUATION:
- g_value_set_long (value, dsoundsink->attenuation);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
}
static void
gst_directsound_sink_init (GstDirectSoundSink * dsoundsink,
GstDirectSoundSinkClass * g_class)
{
+ GstMixerTrack *track = NULL;
+
+ dsoundsink->tracks = NULL;
+ track = g_object_new (GST_TYPE_MIXER_TRACK, NULL);
+ track->label = g_strdup ("DSoundTrack");
+ track->num_channels = 2;
+ track->min_volume = 0;
+ track->max_volume = 100;
+ track->flags = GST_MIXER_TRACK_OUTPUT;
+ dsoundsink->tracks = g_list_append (dsoundsink->tracks, track);
+
dsoundsink->pDS = NULL;
dsoundsink->pDSBSecondary = NULL;
dsoundsink->current_circular_offset = 0;
dsoundsink->buffer_size = DSBSIZE_MIN;
- dsoundsink->attenuation = 0;
+ dsoundsink->volume = 100;
dsoundsink->dsound_lock = g_mutex_new ();
dsoundsink->first_buffer_after_reset = FALSE;
}
@@ -335,10 +386,6 @@ gst_directsound_sink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
return FALSE;
}
- if (dsoundsink->attenuation != 0)
- IDirectSoundBuffer_SetVolume (dsoundsink->pDSBSecondary,
- dsoundsink->attenuation);
-
return TRUE;
}
diff --git a/sys/directsound/gstdirectsoundsink.h b/sys/directsound/gstdirectsoundsink.h
index ea7ccbdf..6acf92b4 100644
--- a/sys/directsound/gstdirectsoundsink.h
+++ b/sys/directsound/gstdirectsoundsink.h
@@ -30,6 +30,7 @@
#include <gst/gst.h>
#include <gst/audio/gstaudiosink.h>
+#include <gst/interfaces/mixer.h>
#include <windows.h>
#include <dxerr9.h>
@@ -51,20 +52,27 @@ struct _GstDirectSoundSink
{
GstAudioSink sink;
+ /* directsound object interface pointer */
LPDIRECTSOUND pDS;
+ /* directsound sound object interface pointer */
LPDIRECTSOUNDBUFFER pDSBSecondary;
- /*DirectSound buffer size */
+ /* directSound buffer size */
guint buffer_size;
- /*Offset of the circular buffer where we must write next */
+ /* offset of the circular buffer where we must write next */
guint current_circular_offset;
guint bytes_per_sample;
- glong attenuation;
+ /* current volume setup by mixer interface */
+ glong volume;
+ /* tracks list of our mixer interface implementation */
+ GList *tracks;
+
+ /* lock used to protect writes and resets */
GMutex *dsound_lock;
gboolean first_buffer_after_reset;
diff --git a/win32/vs6/libgstdirectsound.dsp b/win32/vs6/libgstdirectsound.dsp
index e763d481..e6c37370 100644
--- a/win32/vs6/libgstdirectsound.dsp
+++ b/win32/vs6/libgstdirectsound.dsp
@@ -53,7 +53,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 glib-2.0.lib gobject-2.0.lib libgstaudio-0.10.lib libgstreamer-0.10.lib libgstbase-0.10.lib dsound.lib dxerr9.lib user32.lib /nologo /dll /machine:I386 /libpath:"../../../gstreamer/win32/vs6/release" /libpath:"../../../gst-plugins-base/win32/vs6/release" /libpath:"./release"
+# ADD LINK32 glib-2.0.lib gobject-2.0.lib libgstaudio-0.10.lib libgstreamer-0.10.lib libgstbase-0.10.lib libgstinterfaces-0.10.lib dsound.lib dxerr9.lib user32.lib /nologo /dll /machine:I386 /libpath:"../../../gstreamer/win32/vs6/release" /libpath:"../../../gst-plugins-base/win32/vs6/release" /libpath:"./release"
# Begin Special Build Tool
TargetPath=.\Release\libgstdirectsound.dll
SOURCE="$(InputPath)"
@@ -84,7 +84,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 glib-2.0D.lib gobject-2.0D.lib libgstaudio-0.10.lib libgstreamer-0.10.lib libgstbase-0.10.lib dsound.lib dxerr9.lib user32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"../../../gstreamer/win32/vs6/debug" /libpath:"../../../gst-plugins-base/win32/vs6/debug" /libpath:"./debug"
+# ADD LINK32 glib-2.0D.lib gobject-2.0D.lib libgstaudio-0.10.lib libgstreamer-0.10.lib libgstbase-0.10.lib libgstinterfaces-0.10.lib dsound.lib dxerr9.lib user32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"../../../gstreamer/win32/vs6/debug" /libpath:"../../../gst-plugins-base/win32/vs6/debug" /libpath:"./debug"
# SUBTRACT LINK32 /incremental:no
# Begin Special Build Tool
TargetPath=.\Debug\libgstdirectsound.dll