@@ -108,3 +108,36 @@ Audio_Track::handle ( int m ) | |||||
return Track::handle( m ); | return Track::handle( m ); | ||||
} | } | ||||
} | } | ||||
/**********/ | |||||
/* Engine */ | |||||
/**********/ | |||||
/* THREAD: IO */ | |||||
/** determine region coverage and fill /buf/ with interleaved samples | |||||
* from /frame/ to /nframes/ for exactly /channels/ channels. */ | |||||
void | |||||
Audio_Track::play ( sample_t *buf, nframes_t frame, nframes_t nframes, int channels ) | |||||
{ | |||||
sample_t *cbuf = new sample_t[ nframes ]; | |||||
/* quick and dirty--let the regions figure out coverage for themselves */ | |||||
for ( list <Track_Widget *>::const_iterator i = _widgets.begin(); i != _widgets.end(); i++ ) | |||||
{ | |||||
const Region *r = (Region*)i; | |||||
for ( int i = channels; i-- ) | |||||
{ | |||||
memset( cbuf, 0, nframes * sizeof( sample_t ) ); | |||||
if ( ! r->read( cbuf, frame, nframes, i ) ) | |||||
/* error ? */; | |||||
/* interleave */ | |||||
int k = 0; | |||||
for ( int j = 0; j < nframes; j += channels ) | |||||
buf[ j ] = cbuf[ k++ ]; | |||||
} | |||||
} | |||||
} |
@@ -53,4 +53,6 @@ public: | |||||
void dump ( void ); | void dump ( void ); | ||||
void remove_selected ( void ); | void remove_selected ( void ); | ||||
void play ( sample_t *buf, nframes_t frame, nframes_t nframes, int channels ); | |||||
}; | }; |
@@ -17,6 +17,8 @@ | |||||
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||||
/*******************************************************************************/ | /*******************************************************************************/ | ||||
#include "Track_Header.H" | |||||
static float seconds_to_buffer = 5.0f; | static float seconds_to_buffer = 5.0f; | ||||
/* A Disk_Stream uses a separate I/O thread to stream a track's | /* A Disk_Stream uses a separate I/O thread to stream a track's | ||||
@@ -57,6 +59,12 @@ virtual ~Disk_Stream::Disk_Stream ( ) | |||||
jack_ringbuffer_free( _rb[ i ] ); | jack_ringbuffer_free( _rb[ i ] ); | ||||
} | } | ||||
Audio_Track * | |||||
Disk_Stream::track ( void ) const | |||||
{ | |||||
return (Audio_Track*)_th->track(); | |||||
} | |||||
/** start Disk_Stream thread */ | /** start Disk_Stream thread */ | ||||
void | void | ||||
Disk_Stream::run ( void ) | Disk_Stream::run ( void ) | ||||
@@ -77,7 +85,7 @@ Disk_Stream::io_thread ( void *arg ) | |||||
void | void | ||||
Disk_Stream::read_block ( sample_t *buf ) | Disk_Stream::read_block ( sample_t *buf ) | ||||
{ | { | ||||
if ( _th->track()->play( buf, _frame, _nframes, channels() ) ) | |||||
if ( track()->play( buf, _frame, _nframes, channels() ) ) | |||||
_frame += _nframes; | _frame += _nframes; | ||||
else | else | ||||
/* error */; | /* error */; | ||||
@@ -22,7 +22,10 @@ | |||||
#include <jack/ringbuffer.h> | #include <jack/ringbuffer.h> | ||||
#include <semaphore.h> | #include <semaphore.h> | ||||
#include "Track_Header.H" | |||||
#include <vector> | |||||
using std::vector; | |||||
class Track_Header; | |||||
class Disk_Stream | class Disk_Stream | ||||
{ | { | ||||
@@ -39,7 +42,7 @@ class Disk_Stream | |||||
int channels ( void ) const { return _rb.size(); } | int channels ( void ) const { return _rb.size(); } | ||||
Track * track ( void ) const { return _th->track(); } | |||||
Audio_Track * track ( void ) const; | |||||
protected: | protected: | ||||
@@ -30,6 +30,6 @@ public: | |||||
bool connected ( void ) const { return jack_port_connected( _port ); } | bool connected ( void ) const { return jack_port_connected( _port ); } | ||||
const char * name ( void ) const { return _name; } | const char * name ( void ) const { return _name; } | ||||
nframes_t write ( sample_t *buf, nframes_t nframes ); | |||||
void write ( sample_t *buf, nframes_t nframes ); | |||||
}; | }; |