Browse Source

New latency API implementation (in progress).

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4150 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/1.9.7
sletz 14 years ago
parent
commit
ae99359963
12 changed files with 328 additions and 13 deletions
  1. +1
    -0
      ChangeLog
  2. +58
    -0
      common/JackAPI.cpp
  3. +33
    -0
      common/JackAudioDriver.cpp
  4. +4
    -0
      common/JackAudioDriver.h
  5. +119
    -0
      common/JackClient.cpp
  6. +5
    -0
      common/JackClient.h
  7. +5
    -5
      common/JackDriver.cpp
  8. +41
    -1
      common/JackGraphManager.cpp
  9. +4
    -0
      common/JackGraphManager.h
  10. +2
    -1
      common/JackNotification.h
  11. +49
    -5
      common/JackPort.cpp
  12. +7
    -1
      common/JackPort.h

+ 1
- 0
ChangeLog View File

@@ -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. * 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. * Fix incorrect error codes in alsa/usx2y.c and alsa/JackAlsaDriver.cpp.
* Synchronize public headers with JACK1. Update OSX project. * Synchronize public headers with JACK1. Update OSX project.
* New latency API implementation (in progress).


2011-02-09 Stephane Letz <letz@grame.fr> 2011-02-09 Stephane Letz <letz@grame.fr>




+ 58
- 0
common/JackAPI.cpp View File

@@ -115,6 +115,9 @@ extern "C"
void *); void *);
EXPORT int jack_set_xrun_callback (jack_client_t *, EXPORT int jack_set_xrun_callback (jack_client_t *,
JackXRunCallback xrun_callback, void *arg); 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_activate (jack_client_t *client);
EXPORT int jack_deactivate (jack_client_t *client); EXPORT int jack_deactivate (jack_client_t *client);
EXPORT jack_port_t * jack_port_register (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); const jack_port_t *port);
EXPORT int jack_port_tie (jack_port_t *src, jack_port_t *dst); EXPORT int jack_port_tie (jack_port_t *src, jack_port_t *dst);
EXPORT int jack_port_untie (jack_port_t *port); 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_latency (jack_port_t *port);
EXPORT jack_nframes_t jack_port_get_total_latency (jack_client_t *, EXPORT jack_nframes_t jack_port_get_total_latency (jack_client_t *,
jack_port_t *port); jack_port_t *port);
EXPORT void jack_port_set_latency (jack_port_t *, jack_nframes_t); 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); 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_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_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_set_alias (jack_port_t *port, const char *alias);
EXPORT int jack_port_unset_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) EXPORT int jack_recompute_total_latency(jack_client_t* ext_client, jack_port_t* port)
{ {
#ifdef __CLIENTDEBUG__ #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) EXPORT int jack_set_thread_init_callback(jack_client_t* ext_client, JackThreadInitCallback init_callback, void *arg)
{ {
#ifdef __CLIENTDEBUG__ #ifdef __CLIENTDEBUG__


+ 33
- 0
common/JackAudioDriver.cpp View File

@@ -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); 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 } // end of namespace

+ 4
- 0
common/JackAudioDriver.h View File

@@ -57,6 +57,8 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver
jack_default_audio_sample_t* GetOutputBuffer(int port_index); jack_default_audio_sample_t* GetOutputBuffer(int port_index);
jack_default_audio_sample_t* GetMonitorBuffer(int port_index); jack_default_audio_sample_t* GetMonitorBuffer(int port_index);


void HandleLatencyCallback(int status);

public: public:


JackAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); 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 SetBufferSize(jack_nframes_t buffer_size);
virtual int SetSampleRate(jack_nframes_t sample_rate); 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 } // end of namespace


+ 119
- 0
common/JackClient.cpp View File

@@ -60,6 +60,9 @@ JackClient::JackClient(JackSynchro* table):fThread(this)
fTimebase = NULL; fTimebase = NULL;
fSync = NULL; fSync = NULL;
fThreadFun = NULL; fThreadFun = NULL;
fSession = NULL;
fLatency = NULL;

fProcessArg = NULL; fProcessArg = NULL;
fGraphOrderArg = NULL; fGraphOrderArg = NULL;
fXrunArg = NULL; fXrunArg = NULL;
@@ -75,6 +78,8 @@ JackClient::JackClient(JackSynchro* table):fThread(this)
fSyncArg = NULL; fSyncArg = NULL;
fTimebaseArg = NULL; fTimebaseArg = NULL;
fThreadFunArg = NULL; fThreadFunArg = NULL;
fSessionArg = NULL;
fLatencyArg = NULL;
} }


JackClient::~JackClient() JackClient::~JackClient()
@@ -289,12 +294,113 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync,
res = (fImmediateSessionReply) ? 1 : 2; res = (fImmediateSessionReply) ? 1 : 2;
} }
break; break;

