summaryrefslogtreecommitdiffstats
path: root/akode/plugins/xiph_decoder
diff options
context:
space:
mode:
Diffstat (limited to 'akode/plugins/xiph_decoder')
-rw-r--r--akode/plugins/xiph_decoder/Makefile.am8
-rw-r--r--akode/plugins/xiph_decoder/Makefile.in689
-rw-r--r--akode/plugins/xiph_decoder/flac113_decoder.cpp377
-rw-r--r--akode/plugins/xiph_decoder/flac_decoder.cpp587
-rw-r--r--akode/plugins/xiph_decoder/flac_decoder.h103
-rw-r--r--akode/plugins/xiph_decoder/speex_decoder.cpp351
-rw-r--r--akode/plugins/xiph_decoder/speex_decoder.h74
-rw-r--r--akode/plugins/xiph_decoder/vorbis_decoder.cpp277
-rw-r--r--akode/plugins/xiph_decoder/vorbis_decoder.h70
-rw-r--r--akode/plugins/xiph_decoder/xiph_decoder.cpp84
-rw-r--r--akode/plugins/xiph_decoder/xiph_decoder.h42
11 files changed, 2662 insertions, 0 deletions
diff --git a/akode/plugins/xiph_decoder/Makefile.am b/akode/plugins/xiph_decoder/Makefile.am
new file mode 100644
index 0000000..367760e
--- /dev/null
+++ b/akode/plugins/xiph_decoder/Makefile.am
@@ -0,0 +1,8 @@
+INCLUDES = -I$(top_srcdir)/akode/lib -I$(top_builddir)/akode/lib $(USER_INCLUDES) $(all_includes)
+
+lib_LTLIBRARIES = libakode_xiph_decoder.la
+
+libakode_xiph_decoder_la_SOURCES = flac_decoder.cpp flac113_decoder.cpp speex_decoder.cpp vorbis_decoder.cpp xiph_decoder.cpp
+
+libakode_xiph_decoder_la_LDFLAGS = -module -avoid-version -no-undefined $(USER_LDFLAGS)
+libakode_xiph_decoder_la_LIBADD = ../../lib/libakode.la $(LIBFLAC) $(LIBOGGFLAC) $(VORBIS_LIBS) $(VORBISFILE_LIBS) $(SPEEXLIBS) \ No newline at end of file
diff --git a/akode/plugins/xiph_decoder/Makefile.in b/akode/plugins/xiph_decoder/Makefile.in
new file mode 100644
index 0000000..b603541
--- /dev/null
+++ b/akode/plugins/xiph_decoder/Makefile.in
@@ -0,0 +1,689 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# KDE tags expanded automatically by am_edit - $Revision: 483858 $
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../../..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = akode/plugins/xiph_decoder
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/akode/lib/akode_export.h
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(libdir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libakode_xiph_decoder_la_DEPENDENCIES = ../../lib/libakode.la \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_libakode_xiph_decoder_la_OBJECTS = flac_decoder.lo \
+ flac113_decoder.lo speex_decoder.lo vorbis_decoder.lo \
+ xiph_decoder.lo
+#>- libakode_xiph_decoder_la_OBJECTS = \
+#>- $(am_libakode_xiph_decoder_la_OBJECTS)
+#>+ 6
+libakode_xiph_decoder_la_final_OBJECTS = libakode_xiph_decoder_la.all_cpp.lo
+libakode_xiph_decoder_la_nofinal_OBJECTS = flac_decoder.lo \
+ flac113_decoder.lo speex_decoder.lo vorbis_decoder.lo \
+ xiph_decoder.lo
+@KDE_USE_FINAL_FALSE@libakode_xiph_decoder_la_OBJECTS = $(libakode_xiph_decoder_la_nofinal_OBJECTS)
+@KDE_USE_FINAL_TRUE@libakode_xiph_decoder_la_OBJECTS = $(libakode_xiph_decoder_la_final_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) -I$(top_builddir)/akode/lib
+depcomp = $(SHELL) $(top_srcdir)/admin/depcomp
+am__depfiles_maybe = depfiles
+#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+#>+ 2
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
+#>- LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \
+#>- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+#>- $(AM_CXXFLAGS) $(CXXFLAGS)
+#>+ 3
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
+CXXLD = $(CXX)
+#>- CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+#>- $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+#>+ 2
+CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(KDE_CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libakode_xiph_decoder_la_SOURCES)
+DIST_SOURCES = $(libakode_xiph_decoder_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+#>+ 1
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
+ACLOCAL = @ACLOCAL@
+AKODE_LIBDL = @AKODE_LIBDL@
+ALSA_CFLAGS = @ALSA_CFLAGS@
+ALSA_LIBS = @ALSA_LIBS@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTODIRS = @AUTODIRS@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AVCODEC_CFLAGS = @AVCODEC_CFLAGS@
+AVCODEC_LDFLAGS = @AVCODEC_LDFLAGS@
+AVCODEC_LIBADD = @AVCODEC_LIBADD@
+AVFORMAT_CFLAGS = @AVFORMAT_CFLAGS@
+AVFORMAT_LDFLAGS = @AVFORMAT_LDFLAGS@
+AVFORMAT_LIBADD = @AVFORMAT_LIBADD@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONF_FILES = @CONF_FILES@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_PERMISSIVE_FLAG = @ENABLE_PERMISSIVE_FLAG@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GREP = @GREP@
+HAVE_GCC_VISIBILITY = @HAVE_GCC_VISIBILITY@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+JACK_CFLAGS = @JACK_CFLAGS@
+JACK_LDFLAGS = @JACK_LDFLAGS@
+JACK_LIBADD = @JACK_LIBADD@
+KDE_CHECK_PLUGIN = @KDE_CHECK_PLUGIN@
+KDE_NO_UNDEFINED = @KDE_NO_UNDEFINED@
+KDE_PLUGIN = @KDE_PLUGIN@
+KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
+KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
+KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
+KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
+KDE_USE_NMCHECK_FALSE = @KDE_USE_NMCHECK_FALSE@
+KDE_USE_NMCHECK_TRUE = @KDE_USE_NMCHECK_TRUE@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_AS_NEEDED = @LDFLAGS_AS_NEEDED@
+LDFLAGS_NEW_DTAGS = @LDFLAGS_NEW_DTAGS@
+LIBFLAC = @LIBFLAC@
+LIBOBJS = @LIBOBJS@
+LIBOGGFLAC = @LIBOGGFLAC@
+LIBOSSAUDIO = @LIBOSSAUDIO@
+LIBPTHREAD = @LIBPTHREAD@
+LIBS = @LIBS@
+LIBSAMPLERATE = @LIBSAMPLERATE@
+LIBSEM = @LIBSEM@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MADLIBS = @MADLIBS@
+MAKEINFO = @MAKEINFO@
+NOOPT_CFLAGS = @NOOPT_CFLAGS@
+NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+POLYP_CFLAGS = @POLYP_CFLAGS@
+POLYP_LDFLAGS = @POLYP_LDFLAGS@
+POLYP_LIBADD = @POLYP_LIBADD@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPEEXLIBS = @SPEEXLIBS@
+STRIP = @STRIP@
+TOPSUBDIRS = @TOPSUBDIRS@
+USER_INCLUDES = @USER_INCLUDES@
+USER_LDFLAGS = @USER_LDFLAGS@
+USE_EXCEPTIONS = @USE_EXCEPTIONS@
+USE_RTTI = @USE_RTTI@
+VERSION = @VERSION@
+VORBISFILE_LIBS = @VORBISFILE_LIBS@
+VORBIS_LIBS = @VORBIS_LIBS@
+WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+akode_SUBDIR_included_FALSE = @akode_SUBDIR_included_FALSE@
+akode_SUBDIR_included_TRUE = @akode_SUBDIR_included_TRUE@
+all_includes = @all_includes@
+all_libraries = @all_libraries@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+include_alsa_sink_FALSE = @include_alsa_sink_FALSE@
+include_alsa_sink_TRUE = @include_alsa_sink_TRUE@
+include_ffmpeg_decoder_FALSE = @include_ffmpeg_decoder_FALSE@
+include_ffmpeg_decoder_TRUE = @include_ffmpeg_decoder_TRUE@
+include_jack_sink_FALSE = @include_jack_sink_FALSE@
+include_jack_sink_TRUE = @include_jack_sink_TRUE@
+include_mpeg_decoder_FALSE = @include_mpeg_decoder_FALSE@
+include_mpeg_decoder_TRUE = @include_mpeg_decoder_TRUE@
+include_oss_sink_FALSE = @include_oss_sink_FALSE@
+include_oss_sink_TRUE = @include_oss_sink_TRUE@
+include_polyp_sink_FALSE = @include_polyp_sink_FALSE@
+include_polyp_sink_TRUE = @include_polyp_sink_TRUE@
+include_src_resampler_FALSE = @include_src_resampler_FALSE@
+include_src_resampler_TRUE = @include_src_resampler_TRUE@
+include_sun_sink_FALSE = @include_sun_sink_FALSE@
+include_sun_sink_TRUE = @include_sun_sink_TRUE@
+include_xiph_decoder_FALSE = @include_xiph_decoder_FALSE@
+include_xiph_decoder_TRUE = @include_xiph_decoder_TRUE@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+unsermake_enable_pch_FALSE = @unsermake_enable_pch_FALSE@
+unsermake_enable_pch_TRUE = @unsermake_enable_pch_TRUE@
+INCLUDES = -I$(top_srcdir)/akode/lib -I$(top_builddir)/akode/lib $(USER_INCLUDES) $(all_includes)
+lib_LTLIBRARIES = libakode_xiph_decoder.la
+libakode_xiph_decoder_la_SOURCES = flac_decoder.cpp flac113_decoder.cpp speex_decoder.cpp vorbis_decoder.cpp xiph_decoder.cpp
+#>- libakode_xiph_decoder_la_LDFLAGS = -module -avoid-version -no-undefined $(USER_LDFLAGS)
+#>+ 1
+libakode_xiph_decoder_la_LDFLAGS = -module -avoid-version -no-undefined $(KDE_NO_UNDEFINED) $(USER_LDFLAGS)
+libakode_xiph_decoder_la_LIBADD = ../../lib/libakode.la $(LIBFLAC) $(LIBOGGFLAC) $(VORBIS_LIBS) $(VORBISFILE_LIBS) $(SPEEXLIBS)
+#>- all: all-am
+#>+ 1
+all: docs-am all-am
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+#>- @for dep in $?; do \
+#>- case '$(am__configure_deps)' in \
+#>- *$$dep*) \
+#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+#>- && exit 0; \
+#>- exit 1;; \
+#>- esac; \
+#>- done; \
+#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu akode/plugins/xiph_decoder/Makefile'; \
+#>- cd $(top_srcdir) && \
+#>- $(AUTOMAKE) --gnu akode/plugins/xiph_decoder/Makefile
+#>+ 12
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu akode/plugins/xiph_decoder/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu akode/plugins/xiph_decoder/Makefile
+ cd $(top_srcdir) && perl admin/am_edit akode/plugins/xiph_decoder/Makefile.in
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+#>- libakode_xiph_decoder.la: $(libakode_xiph_decoder_la_OBJECTS) $(libakode_xiph_decoder_la_DEPENDENCIES)
+#>+ 2
+@KDE_USE_CLOSURE_TRUE@libakode_xiph_decoder.la: libakode_xiph_decoder.la.closure $(libakode_xiph_decoder_la_OBJECTS) $(libakode_xiph_decoder_la_DEPENDENCIES)
+@KDE_USE_CLOSURE_FALSE@libakode_xiph_decoder.la: $(libakode_xiph_decoder_la_OBJECTS) $(libakode_xiph_decoder_la_DEPENDENCIES)
+ $(CXXLINK) -rpath $(libdir) $(libakode_xiph_decoder_la_LDFLAGS) $(libakode_xiph_decoder_la_OBJECTS) $(libakode_xiph_decoder_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flac113_decoder.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flac_decoder.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/speex_decoder.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vorbis_decoder.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xiph_decoder.Plo@am__quote@
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+#>- clean: clean-am
+#>+ 1
+clean: kde-rpo-clean clean-am
+
+#>- clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+#>- mostlyclean-am
+#>+ 2
+clean-am: clean-closures clean-bcheck clean-final clean-generic clean-libLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-exec \
+ install-exec-am install-info install-info-am \
+ install-libLTLIBRARIES install-man install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-info-am \
+ uninstall-libLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
+
+#>+ 8
+libakode_xiph_decoder.la.closure: $(libakode_xiph_decoder_la_OBJECTS) $(libakode_xiph_decoder_la_DEPENDENCIES)
+ @echo "int main() {return 0;}" > libakode_xiph_decoder_la_closure.cpp
+ @$(LTCXXCOMPILE) -c libakode_xiph_decoder_la_closure.cpp
+ $(CXXLINK) libakode_xiph_decoder_la_closure.lo $(libakode_xiph_decoder_la_LDFLAGS) $(libakode_xiph_decoder_la_OBJECTS) $(libakode_xiph_decoder_la_LIBADD) $(LIBS)
+ @rm -f libakode_xiph_decoder_la_closure.* libakode_xiph_decoder.la.closure
+ @echo "timestamp" > libakode_xiph_decoder.la.closure
+
+
+#>+ 2
+KDE_DIST=Makefile.in xiph_decoder.h vorbis_decoder.h flac_decoder.h Makefile.am speex_decoder.h
+
+#>+ 3
+clean-closures:
+ -rm -f libakode_xiph_decoder.la.closure
+
+#>+ 2
+docs-am:
+
+#>+ 15
+force-reedit:
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu akode/plugins/xiph_decoder/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu akode/plugins/xiph_decoder/Makefile
+ cd $(top_srcdir) && perl admin/am_edit akode/plugins/xiph_decoder/Makefile.in
+
+
+#>+ 21
+clean-bcheck:
+ rm -f *.bchecktest.cc *.bchecktest.cc.class a.out
+
+bcheck: bcheck-am
+
+bcheck-am:
+ @for i in ; do \
+ if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \
+ echo "int main() {return 0;}" > $$i.bchecktest.cc ; \
+ echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \
+ echo "$$i"; \
+ if ! $(CXXCOMPILE) --dump-class-hierarchy -c $$i.bchecktest.cc; then \
+ rm -f $$i.bchecktest.cc; exit 1; \
+ fi ; \
+ echo "" >> $$i.bchecktest.cc.class; \
+ perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \
+ rm -f a.out; \
+ fi ; \
+ done
+
+
+#>+ 11
+libakode_xiph_decoder_la.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/flac_decoder.cpp $(srcdir)/flac113_decoder.cpp $(srcdir)/speex_decoder.cpp $(srcdir)/vorbis_decoder.cpp $(srcdir)/xiph_decoder.cpp
+ @echo 'creating libakode_xiph_decoder_la.all_cpp.cpp ...'; \
+ rm -f libakode_xiph_decoder_la.all_cpp.files libakode_xiph_decoder_la.all_cpp.final; \
+ echo "#define KDE_USE_FINAL 1" >> libakode_xiph_decoder_la.all_cpp.final; \
+ for file in flac_decoder.cpp flac113_decoder.cpp speex_decoder.cpp vorbis_decoder.cpp xiph_decoder.cpp ; do \
+ echo "#include \"$$file\"" >> libakode_xiph_decoder_la.all_cpp.files; \
+ test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> libakode_xiph_decoder_la.all_cpp.final; \
+ done; \
+ cat libakode_xiph_decoder_la.all_cpp.final libakode_xiph_decoder_la.all_cpp.files > libakode_xiph_decoder_la.all_cpp.cpp; \
+ rm -f libakode_xiph_decoder_la.all_cpp.final libakode_xiph_decoder_la.all_cpp.files
+
+#>+ 3
+clean-final:
+ -rm -f libakode_xiph_decoder_la.all_cpp.cpp
+
+#>+ 3
+final:
+ $(MAKE) libakode_xiph_decoder_la_OBJECTS="$(libakode_xiph_decoder_la_final_OBJECTS)" all-am
+
+#>+ 3
+final-install:
+ $(MAKE) libakode_xiph_decoder_la_OBJECTS="$(libakode_xiph_decoder_la_final_OBJECTS)" install-am
+
+#>+ 3
+no-final:
+ $(MAKE) libakode_xiph_decoder_la_OBJECTS="$(libakode_xiph_decoder_la_nofinal_OBJECTS)" all-am
+
+#>+ 3
+no-final-install:
+ $(MAKE) libakode_xiph_decoder_la_OBJECTS="$(libakode_xiph_decoder_la_nofinal_OBJECTS)" install-am
+
+#>+ 3
+kde-rpo-clean:
+ -rm -f *.rpo
+
+#>+ 3
+nmcheck:
+nmcheck-am: nmcheck
diff --git a/akode/plugins/xiph_decoder/flac113_decoder.cpp b/akode/plugins/xiph_decoder/flac113_decoder.cpp
new file mode 100644
index 0000000..46a46e2
--- /dev/null
+++ b/akode/plugins/xiph_decoder/flac113_decoder.cpp
@@ -0,0 +1,377 @@
+/* aKode: FLAC-Decoder (using libFLAC 1.1.3 API)
+
+ Copyright (C) 2004-2005 Allan Sandfeld Jensen <kde@carewolf.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "akodelib.h"
+
+#ifdef HAVE_LIBFLAC113
+
+#include <string.h>
+#include <iostream>
+
+#include <FLAC/format.h>
+#include <FLAC/stream_decoder.h>
+
+#include "audioframe.h"
+#include "decoder.h"
+#include "file.h"
+#include "flac_decoder.h"
+
+
+namespace aKode {
+
+class FLACDecoder;
+
+static bool checkFLAC(File *src) {
+ char header[6];
+ bool res = false;
+ src->seek(0);
+ if(src->read(header, 4) == 4) {
+ // skip id3v2 headers
+ if (memcmp(header, "ID3", 3) == 0) {
+ if (src->read(header, 6) != 6) goto end;
+ int size = 0;
+ if (header[1] & 0x10) size += 10;
+ size += header[5];
+ size += header[4] << 7;
+ size += header[3] << 14;
+ size += header[2] << 21;
+ src->seek(10+size);
+ if (src->read(header, 4) != 4) goto end;
+ }
+ if (memcmp(header, "fLaC",4) == 0 ) res = true;
+ }
+end:
+ return res;
+}
+
+static bool checkOggFLAC(File *src) {
+ char header[34];
+ bool res = false;
+ src->seek(0);
+ if (src->read(header, 34) == 34)
+ if (memcmp(header, "OggS",4) == 0 )
+ // old FLAC 1.1.0 format
+ if (memcmp(header+28, "fLaC",4) == 0) res = true;
+ else
+ // new FLAC 1.1.1 format
+ if (memcmp(header+29, "FLAC",4) == 0) res = true;
+ return res;
+}
+
+
+bool FLACDecoderPlugin::canDecode(File* src) {
+ src->openRO();
+ bool res = checkFLAC(src);
+ if (!res) res = checkOggFLAC(src);
+ src->close();
+ return res;
+}
+
+extern "C" { FLACDecoderPlugin flac_decoder; }
+extern "C" { FLACDecoderPlugin oggflac_decoder; }
+
+struct FLACDecoder::private_data {
+ private_data() : decoder(0), valid(false), out(0), source(0), eof(false), error(false) {};
+
+ FLAC__StreamDecoder *decoder;
+ const FLAC__StreamMetadata_StreamInfo* si;
+ const FLAC__StreamMetadata_VorbisComment* vc;
+
+ bool valid;
+ AudioFrame *out;
+ File *source;
+ AudioConfiguration config;
+
+ uint32_t max_block_size;
+ uint64_t position, length;
+
+ bool eof, error;
+};
+
+static FLAC__StreamDecoderReadStatus flac_read_callback(
+ const FLAC__StreamDecoder *,
+ FLAC__byte buffer[],
+ unsigned *bytes,
+ void *client_data)
+{
+ FLACDecoder::private_data *data = (FLACDecoder::private_data*)client_data;
+
+ long res = data->source->read((char*)buffer, *bytes);
+ if (res<=0) {
+ if (data->source->eof()) {
+ return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
+ }
+ else
+ return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
+ }
+ else {
+ *bytes = res;
+ return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
+ }
+}
+
+static FLAC__StreamDecoderSeekStatus flac_seek_callback(
+ const FLAC__StreamDecoder *,
+ FLAC__uint64 absolute_byte_offset,
+ void *client_data)
+{
+ FLACDecoder::private_data *data = (FLACDecoder::private_data*)client_data;
+
+ if(data->source->seek(absolute_byte_offset))
+ return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
+ else
+ return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
+}
+
+static FLAC__StreamDecoderTellStatus flac_tell_callback(
+ const FLAC__StreamDecoder *,
+ FLAC__uint64 *absolute_byte_offset,
+ void *client_data)
+{
+ FLACDecoder::private_data *data = (FLACDecoder::private_data*)client_data;
+
+ long res = data->source->position();
+ if (res<0)
+ return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
+ else {
+ *absolute_byte_offset = res;
+ return FLAC__STREAM_DECODER_TELL_STATUS_OK;
+ }
+}
+
+static FLAC__StreamDecoderLengthStatus flac_length_callback(
+ const FLAC__StreamDecoder *,
+ FLAC__uint64 *stream_length,
+ void *client_data)
+{
+ FLACDecoder::private_data *data = (FLACDecoder::private_data*)client_data;
+
+ long res = data->source->length();
+ if (res<0)
+ return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
+ else {
+ *stream_length = res;
+ return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
+ }
+}
+
+static FLAC__bool eof_callback(
+ const FLAC__StreamDecoder *,
+ void *client_data)
+{
+ FLACDecoder::private_data *data = (FLACDecoder::private_data*)client_data;
+
+ return data->source->eof();
+}
+
+static FLAC__StreamDecoderWriteStatus write_callback(
+ const FLAC__StreamDecoder *,
+ const FLAC__Frame *frame,
+ const FLAC__int32 * const buffer[],
+ void* client_data)
+{
+ FLACDecoder::private_data *data = (FLACDecoder::private_data*)client_data;
+
+ if (!data->out) // Handle spurious callbacks (happens during seeks)
+ data->out = new AudioFrame;
+
+ const long frameSize = frame->header.blocksize;
+ const char bits = frame->header.bits_per_sample;
+ const char channels = frame->header.channels;
+
+ AudioFrame* const outFrame = data->out;
+
+ outFrame->reserveSpace(channels, frameSize, bits);
+ outFrame->sample_rate = frame->header.sample_rate;
+
+ if (channels == 1 || channels == 2)
+ outFrame->channel_config = aKode::MonoStereo;
+ else if (channels > 2 && channels < 8)
+ outFrame->channel_config = aKode::Surround;
+ else
+ outFrame->channel_config = aKode::MultiChannel;
+
+ for(int i = 0; i<channels; i++) {
+ if (outFrame->data[i] == 0) break;
+ if (bits<=8) {
+ int8_t** data = (int8_t**)outFrame->data;
+ for(long j=0; j<frameSize; j++)
+ data[i][j] = buffer[i][j];
+ } else
+ if (bits<=16) {
+ int16_t** data = (int16_t**)outFrame->data;
+ for(long j=0; j<frameSize; j++)
+ data[i][j] = buffer[i][j];
+ } else {
+ int32_t** data = (int32_t**)outFrame->data;
+ for(long j=0; j<frameSize; j++)
+ data[i][j] = buffer[i][j];
+ }
+ }
+ data->position+=frameSize;
+ data->valid = true;
+ return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+}
+
+static void metadata_callback(
+ const FLAC__StreamDecoder *,
+ const FLAC__StreamMetadata *metadata,
+ void* client_data)
+{
+ FLACDecoder::private_data *data = (FLACDecoder::private_data*)client_data;
+
+ if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
+ data->length = metadata->data.stream_info.total_samples;
+ data->config.sample_rate = metadata->data.stream_info.sample_rate;
+ data->config.sample_width = metadata->data.stream_info.bits_per_sample;
+ data->config.channels = metadata->data.stream_info.channels;
+ data->max_block_size = metadata->data.stream_info.max_blocksize;
+
+ if (data->config.channels <= 2)
+ data->config.channel_config = aKode::MonoStereo;
+ else if (data->config.channels <= 7)
+ data->config.channel_config = aKode::Surround;
+ else
+ data->config.channel_config = aKode::MultiChannel;
+
+ data->si = &metadata->data.stream_info;
+
+ data->position = 0;
+
+ } else
+ if (metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
+ data->vc = &metadata->data.vorbis_comment;
+ }
+}
+
+static void error_callback(
+ const FLAC__StreamDecoder *,
+ FLAC__StreamDecoderErrorStatus status,
+ void* /* client_data */)
+{
+ std::cerr << "FLAC error: " << FLAC__StreamDecoderErrorStatusString[status] << "\n";
+ switch (status) {
+ case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
+ break;
+ case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
+ break;
+ case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
+ break;
+ case FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM:
+ break;
+ }
+ //data->valid = false;
+}
+
+const AudioConfiguration* FLACDecoder::audioConfiguration() {
+ return &m_data->config;
+}
+
+FLACDecoder::FLACDecoder(File* src) {
+ m_data = new private_data;
+ m_data->out = 0;
+ m_data->decoder = FLAC__stream_decoder_new();
+ m_data->source = src;
+ m_data->source->openRO();
+ m_data->source->fadvise();
+ // ### check return value
+ FLAC__stream_decoder_init_stream(
+ m_data->decoder,
+ flac_read_callback,
+ flac_seek_callback,
+ flac_tell_callback,
+ flac_length_callback,
+ eof_callback,
+ write_callback,
+ metadata_callback,
+ error_callback,
+ m_data
+ );
+ FLAC__stream_decoder_process_until_end_of_metadata(m_data->decoder);
+}
+
+FLACDecoder::~FLACDecoder() {
+ FLAC__stream_decoder_finish(m_data->decoder);
+ FLAC__stream_decoder_delete(m_data->decoder);
+ m_data->source->close();
+ delete m_data;
+}
+
+bool FLACDecoder::readFrame(AudioFrame* frame) {
+ if (m_data->error || m_data->eof) return false;
+
+ if (m_data->out) { // Handle spurious callbacks
+ frame->freeSpace();
+ *frame = *m_data->out; // copy
+ m_data->out->data = 0; // nullify, don't free!
+ delete m_data->out;
+ m_data->out = 0;
+ return true;
+ }
+ m_data->valid = false;
+ m_data->out = frame;
+ bool ret = FLAC__stream_decoder_process_single(m_data->decoder);
+ m_data->out = 0;
+ if (ret && m_data->valid) {
+ frame->pos = position();
+ return true;
+ } else {
+ FLAC__StreamDecoderState state = FLAC__stream_decoder_get_state(m_data->decoder);
+ if (state == FLAC__STREAM_DECODER_END_OF_STREAM)
+ m_data->eof = true;
+ else
+ if (state > FLAC__STREAM_DECODER_END_OF_STREAM)
+ m_data->error = true;
+ return false;
+ }
+}
+
+long FLACDecoder::length() {
+ float pos = ((float)m_data->length)/m_data->config.sample_rate;
+ return (long)(pos*1000.0);
+}
+
+long FLACDecoder::position() {
+ float pos = ((float)m_data->position)/m_data->config.sample_rate;
+ return (long)(pos*1000.0);
+}
+
+bool FLACDecoder::eof() {
+ return m_data->eof;
+}
+
+bool FLACDecoder::error() {
+ return m_data->error;
+}
+
+bool FLACDecoder::seekable() {
+ return m_data->source->seekable();
+}
+
+bool FLACDecoder::seek(long pos) {
+ if (m_data->error) return false;
+ float samplePos = (float)pos * (float)m_data->config.sample_rate / 1000.0;
+ m_data->position = (uint64_t)samplePos;
+ return FLAC__stream_decoder_seek_absolute(m_data->decoder, m_data->position);
+}
+
+} // namespace
+
+#endif // HAVE_LIBFLAC113
diff --git a/akode/plugins/xiph_decoder/flac_decoder.cpp b/akode/plugins/xiph_decoder/flac_decoder.cpp
new file mode 100644
index 0000000..130e2a1
--- /dev/null
+++ b/akode/plugins/xiph_decoder/flac_decoder.cpp
@@ -0,0 +1,587 @@
+/* aKode: FLAC-Decoder
+
+ Copyright (C) 2004-2005 Allan Sandfeld Jensen <kde@carewolf.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "akodelib.h"
+
+#if defined(HAVE_LIBFLAC) && !defined(HAVE_LIBFLAC113)
+
+#include <string.h>
+#include <iostream>
+
+#include <FLAC/format.h>
+#include <FLAC/seekable_stream_decoder.h>
+
+#ifdef HAVE_LIBOGGFLAC
+ #include <OggFLAC/seekable_stream_decoder.h>
+#endif
+
+#include "audioframe.h"
+#include "decoder.h"
+#include "file.h"
+#include "flac_decoder.h"
+
+
+namespace aKode {
+
+class FLACDecoder;
+
+bool FLACDecoderPlugin::canDecode(File* src) {
+ char header[6];
+ bool res = false;
+ src->openRO();
+ if(src->read(header, 4) == 4) {
+ // skip id3v2 headers
+ if (memcmp(header, "ID3", 3) == 0) {
+ if (src->read(header, 6) != 6) goto end;
+ int size = 0;
+ if (header[1] & 0x10) size += 10;
+ size += header[5];
+ size += header[4] << 7;
+ size += header[3] << 14;
+ size += header[2] << 21;
+ src->seek(10+size);
+ if (src->read(header, 4) != 4) goto end;
+ }
+ if (memcmp(header, "fLaC",4) == 0 ) res = true;
+ }
+end:
+ src->close();
+ return res;
+}
+
+extern "C" { FLACDecoderPlugin flac_decoder; }
+
+#ifdef HAVE_LIBOGGFLAC
+bool OggFLACDecoderPlugin::canDecode(File* src) {
+ char header[34];
+ bool res = false;
+ src->openRO();
+ if (src->read(header, 34) == 34)
+ if (memcmp(header, "OggS",4) == 0 )
+ // old FLAC 1.1.0 format
+ if (memcmp(header+28, "fLaC",4) == 0) res = true;
+ else
+ // new FLAC 1.1.1 format
+ if (memcmp(header+29, "FLAC",4) == 0) res = true;
+ src->close();
+ return res;
+}
+extern "C" { OggFLACDecoderPlugin oggflac_decoder; }
+#endif
+
+struct FLACDecoder::private_data {
+ private_data() : decoder(0), valid(false), out(0), source(0), eof(false), error(false) {};
+
+ FLAC__SeekableStreamDecoder *decoder;
+ const FLAC__StreamMetadata_StreamInfo* si;
+ const FLAC__StreamMetadata_VorbisComment* vc;
+
+ bool valid;
+ AudioFrame *out;
+ File *source;
+ AudioConfiguration config;
+
+ uint32_t max_block_size;
+ uint64_t position, length;
+
+ bool eof, error;
+};
+
+#ifdef HAVE_LIBOGGFLAC
+struct OggFLACDecoder::private_data {
+ private_data() : decoder(0), valid(false), out(0), source(0), eof(false), error(false) {};
+
+ OggFLAC__SeekableStreamDecoder *decoder;
+ const FLAC__StreamMetadata_StreamInfo* si;
+ const FLAC__StreamMetadata_VorbisComment* vc;
+
+ bool valid;
+ AudioFrame *out;
+ File *source;
+ AudioConfiguration config;
+
+ uint32_t max_block_size;
+ uint64_t position, length;
+
+ bool eof, error;
+};
+#endif
+
+static FLAC__SeekableStreamDecoderReadStatus flac_read_callback(
+ const FLAC__SeekableStreamDecoder *,
+ FLAC__byte buffer[],
+ unsigned *bytes,
+ void *client_data)
+{
+ FLACDecoder::private_data *data = (FLACDecoder::private_data*)client_data;
+
+ long res = data->source->read((char*)buffer, *bytes);
+ if (res<=0) {
+ return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
+ }
+ else {
+ *bytes = res;
+ return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
+ }
+}
+
+#ifdef HAVE_LIBOGGFLAC
+// God, I hate people doing OO in C!
+static OggFLAC__SeekableStreamDecoderReadStatus oggflac_read_callback(
+ const OggFLAC__SeekableStreamDecoder *,
+ FLAC__byte buffer[],
+ unsigned *bytes,
+ void *client_data)
+{
+ OggFLACDecoder::private_data *data = (OggFLACDecoder::private_data*)client_data;
+
+ long res = data->source->read((char*)buffer, *bytes);
+ if (res<=0) {
+ return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
+ }
+ else {
+ *bytes = res;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
+ }
+}
+#endif
+
+static FLAC__SeekableStreamDecoderSeekStatus flac_seek_callback(
+ const FLAC__SeekableStreamDecoder *,
+ FLAC__uint64 absolute_byte_offset,
+ void *client_data)
+{
+ FLACDecoder::private_data *data = (FLACDecoder::private_data*)client_data;
+
+ if(data->source->seek(absolute_byte_offset))
+ return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
+ else
+ return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
+}
+
+#ifdef HAVE_LIBOGGFLAC
+static OggFLAC__SeekableStreamDecoderSeekStatus oggflac_seek_callback(
+ const OggFLAC__SeekableStreamDecoder *,
+ FLAC__uint64 absolute_byte_offset,
+ void *client_data)
+{
+ OggFLACDecoder::private_data *data = (OggFLACDecoder::private_data*)client_data;
+
+ if(data->source->seek(absolute_byte_offset))
+ return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
+ else
+ return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
+}
+#endif
+
+static FLAC__SeekableStreamDecoderTellStatus flac_tell_callback(
+ const FLAC__SeekableStreamDecoder *,
+ FLAC__uint64 *absolute_byte_offset,
+ void *client_data)
+{
+ FLACDecoder::private_data *data = (FLACDecoder::private_data*)client_data;
+
+ long res = data->source->position();
+ if (res<0)
+ return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
+ else {
+ *absolute_byte_offset = res;
+ return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
+ }
+}
+
+#ifdef HAVE_LIBOGGFLAC
+static OggFLAC__SeekableStreamDecoderTellStatus oggflac_tell_callback(
+ const OggFLAC__SeekableStreamDecoder *,
+ FLAC__uint64 *absolute_byte_offset,
+ void *client_data)
+{
+ OggFLACDecoder::private_data *data = (OggFLACDecoder::private_data*)client_data;
+
+ long res = data->source->position();
+ if (res<0)
+ return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
+ else {
+ *absolute_byte_offset = res;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
+ }
+}
+#endif
+
+static FLAC__SeekableStreamDecoderLengthStatus flac_length_callback(
+ const FLAC__SeekableStreamDecoder *,
+ FLAC__uint64 *stream_length,
+ void *client_data)
+{
+ FLACDecoder::private_data *data = (FLACDecoder::private_data*)client_data;
+
+ long res = data->source->length();
+ if (res<0)
+ return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
+ else {
+ *stream_length = res;
+ return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
+ }
+}
+
+#ifdef HAVE_LIBOGGFLAC
+static OggFLAC__SeekableStreamDecoderLengthStatus oggflac_length_callback(
+ const OggFLAC__SeekableStreamDecoder *,
+ FLAC__uint64 *stream_length,
+ void *client_data)
+{
+ OggFLACDecoder::private_data *data = (OggFLACDecoder::private_data*)client_data;
+
+ long res = data->source->length();
+ if (res<0)
+ return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
+ else {
+ *stream_length = res;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
+ }
+}
+#endif
+
+template<class S, class T>
+static FLAC__bool eof_callback(
+ const S *,
+ void *client_data)
+{
+ T *data = (T*)client_data;
+
+ return data->source->eof();
+}
+
+template<class S, class T>
+static FLAC__StreamDecoderWriteStatus write_callback(
+ const S *,
+ const FLAC__Frame *frame,
+ const FLAC__int32 * const buffer[],
+ void* client_data)
+{
+ T *data = (T*)client_data;
+ //FLACDecoder::private_data *data = (FLACDecoder::private_data*)client_data;
+
+ if (!data->out) // Handle spurious callbacks (happens during seeks)
+ data->out = new AudioFrame;
+
+ const long frameSize = frame->header.blocksize;
+ const char bits = frame->header.bits_per_sample;
+ const char channels = frame->header.channels;
+
+ AudioFrame* const outFrame = data->out;
+
+ outFrame->reserveSpace(channels, frameSize, bits);
+ outFrame->sample_rate = frame->header.sample_rate;
+
+ if (channels == 1 || channels == 2)
+ outFrame->channel_config = aKode::MonoStereo;
+ else if (channels > 2 && channels < 8)
+ outFrame->channel_config = aKode::Surround;
+ else
+ outFrame->channel_config = aKode::MultiChannel;
+
+ for(int i = 0; i<channels; i++) {
+ if (outFrame->data[i] == 0) break;
+ if (bits<=8) {
+ int8_t** data = (int8_t**)outFrame->data;
+ for(long j=0; j<frameSize; j++)
+ data[i][j] = buffer[i][j];
+ } else
+ if (bits<=16) {
+ int16_t** data = (int16_t**)outFrame->data;
+ for(long j=0; j<frameSize; j++)
+ data[i][j] = buffer[i][j];
+ } else {
+ int32_t** data = (int32_t**)outFrame->data;
+ for(long j=0; j<frameSize; j++)
+ data[i][j] = buffer[i][j];
+ }
+ }
+ data->position+=frameSize;
+ data->valid = true;
+ return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+}
+
+template<class S, class T>
+static void metadata_callback(
+ const S *,
+ //const FLAC__SeekableStreamDecoder *decoder,
+ const FLAC__StreamMetadata *metadata,
+ void* client_data)
+{
+ T *data = (T*)client_data;
+// FLACDecoder::private_data *data = (FLACDecoder::private_data*)client_data;
+
+ if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
+ data->length = metadata->data.stream_info.total_samples;
+ data->config.sample_rate = metadata->data.stream_info.sample_rate;
+ data->config.sample_width = metadata->data.stream_info.bits_per_sample;
+ data->config.channels = metadata->data.stream_info.channels;
+ data->max_block_size = metadata->data.stream_info.max_blocksize;
+
+ if (data->config.channels <= 2)
+ data->config.channel_config = aKode::MonoStereo;
+ else if (data->config.channels <= 7)
+ data->config.channel_config = aKode::Surround;
+ else
+ data->config.channel_config = aKode::MultiChannel;
+
+ data->si = &metadata->data.stream_info;
+
+ data->position = 0;
+
+ } else
+ if (metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
+ data->vc = &metadata->data.vorbis_comment;
+ }
+}
+
+template<class S, class T>
+static void error_callback(
+ const S *,
+ //const FLAC__SeekableStreamDecoder *decoder,
+ FLAC__StreamDecoderErrorStatus status,
+ void* /* client_data */)
+{
+ //T *data = (T*)client_data;
+ std::cerr << "FLAC error: " << FLAC__StreamDecoderErrorStatusString[status] << "\n";
+ switch (status) {
+ case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
+ break;
+ case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
+ break;
+ case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
+ break;
+ }
+ //data->valid = false;
+}
+
+const AudioConfiguration* FLACDecoder::audioConfiguration() {
+ return &m_data->config;
+}
+
+#ifdef HAVE_LIBOGGFLAC
+const AudioConfiguration* OggFLACDecoder::audioConfiguration() {
+ return &m_data->config;
+}
+#endif
+
+FLACDecoder::FLACDecoder(File* src) {
+ m_data = new private_data;
+ m_data->out = 0;
+ m_data->decoder = FLAC__seekable_stream_decoder_new();
+ m_data->source = src;
+ m_data->source->openRO();
+ m_data->source->fadvise();
+ FLAC__seekable_stream_decoder_set_client_data(m_data->decoder, m_data);
+ FLAC__seekable_stream_decoder_set_read_callback (m_data->decoder, flac_read_callback);
+ FLAC__seekable_stream_decoder_set_seek_callback (m_data->decoder, flac_seek_callback);
+ FLAC__seekable_stream_decoder_set_tell_callback (m_data->decoder, flac_tell_callback);
+ FLAC__seekable_stream_decoder_set_length_callback (m_data->decoder, flac_length_callback);
+ FLAC__seekable_stream_decoder_set_eof_callback (m_data->decoder,
+ eof_callback<FLAC__SeekableStreamDecoder, private_data>);
+ FLAC__seekable_stream_decoder_set_write_callback (m_data->decoder,
+ write_callback<FLAC__SeekableStreamDecoder, private_data>);
+ FLAC__seekable_stream_decoder_set_error_callback (m_data->decoder,
+ error_callback<FLAC__SeekableStreamDecoder, private_data>);
+ FLAC__seekable_stream_decoder_set_metadata_callback(m_data->decoder,
+ metadata_callback<FLAC__SeekableStreamDecoder, private_data>);
+ FLAC__seekable_stream_decoder_set_metadata_respond (m_data->decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
+
+ FLAC__seekable_stream_decoder_init(m_data->decoder);
+ FLAC__seekable_stream_decoder_process_until_end_of_metadata(m_data->decoder);
+}
+
+FLACDecoder::~FLACDecoder() {
+ FLAC__seekable_stream_decoder_finish(m_data->decoder);
+ FLAC__seekable_stream_decoder_delete(m_data->decoder);
+ m_data->source->close();
+ delete m_data;
+}
+
+#ifdef HAVE_LIBOGGFLAC
+OggFLACDecoder::OggFLACDecoder(File* src) {
+ m_data = new private_data;
+ m_data->out = 0;
+ m_data->decoder = OggFLAC__seekable_stream_decoder_new();
+ m_data->source = src;
+ m_data->source->openRO();
+ m_data->source->fadvise();
+ OggFLAC__seekable_stream_decoder_set_client_data(m_data->decoder, m_data);
+ OggFLAC__seekable_stream_decoder_set_read_callback (m_data->decoder, oggflac_read_callback);
+ OggFLAC__seekable_stream_decoder_set_seek_callback (m_data->decoder, oggflac_seek_callback);
+ OggFLAC__seekable_stream_decoder_set_tell_callback (m_data->decoder, oggflac_tell_callback);
+ OggFLAC__seekable_stream_decoder_set_length_callback (m_data->decoder, oggflac_length_callback);
+ OggFLAC__seekable_stream_decoder_set_eof_callback (m_data->decoder,
+ eof_callback<OggFLAC__SeekableStreamDecoder, private_data>);
+ OggFLAC__seekable_stream_decoder_set_write_callback (m_data->decoder,
+ write_callback<OggFLAC__SeekableStreamDecoder, private_data>);
+ OggFLAC__seekable_stream_decoder_set_error_callback (m_data->decoder,
+ error_callback<OggFLAC__SeekableStreamDecoder, private_data>);
+ OggFLAC__seekable_stream_decoder_set_metadata_callback(m_data->decoder,
+ metadata_callback<OggFLAC__SeekableStreamDecoder, private_data>);
+ OggFLAC__seekable_stream_decoder_set_metadata_respond (m_data->decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
+
+ OggFLAC__seekable_stream_decoder_init(m_data->decoder);
+ OggFLAC__seekable_stream_decoder_process_until_end_of_metadata(m_data->decoder);
+}
+
+OggFLACDecoder::~OggFLACDecoder() {
+ OggFLAC__seekable_stream_decoder_finish(m_data->decoder);
+ OggFLAC__seekable_stream_decoder_delete(m_data->decoder);
+ m_data->source->close();
+ delete m_data;
+}
+#endif
+
+bool FLACDecoder::readFrame(AudioFrame* frame) {
+ if (m_data->error || m_data->eof) return false;
+
+ if (m_data->out) { // Handle spurious callbacks
+ frame->freeSpace();
+ *frame = *m_data->out; // copy
+ m_data->out->data = 0; // nullify, don't free!
+ delete m_data->out;
+ m_data->out = 0;
+ return true;
+ }
+ m_data->valid = false;
+ m_data->out = frame;
+ bool ret = FLAC__seekable_stream_decoder_process_single(m_data->decoder);
+ m_data->out = 0;
+ if (ret && m_data->valid) {
+ frame->pos = position();
+ return true;
+ } else {
+ FLAC__SeekableStreamDecoderState state = FLAC__seekable_stream_decoder_get_state(m_data->decoder);
+ switch (state) {
+ case FLAC__SEEKABLE_STREAM_DECODER_OK:
+ break;
+ case FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM:
+ m_data->eof = true;
+ break;
+ default:
+ m_data->error = true;
+ break;
+ }
+ return false;
+ }
+}
+
+#ifdef HAVE_LIBOGGFLAC
+bool OggFLACDecoder::readFrame(AudioFrame* frame) {
+ if (m_data->error || m_data->eof) return false;
+
+ if (m_data->out) { // Handle spurious callbacks
+ frame->freeSpace();
+ *frame = *m_data->out; // copy
+ m_data->out->data = 0; // nullify, don't free!
+ delete m_data->out;
+ m_data->out = 0;
+ return true;
+ }
+ m_data->valid = false;
+ m_data->out = frame;
+ bool ret = OggFLAC__seekable_stream_decoder_process_single(m_data->decoder);
+ m_data->out = 0;
+ if (ret && m_data->valid) {
+ frame->pos = position();
+ return true;
+ } else {
+ OggFLAC__SeekableStreamDecoderState state = OggFLAC__seekable_stream_decoder_get_state(m_data->decoder);
+ switch (state) {
+ case OggFLAC__SEEKABLE_STREAM_DECODER_OK:
+ break;
+ case OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM:
+ m_data->eof = true;
+ break;
+ default:
+ m_data->error = true;
+ break;
+ }
+ return false;
+ }
+}
+#endif
+
+long FLACDecoder::length() {
+ float pos = ((float)m_data->length)/m_data->config.sample_rate;
+ return (long)(pos*1000.0);
+}
+
+long FLACDecoder::position() {
+ float pos = ((float)m_data->position)/m_data->config.sample_rate;
+ return (long)(pos*1000.0);
+}
+
+bool FLACDecoder::eof() {
+ return m_data->eof;
+}
+
+bool FLACDecoder::error() {
+ return m_data->error;
+}
+
+bool FLACDecoder::seekable() {
+ return m_data->source->seekable();
+}
+
+bool FLACDecoder::seek(long pos) {
+ if (m_data->error) return false;
+ float samplePos = (float)pos * (float)m_data->config.sample_rate / 1000.0;
+ m_data->position = (uint64_t)samplePos;
+ return FLAC__seekable_stream_decoder_seek_absolute(m_data->decoder, m_data->position);
+}
+
+#ifdef HAVE_LIBOGGFLAC
+long OggFLACDecoder::length() {
+ float pos = ((float)m_data->length)/m_data->config.sample_rate;
+ return (long)(pos*1000.0);
+}
+
+long OggFLACDecoder::position() {
+ float pos = ((float)m_data->position)/m_data->config.sample_rate;
+ return (long)(pos*1000.0);
+}
+
+bool OggFLACDecoder::eof() {
+ return m_data->eof;
+}
+
+bool OggFLACDecoder::error() {
+ return m_data->error;
+}
+
+bool OggFLACDecoder::seekable() {
+ return m_data->source->seekable();
+}
+
+bool OggFLACDecoder::seek(long pos) {
+ if (m_data->error) return false;
+ float samplePos = (float)pos * (float)m_data->config.sample_rate / 1000.0;
+ m_data->position = (uint64_t)samplePos;
+ return OggFLAC__seekable_stream_decoder_seek_absolute(m_data->decoder, m_data->position);
+}
+#endif
+
+} // namespace
+
+#endif // HAVE_LIBFLAC
diff --git a/akode/plugins/xiph_decoder/flac_decoder.h b/akode/plugins/xiph_decoder/flac_decoder.h
new file mode 100644
index 0000000..68a4cd9
--- /dev/null
+++ b/akode/plugins/xiph_decoder/flac_decoder.h
@@ -0,0 +1,103 @@
+/* aKode: FLAC-Decoder
+
+ Copyright (C) 2004 Allan Sandfeld Jensen <kde@carewolf.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef _AKODE_FLAC_DECODER_H
+#define _AKODE_FLAC_DECODER_H
+
+#include "akodelib.h"
+#if defined(HAVE_LIBFLAC) || defined(HAVE_LIBFLAC113)
+
+#include "decoder.h"
+
+namespace aKode {
+
+class File;
+class AudioFrame;
+
+class FLACDecoder : public Decoder {
+public:
+ FLACDecoder(File* src);
+ virtual ~FLACDecoder();
+ virtual bool readFrame(AudioFrame*);
+ virtual long length();
+ virtual long position();
+ virtual bool seek(long);
+ virtual bool seekable();
+ virtual bool eof();
+ virtual bool error();
+
+ virtual const AudioConfiguration* audioConfiguration();
+
+ struct private_data;
+private:
+ private_data *m_data;
+};
+
+#ifdef HAVE_LIBOGGFLAC
+class OggFLACDecoder : public Decoder {
+public:
+ OggFLACDecoder(File* src);
+ virtual ~OggFLACDecoder();
+ virtual bool readFrame(AudioFrame*);
+ virtual long length();
+ virtual long position();
+ virtual bool seek(long);
+ virtual bool seekable();
+ virtual bool eof();
+ virtual bool error();
+
+ virtual const AudioConfiguration* audioConfiguration();
+
+ struct private_data;
+private:
+ private_data *m_data;
+};
+#endif
+
+class FLACDecoderPlugin : public DecoderPlugin {
+public:
+ virtual bool canDecode(File*);
+ virtual Decoder* openDecoder(File* fil) {
+ return new FLACDecoder(fil);
+ };
+};
+
+extern "C" FLACDecoderPlugin flac_decoder;
+#ifdef HAVE_LIBFLAC113
+extern "C" FLACDecoderPlugin oggflac_decoder;
+#endif
+
+#ifdef HAVE_LIBOGGFLAC
+class OggFLACDecoderPlugin : public DecoderPlugin {
+public:
+ virtual bool canDecode(File*);
+ virtual Decoder* openDecoder(File* fil) {
+ return new OggFLACDecoder(fil);
+ };
+};
+
+extern "C" OggFLACDecoderPlugin oggflac_decoder;
+#endif
+
+} // namespace
+
+
+#endif // HAVE_LIBFLAC
+#endif
diff --git a/akode/plugins/xiph_decoder/speex_decoder.cpp b/akode/plugins/xiph_decoder/speex_decoder.cpp
new file mode 100644
index 0000000..4c3d816
--- /dev/null
+++ b/akode/plugins/xiph_decoder/speex_decoder.cpp
@@ -0,0 +1,351 @@
+/* aKode: Speex-Decoder
+
+ Copyright (C) 2004 Allan Sandfeld Jensen <kde@carewolf.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "akodelib.h"
+
+#ifdef HAVE_SPEEX
+
+extern "C" {
+#include <string.h>
+#include <stdlib.h>
+#include <speex.h>
+#include <speex_header.h>
+#include <speex_callbacks.h>
+#include <speex_stereo.h>
+#include <ogg/ogg.h>
+}
+
+#ifdef SPEEX_DEBUG
+#include <iostream>
+using std::cerr;
+#endif
+
+#include "file.h"
+#include "audioframe.h"
+#include "decoder.h"
+#include "speex_decoder.h"
+
+namespace aKode {
+
+bool SpeexDecoderPlugin::canDecode(File* src) {
+ char header[36];
+ bool res = false;
+ src->openRO();
+ if (src->read(header, 36) == 36)
+ if (memcmp(header, "OggS",4) == 0 )
+ if (memcmp(header+28, "Speex ",8) == 0) res = true;
+ src->close();
+ return res;
+};
+
+extern "C" { SpeexDecoderPlugin speex_decoder; };
+
+struct SpeexDecoder::private_data
+{
+ SpeexBits bits;
+ SpeexMode *mode;
+ SpeexStereoState stereo;
+
+ ogg_sync_state sync;
+ ogg_stream_state stream;
+ ogg_page page; // current page
+ ogg_packet packet; // current packet
+
+ void *dec_state;
+ File *src;
+#ifdef HAVE_SPEEX11
+ int16_t *out_buffer;
+#else
+ float *out_buffer;
+#endif
+
+ unsigned int bitrate;
+ int frame_size;
+ int frames_per_packet;
+ int frame_nr;
+ AudioConfiguration config;
+ int serialno;
+ long position;
+ bool seeked;
+
+ bool initialized;
+ bool error, eof;
+};
+
+SpeexDecoder::SpeexDecoder(File *src) {
+ m_data = new private_data;
+ m_data->src = src;
+ m_data->out_buffer = 0;
+
+ ogg_sync_init(&m_data->sync);
+
+ m_data->dec_state = 0;
+ SpeexStereoState initstereo = SPEEX_STEREO_STATE_INIT;
+ m_data->stereo = initstereo;
+
+ m_data->initialized = m_data->eof = m_data->error = false;
+ m_data->frame_nr = 100000;
+ m_data->position = 0;
+ m_data->seeked = false;
+
+ src->openRO();
+ src->fadvise();
+};
+
+SpeexDecoder::~SpeexDecoder() {
+ if (m_data->initialized) {
+ speex_bits_reset(&m_data->bits);
+ ogg_sync_clear(&m_data->sync);
+ ogg_stream_clear(&m_data->stream);
+ if (m_data->dec_state) speex_decoder_destroy(m_data->dec_state);
+ m_data->src->close();
+ delete[] m_data->out_buffer;
+ }
+ delete m_data;
+}
+
+bool SpeexDecoder::openFile() {
+ m_data->error = false;
+ while(ogg_sync_pageout(&m_data->sync, &m_data->page) != 1) {
+ char *buf = ogg_sync_buffer(&m_data->sync, 1024);
+ int read = m_data->src->read(buf, 1024);
+ if (read <= 0) {
+ m_data->error = true;
+ return false;
+ }
+ ogg_sync_wrote(&m_data->sync, read);
+ }
+ m_data->serialno = ogg_page_serialno(&m_data->page);
+ ogg_stream_init(&m_data->stream, m_data->serialno);
+ speex_bits_init(&m_data->bits);
+
+// ogg_stream_pagein(&m_data->stream, &m_data->page);
+ //ogg_stream_packetout(&m_data->stream, &m_data->packet);
+// ogg_stream_packetout(&m_data->stream, &m_data->packet);
+
+ if(!decodeHeader())
+ {
+ m_data->error = true;
+ return false;
+ }
+
+ m_data->initialized = true;
+ return true;
+}
+
+bool SpeexDecoder::readPage() {
+
+ while (ogg_sync_pageout(&m_data->sync, &m_data->page) != 1) {
+ char *buf = ogg_sync_buffer(&m_data->sync, 4096);
+ long read = m_data->src->read(buf, 4096);
+ if (read <= 0) return false;
+ ogg_sync_wrote(&m_data->sync, read);
+ }
+
+ ogg_stream_pagein(&m_data->stream, &m_data->page);
+// m_data->packets = ogg_page_packets(&m_data->page);
+ return true;
+}
+
+bool SpeexDecoder::readPacket() {
+ bool res = true;
+ while (ogg_stream_packetpeek(&m_data->stream, &m_data->packet) != 1 && res) {
+ res = readPage();
+ }
+ ogg_stream_packetout(&m_data->stream, &m_data->packet);
+ speex_bits_read_from(&m_data->bits, (char*)m_data->packet.packet, m_data->packet.bytes);
+ m_data->frame_nr = 0;
+
+ return res;
+}
+
+bool SpeexDecoder::decodeHeader() {
+
+ SpeexHeader *header;
+ header = speex_packet_to_header((char*)m_data->page.body, m_data->page.body_len);
+ if (!header) {
+ // invalid file
+ m_data->error = true;
+ #ifdef SPEEX_DEBUG
+ std::cerr << "Invalid file\n";
+ #endif
+ return false;
+ }
+
+ SpeexMode *mode = ( SpeexMode* )speex_mode_list[ header->mode ];
+ m_data->mode = mode;
+ m_data->config.channels = header->nb_channels;
+ m_data->config.channel_config = MonoStereo;
+ m_data->frames_per_packet = header->frames_per_packet;
+
+ if (mode->bitstream_version != header->mode_bitstream_version) {
+ // incompatible bitstream
+ m_data->error = true;
+ return false;
+ }
+
+ m_data->dec_state = speex_decoder_init(mode);
+ speex_decoder_ctl(m_data->dec_state, SPEEX_GET_FRAME_SIZE, &m_data->frame_size);
+ //m_data->bitrate = header->bitrate;
+ speex_decoder_ctl(m_data->dec_state, SPEEX_GET_BITRATE, &m_data->bitrate);
+ m_data->config.sample_rate = header->rate;
+ m_data->config.sample_width = 16;
+ speex_decoder_ctl(m_data->dec_state, SPEEX_SET_SAMPLING_RATE, &m_data->config.sample_rate);
+ //speex_decoder_ctl(m_data->dec_state, SPEEX_GET_SAMPLING_RATE, &m_data->sample_rate);
+
+ // Use the perceptial enhancement, which gives a subjectively better result
+ // but is technically further from the source.
+ int i = 1;
+ speex_decoder_ctl(m_data->dec_state, SPEEX_SET_ENH, &i);
+
+ // Handle the patched-on stereo stuff
+ if (m_data->config.channels != 1) {
+ SpeexCallback callback;
+ callback.callback_id = SPEEX_INBAND_STEREO;
+ callback.func = speex_std_stereo_request_handler;
+ callback.data = &m_data->stereo;
+ speex_decoder_ctl(m_data->dec_state, SPEEX_SET_HANDLER, &callback);
+ }
+ #ifdef HAVE_SPEEX11
+ m_data->out_buffer = new int16_t[m_data->frame_size*m_data->config.channels];
+ #else
+ m_data->out_buffer = new float[m_data->frame_size*m_data->config.channels];
+ #endif
+
+ free(header);
+ return true;
+}
+
+bool SpeexDecoder::readFrame(AudioFrame* frame)
+{
+ if (!m_data->initialized) openFile();
+
+ if (m_data->eof || m_data->error) return false;
+
+ if (m_data->frame_nr >= m_data->frames_per_packet) {
+ if (!readPacket()) {
+ m_data->eof = true;
+ return false;
+ }
+ }
+ #if defined(HAVE_SPEEX11) && !defined(BROKEN_SPEEX11)
+ speex_decode_int(m_data->dec_state, &m_data->bits, m_data->out_buffer);
+ #else
+ speex_decode(m_data->dec_state, &m_data->bits, m_data->out_buffer);
+ #endif
+
+ int channels = m_data->config.channels;
+ int length = m_data->frame_size;
+ frame->reserveSpace(&m_data->config, length);
+
+ if (m_data->config.channels == 2)
+ #if defined(HAVE_SPEEX11) && !defined(BROKEN_SPEEX11)
+ speex_decode_stereo_int(m_data->out_buffer, length, &m_data->stereo);
+ #else
+ speex_decode_stereo(m_data->out_buffer, length, &m_data->stereo);
+ #endif
+
+
+ for (int i=0; i<m_data->frame_size*m_data->config.channels; i++) {
+ if (m_data->out_buffer[i] > 32766) m_data->out_buffer[i] = 32767;
+ else
+ if (m_data->out_buffer[i] < -32767) m_data->out_buffer[i] = -32768;
+ else
+ m_data->out_buffer[i] = m_data->out_buffer[i];
+ };
+
+ // Decode into frame
+ int16_t** data = (int16_t**)frame->data;
+ for(int i=0; i<length; i++)
+ for(int j=0; j<channels; j++)
+ #if defined(HAVE_SPEEX11)
+ data[j][i] = m_data->out_buffer[i*channels+j];
+ #else
+ data[j][i] = (int16_t)(m_data->out_buffer[i*channels+j]+0.5);
+ #endif
+
+
+ m_data->position += m_data->frame_size;
+ frame->pos = position();
+ m_data->frame_nr++;
+ return true;
+}
+
+long SpeexDecoder::length() {
+ if (!m_data->bitrate || !m_data->initialized) return -1;
+ float spxlen = (8.0*m_data->src->length())/(float)m_data->bitrate;
+ return (long)(spxlen*1000.0);
+}
+
+long SpeexDecoder::position() {
+ if (!m_data->bitrate || !m_data->initialized) return -1;
+ float spxpos = ((float)m_data->position)/(float)m_data->config.sample_rate;
+
+ if (m_data->seeked) {
+ float tellpos = (8.0*m_data->src->position())/(float)m_data->bitrate;
+ // tellpos should always be somewhat ahead, if spxpos is worse use tellpos
+ if (tellpos < spxpos) {
+ spxpos = tellpos;
+ m_data->position = (long)(tellpos*m_data->config.sample_rate);
+ }
+ }
+
+ return (long)(spxpos*1000.0);
+}
+
+bool SpeexDecoder::eof() {
+ return m_data->eof || m_data->error;
+ /*return m_data->error || (m_data->src->eof() && m_data->frame_nr >= m_data->frames_per_packet); */
+}
+
+bool SpeexDecoder::error() {
+ return m_data->error;
+}
+
+bool SpeexDecoder::seekable() {
+ return m_data->src->seekable();
+}
+
+bool SpeexDecoder::seek(long pos) {
+ if(!m_data->initialized) return false;
+
+ long bpos = (long)(((float)pos*(float)m_data->bitrate)/8000.0);
+ if (m_data->src->seek(bpos)) {
+ speex_bits_reset(&m_data->bits);
+ ogg_sync_reset(&m_data->sync);
+ ogg_stream_reset(&m_data->stream);
+ readPage();
+ readPacket();
+ // We should now have read in a whole new page
+ bpos = (m_data->src->position()-m_data->page.body_len);
+ m_data->position = (long)((bpos*8.0*m_data->config.sample_rate)/(float)m_data->bitrate);
+ m_data->seeked = true;
+ return true;
+ }
+ return false;
+}
+
+const AudioConfiguration* SpeexDecoder::audioConfiguration() {
+ return &m_data->config;
+}
+
+} // namespace
+
+#endif // HAVE_SPEEX
diff --git a/akode/plugins/xiph_decoder/speex_decoder.h b/akode/plugins/xiph_decoder/speex_decoder.h
new file mode 100644
index 0000000..903f828
--- /dev/null
+++ b/akode/plugins/xiph_decoder/speex_decoder.h
@@ -0,0 +1,74 @@
+/* aKode: Speex-Format
+
+ Copyright (C) 2004 Allan Sandfeld Jensen <kde@carewolf.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef _AKODE_SPEEX_DECODER_H
+#define _AKODE_SPEEX_DECODER_H
+
+#include "akodelib.h"
+#ifdef HAVE_SPEEX
+
+#include "decoder.h"
+
+namespace aKode {
+
+class File;
+class AudioFrame;
+
+class SpeexDecoder : public Decoder {
+public:
+ SpeexDecoder(File* src);
+ virtual ~SpeexDecoder();
+ bool openFile();
+
+ virtual bool readFrame(AudioFrame*);
+ virtual long length();
+ virtual long position();
+ virtual bool seek(long);
+ virtual bool seekable();
+ virtual bool eof();
+ virtual bool error();
+
+ virtual const AudioConfiguration* audioConfiguration();
+
+ struct private_data;
+private:
+ bool readPage();
+ bool readPacket();
+ bool decodeHeader();
+
+ private_data *m_data;
+};
+
+
+class SpeexDecoderPlugin : public DecoderPlugin {
+public:
+ virtual bool canDecode(File*);
+ virtual Decoder* openDecoder(File* src) {
+ return new SpeexDecoder(src);
+ };
+};
+
+extern "C" SpeexDecoderPlugin speex_decoder;
+
+} // namespace
+
+
+#endif // HAVE_SPEEX
+#endif
diff --git a/akode/plugins/xiph_decoder/vorbis_decoder.cpp b/akode/plugins/xiph_decoder/vorbis_decoder.cpp
new file mode 100644
index 0000000..44329d0
--- /dev/null
+++ b/akode/plugins/xiph_decoder/vorbis_decoder.cpp
@@ -0,0 +1,277 @@
+/* aKode: Ogg Vorbis-Decoder
+
+ Copyright (C) 2004 Allan Sandfeld Jensen <kde@carewolf.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "akodelib.h"
+#ifdef HAVE_OGG_VORBIS
+
+#include <vorbis/vorbisfile.h>
+
+#include "file.h"
+#include "audioframe.h"
+#include "decoder.h"
+#include "vorbis_decoder.h"
+
+//#include <iostream>
+
+namespace aKode {
+
+static size_t _read(void *ptr, size_t size, size_t nmemb, void *datasource) {
+ File *src = (File*)datasource;
+ return src->read((char*)ptr, size*nmemb);
+}
+
+static int _seek(void *datasource, ogg_int64_t offset, int whence) {
+ File *src = (File*)datasource;
+ if (src->seek(offset, whence))
+ return 0;
+ else
+ return -1;
+}
+
+static int _close(void *datasource) {
+ File *src = (File*)datasource;
+ src->close();
+ return 0;
+}
+
+static long _tell(void *datasource) {
+ File *src = (File*)datasource;
+ return src->position();
+}
+
+static ov_callbacks _callbacks = {_read, _seek, _close, _tell};
+
+bool VorbisDecoderPlugin::canDecode(File* src) {
+ OggVorbis_File vf;
+ src->openRO();
+ int r = ov_test_callbacks(src, &vf, 0, 0, _callbacks);
+ ov_clear(&vf);
+ src->close();
+ return r==0;
+}
+
+extern "C" { VorbisDecoderPlugin vorbis_decoder; }
+
+
+struct VorbisDecoder::private_data
+{
+ private_data() : bitstream(0), eof(false), error(false), initialized(false), retries(0), big_endian(0) {};
+ OggVorbis_File *vf;
+ vorbis_comment *vc;
+ vorbis_info *vi;
+
+ File *src;
+ AudioConfiguration config;
+
+ int bitstream;
+ bool eof, error;
+ char buffer[8192];
+ bool initialized;
+ int retries;
+
+ int big_endian;
+};
+
+VorbisDecoder::VorbisDecoder(File *src) {
+ m_data = new private_data;
+ m_data->vf = new OggVorbis_File;
+
+ m_data->src = src;
+ m_data->src->openRO();
+ m_data->src->fadvise();
+
+ unsigned short endian_test = 1;
+ m_data->big_endian = 1 - (*((char *)(&endian_test)));
+}
+
+VorbisDecoder::~VorbisDecoder() {
+ if (m_data->initialized)
+ ov_clear(m_data->vf);
+ delete m_data->vf;
+ delete m_data;
+}
+
+static void setAudioConfiguration(AudioConfiguration *config, vorbis_info *vi)
+{
+ config->channels = vi->channels;
+ config->sample_rate = vi->rate;
+ config->sample_width = 16;
+
+ if (config->channels <= 2) {
+ config->channel_config = MonoStereo;
+ config->surround_config = 0;
+ } else
+ if (config->channels <= 6) {
+ config->channel_config = Surround;
+ SurroundConfiguration surround_config;
+ switch (config->channels) {
+ case 3:
+ surround_config.front_channels = 3;
+ break;
+ case 4:
+ surround_config.front_channels = 2;
+ surround_config.rear_channels = 2;
+ break;
+ case 5:
+ surround_config.front_channels = 3;
+ surround_config.rear_channels = 2;
+ break;
+ case 6:
+ surround_config.front_channels = 3;
+ surround_config.rear_channels = 2;
+ surround_config.LFE_channel = 1;
+ break;
+ }
+ config->surround_config = surround_config;
+ }
+ else {
+ config->channel_config = MultiChannel;
+ config->surround_config = 0;
+ }
+}
+
+bool VorbisDecoder::openFile() {
+ int status;
+
+ status = ov_open_callbacks(m_data->src, m_data->vf, 0, 0, _callbacks);
+ if (status != 0) goto fault;
+
+ m_data->vi = ov_info(m_data->vf, -1);
+ //m_data->vc = ov_comment(m_data->vf, -1);
+ setAudioConfiguration(&m_data->config, m_data->vi);
+
+ m_data->initialized = true;
+ m_data->error = false;
+ m_data->retries = 0;
+ return true;
+fault:
+ m_data->initialized = false;
+ m_data->error = true;
+ return false;
+}
+
+// translation from vorbis channel-layout to akodelib channel-layout
+static int vorbis_channel[7][6] = {
+ {-1, -1, -1, -1, -1, -1},
+ {0, -1, -1, -1, -1, -1},
+ {0, 1, -1, -1, -1, -1},
+ {0, 2, 1, -1, -1, -1},
+ {0, 1, 2, 3, -1, -1},
+ {0, 2, 1, 3, 4, -1},
+ {0, 2, 1, 3, 4, 5}
+};
+
+bool VorbisDecoder::readFrame(AudioFrame* frame)
+{
+ if (!m_data->initialized) {
+ if (!openFile()) return false;
+ }
+
+ int old_bitstream = m_data->bitstream;
+ long v = ov_read(m_data->vf, (char*)m_data->buffer, 8192, m_data->big_endian, 2, 1, &m_data->bitstream);
+
+ if (v == 0 || v == OV_EOF ) {
+ // vorbisfile sometimes return 0 even though EOF is not yet reached
+ if (m_data->src->eof() || m_data->src->error() || ++m_data->retries >= 16)
+ m_data->eof = true;
+// std::cerr << "akode-vorbis: EOF\n";
+ }
+ else
+ if (v == OV_HOLE) {
+ if (++m_data->retries >= 16) m_data->error = true;
+// std::cerr << "akode-vorbis: Hole\n";
+ }
+ else
+ if (v < 0) {
+ m_data->error = true;
+// std::cerr << "akode-vorbis: Error\n";
+ }
+
+ if (v <= 0) return false;
+ m_data->retries = 0;
+
+ if (old_bitstream != m_data->bitstream) { // changing streams, update info
+ m_data->vi = ov_info(m_data->vf, -1);
+ //m_data->vc = ov_comment(m_data->vf, -1);
+ setAudioConfiguration(&m_data->config, m_data->vi);
+ }
+
+ int channels = m_data->config.channels;
+ long length = v/(channels*2);
+ frame->reserveSpace(&m_data->config, length);
+
+ // Demux into frame
+ int16_t* buffer = (int16_t*)m_data->buffer;
+ int16_t** data = (int16_t**)frame->data;
+ if (channels <= 6) {
+ int *trans = vorbis_channel[channels];
+ for(int i=0; i<length; i++)
+ for(int j=0; j<channels; j++)
+ data [trans[j]] [i] = buffer[i*channels+j];
+ }
+ else
+ for(int i=0; i<length; i++)
+ for(int j=0; j<channels; j++)
+ data[j][i] = buffer[i*channels+j];
+
+ frame->pos = position();
+ return true;
+}
+
+long VorbisDecoder::length() {
+ if (!m_data->initialized) return -1;
+ // -1 return total length of all bitstreams.
+ // Should we take them one at a time instead?
+ double ogglen = ov_time_total(m_data->vf,-1);
+ return (long)(ogglen*1000.0);
+}
+
+long VorbisDecoder::position() {
+ if (!m_data->initialized) return -1;
+ double oggpos = ov_time_tell(m_data->vf);
+ return (long)(oggpos*1000.0);
+}
+
+bool VorbisDecoder::eof() {
+ return m_data->eof;
+}
+
+bool VorbisDecoder::error() {
+ return m_data->error;
+}
+
+bool VorbisDecoder::seekable() {
+ return m_data->src->seekable();
+}
+
+bool VorbisDecoder::seek(long pos) {
+ if (!m_data->initialized) return false;
+ int r = ov_time_seek(m_data->vf, pos/1000.0);
+ return r == 0;
+}
+
+const AudioConfiguration* VorbisDecoder::audioConfiguration() {
+ if (!m_data->initialized) return 0;
+ return &m_data->config;
+}
+
+} // namespace
+
+#endif //OGG_VORBIS
diff --git a/akode/plugins/xiph_decoder/vorbis_decoder.h b/akode/plugins/xiph_decoder/vorbis_decoder.h
new file mode 100644
index 0000000..5dd6790
--- /dev/null
+++ b/akode/plugins/xiph_decoder/vorbis_decoder.h
@@ -0,0 +1,70 @@
+/* aKode: Ogg Vorbis-Format
+
+ Copyright (C) 2004 Allan Sandfeld Jensen <kde@carewolf.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef _AKODE_VORBISFORMAT_H
+#define _AKODE_VORBISFORMAT_H
+
+#include "akodelib.h"
+#ifdef HAVE_OGG_VORBIS
+
+#include "decoder.h"
+
+namespace aKode {
+
+class File;
+class AudioFrame;
+
+class VorbisDecoder : public Decoder {
+public:
+ VorbisDecoder(File* src);
+ virtual ~VorbisDecoder();
+
+ virtual bool openFile();
+
+ virtual bool readFrame(AudioFrame*);
+ virtual long length();
+ virtual long position();
+ virtual bool seek(long);
+ virtual bool seekable();
+ virtual bool eof();
+ virtual bool error();
+
+ virtual const AudioConfiguration* audioConfiguration();
+
+ struct private_data;
+private:
+ private_data *m_data;
+};
+
+
+class VorbisDecoderPlugin : public DecoderPlugin {
+public:
+ virtual bool canDecode(File*);
+ virtual VorbisDecoder* openDecoder(File* src) {
+ return new VorbisDecoder(src);
+ };
+};
+
+extern "C" VorbisDecoderPlugin vorbis_decoder;
+
+} // namespace
+
+#endif // HAVE_VORBIS
+#endif
diff --git a/akode/plugins/xiph_decoder/xiph_decoder.cpp b/akode/plugins/xiph_decoder/xiph_decoder.cpp
new file mode 100644
index 0000000..841656d
--- /dev/null
+++ b/akode/plugins/xiph_decoder/xiph_decoder.cpp
@@ -0,0 +1,84 @@
+/* aKode: Xiph-Format
+
+ Copyright (C) 2004 Allan Sandfeld Jensen <kde@carewolf.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the src COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "akodelib.h"
+
+#include "file.h"
+#include "audioframe.h"
+#include "decoder.h"
+
+#include "xiph_decoder.h"
+#include "flac_decoder.h"
+#include "vorbis_decoder.h"
+#include "speex_decoder.h"
+
+namespace aKode {
+
+bool XiphDecoderPlugin::canDecode(File* src) {
+#if defined(HAVE_LIBFLAC) || defined(HAVE_LIBFLAC113)
+ if (flac_decoder.canDecode(src))
+ return true;
+ else
+#endif
+#ifdef HAVE_LIBOGGFLAC
+ if (oggflac_decoder.canDecode(src))
+ return true;
+ else
+#endif
+#ifdef HAVE_OGG_VORBIS
+ if (vorbis_decoder.canDecode(src))
+ return true;
+ else
+#endif
+#ifdef HAVE_SPEEX
+ if (speex_decoder.canDecode(src))
+ return true;
+ else
+#endif
+ return false;
+}
+
+Decoder* XiphDecoderPlugin::openDecoder(File* src) {
+#if defined(HAVE_LIBFLAC) || defined(HAVE_LIBFLAC113)
+ if (flac_decoder.canDecode(src))
+ return flac_decoder.openDecoder(src);
+ else
+#endif
+#ifdef HAVE_LIBOGGFLAC
+ if (oggflac_decoder.canDecode(src))
+ return oggflac_decoder.openDecoder(src);
+ else
+#endif
+#ifdef HAVE_OGG_VORBIS
+ if (vorbis_decoder.canDecode(src))
+ return vorbis_decoder.openDecoder(src);
+ else
+#endif
+#ifdef HAVE_SPEEX
+ if (speex_decoder.canDecode(src))
+ return speex_decoder.openDecoder(src);
+ else
+#endif
+ return 0;
+}
+
+extern "C" { XiphDecoderPlugin xiph_decoder; }
+
+} // namespace
diff --git a/akode/plugins/xiph_decoder/xiph_decoder.h b/akode/plugins/xiph_decoder/xiph_decoder.h
new file mode 100644
index 0000000..bef9fc8
--- /dev/null
+++ b/akode/plugins/xiph_decoder/xiph_decoder.h
@@ -0,0 +1,42 @@
+/* aKode: Xiph-Format (parent for various Xiph formats)
+
+ Copyright (C) 2004 Allan Sandfeld Jensen <kde@carewolf.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef _AKODE_XIPH_DECODER_H
+#define _AKODE_XIPH_DECODER_H
+
+#include "akodelib.h"
+
+#include "decoder.h"
+
+namespace aKode {
+
+class File;
+
+class XiphDecoderPlugin : public DecoderPlugin {
+public:
+ virtual bool canDecode(File*);
+ virtual Decoder* openDecoder(File* src);
+};
+
+extern "C" XiphDecoderPlugin xiph_decoder;
+
+} // namespace
+
+#endif