Browse Source

Cleanup capture code and eliminate off-by-one-buffer bug when bouncing tracks.

tags/non-daw-v1.1.0
Jonathan Moore Liles 16 years ago
parent
commit
fed042950f
8 changed files with 98 additions and 33 deletions
  1. +1
    -1
      Timeline/Engine/Disk_Stream.H
  2. +9
    -12
      Timeline/Engine/Playback_DS.C
  3. +39
    -11
      Timeline/Engine/Record_DS.C
  4. +10
    -1
      Timeline/Engine/Timeline.C
  5. +24
    -7
      Timeline/Engine/Track.C
  6. +12
    -0
      Timeline/Engine/dsp.C
  7. +1
    -0
      Timeline/Engine/dsp.h
  8. +2
    -1
      Timeline/Track.H

+ 1
- 1
Timeline/Engine/Disk_Stream.H View File

@@ -51,7 +51,6 @@ protected:


nframes_t _nframes; /* buffer size */ nframes_t _nframes; /* buffer size */


nframes_t _frame; /* location of disk read */


std::vector < jack_ringbuffer_t * >_rb; /* one ringbuffer for each channel */ std::vector < jack_ringbuffer_t * >_rb; /* one ringbuffer for each channel */


@@ -63,6 +62,7 @@ protected:


nframes_t _frame_rate; /* used for buffer size calculations */ nframes_t _frame_rate; /* used for buffer size calculations */


volatile nframes_t _frame; /* location of disk read */
volatile nframes_t _pending_seek; /* absolute transport position to seek to */ volatile nframes_t _pending_seek; /* absolute transport position to seek to */
volatile int _terminate; volatile int _terminate;




+ 9
- 12
Timeline/Engine/Playback_DS.C View File

