git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@1680 0c269be4-1314-0410-8aa9-9f06e86f4224tags/0.68
| @@ -13,6 +13,10 @@ Tom Szilagyi | |||||
| Jackdmp changes log | Jackdmp changes log | ||||
| --------------------------- | --------------------------- | ||||
| 2007-10-30 Stephane Letz <letz@grame.fr> | |||||
| * Fix a bug in freewheel management in async mode: drivers now receive the kStartFreewheelCallback and kStopFreewheelCallback notifications. | |||||
| 2007-10-26 Stephane Letz <letz@grame.fr> | 2007-10-26 Stephane Letz <letz@grame.fr> | ||||
| * Add midiseq and midisine examples. | * Add midiseq and midisine examples. | ||||
| @@ -94,21 +94,20 @@ pthread_t JackClient::GetThreadID() | |||||
| } | } | ||||
| /*! | /*! | ||||
| \brief | |||||
| In ASYNC mode, the server does not synchronize itself on the output drivers, thus it would never "consume" the activations. | |||||
| In "async" mode, the server does not synchronize itself on the output drivers, thus it would never "consume" the activations. | |||||
| The synchronization primitives for drivers are setup in "flush" mode that to not keep unneeded activations. | The synchronization primitives for drivers are setup in "flush" mode that to not keep unneeded activations. | ||||
| Drivers synchro are setup in "flush" mode if server is ASYNC and NOT freewheel. | |||||
| Drivers synchro are setup in "flush" mode if server is "async" and NOT freewheel. | |||||
| */ | */ | ||||
| void JackClient::SetupDriverSync(bool freewheel) | void JackClient::SetupDriverSync(bool freewheel) | ||||
| { | { | ||||
| if (!freewheel && !GetEngineControl()->fSyncMode) { | if (!freewheel && !GetEngineControl()->fSyncMode) { | ||||
| JackLog("JackClient::SetupDriverSync driver sem in flush mode\n"); | JackLog("JackClient::SetupDriverSync driver sem in flush mode\n"); | ||||
| fSynchroTable[AUDIO_DRIVER_REFNUM]->SetFlush(true); | |||||
| fSynchroTable[AUDIO_DRIVER_REFNUM]->SetFlush(true); | |||||
| fSynchroTable[FREEWHEEL_DRIVER_REFNUM]->SetFlush(true); | fSynchroTable[FREEWHEEL_DRIVER_REFNUM]->SetFlush(true); | ||||
| fSynchroTable[LOOPBACK_DRIVER_REFNUM]->SetFlush(true); | fSynchroTable[LOOPBACK_DRIVER_REFNUM]->SetFlush(true); | ||||
| } else { | } else { | ||||
| JackLog("JackClient::SetupDriverSync driver sem in normal mode\n"); | JackLog("JackClient::SetupDriverSync driver sem in normal mode\n"); | ||||
| fSynchroTable[AUDIO_DRIVER_REFNUM]->SetFlush(false); | |||||
| fSynchroTable[AUDIO_DRIVER_REFNUM]->SetFlush(false); | |||||
| fSynchroTable[FREEWHEEL_DRIVER_REFNUM]->SetFlush(false); | fSynchroTable[FREEWHEEL_DRIVER_REFNUM]->SetFlush(false); | ||||
| fSynchroTable[LOOPBACK_DRIVER_REFNUM]->SetFlush(false); | fSynchroTable[LOOPBACK_DRIVER_REFNUM]->SetFlush(false); | ||||
| } | } | ||||
| @@ -66,7 +66,10 @@ struct JackClientControl : public JackShmMem | |||||
| fCallback[kAddClient] = true; | fCallback[kAddClient] = true; | ||||
| fCallback[kRemoveClient] = true; | fCallback[kRemoveClient] = true; | ||||
| fCallback[kActivateClient] = true; | fCallback[kActivateClient] = true; | ||||
| fRefNum = refnum; | |||||
| // So that driver synchro are corectly setup in "flush" or "normal" mode | |||||
| fCallback[kStartFreewheelCallback] = true; | |||||
| fCallback[kStopFreewheelCallback] = true; | |||||
| fRefNum = refnum; | |||||
| fTransportState = JackTransportStopped; | fTransportState = JackTransportStopped; | ||||
| fActive = false; | fActive = false; | ||||
| } | } | ||||
| @@ -76,18 +76,9 @@ int JackDriver::Open() | |||||
| } | } | ||||
| fClientControl->fRefNum = refnum; | fClientControl->fRefNum = refnum; | ||||
| fClientControl->fActive = true; | |||||
| fGraphManager->DirectConnect(fClientControl->fRefNum, fClientControl->fRefNum); // Connect driver to itself for sync | |||||
| /* | |||||
| In ASYNC mode, the server does not synchronize itself on the output drivers, thus it would never "consume" the activations. | |||||
| The synchronization primitives for drivers are setup in "flush" mode that to not keep unneeded activations. | |||||
| */ | |||||
| if (!fEngineControl->fSyncMode) { | |||||
| fSynchroTable[AUDIO_DRIVER_REFNUM]->SetFlush(true); | |||||
| fSynchroTable[FREEWHEEL_DRIVER_REFNUM]->SetFlush(true); | |||||
| fSynchroTable[LOOPBACK_DRIVER_REFNUM]->SetFlush(true); | |||||
| } | |||||
| fClientControl->fActive = true; | |||||
| fGraphManager->DirectConnect(fClientControl->fRefNum, fClientControl->fRefNum); // Connect driver to itself for "sync" mode | |||||
| SetupDriverSync(fClientControl->fRefNum, false); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -113,7 +104,7 @@ int JackDriver::Open(jack_nframes_t nframes, | |||||
| } | } | ||||
| fClientControl->fRefNum = refnum; | fClientControl->fRefNum = refnum; | ||||
| fClientControl->fActive = true; | |||||
| fClientControl->fActive = true; | |||||
| fEngineControl->fBufferSize = nframes; | fEngineControl->fBufferSize = nframes; | ||||
| fEngineControl->fSampleRate = samplerate; | fEngineControl->fSampleRate = samplerate; | ||||
| fCaptureLatency = capture_latency; | fCaptureLatency = capture_latency; | ||||
| @@ -130,17 +121,8 @@ int JackDriver::Open(jack_nframes_t nframes, | |||||
| fEngineControl->fTimeOutUsecs = (jack_time_t)(2.f * fEngineControl->fPeriodUsecs); | fEngineControl->fTimeOutUsecs = (jack_time_t)(2.f * fEngineControl->fPeriodUsecs); | ||||
| fGraphManager->SetBufferSize(nframes); | fGraphManager->SetBufferSize(nframes); | ||||
| fGraphManager->DirectConnect(fClientControl->fRefNum, fClientControl->fRefNum); // Connect driver to itself for sync | |||||
| /* | |||||
| In ASYNC mode, the server does not synchronize itself on the output drivers, thus it would never "consume" the activations. | |||||
| The synchronization primitives for drivers are setup in "flush" mode that to not keep unneeded activations. | |||||
| */ | |||||
| if (!fEngineControl->fSyncMode) { | |||||
| fSynchroTable[AUDIO_DRIVER_REFNUM]->SetFlush(true); | |||||
| fSynchroTable[FREEWHEEL_DRIVER_REFNUM]->SetFlush(true); | |||||
| fSynchroTable[LOOPBACK_DRIVER_REFNUM]->SetFlush(true); | |||||
| } | |||||
| fGraphManager->DirectConnect(fClientControl->fRefNum, fClientControl->fRefNum); // Connect driver to itself for "sync" mode | |||||
| SetupDriverSync(fClientControl->fRefNum, false); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -152,6 +134,40 @@ int JackDriver::Close() | |||||
| return fEngine->ClientInternalClose(fClientControl->fRefNum, false); | return fEngine->ClientInternalClose(fClientControl->fRefNum, false); | ||||
| } | } | ||||
| /*! | |||||
| In "async" mode, the server does not synchronize itself on the output drivers, thus it would never "consume" the activations. | |||||
| The synchronization primitives for drivers are setup in "flush" mode that to not keep unneeded activations. | |||||
| Drivers synchro are setup in "flush" mode if server is "async" and NOT freewheel. | |||||
| */ | |||||
| void JackDriver::SetupDriverSync(int ref, bool freewheel) | |||||
| { | |||||
| if (!freewheel && !fEngineControl->fSyncMode) { | |||||
| JackLog("JackDriver::SetupDriverSync driver sem in flush mode\n"); | |||||
| fSynchroTable[ref]->SetFlush(true); | |||||
| } else { | |||||
| JackLog("JackDriver::SetupDriverSync driver sem in normal mode\n"); | |||||
| fSynchroTable[ref]->SetFlush(false); | |||||
| } | |||||
| } | |||||
| int JackDriver::ClientNotify(int refnum, const char* name, int notify, int sync, int value) | |||||
| { | |||||
| switch (notify) { | |||||
| case kStartFreewheelCallback: | |||||
| JackLog("JackDriver::kStartFreewheel\n"); | |||||
| SetupDriverSync(fClientControl->fRefNum, true); | |||||
| break; | |||||
| case kStopFreewheelCallback: | |||||
| JackLog("JackDriver::kStopFreewheel\n"); | |||||
| SetupDriverSync(fClientControl->fRefNum, false); | |||||
| break; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| bool JackDriver::IsRealTime() | bool JackDriver::IsRealTime() | ||||
| { | { | ||||
| return fEngineControl->fRealTime; | return fEngineControl->fRealTime; | ||||
| @@ -199,10 +199,9 @@ class EXPORT JackDriver : public JackDriverClient | |||||
| virtual bool IsRealTime(); | virtual bool IsRealTime(); | ||||
| int ClientNotify(int refnum, const char* name, int notify, int sync, int value) | |||||
| { | |||||
| return 0; | |||||
| } | |||||
| int ClientNotify(int refnum, const char* name, int notify, int sync, int value); | |||||
| void SetupDriverSync(int ref, bool freewheel); | |||||
| }; | }; | ||||
| @@ -34,7 +34,7 @@ int JackFreewheelDriver::Process() | |||||
| { | { | ||||
| if (fIsMaster) { | if (fIsMaster) { | ||||
| JackLog("JackFreewheelDriver::Process master %lld\n", fEngineControl->fTimeOutUsecs); | JackLog("JackFreewheelDriver::Process master %lld\n", fEngineControl->fTimeOutUsecs); | ||||
| fLastWaitUst = GetMicroSeconds(); | |||||
| fLastWaitUst = GetMicroSeconds(); | |||||
| fEngine->Process(fLastWaitUst); | fEngine->Process(fLastWaitUst); | ||||
| fGraphManager->ResumeRefNum(fClientControl, fSynchroTable); // Signal all clients | fGraphManager->ResumeRefNum(fClientControl, fSynchroTable); // Signal all clients | ||||
| if (fGraphManager->SuspendRefNum(fClientControl, fSynchroTable, 10 * 1000000) < 0) // Wait for all clients to finish for 10 sec | if (fGraphManager->SuspendRefNum(fClientControl, fSynchroTable, 10 * 1000000) < 0) // Wait for all clients to finish for 10 sec | ||||
| @@ -257,7 +257,7 @@ int JackServer::SetFreewheel(bool onoff) | |||||
| fEngine->NotifyFreewheel(onoff); | fEngine->NotifyFreewheel(onoff); | ||||
| fFreewheelDriver->SetMaster(false); | fFreewheelDriver->SetMaster(false); | ||||
| fEngineControl->InitFrameTime(); | fEngineControl->InitFrameTime(); | ||||
| return fAudioDriver->Start(); | |||||
| return fAudioDriver->Start(); | |||||
| } | } | ||||
| } else { | } else { | ||||
| if (onoff) { | if (onoff) { | ||||
| @@ -267,7 +267,7 @@ int JackServer::SetFreewheel(bool onoff) | |||||
| fGraphManager->DisconnectAllPorts(fAudioDriver->GetClientControl()->fRefNum); | fGraphManager->DisconnectAllPorts(fAudioDriver->GetClientControl()->fRefNum); | ||||
| fEngine->NotifyFreewheel(onoff); | fEngine->NotifyFreewheel(onoff); | ||||
| fFreewheelDriver->SetMaster(true); | fFreewheelDriver->SetMaster(true); | ||||
| return fFreewheelDriver->Start(); | |||||
| return fFreewheelDriver->Start(); | |||||
| } else { | } else { | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| @@ -61,7 +61,7 @@ void parse_arguments(int argc, char *argv[]) | |||||
| int | int | ||||
| main (int argc, char *argv[]) | main (int argc, char *argv[]) | ||||
| { | { | ||||
| parse_arguments (argc, argv); | |||||
| //parse_arguments (argc, argv); | |||||
| /* become a JACK client */ | /* become a JACK client */ | ||||
| if ((client = jack_client_new ("freewheel1")) == 0) { | if ((client = jack_client_new ("freewheel1")) == 0) { | ||||
| @@ -69,16 +69,24 @@ main (int argc, char *argv[]) | |||||
| exit(1); | exit(1); | ||||
| } | } | ||||
| /* | |||||
| signal (SIGQUIT, signal_handler); | signal (SIGQUIT, signal_handler); | ||||
| signal (SIGTERM, signal_handler); | signal (SIGTERM, signal_handler); | ||||
| signal (SIGHUP, signal_handler); | signal (SIGHUP, signal_handler); | ||||
| signal (SIGINT, signal_handler); | signal (SIGINT, signal_handler); | ||||
| */ | |||||
| jack_on_shutdown (client, jack_shutdown, 0); | jack_on_shutdown (client, jack_shutdown, 0); | ||||
| /* | |||||
| if (jack_set_freewheel (client, onoff)) { | if (jack_set_freewheel (client, onoff)) { | ||||
| fprintf (stderr, "failed to reset freewheel mode\n"); | fprintf (stderr, "failed to reset freewheel mode\n"); | ||||
| } | } | ||||
| */ | |||||
| jack_set_freewheel (client, 1); | |||||
| sleep(5); | |||||
| jack_set_freewheel (client, 0); | |||||
| sleep(5); | |||||
| jack_client_close(client); | jack_client_close(client); | ||||
| return 0; | return 0; | ||||