Commit 9496158b authored by Led's avatar Led

0.12.0.20041026

parent 7473f7ea
ver 0.11.5 (2004/11/1a
1) New id3v1_ecnoding config option to configure the id3v1 tag encoding (patch from dottemag)
2) Strip '\r' from m3u playlists (thank you windows)
3) Use random() instead of rand() for playlist randomizing
4) Fix a bug trying skipping some commented lines in m3u playlist files
5) Fix a bug when fetching metadata from streams that may cause certain weirdnesses
6) Fix a bug where replaygain preamp was used on files w/o replaygain tags
7) Fix a busy loop when trying to prebuffer a nonexistant or missing stream
8) Fix a bug in forgetting to remove leading ' ' in content-type for http streams
9) Check for ice-name in http headers
10) Be sure the strip all '\n' chars in tags
11) Set $HOME env variable when setuid'ing, this should fix the /root/.mcop errors triggered by arts/libao
ver 0.11.4 (2004/7/26)
1) Fixed a segfault when decoding mp3's with corrupt id3v2 tags
2) Fixed a memory leak when encountering id3v2 tags in mp3 decoder
......
......@@ -107,8 +107,10 @@ OBJDUMP = @OBJDUMP@
OGG_CFLAGS = @OGG_CFLAGS@
OGG_LIBS = @OGG_LIBS@
PACKAGE = @PACKAGE@
PKGCONFIG = @PKGCONFIG@
RANLIB = @RANLIB@
RC = @RC@
SHOUTCONFIG = @SHOUTCONFIG@
STRIP = @STRIP@
VERSION = @VERSION@
VORBISENC_LIBS = @VORBISENC_LIBS@
......
0.12
----
*) Abstract audio stuff into a plugin oriented thing
*) audio_ao & audio_oss & audio_shout
*) allow for sending to multiple audio devices
*) Rewrite replaygain stuff:
*) Replay gain struct with album and track gain's and peak's
*) Pass these to replaygain function
......@@ -14,6 +18,13 @@
*) Optimize read() on clients
*) Add libshout && vorbis encoding support
*) clean up code to make more robust (only works for 16-bits)
*) check for memory leaks and such
*) add option for keeping audio devices alive (i.e. send silence even
when stopped/paused), this should also force a consistant
audio format
*) need some way to send metadata through shout plugin
*) cleanup configure script stuff (shout needs vorbisenc)
*) add command
*) command that takes file/url's (no directory's) and returns the songid
......
......@@ -6963,6 +6963,86 @@ int main ()
rm -f conf.aotest
])
dnl XIPH_PATH_SHOUT
dnl Jack Moffitt <jack@icecast.org> 08-06-2001
dnl Rewritten for libshout 2
dnl Brendan Cully <brendan@xiph.org> 20030612
dnl
dnl $Id: shout.m4,v 1.12 2003/07/11 01:26:31 brendan Exp $
# XIPH_PATH_SHOUT([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
# Test for libshout, and define SHOUT_CPPFLAGS SHOUT_CFLAGS SHOUT_LIBS, and
# SHOUT_THREADSAFE
AC_DEFUN([XIPH_PATH_SHOUT],
[dnl
xt_have_shout="no"
SHOUT_THREADSAFE="no"
SHOUT_CPPFLAGS=""
SHOUT_CFLAGS=""
SHOUT_LIBS=""
# NB: PKG_CHECK_MODULES exits if pkg-config is unavailable on the targe
# system, so we can't use it.
# seed pkg-config with the default libshout location
PKG_CONFIG_PATH=${PKG_CONFIG_PATH:-/usr/local/lib/pkgconfig}
export PKG_CONFIG_PATH
# Step 1: Use pkg-config if available
AC_PATH_PROG([PKGCONFIG], [pkg-config], [no])
if test "$PKGCONFIG" != "no" && `$PKGCONFIG --exists shout`
then
SHOUT_CFLAGS=`$PKGCONFIG --variable=cflags_only shout`
SHOUT_CPPFLAGS=`$PKGCONFIG --variable=cppflags shout`
SHOUT_LIBS=`$PKGCONFIG --libs shout`
xt_have_shout="maybe"
else
if test "$PKGCONFIG" != "no"
then
AC_MSG_NOTICE([$PKGCONFIG couldn't find libshout. Try adjusting PKG_CONFIG_PATH.])
fi
# pkg-config unavailable, try shout-config
AC_PATH_PROG([SHOUTCONFIG], [shout-config], [no])
if test "$SHOUTCONFIG" != "no" && test `$SHOUTCONFIG --package` = "libshout"
then
SHOUT_CPPFLAGS=`$SHOUTCONFIG --cppflags`
SHOUT_CFLAGS=`$SHOUTCONFIG --cflags-only`
SHOUT_LIBS=`$SHOUTCONFIG --libs`
xt_have_shout="maybe"
fi
fi
# Now try actually using libshout
if test "$xt_have_shout" != "no"
then
ac_save_CPPFLAGS="$CPPFLAGS"
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CPPFLAGS="$CPPFLAGS $SHOUT_CPPFLAGS"
CFLAGS="$CFLAGS $SHOUT_CFLAGS"
LIBS="$SHOUT_LIBS $LIBS"
AC_CHECK_HEADERS([shout/shout.h], [
AC_CHECK_FUNC([shout_new], [
ifelse([$1], , :, [$1])
xt_have_shout="yes"
])
AC_EGREP_CPP([yes], [#include <shout/shout.h>
#if SHOUT_THREADSAFE
yes
#endif
], [SHOUT_THREADSAFE="yes"])
])
CPPFLAGS="$ac_save_CPPFLAGS"
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
if test "$xt_have_shout" != "yes"
then
ifelse([$2], , :, [$2])
fi
])dnl XIPH_PATH_SHOUT
# Configure paths for libogg
# Jack Moffitt <jack@icecast.org> 10-21-2000
# Shamelessly stolen from Owen Taylor and Manish Singh
......
......@@ -76,6 +76,12 @@
/* Define for ogg vorbis support */
#undef HAVE_OGG
/* Define to enable libshout support */
#undef HAVE_SHOUT
/* Define to 1 if you have the <shout/shout.h> header file. */
#undef HAVE_SHOUT_SHOUT_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
......
......@@ -2,7 +2,7 @@ dnl AC_INIT(src/main.c)
dnl AM_INIT_AUTOMAKE(mpd, 0.10.0)
AC_PREREQ(2.52)
AC_INIT(mpd, 0.11.5, shank@mercury.chem.pitt.edu)
AC_INIT(mpd, 0.12.0, shank@mercury.chem.pitt.edu)
AM_INIT_AUTOMAKE($PACKAGE_NAME, $PACKAGE_VERSION)
dnl MAD wants this stuff
......@@ -32,6 +32,7 @@ fi
MPD_LIBS=""
AC_ARG_ENABLE(audio,[ --disable-audio disable support for playing],,enable_ao=yes)
AC_ARG_ENABLE(shout,[ --disable-shout disable support for streaming through shout],,enable_shout=yes)
AC_ARG_ENABLE(iconv,[ --disable-iconv disable iconv support],,enable_iconv=yes)
AC_ARG_ENABLE(ipv6,[ --disable-ipv6 disable IPv6 support],,enable_ipv6=yes)
AC_ARG_ENABLE(alsa,[ --disable-alsa disable ALSA Mixer support],,enable_alsa=yes)
......@@ -104,6 +105,10 @@ if test x$enable_ao = xyes; then
AC_DEFINE(HAVE_AUDIO, 1, [Define to play audio])
fi
if test x$enable_shout = xyes; then
XIPH_PATH_SHOUT([AC_DEFINE(HAVE_SHOUT, 1, [Define to enable libshout support]) MPD_LIBS="$MPD_LIBS $SHOUT_LIBS" MPD_CFLAGS="$MPD_CFLAGS $SHOUT_CFLAGS"], enable_shout=no)
fi
AC_CHECK_HEADER(sys/soundcard.h,enable_oss=yes,[AC_MSG_WARN(Soundcard headers not found -- disabling OSS mixer);enable_oss=no;AC_DEFINE(NO_OSS_MIXER,1,[Define to disable OSS mixer support])])
if test x$enable_alsa = xyes; then
......@@ -430,8 +435,8 @@ dnl
dnl End of Vorbis Test
dnl
if test x$enable_ogg = xyes; then
MPD_LIBS="$MPD_LIBS $VORBIS_LIBS $VORBISFILE_LIBS"
MPD_CFLAGS="$MPD_CFLAGS $VORBIS_CFLAGS $VORBISFILE_CFLAGS"
MPD_LIBS="$MPD_LIBS $VORBIS_LIBS $VORBISFILE_LIBS $VORBISENC_LIBS"
MPD_CFLAGS="$MPD_CFLAGS $VORBIS_CFLAGS $VORBISFILE_CFLAGS $VORBISENC_CFLAGS"
fi
fi
......@@ -528,6 +533,12 @@ else
echo "Playing audio .................disabled"
fi
if test x$enable_shout = xyes; then
echo "Streaming through shout .......enabled"
else
echo "Streaming through shout .......disabled"
fi
if test x$enable_id3 = xyes; then
echo "ID3 tag support ...............enabled"
if test x$use_mpd_id3tag = xyes; then
......
......@@ -107,8 +107,10 @@ OBJDUMP = @OBJDUMP@
OGG_CFLAGS = @OGG_CFLAGS@
OGG_LIBS = @OGG_LIBS@
PACKAGE = @PACKAGE@
PKGCONFIG = @PKGCONFIG@
RANLIB = @RANLIB@
RC = @RC@
SHOUTCONFIG = @SHOUTCONFIG@
STRIP = @STRIP@
VERSION = @VERSION@
VORBISENC_LIBS = @VORBISENC_LIBS@
......
......@@ -163,6 +163,20 @@ error_file "~/.mpd/mpd.error"
##########################################
################ SHOUT OPTIONS #####################
#
#shout_host "host"
#shout_port "8000"
#shout_user "source"
#shout_password "hackme"
#shout_name "My MPD!"
#shout_mount "/mpd.ogg"
#shout_quality "0.5"
#shout_format "44100:16:1"
#
####################################################
################ MISCELLANEOUS OPTIONS ###################
#
# This setting exists as precaution against attacks.
......
......@@ -14,6 +14,7 @@ mpd_inputPlugins = \
mpd_headers = \
ack.h \
audio.h \
audioOutput.h \
buffer2array.h \
charConv.h \
command.h \
......@@ -55,6 +56,9 @@ mpd_SOURCES = \
$(mpd_headers) \
$(mpd_inputPlugins) \
audio.c \
audioOutput.c \
audioOutput_ao.c \
audioOutput_shout.c \
buffer2array.c \
charConv.c \
command.c \
......
......@@ -107,8 +107,10 @@ OBJDUMP = @OBJDUMP@
OGG_CFLAGS = @OGG_CFLAGS@
OGG_LIBS = @OGG_LIBS@
PACKAGE = @PACKAGE@
PKGCONFIG = @PKGCONFIG@
RANLIB = @RANLIB@
RC = @RC@
SHOUTCONFIG = @SHOUTCONFIG@
STRIP = @STRIP@
VERSION = @VERSION@
VORBISENC_LIBS = @VORBISENC_LIBS@
......@@ -134,6 +136,7 @@ mpd_inputPlugins = \
mpd_headers = \
ack.h \
audio.h \
audioOutput.h \
buffer2array.h \
charConv.h \
command.h \
......@@ -175,6 +178,9 @@ mpd_SOURCES = \
$(mpd_headers) \
$(mpd_inputPlugins) \
audio.c \
audioOutput.c \
audioOutput_ao.c \
audioOutput_shout.c \
buffer2array.c \
charConv.c \
command.c \
......@@ -229,21 +235,23 @@ am__objects_2 = mpd-aac_plugin.$(OBJEXT) mpd-audiofile_plugin.$(OBJEXT) \
mpd-mp3_plugin.$(OBJEXT) mpd-mp4_plugin.$(OBJEXT) \
mpd-ogg_plugin.$(OBJEXT)
am_mpd_OBJECTS = $(am__objects_1) $(am__objects_2) mpd-audio.$(OBJEXT) \
mpd-buffer2array.$(OBJEXT) mpd-charConv.$(OBJEXT) \
mpd-command.$(OBJEXT) mpd-conf.$(OBJEXT) mpd-decode.$(OBJEXT) \
mpd-directory.$(OBJEXT) mpd-inputPlugin.$(OBJEXT) \
mpd-inputStream.$(OBJEXT) mpd-inputStream_file.$(OBJEXT) \
mpd-inputStream_http.$(OBJEXT) mpd-interface.$(OBJEXT) \
mpd-list.$(OBJEXT) mpd-listen.$(OBJEXT) mpd-log.$(OBJEXT) \
mpd-ls.$(OBJEXT) mpd-main.$(OBJEXT) mpd-metadataChunk.$(OBJEXT) \
mpd-myfprintf.$(OBJEXT) mpd-outputBuffer.$(OBJEXT) \
mpd-path.$(OBJEXT) mpd-pcm_utils.$(OBJEXT) \
mpd-permission.$(OBJEXT) mpd-player.$(OBJEXT) \
mpd-playerData.$(OBJEXT) mpd-playlist.$(OBJEXT) \
mpd-replayGain.$(OBJEXT) mpd-sig_handlers.$(OBJEXT) \
mpd-signal_check.$(OBJEXT) mpd-song.$(OBJEXT) \
mpd-stats.$(OBJEXT) mpd-tables.$(OBJEXT) mpd-tag.$(OBJEXT) \
mpd-utils.$(OBJEXT) mpd-volume.$(OBJEXT) mpd-utf8.$(OBJEXT)
mpd-audioOutput.$(OBJEXT) mpd-audioOutput_ao.$(OBJEXT) \
mpd-audioOutput_shout.$(OBJEXT) mpd-buffer2array.$(OBJEXT) \
mpd-charConv.$(OBJEXT) mpd-command.$(OBJEXT) mpd-conf.$(OBJEXT) \
mpd-decode.$(OBJEXT) mpd-directory.$(OBJEXT) \
mpd-inputPlugin.$(OBJEXT) mpd-inputStream.$(OBJEXT) \
mpd-inputStream_file.$(OBJEXT) mpd-inputStream_http.$(OBJEXT) \
mpd-interface.$(OBJEXT) mpd-list.$(OBJEXT) mpd-listen.$(OBJEXT) \
mpd-log.$(OBJEXT) mpd-ls.$(OBJEXT) mpd-main.$(OBJEXT) \
mpd-metadataChunk.$(OBJEXT) mpd-myfprintf.$(OBJEXT) \
mpd-outputBuffer.$(OBJEXT) mpd-path.$(OBJEXT) \
mpd-pcm_utils.$(OBJEXT) mpd-permission.$(OBJEXT) \
mpd-player.$(OBJEXT) mpd-playerData.$(OBJEXT) \
mpd-playlist.$(OBJEXT) mpd-replayGain.$(OBJEXT) \
mpd-sig_handlers.$(OBJEXT) mpd-signal_check.$(OBJEXT) \
mpd-song.$(OBJEXT) mpd-stats.$(OBJEXT) mpd-tables.$(OBJEXT) \
mpd-tag.$(OBJEXT) mpd-utils.$(OBJEXT) mpd-volume.$(OBJEXT) \
mpd-utf8.$(OBJEXT)
mpd_OBJECTS = $(am_mpd_OBJECTS)
mpd_DEPENDENCIES =
mpd_LDFLAGS =
......@@ -257,6 +265,9 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/mpd-aac_plugin.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/mpd-audio.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/mpd-audioOutput.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/mpd-audioOutput_ao.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/mpd-audioOutput_shout.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/mpd-audiofile_plugin.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/mpd-buffer2array.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/mpd-charConv.Po \
......@@ -355,6 +366,9 @@ mpd-mp3_plugin.$(OBJEXT): inputPlugins/mp3_plugin.c
mpd-mp4_plugin.$(OBJEXT): inputPlugins/mp4_plugin.c
mpd-ogg_plugin.$(OBJEXT): inputPlugins/ogg_plugin.c
mpd-audio.$(OBJEXT): audio.c
mpd-audioOutput.$(OBJEXT): audioOutput.c
mpd-audioOutput_ao.$(OBJEXT): audioOutput_ao.c
mpd-audioOutput_shout.$(OBJEXT): audioOutput_shout.c
mpd-buffer2array.$(OBJEXT): buffer2array.c
mpd-charConv.$(OBJEXT): charConv.c
mpd-command.$(OBJEXT): command.c
......@@ -402,6 +416,9 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpd-aac_plugin.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpd-audio.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpd-audioOutput.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpd-audioOutput_ao.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpd-audioOutput_shout.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpd-audiofile_plugin.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpd-buffer2array.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpd-charConv.Po@am__quote@
......@@ -609,6 +626,60 @@ mpd-audio.lo: audio.c
@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mpd_CFLAGS) $(CFLAGS) -c -o mpd-audio.lo `test -f 'audio.c' || echo '$(srcdir)/'`audio.c
mpd-audioOutput.o: audioOutput.c
@AMDEP_TRUE@ source='audioOutput.c' object='mpd-audioOutput.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/mpd-audioOutput.Po' tmpdepfile='$(DEPDIR)/mpd-audioOutput.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mpd_CFLAGS) $(CFLAGS) -c -o mpd-audioOutput.o `test -f 'audioOutput.c' || echo '$(srcdir)/'`audioOutput.c
mpd-audioOutput.obj: audioOutput.c
@AMDEP_TRUE@ source='audioOutput.c' object='mpd-audioOutput.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/mpd-audioOutput.Po' tmpdepfile='$(DEPDIR)/mpd-audioOutput.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mpd_CFLAGS) $(CFLAGS) -c -o mpd-audioOutput.obj `cygpath -w audioOutput.c`
mpd-audioOutput.lo: audioOutput.c
@AMDEP_TRUE@ source='audioOutput.c' object='mpd-audioOutput.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/mpd-audioOutput.Plo' tmpdepfile='$(DEPDIR)/mpd-audioOutput.TPlo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mpd_CFLAGS) $(CFLAGS) -c -o mpd-audioOutput.lo `test -f 'audioOutput.c' || echo '$(srcdir)/'`audioOutput.c
mpd-audioOutput_ao.o: audioOutput_ao.c
@AMDEP_TRUE@ source='audioOutput_ao.c' object='mpd-audioOutput_ao.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/mpd-audioOutput_ao.Po' tmpdepfile='$(DEPDIR)/mpd-audioOutput_ao.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mpd_CFLAGS) $(CFLAGS) -c -o mpd-audioOutput_ao.o `test -f 'audioOutput_ao.c' || echo '$(srcdir)/'`audioOutput_ao.c
mpd-audioOutput_ao.obj: audioOutput_ao.c
@AMDEP_TRUE@ source='audioOutput_ao.c' object='mpd-audioOutput_ao.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/mpd-audioOutput_ao.Po' tmpdepfile='$(DEPDIR)/mpd-audioOutput_ao.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mpd_CFLAGS) $(CFLAGS) -c -o mpd-audioOutput_ao.obj `cygpath -w audioOutput_ao.c`
mpd-audioOutput_ao.lo: audioOutput_ao.c
@AMDEP_TRUE@ source='audioOutput_ao.c' object='mpd-audioOutput_ao.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/mpd-audioOutput_ao.Plo' tmpdepfile='$(DEPDIR)/mpd-audioOutput_ao.TPlo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mpd_CFLAGS) $(CFLAGS) -c -o mpd-audioOutput_ao.lo `test -f 'audioOutput_ao.c' || echo '$(srcdir)/'`audioOutput_ao.c
mpd-audioOutput_shout.o: audioOutput_shout.c
@AMDEP_TRUE@ source='audioOutput_shout.c' object='mpd-audioOutput_shout.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/mpd-audioOutput_shout.Po' tmpdepfile='$(DEPDIR)/mpd-audioOutput_shout.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mpd_CFLAGS) $(CFLAGS) -c -o mpd-audioOutput_shout.o `test -f 'audioOutput_shout.c' || echo '$(srcdir)/'`audioOutput_shout.c
mpd-audioOutput_shout.obj: audioOutput_shout.c
@AMDEP_TRUE@ source='audioOutput_shout.c' object='mpd-audioOutput_shout.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/mpd-audioOutput_shout.Po' tmpdepfile='$(DEPDIR)/mpd-audioOutput_shout.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mpd_CFLAGS) $(CFLAGS) -c -o mpd-audioOutput_shout.obj `cygpath -w audioOutput_shout.c`
mpd-audioOutput_shout.lo: audioOutput_shout.c
@AMDEP_TRUE@ source='audioOutput_shout.c' object='mpd-audioOutput_shout.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/mpd-audioOutput_shout.Plo' tmpdepfile='$(DEPDIR)/mpd-audioOutput_shout.TPlo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mpd_CFLAGS) $(CFLAGS) -c -o mpd-audioOutput_shout.lo `test -f 'audioOutput_shout.c' || echo '$(srcdir)/'`audioOutput_shout.c
mpd-buffer2array.o: buffer2array.c
@AMDEP_TRUE@ source='buffer2array.c' object='mpd-buffer2array.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/mpd-buffer2array.Po' tmpdepfile='$(DEPDIR)/mpd-buffer2array.TPo' @AMDEPBACKSLASH@
......
......@@ -17,110 +17,42 @@
*/
#include "audio.h"
#include "audioOutput.h"
#include "conf.h"
#include "log.h"
#include "sig_handlers.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <signal.h>
#ifdef HAVE_AUDIO
#include <ao/ao.h>
static int audio_write_size;
static int audio_ao_driver_id;
static ao_option * audio_ao_options;
static AudioFormat audio_format;
static ao_device * audio_device = NULL;
#endif
static AudioFormat * audio_configFormat = NULL;
static AudioOutput * aoOutput = NULL;
static AudioOutput * shoutOutput = NULL;
void copyAudioFormat(AudioFormat * dest, AudioFormat * src) {
if(!src) return;
dest->sampleRate = src->sampleRate;
dest->bits = src->bits;
dest->channels = src->channels;
}
void initAudioDriver() {
#ifdef HAVE_AUDIO
ao_info * ai;
char * dup;
char * stk1;
char * stk2;
char * n1;
char * key;
char * value;
char * test;
/*int found;
int i;*/
audio_write_size = strtol((getConf())[CONF_AUDIO_WRITE_SIZE],&test,10);
if (*test!='\0') {
ERROR("\"%s\" is not a valid write size",
(getConf())[CONF_AUDIO_WRITE_SIZE]);
exit(EXIT_FAILURE);
}
audio_ao_options = NULL;
extern AudioOutputPlugin aoPlugin;
extern AudioOutputPlugin shoutPlugin;
ao_initialize();
if(strcmp(AUDIO_AO_DRIVER_DEFAULT,(getConf())[CONF_AO_DRIVER])==0) {
audio_ao_driver_id = ao_default_driver_id();
}
else if((audio_ao_driver_id =
ao_driver_id((getConf())[CONF_AO_DRIVER]))<0) {
ERROR("\"%s\" is not a valid ao driver\n",
(getConf())[CONF_AO_DRIVER]);
exit(EXIT_FAILURE);
}
if((ai = ao_driver_info(audio_ao_driver_id))==NULL) {
ERROR("problems getting ao_driver_info\n");
ERROR("you may not have permission to the audio device\n");
exit(EXIT_FAILURE);
}
void initAudioDriver() {
initAudioOutputPlugins();
loadAudioOutputPlugin(&aoPlugin);
loadAudioOutputPlugin(&shoutPlugin);
dup = strdup((getConf())[CONF_AO_DRIVER_OPTIONS]);
if(strlen(dup)) {
stk1 = NULL;
n1 = strtok_r(dup,";",&stk1);
while(n1) {
stk2 = NULL;
key = strtok_r(n1,"=",&stk2);
if(!key) {
ERROR("problems parsing "
"ao_driver_options \"%s\"\n", n1);
exit(EXIT_FAILURE);
}
/*found = 0;
for(i=0;i<ai->option_count;i++) {
if(strcmp(ai->options[i],key)==0) {
found = 1;
break;
}
}
if(!found) {
ERROR("\"%s\" is not an option for "
"\"%s\" ao driver\n",key,
ai->short_name);
exit(EXIT_FAILURE);
}*/
value = strtok_r(NULL,"",&stk2);
if(!value) {
ERROR("problems parsing "
"ao_driver_options \"%s\"\n", n1);
exit(EXIT_FAILURE);
}
ao_append_option(&audio_ao_options,key,value);
n1 = strtok_r(NULL,";",&stk1);
}
}
free(dup);
#endif
aoOutput = newAudioOutput("ao");
assert(aoOutput);
shoutOutput = newAudioOutput("shout");
}
void getOutputAudioFormat(AudioFormat * inAudioFormat,
......@@ -134,22 +66,27 @@ void getOutputAudioFormat(AudioFormat * inAudioFormat,
void initAudioConfig() {
char * conf = getConf()[CONF_AUDIO_OUTPUT_FORMAT];
char * test;
if(NULL == conf) return;
audio_configFormat = malloc(sizeof(AudioFormat));
memset(audio_configFormat,0,sizeof(AudioFormat));
if(0 != parseAudioConfig(audio_configFormat, conf)) exit(EXIT_FAILURE);
}
int parseAudioConfig(AudioFormat * audioFormat, char * conf) {
char * test;
memset(audioFormat,0,sizeof(AudioFormat));
audio_configFormat->sampleRate = strtol(conf,&test,10);
audioFormat->sampleRate = strtol(conf,&test,10);
if(*test!=':') {
ERROR("error parsing audio output format: %s\n",conf);
exit(EXIT_FAILURE);
return -1;
}
/*switch(audio_configFormat->sampleRate) {
/*switch(audioFormat->sampleRate) {
case 48000:
case 44100:
case 32000:
......@@ -157,47 +94,50 @@ void initAudioConfig() {
break;
default:
ERROR("sample rate %i can not be used for audio output\n",
(int)audio_configFormat->sampleRate);
exit(EXIT_FAILURE);
(int)audioFormat->sampleRate);
return -1
}*/
if(audio_configFormat->sampleRate <= 0) {
if(audioFormat->sampleRate <= 0) {
ERROR("sample rate %i is not >= 0\n",
(int)audio_configFormat->sampleRate);
exit(EXIT_FAILURE);
(int)audioFormat->sampleRate);
return -1;
}
audio_configFormat->bits = strtol(test+1,&test,10);
audioFormat->bits = strtol(test+1,&test,10);
if(*test!=':') {
ERROR("error parsing audio output format: %s\n",conf);
exit(EXIT_FAILURE);
return -1;
}
switch(audio_configFormat->bits) {
switch(audioFormat->bits) {
case 16:
break;
default:
ERROR("bits %i can not be used for audio output\n",
(int)audio_configFormat->bits);
exit(EXIT_FAILURE);
(int)audioFormat->bits);
return -1;
}
audio_configFormat->channels = strtol(test+1,&test,10);
audioFormat->channels = strtol(test+1,&test,10);
if(*test!='\0') {
ERROR("error parsing audio output format: %s\n",conf);
exit(EXIT_FAILURE);
return -1;
}
switch(audio_configFormat->channels) {
switch(audioFormat->channels) {
case 1:
case 2:
break;
default:
ERROR("channels %i can not be used for audio output\n",
(int)audio_configFormat->channels);
exit(EXIT_FAILURE);
(int)audioFormat->channels);
return -1;
}
return 0;
}
void finishAudioConfig() {
......@@ -205,105 +145,44 @@ void finishAudioConfig() {
}
void finishAudioDriver() {
#ifdef HAVE_AUDIO
ao_free_options(audio_ao_options);
ao_shutdown();
#endif
finishAudioOutput(aoOutput);
if(shoutOutput) finishAudioOutput(shoutOutput);
shoutOutput = NULL;
aoOutput = NULL;
}
int isCurrentAudioFormat(AudioFormat * audioFormat) {
#ifdef HAVE_AUDIO
if(!audio_device || !audioFormat) return 0;
if(!audioFormat) return 0;
if(memcmp(audioFormat,&audio_format,sizeof(AudioFormat)) != 0) return 0;
#endif
return 1;
}
int openAudioDevice(AudioFormat * audioFormat) {
#ifdef HAVE_AUDIO
ao_sample_format format;
if(audio_device && !isCurrentAudioFormat(audioFormat)) {
closeAudioDevice();
if(!aoOutput->open || !isCurrentAudioFormat(audioFormat)) {
if(audioFormat) copyAudioFormat(&audio_format, audioFormat);
if(shoutOutput) openAudioOutput(shoutOutput, &audio_format);
return openAudioOutput(aoOutput, &audio_format);
}
if(!audio_device) {
if(audioFormat) {
copyAudioFormat(&audio_format,audioFormat);
}
format.bits = audio_format.bits;
format.rate = audio_format.sampleRate;
format.byte_format = AO_FMT_NATIVE;
format.channels = audio_format.channels;
blockSignals();
audio_device = ao_open_live(audio_ao_driver_id, &format,
audio_ao_options);
unblockSignals();
if(audio_device==NULL) return -1;
}
#endif
return 0;
}
int playAudio(char * playChunk, int size) {
#ifdef HAVE_AUDIO
int send;
if(audio_device==NULL) {
ERROR("trying to play w/o the audio device being open!\n");
return -1;
}
while(size>0) {
send = audio_write_size>size?size:audio_write_size;
if(ao_play(audio_device,playChunk,send)==0) {
audioError();
ERROR("closing audio device due to write error\n");
closeAudioDevice();
return -1;
}
playChunk+=send;
size-=send;
}
#endif
return 0;
if(shoutOutput) playAudioOutput(shoutOutput, playChunk, size);
return playAudioOutput(aoOutput, playChunk, size);
}
int isAudioDeviceOpen() {
if(audio_device) return 1;
return 0;
return aoOutput->open;
}
void closeAudioDevice() {
#ifdef HAVE_AUDIO
if(audio_device) {
blockSignals();
ao_close(audio_device);
audio_device = NULL;
unblockSignals();
}
#endif
if(shoutOutput) closeAudioOutput(shoutOutput);
closeAudioOutput(aoOutput);
}
void audioError() {
#ifdef HAVE_AUDIO
if(errno==AO_ENOTLIVE) {
ERROR("not a live ao device\n");
}
else if(errno==AO_EOPENDEVICE) {
ERROR("not able to open audio device\n");
}
else if(errno==AO_EBADOPTION) {
ERROR("bad driver option\n");
}
#endif
void sendMetadataToAudioDevice(MpdTag * tag) {
if(shoutOutput) sendMetadataToAudioOutput(shoutOutput, tag);
}
......@@ -38,6 +38,8 @@ void copyAudioFormat(AudioFormat * dest, AudioFormat * src);
void getOutputAudioFormat(AudioFormat * inFormat, AudioFormat * outFormat);
int parseAudioConfig(AudioFormat * audioFormat, char * conf);
void initAudioConfig();
void finishAudioConfig();
......@@ -54,8 +56,8 @@ void closeAudioDevice();
int isAudioDeviceOpen();
void audioError();
int isCurrentAudioFormat(AudioFormat * audioFormat);
void sendMetadataToAudioDevice(MpdTag * tag);
#endif
#include <audioOutput.h>
#include <list.h>
static List * audioOutputPluginList;
void loadAudioOutputPlugin(AudioOutputPlugin * audioOutputPlugin) {
insertInList(audioOutputPluginList, audioOutputPlugin->name,
audioOutputPlugin);
}
void unloadAudioOutputPlugin(AudioOutputPlugin * audioOutputPlugin) {
deleteFromList(audioOutputPluginList, audioOutputPlugin->name);
}
void initAudioOutputPlugins() {
audioOutputPluginList = makeList(NULL);
}
void finishAudioOutputPlugins() {
freeList(audioOutputPluginList);
}
AudioOutput * newAudioOutput(char * name) {
AudioOutput * ret = NULL;
void * data = NULL;
if(findInList(audioOutputPluginList, name, &data)) {
AudioOutputPlugin * plugin = (AudioOutputPlugin *) data;
ret = malloc(sizeof(AudioOutput));
ret->finishDriverFunc = plugin->finishDriverFunc;
ret->openDeviceFunc = plugin->openDeviceFunc;
ret->playFunc = plugin->playFunc;
ret->closeDeviceFunc = plugin->closeDeviceFunc;
ret->sendMetdataFunc = plugin->sendMetdataFunc;
ret->open = 0;
if(plugin->initDriverFunc(ret) != 0) {
free(ret);
ret = NULL;
}
}
return ret;
}
int openAudioOutput(AudioOutput * audioOutput, AudioFormat * audioFormat) {
if(audioOutput->open) closeAudioOutput(audioOutput);
return audioOutput->openDeviceFunc(audioOutput, audioFormat);
}
int playAudioOutput(AudioOutput * audioOutput, char * playChunk, int size) {
if(!audioOutput->open) return -1;
return audioOutput->playFunc(audioOutput, playChunk, size);
}
void closeAudioOutput(AudioOutput * audioOutput) {
if(audioOutput->open) audioOutput->closeDeviceFunc(audioOutput);
}
void finishAudioOutput(AudioOutput * audioOutput) {
closeAudioOutput(audioOutput);
audioOutput->finishDriverFunc(audioOutput);
free(audioOutput);
}
void sendMetadataToAudioOutput(AudioOutput * audioOutput, MpdTag * tag) {
if(!audioOutput->sendMetdataFunc) return;
audioOutput->sendMetdataFunc(audioOutput, tag);
}
/* the Music Player Daemon (MPD)
* (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef AUDIO_OUTPUT_H
#define AUDIO_OUTPUT_H
#include "../config.h"
#include "mpd_types.h"
#include "audio.h"
#include "tag.h"
#define AUDIO_AO_DRIVER_DEFAULT "default"
typedef struct _AudioOutput AudioOutput;
typedef int (* AudioOutputInitDriverFunc) (AudioOutput * audioOutput);
typedef void (* AudioOutputFinishDriverFunc) (AudioOutput * audioOutput);
typedef int (* AudioOutputOpenDeviceFunc) (AudioOutput * audioOutput,
AudioFormat * audioFormat);
typedef int (* AudioOutputPlayFunc) (AudioOutput * audioOutput,
char * playChunk, int size);
typedef void (* AudioOutputCloseDeviceFunc) (AudioOutput * audioOutput);
typedef void (* AudioOutputSendMetadataFunc) (AudioOutput * audioOutput,
MpdTag * tag);
struct _AudioOutput {
int open;
AudioOutputFinishDriverFunc finishDriverFunc;
AudioOutputOpenDeviceFunc openDeviceFunc;
AudioOutputPlayFunc playFunc;
AudioOutputCloseDeviceFunc closeDeviceFunc;
AudioOutputSendMetadataFunc sendMetdataFunc;
void * data;
};
typedef struct _AudioOutputPlugin {
char * name;
AudioOutputInitDriverFunc initDriverFunc;
AudioOutputFinishDriverFunc finishDriverFunc;
AudioOutputOpenDeviceFunc openDeviceFunc;
AudioOutputPlayFunc playFunc;
AudioOutputCloseDeviceFunc closeDeviceFunc;
AudioOutputSendMetadataFunc sendMetdataFunc;
} AudioOutputPlugin;
void initAudioOutputPlugins();
void finishAudioOutputPlugins();
void loadAudioOutputPlugin(AudioOutputPlugin * audioOutputPlugin);
void unloadAudioOutputPlugin(AudioOutputPlugin * audioOutputPlugin);
AudioOutput * newAudioOutput(char * name);
int openAudioOutput(AudioOutput * audioOutput, AudioFormat * audioFormat);
int playAudioOutput(AudioOutput * audioOutput, char * playChunk, int size);
void closeAudioOutput(AudioOutput * audioOutput);
void finishAudioOutput(AudioOutput * audioOutput);
int keepAudioOutputAlive(AudioOutput * audioOutput, int ms);
void sendMetadataToAudioOutput(AudioOutput * audioOutput, MpdTag * tag);
#endif
/* the Music Player Daemon (MPD)
* (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "audioOutput.h"
#include "conf.h"
#include "log.h"
#include "sig_handlers.h"
#include <string.h>
#include <assert.h>
#include <signal.h>
#include <ao/ao.h>
static int driverInitCount = 0;
typedef struct _AoData {
int writeSize;
int driverId;
ao_option * options;
ao_device * device;
} AoData;
static AoData * newAoData() {
AoData * ret = malloc(sizeof(AoData));
ret->device = NULL;
ret->options = NULL;
return ret;
}
static void audioOutputAo_error() {
if(errno==AO_ENOTLIVE) {
ERROR("not a live ao device\n");
}
else if(errno==AO_EOPENDEVICE) {
ERROR("not able to open audio device\n");
}
else if(errno==AO_EBADOPTION) {
ERROR("bad driver option\n");
}
}
static int audioOutputAo_initDriver(AudioOutput * audioOutput) {
ao_info * ai;
char * dup;
char * stk1;
char * stk2;
char * n1;
char * key;
char * value;
char * test;
AoData * ad = newAoData();
audioOutput->data = ad;
ad->writeSize = strtol((getConf())[CONF_AUDIO_WRITE_SIZE],&test,10);
if (*test!='\0') {
ERROR("\"%s\" is not a valid write size\n",
(getConf())[CONF_AUDIO_WRITE_SIZE]);
exit(EXIT_FAILURE);
}
if(driverInitCount == 0) {
ao_initialize();
}
driverInitCount++;
if(strcmp(AUDIO_AO_DRIVER_DEFAULT,(getConf())[CONF_AO_DRIVER])==0) {
ad->driverId = ao_default_driver_id();
}
else if((ad->driverId =
ao_driver_id((getConf())[CONF_AO_DRIVER]))<0) {
ERROR("\"%s\" is not a valid ao driver\n",
(getConf())[CONF_AO_DRIVER]);
exit(EXIT_FAILURE);
}
if((ai = ao_driver_info(ad->driverId))==NULL) {
ERROR("problems getting ao_driver_info\n");
ERROR("you may not have permission to the audio device\n");
exit(EXIT_FAILURE);
}
dup = strdup((getConf())[CONF_AO_DRIVER_OPTIONS]);
if(strlen(dup)) {
stk1 = NULL;
n1 = strtok_r(dup,";",&stk1);
while(n1) {
stk2 = NULL;
key = strtok_r(n1,"=",&stk2);
if(!key) {
ERROR("problems parsing "
"ao_driver_options \"%s\"\n", n1);
exit(EXIT_FAILURE);
}
/*found = 0;
for(i=0;i<ai->option_count;i++) {
if(strcmp(ai->options[i],key)==0) {
found = 1;
break;
}
}
if(!found) {
ERROR("\"%s\" is not an option for "
"\"%s\" ao driver\n",key,
ai->short_name);
exit(EXIT_FAILURE);
}*/
value = strtok_r(NULL,"",&stk2);
if(!value) {
ERROR("problems parsing "
"ao_driver_options \"%s\"\n", n1);
exit(EXIT_FAILURE);
}
ao_append_option(&ad->options,key,value);
n1 = strtok_r(NULL,";",&stk1);
}
}
free(dup);
return 0;
}
static void freeAoData(AoData * ad) {
ao_free_options(ad->options);
free(ad);
}
static void audioOutputAo_finishDriver(AudioOutput * audioOutput) {
AoData * ad = (AoData *)audioOutput->data;
freeAoData(ad);
driverInitCount--;
if(driverInitCount == 0) ao_shutdown();
}
static void audioOutputAo_closeDevice(AudioOutput * audioOutput) {
AoData * ad = (AoData *) audioOutput->data;
if(ad->device) {
blockSignals();
ao_close(ad->device);
audioOutput->open = 0;
ad->device = NULL;
unblockSignals();
}
}
static int audioOutputAo_openDevice(AudioOutput * audioOutput,
AudioFormat * audioFormat)
{
ao_sample_format format;
AoData * ad = (AoData *)audioOutput->data;
if(ad->device) {
audioOutputAo_closeDevice(audioOutput);
}
format.bits = audioFormat->bits;
format.rate = audioFormat->sampleRate;
format.byte_format = AO_FMT_NATIVE;
format.channels = audioFormat->channels;
blockSignals();
ad->device = ao_open_live(ad->driverId, &format, ad->options);
unblockSignals();
if(ad->device==NULL) return -1;
audioOutput->open = 1;
return 0;
}
static int audioOutputAo_play(AudioOutput * audioOutput, char * playChunk,
int size)
{
int send;
AoData * ad = (AoData *)audioOutput->data;
if(ad->device==NULL) {
ERROR("trying to play w/o the ao device being open!\n");
return -1;
}
while(size>0) {
send = ad->writeSize > size ? size : ad->writeSize;
if(ao_play(ad->device, playChunk, send)==0) {
audioOutputAo_error();
ERROR("closing audio device due to write error\n");
audioOutputAo_closeDevice(audioOutput);
return -1;
}
playChunk+=send;
size-=send;
}
return 0;
}
AudioOutputPlugin aoPlugin =
{
"ao",
audioOutputAo_initDriver,
audioOutputAo_finishDriver,
audioOutputAo_openDevice,
audioOutputAo_play,
audioOutputAo_closeDevice,
NULL /* sendMetadataFunc */
};
......@@ -37,7 +37,7 @@
#define CONF_COMMENT '#'
#define CONF_NUMBER_OF_PARAMS 35
#define CONF_NUMBER_OF_PARAMS 43
#define CONF_NUMBER_OF_PATHS 6
#define CONF_NUMBER_OF_REQUIRED 5
#define CONF_NUMBER_OF_ALLOW_CATS 1
......@@ -131,7 +131,15 @@ char ** readConf(char * file) {
"http_proxy_user",
"http_proxy_password",
"replaygain_preamp",
"id3v1_encoding"
"shout_host",
"shout_port",
"shout_password",
"shout_mount",
"shout_name",
"shout_user",
"shout_quality",
"id3v1_encoding",
"shout_format"
};
int conf_absolutePaths[CONF_NUMBER_OF_PATHS] = {
......
......@@ -55,7 +55,15 @@
#define CONF_HTTP_PROXY_USER 31
#define CONF_HTTP_PROXY_PASSWORD 32
#define CONF_REPLAYGAIN_PREAMP 33
#define CONF_ID3V1_ENCODING 34
#define CONF_SHOUT_HOST 34
#define CONF_SHOUT_PORT 35
#define CONF_SHOUT_PASSWD 36
#define CONF_SHOUT_MOUNT 37
#define CONF_SHOUT_NAME 38
#define CONF_SHOUT_USER 39
#define CONF_SHOUT_QUALITY 40
#define CONF_ID3V1_ENCODING 41
#define CONF_SHOUT_FORMAT 42
#define CONF_CAT_CHAR "\n"
......
......@@ -145,6 +145,7 @@ int waitOnDecode(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb,
{
strncpy(pc->currentUrl, pc->utf8url, MAXPATHLEN);
pc->currentUrl[MAXPATHLEN] = '\0';
MpdTag * tag = NULL;
while(decode_pid && *decode_pid>0 && dc->start) my_usleep(10000);
......@@ -156,6 +157,11 @@ int waitOnDecode(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb,
return -1;
}
if((tag = metadataChunkToMpdTagDup(&(pc->fileMetadataChunk)))) {
sendMetadataToAudioDevice(tag);
freeMpdTag(tag);
}
pc->totalTime = pc->fileTime;
pc->bitRate = 0;
pc->sampleRate = 0;
......@@ -420,7 +426,15 @@ void handleMetadata(OutputBuffer * cb, PlayerControl * pc, int * previous,
if(!(*currentChunkSent) && pc->metadataState ==
PLAYER_METADATA_STATE_WRITE)
{
MpdTag * tag = NULL;
*currentChunkSent = 1;
if((tag = metadataChunkToMpdTagDup(currentChunk))) {
sendMetadataToAudioDevice(tag);
freeMpdTag(tag);
}
memcpy(&(pc->metadataChunk), currentChunk,
sizeof(MetadataChunk));
pc->metadataState = PLAYER_METADATA_STATE_READ;
......
......@@ -95,16 +95,21 @@ static int mod_mikModInitiated = 0;
static int mod_mikModInitError = 0;
static int mod_initMikMod() {
if(mod_mikModInitiated) return 0;
if(mod_mikModInitError) return -1;
mod_mikModInitiated = 1;
if(!mod_mikModInitiated) {
mod_mikModInitiated = 1;
MikMod_RegisterDriver(&drv_mpd);
MikMod_RegisterAllLoaders();
md_device = 0;
md_reverb = 0;
md_reverb = 0;
md_mode = (DMODE_SOFT_MUSIC | DMODE_SOFT_SNDFX | DMODE_STEREO |
MikMod_RegisterDriver(&drv_mpd);
MikMod_RegisterAllLoaders();
}
md_pansep = 64;
md_mixfreq = 44100;
md_mode = (DMODE_SOFT_MUSIC | DMODE_INTERP | DMODE_STEREO |
DMODE_16BITS);
if(MikMod_Init("")) {
......@@ -130,7 +135,7 @@ static mod_Data * mod_open(char * path) {
MODULE * moduleHandle;
mod_Data * data;
if(!(moduleHandle = Player_Load(path, 255, 0))) return NULL;
if(!(moduleHandle = Player_Load(path, 128, 0))) return NULL;
data = malloc(sizeof(mod_Data));
......@@ -159,6 +164,7 @@ int mod_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
if(!(data = mod_open(path))) {
ERROR("failed to open mod: %s\n", path);
MikMod_Exit();
return -1;
}
......@@ -192,6 +198,8 @@ int mod_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
mod_close(data);
MikMod_Exit();
if(dc->stop) {
dc->state = DECODE_STATE_STOP;
dc->stop = 0;
......@@ -207,7 +215,7 @@ MpdTag * modTagDup(char * file) {
if(mod_initMikMod() < 0) return NULL;
if(!(moduleHandle = Player_Load(file, 255, 0))) return NULL;
if(!(moduleHandle = Player_Load(file, 128, 0))) goto fail;
Player_Free(moduleHandle);
......@@ -216,6 +224,9 @@ MpdTag * modTagDup(char * file) {
ret->time = 0;
ret->title = Player_LoadTitle(file);
fail:
MikMod_Exit();
return ret;
}
......
......@@ -44,7 +44,6 @@
#define HTTP_BUFFER_SIZE 131072
#define HTTP_PREBUFFER_SIZE (HTTP_BUFFER_SIZE >> 2)
//#define HTTP_PREBUFFER_SIZE 0
#define HTTP_REDIRECT_MAX 10
......
......@@ -261,9 +261,6 @@ void changeToUser(Options * options) {
exit(EXIT_FAILURE);
}
if(userpwd->pw_dir) {
setenv("HOME", userpwd->pw_dir, 1);
}
}
}
......
......@@ -107,8 +107,10 @@ OBJDUMP = @OBJDUMP@
OGG_CFLAGS = @OGG_CFLAGS@
OGG_LIBS = @OGG_LIBS@
PACKAGE = @PACKAGE@
PKGCONFIG = @PKGCONFIG@
RANLIB = @RANLIB@
RC = @RC@
SHOUTCONFIG = @SHOUTCONFIG@
STRIP = @STRIP@
VERSION = @VERSION@
VORBISENC_LIBS = @VORBISENC_LIBS@
......
......@@ -80,7 +80,7 @@ int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,
}
else {
datalen = pcm_sizeOfOutputBufferForAudioFormatConversion(
&(dc->audioFormat), dataIn, dataInLen,
&(dc->audioFormat), dataInLen,
&(cb->audioFormat));
if(datalen > convBufferLen) {
convBuffer = realloc(convBuffer,datalen);
......
......@@ -153,7 +153,7 @@ void pcm_convertAudioFormat(AudioFormat * inFormat, char * inBuffer, size_t
int dataBitLen;
assert(outFormat->bits==16);
assert(outFormat->channels==2);
assert(outFormat->channels==2 || outFormat->channels==1);
/* converts */
switch(inFormat->bits) {
......@@ -185,32 +185,55 @@ void pcm_convertAudioFormat(AudioFormat * inFormat, char * inBuffer, size_t
}
/* converts only between 16 bit audio between mono and stereo */
switch(inFormat->channels) {
case 1:
dataChannelLen = (dataBitLen >> 1) << 2;
if(dataChannelLen > channelConvBufferLength) {
channelConvBuffer = realloc(channelConvBuffer,
dataChannelLen);
channelConvBufferLength = dataChannelLen;
}
dataChannelConv = channelConvBuffer;
{
mpd_sint16 * in = (mpd_sint16 *)dataBitConv;
mpd_sint16 * out = (mpd_sint16 *)dataChannelConv;
int i, inSamples = dataBitLen >> 1;
for(i=0;i<inSamples;i++) {
*out++ = *in;
*out++ = *in++;
}
}
break;
case 2:
if(inFormat->channels == outFormat->channels)
{
dataChannelConv = dataBitConv;
dataChannelLen = dataBitLen;
break;
default:
ERROR("only 1 or 2 channels are supported for conversion!\n");
exit(EXIT_FAILURE);
}
else {
switch(inFormat->channels) {
/* convert from 1 -> 2 channels */
case 1:
dataChannelLen = (dataBitLen >> 1) << 2;
if(dataChannelLen > channelConvBufferLength) {
channelConvBuffer = realloc(channelConvBuffer,
dataChannelLen);
channelConvBufferLength = dataChannelLen;
}
dataChannelConv = channelConvBuffer;
{
mpd_sint16 * in = (mpd_sint16 *)dataBitConv;
mpd_sint16 * out = (mpd_sint16 *)dataChannelConv;
int i, inSamples = dataBitLen >> 1;
for(i=0;i<inSamples;i++) {
*out++ = *in;
*out++ = *in++;
}
}
break;
/* convert from 2 -> 1 channels */
case 2:
dataChannelLen = dataBitLen >> 1;
if(dataChannelLen > channelConvBufferLength) {
channelConvBuffer = realloc(channelConvBuffer,
dataChannelLen);
channelConvBufferLength = dataChannelLen;
}
dataChannelConv = channelConvBuffer;
{
mpd_sint16 * in = (mpd_sint16 *)dataBitConv;
mpd_sint16 * out = (mpd_sint16 *)dataChannelConv;
int i, inSamples = dataBitLen >> 2;
for(i=0;i<inSamples;i++) {
*out = (*in++)/2;
*out++ += (*in++)/2;
}
}
break;
default:
ERROR("only 1 or 2 channels are supported for conversion!\n");
exit(EXIT_FAILURE);
}
}
if(inFormat->sampleRate == outFormat->sampleRate) {
......@@ -219,37 +242,51 @@ void pcm_convertAudioFormat(AudioFormat * inFormat, char * inBuffer, size_t
else {
/* only works if outFormat is 16-bit stereo! */
/* resampling code blatantly ripped from ESD */
mpd_sint32 rd_dat = 0;
mpd_uint32 rd_dat = 0;
mpd_uint32 wr_dat = 0;
mpd_sint16 lsample, rsample;
register mpd_sint16 * out = (mpd_sint16 *)outBuffer;
register mpd_sint16 * in = (mpd_sint16 *)dataChannelConv;
const int shift = sizeof(mpd_sint16);
mpd_uint32 nlen = ((( dataChannelLen >> shift) *
mpd_sint16 * out = (mpd_sint16 *)outBuffer;
mpd_sint16 * in = (mpd_sint16 *)dataChannelConv;
const int shift = sizeof(mpd_sint16)*outFormat->channels;
mpd_uint32 nlen = ((( dataChannelLen / shift) *
(mpd_uint32)(outFormat->sampleRate)) /
inFormat->sampleRate);
nlen <<= shift;
nlen *= outFormat->channels;
while( wr_dat < nlen / shift) {
rd_dat = wr_dat * inFormat->sampleRate /
outFormat->sampleRate;
rd_dat &= ~1;
switch(outFormat->channels) {
case 1:
while( wr_dat < nlen) {
rd_dat = wr_dat * inFormat->sampleRate /
outFormat->sampleRate;
lsample = in[ rd_dat++ ];
rsample = in[ rd_dat++ ];
lsample = in[ rd_dat++ ];
out[ wr_dat++ ] = lsample;
out[ wr_dat++ ] = rsample;
}
out[ wr_dat++ ] = lsample;
}
break;
case 2:
while( wr_dat < nlen) {
rd_dat = wr_dat * inFormat->sampleRate /
outFormat->sampleRate;
rd_dat &= ~1;
lsample = in[ rd_dat++ ];
rsample = in[ rd_dat++ ];
out[ wr_dat++ ] = lsample;
out[ wr_dat++ ] = rsample;
}
break;
}
}
return;
}
size_t pcm_sizeOfOutputBufferForAudioFormatConversion(AudioFormat * inFormat,
char * inBuffer, size_t inSize, AudioFormat * outFormat)
size_t inSize, AudioFormat * outFormat)
{
const int shift = sizeof(mpd_sint16);
const int shift = sizeof(mpd_sint16)*outFormat->channels;
size_t outSize = inSize;
switch(inFormat->bits) {
......@@ -263,21 +300,21 @@ size_t pcm_sizeOfOutputBufferForAudioFormatConversion(AudioFormat * inFormat,
exit(EXIT_FAILURE);
}
switch(inFormat->channels) {
case 1:
outSize = (outSize >> 1) << 2;
break;
case 2:
break;
default:
ERROR("only 1 or 2 channels are supported for conversion!\n");
exit(EXIT_FAILURE);
if(inFormat->channels != outFormat->channels) {
switch(inFormat->channels) {
case 1:
outSize = (outSize >> 1) << 2;
break;
case 2:
outSize >>= 1;
break;
}
}
outSize = (((outSize >> shift) * (mpd_uint32)(outFormat->sampleRate)) /
outSize = (((outSize / shift) * (mpd_uint32)(outFormat->sampleRate)) /
inFormat->sampleRate);
outSize <<= shift;
outSize *= shift;
return outSize;
}
......@@ -37,6 +37,6 @@ void pcm_convertAudioFormat(AudioFormat * inFormat, char * inBuffer, size_t
inSize, AudioFormat * outFormat, char * outBuffer);
size_t pcm_sizeOfOutputBufferForAudioFormatConversion(AudioFormat * inFormat,
char * inBuffer, size_t inSize, AudioFormat * outFormat);
size_t inSize, AudioFormat * outFormat);
#endif
/* vim:set shiftwidth=8 tabstop=8 expandtab: */
......@@ -187,6 +187,8 @@ int playerPlay(FILE * fp, Song * song) {
if(song->tag) pc->fileTime = song->tag->time;
else pc->fileTime = 0;
copyMpdTagToMetadataChunk(song->tag, &(pc->fileMetadataChunk));
strncpy(pc->utf8url, song->utf8url, MAXPATHLEN);
pc->utf8url[MAXPATHLEN] = '\0';
......@@ -338,6 +340,8 @@ int queueSong(Song * song) {
if(song->tag) pc->fileTime = song->tag->time;
else pc->fileTime = 0;
copyMpdTagToMetadataChunk(song->tag, &(pc->fileMetadataChunk));
pc->queueState = PLAYER_QUEUE_FULL;
return 0;
}
......@@ -390,6 +394,8 @@ int playerSeek(FILE * fp, Song * song, float time) {
if(song->tag) pc->fileTime = song->tag->time;
else pc->fileTime = 0;
copyMpdTagToMetadataChunk(song->tag, &(pc->fileMetadataChunk));
strncpy(pc->utf8url, song->utf8url, MAXPATHLEN);
pc->utf8url[MAXPATHLEN] = '\0';
}
......
......@@ -86,6 +86,7 @@ typedef struct _PlayerControl {
volatile mpd_sint8 cycleLogFiles;
volatile mpd_sint8 metadataState;
MetadataChunk metadataChunk;
MetadataChunk fileMetadataChunk;
} PlayerControl;
void clearPlayerPid();
......
......@@ -167,7 +167,7 @@ void initPlaylist() {
memset(playlist.songs,0,sizeof(char *)*playlist_max_length);
srandom(time(NULL));
srand(time(NULL));
if(getConf()[CONF_STATE_FILE]) {
playlist_stateFile = getConf()[CONF_STATE_FILE];
......@@ -635,7 +635,7 @@ int addSongToPlaylist(FILE * fp, Song * song) {
else */if(playlist.queued>=0) start = playlist.queued+1;
else start = playlist.current+1;
if(start < playlist.length) {
swap = random()%(playlist.length-start);
swap = rand()%(playlist.length-start);
swap+=start;
swapOrder(playlist.length-1,swap);
}
......@@ -1129,7 +1129,7 @@ void randomizeOrder(int start,int end) {
}
for(i=start;i<=end;i++) {
ri = random()%(end-start+1)+start;
ri = rand()%(end-start+1)+start;
if(ri==playlist.current) playlist.current = i;
else if(i==playlist.current) playlist.current = ri;
swapOrder(i,ri);
......@@ -1220,7 +1220,7 @@ int shufflePlaylist(FILE * fp) {
}
/* shuffle the rest of the list */
for(;i<playlist.length;i++) {
ri = random()%(playlist.length-1)+1;
ri = rand()%(playlist.length-1)+1;
swapSongs(i,ri);
}
......
......@@ -63,13 +63,13 @@ void validateUtf8Tag(MpdTag * tag) {
fixUtf8(tag->artist);
stripReturnChar(tag->artist);
fixUtf8(tag->album);
stripReturnChar(tag->artist);
stripReturnChar(tag->album);
fixUtf8(tag->track);
stripReturnChar(tag->artist);
stripReturnChar(tag->track);
fixUtf8(tag->title);
stripReturnChar(tag->artist);
stripReturnChar(tag->title);
fixUtf8(tag->name);
stripReturnChar(tag->artist);
stripReturnChar(tag->name);
}
#ifdef HAVE_ID3TAG
......
......@@ -26,4 +26,3 @@ unsigned char * utf8StrToLatin1Dup(unsigned char * utf8);
int validUtf8String(unsigned char * string);
#endif
/* vim:set shiftwidth=4 tabstop=8 expandtab: */
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