Browse Source

Try to get captures to begin and end on the proper frame.

tags/non-daw-v1.1.0
Jonathan Moore Liles 17 years ago
parent
commit
bdd9dc56e4
8 changed files with 99 additions and 41 deletions
  1. +40
    -0
      Timeline/Disk_Stream.C
  2. +3
    -1
      Timeline/Disk_Stream.H
  3. +1
    -17
      Timeline/Playback_DS.C
  4. +41
    -18
      Timeline/Record_DS.C
  5. +5
    -0
      Timeline/Record_DS.H
  6. +6
    -2
      Timeline/Region.C
  7. +1
    -1
      Timeline/Region.H
  8. +2
    -2
      Timeline/Track.C

+ 40
- 0
Timeline/Disk_Stream.C View File

@@ -96,6 +96,46 @@ Disk_Stream::~Disk_Stream ( )
engine->unlock(); engine->unlock();
} }



/* THREAD: RT */
/** flush buffers and reset. Must only be called from the RT thread. */
void
Disk_Stream::flush ( bool is_output )
{

/* flush buffers */
for ( int i = channels(); i--; )
jack_ringbuffer_read_advance( _rb[ i ], jack_ringbuffer_read_space( _rb[ i ] ) );


/* sem_destroy( &_blocks ); */

/* if ( is_output ) */
/* sem_init( &_blocks, 0, _total_blocks ); */
/* else */
/* sem_init( &_blocks, 0, 0 ); */

if ( is_output )
{

int n;
sem_getvalue( &_blocks, &n );

n = _total_blocks - n;

while ( n-- )
sem_post( &_blocks );
}
else
{
sem_destroy( &_blocks );

sem_init( &_blocks, 0, 0 );
}


}

/** stop the IO thread, block until it finishes. */ /** stop the IO thread, block until it finishes. */
void void
Disk_Stream::shutdown ( void ) Disk_Stream::shutdown ( void )


+ 3
- 1
Timeline/Disk_Stream.H View File

@@ -71,7 +71,7 @@ protected:
void block_processed ( void ) { sem_post( &_blocks ); } void block_processed ( void ) { sem_post( &_blocks ); }
bool wait_for_block ( void ) bool wait_for_block ( void )
{ {
while ( sem_wait( &_blocks ) == EINTR );
while ( ! sem_wait( &_blocks ) && errno == EINTR );


if ( _terminate ) if ( _terminate )
return false; return false;
@@ -81,6 +81,8 @@ protected:


virtual void disk_thread ( void ) = 0; virtual void disk_thread ( void ) = 0;


void flush ( bool is_output );

public: public:


/* must be set before any Disk_Streams are created */ /* must be set before any Disk_Streams are created */


+ 1
- 17
Timeline/Playback_DS.C View File

@@ -52,23 +52,7 @@ Playback_DS::seek ( nframes_t frame )


_pending_seek = frame; _pending_seek = frame;


/* flush buffers */
for ( int i = channels(); i--; )
jack_ringbuffer_read_advance( _rb[ i ], jack_ringbuffer_read_space( _rb[ i ] ) );

/* dirty hack... reset the semaphore. Should we just call sem_init
* again instead? */

/* sem_init( &_blocks, 0, _total_blocks ); */

int n;
sem_getvalue( &_blocks, &n );

n = _total_blocks - n;

while ( n-- )
sem_post( &_blocks );

flush( true );
} }


/* THREAD: IO */ /* THREAD: IO */


+ 41
- 18
Timeline/Record_DS.C View File

@@ -43,7 +43,7 @@ Record_DS::write_block ( sample_t *buf, nframes_t nframes )


_th->write( buf, nframes ); _th->write( buf, nframes );


// track()->record( buf, _frame, nframes, channels() );
_frames_written += nframes;


