summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjaromil <jaromil@949728d9-16ea-0310-a75c-cbdf8430a4b8>2006-11-24 10:01:18 (GMT)
committer jaromil <jaromil@949728d9-16ea-0310-a75c-cbdf8430a4b8>2006-11-24 10:01:18 (GMT)
commitad113beb95a13d1cddcf2dcd35d282ce3f2a9ad8 (patch)
tree38141f897e86cb8f192c94fcf979bffc8cc22b68
parent309d883de30bfd9f9c5cedf67cf4195118607f76 (diff)
sound patch devel ongoing
git-svn-id: svn://dyne.org/montevideo/ivysync@77 949728d9-16ea-0310-a75c-cbdf8430a4b8
-rw-r--r--branches/lydia/pipe.cpp386
-rw-r--r--branches/lydia/pipe.h258
-rw-r--r--branches/lydia/sndfile_decoder.cpp6
-rw-r--r--branches/lydia/sndfile_decoder.h16
-rw-r--r--branches/lydia/sound_decoder.cpp15
-rw-r--r--branches/lydia/sound_decoder.h25
6 files changed, 672 insertions, 34 deletions
diff --git a/branches/lydia/pipe.cpp b/branches/lydia/pipe.cpp
new file mode 100644
index 0000000..7279b4f
--- /dev/null
+++ b/branches/lydia/pipe.cpp
@@ -0,0 +1,386 @@
+/*
+ Copyright (c) 2001 Charles Samuels <charles@kde.org>
+ Copyright (c) 2002 - 2004 Denis Rojo <jaromil@dyne.org>
+
+this pipe class was first written by Charles Samuels
+and then heavily mutilated and optimized by Denis "jaromil" Rojo
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with this library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+
+"$Id: pipe.cpp 759 2006-03-16 23:35:57Z xant $"
+
+*/
+
+#include <iostream>
+#include <stdlib.h>
+#include <math.h>
+#include <errno.h>
+
+#include <pipe.h>
+#include <utils.h>
+
+
+#define MIN(a,b) (a<=b) ? a : b;
+
+#define _SIZE(val) \
+ if ((char*)end > (char*)start) \
+ val = (char*)end-(char*)start; \
+ else if((char *)end == (char *)start && (char *)start == (char *)buffer) \
+ val = 0; \
+ else \
+ val = ((char*)bufferEnd-(char*)start)+((char*)end-(char*)buffer);
+
+#define _SPACE(val) \
+ _SIZE(val); \
+ val = ((char*)bufferEnd-(char*)buffer)-val;
+
+// COPY AND MIX CALLBACKS
+// they provide function that are moving data
+// handling it in different ways. it is an optimization when we do
+// conversions while copying the buffer around, or mixing it directly
+// from the pipe to a buffer.
+
+// samples are double if stereo (1 sample is only left or right)
+// multiplying them by the samplesize we can obtain sizes in bytes
+
+static inline void copy_byte(void *dst, void *src, int samples) {
+ memcpy(dst,src,samples);
+ }
+
+static inline void copy_int16_to_float(void *dst, void *src, int samples) {
+ register int c;
+ for( c = samples-1; c>=0 ; c-- ) {
+ ((float*)dst)[c] = ((int16_t*)src)[c] / 32768.0f;
+ }
+}
+
+static inline void copy_float_to_int16(void *dst, void *src, int samples) {
+ register int c;
+ for( c = samples-1; c>=0 ; c-- ) {
+ ((int16_t*)dst)[c] = (int16_t) ( ((float*)src)[c]*32768.0f);
+ }
+}
+
+static inline void mix_int16_to_int32(void *dst, void *src, int samples) {
+ register int c;
+ for( c = samples-1 ; c>=0 ; c-- ) {
+ ((int32_t*)dst)[c]
+ +=
+ ((int16_t*)src)[c];
+ }
+}
+
+///// now register all the copy callbacks functions
+// // this is also a list for the available types
+
+static struct pipe_copy_list callbacks[] = {
+ { "copy_byte", copy_byte, 1, 1 },
+ { "copy_int16_to_float", copy_int16_to_float, sizeof(int16_t), sizeof(float) },
+ { "copy_float_to_int16", copy_float_to_int16, sizeof(float), sizeof(int16_t) },
+ { "mix_int16_to_int32", mix_int16_to_int32, sizeof(int16_t), sizeof(int32_t) },
+ { 0, 0 }
+};
+
+/*
+ start is a pointer to the first character that goes out
+ end is a pointer to the last character to go out
+*/
+
+bool Pipe::set_input_type(char *name) {
+ int c;
+ for(c=0 ; callbacks[c].callback ; c++) {
+ if(strcasecmp(name,callbacks[c].name)==0) {
+ write_copy_cb = &callbacks[c];
+ return true;
+ }
+ }
+ E("can't set input type \"%s\" on pipe",name);
+ return false;
+}
+
+bool Pipe::set_output_type(char *name) {
+ int c;
+ for(c=0 ; callbacks[c].callback ; c++) {
+ if(strcasecmp(name,callbacks[c].name)==0) {
+ read_copy_cb = &callbacks[c];
+ return true;
+ }
+ }
+ E("can't set output type \"%s\" on pipe",name);
+ return false;
+}
+
+
+Pipe::Pipe(int size) {
+ D("Pipe::Pipe(%i)",size);
+ pipesize = size;
+ buffer = calloc(pipesize, 1);
+ if(!buffer)
+ E("FATAL: can't allocate %i bytes buffer for audio Pipe: %s",
+ pipesize, strerror(errno));
+ bufferEnd=(char*)buffer+size;
+ end=start=buffer;
+
+ // set default types to simple bytes
+ set_input_type("copy_byte");
+ set_output_type("copy_byte");
+ // set blocking timeout (ttl) defaults
+ /* default blocking time is 50 millisecs
+ * check read() and write() methods for implementation */
+ read_blocking = false;
+ read_blocking_time = 50000;
+ write_blocking = false;
+ write_blocking_time = 50000;
+ _thread_init();
+ sleep_time = 150; /* defaults to 150 microsecs */
+ //unlock();
+
+}
+
+Pipe::~Pipe() {
+ D("Pipe::~Pipe : freeing %p",buffer);
+ lock();
+ free(buffer);
+ unlock();
+ // _thread_destroy();
+}
+
+void Pipe::set_block(bool input, bool output) {
+ lock();
+ write_blocking = input;
+ read_blocking = output;
+ unlock();
+}
+
+void Pipe::set_block_timeout(int input, int output) {
+ lock();
+ write_blocking_time = input;
+ read_blocking_time = output;
+ unlock();
+}
+
+int Pipe::read(int length, void *data) {
+ int worklen, origlen, truelen;
+ int blk, len, buffered, buffered_bytes;
+ int ttl = 0;
+
+ if(read_blocking) ttl = read_blocking_time;
+
+ lock();
+
+ _SIZE(buffered_bytes);
+ buffered = buffered_bytes
+ / read_copy_cb->src_samplesize;
+ truelen = length;
+
+
+ while(buffered<length) {
+
+ /* if less than desired is in, then
+ (blocking) waits
+ (non blocking) returns what's available */
+ if(read_blocking) {
+ unlock();
+ if(!ttl) {
+ return -1;
+ }
+ jsleep(0,sleep_time*1000); ttl -= sleep_time;
+ lock();
+ _SIZE(buffered_bytes);
+ buffered = buffered_bytes
+ / read_copy_cb->src_samplesize;
+ } else {
+ // nothing in the pipe
+ if(!buffered) {
+ unlock();
+ return 0;
+ } else
+ truelen = buffered;
+ break;
+ }
+ }
+
+ origlen = worklen = truelen * read_copy_cb->src_samplesize;
+
+ while (worklen) {
+
+ /* |buffer*****|end-----------|start********|bufferEnd
+ |buffer-----|start*********|end----------|bufferEnd */
+
+ len = MIN(worklen,buffered_bytes);
+
+ blk = ((char*)bufferEnd - (char*)start);
+
+ blk=MIN(blk,len);
+
+ /* fill */
+ (*read_copy_cb->callback)
+ (data, start,
+ blk / read_copy_cb->src_samplesize);
+ /* blank just copied bytes */
+ //memset(start,0,blk / read_copy_cb->src_samplesize);
+
+ start = &((char*)start)[blk]; // (char*)start += blk;
+ len -= blk;
+ data = &((char*)data)[blk]; // (char*)data += blk;
+ worklen -= blk;
+ if ((end!=buffer) && (start==bufferEnd))
+ start = buffer;
+
+ if (len) { /* short circuit */
+
+ (*read_copy_cb->callback)
+ (data, start,
+ len / read_copy_cb->src_samplesize);
+
+ // /* blank just copied bytes */
+ // memset(start,0,len / read_copy_cb->src_samplesize);
+ data = &((char*)data)[len]; // (char*)data += len;
+ start = &((char*)start)[len]; // (char*)start += len;
+ worklen -= len;
+ if ((end!=buffer) && (start==bufferEnd))
+ start = buffer;
+ }
+ }
+ if (start == end) /* if this read emptied buffer */
+ start = end = buffer; /* reset pointers to le _SIZE behave correctly */
+
+ unlock();
+ return ( (origlen-worklen)/read_copy_cb->src_samplesize );
+}
+
+int Pipe::write(int length, void *data) {
+ int worklen, origlen, space_samples;
+ int space_bytes, len, truelen, blk;
+ int ttl = 0;
+
+ if(write_blocking) ttl = write_blocking_time;
+
+ lock();
+
+ _SPACE(space_bytes);
+ space_samples = (space_bytes / write_copy_cb->dst_samplesize);
+ truelen = length;
+
+ while(length > space_samples) {
+
+ // timeout block mechanism
+ if(write_blocking) {
+ unlock();
+ if(!ttl) {
+ return -1; // block timeout
+ }
+ jsleep(0,sleep_time*1000); ttl -= sleep_time;
+ lock();
+ // recalculate actual sizes
+ _SPACE(space_bytes);
+ space_samples = space_bytes
+ / write_copy_cb->dst_samplesize;
+
+ } else { // non-block
+
+ if(!space_bytes) {
+ unlock();
+ return 0; // nothing in the pipe
+ } else
+ // write what's available
+ truelen = space_samples;
+ break;
+ }
+ }
+
+ origlen = worklen = truelen * write_copy_cb->dst_samplesize;
+
+ while (worklen) {
+
+ /* |buffer-----|end***********|start--------|bufferEnd
+ |buffer*****|start---------|end**********|bufferEnd */
+ len=MIN(worklen, space_bytes);
+
+ blk = (char*)bufferEnd-(char*)end;
+ blk = MIN(blk, len);
+
+ /* fill */
+ (*write_copy_cb->callback)
+ (end, data,
+ blk / write_copy_cb->dst_samplesize);
+
+ end = &((char*)end)[blk]; // (char*)end += blk;
+ len -= blk;
+ data = &((char*)data)[blk]; // (char*)data += blk;
+ worklen -= blk;
+ if ((start!=buffer)
+ && (end==bufferEnd))
+ end = buffer;
+
+ if (len) { // short circuit
+
+ (*write_copy_cb->callback)
+ (end, data,
+ len / write_copy_cb->dst_samplesize);
+
+ data = &((char*)data)[len]; // (char*)data += len;
+ end = &((char*)end)[len]; // (char*)end += len;
+ worklen -= len;
+
+ if ((start!=buffer)
+ && (end==bufferEnd))
+ end = buffer;
+ }
+ }
+ _SPACE(space_bytes);
+ unlock();
+ return ((origlen-worklen) / write_copy_cb->dst_samplesize);
+}
+
+// |buffer******|end--------------|start**************|bufferEnd
+// |buffer-----|start**************|end---------------|bufferEnd
+int Pipe::size() {
+ int res;
+ /* size macro allocates the result variable by itself */
+ lock();
+ _SIZE(res);
+ unlock();
+
+ return res;
+}
+
+// |buffer------|end**************|start--------------|bufferEnd
+// |buffer*****|start--------------|end***************|bufferEnd
+int Pipe::space() {
+ int res;
+ lock();
+ _SPACE(res);
+ unlock();
+
+ return res;
+}
+
+void Pipe::flush() {
+ lock();
+ bufferEnd=(char*)buffer+pipesize;
+ end=start=buffer;
+// memset(buffer,0,pipesize);
+ unlock();
+}
+
+void Pipe::flush(int bytes) {
+ lock();
+ void *temp = malloc(bytes);
+ read(bytes, temp);
+ free(temp);
+ unlock();
+}
diff --git a/branches/lydia/pipe.h b/branches/lydia/pipe.h
new file mode 100644
index 0000000..0d2b758
--- /dev/null
+++ b/branches/lydia/pipe.h
@@ -0,0 +1,258 @@
+/*
+ Copyright (c) 2001 Charles Samuels <charles@kde.org>
+ Copyright (c) 2002-2004 Denis Rojo <jaromil@dyne.org>
+
+ this pipe class was first written by Charles Samuels
+ and almost completely rewritten by Denis "jaromil" Rojo
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ $Id: pipe.h 760 2006-03-16 23:37:40Z xant $
+
+*/
+
+/**
+ @file pipe.h
+ @brief Buffered and threadsafe FIFO pipe
+*/
+
+#ifndef __PIPE_H__
+#define __PIPE_H__
+
+#include <pthread.h>
+#include <string.h>
+#include <inttypes.h>
+
+/**
+ This class defines the implementation of the FIFO (first in, first out)
+ buffered threadsafe pipe. This component is massively used in MuSE's
+ flow of audio data, connecting the Channel to the Stream_mixer and then
+ to the OutChannel.
+
+ This Pipe implementation is fairly well tested and optimized, usesu
+ pthread mutexes for fast atomical locking and has a mixing routine
+ embedded for for reading data from the pipe.
+
+ When an application locks the Pipe, will be waiting until it reaches
+ to gain the lock, then will (pthread_mutex_lock)
+
+ This pipe is never blocking, meaning that it never makes the calling
+ process wait for result. The Pipe::blocking attribute of this class
+ has to be intended in a different way.
+
+ Blocking means that the Pipe::read, Pipe::write and derivative
+ functions will be returning -1 without moving any data, in case
+ the aumount of data requested don't fit for pipe buffers.
+
+ Non-blocking means that the Pipe::read, Pipe::write and derivative
+ functions will move all the data they can move, even if less than
+ requested, and then return the amount of data moved.
+
+ I know, the above might sound weird, just because i used the word
+ 'blocking' where i shouldn't. i beg your pardon and plan to change
+ it in future.
+
+ @brief fast buffered threadsafe FIFO pipe
+*/
+
+/** this function prototype is used in the callbacks that are handling
+ the phisical copying of the memory. they are various functions
+ statically implemented in pipe.cpp */
+typedef void (pipe_copy_f)(void *src, void *dst, int samples);
+
+/** this is the prototype struct holding the list of available types */
+typedef struct pipe_copy_list {
+ char *name;
+ pipe_copy_f *callback;
+ int src_samplesize;
+ int dst_samplesize;
+};
+
+class Pipe {
+public:
+
+/**
+ The constructor initializes all buffers needed, which will be
+ in fact the size of the buffer */
+ Pipe(int size=16384);
+ ///< Pipe constructor class
+
+ ~Pipe();
+ ///< Pipe destructor class
+
+ /**
+ A Pipe can be of different types, meaning that it does different
+ kind of operations when reading or writing like: conversions,
+ mixing of various kinds, all opearations that we can optimize when
+ doing in one single pass, while data is flowing around.
+ Implementations of the various types available can be obtained
+ looking into pipe.cpp when the copy callback functions are registered.
+ The set_input_type and set_output_type methods are used to set which
+ kind of operation the Pipe will execute when moving in and out the
+ data.
+ Default is "copy_byte" which simply copies one byte each sample,
+ you want to change this to set it to the sample type you are using
+
+ types available:
+ * copy_byte
+ * copy_int16_to_float int to float using /32768.0f
+ * copy_float_to_int16 float to int using lrintf()
+ * mix_int16_to_int32 simple sum of 16bit over 32bit int
+
+ */
+ bool set_input_type(char *name);
+ ///< set the input conversion type for this Pipe
+ bool set_output_type(char *name);
+ ///< set the output conversion type for this Pipe
+
+ void set_block(bool input, bool output);
+ ///< set the blocking policy on the read and write
+ void set_block_timeout(int input, int output);
+ ///< set the timeout in milliseconds for the read and write block
+
+ /**
+ Reads out audio data from the pipe filling up the given buffer
+ which has to be properly allocated.
+
+ If the pipe is set 'blocking' then will return -1 if the pipe
+ buffer is full. Otherwise, when non-blocking, will return the
+ amount of data that could be pushed in the pipe.
+
+ @brief FIFO read from pipe
+ @param length amount of data to be read in bytes
+ @param data buffer pointer where to read data, must be allocated allready
+ @return amount of data read, or -1 on error, if Pipe::blocking is true */
+ int read(int length, void *data);
+ ///< read from the pipe
+
+ /**
+ This function is used to read from the pipe directly into a stereo
+ interpolated float audio buffer, which is the ideal input for the
+ secret rabbit code resampler.
+
+ @brief read from FIFO pipe in a float stereo interpolated l/r array
+ @param samples amount of data to be read in samples (1= l&r float)
+ @param buf float buffer to be filled, must be allocated allready
+ @param channels number of channels (1=mono, 2=stereo)
+ @return amount of data read, or -1 on error, if Pipe::blocking is true
+ */
+
+ // int read_float_intl(int samples, float *buf, int channels);
+
+ /**
+ Read from FIFO pipe in a float bidimensional array.
+ It is convenient to read float data for float routines,
+ this one reads into a bidimensional buffer.
+ TAKE CARE THIS FUNCTION IS NOT WELL TESTED
+ i never use it in MuSE i just did it together with the _intl
+
+ */
+ // int read_float_bidi(int samples, float **buf, int channels);
+ ///< read from the pipe into a bidimensional float array
+
+ /**
+ Mixes the audio in the pipe into a given audio buffer.
+ Assumes that the audio buffered is 16bit stereo.
+ This implements the core mixing routine used in Stream_mixer::cafudda.
+
+ @brief Mix audio from FIFO pipe into a mixing buffer
+ @param samples number of samples to be mixed (1= l&r 16bit)
+ @param mix 32bit integer mixing buffer
+ @return amount of samples mixed */
+ // int mix16stereo(int samples, int32_t *mix);
+
+ // int peek(int length, void *data, bool block=true) const; // TODO
+
+ /**
+ Write data inside the FIFO pipe, locking to not overlap read
+ operations (thread safe).
+
+ @brief write into FIFO pipe
+ @param length amount of bytes of data to be written
+ @param data buffer from where to take the data to be written
+ @return when Pipe::blocking is set, this functions returns -1, otherwise
+ the amount of data written.
+ */
+ int write(int length, void *data);
+
+ /**
+ Thread safe write data inside the FIFO pipe, like the main write().
+ In one pass does a conversion over the data being written, from
+
+ @param length amount of bytes of data to be written
+ @param data buffer from where to take the float data to be converted and written
+ @return the amount of data written
+ */
+ // int write_float2int(int length, void *data);
+
+ /**
+ Thread safe write data inside the FIFO pipe, like the main write().
+ In one pass does a conversion over the data being written, from
+ int to float using casting.
+ @param length amount of bytes of data to be written
+ @param data buffer from where to take the int data to be converted and written
+ @return the amount of data written
+ */
+ // int write_int2float(int length, void *data);
+
+ /**
+ @brief Setup blocking behaviour of the Pipe.
+
+ The term 'blocking' here is used in a quite improper way, read more
+ about in the description of the Pipe class. */
+ void block(bool val);
+
+ bool blocking;
+
+ /**
+ @brief tell the amount of data contained in the Pipe
+ @return amount in bytes */
+ int size();
+
+ /**
+ @brief tell the amount of free space in the Pipe
+ @return amount in bytes */
+ int space();
+
+ void flush(); ///< flush all data contained in the Pipe, loosing it
+
+ void flush(int size);
+ ///< flush a certain amount of bytes from FIFO Pipe
+
+ private:
+ pthread_mutex_t _mutex;
+ void _thread_init() { pthread_mutex_init (&_mutex,NULL); };
+ void _thread_destroy() { pthread_mutex_destroy(&_mutex); };
+ void lock() { pthread_mutex_lock(&_mutex); };
+ void unlock() { pthread_mutex_unlock(&_mutex); };
+
+ void *buffer;
+ void *bufferEnd;
+ void *start;
+ void *end;
+
+ pipe_copy_list *read_copy_cb;
+ pipe_copy_list *write_copy_cb;
+
+ int pipesize;
+ bool read_blocking;
+ bool write_blocking;
+ int read_blocking_time;
+ int write_blocking_time;
+ unsigned int sleep_time;
+};
+
+#endif
diff --git a/branches/lydia/sndfile_decoder.cpp b/branches/lydia/sndfile_decoder.cpp
index b09fb17..d14d35d 100644
--- a/branches/lydia/sndfile_decoder.cpp
+++ b/branches/lydia/sndfile_decoder.cpp
@@ -25,10 +25,11 @@
/* ----- LibSndFile input channel ----- */
-MuseDecSndFile::MuseDecSndFile ():MuseDec (){
+MuseDecSndFile::MuseDecSndFile ()
+ : MuseDec(), Entry() {
D("MuseDecSndFile::MuseDecSndFile()");
- strncpy (name, "Snd", 4);
+ set_name("Snd");
memset(&sf_info_struct, 0, sizeof(sf_info_struct));
}
@@ -101,6 +102,7 @@ IN_DATATYPE *MuseDecSndFile::get_audio () {
} else { framepos=0; eos = true; return (NULL); }
}
+
bool MuseDecSndFile::seek (float pos) {
if(pos==0.0) {
diff --git a/branches/lydia/sndfile_decoder.h b/branches/lydia/sndfile_decoder.h
index 0d9cd25..68b08ad 100644
--- a/branches/lydia/sndfile_decoder.h
+++ b/branches/lydia/sndfile_decoder.h
@@ -35,14 +35,7 @@
@class MuseDecSndFile
@brief SndFile decoder
*/
-class MuseDecSndFile:public MuseDec
-{
- private:
- /* pointer to data */
- SNDFILE *sf;
- /* file information struct */
- SF_INFO sf_info_struct;
- short snd_buffer[IN_CHUNK];
+class MuseDecSndFile: public MuseDec, Entry {
public:
/* TODO: scrivere il commento per la doc */
@@ -54,6 +47,13 @@ class MuseDecSndFile:public MuseDec
IN_DATATYPE *get_audio ();
+ private:
+ /* pointer to data */
+ SNDFILE *sf;
+ /* file information struct */
+ SF_INFO sf_info_struct;
+ short snd_buffer[IN_CHUNK];
+
};
#endif
diff --git a/branches/lydia/sound_decoder.cpp b/branches/lydia/sound_decoder.cpp
index ffb85d1..ab743cb 100644
--- a/branches/lydia/sound_decoder.cpp
+++ b/branches/lydia/sound_decoder.cpp
@@ -4,17 +4,16 @@
#include <sound_decoder.h>
#include <utils.h>
-MuseDec::MuseDec() {
+MuseDec::MuseDec()
+ : Thread() {
bitrate = samplerate = channels = frames = 0;
seekable = false; err = false; eos = false;
loaded = false;
- if(pthread_mutex_init (&mutex,NULL) == -1)
- E("%i:%s error initializing POSIX thread mutex",
- __LINE__,__FILE__);
}
-MuseDec::~MuseDec() {
- if(pthread_mutex_destroy(&mutex) == -1)
- E("error destroying POSIX thread mutex",
- __LINE__,__FILE__);
+MuseDec::~MuseDec() { }
+
+void MuseDec::run() {
+ W("TODO: multi-threaded play of channels");
+ return;
}
diff --git a/branches/lydia/sound_decoder.h b/branches/lydia/sound_decoder.h
index b493f50..d930fc1 100644
--- a/branches/lydia/sound_decoder.h
+++ b/branches/lydia/sound_decoder.h
@@ -1,5 +1,5 @@
/* MuSE - Multiple Streaming Engine
- * Copyright (C) 2000-2004 Denis Rojo aka jaromil <jaromil@dyne.org>
+ * Copyright (C) 2000-2006 Denis Rojo aka jaromil <jaromil@dyne.org>
*
* This source code is free software; you can redistribute it and/or
* modify it under the terms of the GNU Public License as published
@@ -15,10 +15,7 @@
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
-
- $Id: decoder.h 408 2004-12-13 00:26:37Z jaromil $"
-
-*/
+ */
/**
@file decoder.h MuSE decoder abstraction
@@ -28,9 +25,11 @@
#ifndef __DECODER_H__
#define __DECODER_H__
-#include <pthread.h>
#include <inttypes.h>
+#include <thread.h>
+#include <linklist.h>
+
#define IN_DATATYPE int16_t
#define MIX_CHUNK 1152 //2048
#define IN_CHUNK MIX_CHUNK
@@ -69,7 +68,7 @@
@brief decoder parent abstraction class
*/
-class MuseDec {
+class MuseDec: public Thread {
public:
@@ -104,6 +103,8 @@ class MuseDec {
*/
virtual int load(char *file) = 0; /* open filename */
+ bool loaded; ///< should be set to true by the implemention on succesful load
+
/**
Seek position over the audio data available to an opened channel.
@@ -130,8 +131,6 @@ class MuseDec {
@return pointer to decoded pcm buffer */
virtual IN_DATATYPE *get_audio() = 0; /* decode audio */
- char name[5]; ///< decoder short name (3 letters)
-
/**
* the following variables describe the audio returned by
* MuseDec::get_audio and must be setted up by the decoder implementation.
@@ -148,14 +147,8 @@ class MuseDec {
bool err; ///< true when an error occurred during audio decoding
///////////////////////////////////////////////////////////
- /* pthread stuff */
- void lock() { pthread_mutex_lock(&mutex); };
- ///< lock decoder thread
- void unlock() { pthread_mutex_unlock(&mutex); };
- ///< unlock decoder thread
+ void run(); ///< @TODO: multithreaded play of channels
- private:
- pthread_mutex_t mutex;
};