Timeline: Rework locking.
This commit is contained in:
parent
a228920ac1
commit
98c5c196d4
|
@ -477,6 +477,8 @@ Audio_Region::draw_box( void )
|
||||||
void
|
void
|
||||||
Audio_Region::peaks_ready_callback ( void *v )
|
Audio_Region::peaks_ready_callback ( void *v )
|
||||||
{
|
{
|
||||||
|
/* this is called from the peak builder thread */
|
||||||
|
|
||||||
DMESSAGE("Damaging region from peaks ready callback");
|
DMESSAGE("Damaging region from peaks ready callback");
|
||||||
Fl::lock();
|
Fl::lock();
|
||||||
((Audio_Region*)v)->redraw();
|
((Audio_Region*)v)->redraw();
|
||||||
|
|
|
@ -85,12 +85,8 @@ Control_Sequence::~Control_Sequence ( )
|
||||||
|
|
||||||
log_destroy();
|
log_destroy();
|
||||||
|
|
||||||
engine->lock();
|
|
||||||
|
|
||||||
track()->remove( this );
|
track()->remove( this );
|
||||||
|
|
||||||
engine->unlock();
|
|
||||||
|
|
||||||
if ( _output )
|
if ( _output )
|
||||||
{
|
{
|
||||||
_output->shutdown();
|
_output->shutdown();
|
||||||
|
@ -144,8 +140,6 @@ Control_Sequence::name ( const char *s )
|
||||||
void
|
void
|
||||||
Control_Sequence::update_port_name ( void )
|
Control_Sequence::update_port_name ( void )
|
||||||
{
|
{
|
||||||
engine->lock();
|
|
||||||
|
|
||||||
bool needs_activation = false;
|
bool needs_activation = false;
|
||||||
if ( ! _output )
|
if ( ! _output )
|
||||||
{
|
{
|
||||||
|
@ -170,8 +164,6 @@ Control_Sequence::update_port_name ( void )
|
||||||
_output = NULL;
|
_output = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
engine->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -769,7 +761,7 @@ Control_Sequence::handle ( int m )
|
||||||
|
|
||||||
add( r );
|
add( r );
|
||||||
|
|
||||||
timeline->unlock();
|
timeline->unlock();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,8 @@ Disk_Stream::Disk_Stream ( Track *track, float frame_rate, nframes_t nframes, in
|
||||||
Disk_Stream::~Disk_Stream ( )
|
Disk_Stream::~Disk_Stream ( )
|
||||||
{
|
{
|
||||||
/* it isn't safe to do all this with the RT thread running */
|
/* it isn't safe to do all this with the RT thread running */
|
||||||
engine->lock();
|
|
||||||
|
timeline->wrlock();
|
||||||
|
|
||||||
shutdown();
|
shutdown();
|
||||||
|
|
||||||
|
@ -84,7 +85,7 @@ Disk_Stream::~Disk_Stream ( )
|
||||||
for ( int i = channels(); i--; )
|
for ( int i = channels(); i--; )
|
||||||
jack_ringbuffer_free( _rb[ i ] );
|
jack_ringbuffer_free( _rb[ i ] );
|
||||||
|
|
||||||
engine->unlock();
|
timeline->unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -146,23 +147,13 @@ Disk_Stream::shutdown ( void )
|
||||||
_terminate = true;
|
_terminate = true;
|
||||||
|
|
||||||
/* try to wake the thread so it'll see that it's time to die */
|
/* try to wake the thread so it'll see that it's time to die */
|
||||||
int total_ms = 0;
|
|
||||||
while ( _terminate )
|
while ( _terminate )
|
||||||
{
|
{
|
||||||
usleep( 1000 * 10 );
|
usleep( 100 );
|
||||||
total_ms += 10;
|
|
||||||
block_processed();
|
block_processed();
|
||||||
|
|
||||||
if ( total_ms > 100 )
|
|
||||||
{
|
|
||||||
WARNING("Disk_Stream thread has taken longer than %ims to respond to terminate signal. Canceling", total_ms );
|
|
||||||
_thread.cancel();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! _terminate )
|
_thread.join();
|
||||||
_thread.join();
|
|
||||||
|
|
||||||
sem_destroy( &_blocks );
|
sem_destroy( &_blocks );
|
||||||
|
|
||||||
|
|
|
@ -168,7 +168,11 @@ Engine::process ( nframes_t nframes )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( ! trylock() )
|
if ( !timeline)
|
||||||
|
/* handle chicken/egg problem */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ( timeline->tryrdlock() )
|
||||||
{
|
{
|
||||||
/* the data structures we need to access here (tracks and
|
/* the data structures we need to access here (tracks and
|
||||||
* their ports, but not track contents) may be in an
|
* their ports, but not track contents) may be in an
|
||||||
|
@ -178,14 +182,12 @@ Engine::process ( nframes_t nframes )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle chicken/egg problem */
|
/* this will initiate the process() call graph for the various
|
||||||
if ( timeline )
|
* number and types of tracks, which will in turn send data out
|
||||||
/* this will initiate the process() call graph for the various
|
* the appropriate ports. */
|
||||||
* number and types of tracks, which will in turn send data out
|
timeline->process( nframes );
|
||||||
* the appropriate ports. */
|
|
||||||
timeline->process( nframes );
|
|
||||||
|
|
||||||
unlock();
|
timeline->unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -27,7 +27,7 @@ class Port;
|
||||||
|
|
||||||
#include "Thread.H"
|
#include "Thread.H"
|
||||||
|
|
||||||
class Engine : public JACK::Client, public Mutex
|
class Engine : public JACK::Client
|
||||||
{
|
{
|
||||||
Thread _thread; /* only used for thread checking */
|
Thread _thread; /* only used for thread checking */
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "const.h"
|
#include "const.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "Thread.H"
|
#include "Thread.H"
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Playback_DS::seek_pending ( void )
|
Playback_DS::seek_pending ( void )
|
||||||
|
@ -76,29 +77,36 @@ Playback_DS::read_block ( sample_t *buf, nframes_t nframes )
|
||||||
|
|
||||||
memset( buf, 0, nframes * sizeof( sample_t ) * channels() );
|
memset( buf, 0, nframes * sizeof( sample_t ) * channels() );
|
||||||
|
|
||||||
/* stupid chicken/egg */
|
|
||||||
if ( ! timeline )
|
|
||||||
return;
|
|
||||||
|
|
||||||
// printf( "IO: attempting to read block @ %lu\n", _frame );
|
// printf( "IO: attempting to read block @ %lu\n", _frame );
|
||||||
|
|
||||||
timeline->rdlock();
|
if ( !timeline )
|
||||||
|
return;
|
||||||
|
|
||||||
if ( sequence() )
|
while ( ! _terminate )
|
||||||
{
|
{
|
||||||
/* FIXME: how does this work if _delay is not a multiple of bufsize? */
|
if ( ! timeline->tryrdlock() )
|
||||||
|
|
||||||
if ( _frame >= _delay )
|
|
||||||
{
|
{
|
||||||
if ( ! sequence()->play( buf, _frame - _delay, nframes, channels() ) )
|
if ( sequence() )
|
||||||
WARNING( "Programming error?" );
|
{
|
||||||
|
|
||||||
|
/* FIXME: how does this work if _delay is not a multiple of bufsize? */
|
||||||
|
|
||||||
|
if ( _frame >= _delay )
|
||||||
|
{
|
||||||
|
if ( ! sequence()->play( buf, _frame - _delay, nframes, channels() ) )
|
||||||
|
WARNING( "Programming error?" );
|
||||||
|
}
|
||||||
|
|
||||||
|
_frame += nframes;
|
||||||
|
}
|
||||||
|
|
||||||
|
timeline->unlock();
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_frame += nframes;
|
usleep( 1000 * 10 );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
timeline->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define AVOID_UNNECESSARY_COPYING 1
|
#define AVOID_UNNECESSARY_COPYING 1
|
||||||
|
@ -146,6 +154,10 @@ Playback_DS::disk_thread ( void )
|
||||||
|
|
||||||
read_block( buf, nframes );
|
read_block( buf, nframes );
|
||||||
|
|
||||||
|
/* might have received terminate signal while waiting for block */
|
||||||
|
if ( _terminate )
|
||||||
|
goto done;
|
||||||
|
|
||||||
// unlock(); // for seeking
|
// unlock(); // for seeking
|
||||||
|
|
||||||
/* deinterleave the buffer and stuff it into the per-channel ringbuffers */
|
/* deinterleave the buffer and stuff it into the per-channel ringbuffers */
|
||||||
|
@ -201,6 +213,8 @@ Playback_DS::disk_thread ( void )
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
|
||||||
DMESSAGE( "playback thread terminating" );
|
DMESSAGE( "playback thread terminating" );
|
||||||
|
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
|
@ -209,6 +223,8 @@ Playback_DS::disk_thread ( void )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_terminate = false;
|
_terminate = false;
|
||||||
|
|
||||||
|
_thread.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** take a single block from the ringbuffers and send it out the
|
/** take a single block from the ringbuffers and send it out the
|
||||||
|
|
|
@ -72,7 +72,7 @@ Track::configure_outputs ( int n )
|
||||||
if ( n == on )
|
if ( n == on )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// engine->lock();
|
DMESSAGE( "Reconfiguring outputs for track %s", name() );
|
||||||
|
|
||||||
if ( playback_ds )
|
if ( playback_ds )
|
||||||
{
|
{
|
||||||
|
@ -111,7 +111,6 @@ Track::configure_outputs ( int n )
|
||||||
if ( output.size() )
|
if ( output.size() )
|
||||||
playback_ds = new Playback_DS( this, engine->frame_rate(), engine->nframes(), output.size() );
|
playback_ds = new Playback_DS( this, engine->frame_rate(), engine->nframes(), output.size() );
|
||||||
|
|
||||||
// engine->unlock();
|
|
||||||
/* FIXME: bogus */
|
/* FIXME: bogus */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -124,6 +123,8 @@ Track::configure_inputs ( int n )
|
||||||
if ( n == on )
|
if ( n == on )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
DMESSAGE( "Reconfiguring inputs for track %s", name() );
|
||||||
|
|
||||||
// engine->lock();
|
// engine->lock();
|
||||||
|
|
||||||
if ( record_ds )
|
if ( record_ds )
|
||||||
|
|
|
@ -204,7 +204,9 @@ Project::close ( void )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
timeline->wrlock();
|
timeline->wrlock();
|
||||||
|
|
||||||
Loggable::close();
|
Loggable::close();
|
||||||
|
|
||||||
timeline->unlock();
|
timeline->unlock();
|
||||||
|
|
||||||
// write_info();
|
// write_info();
|
||||||
|
@ -311,13 +313,11 @@ Project::open ( const char *name )
|
||||||
if ( ! engine )
|
if ( ! engine )
|
||||||
make_engine();
|
make_engine();
|
||||||
|
|
||||||
timeline->wrlock();
|
|
||||||
{
|
{
|
||||||
Block_Timer timer( "Replayed journal" );
|
Block_Timer timer( "Replayed journal" );
|
||||||
if ( ! Loggable::open( "history" ) )
|
if ( ! Loggable::open( "history" ) )
|
||||||
return E_INVALID;
|
return E_INVALID;
|
||||||
}
|
}
|
||||||
timeline->unlock();
|
|
||||||
|
|
||||||
/* /\* really a good idea? *\/ */
|
/* /\* really a good idea? *\/ */
|
||||||
/* timeline->sample_rate( rate ); */
|
/* timeline->sample_rate( rate ); */
|
||||||
|
|
|
@ -76,14 +76,14 @@ Sequence::~Sequence ( )
|
||||||
{
|
{
|
||||||
DMESSAGE( "destroying sequence" );
|
DMESSAGE( "destroying sequence" );
|
||||||
|
|
||||||
if ( _name )
|
|
||||||
free( _name );
|
|
||||||
|
|
||||||
if ( _widgets.size() )
|
if ( _widgets.size() )
|
||||||
FATAL( "programming error: leaf destructor must call Sequence::clear()!" );
|
FATAL( "programming error: leaf destructor must call Sequence::clear()!" );
|
||||||
|
|
||||||
if ( parent() )
|
if ( parent() )
|
||||||
parent()->remove( this );
|
parent()->remove( this );
|
||||||
|
|
||||||
|
if ( _name )
|
||||||
|
free( _name );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -155,10 +155,10 @@ void
|
||||||
Sequence::handle_widget_change ( nframes_t start, nframes_t length )
|
Sequence::handle_widget_change ( nframes_t start, nframes_t length )
|
||||||
{
|
{
|
||||||
/* this might be invoked from Capture or GUI thread */
|
/* this might be invoked from Capture or GUI thread */
|
||||||
Fl::lock();
|
// Fl::lock();
|
||||||
sort();
|
sort();
|
||||||
timeline->damage_sequence();
|
timeline->damage_sequence();
|
||||||
Fl::unlock();
|
// Fl::unlock();
|
||||||
|
|
||||||
// timeline->update_length( start + length );
|
// timeline->update_length( start + length );
|
||||||
}
|
}
|
||||||
|
@ -211,7 +211,6 @@ Sequence::remove ( Sequence_Widget *r )
|
||||||
_widgets.remove( r );
|
_widgets.remove( r );
|
||||||
|
|
||||||
handle_widget_change( r->start(), r->length() );
|
handle_widget_change( r->start(), r->length() );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static nframes_t
|
static nframes_t
|
||||||
|
@ -400,9 +399,7 @@ Sequence::handle ( int m )
|
||||||
/* accept objects dragged from other sequences of this type */
|
/* accept objects dragged from other sequences of this type */
|
||||||
|
|
||||||
timeline->wrlock();
|
timeline->wrlock();
|
||||||
|
|
||||||
add( Sequence_Widget::pushed() );
|
add( Sequence_Widget::pushed() );
|
||||||
|
|
||||||
timeline->unlock();
|
timeline->unlock();
|
||||||
|
|
||||||
damage( FL_DAMAGE_USER1 );
|
damage( FL_DAMAGE_USER1 );
|
||||||
|
@ -487,7 +484,6 @@ Sequence::handle ( int m )
|
||||||
Loggable::block_start();
|
Loggable::block_start();
|
||||||
|
|
||||||
timeline->wrlock();
|
timeline->wrlock();
|
||||||
|
|
||||||
while ( _delete_queue.size() )
|
while ( _delete_queue.size() )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -504,7 +500,6 @@ Sequence::handle ( int m )
|
||||||
|
|
||||||
delete t;
|
delete t;
|
||||||
}
|
}
|
||||||
|
|
||||||
timeline->unlock();
|
timeline->unlock();
|
||||||
|
|
||||||
Loggable::block_end();
|
Loggable::block_end();
|
||||||
|
|
|
@ -168,7 +168,7 @@ Sequence_Widget::begin_drag ( const Drag &d )
|
||||||
{
|
{
|
||||||
_drag = new Drag( d );
|
_drag = new Drag( d );
|
||||||
|
|
||||||
timeline->rdlock();
|
timeline->wrlock();
|
||||||
|
|
||||||
/* copy current values */
|
/* copy current values */
|
||||||
|
|
||||||
|
@ -400,9 +400,7 @@ Sequence_Widget::handle ( int m )
|
||||||
/* deletion */
|
/* deletion */
|
||||||
if ( test_press( FL_BUTTON3 + FL_CTRL ) )
|
if ( test_press( FL_BUTTON3 + FL_CTRL ) )
|
||||||
{
|
{
|
||||||
timeline->wrlock();
|
|
||||||
remove();
|
remove();
|
||||||
timeline->unlock();
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -444,7 +442,9 @@ Sequence_Widget::handle ( int m )
|
||||||
if ( test_press( FL_BUTTON1 + FL_CTRL ) && ! _drag->state )
|
if ( test_press( FL_BUTTON1 + FL_CTRL ) && ! _drag->state )
|
||||||
{
|
{
|
||||||
/* duplication */
|
/* duplication */
|
||||||
|
timeline->wrlock();
|
||||||
sequence()->add( this->clone() );
|
sequence()->add( this->clone() );
|
||||||
|
timeline->unlock();
|
||||||
|
|
||||||
_drag->state = 1;
|
_drag->state = 1;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
#include "Annotation_Sequence.H"
|
#include "Annotation_Sequence.H"
|
||||||
#include "Track.H"
|
#include "Track.H"
|
||||||
#include "Transport.H"
|
#include "Transport.H"
|
||||||
#include "Engine/Engine.H" // for lock()
|
|
||||||
|
|
||||||
#include "FL/menu_popup.H"
|
#include "FL/menu_popup.H"
|
||||||
|
|
||||||
|
@ -362,6 +361,10 @@ Timeline::range ( nframes_t start, nframes_t length )
|
||||||
void
|
void
|
||||||
Timeline::add_take_for_armed_tracks ( void )
|
Timeline::add_take_for_armed_tracks ( void )
|
||||||
{
|
{
|
||||||
|
THREAD_ASSERT( UI );
|
||||||
|
|
||||||
|
wrlock();
|
||||||
|
|
||||||
for ( int i = tracks->children(); i-- ; )
|
for ( int i = tracks->children(); i-- ; )
|
||||||
{
|
{
|
||||||
Track *t = (Track*)tracks->child( i );
|
Track *t = (Track*)tracks->child( i );
|
||||||
|
@ -369,6 +372,8 @@ Timeline::add_take_for_armed_tracks ( void )
|
||||||
if ( t->armed() && t->sequence()->_widgets.size() )
|
if ( t->armed() && t->sequence()->_widgets.size() )
|
||||||
t->sequence( new Audio_Sequence( t ) );
|
t->sequence( new Audio_Sequence( t ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -938,10 +943,12 @@ Timeline::draw_measure_cb ( nframes_t frame, const BBT &bbt, void *v )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( bbt.beat )
|
if ( bbt.beat )
|
||||||
|
{
|
||||||
if ( o->panzoomer->zoom() > 12 )
|
if ( o->panzoomer->zoom() > 12 )
|
||||||
return;
|
return;
|
||||||
else
|
else
|
||||||
c = FL_DARK1;
|
c = FL_DARK1;
|
||||||
|
}
|
||||||
|
|
||||||
fl_color( fl_color_add_alpha( c, 64 ) );
|
fl_color( fl_color_add_alpha( c, 64 ) );
|
||||||
|
|
||||||
|
@ -1246,6 +1253,8 @@ Timeline::draw_cursors ( void ) const
|
||||||
void
|
void
|
||||||
Timeline::draw ( void )
|
Timeline::draw ( void )
|
||||||
{
|
{
|
||||||
|
THREAD_ASSERT( UI );
|
||||||
|
|
||||||
int X, Y, W, H;
|
int X, Y, W, H;
|
||||||
|
|
||||||
int bdx = 0;
|
int bdx = 0;
|
||||||
|
@ -1869,14 +1878,10 @@ Timeline::add_track ( Track *track )
|
||||||
{
|
{
|
||||||
DMESSAGE( "added new track to the timeline" );
|
DMESSAGE( "added new track to the timeline" );
|
||||||
|
|
||||||
engine->lock();
|
|
||||||
|
|
||||||
tracks->add( track );
|
tracks->add( track );
|
||||||
|
|
||||||
// update_track_order();
|
// update_track_order();
|
||||||
|
|
||||||
engine->unlock();
|
|
||||||
|
|
||||||
/* FIXME: why is this necessary? doesn't the above add do DAMAGE_CHILD? */
|
/* FIXME: why is this necessary? doesn't the above add do DAMAGE_CHILD? */
|
||||||
redraw();
|
redraw();
|
||||||
|
|
||||||
|
@ -1888,16 +1893,12 @@ Timeline::insert_track ( Track *track, int n )
|
||||||
if ( n > tracks->children() || n < 0 )
|
if ( n > tracks->children() || n < 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
engine->lock();
|
|
||||||
|
|
||||||
tracks->insert( *track, n );
|
tracks->insert( *track, n );
|
||||||
|
|
||||||
update_track_order();
|
update_track_order();
|
||||||
|
|
||||||
tracks->redraw();
|
tracks->redraw();
|
||||||
|
|
||||||
engine->unlock();
|
|
||||||
|
|
||||||
/* FIXME: why is this necessary? doesn't the above add do DAMAGE_CHILD? */
|
/* FIXME: why is this necessary? doesn't the above add do DAMAGE_CHILD? */
|
||||||
// redraw();
|
// redraw();
|
||||||
}
|
}
|
||||||
|
@ -1912,7 +1913,7 @@ compare_tracks ( Track *a, Track *b )
|
||||||
void
|
void
|
||||||
Timeline::apply_track_order ( void )
|
Timeline::apply_track_order ( void )
|
||||||
{
|
{
|
||||||
engine->lock();
|
/* wrlock(); */
|
||||||
|
|
||||||
std::list<Track*> tl;
|
std::list<Track*> tl;
|
||||||
|
|
||||||
|
@ -1931,7 +1932,7 @@ Timeline::apply_track_order ( void )
|
||||||
|
|
||||||
update_track_order();
|
update_track_order();
|
||||||
|
|
||||||
engine->unlock();
|
/* unlock(); */
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1947,17 +1948,6 @@ Timeline::find_track ( const Track *track ) const
|
||||||
return tracks->find( *track );
|
return tracks->find( *track );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Timeline::move_track_up ( Track *track )
|
|
||||||
{
|
|
||||||
insert_track( track, find_track( track ) - 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Timeline::move_track_down ( Track *track )
|
|
||||||
{
|
|
||||||
insert_track( track, find_track( track ) + 2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/** remove /track/ from the timeline */
|
/** remove /track/ from the timeline */
|
||||||
void
|
void
|
||||||
|
@ -1965,15 +1955,11 @@ Timeline::remove_track ( Track *track )
|
||||||
{
|
{
|
||||||
DMESSAGE( "removed track from the timeline" );
|
DMESSAGE( "removed track from the timeline" );
|
||||||
|
|
||||||
engine->lock();
|
|
||||||
|
|
||||||
/* FIXME: what to do about track contents? */
|
/* FIXME: what to do about track contents? */
|
||||||
tracks->remove( track );
|
tracks->remove( track );
|
||||||
|
|
||||||
update_track_order();
|
update_track_order();
|
||||||
|
|
||||||
engine->unlock();
|
|
||||||
|
|
||||||
/* FIXME: why is this necessary? doesn't the above add do DAMAGE_CHILD? */
|
/* FIXME: why is this necessary? doesn't the above add do DAMAGE_CHILD? */
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
|
@ -1982,6 +1968,30 @@ Timeline::remove_track ( Track *track )
|
||||||
/* Commands */
|
/* Commands */
|
||||||
/************/
|
/************/
|
||||||
|
|
||||||
|
void
|
||||||
|
Timeline::command_move_track_up ( Track *track )
|
||||||
|
{
|
||||||
|
wrlock();
|
||||||
|
insert_track( track, find_track( track ) - 1 );
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Timeline::command_move_track_down ( Track *track )
|
||||||
|
{
|
||||||
|
wrlock();
|
||||||
|
insert_track( track, find_track( track ) + 2 );
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Timeline::command_remove_track ( Track *track )
|
||||||
|
{
|
||||||
|
wrlock();
|
||||||
|
remove_track(track);
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Timeline::command_quit ( )
|
Timeline::command_quit ( )
|
||||||
{
|
{
|
||||||
|
@ -1998,7 +2008,9 @@ Timeline::command_load ( const char *name, const char *display_name )
|
||||||
if ( ! name )
|
if ( ! name )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
wrlock();
|
||||||
int r = Project::open( name );
|
int r = Project::open( name );
|
||||||
|
unlock();
|
||||||
|
|
||||||
if ( r < 0 )
|
if ( r < 0 )
|
||||||
{
|
{
|
||||||
|
@ -2145,7 +2157,7 @@ Timeline::handle_peer_scan_complete ( void *o )
|
||||||
void
|
void
|
||||||
Timeline::connect_osc ( void )
|
Timeline::connect_osc ( void )
|
||||||
{
|
{
|
||||||
wrlock();
|
// rdlock();
|
||||||
|
|
||||||
/* try to (re)connect OSC signals */
|
/* try to (re)connect OSC signals */
|
||||||
for ( int i = tracks->children(); i-- ; )
|
for ( int i = tracks->children(); i-- ; )
|
||||||
|
@ -2155,7 +2167,7 @@ Timeline::connect_osc ( void )
|
||||||
t->connect_osc();
|
t->connect_osc();
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock();
|
// unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2183,7 +2195,6 @@ Timeline::process_osc ( void )
|
||||||
{
|
{
|
||||||
THREAD_ASSERT( OSC );
|
THREAD_ASSERT( OSC );
|
||||||
|
|
||||||
/* FIXME: is holding this lock a problem for recording? */
|
|
||||||
rdlock();
|
rdlock();
|
||||||
|
|
||||||
/* reconnect OSC signals */
|
/* reconnect OSC signals */
|
||||||
|
|
|
@ -57,6 +57,8 @@ class Cursor_Point;
|
||||||
class Fl_Panzoomer;
|
class Fl_Panzoomer;
|
||||||
class Fl_Tile;
|
class Fl_Tile;
|
||||||
|
|
||||||
|
#include "RWLock.H"
|
||||||
|
|
||||||
namespace OSC { class Endpoint; }
|
namespace OSC { class Endpoint; }
|
||||||
|
|
||||||
#define USE_WIDGET_FOR_TIMELINE
|
#define USE_WIDGET_FOR_TIMELINE
|
||||||
|
@ -83,7 +85,6 @@ struct Rectangle
|
||||||
Rectangle ( int X, int Y, int W, int H ) : x( X ), y( Y ), w( W ), h( H ) {}
|
Rectangle ( int X, int Y, int W, int H ) : x( X ), y( Y ), w( W ), h( H ) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "RWLock.H"
|
|
||||||
|
|
||||||
#ifdef USE_WIDGET_FOR_TIMELINE
|
#ifdef USE_WIDGET_FOR_TIMELINE
|
||||||
class Timeline : public Fl_Group, public RWLock
|
class Timeline : public Fl_Group, public RWLock
|
||||||
|
@ -252,9 +253,10 @@ public:
|
||||||
|
|
||||||
void add_track ( Track *track );
|
void add_track ( Track *track );
|
||||||
void remove_track ( Track *track );
|
void remove_track ( Track *track );
|
||||||
|
void command_remove_track ( Track *track );
|
||||||
|
|
||||||
void move_track_up ( Track *track );
|
void command_move_track_up ( Track *track );
|
||||||
void move_track_down ( Track *track );
|
void command_move_track_down ( Track *track );
|
||||||
|
|
||||||
int find_track ( const Track * track ) const;
|
int find_track ( const Track * track ) const;
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,6 @@
|
||||||
#include "FL/Fl_Scalepack.H"
|
#include "FL/Fl_Scalepack.H"
|
||||||
#include "FL/Fl_Blink_Button.H"
|
#include "FL/Fl_Blink_Button.H"
|
||||||
|
|
||||||
#include "Engine/Engine.H" // for lock()
|
|
||||||
|
|
||||||
#include "Control_Sequence.H"
|
#include "Control_Sequence.H"
|
||||||
#include "Annotation_Sequence.H"
|
#include "Annotation_Sequence.H"
|
||||||
|
|
||||||
|
@ -639,12 +637,8 @@ Track::remove ( Control_Sequence *t )
|
||||||
if ( ! control )
|
if ( ! control )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
engine->lock();
|
|
||||||
|
|
||||||
control->remove( t );
|
control->remove( t );
|
||||||
|
|
||||||
engine->unlock();
|
|
||||||
|
|
||||||
adjust_size();
|
adjust_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -681,8 +675,6 @@ Track::add ( Control_Sequence *t )
|
||||||
{
|
{
|
||||||
DMESSAGE( "adding control sequence" );
|
DMESSAGE( "adding control sequence" );
|
||||||
|
|
||||||
engine->lock();
|
|
||||||
|
|
||||||
t->track( this );
|
t->track( this );
|
||||||
|
|
||||||
t->color( random_color() );
|
t->color( random_color() );
|
||||||
|
@ -690,8 +682,6 @@ Track::add ( Control_Sequence *t )
|
||||||
// control->insert( *t, 0 );
|
// control->insert( *t, 0 );
|
||||||
control->add( t );
|
control->add( t );
|
||||||
|
|
||||||
engine->unlock();
|
|
||||||
|
|
||||||
adjust_size();
|
adjust_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -741,6 +731,16 @@ Track::menu_cb ( Fl_Widget *w, void *v )
|
||||||
((Track*)v)->menu_cb( (Fl_Menu_*) w );
|
((Track*)v)->menu_cb( (Fl_Menu_*) w );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Track::command_configure_channels ( int n )
|
||||||
|
{
|
||||||
|
/* due to locking this should only be invoked by direct user action */
|
||||||
|
timeline->wrlock();
|
||||||
|
configure_inputs( n );
|
||||||
|
configure_outputs( n );
|
||||||
|
timeline->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Track::menu_cb ( const Fl_Menu_ *m )
|
Track::menu_cb ( const Fl_Menu_ *m )
|
||||||
{
|
{
|
||||||
|
@ -754,18 +754,15 @@ Track::menu_cb ( const Fl_Menu_ *m )
|
||||||
|
|
||||||
if ( ! strcmp( picked, "Type/Mono" ) )
|
if ( ! strcmp( picked, "Type/Mono" ) )
|
||||||
{
|
{
|
||||||
configure_inputs( 1 );
|
command_configure_channels( 1 );
|
||||||
configure_outputs( 1 );
|
|
||||||
}
|
}
|
||||||
else if ( ! strcmp( picked, "Type/Stereo" ) )
|
else if ( ! strcmp( picked, "Type/Stereo" ) )
|
||||||
{
|
{
|
||||||
configure_inputs( 2 );
|
command_configure_channels( 2 );
|
||||||
configure_outputs( 2 );
|
|
||||||
}
|
}
|
||||||
else if ( ! strcmp( picked, "Type/Quad" ) )
|
else if ( ! strcmp( picked, "Type/Quad" ) )
|
||||||
{
|
{
|
||||||
configure_inputs( 4 );
|
command_configure_channels( 4 );
|
||||||
configure_outputs( 4 );
|
|
||||||
}
|
}
|
||||||
else if ( ! strcmp( picked, "Type/..." ) )
|
else if ( ! strcmp( picked, "Type/..." ) )
|
||||||
{
|
{
|
||||||
|
@ -779,8 +776,7 @@ Track::menu_cb ( const Fl_Menu_ *m )
|
||||||
fl_alert( "Invalid number of channels." );
|
fl_alert( "Invalid number of channels." );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
configure_inputs( c );
|
command_configure_channels(c);
|
||||||
configure_outputs( c );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -789,7 +785,9 @@ Track::menu_cb ( const Fl_Menu_ *m )
|
||||||
/* add audio track */
|
/* add audio track */
|
||||||
char *name = get_unique_control_name( "Control" );
|
char *name = get_unique_control_name( "Control" );
|
||||||
|
|
||||||
|
timeline->wrlock();
|
||||||
new Control_Sequence( this, name );
|
new Control_Sequence( this, name );
|
||||||
|
timeline->unlock();
|
||||||
}
|
}
|
||||||
else if ( ! strcmp( picked, "/Overlay controls" ) )
|
else if ( ! strcmp( picked, "/Overlay controls" ) )
|
||||||
{
|
{
|
||||||
|
@ -846,8 +844,8 @@ Track::menu_cb ( const Fl_Menu_ *m )
|
||||||
|
|
||||||
if ( r == 2 )
|
if ( r == 2 )
|
||||||
{
|
{
|
||||||
timeline->remove_track( this );
|
timeline->command_remove_track( this );
|
||||||
Fl::delete_widget( this );
|
Fl::delete_widget( this );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( ! strcmp( picked, "/Rename" ) )
|
else if ( ! strcmp( picked, "/Rename" ) )
|
||||||
|
@ -856,11 +854,11 @@ Track::menu_cb ( const Fl_Menu_ *m )
|
||||||
}
|
}
|
||||||
else if ( ! strcmp( picked, "/Move Up" ) )
|
else if ( ! strcmp( picked, "/Move Up" ) )
|
||||||
{
|
{
|
||||||
timeline->move_track_up( this );
|
timeline->command_move_track_up( this );
|
||||||
}
|
}
|
||||||
else if ( ! strcmp( picked, "/Move Down" ) )
|
else if ( ! strcmp( picked, "/Move Down" ) )
|
||||||
{
|
{
|
||||||
timeline->move_track_down( this );
|
timeline->command_move_track_down( this );
|
||||||
}
|
}
|
||||||
else if ( !strcmp( picked, "Takes/Show all takes" ) )
|
else if ( !strcmp( picked, "Takes/Show all takes" ) )
|
||||||
{
|
{
|
||||||
|
@ -868,7 +866,9 @@ Track::menu_cb ( const Fl_Menu_ *m )
|
||||||
}
|
}
|
||||||
else if ( !strcmp( picked, "Takes/New" ) )
|
else if ( !strcmp( picked, "Takes/New" ) )
|
||||||
{
|
{
|
||||||
|
timeline->wrlock();
|
||||||
sequence( (Audio_Sequence*)sequence()->clone_empty() );
|
sequence( (Audio_Sequence*)sequence()->clone_empty() );
|
||||||
|
timeline->unlock();
|
||||||
}
|
}
|
||||||
else if ( !strcmp( picked, "Takes/Remove" ) )
|
else if ( !strcmp( picked, "Takes/Remove" ) )
|
||||||
{
|
{
|
||||||
|
@ -876,12 +876,16 @@ Track::menu_cb ( const Fl_Menu_ *m )
|
||||||
{
|
{
|
||||||
Loggable::block_start();
|
Loggable::block_start();
|
||||||
|
|
||||||
|
timeline->wrlock();
|
||||||
|
|
||||||
Audio_Sequence *s = sequence();
|
Audio_Sequence *s = sequence();
|
||||||
|
|
||||||
sequence( (Audio_Sequence*)takes->child( 0 ) );
|
sequence( (Audio_Sequence*)takes->child( 0 ) );
|
||||||
|
|
||||||
delete s;
|
delete s;
|
||||||
|
|
||||||
|
timeline->unlock();
|
||||||
|
|
||||||
Loggable::block_end();
|
Loggable::block_end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -900,7 +904,9 @@ Track::menu_cb ( const Fl_Menu_ *m )
|
||||||
{
|
{
|
||||||
Audio_Sequence* s = (Audio_Sequence*)m->mvalue()->user_data();
|
Audio_Sequence* s = (Audio_Sequence*)m->mvalue()->user_data();
|
||||||
|
|
||||||
|
timeline->wrlock();
|
||||||
sequence( s );
|
sequence( s );
|
||||||
|
timeline->unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,7 @@ private:
|
||||||
|
|
||||||
bool configure_outputs ( int n );
|
bool configure_outputs ( int n );
|
||||||
bool configure_inputs ( int n );
|
bool configure_inputs ( int n );
|
||||||
|
void command_configure_channels ( int n );
|
||||||
|
|
||||||
void update_port_names ( void );
|
void update_port_names ( void );
|
||||||
const char *name_for_port( JACK::Port::type_e type, int n );
|
const char *name_for_port( JACK::Port::type_e type, int n );
|
||||||
|
|
Loading…
Reference in New Issue