summaryrefslogtreecommitdiff
path: root/streamer.c
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2010-11-28 21:56:52 +0100
committerGravatar waker <wakeroid@gmail.com>2010-11-28 21:56:52 +0100
commitd8c31e7a70ed62e44c214ce88434b1b870e2e9a5 (patch)
treeaea26bed9b47edf4704592bbf44f60da3894ac60 /streamer.c
parent8d43782c7415fea1ed98a02d708ad6ba84ae2763 (diff)
fixed gapless playback when dsp is active
Diffstat (limited to 'streamer.c')
-rw-r--r--streamer.c203
1 files changed, 94 insertions, 109 deletions
diff --git a/streamer.c b/streamer.c
index 061380e4..ba25428c 100644
--- a/streamer.c
+++ b/streamer.c
@@ -1298,140 +1298,125 @@ apply_replay_gain_float32 (playItem_t *it, char *bytes, int size) {
}
}
-static void
-mono_int16_to_stereo_int16 (int16_t *in, int16_t *out, int nsamples) {
- while (nsamples > 0) {
- int16_t sample = *in++;
- *out++ = sample;
- *out++ = sample;
- nsamples--;
- }
-}
-
// decodes data and converts to current output format
// returns number of bytes been read
static int
streamer_read_async (char *bytes, int size) {
DB_output_t *output = plug_get_output ();
int initsize = size;
- for (;;) {
- int bytesread = 0;
- mutex_lock (decodemutex);
- if (!fileinfo) {
- // means there's nothing left to stream, so just do nothing
- mutex_unlock (decodemutex);
- break;
- }
- int is_eof = 0;
-
- if (fileinfo->fmt.samplerate != -1) {
- int outputsamplesize = (output->fmt.bps>>3)*output->fmt.channels;
- int inputsamplesize = (fileinfo->fmt.bps>>3)*fileinfo->fmt.channels;
- if (!memcmp (&fileinfo->fmt, &output->fmt, sizeof (ddb_waveformat_t))) {
- // pass through from input to output
- bytesread = fileinfo->plugin->read (fileinfo, bytes, size);
- if (bytesread != size) {
- is_eof = 1;
- }
- }
- else if (output->fmt.samplerate != fileinfo->fmt.samplerate) {
- // convert to float, pass through streamer DSP chain
- int dspsamplesize = output->fmt.channels * sizeof (float);
+ int bytesread = 0;
+ mutex_lock (decodemutex);
+ if (!fileinfo) {
+ // means there's nothing left to stream, so just do nothing
+ mutex_unlock (decodemutex);
+ return 0;
+ }
+ int is_eof = 0;
- float ratio = output->fmt.samplerate/(float)fileinfo->fmt.samplerate;
+ if (fileinfo->fmt.samplerate != -1) {
+ int outputsamplesize = output->fmt.channels * output->fmt.bps / 8;
+ int inputsamplesize = fileinfo->fmt.channels * fileinfo->fmt.bps / 8;
+ if (!memcmp (&fileinfo->fmt, &output->fmt, sizeof (ddb_waveformat_t))) {
+ // pass through from input to output
+ bytesread = fileinfo->plugin->read (fileinfo, bytes, size);
- int max_out_frames = size / (output->fmt.channels * (output->fmt.bps>>3));
- int dsp_num_frames = max_out_frames;
+ if (bytesread != size) {
+ is_eof = 1;
+ }
+ }
+ else if (output->fmt.samplerate != fileinfo->fmt.samplerate) {
+ // convert to float, pass through streamer DSP chain
+ int dspsamplesize = output->fmt.channels * sizeof (float);
- char outbuf[dsp_num_frames * dspsamplesize];
+ float ratio = output->fmt.samplerate/(float)fileinfo->fmt.samplerate;
- bytesread = 0;
+ int max_out_frames = size / (output->fmt.channels * output->fmt.bps / 8);
+ int dsp_num_frames = max_out_frames;
- ddb_waveformat_t dspfmt;
- memcpy (&dspfmt, &output->fmt, sizeof (dspfmt));
- dspfmt.bps = 32;
- dspfmt.is_float = 1;
+ char outbuf[dsp_num_frames * dspsamplesize];
- int inputsize = dsp_num_frames * inputsamplesize;
- char input[inputsize];
+ ddb_waveformat_t dspfmt;
+ memcpy (&dspfmt, &output->fmt, sizeof (dspfmt));
+ dspfmt.bps = 32;
+ dspfmt.is_float = 1;
- // decode pcm
- int nb = fileinfo->plugin->read (fileinfo, input, inputsize);
- if (nb != inputsize) {
- bytesread = nb;
- is_eof = 1;
- }
- inputsize = nb;
+ int inputsize = dsp_num_frames * inputsamplesize;
+ char input[inputsize];
- if (inputsize > 0) {
- // make 2x size buffer for float data
- char tempbuf[inputsize/inputsamplesize * dspsamplesize * 2];
+ // decode pcm
+ int nb = fileinfo->plugin->read (fileinfo, input, inputsize);
+ if (nb != inputsize) {
+ is_eof = 1;
+ }
+ inputsize = nb;
- // convert to float
- int tempsize = pcm_convert (&fileinfo->fmt, input, &dspfmt, tempbuf, inputsize);
- srcplug->set_ratio (src, ratio);
+ if (inputsize > 0) {
+ // make 2x size buffer for float data
+ char tempbuf[inputsize/inputsamplesize * dspsamplesize * 2];
- int nframes = inputsize / inputsamplesize;
- DB_dsp_instance_t *dsp = dsp_chain;
- while (dsp) {
- if (dsp->enabled) {
- nframes = dsp->plugin->process (dsp, (float *)tempbuf, nframes, dspfmt.samplerate, dspfmt.channels);
- }
- dsp = dsp->next;
- }
- int n = pcm_convert (&dspfmt, tempbuf, &output->fmt, bytes, nframes * dspsamplesize);
+ // convert to float
+ int tempsize = pcm_convert (&fileinfo->fmt, input, &dspfmt, tempbuf, inputsize);
+ srcplug->set_ratio (src, ratio);
- bytesread += n;
+ int nframes = inputsize / inputsamplesize;
+ DB_dsp_instance_t *dsp = dsp_chain;
+ while (dsp) {
+ if (dsp->enabled) {
+ nframes = dsp->plugin->process (dsp, (float *)tempbuf, nframes, dspfmt.samplerate, dspfmt.channels);
+ }
+ dsp = dsp->next;
}
+ int n = pcm_convert (&dspfmt, tempbuf, &output->fmt, bytes, nframes * dspsamplesize);
+
+ bytesread = n;
}
- else {
- // convert from input fmt to output fmt
- int inputsize = size/outputsamplesize*inputsamplesize;
- char input[inputsize];
- int nb = fileinfo->plugin->read (fileinfo, input, inputsize);
- if (nb != inputsize) {
- bytesread = nb;
- is_eof = 1;
- }
- inputsize = nb;
- bytesread = pcm_convert (&fileinfo->fmt, input, &output->fmt, bytes, inputsize);
+ }
+ else {
+ // convert from input fmt to output fmt
+ int inputsize = size/outputsamplesize*inputsamplesize;
+ char input[inputsize];
+ int nb = fileinfo->plugin->read (fileinfo, input, inputsize);
+ if (nb != inputsize) {
+ bytesread = nb;
+ is_eof = 1;
}
+ inputsize = nb;
+ bytesread = pcm_convert (&fileinfo->fmt, input, &output->fmt, bytes, inputsize);
+ }
#if WRITE_DUMP
- if (bytesread) {
- fwrite (bytes, 1, bytesread, out);
- }
+ if (bytesread) {
+ fwrite (bytes, 1, bytesread, out);
+ }
#endif
- // FIXME: separate replaygain DSP plugin?
- if (output->fmt.bps == 16) {
- apply_replay_gain_int16 (streaming_track, bytes, bytesread);
- }
- else if (output->fmt.bps == 32 && output->fmt.is_float) {
- apply_replay_gain_float32 (streaming_track, bytes, bytesread);
- }
+ // FIXME: separate replaygain DSP plugin?
+ if (output->fmt.bps == 16) {
+ apply_replay_gain_int16 (streaming_track, bytes, bytesread);
}
- mutex_unlock (decodemutex);
- bytes += bytesread;
- size -= bytesread;
- if (!is_eof) {
- return initsize-size;
- }
- else {
- // that means EOF
- trace ("streamer: EOF! buns: %d, bytesread: %d, buffering: %d, bufferfill: %d\n", bytes_until_next_song, bytesread, streamer_buffering, streambuffer_fill);
-
- // in case of decoder error, or EOF while buffering - switch to next song instantly
- if (bytesread < 0 || (bytes_until_next_song >= 0 && streamer_buffering && bytesread == 0) || bytes_until_next_song < 0) {
- trace ("finished streaming song, queueing next\n");
- bytes_until_next_song = streambuffer_fill;
- if (conf_get_int ("playlist.stop_after_current", 0)) {
- streamer_set_nextsong (-2, 1);
- }
- else {
- streamer_move_to_nextsong (0);
- }
+ else if (output->fmt.bps == 32 && output->fmt.is_float) {
+ apply_replay_gain_float32 (streaming_track, bytes, bytesread);
+ }
+ }
+ mutex_unlock (decodemutex);
+ bytes += bytesread;
+ size -= bytesread;
+ if (!is_eof) {
+ return initsize-size;
+ }
+ else {
+ // that means EOF
+ trace ("streamer: EOF! buns: %d, bytesread: %d, buffering: %d, bufferfill: %d\n", bytes_until_next_song, bytesread, streamer_buffering, streambuffer_fill);
+
+ // in case of decoder error, or EOF while buffering - switch to next song instantly
+ if (bytesread < 0 || (bytes_until_next_song >= 0 && streamer_buffering && bytesread == 0) || bytes_until_next_song < 0) {
+ trace ("finished streaming song, queueing next\n");
+ bytes_until_next_song = streambuffer_fill;
+ if (conf_get_int ("playlist.stop_after_current", 0)) {
+ streamer_set_nextsong (-2, 1);
+ }
+ else {
+ streamer_move_to_nextsong (0);
}
- break;
}
}
return initsize - size;