// timeline->unlock(); // timeline->unlock();
} }
@@ -52,7 +52,6 @@ Record_DS::write_block ( sample_t *buf, nframes_t nframes )
void void
Record_DS::disk_thread ( void ) Record_DS::disk_thread ( void )
{ {

printf( "IO thread running...\n" ); printf( "IO thread running...\n" );


const nframes_t nframes = _nframes * _disk_io_blocks; const nframes_t nframes = _nframes * _disk_io_blocks;
@@ -134,17 +133,47 @@ Record_DS::disk_thread ( void )


printf( "IO thread terminating.\n" ); printf( "IO thread terminating.\n" );



/* flush what remains in the buffer out to disk */

{
/* use JACk sized blocks for this last bit */
const nframes_t nframes = _nframes;
const size_t block_size = _nframes * sizeof( sample_t );


while ( blocks_ready-- > 0 || ! sem_trywait( &_blocks ) && errno != EAGAIN )
{

for ( int i = channels(); i--; )
{
jack_ringbuffer_read( _rb[ i ], (char*)cbuf, block_size );

buffer_interleave_one_channel( buf, cbuf, i, channels(), nframes );
}

const nframes_t frames_remaining = (_stop_frame - _frame ) - _frames_written;

if ( frames_remaining < nframes )
{
/* this is the last block, might be partial */
write_block( buf, frames_remaining );
break;
}
else
write_block( buf, nframes );
}
}

delete[] cbuf; delete[] cbuf;
delete[] buf; delete[] buf;
} }




/** begin recording */ /** begin recording */
/* FIXME: we need to make note of the exact frame we were on when recording began */
void void
Record_DS::start ( nframes_t frame ) Record_DS::start ( nframes_t frame )
{ {
/* FIXME: flush buffers here? */


if ( _recording ) if ( _recording )
{ {
@@ -152,6 +181,8 @@ Record_DS::start ( nframes_t frame )
return; return;
} }


/* FIXME: safe to do this here? */
flush( false );


_frame = frame; _frame = frame;


@@ -174,24 +205,16 @@ Record_DS::stop ( nframes_t frame )
return; return;
} }


shutdown();

/* FIXME: flush buffers here? */

/* char *name = strdup( _af->name() ); */
/* delete _af; */
/* _af = NULL; */

/* Audio_File *af = Audio_File::from_file( name ); */
_recording = false;


/* if ( ! af ) */
/* printf( "impossible!\n" ); */
/* FIXME: we may still have data in the buffers waiting to be
* written to disk... We should flush it out before stopping... */


/* new Region( af, track(), _frame ); */
_stop_frame = frame;


/* track()->redraw(); */
shutdown();


_recording = false;
/* FIXME: flush buffers here? */


_th->stop( frame ); _th->stop( frame );




+ 5
- 0
Timeline/Record_DS.H View File

@@ -28,6 +28,9 @@ class Peak_Writer;
class Record_DS : public Disk_Stream class Record_DS : public Disk_Stream
{ {


nframes_t _frames_written;
volatile nframes_t _stop_frame;

volatile bool _recording; volatile bool _recording;


Audio_File_SF *_af; /* capture file */ Audio_File_SF *_af; /* capture file */
@@ -44,6 +47,8 @@ public:
sem_init( &_blocks, 0, 0 ); sem_init( &_blocks, 0, 0 );


_recording = false; _recording = false;
_stop_frame = -1;
_frames_written = 0;
} }


/* bool seek_pending ( void ); */ /* bool seek_pending ( void ); */


+ 6
- 2
Timeline/Region.C View File

@@ -947,14 +947,18 @@ Region::prepare ( void )
/** finalize region capture. Assumes that this *is* a captured region /** finalize region capture. Assumes that this *is* a captured region
and that no other regions refer to the same source */ and that no other regions refer to the same source */
bool bool
Region::finalize ( void )
Region::finalize ( nframes_t frame )
{ {
log_end(); log_end();


_clip->close(); _clip->close();
_clip->open(); _clip->open();


_range.end = _clip->length();
/* FIXME: should we attempt to truncate the file? */

_range.end = frame - _range.offset;

redraw();


return true; return true;
} }

+ 1
- 1
Timeline/Region.H View File

@@ -204,6 +204,6 @@ public:
nframes_t read ( sample_t *buf, nframes_t pos, nframes_t nframes, int channel ) const; nframes_t read ( sample_t *buf, nframes_t pos, nframes_t nframes, int channel ) const;
nframes_t write ( nframes_t nframes ); nframes_t write ( nframes_t nframes );
void prepare ( void ); void prepare ( void );
bool finalize ( void );
bool finalize ( nframes_t frame );


}; };

+ 2
- 2
Timeline/Track.C View File

@@ -749,9 +749,9 @@ Track::write ( sample_t *buf, nframes_t nframes )


/* THREAD: IO */ /* THREAD: IO */
void void
Track::stop ( nframes_t nframes )
Track::stop ( nframes_t frame )
{ {
_capture->finalize();
_capture->finalize( frame );


_capture = NULL; _capture = NULL;
} }

Loading…
Cancel
Save