Commit 134a9ab3 authored by Led's avatar Led

0.12.1

parent 3e53b9d5
ver 0.12.1 (2006/10/10)
* Fix segfault when scanning an MP3 that has a Xing tag with 0 frames
* Fix segfault when there's no audio output specified and one can't be detected
* Fix handling of escaping in quotes
* Allow a quality of -1 to be specified for shout outputs
* A few minor cleanups
ver 0.12.0 (2006/9/22)
* New audio output code which supports:
* A plugin-like architecture
......
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.59 for mpd 0.12.0.
# Generated by GNU Autoconf 2.59 for mpd 0.12.1.
#
# Report bugs to <warren.dukes@gmail.com>.
#
......@@ -423,8 +423,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='mpd'
PACKAGE_TARNAME='mpd'
PACKAGE_VERSION='0.12.0'
PACKAGE_STRING='mpd 0.12.0'
PACKAGE_VERSION='0.12.1'
PACKAGE_STRING='mpd 0.12.1'
PACKAGE_BUGREPORT='warren.dukes@gmail.com'
# Factoring default headers for most tests.
......@@ -965,7 +965,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures mpd 0.12.0 to adapt to many kinds of systems.
\`configure' configures mpd 0.12.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
......@@ -1031,7 +1031,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of mpd 0.12.0:";;
short | recursive ) echo "Configuration of mpd 0.12.1:";;
esac
cat <<\_ACEOF
......@@ -1236,7 +1236,7 @@ fi
test -n "$ac_init_help" && exit 0
if $ac_init_version; then
cat <<\_ACEOF
mpd configure 0.12.0
mpd configure 0.12.1
generated by GNU Autoconf 2.59
Copyright (C) 2003 Free Software Foundation, Inc.
......@@ -1250,7 +1250,7 @@ cat >&5 <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by mpd $as_me 0.12.0, which was
It was created by mpd $as_me 0.12.1, which was
generated by GNU Autoconf 2.59. Invocation command line was
$ $0 $@
......@@ -18791,7 +18791,7 @@ fi
cat >>confdefs.h <<\_ACEOF
#define PROTOCOL_VERSION "0.12.0"
#define PROTOCOL_VERSION "0.12.1"
_ACEOF
......@@ -27401,7 +27401,7 @@ _ASBOX
} >&5
cat >&5 <<_CSEOF
This file was extended by mpd $as_me 0.12.0, which was
This file was extended by mpd $as_me 0.12.1, which was
generated by GNU Autoconf 2.59. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
......@@ -27464,7 +27464,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
mpd config.status 0.12.0
mpd config.status 0.12.1
configured by $0, generated by GNU Autoconf 2.59,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
......
dnl AC_INIT(src/main.c)
dnl AM_INIT_AUTOMAKE(mpd, 0.12.0)
dnl AM_INIT_AUTOMAKE(mpd, 0.12.1)
AC_PREREQ(2.58)
AC_INIT(mpd, 0.12.0, warren.dukes@gmail.com)
AC_INIT(mpd, 0.12.1, warren.dukes@gmail.com)
AM_INIT_AUTOMAKE($PACKAGE_NAME, $PACKAGE_VERSION)
AC_SUBST(MPD_LIBS)
......@@ -16,7 +16,7 @@ AC_PROG_LIBTOOL
AC_PROG_MAKE_SET
AM_CONFIG_HEADER(config.h)
AC_DEFINE(PROTOCOL_VERSION, "0.12.0", [The mpd protocol version])
AC_DEFINE(PROTOCOL_VERSION, "0.12.1", [The mpd protocol version])
MPD_LIBS=""
MPD_CFLAGS=""
......
......@@ -121,29 +121,40 @@ void initAudioDriver(void)
audioDeviceStates = (getPlayerData())->audioDeviceStates;
audioOutputArray = xmalloc(sizeof(AudioOutput) * audioOutputArraySize);
i = 0;
param = getNextConfigParam(CONF_AUDIO_OUTPUT, param);
do {
for (i = 0; i < audioOutputArraySize; i++)
{
AudioOutput *output = &audioOutputArray[i];
int j;
if (!initAudioOutput(output, param) && param) {
ERROR("problems configuring output device defined at "
"line %i\n", param->line);
param = getNextConfigParam(CONF_AUDIO_OUTPUT, param);
/* only allow param to be NULL if there just one audioOutput */
assert(param || (audioOutputArraySize == 1));
if (!initAudioOutput(output, param)) {
if (param)
{
ERROR("problems configuring output device "
"defined at line %i\n", param->line);
}
else
{
ERROR("No audio_output specified and unable to "
"detect a default audio output device\n");
}
exit(EXIT_FAILURE);
}
/* require output names to be unique: */
for (j = i; --j >= 0; ) {
for (j = 0; j < i; j++) {
if (!strcmp(output->name, audioOutputArray[j].name)) {
ERROR("output devices with identical "
"names: %s\n", output->name);
exit(EXIT_FAILURE);
}
}
audioDeviceStates[i++] = DEVICE_ENABLE;
} while ((param = getNextConfigParam(CONF_AUDIO_OUTPUT, param)));
audioDeviceStates[i] = DEVICE_ENABLE;
}
}
void getOutputAudioFormat(AudioFormat * inAudioFormat,
......@@ -274,7 +285,7 @@ static void syncAudioDeviceStates(void)
if (!audio_format.channels)
return;
for (i = audioOutputArraySize; --i >= 0; ) {
for (i = 0; i < audioOutputArraySize; ++i ) {
switch (audioDeviceStates[i]) {
case DEVICE_ON:
/* This will reopen only if the audio format changed */
......@@ -303,7 +314,7 @@ static int flushAudioBuffer(void)
syncAudioDeviceStates();
for (i = audioOutputArraySize; --i >= 0; ) {
for (i = 0; i < audioOutputArraySize; ++i) {
if (audioDeviceStates[i] != DEVICE_ON)
continue;
err = playAudioOutput(&audioOutputArray[i], audioBuffer,
......@@ -340,7 +351,7 @@ int openAudioDevice(AudioFormat * audioFormat)
syncAudioDeviceStates();
for (i = audioOutputArraySize; --i >= 0; ) {
for (i = 0; i < audioOutputArraySize; ++i) {
if (audioOutputArray[i].open)
ret = 0;
}
......@@ -349,7 +360,7 @@ int openAudioDevice(AudioFormat * audioFormat)
audioOpened = 1;
else {
/* close all devices if there was an error */
for (i = audioOutputArraySize; --i >= 0; ) {
for (i = 0; i < audioOutputArraySize; ++i) {
closeAudioOutput(&audioOutputArray[i]);
}
......@@ -393,7 +404,7 @@ void dropBufferedAudio(void)
syncAudioDeviceStates();
audioBufferPos = 0;
for (i = audioOutputArraySize; --i >= 0; ) {
for (i = 0; i < audioOutputArraySize; ++i) {
if (audioDeviceStates[i] == DEVICE_ON)
dropBufferedAudioOutput(&audioOutputArray[i]);
}
......@@ -409,7 +420,7 @@ void closeAudioDevice(void)
audioBuffer = NULL;
audioBufferSize = 0;
for (i = audioOutputArraySize; --i >= 0; ) {
for (i = 0; i < audioOutputArraySize; ++i) {
if (audioDeviceStates[i] == DEVICE_ON)
audioDeviceStates[i] = DEVICE_ENABLE;
closeAudioOutput(&audioOutputArray[i]);
......@@ -422,7 +433,7 @@ void sendMetadataToAudioDevice(MpdTag * tag)
{
int i;
for (i = audioOutputArraySize; --i >= 0; ) {
for (i = 0; i < audioOutputArraySize; ++i) {
sendMetadataToAudioOutput(&audioOutputArray[i], tag);
}
}
......@@ -500,7 +511,7 @@ void readAudioDevicesState(FILE *fp)
if (!name || !(++name))
goto errline;
for (i = audioOutputArraySize; --i >= 0; ) {
for (i = 0; i < audioOutputArraySize; ++i) {
if (!strcmp(name, audioOutputArray[i].name)) {
/* devices default to on */
if (!atoi(c))
......
......@@ -81,7 +81,7 @@ static ShoutData *newShoutData(void)
ret->tag = NULL;
ret->tagToSend = 0;
ret->bitrate = -1;
ret->quality = -1.0;
ret->quality = -2.0;
ret->connAttempts = 0;
ret->lastAttempt = 0;
ret->audioFormat = NULL;
......@@ -177,9 +177,9 @@ static int myShout_initDriver(AudioOutput * audioOutput, ConfigParam * param)
sd->quality = strtod(blockParam->value, &test);
if (*test != '\0' || sd->quality < 0.0 || sd->quality > 10.0) {
if (*test != '\0' || sd->quality < -1.0 || sd->quality > 10.0) {
ERROR("shout quality \"%s\" is not a number in the "
"range 0-10, line %i\n", blockParam->value,
"range -1 to 10, line %i\n", blockParam->value,
blockParam->line);
exit(EXIT_FAILURE);
}
......@@ -257,7 +257,7 @@ static int myShout_initDriver(AudioOutput * audioOutput, ConfigParam * param)
shout_set_audio_info(sd->shoutConn, SHOUT_AI_SAMPLERATE, temp);
if (sd->quality >= 0) {
if (sd->quality >= -1.0) {
snprintf(temp, sizeof(temp), "%2.2f", sd->quality);
shout_set_audio_info(sd->shoutConn, SHOUT_AI_QUALITY,
temp);
......@@ -418,7 +418,7 @@ static int initEncoder(ShoutData * sd)
{
vorbis_info_init(&(sd->vi));
if (sd->quality >= 0) {
if (sd->quality >= -1.0) {
if (0 != vorbis_encode_init_vbr(&(sd->vi),
sd->audioFormat->channels,
sd->audioFormat->sampleRate,
......
......@@ -24,7 +24,7 @@
#include <ctype.h>
inline static
static inline
int
isWhiteSpace(char c)
{
......@@ -38,22 +38,15 @@ int buffer2array(char *buffer, char *array[], const int max)
while (*c != '\0' && i < max) {
if (*c == '\"') {
int escape = 0;
array[i++] = ++c;
while (*c != '\0') {
if (*c == '\"') {
if (escape) {
memmove(c - 1, c,
strlen(c) + 1);
if (*c == '"')
break;
} else {
*(c++) = '\0';
break;
}
} else if (*c == '\\' && escape)
*(c++) = '\0';
break;
}
else if (*(c++) == '\\' && *c != '\0') {
memmove(c - 1, c, strlen(c) + 1);
escape = (*(c++) != '\\') ? 0 : !escape;
}
}
} else {
while (isWhiteSpace(*c))
......@@ -83,44 +76,56 @@ int main()
{
char *a[4] = { NULL };
char *b;
int i, max;
int max;
b = xstrdup("lsinfo \"/some/dir/name \\\"test\\\"\"");
b = strdup("lsinfo \"/some/dir/name \\\"test\\\"\"");
max = buffer2array(b, a, 4);
assert( !strcmp("lsinfo", a[0]) );
assert( !strcmp("/some/dir/name \"test\"", a[1]) );
assert( !a[2] );
b = xstrdup("lsinfo \"/some/dir/name \\\"test\\\" something else\"");
b = strdup("lsinfo \"/some/dir/name \\\"test\\\" something else\"");
max = buffer2array(b, a, 4);
assert( !strcmp("lsinfo", a[0]) );
assert( !strcmp("/some/dir/name \"test\" something else", a[1]) );
assert( !a[2] );
b = xstrdup("lsinfo \"/some/dir\\\\name\"");
b = strdup("lsinfo \"/some/dir\\\\name\"");
max = buffer2array(b, a, 4);
assert( !strcmp("lsinfo", a[0]) );
assert( !strcmp("/some/dir\\name", a[1]) );
assert( !a[2] );
b = xstrdup("lsinfo \"/some/dir name\"");
b = strdup("lsinfo \"/some/dir name\"");
max = buffer2array(b, a, 4);
assert( !strcmp("lsinfo", a[0]) );
assert( !strcmp("/some/dir name", a[1]) );
assert( !a[2] );
b = xstrdup("lsinfo \"\\\"/some/dir\\\"\"");
b = strdup("lsinfo \"\\\"/some/dir\\\"\"");
max = buffer2array(b, a, 4);
assert( !strcmp("lsinfo", a[0]) );
assert( !strcmp("\"/some/dir\"", a[1]) );
assert( !a[2] );
b = xstrdup("lsinfo \"\\\"/some/dir\\\" x\"");
b = strdup("lsinfo \"\\\"/some/dir\\\" x\"");
max = buffer2array(b, a, 4);
assert( !strcmp("lsinfo", a[0]) );
assert( !strcmp("\"/some/dir\" x", a[1]) );
assert( !a[2] );
b = strdup("lsinfo \"single quote\\'d from php magicquotes\"");
max = buffer2array(b, a, 4);
assert( !strcmp("lsinfo", a[0]) );
assert( !strcmp("single quote\'d from php magicquotes", a[1]) );
assert( !a[2] );
b = strdup("lsinfo \"double quote\\\"d from php magicquotes\"");
max = buffer2array(b, a, 4);
assert( !strcmp("lsinfo", a[0]) );
assert( !strcmp("double quote\"d from php magicquotes", a[1]) );
assert( !a[2] );
return 0;
}
......
......@@ -648,6 +648,33 @@ static int decodeFirstFrame(mp3DecodeData * data, DecoderControl * dc,
ptr = data->stream.anc_ptr;
bitlen = data->stream.anc_bitlen;
/*
* Attempt to calulcate the length of the song from filesize
*/
{
size_t offset = data->inStream->offset;
mad_timer_t duration = data->frame.header.duration;
float frameTime = ((float)mad_timer_count(duration,
MAD_UNITS_MILLISECONDS)) / 1000;
if (data->stream.this_frame != NULL)
offset -= data->stream.bufend - data->stream.this_frame;
else
offset -= data->stream.bufend - data->stream.buffer;
if (data->inStream->size >= offset) {
data->totalTime = ((data->inStream->size - offset) *
8.0) / (data->frame).header.bitrate;
data->maxFrames = data->totalTime / frameTime +
FRAMES_CUSHION;
} else {
data->maxFrames = FRAMES_CUSHION;
data->totalTime = 0;
}
}
/*
* if an xing tag exists, use that!
*/
if (parse_xing(&xing, &ptr, &bitlen)) {
data->foundXing = 1;
data->muteFrame = MUTEFRAME_SKIP;
......@@ -657,31 +684,16 @@ static int decodeFirstFrame(mp3DecodeData * data, DecoderControl * dc,
data->dropSamplesAtEnd = lame.encoderPadding;
}
if (xing.flags & XING_FRAMES) {
if ((xing.flags & XING_FRAMES) && xing.frames) {
mad_timer_t duration = data->frame.header.duration;
mad_timer_multiply(&duration, xing.frames);
data->totalTime = ((float)mad_timer_count(duration, MAD_UNITS_MILLISECONDS)) / 1000;
data->maxFrames = xing.frames;
}
} else {
size_t offset = data->inStream->offset;
mad_timer_t duration = data->frame.header.duration;
float frameTime = ((float)mad_timer_count(duration, MAD_UNITS_MILLISECONDS)) / 1000;
if (data->stream.this_frame != NULL)
offset -= data->stream.bufend - data->stream.this_frame;
else
offset -= data->stream.bufend - data->stream.buffer;
if (data->inStream->size >= offset) {
data->totalTime = ((data->inStream->size - offset) * 8.0) / (data->frame).header.bitrate;
data->maxFrames = data->totalTime / frameTime + FRAMES_CUSHION;
} else {
data->maxFrames = FRAMES_CUSHION;
data->totalTime = 0;
}
}
if (!data->maxFrames) return -1;
data->frameOffset = xmalloc(sizeof(long) * data->maxFrames);
data->times = xmalloc(sizeof(mad_timer_t) * data->maxFrames);
......
......@@ -93,22 +93,28 @@ static void do_log(FILE *fp, const char *fmt, va_list args)
void flushWarningLog(void)
{
char *s;
char *s = warningBuffer;
DEBUG("flushing warning messages\n");
if (warningBuffer == NULL)
return;
s = strtok(warningBuffer, "\n");
while (s != NULL) {
fprintf(stderr, "%s\n", s);
s = strtok(NULL, "\n");
if (warningBuffer != NULL)
{
while (s != NULL) {
char * next = strchr(s, '\n');
if (next != NULL) {
*next = '\0';
next++;
}
fprintf(stderr, "%s\n", s);
s = next;
}
warningBuffer = NULL;
}
free(warningBuffer);
warningBuffer = NULL;
warningFlushed = 1;
DEBUG("done flushing warning messages\n");
}
void initLog(const int verbose)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment