Commit e418ea10 authored by Nedko Arnaudov's avatar Nedko Arnaudov
Browse files

Merge branch 'master' into no-self-connect

Conflicts:
	common/Jackdmp.cpp
parents 0c27942a 6dda8665
......@@ -25,17 +25,155 @@ Paul Davis
Jackdmp changes log
---------------------------
2009-07-22 Stephane Letz <letz@grame.fr>
2009-11-18 Stephane Letz <letz@grame.fr>
* Sync JackCoreAudioAdapter code with JackCoreAudioDriver.
2009-11-17 Stephane Letz <letz@grame.fr>
* In JackCoreAudio driver, clock drift compensation in aggregated devices working.
* In JackCoreAudio driver, clock drift compensation semantic changed a bit : when on, does not activate if not needed (same clock domain).
2009-11-16 Stephane Letz <letz@grame.fr>
* In JackCoreAudio driver, (possibly) clock drift compensation when needed in aggregated devices.
2009-11-14 Stephane Letz <letz@grame.fr>
* Sync with JACK1 : -r parameter now used for no-realtime, realtime (-R) is now default, usable backend given vie platform.
2009-11-13 Stephane Letz <letz@grame.fr>
* Better memory allocation error checking in ringbuffer.c, weak import improvements.
* Memory allocation error checking for jack_client_new and jack_client_open (server and client side).
* Memory allocation error checking in server for RPC.
* Simplify server temporary mode : now use a JackTemporaryException.
* Lock/Unlock shared memory segments (to test...).
2009-11-12 Stephane Letz <letz@grame.fr>
* Better memory allocation error checking on client (library) side.
2009-11-11 Stephane Letz <letz@grame.fr>
* Correct JackCoreAudio driver when empty strings are given as -C, -P or -d parameter.
2009-11-10 Stephane Letz <letz@grame.fr>
* Version 1.9.4 started.
* Solaris boomer backend now working in capture or playback only mode.
* Fix control.h for proper compilation on Solaris.
* Correct JackInfoShutdownCallback prototype, two new JackClientProcessFailure and JackClientZombie JackStatus code.
2009-11-09 Stephane Letz <letz@grame.fr>
* Correct JackGraphManager::GetBuffer for the "client loop with one connection" case : buffer must be copied.
2009-11-07 Stephane Letz <letz@grame.fr>
* Fix AcquireRealTime and DropRealTime: now distinguish when called from another thread (AcquireRealTime/DropRealTime) and from the thread itself (AcquireSelfRealTime/DropSelfRealTime).
* Correct JackPosixThread::StartImp : thread priority setting now done in the RT case only.
2009-11-06 Stephane Letz <letz@grame.fr>
* Correctly save and restore RT mode state in freewheel mode.
* Correct freewheel code on client side.
2009-11-05 Stephane Letz <letz@grame.fr>
* No reason to make jack_on_shutdown deprecated, so revert the incorrect change.
* Thread AcquireRealTime and DropRealTime were (incorrectly) using fThread field. Use pthread_self()) (or GetCurrentThread() on Windows) to get the calling thread.
2009-10-30 Stephane Letz <letz@grame.fr>
* In JackCoreAudioDriver, improve management of input/output channels: -1 is now used internally to indicate a wanted max value.
* In JackCoreAudioDriver::OpenAUHAL, correct stream format setup and cleanup.
* Correct crash bug in JackAudioAdapterInterface when not input is used in adapter (temporary fix...)
* Sync JackCoreAudioAdapter code on JackCoreAudioDriver one.
* JACK_SCHED_POLICY switched to SCHED_FIFO.
* Now can aggregate device that are themselves AD.
2009-10-29 Stephane Letz <letz@grame.fr>
* In JackCoreAudioDriver::Start, wait for the audio driver to effectively start (use the MeasureCallback).
2009-10-28 Stephane Letz <letz@grame.fr>
* In JackCoreAudioDriver, force the SR value to the wanted one *before* creating aggregate device (otherwise creation will fail).
* In JackCoreAudioDriver, better cleanup of AD when intermediate open failure.
2009-10-27 Stephane Letz <letz@grame.fr>
* Dynamic system version detection in JackCoreAudioDriver to either create public or private aggregate device.
2009-10-26 Stephane Letz <letz@grame.fr>
* Implement "hog mode" (exclusive access of the audio device) in JackCoreAudioDriver.
* Fix jack_set_sample_rate_callback to have he same behavior as in JACK1.
2009-10-25 Stephane Letz <letz@grame.fr>
* Improve aggregate device management in JackCoreAudioDriver : now a "private" device only and cleanup properly.
* Aggregate device code added to JackCoreAudioAdapter.
2009-10-23 Stephane Letz <letz@grame.fr>
* Correct JackProcessSync::LockedTimedWait.
* Correct JACK_MESSAGE_SIZE value, particularly in OSX RPC code.
* Now start server channel thread only when backend has been started (so in JackServer::Start). Should solve race conditions at start time.
* jack_verbose moved to JackGlobals class.
2009-10-22 Stephane Letz <letz@grame.fr>
* Correct jackdmp.cpp (failures case were not correct..). Improve JackCoreAudioDriver code. Raise default port number to 2048.
2009-10-20 Stephane Letz <letz@grame.fr>
* Add a string parameter to server ==> client notification, add a new JackInfoShutdownCallback type.
* CoreAudio backend now issue a JackInfoShutdownCallback when an unrecoverable error is detected (sampling rate change, stream configuration change)
2009-10-17 Stephane Letz <letz@grame.fr>
* Correct server temporary mode : now set a global and quit after server/client message handling is finished.
2009-10-15 Stephane Letz <letz@grame.fr>
* Change CoreAudio notification thread setup for OSX Snow Leopard.
2009-09-18 Stephane Letz <letz@grame.fr>
* Simplify transport in NetJack2: master only can control transport.
2009-09-15 Stephane Letz <letz@grame.fr>
* Correct CPU timing in JackNetDriver, now take cycle begin time after Read.
* Fix issues in JackNetDriver::DecodeTransportData and JackNetDriver::Initialize.
2009-08-28 Stephane Letz <letz@grame.fr>
* Correct monitor port naming in JackAudioDriver and JackCoreAudioDriver.
* Big endian bug fix in memops.c (http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=5;filename=11_be24bit.patch;att=1;bug=486308)
2009-07-31 Stephane Letz <letz@grame.fr>
* Use SNDCTL_DSP_SYNCGROUP/SNDCTL_DSP_SYNCSTART API to synchronize input and output in Solaris boomer backend.
2009-07-29 Stephane Letz <letz@grame.fr>
* Add a -G parameter in CoreAudio backend (the computation value in RT thread expressed as percent of period).
2009-07-28 Stephane Letz <letz@grame.fr>
* Fix CopyAndConvertIn for Solaris backends.
2009-07-22 Stephane Letz <letz@grame.fr>
* Version 1.9.4 started.
* Solaris boomer backend now working in capture or playback only mode.
* Fix control.h for proper compilation on Solaris.
2009-07-17 Stephane Letz <letz@grame.fr>
* Loopback backend reborn as a dynamically loadable separated backend.
* Loopback backend reborn as a dynamically loadable separated backend.
* -L parameter for loopback backend activated again in jackd.
2009-07-17 Stephane Letz <letz@grame.fr>
* Big rewrite of Solaris boomer driver, seems to work in duplex mode at least.
......@@ -312,12 +450,12 @@ Paul Davis
2009-01-05 Stephane Letz <letz@grame.fr>
* Synchronize jack2 public headers with jack1 ones.
* Synchronize jack2 public headers with JACK1 ones.
* Implement jack_client_real_time_priority and jack_client_max_real_time_priority API.
2008-12-18 Stephane Letz <letz@grame.fr>
* For ALSA driver, synchronize with latest jack1 memops functions.
* For ALSA driver, synchronize with latest JACK1 memops functions.
* Use memops functions in JackOSSDriver.
* Use memops functions in JackOSSAdapter.
......@@ -351,13 +489,13 @@ Paul Davis
2008-11-27 Stephane Letz <letz@grame.fr>
* Add timing profiling code in JackOSSDriver.
* Report ringbuffer.c fixes from jack1.
* Report ringbuffer.c fixes from JACK1.
2008-11-21 Stephane Letz <letz@grame.fr>
* Report ringbuffer.c fixes from jack1.
* Better isolation of server and clients system resources to allow starting the server in several user account at the same time.
* Correct ressource cleanup in case of driver open failure.
* Report ringbuffer.c fixes from JACK1.
* Better isolation of server and clients system resources to allow starting the server in several user account at the same time.
* Correct ressource cleanup in case of driver open failure.
2008-11-19 Stephane Letz <letz@grame.fr>
......
......@@ -213,6 +213,7 @@ Note : To experiment with the -S option, jackdmp must be launched in a console.
1.9.1 : Fix jackctl_server_unload_internal. Filter SIGPIPE to avoid having client get a SIGPIPE when trying to access a died server. Libjack shutdown handler does not "deactivate" (fActive = false) the client anymore, so that jack_deactivate correctly does the job later on. Better isolation of server and clients system resources to allow starting the server in several user account at the same time. Report ringbuffer.c fixes from jack1. Client and library global context cleanup in case of incorrect shutdown handling (that is applications not correctly closing client after server has shutdown). Use JACK_DRIVER_DIR variable in internal clients loader. For ALSA driver, synchronize with latest jack1 memops functions. Synchronize jack2 public headers with jack1 ones. Implement jack_client_real_time_priority and jack_client_max_real_time_priority API. Use up to BUFFER_SIZE_MAX frames in midi ports, fix for ticket #117. Cleanup server starting code for clients directly linked with libjackserver.so. JackMessageBuffer was using thread "Stop" scheme in destructor, now use the safer thread "Kill" way. Synchronize ALSA backend code with JACK1 one. Set default mode to 'slow' in JackNetDriver and JackNetAdapter. Simplify audio packet order verification. Fix JackNetInterface::SetNetBufferSize for socket buffer size computation and JackNetMasterInterface::DataRecv if synch packet is received, various cleanup. Better recovery of network overload situations, now "resynchronize" by skipping cycles.". Support for BIG_ENDIAN machines in NetJack2. Support for BIG_ENDIAN machines in NetJack2 for MIDI ports. Support for "-h" option in internal clients to print the parameters. In NetJack2, fix a bug when capture or playback only channels are used. Add a JACK_INTERNAL_DIR environment variable to be used for internal clients. Add a resample quality parameter in audioadapter. Now correctly return an error if JackServer::SetBufferSize could not change the buffer size (and was just restoring the current one). Use PRIu32 kind of macro in JackAlsaDriver again. Add a resample quality parameter in netadapter.
1.9.2 : Solaris version. New "profiling" tools. Rework the mutex/signal classes. Support for BIG_ENDIAN machines in NetJack2. D-BUS based device reservation to better coexist with PulseAudio on Linux. Add auto_connect parameter in netmanager and netadapter. Use Torben Hohn PI controler code for adapters. Client incorrect re-naming fixed : now done at socket and fifo level. Virtualize and allow overriding of thread creation function, to allow Wine support (from JACK1).
1.9.3 : New JackBoomerDriver class for Boomer driver on Solaris. Add mixed 32/64 bits mode (off by default). Native MIDI backend (JackCoreMidiDriver, JackWinMMEDriver). In ALSA audio card reservation code, tries to open the card even if reservation fails. Clock source setting on Linux. Add jackctl_server_switch_master API. Fix transport callback (timebase master, sync) issue when used after jack_activate (RT thread was not running). D-Bus access for jackctl_server_add_slave/jackctl_server_remove_slave API. Cleanup "loopback" stuff in server. Torben Hohn fix for InitTime and GetMicroSeconds in JackWinTime.c. New jack_free function added in jack.h. Reworked Torben Hohn fix for server restart issue on Windows. Correct jack_set_error_function, jack_set_info_function and jack_set_thread_creator functions. Correct JackFifo::TimedWait for EINTR handling. Move DBus based audio device reservation code in ALSA backend compilation. Correct JackTransportEngine::MakeAllLocating, sync callback has to be called in this case also. NetJack2 code : better error checkout, method renaming. Tim Bechmann patch : hammerfall, only release monitor thread, if it has been created. Tim Bechmann memops.c optimization patches. In combined --dbus and --classic compilation code, use PulseAudio acquire/release code. Big rewrite of Solaris boomer driver, seems to work in duplex mode at least. Loopback backend reborn as a dynamically loadable separated backend.
1.9.4 : Solaris boomer backend now working in capture or playback only mode. Add a -G parameter in CoreAudio backend (the computation value in RT thread expressed as percent of period). Use SNDCTL_DSP_SYNCGROUP/SNDCTL_DSP_SYNCSTART API to synchronize input and output in Solaris boomer backend. Big endian bug fix in memops.c. Fix issues in JackNetDriver::DecodeTransportData and JackNetDriver::Initialize. Correct CPU timing in JackNetDriver, now take cycle begin time after Read. Simplify transport in NetJack2: master only can control transport. Change CoreAudio notification thread setup for OSX Snow Leopard. Correct server temporary mode : now set a global and quit after server/client message handling is finished. Add a string parameter to server ==> client notification, add a new JackInfoShutdownCallback type. CoreAudio backend now issue a JackInfoShutdownCallback when an unrecoverable error is detected (sampling rate change, stream configuration changeÉ). Correct jackdmp.cpp (failures case were not correct..). Improve JackCoreAudioDriver code. Raise default port number to 2048. Correct JackProcessSync::LockedTimedWait. Correct JACK_MESSAGE_SIZE value, particularly in OSX RPC code. Now start server channel thread only when backend has been started (so in JackServer::Start). Should solve race conditions at start time. jack_verbose moved to JackGlobals class. Improve aggregate device management in JackCoreAudioDriver : now a "private" device only and cleanup properly. Aggregate device code added to JackCoreAudioAdapter. Implement "hog mode" (exclusive access of the audio device) in JackCoreAudioDriver. Fix jack_set_sample_rate_callback to have he same behavior as in JACK1. Dynamic system version detection in JackCoreAudioDriver to either create public or private aggregate device. In JackCoreAudioDriver, force the SR value to the wanted one *before* creating aggregate device (otherwise creation will fail). In JackCoreAudioDriver, better cleanup of AD when intermediate open failure. In JackCoreAudioDriver::Start, wait for the audio driver to effectively start (use the MeasureCallback). In JackCoreAudioDriver, improve management of input/output channels: -1 is now used internally to indicate a wanted max value. In JackCoreAudioDriver::OpenAUHAL, correct stream format setup and cleanup. Correct crash bug in JackAudioAdapterInterface when not input is used in adapter (temporary fixÉ). Sync JackCoreAudioAdapter code on JackCoreAudioDriver one. JACK_SCHED_POLICY switched to SCHED_FIFO. Now can aggregate device that are themselves AD. No reason to make jack_on_shutdown deprecated, so revert the incorrect change. Thread AcquireRealTime and DropRealTime were (incorrectly) using fThread field. Use pthread_self()) (or GetCurrentThread() on Windows) to get the calling thread. Correctly save and restore RT mode state in freewheel mode. Correct freewheel code on client side. Fix AcquireRealTime and DropRealTime: now distinguish when called from another thread (AcquireRealTime/DropRealTime) and from the thread itself (AcquireSelfRealTime/DropSelfRealTime). Correct JackPosixThread::StartImp : thread priority setting now done in the RT case only. Correct JackGraphManager::GetBuffer for the "client loop with one connection" case : buffer must be copied. Correct JackInfoShutdownCallback prototype, two new JackClientProcessFailure and JackClientZombie JackStatus code. Correct JackCoreAudio driver when empty strings are given as -C, -P or -d parameter. Better memory allocation error checking on client (library) side. Better memory allocation error checking in ringbuffer.c, weak import improvements. Memory allocation error checking for jack_client_new and jack_client_open (server and client side). Memory allocation error checking in server for RPC. Simplify server temporary mode : now use a JackTemporaryException. Lock/Unlock shared memory segments (to test...). Sync with JACK1 : -r parameter now used for no-realtime, realtime (-R) is now default, usable backend given vie platform. In JackCoreAudio driver, (possibly) clock drift compensation when needed in aggregated devices. In JackCoreAudio driver, clock drift compensation in aggregated devices working. In JackCoreAudio driver, clock drift compensation semantic changed a bit : when on, does not activate if not needed (same clock domain). Sync JackCoreAudioAdapter code with JackCoreAudioDriver.
This is a work in progress but the implementation is now stable enough to be tested. jackdmp has been used successfully with the following applications : Ardour, Hydrogen, Jamin, Qjackctl, Jack-Rack, SooperLooper, AlsaPlayer...
......
......@@ -72,6 +72,8 @@ extern "C"
EXPORT int jack_is_realtime (jack_client_t *client);
EXPORT void jack_on_shutdown (jack_client_t *client,
JackShutdownCallback shutdown_callback, void *arg);
EXPORT void jack_on_info_shutdown (jack_client_t *client,
JackInfoShutdownCallback shutdown_callback, void *arg);
EXPORT int jack_set_process_callback (jack_client_t *client,
JackProcessCallback process_callback,
void *arg);
......@@ -288,15 +290,23 @@ EXPORT void jack_set_info_function (print_function func)
EXPORT jack_client_t* jack_client_new(const char* client_name)
{
assert(JackGlobals::fOpenMutex);
JackGlobals::fOpenMutex->Lock();
jack_error("jack_client_new: deprecated");
int options = JackUseExactName;
if (getenv("JACK_START_SERVER") == NULL)
options |= JackNoStartServer;
jack_client_t* res = jack_client_open_aux(client_name, (jack_options_t)options, NULL, NULL);
JackGlobals::fOpenMutex->Unlock();
return res;
try {
assert(JackGlobals::fOpenMutex);
JackGlobals::fOpenMutex->Lock();
jack_error("jack_client_new: deprecated");
int options = JackUseExactName;
if (getenv("JACK_START_SERVER") == NULL)
options |= JackNoStartServer;
jack_client_t* res = jack_client_open_aux(client_name, (jack_options_t)options, NULL, NULL);
JackGlobals::fOpenMutex->Unlock();
return res;
} catch (std::bad_alloc& e) {
jack_error("Memory allocation error...");
return NULL;
} catch (...) {
jack_error("Unknown error...");
return NULL;
}
}
EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames)
......@@ -819,6 +829,19 @@ EXPORT void jack_on_shutdown(jack_client_t* ext_client, JackShutdownCallback cal
}
}
EXPORT void jack_on_info_shutdown(jack_client_t* ext_client, JackInfoShutdownCallback callback, void* arg)
{
#ifdef __CLIENTDEBUG__
JackLibGlobals::CheckContext();
#endif
JackClient* client = (JackClient*)ext_client;
if (client == NULL) {
jack_error("jack_on_info_shutdown called with a NULL client");
} else {
client->OnInfoShutdown(callback, arg);
}
}
EXPORT int jack_set_process_callback(jack_client_t* ext_client, JackProcessCallback callback, void* arg)
{
#ifdef __CLIENTDEBUG__
......@@ -1928,5 +1951,7 @@ jack_get_version_string()
EXPORT void jack_free(void* ptr)
{
free(ptr);
if (ptr) {
free(ptr);
}
}
......@@ -128,6 +128,10 @@ namespace Jack {
return -1;
//else allocate and fill it
argv = (char**)calloc (fArgv.size(), sizeof(char*));
if (argv == NULL)
{
return -1;
}
for ( unsigned int i = 0; i < fArgv.size(); i++ )
{
argv[i] = (char*)calloc(fArgv[i].length(), sizeof(char));
......
......@@ -230,10 +230,18 @@ namespace Jack
// Finer estimation of the position in the ringbuffer
int delta_frames = (fPullAndPushTime > 0) ? (int)((float(long(GetMicroSeconds() - fPullAndPushTime)) * float(fAdaptedSampleRate)) / 1000000.f) : 0;
double ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetError() - delta_frames);
double ratio = 1;
// TODO : done like this just to avoid crash when input only or output only...
if (fCaptureChannels > 0)
ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetError() - delta_frames);
else if (fPlaybackChannels > 0)
ratio = fPIControler.GetRatio(fPlaybackRingBuffer[0]->GetError() - delta_frames);
#ifdef JACK_MONITOR
fTable.Write(fCaptureRingBuffer[0]->GetError(), fCaptureRingBuffer[0]->GetError() - delta_frames, ratio, 1/ratio, fCaptureRingBuffer[0]->ReadSpace(), fCaptureRingBuffer[0]->ReadSpace());
if (fCaptureRingBuffer[0] != NULL)
fTable.Write(fCaptureRingBuffer[0]->GetError(), fCaptureRingBuffer[0]->GetError() - delta_frames, ratio, 1/ratio, fCaptureRingBuffer[0]->ReadSpace(), fCaptureRingBuffer[0]->ReadSpace());
#endif
// Push/pull from ringbuffer
......
......@@ -139,12 +139,13 @@ int JackAudioDriver::Attach()
// Monitor ports
if (fWithMonitorPorts) {
jack_log("Create monitor port ");
snprintf(name, sizeof(name) - 1, "%s:%s:monitor_%u", fAliasName, fPlaybackDriverName, i + 1);
snprintf(name, sizeof(name) - 1, "%s:monitor_%u", fClientControl.fName, i + 1);
if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize)) == NO_PORT) {
jack_error("Cannot register monitor port for %s", name);
return -1;
} else {
port = fGraphManager->GetPort(port_index);
port->SetAlias(alias);
port->SetLatency(fEngineControl->fBufferSize);
fMonitorPortList[i] = port_index;
}
......
......@@ -82,7 +82,7 @@ class JackClientChannelInterface
virtual void ClientClose(int refnum, int* result)
{}
virtual void ClientActivate(int refnum, int state, int* result)
virtual void ClientActivate(int refnum, int is_real_time, int* result)
{}
virtual void ClientDeactivate(int refnum, int* result)
{}
......
......@@ -49,6 +49,7 @@ JackClient::JackClient(JackSynchro* table):fThread(this)
fGraphOrder = NULL;
fXrun = NULL;
fShutdown = NULL;
fInfoShutdown = NULL;
fInit = NULL;
fBufferSize = NULL;
fClientRegistration = NULL;
......@@ -63,6 +64,7 @@ JackClient::JackClient(JackSynchro* table):fThread(this)
fGraphOrderArg = NULL;
fXrunArg = NULL;
fShutdownArg = NULL;
fInfoShutdownArg = NULL;
fInitArg = NULL;
fBufferSizeArg = NULL;
fFreewheelArg = NULL;
......@@ -132,12 +134,12 @@ void JackClient::SetupDriverSync(bool freewheel)
\brief Notification received from the server.
*/
int JackClient::ClientNotifyImp(int refnum, const char* name, int notify, int sync, int value1, int value2)
int JackClient::ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2)
{
return 0;
}
int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2)
int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2)
{
int res = 0;
......@@ -145,11 +147,11 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync,
switch (notify) {
case kAddClient:
res = ClientNotifyImp(refnum, name, notify, sync, value1, value2);
res = ClientNotifyImp(refnum, name, notify, sync, message, value1, value2);
break;
case kRemoveClient:
res = ClientNotifyImp(refnum, name, notify, sync, value1, value2);
res = ClientNotifyImp(refnum, name, notify, sync, message, value1, value2);
break;
case kActivateClient:
......@@ -168,84 +170,107 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync,
case kAddClient:
jack_log("JackClient::kAddClient fName = %s name = %s", GetClientControl()->fName, name);
if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) // Don't call the callback for the registering client itself
if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) { // Don't call the callback for the registering client itself
fClientRegistration(name, 1, fClientRegistrationArg);
}
break;
case kRemoveClient:
jack_log("JackClient::kRemoveClient fName = %s name = %s", GetClientControl()->fName, name);
if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) // Don't call the callback for the registering client itself
if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) { // Don't call the callback for the registering client itself
fClientRegistration(name, 0, fClientRegistrationArg);
}
break;
case kBufferSizeCallback:
jack_log("JackClient::kBufferSizeCallback buffer_size = %ld", value1);
if (fBufferSize)
if (fBufferSize) {
res = fBufferSize(value1, fBufferSizeArg);
}
break;
case kSampleRateCallback:
jack_log("JackClient::kSampleRateCallback sample_rate = %ld", value1);
if (fSampleRate)
if (fSampleRate) {
res = fSampleRate(value1, fSampleRateArg);
}
break;
case kGraphOrderCallback:
jack_log("JackClient::kGraphOrderCallback");
if (fGraphOrder)
if (fGraphOrder) {
res = fGraphOrder(fGraphOrderArg);
}
break;
case kStartFreewheelCallback:
jack_log("JackClient::kStartFreewheel");
SetupDriverSync(true);
fThread.DropRealTime();
if (fFreewheel)
fThread.DropRealTime(); // Always done (JACK server in RT mode or not...)
if (fFreewheel) {
fFreewheel(1, fFreewheelArg);
}
break;
case kStopFreewheelCallback:
jack_log("JackClient::kStopFreewheel");
SetupDriverSync(false);
if (fFreewheel)
if (fFreewheel) {
fFreewheel(0, fFreewheelArg);
fThread.AcquireRealTime();
}
if (GetEngineControl()->fRealTime) {
fThread.AcquireRealTime();
}
break;
case kPortRegistrationOnCallback:
jack_log("JackClient::kPortRegistrationOn port_index = %ld", value1);
if (fPortRegistration)
if (fPortRegistration) {
fPortRegistration(value1, 1, fPortRegistrationArg);
}
break;
case kPortRegistrationOffCallback:
jack_log("JackClient::kPortRegistrationOff port_index = %ld ", value1);
if (fPortRegistration)
if (fPortRegistration) {
fPortRegistration(value1, 0, fPortRegistrationArg);
}
break;
case kPortConnectCallback:
jack_log("JackClient::kPortConnectCallback src = %ld dst = %ld", value1, value2);
if (fPortConnect)
if (fPortConnect) {
fPortConnect(value1, value2, 1, fPortConnectArg);
}
break;
case kPortDisconnectCallback:
jack_log("JackClient::kPortDisconnectCallback src = %ld dst = %ld", value1, value2);
if (fPortConnect)
if (fPortConnect) {
fPortConnect(value1, value2, 0, fPortConnectArg);
}
break;
case kPortRenameCallback:
jack_log("JackClient::kPortRenameCallback port = %ld");
if (fPortRename)
if (fPortRename) {
fPortRename(value1, GetGraphManager()->GetPort(value1)->GetName(), fPortRenameArg);
}
break;
case kXRunCallback:
jack_log("JackClient::kXRunCallback");
if (fXrun)
if (fXrun) {
res = fXrun(fXrunArg);
}
break;
case kShutDownCallback:
jack_log("JackClient::kShutDownCallback");
if (fInfoShutdown) {
fInfoShutdown((jack_status_t)value1, message, fInfoShutdownArg);
fInfoShutdown = NULL;
}
break;
}
}
......@@ -444,7 +469,7 @@ inline void JackClient::End()
jack_log("JackClient::Execute end name = %s", GetClientControl()->fName);
// Hum... not sure about this, the following "close" code is called in the RT thread...
int result;
fThread.DropRealTime();
fThread.DropSelfRealTime();
GetClientControl()->fActive = false;
fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result);
fThread.Terminate();
......@@ -455,7 +480,7 @@ inline void JackClient::Error()
jack_error("JackClient::Execute error name = %s", GetClientControl()->fName);
// Hum... not sure about this, the following "close" code is called in the RT thread...
int result;
fThread.DropRealTime();
fThread.DropSelfRealTime();
GetClientControl()->fActive = false;
fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result);
ShutDown();
......@@ -582,7 +607,10 @@ void JackClient::ShutDown()
jack_log("ShutDown");
JackGlobals::fServerRunning = false;
if (fShutdown) {
if (fInfoShutdown) {
fInfoShutdown(JackFailure, "JACK server has been closed", fInfoShutdownArg);
fInfoShutdown = NULL;
} else if (fShutdown) {
fShutdown(fShutdownArg);
fShutdown = NULL;
}
......@@ -772,6 +800,17 @@ void JackClient::OnShutdown(JackShutdownCallback callback, void *arg)
fShutdown = callback;
}
}
void JackClient::OnInfoShutdown(JackInfoShutdownCallback callback, void *arg)
{
if (IsActive()) {
jack_error("You cannot set callbacks on an active client");
} else {
GetClientControl()->fCallback[kShutDownCallback] = (callback != NULL);
fInfoShutdownArg = arg;
fInfoShutdown = callback;
}
}
int JackClient::SetProcessCallback(JackProcessCallback callback, void *arg)
{
......@@ -850,6 +889,9 @@ int JackClient::SetSampleRateCallback(JackSampleRateCallback callback, void *arg
GetClientControl()->fCallback[kSampleRateCallback] = (callback != NULL);
fSampleRateArg = arg;
fSampleRate = callback;
// Now invoke it
if (callback)
callback(GetEngineControl()->fSampleRate, arg);
return 0;
}
}
......@@ -946,14 +988,7 @@ char* JackClient::GetInternalClientName(int ref)
char name_res[JACK_CLIENT_NAME_SIZE + 1];
int result = -1;
fChannel->GetInternalClientName(GetClientControl()->fRefNum, ref, name_res, &result);
if (result < 0) {
return NULL;
} else {
char* name = (char*)malloc(strlen(name_res));
strcpy(name, name_res);
return name;
}
return (result < 0) ? NULL : strdup(name_res);
}
int JackClient::InternalClientHandle(const char* client_name, jack_status_t* status)
......
......@@ -54,6 +54,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface
JackGraphOrderCallback fGraphOrder;
JackXRunCallback fXrun;
JackShutdownCallback fShutdown;
JackInfoShutdownCallback fInfoShutdown;
JackThreadInitCallback fInit;
JackBufferSizeCallback fBufferSize;
JackSampleRateCallback fSampleRate;
......@@ -70,6 +71,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface
void* fGraphOrderArg;
void* fXrunArg;
void* fShutdownArg;
void* fInfoShutdownArg;
void* fInitArg;
void* fBufferSizeArg;
void* fSampleRateArg;
......@@ -95,7 +97,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface
void CallSyncCallback();
void CallTimebaseCallback();
virtual int ClientNotifyImp(int refnum, const char* name, int notify, int sync, int value1, int value);
virtual int ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value);
inline void DummyCycle();
inline void ExecuteThread();
......@@ -123,7 +125,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface
virtual JackEngineControl* GetEngineControl() const = 0;
// Notifications
virtual int ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2);
virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2);
virtual int Activate();
virtual int Deactivate();
......@@ -159,6 +161,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface
// Callbacks
virtual void OnShutdown(JackShutdownCallback callback, void *arg);
virtual void OnInfoShutdown(JackInfoShutdownCallback callback, void *arg);
virtual int SetProcessCallback(JackProcessCallback callback, void* arg);
virtual int SetXRunCallback(JackXRunCallback callback, void* arg);
virtual int SetInitCallback(JackThreadInitCallback callback, void* arg);
......
......@@ -44,7 +44,7 @@ class SERVER_EXPORT JackClientInterface
virtual int Close() = 0;
virtual int ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2) = 0;
virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) = 0;