21 #include "JackTransportEngine.h"    22 #include "JackClientInterface.h"    23 #include "JackClientControl.h"    24 #include "JackEngineControl.h"    25 #include "JackGlobals.h"    26 #include "JackError.h"    37 JackTransportEngine::JackTransportEngine(): JackAtomicArrayState<
jack_position_t>()
    39     fTransportState = JackTransportStopped;
    40     fTransportCmd = fPreviousCmd = TransportCommandStop;
    41     fSyncTimeout = 10000000;    
    46     fConditionnal = 
false;
    52 void JackTransportEngine::SyncTimeout(jack_nframes_t frame_rate, jack_nframes_t buffer_size)
    54     long buf_usecs = (long)((buffer_size * (jack_time_t)1000000) / frame_rate);
    55     fSyncTimeLeft = fSyncTimeout / buf_usecs;
    56     jack_log(
"SyncTimeout fSyncTimeout = %ld fSyncTimeLeft = %ld", (
long)fSyncTimeout, (
long)fSyncTimeLeft);
    60 int JackTransportEngine::ResetTimebase(
int refnum)
    62     if (fTimeBaseMaster == refnum) {
    64         request->
valid = (jack_position_bits_t)0;
    74 int JackTransportEngine::SetTimebaseMaster(
int refnum, 
bool conditionnal)
    76     if (conditionnal && fTimeBaseMaster > 0) {
    77         if (refnum != fTimeBaseMaster) {
    78             jack_log(
"conditional timebase for ref = %ld failed: %ld is already the master", refnum, fTimeBaseMaster);
    81             jack_log(
"ref = %ld was already timebase master", refnum);
    85         fTimeBaseMaster = refnum;
    86         fConditionnal = conditionnal;
    87         jack_log(
"new timebase master: ref = %ld", refnum);
    93 bool JackTransportEngine::CheckAllRolling(JackClientInterface** table)
    95     for (
int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) {
    96         JackClientInterface* client = table[i];
    97         if (client && client->GetClientControl()->fTransportState != JackTransportRolling) {
    98             jack_log(
"CheckAllRolling ref = %ld is not rolling", i);
   107 void JackTransportEngine::MakeAllStartingLocating(JackClientInterface** table)
   109     for (
int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) {
   110         JackClientInterface* client = table[i];
   112             JackClientControl* control = client->GetClientControl();
   114             control->fTransportState = (control->fActive && control->fCallback[kRealTimeCallback]) ? JackTransportStarting : JackTransportRolling;
   115             control->fTransportSync = 
true;
   116             control->fTransportTimebase = 
true;
   117             jack_log(
"MakeAllStartingLocating ref = %ld", i);
   123 void JackTransportEngine::MakeAllStopping(JackClientInterface** table)
   125     for (
int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) {
   126         JackClientInterface* client = table[i];
   128             JackClientControl* control = client->GetClientControl();
   129             control->fTransportState = JackTransportStopped;
   130             control->fTransportSync = 
false;
   131             control->fTransportTimebase = 
false;
   132             jack_log(
"MakeAllStopping ref = %ld", i);
   138 void JackTransportEngine::MakeAllLocating(JackClientInterface** table)
   140     for (
int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) {
   141         JackClientInterface* client = table[i];
   143             JackClientControl* control = client->GetClientControl();
   144             control->fTransportState = JackTransportStopped;
   145             control->fTransportSync = 
true;
   146             control->fTransportTimebase = 
true;
   147             jack_log(
"MakeAllLocating ref = %ld", i);
   153 void JackTransportEngine::CycleBegin(jack_nframes_t frame_rate, jack_time_t time)
   156     pending->
usecs = time;
   162 void JackTransportEngine::CycleEnd(JackClientInterface** table, jack_nframes_t frame_rate, jack_nframes_t buffer_size)
   167     transport_command_t cmd = fTransportCmd;
   168     if (cmd != fPreviousCmd) {
   170         jack_log(
"transport command: %s", (cmd == TransportCommandStart ? 
"Transport start" : 
"Transport stop"));
   172         cmd = TransportCommandNone;
   176     switch (fTransportState) {
   178         case JackTransportStopped:
   180             if (cmd == TransportCommandStart) {
   182                 fTransportState = JackTransportStarting;
   183                 MakeAllStartingLocating(table);
   184                 SyncTimeout(frame_rate, buffer_size);
   185             } 
else if (fPendingPos) {
   187                 MakeAllLocating(table);
   191         case JackTransportStarting:
   192             if (cmd == TransportCommandStop) {
   194                 fTransportState = JackTransportStopped;
   195                 MakeAllStopping(table);
   196             } 
else if (fPendingPos) {
   198                 fTransportState = JackTransportStarting;
   199                 MakeAllStartingLocating(table);
   200                 SyncTimeout(frame_rate, buffer_size);
   201             } 
else if (--fSyncTimeLeft == 0 || CheckAllRolling(table)) {  
   203                     jack_log(
"transport starting ==> netstarting frame = %d");
   204                     fTransportState = JackTransportNetStarting;
   206                     jack_log(
"transport starting ==> rolling fSyncTimeLeft = %ld", fSyncTimeLeft);
   207                     fTransportState = JackTransportRolling;
   212         case JackTransportRolling:
   213             if (cmd == TransportCommandStop) {
   214                 jack_log(
"transport rolling ==> stopped");
   215                 fTransportState = JackTransportStopped;
   216                 MakeAllStopping(table);
   217             } 
else if (fPendingPos) {
   218                 jack_log(
"transport rolling ==> starting");
   219                 fTransportState = JackTransportStarting;
   220                 MakeAllStartingLocating(table);
   221                 SyncTimeout(frame_rate, buffer_size);
   225         case JackTransportNetStarting:
   229             jack_error(
"Invalid JACK transport state: %d", fTransportState);
   233     if (fTransportState == JackTransportRolling) {
   235         pending->
frame += buffer_size;
   244         CopyPosition(request, pending);
   255         cur_index = next_index;
   258     } 
while (cur_index != next_index); 
   265     CopyPosition(pos, request);
   270 jack_transport_state_t JackTransportEngine::Query(
jack_position_t* pos)
   277 jack_nframes_t JackTransportEngine::GetCurrentFrame()
   280     ReadCurrentPos(&pos);
   282     if (fTransportState == JackTransportRolling) {
   283         float usecs = GetMicroSeconds() - pos.
usecs;
   284         jack_nframes_t elapsed = (jack_nframes_t)floor((((
float) pos.
frame_rate) / 1000000.0f) * usecs);
   285         return pos.
frame + elapsed;
   307             if (--timeout == 0) {
   308                 jack_error(
"hung in loop copying position B");
 
UInt16 GetCurrentIndex()
Returns the current switch counter.
SERVER_EXPORT void jack_error(const char *fmt,...)
jack_position_bits_t valid
jack_position_t * ReadCurrentState()
Returns the current state : only valid in the RT reader thread.
jack_nframes_t frame_rate
jack_position_t * TrySwitchState(int state)
Tries to switch to the next state and returns the new current state (either the same as before if cas...
void WriteNextStateStop(int state)
Stop write operation : make the next state ready to be used by the RT thread.
jack_position_t * WriteNextStateStart(int state)
Start write operation : setup and returns the next state to update, check for recursive write calls.
SERVER_EXPORT void jack_log(const char *fmt,...)