directsoundsrc: LF and indent

This commit is contained in:
Julien Isorce 2009-08-10 11:36:41 +02:00
parent cb1f2f2294
commit 94ece2054c

237
sys/directsound/gstdirectsoundsrc.c Normal file → Executable file
View file

@ -50,7 +50,7 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* */
#endif
#include <gst/gst.h>
#include <gst/audio/gstbaseaudiosrc.h>
@ -59,11 +59,13 @@
#include <windows.h>
#include <dsound.h>
GST_DEBUG_CATEGORY_STATIC (directsoundsrc_debug);
GST_DEBUG_CATEGORY_STATIC (directsoundsrc_debug);
#define GST_CAT_DEFAULT directsoundsrc_debug
static GstElementDetails gst_directsound_src_details =
GST_ELEMENT_DETAILS ("Audio Source (DIRECTCSOUND)", "Source/Audio",
GST_ELEMENT_DETAILS ("Direct Sound Audio Src",
"Source/Audio",
"Capture from a soundcard via DIRECTSOUND",
"Joni Valtanen <joni.valtanen@movial.fi>");
@ -72,15 +74,23 @@
/* properties */
enum
{ PROP_0, PROP_DEVICE
{
PROP_0,
PROP_DEVICE
};
static HRESULT (WINAPI * pDSoundCaptureCreate) (LPGUID,
LPDIRECTSOUNDCAPTURE *, LPUNKNOWN);
static void gst_directsound_src_finalise (GObject * object);
static void gst_directsound_src_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_directsound_src_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec);
static gboolean gst_directsound_src_open (GstAudioSrc * asrc);
static gboolean gst_directsound_src_close (GstAudioSrc * asrc);
static gboolean gst_directsound_src_prepare (GstAudioSrc * asrc,
@ -88,49 +98,72 @@
static gboolean gst_directsound_src_unprepare (GstAudioSrc * asrc);
static void gst_directsound_src_reset (GstAudioSrc * asrc);
static GstCaps *gst_directsound_src_getcaps (GstBaseSrc * bsrc);
static guint gst_directsound_src_read (GstAudioSrc * asrc, gpointer data,
guint length);
static guint gst_directsound_src_read (GstAudioSrc * asrc,
gpointer data, guint length);
static void gst_directsound_src_dispose (GObject * object);
static void gst_directsound_src_do_init (GType type);
static guint gst_directsound_src_delay (GstAudioSrc * asrc);
static GstStaticPadTemplate directsound_src_src_factory =
GST_STATIC_PAD_TEMPLATE ( "src", GST_PAD_SRC, GST_PAD_ALWAYS,
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/x-raw-int, "
"endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, "
"signed = (boolean) { TRUE, FALSE }, " "width = (int) 16, "
"depth = (int) 16, " "rate = (int) [ 1, MAX ], "
"channels = (int) [ 1, 2 ]; " "audio/x-raw-int, "
"signed = (boolean) { TRUE, FALSE }, " "width = (int) 8, "
"depth = (int) 8, " "rate = (int) [ 1, MAX ], "
"channels = (int) [ 1, 2 ]"));
"signed = (boolean) { TRUE, FALSE }, "
"width = (int) 16, "
"depth = (int) 16, "
"rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]; "
"audio/x-raw-int, "
"signed = (boolean) { TRUE, FALSE }, "
"width = (int) 8, "
"depth = (int) 8, "
"rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]"));
static void
gst_directsound_src_do_init (GType type)
{
GST_DEBUG_CATEGORY_INIT (directsoundsrc_debug, "directsoundsrc", 0,
"DirectSound Src");
} GST_BOILERPLATE_FULL (GstDirectSoundSrc, gst_directsound_src,
GstAudioSrc, GST_TYPE_AUDIO_SRC, gst_directsound_src_do_init);
}
GST_BOILERPLATE_FULL (GstDirectSoundSrc, gst_directsound_src, GstAudioSrc,
GST_TYPE_AUDIO_SRC, gst_directsound_src_do_init);
static void
gst_directsound_src_dispose (GObject * object)
{
G_OBJECT_CLASS (parent_class)->dispose (object);
} static void
}
static void
gst_directsound_src_finalise (GObject * object)
{
GstDirectSoundSrc *dsoundsrc = GST_DIRECTSOUND_SRC (object);
g_mutex_free (dsoundsrc->dsound_lock);
} static void
g_mutex_free (dsoundsrc->dsound_lock);
}
static void
gst_directsound_src_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
GST_DEBUG ("initializing directsoundsrc base\n");
gst_element_class_set_details (element_class, &gst_directsound_src_details);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&directsound_src_src_factory));
}
/* initialize the plugin's class */
static void
gst_directsound_src_class_init (GstDirectSoundSrcClass * klass)
@ -140,20 +173,24 @@ gst_directsound_src_class_init (GstDirectSoundSrcClass * klass)
GstBaseSrcClass *gstbasesrc_class;
GstBaseAudioSrcClass *gstbaseaudiosrc_class;
GstAudioSrcClass *gstaudiosrc_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
gstbasesrc_class = (GstBaseSrcClass *) klass;
gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass;
gstaudiosrc_class = (GstAudioSrcClass *) klass;
GST_DEBUG ("initializing directsoundsrc class\n");
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_directsound_src_finalise);
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_directsound_src_dispose);
gobject_class->get_property =
GST_DEBUG_FUNCPTR (gst_directsound_src_get_property);
gobject_class->set_property =
GST_DEBUG_FUNCPTR (gst_directsound_src_set_property);
gstbasesrc_class->get_caps =
GST_DEBUG_FUNCPTR (gst_directsound_src_getcaps);
gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_directsound_src_getcaps);
gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_directsound_src_open);
gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_directsound_src_close);
gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_directsound_src_read);
@ -162,36 +199,40 @@ gst_directsound_src_class_init (GstDirectSoundSrcClass * klass)
GST_DEBUG_FUNCPTR (gst_directsound_src_unprepare);
gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_directsound_src_delay);
gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_directsound_src_reset);
} static GstCaps *
}
static GstCaps *
gst_directsound_src_getcaps (GstBaseSrc * bsrc)
{
GstDirectSoundSrc *dsoundsrc;
GstCaps *caps = NULL;
GST_DEBUG ("get caps\n");
dsoundsrc = GST_DIRECTSOUND_SRC (bsrc);
caps = gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD
(bsrc)));
return caps;
}
static void
gst_directsound_src_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
// GstDirectSoundSrc *src = GST_DIRECTSOUND_SRC (object);
GST_DEBUG ("set property\n");
switch (prop_id)
{
switch (prop_id) {
#if 0
/* FIXME */
case PROP_DEVICE:
src->device = g_value_get_uint (value);
break;
#endif /* */
#endif
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -202,21 +243,19 @@ gst_directsound_src_set_property (GObject * object, guint prop_id,
gst_directsound_src_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
#if 0
GstDirectSoundSrc *src = GST_DIRECTSOUND_SRC (object);
#endif
#endif /* */
GST_DEBUG ("get property\n");
switch (prop_id) {
switch (prop_id) {
#if 0
/* FIXME */
case PROP_DEVICE:
g_value_set_uint (value, src->device);
break;
#endif /* */
#endif
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -235,13 +274,18 @@ gst_directsound_src_init (GstDirectSoundSrc * src,
{
GST_DEBUG ("initializing directsoundsrc\n");
src->dsound_lock = g_mutex_new ();
} static gboolean
}
static gboolean
gst_directsound_src_open (GstAudioSrc * asrc)
{
GstDirectSoundSrc *dsoundsrc;
HRESULT hRes; /* Result for windows functions */
GST_DEBUG ("initializing directsoundsrc\n");
dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
/* Open dsound.dll */
@ -266,22 +310,29 @@ gst_directsound_src_open (GstAudioSrc * asrc)
if (FAILED (hRes)) {
goto capture_object;
}
return TRUE;
capture_function: {
capture_function:
{
FreeLibrary (dsoundsrc->DSoundDLL);
GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
("Unable to get capturecreate function"), (NULL));
return FALSE;
}
capture_object: {
capture_object:
{
FreeLibrary (dsoundsrc->DSoundDLL);
GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
("Unable to create capture object"), (NULL));
return FALSE;
}
dsound_open: {
dsound_open:
{
DWORD err = GetLastError ();
GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
("Unable to open dsound.dll"), (NULL));
g_print ("0x%x\n", HRESULT_FROM_WIN32 (err));
return FALSE;
}
}
@ -291,7 +342,9 @@ gst_directsound_src_close (GstAudioSrc * asrc)
{
GstDirectSoundSrc *dsoundsrc;
HRESULT hRes; /* Result for windows functions */
GST_DEBUG ("initializing directsoundsrc\n");
dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
/* Release capture handler */
@ -299,18 +352,23 @@ gst_directsound_src_close (GstAudioSrc * asrc)
/* Close library */
FreeLibrary (dsoundsrc->DSoundDLL);
return TRUE;
}
static gboolean
gst_directsound_src_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
{
GstDirectSoundSrc *dsoundsrc;
WAVEFORMATEX wfx; /* Wave format structure */
HRESULT hRes; /* Result for windows functions */
DSCBUFFERDESC descSecondary; /* Capturebuffer decsiption */
int fmt = 0; /* audio format */
dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
GST_DEBUG ("initializing directsoundsrc\n");
/* Define buffer */
@ -319,6 +377,7 @@ gst_directsound_src_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
wfx.nChannels = spec->channels;
wfx.nSamplesPerSec = spec->rate; /* 8000|11025|22050|44100 */
wfx.wBitsPerSample = spec->width; // 8|16;
wfx.nBlockAlign = wfx.nChannels * (wfx.wBitsPerSample / 8);
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
wfx.cbSize = 0; /* This size is allways for PCM-format */
@ -355,18 +414,19 @@ gst_directsound_src_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
descSecondary.lpwfxFormat = &wfx;
/* Create buffer */
hRes =
IDirectSoundCapture_CreateCaptureBuffer (dsoundsrc->pDSC, &descSecondary,
&dsoundsrc->pDSBSecondary, NULL);
hRes = IDirectSoundCapture_CreateCaptureBuffer (dsoundsrc->pDSC,
&descSecondary, &dsoundsrc->pDSBSecondary, NULL);
if (hRes != DS_OK) {
goto capture_buffer;
}
spec->channels = wfx.nChannels;
spec->rate = wfx.nSamplesPerSec;
spec->bytes_per_sample = (spec->width / 8) * spec->channels;
dsoundsrc->bytes_per_sample = spec->bytes_per_sample;
GST_DEBUG ("latency time: %llu - buffer time: %llu", spec->latency_time,
spec->buffer_time);
GST_DEBUG ("latency time: %llu - buffer time: %llu",
spec->latency_time, spec->buffer_time);
/* Buffer-time should be allways more than 2*latency */
if (spec->buffer_time < spec->latency_time * 2) {
@ -377,57 +437,73 @@ gst_directsound_src_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
/* Save the times */
dsoundsrc->buffer_time = spec->buffer_time;
dsoundsrc->latency_time = spec->latency_time;
dsoundsrc->latency_size =
(gint) wfx.nAvgBytesPerSec * dsoundsrc->latency_time / 1000000.0;
spec->segsize =
(guint) (((double) spec->buffer_time / 1000000.0) * wfx.nAvgBytesPerSec);
dsoundsrc->latency_size = (gint) wfx.nAvgBytesPerSec *
dsoundsrc->latency_time / 1000000.0;
spec->segsize = (guint) (((double) spec->buffer_time / 1000000.0) *
wfx.nAvgBytesPerSec);
/* just in case */
if (spec->segsize < 1)
spec->segsize = 1;
spec->segtotal = spec->width * (wfx.nAvgBytesPerSec / spec->segsize);
GST_DEBUG ("bytes/sec: %d, buffer size: %d, segsize: %d, segtotal: %d",
wfx.nAvgBytesPerSec, dsoundsrc->buffer_size, spec->segsize,
spec->segtotal);
wfx.nAvgBytesPerSec,
dsoundsrc->buffer_size, spec->segsize, spec->segtotal);
spec->silence_sample[0] = 0;
spec->silence_sample[1] = 0;
spec->silence_sample[2] = 0;
spec->silence_sample[3] = 0;
if (spec->width != 16 && spec->width != 8)
goto dodgy_width;
/* Not readed anything yet */
dsoundsrc->current_circular_offset = 0;
GST_DEBUG ("GstRingBufferSpec->channels: %d, GstRingBufferSpec->rate: %d, \
GstRingBufferSpec->bytes_per_sample: %d\n\
WAVEFORMATEX.nSamplesPerSec: %ld, WAVEFORMATEX.wBitsPerSample: %d, \
WAVEFORMATEX.nBlockAlign: %d, WAVEFORMATEX.nAvgBytesPerSec: %ld\n", spec->channels, spec->rate, spec->bytes_per_sample, wfx.nSamplesPerSec, wfx.wBitsPerSample, wfx.nBlockAlign, wfx.nAvgBytesPerSec);
return TRUE;
wrong_format: {
wrong_format:
{
GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
("Unable to get format %d", spec->format), (NULL));
return FALSE;
}
capture_buffer: {
capture_buffer:
{
GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
("Unable to create capturebuffer"), (NULL));
return FALSE;
}
dodgy_width: {
dodgy_width:
{
GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
("Unexpected width %d", spec->width), (NULL));
return FALSE;
}
}
static gboolean
gst_directsound_src_unprepare (GstAudioSrc * asrc)
{
GstDirectSoundSrc *dsoundsrc;
HRESULT hRes; /* Result for windows functions */
/* Resets */
GST_DEBUG ("unpreparing directsoundsrc");
dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
/* Stop capturing */
@ -435,9 +511,10 @@ gst_directsound_src_unprepare (GstAudioSrc * asrc)
/* Release buffer */
hRes = IDirectSoundCaptureBuffer_Release (dsoundsrc->pDSBSecondary);
return TRUE;
}
return TRUE;
}
/*
return number of readed bytes */
@ -445,36 +522,39 @@ static guint
gst_directsound_src_read (GstAudioSrc * asrc, gpointer data, guint length)
{
GstDirectSoundSrc *dsoundsrc;
HRESULT hRes; /* Result for windows functions */
DWORD dwCurrentCaptureCursor = 0;
DWORD dwBufferSize = 0;
LPVOID pLockedBuffer1 = NULL;
LPVOID pLockedBuffer2 = NULL;
DWORD dwSizeBuffer1 = 0;
DWORD dwSizeBuffer2 = 0;
DWORD dwStatus = 0;
GST_DEBUG ("reading directsoundsrc\n");
dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
GST_DSOUND_LOCK (dsoundsrc);
/* Get current buffer status */
hRes =
IDirectSoundCaptureBuffer_GetStatus (dsoundsrc->pDSBSecondary,
hRes = IDirectSoundCaptureBuffer_GetStatus (dsoundsrc->pDSBSecondary,
&dwStatus);
/* Starting capturing if not allready */
if (!(dwStatus & DSCBSTATUS_CAPTURING)) {
hRes =
IDirectSoundCaptureBuffer_Start (dsoundsrc->pDSBSecondary,
hRes = IDirectSoundCaptureBuffer_Start (dsoundsrc->pDSBSecondary,
DSCBSTART_LOOPING);
// Sleep (dsoundsrc->latency_time/1000);
GST_DEBUG ("capture started");
}
// calculate_buffersize:
while (length > dwBufferSize) {
Sleep (dsoundsrc->latency_time / 1000);
hRes =
IDirectSoundCaptureBuffer_GetCurrentPosition (dsoundsrc->pDSBSecondary,
&dwCurrentCaptureCursor, NULL);
@ -487,13 +567,15 @@ gst_directsound_src_read (GstAudioSrc * asrc, gpointer data, guint length)
dwBufferSize =
dwCurrentCaptureCursor - dsoundsrc->current_circular_offset;
}
} // while (...
/* Lock the buffer */
hRes =
IDirectSoundCaptureBuffer_Lock (dsoundsrc->pDSBSecondary,
dsoundsrc->current_circular_offset, length, &pLockedBuffer1,
&dwSizeBuffer1, &pLockedBuffer2, &dwSizeBuffer2, 0L);
hRes = IDirectSoundCaptureBuffer_Lock (dsoundsrc->pDSBSecondary,
dsoundsrc->current_circular_offset,
length,
&pLockedBuffer1, &dwSizeBuffer1, &pLockedBuffer2, &dwSizeBuffer2, 0L);
/* Copy buffer data to another buffer */
if (hRes == DS_OK) {
@ -502,16 +584,20 @@ gst_directsound_src_read (GstAudioSrc * asrc, gpointer data, guint length)
/* ...and if something is in another buffer */
if (pLockedBuffer2 != NULL) {
memcpy ((data + dwSizeBuffer1), pLockedBuffer2, dwSizeBuffer2);
memcpy (((guchar *) data + dwSizeBuffer1), pLockedBuffer2, dwSizeBuffer2);
}
dsoundsrc->current_circular_offset += dwSizeBuffer1 + dwSizeBuffer2;
dsoundsrc->current_circular_offset %= dsoundsrc->buffer_size;
IDirectSoundCaptureBuffer_Unlock (dsoundsrc->pDSBSecondary, pLockedBuffer1,
dwSizeBuffer1, pLockedBuffer2, dwSizeBuffer2);
IDirectSoundCaptureBuffer_Unlock (dsoundsrc->pDSBSecondary,
pLockedBuffer1, dwSizeBuffer1, pLockedBuffer2, dwSizeBuffer2);
GST_DSOUND_UNLOCK (dsoundsrc);
/* return length (readed data size in bytes) */
return length;
}
static guint
@ -522,14 +608,15 @@ gst_directsound_src_delay (GstAudioSrc * asrc)
DWORD dwCurrentCaptureCursor;
DWORD dwBytesInQueue = 0;
gint nNbSamplesInQueue = 0;
GST_DEBUG ("Delay\n");
dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
/* evaluate the number of samples in queue in the circular buffer */
hRes =
IDirectSoundCaptureBuffer_GetCurrentPosition (dsoundsrc->pDSBSecondary,
&dwCurrentCaptureCursor, NULL);
/* FIXME: Check is this calculated right */
if (hRes == S_OK) {
if (dwCurrentCaptureCursor < dsoundsrc->current_circular_offset) {
@ -540,8 +627,10 @@ gst_directsound_src_delay (GstAudioSrc * asrc)
dwBytesInQueue =
dwCurrentCaptureCursor - dsoundsrc->current_circular_offset;
}
nNbSamplesInQueue = dwBytesInQueue / dsoundsrc->bytes_per_sample;
}
return nNbSamplesInQueue;
}
@ -551,37 +640,39 @@ gst_directsound_src_reset (GstAudioSrc * asrc)
GstDirectSoundSrc *dsoundsrc;
LPVOID pLockedBuffer = NULL;
DWORD dwSizeBuffer = 0;
GST_DEBUG ("reset directsoundsrc\n");
dsoundsrc = GST_DIRECTSOUND_SRC (asrc);
#if 0
IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary);
#endif
#endif /* */
GST_DSOUND_LOCK (dsoundsrc);
if (dsoundsrc->pDSBSecondary) {
if (dsoundsrc->pDSBSecondary) {
/*stop capturing */
HRESULT hRes =
IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary);
HRESULT hRes = IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary);
/*reset position */
/* hRes = IDirectSoundCaptureBuffer_SetCurrentPosition (dsoundsrc->pDSBSecondary, 0); */
/*reset the buffer */
hRes =
IDirectSoundCaptureBuffer_Lock (dsoundsrc->pDSBSecondary,
hRes = IDirectSoundCaptureBuffer_Lock (dsoundsrc->pDSBSecondary,
dsoundsrc->current_circular_offset, dsoundsrc->buffer_size,
pLockedBuffer, &dwSizeBuffer, NULL, NULL, 0L);
if (SUCCEEDED (hRes)) {
memset (pLockedBuffer, 0, dwSizeBuffer);
hRes =
IDirectSoundCaptureBuffer_Unlock (dsoundsrc->pDSBSecondary,
pLockedBuffer, dwSizeBuffer, NULL, 0);
}
dsoundsrc->current_circular_offset = 0;
}
GST_DSOUND_UNLOCK (dsoundsrc);
}