diff --git a/ChangeLog b/ChangeLog index 3be82cff..7b2dc8aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -34,6 +34,11 @@ Valerio Pilo Jackdmp changes log --------------------------- +2011-03-08 Stephane Letz + + * Use of latency range in all backends. + * ComputeTotalLatencies now a client/server call. + 2011-03-04 Stephane Letz * Revert r4119 (RT notification in the server). JackAudioDriver::ProcessSync now skip backend write in case of graph process failure. diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index 8bf5ca9b..6e2aa5e3 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -580,10 +580,10 @@ EXPORT int jack_recompute_total_latency(jack_client_t* ext_client, jack_port_t* uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (client == NULL) { - jack_error("jack_recompute_total_latencies called with a NULL client"); + jack_error("jack_recompute_total_latency called with a NULL client"); return -1; } else if (!CheckPort(myport)) { - jack_error("jack_recompute_total_latencies called with a NULL port"); + jack_error("jack_recompute_total_latency called with a NULL port"); return -1; } else { WaitGraphChange(); @@ -603,9 +603,7 @@ EXPORT int jack_recompute_total_latencies(jack_client_t* ext_client) jack_error("jack_recompute_total_latencies called with a NULL client"); return -1; } else { - WaitGraphChange(); - JackGraphManager* manager = GetGraphManager(); - return (manager ? manager->ComputeTotalLatencies() : -1); + return client->ComputeTotalLatencies(); } } diff --git a/common/JackAudioDriver.cpp b/common/JackAudioDriver.cpp index b9bd008a..1e02f213 100644 --- a/common/JackAudioDriver.cpp +++ b/common/JackAudioDriver.cpp @@ -101,6 +101,7 @@ int JackAudioDriver::Attach() jack_port_id_t port_index; char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + jack_latency_range_t range; int i; jack_log("JackAudioDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); @@ -114,7 +115,8 @@ int JackAudioDriver::Attach() } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - port->SetLatency(fEngineControl->fBufferSize + fCaptureLatency); + range.min = range.max = fEngineControl->fBufferSize + fCaptureLatency; + port->SetLatencyRange(JackCaptureLatency, &range); fCapturePortList[i] = port_index; jack_log("JackAudioDriver::Attach fCapturePortList[i] port_index = %ld", port_index); } @@ -129,7 +131,8 @@ int JackAudioDriver::Attach() port = fGraphManager->GetPort(port_index); port->SetAlias(alias); // Add more latency if "async" mode is used... - port->SetLatency(fEngineControl->fBufferSize + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + fPlaybackLatency); + range.min = range.max = fEngineControl->fBufferSize + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + fPlaybackLatency; + port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[i] = port_index; jack_log("JackAudioDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); @@ -143,7 +146,8 @@ int JackAudioDriver::Attach() } else { port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - port->SetLatency(fEngineControl->fBufferSize); + range.min = range.max = fEngineControl->fBufferSize; + port->SetLatencyRange(JackCaptureLatency, &range); fMonitorPortList[i] = port_index; } } diff --git a/common/JackChannel.h b/common/JackChannel.h index cbea58e4..16288151 100644 --- a/common/JackChannel.h +++ b/common/JackChannel.h @@ -108,6 +108,9 @@ class JackClientChannelInterface virtual void SetFreewheel(int onoff, int* result) {} + virtual void ComputeTotalLatencies(int* result) + {} + virtual void ReleaseTimebase(int refnum, int* result) {} diff --git a/common/JackClient.cpp b/common/JackClient.cpp index 729626d8..2eb0fead 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -718,6 +718,13 @@ int JackClient::SetFreeWheel(int onoff) return result; } +int JackClient::ComputeTotalLatencies() +{ + int result = -1; + fChannel->ComputeTotalLatencies(&result); + return result; +} + /* ShutDown is called: - from the RT thread when Execute method fails diff --git a/common/JackClient.h b/common/JackClient.h index 2ba0237c..71a2fbbe 100644 --- a/common/JackClient.h +++ b/common/JackClient.h @@ -141,6 +141,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface // Context virtual int SetBufferSize(jack_nframes_t buffer_size); virtual int SetFreeWheel(int onoff); + virtual int ComputeTotalLatencies(); virtual void ShutDown(); virtual jack_native_thread_t GetThreadID(); diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index f9dd6052..1559abd7 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -209,6 +209,12 @@ void JackEngine::CheckXRun(jack_time_t callback_usecs) // REVOIR les conditions } } +int JackEngine::ComputeTotalLatencies() +{ + // TODO : jack_compute_new_latency + return 0; +} + //--------------- // Notifications //--------------- @@ -295,6 +301,7 @@ void JackEngine::NotifyXRun(int refnum) void JackEngine::NotifyGraphReorder() { + ComputeTotalLatencies(); NotifyClients(kGraphOrderCallback, false, "", 0, 0); } diff --git a/common/JackEngine.h b/common/JackEngine.h index ae969cb7..710126e4 100644 --- a/common/JackEngine.h +++ b/common/JackEngine.h @@ -129,6 +129,8 @@ class SERVER_EXPORT JackEngine : public JackLockAble int PortRename(int refnum, jack_port_id_t port, const char* name); + int ComputeTotalLatencies(); + // Graph bool Process(jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end); @@ -142,8 +144,9 @@ class SERVER_EXPORT JackEngine : public JackLockAble void NotifyFreewheel(bool onoff); void NotifyQuit(); - void SessionNotify( int refnum, const char *target, jack_session_event_type_t type, const char *path, JackChannelTransaction *socket ); - void SessionReply( int refnum ); + // Session management + void SessionNotify(int refnum, const char *target, jack_session_event_type_t type, const char *path, JackChannelTransaction *socket); + void SessionReply(int refnum); void GetUUIDForClientName(const char *client_name, char *uuid_res, int *result); void GetClientNameForUUID(const char *uuid, char *name_res, int *result); diff --git a/common/JackInternalClientChannel.h b/common/JackInternalClientChannel.h index 8deb6b7b..96e0715c 100644 --- a/common/JackInternalClientChannel.h +++ b/common/JackInternalClientChannel.h @@ -112,6 +112,11 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface *result = fServer->SetFreewheel(onoff); } + void ComputeTotalLatencies(int* result) + { + *result = fEngine->ComputeTotalLatencies(); + } + void SessionNotify( int refnum, const char *target, jack_session_event_type_t type, const char *path, jack_session_command_t **result ) { *result = NULL; @@ -126,7 +131,7 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface { *result = fServer->SetTimebaseCallback(refnum, conditional); } - + void GetInternalClientName(int refnum, int int_ref, char* name_res, int* result) { *result = fEngine->GetInternalClientName(int_ref, name_res); @@ -139,7 +144,7 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result) { - *result = fServer->InternalClientLoad(client_name, so_name, objet_data, options, int_ref, uuid, status); + *result = fServer->InternalClientLoad(client_name, so_name, objet_data, options, int_ref, uuid, status); } void InternalClientUnload(int refnum, int int_ref, int* status, int* result) diff --git a/common/JackLockedEngine.h b/common/JackLockedEngine.h index b1620859..3a53d709 100644 --- a/common/JackLockedEngine.h +++ b/common/JackLockedEngine.h @@ -66,7 +66,7 @@ catch (...) { \brief Locked Engine, access to methods is serialized using a mutex. */ -class SERVER_EXPORT JackLockedEngine +class SERVER_EXPORT JackLockedEngine { private: @@ -94,7 +94,7 @@ class SERVER_EXPORT JackLockedEngine return fEngine.Close(); CATCH_EXCEPTION_RETURN } - + // Client management int ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status) { @@ -226,6 +226,14 @@ class SERVER_EXPORT JackLockedEngine CATCH_EXCEPTION_RETURN } + int ComputeTotalLatencies() + { + TRY_CALL + JackLock lock(&fEngine); + return fEngine.ComputeTotalLatencies(); + CATCH_EXCEPTION_RETURN + } + // Graph bool Process(jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end) { @@ -245,7 +253,7 @@ class SERVER_EXPORT JackLockedEngine // RT : no lock fEngine.NotifyXRun(refnum); } - + void NotifyGraphReorder() { TRY_CALL @@ -298,7 +306,7 @@ class SERVER_EXPORT JackLockedEngine return fEngine.GetClientRefNum(name); CATCH_EXCEPTION_RETURN } - + void NotifyQuit() { TRY_CALL @@ -314,7 +322,7 @@ class SERVER_EXPORT JackLockedEngine fEngine.SessionNotify(refnum, target, type, path, socket); CATCH_EXCEPTION } - + void SessionReply(int refnum) { TRY_CALL @@ -322,7 +330,7 @@ class SERVER_EXPORT JackLockedEngine fEngine.SessionReply(refnum); CATCH_EXCEPTION } - + void GetUUIDForClientName(const char *client_name, char *uuid_res, int *result) { TRY_CALL diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index 5f5af5db..d2327eb1 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -118,10 +118,10 @@ namespace Jack //init and restart-------------------------------------------------------------------- /* - JackNetDriver is wrapped in a JackWaitThreadedDriver decorator that behaves + JackNetDriver is wrapped in a JackWaitThreadedDriver decorator that behaves as a "dummy driver, until Init method returns. */ - + bool JackNetDriver::Initialize() { jack_log("JackNetDriver::Initialize()"); @@ -147,7 +147,7 @@ namespace Jack //set global parameters SetParams(); - + //allocate midi ports lists fMidiCapturePortList = new jack_port_id_t [fParams.fSendMidiChannels]; fMidiPlaybackPortList = new jack_port_id_t [fParams.fReturnMidiChannels]; @@ -216,7 +216,7 @@ namespace Jack void JackNetDriver::FreeAll() { FreePorts(); - + delete[] fTxBuffer; delete[] fRxBuffer; delete fNetAudioCaptureBuffer; @@ -225,7 +225,7 @@ namespace Jack delete fNetMidiPlaybackBuffer; delete[] fMidiCapturePortList; delete[] fMidiPlaybackPortList; - + fTxBuffer = NULL; fRxBuffer = NULL; fNetAudioCaptureBuffer = NULL; @@ -234,7 +234,7 @@ namespace Jack fNetMidiPlaybackBuffer = NULL; fMidiCapturePortList = NULL; fMidiPlaybackPortList = NULL; - + #ifdef JACK_MONITOR delete fNetTimeMon; fNetTimeMon = NULL; @@ -253,6 +253,7 @@ namespace Jack unsigned long port_flags; int audio_port_index; uint midi_port_index; + jack_latency_range_t range; //audio port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; @@ -269,7 +270,8 @@ namespace Jack port = fGraphManager->GetPort ( port_id ); port->SetAlias ( alias ); //port latency - port->SetLatency ( fEngineControl->fBufferSize ); + range.min = range.max = fEngineControl->fBufferSize; + port->SetLatencyRange(JackCaptureLatency, &range); fCapturePortList[audio_port_index] = port_id; jack_log ( "JackNetDriver::AllocPorts() fCapturePortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_id, port->GetLatency() ); } @@ -290,15 +292,16 @@ namespace Jack switch ( fParams.fNetworkMode ) { case 'f' : - port->SetLatency ( ( fEngineControl->fSyncMode ) ? 0 : fEngineControl->fBufferSize ); + range.min = range.max = (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize; break; case 'n' : - port->SetLatency ( fEngineControl->fBufferSize + ( fEngineControl->fSyncMode ) ? 0 : fEngineControl->fBufferSize ); + range.min = range.max = (fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize); break; case 's' : - port->SetLatency ( 2 * fEngineControl->fBufferSize + ( fEngineControl->fSyncMode ) ? 0 : fEngineControl->fBufferSize ); + range.min = range.max = (2 * fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize); break; } + port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[audio_port_index] = port_id; jack_log ( "JackNetDriver::AllocPorts() fPlaybackPortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_id, port->GetLatency() ); } @@ -316,7 +319,8 @@ namespace Jack } port = fGraphManager->GetPort ( port_id ); //port latency - port->SetLatency ( fEngineControl->fBufferSize ); + range.min = range.max = fEngineControl->fBufferSize; + port->SetLatencyRange(JackCaptureLatency, &range); fMidiCapturePortList[midi_port_index] = port_id; jack_log ( "JackNetDriver::AllocPorts() fMidiCapturePortList[%d] midi_port_index = %ld fPortLatency = %ld", midi_port_index, port_id, port->GetLatency() ); } @@ -337,15 +341,16 @@ namespace Jack switch ( fParams.fNetworkMode ) { case 'f' : - port->SetLatency ( ( fEngineControl->fSyncMode ) ? 0 : fEngineControl->fBufferSize ); + range.min = range.max = (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize; break; case 'n' : - port->SetLatency ( fEngineControl->fBufferSize + ( fEngineControl->fSyncMode ) ? 0 : fEngineControl->fBufferSize ) ; + range.min = range.max = (fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize); break; case 's' : - port->SetLatency ( 2 * fEngineControl->fBufferSize + ( fEngineControl->fSyncMode ) ? 0 : fEngineControl->fBufferSize ); + range.min = range.max = (2 * fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize); break; } + port->SetLatencyRange(JackPlaybackLatency, &range); fMidiPlaybackPortList[midi_port_index] = port_id; jack_log ( "JackNetDriver::AllocPorts() fMidiPlaybackPortList[%d] midi_port_index = %ld fPortLatency = %ld", midi_port_index, port_id, port->GetLatency() ); } @@ -404,7 +409,7 @@ namespace Jack //is there a transport state change to handle ? if ( fSendTransportData.fNewState && ( fSendTransportData.fState != fEngineControl->fTransport.GetState() ) ) { - + switch ( fSendTransportData.fState ) { case JackTransportStopped : @@ -453,13 +458,13 @@ namespace Jack else fReturnTransportData.fTimebaseMaster = NO_CHANGE; */ - + //update transport state and position fReturnTransportData.fState = fEngineControl->fTransport.Query ( &fReturnTransportData.fPosition ); - + //is it a new state (that the master need to know...) ? fReturnTransportData.fNewState = (( fReturnTransportData.fState == JackTransportNetStarting) && - ( fReturnTransportData.fState != fLastTransportState ) && + ( fReturnTransportData.fState != fLastTransportState ) && ( fReturnTransportData.fState != fSendTransportData.fState ) ); if ( fReturnTransportData.fNewState ) jack_info ( "Sending '%s'.", GetTransportState ( fReturnTransportData.fState ) ); @@ -487,14 +492,14 @@ namespace Jack return 0; #ifdef JACK_MONITOR - // For timing + // For timing fRcvSyncUst = GetMicroSeconds(); #endif //decode sync //if there is an error, don't return -1, it will skip Write() and the network error probably won't be identified DecodeSyncPacket(); - + #ifdef JACK_MONITOR fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - fRcvSyncUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); #endif @@ -529,7 +534,7 @@ namespace Jack //sync EncodeSyncPacket(); - + //send sync if ( SyncSend() == SOCKET_ERROR ) return SOCKET_ERROR; diff --git a/common/JackRequest.h b/common/JackRequest.h index c83753a3..a4f2fe3b 100644 --- a/common/JackRequest.h +++ b/common/JackRequest.h @@ -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. */ @@ -71,7 +71,8 @@ struct JackRequest kSessionReply = 34, kGetClientByUUID = 35, kReserveClientName = 36, - kGetUUIDByClient = 37 + kGetUUIDByClient = 37, + kComputeTotalLatencies = 38 }; RequestType fType; @@ -122,7 +123,7 @@ struct JackResult { return trans->Write(&fResult, sizeof(int)); } - + }; /*! @@ -161,7 +162,7 @@ struct JackClientCheckRequest : public JackRequest CheckRes(trans->Write(&fOptions, sizeof(int))); return trans->Write(&fUUID, sizeof(int)); } - + }; /*! @@ -197,7 +198,7 @@ struct JackClientCheckResult : public JackResult CheckRes(trans->Write(&fStatus, sizeof(int))); return 0; } - + }; /*! @@ -210,7 +211,7 @@ struct JackClientOpenRequest : public JackRequest int fPID; int fUUID; char fName[JACK_CLIENT_NAME_SIZE + 1]; - + JackClientOpenRequest() {} JackClientOpenRequest(const char* name, int pid, int uuid): JackRequest(JackRequest::kClientOpen) @@ -234,7 +235,7 @@ struct JackClientOpenRequest : public JackRequest CheckRes(trans->Write(&fUUID, sizeof(int))); return trans->Write(&fName, sizeof(fName)); } - + }; /*! @@ -247,7 +248,7 @@ struct JackClientOpenResult : public JackResult int fSharedEngine; int fSharedClient; int fSharedGraph; - + JackClientOpenResult() : JackResult(), fSharedEngine(-1), fSharedClient(-1), fSharedGraph(-1) {} @@ -272,7 +273,7 @@ struct JackClientOpenResult : public JackResult CheckRes(trans->Write(&fSharedGraph, sizeof(int))); return 0; } - + }; /*! @@ -299,7 +300,7 @@ struct JackClientCloseRequest : public JackRequest CheckRes(JackRequest::Write(trans)); return trans->Write(&fRefNum, sizeof(int)); } - + }; /*! @@ -402,7 +403,7 @@ struct JackPortRegisterRequest : public JackRequest CheckRes(trans->Write(&fBufferSize, sizeof(unsigned int))); return 0; } - + }; /*! @@ -428,7 +429,7 @@ struct JackPortRegisterResult : public JackResult CheckRes(JackResult::Write(trans)); return trans->Write(&fPortIndex, sizeof(jack_port_id_t)); } - + }; /*! @@ -461,7 +462,7 @@ struct JackPortUnRegisterRequest : public JackRequest CheckRes(trans->Write(&fPortIndex, sizeof(jack_port_id_t))); return 0; } - + }; /*! @@ -501,7 +502,7 @@ struct JackPortConnectNameRequest : public JackRequest CheckRes(trans->Write(&fDst, sizeof(fDst))); return 0; } - + }; /*! @@ -540,7 +541,7 @@ struct JackPortDisconnectNameRequest : public JackRequest CheckRes(trans->Write(&fDst, sizeof(fDst))); return 0; } - + }; /*! @@ -576,7 +577,7 @@ struct JackPortConnectRequest : public JackRequest CheckRes(trans->Write(&fDst, sizeof(jack_port_id_t))); return 0; } - + }; /*! @@ -612,7 +613,7 @@ struct JackPortDisconnectRequest : public JackRequest CheckRes(trans->Write(&fDst, sizeof(jack_port_id_t))); return 0; } - + }; /*! @@ -651,7 +652,7 @@ struct JackPortRenameRequest : public JackRequest return 0; } - + }; /*! @@ -679,7 +680,7 @@ struct JackSetBufferSizeRequest : public JackRequest CheckRes(JackRequest::Write(trans)); return trans->Write(&fBufferSize, sizeof(jack_nframes_t)); } - + }; /*! @@ -707,7 +708,31 @@ struct JackSetFreeWheelRequest : public JackRequest CheckRes(JackRequest::Write(trans)); return trans->Write(&fOnOff, sizeof(int)); } - + +}; + +/*! +\brief ComputeTotalLatencies request. +*/ + +struct JackComputeTotalLatenciesRequest : public JackRequest +{ + + JackComputeTotalLatenciesRequest() + : JackRequest(JackRequest::kComputeTotalLatencies) + {} + + int Read(JackChannelTransaction* trans) + { + return 0; + } + + int Write(JackChannelTransaction* trans) + { + CheckRes(JackRequest::Write(trans)); + return 0; + } + }; /*! @@ -735,7 +760,7 @@ struct JackReleaseTimebaseRequest : public JackRequest CheckRes(JackRequest::Write(trans)); return trans->Write(&fRefNum, sizeof(int)); } - + }; /*! @@ -766,7 +791,7 @@ struct JackSetTimebaseCallbackRequest : public JackRequest CheckRes(trans->Write(&fRefNum, sizeof(int))); return trans->Write(&fConditionnal, sizeof(int)); } - + }; /*! @@ -797,7 +822,7 @@ struct JackGetInternalClientNameRequest : public JackRequest CheckRes(trans->Write(&fRefNum, sizeof(int))); return trans->Write(&fIntRefNum, sizeof(int)); } - + }; /*! @@ -830,7 +855,7 @@ struct JackGetInternalClientNameResult : public JackResult CheckRes(trans->Write(&fName, sizeof(fName))); return 0; } - + }; /*! @@ -863,7 +888,7 @@ struct JackInternalClientHandleRequest : public JackRequest CheckRes(trans->Write(&fRefNum, sizeof(int))); return trans->Write(&fName, sizeof(fName)); } - + }; /*! @@ -897,7 +922,7 @@ struct JackInternalClientHandleResult : public JackResult CheckRes(trans->Write(&fIntRefNum, sizeof(int))); return 0; } - + }; /*! @@ -949,7 +974,7 @@ struct JackInternalClientLoadRequest : public JackRequest CheckRes(trans->Write(&fUUID, sizeof(int))); return trans->Write(&fOptions, sizeof(int)); } - + }; /*! @@ -983,7 +1008,7 @@ struct JackInternalClientLoadResult : public JackResult CheckRes(trans->Write(&fIntRefNum, sizeof(int))); return 0; } - + }; /*! @@ -1044,7 +1069,7 @@ struct JackInternalClientUnloadResult : public JackResult CheckRes(trans->Write(&fStatus, sizeof(int))); return 0; } - + }; /*! @@ -1147,7 +1172,7 @@ struct JackSessionNotifyResult : public JackResult CheckRes(trans->Write(terminator, sizeof(terminator))); return 0; } - + }; /*! @@ -1245,7 +1270,7 @@ struct JackClientNameResult : public JackResult CheckRes(trans->Write(&fName, sizeof(fName))); return 0; } - + }; struct JackUUIDResult : public JackResult @@ -1274,7 +1299,7 @@ struct JackUUIDResult : public JackResult CheckRes(trans->Write(&fUUID, sizeof(fUUID))); return 0; } - + }; struct JackGetUUIDRequest : public JackRequest diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index 756c2cdc..fdf5a0cb 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -2084,6 +2084,7 @@ int JackAlsaDriver::Attach() unsigned long port_flags; char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + jack_latency_range_t range; assert(fCaptureChannels < DRIVER_PORT_NUM); assert(fPlaybackChannels < DRIVER_PORT_NUM); @@ -2110,7 +2111,8 @@ int JackAlsaDriver::Attach() } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - port->SetLatency(alsa_driver->frames_per_cycle + alsa_driver->capture_frame_latency); + range.min = range.max = alsa_driver->frames_per_cycle + alsa_driver->capture_frame_latency; + port->SetLatencyRange(JackCaptureLatency, &range); fCapturePortList[i] = port_index; jack_log("JackAudioDriver::Attach fCapturePortList[i] %ld ", port_index); } @@ -2127,8 +2129,10 @@ int JackAlsaDriver::Attach() port = fGraphManager->GetPort(port_index); port->SetAlias(alias); // Add one buffer more latency if "async" mode is used... - port->SetLatency((alsa_driver->frames_per_cycle * (alsa_driver->user_nperiods - 1)) + - ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + alsa_driver->playback_frame_latency); + range.min = range.max = (alsa_driver->frames_per_cycle * (alsa_driver->user_nperiods - 1)) + + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + alsa_driver->playback_frame_latency; + + port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[i] = port_index; jack_log("JackAudioDriver::Attach fPlaybackPortList[i] %ld ", port_index); @@ -2140,7 +2144,8 @@ int JackAlsaDriver::Attach() jack_error ("ALSA: cannot register monitor port for %s", name); } else { port = fGraphManager->GetPort(port_index); - port->SetLatency(alsa_driver->frames_per_cycle); + range.min = range.max = alsa_driver->frames_per_cycle; + port->SetLatencyRange(JackCaptureLatency, &range); fMonitorPortList[i] = port_index; } } diff --git a/linux/firewire/JackFFADODriver.cpp b/linux/firewire/JackFFADODriver.cpp index 5400df76..486c3794 100644 --- a/linux/firewire/JackFFADODriver.cpp +++ b/linux/firewire/JackFFADODriver.cpp @@ -272,7 +272,7 @@ JackFFADODriver::SetBufferSize (jack_nframes_t nframes) printError("Buffer size change requested but not supported!!!"); /* - driver->period_size = nframes; + driver->period_size = nframes; driver->period_usecs = (jack_time_t) floor ((((float) nframes) / driver->sample_rate) * 1000000.0f); @@ -362,6 +362,7 @@ int JackFFADODriver::Attach() int port_index; char buf[JACK_PORT_NAME_SIZE]; char portname[JACK_PORT_NAME_SIZE]; + jack_latency_range_t range; ffado_driver_t* driver = (ffado_driver_t*)fDriver; @@ -447,7 +448,8 @@ int JackFFADODriver::Attach() ffado_streaming_capture_stream_onoff(driver->dev, chn, 0); port = fGraphManager->GetPort(port_index); - port->SetLatency(driver->period_size + driver->capture_frame_latency); + range.min = range.max = driver->period_size + driver->capture_frame_latency; + port->SetLatencyRange(JackCaptureLatency, &range); // capture port aliases (jackd1 style port names) snprintf(buf, sizeof(buf) - 1, "%s:capture_%i", fClientControl.fName, (int) chn + 1); port->SetAlias(buf); @@ -479,7 +481,8 @@ int JackFFADODriver::Attach() driver->capture_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t)); port = fGraphManager->GetPort(port_index); - port->SetLatency(driver->period_size + driver->capture_frame_latency); + range.min = range.max = driver->period_size + driver->capture_frame_latency; + port->SetLatencyRange(JackCaptureLatency, &range); fCapturePortList[chn] = port_index; jack_log("JackFFADODriver::Attach fCapturePortList[i] %ld ", port_index); fCaptureChannels++; @@ -523,7 +526,8 @@ int JackFFADODriver::Attach() port = fGraphManager->GetPort(port_index); // Add one buffer more latency if "async" mode is used... - port->SetLatency((driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency); + range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency + port->SetLatencyRange(JackPlaybackLatency, &range); // playback port aliases (jackd1 style port names) snprintf(buf, sizeof(buf) - 1, "%s:playback_%i", fClientControl.fName, (int) chn + 1); port->SetAlias(buf); @@ -549,7 +553,7 @@ int JackFFADODriver::Attach() printError(" cannot enable port %s", buf); } // setup the midi buffer - + // This constructor optionally accepts arguments for the // non-realtime buffer size and the realtime buffer size. Ideally, // these would become command-line options for the FFADO driver. @@ -558,7 +562,8 @@ int JackFFADODriver::Attach() driver->playback_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t)); port = fGraphManager->GetPort(port_index); - port->SetLatency((driver->period_size * (driver->device_options.nb_buffers - 1)) + driver->playback_frame_latency); + range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + driver->playback_frame_latency; + port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[chn] = port_index; jack_log("JackFFADODriver::Attach fPlaybackPortList[i] %ld ", port_index); fPlaybackChannels++; @@ -676,7 +681,7 @@ retry: if (nframes == 0) { /* we detected an xrun and restarted: notify - * clients about the delay. + * clients about the delay. */ jack_log("FFADO XRun"); NotifyXRun(fBeginDateUst, fDelayedUsecs); @@ -685,7 +690,7 @@ retry: if (nframes != fEngineControl->fBufferSize) jack_log("JackFFADODriver::Read warning nframes = %ld", nframes); - + // Has to be done before read JackDriver::CycleIncTime(); @@ -755,7 +760,7 @@ extern "C" strcpy (desc->name, "firewire"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->desc, "Linux FFADO API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - + desc->nparams = 13; params = (jack_driver_param_desc_t *)calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); diff --git a/linux/freebob/JackFreebobDriver.cpp b/linux/freebob/JackFreebobDriver.cpp index 47860f21..552e9927 100644 --- a/linux/freebob/JackFreebobDriver.cpp +++ b/linux/freebob/JackFreebobDriver.cpp @@ -260,7 +260,7 @@ JackFreebobDriver::SetBufferSize (jack_nframes_t nframes) printError("Buffer size change requested but not supported!!!"); /* - driver->period_size = nframes; + driver->period_size = nframes; driver->period_usecs = (jack_time_t) floor ((((float) nframes) / driver->sample_rate) * 1000000.0f); @@ -667,9 +667,10 @@ int JackFreebobDriver::Attach() { JackPort* port; int port_index; - + char buf[JACK_PORT_NAME_SIZE]; char portname[JACK_PORT_NAME_SIZE]; + jack_latency_range_t range; freebob_driver_t* driver = (freebob_driver_t*)fDriver; @@ -737,7 +738,8 @@ int JackFreebobDriver::Attach() return -1; } port = fGraphManager->GetPort(port_index); - port->SetLatency(driver->period_size + driver->capture_frame_latency); + range.min = range.max = driver->period_size + driver->capture_frame_latency; + port->SetLatencyRange(JackCaptureLatency, &range); fCapturePortList[i] = port_index; jack_log("JackFreebobDriver::Attach fCapturePortList[i] %ld ", port_index); driver->capture_nchannels_audio++; @@ -766,7 +768,8 @@ int JackFreebobDriver::Attach() } port = fGraphManager->GetPort(port_index); // Add one buffer more latency if "async" mode is used... - port->SetLatency((driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency); + range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency); + port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[i] = port_index; jack_log("JackFreebobDriver::Attach fPlaybackPortList[i] %ld ", port_index); driver->playback_nchannels_audio++; @@ -866,7 +869,7 @@ retry: if (nframes == 0) { /* we detected an xrun and restarted: notify - * clients about the delay. + * clients about the delay. */ jack_log("FreeBoB XRun"); NotifyXRun(fBeginDateUst, fDelayedUsecs); @@ -878,7 +881,7 @@ retry: // Has to be done before read JackDriver::CycleIncTime(); - + printExit(); return freebob_driver_read((freebob_driver_t *)fDriver, fEngineControl->fBufferSize); } @@ -944,7 +947,7 @@ extern "C" strcpy (desc->name, "freebob"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->desc, "Linux FreeBob API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - + desc->nparams = 11; params = (jack_driver_param_desc_t *)calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index d6d1fe02..6f37deff 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -408,6 +408,10 @@ 4B4F9C930DC20C0400706CB0 /* JackMessageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4F9C8B0DC20C0400706CB0 /* JackMessageBuffer.h */; }; 4B4F9D820DC2178E00706CB0 /* JackMessageBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4F9C8A0DC20C0400706CB0 /* JackMessageBuffer.cpp */; }; 4B4F9D830DC2178F00706CB0 /* JackMessageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4F9C8B0DC20C0400706CB0 /* JackMessageBuffer.h */; }; + 4B5160A813215E8B00BB7DCB /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B5160A913215EBF00BB7DCB /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B5160AA13215ED900BB7DCB /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B5160AE13215EF900BB7DCB /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B5A1BBE0CD1CC110005BF74 /* midiseq.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B5A1BBD0CD1CC110005BF74 /* midiseq.c */; }; 4B5A1BDD0CD1CD420005BF74 /* midisine.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B5A1BDC0CD1CD420005BF74 /* midisine.c */; }; 4B5DB9830CD2429A00EBA5EE /* JackDebugClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B98AE000931D30C0091932A /* JackDebugClient.cpp */; }; @@ -3098,6 +3102,7 @@ 4B88D04011298BEE007A87C1 /* weakmacros.h in Headers */, 4B8A38F0117B827900664E07 /* JackSocket.h in Headers */, 4B8A38F7117B82B200664E07 /* JackSocketClientChannel.h in Headers */, + 4B5160A813215E8B00BB7DCB /* systemdeps.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3170,6 +3175,7 @@ 4B8A38AD117B810A00664E07 /* JackSocketNotifyChannel.h in Headers */, 4B8A38B0117B812500664E07 /* JackSocketServerChannel.h in Headers */, 4B8A38C4117B814000664E07 /* JackSocketServerNotifyChannel.h in Headers */, + 4B5160AA13215ED900BB7DCB /* systemdeps.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3450,6 +3456,7 @@ 4B47ACAB10B5890100469C67 /* JackProcessSync.h in Headers */, 4B88D04111298BEE007A87C1 /* weakjack.h in Headers */, 4B88D04211298BEE007A87C1 /* weakmacros.h in Headers */, + 4B5160A913215EBF00BB7DCB /* systemdeps.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3794,6 +3801,7 @@ 4B88D04611298BEE007A87C1 /* weakmacros.h in Headers */, 4BC2CA5E113C6CCA0076717C /* JackNetInterface.h in Headers */, 4BC2CA60113C6CD20076717C /* JackNetUnixSocket.h in Headers */, + 4B5160AE13215EF900BB7DCB /* systemdeps.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 1995edbb..03e22adf 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -1569,6 +1569,7 @@ int JackCoreAudioDriver::Attach() char channel_name[64]; char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + jack_latency_range_t range; jack_log("JackCoreAudioDriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); @@ -1605,7 +1606,8 @@ int JackCoreAudioDriver::Attach() port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - port->SetLatency(fEngineControl->fBufferSize + value1 + value2 + fCaptureLatency); + range.min = range.max = fEngineControl->fBufferSize + value1 + value2 + fCaptureLatency; + port->SetLatencyRange(JackCaptureLatency, &range); fCapturePortList[i] = port_index; } @@ -1643,7 +1645,8 @@ int JackCoreAudioDriver::Attach() port = fGraphManager->GetPort(port_index); port->SetAlias(alias); // Add more latency if "async" mode is used... - port->SetLatency(fEngineControl->fBufferSize + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize * fIOUsage) + value1 + value2 + fPlaybackLatency); + range.min = range.max = fEngineControl->fBufferSize + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize * fIOUsage) + value1 + value2 + fPlaybackLatency; + port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[i] = port_index; // Monitor ports @@ -1656,7 +1659,8 @@ int JackCoreAudioDriver::Attach() } else { port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - port->SetLatency(fEngineControl->fBufferSize); + range.min = range.max = fEngineControl->fBufferSize; + port->SetLatencyRange(JackCaptureLatency, &range); fMonitorPortList[i] = port_index; } } diff --git a/posix/JackSocketClientChannel.cpp b/posix/JackSocketClientChannel.cpp index 1a6d7ad5..65f56d96 100644 --- a/posix/JackSocketClientChannel.cpp +++ b/posix/JackSocketClientChannel.cpp @@ -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. */ @@ -246,6 +246,13 @@ void JackSocketClientChannel::SetFreewheel(int onoff, int* result) ServerSyncCall(&req, &res, result); } +void JackSocketClientChannel::ComputeTotalLatencies(int* result) +{ + JackComputeTotalLatenciesRequest req; + JackResult res; + ServerSyncCall(&req, &res, result); +} + void JackSocketClientChannel::SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t ** result) { JackSessionNotifyRequest req(refnum, path, type, target); @@ -255,22 +262,20 @@ void JackSocketClientChannel::SessionNotify(int refnum, const char* target, jack jack_session_command_t *session_command = (jack_session_command_t *)malloc( sizeof(jack_session_command_t) * (res.fCommandList.size()+1) ); int i=0; - + for (std::list::iterator ci=res.fCommandList.begin(); ci!=res.fCommandList.end(); ci++) { - session_command[i].uuid = strdup( ci->fUUID ); - session_command[i].client_name = strdup( ci->fClientName ); - session_command[i].command = strdup( ci->fCommand ); - session_command[i].flags = ci->fFlags; - - i+=1; - } - + session_command[i].uuid = strdup( ci->fUUID ); + session_command[i].client_name = strdup( ci->fClientName ); + session_command[i].command = strdup( ci->fCommand ); + session_command[i].flags = ci->fFlags; + i+=1; + } + session_command[i].uuid = NULL; session_command[i].client_name = NULL; session_command[i].command = NULL; session_command[i].flags = (jack_session_flags_t)0; - *result = session_command; } diff --git a/posix/JackSocketClientChannel.h b/posix/JackSocketClientChannel.h index 225887e7..c2e4eb69 100644 --- a/posix/JackSocketClientChannel.h +++ b/posix/JackSocketClientChannel.h @@ -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. */ @@ -77,12 +77,14 @@ class JackSocketClientChannel : public detail::JackClientChannelInterface, publi void PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result); void PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result); - + void PortRename(int refnum, jack_port_id_t port, const char* name, int* result); void SetBufferSize(jack_nframes_t buffer_size, int* result); void SetFreewheel(int onoff, int* result); + void ComputeTotalLatencies(int* result); + void ReleaseTimebase(int refnum, int* result); void SetTimebaseCallback(int refnum, int conditional, int* result); diff --git a/posix/JackSocketServerChannel.cpp b/posix/JackSocketServerChannel.cpp index c3741d55..84ee108f 100644 --- a/posix/JackSocketServerChannel.cpp +++ b/posix/JackSocketServerChannel.cpp @@ -332,6 +332,17 @@ bool JackSocketServerChannel::HandleRequest(int fd) break; } + case JackRequest::kComputeTotalLatencies: { + jack_log("JackRequest::ComputeTotalLatencies"); + JackComputeTotalLatenciesRequest req; + JackResult res; + if (req.Read(socket) == 0) + res.fResult = fServer->GetEngine()->ComputeTotalLatencies(); + if (res.Write(socket) < 0) + jack_error("JackRequest::ComputeTotalLatencies write error"); + break; + } + case JackRequest::kReleaseTimebase: { jack_log("JackRequest::ReleaseTimebase"); JackReleaseTimebaseRequest req; diff --git a/windows/JackWinNamedPipeClientChannel.cpp b/windows/JackWinNamedPipeClientChannel.cpp index af390d21..2dd433c1 100644 --- a/windows/JackWinNamedPipeClientChannel.cpp +++ b/windows/JackWinNamedPipeClientChannel.cpp @@ -1,20 +1,20 @@ /* Copyright (C) 2004-2008 Grame - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 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 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - + */ @@ -246,6 +246,13 @@ void JackWinNamedPipeClientChannel::SetFreewheel(int onoff, int* result) ServerSyncCall(&req, &res, result); } +void JackWinNamedPipeClientChannel::ComputeTotalLatencies(int* result) +{ + JackComputeTotalLatenciesRequest req; + JackResult res; + ServerSyncCall(&req, &res, result); +} + void JackWinNamedPipeClientChannel::SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t** result) { JackSessionNotifyRequest req(refnum, target, type, path); diff --git a/windows/JackWinNamedPipeClientChannel.h b/windows/JackWinNamedPipeClientChannel.h index aa23266b..27bfc3b4 100644 --- a/windows/JackWinNamedPipeClientChannel.h +++ b/windows/JackWinNamedPipeClientChannel.h @@ -81,6 +81,7 @@ class JackWinNamedPipeClientChannel : public detail::JackClientChannelInterface, void SetBufferSize(jack_nframes_t buffer_size, int* result); void SetFreewheel(int onoff, int* result); + void ComputeTotalLatencies(int* result); void ReleaseTimebase(int refnum, int* result); void SetTimebaseCallback(int refnum, int conditional, int* result);