| @@ -34,6 +34,15 @@ Valerio Pilo | |||
| Jackdmp changes log | |||
| --------------------------- | |||
| 2011-03-24 Stephane Letz <letz@grame.fr> | |||
| * Implement renaming in JackDriver::Open to avoid name collision (thanks Devin Anderson). | |||
| * Correct alsa_driver_restart (thanks Devin Anderson). | |||
| 2011-03-23 Stephane Letz <letz@grame.fr> | |||
| * Devin Anderson server-ctl-proposal branch merged on trunk: improved control API, slave backend reworked. | |||
| 2011-03-14 Stephane Letz <letz@grame.fr> | |||
| * Correct JackEngine::NotifyGraphReorder, update JackDebugClient with latest API. | |||
| @@ -193,9 +193,9 @@ int JackAudioDriver::ProcessNull() | |||
| JackDriver::CycleTakeBeginTime(); | |||
| if (fEngineControl->fSyncMode) { | |||
| ProcessGraphSync(); | |||
| ProcessGraphSyncMaster(); | |||
| } else { | |||
| ProcessGraphAsync(); | |||
| ProcessGraphAsyncMaster(); | |||
| } | |||
| // Keep end cycle time | |||
| @@ -230,9 +230,9 @@ int JackAudioDriver::ProcessAsync() | |||
| // Process graph | |||
| if (fIsMaster) { | |||
| ProcessGraphAsync(); | |||
| ProcessGraphAsyncMaster(); | |||
| } else { | |||
| fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); | |||
| ProcessGraphAsyncSlave(); | |||
| } | |||
| // Keep end cycle time | |||
| @@ -255,12 +255,12 @@ int JackAudioDriver::ProcessSync() | |||
| // Process graph | |||
| if (fIsMaster) { | |||
| if (ProcessGraphSync() < 0) { | |||
| if (ProcessGraphSyncMaster() < 0) { | |||
| jack_error("JackAudioDriver::ProcessSync: process error, skip cycle..."); | |||
| goto end; | |||
| } | |||
| } else { | |||
| if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { | |||
| if (ProcessGraphSyncSlave() < 0) { | |||
| jack_error("JackAudioDriver::ProcessSync: process error, skip cycle..."); | |||
| goto end; | |||
| } | |||
| @@ -279,27 +279,50 @@ end: | |||
| return 0; | |||
| } | |||
| void JackAudioDriver::ProcessGraphAsync() | |||
| void JackAudioDriver::ProcessGraphAsyncMaster() | |||
| { | |||
| // fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle | |||
| if (!fEngine->Process(fBeginDateUst, fEndDateUst)) | |||
| jack_error("JackAudioDriver::ProcessGraphAsync: Process error"); | |||
| fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); | |||
| if (ProcessSlaves() < 0) | |||
| jack_error("JackAudioDriver::ProcessGraphAsync: ProcessSlaves error"); | |||
| jack_error("JackAudioDriver::ProcessGraphAsyncMaster: Process error"); | |||
| if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) | |||
| jack_error("JackAudioDriver::ProcessGraphAsyncMaster: ResumeRefNum error"); | |||
| if (ProcessReadSlaves() < 0) | |||
| jack_error("JackAudioDriver::ProcessGraphAsyncMaster: ProcessReadSlaves error"); | |||
| if (ProcessWriteSlaves() < 0) | |||
| jack_error("JackAudioDriver::ProcessGraphAsyncMaster: ProcessWriteSlaves error"); | |||
| } | |||
| void JackAudioDriver::ProcessGraphAsyncSlave() | |||
| { | |||
| if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) | |||
| jack_error("JackAudioDriver::ProcessGraphAsyncSlave: ResumeRefNum error"); | |||
| } | |||
| int JackAudioDriver::ProcessGraphSync() | |||
| int JackAudioDriver::ProcessGraphSyncMaster() | |||
| { | |||
| int res = 0; | |||
| // fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle | |||
| if (fEngine->Process(fBeginDateUst, fEndDateUst)) { | |||
| fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); | |||
| if (ProcessSlaves() < 0) { | |||
| jack_error("JackAudioDriver::ProcessGraphSync: ProcessSlaves error, engine may now behave abnormally!!"); | |||
| if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { | |||
| jack_error("JackAudioDriver::ProcessGraphSyncMaster: ResumeRefNum error"); | |||
| res = -1; | |||
| } | |||
| if (ProcessReadSlaves() < 0) { | |||
| jack_error("JackAudioDriver::ProcessGraphSync: ProcessReadSlaves error, engine may now behave abnormally!!"); | |||
| res = -1; | |||
| } | |||
| if (ProcessWriteSlaves() < 0) { | |||
| jack_error("JackAudioDriver::ProcessGraphSync: ProcessWriteSlaves error, engine may now behave abnormally!!"); | |||
| res = -1; | |||
| } | |||
| if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) { | |||
| jack_error("JackAudioDriver::ProcessGraphSync: SuspendRefNum error, engine may now behave abnormally!!"); | |||
| res = -1; | |||
| @@ -312,6 +335,11 @@ int JackAudioDriver::ProcessGraphSync() | |||
| return res; | |||
| } | |||
| int JackAudioDriver::ProcessGraphSyncSlave() | |||
| { | |||
| return fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); | |||
| } | |||
| int JackAudioDriver::Start() | |||
| { | |||
| int res = JackDriver::Start(); | |||
| @@ -35,8 +35,12 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver | |||
| protected: | |||
| void ProcessGraphAsync(); | |||
| int ProcessGraphSync(); | |||
| void ProcessGraphAsyncMaster(); | |||
| void ProcessGraphAsyncSlave(); | |||
| int ProcessGraphSyncMaster(); | |||
| int ProcessGraphSyncSlave(); | |||
| void WaitUntilNextCycle(); | |||
| virtual int ProcessAsync(); | |||
| @@ -82,7 +82,7 @@ int JackDriver::Open() | |||
| return 0; | |||
| } | |||
| int JackDriver::Open (bool capturing, | |||
| int JackDriver::Open(bool capturing, | |||
| bool playing, | |||
| int inchannels, | |||
| int outchannels, | |||
| @@ -95,6 +95,15 @@ int JackDriver::Open (bool capturing, | |||
| jack_log("JackDriver::Open capture_driver_name = %s", capture_driver_name); | |||
| jack_log("JackDriver::Open playback_driver_name = %s", playback_driver_name); | |||
| int refnum = -1; | |||
| char name_res[JACK_CLIENT_NAME_SIZE + 1]; | |||
| int status; | |||
| // Check name and possibly rename | |||
| if (fEngine->ClientCheck(fClientControl.fName, -1, name_res, JACK_PROTOCOL_VERSION, (int)JackNullOption, (int*)&status) < 0) { | |||
| jack_error("Client name = %s conflits with another running client", fClientControl.fName); | |||
| return -1; | |||
| } | |||
| strcpy(fClientControl.fName, name_res); | |||
| if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) { | |||
| jack_error("Cannot allocate internal client for driver"); | |||
| @@ -137,6 +146,15 @@ int JackDriver::Open(jack_nframes_t buffer_size, | |||
| jack_log("JackDriver::Open capture_driver_name = %s", capture_driver_name); | |||
| jack_log("JackDriver::Open playback_driver_name = %s", playback_driver_name); | |||
| int refnum = -1; | |||
| char name_res[JACK_CLIENT_NAME_SIZE + 1]; | |||
| int status; | |||
| // Check name and possibly rename | |||
| if (fEngine->ClientCheck(fClientControl.fName, -1, name_res, JACK_PROTOCOL_VERSION, (int)JackNullOption, (int*)&status) < 0) { | |||
| jack_error("Client name = %s conflits with another running client", fClientControl.fName); | |||
| return -1; | |||
| } | |||
| strcpy(fClientControl.fName, name_res); | |||
| if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) { | |||
| jack_error("Cannot allocate internal client for driver"); | |||
| @@ -282,19 +300,42 @@ void JackDriver::RemoveSlave(JackDriverInterface* slave) | |||
| fSlaveList.remove(slave); | |||
| } | |||
| int JackDriver::ProcessSlaves() | |||
| int JackDriver::ProcessReadSlaves() | |||
| { | |||
| int res = 0; | |||
| list<JackDriverInterface*>::const_iterator it; | |||
| for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { | |||
| JackDriverInterface* slave = *it; | |||
| if (slave->Process() < 0) | |||
| if (slave->ProcessRead() < 0) | |||
| res = -1; | |||
| } | |||
| return res; | |||
| } | |||
| int JackDriver::ProcessWriteSlaves() | |||
| { | |||
| int res = 0; | |||
| list<JackDriverInterface*>::const_iterator it; | |||
| for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { | |||
| JackDriverInterface* slave = *it; | |||
| if (slave->ProcessWrite() < 0) | |||
| res = -1; | |||
| } | |||
| return res; | |||
| } | |||
| int JackDriver::ProcessRead() | |||
| { | |||
| return 0; | |||
| } | |||
| int JackDriver::ProcessWrite() | |||
| { | |||
| return 0; | |||
| } | |||
| int JackDriver::Process() | |||
| { | |||
| return 0; | |||
| @@ -34,6 +34,7 @@ namespace Jack | |||
| class JackLockedEngine; | |||
| class JackGraphManager; | |||
| struct JackEngineControl; | |||
| class JackSlaveDriverInterface; | |||
| /*! | |||
| \brief The base interface for drivers. | |||
| @@ -91,10 +92,17 @@ class SERVER_EXPORT JackDriverInterface | |||
| virtual void SetMaster(bool onoff) = 0; | |||
| virtual bool GetMaster() = 0; | |||
| virtual void AddSlave(JackDriverInterface* slave) = 0; | |||
| virtual void RemoveSlave(JackDriverInterface* slave) = 0; | |||
| virtual std::list<JackDriverInterface*> GetSlaves() = 0; | |||
| virtual int ProcessSlaves() = 0; | |||
| virtual int ProcessReadSlaves() = 0; | |||
| virtual int ProcessWriteSlaves() = 0; | |||
| virtual int ProcessRead() = 0; | |||
| virtual int ProcessWrite() = 0; | |||
| virtual bool IsRealTime() const = 0; | |||
| virtual bool IsRunning() const = 0; | |||
| @@ -159,11 +167,11 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface | |||
| void AddSlave(JackDriverInterface* slave); | |||
| void RemoveSlave(JackDriverInterface* slave); | |||
| std::list<JackDriverInterface*> GetSlaves() | |||
| { | |||
| return fSlaveList; | |||
| } | |||
| int ProcessSlaves(); | |||
| virtual int Open(); | |||
| @@ -200,10 +208,17 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface | |||
| virtual int Write(); | |||
| virtual int Start(); | |||
| virtual int StartSlaves(); | |||
| virtual int Stop(); | |||
| virtual int StartSlaves(); | |||
| virtual int StopSlaves(); | |||
| int ProcessReadSlaves(); | |||
| int ProcessWriteSlaves(); | |||
| int ProcessRead(); | |||
| int ProcessWrite(); | |||
| virtual bool IsFixedBufferSize(); | |||
| virtual int SetBufferSize(jack_nframes_t buffer_size); | |||
| virtual int SetSampleRate(jack_nframes_t sample_rate); | |||
| @@ -519,7 +519,7 @@ void JackEngine::EnsureUUID(int uuid) | |||
| for (int i = 0; i < CLIENT_NUM; i++) { | |||
| JackClientInterface* client = fClientTable[i]; | |||
| if (client && (client->GetClientControl()->fSessionID==uuid)) { | |||
| if (client && (client->GetClientControl()->fSessionID == uuid)) { | |||
| client->GetClientControl()->fSessionID = GetNewUUID(); | |||
| } | |||
| } | |||
| @@ -550,13 +550,13 @@ int JackEngine::GetClientRefNum(const char* name) | |||
| // Used for external clients | |||
| int JackEngine::ClientExternalOpen(const char* name, int pid, int uuid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager) | |||
| { | |||
| char real_name[JACK_CLIENT_NAME_SIZE+1]; | |||
| char real_name[JACK_CLIENT_NAME_SIZE + 1]; | |||
| if (uuid < 0) { | |||
| uuid = GetNewUUID(); | |||
| strncpy(real_name, name, JACK_CLIENT_NAME_SIZE); | |||
| } else { | |||
| std::map<int,std::string>::iterator res = fReservationMap.find(uuid); | |||
| std::map<int, std::string>::iterator res = fReservationMap.find(uuid); | |||
| if (res != fReservationMap.end()) { | |||
| strncpy(real_name, res->second.c_str(), JACK_CLIENT_NAME_SIZE); | |||
| fReservationMap.erase(uuid); | |||
| @@ -567,7 +567,7 @@ int JackEngine::ClientExternalOpen(const char* name, int pid, int uuid, int* ref | |||
| EnsureUUID(uuid); | |||
| } | |||
| jack_log("JackEngine::ClientExternalOpen: uuid=%d, name = %s ", uuid, real_name); | |||
| jack_log("JackEngine::ClientExternalOpen: uuid = %d, name = %s ", uuid, real_name); | |||
| int refnum = AllocateRefnum(); | |||
| if (refnum < 0) { | |||
| @@ -958,7 +958,7 @@ void JackEngine::SessionNotify(int refnum, const char *target, jack_session_even | |||
| if (client && client->GetClientControl()->fCallback[kSessionCallback]) { | |||
| // check if this is a notification to a specific client. | |||
| if (target!=NULL && strlen(target)!=0) { | |||
| if (target != NULL && strlen(target) != 0) { | |||
| if (strcmp(target, client->GetClientControl()->fName)) { | |||
| continue; | |||
| } | |||
| @@ -1018,7 +1018,7 @@ void JackEngine::GetUUIDForClientName(const char *client_name, char *uuid_res, i | |||
| for (int i = 0; i < CLIENT_NUM; i++) { | |||
| JackClientInterface* client = fClientTable[i]; | |||
| if (client && (strcmp(client_name, client->GetClientControl()->fName)==0)) { | |||
| if (client && (strcmp(client_name, client->GetClientControl()->fName) == 0)) { | |||
| snprintf(uuid_res, JACK_UUID_SIZE, "%d", client->GetClientControl()->fSessionID); | |||
| *result = 0; | |||
| return; | |||
| @@ -28,26 +28,72 @@ namespace Jack | |||
| int JackFreewheelDriver::Process() | |||
| { | |||
| if (fIsMaster) { | |||
| jack_log("JackFreewheelDriver::Process master %lld", fEngineControl->fTimeOutUsecs); | |||
| JackDriver::CycleTakeBeginTime(); | |||
| fEngine->Process(fBeginDateUst, fEndDateUst); | |||
| fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); // Signal all clients | |||
| int res = 0; | |||
| jack_log("JackFreewheelDriver::Process master %lld", fEngineControl->fTimeOutUsecs); | |||
| JackDriver::CycleTakeBeginTime(); | |||
| if (fEngine->Process(fBeginDateUst, fEndDateUst)) { | |||
| if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable)) { // Signal all clients | |||
| jack_error("JackFreewheelDriver::Process: ResumeRefNum error"); | |||
| res = -1; | |||
| } | |||
| if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, FREEWHEEL_DRIVER_TIMEOUT * 1000000) < 0) { // Wait for all clients to finish for 10 sec | |||
| jack_error("JackFreewheelDriver::ProcessSync SuspendRefNum error"); | |||
| jack_error("JackFreewheelDriver::ProcessSync: SuspendRefNum error"); | |||
| /* We have a client time-out error, but still continue to process, until a better recovery strategy is chosen */ | |||
| return 0; | |||
| } | |||
| } else { | |||
| fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); // Signal all clients | |||
| if (fEngineControl->fSyncMode) { | |||
| if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) { | |||
| jack_error("JackFreewheelDriver::ProcessSync SuspendRefNum error"); | |||
| return -1; | |||
| } | |||
| } | |||
| } else { // Graph not finished: do not activate it | |||
| jack_error("JackFreewheelDriver::Process: Process error"); | |||
| res = -1; | |||
| } | |||
| return res; | |||
| } | |||
| int JackFreewheelDriver::ProcessRead() | |||
| { | |||
| return (fEngineControl->fSyncMode) ? ProcessReadSync() : ProcessReadAsync(); | |||
| } | |||
| int JackFreewheelDriver::ProcessWrite() | |||
| { | |||
| return (fEngineControl->fSyncMode) ? ProcessWriteSync() : ProcessWriteAsync(); | |||
| } | |||
| int JackFreewheelDriver::ProcessReadSync() | |||
| { | |||
| if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { // Signal all clients | |||
| jack_error("JackFreewheelDriver::ProcessReadSync: ResumeRefNum error"); | |||
| return -1; | |||
| } | |||
| return 0; | |||
| } | |||
| int JackFreewheelDriver::ProcessWriteSync() | |||
| { | |||
| if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) { | |||
| jack_error("JackFreewheelDriver::ProcessSync SuspendRefNum error"); | |||
| return -1; | |||
| } | |||
| return 0; | |||
| } | |||
| int JackFreewheelDriver::ProcessReadAsync() | |||
| { | |||
| if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { // Signal all clients | |||
| jack_error("JackFreewheelDriver::ProcessReadAsync: ResumeRefNum error"); | |||
| return -1; | |||
| } | |||
| return 0; | |||
| } | |||
| int JackFreewheelDriver::ProcessWriteAsync() | |||
| { | |||
| return 0; | |||
| } | |||
| } // end of namespace | |||
| @@ -46,6 +46,16 @@ class JackFreewheelDriver : public JackDriver | |||
| } | |||
| int Process(); | |||
| int ProcessRead(); | |||
| int ProcessWrite(); | |||
| int ProcessReadSync(); | |||
| int ProcessWriteSync(); | |||
| int ProcessReadAsync(); | |||
| int ProcessWriteAsync(); | |||
| }; | |||
| } // end of namespace | |||
| @@ -123,7 +123,7 @@ int JackLoadableInternalClient::Init(const char* so_name) | |||
| { | |||
| char path_to_so[JACK_PATH_MAX + 1]; | |||
| BuildClientPath(path_to_so, sizeof(path_to_so), so_name); | |||
| fHandle = LoadJackModule(path_to_so); | |||
| jack_log("JackLoadableInternalClient::JackLoadableInternalClient path_to_so = %s", path_to_so); | |||
| @@ -151,7 +151,7 @@ int JackLoadableInternalClient1::Init(const char* so_name) | |||
| if (JackLoadableInternalClient::Init(so_name) < 0) { | |||
| return -1; | |||
| } | |||
| fInitialize = (InitializeCallback)GetJackProc(fHandle, "jack_initialize"); | |||
| if (fInitialize == NULL) { | |||
| UnloadJackModule(fHandle); | |||
| @@ -167,7 +167,7 @@ int JackLoadableInternalClient2::Init(const char* so_name) | |||
| if (JackLoadableInternalClient::Init(so_name) < 0) { | |||
| return -1; | |||
| } | |||
| fInitialize = (InternalInitializeCallback)GetJackProc(fHandle, "jack_internal_initialize"); | |||
| if (fInitialize == NULL) { | |||
| UnloadJackModule(fHandle); | |||
| @@ -181,7 +181,7 @@ int JackLoadableInternalClient2::Init(const char* so_name) | |||
| JackLoadableInternalClient1::JackLoadableInternalClient1(JackServer* server, JackSynchro* table, const char* object_data) | |||
| : JackLoadableInternalClient(server, table) | |||
| { | |||
| strncpy(fObjectData, object_data, JACK_LOAD_INIT_LIMIT); | |||
| strncpy(fObjectData, object_data, JACK_LOAD_INIT_LIMIT); | |||
| } | |||
| JackLoadableInternalClient2::JackLoadableInternalClient2(JackServer* server, JackSynchro* table, const JSList* parameters) | |||
| @@ -201,7 +201,7 @@ JackLoadableInternalClient::~JackLoadableInternalClient() | |||
| int JackLoadableInternalClient1::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) | |||
| { | |||
| int res = -1; | |||
| if (JackInternalClient::Open(server_name, name, uuid, options, status) == 0) { | |||
| if (fInitialize((jack_client_t*)this, fObjectData) == 0) { | |||
| res = 0; | |||
| @@ -210,14 +210,14 @@ int JackLoadableInternalClient1::Open(const char* server_name, const char* name, | |||
| fFinish = NULL; | |||
| } | |||
| } | |||
| return res; | |||
| } | |||
| int JackLoadableInternalClient2::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) | |||
| { | |||
| int res = -1; | |||
| if (JackInternalClient::Open(server_name, name, uuid, options, status) == 0) { | |||
| if (fInitialize((jack_client_t*)this, fParameters) == 0) { | |||
| res = 0; | |||
| @@ -226,7 +226,7 @@ int JackLoadableInternalClient2::Open(const char* server_name, const char* name, | |||
| fFinish = NULL; | |||
| } | |||
| } | |||
| return res; | |||
| } | |||
| @@ -30,20 +30,61 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| namespace Jack | |||
| { | |||
| int JackLoopbackDriver::Process() | |||
| int JackLoopbackDriver::ProcessRead() | |||
| { | |||
| return (fEngineControl->fSyncMode) ? ProcessReadSync() : ProcessReadAsync(); | |||
| } | |||
| int JackLoopbackDriver::ProcessWrite() | |||
| { | |||
| return (fEngineControl->fSyncMode) ? ProcessWriteSync() : ProcessWriteAsync(); | |||
| } | |||
| int JackLoopbackDriver::ProcessReadSync() | |||
| { | |||
| int res = 0; | |||
| // Loopback copy | |||
| for (int i = 0; i < fCaptureChannels; i++) { | |||
| memcpy(GetInputBuffer(i), GetOutputBuffer(i), sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); | |||
| } | |||
| fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); // Signal all clients | |||
| if (fEngineControl->fSyncMode) { | |||
| if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) { | |||
| jack_error("JackLoopbackDriver::ProcessSync SuspendRefNum error"); | |||
| return -1; | |||
| } | |||
| if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { | |||
| jack_error("JackLoopbackDriver::ProcessReadSync - ResumeRefNum error"); | |||
| res = -1; | |||
| } | |||
| return res; | |||
| } | |||
| int JackLoopbackDriver::ProcessWriteSync() | |||
| { | |||
| if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) { | |||
| jack_error("JackLoopbackDriver::ProcessWriteSync SuspendRefNum error"); | |||
| return -1; | |||
| } | |||
| return 0; | |||
| } | |||
| int JackLoopbackDriver::ProcessReadAsync() | |||
| { | |||
| int res = 0; | |||
| // Loopback copy | |||
| for (int i = 0; i < fCaptureChannels; i++) { | |||
| memcpy(GetInputBuffer(i), GetOutputBuffer(i), sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); | |||
| } | |||
| if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { | |||
| jack_error("JackLoopbackDriver::ProcessReadAsync - ResumeRefNum error"); | |||
| res = -1; | |||
| } | |||
| return res; | |||
| } | |||
| int JackLoopbackDriver::ProcessWriteAsync() | |||
| { | |||
| return 0; | |||
| } | |||
| @@ -33,6 +33,14 @@ namespace Jack | |||
| class JackLoopbackDriver : public JackAudioDriver | |||
| { | |||
| private: | |||
| virtual int ProcessReadSync(); | |||
| virtual int ProcessWriteSync(); | |||
| virtual int ProcessReadAsync(); | |||
| virtual int ProcessWriteAsync(); | |||
| public: | |||
| JackLoopbackDriver(JackLockedEngine* engine, JackSynchro* table) | |||
| @@ -41,7 +49,8 @@ class JackLoopbackDriver : public JackAudioDriver | |||
| virtual ~JackLoopbackDriver() | |||
| {} | |||
| int Process(); | |||
| virtual int ProcessRead(); | |||
| virtual int ProcessWrite(); | |||
| }; | |||
| } // end of namespace | |||
| @@ -74,9 +74,12 @@ int JackMidiDriver::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 latency_range; | |||
| jack_nframes_t latency = fEngineControl->fBufferSize; | |||
| int i; | |||
| jack_log("JackMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); | |||
| latency_range.max = latency_range.min = latency; | |||
| for (i = 0; i < fCaptureChannels; i++) { | |||
| snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); | |||
| @@ -87,10 +90,16 @@ int JackMidiDriver::Attach() | |||
| } | |||
| port = fGraphManager->GetPort(port_index); | |||
| port->SetAlias(alias); | |||
| port->SetLatencyRange(JackCaptureLatency, &latency_range); | |||
| fCapturePortList[i] = port_index; | |||
| jack_log("JackMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index); | |||
| } | |||
| if (!fEngineControl->fSyncMode) { | |||
| latency += fEngineControl->fBufferSize;; | |||
| latency_range.max = latency_range.min = latency; | |||
| } | |||
| for (i = 0; i < fPlaybackChannels; i++) { | |||
| snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); | |||
| snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); | |||
| @@ -100,6 +109,7 @@ int JackMidiDriver::Attach() | |||
| } | |||
| port = fGraphManager->GetPort(port_index); | |||
| port->SetAlias(alias); | |||
| port->SetLatencyRange(JackPlaybackLatency, &latency_range); | |||
| fPlaybackPortList[i] = port_index; | |||
| jack_log("JackMidiDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); | |||
| } | |||
| @@ -138,101 +148,83 @@ int JackMidiDriver::ProcessNull() | |||
| return 0; | |||
| } | |||
| /* | |||
| int JackMidiDriver::Process() | |||
| int JackMidiDriver::ProcessRead() | |||
| { | |||
| if (Read() < 0) { | |||
| jack_error("JackMidiDriver::Process: read error, skip cycle"); | |||
| return 0; // Skip cycle, but continue processing... | |||
| } | |||
| if (fEngineControl->fSyncMode) { | |||
| int res = 0; | |||
| if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { | |||
| jack_error("JackMidiDriver::Process - ResumeRefNum error"); | |||
| res = -1; | |||
| } | |||
| if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, | |||
| DRIVER_TIMEOUT_FACTOR * | |||
| fEngineControl->fTimeOutUsecs) < 0) { | |||
| jack_error("JackMidiDriver::Process - SuspendRefNum error"); | |||
| res = -1; | |||
| } | |||
| if (Write() < 0) { | |||
| jack_error("JackMidiDriver::Process - Write error"); | |||
| } | |||
| return res; | |||
| } | |||
| // Not in sync mode | |||
| if (Write() < 0) { | |||
| jack_error("JackMidiDriver::Process - Write error"); | |||
| } else { | |||
| fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); | |||
| } | |||
| return 0; | |||
| return (fEngineControl->fSyncMode) ? ProcessReadSync() : ProcessReadAsync(); | |||
| } | |||
| */ | |||
| int JackMidiDriver::Process() | |||
| int JackMidiDriver::ProcessWrite() | |||
| { | |||
| return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync(); | |||
| return (fEngineControl->fSyncMode) ? ProcessWriteSync() : ProcessWriteAsync(); | |||
| } | |||
| int JackMidiDriver::ProcessSync() | |||
| int JackMidiDriver::ProcessReadSync() | |||
| { | |||
| int res = 0; | |||
| // Read input buffers for the current cycle | |||
| if (Read() < 0) { | |||
| jack_error("JackMidiDriver::ProcessSync: read error, skip cycle"); | |||
| return 0; // Skip cycle, but continue processing... | |||
| jack_error("JackMidiDriver::ProcessReadSync: read error, skip cycle"); | |||
| res = -1; | |||
| } | |||
| if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { | |||
| jack_error("JackMidiDriver::ProcessSync - ResumeRefNum error"); | |||
| jack_error("JackMidiDriver::ProcessReadSync - ResumeRefNum error"); | |||
| res = -1; | |||
| } | |||
| return res; | |||
| } | |||
| int JackMidiDriver::ProcessWriteSync() | |||
| { | |||
| int res = 0; | |||
| if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, | |||
| DRIVER_TIMEOUT_FACTOR * | |||
| fEngineControl->fTimeOutUsecs) < 0) { | |||
| jack_error("JackMidiDriver::ProcessSync - SuspendRefNum error"); | |||
| jack_error("JackMidiDriver::ProcessWriteSync - SuspendRefNum error"); | |||
| res = -1; | |||
| } | |||
| // Write output buffers from the current cycle | |||
| if (Write() < 0) { | |||
| jack_error("JackMidiDriver::ProcessSync - Write error"); | |||
| jack_error("JackMidiDriver::ProcessWriteSync - Write error"); | |||
| res = -1; | |||
| } | |||
| return res; | |||
| } | |||
| int JackMidiDriver::ProcessAsync() | |||
| int JackMidiDriver::ProcessReadAsync() | |||
| { | |||
| int res = 0; | |||
| // Read input buffers for the current cycle | |||
| if (Read() < 0) { | |||
| jack_error("JackMidiDriver::ProcessAsync: read error, skip cycle"); | |||
| return 0; // Skip cycle, but continue processing... | |||
| jack_error("JackMidiDriver::ProcessReadAsync: read error, skip cycle"); | |||
| res = -1; | |||
| } | |||
| // Write output buffers from the previous cycle | |||
| if (Write() < 0) { | |||
| jack_error("JackMidiDriver::ProcessAsync - Write error"); | |||
| jack_error("JackMidiDriver::ProcessReadAsync - Write error"); | |||
| res = -1; | |||
| } | |||
| if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { | |||
| jack_error("JackMidiDriver::ProcessAsync - ResumeRefNum error"); | |||
| jack_error("JackMidiDriver::ProcessReadAsync - ResumeRefNum error"); | |||
| res = -1; | |||
| } | |||
| return res; | |||
| } | |||
| int JackMidiDriver::ProcessWriteAsync() | |||
| { | |||
| return 0; | |||
| } | |||
| JackMidiBuffer* JackMidiDriver::GetInputBuffer(int port_index) | |||
| { | |||
| assert(fCapturePortList[port_index]); | |||
| @@ -48,6 +48,12 @@ class SERVER_EXPORT JackMidiDriver : public JackDriver | |||
| JackMidiBuffer* GetInputBuffer(int port_index); | |||
| JackMidiBuffer* GetOutputBuffer(int port_index); | |||
| virtual int ProcessReadSync(); | |||
| virtual int ProcessWriteSync(); | |||
| virtual int ProcessReadAsync(); | |||
| virtual int ProcessWriteAsync(); | |||
| public: | |||
| JackMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); | |||
| @@ -63,9 +69,9 @@ class SERVER_EXPORT JackMidiDriver : public JackDriver | |||
| jack_nframes_t capture_latency, | |||
| jack_nframes_t playback_latency); | |||
| virtual int Process(); | |||
| virtual int ProcessSync(); | |||
| virtual int ProcessAsync(); | |||
| virtual int ProcessRead(); | |||
| virtual int ProcessWrite(); | |||
| virtual int ProcessNull(); | |||
| virtual int Attach(); | |||
| @@ -127,9 +127,24 @@ void JackThreadedDriver::RemoveSlave(JackDriverInterface* slave) | |||
| fDriver->RemoveSlave(slave); | |||
| } | |||
| int JackThreadedDriver::ProcessSlaves() | |||
| int JackThreadedDriver::ProcessReadSlaves() | |||
| { | |||
| return fDriver->ProcessSlaves(); | |||
| return fDriver->ProcessReadSlaves(); | |||
| } | |||
| int JackThreadedDriver::ProcessWriteSlaves() | |||
| { | |||
| return fDriver->ProcessWriteSlaves(); | |||
| } | |||
| int JackThreadedDriver::ProcessRead() | |||
| { | |||
| return fDriver->ProcessRead(); | |||
| } | |||
| int JackThreadedDriver::ProcessWrite() | |||
| { | |||
| return fDriver->ProcessWrite(); | |||
| } | |||
| std::list<JackDriverInterface*> JackThreadedDriver::GetSlaves() | |||
| @@ -89,10 +89,17 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi | |||
| virtual void SetMaster(bool onoff); | |||
| virtual bool GetMaster(); | |||
| virtual void AddSlave(JackDriverInterface* slave); | |||
| virtual void RemoveSlave(JackDriverInterface* slave); | |||
| virtual std::list<JackDriverInterface*> GetSlaves(); | |||
| virtual int ProcessSlaves(); | |||
| virtual int ProcessReadSlaves(); | |||
| virtual int ProcessWriteSlaves(); | |||
| virtual int ProcessRead(); | |||
| virtual int ProcessWrite(); | |||
| virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); | |||
| virtual JackClientControl* GetClientControl() const; | |||
| @@ -39,23 +39,23 @@ extern "C" | |||
| } | |||
| jack_varargs_t; | |||
| static const char* jack_default_server_name (void) | |||
| { | |||
| static const char* jack_default_server_name (void) | |||
| { | |||
| const char *server_name; | |||
| if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL) | |||
| server_name = "default"; | |||
| return server_name; | |||
| } | |||
| static inline void jack_varargs_init (jack_varargs_t *va) | |||
| { | |||
| static inline void jack_varargs_init (jack_varargs_t *va) | |||
| { | |||
| memset (va, 0, sizeof(jack_varargs_t)); | |||
| va->server_name = (char*)jack_default_server_name(); | |||
| va->session_id = -1; | |||
| } | |||
| static inline void jack_varargs_parse (jack_options_t options, va_list ap, jack_varargs_t *va) | |||
| { | |||
| static inline void jack_varargs_parse (jack_options_t options, va_list ap, jack_varargs_t *va) | |||
| { | |||
| // initialize default settings | |||
| jack_varargs_init (va); | |||
| @@ -1048,6 +1048,14 @@ void SetTime(jack_time_t time) | |||
| g_alsa_driver->SetTimetAux(time); | |||
| } | |||
| int Restart() | |||
| { | |||
| int res; | |||
| if ((res = g_alsa_driver->Stop()) == 0) | |||
| res = g_alsa_driver->Start(); | |||
| return res; | |||
| } | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| @@ -1159,8 +1159,12 @@ alsa_driver_restart (alsa_driver_t *driver) | |||
| int res; | |||
| driver->xrun_recovery = 1; | |||
| // JACK2 | |||
| /* | |||
| if ((res = driver->nt_stop((struct _jack_driver_nt *) driver))==0) | |||
| res = driver->nt_start((struct _jack_driver_nt *) driver); | |||
| */ | |||
| res = Restart(); | |||
| driver->xrun_recovery = 0; | |||
| if (res && driver->midi) | |||
| @@ -278,6 +278,7 @@ void MonitorInput(); | |||
| void ClearOutput(); | |||
| void WriteOutput(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nwritten); | |||
| void SetTime(jack_time_t time); | |||
| int Restart(); | |||
| #ifdef __cplusplus | |||
| } | |||
| @@ -168,7 +168,7 @@ OSStatus JackCoreAudioAdapter::SRNotificationCallback(AudioDeviceID inDevice, | |||
| switch (inPropertyID) { | |||
| case kAudioDevicePropertyNominalSampleRate: { | |||
| jack_log("JackCoreAudioDriver::SRNotificationCallback kAudioDevicePropertyNominalSampleRate"); | |||
| jack_log("JackCoreAudioAdapter::SRNotificationCallback kAudioDevicePropertyNominalSampleRate"); | |||
| driver->fState = true; | |||
| break; | |||
| } | |||
| @@ -430,12 +430,15 @@ OSStatus JackCoreAudioAdapter::GetDefaultDevice(AudioDeviceID* id) | |||
| jack_log("GetDefaultDevice: input = %ld output = %ld", inDefault, outDefault); | |||
| // Get the device only if default input and output are the same | |||
| if (inDefault == outDefault) { | |||
| *id = inDefault; | |||
| return noErr; | |||
| } else { | |||
| if (inDefault != outDefault) { | |||
| jack_error("Default input and output devices are not the same !!"); | |||
| return kAudioHardwareBadDeviceError; | |||
| } else if (inDefault == 0) { | |||
| jack_error("Default input and output devices are null !!"); | |||
| return kAudioHardwareBadDeviceError; | |||
| } else { | |||
| *id = inDefault; | |||
| return noErr; | |||
| } | |||
| } | |||
| @@ -444,20 +447,16 @@ OSStatus JackCoreAudioAdapter::GetTotalChannels(AudioDeviceID device, int& chann | |||
| OSStatus err = noErr; | |||
| UInt32 outSize; | |||
| Boolean outWritable; | |||
| AudioBufferList* bufferList = 0; | |||
| channelCount = 0; | |||
| err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, &outWritable); | |||
| if (err == noErr) { | |||
| bufferList = (AudioBufferList*)malloc(outSize); | |||
| AudioBufferList bufferList[outSize]; | |||
| err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, bufferList); | |||
| if (err == noErr) { | |||
| for (unsigned int i = 0; i < bufferList->mNumberBuffers; i++) | |||
| channelCount += bufferList->mBuffers[i].mNumberChannels; | |||
| } | |||
| if (bufferList) | |||
| free(bufferList); | |||
| } | |||
| return err; | |||
| @@ -604,7 +603,7 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, | |||
| // Use default driver in duplex mode | |||
| } else { | |||
| jack_log("JackCoreAudioDriver::Open default driver"); | |||
| jack_log("JackCoreAudioAdapter::Open default driver"); | |||
| if (GetDefaultDevice(&fDeviceID) != noErr) { | |||
| jack_error("Cannot open default device in duplex mode, so aggregate default input and default output"); | |||
| @@ -1030,14 +1029,14 @@ OSStatus JackCoreAudioAdapter::DestroyAggregateDevice() | |||
| osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); | |||
| if (osErr != noErr) { | |||
| jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyDataSize error"); | |||
| jack_error("JackCoreAudioAdapter::DestroyAggregateDevice : AudioObjectGetPropertyDataSize error"); | |||
| printError(osErr); | |||
| return osErr; | |||
| } | |||
| osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, 0, NULL, &outDataSize, &fDeviceID); | |||
| if (osErr != noErr) { | |||
| jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyData error"); | |||
| jack_error("JackCoreAudioAdapter::DestroyAggregateDevice : AudioObjectGetPropertyData error"); | |||
| printError(osErr); | |||
| return osErr; | |||
| } | |||
| @@ -1115,18 +1114,18 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||
| for (UInt32 i = 0; i < captureDeviceID.size(); i++) { | |||
| if (SetupSampleRateAux(captureDeviceID[i], samplerate) < 0) { | |||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of input device"); | |||
| jack_error("JackCoreAudioAdapter::CreateAggregateDevice : cannot set SR of input device"); | |||
| } else { | |||
| // Check clock domain | |||
| osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); | |||
| if (osErr != 0) { | |||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); | |||
| jack_error("JackCoreAudioAdapter::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); | |||
| printError(osErr); | |||
| } else { | |||
| keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; | |||
| jack_log("JackCoreAudioDriver::CreateAggregateDevice : input clockdomain = %d", clockdomain); | |||
| jack_log("JackCoreAudioAdapter::CreateAggregateDevice : input clockdomain = %d", clockdomain); | |||
| if (clockdomain != 0 && clockdomain != keptclockdomain) { | |||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); | |||
| jack_error("JackCoreAudioAdapter::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); | |||
| need_clock_drift_compensation = true; | |||
| } | |||
| } | |||
| @@ -1135,18 +1134,18 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||
| for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { | |||
| if (SetupSampleRateAux(playbackDeviceID[i], samplerate) < 0) { | |||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of output device"); | |||
| jack_error("JackCoreAudioAdapter::CreateAggregateDevice : cannot set SR of output device"); | |||
| } else { | |||
| // Check clock domain | |||
| osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); | |||
| if (osErr != 0) { | |||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); | |||
| jack_error("JackCoreAudioAdapter::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); | |||
| printError(osErr); | |||
| } else { | |||
| keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; | |||
| jack_log("JackCoreAudioDriver::CreateAggregateDevice : output clockdomain = %d", clockdomain); | |||
| jack_log("JackCoreAudioAdapter::CreateAggregateDevice : output clockdomain = %d", clockdomain); | |||
| if (clockdomain != 0 && clockdomain != keptclockdomain) { | |||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); | |||
| jack_error("JackCoreAudioAdapter::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); | |||
| need_clock_drift_compensation = true; | |||
| } | |||
| } | |||
| @@ -1175,7 +1174,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||
| osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable); | |||
| if (osErr != noErr) { | |||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error"); | |||
| jack_error("JackCoreAudioAdapter::CreateAggregateDevice : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error"); | |||
| printError(osErr); | |||
| return osErr; | |||
| } | |||
| @@ -1191,7 +1190,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||
| osErr = AudioHardwareGetProperty(kAudioHardwarePropertyPlugInForBundleID, &outSize, &pluginAVT); | |||
| if (osErr != noErr) { | |||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioHardwareGetProperty kAudioHardwarePropertyPlugInForBundleID error"); | |||
| jack_error("JackCoreAudioAdapter::CreateAggregateDevice : AudioHardwareGetProperty kAudioHardwarePropertyPlugInForBundleID error"); | |||
| printError(osErr); | |||
| return osErr; | |||
| } | |||
| @@ -1218,13 +1217,13 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||
| SInt32 system; | |||
| Gestalt(gestaltSystemVersion, &system); | |||
| jack_log("JackCoreAudioDriver::CreateAggregateDevice : system version = %x limit = %x", system, 0x00001054); | |||
| jack_log("JackCoreAudioAdapter::CreateAggregateDevice : system version = %x limit = %x", system, 0x00001054); | |||
| // Starting with 10.5.4 systems, the AD can be internal... (better) | |||
| if (system < 0x00001054) { | |||
| jack_log("JackCoreAudioDriver::CreateAggregateDevice : public aggregate device...."); | |||
| jack_log("JackCoreAudioAdapter::CreateAggregateDevice : public aggregate device...."); | |||
| } else { | |||
| jack_log("JackCoreAudioDriver::CreateAggregateDevice : private aggregate device...."); | |||
| jack_log("JackCoreAudioAdapter::CreateAggregateDevice : private aggregate device...."); | |||
| CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef); | |||
| } | |||
| @@ -1306,14 +1305,14 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||
| osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); | |||
| if (osErr != noErr) { | |||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectGetPropertyDataSize error"); | |||
| jack_error("JackCoreAudioAdapter::CreateAggregateDevice : AudioObjectGetPropertyDataSize error"); | |||
| printError(osErr); | |||
| goto error; | |||
| } | |||
| osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice); | |||
| if (osErr != noErr) { | |||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectGetPropertyData error"); | |||
| jack_error("JackCoreAudioAdapter::CreateAggregateDevice : AudioObjectGetPropertyData error"); | |||
| printError(osErr); | |||
| goto error; | |||
| } | |||
| @@ -1332,7 +1331,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||
| outDataSize = sizeof(CFMutableArrayRef); | |||
| osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &subDevicesArray); | |||
| if (osErr != noErr) { | |||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectSetPropertyData for sub-device list error"); | |||
| jack_error("JackCoreAudioAdapter::CreateAggregateDevice : AudioObjectSetPropertyData for sub-device list error"); | |||
| printError(osErr); | |||
| goto error; | |||
| } | |||
| @@ -1352,7 +1351,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||
| outDataSize = sizeof(CFStringRef); | |||
| osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID[0]); // First apture is master... | |||
| if (osErr != noErr) { | |||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectSetPropertyData for master device error"); | |||
| jack_error("JackCoreAudioAdapter::CreateAggregateDevice : AudioObjectSetPropertyData for master device error"); | |||
| printError(osErr); | |||
| goto error; | |||
| } | |||
| @@ -1370,19 +1369,19 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||
| // Get the property data size | |||
| osErr = AudioObjectGetPropertyDataSize(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize); | |||
| if (osErr != noErr) { | |||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); | |||
| jack_error("JackCoreAudioAdapter::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); | |||
| printError(osErr); | |||
| } | |||
| // Calculate the number of object IDs | |||
| subDevicesNum = outSize / sizeof(AudioObjectID); | |||
| jack_info("JackCoreAudioDriver::CreateAggregateDevice clock drift compensation, number of sub-devices = %d", subDevicesNum); | |||
| jack_info("JackCoreAudioAdapter::CreateAggregateDevice clock drift compensation, number of sub-devices = %d", subDevicesNum); | |||
| AudioObjectID subDevices[subDevicesNum]; | |||
| outSize = sizeof(subDevices); | |||
| osErr = AudioObjectGetPropertyData(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize, subDevices); | |||
| if (osErr != noErr) { | |||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); | |||
| jack_error("JackCoreAudioAdapter::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); | |||
| printError(osErr); | |||
| } | |||
| @@ -1391,7 +1390,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||
| UInt32 theDriftCompensationValue = 1; | |||
| osErr = AudioObjectSetPropertyData(subDevices[index], &theAddressDrift, 0, NULL, sizeof(UInt32), &theDriftCompensationValue); | |||
| if (osErr != noErr) { | |||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioSubDevicePropertyDriftCompensation error"); | |||
| jack_error("JackCoreAudioAdapter::CreateAggregateDevice kAudioSubDevicePropertyDriftCompensation error"); | |||
| printError(osErr); | |||
| } | |||
| } | |||
| @@ -386,12 +386,15 @@ OSStatus JackCoreAudioDriver::GetDefaultDevice(AudioDeviceID* id) | |||
| jack_log("GetDefaultDevice: input = %ld output = %ld", inDefault, outDefault); | |||
| // Get the device only if default input and output are the same | |||
| if (inDefault == outDefault) { | |||
| *id = inDefault; | |||
| return noErr; | |||
| } else { | |||
| if (inDefault != outDefault) { | |||
| jack_error("Default input and output devices are not the same !!"); | |||
| return kAudioHardwareBadDeviceError; | |||
| } else if (inDefault == 0) { | |||
| jack_error("Default input and output devices are null !!"); | |||
| return kAudioHardwareBadDeviceError; | |||
| } else { | |||
| *id = inDefault; | |||
| return noErr; | |||
| } | |||
| } | |||