Browse Source

Fix a bug in freewheel management in async mode: drivers now receive the kStartFreewheelCallback and kStopFreewheelCallback notifications.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@1680 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.68
sletz 18 years ago
parent
commit
9db8324565
8 changed files with 69 additions and 40 deletions
  1. +4
    -0
      ChangeLog
  2. +4
    -5
      common/JackClient.cpp
  3. +4
    -1
      common/JackClientControl.h
  4. +40
    -24
      common/JackDriver.cpp
  5. +3
    -4
      common/JackDriver.h
  6. +1
    -1
      common/JackFreewheelDriver.cpp
  7. +2
    -2
      common/JackServer.cpp
  8. +11
    -3
      example-clients/freewheel.c

+ 4
- 0
ChangeLog View File

@@ -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.


+ 4
- 5
common/JackClient.cpp View File

@@ -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);
} }


+ 4
- 1
common/JackClientControl.h View File

@@ -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;
} }


+ 40
- 24
common/JackDriver.cpp View File

@@ -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;


+ 3
- 4
common/JackDriver.h View File

@@ -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);


}; };




+ 1
- 1
common/JackFreewheelDriver.cpp View File

@@ -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


+ 2
- 2
common/JackServer.cpp View File

@@ -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;
} }


+ 11
- 3
example-clients/freewheel.c View File

@@ -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;


Loading…
Cancel
Save