summaryrefslogtreecommitdiffstats
path: root/mpeglib_artsplug
diff options
context:
space:
mode:
Diffstat (limited to 'mpeglib_artsplug')
-rw-r--r--mpeglib_artsplug/CDDAPlayObject.mcopclass7
-rw-r--r--mpeglib_artsplug/MP3PlayObject.mcopclass8
-rw-r--r--mpeglib_artsplug/MPGPlayObject.mcopclass8
-rw-r--r--mpeglib_artsplug/Makefile.am106
-rw-r--r--mpeglib_artsplug/NULLPlayObject.mcopclass7
-rw-r--r--mpeglib_artsplug/OGGPlayObject.mcopclass8
-rw-r--r--mpeglib_artsplug/README78
-rw-r--r--mpeglib_artsplug/SplayPlayObject.mcopclass8
-rw-r--r--mpeglib_artsplug/TODO19
-rw-r--r--mpeglib_artsplug/VCDPlayObject.mcopclass7
-rw-r--r--mpeglib_artsplug/WAVPlayObject.mcopclass7
-rw-r--r--mpeglib_artsplug/cddaPlayObject_impl.cpp48
-rw-r--r--mpeglib_artsplug/cddaPlayObject_impl.h43
-rw-r--r--mpeglib_artsplug/configure.in.in3
-rw-r--r--mpeglib_artsplug/decoderBaseObject.idl58
-rw-r--r--mpeglib_artsplug/decoderBaseObject_impl.cpp620
-rw-r--r--mpeglib_artsplug/decoderBaseObject_impl.h121
-rw-r--r--mpeglib_artsplug/doemacs29
-rw-r--r--mpeglib_artsplug/mp3PlayObject_impl.cpp45
-rw-r--r--mpeglib_artsplug/mp3PlayObject_impl.h43
-rw-r--r--mpeglib_artsplug/mpeglibartsplay.cpp276
-rw-r--r--mpeglib_artsplug/mpgPlayObject_impl.cpp53
-rw-r--r--mpeglib_artsplug/mpgPlayObject_impl.h48
-rw-r--r--mpeglib_artsplug/nullPlayObject_impl.cpp120
-rw-r--r--mpeglib_artsplug/nullPlayObject_impl.h75
-rw-r--r--mpeglib_artsplug/oggPlayObject_impl.cpp43
-rw-r--r--mpeglib_artsplug/oggPlayObject_impl.h47
-rw-r--r--mpeglib_artsplug/splayPlayObject.idl15
-rw-r--r--mpeglib_artsplug/splayPlayObject_impl.cpp500
-rw-r--r--mpeglib_artsplug/splayPlayObject_impl.h112
-rw-r--r--mpeglib_artsplug/vcdPlayObject_impl.cpp47
-rw-r--r--mpeglib_artsplug/vcdPlayObject_impl.h44
-rw-r--r--mpeglib_artsplug/wavPlayObject_impl.cpp39
-rw-r--r--mpeglib_artsplug/wavPlayObject_impl.h44
34 files changed, 2736 insertions, 0 deletions
diff --git a/mpeglib_artsplug/CDDAPlayObject.mcopclass b/mpeglib_artsplug/CDDAPlayObject.mcopclass
new file mode 100644
index 00000000..cafe6c68
--- /dev/null
+++ b/mpeglib_artsplug/CDDAPlayObject.mcopclass
@@ -0,0 +1,7 @@
+Interface=CDDAPlayObject,Arts::PitchablePlayObject,Arts::StreamPlayObject,Arts::PlayObject,Arts::SynthModule,Arts::Object
+Author="Martin Vogt <mvogt@rhrk.uni-kl.de>"
+URL="http://mpeglib.sourceforge.net/"
+Extension=cdda,cda
+MimeType=application/x-cda,
+Language=C++
+Library=libarts_mpeglib.la
diff --git a/mpeglib_artsplug/MP3PlayObject.mcopclass b/mpeglib_artsplug/MP3PlayObject.mcopclass
new file mode 100644
index 00000000..a19b32a0
--- /dev/null
+++ b/mpeglib_artsplug/MP3PlayObject.mcopclass
@@ -0,0 +1,8 @@
+Interface=MP3PlayObject,Arts::PitchablePlayObject,Arts::PlayObject,Arts::StreamPlayObject,Arts::SynthModule,Arts::Object
+Author="Martin Vogt <mvogt@rhrk.uni-kl.de>"
+URL="http://mpeglib.sourceforge.net"
+Extension=mp3,mp1,mp2
+MimeType=audio/x-mp3,audio/x-mp1,audio/x-mp2,audio/mpeg
+Language=C++
+Library=libarts_mpeglib.la
+Preference=3
diff --git a/mpeglib_artsplug/MPGPlayObject.mcopclass b/mpeglib_artsplug/MPGPlayObject.mcopclass
new file mode 100644
index 00000000..f2c7322f
--- /dev/null
+++ b/mpeglib_artsplug/MPGPlayObject.mcopclass
@@ -0,0 +1,8 @@
+Interface=MPGPlayObject,Arts::PitchablePlayObject,Arts::PlayObject,Arts::StreamPlayObject,Arts::SynthModule,Arts::Object
+Author="Martin Vogt <mvogt@rhrk.uni-kl.de>"
+URL="http://mpeglib.sourceforge.net"
+Extension=mpg,dat,mpeg
+MimeType=video/x-mpg,video/x-dat,video/x-mpeg,video/mpeg
+Language=C++
+Library=libarts_mpeglib.la
+Preference=3
diff --git a/mpeglib_artsplug/Makefile.am b/mpeglib_artsplug/Makefile.am
new file mode 100644
index 00000000..5cc7af54
--- /dev/null
+++ b/mpeglib_artsplug/Makefile.am
@@ -0,0 +1,106 @@
+# This file you have to edit. Change the name here
+
+
+mcopclassdir = $(libdir)/mcop
+mcopclass_DATA = WAVPlayObject.mcopclass \
+ MP3PlayObject.mcopclass \
+ OGGPlayObject.mcopclass \
+ CDDAPlayObject.mcopclass \
+ NULLPlayObject.mcopclass \
+ SplayPlayObject.mcopclass
+
+
+
+EXTRA_DIST = doemacs \
+ configure.in.in \
+ decoderBaseObject.idl \
+ splayPlayObject.idl \
+ $(mcopclass_DATA)
+
+
+BUILT_SOURCES = decoderBaseObject.h \
+ decoderBaseObject.cc \
+ splayPlayObject.h \
+ splayPlayObject.cc
+
+
+noinst_HEADERS = mp3PlayObject_impl.h \
+ oggPlayObject_impl.h \
+ decoderBaseObject_impl.h \
+ mpgPlayObject_impl.h \
+ wavPlayObject_impl.h \
+ cddaPlayObject_impl.h \
+ vcdPlayObject_impl.h \
+ nullPlayObject_impl.h \
+ splayPlayObject_impl.h
+
+
+ARTS_INCLUDES = $(ARTSC_INCLUDE) \
+ -I$(kde_includes)/arts
+
+
+INCLUDES = -I../mpeglib/lib -I$(srcdir)/../mpeglib/lib $(ARTS_INCLUDES) $(all_includes)
+
+
+lib_LTLIBRARIES = libarts_mpeglib.la \
+ libarts_splay.la
+
+decoderBaseObject.cc decoderBaseObject.h : $(srcdir)/decoderBaseObject.idl
+ $(MCOPIDL) -I$(kde_includes)/arts $(srcdir)/decoderBaseObject.idl
+
+splayPlayObject.cc splayPlayObject.h : $(srcdir)/splayPlayObject.idl
+ $(MCOPIDL) -I$(kde_includes)/arts $(srcdir)/splayPlayObject.idl
+
+mpeglibartsplugdir = $(includedir)/mpeglib_artsplug
+
+mpeglibartsplug_HEADERS = decoderBaseObject_impl.h \
+ decoderBaseObject.h \
+ decoderBaseObject.idl \
+ splayPlayObject_impl.h \
+ splayPlayObject.h \
+ splayPlayObject.idl
+
+
+
+libarts_mpeglib_la_SOURCES = decoderBaseObject.cc \
+ splayPlayObject.cc \
+ decoderBaseObject_impl.cpp \
+ oggPlayObject_impl.cpp \
+ mpgPlayObject_impl.cpp \
+ wavPlayObject_impl.cpp \
+ mp3PlayObject_impl.cpp \
+ cddaPlayObject_impl.cpp \
+ vcdPlayObject_impl.cpp \
+ nullPlayObject_impl.cpp
+libarts_mpeglib_la_COMPILE_FIRST = decoderBaseObject.h
+
+libarts_mpeglib_la_LDFLAGS = $(all_libraries) \
+ -no-undefined \
+ -module \
+ -release $(MPEGLIB_ARTS_VERSION) \
+ -version-info $(MPEGLIB_ARTS_MAJOR_VERSION):$(MPEGLIB_ARTS_MINOR_VERSION):$(MPEGLIB_ARTS_MICRO_VERSION)
+libarts_mpeglib_la_LIBADD = $(top_builddir)/mpeglib/lib/libmpeg.la \
+ $(LIB_ARTS)
+
+libarts_splay_la_SOURCES = splayPlayObject.cc \
+ splayPlayObject_impl.cpp
+
+libarts_splay_la_LDFLAGS = $(all_libraries) \
+ -no-undefined \
+ -module
+libarts_splay_la_LIBADD = $(top_builddir)/mpeglib/lib/libmpeg.la \
+ $(LIB_ARTS)
+
+
+bin_PROGRAMS = mpeglibartsplay
+
+mpeglibartsplay_LDFLAGS = $(ARTSC_LIBS) $(all_libraries)
+mpeglibartsplay_SOURCES = mpeglibartsplay.cpp
+
+mpeglibartsplay_LDADD = -lsoundserver_idl \
+ -lkmedia2_idl \
+ -lartsflow_idl \
+ -lmcop
+
+splayPlayObject.lo: splayPlayObject.h
+splayPlayObject_impl.lo: splayPlayObject.h
diff --git a/mpeglib_artsplug/NULLPlayObject.mcopclass b/mpeglib_artsplug/NULLPlayObject.mcopclass
new file mode 100644
index 00000000..296fcc9b
--- /dev/null
+++ b/mpeglib_artsplug/NULLPlayObject.mcopclass
@@ -0,0 +1,7 @@
+Interface=NULLPlayObject,Arts::PitchablePlayObject,Arts::PlayObject,Arts::SynthModule,Arts::Object
+Author="Martin Vogt <mvogt@rhrk.uni-kl.de>"
+URL="http://mpeglib.sourceforge.net/"
+Extension=null,
+MimeType=null/null,
+Language=C++
+Library=libarts_mpeglib.la
diff --git a/mpeglib_artsplug/OGGPlayObject.mcopclass b/mpeglib_artsplug/OGGPlayObject.mcopclass
new file mode 100644
index 00000000..d41424b2
--- /dev/null
+++ b/mpeglib_artsplug/OGGPlayObject.mcopclass
@@ -0,0 +1,8 @@
+Interface=OGGPlayObject,Arts::PitchablePlayObject,Arts::PlayObject,Arts::StreamPlayObject,Arts::SynthModule,Arts::Object
+Author="Martin Vogt <mvogt@rhrk.uni-kl.de>"
+URL="http://mpeglib.sourceforge.net"
+Extension=ogg
+MimeType=audio/vorbis,application/ogg
+Language=C++
+Library=libarts_mpeglib.la
+Preference=3
diff --git a/mpeglib_artsplug/README b/mpeglib_artsplug/README
new file mode 100644
index 00000000..20015161
--- /dev/null
+++ b/mpeglib_artsplug/README
@@ -0,0 +1,78 @@
+
+
+1) compile arts snapshot with
+
+ ./configure --prefix=/tmp/arts
+ ^^^^^^^^^^^^^^^^^^
+ needed
+
+ This Makefile depends on the assumption that arts is in /tmp/arts !
+
+2) Put the arts libraries into your library search path:
+
+ edit ld.so.conf
+ add: /tmp/arts/lib
+ /sbin/ldconfig
+
+ ---> Make sure the arts path is BEFORE your KDE Library path!
+ (you will link against old arts versions and will get
+ "undefined references")
+
+4) compile & install mpeglib
+
+ ./configure
+ make <-- mabe you get errors here , because I have XFree4.0
+ make install
+
+5) add the library search path for mpeg lib to /etc/ld.so.conf
+ see 2)
+ Per default mpeglib installs in /usr/lib
+
+6) Now build the arts plugins in this directory
+
+ * You should edit the Makefile and remove the XFree4.0 dependecies
+
+Makefile:
+ -lmpeg -lX11 -lXext -lXt -lXv -lXxf86dga -lpthread
+# ^^^^^^^^^^^^^^^
+# needed if you have XFree4.0
+
+
+
+ Type in this directory
+
+ make
+
+ then pray.
+
+ Now check the library dependcies.
+ A success looks similar to this:
+[m_vogt@mv arts]$ ldd ./libarts_splay.so
+ libmpeg--version-info.so => /usr/local/lib/libmpeg--version-info.so (0x40022000)
+ libX11.so.6 => /usr/X11R6/lib/libX11.so.6 (0x4009d000)
+ libXext.so.6 => /usr/X11R6/lib/libXext.so.6 (0x4015f000)
+ libXt.so.6 => /usr/X11R6/lib/libXt.so.6 (0x4016c000)
+ libpthread.so.0 => /lib/libpthread.so.0 (0x401b5000)
+ libstdc++-libc6.1-1.so.2 => /usr/lib/libstdc++-libc6.1-1.so.2 (0x401c8000)
+ libm.so.6 => /lib/libm.so.6 (0x4020a000)
+ libc.so.6 => /lib/libc.so.6 (0x40227000)
+ libSM.so.6 => /usr/X11R6/lib/libSM.so.6 (0x4031c000)
+ libICE.so.6 => /usr/X11R6/lib/libICE.so.6 (0x40325000)
+ /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)
+
+
+If you get undefined references read: 2.
+
+
+7.) Now install the lib
+
+ make install
+
+
+8) start artsd
+
+9) start the ./artsplay in the current directoy with a given mp3
+
+
+
+
diff --git a/mpeglib_artsplug/SplayPlayObject.mcopclass b/mpeglib_artsplug/SplayPlayObject.mcopclass
new file mode 100644
index 00000000..ae366b36
--- /dev/null
+++ b/mpeglib_artsplug/SplayPlayObject.mcopclass
@@ -0,0 +1,8 @@
+Interface=SplayPlayObject,Arts::PitchablePlayObject,Arts::StreamPlayObject,Arts::SynthModule,Arts::Object
+Author="Martin Vogt <mvogt@rhrk.uni-kl.de>"
+URL="http://mpeglib.sourceforge.net"
+Extension=mp3,mp1,mp2
+MimeType=audio/x-mp3,audio/x-mp1,audio/x-mp2
+Language=C++
+Library=libarts_splay.la
+Preference=2
diff --git a/mpeglib_artsplug/TODO b/mpeglib_artsplug/TODO
new file mode 100644
index 00000000..8595715a
--- /dev/null
+++ b/mpeglib_artsplug/TODO
@@ -0,0 +1,19 @@
+
+
+* The arts plugin interface is not touched by me for the
+ next time. Thus you have a good chance that your patches
+ will be applied.
+
+ I have to work on better fullscreen support and other things
+ in mpeglib. And I have to update the vorbis plugin.
+
+
+* The seeking and info things are only experimental.
+ They show you how it works in mpeglib, but are not usefull
+ for a gui. patch welcome.
+
+* MPEG Video Currently exist with :
+ XIO: fatal IO error 0 (Success) on X server ":0.0"
+ ^^^^^ ^^^^^^^^ ?->funny
+
+ after 14 requests (7 known processed) with 0 events remaining.
diff --git a/mpeglib_artsplug/VCDPlayObject.mcopclass b/mpeglib_artsplug/VCDPlayObject.mcopclass
new file mode 100644
index 00000000..993a0140
--- /dev/null
+++ b/mpeglib_artsplug/VCDPlayObject.mcopclass
@@ -0,0 +1,7 @@
+Interface=VCDPlayObject,Arts::PitchablePlayObject,Arts::PlayObject,Arts::SynthModule,Arts::Object
+Author="Martin Vogt <mvogt@rhrk.uni-kl.de>"
+URL="http://mpeglib.sourceforge.net/"
+Extension=vcd,
+MimeType=video/x-vcd,
+Language=C++
+Library=libarts_mpeglib.la
diff --git a/mpeglib_artsplug/WAVPlayObject.mcopclass b/mpeglib_artsplug/WAVPlayObject.mcopclass
new file mode 100644
index 00000000..d368a121
--- /dev/null
+++ b/mpeglib_artsplug/WAVPlayObject.mcopclass
@@ -0,0 +1,7 @@
+Interface=WAVPlayObject,Arts::PitchablePlayObject,Arts::PlayObject,Arts::StreamPlayObject,Arts::SynthModule,Arts::Object
+Author="Martin Vogt <mvogt@rhrk.uni-kl.de>"
+URL="http://mpeglib.sourceforge.net"
+Extension=wav,au
+MimeType=audio/x-wav,audio/x-au
+Language=C++
+Library=libarts_mpeglib.la
diff --git a/mpeglib_artsplug/cddaPlayObject_impl.cpp b/mpeglib_artsplug/cddaPlayObject_impl.cpp
new file mode 100644
index 00000000..f5b85ca8
--- /dev/null
+++ b/mpeglib_artsplug/cddaPlayObject_impl.cpp
@@ -0,0 +1,48 @@
+/*
+ class for mp3-mpeglib decoder
+ Copyright (C) 2000 Martin Vogt
+
+ This program 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+#include "cddaPlayObject_impl.h"
+#include "debug.h"
+#include <iostream>
+
+
+
+CDDAPlayObject_impl::CDDAPlayObject_impl() {
+ arts_debug("CDDAPlayObject_impl");
+}
+
+CDDAPlayObject_impl::~CDDAPlayObject_impl() {
+ arts_debug("~CDDAPlayObject_impl");
+}
+
+
+DecoderPlugin* CDDAPlayObject_impl::createPlugin() {
+ std::cout << "CDDAPlayObject_impl::getPlugin"<<std::endl;
+ return new CDDAPlugin();
+}
+
+InputStream* CDDAPlayObject_impl::createInputStream(const char* ) {
+ cout << "CDDAPlayObject_impl::createInputStream"<<endl;
+ InputStream* back;
+ back=InputPlugin::createInputStream(__INPUT_CDDA,_INPUT_THREADSAFE);
+ return back;
+}
+
+void CDDAPlayObject_impl::calculateBlock(unsigned long samples) {
+ DecoderBaseObject_impl::calculateBlock(samples,left,right);
+}
+
+
+
+REGISTER_IMPLEMENTATION(CDDAPlayObject_impl);
+
+
diff --git a/mpeglib_artsplug/cddaPlayObject_impl.h b/mpeglib_artsplug/cddaPlayObject_impl.h
new file mode 100644
index 00000000..b68aba0d
--- /dev/null
+++ b/mpeglib_artsplug/cddaPlayObject_impl.h
@@ -0,0 +1,43 @@
+/*
+ class for mp3-mpeglib decoder
+ Copyright (C) 2000 Martin Vogt
+
+ This program 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#ifndef __CDDAPLAYOBJECT_IMPL_H
+#define __CDDAPLAYOBJECT_IMPL_H
+
+
+#include "decoderBaseObject_impl.h"
+#include "../mpeglib/lib/decoder/cddaPlugin.h"
+
+
+class CDDAPlayObject_impl:
+ virtual public DecoderBaseObject_impl,
+ virtual public CDDAPlayObject_skel {
+
+
+
+public:
+
+ CDDAPlayObject_impl();
+ virtual ~CDDAPlayObject_impl();
+
+
+ DecoderPlugin* createPlugin();
+
+ InputStream* createInputStream(const char* url);
+
+ void calculateBlock(unsigned long samples);
+
+};
+
+
+#endif
diff --git a/mpeglib_artsplug/configure.in.in b/mpeglib_artsplug/configure.in.in
new file mode 100644
index 00000000..e5a3023f
--- /dev/null
+++ b/mpeglib_artsplug/configure.in.in
@@ -0,0 +1,3 @@
+if test "x$build_arts" = "xno"; then
+ DO_NOT_COMPILE="$DO_NOT_COMPILE mpeglib_artsplug"
+fi
diff --git a/mpeglib_artsplug/decoderBaseObject.idl b/mpeglib_artsplug/decoderBaseObject.idl
new file mode 100644
index 00000000..678a9da1
--- /dev/null
+++ b/mpeglib_artsplug/decoderBaseObject.idl
@@ -0,0 +1,58 @@
+#include "kmedia2.idl"
+#include "artsflow.idl"
+
+/* the interfaces below are not kept binary compatible */
+
+interface DecoderBaseObject :
+ Arts::StreamPlayObject,
+ Arts::SynthModule,
+ Arts::PitchablePlayObject
+{
+
+ async in byte stream indata;
+ /**
+ * blocking flag - defaults to false - when set to true, mpeglib will not
+ * try to minimize latencies by generating answers (i.e. empty blocks)
+ * when the thread producing the data wasn't ready
+ */
+ attribute boolean blocking;
+};
+
+
+interface MP3PlayObject : DecoderBaseObject
+{
+ out audio stream left,right;
+};
+
+
+interface WAVPlayObject : DecoderBaseObject
+{
+ out audio stream left,right;
+};
+
+
+interface MPGPlayObject : DecoderBaseObject
+{
+ out audio stream left,right;
+};
+
+
+interface OGGPlayObject : DecoderBaseObject
+{
+ out audio stream left,right;
+};
+
+interface CDDAPlayObject : DecoderBaseObject
+{
+ out audio stream left,right;
+};
+
+interface VCDPlayObject : DecoderBaseObject
+{
+ out audio stream left,right;
+};
+
+interface NULLPlayObject : Arts::PlayObject , Arts::SynthModule
+{
+ out audio stream left,right;
+};
diff --git a/mpeglib_artsplug/decoderBaseObject_impl.cpp b/mpeglib_artsplug/decoderBaseObject_impl.cpp
new file mode 100644
index 00000000..bd69a901
--- /dev/null
+++ b/mpeglib_artsplug/decoderBaseObject_impl.cpp
@@ -0,0 +1,620 @@
+/*
+ base class for all mpeglib decoders
+ Copyright (C) 2000 Martin Vogt
+
+ This program 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+#include <queue>
+#include <iostream>
+
+#include <connect.h>
+
+#include "decoderBaseObject_impl.h"
+#include "../mpeglib/lib/decoder/decoderPlugin.h"
+#include "debug.h"
+
+// define this to run the playobject without the
+// arts backend. (useful to check if a bug is in arts or mpeglib)
+//#define _STRIP_ZERO
+
+static int instanceCnt=0;
+
+DecoderBaseObject_impl::DecoderBaseObject_impl()
+ : _speed(1.0f)
+{
+
+ flpos=0.0;
+ _blocking = false;
+
+#ifdef _STRIP_ZERO
+ outputStream=NULL;
+#else
+ m_outputStream=new ArtsOutputStream(NULL);
+ arts_debug("outputStream created");
+ decoderPlugin=NULL;
+#endif
+ startTime=0.0;
+ m_inputStream=NULL;
+ setStreamState(_THREADSTATE_INIT);
+ _state=Arts::posIdle;
+ instance=instanceCnt;
+ instanceCnt++;
+
+ m_packetQueue = new std::queue<DataPacket<mcopbyte>*>;
+}
+
+DecoderBaseObject_impl::~DecoderBaseObject_impl() {
+ arts_debug("~DecoderBaseObject_impl -s");
+ shudownPlugins();
+
+ if (decoderPlugin != NULL) {
+ arts_debug("delete decoderPlugin");
+ delete decoderPlugin;
+ decoderPlugin=NULL;
+ }
+ if (m_outputStream != NULL) {
+ arts_debug("delete outputStream");
+ delete m_outputStream;
+ m_outputStream=NULL;
+ }
+
+ if (m_streaming)
+ m_artsInputStream.streamEnd();
+
+ delete m_packetQueue;
+}
+
+
+DecoderPlugin* DecoderBaseObject_impl::createPlugin() {
+ arts_fatal("direct virtual call DecoderBaseObject_impl::getPlugin");
+ return NULL;
+}
+
+
+InputStream* DecoderBaseObject_impl::createInputStream(const char* url) {
+ InputStream* back = InputPlugin::createInputStream(url,true);
+ return back;
+}
+
+
+bool DecoderBaseObject_impl::loadMedia(const string &filename) {
+ arts_debug("loadMedia");
+ int back=true;
+
+ m_streaming = false;
+
+ if ( m_inputStream != NULL ) {
+ arts_fatal("remove resources first with a call to: halt()");
+ }
+ if (decoderPlugin == NULL) {
+ decoderPlugin=createPlugin();
+ if(doFloat()) decoderPlugin->config("dofloat",0,0);
+ }
+
+ flpos=0.0;
+ startTime=0.0;
+
+ lastAudioBufferSize=-1;
+ /**
+ Note: you can only play one file with a PlayObject !!
+ Then you must destroy it.
+ A StreamEnd call should do the job.
+ */
+
+#ifdef _STRIP_ZERO
+ return true;
+#endif
+
+ m_inputStream=createInputStream(filename.c_str());
+
+ // the plugin does not open the stream!
+ // we do it.
+ back=m_inputStream->open((char*)filename.c_str());
+ setStreamState(_THREADSTATE_OPENED);
+
+ // we are still in posIdle here
+ m_outputStream->audioOpen();
+
+ // watch the order!
+ decoderPlugin->setOutputPlugin(m_outputStream);
+ decoderPlugin->setInputPlugin(m_inputStream);
+
+ return back;
+}
+
+#define INPUT_BUFFER_SIZE 32768
+
+bool DecoderBaseObject_impl::streamMedia(Arts::InputStream instream) {
+ arts_debug("DecoderBaseObject_impl::streamMedia -s");
+
+ bool back = true;
+
+ if (m_inputStream != NULL) {
+ arts_fatal("resource in use, call halt() first");
+ }
+ if (decoderPlugin == NULL) {
+ decoderPlugin = createPlugin();
+ if (doFloat())
+ decoderPlugin->config("dofloat", 0, 0);
+ // streaming, don't know the length
+ decoderPlugin->config("-c", 0, 0);
+ }
+
+ flpos = 0.0;
+ startTime = 0.0;
+ m_streaming = true;
+ lastAudioBufferSize = -1;
+
+ m_artsInputStream = instream;
+
+ m_inputStream = new BufferInputStream(INPUT_BUFFER_SIZE, 4096, (char*)"InputStream");
+ m_inputStream->open((char*)"InputStream");
+
+ // connect the stream now
+ Arts::StreamPlayObject self = Arts::StreamPlayObject::_from_base(_copy());
+ connect(m_artsInputStream, "outdata", self);
+
+ setStreamState(_THREADSTATE_OPENED);
+
+ m_outputStream->audioOpen();
+
+ decoderPlugin->setOutputPlugin(m_outputStream);
+ decoderPlugin->setInputPlugin(m_inputStream);
+
+ arts_debug("DecoderBaseObject_impl::streamMedia -e");
+
+ return back;
+}
+
+void DecoderBaseObject_impl::process_indata(DataPacket<mcopbyte> *inpacket) {
+
+ m_packetQueue->push(inpacket);
+ processQueue();
+}
+
+void DecoderBaseObject_impl::processQueue() {
+
+ // early exit if no packets in the queue
+ if (m_packetQueue->empty())
+ return;
+
+ // see how much space we have in the stream
+ BufferInputStream* stream = static_cast<BufferInputStream*>(m_inputStream);
+ if (!stream) return;
+
+ int length = stream->getByteLength();
+ int freeSpace = INPUT_BUFFER_SIZE - length;
+
+ DataPacket<mcopbyte> *inpacket = m_packetQueue->front();
+ if (!inpacket) return;
+
+ if (freeSpace >= inpacket->size) {
+ stream->write((char*)inpacket->contents, inpacket->size, 0);
+ m_packetQueue->pop();
+ inpacket->processed();
+ }
+}
+
+string DecoderBaseObject_impl::description() {
+ arts_debug("description");
+ string back;
+#ifdef _STRIP_ZERO
+ return back;
+#endif
+ PluginInfo* pluginInfo=decoderPlugin->getPluginInfo();
+ pluginInfo->print();
+ return back;
+
+}
+
+void DecoderBaseObject_impl::description(const string &) {
+ arts_debug("description");
+ // what should do this?
+}
+
+poTime DecoderBaseObject_impl::currentTime() {
+ poTime time;
+#ifdef _STRIP_ZERO
+ return time;
+#endif
+ AudioTime* audioTime=m_outputStream->getAudioTime();
+ float currentTime=audioTime->getTime()+(float)startTime;
+ time.seconds=(long)(currentTime);
+ time.ms=(long) (1000.0*(currentTime-(float)time.seconds));
+ return time;
+}
+
+
+
+poTime DecoderBaseObject_impl::overallTime() {
+ poTime time;
+#ifdef _STRIP_ZERO
+ return time;
+#endif
+
+ PluginInfo* pluginInfo=decoderPlugin->getPluginInfo();
+ time.seconds=pluginInfo->getLength();
+ time.ms=0;
+ return time;
+}
+
+poCapabilities DecoderBaseObject_impl::capabilities() {
+ arts_debug("capabilities");
+#ifdef _STRIP_ZERO
+ return capSeek;
+#endif
+ PluginInfo* pluginInfo=decoderPlugin->getPluginInfo();
+ long len=pluginInfo->getLength();
+ if (len == 0) {
+ return Arts::capPause; /* no seek supported */
+ }
+ // seek and pause supported
+ return (poCapabilities)(Arts::capSeek | Arts::capPause);
+}
+
+string DecoderBaseObject_impl::mediaName() {
+ arts_debug("mediaName");
+ string back;
+ // whats a mediaName?
+ return back;
+}
+
+poState DecoderBaseObject_impl::state() {
+ return _state;
+}
+
+void DecoderBaseObject_impl::play() {
+ arts_debug("play: %d", (int)streamState);
+ if (streamState == _THREADSTATE_OPENED) {
+ decoderPlugin->play();
+ } else {
+ Command cmd(_COMMAND_PLAY);
+ decoderPlugin->insertAsyncCommand(&cmd);
+ }
+ setStreamState(_THREADSTATE_PLAYING);
+ _state = Arts::posPlaying;
+}
+
+void DecoderBaseObject_impl::seek(const class poTime& seekTime) {
+#ifdef _STRIP_ZERO
+ return;
+#endif
+
+ long sec=seekTime.seconds;
+
+ arts_debug("sec in plugin is %d:", sec);
+
+ // we send an async command
+ Command cmd(_COMMAND_SEEK,sec);
+ decoderPlugin->insertAsyncCommand(&cmd);
+
+ // if the thread blocks on the artsOutputstream: kick him out
+ // the next command will the the seek command
+ m_outputStream->audioClose();
+
+
+ // thread blocking allowed
+ m_outputStream->audioOpen();
+ arts_debug("************ reopen");
+ // now set a new startTime
+ startTime=sec;
+}
+
+void DecoderBaseObject_impl::pause() {
+ arts_debug("pause");
+ _state = Arts::posPaused;
+ Command cmd(_COMMAND_PAUSE);
+ decoderPlugin->insertAsyncCommand(&cmd);
+}
+
+void DecoderBaseObject_impl::halt() {
+ /*
+ *
+ * halt() (which the normal programmer would probably refer to as stop())
+ * should seek to the beginning and go into the posIdle state, like a just
+ * opened PlayObject
+ *
+ */
+
+ arts_debug("halt");
+ _state=Arts::posIdle;
+ shudownPlugins();
+}
+
+
+void DecoderBaseObject_impl::streamInit() {
+#ifdef _STRIP_ZERO
+ return;
+#endif
+
+}
+
+
+void DecoderBaseObject_impl::streamStart() {
+ arts_debug("DecoderBaseObject_impl::streamStart");
+}
+
+int DecoderBaseObject_impl::fillArts(unsigned long samples,
+ float* left , float* right) {
+ unsigned long haveSamples = 0;
+
+ AudioTime* audioTime=m_outputStream->getAudioTime();
+ int wav_samplingRate=audioTime->getSpeed();
+ int wav_sampleWidth=audioTime->getSampleSize();
+ int wav_channelCount=audioTime->getStereo()+1;
+
+ if(doFloat()) wav_sampleWidth = sizeof(float)*8;
+
+ // here seems to be an error, I have clicks sometimes in the stream
+ //int byteMultiplikator=(wav_sampleWidth/8)*wav_channelCount;
+
+ // maybe first multiply, then divide?
+ int byteMultiplikator = wav_channelCount * wav_sampleWidth / 8;
+
+ char* buffer;
+ int hasBytes = 0;
+ int wantBytes = 0;
+ int bufferSize=getBufferSize();
+ if (bufferSize != lastAudioBufferSize) {
+ lastAudioBufferSize=bufferSize;
+ m_outputStream->setAudioBufferSize(bufferSize);
+ }
+
+ /* difference between the sampling rates in percent */
+ float diff = fabs((double)wav_samplingRate - (double)(samplingRateFloat/_speed))
+ / (double)samplingRateFloat;
+
+ /*
+ * efficient optimized case:
+ * 1. decoder -> float rendering
+ * 2. no resampling (i.e. artsd running @ 44100 Hz, playing an 44100 Hz mp3)
+ */
+ if(_state == Arts::posPlaying && doFloat() && diff < 0.0005) {
+ wantBytes = sizeof(float) * wav_channelCount * samples;
+ hasBytes = m_outputStream->read(&buffer,wantBytes);
+ float *flptr = (float *)buffer;
+
+ if(wav_channelCount == 1)
+ {
+ while((int)(haveSamples * sizeof(float)) < hasBytes)
+ {
+ left[haveSamples] = right[haveSamples] = flptr[haveSamples];
+ haveSamples++;
+ }
+ }
+ else if(wav_channelCount == 2)
+ {
+ while((int)(haveSamples * 2 * sizeof(float)) < hasBytes)
+ {
+ left[haveSamples] = flptr[haveSamples*2];
+ right[haveSamples] = flptr[haveSamples*2+1];
+ haveSamples++;
+ }
+ }
+ m_outputStream->forwardReadPtr(haveSamples*sizeof(float)*wav_channelCount);
+ }
+ else if(_state == Arts::posPlaying) {
+ //
+ // since the samplingrate of the MP3 and the samplingrate of the output
+ // device (soundcard) are not necessarily the same, it's a bit tricky
+ //
+
+ // calculate "how fast" we consume input samples (2.0 means, we need 2
+ // input samples to generate one output sample)
+ double speed = (double)wav_samplingRate / (double)(samplingRateFloat/_speed);
+
+ // calculate how many input samples we need, then to satisfy the request
+ // use a larger amount than "really" required, to ensure that samples are
+ // available for rounding errors and interpolation
+ double wantWavSamples = (double)samples*speed+8.0;
+
+ // convert that into bytes and try to read that many bytes
+ wantBytes=(int) (wantWavSamples*byteMultiplikator);
+ hasBytes=m_outputStream->read(&buffer,wantBytes);
+
+ int format = doFloat()?Arts::uni_convert_float_ne:wav_sampleWidth;
+
+ // convert those bytes into the suitable output form
+ haveSamples = Arts::uni_convert_stereo_2float(samples, (unsigned char *)buffer,
+ hasBytes, wav_channelCount,
+ format,
+ left,right,speed,flpos);
+
+ // calculate where we are now (as floating point position) in our
+ // inputsample buffer
+ flpos += (double)haveSamples * speed;
+
+ // Good - so how many input samples we won't need anymore (for the
+ // next request)? Skip them.
+ int skip = (int)floor(flpos);
+ // we need to call this even on skip == 0
+ // because we must unlock the remoteBuffer
+ int forward=skip*byteMultiplikator;
+
+
+ flpos = flpos - floor(flpos);
+
+ m_outputStream->forwardReadPtr(forward);
+ }
+
+ if(haveSamples != samples) {
+
+ unsigned long i;
+
+ for(i=haveSamples;i<samples;i++)
+ left[i] = right[i] = 0.0;
+
+ }
+ return samples;
+}
+
+void DecoderBaseObject_impl::calculateBlock(unsigned long samples,
+ float* left , float* right) {
+
+
+#ifndef _STRIP_ZERO
+
+ int audioState=m_outputStream->waitStreamState(_OUTPUT_WAIT_METHOD_POLL,
+ _STREAM_MASK_ALL,
+ _STREAMTYPE_AUDIO);
+
+ if (audioState & _STREAM_MASK_IS_INIT) {
+ // now check if we already have enough data
+ int lenough=false;
+ if (audioState & _STREAM_MASK_IS_EOF) {
+ if(_state == Arts::posPlaying) {
+ arts_debug("eof got in arts********** END");
+ _state = Arts::posIdle;
+ }
+
+ lenough=true;
+ }
+ if (m_outputStream->getBufferFillgrade() >= 4096) {
+ lenough=true;
+ }
+
+ if (_state == Arts::posPlaying) {
+ if (m_streaming) {
+ // produce more data
+ processQueue();
+ // check for stream end
+ if ( m_inputStream->getByteLength() == 0 ) {
+ if ( m_artsInputStream.eof() ) {
+ m_inputStream->close();
+ m_artsInputStream.streamEnd();
+ }
+ }
+ }
+ if (lenough || _blocking) {
+ fillArts(samples, left, right);
+ return;
+ }
+ }
+ }
+#endif
+
+ // filling with zero , stream not ready(yet)
+
+ unsigned int i;
+ for(i=0;i<samples;i++)
+ left[i] = right[i] = 0.0;
+}
+
+void DecoderBaseObject_impl::streamEnd() {
+ arts_debug("streamEnd");
+#ifdef _STRIP_ZERO
+ return;
+#endif
+
+ halt();
+}
+
+
+int DecoderBaseObject_impl::getBufferSize() {
+ float hardwareBuffer;
+ float fragmentSize;
+ float fragmentCount;
+ float channels;
+ float sampleSize;
+ fragmentSize=Arts::AudioSubSystem::the()->fragmentSize();
+ fragmentCount=Arts::AudioSubSystem::the()->fragmentCount();
+ channels=Arts::AudioSubSystem::the()->channels();
+ sampleSize=16.0/8.0;
+
+ hardwareBuffer=fragmentSize*fragmentCount;
+
+
+ return (int)hardwareBuffer;
+}
+
+
+void DecoderBaseObject_impl::shudownPlugins() {
+ arts_debug("shudownPlugins -s");
+ /**
+ The order here is important.
+ First we close the audio so that the thread never blocks
+ on the ringbuffer.
+ Then we are sure thst we can safley call plugin->close,
+ because the thread does not block.
+ We then have the thread back in the decoder_loop of
+ the plugin.
+ */
+
+ // this should theoretically be faster
+ if (decoderPlugin != NULL) {
+ Command cmd(_COMMAND_CLOSE);
+ decoderPlugin->insertAsyncCommand(&cmd);
+ }
+ if (m_outputStream != NULL) {
+ m_outputStream->audioClose();
+ }
+
+ // very likely the thread already is closed
+ // because of the asyncCommand above.
+ if (decoderPlugin) {
+ decoderPlugin->close();
+ }
+
+ delete m_inputStream;
+ m_inputStream=NULL;
+
+ if (m_streaming)
+ m_artsInputStream.streamEnd();
+
+ setStreamState(_THREADSTATE_CLOSED);
+
+ arts_debug("shudownPlugins -e");
+}
+
+void DecoderBaseObject_impl::setStreamState(int state) {
+
+ switch (state) {
+ case _THREADSTATE_INIT: {
+ streamState=_THREADSTATE_INIT;
+ break;
+ }
+ case _THREADSTATE_OPENED: {
+ streamState=_THREADSTATE_OPENED;
+ break;
+ }
+ case _THREADSTATE_PLAYING: {
+ streamState=_THREADSTATE_PLAYING;
+ break;
+ }
+ case _THREADSTATE_CLOSED: {
+ streamState=_THREADSTATE_INIT;
+ break;
+ }
+ default:
+ std::cerr << "unknown streamState:DecoderBaseObject_impl:"<<state<<std::endl;
+ }
+
+}
+
+/** internal stuff for testing **/
+
+void DecoderBaseObject_impl::blocking(bool newvalue)
+{
+ _blocking = newvalue;
+}
+
+bool DecoderBaseObject_impl::blocking()
+{
+ return _blocking;
+}
+
+void DecoderBaseObject_impl::speed(float newValue)
+{
+ _speed= newValue;
+}
+
+float DecoderBaseObject_impl::speed()
+{
+ return _speed;
+}
diff --git a/mpeglib_artsplug/decoderBaseObject_impl.h b/mpeglib_artsplug/decoderBaseObject_impl.h
new file mode 100644
index 00000000..6ed3f6da
--- /dev/null
+++ b/mpeglib_artsplug/decoderBaseObject_impl.h
@@ -0,0 +1,121 @@
+/*
+ base class for all mpeglib decoders
+ Copyright (C) 2000 Martin Vogt
+
+ This program 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#ifndef __DECODERBASEOBJECT_IMPL_H
+#define __DECODERBASEOBJECT_IMPL_H
+
+
+#include <math.h>
+#include "decoderBaseObject.h"
+#include "stdsynthmodule.h"
+#include "convert.h"
+#include <X11/Xlib.h>
+#include <audiosubsys.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <arts/kmedia2.h>
+
+#define _THREADSTATE_INIT 0
+#define _THREADSTATE_OPENED 1
+#define _THREADSTATE_PAUSED 2
+#define _THREADSTATE_PLAYING 3
+#define _THREADSTATE_CLOSED 4
+
+#include <queue>
+
+class DecoderPlugin;
+class InputStream;
+class ArtsOutputStream;
+
+using namespace std;
+using Arts::poState;
+using Arts::poTime;
+using Arts::poCapabilities;
+using Arts::DataPacket;
+using Arts::mcopbyte;
+
+class DecoderBaseObject_impl :
+ virtual public Arts::StdSynthModule,
+ virtual public DecoderBaseObject_skel {
+
+ poState _state;
+ InputStream* m_inputStream;
+ Arts::InputStream m_artsInputStream;
+ ArtsOutputStream* m_outputStream;
+
+ double flpos;
+ float startTime;
+ int instance;
+ int lastAudioBufferSize;
+ int streamState;
+ bool _blocking;
+ float _speed;
+
+ bool m_streaming;
+
+ queue<DataPacket<mcopbyte>*> *m_packetQueue;
+
+public:
+
+ DecoderBaseObject_impl();
+ virtual ~DecoderBaseObject_impl();
+
+ virtual DecoderPlugin* createPlugin();
+ virtual InputStream* createInputStream(const char* url);
+ virtual bool doFloat() { return false; }
+
+ bool loadMedia(const string &filename);
+ bool streamMedia(Arts::InputStream instream);
+ void process_indata(DataPacket<mcopbyte>* inpacket);
+ Arts::InputStream inputStream() { return m_artsInputStream; }
+
+ string description();
+ void description(const string &);
+
+ poTime currentTime();
+ poTime overallTime();
+
+ poCapabilities capabilities();
+ string mediaName();
+ poState state();
+ void play();
+ void halt();
+
+ void blocking(bool newvalue);
+ bool blocking();
+
+ void speed(float newValue);
+ float speed();
+
+ void seek(const class poTime &);
+ void pause();
+ void streamInit();
+ void streamStart();
+ void calculateBlock(unsigned long samples,float* left,float* right);
+ void streamEnd();
+
+ DecoderPlugin* decoderPlugin;
+
+ private:
+ void shudownPlugins();
+ int getBufferSize();
+ int fillArts(unsigned long samples,float* left , float* right);
+ void setStreamState(int state);
+ void processQueue();
+
+};
+
+
+
+#endif
diff --git a/mpeglib_artsplug/doemacs b/mpeglib_artsplug/doemacs
new file mode 100644
index 00000000..a875517d
--- /dev/null
+++ b/mpeglib_artsplug/doemacs
@@ -0,0 +1,29 @@
+
+
+A=`find . | grep -v moc > flist.txt`
+A=`grep "\.cpp$" flist.txt >cpp.txt`
+A=`grep "\.h$" flist.txt >h.txt`
+A=`grep "\.c$" flist.txt >c.txt`
+A=`grep "\.cc$" flist.txt >cc.txt`
+A=`grep "\.idl$" flist.txt >idl.txt`
+A=`grep "\.defs$" flist.txt >defs.txt`
+C=`cat c.txt`
+CP=`cat cpp.txt`
+H=`cat h.txt`
+CC=`cat cc.txt`
+IDL=`cat idl.txt`
+DEFS=`cat defs.txt`
+
+B="${CP} ${H} ${C} ${CC} ${DEFS} ${IDL}"
+
+emacs $B &
+rm -f cpp.txt
+rm -f h.txt
+rm c.txt
+rm cc.txt
+rm flist.txt
+rm defs.txt
+rm idl.txt
+
+
+
diff --git a/mpeglib_artsplug/mp3PlayObject_impl.cpp b/mpeglib_artsplug/mp3PlayObject_impl.cpp
new file mode 100644
index 00000000..4073ffbe
--- /dev/null
+++ b/mpeglib_artsplug/mp3PlayObject_impl.cpp
@@ -0,0 +1,45 @@
+/*
+ class for mp3-mpeglib decoder
+ Copyright (C) 2000 Martin Vogt
+
+ This program 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+#include "mp3PlayObject_impl.h"
+#include "debug.h"
+
+
+
+MP3PlayObject_impl::MP3PlayObject_impl() {
+ arts_debug("MP3PlayObject_impl");
+}
+
+MP3PlayObject_impl::~MP3PlayObject_impl() {
+ arts_debug("~MP3PlayObject_impl");
+}
+
+
+DecoderPlugin* MP3PlayObject_impl::createPlugin() {
+ arts_debug("MP3PlayObject_impl::getPlugin");
+ return new SplayPlugin();
+}
+
+bool MP3PlayObject_impl::doFloat()
+{
+ return true;
+}
+
+void MP3PlayObject_impl::calculateBlock(unsigned long samples) {
+ DecoderBaseObject_impl::calculateBlock(samples,left,right);
+}
+
+
+
+REGISTER_IMPLEMENTATION(MP3PlayObject_impl);
+
+
diff --git a/mpeglib_artsplug/mp3PlayObject_impl.h b/mpeglib_artsplug/mp3PlayObject_impl.h
new file mode 100644
index 00000000..22a421dc
--- /dev/null
+++ b/mpeglib_artsplug/mp3PlayObject_impl.h
@@ -0,0 +1,43 @@
+/*
+ class for mp3-mpeglib decoder
+ Copyright (C) 2000 Martin Vogt
+
+ This program 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#ifndef __MP3PLAYOBJECT_IMPL_H
+#define __MP3PLAYOBJECT_IMPL_H
+
+
+#include "decoderBaseObject_impl.h"
+#include "../mpeglib/lib/decoder/splayPlugin.h"
+
+
+class MP3PlayObject_impl:
+ virtual public DecoderBaseObject_impl,
+ virtual public MP3PlayObject_skel {
+
+
+
+public:
+
+ MP3PlayObject_impl();
+ virtual ~MP3PlayObject_impl();
+
+ DecoderPlugin* createPlugin();
+ bool doFloat();
+
+
+
+ void calculateBlock(unsigned long samples);
+
+};
+
+
+#endif
diff --git a/mpeglib_artsplug/mpeglibartsplay.cpp b/mpeglib_artsplug/mpeglibartsplay.cpp
new file mode 100644
index 00000000..66b69150
--- /dev/null
+++ b/mpeglib_artsplug/mpeglibartsplay.cpp
@@ -0,0 +1,276 @@
+// vim:ts=2:sw=2:sts=2:et
+/**
+ Starter for plugins.
+ The plugins are identified by their extension
+
+ .wav ->WavPlayObject
+ .mp3 ->MP3PlayObject
+ .mpg ->MPGPlayObject
+ .ogg ->OGGPlayObject
+*/
+
+
+#include "soundserver.h"
+#include "kmedia2.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <vector>
+#include <string>
+#include <iostream>
+#include <climits>
+
+using namespace std;
+
+#if defined(HAVE_GETOPT_H)
+#include <getopt.h>
+#endif
+
+
+string file1;
+string file2;
+
+Arts::Dispatcher* d=0;
+Arts::SimpleSoundServer* server=0;
+
+
+
+void usage() {
+ cout << "mpeglibartsply command line tool for arts playobjects"<<endl;
+ cout << "Usage : mpeglibartsply [url]"<<endl;
+ cout << endl;
+ cout << "-1 : create/destroy PlayObject test."<<endl;
+ cout << "-2 : create/seek/play/destroy PlayObject test."<<endl;
+ cout << "-3 : torture seek implementation test"<<endl;
+ cout << "-h : help"<<endl;
+ cout << endl;
+ cout << "THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! " \
+ << "USE AT YOUR OWN RISK!"<<endl;
+ cout << endl;
+ exit(0);
+}
+
+
+void initServer() {
+ d=new Arts::Dispatcher();
+ server= new Arts::SimpleSoundServer (Arts::Reference("global:Arts_SimpleSoundServer"));
+
+ if(server->isNull()) {
+ cerr << "Can't connect to sound server" << endl;
+ exit(0);
+ }
+
+}
+
+
+void destroyServer() {
+ delete server;
+ delete d;
+}
+
+/**
+ create destroy playobjects without playing anything
+*/
+void doStress1() {
+ int cnt=0;
+ while (cnt < 10000) {
+ Arts::PlayObject play=server->createPlayObject(file1);
+ cout << "cnt:"<<cnt++<<endl;
+ }
+}
+
+/**
+ create playobjects playing some time, do seek play destroy
+*/
+void doStress2() {
+ int cnt=0;
+ while (cnt < 1000) {
+ Arts::PlayObject play=server->createPlayObject(file1);
+ play.play();
+ sleep(3);
+ Arts::poTime seekTime;
+ seekTime.seconds=100;
+ seekTime.ms=0;
+ play.seek(seekTime);
+ cout << "cnt:"<<cnt++<<endl;
+ }
+}
+
+/**
+ create playobject seek random play seek again
+*/
+void doStress3() {
+ int cnt=0;
+ Arts::PlayObject play=server->createPlayObject(file1);
+ play.play();
+ long secs=0;
+ while(1) {
+ cout << "waiting for length info.."<<endl;
+ sleep(3);
+ Arts::poTime length=play.overallTime();
+ secs=length.seconds;
+ if (secs > 0) break;
+ }
+ // do not jump near to end, the danger that
+ // we get an eof is to high
+ if (secs < 100) {
+ cout << "file to short for test"<<endl;
+ exit(-1);
+ }
+ secs-=10;
+ Arts::poTime seekTime;
+ Arts::poTime startTime;
+ startTime.seconds=0;
+ startTime.ms=0;
+
+ while (cnt < 1000) {
+
+ //
+ // seek to a know position
+ //
+ play.seek(startTime);
+ // now wait for seek completion we need a poll here
+ while(1) {
+ Arts::poTime current=play.currentTime();
+ if (current.seconds < 5) {
+ break;
+ }
+ usleep(50000);
+ }
+
+ //
+ // now we know that the playObject is near the beginning
+ //
+
+ int randNo=rand();
+ long seekPos=(long)(((float)randNo*(float)secs)/(float)RAND_MAX);
+ // need to jump over the start area
+
+ seekPos+=5;
+ cout << "seek to :"<<seekPos
+ << " | cnt:"<<cnt++
+ << " of 1000"<<endl;
+ seekTime.seconds=seekPos;
+ seekTime.ms=0;
+ play.seek(seekTime);
+ // now wait for seek completion we need a poll here
+ while(1) {
+ Arts::poTime current=play.currentTime();
+ if (current.seconds > seekPos) {
+ break;
+ }
+ if (current.seconds == seekPos) {
+ if (current.ms > 0) {
+ break;
+ }
+ }
+ usleep(50000);
+ }
+
+
+ }
+ cout << "stresstest successfully passed."<<endl;
+}
+
+
+int main(int argc, char **argv) {
+ int testNr=0;
+ int c;
+ initServer();
+
+ while(1) {
+ c = getopt (argc, argv, "123456h");
+ if (c == -1) break;
+ switch(c) {
+ case '1': {
+ testNr=1;
+ break;
+ }
+ case '2': {
+ testNr=2;
+ break;
+ }
+ case '3': {
+ testNr=3;
+ break;
+ }
+ case '4': {
+ testNr=4;
+ break;
+ }
+ case '5': {
+ testNr=5;
+ break;
+ }
+ case '6': {
+ testNr=5;
+ break;
+ }
+ case 'h': {
+ usage();
+ break;
+ }
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ usage();
+ exit(-1);
+ }
+ }
+
+ if (optind >= argc ) {
+ usage();
+ exit(-1);
+ }
+
+ if (optind < argc ) {
+ file1=argv[optind];
+ optind++;
+ file2=file1;
+ }
+ if (optind < argc ) {
+ file2=argv[optind];
+ }
+
+
+ switch(testNr) {
+ case 1: {
+ doStress1();
+ break;
+ }
+ case 2: {
+ doStress2();
+ break;
+ }
+ case 3: {
+ doStress3();
+ break;
+ }
+ default:
+ if (file1[0] != '/') {
+ char buf[PATH_MAX+1];
+ char *path = getcwd(buf, PATH_MAX - file1.length());
+ if (path) {
+ file1.insert(0, "/");
+ file1.insert(0, path);
+ }
+ }
+ Arts::PlayObject play=server->createPlayObject(file1);
+ if (play.isNull()) {
+ cout << "cannot play this"<<endl;
+ destroyServer();
+ exit(0);
+ }
+ play.play();
+ while (play.state() != Arts::posIdle) {
+ sleep(1);
+ }
+ }
+
+ destroyServer();
+}
+
diff --git a/mpeglib_artsplug/mpgPlayObject_impl.cpp b/mpeglib_artsplug/mpgPlayObject_impl.cpp
new file mode 100644
index 00000000..3ad5a568
--- /dev/null
+++ b/mpeglib_artsplug/mpgPlayObject_impl.cpp
@@ -0,0 +1,53 @@
+/*
+ class for mpeg video decoder
+ Copyright (C) 2000 Martin Vogt
+
+ This program 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#include "mpgPlayObject_impl.h"
+#include "debug.h"
+
+
+
+
+
+MPGPlayObject_impl::MPGPlayObject_impl() {
+ arts_debug("MPGPlayObject_impl");
+ m_fullscreen = false;
+}
+
+MPGPlayObject_impl::~MPGPlayObject_impl() {
+ arts_debug("~MPGPlayObject_impl");
+}
+
+
+DecoderPlugin* MPGPlayObject_impl::createPlugin() {
+ return new MpgPlugin();
+}
+
+void MPGPlayObject_impl::calculateBlock(unsigned long samples) {
+ DecoderBaseObject_impl::calculateBlock(samples,left,right);
+}
+
+long int MPGPlayObject_impl::x11WindowId() {
+ return decoderPlugin->x11WindowId();
+}
+
+bool MPGPlayObject_impl::fullscreen() {
+ return m_fullscreen;
+}
+
+void MPGPlayObject_impl::fullscreen(bool value) {
+ m_fullscreen = value;
+}
+
+
+REGISTER_IMPLEMENTATION(MPGPlayObject_impl);
+
diff --git a/mpeglib_artsplug/mpgPlayObject_impl.h b/mpeglib_artsplug/mpgPlayObject_impl.h
new file mode 100644
index 00000000..02980a22
--- /dev/null
+++ b/mpeglib_artsplug/mpgPlayObject_impl.h
@@ -0,0 +1,48 @@
+/*
+ class for mpeg video decoder
+ Copyright (C) 2000 Martin Vogt
+
+ This program 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#ifndef __MPGPLAYOBJECT_IMPL_H
+#define __MPGPLAYOBJECT_IMPL_H
+
+
+#include "decoderBaseObject_impl.h"
+#include "../mpeglib/lib/decoder/mpgPlugin.h"
+
+
+
+class MPGPlayObject_impl:
+ virtual public DecoderBaseObject_impl,
+ virtual public MPGPlayObject_skel {
+
+
+public:
+
+ MPGPlayObject_impl();
+ virtual ~MPGPlayObject_impl();
+
+
+ DecoderPlugin* createPlugin();
+
+ long int x11WindowId();
+ void fullscreen(bool value);
+ bool fullscreen();
+
+ void calculateBlock(unsigned long samples);
+
+private:
+ bool m_fullscreen;
+
+};
+
+
+#endif
diff --git a/mpeglib_artsplug/nullPlayObject_impl.cpp b/mpeglib_artsplug/nullPlayObject_impl.cpp
new file mode 100644
index 00000000..2e291ac2
--- /dev/null
+++ b/mpeglib_artsplug/nullPlayObject_impl.cpp
@@ -0,0 +1,120 @@
+/*
+ base class for all mpeglib decoders
+ Copyright (C) 2000 Martin Vogt
+
+ This program 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+#include "nullPlayObject_impl.h"
+#include "debug.h"
+
+NULLPlayObject_impl::NULLPlayObject_impl() {
+ _state=Arts::posIdle;
+
+}
+
+NULLPlayObject_impl::~NULLPlayObject_impl() {
+ arts_debug("~NULLPlayObject_impl -s");
+}
+
+
+bool NULLPlayObject_impl::loadMedia(const string &filename) {
+ arts_debug("NULLPlayObject_impl::loadMedia");
+ return true;
+}
+
+
+
+string NULLPlayObject_impl::description() {
+ arts_debug("description");
+ string back;
+ return back;
+}
+
+void NULLPlayObject_impl::description(const string &) {
+ arts_debug("description");
+ // what should do this?
+}
+
+Arts::poTime NULLPlayObject_impl::currentTime() {
+ poTime time;
+ return time;
+}
+
+
+
+poTime NULLPlayObject_impl::overallTime() {
+ poTime time;
+ return time;
+}
+
+poCapabilities NULLPlayObject_impl::capabilities() {
+ arts_debug("capabilities");
+ return Arts::capPause; /* no seek supported */
+}
+
+string NULLPlayObject_impl::mediaName() {
+ arts_debug("mediaName");
+ string back;
+ // whats a mediaName?
+ return back;
+}
+
+poState NULLPlayObject_impl::state() {
+ return _state;
+}
+
+void NULLPlayObject_impl::play() {
+ arts_debug("NULLPlayObject_impl::play");
+ _state = Arts::posPlaying;
+}
+
+void NULLPlayObject_impl::seek(const class poTime& seekTime) {
+ long sec=seekTime.seconds;
+
+ arts_debug("NULLPlayObject_impl::sec is %d:", sec);
+
+}
+
+void NULLPlayObject_impl::pause() {
+ arts_debug("NULLPlayObject_impl::pause");
+ _state = Arts::posPaused;
+}
+
+void NULLPlayObject_impl::halt() {
+ arts_debug("NULLPlayObject_impl::halt");
+ _state=Arts::posIdle;
+}
+
+
+void NULLPlayObject_impl::streamInit() {
+ arts_debug(" NULLPlayObject_impl::streamInit");
+}
+
+
+void NULLPlayObject_impl::streamStart() {
+ arts_debug(" NULLPlayObject_impl::streamStart");
+}
+
+void NULLPlayObject_impl::calculateBlock(unsigned long samples,
+ float* left , float* right) {
+
+
+ arts_debug(" NULLPlayObject_impl::calculateBlock");
+
+ unsigned int i;
+ for(i=0;i<samples;i++)
+ left[i] = right[i] = 0.0;
+}
+
+void NULLPlayObject_impl::streamEnd() {
+ arts_debug("NULLPlayObject_impl::streamEnd");
+}
+
+
+REGISTER_IMPLEMENTATION(NULLPlayObject_impl);
diff --git a/mpeglib_artsplug/nullPlayObject_impl.h b/mpeglib_artsplug/nullPlayObject_impl.h
new file mode 100644
index 00000000..c557b2f0
--- /dev/null
+++ b/mpeglib_artsplug/nullPlayObject_impl.h
@@ -0,0 +1,75 @@
+/*
+ this playobkect does nothing
+ Copyright (C) 2000 Martin Vogt
+
+ This program 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#ifndef __NULLPLAYOBJECT_IMPL_H
+#define __NULLPLAYOBJECT_IMPL_H
+
+
+
+#include <math.h>
+#include "decoderBaseObject.h"
+#include "stdsynthmodule.h"
+#include "convert.h"
+#include <X11/Xlib.h>
+#include <audiosubsys.h>
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+
+
+using namespace std;
+using Arts::poState;
+using Arts::poTime;
+using Arts::poCapabilities;
+
+
+class NULLPlayObject_impl :
+ virtual public Arts::StdSynthModule,
+ virtual public NULLPlayObject_skel {
+
+ poState _state;
+
+public:
+
+ NULLPlayObject_impl();
+ virtual ~NULLPlayObject_impl();
+
+
+ bool loadMedia(const string &filename);
+ string description();
+ void description(const string &);
+
+ poTime currentTime();
+ poTime overallTime();
+
+ poCapabilities capabilities();
+ string mediaName();
+ poState state();
+ void play();
+ void halt();
+
+ void blocking(bool newvalue);
+ bool blocking();
+
+ void seek(const class poTime &);
+ void pause();
+ void streamInit();
+ void streamStart();
+ void calculateBlock(unsigned long samples,float* left,float* right);
+ void streamEnd();
+
+};
+
+
+
+#endif
diff --git a/mpeglib_artsplug/oggPlayObject_impl.cpp b/mpeglib_artsplug/oggPlayObject_impl.cpp
new file mode 100644
index 00000000..04b03a63
--- /dev/null
+++ b/mpeglib_artsplug/oggPlayObject_impl.cpp
@@ -0,0 +1,43 @@
+/*
+ class for ogg-mpeglib decoder
+ Copyright (C) 2000 Martin Vogt
+
+ This program 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+
+
+#include "oggPlayObject_impl.h"
+#include "debug.h"
+
+
+
+
+OGGPlayObject_impl::OGGPlayObject_impl() {
+ arts_debug("OGGPlayObject_impl");
+}
+
+OGGPlayObject_impl::~OGGPlayObject_impl() {
+ arts_debug("~OGGPlayObject_impl");
+}
+
+
+DecoderPlugin* OGGPlayObject_impl::createPlugin() {
+ arts_debug("OGGPlayObject_impl::getPlugin");
+ return new VorbisPlugin();
+}
+
+void OGGPlayObject_impl::calculateBlock(unsigned long samples) {
+ DecoderBaseObject_impl::calculateBlock(samples,left,right);
+}
+
+
+
+REGISTER_IMPLEMENTATION(OGGPlayObject_impl);
+
diff --git a/mpeglib_artsplug/oggPlayObject_impl.h b/mpeglib_artsplug/oggPlayObject_impl.h
new file mode 100644
index 00000000..bae72a28
--- /dev/null
+++ b/mpeglib_artsplug/oggPlayObject_impl.h
@@ -0,0 +1,47 @@
+/*
+ class for ogg-mpeglib decoder
+ Copyright (C) 2000 Martin Vogt
+
+ This program 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#ifndef __OGGPLAYOBJECT_IMPL_H
+#define __OGGPLAYOBJECT_IMPL_H
+
+
+#include "decoderBaseObject_impl.h"
+#include "../mpeglib/lib/decoder/vorbisPlugin.h"
+
+
+// for dynamic loading
+#include <dlfcn.h>
+
+
+class OGGPlayObject_impl:
+ virtual public DecoderBaseObject_impl,
+ virtual public OGGPlayObject_skel {
+
+
+
+public:
+
+ OGGPlayObject_impl();
+ virtual ~OGGPlayObject_impl();
+
+
+ DecoderPlugin* createPlugin();
+
+
+
+ void calculateBlock(unsigned long samples);
+
+};
+
+
+#endif
diff --git a/mpeglib_artsplug/splayPlayObject.idl b/mpeglib_artsplug/splayPlayObject.idl
new file mode 100644
index 00000000..51aa277d
--- /dev/null
+++ b/mpeglib_artsplug/splayPlayObject.idl
@@ -0,0 +1,15 @@
+#include "kmedia2.idl"
+#include "artsflow.idl"
+
+/* the interfaces below are not kept binary compatible */
+
+interface SplayPlayObject : Arts::StreamPlayObject, Arts::SynthModule
+{
+ async in byte stream indata;
+
+ out audio stream left,right;
+
+};
+
+
+
diff --git a/mpeglib_artsplug/splayPlayObject_impl.cpp b/mpeglib_artsplug/splayPlayObject_impl.cpp
new file mode 100644
index 00000000..d29aa61a
--- /dev/null
+++ b/mpeglib_artsplug/splayPlayObject_impl.cpp
@@ -0,0 +1,500 @@
+/*
+ base class for splay mp3 decoder
+ Copyright (C) 2000 Martin Vogt
+
+ This program 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+#include "splayPlayObject_impl.h"
+#include "../mpeglib/lib/splay/splayDecoder.h"
+#include "../mpeglib/lib/frame/audioFrameQueue.h"
+#include "../mpeglib/lib/splay/mpegAudioFrame.h"
+
+#include "debug.h"
+
+#define INPUT_SIZE 8192
+
+/**
+ Problems with streaming, which must be solved:
+ ==============================================
+
+
+ Deadlocks. I think we cannot have sync streams
+ for input/output.
+
+ This example is an OLD style PlayObject. (it uses sync streams)
+ The task is to convert this into an async PlayObject.
+
+ What does this PlayObject do:
+ -----------------------------
+
+ Current:
+ It reads data from a file and insert it
+ into a queue.
+
+ Future:
+ A "remote" sender of raw data, can test how much
+ bytes he can insert into the "framer".
+ If the framer produces a frame, we decode it,
+ and send an async dataPacket out.
+ (Then the frameQueue is not necessary anymore -IMHO)
+
+*/
+
+
+SplayPlayObject_impl::SplayPlayObject_impl() {
+
+ flpos=0.0;
+
+ splay=new SplayDecoder();
+ frameQueue= new AudioFrameQueue(10,MP3FRAMESIZE,_FRAME_AUDIO_FLOAT);
+ framer=new MpegAudioFrame();
+
+ arts_debug("outputStream created");
+
+ _state=Arts::posIdle;
+ file=NULL;
+ lStreaming=false;
+
+ resampleBuffer=NULL;
+ resampleBufferSize=0;
+ currentPacket=NULL;
+ currentPos=0;
+ // ok, we store packets here. Someday I should make this a template.
+ // use STL? maybe.
+ packetQueue=new FrameQueue(10);
+
+ // Note: The inputbuffer must NOT NOT NOT be on the stack!
+ inputbuffer=new unsigned char[INPUT_SIZE];
+
+}
+
+SplayPlayObject_impl::~SplayPlayObject_impl() {
+ arts_debug("~SplayPlayObject_impl -s");
+ delete splay;
+ delete frameQueue;
+ delete framer;
+ arts_debug("~SplayPlayObject_impl -e");
+
+ if (resampleBuffer != NULL) {
+ delete resampleBuffer;
+ }
+ //
+ // arts wants to free the packets and packetQueue too.
+ // so we dequeue all packets here, before deleting packetQueue
+ // otherwise we call delete on the packets twice.
+ //
+ while (packetQueue->getFillgrade() > 0) packetQueue->dequeue();
+ // now delete the (empty) queue
+
+ delete packetQueue;
+ delete [] inputbuffer;
+}
+
+
+bool SplayPlayObject_impl::loadMedia(const string &filename) {
+ arts_debug("loadMedia");
+
+ if (file != NULL) {
+ arts_fatal("~SplayPlayObject_impl already loaded");
+ }
+
+ lStreaming=false;
+
+ file=fopen(filename.c_str(),"r");
+ if (file == NULL) {
+ arts_debug("splay cannot open file");
+ return false;
+ }
+
+ flpos=0.0;
+
+ return true;
+}
+
+bool SplayPlayObject_impl::streamMedia(Arts::InputStream instream) {
+ arts_debug("streamMedia");
+ lStreaming=true;
+ currentStream = instream;
+ Arts::StreamPlayObject self = Arts::StreamPlayObject::_from_base(_copy());
+ connect(currentStream, "outdata", self);
+ return true;
+}
+
+void SplayPlayObject_impl::process_indata(Arts::DataPacket<Arts::mcopbyte> *inpacket) {
+ arts_debug("receiving packet");
+
+
+ packetQueue->enqueue((Frame*)inpacket);
+ if (packetQueue->getFillgrade() == 1) {
+ currentPos=0;
+ }
+
+ processQueue();
+}
+
+
+void SplayPlayObject_impl::processQueue() {
+
+
+
+ unsigned char* ptr;
+
+ if (packetQueue->getFillgrade() == 0) {
+ return;
+ }
+ Arts::DataPacket<Arts::mcopbyte>* currentPacket;
+
+ currentPacket=(Arts::DataPacket<Arts::mcopbyte>*) packetQueue->peekqueue(0);
+ int rest=currentPacket->size-currentPos;
+
+ int cnt=0;
+ while( (rest > 0) && (frameQueue->emptyQueueCanRead()) ) {
+
+ int state=framer->getState();
+ switch(state) {
+ case FRAME_NEED: {
+ int bytes=framer->canStore();
+ ptr=currentPacket->contents+currentPos;
+ // don't read beyond the packet.
+ if (bytes >= rest) {
+ bytes=rest;
+ // we must copy this, because we can commit a packet,
+ // which then deletes the pointer to the packet.
+ // but the framer still wants to access the data, later!
+ if (bytes > INPUT_SIZE) {
+ cout << "inputbuffer too small"<<endl;
+ exit(0);
+ }
+ memcpy(inputbuffer,ptr,bytes);
+ ptr=inputbuffer;
+ }
+ framer->store(ptr,bytes);
+ currentPos+=bytes;
+ rest-=bytes;
+ break;
+ }
+ case FRAME_WORK:
+ framer->work();
+ break;
+ case FRAME_HAS:{
+ AudioFrame* emptyFrame= frameQueue->emptyQueueDequeue();
+ if (splay->decode(framer->outdata(),framer->len(),emptyFrame)==true) {
+ frameQueue->dataQueueEnqueue(emptyFrame);
+ cnt++;
+ }
+ break;
+ }
+ default:
+ cout << "unknown state in mpeg audio framing"<<endl;
+ exit(0);
+ }
+ }
+ //cout << "rest-last:"<<rest<<" cnt:"<<cnt<<endl;
+
+ if (rest == 0) {
+ arts_debug("packet processed");
+ currentPacket->processed();
+ packetQueue->dequeue();
+ currentPos=0;
+ }
+
+}
+
+string SplayPlayObject_impl::description() {
+ arts_debug("description [GET1]");
+ string back;
+ return back;
+}
+
+void SplayPlayObject_impl::description(const string &) {
+ arts_debug("description [GET2]");
+}
+
+Arts::poTime SplayPlayObject_impl::currentTime() {
+ Arts::poTime time;
+ return time;
+}
+
+
+
+Arts::poTime SplayPlayObject_impl::overallTime() {
+ Arts::poTime time;
+ return time;
+}
+
+Arts::poCapabilities SplayPlayObject_impl::capabilities() {
+ arts_debug("capabilities");
+ return (Arts::poCapabilities)(Arts::capPause);
+}
+
+string SplayPlayObject_impl::mediaName() {
+ arts_debug("mediaName");
+ string back;
+ return back;
+}
+
+Arts::poState SplayPlayObject_impl::state() {
+ return _state;
+}
+
+void SplayPlayObject_impl::play() {
+ arts_debug("play:");
+ if (file == NULL) {
+ arts_debug("file is NULL:");
+ if (lStreaming && _state != Arts::posPlaying) {
+ currentStream.streamStart();
+ _state = Arts::posPlaying;
+ }
+
+ } else {
+ _state = Arts::posPlaying;
+ }
+}
+
+
+void SplayPlayObject_impl::seek(const class Arts::poTime& ) {
+ arts_debug("SEEK - RESET in decoder.");
+ framer->reset();
+ // and remove pre-decoded frame:
+ frameQueue->clear();
+
+ return;
+}
+
+
+void SplayPlayObject_impl::pause() {
+ arts_debug("pause");
+ _state=Arts::posPaused;
+}
+/*
+ *
+ * halt() (which the normal programmer would probably refer to as stop())
+ * should seek to the beginning and go into the posIdle state, like a just
+ * opened PlayObject
+ *
+ */
+
+void SplayPlayObject_impl::halt() {
+ arts_debug("halt");
+ _state=Arts::posIdle;
+}
+
+
+void SplayPlayObject_impl::streamInit() {
+ arts_debug("streamInit");
+ return;
+}
+
+
+void SplayPlayObject_impl::streamStart() {
+ arts_debug("streamStart");
+ return;
+}
+
+
+
+void SplayPlayObject_impl::calculateBlock(unsigned long wantSamples) {
+ unsigned long i;
+ unsigned long haveSamples=frameQueue->getLen();
+
+ // the wantSamples*2 takes care that there is enough data
+ // even if we have stereo.
+
+
+ if (haveSamples < wantSamples*2) {
+ if (lStreaming) {
+ for(i=0;i<wantSamples;i++) {
+ left[i] = right[i] = 0.0;
+ }
+ return;
+ }
+ // else (file access)
+ getMoreSamples(wantSamples*2);
+ }
+
+ // Yep, we have enough data
+
+
+
+ // now check if we need resampling.
+ AudioFrame* audioFrame=frameQueue->getCurrent();
+ double wav_samplingRate=(double)audioFrame->getFrequenceHZ();
+
+ /* difference between the sampling rates in percent */
+ float diff = fabs(wav_samplingRate-samplingRateFloat) / samplingRateFloat;
+ //cout << "wav_samplingRate:"<<wav_samplingRate<<endl;
+ /*
+ * efficient optimized case:
+ * 1. decoder -> float rendering
+ * 2. no resampling (i.e. artsd running @ 44100 Hz, playing an 44100 Hz mp3)
+ */
+
+ if(diff < 0.02) {
+ // no resample (easy+fast case)
+ haveSamples=frameQueue->copy(left,right,wantSamples);
+
+ for(i=haveSamples;i<wantSamples;i++) {
+ left[i] = right[i] = 0.0;
+ }
+ frameQueue->forwardStreamDouble(haveSamples);
+
+ if (lStreaming) {
+ processQueue();
+ }
+ } else {
+ /** FIXME: you can use this to implement pitchable playobject **/
+ double _speed = 1.0;
+
+ // calculate "how fast" we consume input samples (speed = 2.0 means,
+ // we need 2 input samples to generate one output sample)
+ double speed = (double)wav_samplingRate/(double)(samplingRateFloat/_speed);
+
+ // calculate how many samples we need to read from the frameQueue to
+ // satisfy the request
+ long readSamples = long((double)wantSamples*speed+8.0);
+ checkResampleBuffer(readSamples*2);
+
+ // read the samples
+ // - readSamplesOk contains how much we really got
+ // - we put the samples non-interleaved into the resampleBuffer,
+ // first the left channel, then the right channel
+ long readSamplesOk = frameQueue->copy(&resampleBuffer[0],
+ &resampleBuffer[readSamples],
+ readSamples);
+ // check how many output samples we will be able to generate from that
+ long samplesToConvert = long((double)readSamplesOk/speed)-4;
+ if(samplesToConvert < 0) samplesToConvert = 0;
+ if(samplesToConvert > wantSamples) samplesToConvert = wantSamples;
+
+ // do the conversion
+ Arts::interpolate_mono_float_float(samplesToConvert,flpos,speed,
+ &resampleBuffer[0],left);
+ Arts::interpolate_mono_float_float(samplesToConvert,flpos,speed,
+ &resampleBuffer[readSamples],right);
+
+ // calculate where we are now (as floating point position) in our
+ // inputsample buffer
+ flpos += (double)samplesToConvert * speed;
+
+ // Good - so how many input samples we won't need anymore (for the
+ // next request)? Skip them.
+ int skip = (int)floor(flpos);
+ if(skip)
+ {
+ frameQueue->forwardStreamDouble(skip);
+ flpos = flpos - floor(flpos);
+ }
+
+ for(i=samplesToConvert; i<wantSamples; i++) {
+ left[i] = right[i] = 0.0;
+ }
+
+ if (lStreaming) {
+ processQueue();
+ }
+ }
+
+ // ok, eof stop.
+ /*
+ if (haveSamples < wantSamples) {
+ halt();
+ }
+ */
+}
+
+void SplayPlayObject_impl::streamEnd() {
+ arts_debug("streamEnd");
+ if (file != NULL) {
+ fclose(file);
+ file=NULL;
+ }
+ return;
+}
+
+
+void SplayPlayObject_impl::checkResampleBuffer(int size) {
+
+
+ if (resampleBufferSize != size) {
+ if (resampleBuffer != NULL) {
+ delete resampleBuffer;
+ }
+ resampleBuffer = new float[size];
+ resampleBufferSize=size;
+ }
+
+}
+
+
+
+//
+// This method shows how we insert data in the framer,
+// decode a frame and store it in the queue.
+// This damned queue is necessary, becasue a sync out
+// stream needs a guranteed streamsize == samples.
+// an async stream would simply send a packet
+// and we are done.
+
+void SplayPlayObject_impl::getMoreSamples(int needLen) {
+
+
+ while( (feof(file) == false) && (frameQueue->getLen() < needLen) ) {
+
+ //
+ // This switch/case statement "partitions" the fileinput
+ // into mp3frames. We directly decode them to pcmFrames.
+ //
+
+ //
+ // There are three states. One is "I want Input, give me input"
+ // The other is "I have enough input, dont' bother me and let
+ // me do my work"
+ // The last ist "I have a frame here, take care of this, or
+ // I will continue with my work"
+
+ int state=framer->getState();
+ int cnt=0;
+ switch(state) {
+ case FRAME_NEED: {
+ int bytes=framer->canStore();
+ int read=fread(inputbuffer,1,bytes,file);
+ if (read != bytes) {
+ // read error. reset framer
+ framer->reset();
+ continue;
+ }
+ // Note: The inputbuffer must NOT NOT NOT be on the stack!
+ framer->store(inputbuffer,bytes);
+ break;
+ }
+ case FRAME_WORK:
+ framer->work();
+ break;
+ case FRAME_HAS:{
+ AudioFrame* emptyFrame= frameQueue->emptyQueueDequeue();
+ if (splay->decode(framer->outdata(),framer->len(),emptyFrame)==true) {
+ frameQueue->dataQueueEnqueue(emptyFrame);
+ cnt++;
+ }
+ break;
+ }
+ default:
+ cout << "unknown state in mpeg audio framing"<<endl;
+ exit(0);
+ }
+ }
+ if (feof(file)==true) {
+ halt();
+ return;
+ }
+}
+
+REGISTER_IMPLEMENTATION(SplayPlayObject_impl);
+
+// vim:ts=8:sw=2:sts=2
diff --git a/mpeglib_artsplug/splayPlayObject_impl.h b/mpeglib_artsplug/splayPlayObject_impl.h
new file mode 100644
index 00000000..fb0be931
--- /dev/null
+++ b/mpeglib_artsplug/splayPlayObject_impl.h
@@ -0,0 +1,112 @@
+/*
+ base class for all mpeglib decoders
+ Copyright (C) 2000 Martin Vogt
+
+ This program 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#ifndef __DECODERBASEOBJECT_IMPL_H
+#define __DECODERBASEOBJECT_IMPL_H
+
+
+#include <math.h>
+#include "splayPlayObject.h"
+#include "stdsynthmodule.h"
+#include "convert.h"
+#include <X11/Xlib.h>
+#include <audiosubsys.h>
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <arts/kmedia2.h>
+#include <stdlib.h>
+#include <connect.h>
+
+class SplayDecoder;
+class MpegAudioFrame;
+class AudioFrameQueue;
+class FrameQueue;
+
+
+
+using namespace std;
+
+class SplayPlayObject_impl :
+ virtual public Arts::StdSynthModule,
+ virtual public SplayPlayObject_skel {
+
+
+ Arts::poState _state;
+
+ // decoder
+ SplayDecoder* splay;
+ MpegAudioFrame* framer;
+ AudioFrameQueue* frameQueue;
+ FrameQueue* packetQueue;
+
+ // local input
+ FILE* file;
+
+ double flpos;
+ int lStreaming;
+
+ float* resampleBuffer;
+ int resampleBufferSize;
+
+ unsigned char* inputbuffer;
+ Arts::DataPacket<Arts::mcopbyte> *currentPacket;
+ int currentPos;
+
+
+public:
+
+ SplayPlayObject_impl();
+ virtual ~SplayPlayObject_impl();
+
+
+ bool loadMedia(const string &filename);
+
+ bool streamMedia(Arts::InputStream instream);
+ Arts::InputStream inputStream() { return currentStream; }
+ void process_indata(Arts::DataPacket<Arts::mcopbyte> *inpacket);
+
+ string description();
+ void description(const string &);
+
+ Arts::poTime currentTime();
+ Arts::poTime overallTime();
+
+ Arts::poCapabilities capabilities();
+ string mediaName();
+ Arts::poState state();
+ void play();
+ void halt();
+
+ void seek(const class Arts::poTime &);
+ void pause();
+ void streamInit();
+ void streamStart();
+ void calculateBlock(unsigned long samples);
+ void streamEnd();
+
+ private:
+ Arts::InputStream currentStream;
+
+ void checkResampleBuffer(int size);
+ void checkPacketBuffer(int size);
+ void getMoreSamples(int needLen);
+ void processQueue();
+
+
+
+};
+
+
+
+#endif
diff --git a/mpeglib_artsplug/vcdPlayObject_impl.cpp b/mpeglib_artsplug/vcdPlayObject_impl.cpp
new file mode 100644
index 00000000..4e7e4a40
--- /dev/null
+++ b/mpeglib_artsplug/vcdPlayObject_impl.cpp
@@ -0,0 +1,47 @@
+/*
+ class for mp3-mpeglib decoder
+ Copyright (C) 2000 Martin Vogt
+
+ This program 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+#include "vcdPlayObject_impl.h"
+#include "debug.h"
+#include <iostream>
+
+
+VCDPlayObject_impl::VCDPlayObject_impl() {
+ arts_debug("VCDPlayObject_impl");
+}
+
+VCDPlayObject_impl::~VCDPlayObject_impl() {
+ arts_debug("~VCDPlayObject_impl");
+}
+
+
+DecoderPlugin* VCDPlayObject_impl::createPlugin() {
+ std::cout << "VCDPlayObject_impl::getPlugin"<<std::endl;
+ return new MpgPlugin();
+}
+
+InputStream* VCDPlayObject_impl::createInputStream(const char* ) {
+ cout << "VCDPlayObject_impl::createInputStream"<<endl;
+ InputStream* back;
+ back=InputPlugin::createInputStream(__INPUT_CDI,_INPUT_THREADSAFE);
+ return back;
+}
+
+void VCDPlayObject_impl::calculateBlock(unsigned long samples) {
+ DecoderBaseObject_impl::calculateBlock(samples,left,right);
+}
+
+
+
+REGISTER_IMPLEMENTATION(VCDPlayObject_impl);
+
+
diff --git a/mpeglib_artsplug/vcdPlayObject_impl.h b/mpeglib_artsplug/vcdPlayObject_impl.h
new file mode 100644
index 00000000..fd871a17
--- /dev/null
+++ b/mpeglib_artsplug/vcdPlayObject_impl.h
@@ -0,0 +1,44 @@
+/*
+ class for mp3-mpeglib decoder
+ Copyright (C) 2000 Martin Vogt
+
+ This program 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#ifndef __VCDPLAYOBJECT_IMPL_H
+#define __VCDPLAYOBJECT_IMPL_H
+
+
+#include "decoderBaseObject_impl.h"
+#include "../mpeglib/lib/decoder/mpgPlugin.h"
+
+
+
+class VCDPlayObject_impl:
+ virtual public DecoderBaseObject_impl,
+ virtual public VCDPlayObject_skel {
+
+
+
+public:
+
+ VCDPlayObject_impl();
+ virtual ~VCDPlayObject_impl();
+
+
+ DecoderPlugin* createPlugin();
+
+ InputStream* createInputStream(const char* url);
+
+ void calculateBlock(unsigned long samples);
+
+};
+
+
+#endif
diff --git a/mpeglib_artsplug/wavPlayObject_impl.cpp b/mpeglib_artsplug/wavPlayObject_impl.cpp
new file mode 100644
index 00000000..76d717dc
--- /dev/null
+++ b/mpeglib_artsplug/wavPlayObject_impl.cpp
@@ -0,0 +1,39 @@
+/*
+ class for mp3-mpeglib decoder
+ Copyright (C) 2000 Martin Vogt
+
+ This program 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+#include "wavPlayObject_impl.h"
+#include "debug.h"
+#include <iostream>
+
+
+WAVPlayObject_impl::WAVPlayObject_impl() {
+ arts_debug("WAVPlayObject_impl");
+}
+
+WAVPlayObject_impl::~WAVPlayObject_impl() {
+ arts_debug("~WAVPlayObject_impl");
+}
+
+
+DecoderPlugin* WAVPlayObject_impl::createPlugin() {
+ std::cout << "WAVPlayObject_impl::getPlugin"<<std::endl;
+ return new TplayPlugin();
+}
+
+void WAVPlayObject_impl::calculateBlock(unsigned long samples) {
+ DecoderBaseObject_impl::calculateBlock(samples,left,right);
+}
+
+
+
+REGISTER_IMPLEMENTATION(WAVPlayObject_impl);
+
diff --git a/mpeglib_artsplug/wavPlayObject_impl.h b/mpeglib_artsplug/wavPlayObject_impl.h
new file mode 100644
index 00000000..69601066
--- /dev/null
+++ b/mpeglib_artsplug/wavPlayObject_impl.h
@@ -0,0 +1,44 @@
+/*
+ class for wav-mpeglib decoder
+ Copyright (C) 2000 Martin Vogt
+
+ This program 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#ifndef __WAVPLAYOBJECT_IMPL_H
+#define __WAVPLAYOBJECT_IMPL_H
+
+
+#include "decoderBaseObject_impl.h"
+#include "../mpeglib/lib/decoder/tplayPlugin.h"
+
+
+
+class WAVPlayObject_impl:
+ virtual public DecoderBaseObject_impl,
+ virtual public WAVPlayObject_skel {
+
+
+
+public:
+
+ WAVPlayObject_impl();
+ virtual ~WAVPlayObject_impl();
+
+
+ DecoderPlugin* createPlugin();
+
+
+
+ void calculateBlock(unsigned long samples);
+
+};
+
+
+#endif