case kLatencyCallback:
res = HandleLatencyCallback(value1);
break;
} }
} }


return res; 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 \brief We need to start thread before activating in the server, otherwise the FW driver
connected to the client may not be activated. 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 // Internal clients
//------------------ //------------------


+ 5
- 0
common/JackClient.h View File

@@ -67,6 +67,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface
JackSyncCallback fSync; JackSyncCallback fSync;
JackThreadCallback fThreadFun; JackThreadCallback fThreadFun;
JackSessionCallback fSession; JackSessionCallback fSession;
JackLatencyCallback fLatency;


void* fProcessArg; void* fProcessArg;
void* fGraphOrderArg; void* fGraphOrderArg;
@@ -85,6 +86,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface
void* fSyncArg; void* fSyncArg;
void* fThreadFunArg; void* fThreadFunArg;
void* fSessionArg; void* fSessionArg;
void* fLatencyArg;
char fServerName[64]; char fServerName[64];


JackThread fThread; /*! Thread to execute the Process function */ JackThread fThread; /*! Thread to execute the Process function */
@@ -116,6 +118,8 @@ class JackClient : public JackClientInterface, public JackRunnableInterface
inline void CallTimebaseCallbackAux(); inline void CallTimebaseCallbackAux();
inline int ActivateAux(); inline int ActivateAux();


int HandleLatencyCallback(int status);

public: public:


JackClient(); JackClient();
@@ -178,6 +182,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface
virtual int SetPortConnectCallback(JackPortConnectCallback callback, void *arg); virtual int SetPortConnectCallback(JackPortConnectCallback callback, void *arg);
virtual int SetPortRenameCallback(JackPortRenameCallback callback, void *arg); virtual int SetPortRenameCallback(JackPortRenameCallback callback, void *arg);
virtual int SetSessionCallback(JackSessionCallback callback, void *arg); virtual int SetSessionCallback(JackSessionCallback callback, void *arg);
virtual int SetLatencyCallback(JackLatencyCallback callback, void *arg);


// Internal clients // Internal clients
virtual char* GetInternalClientName(int ref); virtual char* GetInternalClientName(int ref);


+ 5
- 5
common/JackDriver.cpp View File

@@ -167,7 +167,7 @@ int JackDriver::Open(jack_nframes_t buffer_size,


int JackDriver::Close() int JackDriver::Close()
{ {
if (fClientControl.fRefNum >= 0) {
if (fClientControl.fRefNum >= 0) {
jack_log("JackDriver::Close"); jack_log("JackDriver::Close");
fGraphManager->DirectDisconnect(fClientControl.fRefNum, fClientControl.fRefNum); // Disconnect driver from itself for sync fGraphManager->DirectDisconnect(fClientControl.fRefNum, fClientControl.fRefNum); // Disconnect driver from itself for sync
fClientControl.fActive = false; fClientControl.fActive = false;
@@ -207,7 +207,7 @@ int JackDriver::ClientNotify(int refnum, const char* name, int notify, int sync,
jack_log("JackDriver::kStopFreewheel"); jack_log("JackDriver::kStopFreewheel");
SetupDriverSync(fClientControl.fRefNum, false); SetupDriverSync(fClientControl.fRefNum, false);
break; break;
}
}


return 0; return 0;
} }
@@ -223,13 +223,13 @@ void JackDriver::CycleIncTime()
} }


void JackDriver::CycleTakeBeginTime() void JackDriver::CycleTakeBeginTime()
{
{
fBeginDateUst = GetMicroSeconds(); // Take callback date here fBeginDateUst = GetMicroSeconds(); // Take callback date here
fEngineControl->CycleIncTime(fBeginDateUst); fEngineControl->CycleIncTime(fBeginDateUst);
} }


void JackDriver::CycleTakeEndTime() void JackDriver::CycleTakeEndTime()
{
{
fEndDateUst = GetMicroSeconds(); // Take end date here fEndDateUst = GetMicroSeconds(); // Take end date here
} }


