Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b552e9a120 | ||
|
|
5923cfcde3 | ||
|
|
e3f4c7b91c | ||
|
|
54294366d5 | ||
|
|
4a7abc9d44 | ||
|
|
589bb54111 | ||
|
|
64dacd175a | ||
|
|
625e4755d1 | ||
|
|
676739c426 | ||
|
|
0fec8e0864 | ||
|
|
1f976d6e54 | ||
|
|
a4908dca42 | ||
|
|
8b055c3127 | ||
|
|
172182b18f | ||
|
|
898a13f196 | ||
|
|
b97e92468f |
19
NEWS
19
NEWS
@@ -1,3 +1,22 @@
|
||||
ver 0.15.13 (2010/10/10)
|
||||
* output_thread: fix race condition after CANCEL command
|
||||
* output:
|
||||
- httpd: fix random data in stream title
|
||||
- httpd: MIME type audio/ogg for Ogg Vorbis
|
||||
* input:
|
||||
- rewind: update MIME not only once
|
||||
- rewind: enable for MMS
|
||||
|
||||
|
||||
ver 0.15.12 (2010/07/20)
|
||||
* input:
|
||||
- curl: remove assertion after curl_multi_fdset()
|
||||
* tags:
|
||||
- rva2: set "gain", not "peak"
|
||||
* decoders:
|
||||
- wildmidi: support version 0.2.3
|
||||
|
||||
|
||||
ver 0.15.11 (2010/06/14)
|
||||
* tags:
|
||||
- ape: support album artist
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
AC_PREREQ(2.60)
|
||||
AC_INIT(mpd, 0.15.11, musicpd-dev-team@lists.sourceforge.net)
|
||||
AC_INIT(mpd, 0.15.13, musicpd-dev-team@lists.sourceforge.net)
|
||||
AC_CONFIG_SRCDIR([src/main.c])
|
||||
AM_INIT_AUTOMAKE([foreign 1.9 dist-bzip2])
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
@@ -950,6 +950,10 @@ if test x$enable_wildmidi = xyes; then
|
||||
AC_CHECK_LIB(WildMidi, WildMidi_Init,,
|
||||
AC_MSG_ERROR([libwildmidi not found]))
|
||||
|
||||
AC_CHECK_LIB(WildMidi, WildMidi_SampledSeek,
|
||||
[AC_DEFINE(HAVE_WILDMIDI_SAMPLED_SEEK, 1,
|
||||
[Defined if WildMidi_SampledSeek() is available (libwildmidi <= 0.2.2)])])
|
||||
|
||||
CFLAGS=$oldcflags
|
||||
LIBS=$oldlibs
|
||||
CPPFLAGS=$oldcppflags
|
||||
|
||||
@@ -209,14 +209,14 @@ mp3_fill_buffer(struct mp3_data *data)
|
||||
|
||||
#ifdef HAVE_ID3TAG
|
||||
/* Parse mp3 RVA2 frame. Shamelessly stolen from madplay. */
|
||||
static int parse_rva2(struct id3_tag * tag, struct replay_gain_info * replay_gain_info)
|
||||
static bool
|
||||
parse_rva2(struct id3_tag *tag, struct replay_gain_info *replay_gain_info)
|
||||
{
|
||||
struct id3_frame const * frame;
|
||||
|
||||
id3_latin1_t const *id;
|
||||
id3_byte_t const *data;
|
||||
id3_length_t length;
|
||||
int found;
|
||||
|
||||
enum {
|
||||
CHANNEL_OTHER = 0x00,
|
||||
@@ -230,18 +230,18 @@ static int parse_rva2(struct id3_tag * tag, struct replay_gain_info * replay_gai
|
||||
CHANNEL_SUBWOOFER = 0x08
|
||||
};
|
||||
|
||||
found = 0;
|
||||
|
||||
/* relative volume adjustment information */
|
||||
|
||||
frame = id3_tag_findframe(tag, "RVA2", 0);
|
||||
if (!frame) return 0;
|
||||
if (frame == NULL)
|
||||
return false;
|
||||
|
||||
id = id3_field_getlatin1(id3_frame_field(frame, 0));
|
||||
data = id3_field_getbinarydata(id3_frame_field(frame, 1),
|
||||
&length);
|
||||
|
||||
if (!id || !data) return 0;
|
||||
if (id == NULL || data == NULL)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* "The 'identification' string is used to identify the
|
||||
@@ -277,22 +277,21 @@ static int parse_rva2(struct id3_tag * tag, struct replay_gain_info * replay_gai
|
||||
|
||||
voladj_float = (double) voladj_fixed / 512;
|
||||
|
||||
replay_gain_info->tuples[REPLAY_GAIN_TRACK].peak = voladj_float;
|
||||
replay_gain_info->tuples[REPLAY_GAIN_ALBUM].peak = voladj_float;
|
||||
replay_gain_info->tuples[REPLAY_GAIN_TRACK].gain = voladj_float;
|
||||
replay_gain_info->tuples[REPLAY_GAIN_ALBUM].gain = voladj_float;
|
||||
|
||||
g_debug("parseRVA2: Relative Volume "
|
||||
"%+.1f dB adjustment (%s)\n",
|
||||
voladj_float, id);
|
||||
|
||||
found = 1;
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
|
||||
data += 4 + peak_bytes;
|
||||
length -= 4 + peak_bytes;
|
||||
}
|
||||
|
||||
return found;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -99,7 +99,11 @@ wildmidi_file_decode(struct decoder *decoder, const char *path_fs)
|
||||
unsigned long seek_where = WILDMIDI_SAMPLE_RATE *
|
||||
decoder_seek_where(decoder);
|
||||
|
||||
#ifdef HAVE_WILDMIDI_SAMPLED_SEEK
|
||||
WildMidi_SampledSeek(wm, &seek_where);
|
||||
#else
|
||||
WildMidi_FastSeek(wm, &seek_where);
|
||||
#endif
|
||||
decoder_command_finished(decoder);
|
||||
cmd = DECODE_COMMAND_NONE;
|
||||
}
|
||||
|
||||
@@ -95,6 +95,7 @@ icy_server_metadata_page(const struct tag *tag, ...)
|
||||
gchar stream_title[(1 + 255 - 28) * 16]; // Length + Metadata -
|
||||
// "StreamTitle='';StreamUrl='';"
|
||||
// = 4081 - 28
|
||||
stream_title[0] = '\0';
|
||||
|
||||
last_item = -1;
|
||||
|
||||
|
||||
@@ -241,7 +241,6 @@ input_curl_select(struct input_curl *c)
|
||||
fd_set rfds, wfds, efds;
|
||||
int max_fd, ret;
|
||||
CURLMcode mcode;
|
||||
/* XXX hard coded timeout value.. */
|
||||
struct timeval timeout = {
|
||||
.tv_sec = 1,
|
||||
.tv_usec = 0,
|
||||
@@ -260,7 +259,23 @@ input_curl_select(struct input_curl *c)
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert(max_fd >= 0);
|
||||
#if LIBCURL_VERSION_NUM >= 0x070f04
|
||||
long timeout2;
|
||||
mcode = curl_multi_timeout(c->multi, &timeout2);
|
||||
if (mcode != CURLM_OK) {
|
||||
g_warning("curl_multi_timeout() failed: %s\n",
|
||||
curl_multi_strerror(mcode));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (timeout2 >= 0) {
|
||||
if (timeout2 > 10000)
|
||||
timeout2 = 10000;
|
||||
|
||||
timeout.tv_sec = timeout2 / 1000;
|
||||
timeout.tv_usec = (timeout2 % 1000) * 1000;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = select(max_fd + 1, &rfds, &wfds, &efds, &timeout);
|
||||
if (ret < 0)
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
#include "config.h"
|
||||
#include "input/rewind_input_plugin.h"
|
||||
#include "input/curl_input_plugin.h"
|
||||
#ifdef ENABLE_MMS
|
||||
#include "input/mms_input_plugin.h"
|
||||
#endif
|
||||
#include "input_plugin.h"
|
||||
#include "tag.h"
|
||||
|
||||
@@ -86,10 +89,11 @@ copy_attributes(struct input_stream *dest)
|
||||
dest->size = src->size;
|
||||
dest->offset = src->offset;
|
||||
|
||||
if (dest->mime == NULL && src->mime != NULL)
|
||||
/* this is set only once, and the duplicated pointer
|
||||
is freed by input_stream_close() */
|
||||
if (src->mime != NULL) {
|
||||
if (dest->mime != NULL)
|
||||
g_free(dest->mime);
|
||||
dest->mime = g_strdup(src->mime);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -219,7 +223,11 @@ input_rewind_open(struct input_stream *is)
|
||||
assert(is != NULL);
|
||||
assert(is->offset == 0);
|
||||
|
||||
if (is->plugin != &input_plugin_curl)
|
||||
if (is->plugin != &input_plugin_curl
|
||||
#ifdef ENABLE_MMS
|
||||
&& is->plugin != &input_plugin_mms
|
||||
#endif
|
||||
)
|
||||
/* due to limitations in the input_plugin API, we only
|
||||
(explicitly) support the CURL input plugin */
|
||||
return;
|
||||
@@ -229,7 +237,8 @@ input_rewind_open(struct input_stream *is)
|
||||
|
||||
/* move the CURL input stream to c->input */
|
||||
c->input = *is;
|
||||
input_curl_reinit(&c->input);
|
||||
if (is->plugin == &input_plugin_curl)
|
||||
input_curl_reinit(&c->input);
|
||||
|
||||
/* convert the existing input_stream pointer to a "rewind"
|
||||
input stream */
|
||||
|
||||
@@ -48,3 +48,10 @@ void notify_signal(struct notify *notify)
|
||||
g_cond_signal(notify->cond);
|
||||
g_mutex_unlock(notify->mutex);
|
||||
}
|
||||
|
||||
void notify_clear(struct notify *notify)
|
||||
{
|
||||
g_mutex_lock(notify->mutex);
|
||||
notify->pending = false;
|
||||
g_mutex_unlock(notify->mutex);
|
||||
}
|
||||
|
||||
@@ -45,4 +45,9 @@ void notify_wait(struct notify *notify);
|
||||
*/
|
||||
void notify_signal(struct notify *notify);
|
||||
|
||||
/**
|
||||
* Clears a pending notification.
|
||||
*/
|
||||
void notify_clear(struct notify *notify);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -70,7 +70,7 @@ httpd_output_init(G_GNUC_UNUSED const struct audio_format *audio_format,
|
||||
}
|
||||
|
||||
if (strcmp(encoder_name, "vorbis") == 0)
|
||||
httpd->content_type = "application/x-ogg";
|
||||
httpd->content_type = "audio/ogg";
|
||||
else if (strcmp(encoder_name, "lame") == 0)
|
||||
httpd->content_type = "audio/mpeg";
|
||||
else
|
||||
|
||||
@@ -268,6 +268,16 @@ static gpointer audio_output_task(gpointer arg)
|
||||
ao->chunk = NULL;
|
||||
if (ao->open)
|
||||
ao_plugin_cancel(ao->plugin, ao->data);
|
||||
|
||||
/* we must clear the notification now, because
|
||||
the notify_wait() call below must wait
|
||||
until audio_output_all_cancel() has cleared
|
||||
the pipe; if another notification happens
|
||||
to be still pending, we get a race
|
||||
condition with a crash or an assertion
|
||||
failure */
|
||||
notify_clear(&ao->notify);
|
||||
|
||||
ao_command_finished(ao);
|
||||
|
||||
/* the player thread will now clear our music
|
||||
|
||||
Reference in New Issue
Block a user