Skip to content

Commit

Permalink
MixStream: Add a function to atomically soundtouchify a stream when n…
Browse files Browse the repository at this point in the history
…eeded.
  • Loading branch information
stump committed Dec 26, 2012
1 parent bf50820 commit 116c67e
Showing 1 changed file with 22 additions and 3 deletions.
25 changes: 22 additions & 3 deletions src/MixStreamCore.c
Expand Up @@ -42,11 +42,14 @@ struct _MixStream {
int out_sample_size;
gboolean out_samples_signed;
gboolean byteswap_needed;
GMutex* st_mutex;
};

static GHashTable* chan_table = NULL;
static GStaticMutex chan_table_mutex = G_STATIC_MUTEX_INIT;

static void _mix_stream_soundtouchify(MixStream* stream);


/* Create a stream that will play data returned by read_cb.
* - samprate and channels specify the format returned by read_cb
Expand Down Expand Up @@ -93,10 +96,10 @@ MixStream* mix_stream_new(int samprate, int channels, mix_stream_read_cb read_cb
default: g_assert_not_reached(); break;
}

stream->st_mutex = g_mutex_new();

if (stream->samprate != stream->out_freq) {
stream->soundtouch = soundtouch_new();
soundtouch_set_sample_rate(stream->soundtouch, stream->samprate);
soundtouch_set_channels(stream->soundtouch, stream->channels);
_mix_stream_soundtouchify(stream);
soundtouch_set_rate(stream->soundtouch, (float)stream->samprate/(float)stream->out_freq);
}

Expand All @@ -109,13 +112,27 @@ void mix_stream_destroy(MixStream* stream)
{
if (stream->channel != -1)
mix_stream_stop(stream);
g_mutex_free(stream->st_mutex);
if (stream->soundtouch != NULL)
soundtouch_delete(stream->soundtouch);
stream->free_cb(stream->cb_data);
g_free(stream);
}


/* Ensure the stream is using a soundtouch object. */
static void _mix_stream_soundtouchify(MixStream* stream)
{
g_mutex_lock(stream->st_mutex);
if (stream->soundtouch == NULL) {
stream->soundtouch = soundtouch_new();
soundtouch_set_sample_rate(stream->soundtouch, stream->samprate);
soundtouch_set_channels(stream->soundtouch, stream->channels);
}
g_mutex_unlock(stream->st_mutex);
}


/* Fill a float buffer using a read callback and possibly a SoundTouch object. */
static gsize _mix_stream_fill_floatbuf(MixStream* stream, float* buf, gsize numframes, guint channels)
{
Expand All @@ -124,6 +141,7 @@ static gsize _mix_stream_fill_floatbuf(MixStream* stream, float* buf, gsize numf
gsize frames_read;
while (numframes > 0) {

g_mutex_lock(stream->st_mutex);
if (stream->soundtouch == NULL) {
frames_read = stream->read_cb(buf, numframes * frame_size, stream->cb_data) / frame_size;
} else {
Expand All @@ -138,6 +156,7 @@ static gsize _mix_stream_fill_floatbuf(MixStream* stream, float* buf, gsize numf
}
frames_read = soundtouch_receive_samples(stream->soundtouch, buf, numframes);
}
g_mutex_unlock(stream->st_mutex);

if (frames_read == 0) {
if (frames_obtained != 0) {
Expand Down

0 comments on commit 116c67e

Please sign in to comment.