summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJosep Torra <n770galaxy@gmail.com>2012-09-20 14:16:25 +0200
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2012-10-18 14:03:08 +0200
commit029195399786e6ae44705b7edb7b5c6ade47ce75 (patch)
tree916065cd7757c017023f7ca01d6b3272e7a8528f /sys
parent29334f323302fee2b8f3ab955f9b252af812fa88 (diff)
opensles: rework on the ringbufffer to properly clear segments
Make the segments bigger (1 second) as it seems to be the minimum size we need to not introduce noise. Sink works in my nexus 7 with rates from 8000 to 44100 and some noise can be noticed on higger sample rates.
Diffstat (limited to 'sys')
-rw-r--r--sys/opensles/openslesringbuffer.c63
-rw-r--r--sys/opensles/openslesringbuffer.h6
2 files changed, 39 insertions, 30 deletions
diff --git a/sys/opensles/openslesringbuffer.c b/sys/opensles/openslesringbuffer.c
index 285ed940d..620215314 100644
--- a/sys/opensles/openslesringbuffer.c
+++ b/sys/opensles/openslesringbuffer.c
@@ -126,11 +126,11 @@ _opensles_recorder_cb (SLAndroidSimpleBufferQueueItf bufferQueue, void *context)
}
static gboolean
-_opensles_recorder_acquire (GstRingBuffer * rb, guint nbuffers,
- SLDataFormat_PCM * format)
+_opensles_recorder_acquire (GstRingBuffer * rb, GstRingBufferSpec * spec)
{
GstOpenSLESRingBuffer *thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
SLresult result;
+ SLDataFormat_PCM format;
/* Configure audio source */
SLDataLocator_IODevice loc_dev =
@@ -141,12 +141,16 @@ _opensles_recorder_acquire (GstRingBuffer * rb, guint nbuffers,
/* Configure audio sink */
SLDataLocator_AndroidSimpleBufferQueue loc_bq =
- { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, nbuffers };
- SLDataSink audioSink = { &loc_bq, format };
+ { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2 };
+ SLDataSink audioSink = { &loc_bq, &format };
/* Create audio recorder (requires the RECORD_AUDIO permission) */
const SLInterfaceID id[1] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE };
const SLboolean req[1] = { SL_BOOLEAN_TRUE };
+
+ /* Define the format in OpenSL ES terms */
+ _opensles_format (spec, &format);
+
result = (*thiz->engineEngine)->CreateAudioRecorder (thiz->engineEngine,
&thiz->recorderObject, &audioSrc, &audioSink, 1, id, req);
if (result != SL_RESULT_SUCCESS) {
@@ -192,6 +196,10 @@ _opensles_recorder_acquire (GstRingBuffer * rb, guint nbuffers,
goto failed;
}
+ /* Define our ringbuffer in terms of number of buffers and buffer size. */
+ spec->segsize = (spec->rate * spec->bytes_per_sample) >> 1;
+ spec->segtotal = 3;
+
return TRUE;
failed:
@@ -279,27 +287,29 @@ _opensles_player_cb (SLAndroidSimpleBufferQueueItf bufferQueue, void *context)
return;
}
- if (thiz->last_readseg >= 0) {
- GST_LOG_OBJECT (thiz, "clear segment %d", thiz->last_readseg);
+ if (G_UNLIKELY (thiz->last_clearseg < 0)) {
+ thiz->last_clearseg++;
+ } else {
+ GST_LOG_OBJECT (thiz, "clear segment %d", thiz->last_clearseg);
/* Clear written samples */
- gst_ring_buffer_clear (rb, thiz->last_readseg);
+ gst_ring_buffer_clear (rb, thiz->last_clearseg);
+ thiz->last_clearseg = (thiz->last_clearseg + 1) % rb->spec.segtotal;
/* We wrote one segment */
}
gst_ring_buffer_advance (rb, 1);
- thiz->last_readseg = readseg;
}
static gboolean
-_opensles_player_acquire (GstRingBuffer * rb, guint nbuffers,
- SLDataFormat_PCM * format)
+_opensles_player_acquire (GstRingBuffer * rb, GstRingBufferSpec * spec)
{
GstOpenSLESRingBuffer *thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
SLresult result;
+ SLDataFormat_PCM format;
/* Configure audio source */
SLDataLocator_AndroidSimpleBufferQueue loc_bufq =
{ SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2 };
- SLDataSource audioSrc = { &loc_bufq, format };
+ SLDataSource audioSrc = { &loc_bufq, &format };
/* Configure audio sink */
SLDataLocator_OutputMix loc_outmix =
@@ -310,6 +320,9 @@ _opensles_player_acquire (GstRingBuffer * rb, guint nbuffers,
const SLInterfaceID ids[2] = { SL_IID_BUFFERQUEUE, SL_IID_VOLUME };
const SLboolean req[2] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
+ /* Define the format in OpenSL ES terms */
+ _opensles_format (spec, &format);
+
result = (*thiz->engineEngine)->CreateAudioPlayer (thiz->engineEngine,
&thiz->playerObject, &audioSrc, &audioSink, 2, ids, req);
if (result != SL_RESULT_SUCCESS) {
@@ -362,6 +375,15 @@ _opensles_player_acquire (GstRingBuffer * rb, guint nbuffers,
goto failed;
}
+ /* Define our ringbuffer in terms of number of buffers and buffer size. */
+ spec->segsize = (spec->rate * spec->bytes_per_sample);
+ spec->segtotal = 4;
+ /* In the Nexus7 device where I'm testing seems that I need buffers of
+ * min 1 second of audio.
+ * Then here we created 4 segments of a second and a queue of 2 buffers
+ * in order to properly clear the older segment */
+ thiz->last_clearseg = -3;
+
return TRUE;
failed:
@@ -383,9 +405,9 @@ _opensles_player_start (GstRingBuffer * rb)
return FALSE;
}
- /* Enqueue some initial data */
+ /* Fill the queue by enqueing two buffers */
+ _opensles_player_cb (NULL, rb);
_opensles_player_cb (NULL, rb);
-
return TRUE;
}
@@ -542,22 +564,11 @@ static gboolean
gst_opensles_ringbuffer_acquire (GstRingBuffer * rb, GstRingBufferSpec * spec)
{
GstOpenSLESRingBuffer *thiz;
- SLDataFormat_PCM format;
thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
- /* Define ringbuffer in terms of number of buffers and buffer size */
- spec->segsize =
- (spec->latency_time * spec->rate / G_USEC_PER_SEC) *
- spec->bytes_per_sample;
- spec->segtotal = (spec->buffer_time / spec->latency_time) << 4;
- thiz->last_readseg = -1;
-
- /* Define the format in OpenSL ES terms */
- _opensles_format (spec, &format);
-
- /* Instantiate and configure the OpenSL ES devices */
- if (!thiz->acquire (rb, spec->segtotal, &format)) {
+ /* Instantiate and configure the OpenSL ES interfaces */
+ if (!thiz->acquire (rb, spec)) {
return FALSE;
}
diff --git a/sys/opensles/openslesringbuffer.h b/sys/opensles/openslesringbuffer.h
index 6aace0c81..98a56fe41 100644
--- a/sys/opensles/openslesringbuffer.h
+++ b/sys/opensles/openslesringbuffer.h
@@ -52,9 +52,7 @@ typedef enum
RB_MODE_LAST
} RingBufferMode;
-typedef gboolean (*AcquireFunc) (GstRingBuffer * rb, guint nbuffers,
- SLDataFormat_PCM * format);
-
+typedef gboolean (*AcquireFunc) (GstRingBuffer * rb, GstRingBufferSpec * spec);
typedef gboolean (*StateFunc) (GstRingBuffer * rb);
typedef struct _GstOpenSLESRingBuffer GstOpenSLESRingBuffer;
@@ -84,7 +82,7 @@ struct _GstOpenSLESRingBuffer
/* buffer queue */
SLAndroidSimpleBufferQueueItf bufferQueue;
- gint last_readseg;
+ gint last_clearseg;
/* vmethods */
AcquireFunc acquire;