1
0
mirror of http://mpg123.de/trunk/.git synced 2025-10-28 02:55:29 +03:00

Finished hacking in loadable output module support from branch "njh-outputplugin".

Legacy support allows statically compiling in a single module.
Still needs some work, but a quick test on my MacBook worked :)


git-svn-id: svn://scm.orgis.org/mpg123/trunk@932 35dc7657-300d-0410-a2e5-dc2837fedb53
This commit is contained in:
njh
2007-09-10 23:23:22 +00:00
parent be4b141a6b
commit 8dd0ee93f0
46 changed files with 2871 additions and 1856 deletions

View File

@@ -10,7 +10,7 @@ AC_PREREQ(2.57)
dnl ############# Initialisation
AC_INIT([mpg123], [0.67], [mpg123-devel@lists.sourceforge.net])
AC_INIT([mpg123], [1.0pre1], [mpg123-devel@lists.sourceforge.net])
AC_CONFIG_SRCDIR(src/mpg123.c)
AC_CONFIG_AUX_DIR(build)
@@ -32,12 +32,27 @@ AC_PROG_RANLIB
AC_C_CONST
AC_INLINE
# Check if system supports termios
AC_SYS_POSIX_TERMIOS
if test "x$ac_cv_sys_posix_termios" = "xyes"; then
AC_DEFINE_UNQUOTED([HAVE_TERMIOS], 1,
[Define this if you have the POSIX termios library])
fi
dnl ############# Use Libtool for dynamic module loading
dnl Enable building of the libltdl library
AC_LIBLTDL_INSTALLABLE
AC_SUBST(LTDLINCL)
AC_SUBST(LIBLTDL)
AC_DEFINE(HAVE_LTDL, 1, [ Define if LTDL library is available. ])
dnl Check for dlopen support
AC_LIBTOOL_DLOPEN
dnl We only want shared libraries by default
AC_DISABLE_STATIC
AC_ENABLE_SHARED
dnl Configure libtool
AM_PROG_LIBTOOL
dnl Configure libltdl
AC_CONFIG_SUBDIRS(libltdl)
@@ -112,23 +127,23 @@ AC_ARG_WITH([cpu], [
])
AC_ARG_WITH([audio], [
--with-audio=aix Use AIX audio output sub-system
--with-audio=alib Use Alib audio output sub-system (for HPUX)
--with-audio=alsa Use ALSA audio output sub-system
--with-audio=dummy Use dummy audio (when no sound card is available)
--with-audio=esd Use ESoundD audio output sub-system
--with-audio=hp Use HP audio output sub-system
--with-audio=jack Use JACK low-latency audio server
--with-audio=macosx Use Mac OS X audio output sub-system (CoreAudio)
--with-audio=mint Use MinT audio output sub-system (Atari)
--with-audio=nas Use NAS audio output (Network Audio System)
--with-audio=os2 Use OS2 audio output sub-system
--with-audio=oss Use OSS audio output sub-system (/dev/dsp)
--with-audio=portaudio Use PortAudio audio output sub-system
--with-audio=sdl Use SDL audio output sub-system (Simple DirectMedia Layer)
--with-audio=sgi Use SGI audio output sub-system (IRIX)
--with-audio=sun Use Sun audio output sub-system (/dev/audio)
--with-audio=win32 Use Windows audio output (WinMM)
--with-default-audio=aix Use AIX as default audio output sub-system
--with-default-audio=alib Use Alib as default audio output sub-system (for HPUX)
--with-default-audio=alsa Use ALSA as default audio output sub-system
--with-default-audio=dummy Use dummy as default audio (when no sound card is available)
--with-default-audio=esd Use ESoundD as default audio output sub-system
--with-default-audio=hp Use HP as default audio output sub-system
--with-default-audio=jack Use JACK as default low-latency audio server
--with-default-audio=macosx Use Mac OS X as default audio output sub-system (CoreAudio)
--with-default-audio=mint Use MinT as default audio output sub-system (Atari)
--with-default-audio=nas Use NAS as default audio output (Network Audio System)
--with-default-audio=os2 Use OS2 as default audio output sub-system
--with-default-audio=oss Use OSS as default audio output sub-system (/dev/dsp)
--with-default-audio=portaudio Use PortAudio as default audio output sub-system
--with-default-audio=pulse Use Pulse audio server as default audio output sub-system
--with-default-audio=sdl Use SDL as default audio output sub-system (Simple DirectMedia Layer)
--with-default-audio=sgi Use SGI as default audio output sub-system (IRIX)
--with-default-audio=sun Use Sun as default audio output sub-system (/dev/audio)
])
AC_ARG_WITH([optimization], [
@@ -143,6 +158,27 @@ AC_ARG_WITH([seektable], [
--with-seektable=<size> choose size of seek index table (0 disables it), default 1000
])
dnl ############## Modules
# Dummy audio output module is alway supported
output_modules="dummy"
# Location that modules are installed to
if test x$libdir = 'x${exec_prefix}/lib'; then
if test x$prefix = xNONE; then
pkglibdir="$ac_default_prefix/lib/$PACKAGE_NAME"
else
pkglibdir="$prefix/lib/$PACKAGE_NAME"
fi
else
pkglibdir="$libdir/$PACKAGE_NAME"
fi
AC_DEFINE_UNQUOTED([PKGLIBDIR], "$pkglibdir", [Path to installed modules] )
AC_SUBST([pkglibdir])
dnl ############## Assembler, compiler properties
# based on posting from John Dalgliesh <johnd@defyne.org> on ffmpeg (LGPL) mailing list
@@ -191,6 +227,14 @@ dnl ############## Function Checks
AC_FUNC_MMAP
# Check if system supports termios
AC_SYS_POSIX_TERMIOS
if test "x$ac_cv_sys_posix_termios" = "xyes"; then
AC_DEFINE_UNQUOTED([HAVE_TERMIOS], 1,
[Define this if you have the POSIX termios library])
fi
# Check for sched_setscheduler
AC_CHECK_FUNCS( sched_setscheduler setuid getuid)
@@ -213,28 +257,41 @@ if test $fifo = "yes" && test $have_mkfifo = "no"; then
AC_MSG_WARN( [ You forced FIFO code while I think there is no mkfifo() available! ] )
fi
dnl ############## Library Checks
# Checks for libraries.
dnl ############## Header and Library Checks
AC_HEADER_STDC
dnl Is it too paranoid to specifically check for stdint.h and limits.h?
AC_CHECK_HEADERS([stdlib.h string.h unistd.h sched.h sys/ioctl.h stdint.h limits.h inttypes.h sys/time.h sys/wait.h sys/resource.h signal.h])
# Checks for maths libraries.
AC_CHECK_LIB([m], [sqrt])
AC_CHECK_LIB([mx], [powf])
# Check for JACK
PKG_CHECK_MODULES(JACK, jack, HAVE_JACK=yes, HAVE_JACK=no)
PKG_CHECK_MODULES(JACK, jack, output_modules="jack $output_modules" HAVE_JACK="yes", HAVE_JACK="no")
AC_SUBST( JACK_CFLAGS )
AC_SUBST( JACK_LDFLAGS )
AC_SUBST( JACK_LIBS )
AM_CONDITIONAL( [HAVE_JACK], [test "x$HAVE_JACK" = xyes] )
# Check for Simple Pulse Audio API
PKG_CHECK_MODULES(PULSE, libpulse-simple, output_modules="pulse $output_modules" HAVE_PULSE="yes", HAVE_PULSE="no")
AC_SUBST( PULSE_CFLAGS )
AC_SUBST( PULSE_LDFLAGS )
AC_SUBST( PULSE_LIBS )
AM_CONDITIONAL( [HAVE_PULSE], [test "x$HAVE_PULSE" = xyes] )
# Check for EsounD
PKG_CHECK_MODULES(ESOUND, esound, HAVE_ESOUND=yes, HAVE_ESOUND=no)
PKG_CHECK_MODULES(ESOUND, esound, output_modules="esound $output_modules" HAVE_ESOUND="yes", HAVE_ESOUND="no")
AC_SUBST( ESOUND_CFLAGS )
AC_SUBST( ESOUND_LDFLAGS )
AC_SUBST( ESOUND_LIBS )
AM_CONDITIONAL( [HAVE_ESOUND], [test "x$HAVE_ESOUND" = xyes] )
# Check for SDL
PKG_CHECK_MODULES(SDL, sdl, HAVE_SDL=yes, HAVE_SDL=no)
# Check for NAS
AC_CHECK_LIB( [audio], [AuOpenServer],
[ AC_CHECK_HEADER( [audio/audiolib.h],
[ HAVE_NAS="yes" ],
[ AC_MSG_WARN([Found NAS library but NOT header files on your system]) ] )
]
)
# Check for PortAudio
case $target in
@@ -243,7 +300,7 @@ case $target in
if test "x$HAVE_PORTAUDIO" != "xyes"; then
AC_CHECK_LIB( [portaudio], [Pa_Initialize],
[ AC_CHECK_HEADER( [portaudio.h],
[ HAVE_PORTAUDIO_WINMM="yes" && HAVE_PORTAUDIO="yes" ],
[ output_modules="portaudio $output_modules" HAVE_PORTAUDIO_WINMM="yes" HAVE_PORTAUDIO="yes" ],
[ AC_MSG_WARN([Found PortAudio library but NOT header files on your system]) ] )
],
[ HAVE_PORTAUDIO="no" ],
@@ -254,31 +311,78 @@ case $target in
*)
AC_CHECK_LIB( [portaudio], [Pa_Initialize],
[ AC_CHECK_HEADER( [portaudio.h],
[ HAVE_PORTAUDIO="yes" ],
[ output_modules="portaudio $output_modules" HAVE_PORTAUDIO="yes" ],
[ AC_MSG_WARN([Found PortAudio library but NOT header files on your system]) ] )
]
)
;;
esac
AM_CONDITIONAL( [HAVE_PORTAUDIO], [test "x$HAVE_PORTAUDIO" = xyes] )
# Check for SDL
PKG_CHECK_MODULES(SDL, sdl, output_modules="sdl $output_modules" HAVE_SDL="yes", HAVE_SDL="no")
AC_SUBST( SDL_CFLAGS )
AC_SUBST( SDL_LDFLAGS )
AC_SUBST( SDL_LIBS )
AM_CONDITIONAL( [HAVE_SDL], [test "x$HAVE_SDL" = xyes] )
# Check for NAS
AC_CHECK_LIB( [audio], [AuOpenServer],
[ AC_CHECK_HEADER( [audio/audiolib.h],
[ output_modules="nas $output_modules" HAVE_NAS="yes"],
[ AC_MSG_WARN([Found NAS library but NOT header files on your system]) ] )
]
)
AM_CONDITIONAL( [HAVE_NAS], [test "x$HAVE_NAS" = xyes] )
# Check for windows ... and win32 audio
# Does not work... instead just check for header
# AC_CHECK_LIB( [winmm], [waveOutOpen] )
AC_CHECK_HEADERS([windows.h], HAVE_WINMM=yes, HAVE_WINMM=no)
# Sun Audio headers
AC_CHECK_HEADERS([sun/audioio.h sys/audioio.h asm/audioio.h sys/audio.h])
if test "x${ac_cv_header_sun_audioio_h}" = "xyes" \
-o "x${ac_cv_header_sys_audioio_h}" = "xyes" \
-o "x${ac_cv_header_asm_audioio_h}" = "xyes";
then
output_modules="sun $output_modules"
HAVE_SUN="yes"
fi
AM_CONDITIONAL( [HAVE_SUN], [test "x$HAVE_SUN" = xyes] )
# OSS Header files
AC_CHECK_HEADERS([sys/soundcard.h linux/soundcard.h machine/soundcard.h])
if test "x${ac_cv_header_sys_soundcard_h}" = "xyes" \
-o "x${ac_cv_header_linux_soundcard_h}" = "xyes" \
-o "x${ac_cv_header_machine_soundcard_h}" = "xyes";
then
output_modules="oss $output_modules"
HAVE_OSS="yes"
fi
AM_CONDITIONAL( [HAVE_OSS], [test "x$HAVE_OSS" = xyes] )
# Check for ALSA
AC_CHECK_LIB( [asound], [snd_pcm_open],
[ AC_CHECK_HEADER( [alsa/asoundlib.h],
[ HAVE_ALSA="yes" ],
[ output_modules="alsa $output_modules" HAVE_ALSA="yes"],
[ AC_MSG_WARN([Found ALSA library but NOT header files on your system]) ] )
]
)
AM_CONDITIONAL( [HAVE_ALSA], [test "x$HAVE_ALSA" = xyes] )
dnl ############## Header Checks
AC_HEADER_STDC
dnl Is it too paranoid to specifically check for stdint.h and limits.h?
AC_CHECK_HEADERS([stdlib.h string.h unistd.h sched.h sys/ioctl.h stdint.h limits.h inttypes.h sys/time.h sys/wait.h sys/resource.h signal.h])
# Mac OS X CoreAudio
AC_CHECK_HEADERS([AudioUnit/AudioUnit.h CoreServices/CoreServices.h AudioToolbox/AudioToolbox.h])
if test "x${ac_cv_header_AudioUnit_AudioUnit_h}" = "xyes" \
-a "x${ac_cv_header_CoreServices_CoreServices_h}" = "xyes" \
-a "x${ac_cv_header_AudioToolbox_AudioToolbox_h}" = "xyes";
then
output_modules="coreaudio $output_modules"
HAVE_COREAUDIO="yes"
fi
AM_CONDITIONAL( [HAVE_COREAUDIO], [test "x$HAVE_COREAUDIO" = xyes] )
# attempt to make the signal stuff work... also with GENERIC - later
#if test $ac_cv_header_sys_signal_h = yes; then
@@ -290,26 +394,6 @@ AC_CHECK_HEADERS([stdlib.h string.h unistd.h sched.h sys/ioctl.h stdint.h limits
# AC_DEFINE(
#fi
# OSS Header files: One of them is enough.
AC_CHECK_HEADERS(sys/soundcard.h)
AC_CHECK_HEADERS(linux/soundcard.h)
AC_CHECK_HEADERS(machine/soundcard.h)
if test "x${ac_cv_header_sys_soundcard_h}" = "xyes" ||
test "x${ac_cv_header_linux_soundcard_h}" = "xyes" ||
test "x${ac_cv_header_machine_soundcard_h}" = "xyes"; then
HAVE_OSS=yes
else
HAVE_OSS=no
fi
# Sun Audio headers
AC_CHECK_HEADERS([sun/audioio.h sys/audioio.h asm/audioio.h sys/audio.h], HAVE_SUNAUDIO=yes, HAVE_SUNAUDIO=no)
# Mac OS X
AC_CHECK_HEADERS([AudioUnit/AudioUnit.h CoreServices/CoreServices.h AudioToolbox/AudioToolbox.h],
HAVE_MACOSXAUDIO=yes, HAVE_MACOSXAUDIO=no)
dnl ############## Choose compiler flags and CPU
@@ -509,6 +593,19 @@ fi
AC_SUBST( CPU_TYPE_LIB )
dnl ############## Create list of modules to build
# Enable module support in source code
AC_DEFINE( USE_MODULES, 1, [Define if modules are enabled] )
# Did user choose default audio subsystem ?
if test "x$with_default_audio" != "x"; then
default_output_module=$with_default_audio
else
default_output_module=`echo "$output_modules" | $AWK '{ print $1 }'`
fi
AC_DEFINE_UNQUOTED( DEFAULT_OUTPUT_MODULE, "$default_output_module", [The default audio output module to use] )
dnl ############## Compiler Optimizations
@@ -721,34 +818,32 @@ AC_SUBST(AUDIO_LIBS)
dnl ############## Final Output
AC_OUTPUT([Makefile src/Makefile])
AC_CONFIG_FILES([
Makefile
src/Makefile
src/output/Makefile
])
AC_OUTPUT
dnl ############## Display Message
echo -n "
$PACKAGE $VERSION
echo "
$PACKAGE_NAME $PACKAGE_VERSION
Install path ............ $prefix
CPU Optimisation......... $cpu_type
Compiler Optimization ... $with_optimization
Audio output ............ $audio_system (detected:"
test "x$HAVE_ALSA" = "xyes" && echo -n " alsa"
test "x$HAVE_OSS" = "xyes" && echo -n " oss"
test "x$HAVE_MACOSXAUDIO" = "xyes" && echo -n " coreaudio"
test "x$HAVE_SUNAUDIO" = "xyes" && echo -n " sun"
test "x$HAVE_JACK" = "xyes" && echo -n " jack"
test "x$HAVE_PORTAUDIO" = "xyes" && echo -n " portaudio"
test "x$HAVE_NAS" = "xyes" && echo -n " nas"
test "x$HAVE_SDL" = "xyes" && echo -n " sdl"
test "x$HAVE_ESOUND" = "xyes" && echo -n " esd"
test "x$HAVE_WINMM" = "xyes" && echo -n " win32"
echo ")
Gapless Support ......... $gapless
Debugging ............... $debugging
Seek table size ......... $seektable
FIFO support ............ $fifo
Modules Directory ....... $pkglibdir
Audio output modules .... $output_modules
Default output module ... $default_output_module
"
if test $cpu_type = "generic_float"; then
echo "You chose the generic build with 32bit float output.
@@ -762,8 +857,6 @@ fi
if test "$debugging" = "enabled"; then
echo "CFLAGS='$CFLAGS'"
echo "LIBS='$LIBS'"
echo "AUDIO_CFLAGS='$AUDIO_CFLAGS'"
echo "AUDIO_LIBS='$AUDIO_LIBS'"
else
echo "Next type 'make' and then 'make install'."
fi

View File

@@ -4,11 +4,12 @@
## see COPYING and AUTHORS files in distribution or http://mpg123.org
## initially written by Nicholas J. Humfrey
AM_CFLAGS = @AUDIO_CFLAGS@
#AM_LDFLAGS =
mpg123_LDADD = @AUDIO_OBJ@ @CPU_TYPE_LIB@ @AUDIO_LIBS@
mpg123_DEPENDENCIES = @AUDIO_OBJ@ @CPU_TYPE_LIB@
mpg123_LDADD = @LIBLTDL@ @CPU_TYPE_LIB@
mpg123_LDFLAGS = -export-dynamic
mpg123_INCLUDES = @LTDLINCL@
mpg123_DEPENDENCIES = @LIBLTDL@ @CPU_TYPE_LIB@
SUBDIRS = output
EXTRA_DIST = Makefile.legacy config.h.legacy
CLEANFILES = *.a
@@ -52,6 +53,8 @@ mpg123_SOURCES = \
layer3.c \
layer3.h \
mangle.h \
module.c \
module.h \
mpg123.c \
mpg123.h \
optimize.h \
@@ -70,25 +73,8 @@ mpg123_SOURCES = \
xfermem.c \
xfermem.h
EXTRA_mpg123_SOURCES = \
audio_aix.c \
audio_alib.c \
audio_alsa.c \
audio_dummy.c \
audio_esd.c \
audio_hp.c \
audio_jack.c \
audio_coreaudio.c \
audio_mint.c \
audio_nas.c \
audio_os2.c \
audio_oss.c \
audio_portaudio.c \
audio_sdl.c \
audio_sgi.c \
audio_sun.c \
audio_win32.c \
getcpuflags.h
EXTRA_mpg123_SOURCES = getcpuflags.h
# Processor dependent decoder code

View File

@@ -55,6 +55,7 @@ nothing-specified:
@echo "make bsdos4 BSDI BSD/OS 4.0"
@echo "make bsdos-nas BSDI BSD/OS with NAS support"
@echo "make mint MiNT on Atari"
@echo "make macosx CoreAudio on Mac OS X"
@echo "make generic try this one if your system isn't listed above"
@echo ""
@echo "Please read the file INSTALL for additional information."
@@ -104,15 +105,17 @@ freebsd-help:
@echo ""
linux-devel:
$(MAKE) OBJECTS="decode_i386.o dct64_i386.o audio_oss.o" \
CC=gcc \
$(MAKE) CC=gcc
OBJECTS="decode_i386.o dct64_i386.o" \
OUTPUT_MODULE=oss \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -IOPT_I386 -DREAL_IS_FLOAT -DLINUX -Wall -g \
-DREAD_MMAP -DOSS -funroll-all-loops \
-finline-functions -ffast-math" \
mpg123-make
linux-profile:
$(MAKE) OBJECTS="decode_i386.o dct64_i386.o audio_oss.o" \
$(MAKE) OBJECTS="decode_i386.o dct64_i386.o" \
OUTPUT_MODULE=oss \
CC=gcc LDFLAGS="$(LDFLAGS) -pg" \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_I386 -DREAL_IS_FLOAT -DLINUX -Wall -pg \
-DREAD_MMAP -DOSS -funroll-all-loops \
@@ -121,7 +124,8 @@ linux-profile:
linux:
$(MAKE) CC=gcc \
OBJECTS="decode.o dct64.o audio_oss.o term.o" \
OBJECTS="decode.o dct64.o term.o" \
OUTPUT_MODULE=oss \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -DREAL_IS_FLOAT -DLINUX -O2 -funroll-all-loops \
-DOSS -DHAVE_TERMIOS \
-Wall" \
@@ -129,8 +133,8 @@ linux:
linux-x86:
$(MAKE) CC=gcc \
OBJECTS="decode_i386.o dct64_i386.o $(PENTIUM_DECODE).o \
audio_oss.o term.o" \
OBJECTS="decode_i386.o dct64_i386.o $(PENTIUM_DECODE).o term.o" \
OUTPUT_MODULE=oss \
CFLAGS="$(CFLAGS) $(CPPFLAGS) $(PENTIUM_OPT) -DREAL_IS_FLOAT -DLINUX \
-DOSS -DHAVE_TERMIOS\
-Wall -O2 \
@@ -141,8 +145,8 @@ linux-x86:
#just for development... gapless will be on for normal builds when stable
linux-x86-gapless:
$(MAKE) CC=gcc \
OBJECTS="decode_i386.o dct64_i386.o $(PENTIUM_DECODE).o \
audio_oss.o term.o" \
OBJECTS="decode_i386.o dct64_i386.o $(PENTIUM_DECODE).o term.o" \
OUTPUT_MODULE=oss \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DGAPLESS $(PENTIUM_OPT) -DREAL_IS_FLOAT -DLINUX \
-DOSS -DHAVE_TERMIOS\
-Wall -O2 \
@@ -152,8 +156,8 @@ linux-x86-gapless:
linux-mmx:
$(MAKE) CC=gcc \
OBJECTS="decode_i386.o dct64_mmx.o tabinit_mmx.o decode_mmx.o \
audio_oss.o term.o" \
OBJECTS="decode_i386.o dct64_mmx.o tabinit_mmx.o decode_mmx.o term.o" \
OUTPUT_MODULE=oss \
CFLAGS=" $(CFLAGS) -DOPT_MMX -DREAL_IS_FLOAT \
-DLINUX -DOSS -DHAVE_TERMIOS\
-Wall -O2 \
@@ -163,8 +167,8 @@ linux-mmx:
linux-mmap:
$(MAKE) CC=gcc \
OBJECTS="decode_i386.o dct64_i386.o $(PENTIUM_DECODE).o \
audio_oss.o term.o" \
OBJECTS="decode_i386.o dct64_i386.o $(PENTIUM_DECODE).o term.o" \
OUTPUT_MODULE=oss \
CFLAGS="$(CFLAGS) $(CPPFLAGS) $(PENTIUM_OPT) -DREAL_IS_FLOAT -DLINUX \
-DREAD_MMAP -DOSS -DHAVE_TERMIOS\
-Wall -O2 \
@@ -176,9 +180,10 @@ linux-3dnow:
$(MAKE) CC=gcc \
OBJECTS="decode_i386.o decode_3dnow.o dct64_3dnow.o \
dct64_i386.o dct36_3dnow.o getcpuflags.o \
equalizer_3dnow.o decode_i586.o audio_oss.o term.o optimize.o" \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_MULTI -DOPT_I586 -DOPT_3DNOW -DREAL_IS_FLOAT -DLINUX \
-DOSS -DHAVE_TERMIOS\
equalizer_3dnow.o decode_i586.o term.o optimize.o" \
OUTPUT_MODULE=oss \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_MULTI -DOPT_I586 -DOPT_3DNOW \
-DREAL_IS_FLOAT -DLINUX -DOSS -DHAVE_TERMIOS \
-Wall -O2 \
-fomit-frame-pointer -funroll-all-loops \
-finline-functions -ffast-math" \
@@ -186,8 +191,8 @@ linux-3dnow:
linux-i486:
$(MAKE) CC=gcc \
OBJECTS="decode_i386.o dct64_i386.o \
decode_i486.o dct64_i486.o audio_oss.o term.o" \
OBJECTS="decode_i386.o dct64_i386.o decode_i486.o dct64_i486.o term.o" \
OUTPUT_MODULE=oss \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_I486 -DREAL_IS_FLOAT -DLINUX \
-DOSS -DHAVE_TERMIOS\
-Wall -O2 -march=i486 \
@@ -197,8 +202,8 @@ linux-i486:
linux-i386:
$(MAKE) CC=gcc \
OBJECTS="decode_i386.o dct64_i386.o \
audio_oss.o term.o" \
OBJECTS="decode_i386.o dct64_i386.o term.o" \
OUTPUT_MODULE=oss \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_I386 -DREAL_IS_FLOAT -DLINUX \
-DOSS -DHAVE_TERMIOS\
-Wall -O2 \
@@ -209,8 +214,8 @@ linux-i386:
linux-esd:
$(MAKE) CC=gcc \
AUDIO_LIB="-lesd -laudiofile" \
OBJECTS="decode_i386.o dct64_i386.o $(PENTIUM_DECODE).o \
audio_esd.o term.o" \
OBJECTS="decode_i386.o dct64_i386.o $(PENTIUM_DECODE).o term.o" \
OUTPUT_MODULE=esd \
CFLAGS="$(CFLAGS) $(CPPFLAGS) $(PENTIUM_OPT) -DREAL_IS_FLOAT -DLINUX \
-DOSS -DUSE_ESD -DHAVE_TERMIOS\
-Wall -O2 -mcpu=i486 \
@@ -221,8 +226,8 @@ linux-esd:
linux-alsa:
$(MAKE) CC=gcc \
AUDIO_LIB="-lasound" \
OBJECTS="decode_i386.o dct64_i386.o $(PENTIUM_DECODE).o \
audio_alsa.o term.o" \
OBJECTS="decode_i386.o dct64_i386.o $(PENTIUM_DECODE).o term.o" \
OUTPUT_MODULE=alsa \
CFLAGS="$(CFLAGS) $(CPPFLAGS) $(PENTIUM_OPT) -DREAL_IS_FLOAT -DLINUX \
-DALSA -DHAVE_TERMIOS\
-Wall -O2 -mcpu=i486 \
@@ -233,7 +238,8 @@ linux-alsa:
linux-mips-alsa:
$(MAKE) CC=gcc \
AUDIO_LIB="-lasound" \
OBJECTS="decode.o dct64.o audio_alsa.o term.o" \
OBJECTS="decode.o dct64.o term.o" \
OUTPUT_MODULE=alsa \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -DREAL_IS_FLOAT -DLINUX -DALSA \
-DHAVE_TERMIOS -Wall -O2 \
-fomit-frame-pointer -funroll-all-loops \
@@ -241,7 +247,8 @@ linux-mips-alsa:
mpg123-make
linux-alpha:
$(MAKE) CC=gcc OBJECTS="decode.o dct64.o audio_oss.o term.o" \
$(MAKE) CC=gcc OBJECTS="decode.o dct64.o term.o" \
OUTPUT_MODULE=oss \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -DLINUX -DOSS -DHAVE_TERMIOS -Wall -O2 \
-fomit-frame-pointer -funroll-all-loops \
-finline-functions -ffast-math \
@@ -251,7 +258,8 @@ linux-alpha:
linux-alpha-esd:
$(MAKE) CC=gcc \
AUDIO_LIB="-lesd -laudiofile" \
OBJECTS="decode.o dct64.o audio_esd.o term.o" \
OBJECTS="decode.o dct64.o term.o" \
OUTPUT_MODULE=esd \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -DLINUX -DOSS -DHAVE_TERMIOS -Wall -O2 \
-fomit-frame-pointer -funroll-all-loops \
-finline-functions -ffast-math \
@@ -260,7 +268,8 @@ linux-alpha-esd:
#linux-ppc:
# $(MAKE) CC=gcc LDFLAGS= \
# OBJECTS="decode.o dct64.o audio_oss.o" \
# OBJECTS="decode.o dct64.o" \
# OUTPUT_MODULE=oss \
# CFLAGS="-DREAL_IS_FLOAT -DLINUX -Wall -O2 -mcpu=ppc \
# -DOSS -DPPC_ENDIAN \
# -fomit-frame-pointer -funroll-all-loops \
@@ -270,7 +279,8 @@ linux-alpha-esd:
#linux-ppc-esd:
# $(MAKE) CC=gcc LDFLAGS= \
# AUDIO_LIB="-lesd -laudiofile" \
# OBJECTS="decode.o dct64.o audio_esd.o" \
# OBJECTS="decode.o dct64.o" \
# OUTPUT_MODULE=esd \
# CFLAGS="-DREAL_IS_FLOAT -DLINUX -Wall -O2 -mcpu=ppc \
# -DOSS -DPPC_ENDIAN \
# -fomit-frame-pointer -funroll-all-loops \
@@ -279,7 +289,8 @@ linux-alpha-esd:
linux-ppc:
$(MAKE) CC=gcc \
OBJECTS="decode.o dct64.o audio_oss.o term.o" \
OBJECTS="decode.o dct64.o term.o" \
OUTPUT_MODULE=oss \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -DREAL_IS_FLOAT -DLINUX -Wall -O2 -mcpu=powerpc \
-DOSS -DHAVE_TERMIOS\
-fomit-frame-pointer -funroll-all-loops \
@@ -289,7 +300,8 @@ linux-ppc:
linux-ppc-esd:
$(MAKE) CC=gcc \
AUDIO_LIB="-lesd -laudiofile" \
OBJECTS="decode.o dct64.o audio_esd.o term.o" \
OBJECTS="decode.o dct64.o term.o" \
OUTPUT_MODULE=esd \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -DREAL_IS_FLOAT -DLINUX -Wall -O2 -mcpu=powerpc \
-DOSS -DHAVE_TERMIOS\
-fomit-frame-pointer -funroll-all-loops \
@@ -299,7 +311,8 @@ linux-ppc-esd:
linux-ppc-nas:
$(MAKE) CC=gcc LDFLAGS='-L/usr/X11R6/lib' \
AUDIO_LIB='-laudio -lXau -lXt' \
OBJECTS='decode.o dct64.o audio_nas.o term.o' \
OBJECTS='decode.o dct64.o term.o' \
OUTPUT_MODULE=nas \
CFLAGS="-I/usr/X11R6/include -DOPT_GENERIC -DREAL_IS_FLOAT -DLINUX -DNAS -DTERM_CONTROL \
-Wall -O2 -mcpu=powerpc \
-fomit-frame-pointer -funroll-all-loops \
@@ -308,7 +321,8 @@ linux-ppc-nas:
linux-sparc:
$(MAKE) CC=gcc \
OBJECTS="decode.o dct64.o audio_sun.o term.o" \
OBJECTS="decode.o dct64.o term.o" \
OUTPUT_MODULE=sun \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -DREAL_IS_FLOAT -DHAVE_MMAP -DSPARCLINUX -Wall -O2 \
-DHAVE_TERMIOS \
-fomit-frame-pointer -funroll-all-loops \
@@ -317,7 +331,8 @@ linux-sparc:
linux-hppa:
$(MAKE) CC=gcc \
OBJECTS="decode.o dct64.o audio_oss.o term.o" \
OBJECTS="decode.o dct64.o term.o" \
OUTPUT_MODULE=oss \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -DREAL_IS_FLOAT -DLINUX -Wall -O2 \
-DHAVE_TERMIOS \
-fomit-frame-pointer -funroll-all-loops \
@@ -325,7 +340,8 @@ linux-hppa:
mpg123-make
linux-m68k:
$(MAKE) CC=gcc OBJECTS="decode.o dct64.o audio_oss.o term.o" \
$(MAKE) CC=gcc OBJECTS="decode.o dct64.o term.o" \
OUTPUT_MODULE=oss \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -DREAL_IS_FLOAT -DLINUX -DHAVE_TERMIOS \
-DOSS -DOSS_BIG_ENDIAN -Wall -O2 -m68040 \
-fomit-frame-pointer -funroll-loops \
@@ -333,7 +349,8 @@ linux-m68k:
mpg123-make
linux-arm:
$(MAKE) CC=gcc OBJECTS="decode.o dct64.o audio_oss.o term.o" \
$(MAKE) CC=gcc OBJECTS="decode.o dct64.o term.o" \
OUTPUT_MODULE=oss \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -DREAL_IS_FIXED -DLINUX -DHAVE_TERMIOS \
-DOSS -Wall -O6 -mtune=xscale \
-fomit-frame-pointer -funroll-all-loops \
@@ -343,7 +360,8 @@ linux-arm:
linux-nas:
$(MAKE) CC=gcc LDFLAGS="$(LDFLAGS) -L/usr/X11R6/lib" \
AUDIO_LIB="-laudio -lXau -lXt" \
OBJECTS="decode_i386.o dct64_i386.o audio_nas.o term.o" \
OBJECTS="decode_i386.o dct64_i386.o term.o" \
OUTPUT_MODULE=nas \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -I/usr/X11R6/include \
-DOPT_I386 -DREAL_IS_FLOAT -DLINUX -DNAS \
-DHAVE_TERMIOS \
@@ -360,7 +378,8 @@ linux-nas:
freebsd:
$(MAKE) CC=cc \
OBJECTS="decode_i386.o dct64_i386.o audio_oss.o" \
OBJECTS="decode_i386.o dct64_i386.o" \
OUTPUT_MODULE=oss \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_I386 -Wall -ansi -pedantic -O4 -fomit-frame-pointer \
-funroll-all-loops -ffast-math -DROT_I386 \
-DREAD_MMAP \
@@ -370,7 +389,8 @@ freebsd:
freebsd-esd:
$(MAKE) CC=cc \
AUDIO_LIB="-lesd -laudiofile" \
OBJECTS="decode_i386.o dct64_i386.o $(GETBITS) audio_esd.o" \
OBJECTS="decode_i386.o dct64_i386.o $(GETBITS)" \
OUTPUT_MODULE=esd \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_I386 -Wall -ansi -pedantic -O4 -fomit-frame-pointer \
-funroll-all-loops -ffast-math -DROT_I386 \
-DREAD_MMAP \
@@ -385,14 +405,16 @@ freebsd-esd:
solaris-pure:
$(MAKE) CC="purify -cache-dir=/tmp cc" \
LDFLAGS="$(LDFLAGS) -lsocket -lnsl" \
OBJECTS="decode.o dct64.o audio_sun.o term.o" \
OBJECTS="decode.o dct64.o term.o" \
OUTPUT_MODULE=sun \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -fast -native -xO4 -DSOLARIS -DHAVE_TERMIOS \
-DHAVE_MMAP" \
mpg123-make
solaris-ccscc:
$(MAKE) CC=/usr/ccs/bin/ucbcc LDFLAGS="$(LDFLAGS) -lsocket -lnsl" \
OBJECTS="decode.o dct64.o audio_sun.o term.o" \
OBJECTS="decode.o dct64.o term.o" \
OUTPUT_MODULE=sun \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -fast -native -xO4 -DSOLARIS \
-DHAVE_MMAP" \
mpg123-make
@@ -400,7 +422,8 @@ solaris-ccscc:
# common solaris compile entries
solaris:
$(MAKE) CC=cc LDFLAGS="$(LDFLAGS) -lsocket -lnsl" \
OBJECTS="decode.o dct64.o audio_sun.o term.o" \
OBJECTS="decode.o dct64.o term.o" \
OUTPUT_MODULE=sun \
CFLAGS="$(CFLAGS)-fast -DOPT_GENERIC -native -xO4 -DSOLARIS \
-DHAVE_MMAP -DHAVE_TERMIOS" \
mpg123-make
@@ -408,7 +431,8 @@ solaris:
solaris-gcc-profile:
$(MAKE) CC=gcc \
LDFLAGS="$(LDFLAGS) -lsocket -lnsl -pg" \
OBJECTS="decode.o dct64.o audio_sun.o" \
OBJECTS="decode.o dct64.o" \
OUTPUT_MODULE=sun \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -g -pg -O2 -Wall -DSOLARIS -DREAL_IS_FLOAT -DHAVE_MMAP \
-DREAD_MMAP \
-funroll-all-loops -finline-functions" \
@@ -417,7 +441,8 @@ solaris-gcc-profile:
solaris-gcc:
$(MAKE) CC=gcc \
LDFLAGS="$(LDFLAGS) -lsocket -lnsl" \
OBJECTS="decode.o dct64.o audio_sun.o term.o" \
OBJECTS="decode.o dct64.o term.o" \
OUTPUT_MODULE=sun \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -O2 -Wall -pedantic -DSOLARIS -DREAL_IS_FLOAT -DHAVE_MMAP \
-DREAD_MMAP -DHAVE_TERMIOS \
-funroll-all-loops -finline-functions" \
@@ -426,7 +451,8 @@ solaris-gcc:
solaris-gcc-esd:
$(MAKE) CC=gcc LDFLAGS="$(LDFLAGS) -lsocket -lnsl" \
AUDIO_LIB="-lesd -lresolv" \
OBJECTS="decode.o dct64.o audio_esd.o" \
OBJECTS="decode.o dct64.o" \
OUTPUT_MODULE=esd \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -O2 -Wall -DSOLARIS -DREAL_IS_FLOAT -DHAVE_MMAP \
-DREAD_MMAP \
-funroll-all-loops -finline-functions" \
@@ -434,8 +460,8 @@ solaris-gcc-esd:
solaris-x86-gcc-oss:
$(MAKE) CC=gcc LDFLAGS="$(LDFLAGS) -lsocket -lnsl" \
OBJECTS="decode_i386.o dct64_i386.o $(PENTIUM_DECODE).o \
audio_oss.o" \
OBJECTS="decode_i386.o dct64_i386.o $(PENTIUM_DECODE).o" \
OUTPUT_MODULE=oss \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_I586 -DREAL_IS_FLOAT -DHAVE_MMAP \
-DREAD_MMAP -DOSS \
-Wall -O2 -mcpu=i486 \
@@ -445,7 +471,8 @@ solaris-x86-gcc-oss:
solaris-gcc-nas:
$(MAKE) CC=gcc LDFLAGS="$(LDFLAGS) -lsocket -lnsl" \
AUDIO_LIB="-L/usr/openwin/lib -laudio -lXau"\
OBJECTS="decode.o dct64.o audio_nas.o" \
OBJECTS="decode.o dct64.o" \
OUTPUT_MODULE=nas \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -O2 -I/usr/openwin/include -Wall \
-DSOLARIS -DREAL_IS_FLOAT -DHAVE_MMAP \
-DREAD_MMAP -DNAS \
@@ -454,50 +481,60 @@ solaris-gcc-nas:
sunos:
$(MAKE) CC=gcc \
OBJECTS="decode.o dct64.o audio_sun.o" \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -O2 -DOPT_GENERIC -DSUNOS -DREAL_IS_FLOAT -DHAVE_MMAP -DHAVE_SYS_IOCTL_H -DHAVE_SUN_AUDIOIO_H -DNO_RT -DHAVE_NO_STRERROR \
OBJECTS="decode.o dct64.o" \
OUTPUT_MODULE=sun \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -O2 -DOPT_GENERIC -DSUNOS -DREAL_IS_FLOAT -DHAVE_MMAP \
-funroll-loops" \
mpg123-make
# CFLAGS='-DREAL_IS_FLOAT -Aa +O3 -D_HPUX_SOURCE -DHPUX'
hpux:
$(MAKE) CC=cc \
OBJECTS="decode.o dct64.o audio_hp.o" \
OBJECTS="decode.o dct64.o" \
OUTPUT_MODULE=hp \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -DREAL_IS_FLOAT -Ae +O3 -D_HPUX_SOURCE -DHPUX" \
mpg123-make
hpux-alib:
$(MAKE) CC=cc LDFLAGS="$(LDFLAGS) -L/opt/audio/lib" \
OBJECTS="decode.o dct64.o audio_alib.o" \
OBJECTS="decode.o dct64.o" \
OUTPUT_MODULE=alib \
AUDIO_LIB=-lAlib \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DREAL_IS_FLOAT -Ae +O3 -D_HPUX_SOURCE -DHPUX \
-I/opt/audio/include" \
mpg123-make
hpux-gcc:
$(MAKE) CC=gcc OBJECTS="decode.o dct64.o audio_hp.o" \
$(MAKE) CC=gcc OBJECTS="decode.o dct64.o" \
OUTPUT_MODULE=hp \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -DREAL_IS_FLOAT -O3 -D_HPUX_SOURCE -DHPUX" \
mpg123-make
sgi:
$(MAKE) CC=cc \
OBJECTS="decode.o dct64.o audio_sgi.o" AUDIO_LIB=-laudio \
OBJECTS="decode.o dct64.o"
OUTPUT_MODULE=sgi \
AUDIO_LIB=-laudio \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -O2 -DSGI -DREAL_IS_FLOAT -DHAVE_MMAP" \
mpg123-make
sgi-gcc:
$(MAKE) CC=gcc \
OBJECTS="decode.o dct64.o audio_sgi.o" AUDIO_LIB=-laudio \
OBJECTS="decode.o dct64.o" \
OUTPUT_MODULE=sgi \
AUDIO_LIB=-laudio \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -O2 -DSGI -DREAL_IS_FLOAT -DHAVE_MMAP" \
mpg123-make
dec:
$(MAKE) CC=cc OBJECTS="decode.o dct64.o audio_dummy.o" \
$(MAKE) CC=cc OBJECTS="decode.o dct64.o" \
OUTPUT_MODULE=dummy \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -std1 -warnprotos -O4 -DHAVE_MMAP" \
LDFLAGS="$(LDFLAGS) -lrt" \
mpg123-make
dec-debug:
$(MAKE) CC=cc OBJECTS="decode.o dct64.o audio_dummy.o" \
$(MAKE) CC=cc OBJECTS="decode.o dct64.o" \
OUTPUT_MODULE=dummy \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -g3 -std1 -warnprotos -O4 -DHAVE_MMAP" \
LDFLAGS="$(LDFLAGS) -lrt" \
mpg123-make
@@ -505,31 +542,36 @@ dec-debug:
dec-nas:
$(MAKE) CC=cc LDFLAGS="$(LDFLAGS) -L/usr/X11R6/lib" \
AUDIO_LIB="-laudio -lXau -ldnet_stub"\
OBJECTS="decode.o dct64.o audio_nas.o" \
OUTPUT_MODULE=nas \
OBJECTS="decode.o dct64.o" \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -I/usr/X11R6/include -std1 -warnprotos -O4 -DHAVE_MMAP" \
mpg123-make
ultrix:
$(MAKE) CC=cc OBJECTS="decode.o dct64.o audio_dummy.o" \
$(MAKE) CC=cc OBJECTS="decode.o dct64.o" \
OUTPUT_MODULE=dummy \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -std1 -O2 -DULTRIX" \
mpg123-make
aix-gcc:
$(MAKE) CC=gcc OBJECTS="decode.o dct64.o audio_aix.o" \
$(MAKE) CC=gcc OBJECTS="decode.o dct64.o" \
OUTPUT_MODULE=aix \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -DAIX -Wall -O6 -DHAVE_MMAP -DREAD_MMAP -DREAL_IS_FLOAT \
-fomit-frame-pointer -funroll-all-loops \
-finline-functions -ffast-math" \
mpg123-make
aix-xlc:
$(MAKE) OBJECTS="decode.o dct64.o audio_aix.o" \
$(MAKE) OBJECTS="decode.o dct64.o" \
OUTPUT_MODULE=aix \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -O3 -qstrict -qcpluscmt -DAIX -DHAVE_MMAP \
-DREAD_MMAP" \
mpg123-make
os2:
$(MAKE) CC=gcc \
OBJECTS="decode_i386.o dct64_i386.o audio_os2.o" \
OBJECTS="decode_i386.o dct64_i386.o" \
OUTPUT_MODULE=os2 \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_I386 DREAL_IS_FLOAT -DNOXFERMEM -DOS2 -Wall -O2 -mcpu=i486 \
-fomit-frame-pointer -funroll-all-loops \
-finline-functions -ffast-math" \
@@ -538,7 +580,8 @@ os2:
netbsd:
$(MAKE) CC=cc \
OBJECTS="decode.o dct64.o audio_sun.o" \
OBJECTS="decode.o dct64.o" \
OUTPUT_MODULE=sun \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -Wall -ansi -pedantic -O3 -fomit-frame-pointer \
-funroll-all-loops -ffast-math \
-DREAL_IS_FLOAT -DHAVE_MMAP -DNETBSD -DNO_RT" \
@@ -546,7 +589,8 @@ netbsd:
netbsd-x86:
$(MAKE) CC=cc \
OBJECTS="decode_i386.o dct64_i386.o audio_sun.o" \
OBJECTS="decode_i386.o dct64_i386.o" \
OUTPUT_MODULE=sun \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_I386 -Wall -ansi -pedantic -O4 -mcpu=i486 -fomit-frame-pointer \
-funroll-all-loops -ffast-math -DROT_I386 \
-DI386_ASSEM -DREAL_IS_FLOAT -DHAVE_MMAP -DNETBSD -DNO_RT" \
@@ -554,7 +598,8 @@ netbsd-x86:
netbsd-rt:
$(MAKE) CC=cc LDFLAGS="$(LDFLAGS) -lpthread" \
OBJECTS="decode.o dct64.o audio_sun.o" \
OBJECTS="decode.o dct64.o" \
OUTPUT_MODULE=sun \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -Wall -ansi -pedantic -O3 -fomit-frame-pointer \
-funroll-all-loops -ffast-math \
-DREAL_IS_FLOAT -DHAVE_MMAP -DNETBSD" \
@@ -562,7 +607,8 @@ netbsd-rt:
netbsd-x86-rt:
$(MAKE) CC=cc LDFLAGS="$(LDFLAGS) -lpthread" \
OBJECTS="decode_i386.o dct64_i386.o audio_sun.o" \
OBJECTS="decode_i386.o dct64_i386.o" \
OUTPUT_MODULE=sun \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_I386 -Wall -ansi -pedantic -O4 -mcpu=i486 -fomit-frame-pointer \
-funroll-all-loops -ffast-math -DROT_I386 \
-DREAL_IS_FLOAT -DHAVE_MMAP -DNETBSD" \
@@ -570,8 +616,8 @@ netbsd-x86-rt:
bsdos:
$(MAKE) CC=shlicc2 \
OBJECTS="decode_i386.o dct64_i386.o \
audio_oss.o" \
OBJECTS="decode_i386.o dct64_i386.o" \
OUTPUT_MODULE=oss \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -Wall -O4 -mcpu=i486 -fomit-frame-pointer \
-funroll-all-loops -ffast-math -DROT_I386 \
-DI386_ASSEM -DREAL_IS_FLOAT -DHAVE_MMAP -DOSS \
@@ -580,7 +626,8 @@ bsdos:
bsdos4:
$(MAKE) CC=gcc \
OBJECTS="decode_i386.o dct64_i386.o audio_oss.o" \
OBJECTS="decode_i386.o dct64_i386.o" \
OUTPUT_MODULE=oss \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -Wall -O4 -mcpu=i486 -fomit-frame-pointer \
-funroll-all-loops -ffast-math -DROT_I386 \
-DOPT_I386 -DREAL_IS_FLOAT -DHAVE_MMAP -DOSS \
@@ -590,8 +637,8 @@ bsdos4:
bsdos-nas:
$(MAKE) CC=shlicc2 \
AUDIO_LIB="-laudio -lXau -L/usr/X11R6/lib" \
OBJECTS="decode_i386.o dct64_i386.o \
audio_nas.o" \
OBJECTS="decode_i386.o dct64_i386.o" \
OUTPUT_MODULE=nas \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -Wall -O4 -mcpu=i486 -fomit-frame-pointer \
-funroll-all-loops -ffast-math -DROT_I386 \
-DOPT_I386 -DREAL_IS_FLOAT -DHAVE_MMAP -DOSS \
@@ -600,7 +647,8 @@ bsdos-nas:
mint:
$(MAKE) CC=gcc \
OBJECTS="decode.o dct64.o audio_mint.o" \
OBJECTS="decode.o dct64.o" \
OUTPUT_MODULE=mint \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -Wall -O2 -m68020-40 -m68881 \
-fomit-frame-pointer -funroll-all-loops \
-finline-functions -ffast-math \
@@ -608,9 +656,21 @@ mint:
AUDIO_LIB='-lsocket' \
mpg123-make
macosx:
$(MAKE) CC=gcc \
OBJECTS="decode.o dct64.o sfifo.o term.o" \
OUTPUT_MODULE=coreaudio \
CFLAGS="$(CFLAGS) $(CPPFLAGS) \
-DREAL_IS_FLOAT -DHAVE_TERMIOS -DNO_RT -DOPT_GENERIC \
-Wall -O2 -fomit-frame-pointer -funroll-all-loops \
-finline-functions -ffast-math" \
AUDIO_LIB="-framework AudioToolbox -framework AudioUnit -framework CoreServices" \
mpg123-make
# maybe you need the additonal options LDFLAGS='-lnsl -lsocket' when linking (see solaris:)
generic:
$(MAKE) LDFLAGS= OBJECTS="decode.o dct64.o audio_dummy.o" \
$(MAKE) LDFLAGS= OBJECTS="decode.o dct64.o" \
OUTPUT_MODULE=dummy \
CFLAGS="$(CFLAGS) $(CPPFLAGS) -DOPT_GENERIC -DGENERIC -DNOXFERMEM" \
mpg123-make
@@ -625,11 +685,13 @@ mpg123: mpg123.o playlist.o stringbuf.o common.o id3.o icy.o $(OBJECTS) decode_2
tabinit.o audio.o layer1.o layer2.o layer3.o buffer.o \
getlopt.o httpget.o xfermem.o equalizer.o \
decode_ntom.o $(MAKEFILE) wav.o readers.o getbits.o \
control_generic.o
$(CC) $(CFLAGS) $(LDFLAGS) mpg123.o playlist.o stringbuf.o tabinit.o common.o id3.o icy.o layer1.o \
control_generic.o legacy_module.o output/$(OUTPUT_MODULE).o
$(CC) $(CFLAGS) $(LDFLAGS) \
mpg123.o playlist.o stringbuf.o tabinit.o common.o id3.o icy.o layer1.o \
layer2.o layer3.o audio.o buffer.o decode_2to1.o equalizer.o \
decode_4to1.o getlopt.o httpget.o xfermem.o decode_ntom.o \
wav.o readers.o getbits.o control_generic.o \
output/$(OUTPUT_MODULE).o legacy_module.o \
$(OBJECTS) -o $(BINNAME) -lm $(AUDIO_LIB)
mpg123.exe: mpg123.o playlist.o stringbuf.o common.o id3.o $(OBJECTS) decode_2to1.o decode_4to1.o \
@@ -637,6 +699,9 @@ mpg123.exe: mpg123.o playlist.o stringbuf.o common.o id3.o $(OBJECTS) decode_2to
getlopt.o httpget.o $(MAKEFILE) wav.o readers.o getbits.o
$(CC) $(CFLAGS) $(LDFLAGS) $^ -o mpg123.exe -lm $(LIBS)
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -I. -I.. -DDEFAULT_OUTPUT_MODULE="\"$(OUTPUT_MODULE)\"" -c -o $@ $<
###########################################################################
###########################################################################
###########################################################################
@@ -653,13 +718,6 @@ common.o: mpg123.h common.h layer3.h debug.h config.h id3.h icy.h
mpg123.o: mpg123.c mpg123.h getlopt.h xfermem.h buffer.h term.h debug.h id3.h config.h
mpg123.h: audio.h debug.h config.h
audio.o: mpg123.h debug.h config.h
audio_oss.o: mpg123.h debug.h config.h
audio_sun.o: mpg123.h debug.h config.h
audio_sgi.o: mpg123.h debug.h config.h
audio_hp.o: mpg123.h debug.h config.h
audio_nas.o: mpg123.h debug.h config.h
audio_os2.o: mpg123.h debug.h config.h
audio_dummy.o: mpg123.h debug.h config.h
buffer.o: mpg123.h xfermem.h buffer.h debug.h config.h
getbits.o: common.h mpg123.h debug.h config.h
tabinit.o: mpg123.h audio.h debug.h config.h
@@ -678,13 +736,27 @@ id3.o: config.h mpg123.h stringbuf.h genre.h id3.h debug.h common.h
icy.o: icy.h stringbuf.h
control_generic.o: config.h mpg123.h common.h debug.h layer3.h id3.h icy.h
output/aix.o: audio.h mpg123.h debug.h config.h
output/alib.o: audio.h mpg123.h debug.h config.h
output/alsa.o: audio.h mpg123.h debug.h config.h
output/coreaudio.o: audio.h mpg123.h debug.h config.h
output/dummy.o: audio.h mpg123.h debug.h config.h
output/esd.o: audio.h mpg123.h debug.h config.h
output/hp.o: audio.h mpg123.h debug.h config.h
output/mint.o: audio.h mpg123.h debug.h config.h
output/nas.o: audio.h mpg123.h debug.h config.h
output/os2.o: audio.h mpg123.h debug.h config.h
output/oss.o: audio.h mpg123.h debug.h config.h
output/sgi.o: audio.h mpg123.h debug.h config.h
output/sun.o: audio.h mpg123.h debug.h config.h
###########################################################################
###########################################################################
###########################################################################
clean:
rm -f *.o *core *~ mpg123 gmon.out system
rm -f *.o *core *~ output/*.o mpg123 gmon.out system
prepared-for-install:
@if [ ! -x mpg123 ]; then \

View File

@@ -8,29 +8,105 @@
#include "mpg123.h"
void audio_info_struct_init(struct audio_info_struct *ai)
/* Open an audio output module */
audio_output_t* open_output_module( const char* name )
{
ai->fn = -1;
ai->rate = -1;
ai->gain = -1;
ai->output = -1;
ai->handle = NULL;
ai->device = NULL;
ai->channels = -1;
ai->format = -1;
mpg123_module_t *module = NULL;
audio_output_t *ao = NULL;
int result = 0;
/* Open the module */
module = open_module( "output", name );
if (module == NULL) return NULL;
/* Check module supports output */
if (module->init_output == NULL) {
error1("Module '%s' does not support audio output.", name);
close_module( module );
return NULL;
}
/* Allocation memory for audio output type */
ao = alloc_audio_output();
if (ao==NULL) {
error( "Failed to allocate audio output structure." );
return NULL;
}
/* Call the init function */
result = module->init_output(ao);
if (result) {
error1( "Module's init function failed: %d", result );
close_module( module );
return NULL;
}
/* Store the pointer to the module (so we can close it later) */
ao->module = module;
return ao;
}
void audio_info_struct_dump(struct audio_info_struct *ai)
/* FIXME: this is called anywhere */
void close_output_module( audio_output_t* ao )
{
fprintf(stderr, "ai->fn=%d\n", ai->fn);
fprintf(stderr, "ai->handle=%p\n", ai->handle);
fprintf(stderr, "ai->rate=%ld\n", ai->rate);
fprintf(stderr, "ai->gain=%ld\n", ai->gain);
fprintf(stderr, "ai->output=%d\n", ai->output);
fprintf(stderr, "ai->device='%s'\n", ai->device);
fprintf(stderr, "ai->channels=%d\n", ai->channels);
fprintf(stderr, "ai->format=%d\n", ai->format);
if (!ao) return;
/* Close the audio output */
if (ao->close) ao->close( ao );
/* Deinitialise the audio output */
if (ao->deinit) ao->deinit( ao );
/* Unload the module */
if (ao->module) close_module( ao->module );
/* Free up memory */
free( ao );
}
/* allocate and initialise memory */
audio_output_t* alloc_audio_output()
{
audio_output_t* ao = malloc( sizeof( audio_output_t ) );
if (ao==NULL) error( "Failed to allocate memory for audio_output_t." );
/* Initialise variables */
ao->fn = -1;
ao->rate = -1;
ao->gain = -1;
ao->userptr = NULL;
ao->device = NULL;
ao->channels = -1;
ao->format = -1;
/*ao->module = NULL;*/
/* Set the callbacks to NULL */
ao->open = NULL;
ao->get_formats = NULL;
ao->write = NULL;
ao->flush = NULL;
ao->close = NULL;
ao->deinit = NULL;
return ao;
}
void audio_output_dump(audio_output_t *ao)
{
fprintf(stderr, "ao->fn=%d\n", ao->fn);
fprintf(stderr, "ao->userptr=%p\n", ao->userptr);
fprintf(stderr, "ao->rate=%ld\n", ao->rate);
fprintf(stderr, "ao->gain=%ld\n", ao->gain);
fprintf(stderr, "ao->device='%s'\n", ao->device);
fprintf(stderr, "ao->channels=%d\n", ao->channels);
fprintf(stderr, "ao->format=%d\n", ao->format);
}
@@ -38,7 +114,7 @@ void audio_info_struct_dump(struct audio_info_struct *ai)
#define NUM_ENCODINGS 6
#define NUM_RATES 10
struct audio_name audio_val2name[NUM_ENCODINGS+1] = {
struct audio_format_name audio_val2name[NUM_ENCODINGS+1] = {
{ AUDIO_FORMAT_SIGNED_16 , "signed 16 bit" , "s16 " } ,
{ AUDIO_FORMAT_UNSIGNED_16, "unsigned 16 bit" , "u16 " } ,
{ AUDIO_FORMAT_UNSIGNED_8 , "unsigned 8 bit" , "u8 " } ,
@@ -48,10 +124,6 @@ struct audio_name audio_val2name[NUM_ENCODINGS+1] = {
{ -1 , NULL }
};
#if 0
static char *channel_name[NUM_CHANNELS] =
{ "mono" , "stereo" };
#endif
static int channels[NUM_CHANNELS] = { 1 , 2 };
static int rates[NUM_RATES] = {
@@ -59,8 +131,8 @@ static int rates[NUM_RATES] = {
16000, 22050, 24000,
32000, 44100, 48000,
8000 /* 8000 = dummy for user forced */
};
static int encodings[NUM_ENCODINGS] = {
AUDIO_FORMAT_SIGNED_16,
AUDIO_FORMAT_UNSIGNED_16,
@@ -72,14 +144,15 @@ static int encodings[NUM_ENCODINGS] = {
static char capabilities[NUM_CHANNELS][NUM_ENCODINGS][NUM_RATES];
void print_capabilities(struct audio_info_struct *ai)
static void print_capabilities(audio_output_t *ao)
{
int j,k,k1=NUM_RATES-1;
if(param.force_rate) {
rates[NUM_RATES-1] = param.force_rate;
k1 = NUM_RATES;
}
fprintf(stderr,"\nAudio device: %s\nAudio capabilities:\n(matrix of [S]tereo or [M]ono support for sample format and rate in Hz)\n |", ai->device != NULL ? ai->device : "<none>");
fprintf(stderr,"\nAudio device: %s\nAudio capabilities:\n(matrix of [S]tereo or [M]ono support for sample format and rate in Hz)\n |",
ao->device != NULL ? ao->device : "<none>");
for(j=0;j<NUM_ENCODINGS;j++) {
fprintf(stderr," %5s |",audio_val2name[j].sname);
}
@@ -104,11 +177,11 @@ void print_capabilities(struct audio_info_struct *ai)
}
void audio_capabilities(struct audio_info_struct *ai)
void audio_capabilities(audio_output_t *ao)
{
int fmts;
int i,j,k,k1=NUM_RATES-1;
struct audio_info_struct ai1 = *ai;
audio_output_t ao1 = *ao;
if (param.outmode != DECODE_AUDIO) {
memset(capabilities,1,sizeof(capabilities));
@@ -122,16 +195,16 @@ void audio_capabilities(struct audio_info_struct *ai)
}
/* if audio_open fails, the device is just not capable of anything... */
if(audio_open(&ai1) < 0) {
perror("audio");
if(ao1.open(&ao1) < 0) {
error("failed to open audio device");
}
else
{
for(i=0;i<NUM_CHANNELS;i++) {
for(j=0;j<NUM_RATES;j++) {
ai1.channels = channels[i];
ai1.rate = rates[j];
fmts = audio_get_formats(&ai1);
ao1.channels = channels[i];
ao1.rate = rates[j];
fmts = ao1.get_formats(&ao1);
if(fmts < 0)
continue;
for(k=0;k<NUM_ENCODINGS;k++) {
@@ -140,10 +213,10 @@ void audio_capabilities(struct audio_info_struct *ai)
}
}
}
audio_close(&ai1);
ao1.close(&ao1);
}
if(param.verbose > 1) print_capabilities(ai);
if(param.verbose > 1) print_capabilities(ao);
}
static int rate2num(int r)
@@ -156,16 +229,16 @@ static int rate2num(int r)
}
static int audio_fit_cap_helper(struct audio_info_struct *ai,int rn,int f0,int f2,int c)
static int audio_fit_cap_helper(audio_output_t *ao,int rn,int f0,int f2,int c)
{
int i;
if(rn >= 0) {
for(i=f0;i<f2;i++) {
if(capabilities[c][i][rn]) {
ai->rate = rates[rn];
ai->format = encodings[i];
ai->channels = channels[c];
ao->rate = rates[rn];
ao->format = encodings[i];
ao->channels = channels[c];
return 1;
}
}
@@ -179,12 +252,15 @@ static int audio_fit_cap_helper(struct audio_info_struct *ai,int rn,int f0,int f
* r=rate of stream
* return 0 on error
*/
int audio_fit_capabilities(struct audio_info_struct *ai,int c,int r)
int audio_fit_capabilities(audio_output_t *ao,int c,int r)
{
int rn;
int f0=0;
if(param.force_8bit) f0 = 2; /* skip the 16bit encodings */
/* skip the 16bit encodings */
if(param.force_8bit) {
f0 = 2;
}
c--; /* stereo=1 ,mono=0 */
@@ -196,76 +272,76 @@ int audio_fit_capabilities(struct audio_info_struct *ai,int c,int r)
rates[NUM_RATES-1] = param.force_rate; /* To make STDOUT decoding work. */
rn = rate2num(param.force_rate);
/* 16bit encodings */
if(audio_fit_cap_helper(ai,rn,f0,2,c)) return 1;
if(audio_fit_cap_helper(ao,rn,f0,2,c)) return 1;
/* 8bit encodings */
if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c)) return 1;
if(audio_fit_cap_helper(ao,rn,2,NUM_ENCODINGS,c)) return 1;
/* try again with different stereoness */
if(c == 1 && !param.force_stereo) c = 0;
else if(c == 0 && !param.force_mono) c = 1;
/* 16bit encodings */
if(audio_fit_cap_helper(ai,rn,f0,2,c)) return 1;
if(audio_fit_cap_helper(ao,rn,f0,2,c)) return 1;
/* 8bit encodings */
if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c)) return 1;
if(audio_fit_cap_helper(ao,rn,2,NUM_ENCODINGS,c)) return 1;
error3("Unable to set up output device! Constraints: %s%s%liHz.",
(param.force_stereo ? "stereo, " :
(param.force_mono ? "mono, " : "")),
(param.force_8bit ? "8bit, " : ""),
param.force_rate);
if(param.verbose <= 1) print_capabilities(ai);
if(param.verbose <= 1) print_capabilities(ao);
return 0;
}
/* try different rates with 16bit */
rn = rate2num(r>>0);
if(audio_fit_cap_helper(ai,rn,f0,2,c))
if(audio_fit_cap_helper(ao,rn,f0,2,c))
return 1;
rn = rate2num(r>>1);
if(audio_fit_cap_helper(ai,rn,f0,2,c))
if(audio_fit_cap_helper(ao,rn,f0,2,c))
return 1;
rn = rate2num(r>>2);
if(audio_fit_cap_helper(ai,rn,f0,2,c))
if(audio_fit_cap_helper(ao,rn,f0,2,c))
return 1;
/* try different rates with 8bit */
rn = rate2num(r>>0);
if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
if(audio_fit_cap_helper(ao,rn,2,NUM_ENCODINGS,c))
return 1;
rn = rate2num(r>>1);
if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
if(audio_fit_cap_helper(ao,rn,2,NUM_ENCODINGS,c))
return 1;
rn = rate2num(r>>2);
if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
if(audio_fit_cap_helper(ao,rn,2,NUM_ENCODINGS,c))
return 1;
/* try again with different stereoness */
/* try agaon with different stereoness */
if(c == 1 && !param.force_stereo) c = 0;
else if(c == 0 && !param.force_mono) c = 1;
/* 16bit */
rn = rate2num(r>>0);
if(audio_fit_cap_helper(ai,rn,f0,2,c)) return 1;
if(audio_fit_cap_helper(ao,rn,f0,2,c)) return 1;
rn = rate2num(r>>1);
if(audio_fit_cap_helper(ai,rn,f0,2,c)) return 1;
if(audio_fit_cap_helper(ao,rn,f0,2,c)) return 1;
rn = rate2num(r>>2);
if(audio_fit_cap_helper(ai,rn,f0,2,c)) return 1;
if(audio_fit_cap_helper(ao,rn,f0,2,c)) return 1;
/* 8bit */
rn = rate2num(r>>0);
if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c)) return 1;
if(audio_fit_cap_helper(ao,rn,2,NUM_ENCODINGS,c)) return 1;
rn = rate2num(r>>1);
if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c)) return 1;
if(audio_fit_cap_helper(ao,rn,2,NUM_ENCODINGS,c)) return 1;
rn = rate2num(r>>2);
if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c)) return 1;
if(audio_fit_cap_helper(ao,rn,2,NUM_ENCODINGS,c)) return 1;
error5("Unable to set up output device! Constraints: %s%s%i, %i or %iHz.",
(param.force_stereo ? "stereo, " :
(param.force_mono ? "mono, " : "")),
(param.force_8bit ? "8bit, " : ""),
r, r>>1, r>>2);
if(param.verbose <= 1) print_capabilities(ai);
if(param.verbose <= 1) print_capabilities(ao);
return 0;
}
@@ -279,3 +355,105 @@ char *audio_encoding_name(int format)
}
return "Unknown";
}
#if !defined(WIN32) && !defined(GENERIC)
#ifndef NOXFERMEM
static void catch_child(void)
{
while (waitpid(-1, NULL, WNOHANG) > 0);
}
#endif
#endif
/* FIXME: Old output initialization code that needs updating */
int init_output( audio_output_t *ao )
{
static int init_done = FALSE;
if (init_done) return 0;
init_done = TRUE;
#ifndef NOXFERMEM
/*
* Only DECODE_AUDIO and DECODE_FILE are sanely handled by the
* buffer process. For now, we just ignore the request
* to buffer the output. [dk]
*/
if (param.usebuffer && (param.outmode != DECODE_AUDIO) &&
(param.outmode != DECODE_FILE)) {
fprintf(stderr, "Sorry, won't buffer output unless writing plain audio.\n");
param.usebuffer = 0;
}
if (param.usebuffer) {
unsigned int bufferbytes;
sigset_t newsigset, oldsigset;
if (param.usebuffer < 32)
param.usebuffer = 32; /* minimum is 32 Kbytes! */
bufferbytes = (param.usebuffer * 1024);
bufferbytes -= bufferbytes % FRAMEBUFUNIT;
/* +1024 for NtoM rounding problems */
xfermem_init (&buffermem, bufferbytes ,0,1024);
pcm_sample = (unsigned char *) buffermem->data;
pcm_point = 0;
sigemptyset (&newsigset);
sigaddset (&newsigset, SIGUSR1);
sigprocmask (SIG_BLOCK, &newsigset, &oldsigset);
#if !defined(WIN32) && !defined(GENERIC)
catchsignal (SIGCHLD, catch_child);
#endif
switch ((buffer_pid = fork())) {
case -1: /* error */
perror("fork()");
return 1;
case 0: /* child */
if(rd) rd->close(rd); /* child doesn't need the input stream */
xfermem_init_reader (buffermem);
buffer_loop(ao, &oldsigset);
xfermem_done_reader (buffermem);
xfermem_done (buffermem);
exit(0);
default: /* parent */
xfermem_init_writer (buffermem);
param.outmode = DECODE_BUFFER;
break;
}
} else {
#endif
/* + 1024 for NtoM rate converter */
if (!(pcm_sample = (unsigned char *) malloc(audiobufsize * 2 + 1024))) {
perror ("malloc()");
return 1;
#ifndef NOXFERMEM
}
#endif
}
switch(param.outmode) {
case DECODE_AUDIO:
if(ao->open(ao) < 0) {
error("failed to open audio device");
return 1;
}
break;
case DECODE_WAV:
wav_open(ao,param.filename);
break;
case DECODE_AU:
au_open(ao,param.filename);
break;
case DECODE_CDR:
cdr_open(ao,param.filename);
break;
}
return 0;
}

