Commit e9beea07 authored by Max Kellermann's avatar Max Kellermann

Merge release 0.15.9 from branch 'v0.15.x'

Conflicts: NEWS configure.ac src/cue/cue_tag.c src/decoder/mpcdec_decoder_plugin.c src/player_thread.c
parents e69bb3b3 d612e5e0
......@@ -96,6 +96,15 @@ ver 0.16 (20??/??/??)
* added libwrap support
ver 0.15.9 (2010/03/21)
* decoders:
- mad: fix crash when seeking at end of song
- mpcdec: fix negative shift on fixed-point samples
- mpcdec: fix replay gain formula with v8
* playlist: fix single+repeat in random mode
* player: postpone song tags during cross-fade
ver 0.15.8 (2010/01/17)
* input:
- curl: allow rewinding with Icy-Metadata
......
......@@ -155,22 +155,6 @@ cue_tag_track(struct Cdtext *cdtext, struct Rem *rem)
return tag;
}
static struct tag *
cue_tag_merge(struct tag *a, struct tag *b)
{
if (a != NULL && b != NULL) {
struct tag *merge_tag = tag_merge(a, b);
tag_free(a);
tag_free(b);
return merge_tag;
} else if (a != NULL)
return a;
else if (b != NULL)
return b;
else
return NULL;
}
struct tag *
cue_tag(struct Cd *cd, unsigned tnum)
{
......@@ -190,7 +174,7 @@ cue_tag(struct Cd *cd, unsigned tnum)
track_tag = cue_tag_track(track_get_cdtext(track),
track_get_rem(track));
tag = cue_tag_merge(cd_tag, track_tag);
tag = tag_merge_replace(cd_tag, track_tag);
if (tag == NULL)
return NULL;
......
......@@ -1238,10 +1238,6 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream)
while (mp3_read(&data)) ;
if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK &&
data.mute_frame == MUTEFRAME_SEEK)
decoder_command_finished(decoder);
mp3_data_finish(&data);
}
......
......@@ -25,6 +25,7 @@
#include <mpcdec/mpcdec.h>
#else
#include <mpc/mpcdec.h>
#include <math.h>
#endif
#include <glib.h>
......@@ -105,7 +106,7 @@ mpc_to_mpd_sample(MPC_SAMPLE_FORMAT sample)
const int shift = bits - MPC_FIXED_POINT_SCALE_SHIFT;
if (shift < 0)
val = sample << -shift;
val = sample >> -shift;
else
val = sample << shift;
#else
......@@ -206,10 +207,18 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is)
struct replay_gain_info replay_gain_info;
replay_gain_info_init(&replay_gain_info);
#ifdef MPC_IS_OLD_API
replay_gain_info.tuples[REPLAY_GAIN_ALBUM].gain = info.gain_album * 0.01;
replay_gain_info.tuples[REPLAY_GAIN_ALBUM].peak = info.peak_album / 32767.0;
replay_gain_info.tuples[REPLAY_GAIN_TRACK].gain = info.gain_title * 0.01;
replay_gain_info.tuples[REPLAY_GAIN_TRACK].peak = info.peak_title / 32767.0;
#else
replay_gain_info.tuples[REPLAY_GAIN_ALBUM].gain = MPC_OLD_GAIN_REF - (info.gain_album / 256.);
replay_gain_info.tuples[REPLAY_GAIN_ALBUM].peak = pow(10, info.peak_album / 256. / 20) / 32767;
replay_gain_info.tuples[REPLAY_GAIN_TRACK].gain = MPC_OLD_GAIN_REF - (info.gain_title / 256.);
replay_gain_info.tuples[REPLAY_GAIN_TRACK].peak = pow(10, info.peak_title / 256. / 20) / 32767;
#endif
decoder_replay_gain(mpd_decoder, &replay_gain_info);
decoder_initialized(mpd_decoder, &audio_format,
......
......@@ -93,6 +93,13 @@ struct player {
unsigned cross_fade_chunks;
/**
* The tag of the "next" song during cross-fade. It is
* postponed, and sent to the output thread when the new song
* really begins.
*/
struct tag *cross_fade_tag;
/**
* The current audio format for the audio outputs.
*/
struct audio_format play_audio_format;
......@@ -649,6 +656,14 @@ play_next_chunk(struct player *player)
chunk = music_pipe_shift(player->pipe);
assert(chunk != NULL);
/* don't send the tags of the new song (which
is being faded in) yet; postpone it until
the current song is faded out */
player->cross_fade_tag =
tag_merge_replace(player->cross_fade_tag,
other_chunk->tag);
other_chunk->tag = NULL;
if (isnan(pc.mixramp_delay_seconds)) {
mix_ratio = ((float)cross_fade_position)
/ player->cross_fade_chunks;
......@@ -687,6 +702,14 @@ play_next_chunk(struct player *player)
assert(chunk != NULL);
/* insert the postponed tag if cross-fading is finished */
if (player->xfade != XFADE_ENABLED && player->cross_fade_tag != NULL) {
chunk->tag = tag_merge_replace(chunk->tag,
player->cross_fade_tag);
player->cross_fade_tag = NULL;
}
/* play the current chunk */
success = play_chunk(player->song, chunk, &player->play_audio_format);
......@@ -769,6 +792,7 @@ static void do_play(struct decoder_control *dc)
.xfade = XFADE_UNKNOWN,
.cross_fading = false,
.cross_fade_chunks = 0,
.cross_fade_tag = NULL,
.elapsed_time = 0.0,
};
......@@ -939,6 +963,9 @@ static void do_play(struct decoder_control *dc)
music_pipe_clear(player.pipe, player_buffer);
music_pipe_free(player.pipe);
if (player.cross_fade_tag != NULL)
tag_free(player.cross_fade_tag);
player_lock();
if (player.queued) {
......
......@@ -139,7 +139,8 @@ playlist_update_queued_song(struct playlist *playlist, const struct song *prev)
? queue_next_order(&playlist->queue, playlist->current)
: 0;
if (next_order == 0 && playlist->queue.random) {
if (next_order == 0 && playlist->queue.random &&
!playlist->queue.single) {
/* shuffle the song order again, so we get a different
order each time the playlist is played
completely */
......
......@@ -282,6 +282,22 @@ tag_merge(const struct tag *base, const struct tag *add)
return ret;
}
struct tag *
tag_merge_replace(struct tag *base, struct tag *add)
{
if (add == NULL)
return base;
if (base == NULL)
return add;
struct tag *tag = tag_merge(base, add);
tag_free(base);
tag_free(add);
return tag;
}
const char *
tag_get_value(const struct tag *tag, enum tag_type type)
{
......
......@@ -184,6 +184,15 @@ struct tag *
tag_merge(const struct tag *base, const struct tag *add);
/**
* Merges the data from two tags. Any of the two may be NULL. Both
* are freed by this function.
*
* @return a newly allocated tag, which must be freed with tag_free()
*/
struct tag *
tag_merge_replace(struct tag *base, struct tag *add);
/**
* Returns true if the tag contains no items. This ignores the "time"
* attribute.
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment