diff options
author | Max Kellermann <max@duempel.org> | 2011-01-07 23:52:23 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2011-01-07 23:52:23 +0100 |
commit | 1a2ea4c06cd9fd648bb0243a0dfd9e0b960a6788 (patch) | |
tree | 8a13ed86728b59caebd86dc7a1287c234b4985f1 | |
parent | a800afcbf8845df0edc6aee3bb48036bba34e255 (diff) | |
parent | 8c0afd8557b1823e2df94c9f4de90c29eafbf035 (diff) | |
download | mpd-1a2ea4c06cd9fd648bb0243a0dfd9e0b960a6788.tar.gz mpd-1a2ea4c06cd9fd648bb0243a0dfd9e0b960a6788.tar.xz mpd-1a2ea4c06cd9fd648bb0243a0dfd9e0b960a6788.zip |
Merge branch 'v0.16.x'
Conflicts:
NEWS
configure.ac
Diffstat (limited to '')
-rw-r--r-- | NEWS | 20 | ||||
-rw-r--r-- | configure.ac | 32 | ||||
-rw-r--r-- | m4/faad.m4 | 12 | ||||
-rw-r--r-- | m4/mpd_check_cflag.m4 | 4 | ||||
-rw-r--r-- | m4/pretty_print.m4 | 12 | ||||
-rw-r--r-- | src/audio_check.h | 2 | ||||
-rw-r--r-- | src/decoder/mad_decoder_plugin.c | 4 | ||||
-rw-r--r-- | src/directory.h | 4 | ||||
-rw-r--r-- | src/encoder/lame_encoder.c | 7 | ||||
-rw-r--r-- | src/output/httpd_client.c | 3 | ||||
-rw-r--r-- | src/output/osx_plugin.c | 19 | ||||
-rw-r--r-- | src/output/solaris_output_plugin.c | 2 | ||||
-rw-r--r-- | src/output_thread.c | 5 | ||||
-rw-r--r-- | src/player_thread.c | 72 | ||||
-rw-r--r-- | src/poison.h | 4 |
15 files changed, 115 insertions, 87 deletions
@@ -5,6 +5,21 @@ ver 0.17 (2010/??/??) - osx: allow user to specify other audio devices +ver 0.16.1 (2010/??/??) +* 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 +* 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 @@ -119,6 +134,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 diff --git a/configure.ac b/configure.ac index 0b92e70f5..a4ebde3a0 100644 --- a/configure.ac +++ b/configure.ac @@ -162,7 +162,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], @@ -1510,23 +1510,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]) @@ -1534,7 +1534,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]) @@ -1542,23 +1542,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) @@ -1567,14 +1567,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]) @@ -1582,7 +1582,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]) @@ -1590,20 +1590,20 @@ 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]) results(cdio_paranoia, [CDIO_PARANOIA]) -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 diff --git a/m4/faad.m4 b/m4/faad.m4 index f6447b0fb..007787557 100644 --- a/m4/faad.m4 +++ b/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])]) diff --git a/m4/mpd_check_cflag.m4 b/m4/mpd_check_cflag.m4 index 9b5788f7b..8e7144936 100644 --- a/m4/mpd_check_cflag.m4 +++ b/m4/mpd_check_cflag.m4 @@ -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" ]) diff --git a/m4/pretty_print.m4 b/m4/pretty_print.m4 index a22357a8d..687dceefe 100644 --- a/m4/pretty_print.m4 +++ b/m4/pretty_print.m4 @@ -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" ]) diff --git a/src/audio_check.h b/src/audio_check.h index cc08c9ba1..4862e7f15 100644 --- a/src/audio_check.h +++ b/src/audio_check.h @@ -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); diff --git a/src/decoder/mad_decoder_plugin.c b/src/decoder/mad_decoder_plugin.c index a11d1b020..2c2906c5c 100644 --- a/src/decoder/mad_decoder_plugin.c +++ b/src/decoder/mad_decoder_plugin.c @@ -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 */ diff --git a/src/directory.h b/src/directory.h index dde741a71..69e2b3638 100644 --- a/src/directory.h +++ b/src/directory.h @@ -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; diff --git a/src/encoder/lame_encoder.c b/src/encoder/lame_encoder.c index a8ef72020..df843471b 100644 --- a/src/encoder/lame_encoder.c +++ b/src/encoder/lame_encoder.c @@ -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"); diff --git a/src/output/httpd_client.c b/src/output/httpd_client.c index 6bd095838..f5e14925b 100644 --- a/src/output/httpd_client.c +++ b/src/output/httpd_client.c @@ -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. diff --git a/src/output/osx_plugin.c b/src/output/osx_plugin.c index 9c3c2b1ba..b6d42c8f6 100644 --- a/src/output/osx_plugin.c +++ b/src/output/osx_plugin.c @@ -332,15 +332,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: @@ -357,6 +348,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, diff --git a/src/output/solaris_output_plugin.c b/src/output/solaris_output_plugin.c index deb3298a5..22c583805 100644 --- a/src/output/solaris_output_plugin.c +++ b/src/output/solaris_output_plugin.c @@ -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", diff --git a/src/output_thread.c b/src/output_thread.c index 380956fac..a5244c693 100644 --- a/src/output_thread.c +++ b/src/output_thread.c @@ -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; } diff --git a/src/player_thread.c b/src/player_thread.c index 2d8822eb0..cce51c1a7 100644 --- a/src/player_thread.c +++ b/src/player_thread.c @@ -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); diff --git a/src/poison.h b/src/poison.h index 9c7052c91..3654f2e9c 100644 --- a/src/poison.h +++ b/src/poison.h @@ -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 } |