git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4150 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.9.7
@@ -39,6 +39,7 @@ Valerio Pilo | |||
* Revert r4119 (RT notification in the server). JackAudioDriver::ProcessSync now skip backend write in case of graph process failure. | |||
* Fix incorrect error codes in alsa/usx2y.c and alsa/JackAlsaDriver.cpp. | |||
* Synchronize public headers with JACK1. Update OSX project. | |||
* New latency API implementation (in progress). | |||
2011-02-09 Stephane Letz <letz@grame.fr> | |||
@@ -115,6 +115,9 @@ extern "C" | |||
void *); | |||
EXPORT int jack_set_xrun_callback (jack_client_t *, | |||
JackXRunCallback xrun_callback, void *arg); | |||
EXPORT int jack_set_latency_callback (jack_client_t *client, | |||
JackLatencyCallback callback, void *arg); | |||
EXPORT int jack_activate (jack_client_t *client); | |||
EXPORT int jack_deactivate (jack_client_t *client); | |||
EXPORT jack_port_t * jack_port_register (jack_client_t *client, | |||
@@ -138,12 +141,19 @@ extern "C" | |||
const jack_port_t *port); | |||
EXPORT int jack_port_tie (jack_port_t *src, jack_port_t *dst); | |||
EXPORT int jack_port_untie (jack_port_t *port); | |||
// Old latency API | |||
EXPORT jack_nframes_t jack_port_get_latency (jack_port_t *port); | |||
EXPORT jack_nframes_t jack_port_get_total_latency (jack_client_t *, | |||
jack_port_t *port); | |||
EXPORT void jack_port_set_latency (jack_port_t *, jack_nframes_t); | |||
EXPORT int jack_recompute_total_latency (jack_client_t*, jack_port_t* port); | |||
// New latency API | |||
EXPORT void jack_port_get_latency_range (jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range); | |||
EXPORT void jack_port_set_latency_range (jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range); | |||
EXPORT int jack_recompute_total_latencies (jack_client_t*); | |||
EXPORT int jack_port_set_name (jack_port_t *port, const char *port_name); | |||
EXPORT int jack_port_set_alias (jack_port_t *port, const char *alias); | |||
EXPORT int jack_port_unset_alias (jack_port_t *port, const char *alias); | |||
@@ -526,6 +536,40 @@ EXPORT void jack_port_set_latency(jack_port_t* port, jack_nframes_t frames) | |||
} | |||
} | |||
EXPORT void jack_port_get_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range) | |||
{ | |||
#ifdef __CLIENTDEBUG__ | |||
JackGlobals::CheckContext("jack_port_get_latency_range"); | |||
#endif | |||
uintptr_t port_aux = (uintptr_t)port; | |||
jack_port_id_t myport = (jack_port_id_t)port_aux; | |||
if (!CheckPort(myport)) { | |||
jack_error("jack_port_get_latency_range called with an incorrect port %ld", myport); | |||
} else { | |||
WaitGraphChange(); | |||
JackGraphManager* manager = GetGraphManager(); | |||
if (manager) | |||
manager->GetPort(myport)->GetLatencyRange(mode, range); | |||
} | |||
} | |||
EXPORT void jack_port_set_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range) | |||
{ | |||
#ifdef __CLIENTDEBUG__ | |||
JackGlobals::CheckContext("jack_port_set_latency_range"); | |||
#endif | |||
uintptr_t port_aux = (uintptr_t)port; | |||
jack_port_id_t myport = (jack_port_id_t)port_aux; | |||
if (!CheckPort(myport)) { | |||
jack_error("jack_port_set_latency_range called with an incorrect port %ld", myport); | |||
} else { | |||
WaitGraphChange(); | |||
JackGraphManager* manager = GetGraphManager(); | |||
if (manager) | |||
manager->GetPort(myport)->SetLatencyRange(mode, range); | |||
} | |||
} | |||
EXPORT int jack_recompute_total_latency(jack_client_t* ext_client, jack_port_t* port) | |||
{ | |||
#ifdef __CLIENTDEBUG__ | |||
@@ -988,6 +1032,20 @@ EXPORT int jack_set_xrun_callback(jack_client_t* ext_client, JackXRunCallback xr | |||
} | |||
} | |||
EXPORT int jack_set_latency_callback(jack_client_t *ext_client, JackLatencyCallback latency_callback, void *arg) | |||
{ | |||
#ifdef __CLIENTDEBUG__ | |||
JackGlobals::CheckContext("jack_set_latency_callback"); | |||
#endif | |||
JackClient* client = (JackClient*)ext_client; | |||
if (client == NULL) { | |||
jack_error("jack_set_latency_callback called with a NULL client"); | |||
return -1; | |||
} else { | |||
return client->SetLatencyCallback(latency_callback, arg); | |||
} | |||
} | |||
EXPORT int jack_set_thread_init_callback(jack_client_t* ext_client, JackThreadInitCallback init_callback, void *arg) | |||
{ | |||
#ifdef __CLIENTDEBUG__ | |||
@@ -335,4 +335,37 @@ jack_default_audio_sample_t* JackAudioDriver::GetMonitorBuffer(int port_index) | |||
return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[port_index], fEngineControl->fBufferSize); | |||
} | |||
int JackAudioDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) | |||
{ | |||
switch (notify) { | |||
case kLatencyCallback: | |||
HandleLatencyCallback(value1); | |||
break; | |||
default: | |||
JackDriver::ClientNotify(refnum, name, notify, sync, message, value1, value2); | |||
break; | |||
} | |||
return 0; | |||
} | |||
void JackAudioDriver::HandleLatencyCallback(int status) | |||
{ | |||
jack_latency_callback_mode_t mode = (status == 0) ? JackCaptureLatency : JackPlaybackLatency; | |||
for (int i = 0; i < fCaptureChannels; i++) { | |||
if (mode == JackPlaybackLatency) { | |||
fGraphManager->RecalculateLatency(fCapturePortList[i], mode); | |||
} | |||
} | |||
for (int i = 0; i < fPlaybackChannels; i++) { | |||
if (mode == JackCaptureLatency) { | |||
fGraphManager->RecalculateLatency(fPlaybackPortList[i], mode); | |||
} | |||
} | |||
} | |||
} // end of namespace |
@@ -57,6 +57,8 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver | |||
jack_default_audio_sample_t* GetOutputBuffer(int port_index); | |||
jack_default_audio_sample_t* GetMonitorBuffer(int port_index); | |||
void HandleLatencyCallback(int status); | |||
public: | |||
JackAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); | |||
@@ -95,6 +97,8 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver | |||
virtual int SetBufferSize(jack_nframes_t buffer_size); | |||
virtual int SetSampleRate(jack_nframes_t sample_rate); | |||
virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); | |||
}; | |||
} // end of namespace | |||
@@ -60,6 +60,9 @@ JackClient::JackClient(JackSynchro* table):fThread(this) | |||
fTimebase = NULL; | |||
fSync = NULL; | |||
fThreadFun = NULL; | |||
fSession = NULL; | |||
fLatency = NULL; | |||
fProcessArg = NULL; | |||
fGraphOrderArg = NULL; | |||
fXrunArg = NULL; | |||
@@ -75,6 +78,8 @@ JackClient::JackClient(JackSynchro* table):fThread(this) | |||
fSyncArg = NULL; | |||
fTimebaseArg = NULL; | |||
fThreadFunArg = NULL; | |||
fSessionArg = NULL; | |||
fLatencyArg = NULL; | |||
} | |||
JackClient::~JackClient() | |||
@@ -289,12 +294,113 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, | |||
res = (fImmediateSessionReply) ? 1 : 2; | |||
} | |||
break; | |||
case kLatencyCallback: | |||
res = HandleLatencyCallback(value1); | |||
break; | |||
} | |||
} | |||
return res; | |||
} | |||
int JackClient::HandleLatencyCallback(int status) | |||
{ | |||
jack_latency_callback_mode_t mode = (status == 0) ? JackCaptureLatency : JackPlaybackLatency; | |||
jack_latency_range_t latency = { UINT32_MAX, 0 }; | |||
/* first setup all latency values of the ports. | |||
* this is based on the connections of the ports. | |||
*/ | |||
list<jack_port_id_t>::iterator it; | |||
for (it = fPortList.begin(); it != fPortList.end(); it++) { | |||
JackPort* port = GetGraphManager()->GetPort(*it); | |||
if ((port->GetFlags() & JackPortIsOutput) && (mode == JackPlaybackLatency)) { | |||
GetGraphManager()->RecalculateLatency(*it, mode); | |||
} | |||
if ((port->GetFlags() & JackPortIsInput) && (mode == JackCaptureLatency)) { | |||
GetGraphManager()->RecalculateLatency(*it, mode); | |||
} | |||
} | |||
if (!fLatency) { | |||
/* | |||
* default action is to assume all ports depend on each other. | |||
* then always take the maximum latency. | |||
*/ | |||
if (mode == JackPlaybackLatency) { | |||
/* iterate over all OutputPorts, to find maximum playback latency | |||
*/ | |||
for (it = fPortList.begin(); it != fPortList.end(); it++) { | |||
JackPort* port = GetGraphManager()->GetPort(*it); | |||
if (port->GetFlags() & JackPortIsOutput) { | |||
jack_latency_range_t other_latency; | |||
port->GetLatencyRange(mode, &other_latency); | |||
if (other_latency.max > latency.max) | |||
latency.max = other_latency.max; | |||
if (other_latency.min < latency.min) | |||
latency.min = other_latency.min; | |||
} | |||
} | |||
if (latency.min == UINT32_MAX) | |||
latency.min = 0; | |||
/* now set the found latency on all input ports | |||
*/ | |||
for (it = fPortList.begin(); it != fPortList.end(); it++) { | |||
JackPort* port = GetGraphManager()->GetPort(*it); | |||
if (port->GetFlags() & JackPortIsInput) { | |||
port->SetLatencyRange(mode, &latency); | |||
} | |||
} | |||
} | |||
if (mode == JackCaptureLatency) { | |||
/* iterate over all InputPorts, to find maximum playback latency | |||
*/ | |||
for (it = fPortList.begin(); it != fPortList.end(); it++) { | |||
JackPort* port = GetGraphManager()->GetPort(*it); | |||
if (port->GetFlags() & JackPortIsInput) { | |||
jack_latency_range_t other_latency; | |||
port->GetLatencyRange(mode, &other_latency); | |||
if (other_latency.max > latency.max) | |||
latency.max = other_latency.max; | |||
if (other_latency.min < latency.min) | |||
latency.min = other_latency.min; | |||
} | |||
} | |||
if (latency.min == UINT32_MAX) | |||
latency.min = 0; | |||
/* now set the found latency on all output ports | |||
*/ | |||
for (it = fPortList.begin(); it != fPortList.end(); it++) { | |||
JackPort* port = GetGraphManager()->GetPort(*it); | |||
if (port->GetFlags() & JackPortIsOutput) { | |||
port->SetLatencyRange(mode, &latency); | |||
} | |||
} | |||
} | |||
return 0; | |||
} | |||
/* we have a latency callback setup by the client, | |||
* lets use it... | |||
*/ | |||
fLatency(mode, fLatencyArg); | |||
return 0; | |||
} | |||
/*! | |||
\brief We need to start thread before activating in the server, otherwise the FW driver | |||
connected to the client may not be activated. | |||
@@ -1011,6 +1117,19 @@ int JackClient::SetSessionCallback(JackSessionCallback callback, void *arg) | |||
} | |||
} | |||
int JackClient::SetLatencyCallback(JackLatencyCallback callback, void *arg) | |||
{ | |||
if (IsActive()) { | |||
jack_error("You cannot set callbacks on an active client"); | |||
return -1; | |||
} else { | |||
GetClientControl()->fCallback[kLatencyCallback] = (callback != NULL); | |||
fLatencyArg = arg; | |||
fLatency = callback; | |||
return 0; | |||
} | |||
} | |||
//------------------ | |||
// Internal clients | |||
//------------------ | |||
@@ -67,6 +67,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface | |||
JackSyncCallback fSync; | |||
JackThreadCallback fThreadFun; | |||
JackSessionCallback fSession; | |||
JackLatencyCallback fLatency; | |||
void* fProcessArg; | |||
void* fGraphOrderArg; | |||
@@ -85,6 +86,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface | |||
void* fSyncArg; | |||
void* fThreadFunArg; | |||
void* fSessionArg; | |||
void* fLatencyArg; | |||
char fServerName[64]; | |||
JackThread fThread; /*! Thread to execute the Process function */ | |||
@@ -116,6 +118,8 @@ class JackClient : public JackClientInterface, public JackRunnableInterface | |||
inline void CallTimebaseCallbackAux(); | |||
inline int ActivateAux(); | |||
int HandleLatencyCallback(int status); | |||
public: | |||
JackClient(); | |||
@@ -178,6 +182,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface | |||
virtual int SetPortConnectCallback(JackPortConnectCallback callback, void *arg); | |||
virtual int SetPortRenameCallback(JackPortRenameCallback callback, void *arg); | |||
virtual int SetSessionCallback(JackSessionCallback callback, void *arg); | |||
virtual int SetLatencyCallback(JackLatencyCallback callback, void *arg); | |||
// Internal clients | |||
virtual char* GetInternalClientName(int ref); | |||
@@ -167,7 +167,7 @@ int JackDriver::Open(jack_nframes_t buffer_size, | |||
int JackDriver::Close() | |||
{ | |||
if (fClientControl.fRefNum >= 0) { | |||
if (fClientControl.fRefNum >= 0) { | |||
jack_log("JackDriver::Close"); | |||
fGraphManager->DirectDisconnect(fClientControl.fRefNum, fClientControl.fRefNum); // Disconnect driver from itself for sync | |||
fClientControl.fActive = false; | |||
@@ -207,7 +207,7 @@ int JackDriver::ClientNotify(int refnum, const char* name, int notify, int sync, | |||
jack_log("JackDriver::kStopFreewheel"); | |||
SetupDriverSync(fClientControl.fRefNum, false); | |||
break; | |||
} | |||
} | |||
return 0; | |||
} | |||
@@ -223,13 +223,13 @@ void JackDriver::CycleIncTime() | |||
} | |||
void JackDriver::CycleTakeBeginTime() | |||
{ | |||
{ | |||
fBeginDateUst = GetMicroSeconds(); // Take callback date here | |||
fEngineControl->CycleIncTime(fBeginDateUst); | |||
} | |||
void JackDriver::CycleTakeEndTime() | |||
{ | |||
{ | |||
fEndDateUst = GetMicroSeconds(); // Take end date here | |||
} | |||
@@ -254,7 +254,7 @@ void JackDriver::NotifySampleRate(jack_nframes_t sample_rate) | |||
fEngine->NotifySampleRate(sample_rate); | |||
fEngineControl->InitFrameTime(); | |||
} | |||
void JackDriver::NotifyFailure(int code, const char* reason) | |||
{ | |||
fEngine->NotifyFailure(code, reason); | |||
@@ -245,7 +245,7 @@ int JackGraphManager::RequestMonitor(jack_port_id_t port_index, bool onoff) // C | |||
// Client | |||
jack_nframes_t JackGraphManager::ComputeTotalLatencyAux(jack_port_id_t port_index, jack_port_id_t src_port_index, JackConnectionManager* manager, int hop_count) | |||
{ | |||
const jack_int_t* connections = manager->GetConnections(port_index); | |||
const jack_int_t* connections = ReadCurrentState()->GetConnections(port_index); | |||
jack_nframes_t max_latency = 0; | |||
jack_port_id_t dst_index; | |||
@@ -296,6 +296,46 @@ int JackGraphManager::ComputeTotalLatencies() | |||
return 0; | |||
} | |||
void JackGraphManager::RecalculateLatencyAux(jack_port_id_t port_index, jack_latency_callback_mode_t mode) | |||
{ | |||
const jack_int_t* connections = ReadCurrentState()->GetConnections(port_index); | |||
JackPort* port = GetPort(port_index); | |||
jack_latency_range_t latency = { UINT32_MAX, 0 }; | |||
jack_port_id_t dst_index; | |||
for (int i = 0; (i < CONNECTION_NUM_FOR_PORT) && ((dst_index = connections[i]) != EMPTY); i++) { | |||
AssertPort(dst_index); | |||
JackPort* dst_port = GetPort(dst_index); | |||
jack_latency_range_t other_latency; | |||
dst_port->GetLatencyRange(mode, &other_latency); | |||
if (other_latency.max > latency.max) | |||
latency.max = other_latency.max; | |||
if (other_latency.min < latency.min) | |||
latency.min = other_latency.min; | |||
} | |||
if (latency.min == UINT32_MAX) | |||
latency.min = 0; | |||
port->SetLatencyRange(mode, &latency); | |||
} | |||
void JackGraphManager::RecalculateLatency(jack_port_id_t port_index, jack_latency_callback_mode_t mode) | |||
{ | |||
UInt16 cur_index; | |||
UInt16 next_index; | |||
do { | |||
cur_index = GetCurrentIndex(); | |||
RecalculateLatencyAux(port_index, mode); | |||
next_index = GetCurrentIndex(); | |||
} while (cur_index != next_index); // Until a coherent state has been read | |||
jack_log("JackGraphManager::RecalculateLatency port_index = %ld", port_index); | |||
} | |||
// Server | |||
void JackGraphManager::SetBufferSize(jack_nframes_t buffer_size) | |||
{ | |||
@@ -53,6 +53,7 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState | |||
float* GetBuffer(jack_port_id_t port_index); | |||
void* GetBufferAux(JackConnectionManager* manager, jack_port_id_t port_index, jack_nframes_t frames); | |||
jack_nframes_t ComputeTotalLatencyAux(jack_port_id_t port_index, jack_port_id_t src_port_index, JackConnectionManager* manager, int hop_count); | |||
void RecalculateLatencyAux(jack_port_id_t port_index, jack_latency_callback_mode_t mode); | |||
public: | |||
@@ -72,8 +73,11 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState | |||
JackPort* GetPort(jack_port_id_t index); | |||
jack_port_id_t GetPort(const char* name); | |||
int ComputeTotalLatency(jack_port_id_t port_index); | |||
int ComputeTotalLatencies(); | |||
void RecalculateLatency(jack_port_id_t port_index, jack_latency_callback_mode_t mode); | |||
int RequestMonitor(jack_port_id_t port_index, bool onoff); | |||
// Connections management | |||
@@ -12,7 +12,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU Lesser General Public License for more details. | |||
You should have received a copy of the GNU Lesser General Public License | |||
along with this program; if not, write to the Free Software | |||
along with this program; if not, write to the Free Software | |||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
*/ | |||
@@ -46,6 +46,7 @@ enum NotificationType { | |||
kShutDownCallback = 15, | |||
kQUIT = 16, | |||
kSessionCallback = 17, | |||
kLatencyCallback = 18, | |||
kMaxNotification | |||
}; | |||
@@ -13,7 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU Lesser General Public License for more details. | |||
You should have received a copy of the GNU Lesser General Public License | |||
along with this program; if not, write to the Free Software | |||
along with this program; if not, write to the Free Software | |||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
*/ | |||
@@ -44,6 +44,8 @@ bool JackPort::Allocate(int refnum, const char* port_name, const char* port_type | |||
fInUse = true; | |||
fLatency = 0; | |||
fTotalLatency = 0; | |||
fPlaybackLatency.min = fPlaybackLatency.max = 0; | |||
fCaptureLatency.min = fCaptureLatency.max = 0; | |||
fTied = NO_PORT; | |||
// DB: At this point we do not know current buffer size in frames, | |||
// but every time buffer will be returned to any user, | |||
@@ -86,6 +88,48 @@ jack_nframes_t JackPort::GetTotalLatency() const | |||
void JackPort::SetLatency(jack_nframes_t nframes) | |||
{ | |||
fLatency = nframes; | |||
/* setup the new latency values here, | |||
* so we dont need to change the backend codes. | |||
*/ | |||
if (fFlags & JackPortIsOutput) { | |||
fCaptureLatency.min = nframes; | |||
fCaptureLatency.max = nframes; | |||
} | |||
if (fFlags & JackPortIsInput) { | |||
fPlaybackLatency.min = nframes; | |||
fPlaybackLatency.max = nframes; | |||
} | |||
} | |||
void JackPort::SetLatencyRange(jack_latency_callback_mode_t mode, jack_latency_range_t* range) | |||
{ | |||
if (mode == JackCaptureLatency) { | |||
fCaptureLatency = *range; | |||
/* hack to set port->shared->latency up for | |||
* backend ports | |||
*/ | |||
if ((fFlags & JackPortIsOutput) && (fFlags & JackPortIsPhysical)) | |||
fLatency = (range->min + range->max) / 2; | |||
} else { | |||
fPlaybackLatency = *range; | |||
/* hack to set port->shared->latency up for | |||
* backend ports | |||
*/ | |||
if ((fFlags & JackPortIsInput) && (fFlags & JackPortIsPhysical)) | |||
fLatency = (range->min + range->max) / 2; | |||
} | |||
} | |||
void JackPort::GetLatencyRange(jack_latency_callback_mode_t mode, jack_latency_range_t* range) const | |||
{ | |||
if (mode == JackCaptureLatency) { | |||
*range = fCaptureLatency; | |||
} else { | |||
*range = fPlaybackLatency; | |||
} | |||
} | |||
int JackPort::Tie(jack_port_id_t port_index) | |||
@@ -103,10 +147,10 @@ int JackPort::UnTie() | |||
int JackPort::RequestMonitor(bool onoff) | |||
{ | |||
/** | |||
jackd.h | |||
jackd.h | |||
* If @ref JackPortCanMonitor is set for this @a port, turn input | |||
* monitoring on or off. Otherwise, do nothing. | |||
if (!(fFlags & JackPortCanMonitor)) | |||
return -1; | |||
*/ | |||
@@ -123,10 +167,10 @@ int JackPort::RequestMonitor(bool onoff) | |||
int JackPort::EnsureMonitor(bool onoff) | |||
{ | |||
/** | |||
jackd.h | |||
jackd.h | |||
* If @ref JackPortCanMonitor is set for this @a port, turn input | |||
* monitoring on or off. Otherwise, do nothing. | |||
if (!(fFlags & JackPortCanMonitor)) | |||
return -1; | |||
*/ | |||
@@ -51,6 +51,8 @@ class SERVER_EXPORT JackPort | |||
jack_nframes_t fLatency; | |||
jack_nframes_t fTotalLatency; | |||
jack_latency_range_t fPlaybackLatency; | |||
jack_latency_range_t fCaptureLatency; | |||
uint8_t fMonitorRequests; | |||
bool fInUse; | |||
@@ -88,9 +90,13 @@ class SERVER_EXPORT JackPort | |||
int UnTie(); | |||
jack_nframes_t GetLatency() const; | |||
jack_nframes_t GetTotalLatency() const; | |||
void SetLatency(jack_nframes_t latency); | |||
void SetLatencyRange(jack_latency_callback_mode_t mode, jack_latency_range_t* range); | |||
void GetLatencyRange(jack_latency_callback_mode_t mode, jack_latency_range_t* range) const; | |||
jack_nframes_t GetTotalLatency() const; | |||
int RequestMonitor(bool onoff); | |||
int EnsureMonitor(bool onoff); | |||
bool MonitoringInput() | |||