@@ -95,8 +95,10 @@ Engine::freewheel ( bool starting ) | |||||
{ | { | ||||
_freewheeling = starting; | _freewheeling = starting; | ||||
if ( _freewheeling ) | |||||
FATAL( "Freewheeling mode is unimplemented" ); | |||||
if ( starting ) | |||||
DMESSAGE( "entering freewheeling mode" ); | |||||
else | |||||
DMESSAGE( "leaving freewheeling mode" ); | |||||
} | } | ||||
/* THREAD: RT */ | /* THREAD: RT */ | ||||
@@ -174,29 +176,38 @@ Engine::process ( nframes_t nframes ) | |||||
{ | { | ||||
transport->poll(); | transport->poll(); | ||||
if ( ! trylock() ) | |||||
if ( freewheeling() ) | |||||
{ | { | ||||
/* the data structures we need to access here (tracks and | |||||
* their ports, but not track contents) may be in an | |||||
* inconsistent state at the moment. Just punt and drop this | |||||
* buffer. */ | |||||
++_buffers_dropped; | |||||
return 0; | |||||
/* freewheeling mode/export. We're actually running | |||||
non-RT. Assume that everything is quiescent, locking is | |||||
unecessary and do I/O synchronously */ | |||||
if ( timeline ) | |||||
timeline->process( nframes ); | |||||
/* because we're going faster than realtime. */ | |||||
timeline->wait_for_buffers(); | |||||
} | } | ||||
else | |||||
{ | |||||
if ( ! trylock() ) | |||||
{ | |||||
/* the data structures we need to access here (tracks and | |||||
* their ports, but not track contents) may be in an | |||||
* inconsistent state at the moment. Just punt and drop this | |||||
* buffer. */ | |||||
++_buffers_dropped; | |||||
return 0; | |||||
} | |||||
/* if ( ! transport->rolling ) */ | |||||
/* timeline->silence( nframes ); */ | |||||
/* return 0; */ | |||||
/* handle chicken/egg problem */ | |||||
if ( timeline ) | |||||
/* this will initiate the process() call graph for the various | |||||
* number and types of tracks, which will in turn send data out | |||||
* the appropriate ports. */ | |||||
timeline->process( nframes ); | |||||
/* handle chicken/egg problem */ | |||||
if ( timeline ) | |||||
/* this will initiate the process() call graph for the various | |||||
* number and types of tracks, which will in turn send data out | |||||
* the appropriate ports. */ | |||||
timeline->process( nframes ); | |||||
unlock(); | |||||
unlock(); | |||||
} | |||||
return 0; | return 0; | ||||
} | } | ||||
@@ -79,7 +79,7 @@ public: | |||||
nframes_t sample_rate ( void ) const { return _sample_rate; } | nframes_t sample_rate ( void ) const { return _sample_rate; } | ||||
int xruns ( void ) const { return _xruns; }; | int xruns ( void ) const { return _xruns; }; | ||||
int dropped ( void ) const { return _buffers_dropped; } | int dropped ( void ) const { return _buffers_dropped; } | ||||
bool freehweeling ( void ) const { return _freewheeling; } | |||||
bool freewheeling ( void ) const { return _freewheeling; } | |||||
void freewheeling ( bool yes ); | void freewheeling ( bool yes ); | ||||
float cpu_load ( void ) const { return jack_cpu_load( _client ); } | float cpu_load ( void ) const { return jack_cpu_load( _client ); } | ||||
@@ -1284,6 +1284,15 @@ Timeline::total_output_buffer_percent ( void ) | |||||
return r / cnt; | return r / cnt; | ||||
} | } | ||||
/** wait for I/O threads to fill their buffers */ | |||||
void | |||||
Timeline::wait_for_buffers ( void ) | |||||
{ | |||||
while ( total_output_buffer_percent() + total_input_buffer_percent() < 200 ) | |||||
usleep( 5000 ); | |||||
} | |||||
int | int | ||||
Timeline::total_playback_xruns ( void ) | Timeline::total_playback_xruns ( void ) | ||||
{ | { | ||||
@@ -183,6 +183,14 @@ public: | |||||
void add_track ( Track *track ); | void add_track ( Track *track ); | ||||
void remove_track ( Track *track ); | void remove_track ( Track *track ); | ||||
void zoom ( float secs ); | |||||
void zoom_in ( void ); | |||||
void zoom_out ( void ); | |||||
void zoom_fit ( void ); | |||||
/* Engine */ | |||||
int total_input_buffer_percent ( void ); | int total_input_buffer_percent ( void ); | ||||
int total_output_buffer_percent ( void ); | int total_output_buffer_percent ( void ); | ||||
@@ -192,11 +200,7 @@ public: | |||||
bool record ( void ); | bool record ( void ); | ||||
void stop ( void ); | void stop ( void ); | ||||
void zoom ( float secs ); | |||||
void zoom_in ( void ); | |||||
void zoom_out ( void ); | |||||
void zoom_fit ( void ); | |||||
void wait_for_buffers ( void ); | |||||
private: | private: | ||||