aboutsummaryrefslogtreecommitdiffstats
path: root/src/output_thread.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2010-05-02 15:31:31 +0200
committerMax Kellermann <max@duempel.org>2010-05-02 17:46:07 +0200
commit5399a72ec1141307e79970993e4a90a8d643ac50 (patch)
tree87f3ecbbb6c4875f2754dd72b0a577a7b81d652d /src/output_thread.c
parentd093fb2441ee99722670f0401215031fc324bb31 (diff)
downloadmpd-5399a72ec1141307e79970993e4a90a8d643ac50.tar.gz
mpd-5399a72ec1141307e79970993e4a90a8d643ac50.tar.xz
mpd-5399a72ec1141307e79970993e4a90a8d643ac50.zip
player_thread: move cross-fading to output thread
Remove cross_fade_apply(), and call pcm_mix() in the output thread, mixing the chunk and chunk->other together.
Diffstat (limited to '')
-rw-r--r--src/output_thread.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/output_thread.c b/src/output_thread.c
index c3e064c3f..7f1e4935e 100644
--- a/src/output_thread.c
+++ b/src/output_thread.c
@@ -24,6 +24,7 @@
#include "chunk.h"
#include "pipe.h"
#include "player_control.h"
+#include "pcm_mix.h"
#include "filter_plugin.h"
#include "filter/convert_filter_plugin.h"
#include "filter/replay_gain_filter_plugin.h"
@@ -299,6 +300,35 @@ ao_filter_chunk(struct audio_output *ao, const struct music_chunk *chunk,
ao->replay_gain_serial = chunk->replay_gain_serial;
}
+ /* cross-fade */
+
+ if (chunk->other != NULL) {
+ size_t other_length;
+ const char *other_data = ao_chunk_data(ao, chunk->other,
+ &other_length);
+ if (other_length == 0) {
+ *length_r = 0;
+ return data;
+ }
+
+ /* if the "other" chunk is longer, then that trailer
+ is used as-is, without mixing; it is part of the
+ "next" song being faded in, and if there's a rest,
+ it means cross-fading ends here */
+
+ if (length > other_length)
+ length = other_length;
+
+ char *dest = pcm_buffer_get(&ao->cross_fade_buffer,
+ other_length);
+ memcpy(dest, other_data, other_length);
+ pcm_mix(dest, data, length, &ao->in_audio_format,
+ 1.0 - chunk->mix_ratio);
+
+ data = dest;
+ length = other_length;
+ }
+
/* apply filter chain */
data = filter_filter(ao->filter, data, length, &length, &error);