@@ -49,7 +49,8 @@ Playback_DS::seek ( nframes_t frame )
{ {
THREAD_ASSERT( RT ); THREAD_ASSERT( RT );


DMESSAGE( "requesting seek" );
/* FIXME: non-RT-safe IO */
DMESSAGE( "requesting seek to frame %lu", (unsigned long)frame );


if ( seek_pending() ) if ( seek_pending() )
printf( "seek error, attempt to seek while seek is pending\n" ); printf( "seek error, attempt to seek while seek is pending\n" );
@@ -104,7 +105,7 @@ Playback_DS::disk_thread ( void )
sample_t *cbuf = new sample_t[ _nframes * _disk_io_blocks ]; sample_t *cbuf = new sample_t[ _nframes * _disk_io_blocks ];
#endif #endif


int blocks_ready = 1;
int blocks_ready = 0;


const nframes_t nframes = _nframes * _disk_io_blocks; const nframes_t nframes = _nframes * _disk_io_blocks;


@@ -115,27 +116,22 @@ Playback_DS::disk_thread ( void )


if ( seek_pending() ) if ( seek_pending() )
{ {
DMESSAGE( "performing seek" );
/* FIXME: non-RT-safe IO */
DMESSAGE( "performing seek to frame %lu", (unsigned long)_pending_seek );


_frame = _pending_seek; _frame = _pending_seek;
_pending_seek = -1; _pending_seek = -1;
blocks_ready = 1;
/* finish flushing the buffer */

/* for ( int i = channels(); i-- ) */
/* jack_ringbuffer_write_advance( _rb[ i ], jack_ringbuffer_write_space( _rb[ i ] ) ); */

blocks_ready = 0;
} }


if ( blocks_ready < _disk_io_blocks )
if ( ++blocks_ready < _disk_io_blocks )
{ {
++blocks_ready;
/* wait for more space */ /* wait for more space */
continue; continue;
} }


/* reset */ /* reset */
blocks_ready = 1;
blocks_ready = 0;


read_block( buf, nframes ); read_block( buf, nframes );


@@ -211,6 +207,7 @@ Playback_DS::process ( nframes_t nframes )
{ {
THREAD_ASSERT( RT ); THREAD_ASSERT( RT );



const size_t block_size = nframes * sizeof( sample_t ); const size_t block_size = nframes * sizeof( sample_t );


// printf( "process: %lu %lu %lu\n", _frame, _frame + nframes, nframes ); // printf( "process: %lu %lu %lu\n", _frame, _frame + nframes, nframes );


+ 39
- 11
Timeline/Engine/Record_DS.C View File

@@ -72,7 +72,6 @@ Record_DS::disk_thread ( void )


DMESSAGE( "capture thread running..." ); DMESSAGE( "capture thread running..." );



const nframes_t nframes = _nframes * _disk_io_blocks; const nframes_t nframes = _nframes * _disk_io_blocks;


/* buffer to hold the interleaved data returned by the track reader */ /* buffer to hold the interleaved data returned by the track reader */
@@ -83,18 +82,14 @@ Record_DS::disk_thread ( void )


const size_t block_size = nframes * sizeof( sample_t ); const size_t block_size = nframes * sizeof( sample_t );


int blocks_ready = 1;
int blocks_ready = 0;


while ( wait_for_block() ) while ( wait_for_block() )
{ {

if ( blocks_ready < _disk_io_blocks )
{
++blocks_ready;
if ( ++blocks_ready < _disk_io_blocks )
continue; continue;
}

blocks_ready = 1;
else
blocks_ready = 0;


/* pull data from the per-channel ringbuffers and interlace it */ /* pull data from the per-channel ringbuffers and interlace it */
for ( int i = channels(); i--; ) for ( int i = channels(); i--; )
@@ -204,6 +199,7 @@ Record_DS::disk_thread ( void )
_capture = NULL; _capture = NULL;


/* now finalize the recording */ /* now finalize the recording */

track()->finalize( c, _stop_frame ); track()->finalize( c, _stop_frame );


delete c; delete c;
@@ -228,6 +224,8 @@ Record_DS::start ( nframes_t frame )
/* /\* FIXME: safe to do this here? *\/ */ /* /\* FIXME: safe to do this here? *\/ */
/* flush(); */ /* flush(); */


DMESSAGE( "recording started at frame %lu", (unsigned long)frame);

_frame = frame; _frame = frame;


_capture = new Track::Capture; _capture = new Track::Capture;
@@ -260,6 +258,9 @@ Record_DS::stop ( nframes_t frame )
} }




#include "../Transport.H"
extern Transport *transport;

/** read from the attached track's ports and stuff the ringbuffers */ /** read from the attached track's ports and stuff the ringbuffers */
nframes_t nframes_t
Record_DS::process ( nframes_t nframes ) Record_DS::process ( nframes_t nframes )
@@ -269,13 +270,40 @@ Record_DS::process ( nframes_t nframes )
if ( ! _recording ) if ( ! _recording )
return 0; return 0;


const size_t block_size = nframes * sizeof( sample_t );
if ( transport->frame < _frame )
return 0;

/* DMESSAGE( "recording actually happening at %lu (start frame %lu)", (unsigned long)transport->frame, (unsigned long)_frame); */

nframes_t offset = 0;

if ( _frame > transport->frame &&
_frame < transport->frame + nframes )
{
/* The record start frame falls somewhere within the current
buffer. We must discard the unneeded portion and only
stuff the part requested into the ringbuffer. */

offset = _frame - transport->frame;

/* DMESSAGE( "offset = %lu", (unsigned long)offset ); */
}

const size_t offset_size = offset * sizeof( sample_t );
const size_t block_size = ( nframes * sizeof( sample_t ) ) - offset_size;


for ( int i = channels(); i--; ) for ( int i = channels(); i--; )
{ {
/* read the entire input buffer */
void *buf = track()->input[ i ].buffer( nframes ); void *buf = track()->input[ i ].buffer( nframes );


if ( jack_ringbuffer_write( _rb[ i ], (char*)buf, block_size ) < block_size )
/* if ( buffer_is_digital_black( (sample_t*)buf, nframes ) ) */
/* DWARNING( "recording an entirely blank buffer" ); */

/* FIXME: this results in a ringbuffer size that is no longer
necessarily a multiple of nframes... how will the other side
handle that? */
if ( jack_ringbuffer_write( _rb[ i ], (char*)buf + offset, block_size ) < block_size )
{ {
++_xruns; ++_xruns;
memset( buf, 0, block_size ); memset( buf, 0, block_size );


+ 10
- 1
Timeline/Engine/Timeline.C View File

@@ -38,6 +38,8 @@ Timeline::record ( void )


nframes_t frame = transport->frame; nframes_t frame = transport->frame;


DMESSAGE( "Going to record starting at frame %lu", (unsigned long)frame );

for ( int i = tracks->children(); i-- ; ) for ( int i = tracks->children(); i-- ; )
{ {
Track *t = (Track*)tracks->child( i ); Track *t = (Track*)tracks->child( i );
@@ -85,7 +87,14 @@ Timeline::process ( nframes_t nframes )
{ {
Track *t = (Track*)tracks->child( i ); Track *t = (Track*)tracks->child( i );


t->process( nframes );
t->process_output( nframes );
}

for ( int i = tracks->children(); i-- ; )
{
Track *t = (Track*)tracks->child( i );

t->process_input( nframes );
} }


/* FIXME: BOGUS */ /* FIXME: BOGUS */


+ 24
- 7
Timeline/Engine/Track.C View File

@@ -151,33 +151,50 @@ Track::configure_inputs ( int n )
} }


nframes_t nframes_t
Track::process ( nframes_t nframes )
Track::process_input ( nframes_t nframes )
{ {
THREAD_ASSERT( RT ); THREAD_ASSERT( RT );


if ( ! transport->rolling ) if ( ! transport->rolling )
{ {
for ( int i = output.size(); i--; )
output[ i ].silence( nframes );

for ( int i = input.size(); i--; ) for ( int i = input.size(); i--; )
input[ i ].silence( nframes ); input[ i ].silence( nframes );


return 0; return 0;
} }


if ( record_ds )
return record_ds->process( nframes );
else
return 0;

}

nframes_t
Track::process_output ( nframes_t nframes )
{
THREAD_ASSERT( RT );

if ( ! transport->rolling )
{
for ( int i = output.size(); i--; )
output[ i ].silence( nframes );

return 0;
}

/* FIXME: should we blank the control output here or leave it floating? */
for ( int i = control->children(); i--; ) for ( int i = control->children(); i--; )
((Control_Sequence*)control->child( i ))->process( nframes ); ((Control_Sequence*)control->child( i ))->process( nframes );


if ( playback_ds ) if ( playback_ds )
{
record_ds->process( nframes );
return playback_ds->process( nframes ); return playback_ds->process( nframes );
}
else else
return 0; return 0;
} }




void void
Track::seek ( nframes_t frame ) Track::seek ( nframes_t frame )
{ {


+ 12
- 0
Timeline/Engine/dsp.C View File

@@ -95,3 +95,15 @@ buffer_fill_with_silence ( sample_t *buf, nframes_t nframes )
{ {
memset( buf, 0, nframes * sizeof( sample_t ) ); memset( buf, 0, nframes * sizeof( sample_t ) );
} }

bool
buffer_is_digital_black ( sample_t *buf, nframes_t nframes )
{
while ( nframes-- )
{
if ( 0 != buf[nframes] )
return false;
}

return true;
}

+ 1
- 0
Timeline/Engine/dsp.h View File

@@ -29,3 +29,4 @@ void buffer_interleave_one_channel ( sample_t *dst, sample_t *src, int channel,
void buffer_interleave_one_channel_and_mix ( sample_t *dst, sample_t *src, int channel, int channels, nframes_t nframes ); void buffer_interleave_one_channel_and_mix ( sample_t *dst, sample_t *src, int channel, int channels, nframes_t nframes );
void buffer_deinterleave_one_channel ( sample_t *dst, sample_t *src, int channel, int channels, nframes_t nframes ); void buffer_deinterleave_one_channel ( sample_t *dst, sample_t *src, int channel, int channels, nframes_t nframes );
void buffer_fill_with_silence ( sample_t *buf, nframes_t nframes ); void buffer_fill_with_silence ( sample_t *buf, nframes_t nframes );
bool buffer_is_digital_black ( sample_t *buf, nframes_t nframes );

+ 2
- 1
Timeline/Track.H View File

@@ -207,7 +207,8 @@ public:
const Audio_Region *capture_region ( void ) const; const Audio_Region *capture_region ( void ) const;


void resize_buffers ( nframes_t nframes ); void resize_buffers ( nframes_t nframes );
nframes_t process ( nframes_t nframes );
nframes_t process_input ( nframes_t nframes );
nframes_t process_output ( nframes_t nframes );
void seek ( nframes_t frame ); void seek ( nframes_t frame );


void record ( Capture *c, nframes_t frame ); void record ( Capture *c, nframes_t frame );


Loading…
Cancel
Save