View File

@@ -14,6 +14,8 @@
#ifndef _MPG123_AUDIO_H_
#define _MPG123_AUDIO_H_
#include "module.h"
#define AUDIO_OUT_HEADPHONES 0x01
#define AUDIO_OUT_INTERNAL_SPEAKER 0x02
#define AUDIO_OUT_LINE_OUT 0x04
@@ -29,6 +31,7 @@ enum {
DECODE_AUDIOFILE
};
#define AUDIO_FORMAT_MASK 0x100
#define AUDIO_FORMAT_16 0x100
#define AUDIO_FORMAT_8 0x000
@@ -45,22 +48,32 @@ enum {
struct audio_info_struct
typedef struct audio_output_struct
{
int fn; /* filenumber */
void *handle; /* driver specific pointer */
void *userptr; /* driver specific pointer */
long rate;
long gain;
int output;
/* Callbacks */
int (*open)(struct audio_output_struct *);
int (*get_formats)(struct audio_output_struct *);
int (*write)(struct audio_output_struct *, unsigned char *,int);
void (*flush)(struct audio_output_struct *);
int (*close)(struct audio_output_struct *);
int (*deinit)(struct audio_output_struct *);
char *device;
int channels;
int format;
/* the module this belongs to */
mpg123_module_t *module;
};
char *device; /* device name */
long rate; /* sample rate */
long gain; /* output gain */
int channels; /* number of channels */
int format; /* format flags */
int output; /* headphone/speaker/lineout */
struct audio_name {
} audio_output_t;
struct audio_format_name {
int val;
char *name;
char *sname;
@@ -69,20 +82,16 @@ struct audio_name {
/* ------ Declarations from "audio.c" ------ */
extern void audio_info_struct_init(struct audio_info_struct *);
extern void audio_info_struct_dump(struct audio_info_struct *ai);
extern void audio_capabilities(struct audio_info_struct *);
extern int audio_fit_capabilities(struct audio_info_struct *ai,int c,int r);
extern audio_output_t* open_output_module( const char* name );
extern audio_output_t* alloc_audio_output();
extern void deinit_audio_output( audio_output_t* ao );
extern void audio_output_dump(audio_output_t *ao);
extern void audio_capabilities(audio_output_t *ao);
extern int audio_fit_capabilities(audio_output_t *ao,int c,int r);
extern char *audio_encoding_name(int format);
extern int init_output( audio_output_t *ao );
/* ------ Declarations from "audio_*.c" ------ */
extern int audio_open(struct audio_info_struct *);
extern int audio_get_formats(struct audio_info_struct *);
extern int audio_play_samples(struct audio_info_struct *, unsigned char *,int);
extern void audio_queueflush(struct audio_info_struct *ai);
extern int audio_close(struct audio_info_struct *);
#endif

View File

@@ -1,216 +0,0 @@
/*
audio_alsa: sound output with Advanced Linux Sound Architecture 1.x API
copyright 2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
written by Clemens Ladisch <clemens@ladisch.de>
*/
#include "mpg123.h"
#include <errno.h>
/* make ALSA 0.9.x compatible to the 1.0.x API */
#define ALSA_PCM_NEW_HW_PARAMS_API
#define ALSA_PCM_NEW_SW_PARAMS_API
#include <alsa/asoundlib.h>
/* My laptop has probs playing low-sampled files with only 0.5s buffer... this should be a user setting -- ThOr */
#define BUFFER_LENGTH 0.5 /* in seconds */
static const struct {
snd_pcm_format_t alsa;
int mpg123;
} format_map[] = {
{ SND_PCM_FORMAT_S16, AUDIO_FORMAT_SIGNED_16 },
{ SND_PCM_FORMAT_U16, AUDIO_FORMAT_UNSIGNED_16 },
{ SND_PCM_FORMAT_U8, AUDIO_FORMAT_UNSIGNED_8 },
{ SND_PCM_FORMAT_S8, AUDIO_FORMAT_SIGNED_8 },
{ SND_PCM_FORMAT_A_LAW, AUDIO_FORMAT_ALAW_8 },
{ SND_PCM_FORMAT_MU_LAW, AUDIO_FORMAT_ULAW_8 },
};
#define NUM_FORMATS (sizeof format_map / sizeof format_map[0])
static int initialize_device(struct audio_info_struct *ai);
int audio_open(struct audio_info_struct *ai)
{
const char *pcm_name;
snd_pcm_t *pcm;
pcm_name = ai->device ? ai->device : "default";
if (snd_pcm_open(&pcm, pcm_name, SND_PCM_STREAM_PLAYBACK, 0) < 0) {
fprintf(stderr, "audio_open(): cannot open device %s\n", pcm_name);
return -1;
}
ai->handle = pcm;
if (ai->format != -1) {
/* we're going to play: initalize sample format */
return initialize_device(ai);
} else {
/* query mode; sample format will be set for each query */
return 0;
}
}
static int rates_match(long int desired, unsigned int actual)
{
return actual * 100 > desired * (100 - AUDIO_RATE_TOLERANCE) &&
actual * 100 < desired * (100 + AUDIO_RATE_TOLERANCE);
}
static int initialize_device(struct audio_info_struct *ai)
{
snd_pcm_hw_params_t *hw;
int i;
snd_pcm_format_t format;
unsigned int rate;
snd_pcm_uframes_t buffer_size;
snd_pcm_uframes_t period_size;
snd_pcm_sw_params_t *sw;
snd_pcm_hw_params_alloca(&hw);
if (snd_pcm_hw_params_any(ai->handle, hw) < 0) {
fprintf(stderr, "initialize_device(): no configuration available\n");
return -1;
}
if (snd_pcm_hw_params_set_access(ai->handle, hw, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
fprintf(stderr, "initialize_device(): device does not support interleaved access\n");
return -1;
}
format = SND_PCM_FORMAT_UNKNOWN;
for (i = 0; i < NUM_FORMATS; ++i) {
if (ai->format == format_map[i].mpg123) {
format = format_map[i].alsa;
break;
}
}
if (format == SND_PCM_FORMAT_UNKNOWN) {
fprintf(stderr, "initialize_device(): invalid sample format %d\n", ai->format);
errno = EINVAL;
return -1;
}
if (snd_pcm_hw_params_set_format(ai->handle, hw, format) < 0) {
fprintf(stderr, "initialize_device(): cannot set format %s\n", snd_pcm_format_name(format));
return -1;
}
if (snd_pcm_hw_params_set_channels(ai->handle, hw, ai->channels) < 0) {
fprintf(stderr, "initialize_device(): cannot set %d channels\n", ai->channels);
return -1;
}
rate = ai->rate;
if (snd_pcm_hw_params_set_rate_near(ai->handle, hw, &rate, NULL) < 0) {
fprintf(stderr, "initialize_device(): cannot set rate %u\n", rate);
return -1;
}
if (!rates_match(ai->rate, rate)) {
fprintf(stderr, "initialize_device(): rate %ld not available, using %u\n", ai->rate, rate);
/* return -1; */
}
buffer_size = rate * BUFFER_LENGTH;
if (snd_pcm_hw_params_set_buffer_size_near(ai->handle, hw, &buffer_size) < 0) {
fprintf(stderr, "initialize_device(): cannot set buffer size\n");
return -1;
}
period_size = buffer_size / 4;
if (snd_pcm_hw_params_set_period_size_near(ai->handle, hw, &period_size, NULL) < 0) {
fprintf(stderr, "initialize_device(): cannot set period size\n");
return -1;
}
if (snd_pcm_hw_params(ai->handle, hw) < 0) {
fprintf(stderr, "initialize_device(): cannot set hw params\n");
return -1;
}
snd_pcm_sw_params_alloca(&sw);
if (snd_pcm_sw_params_current(ai->handle, sw) < 0) {
fprintf(stderr, "initialize_device(): cannot get sw params\n");
return -1;
}
/* start playing after the first write */
if (snd_pcm_sw_params_set_start_threshold(ai->handle, sw, 1) < 0) {
fprintf(stderr, "initialize_device(): cannot set start threshold\n");
return -1;
}
/* wake up on every interrupt */
if (snd_pcm_sw_params_set_avail_min(ai->handle, sw, 1) < 0) {
fprintf(stderr, "initialize_device(): cannot set min avail\n");
return -1;
}
/* always write as many frames as possible */
if (snd_pcm_sw_params_set_xfer_align(ai->handle, sw, 1) < 0) {
fprintf(stderr, "initialize_device(): cannot set transfer alignment\n");
return -1;
}
if (snd_pcm_sw_params(ai->handle, sw) < 0) {
fprintf(stderr, "initialize_device(): cannot set sw params\n");
return -1;
}
return 0;
}
int audio_get_formats(struct audio_info_struct *ai)
{
snd_pcm_hw_params_t *hw;
unsigned int rate;
int supported_formats, i;
snd_pcm_hw_params_alloca(&hw);
if (snd_pcm_hw_params_any(ai->handle, hw) < 0) {
fprintf(stderr, "audio_get_formats(): no configuration available\n");
return -1;
}
if (snd_pcm_hw_params_set_access(ai->handle, hw, SND_PCM_ACCESS_RW_INTERLEAVED) < 0)
return -1;
if (snd_pcm_hw_params_set_channels(ai->handle, hw, ai->channels) < 0)
return 0;
rate = ai->rate;
if (snd_pcm_hw_params_set_rate_near(ai->handle, hw, &rate, NULL) < 0)
return -1;
if (!rates_match(ai->rate, rate))
return 0;
supported_formats = 0;
for (i = 0; i < NUM_FORMATS; ++i) {
if (snd_pcm_hw_params_test_format(ai->handle, hw, format_map[i].alsa) == 0)
supported_formats |= format_map[i].mpg123;
}
return supported_formats;
}
int audio_play_samples(struct audio_info_struct *ai, unsigned char *buf, int bytes)
{
snd_pcm_uframes_t frames;
snd_pcm_sframes_t written;
frames = snd_pcm_bytes_to_frames(ai->handle, bytes);
written = snd_pcm_writei(ai->handle, buf, frames);
if (written == -EINTR) /* interrupted system call */
written = 0;
else if (written == -EPIPE) { /* underrun */
if (snd_pcm_prepare(ai->handle) >= 0)
written = snd_pcm_writei(ai->handle, buf, frames);
}
if (written >= 0)
return snd_pcm_frames_to_bytes(ai->handle, written);
else
return written;
}
void audio_queueflush(struct audio_info_struct *ai)
{
/* is this the optimal solution? - we should figure out what we really whant from this function */
snd_pcm_drop(ai->handle);
snd_pcm_prepare(ai->handle);
}
int audio_close(struct audio_info_struct *ai)
{
if(ai->handle != NULL) /* be really generous for being called without any device opening */
{
if (snd_pcm_state(ai->handle) == SND_PCM_STATE_RUNNING)
snd_pcm_drain(ai->handle);
return snd_pcm_close(ai->handle);
}
else return 0;
}

View File

@@ -1,34 +0,0 @@
/*
audio_dummy.c: dummy audio output
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
#include "mpg123.h"
int audio_open(struct audio_info_struct *ai)
{
fprintf(stderr,"No audio device support compiled into this binary (use -s).\n");
return -1;
}
int audio_get_formats(struct audio_info_struct *ai)
{
return AUDIO_FORMAT_SIGNED_16;
}
int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
{
return len;
}
int audio_close(struct audio_info_struct *ai)
{
return 0;
}
void audio_queueflush(struct audio_info_struct *ai)
{
}

View File

@@ -1,128 +0,0 @@
/*
audio_esd.c: audio output for ESounD (highly untested nowadays (?))
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Eric B. Mitchell ("esd port" should be this file...)
*/
#include <esd.h>
#include <errno.h>
#include <assert.h>
#include "mpg123.h"
#ifdef SOLARIS
#include <stropts.h>
#include <sys/conf.h>
#endif
static unsigned esd_rate = 0, esd_format = 0, esd_channels = 0;
static char *esdserver = NULL;
int audio_open(struct audio_info_struct *ai)
{
esd_format_t format = ESD_STREAM | ESD_PLAY;
if (!esd_rate)
{
int esd;
esd_server_info_t *info;
esd_format_t fmt;
if ((esd = esd_open_sound(NULL)) >= 0)
{
info = esd_get_server_info(esd);
esd_rate = info->rate;
fmt = info->format;
esd_free_server_info(info);
esd_close(esd);
}
else
{
esd_rate = esd_audio_rate;
fmt = esd_audio_format;
}
esd_format = AUDIO_FORMAT_UNSIGNED_8;
if ((fmt & ESD_MASK_BITS) == ESD_BITS16)
esd_format |= AUDIO_FORMAT_SIGNED_16;
esd_channels = fmt & ESD_MASK_CHAN;
}
if (ai->format == -1)
ai->format = esd_format;
else if (!(ai->format & esd_format))
{
fprintf(stderr, "audio: Unsupported audio format: %d\n", ai->format);
errno = EINVAL;
return -1;
}
if (ai->format & AUDIO_FORMAT_SIGNED_16)
format |= ESD_BITS16;
else if (ai->format & AUDIO_FORMAT_UNSIGNED_8)
format |= ESD_BITS8;
else
assert(0);
if (ai->channels == -1)
ai->channels = 2;
else if (ai->channels <= 0 || ai->channels > esd_channels)
{
fprintf(stderr, "audio: Unsupported no of channels: %d\n", ai->channels);
errno = EINVAL;
return -1;
}
if (ai->channels == 1)
format |= ESD_MONO;
else if (ai->channels == 2)
format |= ESD_STEREO;
else
assert(0);
if (ai->rate == -1)
ai->rate = esd_rate;
else if (ai->rate > esd_rate)
return -1;
ai->fn = esd_play_stream_fallback(format, ai->rate, ai->device, "mpg123");
return (ai->fn);
}
int audio_get_formats(struct audio_info_struct *ai)
{
if (0 < ai->channels && ai->channels <= esd_channels
&& 0 < ai->rate && ai->rate <= esd_rate)
return esd_format;
else
return -1;
}
int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
{
return write(ai->fn,buf,len);
}
int audio_close(struct audio_info_struct *ai)
{
close (ai->fn);
return 0;
}
#ifdef SOLARIS
void audio_queueflush (struct audio_info_struct *ai)
{
ioctl (ai->fn, I_FLUSH, FLUSHRW);
}
#else
#ifdef NETBSD
void audio_queueflush (struct audio_info_struct *ai)
{
ioctl (ai->fn, AUDIO_FLUSH, 0);
}
#else
/* Dunno what to do on Linux and Cygwin, but the func must be at least defined! */
void audio_queueflush (struct audio_info_struct *ai)
{
}
#endif
#endif

View File

@@ -1,150 +0,0 @@
/*
audio_hp.c: audio output for HP-UX
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
#include "mpg123.h"
#include <fcntl.h>
#include <sys/audio.h>
static int audio_set_rate(struct audio_info_struct *ai)
{
if(ai->rate >= 0)
return ioctl(ai->fn,AUDIO_SET_SAMPLE_RATE,ai->rate);
return 0;
}
static int audio_set_channels(struct audio_info_struct *ai)
{
if(ai->channels<0)
return 0;
return ioctl(ai->fn,AUDIO_SET_CHANNELS,ai->channels);
}
static int audio_set_format(struct audio_info_struct *ai)
{
int fmt;
switch(ai->format) {
case -1:
case AUDIO_FORMAT_SIGNED_16:
default:
fmt = AUDIO_FORMAT_LINEAR16BIT;
break;
case AUDIO_FORMAT_UNSIGNED_8:
fprintf(stderr,"unsigned 8 bit linear not supported\n");
return -1;
case AUDIO_FORMAT_SIGNED_8:
fprintf(stderr,"signed 8 bit linear not supported\n");
return -1;
case AUDIO_FORMAT_ALAW_8:
fmt = AUDIO_FORMAT_ALAW;
break;
case AUDIO_FORMAT_ULAW_8:
fmt = AUDIO_FORMAT_ULAW;
break;
}
return ioctl(ai->fn,AUDIO_SET_DATA_FORMAT,fmt);
}
static int audio_get_formats(struct audio_info_struct *ai)
{
return AUDIO_FORMAT_SIGNED_16;
}
static int audio_reset_parameters(struct audio_info_struct *ai)
{
int ret;
ret = audio_set_format(ai);
if(ret >= 0)
ret = audio_set_channels(ai);
if(ret >= 0)
ret = audio_set_rate(ai);
return ret;
}
int audio_open(struct audio_info_struct *ai)
{
struct audio_describe ades;
struct audio_gain again;
int i,audio;
ai->fn = open("/dev/audio",O_RDWR);
if(ai->fn < 0)
return -1;
ioctl(ai->fn,AUDIO_DESCRIBE,&ades);
if(ai->gain != -1)
{
if(ai->gain > ades.max_transmit_gain)
{
fprintf(stderr,"your gainvalue was to high -> set to maximum.\n");
ai->gain = ades.max_transmit_gain;
}
if(ai->gain < ades.min_transmit_gain)
{
fprintf(stderr,"your gainvalue was to low -> set to minimum.\n");
ai->gain = ades.min_transmit_gain;
}
again.channel_mask = AUDIO_CHANNEL_0 | AUDIO_CHANNEL_1;
ioctl(ai->fn,AUDIO_GET_GAINS,&again);
again.cgain[0].transmit_gain = ai->gain;
again.cgain[1].transmit_gain = ai->gain;
again.channel_mask = AUDIO_CHANNEL_0 | AUDIO_CHANNEL_1;
ioctl(ai->fn,AUDIO_SET_GAINS,&again);
}
if(ai->output != -1)
{
if(ai->output & AUDIO_OUT_INTERNAL_SPEAKER)
ioctl(ai->fn,AUDIO_SET_OUTPUT,AUDIO_OUT_SPEAKER);
else if(ai->output & AUDIO_OUT_HEADPHONES)
ioctl(ai->fn,AUDIO_SET_OUTPUT,AUDIO_OUT_HEADPHONE);
else if(ai->output & AUDIO_OUT_LINE_OUT)
ioctl(ai->fn,AUDIO_SET_OUTPUT,AUDIO_OUT_LINE);
}
if(ai->rate == -1)
ai->rate = 44100;
for(i=0;i<ades.nrates;i++)
{
if(ai->rate == ades.sample_rate[i])
break;
}
if(i == ades.nrates)
{
fprintf(stderr,"Can't set sample-rate to %ld.\n",ai->rate);
i = 0;
}
if(audio_reset_parameters(ai) < 0)
return -1;
return ai->fn;
}
int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
{
return write(ai->fn,buf,len);
}
int audio_close(struct audio_info_struct *ai)
{
close (ai->fn);
return 0;
}
void audio_queueflush(struct audio_info_struct *ai)
{
}

View File

@@ -1,293 +0,0 @@
/*
audio_oss.c: audio output via Open Sound System
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
#include <sys/ioctl.h>
#include <fcntl.h>
#include "mpg123.h"
#ifdef HAVE_LINUX_SOUNDCARD_H
#include <linux/soundcard.h>
#endif
#ifdef HAVE_SYS_SOUNDCARD_H
#include <sys/soundcard.h>
#endif
#ifdef HAVE_MACHINE_SOUNDCARD_H
#include <machine/soundcard.h>
#endif
#ifndef AFMT_S16_NE
# ifdef OSS_BIG_ENDIAN
# define AFMT_S16_NE AFMT_S16_BE
# else
# define AFMT_S16_NE AFMT_S16_LE
# endif
#endif
#ifndef AFMT_U16_NE
# ifdef OSS_BIG_ENDIAN
# define AFMT_U16_NE AFMT_U16_BE
# else
# define AFMT_U16_NE AFMT_U16_LE
# endif
#endif
extern int outburst;
static int audio_rate_best_match(struct audio_info_struct *ai)
{
int ret,dsp_rate;
if(!ai || ai->fn < 0 || ai->rate < 0)
return -1;
dsp_rate = ai->rate;
ret = ioctl(ai->fn, SNDCTL_DSP_SPEED,&dsp_rate);
if(ret < 0)
return ret;
ai->rate = dsp_rate;
return 0;
}
static int audio_set_rate(struct audio_info_struct *ai)
{
int dsp_rate;
int ret = 0;
if(ai->rate >= 0) {
dsp_rate = ai->rate;
ret = ioctl(ai->fn, SNDCTL_DSP_SPEED,&dsp_rate);
}
return ret;
}
static int audio_set_channels(struct audio_info_struct *ai)
{
int chan = ai->channels - 1;
int ret;
if(ai->channels < 0)
return 0;
ret = ioctl(ai->fn, SNDCTL_DSP_STEREO, &chan);
if(chan != (ai->channels-1)) {
return -1;
}
return ret;
}
static int audio_set_format(struct audio_info_struct *ai)
{
int sample_size,fmts;
int sf,ret;
if(ai->format == -1)
return 0;
switch(ai->format) {
case AUDIO_FORMAT_SIGNED_16:
default:
fmts = AFMT_S16_NE;
sample_size = 16;
break;
case AUDIO_FORMAT_UNSIGNED_8:
fmts = AFMT_U8;
sample_size = 8;
break;
case AUDIO_FORMAT_SIGNED_8:
fmts = AFMT_S8;
sample_size = 8;
break;
case AUDIO_FORMAT_ULAW_8:
fmts = AFMT_MU_LAW;
sample_size = 8;
break;
case AUDIO_FORMAT_ALAW_8:
fmts = AFMT_A_LAW;
sample_size = 8;
break;
case AUDIO_FORMAT_UNSIGNED_16:
fmts = AFMT_U16_NE;
break;
}
#if 0
if(ioctl(ai->fn, SNDCTL_DSP_SAMPLESIZE,&sample_size) < 0)
return -1;
#endif
sf = fmts;
ret = ioctl(ai->fn, SNDCTL_DSP_SETFMT, &fmts);
if(sf != fmts) {
return -1;
}
return ret;
}
static int audio_reset_parameters(struct audio_info_struct *ai)
{
int ret;
ret = ioctl(ai->fn, SNDCTL_DSP_RESET, NULL);
if(ret < 0)
error("Can't reset audio!");
ret = audio_set_format(ai);
if (ret == -1)
goto err;
ret = audio_set_channels(ai);
if (ret == -1)
goto err;
ret = audio_set_rate(ai);
if (ret == -1)
goto err;
/* Careful here. As per OSS v1.1, the next ioctl() commits the format
* set above, so we must issue SNDCTL_DSP_RESET before we're allowed to
* change it again. [dk]
*/
if (ioctl(ai->fn, SNDCTL_DSP_GETBLKSIZE, &outburst) == -1 ||
outburst > MAXOUTBURST)
outburst = MAXOUTBURST;
err:
return ret;
}
int audio_open(struct audio_info_struct *ai)
{
char usingdefdev = 0;
if(!ai)
return -1;
if(!ai->device) {
ai->device = "/dev/dsp";
usingdefdev = 1;
}
ai->fn = open(ai->device,O_WRONLY);
if(ai->fn < 0)
{
if(usingdefdev) {
ai->device = "/dev/sound/dsp";
ai->fn = open(ai->device,O_WRONLY);
if(ai->fn < 0) {
error("Can't open default sound device!");
return -1;
}
} else {
error1("Can't open %s!",ai->device);
return -1;
}
}
if(audio_reset_parameters(ai) < 0) {
close(ai->fn);
return -1;
}
if(ai->gain >= 0) {
int e,mask;
e = ioctl(ai->fn , SOUND_MIXER_READ_DEVMASK ,&mask);
if(e < 0) {
error("audio/gain: Can't get audio device features list.");
}
else if(mask & SOUND_MASK_PCM) {
int gain = (ai->gain<<8)|(ai->gain);
e = ioctl(ai->fn, SOUND_MIXER_WRITE_PCM , &gain);
}
else if(!(mask & SOUND_MASK_VOLUME)) {
error1("audio/gain: setable Volume/PCM-Level not supported by your audio device: %#04x",mask);
}
else {
int gain = (ai->gain<<8)|(ai->gain);
e = ioctl(ai->fn, SOUND_MIXER_WRITE_VOLUME , &gain);
}
}
return ai->fn;
}
/*
* get formats for specific channel/rate parameters
*/
int audio_get_formats(struct audio_info_struct *ai)
{
int fmt = 0;
int r = ai->rate;
int c = ai->channels;
int i;
static int fmts[] = {
AUDIO_FORMAT_ULAW_8 , AUDIO_FORMAT_SIGNED_16 ,
AUDIO_FORMAT_UNSIGNED_8 , AUDIO_FORMAT_SIGNED_8 ,
AUDIO_FORMAT_UNSIGNED_16 , AUDIO_FORMAT_ALAW_8 };
/* Reset is required before we're allowed to set the new formats. [dk] */
ioctl(ai->fn, SNDCTL_DSP_RESET, NULL);
for(i=0;i<6;i++) {
ai->format = fmts[i];
if(audio_set_format(ai) < 0) {
continue;
}
ai->channels = c;
if(audio_set_channels(ai) < 0) {
continue;
}
ai->rate = r;
if(audio_rate_best_match(ai) < 0) {
continue;
}
if( (ai->rate*100 > r*(100-AUDIO_RATE_TOLERANCE)) && (ai->rate*100 < r*(100+AUDIO_RATE_TOLERANCE)) ) {
fmt |= fmts[i];
}
}
#if 0
if(ioctl(ai->fn,SNDCTL_DSP_GETFMTS,&fmts) < 0) {
fprintf(stderr,"No");
return -1;
}
if(fmts & AFMT_MU_LAW)
ret |= AUDIO_FORMAT_ULAW_8;
if(fmts & AFMT_S16_NE)
ret |= AUDIO_FORMAT_SIGNED_16;
if(fmts & AFMT_U8)
ret |= AUDIO_FORMAT_UNSIGNED_8;
if(fmts & AFMT_S8)
ret |= AUDIO_FORMAT_SIGNED_8;
if(fmts & AFMT_U16_NE)
ret |= AUDIO_FORMAT_UNSIGNED_16;
if(fmts & AFMT_A_LAW)
ret |= AUDIO_FORMAT_ALAW_8;
#endif
return fmt;
}
int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
{
return write(ai->fn,buf,len);
}
int audio_close(struct audio_info_struct *ai)
{
close (ai->fn);
return 0;
}
void audio_queueflush(struct audio_info_struct *ai)
{
}

View File

@@ -92,7 +92,7 @@ void buffer_sig(int signal, int block)
return;
}
void buffer_loop(struct audio_info_struct *ai, sigset_t *oldsigset)
void buffer_loop(audio_output_t *ao, sigset_t *oldsigset)
{
int bytes;
int my_fd = buffermem->fd[XF_READER];
@@ -104,7 +104,7 @@ void buffer_loop(struct audio_info_struct *ai, sigset_t *oldsigset)
catchsignal (SIGUSR1, catch_usr1);
sigprocmask (SIG_SETMASK, oldsigset, NULL);
if (param.outmode == DECODE_AUDIO) {
if (audio_open(ai) < 0) {
if (ao->open(ao) < 0) {
perror("audio");
exit(1);
}
@@ -119,7 +119,7 @@ void buffer_loop(struct audio_info_struct *ai, sigset_t *oldsigset)
if (intflag) {
intflag = FALSE;
if (param.outmode == DECODE_AUDIO)
audio_queueflush (ai);
ao->flush(ao);
xf->readindex = xf->freeindex;
if (xf->wakeme[XF_WRITER])
xfermem_putcmd(my_fd, XF_CMD_WAKEUP);
@@ -141,11 +141,11 @@ void buffer_loop(struct audio_info_struct *ai, sigset_t *oldsigset)
if (xf->wakeme[XF_WRITER])
xfermem_putcmd(my_fd, XF_CMD_WAKEUP);
if (param.outmode == DECODE_AUDIO) {
audio_close (ai);
ai->rate = xf->buf[0];
ai->channels = xf->buf[1];
ai->format = xf->buf[2];
if (audio_open(ai) < 0) {
ao->close(ao);
ao->rate = xf->buf[0];
ao->channels = xf->buf[1];
ao->format = xf->buf[2];
if (ao->open(ao) < 0) {
perror("audio");
exit(1);
}
@@ -218,7 +218,7 @@ void buffer_loop(struct audio_info_struct *ai, sigset_t *oldsigset)
if (param.outmode == DECODE_FILE)
bytes = write(OutputDescriptor, xf->data + xf->readindex, bytes);
else if (param.outmode == DECODE_AUDIO)
bytes = audio_play_samples(ai,
bytes = ao->write(ao,
(unsigned char *) (xf->data + xf->readindex), bytes);
if(bytes < 0) {
@@ -246,7 +246,7 @@ void buffer_loop(struct audio_info_struct *ai, sigset_t *oldsigset)
}
if (param.outmode == DECODE_AUDIO)
audio_close (ai);
ao->close(ao);
}
#endif

View File

@@ -104,24 +104,24 @@ static int decode_header(struct frame *fr,unsigned long newhead);
#ifdef GAPLESS
/* take into account: channels, bytes per sample, resampling (integer samples!) */
unsigned long samples_to_bytes(unsigned long s, struct frame *fr , struct audio_info_struct* ai)
unsigned long samples_to_bytes(unsigned long s, struct frame *fr , audio_output_t *ao)
{
/* rounding positive number... */
double sammy, samf;
sammy = (1.0*s) * (1.0*ai->rate)/freqs[fr->sampling_frequency];
debug4("%lu samples to bytes with freq %li (ai.rate %li); sammy %f", s, freqs[fr->sampling_frequency], ai->rate, sammy);
sammy = (1.0*s) * (1.0*ao->rate)/freqs[fr->sampling_frequency];
debug4("%lu samples to bytes with freq %li (ai.rate %li); sammy %f", s, freqs[fr->sampling_frequency], ao->rate, sammy);
samf = floor(sammy);
return (unsigned long)
(((ai->format & AUDIO_FORMAT_MASK) == AUDIO_FORMAT_16) ? 2 : 1)
(((ao->format & AUDIO_FORMAT_MASK) == AUDIO_FORMAT_16) ? 2 : 1)
#ifdef FLOATOUT
* 2
#endif
* ai->channels
* ao->channels
* (int) (((sammy - samf) < 0.5) ? samf : ( sammy-samf > 0.5 ? samf+1 : ((unsigned long) samf % 2 == 0 ? samf : samf + 1)));
}
#endif
void audio_flush(int outmode, struct audio_info_struct *ai)
void audio_flush(int outmode, audio_output_t *ao)
{
/* the gapless code is not in effect for buffered mode... as then condition for audio_flush is never met */
#ifdef GAPLESS
@@ -135,7 +135,7 @@ void audio_flush(int outmode, struct audio_info_struct *ai)
write (OutputDescriptor, pcm_sample, pcm_point);
break;
case DECODE_AUDIO:
audio_play_samples (ai, pcm_sample, pcm_point);
ao->write(ao, pcm_sample, pcm_point);
break;
case DECODE_BUFFER:
error("The buffer doesn't work like that... I shouldn't ever be getting here.");
@@ -452,7 +452,8 @@ init_resync:
}
else if (give_note)
{
fprintf(stderr,"Note: Illegal Audio-MPEG-Header 0x%08lx at offset 0x%lx.\n", newhead,rd->tell(rd)-4);
fprintf(stderr,"Note: Illegal Audio-MPEG-Header 0x%08lx at offset 0x%lx.\n",
newhead, (long unsigned int)rd->tell(rd)-4);
}
if(give_note && (newhead & 0xffffff00) == ('b'<<24)+('m'<<16)+('p'<<8)) fprintf(stderr,"Note: Could be a BMP album art.\n");
@@ -1183,7 +1184,7 @@ long compute_buffer_offset(struct frame *fr)
}
/* Way too many parameters - heck, this fr and ai is always the same! */
int position_info(struct frame* fr, unsigned long no, long buffsize, struct audio_info_struct* ai,
int position_info(struct frame* fr, unsigned long no, long buffsize, audio_output_t *ao,
unsigned long* frames_left, double* current_seconds, double* seconds_left)
{
double tpf;
@@ -1212,9 +1213,9 @@ int position_info(struct frame* fr, unsigned long no, long buffsize, struct audi
#endif
tpf = compute_tpf(fr);
if(buffsize > 0 && ai && ai->rate > 0 && ai->channels > 0) {
dt = (double) buffsize / ai->rate / ai->channels;
if( (ai->format & AUDIO_FORMAT_MASK) == AUDIO_FORMAT_16)
if(buffsize > 0 && ao && ao->rate > 0 && ao->channels > 0) {
dt = (double) buffsize / ao->rate / ao->channels;
if( (ao->format & AUDIO_FORMAT_MASK) == AUDIO_FORMAT_16)
dt *= 0.5;
}
@@ -1267,11 +1268,11 @@ unsigned int roundui(double val)
return (unsigned int) ((val-base) < 0.5 ? base : base + 1 );
}
void print_stat(struct frame *fr,unsigned long no,long buffsize,struct audio_info_struct *ai)
void print_stat(struct frame *fr, unsigned long no, long buffsize, audio_output_t *ao)
{
double tim1,tim2;
unsigned long rno;
if(!position_info(fr, no, buffsize, ai, &rno, &tim1, &tim2))
if(!position_info(fr, no, buffsize, ao, &rno, &tim1, &tim2))
{
/* All these sprintf... only to avoid two writes to stderr in case of using buffer?
I guess we can drop that. */

View File

@@ -61,7 +61,7 @@ extern struct bitstream_info bsi;
#define DECODER_DELAY 529
#ifdef GAPLESS
unsigned long samples_to_bytes(unsigned long s, struct frame *fr , struct audio_info_struct* ai);
unsigned long samples_to_bytes(unsigned long s, struct frame *fr, audio_output_t* ao);
/* samples per frame ...
Layer I
Layer II
@@ -89,7 +89,7 @@ extern const char* remote_header_help;
void print_remote_header(struct frame* fr);
void generic_sendmsg (const char *fmt, ...);
int position_info(struct frame* fr, unsigned long no, long buffsize, struct audio_info_struct* ai,
int position_info(struct frame* fr, unsigned long no, long buffsize, audio_output_t *ao,
unsigned long* frames_left, double* current_seconds, double* seconds_left);
int read_frame_recover(struct frame* fr);
@@ -99,7 +99,7 @@ void print_frame_index(FILE* out);
#endif
void print_stat(struct frame *fr,unsigned long no,long buffsize,struct audio_info_struct *ai);
void print_stat(struct frame *fr,unsigned long no,long buffsize,audio_output_t *ao);
void clear_stat();
/* rva data, used in common.c, set in id3.c */

View File

@@ -25,13 +25,13 @@
#include "icy.h"
#ifdef GAPLESS
#include "layer3.h"
extern struct audio_info_struct pre_ai;
extern audio_output_t pre_ao;
#endif
#define MODE_STOPPED 0
#define MODE_PLAYING 1
#define MODE_PAUSED 2
extern struct audio_info_struct ai;
extern audio_output_t ao;
extern int buffer_pid;
#ifdef FIFO
#include <sys/stat.h>
@@ -55,7 +55,7 @@ void generic_sendstat (struct frame *fr)
{
unsigned long frames_left;
double current_seconds, seconds_left;
if(!position_info(fr, fr->num, xfermem_get_usedspace(buffermem), &ai, &frames_left, &current_seconds, &seconds_left))
if(!position_info(fr, fr->num, xfermem_get_usedspace(buffermem), &ao, &frames_left, &current_seconds, &seconds_left))
generic_sendmsg("F %li %lu %3.2f %3.2f", fr->num, frames_left, current_seconds, seconds_left);
}
@@ -148,7 +148,7 @@ int control_generic (struct frame *fr)
if (n == 0) {
if (!read_frame(fr)) {
mode = MODE_STOPPED;
audio_flush(param.outmode, &ai);
audio_flush(param.outmode, &ao);
rd->close(rd);
generic_sendmsg("P 0");
continue;
@@ -156,7 +156,7 @@ int control_generic (struct frame *fr)
if(!play_frame(init,fr))
{
generic_sendmsg("E play_frame failed");
audio_flush(param.outmode, &ai);
audio_flush(param.outmode, &ao);
rd->close(rd);
mode = MODE_STOPPED;
generic_sendmsg("P 0");
@@ -247,7 +247,7 @@ int control_generic (struct frame *fr)
{
if (mode == MODE_PLAYING) {
mode = MODE_PAUSED;
audio_flush(param.outmode, &ai);
audio_flush(param.outmode, &ao);
buffer_stop();
generic_sendmsg("P 1");
} else {
@@ -262,7 +262,7 @@ int control_generic (struct frame *fr)
/* STOP */
if (!strcasecmp(comstr, "S") || !strcasecmp(comstr, "STOP")) {
if (mode != MODE_STOPPED) {
audio_flush(param.outmode, &ai);
audio_flush(param.outmode, &ao);
rd->close(rd);
mode = MODE_STOPPED;
generic_sendmsg("P 0");
@@ -360,7 +360,7 @@ int control_generic (struct frame *fr)
char *spos;
long offset;
double secs;
audio_flush(param.outmode, &ai);
audio_flush(param.outmode, &ao);
spos = arg;
if (!spos)
@@ -404,9 +404,9 @@ int control_generic (struct frame *fr)
#ifdef GAPLESS
if(param.gapless && (fr->lay == 3))
{
prepare_audioinfo(fr, &pre_ai);
layer3_gapless_set_position(fr->num, fr, &pre_ai);
layer3_gapless_set_ignore(frame_before, fr, &pre_ai);
prepare_audioinfo(fr, &pre_ao);
layer3_gapless_set_position(fr->num, fr, &pre_ao);
layer3_gapless_set_ignore(frame_before, fr, &pre_ao);
}
#endif
@@ -521,13 +521,13 @@ int control_generic (struct frame *fr)
xfermem_done(buffermem);
} else {
#endif
audio_flush(param.outmode, &ai);
audio_flush(param.outmode, &ao);
free(pcm_sample);
#ifndef NOXFERMEM
}
#endif
if (param.outmode == DECODE_AUDIO)
audio_close(&ai);
ao.close(&ao);
if (param.outmode == DECODE_WAV)
wav_close();

View File

@@ -115,7 +115,7 @@ void I_step_two(real fraction[2][SBLIMIT],unsigned int balloc[2*SBLIMIT],
}
}
int do_layer1(struct frame *fr,int outmode,struct audio_info_struct *ai)
int do_layer1(struct frame *fr,int outmode,audio_output_t *ao)
{
int clip=0;
int i,stereo = fr->stereo;
@@ -146,7 +146,7 @@ int do_layer1(struct frame *fr,int outmode,struct audio_info_struct *ai)
}
if(pcm_point >= audiobufsize)
audio_flush(outmode,ai);
audio_flush(outmode,ao);
}
return clip;

View File

@@ -275,7 +275,7 @@ static void II_select_table(struct frame *fr)
}
int do_layer2(struct frame *fr,int outmode,struct audio_info_struct *ai)
int do_layer2(struct frame *fr,int outmode,audio_output_t *ao)
{
int clip=0;
int i,j;
@@ -315,7 +315,7 @@ int do_layer2(struct frame *fr,int outmode,struct audio_info_struct *ai)
}
if(pcm_point >= audiobufsize)
audio_flush(outmode,ai);
audio_flush(outmode,ao);
}
}

View File

@@ -123,27 +123,27 @@ void layer3_gapless_init(unsigned long b, unsigned long e)
debug2("layer3_gapless_init: from %lu to %lu samples", begin, end);
}
void layer3_gapless_set_position(unsigned long frames, struct frame* fr, struct audio_info_struct *ai)
void layer3_gapless_set_position(unsigned long frames, struct frame* fr, audio_output_t *ao)
{
position = samples_to_bytes(frames*spf(fr), fr, ai);
position = samples_to_bytes(frames*spf(fr), fr, ao);
debug1("set; position now %lu", position);
}
void layer3_gapless_bytify(struct frame *fr, struct audio_info_struct *ai)
void layer3_gapless_bytify(struct frame *fr, audio_output_t *ao)
{
if(!bytified)
{
begin = samples_to_bytes(begin, fr, ai);
end = samples_to_bytes(end, fr, ai);
begin = samples_to_bytes(begin, fr, ao);
end = samples_to_bytes(end, fr, ao);
bytified = 1;
debug2("bytified: begin=%lu; end=%5lu", begin, end);
}
}
/* I need initialized fr here! */
void layer3_gapless_set_ignore(unsigned long frames, struct frame *fr, struct audio_info_struct *ai)
void layer3_gapless_set_ignore(unsigned long frames, struct frame *fr, audio_output_t *ao)
{
ignore = samples_to_bytes(frames*spf(fr), fr, ai);
ignore = samples_to_bytes(frames*spf(fr), fr, ao);
}
/*
@@ -1773,7 +1773,7 @@ static void III_hybrid(real fsIn[SBLIMIT][SSLIMIT], real tsOut[SSLIMIT][SBLIMIT]
/*
* main layer3 handler
*/
int do_layer3(struct frame *fr,int outmode,struct audio_info_struct *ai)
int do_layer3(struct frame *fr,int outmode,audio_output_t *ao)
{
int gr, ch, ss,clip=0;
int scalefacs[2][39]; /* max 39 for short[13][3] mode, mixed: 38, long: 22 */
@@ -1916,7 +1916,7 @@ int do_layer3(struct frame *fr,int outmode,struct audio_info_struct *ai)
else
playlimit -= 128;
#endif
if(pcm_point >= audiobufsize) audio_flush(outmode,ai);
if(pcm_point >= audiobufsize) audio_flush(outmode,ao);
}
#ifdef OPT_I486
} else {
@@ -1932,7 +1932,7 @@ int do_layer3(struct frame *fr,int outmode,struct audio_info_struct *ai)
ss+=n;
pcm_point+=(2*2*32)*n;
if(pcm_point >= audiobufsize) audio_flush(outmode,ai);
if(pcm_point >= audiobufsize) audio_flush(outmode,ao);
}
}
#endif

View File

@@ -9,9 +9,9 @@
/* init part 1; set start/end in samples_*/
void layer3_gapless_init(unsigned long b, unsigned long e);
/* init part 2; transform to byte addresses with new info */
void layer3_gapless_bytify(struct frame *fr, struct audio_info_struct *ai);
void layer3_gapless_bytify(struct frame *fr, audio_output_t *ao);
/* after some seeking action to a new frame, the decoder needs to know which one is coming next */
void layer3_gapless_set_position(unsigned long frames, struct frame* fr, struct audio_info_struct *ai);
void layer3_gapless_set_ignore(unsigned long frames, struct frame* fr, struct audio_info_struct *ai);
void layer3_gapless_set_position(unsigned long frames, struct frame* fr, audio_output_t *ao);
void layer3_gapless_set_ignore(unsigned long frames, struct frame* fr, audio_output_t *ao);
/* removing the gaps from buffer */
void layer3_gapless_buffercheck();

74
src/legacy_module.c Normal file
View File

@@ -0,0 +1,74 @@
/*
legacy_module.c: dummy interface to modular code loader for legacy build system
copyright 2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://www.mpg123.org
initially written by Nicholas J Humfrey
*/
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "config.h"
#include "debug.h"
#include "module.h"
/* A single module is staticly compiled in for each type */
extern mpg123_module_t mpg123_output_module_info;
/* extern mpg123_module_t mpg123_input_module_info; */
/* Open a module */
mpg123_module_t*
open_module( const char* type, const char* name )
{
mpg123_module_t *mod = NULL;
/* Select the module info structure, based on the desired type */
if (strcmp(type, "output")==0) {
mod = &mpg123_output_module_info;
/*
} else if (strcmp(type, "input")==0) {
mod = &mpg123_input_module_info;
*/
} else {
error1("Unable to open module type '%s'.", type);
return NULL;
}
/* Check the module compiled in is the module requested */
if (strcmp(name, mod->name)!=0) {
error1("Unable to open requesed module '%s'.", name);
error1("The only available staticly compiled module is '%s'.", mod->name);
return NULL;
}
// Debugging info
debug1("Details of static module type '%s':", type);
debug1(" api_version=%d", mod->api_version);
debug1(" name=%s", mod->name);
debug1(" description=%s", mod->description);
debug1(" revision=%s", mod->revision);
debug1(" handle=%x", (unsigned int)mod->handle);
return mod;
}
void close_module( mpg123_module_t* module )
{
debug("close_module()");
/* Module was never really 'loaded', so nothing to do here. */
}
void list_modules()
{
debug("list_modules()" );
}

170
src/module.c Normal file
View File

@@ -0,0 +1,170 @@
/*
module.c: modular code loader
copyright 1995-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.de
initially written by Nicholas J Humfrey
*/
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "config.h"
#include "debug.h"
#include "module.h"
#ifndef HAVE_LTDL
#error Cannot build without LTDL library support
#endif
#define MODULE_FILE_SUFFIX ".la"
#define MODULE_SYMBOL_PREFIX "mpg123_"
#define MODULE_SYMBOL_SUFFIX "_module_info"
/* Open a module */
mpg123_module_t*
open_module( const char* type, const char* name )
{
lt_dlhandle handle = NULL;
mpg123_module_t *module = NULL;
char* module_name = strdup( name );
char* module_path = NULL;
int module_path_len = 0;
char* module_symbol = NULL;
int module_symbol_len = 0;
int i;
/* Initialize libltdl */
if (lt_dlinit()) error( "Failed to initialise libltdl" );
/* Clean up the module name to prevent loading random files */
for(i=0; i<strlen(module_name); i++) {
if (!isalnum(module_name[i])) module_name[i] = '_';
}
/* Work out the path of the module to open */
module_path_len = strlen( PKGLIBDIR ) + 1 +
strlen( type ) + 1 + strlen( module_name ) +
strlen( MODULE_FILE_SUFFIX ) + 1;
module_path = malloc( module_path_len );
if (module_path == NULL) {
error1( "Failed to allocate memory for module name: %s", strerror(errno) );
return NULL;
}
snprintf( module_path, module_path_len, "%s/%s_%s%s", PKGLIBDIR, type, module_name, MODULE_FILE_SUFFIX );
/* Display the path of the module created */
debug1( "Module path: %s", module_path );
/* Open the module */
handle = lt_dlopen( module_path );
free( module_path );
free( module_name );
if (handle==NULL) {
error1( "Failed to open module: %s", lt_dlerror() );
return NULL;
}
/* Work out the symbol name */
module_symbol_len = strlen( MODULE_SYMBOL_PREFIX ) +
strlen( type ) +
strlen( MODULE_SYMBOL_SUFFIX ) + 1;
module_symbol = malloc( module_path_len );
snprintf( module_symbol, module_symbol_len, "%s%s%s", MODULE_SYMBOL_PREFIX, type, MODULE_SYMBOL_SUFFIX );
debug1( "Module symbol: %s", module_symbol );
/* Get the information structure from the module */
module = (mpg123_module_t*)lt_dlsym(handle, module_symbol );
if (module==NULL) {
error1( "Failed to get module symbol: %s", lt_dlerror() );
lt_dlclose( handle );
return NULL;
}
free( module_symbol );
/* Store handle in the data structure */
module->handle = handle;
return module;
}
void close_module( mpg123_module_t* module )
{
lt_dlhandle handle = module->handle;
int err = lt_dlclose( handle );
if (err) error1("Failed to close module: %s", lt_dlerror() );
}
void list_modules()
{
DIR* dir = NULL;
struct dirent *dp = NULL;
/* Open the module directory */
dir = opendir( PKGLIBDIR );
if (dir==NULL) {
error2("Failed to open the module directory (%s): %s\n", PKGLIBDIR, strerror(errno));
exit(-1);
}
/* Display the program title */
/* print_title(stderr); */
/* List the output modules */
printf("\n");
printf("Available modules\n");
printf("-----------------\n");
while( (dp = readdir(dir)) != NULL ) {
if (dp->d_type == DT_REG) {
char* ext = dp->d_name + strlen( dp->d_name ) - strlen( MODULE_FILE_SUFFIX );
if (strcmp(ext, MODULE_FILE_SUFFIX) == 0)
{
char *module_name = NULL;
char *module_type = NULL;
char *uscore_pos = NULL;
mpg123_module_t *module = NULL;
/* Extract the module type */
module_type = strdup( dp->d_name );
uscore_pos = strchr( module_type, '_' );
if (uscore_pos==NULL) continue;
if (uscore_pos>=module_type+strlen(module_type)+1) continue;
*uscore_pos = '\0';
/* Extract the short name of the module */
module_name = strdup( dp->d_name + strlen( module_type ) + 1 );
module_name[ strlen( module_name ) - strlen( MODULE_FILE_SUFFIX ) ] = '\0';
/* Open the module */
module = open_module( module_type, module_name );
if (module) {
printf("%-15s%s %s\n", module->name, module_type, module->description );
/* Close the module again */
close_module( module );
}
free( module_name );
}
}
}
closedir( dir );
exit(0);
}

48
src/module.h Normal file
View File

@@ -0,0 +1,48 @@
/*
module: module loading and listing interface
copyright ?-2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.de
*/
#include "config.h"
#ifndef _MPG123_MODULE_H_
#define _MPG123_MODULE_H_
#ifdef HAVE_LTDL
#include <ltdl.h>
#endif
#define MPG123_MODULE_API_VERSION (1)
/* The full structure is delared in audio.h */
struct audio_output_struct;
typedef struct mpg123_module_struct {
const int api_version; /* module API version number */
const char* name; /* short name of the module */
const char* description; /* description of what the module does */
const char* revision; /* source code revision */
#ifdef HAVE_LTDL
lt_dlhandle handle; /* ltdl handle - set by open_module */
#else
void* handle;
#endif
/* Initialisers - set to NULL if unsupported by module */
int (*init_output)(struct audio_output_struct* ao); /* audio output - returns 0 on success */
} mpg123_module_t;
/* ------ Declarations from "module.c" ------ */
mpg123_module_t* open_module( const char* type, const char* name );
void close_module( mpg123_module_t* module );
void list_modules();
#endif

View File

@@ -68,6 +68,8 @@ struct parameter param = {
0 , /* second level buffer size */
TRUE , /* resync after stream error */
0 , /* verbose level */
DEFAULT_OUTPUT_MODULE, /* output module */
NULL, /* output device */
#ifdef HAVE_TERMIOS
FALSE , /* term control */
#endif
@@ -124,7 +126,6 @@ int buffer_fd[2];
int buffer_pid;
static int intflag = FALSE;
int OutputDescriptor;
/* A safe realloc also for very old systems where realloc(NULL, size) returns NULL. */
@@ -145,13 +146,6 @@ const char *strerror(int errnum)
#endif
#if !defined(WIN32) && !defined(GENERIC)
#ifndef NOXFERMEM
static void catch_child(void)
{
while (waitpid(-1, NULL, WNOHANG) > 0);
}
#endif
static void catch_interrupt(void)
{
intflag = TRUE;
@@ -173,116 +167,37 @@ void safe_exit(int code)
exit(code);
}
audio_output_t *ao = NULL;
audio_output_t pre_ao;
static struct frame fr;
struct audio_info_struct ai,pre_ai;
txfermem *buffermem = NULL;
#define FRAMEBUFUNIT (18 * 64 * 4)
void set_synth_functions(struct frame *fr);
void init_output(void)
{
static int init_done = FALSE;
if (init_done)
return;
init_done = TRUE;
#ifndef NOXFERMEM
/*
* Only DECODE_AUDIO and DECODE_FILE are sanely handled by the
* buffer process. For now, we just ignore the request
* to buffer the output. [dk]
*/
if (param.usebuffer && (param.outmode != DECODE_AUDIO) &&
(param.outmode != DECODE_FILE)) {
fprintf(stderr, "Sorry, won't buffer output unless writing plain audio.\n");
param.usebuffer = 0;
}
if (param.usebuffer) {
unsigned int bufferbytes;
sigset_t newsigset, oldsigset;
if (param.usebuffer < 32)
param.usebuffer = 32; /* minimum is 32 Kbytes! */
bufferbytes = (param.usebuffer * 1024);
bufferbytes -= bufferbytes % FRAMEBUFUNIT;
/* +1024 for NtoM rounding problems */
xfermem_init (&buffermem, bufferbytes ,0,1024);
pcm_sample = (unsigned char *) buffermem->data;
pcm_point = 0;
sigemptyset (&newsigset);
sigaddset (&newsigset, SIGUSR1);
sigprocmask (SIG_BLOCK, &newsigset, &oldsigset);
#if !defined(WIN32) && !defined(GENERIC)
catchsignal (SIGCHLD, catch_child);
#endif
switch ((buffer_pid = fork())) {
case -1: /* error */
perror("fork()");
safe_exit(1);
case 0: /* child */
if(rd)
rd->close(rd); /* child doesn't need the input stream */
xfermem_init_reader (buffermem);
buffer_loop (&ai, &oldsigset);
xfermem_done_reader (buffermem);
xfermem_done (buffermem);
exit(0);
default: /* parent */
xfermem_init_writer (buffermem);
param.outmode = DECODE_BUFFER;
}
}
else {
#endif
/* + 1024 for NtoM rate converter */
if (!(pcm_sample = (unsigned char *) malloc(audiobufsize * 2 + 1024))) {
perror ("malloc()");
safe_exit (1);
#ifndef NOXFERMEM
}
#endif
}
switch(param.outmode) {
case DECODE_AUDIO:
if(audio_open(&ai) < 0) {
perror("audio");
safe_exit(1);
}
break;
case DECODE_WAV:
wav_open(&ai,param.filename);
break;
case DECODE_AU:
au_open(&ai,param.filename);
break;
case DECODE_CDR:
cdr_open(&ai,param.filename);
break;
}
}
static void set_output_h(char *a)
{
if(ai.output <= 0)
ai.output = AUDIO_OUT_HEADPHONES;
if(ao->output <= 0)
ao->output = AUDIO_OUT_HEADPHONES;
else
ai.output |= AUDIO_OUT_HEADPHONES;
ao->output |= AUDIO_OUT_HEADPHONES;
}
static void set_output_s(char *a)
{
if(ai.output <= 0)
ai.output = AUDIO_OUT_INTERNAL_SPEAKER;
if(ao->output <= 0)
ao->output = AUDIO_OUT_INTERNAL_SPEAKER;
else
ai.output |= AUDIO_OUT_INTERNAL_SPEAKER;
ao->output |= AUDIO_OUT_INTERNAL_SPEAKER;
}
static void set_output_l(char *a)
{
if(ai.output <= 0)
ai.output = AUDIO_OUT_LINE_OUT;
if(ao->output <= 0)
ao->output = AUDIO_OUT_LINE_OUT;
else
ai.output |= AUDIO_OUT_LINE_OUT;
ao->output |= AUDIO_OUT_LINE_OUT;
}
static void set_output (char *arg)
@@ -302,39 +217,44 @@ void set_verbose (char *arg)
{
param.verbose++;
}
void set_wav(char *arg)
static void set_out_wav(char *arg)
{
param.outmode = DECODE_WAV;
strncpy(param.filename,arg,255);
param.filename[255] = 0;
}
void set_cdr(char *arg)
static void set_out_cdr(char *arg)
{
param.outmode = DECODE_CDR;
strncpy(param.filename,arg,255);
param.filename[255] = 0;
}
void set_au(char *arg)
static void set_out_au(char *arg)
{
param.outmode = DECODE_AU;
strncpy(param.filename,arg,255);
param.filename[255] = 0;
}
static void SetOutFile(char *Arg)
static void set_out_file(char *arg)
{
param.outmode=DECODE_FILE;
#ifdef WIN32
OutputDescriptor=_open(Arg,_O_CREAT|_O_WRONLY|_O_BINARY|_O_TRUNC,0666);
OutputDescriptor=_open(arg,_O_CREAT|_O_WRONLY|_O_BINARY|_O_TRUNC,0666);
#else
OutputDescriptor=open(Arg,O_CREAT|O_WRONLY|O_TRUNC,0666);
OutputDescriptor=open(arg,O_CREAT|O_WRONLY|O_TRUNC,0666);
#endif
if(OutputDescriptor==-1)
{
error2("Can't open %s for writing (%s).\n",Arg,strerror(errno));
error2("Can't open %s for writing (%s).\n",arg,strerror(errno));
safe_exit(1);
}
}
static void SetOutStdout(char *Arg)
static void set_out_stdout(char *arg)
{
param.outmode=DECODE_FILE;
param.remote_err=TRUE;
@@ -343,7 +263,8 @@ static void SetOutStdout(char *Arg)
_setmode(STDOUT_FILENO, _O_BINARY);
#endif
}
static void SetOutStdout1(char *Arg)
static void set_out_stdout1(char *arg)
{
param.outmode=DECODE_AUDIOFILE;
param.remote_err=TRUE;
@@ -358,37 +279,40 @@ void realtime_not_compiled(char *arg)
fprintf(stderr,"Option '-T / --realtime' not compiled into this binary.\n");
}
/* Please note: GLO_NUM expects point to LONG! */
/* ThOr:
* Yeah, and despite that numerous addresses to int variables were
passed.
* Yeah, and despite that numerous addresses to int variables were passed.
* That's not good on my Alpha machine with int=32bit and long=64bit!
* Introduced GLO_INT and GLO_LONG as different bits to make that clear.
* GLO_NUM no longer exists.
*/
topt opts[] = {
{'k', "skip", GLO_ARG | GLO_LONG, 0, &startFrame, 0},
{'a', "audiodevice", GLO_ARG | GLO_CHAR, 0, &ai.device, 0},
{'o', "output", GLO_ARG | GLO_CHAR, set_output, NULL, 0},
{0, "list-modules",0, list_modules, NULL, 0},
{'a', "audiodevice", GLO_ARG | GLO_CHAR, 0, &param.output_device, 0},
{'2', "2to1", GLO_INT, 0, &param.down_sample, 1},
{'4', "4to1", GLO_INT, 0, &param.down_sample, 2},
{'t', "test", GLO_INT, 0, &param.outmode, DECODE_TEST},
{'s', "stdout", GLO_INT, SetOutStdout, &param.outmode, DECODE_FILE},
{'S', "STDOUT", GLO_INT, SetOutStdout1, &param.outmode,DECODE_AUDIOFILE},
{'O', "outfile", GLO_ARG | GLO_CHAR, SetOutFile, NULL, 0},
{'s', "stdout", GLO_INT, set_out_stdout, &param.outmode, DECODE_FILE},
{'S', "STDOUT", GLO_INT, set_out_stdout1, &param.outmode,DECODE_AUDIOFILE},
{'O', "outfile", GLO_ARG | GLO_CHAR, set_out_file, NULL, 0},
{'c', "check", GLO_INT, 0, &param.checkrange, TRUE},
{'v', "verbose", 0, set_verbose, 0, 0},
{'q', "quiet", GLO_INT, 0, &param.quiet, TRUE},
{'y', "resync", GLO_INT, 0, &param.tryresync, FALSE},
{'0', "single0", GLO_INT, 0, &param.force_mono, MONO_LEFT},
{0, "left", GLO_INT, 0, &param.force_mono, MONO_LEFT},
{'1', "single1", GLO_INT, 0, &param.force_mono, MONO_RIGHT},
{0, "right", GLO_INT, 0, &param.force_mono, MONO_RIGHT},
{'m', "singlemix", GLO_INT, 0, &param.force_mono, MONO_MIX},
{0, "mix", GLO_INT, 0, &param.force_mono, MONO_MIX},
{0, "mono", GLO_INT, 0, &param.force_mono, MONO_MIX},
{'0', "single0", GLO_INT, 0, &param.force_mono, 0},
{0, "left", GLO_INT, 0, &param.force_mono, 0},
{'1', "single1", GLO_INT, 0, &param.force_mono, 1},
{0, "right", GLO_INT, 0, &param.force_mono, 1},
{'m', "singlemix", GLO_INT, 0, &param.force_mono, 3},
{0, "mix", GLO_INT, 0, &param.force_mono, 3},
{0, "mono", GLO_INT, 0, &param.force_mono, 3},
{0, "stereo", GLO_INT, 0, &param.force_stereo, 1},
{0, "reopen", GLO_INT, 0, &param.force_reopen, 1},
{'g', "gain", GLO_ARG | GLO_LONG, 0, &ai.gain, 0},
/* {'g', "gain", GLO_ARG | GLO_LONG, 0, &ao.gain, 0}, FIXME */
{'r', "rate", GLO_ARG | GLO_LONG, 0, &param.force_rate, 0},
{0, "8bit", GLO_INT, 0, &param.force_8bit, 1},
{0, "headphones", 0, set_output_h, 0,0},
@@ -438,9 +362,9 @@ topt opts[] = {
{'T', "realtime", 0, realtime_not_compiled, 0, 0 },
#endif
{0, "title", GLO_INT, 0, &param.xterm_title, TRUE },
{'w', "wav", GLO_ARG | GLO_CHAR, set_wav, 0 , 0 },
{0, "cdr", GLO_ARG | GLO_CHAR, set_cdr, 0 , 0 },
{0, "au", GLO_ARG | GLO_CHAR, set_au, 0 , 0 },
{'w', "wav", GLO_ARG | GLO_CHAR, set_out_wav, 0, 0 },
{0, "cdr", GLO_ARG | GLO_CHAR, set_out_cdr, 0, 0 },
{0, "au", GLO_ARG | GLO_CHAR, set_out_au, 0, 0 },
#ifdef GAPLESS
{0, "gapless", GLO_INT, 0, &param.gapless, 1},
#endif
@@ -485,22 +409,22 @@ static void reset_audio(void)
buffermem->freeindex = 0;
if (intflag)
return;
buffermem->buf[0] = ai.rate;
buffermem->buf[1] = ai.channels;
buffermem->buf[2] = ai.format;
buffermem->buf[0] = ao->rate;
buffermem->buf[1] = ao->channels;
buffermem->buf[2] = ao->format;
buffer_reset();
}
else
#endif
if (param.outmode == DECODE_AUDIO) {
/* audio_reset_parameters(&ai); */
/* audio_reset_parameters(ao); */
/* close and re-open in order to flush
* the device's internal buffer before
* changing the sample rate. [OF]
*/
audio_close (&ai);
if (audio_open(&ai) < 0) {
perror("audio");
ao->close(ao);
if (ao->open(ao) < 0) {
error("failed to open audio device");
safe_exit(1);
}
}
@@ -511,11 +435,11 @@ static void reset_audio(void)
precog the audio rate that will be set before output begins
this is needed to give gapless code a chance to keep track for firstframe != 0
*/
void prepare_audioinfo(struct frame *fr, struct audio_info_struct *nai)
void prepare_audioinfo(struct frame *fr, audio_output_t *ao)
{
long newrate = freqs[fr->sampling_frequency]>>(param.down_sample);
fr->down_sample = param.down_sample;
if(!audio_fit_capabilities(nai,fr->stereo,newrate)) safe_exit(1);
if(!audio_fit_capabilities(ao,fr->stereo,newrate)) safe_exit(1);
}
/*
@@ -540,22 +464,22 @@ int play_frame(int init,struct frame *fr)
}
if(fr->header_change > 1 || init) {
old_rate = ai.rate;
old_format = ai.format;
old_channels = ai.channels;
old_rate = ao->rate;
old_format = ao->format;
old_channels = ao->channels;
newrate = freqs[fr->sampling_frequency]>>(param.down_sample);
prepare_audioinfo(fr, &ai);
if(param.verbose > 1) fprintf(stderr, "Note: audio output rate = %li\n", ai.rate);
prepare_audioinfo(fr, ao);
if(param.verbose > 1) fprintf(stderr, "Note: audio output rate = %li\n", ao->rate);
#ifdef GAPLESS
if(param.gapless && (fr->lay == 3)) layer3_gapless_bytify(fr, &ai);
if(param.gapless && (fr->lay == 3)) layer3_gapless_bytify(fr, ao);
#endif
/* check, whether the fitter set our proposed rate */
if(ai.rate != newrate) {
if(ai.rate == (newrate>>1) )
if(ao->rate != newrate) {
if(ao->rate == (newrate>>1) )
fr->down_sample++;
else if(ai.rate == (newrate>>2) )
else if(ao->rate == (newrate>>2) )
fr->down_sample+=2;
else {
fr->down_sample = 3;
@@ -574,7 +498,7 @@ int play_frame(int init,struct frame *fr)
case 3:
{
long n = freqs[fr->sampling_frequency];
long m = ai.rate;
long m = ao->rate;
if(!synth_ntom_set_step(n,m)) return 0;
@@ -589,11 +513,14 @@ int play_frame(int init,struct frame *fr)
break;
}
init_output();
if(ai.rate != old_rate || ai.channels != old_channels ||
ai.format != old_format || param.force_reopen) {
if(!param.force_mono) {
if(ai.channels == 1)
if (init_output( ao )) {
safe_exit(-1);
}
if(ao->rate != old_rate || ao->channels != old_channels ||
ao->format != old_format || param.force_reopen) {
if(param.force_mono < 0) {
if(ao->channels == 1)
fr->single = 3;
else
fr->single = -1;
@@ -602,7 +529,7 @@ int play_frame(int init,struct frame *fr)
fr->single = param.force_mono-1;
param.force_stereo &= ~0x2;
if(fr->single >= 0 && ai.channels == 2) {
if(fr->single >= 0 && ao->channels == 2) {
param.force_stereo |= 0x2;
}
@@ -612,7 +539,7 @@ int play_frame(int init,struct frame *fr)
if(param.verbose) {
if(fr->down_sample == 3) {
long n = freqs[fr->sampling_frequency];
long m = ai.rate;
long m = ao->rate;
if(n > m) {
fprintf(stderr,"Audio: %2.4f:1 conversion,",(float)n/(float)m);
}
@@ -623,7 +550,7 @@ int play_frame(int init,struct frame *fr)
else {
fprintf(stderr,"Audio: %ld:1 conversion,",(long)pow(2.0,fr->down_sample));
}
fprintf(stderr," rate: %ld, encoding: %s, channels: %d\n",ai.rate,audio_encoding_name(ai.format),ai.channels);
fprintf(stderr," rate: %ld, encoding: %s, channels: %d\n",ao->rate,audio_encoding_name(ao->format),ao->channels);
}
}
if (intflag)
@@ -636,7 +563,7 @@ int play_frame(int init,struct frame *fr)
}
/* do the decoding */
clip = (fr->do_layer)(fr,param.outmode,&ai);
clip = (fr->do_layer)(fr,param.outmode,ao);
#ifndef NOXFERMEM
if (param.usebuffer) {
@@ -705,13 +632,13 @@ void set_synth_functions(struct frame *fr)
funcs_mono[1][0][0] = opt_synth_1to1_mono;
funcs_mono[1][1][0] = opt_synth_1to1_8bit_mono;
if((ai.format & AUDIO_FORMAT_MASK) == AUDIO_FORMAT_8)
if((ao->format & AUDIO_FORMAT_MASK) == AUDIO_FORMAT_8)
p8 = 1;
fr->synth = funcs[p8][ds];
fr->synth_mono = funcs_mono[ai.channels==2 ? 0 : 1][p8][ds];
fr->synth_mono = funcs_mono[param.force_stereo?0:1][p8][ds];
if(p8) {
if(make_conv16to8_table(ai.format) != 0)
if(make_conv16to8_table(ao->format) != 0)
{
/* it's a bit more work to get proper error propagation up */
safe_exit(1);
@@ -747,7 +674,6 @@ int main(int argc, char *argv[])
(prgName = strrchr(argv[0], '/')) ? prgName++ : (prgName = argv[0]);
audio_info_struct_init(&ai);
while ((result = getlopt(argc, argv, opts)))
switch (result) {
@@ -811,11 +737,21 @@ int main(int argc, char *argv[])
}
if(param.force_rate && param.down_sample) {
fprintf(stderr,"Down sampling and fixed rate options not allowed together!\n");
error("Down sampling and fixed rate options not allowed together!");
safe_exit(1);
}
audio_capabilities(&ai);
/* Open audio output module */
ao = open_output_module( param.output_module );
if (!ao) {
error("Failed to open audio output module.");
safe_exit(1);
}
audio_capabilities(ao);
/* equalizer initialization regardless of equalfile */
for(j=0; j<32; j++) {
equalizer[0][j] = equalizer[1][j] = 1.0;
@@ -960,11 +896,11 @@ tc_hack:
{
if(pre_init)
{
prepare_audioinfo(&fr, &pre_ai);
prepare_audioinfo(&fr, &pre_ao);
pre_init = 0;
}
/* keep track... */
layer3_gapless_set_position(fr.num, &fr, &pre_ai);
layer3_gapless_set_position(fr.num, &fr, &pre_ao);
}
#endif
}
@@ -982,12 +918,12 @@ tc_hack:
if(param.verbose) {
#ifndef NOXFERMEM
if (param.verbose > 1 || !(fr.num & 0x7))
print_stat(&fr,fr.num,xfermem_get_usedspace(buffermem),&ai);
print_stat(&fr,fr.num,xfermem_get_usedspace(buffermem),ao);
if(param.verbose > 2 && param.usebuffer)
fprintf(stderr,"[%08x %08x]",buffermem->readindex,buffermem->freeindex);
#else
if (param.verbose > 1 || !(fr.num & 0x7))
print_stat(&fr,fr.num,0,&ai);
print_stat(&fr,fr.num,0,ao);
#endif
}
#ifdef HAVE_TERMIOS
@@ -995,12 +931,12 @@ tc_hack:
continue;
} else {
long offset;
if((offset=term_control(&fr,&ai))) {
if((offset=term_control(&fr,ao))) {
if(!rd->back_frame(rd, &fr, -offset)) {
debug1("seeked to %lu", fr.num);
#ifdef GAPLESS
if(param.gapless && (fr.lay == 3))
layer3_gapless_set_position(fr.num, &fr, &ai);
layer3_gapless_set_position(fr.num, &fr, ao);
#endif
} else { error("seek failed!"); }
}
@@ -1010,7 +946,7 @@ tc_hack:
}
#ifdef GAPLESS
/* make sure that the correct padding is skipped after track ended */
if(param.gapless) audio_flush(param.outmode, &ai);
if(param.gapless) audio_flush(param.outmode, ao);
#endif
#ifndef NOXFERMEM
@@ -1022,18 +958,18 @@ tc_hack:
buffer_ignore_lowmem();
if(param.verbose)
print_stat(&fr,fr.num,s,&ai);
print_stat(&fr,fr.num,s,ao);
#ifdef HAVE_TERMIOS
if(param.term_ctrl) {
long offset;
if((offset=term_control(&fr,&ai))) {
if((offset=term_control(&fr,ao))) {
if((!rd->back_frame(rd, &fr, -offset))
&& read_frame(&fr))
{
debug1("seeked to %lu", fr.num);
#ifdef GAPLESS
if(param.gapless && (fr.lay == 3))
layer3_gapless_set_position(fr.num, &fr, &ai);
layer3_gapless_set_position(fr.num, &fr, ao);
#endif
goto tc_hack; /* Doh! Gag me with a spoon! */
} else { error("seek failed!"); }
@@ -1045,7 +981,7 @@ tc_hack:
}
#endif
if(param.verbose)
print_stat(&fr,fr.num,xfermem_get_usedspace(buffermem),&ai);
print_stat(&fr,fr.num,xfermem_get_usedspace(buffermem),ao);
#ifdef HAVE_TERMIOS
if(param.term_ctrl)
term_restore();
@@ -1112,7 +1048,7 @@ tc_hack:
}
else {
#endif
audio_flush(param.outmode, &ai);
audio_flush(param.outmode, ao);
free (pcm_sample);
#ifndef NOXFERMEM
}
@@ -1120,7 +1056,7 @@ tc_hack:
switch(param.outmode) {
case DECODE_AUDIO:
audio_close(&ai);
ao->close(ao);
break;
case DECODE_WAV:
wav_close();
@@ -1222,6 +1158,8 @@ static void long_usage(int err)
fprintf(o," -Z --random full random play\n");
fprintf(o,"\noutput/processing options\n\n");
fprintf(o," -o <o> --output <o> select audio output module\n");
fprintf(o," --list-modules list the available modules\n");
fprintf(o," -a <d> --audiodevice <d> select audio device\n");
fprintf(o," -s --stdout write raw audio to stdout (host native format)\n");
fprintf(o," -S --STDOUT play AND output stream (not implemented yet)\n");

View File

@@ -118,6 +118,7 @@ typedef unsigned char byte;
# define REAL_MUL(x, y) ((x) * (y))
#endif
#include "module.h"
#include "audio.h"
/* AUDIOBUFSIZE = n*64 with n=1,2,3 ... */
@@ -171,7 +172,7 @@ struct frame {
int down_sample;
int header_change;
int lay;
int (*do_layer)(struct frame *fr,int,struct audio_info_struct *);
int (*do_layer)(struct frame *fr,int,audio_output_t *);
int error_protection;
int bitrate_index;
int sampling_frequency;
@@ -187,6 +188,9 @@ struct frame {
unsigned long num; /* the nth frame in some stream... */
};
#define FRAMEBUFUNIT (18 * 64 * 4)
#define VERBOSE_MAX 3
#define MONO_LEFT 1
@@ -204,6 +208,8 @@ struct parameter {
long usebuffer; /* second level buffer size */
int tryresync; /* resync stream after error */
int verbose; /* verbose level */
char* output_module; /* audio output module to use */
char* output_device; /* audio output device to use */
#ifdef HAVE_TERMIOS
int term_ctrl;
#endif
@@ -279,12 +285,12 @@ extern int buffer_fd[2];
extern txfermem *buffermem;
#ifndef NOXFERMEM
extern void buffer_loop(struct audio_info_struct *ai,sigset_t *oldsigset);
extern void buffer_loop(audio_output_t *ao,sigset_t *oldsigset);
#endif
/* ------ Declarations from "common.c" ------ */
extern void audio_flush(int, struct audio_info_struct *);
extern void audio_flush(int, audio_output_t *);
extern void (*catchsignal(int signum, void(*handler)()))();
extern void print_header(struct frame *);
@@ -305,6 +311,7 @@ extern void set_pointer(long);
extern unsigned char *pcm_sample;
extern int pcm_point;
extern int audiobufsize;
extern int buffer_pid;
extern int OutputDescriptor;
@@ -347,11 +354,11 @@ extern int open_stream(char *,int fd);
extern void read_frame_init (struct frame* fr);
extern int read_frame(struct frame *fr);
/* why extern? */
void prepare_audioinfo(struct frame *fr, struct audio_info_struct *nai);
extern void prepare_audioinfo(struct frame *fr, audio_output_t *ao);
extern int play_frame(int init,struct frame *fr);
extern int do_layer3(struct frame *fr,int,struct audio_info_struct *);
extern int do_layer2(struct frame *fr,int,struct audio_info_struct *);
extern int do_layer1(struct frame *fr,int,struct audio_info_struct *);
extern int do_layer3(struct frame *fr,int,audio_output_t *);
extern int do_layer2(struct frame *fr,int,audio_output_t *);
extern int do_layer1(struct frame *fr,int,audio_output_t *);
extern void do_equalizer(real *bandPtr,int channel);
/* synth_1to1 in optimize.h, one should also use opts for these here... */
@@ -392,18 +399,18 @@ extern int synth_ntom_set_step(long,long);
extern int control_generic(struct frame *fr);
extern int cdr_open(struct audio_info_struct *ai, char *ame);
extern int au_open(struct audio_info_struct *ai, char *name);
extern int wav_open(struct audio_info_struct *ai, char *wavfilename);
extern int cdr_open(audio_output_t *, char *ame);
extern int au_open(audio_output_t *, char *name);
extern int wav_open(audio_output_t *, char *wavfilename);
extern int wav_write(unsigned char *buf,int len);
extern int cdr_close(void);
extern int au_close(void);
extern int wav_close(void);
extern int au_open(struct audio_info_struct *ai, char *aufilename);
extern int au_open(audio_output_t *, char *aufilename);
extern int au_close(void);
extern int cdr_open(struct audio_info_struct *ai, char *cdrfilename);
extern int cdr_open(audio_output_t *, char *cdrfilename);
extern int cdr_close(void);
extern unsigned char *conv16to8;
@@ -414,7 +421,7 @@ extern real equalizer[2][32];
extern real equalizer_sum[2][32];
extern int equalizer_cnt;
extern struct audio_name audio_val2name[];
extern struct audio_format_name audio_val2name[];
extern struct parameter param;

126
src/output/Makefile.am Normal file
View File

@@ -0,0 +1,126 @@
## Makefile.am: produce Makefile.in from this
## copyright by the mpg123 project - free software under the terms of the LGPL 2.1
## see COPYING and AUTHORS files in distribution or http://www.mpg123.org
## initially written by Nicholas J. Humfrey
pkglib_LTLIBRARIES = output_dummy.la
output_dummy_la_SOURCES = dummy.c
output_dummy_la_LDFLAGS = -module -avoid-version
#if HAVE_AIX
#pkglib_LTLIBRARIES += output_aix.la
#output_aix_la_SOURCES = aix.c
#output_aix_la_LDFLAGS = -module -avoid-version
#endif
#if HAVE_ALIB
#pkglib_LTLIBRARIES += output_alib.la
#output_alib_la_SOURCES = alib.c
#output_alib_la_LDFLAGS = -module -avoid-version
#endif
if HAVE_ALSA
pkglib_LTLIBRARIES += output_alsa.la
output_alsa_la_SOURCES = alsa.c
output_alsa_la_LDFLAGS = -module -avoid-version
output_alsa_la_LIBADD = -lasound
endif
if HAVE_COREAUDIO
pkglib_LTLIBRARIES += output_coreaudio.la
output_coreaudio_la_SOURCES = coreaudio.c
output_coreaudio_la_LDFLAGS = -module -avoid-version \
-framework AudioToolbox \
-framework AudioUnit \
-framework CoreServices
endif
if HAVE_ESOUND
pkglib_LTLIBRARIES += output_esound.la
output_esound_la_SOURCES = esd.c
output_esound_la_CFLAGS = @ESOUND_CFLAGS@
output_esound_la_LDFLAGS = -module -avoid-version @ESOUND_LDFLAGS@
output_esound_la_LIBADD = @ESOUND_LIBS@
endif
#if HAVE_HP
#pkglib_LTLIBRARIES += output_hp.la
#output_hp_la_SOURCES = hp.c
#output_hp_la_LDFLAGS = -module -avoid-version
#endif
if HAVE_JACK
pkglib_LTLIBRARIES += output_jack.la
output_jack_la_SOURCES = jack.c
output_jack_la_CFLAGS = @JACK_CFLAGS@
output_jack_la_LDFLAGS = -module -avoid-version @JACK_LDFLAGS@
output_jack_la_LIBADD = @JACK_LIBS@
endif
#if HAVE_MINT
#pkglib_LTLIBRARIES += output_mint.la
#output_mint_la_SOURCES = mint.c
#output_mint_la_LDFLAGS = -module -avoid-version
#endif
if HAVE_NAS
pkglib_LTLIBRARIES += output_nas.la
output_nas_la_SOURCES = nas.c
output_nas_la_LDFLAGS = -module -avoid-version
output_nas_la_LIBADD = -laudio
endif
#if HAVE_OS2
#pkglib_LTLIBRARIES += output_os2.la
#output_os2_la_SOURCES = os2.c
#output_os2_la_LDFLAGS = -module -avoid-version
#endif
if HAVE_OSS
pkglib_LTLIBRARIES += output_oss.la
output_oss_la_SOURCES = oss.c
output_oss_la_LDFLAGS = -module -avoid-version
endif
if HAVE_PORTAUDIO
pkglib_LTLIBRARIES += output_portaudio.la
output_portaudio_la_SOURCES = portaudio.c
output_portaudio_la_LDFLAGS = -module -avoid-version
output_portaudio_la_LIBADD = -lportaudio
endif
if HAVE_PULSE
pkglib_LTLIBRARIES += output_pulse.la
output_pulse_la_SOURCES = pulse.c
output_pulse_la_CFLAGS = @PULSE_CFLAGS@
output_pulse_la_LDFLAGS = -module -avoid-version @PULSE_LDFLAGS@
output_pulse_la_LIBADD = @PULSE_LIBS@
endif
if HAVE_SDL
pkglib_LTLIBRARIES += output_sdl.la
output_sdl_la_SOURCES = sdl.c
output_sdl_la_CFLAGS = @SDL_CFLAGS@
output_sdl_la_LDFLAGS = -module -avoid-version @SDL_LDFLAGS@
output_sdl_la_LIBADD = @SDL_LIBS@
endif
#if HAVE_SGI
#pkglib_LTLIBRARIES += output_sgi.la
#output_sgi_la_SOURCES = sgi.c
#output_sgi_la_LDFLAGS = -module -avoid-version
#endif
if HAVE_SUN
pkglib_LTLIBRARIES += output_sun.la
output_sun_la_SOURCES = sun.c
output_sun_la_LDFLAGS = -module -avoid-version
endif
#if HAVE_WIN32
#pkglib_LTLIBRARIES += output_win32.la
#output_win32_la_SOURCES = win32.c
#output_win32_la_LDFLAGS = -module -avoid-version
#endif

View File

@@ -1,15 +1,20 @@
/*
audio_aix.c: Driver for IBM RS/6000 with AIX Ultimedia Services
aix: Driver for IBM RS/6000 with AIX Ultimedia Services
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Juergen Schoew and Tomas Oegren
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/audio.h>
#include <stropts.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/param.h>
@@ -21,56 +26,56 @@
/* #define AUDIO_BSIZE AUDIO_IGNORE */
#define AUDIO_BSIZE 200
int audio_rate_best_match(struct audio_info_struct *ai)
int audio_rate_best_match(audio_output_t *ao)
{
static long valid [ ] = { 5510, 6620, 8000, 9600, 11025, 16000, 18900,
22050, 27420, 32000, 33075, 37800, 44100, 48000, 0 };
int i = 0;
long best = 8000;
if(!ai || ai->fn < 0 || ai->rate < 0) {
if(!ai || ao->fn < 0 || ao->rate < 0) {
return -1;
}
while (valid [i])
{
if (abs(valid[i] - ai->rate) < abs(best - ai->rate))
if (abs(valid[i] - ao->rate) < abs(best - ao->rate))
{
best = valid [i];
}
i = i + 1;
}
ai->rate = best;
ao->rate = best;
return best;
}
int audio_open(struct audio_info_struct *ai)
int audio_open(audio_output_t *ao)
{
audio_init ainit;
int ret;
if(!ai->device) {
if(!ao->device) {
if(getenv("AUDIODEV")) {
if(param.verbose > 1)
fprintf(stderr,"Using audio-device value from AUDIODEV environmentvariable!\n");
ai->device = getenv("AUDIODEV");
ai->fn = open(ai->device,O_WRONLY);
ao->device = getenv("AUDIODEV");
ao->fn = open(ao->device,O_WRONLY);
}
else {
ai->device = "/dev/paud0/1"; /* paud0 for PCI */
ai->fn = open(ai->device,O_WRONLY);
if ((ai->fn == -1) & (errno == ENOENT)) {
ai->device = "/dev/baud0/1"; /* baud0 for MCA */
ai->fn = open(ai->device,O_WRONLY);
ao->device = "/dev/paud0/1"; /* paud0 for PCI */
ao->fn = open(ao->device,O_WRONLY);
if ((ao->fn == -1) & (errno == ENOENT)) {
ao->device = "/dev/baud0/1"; /* baud0 for MCA */
ao->fn = open(ao->device,O_WRONLY);
}
}
} else ai->fn = open(ai->device,O_WRONLY);
} else ao->fn = open(ao->device,O_WRONLY);
if(ai->fn < 0){
if(ao->fn < 0){
fprintf(stderr,"Can't open audio device!\n");
return ai->fn;
return ao->fn;
}
/* Init to default values */
@@ -83,14 +88,14 @@ int audio_open(struct audio_info_struct *ai)
ainit.operation = PLAY;
ainit.bsize = AUDIO_BSIZE;
ret = ioctl (ai->fn, AUDIO_INIT, & ainit);
ret = ioctl (ao->fn, AUDIO_INIT, & ainit);
if (ret < 0)
return ret;
audio_reset_parameters(ai);
return ai->fn;
return ao->fn;
}
int audio_reset_parameters(struct audio_info_struct *ai)
int audio_reset_parameters(audio_output_t *ao)
{
audio_control acontrol;
audio_change achange;
@@ -105,16 +110,16 @@ int audio_reset_parameters(struct audio_info_struct *ai)
achange.volume = (long) (0x7fff << 16);
achange.volume_delay = 0;
achange.input = AUDIO_IGNORE;
if (ai->output == -1) achange.output = INTERNAL_SPEAKER;
if (ao->output == -1) achange.output = INTERNAL_SPEAKER;
else
achange.output = 0;
if(ai->output & AUDIO_OUT_INTERNAL_SPEAKER)
if(ao->output & AUDIO_OUT_INTERNAL_SPEAKER)
achange.output |= INTERNAL_SPEAKER;
if(ai->output & AUDIO_OUT_HEADPHONES)
if(ao->output & AUDIO_OUT_HEADPHONES)
achange.output |= EXTERNAL_SPEAKER;
if(ai->output & AUDIO_OUT_LINE_OUT)
if(ao->output & AUDIO_OUT_LINE_OUT)
achange.output |= OUTPUT_1;
if(ai->output == 0)
if(ao->output == 0)
achange.output = AUDIO_IGNORE;
achange.treble = AUDIO_IGNORE;
achange.bass = AUDIO_IGNORE;
@@ -126,19 +131,19 @@ int audio_reset_parameters(struct audio_info_struct *ai)
acontrol.position = 0;
acontrol.request_info = (char *) & achange;
ret = ioctl (ai->fn, AUDIO_CONTROL, & acontrol);
ret = ioctl (ao->fn, AUDIO_CONTROL, & acontrol);
if (ret < 0)
return ret;
/* Init Device for new values */
if (ai->rate >0) {
if (ao->rate >0) {
memset ( & ainit, '\0', sizeof (ainit));
ainit.srate = audio_rate_best_match(ai);
if (ai->channels > 0)
ainit.channels = ai->channels;
if (ao->channels > 0)
ainit.channels = ao->channels;
else
ainit.channels = 1;
switch (ai->format) {
switch (ao->format) {
default :
ainit.mode = PCM;
ainit.bits_per_sample = 8;
@@ -178,7 +183,7 @@ int audio_reset_parameters(struct audio_info_struct *ai)
ainit.operation = PLAY;
ainit.bsize = AUDIO_BSIZE;
ret = ioctl (ai->fn, AUDIO_INIT, & ainit);
ret = ioctl (ao->fn, AUDIO_INIT, & ainit);
if (ret < 0) {
fprintf(stderr,"Can't set new audio parameters!\n");
return ret;
@@ -189,7 +194,7 @@ int audio_reset_parameters(struct audio_info_struct *ai)
acontrol.request_info = NULL;
acontrol.position = 0;
ret = ioctl (ai->fn, AUDIO_CONTROL, & acontrol);
ret = ioctl (ao->fn, AUDIO_CONTROL, & acontrol);
if (ret < 0) {
fprintf(stderr,"Can't reset audio!\n");
return ret;
@@ -197,7 +202,7 @@ int audio_reset_parameters(struct audio_info_struct *ai)
return 0;
}
int audio_get_formats(struct audio_info_struct *ai)
int audio_get_formats(audio_output_t *ao)
{
/* ULTIMEDIA DOCUMENTATION SAYS:
The Ultimedia Audio Adapter supports fourteen sample rates you can use to
@@ -209,9 +214,9 @@ int audio_get_formats(struct audio_info_struct *ai)
long rate;
rate = ai->rate;
rate = ao->rate;
audio_rate_best_match(ai);
if (ai->rate == rate)
if (ao->rate == rate)
return (AUDIO_FORMAT_SIGNED_16|AUDIO_FORMAT_UNSIGNED_16|
AUDIO_FORMAT_UNSIGNED_8|AUDIO_FORMAT_SIGNED_8|
AUDIO_FORMAT_ULAW_8|AUDIO_FORMAT_ALAW_8);
@@ -219,12 +224,12 @@ int audio_get_formats(struct audio_info_struct *ai)
return 0;
}
int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
int audio_play_samples(audio_output_t *ao,unsigned char *buf,int len)
{
return write(ai->fn,buf,len);
return write(ao->fn,buf,len);
}
int audio_close(struct audio_info_struct *ai)
int audio_close(audio_output_t *ao)
{
audio_control acontrol;
audio_buffer abuffer;
@@ -236,7 +241,7 @@ int audio_close(struct audio_info_struct *ai)
acontrol.position = 0;
i=50; /* Don't do this forever on a bad day :-) */
while (i-- > 0) {
if ((ioctl(ai->fn, AUDIO_BUFFER, &acontrol))< 0) {
if ((ioctl(ao->fn, AUDIO_BUFFER, &acontrol))< 0) {
fprintf(stderr, "buffer read failed: %d\n", errno);
break;
} else {
@@ -251,18 +256,18 @@ int audio_close(struct audio_info_struct *ai)
acontrol.request_info = NULL;
acontrol.position = 0;
ret = ioctl ( ai->fn, AUDIO_CONTROL, & acontrol );
ret = ioctl ( ao->fn, AUDIO_CONTROL, & acontrol );
if (ret < 0)
fprintf(stderr,"Can't close audio!\n");
ret = close (ai->fn);
ret = close (ao->fn);
if (ret < 0)
fprintf(stderr,"Can't close audio!\n");
return 0;
}
void audio_queueflush(struct audio_info_struct *ai)
void audio_queueflush(audio_output_t *ao)
{
}

View File

@@ -1,5 +1,5 @@
/*
audio_alib.c: audio output for HP-UX using alib
alib: audio output for HP-UX using alib
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
@@ -54,14 +54,14 @@
*
* used :
*
* int audio_open(struct audio_info_struct *ai);
* int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len);
* int audio_close(struct audio_info_struct *ai);
* int audio_open(audio_output_t *ao);
* int audio_play_samples(audio_output_t *ao,unsigned char *buf,int len);
* int audio_close(audio_output_t *ao);
*
* unused :
*
* int audio_set_rate(struct audio_info_struct *ai);
* int audio_set_channels(struct audio_info_struct *ai);
* int audio_set_rate(audio_output_t *ao);
* int audio_set_channels(audio_output_t *ao);
*
*/
@@ -91,12 +91,12 @@ static long myHandler(Audio *audio,AErrorEvent *err_event) {
/*
* Set the fn element of ai
* Use ai->rate and ai->channels
* Use ao->rate and ao->channels
* Doesn't set any volume
*/
/* return on error leaves stuff dirty here... */
int audio_open(struct audio_info_struct *ai) {
int audio_open(audio_output_t *ao) {
AudioAttributes Attribs;
AudioAttrMask AttribsMask;
AGainEntry gainEntry[4];
@@ -117,13 +117,13 @@ int audio_open(struct audio_info_struct *ai) {
if(audioServer==NULL)
{error("Error: could not open audio\n"); return -1; }
ai->fn = socket( AF_INET, SOCK_STREAM, 0 );
if(ai->fn<0)
ao->fn = socket( AF_INET, SOCK_STREAM, 0 );
if(ao->fn<0)
{error("Socket creation failed"); return -1; }
Attribs.type = ATSampled;
Attribs.attr.sampled_attr.sampling_rate = ai->rate;
Attribs.attr.sampled_attr.channels = ai->channels;
Attribs.attr.sampled_attr.sampling_rate = ao->rate;
Attribs.attr.sampled_attr.channels = ao->channels;
Attribs.attr.sampled_attr.data_format = ADFLin16;
AttribsMask = ASSamplingRateMask | ASChannelsMask | ASDataFormatMask;
@@ -141,23 +141,23 @@ int audio_open(struct audio_info_struct *ai) {
xid=APlaySStream(audioServer,AttribsMask,&Attribs,
&playParams,&audioStream,NULL);
status=connect(ai->fn,
status=connect(ao->fn,
(struct sockaddr *) &audioStream.tcp_sockaddr,
sizeof(struct sockaddr_in) );
if(status<0){error("Connect failed"); return -1;}
i=-1;
tcpProtocolEntry=getprotobyname("tcp");
setsockopt(ai->fn,tcpProtocolEntry->p_proto,TCP_NODELAY,&i,sizeof(i));
setsockopt(ao->fn,tcpProtocolEntry->p_proto,TCP_NODELAY,&i,sizeof(i));
return ai->fn;
return ao->fn;
}
/**************************************************************************/
int audio_close(struct audio_info_struct *ai)
int audio_close(audio_output_t *ao)
{
close(ai->fn);
close(ao->fn);
ASetCloseDownMode( audioServer, AKeepTransactions, NULL );
ACloseAudio( audioServer, NULL );
audioServer = (Audio *) NULL;
@@ -171,19 +171,19 @@ int audio_close(struct audio_info_struct *ai)
* deserv to be inline
*/
inline int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
inline int audio_play_samples(audio_output_t *ao,unsigned char *buf,int len)
{
return write(ai->fn,buf,len*2);
return write(ao->fn,buf,len*2);
}
/**************************************************************************/
int audio_get_formats(struct audio_info_struct *ai)
int audio_get_formats(audio_output_t *ao)
{
return AUDIO_FORMAT_SIGNED_16;
}
void audio_queueflush(struct audio_info_struct *ai)
void audio_queueflush(audio_output_t *ao)
{
}

251
src/output/alsa.c Normal file
View File

@@ -0,0 +1,251 @@
/*
alsa: sound output with Advanced Linux Sound Architecture 1.x API
copyright 2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
written by Clemens Ladisch <clemens@ladisch.de>
*/
#include "mpg123.h"
#include "audio.h"
#include "module.h"
#include <errno.h>
/* make ALSA 0.9.x compatible to the 1.0.x API */
#define ALSA_PCM_NEW_HW_PARAMS_API
#define ALSA_PCM_NEW_SW_PARAMS_API
#include <alsa/asoundlib.h>
/* My laptop has probs playing low-sampled files with only 0.5s buffer... this should be a user setting -- ThOr */
#define BUFFER_LENGTH 0.5 /* in seconds */
static const struct {
snd_pcm_format_t alsa;
int mpg123;
} format_map[] = {
{ SND_PCM_FORMAT_S16, AUDIO_FORMAT_SIGNED_16 },
{ SND_PCM_FORMAT_U16, AUDIO_FORMAT_UNSIGNED_16 },
{ SND_PCM_FORMAT_U8, AUDIO_FORMAT_UNSIGNED_8 },
{ SND_PCM_FORMAT_S8, AUDIO_FORMAT_SIGNED_8 },
{ SND_PCM_FORMAT_A_LAW, AUDIO_FORMAT_ALAW_8 },
{ SND_PCM_FORMAT_MU_LAW, AUDIO_FORMAT_ULAW_8 },
};
#define NUM_FORMATS (sizeof format_map / sizeof format_map[0])
static int rates_match(long int desired, unsigned int actual)
{
return actual * 100 > desired * (100 - AUDIO_RATE_TOLERANCE) &&
actual * 100 < desired * (100 + AUDIO_RATE_TOLERANCE);
}
static int initialize_device(audio_output_t *ao)
{
snd_pcm_hw_params_t *hw;
int i;
snd_pcm_format_t format;
unsigned int rate;
snd_pcm_uframes_t buffer_size;
snd_pcm_uframes_t period_size;
snd_pcm_sw_params_t *sw;
snd_pcm_hw_params_alloca(&hw);
if (snd_pcm_hw_params_any(ao->userptr, hw) < 0) {
error("initialize_device(): no configuration available");
return -1;
}
if (snd_pcm_hw_params_set_access(ao->userptr, hw, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
error("initialize_device(): device does not support interleaved access");
return -1;
}
format = SND_PCM_FORMAT_UNKNOWN;
for (i = 0; i < NUM_FORMATS; ++i) {
if (ao->format == format_map[i].mpg123) {
format = format_map[i].alsa;
break;
}
}
if (format == SND_PCM_FORMAT_UNKNOWN) {
error1("initialize_device(): invalid sample format %d", ao->format);
errno = EINVAL;
return -1;
}
if (snd_pcm_hw_params_set_format(ao->userptr, hw, format) < 0) {
error1("initialize_device(): cannot set format %s", snd_pcm_format_name(format));
return -1;
}
if (snd_pcm_hw_params_set_channels(ao->userptr, hw, ao->channels) < 0) {
error1("initialize_device(): cannot set %d channels", ao->channels);
return -1;
}
rate = ao->rate;
if (snd_pcm_hw_params_set_rate_near(ao->userptr, hw, &rate, NULL) < 0) {
error1("initialize_device(): cannot set rate %u", rate);
return -1;
}
if (!rates_match(ao->rate, rate)) {
error2("initialize_device(): rate %ld not available, using %u", ao->rate, rate);
/* return -1; */
}
buffer_size = rate * BUFFER_LENGTH;
if (snd_pcm_hw_params_set_buffer_size_near(ao->userptr, hw, &buffer_size) < 0) {
error("initialize_device(): cannot set buffer size");
return -1;
}
period_size = buffer_size / 4;
if (snd_pcm_hw_params_set_period_size_near(ao->userptr, hw, &period_size, NULL) < 0) {
error("initialize_device(): cannot set period size");
return -1;
}
if (snd_pcm_hw_params(ao->userptr, hw) < 0) {
error("initialize_device(): cannot set hw params");
return -1;
}
snd_pcm_sw_params_alloca(&sw);
if (snd_pcm_sw_params_current(ao->userptr, sw) < 0) {
error("initialize_device(): cannot get sw params");
return -1;
}
/* start playing after the first write */
if (snd_pcm_sw_params_set_start_threshold(ao->userptr, sw, 1) < 0) {
error("initialize_device(): cannot set start threshold");
return -1;
}
/* wake up on every interrupt */
if (snd_pcm_sw_params_set_avail_min(ao->userptr, sw, 1) < 0) {
error("initialize_device(): cannot set min available");
return -1;
}
/* always write as many frames as possible */
if (snd_pcm_sw_params_set_xfer_align(ao->userptr, sw, 1) < 0) {
error("initialize_device(): cannot set transfer alignment");
return -1;
}
if (snd_pcm_sw_params(ao->userptr, sw) < 0) {
error("initialize_device(): cannot set sw params");
return -1;
}
return 0;
}
static int open_alsa(audio_output_t *ao)
{
const char *pcm_name;
snd_pcm_t *pcm;
pcm_name = ao->device ? ao->device : "default";
if (snd_pcm_open(&pcm, pcm_name, SND_PCM_STREAM_PLAYBACK, 0) < 0) {
error1("cannot open device %s", pcm_name);
return -1;
}
ao->userptr = pcm;
if (ao->format != -1) {
/* we're going to play: initalize sample format */
return initialize_device(ao);
} else {
/* query mode; sample format will be set for each query */
return 0;
}
}
static int get_formats_alsa(audio_output_t *ao)
{
snd_pcm_hw_params_t *hw;
unsigned int rate;
int supported_formats, i;
snd_pcm_hw_params_alloca(&hw);
if (snd_pcm_hw_params_any(ao->userptr, hw) < 0) {
error("get_formats_alsa(): no configuration available");
return -1;
}
if (snd_pcm_hw_params_set_access(ao->userptr, hw, SND_PCM_ACCESS_RW_INTERLEAVED) < 0)
return -1;
if (snd_pcm_hw_params_set_channels(ao->userptr, hw, ao->channels) < 0)
return 0;
rate = ao->rate;
if (snd_pcm_hw_params_set_rate_near(ao->userptr, hw, &rate, NULL) < 0)
return -1;
if (!rates_match(ao->rate, rate))
return 0;
supported_formats = 0;
for (i = 0; i < NUM_FORMATS; ++i) {
if (snd_pcm_hw_params_test_format(ao->userptr, hw, format_map[i].alsa) == 0)
supported_formats |= format_map[i].mpg123;
}
return supported_formats;
}
static int write_alsa(audio_output_t *ao, unsigned char *buf, int bytes)
{
snd_pcm_uframes_t frames;
snd_pcm_sframes_t written;
frames = snd_pcm_bytes_to_frames(ai->handle, bytes);
written = snd_pcm_writei(ai->handle, buf, frames);
if (written == -EINTR) /* interrupted system call */
written = 0;
else if (written == -EPIPE) { /* underrun */
if (snd_pcm_prepare(ai->handle) >= 0)
written = snd_pcm_writei(ai->handle, buf, frames);
}
if (written >= 0)
return snd_pcm_frames_to_bytes(ao->userptr, written);
else
return written;
}
static void flush_alsa(audio_output_t *ao)
{
/* is this the optimal solution? - we should figure out what we really whant from this function */
snd_pcm_drop(ao->userptr);
snd_pcm_prepare(ao->userptr);
}
static int close_alsa(audio_output_t *ao)
{
if(ao->userptr != NULL) /* be really generous for being called without any device opening */
{
if (snd_pcm_state(ao->userptr) == SND_PCM_STATE_RUNNING)
snd_pcm_drain(ao->userptr);
return snd_pcm_close(ao->userptr);
}
else return 0;
}
static int init_alsa(audio_output_t* ao)
{
if (ao==NULL) return -1;
/* Set callbacks */
ao->open = open_alsa;
ao->flush = flush_alsa;
ao->write = write_alsa;
ao->get_formats = get_formats_alsa;
ao->close = close_alsa;
/* Success */
return 0;
}
/*
Module information data structure
*/
mpg123_module_t mpg123_output_module_info = {
/* api_version */ MPG123_MODULE_API_VERSION,
/* name */ "alsa",
/* description */ "Output audio using Advanced Linux Sound Architecture (ALSA).",
/* revision */ "$Rev:$",
/* handle */ NULL,
/* init_output */ init_alsa,
};

View File

@@ -33,7 +33,7 @@
int audio_open(struct audio_info_struct *ai)
int audio_open(audio_output_t *ao)
{
int err;
int card=0,device=0;
@@ -42,9 +42,9 @@ int audio_open(struct audio_info_struct *ai)
if(!ai)
return -1;
if(ai->device) { /* parse ALSA device name */
if(strchr(ai->device,':')) { /* card with device */
strncpy(scard, ai->device, sizeof(scard)-1);
if(ao->device) { /* parse ALSA device name */
if(strchr(ao->device,':')) { /* card with device */
strncpy(scard, ao->device, sizeof(scard)-1);
scard[sizeof(scard)-1] = '\0';
if (strchr(scard,':')) *strchr(scard,':') = '\0';
card = snd_card_name(scard);
@@ -52,9 +52,9 @@ int audio_open(struct audio_info_struct *ai)
fprintf(stderr, "wrong soundcard number: %s\n", scard);
exit(1);
}
strncpy(sdevice, strchr(ai->device, ':') + 1, sizeof(sdevice)-1);
strncpy(sdevice, strchr(ao->device, ':') + 1, sizeof(sdevice)-1);
} else {
strncpy(sdevice, ai->device, sizeof(sdevice)-1);
strncpy(sdevice, ao->device, sizeof(sdevice)-1);
}
sdevice[sizeof(sdevice)-1] = '\0';
device = atoi(sdevice);
@@ -65,7 +65,7 @@ int audio_open(struct audio_info_struct *ai)
}
// Open the ALSA device
if((err=snd_pcm_open(&ai->handle, card, device, SND_PCM_OPEN_PLAYBACK)) < 0 )
if((err=snd_pcm_open(&ao->handle, card, device, SND_PCM_OPEN_PLAYBACK)) < 0 )
{
fprintf(stderr, "open failed: %s\n", snd_strerror(err));
exit(1);
@@ -81,38 +81,38 @@ int audio_open(struct audio_info_struct *ai)
}
static void audio_set_playback_format(struct audio_info_struct *ai)
static void audio_set_playback_format(audio_output_t *ao)
{
snd_pcm_format_t alsa_format;
int err;
alsa_format.rat = ai->rate;
alsa_format.channels = ai->channels;
alsa_format.rat = ao->rate;
alsa_format.channels = ao->channels;
switch(ai->format)
switch(ao->format)
{
case AUDIO_FORMAT_SIGNED_16:
default:
ai->alsa_format.format=SND_PCM_SFMT_S16_NE;
ao->alsa_format.format=SND_PCM_SFMT_S16_NE;
break;
case AUDIO_FORMAT_UNSIGNED_8:
ai->alsa_format.format=SND_PCM_SFMT_U8;
ao->alsa_format.format=SND_PCM_SFMT_U8;
break;
case AUDIO_FORMAT_SIGNED_8:
ai->alsa_format.format=SND_PCM_SFMT_S8;
ao->alsa_format.format=SND_PCM_SFMT_S8;
break;
case AUDIO_FORMAT_ULAW_8:
ai->alsa_format.format=SND_PCM_SFMT_MU_LAW;
ao->alsa_format.format=SND_PCM_SFMT_MU_LAW;
break;
case AUDIO_FORMAT_ALAW_8:
ai->alsa_format.format=SND_PCM_SFMT_A_LAW;
ao->alsa_format.format=SND_PCM_SFMT_A_LAW;
break;
case AUDIO_FORMAT_UNSIGNED_16:
ai->alsa_format.format=SND_PCM_SFMT_U16_NE;
ao->alsa_format.format=SND_PCM_SFMT_U16_NE;
break;
}
if((err=snd_pcm_playback_format(ai->handle, &alsa_format)) < 0 )
if((err=snd_pcm_playback_format(ao->handle, &alsa_format)) < 0 )
{
fprintf(stderr, "snd_pcm_playback_format failed: %s\n", snd_strerror(err));
exit(1);
@@ -120,13 +120,13 @@ static void audio_set_playback_format(struct audio_info_struct *ai)
}
static void audio_set_playback_params(struct audio_info_struct *ai)
static void audio_set_playback_params(audio_output_t *ao)
{
int err;
snd_pcm_playback_info_t pi;
snd_pcm_playback_params_t pp;
if((err=snd_pcm_playback_info(ai->handle, &pi)) < 0 )
if((err=snd_pcm_playback_info(ao->handle, &pi)) < 0 )
{
fprintf(stderr, "playback info failed: %s\n", snd_strerror(err));
return; /* not fatal error */
@@ -139,7 +139,7 @@ static void audio_set_playback_params(struct audio_info_struct *ai)
pp.fragments_max = -1;
pp.fragments_room = 1;
if((err=snd_pcm_playback_params(ai->handle, &pp)) < 0 )
if((err=snd_pcm_playback_params(ao->handle, &pp)) < 0 )
{
fprintf(stderr, "playback params failed: %s\n", snd_strerror(err));
return; /* not fatal error */
@@ -149,7 +149,7 @@ static void audio_set_playback_params(struct audio_info_struct *ai)
int audio_get_formats(struct audio_info_struct *ai)
int audio_get_formats(audio_output_t *ao)
{
int i, err;
int fmt = -1;
@@ -166,7 +166,7 @@ int audio_get_formats(struct audio_info_struct *ai)
SND_PCM_FMT_MU_LAW, SND_PCM_FMT_A_LAW
};
if((err=snd_pcm_playback_info(ai->handle, &pi)) < 0 )
if((err=snd_pcm_playback_info(ao->handle, &pi)) < 0 )
{
fprintf(stderr, "playback info failed: %s\n", snd_strerror(err));
return -1;
@@ -183,23 +183,23 @@ int audio_get_formats(struct audio_info_struct *ai)
return fmt;
}
int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
int audio_play_samples(audio_output_t *ao,unsigned char *buf,int len)
{
ssize_t ret;
ret=snd_pcm_write(ai->handle, buf, len);
ret=snd_pcm_write(ao->handle, buf, len);
return ret;
}
int audio_close(struct audio_info_struct *ai)
int audio_close(audio_output_t *ao)
{
int ret;
ret = snd_pcm_close(ai->handle);
ret = snd_pcm_close(ao->handle);
return ret;
}
void audio_queueflush(struct audio_info_struct *ai)
void audio_queueflush(audio_output_t *ao)
{
}

View File

@@ -1,5 +1,5 @@
/*
audio_macosx: audio output on MacOS X
coreaudio: audio output on MacOS X
copyright ?-2006 by the mpg123 project - free software under the terms of the GPL 2
see COPYING and AUTHORS files in distribution or http://mpg123.org
@@ -17,7 +17,7 @@
#include <AudioToolbox/AudioToolbox.h>
#include <errno.h>
#define FIFO_DURATION (0.5f)
#define FIFO_DURATION (0.5f) /* Duration of the ring buffer in seconds */
struct anEnv
@@ -38,8 +38,6 @@ struct anEnv
sfifo_t fifo;
};
static struct anEnv *env=NULL;
static OSStatus playProc(AudioConverterRef inAudioConverter,
@@ -48,8 +46,10 @@ static OSStatus playProc(AudioConverterRef inAudioConverter,
AudioStreamPacketDescription **outDataPacketDescription,
void* inClientData)
{
struct anEnv *env = (struct anEnv *)inClientData;
long n;
if(env->last_buffer) {
env->play_done = 1;
return noErr;
@@ -94,18 +94,18 @@ static OSStatus convertProc(void *inRefCon, AudioUnitRenderActionFlags *inAction
const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber,
UInt32 inNumFrames, AudioBufferList *ioData)
{
AudioStreamPacketDescription* outPacketDescription = NULL;
struct anEnv *env = (struct anEnv *)inRefCon;
OSStatus err= noErr;
void *inInputDataProcUserData=NULL;
AudioStreamPacketDescription* outPacketDescription =NULL;
err = AudioConverterFillComplexBuffer(env->converter, playProc, inInputDataProcUserData, &inNumFrames, ioData, outPacketDescription);
err = AudioConverterFillComplexBuffer(env->converter, playProc, inRefCon, &inNumFrames, ioData, outPacketDescription);
return err;
}
int audio_open(struct audio_info_struct *ai)
static int open_coreaudio(audio_output_t *ao)
{
struct anEnv *env = NULL;
UInt32 size;
ComponentDescription desc;
Component comp;
@@ -115,15 +115,16 @@ int audio_open(struct audio_info_struct *ai)
Boolean outWritable;
/* Allocate memory for data structure */
if (!env) {
env = (struct anEnv*)malloc( sizeof( struct anEnv ) );
if (!env) {
if (!ao->userptr) {
ao->userptr = malloc( sizeof( struct anEnv ) );
if (!ao->userptr) {
error("failed to malloc memory for 'struct anEnv'");
return -1;
}
}
/* Initialize our environment */
env = (struct anEnv *)ao->userptr;
env->play = 0;
env->buffer = NULL;
env->buffer_size = 0;
@@ -167,9 +168,9 @@ int audio_open(struct audio_info_struct *ai)
}
/* Specify the input PCM format */
env->channels = ai->channels;
inFormat.mSampleRate = ai->rate;
inFormat.mChannelsPerFrame = ai->channels;
env->channels = ao->channels;
inFormat.mSampleRate = ao->rate;
inFormat.mChannelsPerFrame = ao->channels;
inFormat.mBitsPerChannel = 16;
inFormat.mBytesPerPacket = 2*inFormat.mChannelsPerFrame;
inFormat.mFramesPerPacket = 1;
@@ -185,7 +186,7 @@ int audio_open(struct audio_info_struct *ai)
/* Add our callback - but don't start it yet */
memset(&renderCallback, 0, sizeof(AURenderCallbackStruct));
renderCallback.inputProc = convertProc;
renderCallback.inputProcRefCon = 0;
renderCallback.inputProcRefCon = ao->userptr;
if(AudioUnitSetProperty(env->outputUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &renderCallback, sizeof(AURenderCallbackStruct))) {
error("AudioUnitSetProperty(kAudioUnitProperty_SetRenderCallback) failed");
return(-1);
@@ -193,14 +194,14 @@ int audio_open(struct audio_info_struct *ai)
/* Open an audio I/O stream and create converter */
if (ai->rate > 0 && ai->channels >0 ) {
if (ao->rate > 0 && ao->channels >0 ) {
int ringbuffer_len;
if(AudioConverterNew(&inFormat, &outFormat, &(env->converter))) {
error("AudioConverterNew failed");
return(-1);
}
if(ai->channels == 1) {
if(ao->channels == 1) {
SInt32 channelMap[2] = { 0, 0 };
if(AudioConverterSetProperty(env->converter, kAudioConverterChannelMap, sizeof(channelMap), channelMap)) {
error("AudioConverterSetProperty(kAudioConverterChannelMap) failed");
@@ -209,7 +210,7 @@ int audio_open(struct audio_info_struct *ai)
}
/* Initialise FIFO */
ringbuffer_len = ai->rate * FIFO_DURATION * sizeof(short) *ai->channels;
ringbuffer_len = ao->rate * FIFO_DURATION * sizeof(short) *ao->channels;
debug2( "Allocating %d byte ring-buffer (%f seconds)", ringbuffer_len, (float)FIFO_DURATION);
sfifo_init( &env->fifo, ringbuffer_len );
@@ -218,16 +219,15 @@ int audio_open(struct audio_info_struct *ai)
return(0);
}
int audio_get_formats(struct audio_info_struct *ai)
static int get_formats_coreaudio(audio_output_t *ao)
{
/* Only support Signed 16-bit output */
return AUDIO_FORMAT_SIGNED_16;
}
int audio_play_samples(struct audio_info_struct *ai, unsigned char *buf, int len)
static int write_coreaudio(audio_output_t *ao, unsigned char *buf, int len)
{
struct anEnv *env = (struct anEnv *)ao->userptr;
int written;
/* If there is no room, then sleep for half the length of the FIFO */
@@ -255,8 +255,10 @@ int audio_play_samples(struct audio_info_struct *ai, unsigned char *buf, int len
return len;
}
int audio_close(struct audio_info_struct *ai)
static int close_coreaudio(audio_output_t *ao)
{
struct anEnv *env = (struct anEnv *)ao->userptr;
if (env) {
env->decode_done = 1;
while(!env->play_done && env->play) usleep(10000);
@@ -275,14 +277,15 @@ int audio_close(struct audio_info_struct *ai)
/* Free environment data structure */
free(env);
env=NULL;
ao->userptr=NULL;
}
return 0;
}
void audio_queueflush(struct audio_info_struct *ai)
static void flush_coreaudio(audio_output_t *ao)
{
struct anEnv *env = (struct anEnv *)ao->userptr;
/* Stop playback */
if(AudioOutputUnitStop(env->outputUnit)) {
@@ -293,3 +296,36 @@ void audio_queueflush(struct audio_info_struct *ai)
/* Empty out the ring buffer */
sfifo_flush( &env->fifo );
}
static int init_coreaudio(audio_output_t* ao)
{
if (ao==NULL) return -1;
/* Set callbacks */
ao->open = open_coreaudio;
ao->flush = flush_coreaudio;
ao->write = write_coreaudio;
ao->get_formats = get_formats_coreaudio;
ao->close = close_coreaudio;
/* Success */
return 0;
}
/*
Module information data structure
*/
mpg123_module_t mpg123_output_module_info = {
/* api_version */ MPG123_MODULE_API_VERSION,
/* name */ "coreaudio",
/* description */ "Output audio using Mac OS X's CoreAudio.",
/* revision */ "$Rev:$",
/* handle */ NULL,
/* init_output */ init_coreaudio,
};

70
src/output/dummy.c Normal file
View File

@@ -0,0 +1,70 @@
/*
dummy: dummy audio output
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
*/
#include "mpg123.h"
static int open_dummy(audio_output_t *ao)
{
debug("open_dummy()");
warning("Using the dummy audio output module.");
return 0;
}
static int get_formats_dummy(audio_output_t *ao)
{
debug("get_formats_dummy()");
return AUDIO_FORMAT_SIGNED_16;
}
static int write_dummy(audio_output_t *ao,unsigned char *buf,int len)
{
debug("write_dummy()");
return len;
}
static void flush_dummy(audio_output_t *ao)
{
debug("flush_dummy()");
}
static int close_dummy(audio_output_t *ao)
{
debug("close_dummy()");
return 0;
}
static int init_dummy(audio_output_t* ao)
{
if (ao==NULL) return -1;
/* Set callbacks */
ao->open = open_dummy;
ao->flush = flush_dummy;
ao->write = write_dummy;
ao->get_formats = get_formats_dummy;
ao->close = close_dummy;
/* Success */
return 0;
}
/*
Module information data structure
*/
mpg123_module_t mpg123_output_module_info = {
/* api_version */ MPG123_MODULE_API_VERSION,
/* name */ "dummy",
/* description */ "Dummy audio output - does not output audio.",
/* revision */ "$Rev:$",
/* handle */ NULL,
/* init_output */ init_dummy,
};

160
src/output/esd.c Normal file
View File

@@ -0,0 +1,160 @@
/*
esd: audio output for ESounD (highly untested nowadays (?))
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Eric B. Mitchell ("esd port" should be this file...)
*/
#include <esd.h>
#include <errno.h>
#include <assert.h>
#include "mpg123.h"
#ifdef SOLARIS
#include <stropts.h>
#include <sys/conf.h>
#endif
static unsigned esd_rate = 0, esd_format = 0, esd_channels = 0;
static int open_esound(audio_output_t *ao)
{
esd_format_t format = ESD_STREAM | ESD_PLAY;
if (!esd_rate)
{
int esd;
esd_server_info_t *info;
esd_format_t fmt;
if ((esd = esd_open_sound(NULL)) >= 0)
{
info = esd_get_server_info(esd);
esd_rate = info->rate;
fmt = info->format;
esd_free_server_info(info);
esd_close(esd);
}
else
{
esd_rate = esd_audio_rate;
fmt = esd_audio_format;
}
esd_format = AUDIO_FORMAT_UNSIGNED_8;
if ((fmt & ESD_MASK_BITS) == ESD_BITS16)
esd_format |= AUDIO_FORMAT_SIGNED_16;
esd_channels = fmt & ESD_MASK_CHAN;
}
if (ao->format == -1)
ao->format = esd_format;
else if (!(ao->format & esd_format))
{
error1("Unsupported audio format: %d\n", ao->format);
errno = EINVAL;
return -1;
}
if (ao->format & AUDIO_FORMAT_SIGNED_16)
format |= ESD_BITS16;
else if (ao->format & AUDIO_FORMAT_UNSIGNED_8)
format |= ESD_BITS8;
else assert(0);
if (ao->channels == -1) ao->channels = 2;
else if (ao->channels <= 0 || ao->channels > esd_channels)
{
error1("Unsupported no of channels: %d\n", ao->channels);
errno = EINVAL;
return -1;
}
if (ao->channels == 1)
format |= ESD_MONO;
else if (ao->channels == 2)
format |= ESD_STEREO;
else assert(0);
if (ao->rate == -1) ao->rate = esd_rate;
else if (ao->rate > esd_rate)
return -1;
ao->fn = esd_play_stream_fallback(format, ao->rate, ao->device, "mpg123");
return (ao->fn);
}
static int get_formats_esound (audio_output_t *ao)
{
if (0 < ao->channels && ao->channels <= esd_channels
&& 0 < ao->rate && ao->rate <= esd_rate)
{
return esd_format;
} else {
return -1;
}
}
static int write_esound(audio_output_t *ao,unsigned char *buf,int len)
{
return write(ao->fn,buf,len);
}
static int close_esound(audio_output_t *ao)
{
close (ao->fn);
return 0;
}
#ifdef SOLARIS
static void flush_esound (audio_output_t *ao)
{
ioctl (ao->fn, I_FLUSH, FLUSHRW);
}
#else
#ifdef NETBSD
static void flush_esound (audio_output_t *ao)
{
ioctl (ao->fn, AUDIO_FLUSH, 0);
}
#else
/* Dunno what to do on Linux and Cygwin, but the func must be at least defined! */
static void flush_esound (audio_output_t *ao)
{
}
#endif
#endif
static int init_esound(audio_output_t* ao)
{
if (ao==NULL) return -1;
/* Set callbacks */
ao->open = open_esound;
ao->flush = flush_esound;
ao->write = write_esound;
ao->get_formats = get_formats_esound;
ao->close = close_esound;
/* Success */
return 0;
}
/*
Module information data structure
*/
mpg123_module_t mpg123_output_module_info = {
/* api_version */ MPG123_MODULE_API_VERSION,
/* name */ "esound",
/* description */ "Output audio using ESounD (The Enlightened Sound Daemon).",
/* revision */ "$Rev$",
/* handle */ NULL,
/* init_output */ init_esound,
};

153
src/output/hp.c Normal file
View File

@@ -0,0 +1,153 @@
/*
hp: audio output for HP-UX
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
#include "mpg123.h"
#include <fcntl.h>
#include <sys/audio.h>
static int audio_set_rate(audio_output_t *ao)
{
if(ao->rate >= 0) {
return ioctl(ao->fn,AUDIO_SET_SAMPLE_RATE,ao->rate);
} else {
return 0;
}
}
static int audio_set_channels(audio_output_t *ao)
{
if(ao->channels<0) return 0;
return ioctl(ao->fn,AUDIO_SET_CHANNELS,ao->channels);
}
static int audio_set_format(audio_output_t *ao)
{
int fmt;
switch(ao->format) {
case -1:
case AUDIO_FORMAT_SIGNED_16:
default:
fmt = AUDIO_FORMAT_LINEAR16BIT;
break;
case AUDIO_FORMAT_UNSIGNED_8:
fprintf(stderr,"unsigned 8 bit linear not supported\n");
return -1;
case AUDIO_FORMAT_SIGNED_8:
fprintf(stderr,"signed 8 bit linear not supported\n");
return -1;
case AUDIO_FORMAT_ALAW_8:
fmt = AUDIO_FORMAT_ALAW;
break;
case AUDIO_FORMAT_ULAW_8:
fmt = AUDIO_FORMAT_ULAW;
break;
}
return ioctl(ao->fn,AUDIO_SET_DATA_FORMAT,fmt);
}
static int audio_get_formats(audio_output_t *ao)
{
return AUDIO_FORMAT_SIGNED_16;
}
static int audio_reset_parameters(audio_output_t *ao)
{
int ret;
ret = audio_set_format(ai);
if(ret >= 0)
ret = audio_set_channels(ai);
if(ret >= 0)
ret = audio_set_rate(ai);
return ret;
}
int audio_open(audio_output_t *ao)
{
struct audio_describe ades;
struct audio_gain again;
int i,audio;
ao->fn = open("/dev/audio",O_RDWR);
if(ao->fn < 0)
return -1;
ioctl(ao->fn,AUDIO_DESCRIBE,&ades);
if(ao->gain != -1)
{
if(ao->gain > ades.max_transmit_gain)
{
fprintf(stderr,"your gainvalue was to high -> set to maximum.\n");
ao->gain = ades.max_transmit_gain;
}
if(ao->gain < ades.min_transmit_gain)
{
fprintf(stderr,"your gainvalue was to low -> set to minimum.\n");
ao->gain = ades.min_transmit_gain;
}
again.channel_mask = AUDIO_CHANNEL_0 | AUDIO_CHANNEL_1;
ioctl(ao->fn,AUDIO_GET_GAINS,&again);
again.cgain[0].transmit_gain = ao->gain;
again.cgain[1].transmit_gain = ao->gain;
again.channel_mask = AUDIO_CHANNEL_0 | AUDIO_CHANNEL_1;
ioctl(ao->fn,AUDIO_SET_GAINS,&again);
}
if(ao->output != -1)
{
if(ao->output & AUDIO_OUT_INTERNAL_SPEAKER)
ioctl(ao->fn,AUDIO_SET_OUTPUT,AUDIO_OUT_SPEAKER);
else if(ao->output & AUDIO_OUT_HEADPHONES)
ioctl(ao->fn,AUDIO_SET_OUTPUT,AUDIO_OUT_HEADPHONE);
else if(ao->output & AUDIO_OUT_LINE_OUT)
ioctl(ao->fn,AUDIO_SET_OUTPUT,AUDIO_OUT_LINE);
}
if(ao->rate == -1)
ao->rate = 44100;
for(i=0;i<ades.nrates;i++)
{
if(ao->rate == ades.sample_rate[i])
break;
}
if(i == ades.nrates)
{
fprintf(stderr,"Can't set sample-rate to %ld.\n",ao->rate);
i = 0;
}
if(audio_reset_parameters(ai) < 0)
return -1;
return ao->fn;
}
int audio_play_samples(audio_output_t *ao,unsigned char *buf,int len)
{
return write(ao->fn,buf,len);
}
int audio_close(audio_output_t *ao)
{
close (ao->fn);
return 0;
}
void audio_queueflush(audio_output_t *ao)
{
}

View File

@@ -1,5 +1,5 @@
/*
audio_jack.c: audio output via JACK
jack: audio output via JACK Audio Connection Kit
copyright 2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
@@ -31,7 +31,7 @@ static jack_handle_t* alloc_jack_handle()
handle = malloc(sizeof(jack_handle_t));
if (!handle) {
error("audio_open(): Failed to allocate memory for our handle.");
error("Failed to allocate memory for our handle.");
return NULL;
}
@@ -72,8 +72,7 @@ static void free_jack_handle( jack_handle_t* handle )
}
static int
process_callback( jack_nframes_t nframes, void *arg )
static int process_callback( jack_nframes_t nframes, void *arg )
{
jack_handle_t* handle = (jack_handle_t*)arg;
size_t to_read = sizeof (jack_default_audio_sample_t) * nframes;
@@ -92,25 +91,24 @@ process_callback( jack_nframes_t nframes, void *arg )
bzero( buf+len, to_read - len );
/*if (len < to_read)*/
/* fprintf(stderr, "failed to read from ring buffer %d\n",c);*/
/* error1("failed to read from ring buffer %d",c);*/
}
/* Success*/
return 0;
}
static void
shutdown_callback( void *arg )
static void shutdown_callback( void *arg )
{
/* jack_handle_t* handle = (jack_handle_t*)arg; */
fprintf(stderr, "shutdown_callback()\n");
debug("shutdown_callback()");
}
/* crude way of automatically connecting up jack ports */
/* 0 on error */
int autoconnect_jack_ports( jack_handle_t* handle )
static int autoconnect_jack_ports( jack_handle_t* handle )
{
const char **all_ports;
unsigned int ch=0;
@@ -129,7 +127,7 @@ int autoconnect_jack_ports( jack_handle_t* handle )
const char* in = jack_port_name( handle->ports[ch] );
const char* out = all_ports[i];
fprintf(stderr, "Connecting %s to %s\n", in, out);
debug2("Connecting %s to %sesound", in, out);
if ((err = jack_connect(handle->client, in, out)) != 0) {
error1("connect_jack_ports(): failed to jack_connect() ports: %d",err);
@@ -145,36 +143,54 @@ int autoconnect_jack_ports( jack_handle_t* handle )
}
int connect_jack_ports( jack_handle_t* handle, const char *dev )
static int connect_jack_ports( jack_handle_t* handle, const char *dev )
{
if (dev==NULL || strcmp(dev, "auto")==0) {
return autoconnect_jack_ports( handle );
} else if (strcmp(dev, "none")==0) {
fprintf(stderr, "Not connecting up jack ports as requested.\n");
warning("Not connecting up jack ports as requested.");
} else {
fprintf(stderr, "Sorry I don't know how to connect up ports yet.\n");
warning("Sorry I don't know how to connect up ports yet.");
}
return 1;
}
int audio_open(struct audio_info_struct *ai)
static int close_jack(audio_output_t *ao)
{
jack_handle_t *handle = (jack_handle_t*)ao->userptr;
debug("close_jack().");
/* Close and shutdown*/
if (handle) {
free_jack_handle( handle );
ao->userptr = NULL;
}
return 0;
}
static int open_jack(audio_output_t *ao)
{
char client_name[255];
jack_handle_t *handle=NULL;
jack_options_t jopt = JackNullOption;
jack_status_t jstat = 0;
unsigned int i;
if(!ai) return -1;
if(!ao) return -1;
/* Return if already open*/
if (ai->handle) {
fprintf(stderr, "audio_open(): error, already open\n");
if (ao->userptr) {
error("audio device is already open.");
return -1;
}
/* For some reason we get called with format=-1 initially*/
/* Just prentend that it didn't happen*/
if (ai->format==-1) {
if (ao->format==-1) {
return 0;
}
@@ -183,51 +199,54 @@ int audio_open(struct audio_info_struct *ai)
/* Create some storage for ourselves*/
if((handle = alloc_jack_handle()) == NULL) return -1;
ai->handle = (void*)handle;
ao->userptr = (void*)handle;
/* Register with Jack*/
snprintf(client_name, 255, "mpg123-%d", getpid());
if ((handle->client = jack_client_new(client_name)) == 0) {
error("JACK server not running?");
audio_close(ai);
if ((handle->client = jack_client_open(client_name, jopt, &jstat)) == 0) {
error1("Failed to open jack client: 0x%x", jstat);
close_jack(ao);
return -1;
}
printf("Registering as JACK client %s.\n", client_name);
/* Display the unique client name allocated to us */
printf("Registered as JACK client %s.\n",
jack_get_client_name( handle->client ) );
/* Check the sample rate is correct*/
if (jack_get_sample_rate( handle->client ) != (jack_nframes_t)ai->rate) {
if (jack_get_sample_rate( handle->client ) != (jack_nframes_t)ao->rate) {
error("JACK Sample Rate is different to sample rate of file.");
audio_close(ai);
close_jack(ao);
return -1;
}
/* Register ports with Jack*/
handle->channels = ai->channels;
handle->channels = ao->channels;
if (handle->channels == 1) {
if (!(handle->ports[0] = jack_port_register(handle->client, "mono", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)))
{
error("Cannot register JACK output port 'mono'.");
audio_close(ai);
close_jack(ao);
return -1;
}
} else if (handle->channels == 2) {
if (!(handle->ports[0] = jack_port_register(handle->client, "left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)))
{
error("Cannot register JACK output port 'left'.");
audio_close(ai);
close_jack(ao);
return -1;
}
if (!(handle->ports[1] = jack_port_register(handle->client, "right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)))
{
error("Cannot register JACK output port 'right'.");
audio_close(ai);
close_jack(ao);
return -1;
}
} else {
error1("audio_open(): invalid number of channels (%d).", handle->channels);
audio_close(ai);
error1("invalid number of output channels (%d).", handle->channels);
close_jack(ao);
return -1;
}
@@ -243,14 +262,14 @@ int audio_open(struct audio_info_struct *ai)
/* Activate client*/
if (jack_activate(handle->client)) {
fprintf(stderr, "audio_open(): Can't activate client\n");
error("Can't activate client.");
}
/* Connect up the portsm, return */
if(!connect_jack_ports( handle, ai->device ))
if(!connect_jack_ports( handle, ao->device ))
{
/* deregistering of ports will not work but should just fail, then, and let the rest clean up */
audio_close(ai);
close_jack(ao);
return -1;
}
@@ -259,24 +278,24 @@ int audio_open(struct audio_info_struct *ai)
/* Jack is in fact 32-bit floats only */
int audio_get_formats(struct audio_info_struct *ai)
static int get_formats_jack(audio_output_t *ao)
{
return AUDIO_FORMAT_SIGNED_16;
}
int audio_play_samples(struct audio_info_struct *ai, unsigned char *buf, int len)
static int write_jack(audio_output_t *ao, unsigned char *buf, int len)
{
int c,n = 0;
short* src = (short*)buf;
jack_handle_t *handle = (jack_handle_t*)ai->handle;
jack_handle_t *handle = (jack_handle_t*)ao->userptr;
jack_nframes_t samples = len / 2 / handle->channels;
size_t tmp_size = samples * sizeof( jack_default_audio_sample_t );
/* Sanity check that ring buffer is at least twice the size of the audio we just got*/
if (handle->rb_size/2 < len) {
error("audio_play_samples(): ring buffer is less than twice the size of audio given.");
error("ring buffer is less than twice the size of audio given.");
return -1;
}
@@ -291,7 +310,7 @@ int audio_play_samples(struct audio_info_struct *ai, unsigned char *buf, int len
/* Ensure the temporary buffer is big enough*/
handle->tmp_buffer = (jack_default_audio_sample_t*)realloc( handle->tmp_buffer, tmp_size);
if (!handle->tmp_buffer) {
error("audio_play_samples(): failed to realloc temporary buffer.");
error("failed to realloc temporary buffer.");
return -1;
}
@@ -308,7 +327,7 @@ int audio_play_samples(struct audio_info_struct *ai, unsigned char *buf, int len
len = jack_ringbuffer_write(handle->rb[c], (char*)handle->tmp_buffer, tmp_size);
if (len < tmp_size)
{
error("audio_play_samples(): failed to write to ring ruffer.");
error("failed to write to ring ruffer.");
return -1;
}
}
@@ -317,31 +336,42 @@ int audio_play_samples(struct audio_info_struct *ai, unsigned char *buf, int len
return len;
}
int audio_close(struct audio_info_struct *ai)
static void flush_jack(audio_output_t *ao)
{
jack_handle_t *handle = (jack_handle_t*)ai->handle;
/*fprintf(stderr, "audio_close().\n");*/
/* Close and shutdown*/
if (handle) {
free_jack_handle( handle );
ai->handle = NULL;
}
return 0;
}
void audio_queueflush(struct audio_info_struct *ai)
{
jack_handle_t *handle = (jack_handle_t*)ai->handle;
jack_handle_t *handle = (jack_handle_t*)ao->userptr;
int c;
fprintf(stderr, "audio_queueflush().\n");
/* Reset the ring buffers*/
for(c=0; c<handle->channels; c++) {
jack_ringbuffer_reset(handle->rb[c]);
}
}
static int init_jack(audio_output_t* ao)
{
if (ao==NULL) return -1;
/* Set callbacks */
ao->open = open_jack;
ao->flush = flush_jack;
ao->write = write_jack;
ao->get_formats = get_formats_jack;
ao->close = close_jack;
/* Success */
return 0;
}
/*
Module information data structure
*/
mpg123_module_t mpg123_output_module_info = {
/* api_version */ MPG123_MODULE_API_VERSION,
/* name */ "jack",
/* description */ "Output audio using JACK (JACK Audio Connection Kit).",
/* revision */ "$Rev:$",
/* handle */ NULL,
/* init_output */ init_jack,
};

View File

@@ -1,5 +1,5 @@
/*
audio_libao.c: audio output via libao (now doing something like mpg321;-)
libao: audio output via libao
copyright 2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
@@ -13,25 +13,6 @@
#include "mpg123.h"
static int initialized=0;
static void audio_initialize()
{
if (!initialized) {
ao_initialize();
initialized=1;
}
}
static void audio_shutdown()
{
if (initialized) {
ao_shutdown();
initialized=0;
}
}
int audio_open(struct audio_info_struct *ai)
{
ao_device *device = NULL;
@@ -43,13 +24,13 @@ int audio_open(struct audio_info_struct *ai)
if(!ai) return -1;
/* Return if already open */
if (ai->handle) {
if (ao->handle) {
fprintf(stderr, "audio_open(): error, already open\n");
return -1;
}
/* Work out the sample size */
switch (ai->format) {
switch (ao->format) {
case AUDIO_FORMAT_SIGNED_16:
format.bits = 16;
break;
@@ -65,29 +46,29 @@ int audio_open(struct audio_info_struct *ai)
break;
default:
fprintf(stderr, "audio_open(): Unsupported Audio Format: %d\n", ai->format);
fprintf(stderr, "audio_open(): Unsupported Audio Format: %d\n", ao->format);
return -1;
break;
}
/* Set the reset of the format */
format.channels = ai->channels;
format.rate = ai->rate;
format.channels = ao->channels;
format.rate = ao->rate;
format.byte_format = AO_FMT_NATIVE;
/* Initialize libao */
audio_initialize();
/* Choose the driver to use */
if (ai->device) {
if (ao->device) {
/* parse device:filename; remember to free stuff before bailing out */
char* search_ptr;
if( (search_ptr = strchr(ai->device, ':')) != NULL )
if( (search_ptr = strchr(ao->device, ':')) != NULL )
{
/* going to split up the info in new memory to preserve the original string */
size_t devlen = search_ptr-ai->device+1;
size_t filelen = strlen(ai->device)-devlen+1;
size_t devlen = search_ptr-ao->device+1;
size_t filelen = strlen(ao->device)-devlen+1;
debug("going to allocate %lu:%lu bytes", (unsigned long)devlen, (unsigned long)filelen);
char* devicename = malloc(devlen*sizeof(char));
devicename[devlen-1] = 0;
@@ -95,7 +76,7 @@ int audio_open(struct audio_info_struct *ai)
filename[filelen-1] = 0;
if((devicename != NULL) && (filename != NULL))
{
strncpy(devicename, ai->device, devlen-1);
strncpy(devicename, ao->device, devlen-1);
strncpy(filename, search_ptr+1, filelen-1);
if(filename[0] == 0){ free(filename); filename = NULL; }
}
@@ -109,7 +90,7 @@ int audio_open(struct audio_info_struct *ai)
driver = ao_driver_id( devicename );
if(devicename != NULL) free(devicename);
}
else driver = ao_driver_id( ai->device );
else driver = ao_driver_id( ao->device );
} else {
driver = ao_default_driver_id();
}
@@ -160,7 +141,7 @@ int audio_open(struct audio_info_struct *ai)
if(!err)
{
/* Store it for later */
ai->handle = (void*)device;
ao->handle = (void*)device;
}
/* always do this here! */
if(filename != NULL) free(filename);
@@ -170,15 +151,15 @@ int audio_open(struct audio_info_struct *ai)
/* The two formats we support */
int audio_get_formats(struct audio_info_struct *ai)
int audio_get_formats(audio_output_t *ao)
{
return AUDIO_FORMAT_SIGNED_16 | AUDIO_FORMAT_SIGNED_8;
}
int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
int audio_play_samples(audio_output_t *ao,unsigned char *buf,int len)
{
int res = 0;
ao_device *device = (ao_device*)ai->handle;
ao_device *device = (ao_device*)ao->handle;
res = ao_play(device, (char*)buf, len);
if (res==0) {
@@ -189,14 +170,14 @@ int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
return len;
}
int audio_close(struct audio_info_struct *ai)
int audio_close(audio_output_t *ao)
{
ao_device *device = (ao_device*)ai->handle;
ao_device *device = (ao_device*)ao->handle;
/* Close and shutdown */
if (device) {
ao_close(device);
ai->handle = NULL;
ao->handle = NULL;
}
audio_shutdown();
@@ -204,7 +185,49 @@ int audio_close(struct audio_info_struct *ai)
return 0;
}
void audio_queueflush(struct audio_info_struct *ai)
void audio_queueflush(audio_output_t *ao)
{
}
static int deinit_libao(audio_output_t* ao)
{
ao_shutdown();
}
static int init_libao(audio_output_t* ao)
{
if (ao==NULL) return -1;
/* Initialise LibAO */
ao_initialize();
/* Set callbacks */
ao->open = open_libao;
ao->flush = flush_libao;
ao->write = write_libao;
ao->get_formats = get_formats_libao;
ao->close = close_libao;
ao->deinit = deinit_libao;
/* Success */
return 0;
}
/*
Module information data structure
*/
mpg123_module_t mpg123_output_module_info = {
/* api_version */ MPG123_MODULE_API_VERSION,
/* name */ "libao",
/* description */ "Output audio using LibAO.",
/* revision */ "$Rev:$",
/* handle */ NULL,
/* init_output */ init_libao,
};

View File

@@ -1,5 +1,5 @@
/*
audio_mint: audio output for MINT
mint: audio output for MINT
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
@@ -18,30 +18,30 @@ int real_rate_printed = 0;
static int audio_rate_best_match(struct audio_info_struct *ai)
static int audio_rate_best_match(audio_output_t *ao)
{
int ret,dsp_rate;
if(!ai || ai->fn < 0 || ai->rate < 0)
if(!ai || ao->fn < 0 || ao->rate < 0)
return -1;
dsp_rate = ai->rate;
ret = ioctl(ai->fn,AIOCSSPEED, (void *)dsp_rate);
ret = ioctl(ai->fn,AIOCGSPEED,&dsp_rate);
dsp_rate = ao->rate;
ret = ioctl(ao->fn,AIOCSSPEED, (void *)dsp_rate);
ret = ioctl(ao->fn,AIOCGSPEED,&dsp_rate);
if(ret < 0)
return ret;
ai->rate = dsp_rate;
ao->rate = dsp_rate;
return 0;
}
static int audio_set_rate(struct audio_info_struct *ai)
static int audio_set_rate(audio_output_t *ao)
{
int dsp_rate = ai->rate;
int dsp_rate = ao->rate;
if(ai->rate >= 0) {
if(ao->rate >= 0) {
int ret, real_rate;
ret = ioctl(ai->fn, AIOCSSPEED, (void *)dsp_rate);
ret = ioctl(ao->fn, AIOCSSPEED, (void *)dsp_rate);
if (ret >= 0 && !real_rate_printed) {
ioctl(ai->fn,AIOCGSPEED,&real_rate);
ioctl(ao->fn,AIOCGSPEED,&real_rate);
if (real_rate != dsp_rate) {
fprintf(stderr, "Replay rate: %d Hz\n", real_rate);
real_rate_printed = 1;
@@ -53,24 +53,24 @@ static int audio_set_rate(struct audio_info_struct *ai)
return 0;
}
static int audio_set_channels(struct audio_info_struct *ai)
static int audio_set_channels(audio_output_t *ao)
{
int chan = ai->channels;
int chan = ao->channels;
if(ai->channels < 1)
if(ao->channels < 1)
return 0;
return ioctl(ai->fn, AIOCSCHAN, (void *)chan);
return ioctl(ao->fn, AIOCSCHAN, (void *)chan);
}
static int audio_set_format(struct audio_info_struct *ai)
static int audio_set_format(audio_output_t *ao)
{
int fmts;
if(ai->format == -1)
if(ao->format == -1)
return 0;
switch(ai->format) {
switch(ao->format) {
case AUDIO_FORMAT_SIGNED_16:
default:
fmts = AFMT_S16;
@@ -85,13 +85,13 @@ static int audio_set_format(struct audio_info_struct *ai)
fmts = AFMT_ULAW;
break;
}
return ioctl(ai->fn, AIOCSFMT, (void *)fmts);
return ioctl(ao->fn, AIOCSFMT, (void *)fmts);
}
static int audio_reset_parameters(struct audio_info_struct *ai)
static int audio_reset_parameters(audio_output_t *ao)
{
int ret;
ret = ioctl(ai->fn,AIOCRESET,NULL);
ret = ioctl(ao->fn,AIOCRESET,NULL);
if(ret >= 0)
ret = audio_set_format(ai);
if(ret >= 0)
@@ -103,36 +103,36 @@ static int audio_reset_parameters(struct audio_info_struct *ai)
int audio_open(struct audio_info_struct *ai)
int audio_open(audio_output_t *ao)
{
if(!ai)
return -1;
if(!ai->device)
ai->device = "/dev/audio";
if(!ao->device)
ao->device = "/dev/audio";
ai->fn = open(ai->device,O_WRONLY);
ao->fn = open(ao->device,O_WRONLY);
if(ai->fn < 0)
if(ao->fn < 0)
{
error1("Can't open %s!",ai->device);
error1("Can't open %s!",ao->device);
return -1;
}
ioctl(ai->fn, AIOCGBLKSIZE, &outburst);
ioctl(ao->fn, AIOCGBLKSIZE, &outburst);
if(outburst > MAXOUTBURST)
outburst = MAXOUTBURST;
if(audio_reset_parameters(ai) < 0) {
close(ai->fn);
close(ao->fn);
return -1;
}
return ai->fn;
return ao->fn;
}
int audio_get_formats(struct audio_info_struct *ai)
int audio_get_formats(audio_output_t *ao)
{
int ret = 0;
int fmts;
if(ioctl(ai->fn,AIOCGFMTS,&fmts) < 0)
if(ioctl(ao->fn,AIOCGFMTS,&fmts) < 0)
return -1;
if(fmts & AFMT_ULAW)
@@ -147,18 +147,18 @@ int audio_get_formats(struct audio_info_struct *ai)
return ret;
}
int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
int audio_play_samples(audio_output_t *ao,unsigned char *buf,int len)
{
return write(ai->fn,buf,len);
return write(ao->fn,buf,len);
}
int audio_close(struct audio_info_struct *ai)
int audio_close(audio_output_t *ao)
{
close (ai->fn);
close (ao->fn);
return 0;
}
void audio_queueflush(struct audio_info_struct *ai)
void audio_queueflush(audio_output_t *ao)
{
}

View File

@@ -1,5 +1,5 @@
/*
audio_nas: audio output via NAS
nas: audio output via NAS
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
@@ -28,12 +28,13 @@ typedef struct
#define NAS_SOUND_LOW_WATER_MARK 25 /* percent */
#define NAS_MAX_FORMAT 10 /* currently, there are 7 supported formats */
/* FIXME: stick this inside userptr inside audio_output_t instead */
static InfoRec info;
/* NAS specific routines */
static void
nas_sendData(AuServer *aud, InfoPtr i, AuUint32 numBytes)
static void nas_sendData(AuServer *aud, InfoPtr i, AuUint32 numBytes)
{
if (numBytes < i->buf_cnt) {
AuWriteElement(aud, i->flow, 0, numBytes, i->buf, AuFalse, NULL);
@@ -48,8 +49,7 @@ nas_sendData(AuServer *aud, InfoPtr i, AuUint32 numBytes)
i->data_sent = AuTrue;
}
static AuBool
nas_eventHandler(AuServer *aud, AuEvent *ev, AuEventHandlerRec *handler)
static AuBool nas_eventHandler(AuServer *aud, AuEvent *ev, AuEventHandlerRec *handler)
{
InfoPtr i = (InfoPtr) handler->data;
@@ -85,7 +85,7 @@ nas_eventHandler(AuServer *aud, AuEvent *ev, AuEventHandlerRec *handler)
}
/* 0 on error */
int nas_createFlow(struct audio_info_struct *ai)
static int nas_createFlow(audio_output_t *ao)
{
AuDeviceID device = AuNone;
AuElement elements[2];
@@ -94,7 +94,7 @@ int nas_createFlow(struct audio_info_struct *ai)
int i;
switch(ai->format) {
switch(ao->format) {
case AUDIO_FORMAT_SIGNED_16:
default:
if (((char) *(short *)"x")=='x') /* ugly, but painless */
@@ -117,20 +117,20 @@ int nas_createFlow(struct audio_info_struct *ai)
if (((AuDeviceKind(AuServerDevice(info.aud, i)) ==
AuComponentKindPhysicalOutput) &&
AuDeviceNumTracks(AuServerDevice(info.aud, i))
== ai->channels )) {
== ao->channels )) {
device = AuDeviceIdentifier(AuServerDevice(info.aud, i));
break;
}
if (device == AuNone) {
error1("Couldn't find an output device providing %d channels.", ai->channels);
error1("Couldn't find an output device providing %d channels.", ao->channels);
return 0;
}
/* set gain */
if(ai->gain >= 0) {
if(ao->gain >= 0) {
info.da = AuGetDeviceAttributes(info.aud, device, NULL);
if ((info.da)!=NULL) {
AuDeviceGain(info.da) = AuFixedPointFromSum(ai->gain, 0);
AuDeviceGain(info.da) = AuFixedPointFromSum(ao->gain, 0);
AuSetDeviceAttributes(info.aud, AuDeviceIdentifier(info.da),
AuCompDeviceGainMask, info.da, NULL);
}
@@ -143,13 +143,13 @@ int nas_createFlow(struct audio_info_struct *ai)
return 0;
}
buf_samples = ai->rate * NAS_SOUND_PORT_DURATION;
buf_samples = ao->rate * NAS_SOUND_PORT_DURATION;
AuMakeElementImportClient(&elements[0], /* element */
(unsigned short) ai->rate,
(unsigned short) ao->rate,
/* rate */
format, /* format */
ai->channels, /* channels */
ao->channels, /* channels */
AuTrue, /* ??? */
buf_samples, /* max samples */
(AuUint32) (buf_samples / 100
@@ -160,7 +160,7 @@ int nas_createFlow(struct audio_info_struct *ai)
AuMakeElementExportDevice(&elements[1], /* element */
0, /* input */
device, /* device */
(unsigned short) ai->rate,
(unsigned short) ao->rate,
/* rate */
AuUnlimitedSamples, /* num samples */
0, /* num actions */
@@ -179,7 +179,7 @@ int nas_createFlow(struct audio_info_struct *ai)
nas_eventHandler, /* callback */
(AuPointer) &info); /* data */
info.buf_size = buf_samples * ai->channels * AuSizeofFormat(format);
info.buf_size = buf_samples * ao->channels * AuSizeofFormat(format);
info.buf = (char *) malloc(info.buf_size);
if (info.buf == NULL) {
error1("Unable to allocate input/output buffer of size %ld",
@@ -197,7 +197,7 @@ int nas_createFlow(struct audio_info_struct *ai)
}
void nas_flush()
static void flush_nas(audio_output_t *ao)
{
AuEvent ev;
@@ -208,19 +208,18 @@ void nas_flush()
info.data_sent = AuFalse;
}
/* required functions */
/* returning -1 on error, 0 on success... */
int audio_open(struct audio_info_struct *ai)
static int open_nas(audio_output_t *ao)
{
if(!ai)
return -1;
if(!ao) return -1;
if (!(info.aud = AuOpenServer(ai->device, 0, NULL, 0, NULL, NULL))) {
if (ai->device==NULL)
if (!(info.aud = AuOpenServer(ao->device, 0, NULL, 0, NULL, NULL))) {
if (ao->device==NULL) {
error("could not open default NAS server");
else
error1("could not open NAS server %s\n", ai->device);
} else {
error1("could not open NAS server %s\n", ao->device);
}
return -1;
}
info.buf_size = 0;
@@ -229,7 +228,7 @@ int audio_open(struct audio_info_struct *ai)
}
int audio_get_formats(struct audio_info_struct *ai)
static int get_formats_nas(audio_output_t *ao)
{
int i, j, k, ret;
@@ -256,12 +255,12 @@ int audio_get_formats(struct audio_info_struct *ai)
return ret;
}
int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
static int write_nas(audio_output_t *ao,unsigned char *buf,int len)
{
int buf_cnt = 0;
if (info.buf_size == 0)
if(!nas_createFlow(ai)) return -1;
if(!nas_createFlow(ao)) return -1;
while ((info.buf_cnt + (len - buf_cnt)) > info.buf_size) {
memcpy(info.buf + info.buf_cnt,
@@ -269,7 +268,7 @@ int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
(info.buf_size - info.buf_cnt));
buf_cnt += (info.buf_size - info.buf_cnt);
info.buf_cnt += (info.buf_size - info.buf_cnt);
nas_flush();
flush_nas(ao);
}
memcpy(info.buf + info.buf_cnt,
buf + buf_cnt,
@@ -279,7 +278,7 @@ int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
return len;
}
int audio_close(struct audio_info_struct *ai)
static int close_nas(audio_output_t *ao)
{
if (info.aud == NULL) {
return 0;
@@ -292,7 +291,7 @@ int audio_close(struct audio_info_struct *ai)
}
while (!info.finished) {
nas_flush();
flush_nas(ao);
}
AuCloseServer(info.aud);
free(info.buf);
@@ -300,6 +299,38 @@ int audio_close(struct audio_info_struct *ai)
return 0;
}
void audio_queueflush(struct audio_info_struct *ai)
static int init_nas(audio_output_t* ao)
{
if (ao==NULL) return -1;
/* Set callbacks */
ao->open = open_nas;
ao->flush = flush_nas;
ao->write = write_nas;
ao->get_formats = get_formats_nas;
ao->close = close_nas;
/* Success */
return 0;
}
/*
Module information data structure
*/
mpg123_module_t mpg123_output_module_info = {
/* api_version */ MPG123_MODULE_API_VERSION,
/* name */ "nas",
/* description */ "Output audio using NAS (Network Audio System)",
/* revision */ "$Rev:$",
/* handle */ NULL,
/* init_output */ init_nas,
};

View File

@@ -1,5 +1,5 @@
/*
audio_os2: OS/2 RealTime DART Engine
os2: OS/2 RealTime DART Engine
copyright 1998-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
@@ -137,7 +137,7 @@ static void MciError(ULONG ulError)
fprintf(stderr,"%s",mmerror);
}
int audio_set_volume(struct audio_info_struct *ai, USHORT setvolume)
int audio_set_volume(audio_output_t *ao, USHORT setvolume)
{
if(setvolume > 100) setvolume = 100;
volume = setvolume; /* useful when device is closed and reopened */
@@ -154,7 +154,7 @@ int audio_set_volume(struct audio_info_struct *ai, USHORT setvolume)
return setvolume;
}
int audio_pause(struct audio_info_struct *ai, int pause)
int audio_pause(audio_output_t *ao, int pause)
{
if(maop.usDeviceID)
{
@@ -170,7 +170,7 @@ int audio_pause(struct audio_info_struct *ai, int pause)
return pause;
}
int audio_open(struct audio_info_struct *ai)
int audio_open(audio_output_t *ao)
{
ULONG rc,i;
char *temp;
@@ -182,22 +182,22 @@ int audio_open(struct audio_info_struct *ai)
if(!ai) return -1;
if(!ai->device) ai->device = "0";
if(!ao->device) ao->device = "0";
if(ai->rate < 0) ai->rate = 44100;
if(ai->channels < 0) ai->channels = 2;
if(ai->format < 0) ai->format = AUDIO_FORMAT_SIGNED_16;
if(ao->rate < 0) ao->rate = 44100;
if(ao->channels < 0) ao->channels = 2;
if(ao->format < 0) ao->format = AUDIO_FORMAT_SIGNED_16;
if(ai->format == AUDIO_FORMAT_SIGNED_16)
if(ao->format == AUDIO_FORMAT_SIGNED_16)
bits = 16;
else if(ai->format == AUDIO_FORMAT_UNSIGNED_8)
else if(ao->format == AUDIO_FORMAT_UNSIGNED_8)
bits = 8;
else return -1;
/* open the mixer device */
memset (&maop, 0, sizeof(maop));
maop.usDeviceID = 0;
maop.pszDeviceType = (PSZ) MAKEULONG(MCI_DEVTYPE_AUDIO_AMPMIX, atoi(ai->device));
maop.pszDeviceType = (PSZ) MAKEULONG(MCI_DEVTYPE_AUDIO_AMPMIX, atoi(ao->device));
openflags = MCI_WAIT | MCI_OPEN_TYPE_ID;
if(!lockdevice) openflags |= MCI_OPEN_SHAREABLE;
@@ -215,7 +215,7 @@ int audio_open(struct audio_info_struct *ai)
return(-1);
}
/* volume in ai->gain ?? */
/* volume in ao->gain ?? */
/* Set the MCI_MIXSETUP_PARMS data structure to match the audio stream. */
@@ -223,8 +223,8 @@ int audio_open(struct audio_info_struct *ai)
mmp.ulBitsPerSample = bits;
mmp.ulFormatTag = MCI_WAVE_FORMAT_PCM;
mmp.ulSamplesPerSec = ai->rate;
mmp.ulChannels = ai->channels;
mmp.ulSamplesPerSec = ao->rate;
mmp.ulChannels = ao->channels;
/* Setup the mixer for playback of wave data */
mmp.ulFormatMode = MCI_PLAY;
@@ -345,7 +345,7 @@ int audio_open(struct audio_info_struct *ai)
return maop.usDeviceID;
}
int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
int audio_play_samples(audio_output_t *ao,unsigned char *buf,int len)
{
/* if we're too quick, let's wait */
if(nobuffermode)
@@ -390,18 +390,18 @@ int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
return len;
}
int audio_playing_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
int audio_playing_samples(audio_output_t *ao,unsigned char *buf,int len)
{
if(len > audiobufsize || !playingbuffer) return -1;
if(mmp.ulBitsPerSample == 16)
ai->format = AUDIO_FORMAT_SIGNED_16;
ao->format = AUDIO_FORMAT_SIGNED_16;
else if(mmp.ulBitsPerSample == 8)
ai->format = AUDIO_FORMAT_UNSIGNED_8;
ao->format = AUDIO_FORMAT_UNSIGNED_8;
else return -1;
ai->rate = mmp.ulSamplesPerSec;
ai->channels = mmp.ulChannels;
ao->rate = mmp.ulSamplesPerSec;
ao->channels = mmp.ulChannels;
if(buf && len)
{
@@ -445,13 +445,13 @@ int audio_playing_samples(struct audio_info_struct *ai,unsigned char *buf,int le
return 0;
}
int audio_nobuffermode(struct audio_info_struct *ai, int setnobuffermode)
int audio_nobuffermode(audio_output_t *ao, int setnobuffermode)
{
nobuffermode = setnobuffermode;
return TRUE;
}
int audio_trash_buffers(struct audio_info_struct *ai)
int audio_trash_buffers(audio_output_t *ao)
{
int i;
@@ -467,7 +467,7 @@ int audio_trash_buffers(struct audio_info_struct *ai)
return TRUE;
}
int audio_close(struct audio_info_struct *ai)
int audio_close(audio_output_t *ao)
{
ULONG rc;
@@ -526,7 +526,7 @@ int audio_close(struct audio_info_struct *ai)
/*
* get formats for specific channel/rate parameters
*/
int audio_get_formats(struct audio_info_struct *ai)
int audio_get_formats(audio_output_t *ao)
{
int fmts = 0;
ULONG rc;
@@ -536,8 +536,8 @@ int audio_get_formats(struct audio_info_struct *ai)
mmp.pmixEvent = DARTEvent;
mmptemp.ulFormatMode = MCI_PLAY;
mmptemp.ulSamplesPerSec = ai->rate;
mmptemp.ulChannels = ai->channels;
mmptemp.ulSamplesPerSec = ao->rate;
mmptemp.ulChannels = ao->channels;
mmptemp.ulFormatTag = MCI_WAVE_FORMAT_PCM;
mmptemp.ulBitsPerSample = 16;
@@ -634,6 +634,6 @@ int audio_get_devices(char *info, int deviceid)
}
}
void audio_queueflush(struct audio_info_struct *ai)
void audio_queueflush(audio_output_t *ao)
{
}

322
src/output/oss.c Normal file
View File

@@ -0,0 +1,322 @@
/*
oss: audio output via Open Sound System
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
#include <sys/ioctl.h>
#include <fcntl.h>
#include "mpg123.h"
#ifdef HAVE_LINUX_SOUNDCARD_H
#include <linux/soundcard.h>
#endif
#ifdef HAVE_SYS_SOUNDCARD_H
#include <sys/soundcard.h>
#endif
#ifdef HAVE_MACHINE_SOUNDCARD_H
#include <machine/soundcard.h>
#endif
#ifndef AFMT_S16_NE
# ifdef OSS_BIG_ENDIAN
# define AFMT_S16_NE AFMT_S16_BE
# else
# define AFMT_S16_NE AFMT_S16_LE
# endif
#endif
#ifndef AFMT_U16_NE
# ifdef OSS_BIG_ENDIAN
# define AFMT_U16_NE AFMT_U16_BE
# else
# define AFMT_U16_NE AFMT_U16_LE
# endif
#endif
static int rate_best_match_oss(audio_output_t *ao)
{
int ret,dsp_rate;
if(!ao || ao->fn < 0 || ao->rate < 0) return -1;
dsp_rate = ao->rate;
ret = ioctl(ao->fn, SNDCTL_DSP_SPEED,&dsp_rate);
if(ret < 0) return ret;
ao->rate = dsp_rate;
return 0;
}
static int set_rate_oss(audio_output_t *ao)
{
int dsp_rate;
int ret = 0;
if(ao->rate >= 0) {
dsp_rate = ao->rate;
ret = ioctl(ao->fn, SNDCTL_DSP_SPEED,&dsp_rate);
}
return ret;
}
static int set_channels_oss(audio_output_t *ao)
{
int chan = ao->channels - 1;
int ret;
if(ao->channels < 0) return 0;
ret = ioctl(ao->fn, SNDCTL_DSP_STEREO, &chan);
if(chan != (ao->channels-1)) return -1;
return ret;
}
static int set_format_oss(audio_output_t *ao)
{
int sample_size,fmts;
int sf,ret;
if(ao->format == -1) return 0;
switch(ao->format) {
case AUDIO_FORMAT_SIGNED_16:
default:
fmts = AFMT_S16_NE;
sample_size = 16;
break;
case AUDIO_FORMAT_UNSIGNED_8:
fmts = AFMT_U8;
sample_size = 8;
break;
case AUDIO_FORMAT_SIGNED_8:
fmts = AFMT_S8;
sample_size = 8;
break;
case AUDIO_FORMAT_ULAW_8:
fmts = AFMT_MU_LAW;
sample_size = 8;
break;
case AUDIO_FORMAT_ALAW_8:
fmts = AFMT_A_LAW;
sample_size = 8;
break;
case AUDIO_FORMAT_UNSIGNED_16:
fmts = AFMT_U16_NE;
break;
}
#if 0
if(ioctl(ao->fn, SNDCTL_DSP_SAMPLESIZE, &sample_size) < 0)
return -1;
#endif
sf = fmts;
ret = ioctl(ao->fn, SNDCTL_DSP_SETFMT, &fmts);
if(sf != fmts) return -1;
return ret;
}
static int reset_parameters_oss(audio_output_t *ao)
{
int ret;
ret = ioctl(ao->fn, SNDCTL_DSP_RESET, NULL);
if(ret < 0) error("Can't reset audio!");
ret = set_format_oss(ao);
if (ret == -1) goto err;
ret = set_channels_oss(ao);
if (ret == -1) goto err;
ret = set_rate_oss(ao);
if (ret == -1) goto err;
/* Careful here. As per OSS v1.1, the next ioctl() commits the format
* set above, so we must issue SNDCTL_DSP_RESET before we're allowed to
* change it again. [dk]
*/
/* FIXME: this needs re-enabled (but not using global variables this time):
if (ioctl(ao->fn, SNDCTL_DSP_GETBLKSIZE, &outburst) == -1 ||
outburst > MAXOUTBURST)
outburst = MAXOUTBURST;
*/
err:
return ret;
}
static int open_oss(audio_output_t *ao)
{
char usingdefdev = 0;
if(!ao) return -1;
if(!ao->device) {
ao->device = "/dev/dsp";
usingdefdev = 1;
}
ao->fn = open(ao->device,O_WRONLY);
if(ao->fn < 0)
{
if(usingdefdev) {
ao->device = "/dev/sound/dsp";
ao->fn = open(ao->device,O_WRONLY);
if(ao->fn < 0) {
error("Can't open default sound device!");
return -1;
}
} else {
error1("Can't open %s!",ao->device);
return -1;
}
}
if(reset_parameters_oss(ao) < 0) {
close(ao->fn);
return -1;
}
if(ao->gain >= 0) {
int e,mask;
e = ioctl(ao->fn , SOUND_MIXER_READ_DEVMASK ,&mask);
if(e < 0) {
error("audio/gain: Can't get audio device features list.");
}
else if(mask & SOUND_MASK_PCM) {
int gain = (ao->gain<<8)|(ao->gain);
e = ioctl(ao->fn, SOUND_MIXER_WRITE_PCM , &gain);
}
else if(!(mask & SOUND_MASK_VOLUME)) {
error1("audio/gain: setable Volume/PCM-Level not supported by your audio device: %#04x",mask);
}
else {
int gain = (ao->gain<<8)|(ao->gain);
e = ioctl(ao->fn, SOUND_MIXER_WRITE_VOLUME , &gain);
}
}
return ao->fn;
}
/*
* get formats for specific channel/rate parameters
*/
static int get_formats_oss(audio_output_t *ao)
{
int fmt = 0;
int r = ao->rate;
int c = ao->channels;
int i;
static int fmts[] = {
AUDIO_FORMAT_ULAW_8 , AUDIO_FORMAT_SIGNED_16 ,
AUDIO_FORMAT_UNSIGNED_8 , AUDIO_FORMAT_SIGNED_8 ,
AUDIO_FORMAT_UNSIGNED_16 , AUDIO_FORMAT_ALAW_8
};
/* Reset is required before we're allowed to set the new formats. [dk] */
ioctl(ao->fn, SNDCTL_DSP_RESET, NULL);
for(i=0;i<6;i++) {
ao->format = fmts[i];
if(set_format_oss(ao) < 0) {
continue;
}
ao->channels = c;
if(set_channels_oss(ao) < 0) {
continue;
}
ao->rate = r;
if(rate_best_match_oss(ao) < 0) {
continue;
}
if( (ao->rate*100 > r*(100-AUDIO_RATE_TOLERANCE)) && (ao->rate*100 < r*(100+AUDIO_RATE_TOLERANCE)) ) {
fmt |= fmts[i];
}
}
#if 0
if(ioctl(ao->fn,SNDCTL_DSP_GETFMTS,&fmts) < 0) {
fprintf(stderr,"No");
return -1;
}
if(fmts & AFMT_MU_LAW)
ret |= AUDIO_FORMAT_ULAW_8;
if(fmts & AFMT_S16_NE)
ret |= AUDIO_FORMAT_SIGNED_16;
if(fmts & AFMT_U8)
ret |= AUDIO_FORMAT_UNSIGNED_8;
if(fmts & AFMT_S8)
ret |= AUDIO_FORMAT_SIGNED_8;
if(fmts & AFMT_U16_NE)
ret |= AUDIO_FORMAT_UNSIGNED_16;
if(fmts & AFMT_A_LAW)
ret |= AUDIO_FORMAT_ALAW_8;
#endif
return fmt;
}
static int write_oss(audio_output_t *ao,unsigned char *buf,int len)
{
return write(ao->fn,buf,len);
}
static int close_oss(audio_output_t *ao)
{
close (ao->fn);
return 0;
}
static void flush_oss(audio_output_t *ao)
{
}
static int init_oss(audio_output_t* ao)
{
if (ao==NULL) return -1;
/* Set callbacks */
ao->open = open_oss;
ao->flush = flush_oss;
ao->write = write_oss;
ao->get_formats = get_formats_oss;
ao->close = close_oss;
/* Success */
return 0;
}
/*
Module information data structure
*/
mpg123_module_t mpg123_output_module_info = {
/* api_version */ MPG123_MODULE_API_VERSION,
/* name */ "oss",
/* description */ "Output audio using OSS",
/* revision */ "$Rev$",
/* handle */ NULL,
/* init_output */ init_oss,
};

View File

@@ -1,5 +1,5 @@
/*
audio_portaudio: audio output via PortAudio cross-platform audio API
portaudio: audio output via PortAudio cross-platform audio API
copyright 2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
@@ -23,7 +23,6 @@
#define FIFO_DURATION (0.5f)
static int pa_initialised=0;
static PaStream *pa_stream=NULL;
static sfifo_t fifo;
@@ -34,8 +33,8 @@ static int paCallback( void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
PaTimestamp outTime, void *userData )
{
struct audio_info_struct *ai = userData;
unsigned long bytes = framesPerBuffer * SAMPLE_SIZE * ai->channels;
audio_output_t *ao = userData;
unsigned long bytes = framesPerBuffer * SAMPLE_SIZE * ao->channels;
if (sfifo_used(&fifo)<bytes) {
error("ringbuffer for PortAudio is empty");
@@ -47,36 +46,23 @@ static int paCallback( void *inputBuffer, void *outputBuffer,
}
int audio_open(struct audio_info_struct *ai)
static int open_portaudio(audio_output_t *ao)
{
PaError err;
/* Initialise PortAudio */
if (!pa_initialised) {
err = Pa_Initialize();
if( err != paNoError ) {
error1("Failed to initialise PortAudio: %s", Pa_GetErrorText( err ));
return -1;
} else {
pa_initialised=1;
}
}
/* Open an audio I/O stream. */
if (ai->rate > 0 && ai->channels >0 ) {
if (ao->rate > 0 && ao->channels >0 ) {
err = Pa_OpenDefaultStream(
&pa_stream,
0, /* no input channels */
ai->channels, /* number of output channels */
ao->channels, /* number of output channels */
paInt16, /* signed 16-bit samples */
ai->rate, /* sample rate */
ao->rate, /* sample rate */
FRAMES_PER_BUFFER, /* frames per buffer */
0, /* number of buffers, if zero then use default minimum */
paCallback, /* no callback - use blocking IO */
ai );
ao );
if( err != paNoError ) {
error1("Failed to open PortAudio default stream: %s", Pa_GetErrorText( err ));
@@ -84,7 +70,7 @@ int audio_open(struct audio_info_struct *ai)
}
/* Initialise FIFO */
sfifo_init( &fifo, ai->rate * FIFO_DURATION * SAMPLE_SIZE *ai->channels );
sfifo_init( &fifo, ao->rate * FIFO_DURATION * SAMPLE_SIZE *ao->channels );
}
@@ -92,14 +78,14 @@ int audio_open(struct audio_info_struct *ai)
}
int audio_get_formats(struct audio_info_struct *ai)
static int get_formats_portaudio(audio_output_t *ao)
{
/* Only implemented Signed 16-bit audio for now */
return AUDIO_FORMAT_SIGNED_16;
}
int audio_play_samples(struct audio_info_struct *ai, unsigned char *buf, int len)
static int write_portaudio(audio_output_t *ao, unsigned char *buf, int len)
{
PaError err;
int written;
@@ -132,7 +118,7 @@ int audio_play_samples(struct audio_info_struct *ai, unsigned char *buf, int len
return written;
}
int audio_close(struct audio_info_struct *ai)
static int close_portaudio(audio_output_t *ao)
{
PaError err;
@@ -141,7 +127,7 @@ int audio_close(struct audio_info_struct *ai)
if (Pa_StreamActive( pa_stream ) == 1) {
err = Pa_StopStream( pa_stream );
if( err != paNoError ) {
fprintf(stderr, "Failed to stop PortAudio stream: %s", Pa_GetErrorText( err ));
error1("Failed to stop PortAudio stream: %s", Pa_GetErrorText( err ));
return -1;
}
}
@@ -149,7 +135,7 @@ int audio_close(struct audio_info_struct *ai)
/* and then close the stream */
err = Pa_CloseStream( pa_stream );
if( err != paNoError ) {
fprintf(stderr, "Failed to close PortAudio stream: %s", Pa_GetErrorText( err ));
error1("Failed to close PortAudio stream: %s", Pa_GetErrorText( err ));
return -1;
}
@@ -162,7 +148,7 @@ int audio_close(struct audio_info_struct *ai)
return 0;
}
void audio_queueflush(struct audio_info_struct *ai)
static void flush_portaudio(audio_output_t *ao)
{
PaError err;
@@ -174,3 +160,43 @@ void audio_queueflush(struct audio_info_struct *ai)
}
static int init_portaudio(audio_output_t* ao)
{
int err = paNoError;
if (ao==NULL) return -1;
/* Initialise PortAudio */
err = Pa_Initialize();
if( err != paNoError ) {
error1("Failed to initialise PortAudio: %s", Pa_GetErrorText( err ));
return -1;
}
/* Set callbacks */
ao->open = open_portaudio;
ao->flush = flush_portaudio;
ao->write = write_portaudio;
ao->get_formats = get_formats_portaudio;
ao->close = close_portaudio;
/* Success */
return 0;
}
/*
Module information data structure
*/
mpg123_module_t mpg123_output_module_info = {
/* api_version */ MPG123_MODULE_API_VERSION,
/* name */ "portaudio",
/* description */ "Output audio using PortAudio",
/* revision */ "$Rev:$",
/* handle */ NULL,
/* init_output */ init_portaudio,
};

View File

@@ -1,5 +1,5 @@
/*
audio_portaudio.c: audio output via PortAudio cross-platform audio API
sdl: audio output via SDL cross-platform API
copyright 2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
@@ -19,7 +19,6 @@
#define FRAMES_PER_BUFFER (256)
#define FIFO_DURATION (0.5f)
static int sdl_initialised=0;
static sfifo_t fifo;
@@ -28,10 +27,9 @@ static sfifo_t fifo;
stream: A pointer to the audio buffer to be filled
len: The length (in bytes) of the audio buffer
*/
static void
audio_callback_sdl(void *udata, Uint8 *stream, int len)
static void audio_callback_sdl(void *udata, Uint8 *stream, int len)
{
/* struct audio_info_struct *ai = udata; */
/* audio_output_t *ao = udata; */
int read;
/* Only play if we have data left */
@@ -49,23 +47,11 @@ audio_callback_sdl(void *udata, Uint8 *stream, int len)
}
int audio_open(struct audio_info_struct *ai)
static int open_sdl(audio_output_t *ao)
{
/* Initalise SDL */
if (!sdl_initialised) {
if (SDL_Init( SDL_INIT_AUDIO ) ) {
error1("Failed to initialise SDL: %s\n", SDL_GetError());
return -1;
}
sdl_initialised=1;
}
/* Open an audio I/O stream. */
if (ai->rate > 0 && ai->channels >0 ) {
if (ao->rate > 0 && ao->channels >0 ) {
SDL_AudioSpec wanted;
size_t ringbuffer_len;
@@ -74,9 +60,9 @@ int audio_open(struct audio_info_struct *ai)
wanted.format = AUDIO_S16SYS;
wanted.samples = 1024; /* Good low-latency value for callback */
wanted.callback = audio_callback_sdl;
wanted.userdata = ai;
wanted.channels = ai->channels;
wanted.freq = ai->rate;
wanted.userdata = ao;
wanted.channels = ao->channels;
wanted.freq = ao->rate;
/* Open the audio device, forcing the desired format */
if ( SDL_OpenAudio(&wanted, NULL) ) {
@@ -85,8 +71,8 @@ int audio_open(struct audio_info_struct *ai)
}
/* Initialise FIFO */
ringbuffer_len = ai->rate * FIFO_DURATION * SAMPLE_SIZE *ai->channels;
debug2( "Allocating %d byte ring-buffer (%f seconds)", ringbuffer_len, (float)FIFO_DURATION);
ringbuffer_len = ao->rate * FIFO_DURATION * SAMPLE_SIZE *ao->channels;
debug2( "Allocating %d byte ring-buffer (%f seconds)", (int)ringbuffer_len, (float)FIFO_DURATION);
sfifo_init( &fifo, ringbuffer_len );
}
@@ -95,14 +81,14 @@ int audio_open(struct audio_info_struct *ai)
}
int audio_get_formats(struct audio_info_struct *ai)
static int get_formats_sdl(audio_output_t *ao)
{
/* Only implemented Signed 16-bit audio for now */
return AUDIO_FORMAT_SIGNED_16;
}
int audio_play_samples(struct audio_info_struct *ai, unsigned char *buf, int len)
static int write_sdl(audio_output_t *ao, unsigned char *buf, int len)
{
/* Sleep for half the length of the FIFO */
@@ -128,7 +114,7 @@ int audio_play_samples(struct audio_info_struct *ai, unsigned char *buf, int len
return len;
}
int audio_close(struct audio_info_struct *ai)
static int close_sdl(audio_output_t *ao)
{
SDL_CloseAudio();
@@ -137,10 +123,46 @@ int audio_close(struct audio_info_struct *ai)
return 0;
}
void audio_queueflush(struct audio_info_struct *ai)
static void flush_sdl(audio_output_t *ao)
{
SDL_PauseAudio(1);
sfifo_flush( &fifo );
}
static int init_sdl(audio_output_t* ao)
{
if (ao==NULL) return -1;
/* Initialise SDL */
if (SDL_Init( SDL_INIT_AUDIO ) ) {
error1("Failed to initialise SDL: %s\n", SDL_GetError());
return -1;
}
/* Set callbacks */
ao->open = open_sdl;
ao->flush = flush_sdl;
ao->write = write_sdl;
ao->get_formats = get_formats_sdl;
ao->close = close_sdl;
/* Success */
return 0;
}
/*
Module information data structure
*/
mpg123_module_t mpg123_output_module_info = {
/* api_version */ MPG123_MODULE_API_VERSION,
/* name */ "sdl",
/* description */ "Output audio using SDL (Simple DirectMedia Layer).",
/* revision */ "$Rev:$",
/* handle */ NULL,
/* init_output */ init_sdl,
};

View File

@@ -1,5 +1,5 @@
/*
audio_sgi.c: audio output on sgi boxen
sgi: audio output on SGI boxen
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
@@ -18,7 +18,7 @@
static const char analog_output_res_name[] = ".AnalogOut";
static int audio_set_rate(struct audio_info_struct *ai, ALconfig config)
static int audio_set_rate(audio_output_t *ao, ALconfig config)
{
int dev = alGetDevice(config);
ALpv params[1];
@@ -31,7 +31,7 @@ static int audio_set_rate(struct audio_info_struct *ai, ALconfig config)
}
params[0].param = AL_OUTPUT_RATE;
params[0].value.ll = alDoubleToFixed(ai->rate);
params[0].value.ll = alDoubleToFixed(ao->rate);
if (alSetParams(dev, params,1) < 0)
fprintf(stderr,"audio_set_rate : %s\n",alGetErrorString(oserror()));
@@ -39,11 +39,11 @@ static int audio_set_rate(struct audio_info_struct *ai, ALconfig config)
return 0;
}
static int audio_set_channels(struct audio_info_struct *ai, ALconfig config)
static int audio_set_channels(audio_output_t *ao, ALconfig config)
{
int ret;
if(ai->channels == 2)
if(ao->channels == 2)
ret = alSetChannels(config, AL_STEREO);
else
ret = alSetChannels(config, AL_MONO);
@@ -54,7 +54,7 @@ static int audio_set_channels(struct audio_info_struct *ai, ALconfig config)
return 0;
}
static int audio_set_format(struct audio_info_struct *ai, ALconfig config)
static int audio_set_format(audio_output_t *ao, ALconfig config)
{
if (alSetSampFmt(config,AL_SAMPFMT_TWOSCOMP) < 0)
fprintf(stderr,"audio_set_format : %s\n",alGetErrorString(oserror()));
@@ -66,7 +66,7 @@ static int audio_set_format(struct audio_info_struct *ai, ALconfig config)
}
int audio_open(struct audio_info_struct *ai)
int audio_open(audio_output_t *ao)
{
int dev = AL_DEFAULT_OUTPUT;
ALconfig config = alNewConfig();
@@ -79,7 +79,7 @@ int audio_open(struct audio_info_struct *ai)
}
/* Set port parameters */
if(ai->channels == 2)
if(ao->channels == 2)
alSetChannels(config, AL_STEREO);
else
alSetChannels(config, AL_MONO);
@@ -90,14 +90,14 @@ int audio_open(struct audio_info_struct *ai)
/* Setup output device to specified module. If there is no module
specified in ai structure, use the default four output */
if ((ai->device) != NULL) {
if ((ao->device) != NULL) {
char *dev_name;
dev_name=malloc((strlen(ai->device) + strlen(analog_output_res_name) + 1) *
dev_name=malloc((strlen(ao->device) + strlen(analog_output_res_name) + 1) *
sizeof(char));
strcpy(dev_name,ai->device);
strcpy(dev_name,ao->device);
strcat(dev_name,analog_output_res_name);
/* Find the asked device resource */
@@ -128,7 +128,7 @@ int audio_open(struct audio_info_struct *ai)
return -1;
}
ai->handle = (void*)port;
ao->handle = (void*)port;
audio_set_format(ai, config);
@@ -142,17 +142,17 @@ int audio_open(struct audio_info_struct *ai)
}
int audio_get_formats(struct audio_info_struct *ai)
int audio_get_formats(audio_output_t *ao)
{
return AUDIO_FORMAT_SIGNED_16;
}
int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
int audio_play_samples(audio_output_t *ao,unsigned char *buf,int len)
{
ALport port = (ALport)ai->handle;
ALport port = (ALport)ao->handle;
if(ai->format == AUDIO_FORMAT_SIGNED_8)
if(ao->format == AUDIO_FORMAT_SIGNED_8)
alWriteFrames(port, buf, len>>1);
else
alWriteFrames(port, buf, len>>2);
@@ -160,20 +160,20 @@ int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
return len;
}
int audio_close(struct audio_info_struct *ai)
int audio_close(audio_output_t *ao)
{
ALport port = (ALport)ai->handle;
ALport port = (ALport)ao->handle;
if (port) {
while(alGetFilled(port) > 0)
sginap(1);
alClosePort(port);
ai->handle=NULL;
ao->handle=NULL;
}
return 0;
}
void audio_queueflush(struct audio_info_struct *ai)
void audio_queueflush(audio_output_t *ao)
{
}

View File

@@ -1,13 +1,18 @@
/*
audio_sun.c: audio output for Sun systems
sun: audio output for Sun systems
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include "config.h"
#include "mpg123.h"
#ifdef HAVE_SYS_IOCTL_H
@@ -34,10 +39,10 @@
static void audio_set_format_helper(struct audio_info_struct *ai, audio_info_t *ainfo)
static void audio_set_format_helper(audio_output_t *ao, audio_info_t *ainfo)
{
switch(ai->format) {
switch(ao->format) {
case -1:
case AUDIO_FORMAT_SIGNED_16:
default:
@@ -69,99 +74,99 @@ static void audio_set_format_helper(struct audio_info_struct *ai, audio_info_t *
}
static int audio_reset_parameters(struct audio_info_struct *ai)
static int audio_reset_parameters(audio_output_t *ao)
{
audio_info_t ainfo;
AUDIO_INITINFO(&ainfo);
if(ai->rate != -1)
ainfo.play.sample_rate = ai->rate;
if(ai->channels >= 0)
ainfo.play.channels = ai->channels;
if(ao->rate != -1)
ainfo.play.sample_rate = ao->rate;
if(ao->channels >= 0)
ainfo.play.channels = ao->channels;
audio_set_format_helper(ai,&ainfo);
if(ioctl(ai->fn, AUDIO_SETINFO, &ainfo) == -1)
if(ioctl(ao->fn, AUDIO_SETINFO, &ainfo) == -1)
return -1;
return 0;
}
static int audio_rate_best_match(struct audio_info_struct *ai)
static int audio_rate_best_match(audio_output_t *ao)
{
audio_info_t ainfo;
AUDIO_INITINFO(&ainfo);
ainfo.play.sample_rate = ai->rate;
if(ioctl(ai->fn, AUDIO_SETINFO, &ainfo) < 0) {
ai->rate = 0;
ainfo.play.sample_rate = ao->rate;
if(ioctl(ao->fn, AUDIO_SETINFO, &ainfo) < 0) {
ao->rate = 0;
return 0;
}
if(ioctl(ai->fn, AUDIO_GETINFO, &ainfo) < 0) {
if(ioctl(ao->fn, AUDIO_GETINFO, &ainfo) < 0) {
return -1;
}
ai->rate = ainfo.play.sample_rate;
ao->rate = ainfo.play.sample_rate;
return 0;
}
static int audio_set_rate(struct audio_info_struct *ai)
static int audio_set_rate(audio_output_t *ao)
{
audio_info_t ainfo;
if(ai->rate != -1) {
if(ao->rate != -1) {
AUDIO_INITINFO(&ainfo);
ainfo.play.sample_rate = ai->rate;
if(ioctl(ai->fn, AUDIO_SETINFO, &ainfo) == -1)
ainfo.play.sample_rate = ao->rate;
if(ioctl(ao->fn, AUDIO_SETINFO, &ainfo) == -1)
return -1;
return 0;
}
return -1;
}
static int audio_set_channels(struct audio_info_struct *ai)
static int audio_set_channels(audio_output_t *ao)
{
audio_info_t ainfo;
AUDIO_INITINFO(&ainfo);
ainfo.play.channels = ai->channels;
if(ioctl(ai->fn, AUDIO_SETINFO, &ainfo) == -1)
ainfo.play.channels = ao->channels;
if(ioctl(ao->fn, AUDIO_SETINFO, &ainfo) == -1)
return -1;
return 0;
}
static int audio_set_format(struct audio_info_struct *ai)
static int audio_set_format(audio_output_t *ao)
{
audio_info_t ainfo;
AUDIO_INITINFO(&ainfo);
audio_set_format_helper(ai,&ainfo);
if(ioctl(ai->fn, AUDIO_SETINFO, &ainfo) == -1)
if(ioctl(ao->fn, AUDIO_SETINFO, &ainfo) == -1)
return -1;
return 0;
}
int audio_open(struct audio_info_struct *ai)
int audio_open(audio_output_t *ao)
{
audio_info_t ainfo;
if(!ai->device) {
if(!ao->device) {
if(getenv("AUDIODEV")) {
if(param.verbose > 1)
fprintf(stderr,"Using audio-device value from AUDIODEV environment variable!\n");
ai->device = getenv("AUDIODEV");
ao->device = getenv("AUDIODEV");
}
else
ai->device = "/dev/audio";
ao->device = "/dev/audio";
}
ai->fn = open(ai->device,O_WRONLY);
if(ai->fn < 0)
return ai->fn;
ao->fn = open(ao->device,O_WRONLY);
if(ao->fn < 0)
return ao->fn;
#if defined(SUNOS) && defined(AUDIO_GETDEV)
{
int type;
if(ioctl(ai->fn, AUDIO_GETDEV, &type) == -1)
if(ioctl(ao->fn, AUDIO_GETDEV, &type) == -1)
return -1;
if(type == AUDIO_DEV_UNKNOWN || type == AUDIO_DEV_AMD)
return -1;
@@ -170,7 +175,7 @@ int audio_open(struct audio_info_struct *ai)
#if defined(SOLARIS) || defined(SPARCLINUX)
{
struct audio_device ad;
if(ioctl(ai->fn, AUDIO_GETDEV, &ad) == -1)
if(ioctl(ao->fn, AUDIO_GETDEV, &ad) == -1)
return -1;
if(param.verbose > 1)
fprintf(stderr,"Audio device type: %s\n",ad.name);
@@ -180,36 +185,36 @@ int audio_open(struct audio_info_struct *ai)
#endif
#endif
if(audio_reset_parameters(ai) < 0) {
if(audio_reset_parameters(ao) < 0) {
return -1;
}
AUDIO_INITINFO(&ainfo);
if(ai->output > 0)
if(ao->output > 0)
ainfo.play.port = 0;
if(ai->output & AUDIO_OUT_INTERNAL_SPEAKER)
if(ao->output & AUDIO_OUT_INTERNAL_SPEAKER)
ainfo.play.port |= AUDIO_SPEAKER;
if(ai->output & AUDIO_OUT_HEADPHONES)
if(ao->output & AUDIO_OUT_HEADPHONES)
ainfo.play.port |= AUDIO_HEADPHONE;
#ifdef AUDIO_LINE_OUT
if(ai->output & AUDIO_OUT_LINE_OUT)
if(ao->output & AUDIO_OUT_LINE_OUT)
ainfo.play.port |= AUDIO_LINE_OUT;
#endif
if(ai->gain != -1)
ainfo.play.gain = ai->gain;
if(ao->gain != -1)
ainfo.play.gain = ao->gain;
if(ioctl(ai->fn, AUDIO_SETINFO, &ainfo) == -1)
if(ioctl(ao->fn, AUDIO_SETINFO, &ainfo) == -1)
return -1;
return ai->fn;
return ao->fn;
}
int audio_get_formats(struct audio_info_struct *ai)
int audio_get_formats(audio_output_t *ao)
{
static int tab[][3] = {
{ AUDIO_ENCODING_ULAW , 8, AUDIO_FORMAT_ULAW_8 } ,
@@ -223,33 +228,33 @@ int audio_get_formats(struct audio_info_struct *ai)
audio_info_t ainfo;
int i,fmts=0;
for(i=0;i<sizeof(tab)/sizeof(tab[0]);i++) {
for(i=0;i<4;i++) {
AUDIO_INITINFO(&ainfo);
ainfo.play.encoding = tab[i][0];
ainfo.play.precision = tab[i][1];
#if 1
ainfo.play.sample_rate = ai->rate;
ainfo.play.channels = ai->channels;
ainfo.play.sample_rate = ao->rate;
ainfo.play.channels = ao->channels;
#endif
if(ioctl(ai->fn, AUDIO_SETINFO, &ainfo) >= 0) {
if(ioctl(ao->fn, AUDIO_SETINFO, &ainfo) >= 0) {
fmts |= tab[i][2];
}
}
return fmts;
}
int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
int audio_play_samples(audio_output_t *ao,unsigned char *buf,int len)
{
return write(ai->fn,buf,len);
return write(ao->fn,buf,len);
}
int audio_close(struct audio_info_struct *ai)
int audio_close(audio_output_t *ao)
{
close (ai->fn);
close (ao->fn);
return 0;
}
void audio_queueflush (struct audio_info_struct *ai)
void audio_queueflush (audio_output_t *ao)
{
/*ioctl (ai->fn, I_FLUSH, FLUSHRW);*/
/*ioctl (ao->fn, I_FLUSH, FLUSHRW);*/
}

View File

@@ -1,5 +1,5 @@
/*
audio_win32.c: audio output for Windows 32bit
win32: audio output for Windows 32bit
copyright ?-2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org

View File

@@ -19,6 +19,7 @@
#include "common.h"
extern int buffer_pid;
extern audio_output_t ao;
static int term_enable = 0;
static struct termios old_tio;
@@ -75,7 +76,7 @@ static int stopped = 0;
static int paused = 0;
static int pause_cycle;
long term_control(struct frame *fr, struct audio_info_struct *ai)
long term_control(struct frame *fr, audio_output_t *ao)
{
long offset = 0;
@@ -104,7 +105,7 @@ long term_control(struct frame *fr, struct audio_info_struct *ai)
offset += term_handle_input(fr, stopped);
if((offset < 0) && (-offset > fr->num)) offset = - fr->num;
if(param.verbose && offset != 0)
print_stat(fr,fr->num+offset,0,ai);
print_stat(fr,fr->num+offset,0,ao);
} while (stopped);
return offset;
@@ -114,7 +115,6 @@ static long term_handle_input(struct frame *fr, int do_delay)
{
int n = 1;
long offset = 0;
extern struct audio_info_struct ai;
while(n > 0) {
fd_set r;
@@ -133,7 +133,7 @@ static long term_handle_input(struct frame *fr, int do_delay)
switch(tolower(val)) {
case BACK_KEY:
if(!param.usebuffer) audio_queueflush(&ai);
if(!param.usebuffer) ao.flush(&ao);
/*
* NOTE: rd->rewind() calls buffer_resync() that blocks until
* buffer process returns ACK. If buffer process is stopped, we
@@ -154,7 +154,7 @@ static long term_handle_input(struct frame *fr, int do_delay)
fr->num=0;
break;
case NEXT_KEY:
if(!param.usebuffer) audio_queueflush(&ai);
if(!param.usebuffer) ao.flush(&ao);
plain_buffer_resync();
next_track();
break;
@@ -178,7 +178,7 @@ static long term_handle_input(struct frame *fr, int do_delay)
case STOP_KEY:
case ' ':
/* when seeking while stopped and then resuming, I want to prevent the chirp from the past */
if(!param.usebuffer) audio_queueflush(&ai);
if(!param.usebuffer) ao.flush(&ao);
stopped=1-stopped;
if(paused) {
paused=0;

View File

@@ -57,7 +57,7 @@
#define EMPTY_STRING " \b\b\b\b\b\b\b\b"
void term_init(void);
long term_control(struct frame *fr, struct audio_info_struct *ai);
long term_control(struct frame *fr, audio_output_t *ao);
void term_restore(void);
#endif

View File

@@ -169,7 +169,7 @@ static int open_file(char *filename)
}
int au_open(struct audio_info_struct *ai, char *aufilename)
int au_open(audio_output_t *ao, char *aufilename)
{
#ifdef FLOATOUT
error("AU file support for float values not there yet");
@@ -177,7 +177,7 @@ int au_open(struct audio_info_struct *ai, char *aufilename)
#else
flipendian = 0;
switch(ai->format) {
switch(ao->format) {
case AUDIO_FORMAT_SIGNED_16:
{
int endiantest = testEndian();
@@ -187,7 +187,7 @@ int au_open(struct audio_info_struct *ai, char *aufilename)
}
break;
case AUDIO_FORMAT_UNSIGNED_8:
ai->format = AUDIO_FORMAT_ULAW_8;
ao->format = AUDIO_FORMAT_ULAW_8;
case AUDIO_FORMAT_ULAW_8:
long2bigendian(1,auhead.encoding,sizeof(auhead.encoding));
break;
@@ -197,8 +197,8 @@ int au_open(struct audio_info_struct *ai, char *aufilename)
}
long2bigendian(0xffffffff,auhead.datalen,sizeof(auhead.datalen));
long2bigendian(ai->rate,auhead.rate,sizeof(auhead.rate));
long2bigendian(ai->channels,auhead.channels,sizeof(auhead.channels));
long2bigendian(ao->rate,auhead.rate,sizeof(auhead.rate));
long2bigendian(ao->channels,auhead.channels,sizeof(auhead.channels));
if(open_file(aufilename) < 0)
return -1;
@@ -210,18 +210,18 @@ int au_open(struct audio_info_struct *ai, char *aufilename)
#endif
}
int cdr_open(struct audio_info_struct *ai, char *cdrfilename)
int cdr_open(audio_output_t *ao, char *cdrfilename)
{
#ifdef FLOATOUT
error("refusing to produce cdr file with float values");
return -1;
#else
param.force_stereo = 0;
ai->format = AUDIO_FORMAT_SIGNED_16;
ai->rate = 44100;
ai->channels = 2;
ao->format = AUDIO_FORMAT_SIGNED_16;
ao->rate = 44100;
ao->channels = 2;
/*
if(ai->format != AUDIO_FORMAT_SIGNED_16 || ai->rate != 44100 || ai->channels != 2) {
if(ao->format != AUDIO_FORMAT_SIGNED_16 || ao->rate != 44100 || ao->channels != 2) {
fprintf(stderr,"Oops .. not forced to 16 bit, 44kHz?, stereo\n");
exit(1);
}
@@ -236,7 +236,7 @@ int cdr_open(struct audio_info_struct *ai, char *cdrfilename)
#endif
}
int wav_open(struct audio_info_struct *ai, char *wavfilename)
int wav_open(audio_output_t *ao, char *wavfilename)
{
int bps;
@@ -248,11 +248,11 @@ int wav_open(struct audio_info_struct *ai, char *wavfilename)
long2littleendian(bps=32,RIFF.WAVE.fmt.BitsPerSample,sizeof(RIFF.WAVE.fmt.BitsPerSample));
flipendian = testEndian();
#else
if(ai->format == AUDIO_FORMAT_SIGNED_16) {
if(ao->format == AUDIO_FORMAT_SIGNED_16) {
long2littleendian(bps=16,RIFF.WAVE.fmt.BitsPerSample,sizeof(RIFF.WAVE.fmt.BitsPerSample));
flipendian = testEndian();
}
else if(ai->format == AUDIO_FORMAT_UNSIGNED_8)
else if(ao->format == AUDIO_FORMAT_UNSIGNED_8)
long2littleendian(bps=8,RIFF.WAVE.fmt.BitsPerSample,sizeof(RIFF.WAVE.fmt.BitsPerSample));
else
{
@@ -261,13 +261,13 @@ int wav_open(struct audio_info_struct *ai, char *wavfilename)
}
#endif
if(ai->rate < 0) ai->rate = 44100;
if(ao->rate < 0) ao->rate = 44100;
long2littleendian(ai->channels,RIFF.WAVE.fmt.Channels,sizeof(RIFF.WAVE.fmt.Channels));
long2littleendian(ai->rate,RIFF.WAVE.fmt.SamplesPerSec,sizeof(RIFF.WAVE.fmt.SamplesPerSec));
long2littleendian((int)(ai->channels * ai->rate * bps)>>3,
long2littleendian(ao->channels,RIFF.WAVE.fmt.Channels,sizeof(RIFF.WAVE.fmt.Channels));
long2littleendian(ao->rate,RIFF.WAVE.fmt.SamplesPerSec,sizeof(RIFF.WAVE.fmt.SamplesPerSec));
long2littleendian((int)(ao->channels * ao->rate * bps)>>3,
RIFF.WAVE.fmt.AvgBytesPerSec,sizeof(RIFF.WAVE.fmt.AvgBytesPerSec));
long2littleendian((int)(ai->channels * bps)>>3,
long2littleendian((int)(ao->channels * bps)>>3,
RIFF.WAVE.fmt.BlockAlign,sizeof(RIFF.WAVE.fmt.BlockAlign));
if(open_file(wavfilename) < 0)