1.1 --- a/AUTHORS Sun May 25 12:00:22 2003 +0000
1.2 +++ b/AUTHORS Sun May 25 13:39:13 2003 +0000
1.3 @@ -383,4 +383,7 @@
1.4 Matthew Grooms
1.5 msvc win32 port
1.6
1.7 +Conrad Parker <conrad@metadecks.org>
1.8 + speex support
1.9 +
1.10 (let us know if we've forgotten anyone)
2.1 --- a/ChangeLog Sun May 25 12:00:22 2003 +0000
2.2 +++ b/ChangeLog Sun May 25 13:39:13 2003 +0000
2.3 @@ -14,7 +14,8 @@
2.4 (23.976, 59.94 and 60 fps)
2.5 * move http proxy configuration to xine itself
2.6 * add expand post video filter for displaying subtitles in borders
2.7 -
2.8 + * speex (http://www.speex.org) audio decoder support
2.9 +
2.10 xine-lib (1-beta12)
2.11 * enabled SVQ3 video decoding via ffmpeg
2.12 * playback of theorastreams added
3.1 --- a/configure.ac Sun May 25 12:00:22 2003 +0000
3.2 +++ b/configure.ac Sun May 25 13:39:13 2003 +0000
3.3 @@ -41,7 +41,7 @@
3.4 if test -f .cvsversion; then
3.5 XINE_PRE="cvs"
3.6 else
3.7 - XINE_PRE="beta12"
3.8 + XINE_PRE="beta13"
3.9 fi
3.10
3.11 AC_SUBST(XINE_MAJOR)
3.12 @@ -626,6 +626,17 @@
3.13 AM_CONDITIONAL(HAVE_THEORA, [test x"$no_ogg" != "xyes" -a x"$no_theora" != "xyes"])
3.14
3.15 dnl ---------------------------------------------
3.16 +dnl Ogg/Speex libs.
3.17 +dnl ---------------------------------------------
3.18 +
3.19 +AM_PATH_OGG(
3.20 + [ AM_PATH_SPEEX(AC_DEFINE(HAVE_SPEEX,1,[Define this if you have speex]),
3.21 + AC_MSG_RESULT([*** All OGG/SPEEX dependent parts will be disabled ***]))
3.22 + ],
3.23 + AC_MSG_RESULT([*** All of OGG/Speex dependent parts will be disabled ***]))
3.24 +AM_CONDITIONAL(HAVE_SPEEX, [test x"$no_ogg" != "xyes" -a x"$no_speex" != "xyes"])
3.25 +
3.26 +dnl ---------------------------------------------
3.27 dnl check for libFLAC
3.28 dnl ---------------------------------------------
3.29 AM_PATH_LIBFLAC([],
3.30 @@ -1364,6 +1375,7 @@
3.31 src/libsputext/Makefile
3.32 src/libvorbis/Makefile
3.33 src/libtheora/Makefile
3.34 +src/libspeex/Makefile
3.35 src/libw32dll/Makefile
3.36 src/libw32dll/wine/Makefile
3.37 src/libw32dll/DirectShow/Makefile
3.38 @@ -1511,6 +1523,9 @@
3.39 if test x"$no_vorbis" != "xyes"; then
3.40 echo " - vorbis"
3.41 fi
3.42 +if test x"$no_speex" != "xyes"; then
3.43 + echo " - speex"
3.44 +fi
3.45 if test x"$enable_w32dll" = "xyes"; then
3.46 echo " - w32dll"
3.47 fi
4.1 --- a/m4/Makefile.am Sun May 25 12:00:22 2003 +0000
4.2 +++ b/m4/Makefile.am Sun May 25 13:39:13 2003 +0000
4.3 @@ -29,6 +29,7 @@
4.4 progtest.m4 \
4.5 sdl.m4 \
4.6 vorbis.m4 \
4.7 + speex.m4 \
4.8 theora.m4 \
4.9 xine.m4 \
4.10 _xine.m4 \
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/m4/speex.m4 Sun May 25 13:39:13 2003 +0000
5.3 @@ -0,0 +1,90 @@
5.4 +# Configure paths for libspeex
5.5 +# Jack Moffitt <jack@icecast.org> 10-21-2000
5.6 +# Shamelessly stolen from Owen Taylor and Manish Singh
5.7 +
5.8 +dnl AM_PATH_SPEEX([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
5.9 +dnl Test for libspeex, and define SPEEX_CFLAGS and SPEEX_LIBS
5.10 +dnl
5.11 +AC_DEFUN([AM_PATH_SPEEX],
5.12 +[dnl
5.13 +dnl Get the cflags and libraries
5.14 +dnl
5.15 +AC_ARG_WITH(speex-prefix,[ --with-speex-prefix=PFX Prefix where libspeex is installed (optional)], speex_prefix="$withval", speex_prefix="")
5.16 +AC_ARG_ENABLE(speextest, [ --disable-speextest Do not try to compile and run a test Speex program],, enable_speextest=yes)
5.17 +
5.18 + if test x$speex_prefix != x ; then
5.19 + speex_args="$speex_args --prefix=$speex_prefix"
5.20 + SPEEX_CFLAGS="-I$speex_prefix/include"
5.21 + SPEEX_LIBDIR="-L$speex_prefix/lib"
5.22 + fi
5.23 +
5.24 + SPEEX_LIBS="$SPEEX_LIBDIR -lspeex -lm"
5.25 +
5.26 + AC_MSG_CHECKING(for Speex)
5.27 + no_speex=""
5.28 +
5.29 +
5.30 + if test "x$enable_speextest" = "xyes" ; then
5.31 + ac_save_CFLAGS="$CFLAGS"
5.32 + ac_save_LIBS="$LIBS"
5.33 + CFLAGS="$CFLAGS $SPEEX_CFLAGS"
5.34 + LIBS="$LIBS $SPEEX_LIBS $OGG_LIBS"
5.35 +dnl
5.36 +dnl Now check if the installed Speex is sufficiently new.
5.37 +dnl
5.38 + rm -f conf.speextest
5.39 + AC_TRY_RUN([
5.40 +#include <stdio.h>
5.41 +#include <stdlib.h>
5.42 +#include <string.h>
5.43 +#include <speex.h>
5.44 +
5.45 +int main ()
5.46 +{
5.47 + system("touch conf.speextest");
5.48 + return 0;
5.49 +}
5.50 +
5.51 +],, no_speex=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
5.52 + CFLAGS="$ac_save_CFLAGS"
5.53 + LIBS="$ac_save_LIBS"
5.54 + fi
5.55 +
5.56 + if test "x$no_speex" = x ; then
5.57 + AC_MSG_RESULT(yes)
5.58 + ifelse([$1], , :, [$1])
5.59 + else
5.60 + AC_MSG_RESULT(no)
5.61 + if test -f conf.speextest ; then
5.62 + :
5.63 + else
5.64 + echo "*** Could not run Speex test program, checking why..."
5.65 + CFLAGS="$CFLAGS $SPEEX_CFLAGS"
5.66 + LIBS="$LIBS $SPEEX_LIBS $OGG_LIBS"
5.67 + AC_TRY_LINK([
5.68 +#include <stdio.h>
5.69 +#include <speex/codec.h>
5.70 +], [ return 0; ],
5.71 + [ echo "*** The test program compiled, but did not run. This usually means"
5.72 + echo "*** that the run-time linker is not finding Speex or finding the wrong"
5.73 + echo "*** version of Speex. If it is not finding Speex, you'll need to set your"
5.74 + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
5.75 + echo "*** to the installed location Also, make sure you have run ldconfig if that"
5.76 + echo "*** is required on your system"
5.77 + echo "***"
5.78 + echo "*** If you have an old version installed, it is best to remove it, although"
5.79 + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
5.80 + [ echo "*** The test program failed to compile or link. See the file config.log for the"
5.81 + echo "*** exact error that occured. This usually means Speex was incorrectly installed"
5.82 + echo "*** or that you have moved Speex since it was installed." ])
5.83 + CFLAGS="$ac_save_CFLAGS"
5.84 + LIBS="$ac_save_LIBS"
5.85 + fi
5.86 + SPEEX_CFLAGS=""
5.87 + SPEEX_LIBS=""
5.88 + ifelse([$2], , :, [$2])
5.89 + fi
5.90 + AC_SUBST(SPEEX_CFLAGS)
5.91 + AC_SUBST(SPEEX_LIBS)
5.92 + rm -f conf.speextest
5.93 +])
6.1 --- a/src/Makefile.am Sun May 25 12:00:22 2003 +0000
6.2 +++ b/src/Makefile.am Sun May 25 13:39:13 2003 +0000
6.3 @@ -27,6 +27,7 @@
6.4 libxineadec \
6.5 libvorbis \
6.6 libtheora \
6.7 + libspeex \
6.8 libreal \
6.9 libfaad \
6.10 libflac \
7.1 --- a/src/demuxers/Makefile.am Sun May 25 12:00:22 2003 +0000
7.2 +++ b/src/demuxers/Makefile.am Sun May 25 13:39:13 2003 +0000
7.3 @@ -46,7 +46,7 @@
7.4 xineplug_dmx_nsv.la
7.5
7.6 xineplug_dmx_ogg_la_SOURCES = demux_ogg.c
7.7 -xineplug_dmx_ogg_la_LIBADD = $(OGG_LIBS) $(VORBIS_LIBS) $(THEORA_LIBS) $(XINE_LIB)
7.8 +xineplug_dmx_ogg_la_LIBADD = $(OGG_LIBS) $(VORBIS_LIBS) $(SPEEX_LIBS) $(THEORA_LIBS) $(XINE_LIB)
7.9 xineplug_dmx_ogg_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
7.10
7.11 xineplug_dmx_avi_la_SOURCES = demux_avi.c
8.1 --- a/src/demuxers/demux_ogg.c Sun May 25 12:00:22 2003 +0000
8.2 +++ b/src/demuxers/demux_ogg.c Sun May 25 13:39:13 2003 +0000
8.3 @@ -17,7 +17,7 @@
8.4 * along with this program; if not, write to the Free Software
8.5 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
8.6 *
8.7 - * $Id: demux_ogg.c,v 1.100 2003/05/12 19:44:35 heinchen Exp $
8.8 + * $Id: demux_ogg.c,v 1.101 2003/05/25 13:39:14 guenter Exp $
8.9 *
8.10 * demultiplexer for ogg streams
8.11 *
8.12 @@ -38,6 +38,13 @@
8.13 #include <ogg/ogg.h>
8.14 #include <vorbis/codec.h>
8.15
8.16 +#ifdef HAVE_SPEEX
8.17 +#include <speex.h>
8.18 +#include <speex_header.h>
8.19 +#include <speex_stereo.h>
8.20 +#include <speex_callbacks.h>
8.21 +#endif
8.22 +
8.23 #ifdef HAVE_THEORA
8.24 #include <theora/theora.h>
8.25 #endif
8.26 @@ -181,7 +188,7 @@
8.27 buffer = ogg_sync_buffer(&this->oy, CHUNKSIZE);
8.28 bytes = this->input->read(this->input, buffer, CHUNKSIZE);
8.29 ogg_sync_wrote(&this->oy, bytes);
8.30 - if (bytes < CHUNKSIZE) {
8.31 + if (bytes < CHUNKSIZE/2) {
8.32 return 0;
8.33 }
8.34 }
8.35 @@ -369,6 +376,9 @@
8.36 og_ghost->packet = buf->content + op_size;
8.37
8.38 buf->size = op->bytes;
8.39 + } else if ((this->buf_types[stream_num] & 0xFFFF0000) == BUF_AUDIO_SPEEX) {
8.40 + memcpy (buf->content, op->packet, op->bytes);
8.41 + buf->size = op->bytes;
8.42 } else {
8.43 memcpy (buf->content, op->packet+1+hdrlen, op->bytes-1-hdrlen);
8.44 buf->size = op->bytes-1-hdrlen;
8.45 @@ -386,7 +396,7 @@
8.46 buf->pts = 0;
8.47
8.48 #ifdef LOG
8.49 - printf ("demuxogg: audiostream %d op-gpos %lld hdr-gpos %lld pts %lld \n"
8.50 + printf ("demux_ogg: audiostream %d op-gpos %lld hdr-gpos %lld pts %lld \n"
8.51 ,stream_num
8.52 ,op->granulepos
8.53 ,this->header_granulepos[stream_num]
8.54 @@ -648,6 +658,54 @@
8.55 }
8.56 vorbis_comment_clear(&vc);
8.57 vorbis_info_clear(&vi);
8.58 + } else if (!strncmp (&op.packet[0], "Speex", 5)) {
8.59 +
8.60 +#ifdef HAVE_SPEEX
8.61 + void * st;
8.62 + SpeexMode * mode;
8.63 + SpeexHeader * header;
8.64 +
8.65 + this->buf_types[stream_num] = BUF_AUDIO_SPEEX
8.66 + +this->num_audio_streams++;
8.67 +
8.68 + this->preview_buffers[stream_num] = 1;
8.69 +
8.70 + header = speex_packet_to_header (op.packet, op.bytes);
8.71 +
8.72 + if (header) {
8.73 + int bitrate;
8.74 + mode = speex_mode_list[header->mode];
8.75 +
8.76 + st = speex_decoder_init (mode);
8.77 +
8.78 + speex_decoder_ctl (st, SPEEX_GET_BITRATE, &bitrate);
8.79 +
8.80 + if (bitrate <= 1)
8.81 + bitrate = 16000; /* assume 16 kbit */
8.82 +
8.83 + this->stream->stream_info[XINE_STREAM_INFO_AUDIO_BITRATE]
8.84 + = bitrate;
8.85 +
8.86 + this->factor[stream_num] = 90000;
8.87 + this->quotient[stream_num] = header->rate;
8.88 +
8.89 + this->avg_bitrate += bitrate;
8.90 +
8.91 +#ifdef LOG
8.92 + printf ("demux_ogg: detected Speex stream,\trate %d\tbitrate %d\n",
8.93 + header->rate, bitrate);
8.94 +#endif
8.95 +
8.96 + this->stream->stream_info[XINE_STREAM_INFO_AUDIO_SAMPLERATE]
8.97 + = header->rate;
8.98 +
8.99 + this->preview_buffers[stream_num] += header->extra_headers;
8.100 + }
8.101 +#else
8.102 + printf ("demux_ogg: Speex stream detected, unable to play\n");
8.103 +
8.104 + this->buf_types[stream_num] = BUF_CONTROL_NOP;
8.105 +#endif
8.106 } else if (!strncmp (&op.packet[1], "video", 5)) {
8.107
8.108 buf_element_t *buf;
8.109 @@ -1135,7 +1193,7 @@
8.110 /* printf("demux_ogg: packet: %.8s\n", op.packet); */
8.111 /* printf("demux_ogg: got a packet\n"); */
8.112
8.113 - if ((*op.packet & PACKET_TYPE_HEADER) && (this->buf_types[stream_num]!=BUF_VIDEO_THEORA)) {
8.114 + if ((*op.packet & PACKET_TYPE_HEADER) && (this->buf_types[stream_num]!=BUF_VIDEO_THEORA) && (this->buf_types[stream_num]!=BUF_AUDIO_SPEEX)) {
8.115 if (op.granulepos!=-1) {
8.116 this->header_granulepos[stream_num]=op.granulepos;
8.117 #ifdef LOG
8.118 @@ -1487,7 +1545,8 @@
8.119 return NULL;
8.120
8.121 if (strncasecmp(ending, ".ogg", 4) &&
8.122 - strncasecmp(ending, ".ogm", 4)) {
8.123 + strncasecmp(ending, ".ogm", 4) &&
8.124 + strncasecmp(ending, ".spx", 4)) {
8.125 return NULL;
8.126 }
8.127
8.128 @@ -1542,12 +1601,13 @@
8.129 }
8.130
8.131 static char *get_extensions (demux_class_t *this_gen) {
8.132 - return "ogg ogm";
8.133 + return "ogg ogm spx";
8.134 }
8.135
8.136 static char *get_mimetypes (demux_class_t *this_gen) {
8.137 return "audio/x-ogg: ogg: OggVorbis Audio;"
8.138 - "application/x-ogg: ogg: OggVorbis Audio;";
8.139 + "audio/x-speex: ogg: Speex Audio;"
8.140 + "application/x-ogg: ogg: OggVorbis Audio;";
8.141 }
8.142
8.143 static void class_dispose (demux_class_t *this_gen) {
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/src/libspeex/Makefile.am Sun May 25 13:39:13 2003 +0000
9.3 @@ -0,0 +1,34 @@
9.4 +##
9.5 +## Process this file with automake to produce Makefile.in
9.6 +##
9.7 +
9.8 +AM_CFLAGS = $(SPEEX_CFLAGS)
9.9 +
9.10 +LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic
9.11 +
9.12 +libdir = $(XINE_PLUGINDIR)
9.13 +
9.14 +if HAVE_SPEEX
9.15 +speex_module = xineplug_decode_speex.la
9.16 +endif
9.17 +
9.18 +lib_LTLIBRARIES = $(speex_module)
9.19 +
9.20 +xineplug_decode_speex_la_SOURCES = xine_decoder.c
9.21 +xineplug_decode_speex_la_LIBADD = $(SPEEX_LIBS)
9.22 +xineplug_decode_speex_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
9.23 +
9.24 +debug:
9.25 +# @$(MAKE) CFLAGS="$(DEBUG_CFLAGS) $(OGG_CFLAGS) $(SPEEX_CFLAGS)"
9.26 + @$(MAKE) CFLAGS="$(DEBUG_CFLAGS)"
9.27 +
9.28 +install-debug: debug
9.29 + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
9.30 +
9.31 +mostlyclean-generic:
9.32 + -rm -f *~ \#* .*~ .\#*
9.33 +
9.34 +maintainer-clean-generic:
9.35 + -@echo "This command is intended for maintainers to use;"
9.36 + -@echo "it deletes files that may require special tools to rebuild."
9.37 + -rm -f Makefile.in
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/src/libspeex/xine_decoder.c Sun May 25 13:39:13 2003 +0000
10.3 @@ -0,0 +1,462 @@
10.4 +/*
10.5 + * Copyright (C) 2000-2002 the xine project
10.6 + *
10.7 + * This file is part of xine, a free video player.
10.8 + *
10.9 + * xine is free software; you can redistribute it and/or modify
10.10 + * it under the terms of the GNU General Public License as published by
10.11 + * the Free Software Foundation; either version 2 of the License, or
10.12 + * (at your option) any later version.
10.13 + *
10.14 + * xine is distributed in the hope that it will be useful,
10.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10.17 + * GNU General Public License for more details.
10.18 + *
10.19 + * You should have received a copy of the GNU General Public License
10.20 + * along with this program; if not, write to the Free Software
10.21 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
10.22 + *
10.23 + * $Id: xine_decoder.c,v 1.1 2003/05/25 13:39:14 guenter Exp $
10.24 + *
10.25 + * (ogg/)speex audio decoder plugin (libspeex wrapper) for xine
10.26 + */
10.27 +
10.28 +#ifdef HAVE_CONFIG_H
10.29 +#include "config.h"
10.30 +#endif
10.31 +
10.32 +#include <stdlib.h>
10.33 +#include <string.h>
10.34 +
10.35 +#include "xine_internal.h"
10.36 +#include "audio_out.h"
10.37 +#include "buffer.h"
10.38 +
10.39 +#include <ogg/ogg.h>
10.40 +#include <speex.h>
10.41 +#include <speex_header.h>
10.42 +#include <speex_callbacks.h>
10.43 +#include <speex_stereo.h>
10.44 +
10.45 +#define MAX_FRAME_SIZE 2000
10.46 +
10.47 +/*
10.48 +#define LOG
10.49 +*/
10.50 +
10.51 +typedef struct {
10.52 + audio_decoder_class_t decoder_class;
10.53 +} speex_class_t;
10.54 +
10.55 +typedef struct speex_decoder_s {
10.56 + audio_decoder_t audio_decoder;
10.57 +
10.58 + int64_t pts;
10.59 +
10.60 + int output_sampling_rate;
10.61 + int output_open;
10.62 + int output_mode;
10.63 +
10.64 + /* speex stuff */
10.65 + void *st;
10.66 + int frame_size;
10.67 + int rate;
10.68 + int nframes;
10.69 + int channels;
10.70 + SpeexBits bits;
10.71 + SpeexStereoState stereo;
10.72 + int expect_metadata;
10.73 +
10.74 + float output[MAX_FRAME_SIZE];
10.75 +
10.76 + int header_count;
10.77 +
10.78 + xine_stream_t *stream;
10.79 +
10.80 +} speex_decoder_t;
10.81 +
10.82 +
10.83 +static void speex_reset (audio_decoder_t *this_gen) {
10.84 +
10.85 + speex_decoder_t *this = (speex_decoder_t *) this_gen;
10.86 +
10.87 + speex_bits_init (&this->bits);
10.88 +}
10.89 +
10.90 +static void speex_discontinuity (audio_decoder_t *this_gen) {
10.91 +
10.92 + speex_decoder_t *this = (speex_decoder_t *) this_gen;
10.93 +
10.94 + this->pts=0;
10.95 +}
10.96 +
10.97 +/* Known speex comment keys from ogg123 sources*/
10.98 +static struct {
10.99 + char *key; /* includes the '=' for programming convenience */
10.100 + int xine_metainfo_index;
10.101 +} speex_comment_keys[] = {
10.102 + {"ARTIST=", XINE_META_INFO_ARTIST},
10.103 + {"ALBUM=", XINE_META_INFO_ALBUM},
10.104 + {"TITLE=", XINE_META_INFO_TITLE},
10.105 + {"GENRE=", XINE_META_INFO_GENRE},
10.106 + {"DESCRIPTION=", XINE_META_INFO_COMMENT},
10.107 + {"DATE=", XINE_META_INFO_YEAR},
10.108 + {NULL, 0}
10.109 +};
10.110 +
10.111 +#define readint(buf, base) (((buf[base+3]<<24)&0xff000000)| \
10.112 + ((buf[base+2]<<16)&0xff0000)| \
10.113 + ((buf[base+1]<<8)&0xff00)| \
10.114 + (buf[base]&0xff))
10.115 +
10.116 +static
10.117 +void read_metadata (speex_decoder_t *this, char * comments, int length)
10.118 +{
10.119 + char * c = comments;
10.120 + int len, i, nb_fields;
10.121 + char * end;
10.122 +
10.123 + this->stream->meta_info[XINE_META_INFO_AUDIOCODEC] = strdup ("speex");
10.124 +
10.125 + if (length < 8) {
10.126 + printf ("libspeex: invalid/corrupted comments\n");
10.127 + return;
10.128 + }
10.129 +
10.130 + end = c+length;
10.131 + len = readint (c, 0);
10.132 + c += 4;
10.133 +
10.134 + if (c+len > end) {
10.135 + printf ("libspeex: invalid/corrupted comments\n");
10.136 + return;
10.137 + }
10.138 +
10.139 +#ifdef LOG
10.140 + /* Encoder */
10.141 + printf ("libspeex: ");
10.142 + fwrite (c, 1, len, stdout);
10.143 + printf ("\n");
10.144 +#endif
10.145 +
10.146 + c += len;
10.147 +
10.148 + if (c+4 > end) {
10.149 + printf ("libspeex: invalid/corrupted comments\n");
10.150 + return;
10.151 + }
10.152 +
10.153 + nb_fields = readint (c, 0);
10.154 + c += 4;
10.155 +
10.156 + for (i = 0; i < nb_fields; i++) {
10.157 + if (c+4 > end) {
10.158 + printf ("libspeex: invalid/corrupted comments\n");
10.159 + return;
10.160 + }
10.161 +
10.162 + len = readint (c, 0);
10.163 + c += 4;
10.164 + if (c+len > end) {
10.165 + printf ("libspeex: invalid/corrupted comments\n");
10.166 + return;
10.167 + }
10.168 +
10.169 +#ifdef LOG
10.170 + printf ("libspeex: ");
10.171 + fwrite (c, 1, len, stdout);
10.172 + printf ("\n");
10.173 +#endif
10.174 +
10.175 + for (i = 0; speex_comment_keys[i].key != NULL; i++) {
10.176 +
10.177 + if ( !strncasecmp (speex_comment_keys[i].key, c,
10.178 + strlen(speex_comment_keys[i].key)) ) {
10.179 + int keylen = strlen(speex_comment_keys[i].key);
10.180 + char * meta_info;
10.181 +
10.182 +#ifdef LOG
10.183 + printf ("libspeex: known metadata %d %d\n",
10.184 + i, speex_comment_keys[i].xine_metainfo_index);
10.185 +#endif
10.186 +
10.187 + meta_info = xine_xmalloc (len - keylen);
10.188 + memcpy (meta_info, c + keylen, len - keylen);
10.189 +
10.190 + this->stream->meta_info[speex_comment_keys[i].xine_metainfo_index] =
10.191 + meta_info;
10.192 + }
10.193 + }
10.194 +
10.195 + c += len;
10.196 + }
10.197 +}
10.198 +
10.199 +static void speex_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
10.200 +
10.201 + speex_decoder_t *this = (speex_decoder_t *) this_gen;
10.202 +
10.203 +#ifdef LOG
10.204 + printf ("libspeex: decode buf=%8p content=%8p flags=%08x\n",
10.205 + buf, buf->content, buf->decoder_flags);
10.206 +#endif
10.207 +
10.208 + if (buf->decoder_flags & BUF_FLAG_PREVIEW) {
10.209 +#ifdef LOG
10.210 + printf ("libspeex: preview buffer, %d headers to go\n", this->header_count);
10.211 +#endif
10.212 +
10.213 + if (this->header_count) {
10.214 +
10.215 + if (!this->st) {
10.216 + SpeexMode * spx_mode;
10.217 + SpeexHeader * spx_header;
10.218 + int modeID;
10.219 + int bitrate;
10.220 +
10.221 + speex_bits_init (&this->bits);
10.222 +
10.223 + spx_header = speex_packet_to_header (buf->content, buf->size);
10.224 +
10.225 + if (!spx_header) {
10.226 + printf ("libspeex: could not read Speex header\n");
10.227 + return;
10.228 + }
10.229 +
10.230 + modeID = spx_header->mode;
10.231 + spx_mode = speex_mode_list[modeID];
10.232 +
10.233 + if (spx_mode->bitstream_version != spx_header->mode_bitstream_version) {
10.234 + printf ("libspeex: incompatible Speex mode bitstream version\n");
10.235 + return;
10.236 + }
10.237 +
10.238 + this->st = speex_decoder_init (spx_mode);
10.239 + if (!this->st) {
10.240 + printf ("libspeex: decoder initialization failed\n");
10.241 + return;
10.242 + }
10.243 +
10.244 + this->rate = spx_header->rate;
10.245 + speex_decoder_ctl (this->st, SPEEX_SET_SAMPLING_RATE, &this->rate);
10.246 + this->stream->stream_info[XINE_STREAM_INFO_AUDIO_SAMPLERATE]
10.247 + = this->rate;
10.248 +
10.249 + this->channels = spx_header->nb_channels;
10.250 + if (this->channels == 2) {
10.251 + SpeexCallback callback;
10.252 +
10.253 + callback.callback_id = SPEEX_INBAND_STEREO;
10.254 + callback.func = speex_std_stereo_request_handler;
10.255 + callback.data = &this->stereo;
10.256 + speex_decoder_ctl (this->st, SPEEX_SET_HANDLER, &callback);
10.257 + }
10.258 +
10.259 + this->nframes = spx_header->frames_per_packet;
10.260 + if (!this->nframes) this->nframes = 1;
10.261 +
10.262 + speex_decoder_ctl (this->st, SPEEX_GET_FRAME_SIZE, &this->frame_size);
10.263 +
10.264 + speex_decoder_ctl (this->st, SPEEX_GET_BITRATE, &bitrate);
10.265 + if (bitrate <= 1) bitrate = 16000; /* assume 16 kbit */
10.266 + this->stream->stream_info[XINE_STREAM_INFO_AUDIO_BITRATE] = bitrate;
10.267 +
10.268 + this->header_count += spx_header->extra_headers;
10.269 + this->expect_metadata = 1;
10.270 +
10.271 + free (spx_header);
10.272 + } else if (this->expect_metadata) {
10.273 + read_metadata (this, buf->content, buf->size);
10.274 + }
10.275 +
10.276 + this->header_count--;
10.277 +
10.278 + if (!this->header_count) {
10.279 + int mode = AO_CAP_MODE_MONO;
10.280 +
10.281 + switch (this->channels) {
10.282 + case 1:
10.283 + mode = AO_CAP_MODE_MONO;
10.284 + break;
10.285 + case 2:
10.286 + mode = AO_CAP_MODE_STEREO;
10.287 + break;
10.288 + case 4:
10.289 + mode = AO_CAP_MODE_4CHANNEL;
10.290 + break;
10.291 + case 5:
10.292 + mode = AO_CAP_MODE_5CHANNEL;
10.293 + break;
10.294 + case 6:
10.295 + mode = AO_CAP_MODE_5_1CHANNEL;
10.296 + break;
10.297 + default:
10.298 + printf ("libspeex: help, %d channels ?!\n",
10.299 + this->channels);
10.300 + /* FIXME: handle error */
10.301 + }
10.302 +
10.303 + if (!this->output_open) {
10.304 + this->output_open =
10.305 + this->stream->audio_out->open(this->stream->audio_out,
10.306 + this->stream,
10.307 + 16,
10.308 + this->rate,
10.309 + mode);
10.310 + }
10.311 + }
10.312 + }
10.313 +
10.314 + } else if (this->output_open) {
10.315 + int i, j;
10.316 +
10.317 + audio_buffer_t *audio_buffer;
10.318 +
10.319 + audio_buffer =
10.320 + this->stream->audio_out->get_buffer (this->stream->audio_out);
10.321 +
10.322 + speex_bits_read_from (&this->bits, buf->content, buf->size);
10.323 +
10.324 + for (j = 0; j < this->nframes; j++) {
10.325 + int ret;
10.326 + int bitrate;
10.327 + ogg_int16_t * ptr = audio_buffer->mem;
10.328 +
10.329 + ret = speex_decode (this->st, &this->bits, this->output);
10.330 +
10.331 + if (ret==-1)
10.332 + break;
10.333 + if (ret==-2) {
10.334 + printf ("libspeex: Decoding error, corrupted stream?\n");
10.335 + break;
10.336 + }
10.337 + if (speex_bits_remaining(&this->bits)<0) {
10.338 + printf ("libspeex: Decoding overflow, corrupted stream?\n");
10.339 + break;
10.340 + }
10.341 +
10.342 + if (this->channels == 2) {
10.343 + speex_decode_stereo (this->output, this->frame_size, &this->stereo);
10.344 + }
10.345 +
10.346 + speex_decoder_ctl (this->st, SPEEX_GET_BITRATE, &bitrate);
10.347 + if (bitrate <= 1) bitrate = 16000; /* assume 16 kbit */
10.348 + this->stream->stream_info[XINE_STREAM_INFO_AUDIO_BITRATE] = bitrate;
10.349 +
10.350 + /*PCM saturation (just in case)*/
10.351 + for (i=0; i < this->frame_size * this->channels; i++)
10.352 + {
10.353 + if (this->output[i]>32000.0)
10.354 + this->output[i]=32000.0;
10.355 + else if (this->output[i]<-32000.0)
10.356 + this->output[i]=-32000.0;
10.357 + }
10.358 +
10.359 + /*Convert to short and play */
10.360 + for (i=0; i< this->frame_size * this->channels; i++) {
10.361 + *ptr++ = (ogg_int16_t)this->output[i];
10.362 + }
10.363 +
10.364 + audio_buffer->vpts = this->pts;
10.365 + this->pts=0;
10.366 + audio_buffer->num_frames = this->frame_size;
10.367 +
10.368 + this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream);
10.369 +
10.370 + buf->pts=0;
10.371 +
10.372 + }
10.373 + }
10.374 +#ifdef LOG
10.375 + else
10.376 + printf ("libspeex: output not open\n");
10.377 +#endif
10.378 +}
10.379 +
10.380 +static void speex_dispose (audio_decoder_t *this_gen) {
10.381 +
10.382 + speex_decoder_t *this = (speex_decoder_t *) this_gen;
10.383 +
10.384 + if (this->st) {
10.385 + speex_decoder_destroy (this->st);
10.386 + }
10.387 + speex_bits_destroy (&this->bits);
10.388 +
10.389 + if (this->output_open)
10.390 + this->stream->audio_out->close (this->stream->audio_out, this->stream);
10.391 +
10.392 + free (this_gen);
10.393 +}
10.394 +
10.395 +static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen,
10.396 + xine_stream_t *stream) {
10.397 +
10.398 + speex_decoder_t *this ;
10.399 + static SpeexStereoState init_stereo = SPEEX_STEREO_STATE_INIT;
10.400 +
10.401 + this = (speex_decoder_t *) malloc (sizeof (speex_decoder_t));
10.402 +
10.403 + this->audio_decoder.decode_data = speex_decode_data;
10.404 + this->audio_decoder.reset = speex_reset;
10.405 + this->audio_decoder.discontinuity = speex_discontinuity;
10.406 + this->audio_decoder.dispose = speex_dispose;
10.407 + this->stream = stream;
10.408 +
10.409 + this->output_open = 0;
10.410 + this->header_count = 2;
10.411 + this->expect_metadata = 0;
10.412 +
10.413 + this->st = NULL;
10.414 +
10.415 + this->channels = 1;
10.416 +
10.417 + memcpy (&this->stereo, &init_stereo, sizeof (SpeexStereoState));
10.418 +
10.419 + return (audio_decoder_t *) this;
10.420 +}
10.421 +
10.422 +/*
10.423 + * speex plugin class
10.424 + */
10.425 +
10.426 +static char *get_identifier (audio_decoder_class_t *this) {
10.427 + return "speex";
10.428 +}
10.429 +
10.430 +static char *get_description (audio_decoder_class_t *this) {
10.431 + return "Speex audio decoder plugin";
10.432 +}
10.433 +
10.434 +static void dispose_class (audio_decoder_class_t *this) {
10.435 + free (this);
10.436 +}
10.437 +
10.438 +static void *init_plugin (xine_t *xine, void *data) {
10.439 +
10.440 + speex_class_t *this;
10.441 +
10.442 + this = (speex_class_t *) malloc (sizeof (speex_class_t));
10.443 +
10.444 + this->decoder_class.open_plugin = open_plugin;
10.445 + this->decoder_class.get_identifier = get_identifier;
10.446 + this->decoder_class.get_description = get_description;
10.447 + this->decoder_class.dispose = dispose_class;
10.448 +
10.449 + return this;
10.450 +}
10.451 +
10.452 +static uint32_t audio_types[] = {
10.453 + BUF_AUDIO_SPEEX, 0
10.454 + };
10.455 +
10.456 +static decoder_info_t dec_info_audio = {
10.457 + audio_types, /* supported types */
10.458 + 5 /* priority */
10.459 +};
10.460 +
10.461 +plugin_info_t xine_plugin_info[] = {
10.462 + /* type, API, "name", version, special_info, init_function */
10.463 + { PLUGIN_AUDIO_DECODER, 13, "speex", XINE_VERSION_CODE, &dec_info_audio, init_plugin },
10.464 + { PLUGIN_NONE, 0, "", 0, NULL, NULL }
10.465 +};
11.1 --- a/src/xine-engine/buffer.h Sun May 25 12:00:22 2003 +0000
11.2 +++ b/src/xine-engine/buffer.h Sun May 25 13:39:13 2003 +0000
11.3 @@ -17,7 +17,7 @@
11.4 * along with this program; if not, write to the Free Software
11.5 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
11.6 *
11.7 - * $Id: buffer.h,v 1.114 2003/05/20 13:50:57 mroi Exp $
11.8 + * $Id: buffer.h,v 1.115 2003/05/25 13:39:14 guenter Exp $
11.9 *
11.10 *
11.11 * contents:
11.12 @@ -204,6 +204,7 @@
11.13 #define BUF_AUDIO_FLAC 0x032C0000
11.14 #define BUF_AUDIO_DV 0x032D0000
11.15 #define BUF_AUDIO_WMAV 0x032E0000
11.16 +#define BUF_AUDIO_SPEEX 0x032F0000
11.17
11.18 /* spu buffer types: */
11.19
12.1 --- a/src/xine-engine/buffer_types.c Sun May 25 12:00:22 2003 +0000
12.2 +++ b/src/xine-engine/buffer_types.c Sun May 25 13:39:13 2003 +0000
12.3 @@ -17,7 +17,7 @@
12.4 * along with this program; if not, write to the Free Software
12.5 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
12.6 *
12.7 - * $Id: buffer_types.c,v 1.63 2003/05/19 21:49:57 tmmm Exp $
12.8 + * $Id: buffer_types.c,v 1.64 2003/05/25 13:39:14 guenter Exp $
12.9 *
12.10 *
12.11 * contents:
12.12 @@ -863,6 +863,13 @@
12.13 BUF_AUDIO_28_8,
12.14 "Real 28.8"
12.15 },
12.16 +{
12.17 + {
12.18 + 0
12.19 + },
12.20 + BUF_AUDIO_SPEEX,
12.21 + "Speex"
12.22 +},
12.23 { { 0 }, 0, "last entry" }
12.24 };
12.25