diff options
author | Max Kellermann <max@duempel.org> | 2010-05-02 15:31:31 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2010-05-02 17:46:07 +0200 |
commit | 5399a72ec1141307e79970993e4a90a8d643ac50 (patch) | |
tree | 87f3ecbbb6c4875f2754dd72b0a577a7b81d652d /src/output | |
parent | d093fb2441ee99722670f0401215031fc324bb31 (diff) | |
download | mpd-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_control.c | 2 | ||||
-rw-r--r-- | src/output_init.c | 2 | ||||
-rw-r--r-- | src/output_internal.h | 6 | ||||
-rw-r--r-- | src/output_thread.c | 30 |
4 files changed, 40 insertions, 0 deletions
diff --git a/src/output_control.c b/src/output_control.c index 17edc3d72..bcedae247 100644 --- a/src/output_control.c +++ b/src/output_control.c @@ -301,4 +301,6 @@ void audio_output_finish(struct audio_output *ao) g_mutex_free(ao->mutex); filter_free(ao->filter); + + pcm_buffer_deinit(&ao->cross_fade_buffer); } diff --git a/src/output_init.c b/src/output_init.c index 6ee340edc..a091e749a 100644 --- a/src/output_init.c +++ b/src/output_init.c @@ -191,6 +191,8 @@ audio_output_init(struct audio_output *ao, const struct config_param *param, ao->pause = false; ao->fail_timer = NULL; + pcm_buffer_init(&ao->cross_fade_buffer); + /* set up the filter chain */ ao->filter = filter_chain_new(); diff --git a/src/output_internal.h b/src/output_internal.h index 06df9531b..06e209374 100644 --- a/src/output_internal.h +++ b/src/output_internal.h @@ -21,6 +21,7 @@ #define MPD_OUTPUT_INTERNAL_H #include "audio_format.h" +#include "pcm_buffer.h" #include <glib.h> @@ -135,6 +136,11 @@ struct audio_output { struct audio_format out_audio_format; /** + * The buffer used to allocate the cross-fading result. + */ + struct pcm_buffer cross_fade_buffer; + + /** * The filter object of this audio output. This is an * instance of chain_filter_plugin. */ 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); |