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
This commit is contained in:
commit
e9beea072d
9
NEWS
9
NEWS
@ -96,6 +96,15 @@ ver 0.16 (20??/??/??)
|
|||||||
* added libwrap support
|
* 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)
|
ver 0.15.8 (2010/01/17)
|
||||||
* input:
|
* input:
|
||||||
- curl: allow rewinding with Icy-Metadata
|
- curl: allow rewinding with Icy-Metadata
|
||||||
|
@ -155,22 +155,6 @@ cue_tag_track(struct Cdtext *cdtext, struct Rem *rem)
|
|||||||
return tag;
|
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 *
|
struct tag *
|
||||||
cue_tag(struct Cd *cd, unsigned tnum)
|
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_tag = cue_tag_track(track_get_cdtext(track),
|
||||||
track_get_rem(track));
|
track_get_rem(track));
|
||||||
|
|
||||||
tag = cue_tag_merge(cd_tag, track_tag);
|
tag = tag_merge_replace(cd_tag, track_tag);
|
||||||
if (tag == NULL)
|
if (tag == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -1238,10 +1238,6 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream)
|
|||||||
|
|
||||||
while (mp3_read(&data)) ;
|
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);
|
mp3_data_finish(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <mpcdec/mpcdec.h>
|
#include <mpcdec/mpcdec.h>
|
||||||
#else
|
#else
|
||||||
#include <mpc/mpcdec.h>
|
#include <mpc/mpcdec.h>
|
||||||
|
#include <math.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
@ -105,7 +106,7 @@ mpc_to_mpd_sample(MPC_SAMPLE_FORMAT sample)
|
|||||||
const int shift = bits - MPC_FIXED_POINT_SCALE_SHIFT;
|
const int shift = bits - MPC_FIXED_POINT_SCALE_SHIFT;
|
||||||
|
|
||||||
if (shift < 0)
|
if (shift < 0)
|
||||||
val = sample << -shift;
|
val = sample >> -shift;
|
||||||
else
|
else
|
||||||
val = sample << shift;
|
val = sample << shift;
|
||||||
#else
|
#else
|
||||||
@ -206,10 +207,18 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is)
|
|||||||
|
|
||||||
struct replay_gain_info replay_gain_info;
|
struct replay_gain_info replay_gain_info;
|
||||||
replay_gain_info_init(&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].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_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].gain = info.gain_title * 0.01;
|
||||||
replay_gain_info.tuples[REPLAY_GAIN_TRACK].peak = info.peak_title / 32767.0;
|
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_replay_gain(mpd_decoder, &replay_gain_info);
|
||||||
|
|
||||||
decoder_initialized(mpd_decoder, &audio_format,
|
decoder_initialized(mpd_decoder, &audio_format,
|
||||||
|
@ -92,6 +92,13 @@ struct player {
|
|||||||
*/
|
*/
|
||||||
unsigned cross_fade_chunks;
|
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.
|
* The current audio format for the audio outputs.
|
||||||
*/
|
*/
|
||||||
@ -649,6 +656,14 @@ play_next_chunk(struct player *player)
|
|||||||
chunk = music_pipe_shift(player->pipe);
|
chunk = music_pipe_shift(player->pipe);
|
||||||
assert(chunk != NULL);
|
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)) {
|
if (isnan(pc.mixramp_delay_seconds)) {
|
||||||
mix_ratio = ((float)cross_fade_position)
|
mix_ratio = ((float)cross_fade_position)
|
||||||
/ player->cross_fade_chunks;
|
/ player->cross_fade_chunks;
|
||||||
@ -687,6 +702,14 @@ play_next_chunk(struct player *player)
|
|||||||
|
|
||||||
assert(chunk != NULL);
|
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 */
|
/* play the current chunk */
|
||||||
|
|
||||||
success = play_chunk(player->song, chunk, &player->play_audio_format);
|
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,
|
.xfade = XFADE_UNKNOWN,
|
||||||
.cross_fading = false,
|
.cross_fading = false,
|
||||||
.cross_fade_chunks = 0,
|
.cross_fade_chunks = 0,
|
||||||
|
.cross_fade_tag = NULL,
|
||||||
.elapsed_time = 0.0,
|
.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_clear(player.pipe, player_buffer);
|
||||||
music_pipe_free(player.pipe);
|
music_pipe_free(player.pipe);
|
||||||
|
|
||||||
|
if (player.cross_fade_tag != NULL)
|
||||||
|
tag_free(player.cross_fade_tag);
|
||||||
|
|
||||||
player_lock();
|
player_lock();
|
||||||
|
|
||||||
if (player.queued) {
|
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)
|
? queue_next_order(&playlist->queue, playlist->current)
|
||||||
: 0;
|
: 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
|
/* shuffle the song order again, so we get a different
|
||||||
order each time the playlist is played
|
order each time the playlist is played
|
||||||
completely */
|
completely */
|
||||||
|
16
src/tag.c
16
src/tag.c
@ -282,6 +282,22 @@ tag_merge(const struct tag *base, const struct tag *add)
|
|||||||
return ret;
|
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 *
|
const char *
|
||||||
tag_get_value(const struct tag *tag, enum tag_type type)
|
tag_get_value(const struct tag *tag, enum tag_type type)
|
||||||
{
|
{
|
||||||
|
@ -183,6 +183,15 @@ struct tag *tag_dup(const struct tag *tag);
|
|||||||
struct tag *
|
struct tag *
|
||||||
tag_merge(const struct tag *base, const struct tag *add);
|
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"
|
* Returns true if the tag contains no items. This ignores the "time"
|
||||||
* attribute.
|
* attribute.
|
||||||
|
Loading…
Reference in New Issue
Block a user