Commit c0a444d7 authored by Led's avatar Led

0.9.3-rc1

parent 4e533633
Developer -> Warren Dukes <shank@mercury.chem.pitt.edu>
Developer -> tw-nym
wave File Support -> normalperson
setuid patch -> Nagilum
'next' and 'previous' patch -> Niklas Hofer
ver 0.9.3 (2003/10/31)
1) Store total time/length of songs in db and display in *info commands
2) Display instantaneous bitrate in status command
3) Add Wave Support using libaudiofile (Patch from normalperson)
4) Command code cleanup (Patch from tw-nym)
5) Optimize listing of playlists (10-100x faster)
6) Optimize interface output (write in 4kB chunks instead of on every '\n')
7) Fix bug that prevented rm command from working
8) Fix bug where deleting current song skips the next song
ver 0.9.2 (2003/10/6) ver 0.9.2 (2003/10/6)
1) Fix FreeBSD Compilation Problems 1) Fix FreeBSD Compilation Problems
2) Fix bug in move command 2) Fix bug in move command
......
...@@ -70,6 +70,9 @@ AO_CFLAGS = @AO_CFLAGS@ ...@@ -70,6 +70,9 @@ AO_CFLAGS = @AO_CFLAGS@
AO_LIBS = @AO_LIBS@ AO_LIBS = @AO_LIBS@
AR = @AR@ AR = @AR@
AS = @AS@ AS = @AS@
AUDIOFILE_CFLAGS = @AUDIOFILE_CFLAGS@
AUDIOFILE_CONFIG = @AUDIOFILE_CONFIG@
AUDIOFILE_LIBS = @AUDIOFILE_LIBS@
AWK = @AWK@ AWK = @AWK@
CC = @CC@ CC = @CC@
CCAS = @CCAS@ CCAS = @CCAS@
...@@ -125,9 +128,10 @@ RECURSIVE_TARGETS = info-recursive dvi-recursive install-info-recursive \ ...@@ -125,9 +128,10 @@ RECURSIVE_TARGETS = info-recursive dvi-recursive install-info-recursive \
uninstall-info-recursive all-recursive install-data-recursive \ uninstall-info-recursive all-recursive install-data-recursive \
install-exec-recursive installdirs-recursive install-recursive \ install-exec-recursive installdirs-recursive install-recursive \
uninstall-recursive check-recursive installcheck-recursive uninstall-recursive check-recursive installcheck-recursive
DIST_COMMON = README COPYING ChangeLog INSTALL Makefile.am Makefile.in \ DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \
TODO aclocal.m4 config.guess config.sub configure configure.in \ Makefile.in TODO aclocal.m4 compile config.guess config.sub \
depcomp install-sh ltmain.sh missing mkinstalldirs configure configure.in depcomp install-sh ltmain.sh missing \
mkinstalldirs
DIST_SUBDIRS = $(SUBDIRS) DIST_SUBDIRS = $(SUBDIRS)
all: all-recursive all: all-recursive
......
Music Player Daemon (MPD) - UPGRADING Music Player Daemon (MPD) - UPGRADING
Upgrading to 0.9.x Upgrading to 0.9.3
------------------
Wave support was added, so to have your wave files added, update the db (mpc
update).
Also, song lengths are now stored in the db. To get this stuff
added to the db, you will need to recreate the db from scratch. To do this,
run mpd with the "--create-db" commandline option.
Upgrading to 0.9.0
------------------ ------------------
The "stop_on_error" config parameter was removed, so be sure to remove this The "stop_on_error" config parameter was removed, so be sure to remove this
......
...@@ -7116,3 +7116,183 @@ int main () ...@@ -7116,3 +7116,183 @@ int main ()
rm -f conf.libFLACtest rm -f conf.libFLACtest
]) ])
# Configure paths for the Audio File Library
# Bertrand Guiheneuf 98-10-21
# stolen from esd.m4 in esound :
# Manish Singh 98-9-30
# stolen back from Frank Belew
# stolen from Manish Singh
# Shamelessly stolen from Owen Taylor
dnl AM_PATH_AUDIOFILE([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
dnl Test for Audio File Library, and define AUDIOFILE_CFLAGS and AUDIOFILE_LIBS.
dnl
AC_DEFUN(AM_PATH_AUDIOFILE,
[dnl
dnl Get compiler flags and libraries from the audiofile-config script.
dnl
AC_ARG_WITH(audiofile-prefix,[ --with-audiofile-prefix=PFX Prefix where Audio File Library is installed (optional)],
audiofile_prefix="$withval", audiofile_prefix="")
AC_ARG_WITH(audiofile-exec-prefix,[ --with-audiofile-exec-prefix=PFX Exec prefix where Audio File Library is installed (optional)],
audiofile_exec_prefix="$withval", audiofile_exec_prefix="")
AC_ARG_ENABLE(audiofiletest, [ --disable-audiofiletest Do not try to compile and run a test Audio File Library program], , enable_audiofiletest=yes)
if test x$audiofile_exec_prefix != x ; then
audiofile_args="$audiofile_args --exec-prefix=$audiofile_exec_prefix"
if test x${AUDIOFILE_CONFIG+set} != xset ; then
AUDIOFILE_CONFIG=$audiofile_exec_prefix/bin/audiofile-config
fi
fi
if test x$audiofile_prefix != x ; then
audiofile_args="$audiofile_args --prefix=$audiofile_prefix"
if test x${AUDIOFILE_CONFIG+set} != xset ; then
AUDIOFILE_CONFIG=$audiofile_prefix/bin/audiofile-config
fi
fi
AC_PATH_PROG(AUDIOFILE_CONFIG, audiofile-config, no)
min_audiofile_version=ifelse([$1], ,0.2.5,$1)
AC_MSG_CHECKING(for Audio File Library - version >= $min_audiofile_version)
no_audiofile=""
if test "$AUDIOFILE_CONFIG" = "no" ; then
no_audiofile=yes
else
AUDIOFILE_LIBS=`$AUDIOFILE_CONFIG $audiofileconf_args --libs`
AUDIOFILE_CFLAGS=`$AUDIOFILE_CONFIG $audiofileconf_args --cflags`
audiofile_major_version=`$AUDIOFILE_CONFIG $audiofile_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
audiofile_minor_version=`$AUDIOFILE_CONFIG $audiofile_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
audiofile_micro_version=`$AUDIOFILE_CONFIG $audiofile_config_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
if test "x$enable_audiofiletest" = "xyes" ; then
AC_LANG_SAVE
AC_LANG_C
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $AUDIOFILE_CFLAGS"
LIBS="$LIBS $AUDIOFILE_LIBS"
dnl
dnl Now check if the installed Audio File Library is sufficiently new.
dnl (Also checks the sanity of the results of audiofile-config to some extent.)
dnl
rm -f conf.audiofiletest
AC_TRY_RUN([
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <audiofile.h>
char*
my_strdup (char *str)
{
char *new_str;
if (str)
{
new_str = malloc ((strlen (str) + 1) * sizeof(char));
strcpy (new_str, str);
}
else
new_str = NULL;
return new_str;
}
int main ()
{
int major, minor, micro;
char *tmp_version;
system ("touch conf.audiofiletest");
/* HP/UX 9 (%@#!) writes to sscanf strings */
tmp_version = my_strdup("$min_audiofile_version");
if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
printf("%s, bad version string\n", "$min_audiofile_version");
exit(1);
}
if (($audiofile_major_version > major) ||
(($audiofile_major_version == major) && ($audiofile_minor_version > minor)) ||
(($audiofile_major_version == major) && ($audiofile_minor_version == minor) && ($audiofile_micro_version >= micro)))
{
return 0;
}
else
{
printf("\n*** 'audiofile-config --version' returned %d.%d.%d, but the minimum version\n", $audiofile_major_version, $audiofile_minor_version, $audiofile_micro_version);
printf("*** of the Audio File Library required is %d.%d.%d. If audiofile-config is correct, then it is\n", major, minor, micro);
printf("*** best to upgrade to the required version.\n");
printf("*** If audiofile-config was wrong, set the environment variable AUDIOFILE_CONFIG\n");
printf("*** to point to the correct copy of audiofile-config, and remove the file\n");
printf("*** config.cache before re-running configure\n");
return 1;
}
}
],, no_audiofile=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
AC_LANG_RESTORE
fi
fi
if test "x$no_audiofile" = x ; then
AC_MSG_RESULT(yes)
ifelse([$2], , :, [$2])
else
AC_MSG_RESULT(no)
if test "$AUDIOFILE_CONFIG" = "no" ; then
cat <<END
*** The audiofile-config script installed by the Audio File Library could
*** not be found. If the Audio File Library was installed in PREFIX, make
*** sure PREFIX/bin is in your path, or set the AUDIOFILE_CONFIG
*** environment variable to the full path to audiofile-config.
END
else
if test -f conf.audiofiletest ; then
:
else
echo "*** Could not run Audio File Library test program; checking why..."
AC_LANG_SAVE
AC_LANG_C
CFLAGS="$CFLAGS $AUDIOFILE_CFLAGS"
LIBS="$LIBS $AUDIOFILE_LIBS"
AC_TRY_LINK([
#include <stdio.h>
#include <audiofile.h>
], [ return 0; ],
[ cat <<END
*** The test program compiled, but did not run. This usually means that
*** the run-time linker is not finding Audio File Library or finding the
*** wrong version of Audio File Library.
***
*** If it is not finding Audio File Library, you'll need to set your
*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point
*** to the installed location. Also, make sure you have run ldconfig if
*** that is required on your system.
***
*** If you have an old version installed, it is best to remove it, although
*** you may also be able to get things to work by modifying
*** LD_LIBRARY_PATH.
END
],
[ echo "*** The test program failed to compile or link. See the file config.log"
echo "*** for the exact error that occured. This usually means the Audio File"
echo "*** Library was incorrectly installed or that you have moved the Audio"
echo "*** File Library since it was installed. In the latter case, you may want"
echo "*** to edit the audiofile-config script: $AUDIOFILE_CONFIG" ])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
AC_LANG_RESTORE
fi
fi
AUDIOFILE_CFLAGS=""
AUDIOFILE_LIBS=""
ifelse([$3], , :, [$3])
fi
AC_SUBST(AUDIOFILE_CFLAGS)
AC_SUBST(AUDIOFILE_LIBS)
rm -f conf.audiofiletest
])
#! /bin/sh
# Wrapper for compilers which do not understand `-c -o'.
# Copyright 1999, 2000 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# 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, 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.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Usage:
# compile PROGRAM [ARGS]...
# `-o FOO.o' is removed from the args passed to the actual compile.
prog=$1
shift
ofile=
cfile=
args=
while test $# -gt 0; do
case "$1" in
-o)
# configure might choose to run compile as `compile cc -o foo foo.c'.
# So we do something ugly here.
ofile=$2
shift
case "$ofile" in
*.o | *.obj)
;;
*)
args="$args -o $ofile"
ofile=
;;
esac
;;
*.c)
cfile=$1
args="$args $1"
;;
*)
args="$args $1"
;;
esac
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no `-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# `.c' file was seen then we are probably linking. That is also
# ok.
exec "$prog" $args
fi
# Name of file we expect compiler to create.
cofile=`echo $cfile | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
# Create the lock directory.
# Note: use `[/.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo $cofile | sed -e 's|[/.-]|_|g'`.d
while true; do
if mkdir $lockdir > /dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir $lockdir; exit 1" 1 2 15
# Run the compile.
"$prog" $args
status=$?
if test -f "$cofile"; then
mv "$cofile" "$ofile"
fi
rmdir $lockdir
exit $status
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. # 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
timestamp='2003-07-02' timestamp='2003-10-07'
# This file is free software; you can redistribute it and/or modify it # This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by # under the terms of the GNU General Public License as published by
...@@ -734,7 +734,7 @@ EOF ...@@ -734,7 +734,7 @@ EOF
echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;; exit 0 ;;
*:UNICOS/mp:*:*) *:UNICOS/mp:*:*)
echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;; exit 0 ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
...@@ -751,7 +751,7 @@ EOF ...@@ -751,7 +751,7 @@ EOF
*:BSD/OS:*:*) *:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
*:FreeBSD:*:*|*:GNU/FreeBSD:*:*) *:FreeBSD:*:*)
# Determine whether the default compiler uses glibc. # Determine whether the default compiler uses glibc.
eval $set_cc_for_build eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c sed 's/^ //' << EOF >$dummy.c
...@@ -763,7 +763,7 @@ EOF ...@@ -763,7 +763,7 @@ EOF
#endif #endif
EOF EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
# GNU/FreeBSD systems have a "k" prefix to indicate we are using # GNU/KFreeBSD systems have a "k" prefix to indicate we are using
# FreeBSD's kernel, but not the complete OS. # FreeBSD's kernel, but not the complete OS.
case ${LIBC} in gnu) kernel_only='k' ;; esac case ${LIBC} in gnu) kernel_only='k' ;; esac
echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
...@@ -799,8 +799,13 @@ EOF ...@@ -799,8 +799,13 @@ EOF
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;; exit 0 ;;
*:GNU:*:*) *:GNU:*:*)
# the GNU system
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit 0 ;; exit 0 ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
exit 0 ;;
i*86:Minix:*:*) i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix echo ${UNAME_MACHINE}-pc-minix
exit 0 ;; exit 0 ;;
...@@ -948,6 +953,9 @@ EOF ...@@ -948,6 +953,9 @@ EOF
LIBC=gnuaout LIBC=gnuaout
#endif #endif
#endif #endif
#ifdef __dietlibc__
LIBC=dietlibc
#endif
EOF EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
...@@ -1049,7 +1057,7 @@ EOF ...@@ -1049,7 +1057,7 @@ EOF
exit 0 ;; exit 0 ;;
M68*:*:R3V[567]*:*) M68*:*:R3V[567]*:*)
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0) 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)
OS_REL='' OS_REL=''
test -r /etc/.relid \ test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
...@@ -1164,7 +1172,7 @@ EOF ...@@ -1164,7 +1172,7 @@ EOF
*:QNX:*:4*) *:QNX:*:4*)
echo i386-pc-qnx echo i386-pc-qnx
exit 0 ;; exit 0 ;;
NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) NSR-[DGKLNPTVWY]:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE} echo nsr-tandem-nsk${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
*:NonStop-UX:*:*) *:NonStop-UX:*:*)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. # 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
timestamp='2003-07-17' timestamp='2003-10-07'
# This file is (in principle) common to ALL GNU software. # This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software # The presence of a machine in this file suggests that SOME GNU software
...@@ -118,7 +118,7 @@ esac ...@@ -118,7 +118,7 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations. # Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in case $maybe_os in
nto-qnx* | linux-gnu* | kfreebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) nto-qnx* | linux-gnu* | linux-dietlibc | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;; ;;
...@@ -248,6 +248,7 @@ case $basic_machine in ...@@ -248,6 +248,7 @@ case $basic_machine in
| mipsisa32 | mipsisa32el \ | mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \ | mipsisa32r2 | mipsisa32r2el \
| mipsisa64 | mipsisa64el \ | mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \ | mipsisa64sr71k | mipsisa64sr71kel \
| mipstx39 | mipstx39el \ | mipstx39 | mipstx39el \
...@@ -320,6 +321,7 @@ case $basic_machine in ...@@ -320,6 +321,7 @@ case $basic_machine in
| mipsisa32-* | mipsisa32el-* \ | mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa64-* | mipsisa64el-* \ | mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipstx39-* | mipstx39el-* \ | mipstx39-* | mipstx39el-* \
...@@ -1129,7 +1131,7 @@ case $os in ...@@ -1129,7 +1131,7 @@ case $os in
| -aos* \ | -aos* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -kfreebsd* | -freebsd* | -riscix* \ | -hiux* | -386bsd* | -knetbsd* | -netbsd* | -openbsd* | -kfreebsd* | -freebsd* | -riscix* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
...@@ -1165,6 +1167,9 @@ case $os in ...@@ -1165,6 +1167,9 @@ case $os in
-mac*) -mac*)
os=`echo $os | sed -e 's|mac|macos|'` os=`echo $os | sed -e 's|mac|macos|'`
;; ;;
-linux-dietlibc)
os=-linux-dietlibc
;;
-linux*) -linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'` os=`echo $os | sed -e 's|linux|linux-gnu|'`
;; ;;
......
AC_INIT(src/main.c) AC_INIT(src/main.c)
AM_INIT_AUTOMAKE(mpd, 0.9.2) AM_INIT_AUTOMAKE(mpd, 0.9.3)
AC_PROG_CC AC_PROG_CC
AC_PROG_INSTALL AC_PROG_INSTALL
...@@ -19,9 +19,11 @@ AC_SUBST(MPD_CFLAGS) ...@@ -19,9 +19,11 @@ AC_SUBST(MPD_CFLAGS)
MPD_CFLAGS="-Wall" MPD_CFLAGS="-Wall"
MPD_LIBS="" MPD_LIBS=""
AC_ARG_ENABLE(ogg,[ --disable-iconv disable iconv support],,enable_iconv=yes)
AC_ARG_ENABLE(ogg,[ --disable-ogg disable ogg support],,enable_ogg=yes) AC_ARG_ENABLE(ogg,[ --disable-ogg disable ogg support],,enable_ogg=yes)
AC_ARG_ENABLE(flac,[ --disable-flac disable flac support],,enable_flac=yes) AC_ARG_ENABLE(flac,[ --disable-flac disable flac support],,enable_flac=yes)
AC_ARG_ENABLE(mp3,[ --disable-mp3 disable mp3 support],,enable_mp3=yes) AC_ARG_ENABLE(mp3,[ --disable-mp3 disable mp3 support],,enable_mp3=yes)
AC_ARG_ENABLE(audiofile,[ --disable-audiofile disable audiofile support],,enable_audiofile=yes)
AC_ARG_ENABLE(mpd_mad,[ --enable-mpd-mad use mpd libmad],use_mpd_mad=yes,) AC_ARG_ENABLE(mpd_mad,[ --enable-mpd-mad use mpd libmad],use_mpd_mad=yes,)
AC_ARG_ENABLE(id3,[ --disable-id3 disable id3 support],,enable_id3=yes) AC_ARG_ENABLE(id3,[ --disable-id3 disable id3 support],,enable_id3=yes)
AC_ARG_ENABLE(mpd_id3tag,[ --enable-mpd-id3tag use mpd libid3tag],use_mpd_id3tag=yes,) AC_ARG_ENABLE(mpd_id3tag,[ --enable-mpd-id3tag use mpd libid3tag],use_mpd_id3tag=yes,)
...@@ -37,6 +39,10 @@ AC_ARG_WITH(mad-includes,[ --with-mad-includes=DIR Directory where mad header ...@@ -37,6 +39,10 @@ AC_ARG_WITH(mad-includes,[ --with-mad-includes=DIR Directory where mad header
AC_CHECK_LIB(socket,socket,MPD_LIBS="$MPD_LIBS -lsocket",) AC_CHECK_LIB(socket,socket,MPD_LIBS="$MPD_LIBS -lsocket",)
AC_CHECK_LIB(nsl,gethostbyname,MPD_LIBS="$MPD_LIBS -lnsl",) AC_CHECK_LIB(nsl,gethostbyname,MPD_LIBS="$MPD_LIBS -lnsl",)
if test x$enable_iconv = xyes; then
AC_CHECK_HEADER(iconv.h,MPD_CFLAGS="$MPD_CFLAGS -DHAVE_ICONV",)
fi
AC_MSG_CHECKING(for ipv6) AC_MSG_CHECKING(for ipv6)
AC_EGREP_CPP([AP_maGiC_VALUE], AC_EGREP_CPP([AP_maGiC_VALUE],
[ [
...@@ -242,4 +248,9 @@ if test x$enable_flac = xyes; then ...@@ -242,4 +248,9 @@ if test x$enable_flac = xyes; then
MPD_CFLAGS="$MPD_CFLAGS -DHAVE_FLAC" MPD_CFLAGS="$MPD_CFLAGS -DHAVE_FLAC"
fi fi
if test x$enable_audiofile = xyes; then
AM_PATH_AUDIOFILE(0.1.7, MPD_LIBS="$MPD_LIBS -laudiofile" MPD_CFLAGS="$MPD_CFLAGS -DHAVE_AUDIOFILE",
[enable_audiofile=no;AC_MSG_WARN(You need audiofile -- disabling audiofile support)])
fi
AC_OUTPUT(debian/Makefile doc/Makefile src/Makefile Makefile ) AC_OUTPUT(debian/Makefile doc/Makefile src/Makefile Makefile )
EXTRA_DIST = changelog compat control copyright dirs docs rules EXTRA_DIST = changelog compat control copyright dirs docs rules config \
init postinst postrm prerm templates conffiles
...@@ -70,6 +70,9 @@ AO_CFLAGS = @AO_CFLAGS@ ...@@ -70,6 +70,9 @@ AO_CFLAGS = @AO_CFLAGS@
AO_LIBS = @AO_LIBS@ AO_LIBS = @AO_LIBS@
AR = @AR@ AR = @AR@
AS = @AS@ AS = @AS@
AUDIOFILE_CFLAGS = @AUDIOFILE_CFLAGS@
AUDIOFILE_CONFIG = @AUDIOFILE_CONFIG@
AUDIOFILE_LIBS = @AUDIOFILE_LIBS@
AWK = @AWK@ AWK = @AWK@
CC = @CC@ CC = @CC@
CCAS = @CCAS@ CCAS = @CCAS@
...@@ -109,7 +112,9 @@ VORBIS_LIBS = @VORBIS_LIBS@ ...@@ -109,7 +112,9 @@ VORBIS_LIBS = @VORBIS_LIBS@
am__include = @am__include@ am__include = @am__include@
am__quote = @am__quote@ am__quote = @am__quote@
install_sh = @install_sh@ install_sh = @install_sh@
EXTRA_DIST = changelog compat control copyright dirs docs rules EXTRA_DIST = changelog compat control copyright dirs docs rules config \
init postinst postrm prerm templates conffiles
subdir = debian subdir = debian
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_CLEAN_FILES = CONFIG_CLEAN_FILES =
......
mpd (0.9.3-1) unstable; urgency=low
* Update to 0.9.3
* Switch to cdbs
* Use debconf for configure music_directory, playlist_directory, port
* Add /etc/mpd.conf and /etc/mpd/conf
* Add initd script
-- Warren Dukes (aka shank) <shank@mercury.chem.pitt.edu> Tue, 31 Oct 2003 18:16:00 -0400
mpd (0.9.2-1) unstable; urgency=low mpd (0.9.2-1) unstable; urgency=low
* Update to 0.9.2 * Update to 0.9.2
-- Warren Dukes <shank@mercury.chem.pitt.edu> Tue, 06 Oct 2003 22:04:00 -0400 -- Warren Dukes (aka shank) <shank@mercury.chem.pitt.edu> Tue, 06 Oct 2003 22:04:00 -0400
mpd (0.9.1-1) unstable; urgency=low mpd (0.9.1-1) unstable; urgency=low
......
/etc/mpd/conf
#!/bin/sh -e
# Source debconf library.
. /usr/share/debconf/confmodule
# Do you like debian?
db_input medium mpd/systemwide || true
db_go
db_get mpd/systemwide || true
if [ "$RET" = "true" ] ; then
db_input medium mpd/music_directory || true
db_go
db_input medium mpd/playlist_directory || true
db_go
db_input low mpd/port || true
db_go
fi
Source: mpd Source: mpd
Section: sound Section: sound
Priority: optional Priority: optional
Maintainer: Warren Dukes <shank@mercury.chem.pitt.edu> Maintainer: Warren Dukes (aka shank) <shank@mercury.chem.pitt.edu>
Build-Depends: debhelper (>> 4.0.0), libao-dev (>=0.8.3-1), libogg-dev, libvorbis-dev, libflac-dev (>=1.1.0-4), libmad0-dev, libid3tag0-dev Build-Depends: debhelper (>> 4.0.0), libao-dev (>=0.8.3-1), libogg-dev, libvorbis-dev, libflac-dev (>=1.1.0-4), libmad0-dev, libid3tag0-dev, debconf, cdbs, libaudiofile-dev
Standards-Version: 3.5.8 Standards-Version: 3.5.8
Package: mpd Package: mpd
Architecture: any Architecture: any
Depends: ${shlibs:Depends} Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Music Player Daemon (MPD) Description: Music Player Daemon (MPD)
MPD is a server that allows remote access for playing MPD is a server that allows remote access for playing
music (MP3, Ogg Vorbis, and Flac) and managing playlists. The design focus is music (MP3, Ogg Vorbis, and Flac) and managing playlists. The design focus is
......
#! /bin/sh
set -e
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/mpd
DBFILE=/var/run/mpd/mpddb
test -x $DAEMON || exit 0
case "$1" in
start)
if test -f $DBFILE; then
echo -n "Starting Music Player Daemon: mpd"
start-stop-daemon --start --quiet --exec $DAEMON
echo "."
else
echo "MPD db not found, run: $DAEMON --create-db."
fi
;;
stop)
echo -n "Stopping Music Player Daemon: mpd"
start-stop-daemon --stop --quiet --exec $DAEMON || echo -n " ... mpd not running"
echo "."
;;
restart|force-reload)
$0 stop
$0 start
;;
*)
echo "Usage: /etc/init.d/mpd {start|stop|restart|force-reload}"
exit 1
;;
esac
exit 0
#!/bin/sh -e
# Source debconf library.
. /usr/share/debconf/confmodule
db_get mpd/systemwide || true
if [ "$RET" = "true" ] ; then
echo "# BEGIN - GENERTATED BY DEBCONF" > /etc/mpd.conf
db_get mpd/music_directory || true
echo "music_directory \"$RET\"" >> /etc/mpd.conf
db_get mpd/playlist_directory || true
echo "playlist_directory \"$RET\"" >> /etc/mpd.conf
db_get mpd/port || true
echo "port \"$RET\"" >> /etc/mpd.conf
echo "# END - GENERTATED BY DEBCONF" >> /etc/mpd.conf
echo "" >> /etc/mpd.conf
echo "# Rest included from /etc/mpd/conf" >> /etc/mpd.conf
cat /etc/mpd/conf >> /etc/mpd.conf
chmod 600 /etc/mpd.conf
groupadd mpd > /dev/null 2>&1 || true
useradd -M -g mpd -G mpd,audio mpd > /dev/null 2>&1 || true
mkdir -p /var/log/mpd
chown mpd.mpd /var/log/mpd
chmod 700 /var/log/mpd
mkdir -p /var/lib/mpd
chown mpd.mpd /var/lib/mpd
chmod 700 /var/lib/mpd
# Automatically added by dh_installinit
if [ -x "/etc/init.d/mpd" ]; then
update-rc.d mpd defaults >/dev/null
if [ -x /usr/sbin/invoke-rc.d ]; then
invoke-rc.d mpd start
else
/etc/init.d/mpd start
fi
fi
# End automatically added section
fi
#!/bin/sh -e
rm -r /var/log/mpd > /dev/null 2>&1 || true
rm -r /var/lib/mpd > /dev/null 2>&1 || true
# Automatically added by dh_installinit
if [ "$1" = "purge" ] ; then
update-rc.d mpd remove defaults >/dev/null
rm -rf /var/log/mpd
rm -rf /var/lib/mpd
rm -f /etc/mpd.conf
fi
# Automatically added by dh_installdebconf
if [ "$1" = purge ] && [ -e /usr/share/debconf/confmodule ]; then
. /usr/share/debconf/confmodule
db_purge
fi
# End automatically added section
#!/bin/sh -e
# Automatically added by dh_installinit
if [ -x "/etc/init.d/mpd" ]; then
if [ -x /usr/sbin/invoke-rc.d ] ; then
invoke-rc.d mpd stop
else
/etc/init.d/mpd stop
fi
fi
# End automatically added section
#!/usr/bin/make -f #!/usr/bin/make -f
# Sample debian/rules that uses debhelper. include /usr/share/cdbs/1/rules/debhelper.mk
# GNU copyright 1997 to 1999 by Joey Hess. include /usr/share/cdbs/1/class/autotools.mk
# Uncomment this to turn on verbose mode. binary-post-install/mpd::
#export DH_VERBOSE=1 mkdir -p debian/mpd/usr/share/doc/mpd/examples
cp doc/mpdconf.example debian/mpd/usr/share/doc/mpd/examples
mkdir -p debian/mpd/etc/mpd
# These are used for cross-compiling and for saving the configure script echo "#see manpage for mpd for all config options" > debian/mpd/etc/mpd/conf
# from having to guess our platform (since we know it already) echo "log_file \"/var/log/mpd/mpd_log\"" >> debian/mpd/etc/mpd/conf
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) echo "error_file \"/var/log/mpd/mpd_errors\"" >> debian/mpd/etc/mpd/conf
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) echo "db_file \"/var/lib/mpd/mpddb\"" >> debian/mpd/etc/mpd/conf
echo "user \"mpd\"" >> debian/mpd/etc/mpd/conf
CFLAGS = -Wall -g
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
CFLAGS += -O0
else
CFLAGS += -O2
endif
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
INSTALL_PROGRAM += -s
endif
config.status: configure
dh_testdir
# Add here commands to configure the package.
./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info
build: build-stamp
build-stamp: config.status
dh_testdir
# Add here commands to compile the package.
$(MAKE)
#/usr/bin/docbook-to-man debian/mpd.sgml > mpd.1
touch build-stamp
clean:
dh_testdir
dh_testroot
rm -f build-stamp
# Add here commands to clean up after the build process.
-$(MAKE) distclean
ifneq "$(wildcard /usr/share/misc/config.sub)" ""
cp -f /usr/share/misc/config.sub config.sub
endif
ifneq "$(wildcard /usr/share/misc/config.guess)" ""
cp -f /usr/share/misc/config.guess config.guess
endif
dh_clean
install: build
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
# Add here commands to install the package into debian/mpd.
$(MAKE) install DESTDIR=$(CURDIR)/debian/mpd
# Build architecture-independent files here.
binary-indep: build install
# We have nothing to do by default.
# Build architecture-dependent files here.
binary-arch: build install
dh_testdir
dh_testroot
dh_installchangelogs ChangeLog
dh_installdocs
dh_installexamples doc/mpdconf.example
# dh_install
# dh_installmenu
# dh_installdebconf
# dh_installlogrotate
# dh_installemacsen
# dh_installpam
# dh_installmime
# dh_installinit
# dh_installcron
# dh_installinfo
dh_installman
# dh_link
dh_strip
dh_compress
dh_fixperms
# dh_perl
# dh_python
# dh_makeshlibs
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install
Template: mpd/systemwide
Type: boolean
Default: false
Description: Install system mpd service?
You can install mpd as a system daemon. This will create a mpd user and
config file (/etc/mpd.conf). The mpd service will be
started on boot.
Template: mpd/music_directory
Type: string
Default: /usr/share/mpd/music
Description: Music directory for MPD
Which directory do you want MPD to search in for music files?
Template: mpd/playlist_directory
Type: string
Default: /usr/share/mpd/playlists
Description: Music directory for MPD
Which directory do you want MPD to search in for music files?
Template: mpd/port
Type: string
Default: 2100
Description: Port MPD listens on
Which port number do you want MPD to listen on?
...@@ -130,6 +130,7 @@ status ...@@ -130,6 +130,7 @@ status
state: ("play", "stop", or "pause") state: ("play", "stop", or "pause")
song: (current song playing/paused, playlist song number) song: (current song playing/paused, playlist song number)
time: <int elapsed>:<time total> (of current playing/paused song) time: <int elapsed>:<time total> (of current playing/paused song)
bitrate: <int bitrate> (instantaneous bitrate in kbps)
error: if there is an error, returns message here error: if there is an error, returns message here
stop stop
......
...@@ -70,6 +70,9 @@ AO_CFLAGS = @AO_CFLAGS@ ...@@ -70,6 +70,9 @@ AO_CFLAGS = @AO_CFLAGS@
AO_LIBS = @AO_LIBS@ AO_LIBS = @AO_LIBS@
AR = @AR@ AR = @AR@
AS = @AS@ AS = @AS@
AUDIOFILE_CFLAGS = @AUDIOFILE_CFLAGS@
AUDIOFILE_CONFIG = @AUDIOFILE_CONFIG@
AUDIOFILE_LIBS = @AUDIOFILE_LIBS@
AWK = @AWK@ AWK = @AWK@
CC = @CC@ CC = @CC@
CCAS = @CCAS@ CCAS = @CCAS@
......
...@@ -124,7 +124,8 @@ This specifies which address MPD binds to and listens on. The default is "any", ...@@ -124,7 +124,8 @@ This specifies which address MPD binds to and listens on. The default is "any",
which binds to all available addresses. which binds to all available addresses.
.SH EXAMPLES .SH EXAMPLES
.TP .TP
Below is an example config file. Below is an example config file. (Note: '#' at the beginning of a line denotes
a comment. The '#' must be the first character/symbol on that line.)
.br .br
.br .br
......
...@@ -127,7 +127,7 @@ then ...@@ -127,7 +127,7 @@ then
echo "install: no input file specified" echo "install: no input file specified"
exit 1 exit 1
else else
: true
fi fi
if [ x"$dir_arg" != x ]; then if [ x"$dir_arg" != x ]; then
...@@ -138,7 +138,7 @@ if [ x"$dir_arg" != x ]; then ...@@ -138,7 +138,7 @@ if [ x"$dir_arg" != x ]; then
instcmd=: instcmd=:
chmodcmd="" chmodcmd=""
else else
instcmd=$mkdirprog instcmd=mkdir
fi fi
else else
...@@ -146,9 +146,9 @@ else ...@@ -146,9 +146,9 @@ else
# might cause directories to be created, which would be especially bad # might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'. # if $src (and thus $dsttmp) contains '*'.
if [ -f "$src" ] || [ -d "$src" ] if [ -f $src -o -d $src ]
then then
: true
else else
echo "install: $src does not exist" echo "install: $src does not exist"
exit 1 exit 1
...@@ -159,7 +159,7 @@ else ...@@ -159,7 +159,7 @@ else
echo "install: no destination specified" echo "install: no destination specified"
exit 1 exit 1
else else
: true
fi fi
# If destination is a directory, append the input filename; if your system # If destination is a directory, append the input filename; if your system
...@@ -169,7 +169,7 @@ else ...@@ -169,7 +169,7 @@ else
then then
dst="$dst"/`basename $src` dst="$dst"/`basename $src`
else else
: true
fi fi
fi fi
...@@ -181,8 +181,8 @@ dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` ...@@ -181,8 +181,8 @@ dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Skip lots of stat calls in the usual case. # Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then if [ ! -d "$dstdir" ]; then
defaultIFS=' defaultIFS='
' '
IFS="${IFS-${defaultIFS}}" IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}" oIFS="${IFS}"
...@@ -201,7 +201,7 @@ while [ $# -ne 0 ] ; do ...@@ -201,7 +201,7 @@ while [ $# -ne 0 ] ; do
then then
$mkdirprog "${pathcomp}" $mkdirprog "${pathcomp}"
else else
: true
fi fi
pathcomp="${pathcomp}/" pathcomp="${pathcomp}/"
...@@ -212,10 +212,10 @@ if [ x"$dir_arg" != x ] ...@@ -212,10 +212,10 @@ if [ x"$dir_arg" != x ]
then then
$doit $instcmd $dst && $doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else else
# If we're going to rename the final executable, determine the name now. # If we're going to rename the final executable, determine the name now.
...@@ -234,7 +234,7 @@ else ...@@ -234,7 +234,7 @@ else
then then
dstfile=`basename $dst` dstfile=`basename $dst`
else else
: true
fi fi
# Make a temp file name in the proper directory. # Make a temp file name in the proper directory.
...@@ -253,10 +253,10 @@ else ...@@ -253,10 +253,10 @@ else
# ignore errors from any of these, just make sure not to ignore # ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command. # errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination. # Now rename the file to the real destination.
......
...@@ -4,53 +4,9 @@ ...@@ -4,53 +4,9 @@
# Created: 1993-05-16 # Created: 1993-05-16
# Public domain # Public domain
errstatus=0 # $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $
dirmode=""
usage="\
Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
# process command line arguments
while test $# -gt 0 ; do
case "${1}" in
-h | --help | --h* ) # -h for help
echo "${usage}" 1>&2; exit 0 ;;
-m ) # -m PERM arg
shift
test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; }
dirmode="${1}"
shift ;;
-- ) shift; break ;; # stop option processing
-* ) echo "${usage}" 1>&2; exit 1 ;; # unknown option
* ) break ;; # first non-opt arg
esac
done
for file
do
if test -d "$file"; then
shift
else
break
fi
done
case $# in
0) exit 0 ;;
esac
case $dirmode in errstatus=0
'')
if mkdir -p -- . 2>/dev/null; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
fi ;;
*)
if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
fi ;;
esac
for file for file
do do
...@@ -66,24 +22,13 @@ do ...@@ -66,24 +22,13 @@ do
esac esac
if test ! -d "$pathcomp"; then if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp" echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr="" mkdir "$pathcomp" || lasterr=$?
chmod "$dirmode" "$pathcomp" || lasterr=$?
if test ! -z "$lasterr"; then if test ! -d "$pathcomp"; then
errstatus=$lasterr errstatus=$lasterr
fi fi
fi
fi
fi fi
pathcomp="$pathcomp/" pathcomp="$pathcomp/"
...@@ -92,8 +37,4 @@ done ...@@ -92,8 +37,4 @@ done
exit $errstatus exit $errstatus
# Local Variables:
# mode: shell-script
# sh-indentation: 3
# End:
# mkinstalldirs ends here # mkinstalldirs ends here
...@@ -3,12 +3,13 @@ SUBDIRS = $(ID3_SUBDIR) $(MAD_SUBDIR) ...@@ -3,12 +3,13 @@ SUBDIRS = $(ID3_SUBDIR) $(MAD_SUBDIR)
mpd_headers = buffer2array.h interface.h command.h playlist.h ls.h \ mpd_headers = buffer2array.h interface.h command.h playlist.h ls.h \
song.h list.h directory.h tables.h utils.h path.h mp3_decode.h \ song.h list.h directory.h tables.h utils.h path.h mp3_decode.h \
tag.h player.h listen.h conf.h ogg_decode.h volume.h flac_decode.h \ tag.h player.h listen.h conf.h ogg_decode.h volume.h flac_decode.h \
audio.h playerData.h stats.h myfprintf.h sig_handlers.h decode.h log.h audio.h playerData.h stats.h myfprintf.h sig_handlers.h decode.h log.h \
char_conv.h audiofile_decode.h
mpd_SOURCES = main.c buffer2array.c interface.c command.c playlist.c ls.c \ mpd_SOURCES = main.c buffer2array.c interface.c command.c playlist.c ls.c \
song.c list.c directory.c tables.c utils.c path.c mp3_decode.c \ song.c list.c directory.c tables.c utils.c path.c mp3_decode.c \
tag.c player.c listen.c conf.c ogg_decode.c volume.c flac_decode.c \ tag.c player.c listen.c conf.c ogg_decode.c volume.c flac_decode.c \
audio.c playerData.c stats.c myfprintf.c sig_handlers.c decode.c log.c \ audio.c playerData.c stats.c myfprintf.c sig_handlers.c decode.c log.c \
$(mpd_headers) char_conv.c audiofile_decode.c $(mpd_headers)
CFLAGS = @CFLAGS@ $(MPD_CFLAGS) mpd_CFLAGS = $(MPD_CFLAGS)
mpd_LDADD = $(MPD_LIBS) $(ID3_LIB) $(MAD_LIB) mpd_LDADD = $(MPD_LIBS) $(ID3_LIB) $(MAD_LIB)
/* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://www.musicpd.org
*
* libaudiofile (wave) support added by Eric Wong <normalperson@yhbt.net>
*
* 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
*/
#ifdef HAVE_AUDIOFILE
#include "audiofile_decode.h"
#include "command.h"
#include "utils.h"
#include "audio.h"
#include "log.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <audiofile.h>
int getAudiofileTotalTime(char * file)
{
int time;
AFfilehandle af_fp = afOpenFile(file, "r", NULL);
if(af_fp == AF_NULL_FILEHANDLE) {
return -1;
}
time = (int)
((double)afGetFrameCount(af_fp,AF_DEFAULT_TRACK)
/afGetRate(af_fp,AF_DEFAULT_TRACK));
afCloseFile(af_fp);
return time;
}
int audiofile_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc)
{
int fs, frame_count;
AFfilehandle af_fp;
af_fp = afOpenFile(dc->file,"r", NULL);
if(af_fp == AF_NULL_FILEHANDLE) {
ERROR1("failed to open %s\n",dc->file);
return -1;
}
afGetSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &af->bits);
af->sampleRate = (int)afGetRate(af_fp, AF_DEFAULT_TRACK);
af->channels = afGetChannels(af_fp,AF_DEFAULT_TRACK);
frame_count = afGetFrameCount(af_fp,AF_DEFAULT_TRACK);
cb->totalTime = ((float)frame_count/(float)af->sampleRate);
if (af->bits != 8 && af->bits != 16) {
ERROR2("Only 8 and 16-bit files are supported. %s is %i-bit\n",
dc->file,af->bits);
afCloseFile(af_fp);
return -1;
}
fs = (int)afGetFrameSize(af_fp, AF_DEFAULT_TRACK,1);
dc->state = DECODE_STATE_DECODE;
dc->start = 0;
{
int ret, eof = 0, current = 0;
unsigned char chunk[CHUNK_SIZE];
while(!eof) {
if(dc->seek) {
cb->end = 0;
cb->wrap = 0;
current = dc->seekWhere * af->sampleRate;
afSeekFrame(af_fp, AF_DEFAULT_TRACK,current);
dc->seek = 0;
}
ret = afReadFrames(af_fp, AF_DEFAULT_TRACK, chunk, CHUNK_SIZE/fs);
if(ret<=0) eof = 1;
else {
while(cb->begin==cb->end && cb->wrap &&
!dc->stop && !dc->seek){
usleep(1000);
}
if(dc->stop) break;
else if(dc->seek) continue;
memcpy(cb->chunks[cb->end],chunk,CHUNK_SIZE);
cb->chunkSize[cb->end] = CHUNK_SIZE;
current += ret;
cb->times[cb->end] = (float)current/(float)af->sampleRate;
++cb->end;
if(cb->end>=BUFFERED_CHUNKS) {
cb->end = 0;
cb->wrap = 1;
}
}
}
if(dc->seek) dc->seek = 0;
if(dc->stop) {
dc->state = DECODE_STATE_STOP;
dc->stop = 0;
}
else dc->state = DECODE_STATE_STOP;
}
afCloseFile(af_fp);
return 0;
}
#endif /* HAVE_AUDIOFILE */
/* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://www.musicpd.org
*
* libaudiofile (wave) support added by Eric Wong <normalperson@yhbt.net>
*
* 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 AUDIOFILE_DECODE_H
#define AUDIOFILE_DECODE_H
#ifdef HAVE_AUDIOFILE
#include "playerData.h"
int audiofile_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc);
int getAudiofileTotalTime(char * file);
#endif /* HAVE_AUDIOFILE */
#endif /* AUDIOFILE_DECODE_H */
/* the Music Player Daemon (MPD)
* (c)2003 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 "char_conv.h"
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#ifdef HAVE_ICONV
#include <iconv.h>
iconv_t char_conv_iconv;
char * char_conv_to = NULL;
char * char_conv_from = NULL;
#endif
#define BUFFER_SIZE 1024
int setCharSetConversion(char * to, char * from) {
#ifdef HAVE_ICONV
if(char_conv_to && strcmp(to,char_conv_to)==0 &&
char_conv_from && strcmp(from,char_conv_from)==0)
{
return 0;
}
closeCharSetConversion();
if((char_conv_iconv = iconv_open(to,from))==(iconv_t)(-1)) return -1;
char_conv_to = strdup(to);
char_conv_from = strdup(from);
return 0;
#endif
return -1;
}
char * convStrDup(char * string) {
#ifdef HAVE_ICONV
char buffer[BUFFER_SIZE];
int inleft = strlen(string);
char * ret;
int outleft;
int retlen = 0;
size_t err;
char * bufferPtr;
if(!char_conv_to) return NULL;
ret = strdup("");
while(inleft) {
bufferPtr = buffer;
outleft = BUFFER_SIZE;
err = iconv(char_conv_iconv,&string,&inleft,&bufferPtr,
&outleft);
if(outleft==BUFFER_SIZE || (err<0 && errno!=E2BIG)) {
free(ret);
return NULL;
}
ret = realloc(ret,retlen+BUFFER_SIZE-outleft+1);
strncpy(&(ret[retlen]),buffer,BUFFER_SIZE-outleft);
retlen+=BUFFER_SIZE-outleft;
ret[retlen] = '\0';
}
return ret;
#endif
return NULL;
}
void closeCharSetConversion() {
#ifdef HAVE_ICONV
if(char_conv_to) {
iconv_close(char_conv_iconv);
free(char_conv_to);
free(char_conv_from);
char_conv_to = NULL;
char_conv_from = NULL;
}
#endif
}
/* the Music Player Daemon (MPD)
* (c)2003 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 CHAR_CONV_H
#define CHAR_CONV_H
int setCharSetConversion(char * to, char * from);
char * convStrDup(char * string);
void closeCharSetConversion();
#endif
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "decode.h" #include "decode.h"
#include "player.h" #include "player.h"
#include "playerData.h"
#include "utils.h" #include "utils.h"
#include "audio.h" #include "audio.h"
...@@ -30,6 +31,9 @@ ...@@ -30,6 +31,9 @@
#ifdef HAVE_FLAC #ifdef HAVE_FLAC
#include "flac_decode.h" #include "flac_decode.h"
#endif #endif
#ifdef HAVE_AUDIOFILE
#include "audiofile_decode.h"
#endif
#include "path.h" #include "path.h"
#include "log.h" #include "log.h"
...@@ -98,6 +102,7 @@ int waitOnDecode(PlayerControl * pc, AudioFormat * af, DecoderControl * dc, ...@@ -98,6 +102,7 @@ int waitOnDecode(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
} }
pc->elapsedTime = 0; pc->elapsedTime = 0;
pc->bitRate = 0;
pc->totalTime = cb->totalTime; pc->totalTime = cb->totalTime;
return 0; return 0;
...@@ -125,6 +130,7 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc, ...@@ -125,6 +130,7 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
cb->begin = 0; cb->begin = 0;
dc->seek = 1; dc->seek = 1;
pc->elapsedTime = dc->seekWhere; pc->elapsedTime = dc->seekWhere;
pc->bitRate = 0;
while(decode_pid>0 && dc->seek) usleep(10); while(decode_pid>0 && dc->seek) usleep(10);
} }
} }
...@@ -182,6 +188,11 @@ int decoderInit(PlayerControl * pc, Buffer * cb, AudioFormat *af, ...@@ -182,6 +188,11 @@ int decoderInit(PlayerControl * pc, Buffer * cb, AudioFormat *af,
dc->error = flac_decode(cb,af,dc); dc->error = flac_decode(cb,af,dc);
break; break;
#endif #endif
#ifdef HAVE_AUDIOFILE
case DECODE_TYPE_AUDIOFILE:
dc->error = audiofile_decode(cb,af,dc);
break;
#endif
default: default:
dc->error = DECODE_ERROR_UNKTYPE; dc->error = DECODE_ERROR_UNKTYPE;
} }
...@@ -196,7 +207,7 @@ int decoderInit(PlayerControl * pc, Buffer * cb, AudioFormat *af, ...@@ -196,7 +207,7 @@ int decoderInit(PlayerControl * pc, Buffer * cb, AudioFormat *af,
dc->stop = 0; dc->stop = 0;
} }
else if(dc->seek) dc->start = 1; else if(dc->seek) dc->start = 1;
else usleep(10); else usleep(1000);
} }
exit(0); exit(0);
...@@ -279,6 +290,7 @@ void decode() { ...@@ -279,6 +290,7 @@ void decode() {
cb->begin!=cb->next) cb->begin!=cb->next)
{ {
pc->elapsedTime = cb->times[cb->begin]; pc->elapsedTime = cb->times[cb->begin];
pc->bitRate = cb->bitRate[cb->begin];
playAudio(cb->chunks[cb->begin], playAudio(cb->chunks[cb->begin],
cb->chunkSize[cb->begin]); cb->chunkSize[cb->begin]);
cb->begin++; cb->begin++;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#define DECODE_TYPE_MP3 0 #define DECODE_TYPE_MP3 0
#define DECODE_TYPE_OGG 1 #define DECODE_TYPE_OGG 1
#define DECODE_TYPE_FLAC 2 #define DECODE_TYPE_FLAC 2
#define DECODE_TYPE_AUDIOFILE 3
#define DECODE_STATE_STOP 0 #define DECODE_STATE_STOP 0
#define DECODE_STATE_DECODE 1 #define DECODE_STATE_DECODE 1
......
...@@ -526,31 +526,36 @@ void initMp3Directory() { ...@@ -526,31 +526,36 @@ void initMp3Directory() {
} }
Song * getSong(char * file) { Song * getSong(char * file) {
static char * c; void * song;
static char * shortname; Directory * directory;
static char dir[MAXPATHLEN]; char * shortname = NULL;
static char dup[MAXPATHLEN]; char * dir = NULL;
static Directory * directory; char * dup = strdup(file);
static void * song; char * c = strtok(dup,"/");
if(strlen(file)>MAXPATHLEN) return NULL;
dir[0] = '\0';
strcpy(dup,file);
c = strtok(dup,"/");
while(c) { while(c) {
shortname = c; shortname = c;
c = strtok(NULL,"/"); c = strtok(NULL,"/");
if(c) { }
strcat(dir,shortname);
strcat(dir,"/"); if(shortname!=dup) {
for(c = dup; c < shortname-1; c++) {
if(*c=='\0') *c = '/';
} }
dir = dup;
} }
if(!(directory = getSubDirectory(mp3rootDirectory,dir))) return NULL; if(!(directory = getSubDirectory(mp3rootDirectory,dir))) {
free(dup);
return NULL;
}
if(!findInList(directory->songs,shortname,&song)) return NULL; if(!findInList(directory->songs,shortname,&song)) {
free(dup);
return NULL;
}
free(dup);
return (Song *)song; return (Song *)song;
} }
......
...@@ -175,7 +175,7 @@ int flacSendChunk(FlacData * data) { ...@@ -175,7 +175,7 @@ int flacSendChunk(FlacData * data) {
while(data->cb->begin==data->cb->end && data->cb->wrap && while(data->cb->begin==data->cb->end && data->cb->wrap &&
!data->dc->stop && !data->dc->seek) !data->dc->stop && !data->dc->seek)
{ {
usleep(10); usleep(1000);
} }
if(data->dc->stop) return -1; if(data->dc->stop) return -1;
...@@ -184,6 +184,7 @@ int flacSendChunk(FlacData * data) { ...@@ -184,6 +184,7 @@ int flacSendChunk(FlacData * data) {
memcpy(data->cb->chunks[data->cb->end],data->chunk,CHUNK_SIZE); memcpy(data->cb->chunks[data->cb->end],data->chunk,CHUNK_SIZE);
data->cb->chunkSize[data->cb->end] = data->chunk_length; data->cb->chunkSize[data->cb->end] = data->chunk_length;
data->cb->times[data->cb->end] = data->time; data->cb->times[data->cb->end] = data->time;
data->cb->bitRate[data->cb->end] = 0;
data->cb->end++; data->cb->end++;
if(data->cb->end>=BUFFERED_CHUNKS) { if(data->cb->end>=BUFFERED_CHUNKS) {
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#define INTERFACE_MAX_BUFFER_LENGTH MAXPATHLEN+1024 #define INTERFACE_MAX_BUFFER_LENGTH MAXPATHLEN+1024
#define INTERFACE_LIST_MODE_BEGIN "command_list_begin" #define INTERFACE_LIST_MODE_BEGIN "command_list_begin"
#define INTERFACE_LIST_MODE_END "command_list_end" #define INTERFACE_LIST_MODE_END "command_list_end"
#define INTERFACE_MAX_OUT_BUFFER_LENGTH 4096
int interface_max_connections; int interface_max_connections;
int interface_timeout; int interface_timeout;
...@@ -65,12 +66,16 @@ typedef struct _Interface { ...@@ -65,12 +66,16 @@ typedef struct _Interface {
int expired; /* set whether this interface should be closed on next int expired; /* set whether this interface should be closed on next
check of old interfaces */ check of old interfaces */
int num; /* interface number */ int num; /* interface number */
char outBuffer[INTERFACE_MAX_OUT_BUFFER_LENGTH];
int outBuflen;
} Interface; } Interface;
Interface * interfaces = NULL; Interface * interfaces = NULL;
void flushInterfaceBuffer(Interface * interface); void flushInterfaceBuffer(Interface * interface);
void printInterfaceOutBuffer(Interface * interface);
void openInterface(Interface * interface, int fd) { void openInterface(Interface * interface, int fd) {
int flags; int flags;
...@@ -90,9 +95,12 @@ void openInterface(Interface * interface, int fd) { ...@@ -90,9 +95,12 @@ void openInterface(Interface * interface, int fd) {
interface->bufferList = NULL; interface->bufferList = NULL;
interface->expired = 0; interface->expired = 0;
interface->outputBufferSize = 0; interface->outputBufferSize = 0;
interface->outBuflen = 0;
unblockSignals(); unblockSignals();
myfprintf(interface->fp,"%s %s %s\n",COMMAND_RESPOND_OK,GREETING,VERSION); myfprintf(interface->fp,"%s %s %s\n",COMMAND_RESPOND_OK,GREETING,
VERSION);
printInterfaceOutBuffer(interface);
} }
void closeInterface(Interface * interface) { void closeInterface(Interface * interface) {
...@@ -205,6 +213,7 @@ int interfaceReadInput(Interface * interface) { ...@@ -205,6 +213,7 @@ int interfaceReadInput(Interface * interface) {
interface->expired) { interface->expired) {
closeInterface(interface); closeInterface(interface);
} }
printInterfaceOutBuffer(interface);
freeList(interface->commandList); freeList(interface->commandList);
interface->commandList = NULL; interface->commandList = NULL;
...@@ -246,6 +255,7 @@ int interfaceReadInput(Interface * interface) { ...@@ -246,6 +255,7 @@ int interfaceReadInput(Interface * interface) {
interface->expired) { interface->expired) {
closeInterface(interface); closeInterface(interface);
} }
printInterfaceOutBuffer(interface);
} }
} }
freeArgArray(argArray,argArrayLength); freeArgArray(argArray,argArrayLength);
...@@ -260,28 +270,30 @@ int interfaceReadInput(Interface * interface) { ...@@ -260,28 +270,30 @@ int interfaceReadInput(Interface * interface) {
return 1; return 1;
} }
void addInterfacesReadyToReadAndListenSocketToFdSet(fd_set * fds) { void addInterfacesReadyToReadAndListenSocketToFdSet(fd_set * fds, int * fdmax) {
int i; int i;
FD_ZERO(fds); FD_ZERO(fds);
FD_SET(listenSocket,fds); FD_SET(listenSocket,fds);
if(*fdmax<listenSocket) *fdmax = listenSocket;
for(i=0;i<interface_max_connections;i++) { for(i=0;i<interface_max_connections;i++) {
if(interfaces[i].open && !interfaces[i].expired && !interfaces[i].bufferList) { if(interfaces[i].open && !interfaces[i].expired && !interfaces[i].bufferList) {
FD_SET(interfaces[i].fd,fds); FD_SET(interfaces[i].fd,fds);
if(*fdmax<interfaces[i].fd) *fdmax = interfaces[i].fd;
} }
} }
} }
void addInterfacesForBufferFlushToFdSet(fd_set * fds) { void addInterfacesForBufferFlushToFdSet(fd_set * fds, int * fdmax) {
int i; int i;
FD_ZERO(fds); FD_ZERO(fds);
FD_SET(listenSocket,fds);
for(i=0;i<interface_max_connections;i++) { for(i=0;i<interface_max_connections;i++) {
if(interfaces[i].open && !interfaces[i].expired && interfaces[i].bufferList) { if(interfaces[i].open && !interfaces[i].expired && interfaces[i].bufferList) {
FD_SET(interfaces[i].fd,fds); FD_SET(interfaces[i].fd,fds);
if(*fdmax<interfaces[i].fd) *fdmax = interfaces[i].fd;
} }
} }
} }
...@@ -312,14 +324,15 @@ int doIOForInterfaces() { ...@@ -312,14 +324,15 @@ int doIOForInterfaces() {
struct timeval tv; struct timeval tv;
int i; int i;
int selret; int selret;
int fdmax = 0;
tv.tv_sec = 1; tv.tv_sec = 1;
tv.tv_usec = 0; tv.tv_usec = 0;
addInterfacesReadyToReadAndListenSocketToFdSet(&rfds); addInterfacesReadyToReadAndListenSocketToFdSet(&rfds,&fdmax);
addInterfacesForBufferFlushToFdSet(&wfds); addInterfacesForBufferFlushToFdSet(&wfds,&fdmax);
while((selret = select(FD_SETSIZE,&rfds,&wfds,NULL,&tv))) { while((selret = select(fdmax+1,&rfds,&wfds,NULL,&tv))) {
if(FD_ISSET(listenSocket,&rfds)) getConnections(listenSocket); if(FD_ISSET(listenSocket,&rfds)) getConnections(listenSocket);
if(selret<0 && errno==EINTR) break; if(selret<0 && errno==EINTR) break;
else if(selret<0) { else if(selret<0) {
...@@ -340,8 +353,9 @@ int doIOForInterfaces() { ...@@ -340,8 +353,9 @@ int doIOForInterfaces() {
} }
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = 0; tv.tv_usec = 0;
addInterfacesReadyToReadAndListenSocketToFdSet(&rfds); fdmax = 0;
addInterfacesForBufferFlushToFdSet(&wfds); addInterfacesReadyToReadAndListenSocketToFdSet(&rfds,&fdmax);
addInterfacesForBufferFlushToFdSet(&wfds,&fdmax);
} }
return 1; return 1;
...@@ -474,9 +488,11 @@ void flushAllInterfaceBuffers() { ...@@ -474,9 +488,11 @@ void flushAllInterfaceBuffers() {
int interfacePrintWithFD(int fd,char * buffer) { int interfacePrintWithFD(int fd,char * buffer) {
int i; int i;
int ret; int buflen;
int copylen;
Interface * interface;
if(!strlen(buffer)) return -1; if(!(buflen = strlen(buffer))) return -1;
for(i=0;i<interface_max_connections;i++) { for(i=0;i<interface_max_connections;i++) {
if(interfaces[i].fd==fd) break; if(interfaces[i].fd==fd) break;
...@@ -485,50 +501,96 @@ int interfacePrintWithFD(int fd,char * buffer) { ...@@ -485,50 +501,96 @@ int interfacePrintWithFD(int fd,char * buffer) {
/* if fd isn't found or interfaces is going to be closed, do nothing */ /* if fd isn't found or interfaces is going to be closed, do nothing */
if(i==interface_max_connections || interfaces[i].expired) return -1; if(i==interface_max_connections || interfaces[i].expired) return -1;
if(interfaces[i].bufferList) { interface = interfaces+i;
interfaces[i].outputBufferSize+=sizeof(ListNode);
interfaces[i].outputBufferSize+=strlen(buffer)+1; while(buflen>0) {
if(interfaces[i].outputBufferSize>interface_max_output_buffer_size) { copylen = buflen>
INTERFACE_MAX_OUT_BUFFER_LENGTH-interface->outBuflen?
INTERFACE_MAX_OUT_BUFFER_LENGTH-interface->outBuflen:
buflen;
memcpy(interface->outBuffer+interface->outBuflen,buffer,
copylen);
buflen-=copylen;
interface->outBuflen+=copylen;
buffer+=copylen;
if(interface->outBuflen>=INTERFACE_MAX_OUT_BUFFER_LENGTH) {
printInterfaceOutBuffer(interface);
}
}
return 0;
}
void printInterfaceOutBuffer(Interface * interface) {
char * buffer;
int ret;
if(!interface->open || interface->expired || !interface->outBuflen) {
return;
}
if(interface->bufferList) {
interface->outputBufferSize+=sizeof(ListNode);
interface->outputBufferSize+=interface->outBuflen+1;
if(interface->outputBufferSize>
interface_max_output_buffer_size)
{
ERROR3("interface %i: output buffer size (%lli) is " ERROR3("interface %i: output buffer size (%lli) is "
"larger than the max (%lli)\n", "larger than the max (%lli)\n",
interfaces[i].num, interface->num,
interfaces[i].outputBufferSize, interface->outputBufferSize,
interface_max_output_buffer_size); interface_max_output_buffer_size);
/* cause interface to close */ /* cause interface to close */
freeList(interfaces[i].bufferList); freeList(interface->bufferList);
interfaces[i].bufferList = NULL; interface->bufferList = NULL;
interfaces[i].expired = 1; interface->expired = 1;
return 0;
} }
else { else {
insertInListWithoutKey(interfaces[i].bufferList,(void *)strdup(buffer)); buffer = malloc(interface->outBuflen+1);
flushInterfaceBuffer(&interfaces[i]); memcpy(buffer,interface->outBuffer,interface->outBuflen);
buffer[interface->outBuflen] = '\0';
insertInListWithoutKey(interface->bufferList,(void *)buffer);
flushInterfaceBuffer(interface);
} }
} }
else { else {
if((ret = write(fd,buffer,strlen(buffer)))<0) { if((ret = write(interface->fd,interface->outBuffer,
interface->outBuflen))<0)
{
if(errno==EAGAIN || errno==EINTR) { if(errno==EAGAIN || errno==EINTR) {
interfaces[i].bufferList = makeList(free); buffer = malloc(interface->outBuflen+1);
insertInListWithoutKey(interfaces[i].bufferList,(void *)strdup(buffer)); memcpy(buffer,interface->outBuffer,
interface->outBuflen);
buffer[interface->outBuflen] = '\0';
interface->bufferList = makeList(free);
insertInListWithoutKey(interface->bufferList,
(void *)buffer);
} }
else { else {
DEBUG1("interface %i: problems writing\n",i); DEBUG1("interface %i: problems writing\n",
interfaces[i].expired = 1; interface->num);
return 0; interface->expired = 1;
return;
} }
} }
else if(ret<strlen(buffer)) { else if(ret<interface->outBuflen) {
interfaces[i].bufferList = makeList(free); buffer = malloc(interface->outBuflen-ret+1);
insertInListWithoutKey(interfaces[i].bufferList,(void *)strdup(&buffer[ret])); memcpy(buffer,interface->outBuffer+ret,
interface->outBuflen-ret);
buffer[interface->outBuflen-ret] = '\0';
interface->bufferList = makeList(free);
insertInListWithoutKey(interface->bufferList,buffer);
} }
/* if we needed to create buffer, initialize bufferSize info */ /* if we needed to create buffer, initialize bufferSize info */
if(interfaces[i].bufferList) { if(interface->bufferList) {
DEBUG1("interface %i: buffer created\n",i); DEBUG1("interface %i: buffer created\n",interface->num);
interfaces[i].outputBufferSize = sizeof(List); interface->outputBufferSize = sizeof(List);
interfaces[i].outputBufferSize+=sizeof(ListNode); interface->outputBufferSize+=sizeof(ListNode);
interfaces[i].outputBufferSize+=strlen((char *)interfaces[i].bufferList->firstNode->data)+1; interface->outputBufferSize+=strlen(
(char *)interface->bufferList->
firstNode->data)+1;
} }
} }
return 0; interface->outBuflen = 0;
} }
...@@ -82,36 +82,40 @@ int lsPlaylists(FILE * fp, char * path) { ...@@ -82,36 +82,40 @@ int lsPlaylists(FILE * fp, char * path) {
DIR * dir; DIR * dir;
struct stat st; struct stat st;
struct dirent * ent; struct dirent * ent;
char * cLast;
char * cNext;
char * dup; char * dup;
char s[MAXPATHLEN+1]; char s[MAXPATHLEN+1];
List * list = NULL; List * list = NULL;
ListNode * node = NULL; ListNode * node = NULL;
char * actualPath = rpp2app(path); char * actualPath = rpp2app(path);
int actlen = strlen(actualPath)+1;
int maxlen = MAXPATHLEN-actlen;
int suflen = strlen(PLAYLIST_FILE_SUFFIX)+1;
int suff;
if(actlen>MAXPATHLEN-1) return 0;
if((dir = opendir(actualPath))==NULL) return 0; if((dir = opendir(actualPath))==NULL) return 0;
s[MAXPATHLEN] = '\0';
strcpy(s,actualPath);
strcat(s,"/");
while((ent = readdir(dir))) { while((ent = readdir(dir))) {
if(ent->d_name[0]=='.') continue; /* hide hidden stuff */ dup = ent->d_name;
snprintf(s,MAXPATHLEN,"%s/%s",actualPath,ent->d_name); if(dup[0]!='.' &&
if(stat(s,&st)==0) { (suff=strlen(dup)-suflen)>0 &&
if(S_ISREG(st.st_mode)) { dup[suff]=='.' &&
dup = strdup(ent->d_name); strcmp(dup+suff+1,PLAYLIST_FILE_SUFFIX)==0)
cNext = cLast = strtok(dup,"."); {
while((cNext = strtok(NULL,"."))) cLast = cNext; strncpy(s+actlen,ent->d_name,maxlen);
if(cLast && 0==strcmp(cLast, if(stat(s,&st)==0) {
PLAYLIST_FILE_SUFFIX)) if(S_ISREG(st.st_mode)) {
{
if(list==NULL) list = makeList(NULL); if(list==NULL) list = makeList(NULL);
memset(dup,0,strlen(ent->d_name)); dup = strdup(ent->d_name);
strncpy(dup,ent->d_name, dup[suff] = '\0';
strlen(ent->d_name)-
strlen(PLAYLIST_FILE_SUFFIX)-1);
//myfprintf(fp,"playlist: %s\n",dup);
insertInList(list,dup,NULL); insertInList(list,dup,NULL);
free(dup);
} }
free(dup);
} }
} }
} }
...@@ -151,6 +155,9 @@ time_t isMusic(char * file) { ...@@ -151,6 +155,9 @@ time_t isMusic(char * file) {
#ifdef HAVE_MAD #ifdef HAVE_MAD
if((ret = isMp3(file)>0)) return ret; if((ret = isMp3(file)>0)) return ret;
#endif #endif
#ifdef HAVE_AUDIOFILE
if((ret = isWave(file)>0)) return ret;
#endif
return ret; return ret;
} }
...@@ -184,6 +191,33 @@ time_t isPlaylist(char * file) { ...@@ -184,6 +191,33 @@ time_t isPlaylist(char * file) {
return 0; return 0;
} }
time_t isWave(char * file) {
struct stat st;
char * actualFile = file;
if(actualFile[0]!='/') actualFile = rmp2amp(file);
if(stat(actualFile,&st)==0) {
if(S_ISREG(st.st_mode)) {
char * dup;
char * cLast;
char * cNext;
int ret = 0;
dup = strdup(file);
cNext = cLast = strtok(dup,".");
while((cNext = strtok(NULL,"."))) cLast = cNext;
if(cLast && 0==strcasecmp(cLast,"wav")) {
ret = st.st_mtime;
}
free(dup);
return ret;
}
else return 0;
}
return 0;
}
time_t isFlac(char * file) { time_t isFlac(char * file) {
struct stat st; struct stat st;
char * actualFile = file; char * actualFile = file;
......
...@@ -32,6 +32,8 @@ time_t isOgg(char * file); ...@@ -32,6 +32,8 @@ time_t isOgg(char * file);
time_t isFlac(char * file); time_t isFlac(char * file);
time_t isWave(char * file);
time_t isMusic(char * file); time_t isMusic(char * file);
time_t isDir(char * name); time_t isDir(char * name);
......
...@@ -67,11 +67,12 @@ void usage(char * argv[]) { ...@@ -67,11 +67,12 @@ void usage(char * argv[]) {
SYSTEM_CONFIG_FILE_LOCATION); SYSTEM_CONFIG_FILE_LOCATION);
ERROR0("\n"); ERROR0("\n");
ERROR0("options:\n"); ERROR0("options:\n");
ERROR0(" --help this usage statement\n"); ERROR0(" --help this usage statement\n");
ERROR0(" --no-daemon don't detach from console\n"); ERROR0(" --no-daemon don't detach from console\n");
ERROR0(" --create-db (re)create database\n"); ERROR0(" --create-db force (re)creation database\n");
ERROR0(" --verbose verbose logging\n"); ERROR0(" --no-create-db don't create database\n");
ERROR0(" --version prints version information\n"); ERROR0(" --verbose verbose logging\n");
ERROR0(" --version prints version information\n");
} }
void version() { void version() {
...@@ -106,6 +107,10 @@ void parseOptions(int argc, char ** argv, Options * options) { ...@@ -106,6 +107,10 @@ void parseOptions(int argc, char ** argv, Options * options) {
options->createDB = 1; options->createDB = 1;
argcLeft--; argcLeft--;
} }
else if(strcmp(argv[i],"--no-create-db")==0) {
options->createDB = -1;
argcLeft--;
}
else if(strcmp(argv[i],"--verbose")==0) { else if(strcmp(argv[i],"--verbose")==0) {
logLevel = LOG_LEVEL_DEBUG; logLevel = LOG_LEVEL_DEBUG;
argcLeft--; argcLeft--;
...@@ -174,6 +179,18 @@ int main(int argc, char * argv[]) { ...@@ -174,6 +179,18 @@ int main(int argc, char * argv[]) {
FILE * out; FILE * out;
FILE * err; FILE * err;
Options options; Options options;
int i;
for(i=0;i<FD_SETSIZE;i++) {
switch(i) {
case STDIN_FILENO:
case STDOUT_FILENO:
case STDERR_FILENO:
break;
default:
close(i);
}
}
initConf(); initConf();
...@@ -309,6 +326,11 @@ int main(int argc, char * argv[]) { ...@@ -309,6 +326,11 @@ int main(int argc, char * argv[]) {
} }
else strncpy(directorydb,options.dbFile,MAXPATHLEN); else strncpy(directorydb,options.dbFile,MAXPATHLEN);
if(options.createDB || readDirectoryDB()<0) { if(options.createDB || readDirectoryDB()<0) {
if(options.createDB<0) {
ERROR0("can't open db file and using \"--no-create-db\""
" command line option\n");
exit(-1);
}
initMp3Directory(); initMp3Directory();
if(writeDirectoryDB()<0) { if(writeDirectoryDB()<0) {
ERROR0("problem opening db for reading or writing\n"); ERROR0("problem opening db for reading or writing\n");
...@@ -323,9 +345,12 @@ int main(int argc, char * argv[]) { ...@@ -323,9 +345,12 @@ int main(int argc, char * argv[]) {
initStats(); initStats();
initPlaylist(); initPlaylist();
close(STDIN_FILENO);
if(options.daemon) { if(options.daemon) {
int pid = fork(); int pid;
fflush(NULL);
pid = fork();
if(pid>0) _exit(0); if(pid>0) _exit(0);
else if(pid<0) { else if(pid<0) {
ERROR0("problems fork'ing for daemon!\n"); ERROR0("problems fork'ing for daemon!\n");
...@@ -337,6 +362,11 @@ int main(int argc, char * argv[]) { ...@@ -337,6 +362,11 @@ int main(int argc, char * argv[]) {
exit(-1); exit(-1);
} }
if(setsid()<0) {
ERROR0("problems setsid'ing\n");
exit(-1);
}
if(close(STDOUT_FILENO)) { if(close(STDOUT_FILENO)) {
fprintf(err,"problems closing stdout : %s\n", fprintf(err,"problems closing stdout : %s\n",
strerror(errno)); strerror(errno));
...@@ -362,13 +392,20 @@ int main(int argc, char * argv[]) { ...@@ -362,13 +392,20 @@ int main(int argc, char * argv[]) {
} }
myfprintfStdLogMode(out,err); myfprintfStdLogMode(out,err);
fflush(NULL);
pid = fork();
if(pid>0) _exit(0);
else if(pid<0) {
ERROR0("problems fork'ing for daemon!\n");
exit(-1);
}
} }
else { else {
fclose(out); fclose(out);
fclose(err); fclose(err);
} }
fclose(stdin);
/* lets redirect stdin to dev null as a work around for libao bug */ /* lets redirect stdin to dev null as a work around for libao bug */
{ {
int fd = open("/dev/null",O_RDONLY); int fd = open("/dev/null",O_RDONLY);
......
...@@ -118,6 +118,7 @@ typedef struct _mp3DecodeData { ...@@ -118,6 +118,7 @@ typedef struct _mp3DecodeData {
long maxFrames; long maxFrames;
long currentFrame; long currentFrame;
int flush; int flush;
unsigned long bitRate;
} mp3DecodeData; } mp3DecodeData;
void initMp3DecodeData(mp3DecodeData * data) { void initMp3DecodeData(mp3DecodeData * data) {
...@@ -325,6 +326,22 @@ void mp3DecodeDataFinalize(mp3DecodeData * data) { ...@@ -325,6 +326,22 @@ void mp3DecodeDataFinalize(mp3DecodeData * data) {
if(data->times) free(data->times); if(data->times) free(data->times);
} }
/* this is primarily used for getting total time for tags */
int getMp3TotalTime(char * file) {
mp3DecodeData data;
int ret;
while(!(data.fp = fopen(file,"r")) && errno==EINTR);
if(!data.fp) return -1;
initMp3DecodeData(&data);
if(decodeFirstFrame(&data)<0) ret = -1;
else ret = data.totalTime;
mp3DecodeDataFinalize(&data);
return ret;
}
int openMp3(char * file, mp3DecodeData * data) { int openMp3(char * file, mp3DecodeData * data) {
if((data->fp = fopen(file,"r"))<=0) { if((data->fp = fopen(file,"r"))<=0) {
ERROR1("problems opening \"%s\"\n",file); ERROR1("problems opening \"%s\"\n",file);
...@@ -341,7 +358,7 @@ int openMp3(char * file, mp3DecodeData * data) { ...@@ -341,7 +358,7 @@ int openMp3(char * file, mp3DecodeData * data) {
int mp3ChildSendData(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) { int mp3ChildSendData(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) {
while(cb->begin==cb->end && cb->wrap && !dc->stop && !dc->seek) while(cb->begin==cb->end && cb->wrap && !dc->stop && !dc->seek)
usleep(10); usleep(1000);
if(dc->stop) return -1; if(dc->stop) return -1;
/* just for now, so it doesn't hang */ /* just for now, so it doesn't hang */
if(dc->seek) return 0; if(dc->seek) return 0;
...@@ -349,6 +366,7 @@ int mp3ChildSendData(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) { ...@@ -349,6 +366,7 @@ int mp3ChildSendData(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) {
memcpy(cb->chunks[cb->end],data->outputBuffer,CHUNK_SIZE); memcpy(cb->chunks[cb->end],data->outputBuffer,CHUNK_SIZE);
cb->chunkSize[cb->end] = data->outputPtr-data->outputBuffer; cb->chunkSize[cb->end] = data->outputPtr-data->outputBuffer;
cb->bitRate[cb->end] = data->bitRate/1000;
cb->times[cb->end] = data->elapsedTime; cb->times[cb->end] = data->elapsedTime;
cb->end++; cb->end++;
...@@ -369,6 +387,7 @@ int mp3Read(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) { ...@@ -369,6 +387,7 @@ int mp3Read(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) {
data->highestFrame<data->maxFrames) data->highestFrame<data->maxFrames)
{ {
mad_timer_add(&data->timer,(data->frame).header.duration); mad_timer_add(&data->timer,(data->frame).header.duration);
data->bitRate = (data->frame).header.bitrate;
data->frameOffset[data->currentFrame] = data->frameOffset[data->currentFrame] =
data->currentOffset; data->currentOffset;
if(data->stream.this_frame!=NULL) { if(data->stream.this_frame!=NULL) {
......
...@@ -19,8 +19,15 @@ ...@@ -19,8 +19,15 @@
#ifndef MP3_DECODE_H #ifndef MP3_DECODE_H
#define MP3_DECODE_H #define MP3_DECODE_H
#ifdef HAVE_MAD
#include "playerData.h" #include "playerData.h"
/* this is primarily used in tag.c */
int getMp3TotalTime(char * file);
int mp3_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc); int mp3_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc);
#endif #endif
#endif
...@@ -61,6 +61,8 @@ int ogg_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) ...@@ -61,6 +61,8 @@ int ogg_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc)
int eof = 0; int eof = 0;
long ret; long ret;
char chunk[CHUNK_SIZE]; char chunk[CHUNK_SIZE];
long bitRate = 0;
long test;
while(!eof) { while(!eof) {
if(dc->seek) { if(dc->seek) {
...@@ -76,13 +78,17 @@ int ogg_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) ...@@ -76,13 +78,17 @@ int ogg_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc)
while(cb->begin==cb->end && cb->wrap && while(cb->begin==cb->end && cb->wrap &&
!dc->stop && !dc->seek) !dc->stop && !dc->seek)
{ {
usleep(10); usleep(1000);
} }
if(dc->stop) break; if(dc->stop) break;
else if(dc->seek) continue; else if(dc->seek) continue;
memcpy(cb->chunks[cb->end],chunk,CHUNK_SIZE); memcpy(cb->chunks[cb->end],chunk,CHUNK_SIZE);
cb->chunkSize[cb->end] = ret; cb->chunkSize[cb->end] = ret;
cb->times[cb->end] = ov_time_tell(&vf); cb->times[cb->end] = ov_time_tell(&vf);
if((test = ov_bitrate_instant(&vf))>0) {
bitRate = test/1000;
}
cb->bitRate[cb->end] = bitRate;
cb->end++; cb->end++;
if(cb->end>=BUFFERED_CHUNKS) { if(cb->end>=BUFFERED_CHUNKS) {
cb->end = 0; cb->end = 0;
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "directory.h" #include "directory.h"
#include "volume.h" #include "volume.h"
#include "playerData.h" #include "playerData.h"
#include "char_conv.h"
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
...@@ -97,6 +98,7 @@ int playerInit() { ...@@ -97,6 +98,7 @@ int playerInit() {
closeMp3Directory(); closeMp3Directory();
closeTables(); closeTables();
finishVolume(); finishVolume();
closeCharSetConversion();
while(1) { while(1) {
if(pc->play) decode(); if(pc->play) decode();
...@@ -115,7 +117,7 @@ int playerInit() { ...@@ -115,7 +117,7 @@ int playerInit() {
pc->queueLockState = PLAYER_QUEUE_UNLOCKED; pc->queueLockState = PLAYER_QUEUE_UNLOCKED;
pc->unlockQueue = 0; pc->unlockQueue = 0;
} }
else usleep(10); else usleep(1000);
} }
exit(0); exit(0);
...@@ -155,6 +157,9 @@ int playerPlay(FILE * fp, char * file) { ...@@ -155,6 +157,9 @@ int playerPlay(FILE * fp, char * file) {
#ifdef HAVE_FLAC #ifdef HAVE_FLAC
else if(isFlac(file)) pc->decodeType = DECODE_TYPE_FLAC; else if(isFlac(file)) pc->decodeType = DECODE_TYPE_FLAC;
#endif #endif
#ifdef HAVE_AUDIOFILE
else if(isWave(file)) pc->decodeType = DECODE_TYPE_AUDIOFILE;
#endif
else { else {
strcpy(pc->erroredFile,pc->file); strcpy(pc->erroredFile,pc->file);
pc->error = PLAYER_ERROR_UNKTYPE; pc->error = PLAYER_ERROR_UNKTYPE;
...@@ -215,6 +220,10 @@ int getPlayerElapsedTime() { ...@@ -215,6 +220,10 @@ int getPlayerElapsedTime() {
return (int)(getPlayerData()->playerControl.elapsedTime+0.5); return (int)(getPlayerData()->playerControl.elapsedTime+0.5);
} }
unsigned long getPlayerBitRate() {
return getPlayerData()->playerControl.bitRate;
}
int getPlayerTotalTime() { int getPlayerTotalTime() {
return (int)(getPlayerData()->playerControl.totalTime+0.5); return (int)(getPlayerData()->playerControl.totalTime+0.5);
} }
...@@ -282,6 +291,9 @@ int queueSong(char * file) { ...@@ -282,6 +291,9 @@ int queueSong(char * file) {
#ifdef HAVE_FLAC #ifdef HAVE_FLAC
else if(isFlac(file)) pc->decodeType = DECODE_TYPE_FLAC; else if(isFlac(file)) pc->decodeType = DECODE_TYPE_FLAC;
#endif #endif
#ifdef HAVE_AUDIOFILE
else if(isWave(file)) pc->decodeType = DECODE_TYPE_AUDIOFILE;
#endif
else return -1; else return -1;
pc->queueState = PLAYER_QUEUE_FULL; pc->queueState = PLAYER_QUEUE_FULL;
return 0; return 0;
......
...@@ -54,6 +54,7 @@ typedef struct _PlayerControl { ...@@ -54,6 +54,7 @@ typedef struct _PlayerControl {
int state; int state;
int closeAudio; int closeAudio;
int error; int error;
unsigned long bitRate;
float totalTime; float totalTime;
float elapsedTime; float elapsedTime;
char file[MAXPATHLEN+1]; char file[MAXPATHLEN+1];
...@@ -84,6 +85,8 @@ int getPlayerTotalTime(); ...@@ -84,6 +85,8 @@ int getPlayerTotalTime();
int getPlayerElapsedTime(); int getPlayerElapsedTime();
unsigned long getPlayerBitRate();
int getPlayerState(); int getPlayerState();
void clearPlayerError(); void clearPlayerError();
......
...@@ -31,6 +31,7 @@ extern int buffered_before_play; ...@@ -31,6 +31,7 @@ extern int buffered_before_play;
typedef struct _Buffer { typedef struct _Buffer {
char chunks[BUFFERED_CHUNKS][CHUNK_SIZE]; char chunks[BUFFERED_CHUNKS][CHUNK_SIZE];
uint_16 chunkSize[BUFFERED_CHUNKS]; uint_16 chunkSize[BUFFERED_CHUNKS];
uint_16 bitRate[BUFFERED_CHUNKS];
float times[BUFFERED_CHUNKS]; float times[BUFFERED_CHUNKS];
int begin; int begin;
int end; int end;
......
...@@ -77,6 +77,7 @@ int playlist_max_length; ...@@ -77,6 +77,7 @@ int playlist_max_length;
int playlist_stopOnError; int playlist_stopOnError;
int playlist_errorCount = 0; int playlist_errorCount = 0;
int playlist_queueError; int playlist_queueError;
int playlist_noGoToNext = 0;
int playlist_saveAbsolutePaths; int playlist_saveAbsolutePaths;
...@@ -452,6 +453,10 @@ int addToPlaylist(FILE * fp, char * file) { ...@@ -452,6 +453,10 @@ int addToPlaylist(FILE * fp, char * file) {
return -1; return -1;
} }
return addSongToPlaylist(fp,song);
}
int addSongToPlaylist(FILE * fp, Song * song) {
if(playlist.length==playlist_max_length) { if(playlist.length==playlist_max_length) {
myfprintf(fp,"%s playlist is at the max size\n",COMMAND_RESPOND_ERROR); myfprintf(fp,"%s playlist is at the max size\n",COMMAND_RESPOND_ERROR);
return -1; return -1;
...@@ -592,6 +597,7 @@ int deleteFromPlaylist(FILE * fp, int song) { ...@@ -592,6 +597,7 @@ int deleteFromPlaylist(FILE * fp, int song) {
/*if(playlist.current>=playlist.length) return playerStop(fp); /*if(playlist.current>=playlist.length) return playerStop(fp);
else return playPlaylistOrderNumber(fp,playlist.current);*/ else return playPlaylistOrderNumber(fp,playlist.current);*/
playerStop(stderr); playerStop(stderr);
playlist_noGoToNext = 1;
} }
else if(playlist_state!=PLAYLIST_STATE_STOP && else if(playlist_state!=PLAYLIST_STATE_STOP &&
playlist.current>songOrder) { playlist.current>songOrder) {
...@@ -632,6 +638,7 @@ int stopPlaylist(FILE * fp) { ...@@ -632,6 +638,7 @@ int stopPlaylist(FILE * fp) {
playerCloseAudio(); playerCloseAudio();
playlist.queued = -1; playlist.queued = -1;
playlist_state = PLAYLIST_STATE_STOP; playlist_state = PLAYLIST_STATE_STOP;
playlist_noGoToNext = 0;
/*stats.playTime+=getPlayerElapsedTime();*/ /*stats.playTime+=getPlayerElapsedTime();*/
if(playlist.random) randomizeOrder(0,playlist.length-1); if(playlist.random) randomizeOrder(0,playlist.length-1);
return 0; return 0;
...@@ -643,6 +650,7 @@ int playPlaylistOrderNumber(FILE * fp, int orderNum) { ...@@ -643,6 +650,7 @@ int playPlaylistOrderNumber(FILE * fp, int orderNum) {
if(playerStop(fp)<0) return -1; if(playerStop(fp)<0) return -1;
playlist_state = PLAYLIST_STATE_PLAY; playlist_state = PLAYLIST_STATE_PLAY;
playlist_noGoToNext = 0;
playlist.queued = -1; playlist.queued = -1;
playlist_queueError = 0; playlist_queueError = 0;
playlist.current = orderNum; playlist.current = orderNum;
...@@ -700,25 +708,6 @@ int playPlaylist(FILE * fp, int song, int stopOnError) { ...@@ -700,25 +708,6 @@ int playPlaylist(FILE * fp, int song, int stopOnError) {
return playPlaylistOrderNumber(fp,i); return playPlaylistOrderNumber(fp,i);
} }
void playPlaylistIfPlayerStopped() {
if(getPlayerState()==PLAYER_STATE_STOP) {
int error = getPlayerError();
if(error==PLAYER_ERROR_NOERROR) playlist_errorCount = 0;
else playlist_errorCount++;
if(playlist_state==PLAYLIST_STATE_PLAY && (
(playlist_stopOnError &&
error!=PLAYER_ERROR_NOERROR) ||
error==PLAYER_ERROR_AUDIO ||
error==PLAYER_ERROR_SYSTEM ||
playlist_errorCount>=playlist.length)) {
stopPlaylist(stderr);
}
else nextSongInPlaylist(stderr);
}
}
void syncPlayerAndPlaylist() { void syncPlayerAndPlaylist() {
if(playlist_state!=PLAYLIST_STATE_PLAY) return; if(playlist_state!=PLAYLIST_STATE_PLAY) return;
...@@ -726,6 +715,19 @@ void syncPlayerAndPlaylist() { ...@@ -726,6 +715,19 @@ void syncPlayerAndPlaylist() {
else syncPlaylistWithQueue(!playlist_queueError); else syncPlaylistWithQueue(!playlist_queueError);
} }
int currentSongInPlaylist(FILE * fp) {
if(playlist_state!=PLAYLIST_STATE_PLAY) return 0;
playlist_stopOnError = 0;
if(playlist.current<playlist.length) {
return playPlaylistOrderNumber(fp,playlist.current);
}
else return stopPlaylist(fp);;
return 0;
}
int nextSongInPlaylist(FILE * fp) { int nextSongInPlaylist(FILE * fp) {
if(playlist_state!=PLAYLIST_STATE_PLAY) return 0; if(playlist_state!=PLAYLIST_STATE_PLAY) return 0;
...@@ -747,6 +749,26 @@ int nextSongInPlaylist(FILE * fp) { ...@@ -747,6 +749,26 @@ int nextSongInPlaylist(FILE * fp) {
return 0; return 0;
} }
void playPlaylistIfPlayerStopped() {
if(getPlayerState()==PLAYER_STATE_STOP) {
int error = getPlayerError();
if(error==PLAYER_ERROR_NOERROR) playlist_errorCount = 0;
else playlist_errorCount++;
if(playlist_state==PLAYLIST_STATE_PLAY && (
(playlist_stopOnError &&
error!=PLAYER_ERROR_NOERROR) ||
error==PLAYER_ERROR_AUDIO ||
error==PLAYER_ERROR_SYSTEM ||
playlist_errorCount>=playlist.length)) {
stopPlaylist(stderr);
}
else if(playlist_noGoToNext) currentSongInPlaylist(stderr);
else nextSongInPlaylist(stderr);
}
}
int getPlaylistRepeatStatus() { int getPlaylistRepeatStatus() {
return playlist.repeat; return playlist.repeat;
} }
...@@ -977,7 +999,6 @@ int shufflePlaylist(FILE * fp) { ...@@ -977,7 +999,6 @@ int shufflePlaylist(FILE * fp) {
} }
int deletePlaylist(FILE * fp, char * file) { int deletePlaylist(FILE * fp, char * file) {
struct stat st;
char * rfile = malloc(strlen(file)+strlen(".")+ char * rfile = malloc(strlen(file)+strlen(".")+
strlen(PLAYLIST_FILE_SUFFIX)+1); strlen(PLAYLIST_FILE_SUFFIX)+1);
char * actualFile; char * actualFile;
...@@ -994,17 +1015,7 @@ int deletePlaylist(FILE * fp, char * file) { ...@@ -994,17 +1015,7 @@ int deletePlaylist(FILE * fp, char * file) {
return -1; return -1;
} }
if(stat(file,&st)<0) { if(unlink(actualFile)<0) {
myfprintf(fp,"%s problems stat'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
if(!S_ISREG(st.st_mode)) {
myfprintf(fp,"%s not a file\n",COMMAND_RESPOND_ERROR);
return -1;
}
if(unlink(file)<0) {
myfprintf(fp,"%s problems deleting file\n",COMMAND_RESPOND_ERROR); myfprintf(fp,"%s problems deleting file\n",COMMAND_RESPOND_ERROR);
return -1; return -1;
} }
...@@ -1132,7 +1143,7 @@ int loadPlaylist(FILE * fp, char * file) { ...@@ -1132,7 +1143,7 @@ int loadPlaylist(FILE * fp, char * file) {
while(fclose(fileP) && errno==EINTR); while(fclose(fileP) && errno==EINTR);
if(erroredFile) { if(erroredFile) {
fprintf(fp,"%s can't add file \"%s\"\n",COMMAND_RESPOND_ERROR, myfprintf(fp,"%s can't add file \"%s\"\n",COMMAND_RESPOND_ERROR,
erroredFile); erroredFile);
free(erroredFile); free(erroredFile);
return -1; return -1;
......
...@@ -41,6 +41,8 @@ int clearPlaylist(FILE * fp); ...@@ -41,6 +41,8 @@ int clearPlaylist(FILE * fp);
int addToPlaylist(FILE * fp, char * file); int addToPlaylist(FILE * fp, char * file);
int addSongToPlaylist(FILE * fp, Song * song);
int showPlaylist(FILE * fp); int showPlaylist(FILE * fp);
int deleteFromPlaylist(FILE * fp, int song); int deleteFromPlaylist(FILE * fp, int song);
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#define SONG_ALBUM "Album: " #define SONG_ALBUM "Album: "
#define SONG_TRACK "Track: " #define SONG_TRACK "Track: "
#define SONG_TITLE "Title: " #define SONG_TITLE "Title: "
#define SONG_TIME "Time: "
#define SONG_MTIME "mtime: " #define SONG_MTIME "mtime: "
#include <stdlib.h> #include <stdlib.h>
...@@ -43,25 +44,28 @@ Song * newSong(char * file) { ...@@ -43,25 +44,28 @@ Song * newSong(char * file) {
song->file = strdup(file); song->file = strdup(file);
#ifdef HAVE_OGG #ifdef HAVE_OGG
if((song->mtime = isOgg(file))) { if((song->mtime = isOgg(file))) {
song->tag = oggCommentDup(file); song->tag = oggTagDup(file);
return song; return song;
} }
#endif #endif
#ifdef HAVE_FLAC #ifdef HAVE_FLAC
if((song->mtime = isFlac(file))) { if((song->mtime = isFlac(file))) {
if(!(song->tag = flacVorbisCommentDup(file))) { song->tag = flacTagDup(file);
song->tag = id3Dup(file);
}
return song; return song;
} }
#endif #endif
#ifdef HAVE_MAD #ifdef HAVE_MAD
if((song->mtime = isMp3(file))) { if((song->mtime = isMp3(file))) {
song->tag = id3Dup(file); song->tag = mp3TagDup(file);
return song;
}
#endif
#ifdef HAVE_AUDIOFILE
if((song->mtime = isWave(file))) {
song->tag = audiofileTagDup(file);
return song; return song;
} }
#endif #endif
return song; return song;
} }
...@@ -169,6 +173,10 @@ void readSongInfoIntoList(FILE * fp, SongList * list) { ...@@ -169,6 +173,10 @@ void readSongInfoIntoList(FILE * fp, SongList * list) {
if(!song->tag) song->tag = newMpdTag(); if(!song->tag) song->tag = newMpdTag();
song->tag->title = strdup(&(buffer[strlen(SONG_TITLE)])); song->tag->title = strdup(&(buffer[strlen(SONG_TITLE)]));
} }
else if(0==strncmp(SONG_TIME,buffer,strlen(SONG_TIME))) {
if(!song->tag) song->tag = newMpdTag();
song->tag->time = atoi(&(buffer[strlen(SONG_TIME)]));
}
else if(0==strncmp(SONG_MTIME,buffer,strlen(SONG_MTIME))) { else if(0==strncmp(SONG_MTIME,buffer,strlen(SONG_MTIME))) {
song->mtime = atoi(&(buffer[strlen(SONG_TITLE)])); song->mtime = atoi(&(buffer[strlen(SONG_TITLE)]));
} }
...@@ -189,21 +197,25 @@ int updateSongInfo(Song * song) { ...@@ -189,21 +197,25 @@ int updateSongInfo(Song * song) {
if(song->tag) freeMpdTag(song->tag); if(song->tag) freeMpdTag(song->tag);
#ifdef HAVE_MAD #ifdef HAVE_MAD
if((song->mtime = isMp3(song->file))) { if((song->mtime = isMp3(song->file))) {
song->tag = id3Dup(song->file); song->tag = mp3TagDup(song->file);
return 0; return 0;
} }
#endif #endif
#ifdef HAVE_OGG #ifdef HAVE_OGG
if((song->mtime = isOgg(song->file))) { if((song->mtime = isOgg(song->file))) {
song->tag = oggCommentDup(song->file); song->tag = oggTagDup(song->file);
return 0; return 0;
} }
#endif #endif
#ifdef HAVE_FLAC #ifdef HAVE_FLAC
if((song->mtime = isFlac(song->file))) { if((song->mtime = isFlac(song->file))) {
if(!(song->tag = flacVorbisCommentDup(song->file))) { song->tag = flacTagDup(song->file);
song->tag = id3Dup(song->file); return 0;
} }
#endif
#ifdef HAVE_AUDIOFILE
if((song->mtime = isWave(song->file))) {
song->tag = audiofileTagDup(song->file);
return 0; return 0;
} }
#endif #endif
......
...@@ -68,7 +68,7 @@ void closeTables() { ...@@ -68,7 +68,7 @@ void closeTables() {
void addSongToSomeAlbumTable(List * table, Song * song) { void addSongToSomeAlbumTable(List * table, Song * song) {
void * album; void * album;
if(!song->tag) return; if(!song->tag) return;
if(!song->tag->title || !strlen(song->tag->title)) return; if(!song->tag->album || !strlen(song->tag->album)) return;
if(findInList(table,song->tag->album,&album)) { if(findInList(table,song->tag->album,&album)) {
insertInList((SongList *)album,song->file,song); insertInList((SongList *)album,song->file,song);
} }
......
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
#include "path.h" #include "path.h"
#include "myfprintf.h" #include "myfprintf.h"
#include "sig_handlers.h" #include "sig_handlers.h"
#include "mp3_decode.h"
#include "audiofile_decode.h"
#include "char_conv.h"
#include <sys/stat.h> #include <sys/stat.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -47,6 +50,7 @@ void printMpdTag(FILE * fp, MpdTag * tag) { ...@@ -47,6 +50,7 @@ void printMpdTag(FILE * fp, MpdTag * tag) {
if(tag->album) myfprintf(fp,"Album: %s\n",tag->album); if(tag->album) myfprintf(fp,"Album: %s\n",tag->album);
if(tag->track) myfprintf(fp,"Track: %s\n",tag->track); if(tag->track) myfprintf(fp,"Track: %s\n",tag->track);
if(tag->title) myfprintf(fp,"Title: %s\n",tag->title); if(tag->title) myfprintf(fp,"Title: %s\n",tag->title);
if(tag->time>=0) myfprintf(fp,"Time: %i\n",tag->time);
} }
#ifdef HAVE_ID3TAG #ifdef HAVE_ID3TAG
...@@ -121,19 +125,45 @@ MpdTag * id3Dup(char * filename) { ...@@ -121,19 +125,45 @@ MpdTag * id3Dup(char * filename) {
id3_file_close(file); id3_file_close(file);
if(ret) {
if(!ret->artist) ret->artist = strdup("");
if(!ret->album) ret->album = strdup("");
if(!ret->title) ret->title = strdup("");
if(!ret->track) ret->track = strdup("");
}
unblockSignals(); unblockSignals();
#endif #endif
return ret; return ret;
} }
#ifdef HAVE_AUDIOFILE
MpdTag * audiofileTagDup(char * file) {
MpdTag * ret = NULL;
int time = getAudiofileTotalTime(rmp2amp(file));
if (time>=0) {
if(!ret) ret = newMpdTag();
ret->time = time;
}
return ret;
}
#endif
#ifdef HAVE_MAD
MpdTag * mp3TagDup(char * file) {
MpdTag * ret = NULL;
int time;
ret = id3Dup(file);
time = getMp3TotalTime(rmp2amp(file));
if(time>=0) {
if(!ret) ret = newMpdTag();
ret->time = time;
}
return ret;
}
#endif
#ifdef HAVE_OGG #ifdef HAVE_OGG
MpdTag * oggCommentDup(char * file) { MpdTag * oggTagDup(char * file) {
MpdTag * ret = NULL; MpdTag * ret = NULL;
FILE * fp; FILE * fp;
OggVorbis_File vf; OggVorbis_File vf;
...@@ -142,6 +172,8 @@ MpdTag * oggCommentDup(char * file) { ...@@ -142,6 +172,8 @@ MpdTag * oggCommentDup(char * file) {
char * s1; char * s1;
char * s2; char * s2;
setCharSetConversion("LATIN1","UTF-8");
while(!(fp = fopen(rmp2amp(file),"r")) && errno==EINTR); while(!(fp = fopen(rmp2amp(file),"r")) && errno==EINTR);
if(!fp) return NULL; if(!fp) return NULL;
blockSignals(); blockSignals();
...@@ -151,6 +183,9 @@ MpdTag * oggCommentDup(char * file) { ...@@ -151,6 +183,9 @@ MpdTag * oggCommentDup(char * file) {
return NULL; return NULL;
} }
ret = newMpdTag();
ret->time = (int)(ov_time_total(&vf,-1)+0.5);
comments = ov_comment(&vf,-1)->user_comments; comments = ov_comment(&vf,-1)->user_comments;
while(*comments) { while(*comments) {
...@@ -158,20 +193,32 @@ MpdTag * oggCommentDup(char * file) { ...@@ -158,20 +193,32 @@ MpdTag * oggCommentDup(char * file) {
s1 = strtok(temp,"="); s1 = strtok(temp,"=");
s2 = strtok(NULL,"="); s2 = strtok(NULL,"=");
if(0==strcasecmp(s1,"artist")) { if(0==strcasecmp(s1,"artist")) {
if(!ret) ret = newMpdTag(); if(!ret->artist && s2) {
if(!ret->artist && s2) ret->artist = strdup(s2); if(!(ret->artist = convStrDup(s2))) {
ret->artist = strdup(s2);
}
}
} }
else if(0==strcasecmp(s1,"title")) { else if(0==strcasecmp(s1,"title")) {
if(!ret) ret = newMpdTag(); if(!ret->title && s2) {
if(!ret->title && s2) ret->title = strdup(s2); if(!(ret->title = convStrDup(s2))) {
ret->title = strdup(s2);
}
}
} }
else if(0==strcasecmp(s1,"album")) { else if(0==strcasecmp(s1,"album")) {
if(!ret) ret = newMpdTag(); if(!ret->album && s2) {
if(!ret->album && s2) ret->album = strdup(s2); if(!(ret->album = convStrDup(s2))) {
ret->album = strdup(s2);
}
}
} }
else if(0==strcasecmp(s1,"tracknumber")) { else if(0==strcasecmp(s1,"tracknumber")) {
if(!ret) ret = newMpdTag(); if(!ret->track && s2) {
if(!ret->track && s2) ret->track = strdup(s2); if(!(ret->track = convStrDup(s2))) {
ret->track = strdup(s2);
}
}
} }
free(temp); free(temp);
++comments; ++comments;
...@@ -179,27 +226,21 @@ MpdTag * oggCommentDup(char * file) { ...@@ -179,27 +226,21 @@ MpdTag * oggCommentDup(char * file) {
ov_clear(&vf); ov_clear(&vf);
if(ret) {
if(!ret->artist) ret->artist = strdup("");
if(!ret->album) ret->album = strdup("");
if(!ret->title) ret->title = strdup("");
if(!ret->track) ret->track = strdup("");
}
unblockSignals(); unblockSignals();
return ret; return ret;
} }
#endif #endif
#ifdef HAVE_FLAC #ifdef HAVE_FLAC
MpdTag * flacVorbisCommentDup(char * file) { MpdTag * flacMetadataDup(char * file, int * vorbisCommentFound) {
MpdTag * ret = NULL; MpdTag * ret = NULL;
FLAC__Metadata_SimpleIterator * it; FLAC__Metadata_SimpleIterator * it;
FLAC__StreamMetadata * block = NULL; FLAC__StreamMetadata * block = NULL;
int found = 0;
int offset; int offset;
int len, pos; int len, pos;
*vorbisCommentFound = 0;
blockSignals(); blockSignals();
it = FLAC__metadata_simple_iterator_new(); it = FLAC__metadata_simple_iterator_new();
if(!FLAC__metadata_simple_iterator_init(it,rmp2amp(file),1,0)) { if(!FLAC__metadata_simple_iterator_init(it,rmp2amp(file),1,0)) {
...@@ -209,69 +250,110 @@ MpdTag * flacVorbisCommentDup(char * file) { ...@@ -209,69 +250,110 @@ MpdTag * flacVorbisCommentDup(char * file) {
} }
do { do {
if(block) FLAC__metadata_object_delete(block);
block = FLAC__metadata_simple_iterator_get_block(it); block = FLAC__metadata_simple_iterator_get_block(it);
if(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) found=1; if(!block) break;
} while(!found && FLAC__metadata_simple_iterator_next(it)); if(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
char * dup;
if(found) {
offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"artist"); setCharSetConversion("LATIN1","UTF-8");
if(offset>=0) {
if(!ret) ret = newMpdTag(); offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"artist");
pos = strlen("artist="); if(offset>=0) {
len = block->data.vorbis_comment.comments[offset].length-pos; *vorbisCommentFound = 1;
if(len>0) { if(!ret) ret = newMpdTag();
ret->artist = malloc(len+1); pos = strlen("artist=");
memcpy(ret->artist,&(block->data.vorbis_comment.comments[offset].entry[pos]),len); len = block->data.vorbis_comment.comments[offset].length-pos;
ret->artist[len] = '\0'; if(len>0) {
dup = malloc(len+1);
memcpy(dup,&(block->data.vorbis_comment.comments[offset].entry[pos]),len);
dup[len] = '\0';
if((ret->artist = convStrDup(dup))) {
free(dup);
}
else ret->artist = dup;
}
} }
} offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"album");
offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"album"); if(offset>=0) {
if(offset>=0) { *vorbisCommentFound = 1;
if(!ret) ret = newMpdTag(); if(!ret) ret = newMpdTag();
pos = strlen("album="); pos = strlen("album=");
len = block->data.vorbis_comment.comments[offset].length-pos; len = block->data.vorbis_comment.comments[offset].length-pos;
if(len>0) { if(len>0) {
ret->album = malloc(len+1); dup = malloc(len+1);
memcpy(ret->album,&(block->data.vorbis_comment.comments[offset].entry[pos]),len); memcpy(dup,&(block->data.vorbis_comment.comments[offset].entry[pos]),len);
ret->album[len] = '\0'; dup[len] = '\0';
if((ret->album = convStrDup(dup))) {
free(dup);
}
else ret->album = dup;
}
} }
} offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"title");
offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"title"); if(offset>=0) {
if(offset>=0) { *vorbisCommentFound = 1;
if(!ret) ret = newMpdTag(); if(!ret) ret = newMpdTag();
pos = strlen("title="); pos = strlen("title=");
len = block->data.vorbis_comment.comments[offset].length-pos; len = block->data.vorbis_comment.comments[offset].length-pos;
if(len>0) { if(len>0) {
ret->title = malloc(len+1); dup = malloc(len+1);
memcpy(ret->title,&(block->data.vorbis_comment.comments[offset].entry[pos]),len); memcpy(dup,&(block->data.vorbis_comment.comments[offset].entry[pos]),len);
ret->title[len] = '\0'; dup[len] = '\0';
if((ret->title = convStrDup(dup))) {
free(dup);
}
else ret->title = dup;
}
} }
} offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"tracknumber");
offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"tracknumber"); if(offset>=0) {
if(offset>=0) { *vorbisCommentFound = 1;
if(!ret) ret = newMpdTag(); if(!ret) ret = newMpdTag();
pos = strlen("tracknumber="); pos = strlen("tracknumber=");
len = block->data.vorbis_comment.comments[offset].length-pos; len = block->data.vorbis_comment.comments[offset].length-pos;
if(len>0) { if(len>0) {
ret->track = malloc(len+1); dup = malloc(len+1);
memcpy(ret->track,&(block->data.vorbis_comment.comments[offset].entry[pos]),len); memcpy(dup,&(block->data.vorbis_comment.comments[offset].entry[pos]),len);
ret->track[len] = '\0'; dup[len] = '\0';
if((ret->track = convStrDup(dup))) {
free(dup);
}
else ret->track = dup;
}
} }
} }
if(ret) { else if(block->type == FLAC__METADATA_TYPE_STREAMINFO) {
if(!ret->artist) ret->artist = strdup(""); if(!ret) ret = newMpdTag();
if(!ret->album) ret->album = strdup(""); ret->time = ((float)block->data.stream_info.
if(!ret->title) ret->title = strdup(""); total_samples) /
if(!ret->track) ret->track = strdup(""); block->data.stream_info.sample_rate +
0.5;
} }
} FLAC__metadata_object_delete(block);
} while(FLAC__metadata_simple_iterator_next(it));
if(block) FLAC__metadata_object_delete(block);
FLAC__metadata_simple_iterator_delete(it); FLAC__metadata_simple_iterator_delete(it);
unblockSignals(); unblockSignals();
return ret; return ret;
} }
MpdTag * flacTagDup(char * file) {
MpdTag * ret = NULL;
int foundVorbisComment = 0;
ret = flacMetadataDup(file,&foundVorbisComment);
if(!ret) return NULL;
if(!foundVorbisComment) {
MpdTag * temp = id3Dup(file);
if(temp) {
temp->time = ret->time;
freeMpdTag(ret);
ret = temp;
}
}
return ret;
}
#endif #endif
MpdTag * newMpdTag() { MpdTag * newMpdTag() {
...@@ -280,6 +362,7 @@ MpdTag * newMpdTag() { ...@@ -280,6 +362,7 @@ MpdTag * newMpdTag() {
ret->artist = NULL; ret->artist = NULL;
ret->title = NULL; ret->title = NULL;
ret->track = NULL; ret->track = NULL;
ret->time = -1;
return ret; return ret;
} }
...@@ -300,6 +383,7 @@ MpdTag * mpdTagDup(MpdTag * tag) { ...@@ -300,6 +383,7 @@ MpdTag * mpdTagDup(MpdTag * tag) {
ret->album = strdup(tag->album); ret->album = strdup(tag->album);
ret->title = strdup(tag->title); ret->title = strdup(tag->title);
ret->track = strdup(tag->track); ret->track = strdup(tag->track);
ret->time = tag->time;
} }
return ret; return ret;
......
...@@ -26,17 +26,28 @@ typedef struct _MpdTag { ...@@ -26,17 +26,28 @@ typedef struct _MpdTag {
char * album; char * album;
char * track; char * track;
char * title; char * title;
int time;
} MpdTag; } MpdTag;
MpdTag * newMpdTag(); MpdTag * newMpdTag();
void freeMpdTag(MpdTag * tag); void freeMpdTag(MpdTag * tag);
MpdTag * id3Dup(char * file); #ifdef HAVE_MAD
MpdTag * mp3TagDup(char * file);
#endif
MpdTag * oggCommentDup(char * file); #ifdef HAVE_OGG
MpdTag * oggTagDup(char * file);
#endif
MpdTag * flacVorbisCommentDup(char * file); #ifdef HAVE_FLAC
MpdTag * flacTagDup(char * file);
#endif
#ifdef HAVE_AUDIOFILE
MpdTag * audiofileTagDup(char * file);
#endif
void printMpdTag(FILE * fp, MpdTag * tag); void printMpdTag(FILE * fp, MpdTag * tag);
......
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