From a0dd1a1b8bd931c4e7256d389646f25bdcc400c2 Mon Sep 17 00:00:00 2001 From: Alex Viskovatoff Date: Tue, 21 Dec 2010 07:24:43 +0100 Subject: audio_check: fix parameter in prototype --- src/audio_check.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') 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); -- cgit v1.2.3 From 144ad7992e16f82bf068bf5f4b397729aeb40a61 Mon Sep 17 00:00:00 2001 From: Alex Viskovatoff Date: Tue, 21 Dec 2010 07:27:35 +0100 Subject: output/solaris: add missing parameter to open_cloexec() call --- src/output/solaris_output_plugin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') 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", -- cgit v1.2.3 From 41fdcf328c0a08fe9adb4007a60c007167054862 Mon Sep 17 00:00:00 2001 From: Alex Viskovatoff Date: Mon, 20 Dec 2010 19:21:53 -0800 Subject: decoder/mad: work around build failure on Solaris Rename the "version" struct, because it seems to be a reserved name on Solaris: "src/decoder/mad_decoder_plugin.c", line 550: (enum) tag redeclared: version cc: acomp failed for src/decoder/mad_decoder_plugin.c --- src/decoder/mad_decoder_plugin.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') 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 */ -- cgit v1.2.3 From fb00e7fddc0e1d03cf26533a8b64c7778e5920ae Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 21 Dec 2010 08:05:36 +0100 Subject: add void casts to suppress "result unused" warnings (clang) --- src/output_thread.c | 2 +- src/poison.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/output_thread.c b/src/output_thread.c index 380956fac..a334fcef5 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; 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 } -- cgit v1.2.3 From 546232b1c02d4e2c408eb9b0055068fc8204e977 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 21 Dec 2010 19:54:44 +0100 Subject: zeroconf-bonjour: use g_htons() instead of htons() Fixes the gcc warning "implicit declaration of function 'htons'". --- src/zeroconf-bonjour.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/zeroconf-bonjour.c b/src/zeroconf-bonjour.c index 4e06319e7..6ad2a2bac 100644 --- a/src/zeroconf-bonjour.c +++ b/src/zeroconf-bonjour.c @@ -62,7 +62,7 @@ void init_zeroconf_osx(const char *serviceName) DNSServiceErrorType error = DNSServiceRegister(&dnsReference, 0, 0, serviceName, SERVICE_TYPE, NULL, NULL, - htons(listen_port), 0, + g_htons(listen_port), 0, NULL, dnsRegisterCallback, NULL); -- cgit v1.2.3 From 60b4f6b3eb789f7e96939b770bfc84cd5f569ca4 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 21 Dec 2010 19:53:17 +0100 Subject: directory: fix warning "comparison between signed and unsigned" Cast the constant to dev_t, not to unsigned. --- src/directory.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/directory.h b/src/directory.h index 8207bd3a2..ac2310429 100644 --- a/src/directory.h +++ b/src/directory.h @@ -28,8 +28,8 @@ #define DIRECTORY_DIR "directory: " -#define DEVICE_INARCHIVE (unsigned)(-1) -#define DEVICE_CONTAINER (unsigned)(-2) +#define DEVICE_INARCHIVE (dev_t)(-1) +#define DEVICE_CONTAINER (dev_t)(-2) struct directory { struct dirvec children; -- cgit v1.2.3 From b5645ab29f4be93ef43d9995f03b48b942cdaa14 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 7 Jan 2011 17:15:37 +0100 Subject: output/osx: fix up audio format first, then apply it to device This is a MPD 0.16 regression: when playing a 24 bit file, the switch to 16 bit was made only partially, after mBytesPerPacket and mBytesPerFrame had already been applied. That means mBytesPerFrame referred to 24 bit, and mBitsPerChannel referred to 16 bits. Of course, that cannot work. --- src/output/osx_plugin.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/output/osx_plugin.c b/src/output/osx_plugin.c index 17d138d35..ce82656bd 100644 --- a/src/output/osx_plugin.c +++ b/src/output/osx_plugin.c @@ -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, -- cgit v1.2.3 From 4f2d67dfb036e38be3bdb67d95eeb64bb7747d4f Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 7 Jan 2011 18:00:12 +0100 Subject: output/httpd: define G_LOG_DOMAIN in httpd_client.c --- src/output/httpd_client.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/output/httpd_client.c b/src/output/httpd_client.c index 52a398e3b..adbdf7326 100644 --- a/src/output/httpd_client.c +++ b/src/output/httpd_client.c @@ -27,6 +27,9 @@ #include #include +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "httpd_output" + struct httpd_client { /** * The httpd output object this client is connected to. -- cgit v1.2.3 From 0022fb100b7d22b9612474ebee944e66c2a7b33b Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 7 Jan 2011 19:37:39 +0100 Subject: encoder/lame: explicitly configure the output sample rate When you don't explicitly set an output sample rate, liblame tries to guess an output sample rate from the input sample rate. You would think that this "guessing" consists of just setting both equal, but that is not the case. For 44.1kHz at 96kbit/s, liblame chooses 32kHz. This patch explicitly configures the output sample rate, to stop the bad guessing. --- src/encoder/lame_encoder.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/encoder/lame_encoder.c b/src/encoder/lame_encoder.c index acaf4470f..6c8f20890 100644 --- a/src/encoder/lame_encoder.c +++ b/src/encoder/lame_encoder.c @@ -169,6 +169,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"); -- cgit v1.2.3 From af892e7e804ccf96356e8f71239a1bce9616da02 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 7 Jan 2011 22:29:47 +0100 Subject: player_thread: make variables more local --- src/player_thread.c | 55 ++++++++++++++++++----------------------------------- 1 file changed, 19 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/player_thread.c b/src/player_thread.c index 2d8822eb0..cdcff3f92 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)) @@ -732,9 +723,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 +765,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,15 +862,12 @@ 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 && !dc_seek(dc, song->start_ms / 1000.0)) player_dc_stop(&player); @@ -1092,10 +1076,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); -- cgit v1.2.3 From 4c09aeb5a1ac7dbf80af680c18f4e36d4776dc8c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 7 Jan 2011 22:51:50 +0100 Subject: player_thread: fix assertion failure due to early seek Until the decoder plugin has called decoder_initialized(), the player may not submit seek commands. This however could occur with a slow decoder and a CUE file with a virtual song offset. This patch adds another check. --- src/player_thread.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/player_thread.c b/src/player_thread.c index cdcff3f92..776d6667f 100644 --- a/src/player_thread.c +++ b/src/player_thread.c @@ -869,6 +869,10 @@ static void do_play(struct decoder_control *dc) /* seek to the beginning of the range */ 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); -- cgit v1.2.3 From 5f06999686b1c02c3dc612fe8a6a84ebecc76405 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 7 Jan 2011 23:08:18 +0100 Subject: output_thread: fix double lock During the whole output thread, the audio_output object is locked, and it is only unlocked while waiting for the GCond and while running a plugin method. The error handler in ao_play_chunk() attempted to lock the object again, which was code from MPD 0.15.x which should have been removed a long time ago. --- src/output_thread.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/output_thread.c b/src/output_thread.c index a334fcef5..a5244c693 100644 --- a/src/output_thread.c +++ b/src/output_thread.c @@ -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; } -- cgit v1.2.3 From 2a56300f7bad00860f5ff44dfea061386173a852 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 7 Jan 2011 23:45:51 +0100 Subject: player_thread: discard empty chunks while cross-fading When a music_chunk to be crossfaded consists only of a tag, cross-fading is not possible, and led to an assertion failure. This patch just discards those, as if cross-fading was not enabled. --- src/player_thread.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/player_thread.c b/src/player_thread.c index 776d6667f..cce51c1a7 100644 --- a/src/player_thread.c +++ b/src/player_thread.c @@ -685,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 */ -- cgit v1.2.3