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
......
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.59 for mpd 0.11.5.
# Generated by GNU Autoconf 2.59 for mpd 0.12.0.
#
# Report bugs to <shank@mercury.chem.pitt.edu>.
#
......@@ -423,8 +423,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='mpd'
PACKAGE_TARNAME='mpd'
PACKAGE_VERSION='0.11.5'
PACKAGE_STRING='mpd 0.11.5'
PACKAGE_VERSION='0.12.0'
PACKAGE_STRING='mpd 0.12.0'
PACKAGE_BUGREPORT='shank@mercury.chem.pitt.edu'
# Factoring default headers for most tests.
......@@ -466,7 +466,7 @@ ac_includes_default="\
ac_subdirs_all="$ac_subdirs_all src/libid3tag"
ac_subdirs_all="$ac_subdirs_all src/libmad"
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE CCAS CCASFLAGS MAD_SUBDIR MAD_LIB ID3_SUBDIR ID3_LIB MP4FF_LIB MP4FF_SUBDIR MPD_LIBS MPD_CFLAGS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE build build_cpu build_vendor build_os host host_cpu host_vendor host_os EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL AO_CFLAGS AO_LIBS subdirs OGG_CFLAGS OGG_LIBS VORBIS_CFLAGS VORBIS_LIBS VORBISFILE_LIBS VORBISENC_LIBS LIBFLAC_CFLAGS LIBFLAC_LIBS AUDIOFILE_CONFIG AUDIOFILE_CFLAGS AUDIOFILE_LIBS LIBMIKMOD_CONFIG LIBMIKMOD_CFLAGS LIBMIKMOD_LIBS LIBMIKMOD_LDADD LIBOBJS LTLIBOBJS'
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE CCAS CCASFLAGS MAD_SUBDIR MAD_LIB ID3_SUBDIR ID3_LIB MP4FF_LIB MP4FF_SUBDIR MPD_LIBS MPD_CFLAGS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE build build_cpu build_vendor build_os host host_cpu host_vendor host_os EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL AO_CFLAGS AO_LIBS PKGCONFIG SHOUTCONFIG subdirs OGG_CFLAGS OGG_LIBS VORBIS_CFLAGS VORBIS_LIBS VORBISFILE_LIBS VORBISENC_LIBS LIBFLAC_CFLAGS LIBFLAC_LIBS AUDIOFILE_CONFIG AUDIOFILE_CFLAGS AUDIOFILE_LIBS LIBMIKMOD_CONFIG LIBMIKMOD_CFLAGS LIBMIKMOD_LIBS LIBMIKMOD_LDADD LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
......@@ -955,7 +955,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.11.5 to adapt to many kinds of systems.
\`configure' configures mpd 0.12.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
......@@ -1021,7 +1021,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of mpd 0.11.5:";;
short | recursive ) echo "Configuration of mpd 0.12.0:";;
esac
cat <<\_ACEOF
......@@ -1038,6 +1038,7 @@ Optional Features:
optimize for fast installation [default=yes]
--disable-libtool-lock avoid locking (might break parallel builds)
--disable-audio disable support for playing
--disable-shout disable support for streaming through shout
--disable-iconv disable iconv support
--disable-ipv6 disable IPv6 support
--disable-alsa disable ALSA Mixer support
......@@ -1207,7 +1208,7 @@ fi
test -n "$ac_init_help" && exit 0
if $ac_init_version; then
cat <<\_ACEOF
mpd configure 0.11.5
mpd configure 0.12.0
generated by GNU Autoconf 2.59
Copyright (C) 2003 Free Software Foundation, Inc.
......@@ -1221,7 +1222,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.11.5, which was
It was created by mpd $as_me 0.12.0, which was
generated by GNU Autoconf 2.59. Invocation command line was
$ $0 $@
......@@ -3711,7 +3712,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
echo '#line 3714 "configure"' > conftest.$ac_ext
echo '#line 3715 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
......@@ -5261,7 +5262,7 @@ fi
# Provide some information about the compiler.
echo "$as_me:5264:" \
echo "$as_me:5265:" \
"checking for Fortran 77 compiler version" >&5
ac_compiler=`set X $ac_compile; echo $2`
{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
......@@ -6295,11 +6296,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:6298: $lt_compile\"" >&5)
(eval echo "\"\$as_me:6299: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:6302: \$? = $ac_status" >&5
echo "$as_me:6303: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
......@@ -6528,11 +6529,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:6531: $lt_compile\"" >&5)
(eval echo "\"\$as_me:6532: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:6535: \$? = $ac_status" >&5
echo "$as_me:6536: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
......@@ -6588,11 +6589,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:6591: $lt_compile\"" >&5)
(eval echo "\"\$as_me:6592: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:6595: \$? = $ac_status" >&5
echo "$as_me:6596: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
......@@ -7967,7 +7968,7 @@ linux*)
libsuff=
case "$host_cpu" in
x86_64*)
echo '#line 7970 "configure"' > conftest.$ac_ext
echo '#line 7971 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
......@@ -8827,7 +8828,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 8830 "configure"
#line 8831 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
......@@ -8925,7 +8926,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 8928 "configure"
#line 8929 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
......@@ -11104,11 +11105,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:11107: $lt_compile\"" >&5)
(eval echo "\"\$as_me:11108: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:11111: \$? = $ac_status" >&5
echo "$as_me:11112: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
......@@ -11164,11 +11165,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:11167: $lt_compile\"" >&5)
(eval echo "\"\$as_me:11168: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:11171: \$? = $ac_status" >&5
echo "$as_me:11172: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
......@@ -11720,7 +11721,7 @@ linux*)
libsuff=
case "$host_cpu" in
x86_64*)
echo '#line 11723 "configure"' > conftest.$ac_ext
echo '#line 11724 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
......@@ -12580,7 +12581,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 12583 "configure"
#line 12584 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
......@@ -12678,7 +12679,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 12681 "configure"
#line 12682 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
......@@ -13505,11 +13506,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:13508: $lt_compile\"" >&5)
(eval echo "\"\$as_me:13509: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:13512: \$? = $ac_status" >&5
echo "$as_me:13513: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
......@@ -13565,11 +13566,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:13568: $lt_compile\"" >&5)
(eval echo "\"\$as_me:13569: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:13572: \$? = $ac_status" >&5
echo "$as_me:13573: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
......@@ -14924,7 +14925,7 @@ linux*)
libsuff=
case "$host_cpu" in
x86_64*)
echo '#line 14927 "configure"' > conftest.$ac_ext
echo '#line 14928 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
......@@ -15654,11 +15655,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:15657: $lt_compile\"" >&5)
(eval echo "\"\$as_me:15658: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:15661: \$? = $ac_status" >&5
echo "$as_me:15662: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
......@@ -15887,11 +15888,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:15890: $lt_compile\"" >&5)
(eval echo "\"\$as_me:15891: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:15894: \$? = $ac_status" >&5
echo "$as_me:15895: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
......@@ -15947,11 +15948,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:15950: $lt_compile\"" >&5)
(eval echo "\"\$as_me:15951: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:15954: \$? = $ac_status" >&5
echo "$as_me:15955: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
......@@ -17326,7 +17327,7 @@ linux*)
libsuff=
case "$host_cpu" in
x86_64*)
echo '#line 17329 "configure"' > conftest.$ac_ext
echo '#line 17330 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
......@@ -18186,7 +18187,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 18189 "configure"
#line 18190 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
......@@ -18284,7 +18285,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 18287 "configure"
#line 18288 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
......@@ -19366,6 +19367,13 @@ if test "${enable_audio+set}" = set; then
else
enable_ao=yes
fi;
# Check whether --enable-shout or --disable-shout was given.
if test "${enable_shout+set}" = set; then
enableval="$enable_shout"
else
enable_shout=yes
fi;
# Check whether --enable-iconv or --disable-iconv was given.
if test "${enable_iconv+set}" = set; then
enableval="$enable_iconv"
......@@ -22425,6 +22433,414 @@ _ACEOF
fi
if test x$enable_shout = xyes; then
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
# Extract the first word of "pkg-config", so it can be a program name with args.
set dummy pkg-config; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_path_PKGCONFIG+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
case $PKGCONFIG in
[\\/]* | ?:[\\/]*)
ac_cv_path_PKGCONFIG="$PKGCONFIG" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_PKGCONFIG="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
test -z "$ac_cv_path_PKGCONFIG" && ac_cv_path_PKGCONFIG="no"
;;
esac
fi
PKGCONFIG=$ac_cv_path_PKGCONFIG
if test -n "$PKGCONFIG"; then
echo "$as_me:$LINENO: result: $PKGCONFIG" >&5
echo "${ECHO_T}$PKGCONFIG" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
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
{ echo "$as_me:$LINENO: $PKGCONFIG couldn't find libshout. Try adjusting PKG_CONFIG_PATH." >&5
echo "$as_me: $PKGCONFIG couldn't find libshout. Try adjusting PKG_CONFIG_PATH." >&6;}
fi
# pkg-config unavailable, try shout-config
# Extract the first word of "shout-config", so it can be a program name with args.
set dummy shout-config; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_path_SHOUTCONFIG+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
case $SHOUTCONFIG in
[\\/]* | ?:[\\/]*)
ac_cv_path_SHOUTCONFIG="$SHOUTCONFIG" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_SHOUTCONFIG="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
test -z "$ac_cv_path_SHOUTCONFIG" && ac_cv_path_SHOUTCONFIG="no"
;;
esac
fi
SHOUTCONFIG=$ac_cv_path_SHOUTCONFIG
if test -n "$SHOUTCONFIG"; then
echo "$as_me:$LINENO: result: $SHOUTCONFIG" >&5
echo "${ECHO_T}$SHOUTCONFIG" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
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"
for ac_header in shout/shout.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
else
# Is the header compilable?
echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
#include <$ac_header>
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_header_compiler=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6
# Is the header present?
echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <$ac_header>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
else
ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
ac_header_preproc=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_preproc=no
fi
rm -f conftest.err conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6
# So? What about this header?
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
yes:no: )
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
ac_header_preproc=yes
;;
no:yes:* )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
(
cat <<\_ASBOX
## ------------------------------------------ ##
## Report this to shank@mercury.chem.pitt.edu ##
## ------------------------------------------ ##
_ASBOX
) |
sed "s/^/$as_me: WARNING: /" >&2
;;
esac
echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
eval "$as_ac_Header=\$ac_header_preproc"
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
fi
if test `eval echo '${'$as_ac_Header'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
echo "$as_me:$LINENO: checking for shout_new" >&5
echo $ECHO_N "checking for shout_new... $ECHO_C" >&6
if test "${ac_cv_func_shout_new+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Define shout_new to an innocuous variant, in case <limits.h> declares shout_new.
For example, HP-UX 11i <limits.h> declares gettimeofday. */
#define shout_new innocuous_shout_new
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char shout_new (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
#undef shout_new
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
{
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char shout_new ();
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_shout_new) || defined (__stub___shout_new)
choke me
#else
char (*f) () = shout_new;
#endif
#ifdef __cplusplus
}
#endif
int
main ()
{
return f != shout_new;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_func_shout_new=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_func_shout_new=no
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_func_shout_new" >&5
echo "${ECHO_T}$ac_cv_func_shout_new" >&6
if test $ac_cv_func_shout_new = yes; then
cat >>confdefs.h <<\_ACEOF
#define HAVE_SHOUT 1
_ACEOF
MPD_LIBS="$MPD_LIBS $SHOUT_LIBS" MPD_CFLAGS="$MPD_CFLAGS $SHOUT_CFLAGS"
xt_have_shout="yes"
fi
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <shout/shout.h>
#if SHOUT_THREADSAFE
yes
#endif
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP "yes" >/dev/null 2>&1; then
SHOUT_THREADSAFE="yes"
fi
rm -f conftest*
fi
done
CPPFLAGS="$ac_save_CPPFLAGS"
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
if test "$xt_have_shout" != "yes"
then
enable_shout=no
fi
fi
if test "${ac_cv_header_sys_soundcard_h+set}" = set; then
echo "$as_me:$LINENO: checking for sys/soundcard.h" >&5
echo $ECHO_N "checking for sys/soundcard.h... $ECHO_C" >&6
......@@ -24889,8 +25305,8 @@ fi
LIBS="$ac_save_LIBS"
fi
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
......@@ -26257,7 +26673,7 @@ _ASBOX
} >&5
cat >&5 <<_CSEOF
This file was extended by mpd $as_me 0.11.5, which was
This file was extended by mpd $as_me 0.12.0, which was
generated by GNU Autoconf 2.59. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
......@@ -26320,7 +26736,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
mpd config.status 0.11.5
mpd config.status 0.12.0
configured by $0, generated by GNU Autoconf 2.59,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
......@@ -26589,6 +27005,8 @@ s,@ac_ct_F77@,$ac_ct_F77,;t t
s,@LIBTOOL@,$LIBTOOL,;t t
s,@AO_CFLAGS@,$AO_CFLAGS,;t t
s,@AO_LIBS@,$AO_LIBS,;t t
s,@PKGCONFIG@,$PKGCONFIG,;t t
s,@SHOUTCONFIG@,$SHOUTCONFIG,;t t
s,@subdirs@,$subdirs,;t t
s,@OGG_CFLAGS@,$OGG_CFLAGS,;t t
s,@OGG_LIBS@,$OGG_LIBS,;t t
......@@ -27534,6 +27952,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
......
......@@ -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);
}
extern AudioOutputPlugin aoPlugin;
extern AudioOutputPlugin shoutPlugin;
audio_ao_options = NULL;
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 */
};
/* 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 "../config.h"
#ifdef HAVE_SHOUT
#include "audioOutput.h"
#include "conf.h"
#include "log.h"
#include "sig_handlers.h"
#include "pcm_utils.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <signal.h>
#include <shout/shout.h>
#include <vorbis/vorbisenc.h>
#include <vorbis/codec.h>
static int shoutInitCount = 0;
/* lots of this code blatantly stolent from bossogg/bossao2 */
typedef struct _ShoutData {
shout_t * shoutConn;
ogg_stream_state os;
ogg_page og;
ogg_packet op;
ogg_packet header_main;
ogg_packet header_comments;
ogg_packet header_codebooks;
vorbis_dsp_state vd;
vorbis_block vb;
vorbis_info vi;
vorbis_comment vc;
float quality;
AudioFormat outAudioFormat;
AudioFormat inAudioFormat;
char * convBuffer;
long convBufferLen;
/* shoud we convert the audio to a different format? */
int audioFormatConvert;
int opened;
MpdTag * tag;
} ShoutData;
static ShoutData * newShoutData() {
ShoutData * ret = malloc(sizeof(ShoutData));
ret->shoutConn = shout_new();
ret->convBuffer = NULL;
ret->convBufferLen = 0;
ret->opened = 0;
ret->tag = NULL;
return ret;
}
static void freeShoutData(ShoutData * sd) {
if(sd->shoutConn) shout_free(sd->shoutConn);
if(sd->tag) freeMpdTag(sd->tag);
free(sd);
}
static int shout_initDriver(AudioOutput * audioOutput) {
ShoutData * sd;
char * test;
int port;
char * host;
char * mount;
char * passwd;
char * user;
char * name;
if(!getConf()[CONF_SHOUT_HOST]) {
return -1;
}
sd = newShoutData();
if(!getConf()[CONF_SHOUT_MOUNT]) {
ERROR("shout host defined but not shout mount point\n");
exit(EXIT_FAILURE);
}
if(!getConf()[CONF_SHOUT_PORT]) {
ERROR("shout host defined but not shout port\n");
exit(EXIT_FAILURE);
}
if(!getConf()[CONF_SHOUT_PASSWD]) {
ERROR("shout host defined but not shout password\n");
exit(EXIT_FAILURE);
}
if(!getConf()[CONF_SHOUT_NAME]) {
ERROR("shout host defined but not shout name\n");
exit(EXIT_FAILURE);
}
if(!getConf()[CONF_SHOUT_USER]) {
ERROR("shout host defined but not shout user\n");
exit(EXIT_FAILURE);
}
if(!getConf()[CONF_SHOUT_QUALITY]) {
ERROR("shout host defined but not shout quality\n");
exit(EXIT_FAILURE);
}
if(!getConf()[CONF_SHOUT_FORMAT]) {
ERROR("shout host defined but not shout format\n");
exit(EXIT_FAILURE);
}
host = getConf()[CONF_SHOUT_HOST];
passwd = getConf()[CONF_SHOUT_PASSWD];
user = getConf()[CONF_SHOUT_USER];
mount = getConf()[CONF_SHOUT_MOUNT];
name = getConf()[CONF_SHOUT_NAME];
port = strtol(getConf()[CONF_SHOUT_PORT], &test, 10);
if(*test != '\0' || port <= 0) {
ERROR("shout port \"%s\" is not a positive integer\n",
getConf()[CONF_SHOUT_PORT]);
exit(EXIT_FAILURE);
}
sd->quality = strtod(getConf()[CONF_SHOUT_QUALITY], &test);
if(*test != '\0' || sd->quality < 0.0 || sd->quality > 10.0) {
ERROR("shout quality \"%s\" is not a number in the range "
"0-10\n", getConf()[CONF_SHOUT_QUALITY]);
exit(EXIT_FAILURE);
}
if(0 != parseAudioConfig(&(sd->outAudioFormat),
getConf()[CONF_SHOUT_FORMAT]) )
{
exit(EXIT_FAILURE);
}
if(shout_set_host(sd->shoutConn, host) != SHOUTERR_SUCCESS ||
shout_set_port(sd->shoutConn, port) != SHOUTERR_SUCCESS ||
shout_set_password(sd->shoutConn, passwd) != SHOUTERR_SUCCESS ||
shout_set_mount(sd->shoutConn, mount) != SHOUTERR_SUCCESS ||
shout_set_name(sd->shoutConn, name) != SHOUTERR_SUCCESS ||
shout_set_user(sd->shoutConn, user) != SHOUTERR_SUCCESS ||
shout_set_format(sd->shoutConn, SHOUT_FORMAT_VORBIS)
!= SHOUTERR_SUCCESS ||
shout_set_protocol(sd->shoutConn, SHOUT_PROTOCOL_HTTP)
!= SHOUTERR_SUCCESS)
{
ERROR("error configuring shout: %s\n",
shout_get_error(sd->shoutConn));
exit(EXIT_FAILURE);
}
audioOutput->data = sd;
if(shoutInitCount == 0) shout_init();
shoutInitCount++;
return 0;
}
static void clearEncoder(ShoutData * sd) {
ogg_stream_clear(&(sd->os));
vorbis_block_clear(&(sd->vb));
vorbis_dsp_clear(&(sd->vd));
vorbis_comment_clear(&(sd->vc));
vorbis_info_clear(&(sd->vi));
}
static void shout_closeShoutConn(ShoutData * sd) {
if(sd->opened) {
clearEncoder(sd);
if(shout_close(sd->shoutConn) != SHOUTERR_SUCCESS) {
ERROR("problem closing connection to shout server: "
"%s\n", shout_get_error(sd->shoutConn));
}
}
sd->opened = 0;
}
static void shout_finishDriver(AudioOutput * audioOutput) {
ShoutData * sd = (ShoutData *)audioOutput->data;
shout_closeShoutConn(sd);
freeShoutData(sd);
shoutInitCount--;
if(shoutInitCount == 0) shout_shutdown();
}
static void shout_closeDevice(AudioOutput * audioOutput) {
audioOutput->open = 0;
}
static int shout_handleError(ShoutData * sd, int err) {
switch(err) {
case SHOUTERR_SUCCESS:
break;
case SHOUTERR_UNCONNECTED:
case SHOUTERR_SOCKET:
ERROR("Lost shout connection\n");
return -1;
default:
ERROR("shout: error: %s\n", shout_get_error(sd->shoutConn));
return -1;
}
return 0;
}
static int write_page(ShoutData * sd) {
shout_sync(sd->shoutConn);
int err = shout_send(sd->shoutConn, sd->og.header, sd->og.header_len);
if(shout_handleError(sd, err) < 0) goto fail;
err = shout_send(sd->shoutConn, sd->og.body, sd->og.body_len);
if(shout_handleError(sd, err) < 0) goto fail;
/*shout_sync(sd->shoutConn);*/
return 0;
fail:
shout_closeShoutConn(sd);
return -1;
}
#define addTag(name, value) { \
if(value) vorbis_comment_add_tag(&(sd->vc), name, value); \
}
static void copyTagToVorbisComment(ShoutData * sd) {
if(sd->tag) {
addTag("ARTIST", sd->tag->artist);
addTag("ALBUM", sd->tag->album);
addTag("TITLE", sd->tag->title);
}
}
static int initEncoder(ShoutData * sd) {
vorbis_info_init(&(sd->vi));
if( 0 != vorbis_encode_init_vbr(&(sd->vi), sd->outAudioFormat.channels,
sd->outAudioFormat.sampleRate, sd->quality) )
{
ERROR("problem seting up vorbis encoder for shout\n");
vorbis_info_clear(&(sd->vi));
return -1;
}
vorbis_analysis_init(&(sd->vd), &(sd->vi));
vorbis_block_init (&(sd->vd), &(sd->vb));
ogg_stream_init(&(sd->os), rand());
vorbis_comment_init(&(sd->vc));
return 0;
}
static int shout_openShoutConn(AudioOutput * audioOutput) {
ShoutData * sd = (ShoutData *)audioOutput->data;
if(shout_open(sd->shoutConn) != SHOUTERR_SUCCESS)
{
ERROR("problem opening connection to shout server: %s\n",
shout_get_error(sd->shoutConn));
audioOutput->open = 0;
return -1;
}
if(initEncoder(sd) < 0) {
shout_close(sd->shoutConn);
audioOutput->open = 1;
return -1;
}
copyTagToVorbisComment(sd);
vorbis_analysis_headerout(&(sd->vd), &(sd->vc), &(sd->header_main),
&(sd->header_comments), &(sd->header_codebooks));
ogg_stream_packetin(&(sd->os), &(sd->header_main));
ogg_stream_packetin(&(sd->os), &(sd->header_comments));
ogg_stream_packetin(&(sd->os), &(sd->header_codebooks));
while(ogg_stream_flush(&(sd->os), &(sd->og)))
{
if(write_page(sd) < 0) return -1;
}
if(sd->tag) freeMpdTag(sd->tag);
sd->tag = NULL;
sd->opened = 1;
return 0;
}
static int shout_openDevice(AudioOutput * audioOutput,
AudioFormat * audioFormat)
{
ShoutData * sd = (ShoutData *)audioOutput->data;
memcpy(&(sd->inAudioFormat), audioFormat, sizeof(AudioFormat));
if(0 == memcmp(&(sd->inAudioFormat), &(sd->outAudioFormat),
sizeof(AudioFormat)))
{
sd->audioFormatConvert = 0;
}
else sd->audioFormatConvert = 1;
audioOutput->open = 1;
if(sd->opened) return 0;
return shout_openShoutConn(audioOutput);
}
static void shout_convertAudioFormat(ShoutData * sd, char ** chunkArgPtr,
int * sizeArgPtr)
{
int size = pcm_sizeOfOutputBufferForAudioFormatConversion(
&(sd->inAudioFormat), *sizeArgPtr,
&(sd->outAudioFormat));
if(size > sd->convBufferLen) {
sd->convBuffer = realloc(sd->convBuffer, size);
sd->convBufferLen = size;
}
pcm_convertAudioFormat(&(sd->inAudioFormat), *chunkArgPtr, *sizeArgPtr,
&(sd->outAudioFormat), sd->convBuffer);
*sizeArgPtr = size;
*chunkArgPtr = sd->convBuffer;
}
static void shout_sendMetadata(ShoutData * sd) {
ogg_int64_t granulepos = sd->vd.granulepos;
if(!sd->opened || !sd->tag) return;
clearEncoder(sd);
if(initEncoder(sd) < 0) return;
sd->vd.granulepos = granulepos;
copyTagToVorbisComment(sd);
vorbis_analysis_headerout(&(sd->vd), &(sd->vc), &(sd->header_main),
&(sd->header_comments), &(sd->header_codebooks));
ogg_stream_packetin(&(sd->os), &(sd->header_main));
ogg_stream_packetin(&(sd->os), &(sd->header_comments));
ogg_stream_packetin(&(sd->os), &(sd->header_codebooks));
while(ogg_stream_flush(&(sd->os), &(sd->og)))
{
if(write_page(sd) < 0) return;
}
if(sd->tag) freeMpdTag(sd->tag);
sd->tag = NULL;
}
static int shout_play(AudioOutput * audioOutput, char * playChunk, int size) {
int i,j;
ShoutData * sd = (ShoutData *)audioOutput->data;
float ** vorbbuf;
int samples;
int bytes = sd->outAudioFormat.bits/8;
if(sd->opened && sd->tag) shout_sendMetadata(sd);
if(!sd->opened) {
if(shout_openShoutConn(audioOutput) < 0) {
return -1;
}
}
if(sd->audioFormatConvert) {
shout_convertAudioFormat(sd, &playChunk, &size);
}
samples = size/(bytes*sd->outAudioFormat.channels);
/* this is for only 16-bit audio */
vorbbuf = vorbis_analysis_buffer(&(sd->vd), samples);
for(i=0; i<samples; i++) {
for(j=0; j<sd->outAudioFormat.channels; j++) {
vorbbuf[j][i] = (*((mpd_sint16 *)playChunk)) / 32768.0;
playChunk += bytes;
}
}
vorbis_analysis_wrote(&(sd->vd), samples);
while(1 == vorbis_analysis_blockout(&(sd->vd), &(sd->vb))) {
vorbis_analysis(&(sd->vb), NULL);
vorbis_bitrate_addblock(&(sd->vb));
while(vorbis_bitrate_flushpacket(&(sd->vd), &(sd->op))) {
ogg_stream_packetin(&(sd->os), &(sd->op));
do {
if(ogg_stream_pageout(&(sd->os), &(sd->og)) == 0) {
break;
}
if(write_page(sd) < 0) return -1;
} while(ogg_page_eos(&(sd->og)));
}
}
return 0;
}
static void shout_setTag(AudioOutput * audioOutput, MpdTag * tag) {
ShoutData * sd = (ShoutData *)audioOutput->data;
if(sd->tag) freeMpdTag(sd->tag);
sd->tag = NULL;
if(!tag) return;
sd->tag = mpdTagDup(tag);
}
AudioOutputPlugin shoutPlugin =
{
"shout",
shout_initDriver,
shout_finishDriver,
shout_openDevice,
shout_play,
shout_closeDevice,
shout_setTag
};
#else
#include <stdlib.h>
AudioOutputPlugin shoutPlugin =
{
"shout",
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
#endif
......@@ -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;
if(!mod_mikModInitiated) {
mod_mikModInitiated = 1;
md_device = 0;
md_reverb = 0;
MikMod_RegisterDriver(&drv_mpd);
MikMod_RegisterAllLoaders();
}
md_reverb = 0;
md_mode = (DMODE_SOFT_MUSIC | DMODE_SOFT_SNDFX | DMODE_STEREO |
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,7 +185,14 @@ void pcm_convertAudioFormat(AudioFormat * inFormat, char * inBuffer, size_t
}
/* converts only between 16 bit audio between mono and stereo */
if(inFormat->channels == outFormat->channels)
{
dataChannelConv = dataBitConv;
dataChannelLen = dataBitLen;
}
else {
switch(inFormat->channels) {
/* convert from 1 -> 2 channels */
case 1:
dataChannelLen = (dataBitLen >> 1) << 2;
if(dataChannelLen > channelConvBufferLength) {
......@@ -204,14 +211,30 @@ void pcm_convertAudioFormat(AudioFormat * inFormat, char * inBuffer, size_t
}
}
break;
/* convert from 2 -> 1 channels */
case 2:
dataChannelConv = dataBitConv;
dataChannelLen = dataBitLen;
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) {
memcpy(outBuffer,dataChannelConv,dataChannelLen);
......@@ -219,18 +242,30 @@ 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) {
switch(outFormat->channels) {
case 1:
while( wr_dat < nlen) {
rd_dat = wr_dat * inFormat->sampleRate /
outFormat->sampleRate;
lsample = in[ rd_dat++ ];
out[ wr_dat++ ] = lsample;
}
break;
case 2:
while( wr_dat < nlen) {
rd_dat = wr_dat * inFormat->sampleRate /
outFormat->sampleRate;
rd_dat &= ~1;
......@@ -241,15 +276,17 @@ void pcm_convertAudioFormat(AudioFormat * inFormat, char * inBuffer, size_t
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);
}
if(inFormat->channels != outFormat->channels) {
switch(inFormat->channels) {
case 1:
outSize = (outSize >> 1) << 2;
break;
case 2:
outSize >>= 1;
break;
default:
ERROR("only 1 or 2 channels are supported for conversion!\n");
exit(EXIT_FAILURE);
}
}
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