Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9ad862d3a6 | ||
![]() |
77d71c4ee6 | ||
![]() |
8c0afd8557 | ||
![]() |
2a56300f7b | ||
![]() |
5f06999686 | ||
![]() |
4c09aeb5a1 | ||
![]() |
af892e7e80 | ||
![]() |
0022fb100b | ||
![]() |
4f2d67dfb0 | ||
![]() |
b5645ab29f | ||
![]() |
3149d1abf9 | ||
![]() |
59a417fc84 | ||
![]() |
b75d53413d | ||
![]() |
c44a744c0b | ||
![]() |
76cddfab90 | ||
![]() |
60b4f6b3eb | ||
![]() |
546232b1c0 | ||
![]() |
42c5788de3 | ||
![]() |
fb00e7fddc | ||
![]() |
41fdcf328c | ||
![]() |
144ad7992e | ||
![]() |
a0dd1a1b8b | ||
![]() |
c360e69162 |
10
Makefile.am
10
Makefile.am
@@ -7,6 +7,8 @@ AM_CPPFLAGS += -DSYSTEM_CONFIG_FILE_LOCATION='"$(sysconfdir)/mpd.conf"'
|
||||
|
||||
bin_PROGRAMS = src/mpd
|
||||
|
||||
noinst_LIBRARIES =
|
||||
|
||||
src_mpd_CFLAGS = $(AM_CFLAGS) $(MPD_CFLAGS)
|
||||
src_mpd_CPPFLAGS = $(AM_CPPFLAGS) \
|
||||
$(LIBWRAP_CFLAGS) \
|
||||
@@ -432,7 +434,6 @@ DECODER_CFLAGS = \
|
||||
$(SNDFILE_CFLAGS) \
|
||||
$(AUDIOFILE_CFLAGS) \
|
||||
$(LIBMIKMOD_CFLAGS) \
|
||||
$(MODPLUG_CFLAGS) \
|
||||
$(GME_CFLAGS) \
|
||||
$(SIDPLAY_CFLAGS) \
|
||||
$(FLUIDSYNTH_CFLAGS) \
|
||||
@@ -448,7 +449,6 @@ DECODER_LIBS = \
|
||||
$(FLAC_LIBS) \
|
||||
$(SNDFILE_LIBS) \
|
||||
$(AUDIOFILE_LIBS) $(LIBMIKMOD_LIBS) \
|
||||
$(MODPLUG_LIBS) \
|
||||
$(GME_LIBS) \
|
||||
$(SIDPLAY_LIBS) \
|
||||
$(FLUIDSYNTH_LIBS) \
|
||||
@@ -521,7 +521,11 @@ DECODER_SRC += src/decoder/mikmod_decoder_plugin.c
|
||||
endif
|
||||
|
||||
if HAVE_MODPLUG
|
||||
DECODER_SRC += src/decoder/modplug_decoder_plugin.c
|
||||
libmodplug_decoder_plugin_a_SOURCES = src/decoder/modplug_decoder_plugin.c
|
||||
libmodplug_decoder_plugin_a_CFLAGS = $(src_mpd_CFLAGS) $(MODPLUG_CFLAGS)
|
||||
libmodplug_decoder_plugin_a_CPPFLAGS = $(src_mpd_CPPFLAGS)
|
||||
noinst_LIBRARIES += libmodplug_decoder_plugin.a
|
||||
DECODER_LIBS += libmodplug_decoder_plugin.a $(MODPLUG_LIBS)
|
||||
endif
|
||||
|
||||
if ENABLE_SIDPLAY
|
||||
|
21
NEWS
21
NEWS
@@ -1,3 +1,19 @@
|
||||
ver 0.16.1 (2010/01/09)
|
||||
* audio_check: fix parameter in prototype
|
||||
* add void casts to suppress "result unused" warnings (clang)
|
||||
* input:
|
||||
- ffado: disable by default
|
||||
* decoder:
|
||||
- mad: work around build failure on Solaris
|
||||
- resolve modplug vs. libsndfile cflags/headers conflict
|
||||
* output:
|
||||
- solaris: add missing parameter to open_cloexec() cal
|
||||
- osx: fix up audio format first, then apply it to device
|
||||
* player_thread: discard empty chunks while cross-fading
|
||||
* player_thread: fix assertion failure due to early seek
|
||||
* output_thread: fix double lock
|
||||
|
||||
|
||||
ver 0.16 (2010/12/11)
|
||||
* protocol:
|
||||
- send song modification time to client
|
||||
@@ -112,6 +128,11 @@ ver 0.16 (2010/12/11)
|
||||
* make single mode 'sticky'
|
||||
|
||||
|
||||
ver 0.15.16 (2010/??/??)
|
||||
* encoders:
|
||||
- lame: explicitly configure the output sample rate
|
||||
|
||||
|
||||
ver 0.15.15 (2010/11/08)
|
||||
* input:
|
||||
- rewind: fix assertion failure
|
||||
|
49
configure.ac
49
configure.ac
@@ -1,5 +1,5 @@
|
||||
AC_PREREQ(2.60)
|
||||
AC_INIT(mpd, 0.16, musicpd-dev-team@lists.sourceforge.net)
|
||||
AC_INIT(mpd, 0.16.1, musicpd-dev-team@lists.sourceforge.net)
|
||||
AC_CONFIG_SRCDIR([src/main.c])
|
||||
AM_INIT_AUTOMAKE([foreign 1.10 dist-bzip2 subdir-objects])
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
@@ -13,6 +13,7 @@ dnl Programs
|
||||
dnl ---------------------------------------------------------------------------
|
||||
AC_PROG_CC_C99
|
||||
AC_PROG_CXX
|
||||
AC_PROG_RANLIB
|
||||
|
||||
HAVE_CXX=yes
|
||||
if test x$CXX = xg++; then
|
||||
@@ -157,7 +158,7 @@ AC_ARG_ENABLE(documentation,
|
||||
|
||||
AC_ARG_ENABLE(ffado,
|
||||
AS_HELP_STRING([--enable-ffado], [enable libffado (FireWire) support]),,
|
||||
[enable_ffado=auto])
|
||||
[enable_ffado=no])
|
||||
|
||||
AC_ARG_ENABLE(ffmpeg,
|
||||
AS_HELP_STRING([--enable-ffmpeg],
|
||||
@@ -849,15 +850,6 @@ if test x$enable_modplug = xyes; then
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_MODPLUG, test x$enable_modplug = xyes)
|
||||
|
||||
dnl --------------------------- sndfile/modplug test --------------------------
|
||||
if test x$enable_sndfile = xauto && test x$enable_modplug = xyes; then
|
||||
dnl If modplug is enabled, enable sndfile only if explicitly
|
||||
dnl requested - modplug's modplug/sndfile.h is known to
|
||||
dnl conflict with libsndfile's sndfile.h.
|
||||
AC_MSG_NOTICE([disabling libsndfile auto-detection, because the modplug decoder is enabled])
|
||||
enable_sndfile=no
|
||||
fi
|
||||
|
||||
dnl -------------------------------- libsndfile -------------------------------
|
||||
dnl See above test, which may disable this.
|
||||
MPD_AUTO_PKG(sndfile, SNDFILE, [sndfile],
|
||||
@@ -1495,23 +1487,23 @@ dnl ---------------------------------------------------------------------------
|
||||
echo ''
|
||||
echo '########### MPD CONFIGURATION ############'
|
||||
|
||||
echo -ne '\nArchive support:\n\t'
|
||||
printf '\nArchive support:\n\t'
|
||||
results(bzip2,[bzip2])
|
||||
results(iso9660,[ISO9660])
|
||||
results(zzip,[ZIP])
|
||||
|
||||
if test x$with_zeroconf != xno; then
|
||||
echo -ne '\nAutodiscovery support:\n\t'
|
||||
printf '\nAutodiscovery support:\n\t'
|
||||
results(avahi, [Avahi])
|
||||
results(bonjour, [Bonjour])
|
||||
fi
|
||||
|
||||
echo -ne '\nClient support:\n\t'
|
||||
printf '\nClient support:\n\t'
|
||||
results(ipv6, "IPv6")
|
||||
results(tcp, "TCP")
|
||||
results(un,[UNIX Domain Sockets])
|
||||
|
||||
echo -ne '\nFile format support:\n\t'
|
||||
printf '\nFile format support:\n\t'
|
||||
results(aac, [AAC])
|
||||
results(sidplay, [C64 SID])
|
||||
results(ffmpeg, [FFMPEG])
|
||||
@@ -1519,7 +1511,7 @@ results(flac, [FLAC])
|
||||
results(fluidsynth, [FluidSynth])
|
||||
results(gme, [GME])
|
||||
results(sndfile, [libsndfile])
|
||||
echo -ne '\n\t'
|
||||
printf '\n\t'
|
||||
results(mikmod, [MikMod])
|
||||
results(modplug, [MODPLUG])
|
||||
results(mad, [MAD])
|
||||
@@ -1527,23 +1519,23 @@ results(mpg123, [MPG123])
|
||||
results(mp4, [MP4])
|
||||
results(mpc, [Musepack])
|
||||
results(oggflac, [OggFLAC], flac)
|
||||
echo -ne '\n\t'
|
||||
printf '\n\t'
|
||||
results(tremor, [OggTremor])
|
||||
results(vorbis, [OggVorbis])
|
||||
results(audiofile, [WAVE])
|
||||
results(wavpack, [WavPack])
|
||||
results(wildmidi, [WildMidi])
|
||||
|
||||
echo -en '\nOther features:\n\t'
|
||||
printf '\nOther features:\n\t'
|
||||
results(lsr, [libsamplerate])
|
||||
results(inotify, [inotify])
|
||||
results(sqlite, [SQLite])
|
||||
|
||||
echo -en '\nMetadata support:\n\t'
|
||||
printf '\nMetadata support:\n\t'
|
||||
results(cue,[cue])
|
||||
results(id3,[ID3])
|
||||
|
||||
echo -en '\nPlayback support:\n\t'
|
||||
printf '\nPlayback support:\n\t'
|
||||
results(alsa,ALSA)
|
||||
results(ffado,FFADO)
|
||||
results(fifo,FIFO)
|
||||
@@ -1552,14 +1544,14 @@ results(httpd_output,[HTTP Daemon])
|
||||
results(jack,[JACK])
|
||||
results(ao,[libao])
|
||||
results(oss,[OSS])
|
||||
echo -ne '\n\t'
|
||||
printf '\n\t'
|
||||
results(openal,[OpenAL])
|
||||
results(osx, [OS X])
|
||||
results(pipe_output, [Pipeline])
|
||||
results(pulse, [PulseAudio])
|
||||
results(mvp, [Media MVP])
|
||||
results(shout, [SHOUTcast])
|
||||
echo -ne '\n\t'
|
||||
printf '\n\t'
|
||||
results(solaris, [Solaris])
|
||||
results(winmm_output, [WinMM])
|
||||
|
||||
@@ -1567,7 +1559,7 @@ if
|
||||
test x$enable_shout = xyes ||
|
||||
test x$enable_recorder = xyes ||
|
||||
test x$enable_httpd_output = xyes; then
|
||||
echo -en '\nStreaming encoder support:\n\t'
|
||||
printf '\nStreaming encoder support:\n\t'
|
||||
results(flac_encoder, [FLAC])
|
||||
results(lame_encoder, [LAME])
|
||||
results(vorbis_encoder, [Ogg Vorbis])
|
||||
@@ -1575,19 +1567,14 @@ if
|
||||
results(wave_encoder, [WAVE])
|
||||
fi
|
||||
|
||||
echo -en '\nStreaming support:\n\t'
|
||||
printf '\nStreaming support:\n\t'
|
||||
results(curl,[CURL])
|
||||
results(lastfm,[Last.FM])
|
||||
results(mms,[MMS])
|
||||
|
||||
echo -ne '\n\n##########################################\n\n'
|
||||
printf '\n\n##########################################\n\n'
|
||||
|
||||
if test x$enable_sndfile = xyes && test x$enable_modplug = xyes; then
|
||||
AC_MSG_WARN([compilation may fail, because libmodplug conflicts with libsndfile])
|
||||
AC_MSG_WARN([libmodplug ships modplug/sndfile.h, which hides libsndfile's sndfile.h])
|
||||
fi
|
||||
|
||||
echo -ne 'Generating files needed for compilation\n'
|
||||
echo 'Generating files needed for compilation'
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl Generate files
|
||||
|
12
m4/faad.m4
12
m4/faad.m4
@@ -58,7 +58,7 @@ if test x$enable_aac = xyes; then
|
||||
fi
|
||||
if test x$enable_aac = xyes; then
|
||||
AC_MSG_CHECKING(that FAAD2 uses buffer and bufferlen)
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
|
||||
#include <faad.h>
|
||||
|
||||
int main() {
|
||||
@@ -82,9 +82,9 @@ int main() {
|
||||
|
||||
return 0;
|
||||
}
|
||||
],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_FAAD_BUFLEN_FUNCS,1,[Define if FAAD2 uses buflen in function calls])],[AC_MSG_RESULT(no);
|
||||
])],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_FAAD_BUFLEN_FUNCS,1,[Define if FAAD2 uses buflen in function calls])],[AC_MSG_RESULT(no);
|
||||
AC_MSG_CHECKING(that FAAD2 can even be used)
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
|
||||
#include <faad.h>
|
||||
|
||||
int main() {
|
||||
@@ -113,7 +113,7 @@ int main() {
|
||||
|
||||
return 0;
|
||||
}
|
||||
],AC_MSG_RESULT(yes),[AC_MSG_RESULT(no);enable_aac=no])
|
||||
])],AC_MSG_RESULT(yes),[AC_MSG_RESULT(no);enable_aac=no])
|
||||
])
|
||||
fi
|
||||
if test x$enable_aac = xyes; then
|
||||
@@ -136,7 +136,7 @@ if test x$enable_aac = xyes; then
|
||||
CPPFLAGS=$CFLAGS
|
||||
|
||||
AC_MSG_CHECKING(for broken libfaad headers)
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
|
||||
#include <faad.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
@@ -148,7 +148,7 @@ int main() {
|
||||
faacDecInit2(NULL, NULL, 0, &sample_rate, &channels);
|
||||
return 0;
|
||||
}
|
||||
],
|
||||
])],
|
||||
[AC_MSG_RESULT(correct)],
|
||||
[AC_MSG_RESULT(broken);
|
||||
AC_DEFINE(HAVE_FAAD_LONG, 1, [Define if faad.h uses the broken "unsigned long" pointers])])
|
||||
|
@@ -4,9 +4,9 @@ AC_DEFUN([MPD_CHECK_FLAG],[
|
||||
[mpd_check_cflag_$var],[
|
||||
save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $1"
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
|
||||
int main(void) { return 0; }
|
||||
], [ eval "mpd_check_cflag_$var=yes"
|
||||
])], [ eval "mpd_check_cflag_$var=yes"
|
||||
], [ eval "mpd_check_cflag_$var=no" ])
|
||||
CFLAGS="$save_CFLAGS"
|
||||
])
|
||||
|
@@ -1,19 +1,19 @@
|
||||
AC_DEFUN([results], [
|
||||
dnl This is a hack to allow "with" names, otherwise "enable".
|
||||
num=`expr match $1 'with'`
|
||||
num=`expr $1 : 'with'`
|
||||
if test "$num" != "0"; then
|
||||
var="`echo '$'$1`"
|
||||
else
|
||||
var="`echo '$'enable_$1`"
|
||||
fi
|
||||
|
||||
echo -n '('
|
||||
printf '('
|
||||
if eval "test x$var = xyes"; then
|
||||
echo -n '+'
|
||||
printf '+'
|
||||
elif test -n "$3" && eval "test x$var = x$3"; then
|
||||
echo -n '+'
|
||||
printf '+'
|
||||
else
|
||||
echo -n '-'
|
||||
printf '-'
|
||||
fi
|
||||
echo -n "$2) "
|
||||
printf '%s) ' "$2"
|
||||
])
|
||||
|
@@ -38,7 +38,7 @@ bool
|
||||
audio_check_sample_rate(unsigned long sample_rate, GError **error_r);
|
||||
|
||||
bool
|
||||
audio_check_sample_format(unsigned sample_format, GError **error_r);
|
||||
audio_check_sample_format(enum sample_format, GError **error_r);
|
||||
|
||||
bool
|
||||
audio_check_channel_count(unsigned sample_format, GError **error_r);
|
||||
|
@@ -547,14 +547,14 @@ enum {
|
||||
XING_SCALE = 0x00000008L
|
||||
};
|
||||
|
||||
struct version {
|
||||
struct lame_version {
|
||||
unsigned major;
|
||||
unsigned minor;
|
||||
};
|
||||
|
||||
struct lame {
|
||||
char encoder[10]; /* 9 byte encoder name/version ("LAME3.97b") */
|
||||
struct version version; /* struct containing just the version */
|
||||
struct lame_version version; /* struct containing just the version */
|
||||
float peak; /* replaygain peak */
|
||||
float track_gain; /* replaygain track gain */
|
||||
float album_gain; /* replaygain album gain */
|
||||
|
@@ -30,8 +30,8 @@
|
||||
|
||||
#define DIRECTORY_DIR "directory: "
|
||||
|
||||
#define DEVICE_INARCHIVE (dev_t)(-1)
|
||||
#define DEVICE_CONTAINER (dev_t)(-2)
|
||||
#define DEVICE_INARCHIVE (dev_t)(-1)
|
||||
#define DEVICE_CONTAINER (dev_t)(-2)
|
||||
|
||||
struct directory {
|
||||
struct dirvec children;
|
||||
|
@@ -170,6 +170,13 @@ lame_encoder_setup(struct lame_encoder *encoder, GError **error)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 != lame_set_out_samplerate(encoder->gfp,
|
||||
encoder->audio_format.sample_rate)) {
|
||||
g_set_error(error, lame_encoder_quark(), 0,
|
||||
"error setting lame out sample rate");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 > lame_init_params(encoder->gfp)) {
|
||||
g_set_error(error, lame_encoder_quark(), 0,
|
||||
"error initializing lame params");
|
||||
|
@@ -29,6 +29,9 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
#define G_LOG_DOMAIN "httpd_output"
|
||||
|
||||
struct httpd_client {
|
||||
/**
|
||||
* The httpd output object this client is connected to.
|
||||
|
@@ -214,15 +214,6 @@ osx_output_open(void *data, struct audio_format *audio_format, GError **error)
|
||||
stream_description.mSampleRate = audio_format->sample_rate;
|
||||
stream_description.mFormatID = kAudioFormatLinearPCM;
|
||||
stream_description.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
stream_description.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
|
||||
#endif
|
||||
|
||||
stream_description.mBytesPerPacket =
|
||||
audio_format_frame_size(audio_format);
|
||||
stream_description.mFramesPerPacket = 1;
|
||||
stream_description.mBytesPerFrame = stream_description.mBytesPerPacket;
|
||||
stream_description.mChannelsPerFrame = audio_format->channels;
|
||||
|
||||
switch (audio_format->format) {
|
||||
case SAMPLE_FORMAT_S8:
|
||||
@@ -239,6 +230,16 @@ osx_output_open(void *data, struct audio_format *audio_format, GError **error)
|
||||
break;
|
||||
}
|
||||
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
stream_description.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
|
||||
#endif
|
||||
|
||||
stream_description.mBytesPerPacket =
|
||||
audio_format_frame_size(audio_format);
|
||||
stream_description.mFramesPerPacket = 1;
|
||||
stream_description.mBytesPerFrame = stream_description.mBytesPerPacket;
|
||||
stream_description.mChannelsPerFrame = audio_format->channels;
|
||||
|
||||
result = AudioUnitSetProperty(od->au, kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input, 0,
|
||||
&stream_description,
|
||||
|
@@ -93,7 +93,7 @@ solaris_output_open(void *data, struct audio_format *audio_format,
|
||||
|
||||
/* open the device in non-blocking mode */
|
||||
|
||||
so->fd = open_cloexec(so->device, O_WRONLY|O_NONBLOCK);
|
||||
so->fd = open_cloexec(so->device, O_WRONLY|O_NONBLOCK, 0);
|
||||
if (so->fd < 0) {
|
||||
g_set_error(error, solaris_output_quark(), errno,
|
||||
"Failed to open %s: %s",
|
||||
|
@@ -303,7 +303,7 @@ ao_wait(struct audio_output *ao)
|
||||
GTimeVal tv;
|
||||
g_get_current_time(&tv);
|
||||
g_time_val_add(&tv, delay * 1000);
|
||||
g_cond_timed_wait(ao->cond, ao->mutex, &tv);
|
||||
(void)g_cond_timed_wait(ao->cond, ao->mutex, &tv);
|
||||
|
||||
if (ao->command != AO_COMMAND_NONE)
|
||||
return false;
|
||||
@@ -463,12 +463,9 @@ ao_play_chunk(struct audio_output *ao, const struct music_chunk *chunk)
|
||||
|
||||
/* don't automatically reopen this device for
|
||||
10 seconds */
|
||||
g_mutex_lock(ao->mutex);
|
||||
|
||||
assert(ao->fail_timer == NULL);
|
||||
ao->fail_timer = g_timer_new();
|
||||
|
||||
g_mutex_unlock(ao->mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -356,16 +356,9 @@ player_check_decoder_startup(struct player *player)
|
||||
static bool
|
||||
player_send_silence(struct player *player)
|
||||
{
|
||||
struct music_chunk *chunk;
|
||||
size_t frame_size =
|
||||
audio_format_frame_size(&player->play_audio_format);
|
||||
/* this formula ensures that we don't send
|
||||
partial frames */
|
||||
unsigned num_frames = sizeof(chunk->data) / frame_size;
|
||||
|
||||
assert(audio_format_defined(&player->play_audio_format));
|
||||
|
||||
chunk = music_buffer_allocate(player_buffer);
|
||||
struct music_chunk *chunk = music_buffer_allocate(player_buffer);
|
||||
if (chunk == NULL) {
|
||||
g_warning("Failed to allocate silence buffer");
|
||||
return false;
|
||||
@@ -375,6 +368,12 @@ player_send_silence(struct player *player)
|
||||
chunk->audio_format = player->play_audio_format;
|
||||
#endif
|
||||
|
||||
size_t frame_size =
|
||||
audio_format_frame_size(&player->play_audio_format);
|
||||
/* this formula ensures that we don't send
|
||||
partial frames */
|
||||
unsigned num_frames = sizeof(chunk->data) / frame_size;
|
||||
|
||||
chunk->times = -1.0; /* undefined time stamp */
|
||||
chunk->length = num_frames * frame_size;
|
||||
memset(chunk->data, 0, chunk->length);
|
||||
@@ -396,8 +395,6 @@ static bool player_seek_decoder(struct player *player)
|
||||
{
|
||||
struct song *song = pc.next_song;
|
||||
struct decoder_control *dc = player->dc;
|
||||
double where;
|
||||
bool ret;
|
||||
|
||||
assert(pc.next_song != NULL);
|
||||
|
||||
@@ -413,8 +410,7 @@ static bool player_seek_decoder(struct player *player)
|
||||
|
||||
/* re-start the decoder */
|
||||
player_dc_start(player, player->pipe);
|
||||
ret = player_wait_for_decoder(player);
|
||||
if (!ret) {
|
||||
if (!player_wait_for_decoder(player)) {
|
||||
/* decoder failure */
|
||||
player_command_finished();
|
||||
return false;
|
||||
@@ -435,8 +431,7 @@ static bool player_seek_decoder(struct player *player)
|
||||
/* wait for the decoder to complete initialization */
|
||||
|
||||
while (player->decoder_starting) {
|
||||
ret = player_check_decoder_startup(player);
|
||||
if (!ret) {
|
||||
if (!player_check_decoder_startup(player)) {
|
||||
/* decoder failure */
|
||||
player_command_finished();
|
||||
return false;
|
||||
@@ -445,14 +440,13 @@ static bool player_seek_decoder(struct player *player)
|
||||
|
||||
/* send the SEEK command */
|
||||
|
||||
where = pc.seek_where;
|
||||
double where = pc.seek_where;
|
||||
if (where > pc.total_time)
|
||||
where = pc.total_time - 0.1;
|
||||
if (where < 0.0)
|
||||
where = 0.0;
|
||||
|
||||
ret = dc_seek(dc, where + song->start_ms / 1000.0);
|
||||
if (!ret) {
|
||||
if (!dc_seek(dc, where + song->start_ms / 1000.0)) {
|
||||
/* decoder failure */
|
||||
player_command_finished();
|
||||
return false;
|
||||
@@ -583,14 +577,12 @@ static void player_process_command(struct player *player)
|
||||
static void
|
||||
update_song_tag(struct song *song, const struct tag *new_tag)
|
||||
{
|
||||
struct tag *old_tag;
|
||||
|
||||
if (song_is_file(song))
|
||||
/* don't update tags of local files, only remote
|
||||
streams may change tags dynamically */
|
||||
return;
|
||||
|
||||
old_tag = song->tag;
|
||||
struct tag *old_tag = song->tag;
|
||||
song->tag = tag_dup(new_tag);
|
||||
|
||||
if (old_tag != NULL)
|
||||
@@ -648,15 +640,14 @@ static bool
|
||||
play_next_chunk(struct player *player)
|
||||
{
|
||||
struct decoder_control *dc = player->dc;
|
||||
struct music_chunk *chunk = NULL;
|
||||
unsigned cross_fade_position;
|
||||
bool success;
|
||||
|
||||
if (!audio_output_all_wait(64))
|
||||
/* the output pipe is still large enough, don't send
|
||||
another chunk */
|
||||
return true;
|
||||
|
||||
unsigned cross_fade_position;
|
||||
struct music_chunk *chunk = NULL;
|
||||
if (player->xfade == XFADE_ENABLED &&
|
||||
player_dc_at_next_song(player) &&
|
||||
(cross_fade_position = music_pipe_size(player->pipe))
|
||||
@@ -694,6 +685,19 @@ play_next_chunk(struct player *player)
|
||||
chunk->mix_ratio = nan("");
|
||||
}
|
||||
|
||||
if (music_chunk_is_empty(other_chunk)) {
|
||||
/* the "other" chunk was a music_chunk
|
||||
which had only a tag, but no music
|
||||
data - we cannot cross-fade that;
|
||||
but since this happens only at the
|
||||
beginning of the new song, we can
|
||||
easily recover by throwing it away
|
||||
now */
|
||||
music_buffer_return(player_buffer,
|
||||
other_chunk);
|
||||
other_chunk = NULL;
|
||||
}
|
||||
|
||||
chunk->other = other_chunk;
|
||||
} else {
|
||||
/* there are not enough decoded chunks yet */
|
||||
@@ -732,9 +736,7 @@ play_next_chunk(struct player *player)
|
||||
|
||||
/* play the current chunk */
|
||||
|
||||
success = play_chunk(player->song, chunk, &player->play_audio_format);
|
||||
|
||||
if (!success) {
|
||||
if (!play_chunk(player->song, chunk, &player->play_audio_format)) {
|
||||
music_buffer_return(player_buffer, chunk);
|
||||
|
||||
player_lock();
|
||||
@@ -776,11 +778,9 @@ play_next_chunk(struct player *player)
|
||||
static bool
|
||||
player_song_border(struct player *player)
|
||||
{
|
||||
char *uri;
|
||||
|
||||
player->xfade = XFADE_UNKNOWN;
|
||||
|
||||
uri = song_get_uri(player->song);
|
||||
char *uri = song_get_uri(player->song);
|
||||
g_message("played \"%s\"", uri);
|
||||
g_free(uri);
|
||||
|
||||
@@ -875,16 +875,17 @@ static void do_play(struct decoder_control *dc)
|
||||
|
||||
if (player.decoder_starting) {
|
||||
/* wait until the decoder is initialized completely */
|
||||
bool success;
|
||||
const struct song *song;
|
||||
|
||||
success = player_check_decoder_startup(&player);
|
||||
if (!success)
|
||||
if (!player_check_decoder_startup(&player))
|
||||
break;
|
||||
|
||||
/* seek to the beginning of the range */
|
||||
song = decoder_current_song(dc);
|
||||
const struct song *song = decoder_current_song(dc);
|
||||
if (song != NULL && song->start_ms > 0 &&
|
||||
/* we must not send a seek command until
|
||||
the decoder is initialized
|
||||
completely */
|
||||
!player.decoder_starting &&
|
||||
!dc_seek(dc, song->start_ms / 1000.0))
|
||||
player_dc_stop(&player);
|
||||
|
||||
@@ -1092,10 +1093,9 @@ static gpointer player_task(G_GNUC_UNUSED gpointer arg)
|
||||
|
||||
void player_create(void)
|
||||
{
|
||||
GError *e = NULL;
|
||||
|
||||
assert(pc.thread == NULL);
|
||||
|
||||
GError *e = NULL;
|
||||
pc.thread = g_thread_create(player_task, NULL, true, &e);
|
||||
if (pc.thread == NULL)
|
||||
MPD_ERROR("Failed to spawn player task: %s", e->message);
|
||||
|
@@ -47,7 +47,7 @@ poison_noaccess(void *p, size_t length)
|
||||
memset(p, 0x01, length);
|
||||
|
||||
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
||||
VALGRIND_MAKE_MEM_NOACCESS(p, length);
|
||||
(void)VALGRIND_MAKE_MEM_NOACCESS(p, length);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
@@ -68,7 +68,7 @@ poison_undefined(void *p, size_t length)
|
||||
memset(p, 0x02, length);
|
||||
|
||||
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
||||
VALGRIND_MAKE_MEM_UNDEFINED(p, length);
|
||||
(void)VALGRIND_MAKE_MEM_UNDEFINED(p, length);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
Reference in New Issue
Block a user