// RT, client void JackTransportEngine::CopyPosition(jack_position_t* from, jack_position_t* to) { int tries = 0; long timeout = 1000; do { /* throttle the busy wait if we don't get the answer * very quickly. See comment above about this * design. */ if (tries > 10) { JackSleep(20); tries = 0; /* debug code to avoid system hangs... */ if (--timeout == 0) { jack_error("hung in loop copying position B"); abort(); } } *to = *from; tries++; } while (to->unique_1 != to->unique_2); }
int JackAndroidThread::StartSync() { fStatus = kStarting; if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) { fStatus = kIdle; return -1; } else { int count = 0; while (fStatus == kStarting && ++count < 1000) { JackSleep(1000); } return (count == 1000) ? -1 : 0; } }
void JackDriver::LoadConnections(int alias, bool full_name) { list<pair<string, pair<string, string> > >::const_iterator it; if (full_name) { for (it = fConnections.begin(); it != fConnections.end(); it++) { pair<string, string> connection = (*it).second; jack_info("Load connection: %s %s", connection.first.c_str(), connection.second.c_str()); fEngine->PortConnect(fClientControl.fRefNum, connection.first.c_str(), connection.second.c_str()); } } else { const char** inputs = fGraphManager->GetPorts(NULL, NULL, JackPortIsInput); const char** outputs = fGraphManager->GetPorts(NULL, NULL, JackPortIsOutput); for (it = fConnections.begin(); it != fConnections.end(); it++) { pair<string, string> connection = (*it).second; string real_input = MatchPortName(connection.first.c_str(), outputs, alias, (*it).first); string real_output = MatchPortName(connection.second.c_str(), inputs, alias, (*it).first); if ((real_input != "") && (real_output != "")) { jack_info("Load connection: %s %s", real_input.c_str(), real_output.c_str()); fEngine->PortConnect(fClientControl.fRefNum, real_input.c_str(), real_output.c_str()); } } // Wait for connection change if (fGraphManager->IsPendingChange()) { JackSleep(int(fEngineControl->fPeriodUsecs * 1.1f)); } if (inputs) { free(inputs); } if (outputs) { free(outputs); } } }
/* JackProxyDriver is wrapped in a JackWaitCallbackDriver decorator that behaves as a "dummy driver, until Initialize method returns. */ bool JackProxyDriver::Initialize() { jack_log("JackProxyDriver::Initialize"); // save existing local connections if needed if (fAutoSave) { SaveConnections(0); } // new loading, but existing client, restart the driver if (fClient) { jack_info("JackProxyDriver restarting..."); jack_client_close(fClient); } FreePorts(); // display some additional infos jack_info("JackProxyDriver started in %s mode.", (fEngineControl->fSyncMode) ? "sync" : "async"); do { jack_status_t status; char *old = NULL; if (fPromiscuous) { // as we are fiddling with the environment variable content, save it const char* tmp = getenv("JACK_PROMISCUOUS_SERVER"); if (tmp) { old = strdup(tmp); } // temporary enable promiscuous mode if (setenv("JACK_PROMISCUOUS_SERVER", fPromiscuous, 1) < 0) { free(old); jack_error("Error allocating memory."); return false; } } jack_info("JackProxyDriver connecting to %s", fUpstream); fClient = jack_client_open(fClientName, static_cast<jack_options_t>(JackNoStartServer|JackServerName), &status, fUpstream); if (fPromiscuous) { // restore previous environment variable content if (old) { if (setenv("JACK_PROMISCUOUS_SERVER", old, 1) < 0) { free(old); jack_error("Error allocating memory."); return false; } free(old); } else { unsetenv("JACK_PROMISCUOUS_SERVER"); } } // the connection failed, try again later if (!fClient) { JackSleep(1000000); } } while (!fClient); jack_info("JackProxyDriver connected to %s", fUpstream); // we are connected, let's register some callbacks jack_on_shutdown(fClient, shutdown_callback, this); if (jack_set_process_callback(fClient, process_callback, this) != 0) { jack_error("Cannot set process callback."); return false; } if (jack_set_buffer_size_callback(fClient, bufsize_callback, this) != 0) { jack_error("Cannot set buffer size callback."); return false; } if (jack_set_sample_rate_callback(fClient, srate_callback, this) != 0) { jack_error("Cannot set sample rate callback."); return false; } if (jack_set_port_connect_callback(fClient, connect_callback, this) != 0) { jack_error("Cannot set port connect callback."); return false; } // detect upstream physical playback ports if needed if (fDetectPlaybackChannels) { fPlaybackChannels = CountIO(JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsOutput); } // detect upstream physical capture ports if needed if (fDetectCaptureChannels) { fCaptureChannels = CountIO(JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsInput); } if (AllocPorts() != 0) { jack_error("Can't allocate ports."); return false; } bufsize_callback(jack_get_buffer_size(fClient)); srate_callback(jack_get_sample_rate(fClient)); // restore local connections if needed if (fAutoSave) { LoadConnections(0); } // everything is ready, start upstream processing if (jack_activate(fClient) != 0) { jack_error("Cannot activate jack client."); return false; } // connect upstream ports if needed if (fAutoConnect) { ConnectPorts(); } return true; }
int main (int argc, char *argv[]) { ExternalMetro* client1 = NULL; ExternalMetro* client2 = NULL; ExternalMetro* client3 = NULL; ExternalMetro* client4 = NULL; ExternalMetro* client5 = NULL; printf("Testing multiple Jack clients in one process: open 5 metro clients...\n"); client1 = new ExternalMetro(1200, 0.4, 20, 80, "t1"); client2 = new ExternalMetro(600, 0.4, 20, 150, "t2"); client3 = new ExternalMetro(1000, 0.4, 20, 110, "t3"); client4 = new ExternalMetro(400, 0.4, 20, 200, "t4"); client5 = new ExternalMetro(1500, 0.4, 20, 150, "t5"); printf("Type 'c' to close all clients and go to next test...\n"); while ((getchar() != 'c')) { JackSleep(1); }; delete client1; delete client2; delete client3; delete client4; delete client5; printf("Testing quitting the server while a client is running...\n"); client1 = new ExternalMetro(1200, 0.4, 20, 80, "t1"); printf("Now quit the server, shutdown callback should be called...\n"); printf("Type 'c' to move on...\n"); while ((getchar() != 'c')) { JackSleep(1); }; printf("Closing client...\n"); delete client1; printf("Now start the server again...\n"); printf("Type 'c' to move on...\n"); while ((getchar() != 'c')) { JackSleep(1); }; printf("Opening a new client....\n"); client1 = new ExternalMetro(1200, 0.4, 20, 80, "t1"); printf("Now quit the server, shutdown callback should be called...\n"); printf("Type 'c' to move on...\n"); while ((getchar() != 'c')) { JackSleep(1); }; printf("Simulating client not correctly closed...\n"); printf("Opening a new client....\n"); try { client1 = new ExternalMetro(1200, 0.4, 20, 80, "t1"); } catch (int num) { printf("Cannot open a new client since old one was not closed correctly... OK\n"); } printf("Type 'q' to quit...\n"); while ((getchar() != 'q')) { JackSleep(1); }; delete client1; return 0; }