@@ -254,7 +254,7 @@ void JackDriver::NotifySampleRate(jack_nframes_t sample_rate)
fEngine->NotifySampleRate(sample_rate); fEngine->NotifySampleRate(sample_rate);
fEngineControl->InitFrameTime(); fEngineControl->InitFrameTime();
} }
void JackDriver::NotifyFailure(int code, const char* reason) void JackDriver::NotifyFailure(int code, const char* reason)
{ {
fEngine->NotifyFailure(code, reason); fEngine->NotifyFailure(code, reason);


+ 41
- 1
common/JackGraphManager.cpp View File

@@ -245,7 +245,7 @@ int JackGraphManager::RequestMonitor(jack_port_id_t port_index, bool onoff) // C
// Client // Client
jack_nframes_t JackGraphManager::ComputeTotalLatencyAux(jack_port_id_t port_index, jack_port_id_t src_port_index, JackConnectionManager* manager, int hop_count) 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_nframes_t max_latency = 0;
jack_port_id_t dst_index; jack_port_id_t dst_index;


@@ -296,6 +296,46 @@ int JackGraphManager::ComputeTotalLatencies()
return 0; 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 // Server
void JackGraphManager::SetBufferSize(jack_nframes_t buffer_size) void JackGraphManager::SetBufferSize(jack_nframes_t buffer_size)
{ {


+ 4
- 0
common/JackGraphManager.h View File

@@ -53,6 +53,7 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState
float* GetBuffer(jack_port_id_t port_index); float* GetBuffer(jack_port_id_t port_index);
void* GetBufferAux(JackConnectionManager* manager, jack_port_id_t port_index, jack_nframes_t frames); 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); 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: public:


@@ -72,8 +73,11 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState


JackPort* GetPort(jack_port_id_t index); JackPort* GetPort(jack_port_id_t index);
jack_port_id_t GetPort(const char* name); jack_port_id_t GetPort(const char* name);

int ComputeTotalLatency(jack_port_id_t port_index); int ComputeTotalLatency(jack_port_id_t port_index);
int ComputeTotalLatencies(); 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); int RequestMonitor(jack_port_id_t port_index, bool onoff);


// Connections management // Connections management


+ 2
- 1
common/JackNotification.h View File

@@ -12,7 +12,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.


You should have received a copy of the GNU Lesser General Public License 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. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


*/ */
@@ -46,6 +46,7 @@ enum NotificationType {
kShutDownCallback = 15, kShutDownCallback = 15,
kQUIT = 16, kQUIT = 16,
kSessionCallback = 17, kSessionCallback = 17,
kLatencyCallback = 18,
kMaxNotification kMaxNotification
}; };




+ 49
- 5
common/JackPort.cpp View File

@@ -13,7 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.


You should have received a copy of the GNU Lesser General Public License 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. 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; fInUse = true;
fLatency = 0; fLatency = 0;
fTotalLatency = 0; fTotalLatency = 0;
fPlaybackLatency.min = fPlaybackLatency.max = 0;
fCaptureLatency.min = fCaptureLatency.max = 0;
fTied = NO_PORT; fTied = NO_PORT;
// DB: At this point we do not know current buffer size in frames, // DB: At this point we do not know current buffer size in frames,
// but every time buffer will be returned to any user, // 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) void JackPort::SetLatency(jack_nframes_t nframes)
{ {
fLatency = 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) int JackPort::Tie(jack_port_id_t port_index)
@@ -103,10 +147,10 @@ int JackPort::UnTie()
int JackPort::RequestMonitor(bool onoff) int JackPort::RequestMonitor(bool onoff)
{ {
/** /**
jackd.h
jackd.h
* If @ref JackPortCanMonitor is set for this @a port, turn input * If @ref JackPortCanMonitor is set for this @a port, turn input
* monitoring on or off. Otherwise, do nothing. * monitoring on or off. Otherwise, do nothing.
if (!(fFlags & JackPortCanMonitor)) if (!(fFlags & JackPortCanMonitor))
return -1; return -1;
*/ */
@@ -123,10 +167,10 @@ int JackPort::RequestMonitor(bool onoff)
int JackPort::EnsureMonitor(bool onoff) int JackPort::EnsureMonitor(bool onoff)
{ {
/** /**
jackd.h
jackd.h
* If @ref JackPortCanMonitor is set for this @a port, turn input * If @ref JackPortCanMonitor is set for this @a port, turn input
* monitoring on or off. Otherwise, do nothing. * monitoring on or off. Otherwise, do nothing.
if (!(fFlags & JackPortCanMonitor)) if (!(fFlags & JackPortCanMonitor))
return -1; return -1;
*/ */


+ 7
- 1
common/JackPort.h View File

@@ -51,6 +51,8 @@ class SERVER_EXPORT JackPort


jack_nframes_t fLatency; jack_nframes_t fLatency;
jack_nframes_t fTotalLatency; jack_nframes_t fTotalLatency;
jack_latency_range_t fPlaybackLatency;
jack_latency_range_t fCaptureLatency;
uint8_t fMonitorRequests; uint8_t fMonitorRequests;


bool fInUse; bool fInUse;
@@ -88,9 +90,13 @@ class SERVER_EXPORT JackPort
int UnTie(); int UnTie();


jack_nframes_t GetLatency() const; jack_nframes_t GetLatency() const;
jack_nframes_t GetTotalLatency() const;
void SetLatency(jack_nframes_t latency); 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 RequestMonitor(bool onoff);
int EnsureMonitor(bool onoff); int EnsureMonitor(bool onoff);
bool MonitoringInput() bool MonitoringInput()


Loading…
Cancel
Save