summaryrefslogtreecommitdiff
path: root/modules/opensles
diff options
context:
space:
mode:
authorAlfred E. Heggestad <aeh@db.org>2014-06-29 18:08:27 +0200
committerAlfred E. Heggestad <aeh@db.org>2014-06-29 18:08:27 +0200
commit2e3d6a0ff8b621cd8536796d88e804d4dac3ee2a (patch)
treebe6d7ffe78ded455b66c4411f63784e2597d4343 /modules/opensles
parent0e00a48c79154097bdf26035e0814e8388e4f450 (diff)
opensles: add double-buffering and some tuning
Credits to Francesco Bradascio for the original work.
Diffstat (limited to 'modules/opensles')
-rw-r--r--modules/opensles/opensles.c6
-rw-r--r--modules/opensles/player.c35
-rw-r--r--modules/opensles/recorder.c104
3 files changed, 70 insertions, 75 deletions
diff --git a/modules/opensles/opensles.c b/modules/opensles/opensles.c
index 9da39f0..665288c 100644
--- a/modules/opensles/opensles.c
+++ b/modules/opensles/opensles.c
@@ -20,10 +20,14 @@ static struct ausrc *ausrc;
static int module_init(void)
{
+ SLEngineOption engineOption[] = {
+ { (SLuint32) SL_ENGINEOPTION_THREADSAFE,
+ (SLuint32) SL_BOOLEAN_TRUE },
+ };
SLresult r;
int err;
- r = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
+ r = slCreateEngine(&engineObject, 1, engineOption, 0, NULL, NULL);
if (SL_RESULT_SUCCESS != r)
return ENODEV;
diff --git a/modules/opensles/player.c b/modules/opensles/player.c
index c899750..797ae48 100644
--- a/modules/opensles/player.c
+++ b/modules/opensles/player.c
@@ -10,12 +10,17 @@
#include "opensles.h"
+#define N_PLAY_QUEUE_BUFFERS 2
+#define PTIME 10
+
+
struct auplay_st {
struct auplay *ap; /* inheritance */
- int16_t *sampv;
- size_t sampc;
auplay_write_h *wh;
void *arg;
+ int16_t *sampv[N_PLAY_QUEUE_BUFFERS];
+ size_t sampc;
+ uint8_t bufferId;
SLObjectItf outputMixObject;
SLObjectItf bqPlayerObject;
@@ -34,7 +39,11 @@ static void auplay_destructor(void *arg)
if (st->outputMixObject != NULL)
(*st->outputMixObject)->Destroy(st->outputMixObject);
- mem_deref(st->sampv);
+ st->bufferId = 0;
+ for (int i=0; i<N_PLAY_QUEUE_BUFFERS; i++) {
+ mem_deref(st->sampv[i]);
+ }
+
mem_deref(st->ap);
}
@@ -43,9 +52,12 @@ static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
{
struct auplay_st *st = context;
- st->wh(st->sampv, st->sampc, st->arg);
+ st->wh(st->sampv[st->bufferId], st->sampc, st->arg);
+
+ (*st->BufferQueue)->Enqueue(bq /*st->BufferQueue*/,
+ st->sampv[st->bufferId], st->sampc * 2);
- (*st->BufferQueue)->Enqueue(bq, st->sampv, st->sampc * 2);
+ st->bufferId = ( st->bufferId + 1 ) % N_PLAY_QUEUE_BUFFERS;
}
@@ -148,12 +160,15 @@ int opensles_player_alloc(struct auplay_st **stp, struct auplay *ap,
st->wh = wh;
st->arg = arg;
- st->sampc = prm->srate * prm->ch * prm->ptime / 1000;
+ st->sampc = prm->srate * prm->ch * PTIME / 1000;
- st->sampv = mem_alloc(2 * st->sampc, NULL);
- if (!st->sampv) {
- err = ENOMEM;
- goto out;
+ st->bufferId = 0;
+ for (int i=0; i<N_PLAY_QUEUE_BUFFERS; i++) {
+ st->sampv[i] = mem_zalloc(2 * st->sampc, NULL);
+ if (!st->sampv[i]) {
+ err = ENOMEM;
+ goto out;
+ }
}
err = createOutput(st);
diff --git a/modules/opensles/recorder.c b/modules/opensles/recorder.c
index 6706428..48af5c0 100644
--- a/modules/opensles/recorder.c
+++ b/modules/opensles/recorder.c
@@ -5,19 +5,22 @@
*/
#include <re.h>
#include <baresip.h>
-#include <pthread.h>
+#include <string.h>
#include <SLES/OpenSLES.h>
#include "SLES/OpenSLES_Android.h"
#include "opensles.h"
+#define N_REC_QUEUE_BUFFERS 2
+#define PTIME 10
+
+
struct ausrc_st {
struct ausrc *as; /* inheritance */
- int16_t *sampv;
- size_t sampc;
- uint32_t ptime;
- pthread_t thread;
- bool run;
+
+ int16_t *sampv[N_REC_QUEUE_BUFFERS];
+ size_t sampc;
+ uint8_t bufferId;
ausrc_read_h *rh;
void *arg;
@@ -31,60 +34,39 @@ static void ausrc_destructor(void *arg)
{
struct ausrc_st *st = arg;
- if (st->run) {
- st->run = false;
- pthread_join(st->thread, NULL);
- }
-
- if (st->recObject != NULL)
- (*st->recObject)->Destroy(st->recObject);
-
- mem_deref(st->sampv);
- mem_deref(st->as);
-}
-
-
-static void *record_thread(void *arg)
-{
- uint64_t now, ts = tmr_jiffies();
- struct ausrc_st *st = arg;
- SLresult r;
-
- while (st->run) {
-
- (void)sys_usleep(4000);
-
- now = tmr_jiffies();
+ if (st->recObject != NULL) {
+ SLuint32 state;
- if (ts > now)
- continue;
-#if 1
- if (now > ts + 100) {
- debug("opensles: cpu lagging behind (%u ms)\n",
- now - ts);
- }
-#endif
-
- r = (*st->recBufferQueue)->Enqueue(st->recBufferQueue,
- st->sampv,
- st->sampc * 2);
- if (r != SL_RESULT_SUCCESS) {
- warning("opensles: Enqueue: r = %d\n", r);
+ if (SL_OBJECT_STATE_UNREALIZED !=
+ (*st->recObject)->GetState(st->recObject,&state)) {
+ (*st->recObject)->Destroy(st->recObject);
}
+ }
- ts += st->ptime;
+ st->bufferId = 0;
+ for (int i=0; i<N_REC_QUEUE_BUFFERS; i++) {
+ mem_deref(st->sampv[i]);
}
- return NULL;
+ mem_deref(st->as);
}
static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
{
struct ausrc_st *st = context;
+
(void)bq;
- st->rh(st->sampv, st->sampc, st->arg);
+ st->rh(st->sampv[st->bufferId], st->sampc, st->arg);
+
+ st->bufferId = ( st->bufferId + 1 ) % N_REC_QUEUE_BUFFERS;
+
+ memset(st->sampv[st->bufferId], 0, st->sampc * 2);
+
+ (*st->recBufferQueue)->Enqueue(st->recBufferQueue,
+ st->sampv[st->bufferId],
+ st->sampc * 2);
}
@@ -152,12 +134,12 @@ static int startRecording(struct ausrc_st *st)
SL_RECORDSTATE_STOPPED);
(*st->recBufferQueue)->Clear(st->recBufferQueue);
-#if 0
+ st->bufferId = 0;
r = (*st->recBufferQueue)->Enqueue(st->recBufferQueue,
- st->buf, sizeof(st->buf));
+ st->sampv[st->bufferId],
+ st->sampc * 2);
if (SL_RESULT_SUCCESS != r)
return ENODEV;
-#endif
r = (*st->recRecord)->SetRecordState(st->recRecord,
SL_RECORDSTATE_RECORDING);
@@ -189,13 +171,15 @@ int opensles_recorder_alloc(struct ausrc_st **stp, struct ausrc *as,
st->as = mem_ref(as);
st->rh = rh;
st->arg = arg;
- st->ptime = prm->ptime;
- st->sampc = prm->srate * prm->ch * prm->ptime / 1000;
- st->sampv = mem_alloc(2 * st->sampc, NULL);
- if (!st->sampv) {
- err = ENOMEM;
- goto out;
+ st->sampc = prm->srate * prm->ch * PTIME / 1000;
+ st->bufferId = 0;
+ for (int i=0; i<N_REC_QUEUE_BUFFERS; i++) {
+ st->sampv[i] = mem_zalloc(2 * st->sampc, NULL);
+ if (!st->sampv[i]) {
+ err = ENOMEM;
+ goto out;
+ }
}
err = createAudioRecorder(st, prm);
@@ -208,14 +192,6 @@ int opensles_recorder_alloc(struct ausrc_st **stp, struct ausrc *as,
goto out;
}
- st->run = true;
-
- err = pthread_create(&st->thread, NULL, record_thread, st);
- if (err) {
- st->run = false;
- goto out;
- }
-
out:
if (err)