git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4120 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.9.7
| @@ -34,6 +34,10 @@ Valerio Pilo | |||||
| Jackdmp changes log | Jackdmp changes log | ||||
| --------------------------- | --------------------------- | ||||
| 2011-02-09 Stephane Letz <letz@grame.fr> | |||||
| * Remove JackPortIsActive flag. | |||||
| 2011-02-07 Stephane Letz <letz@grame.fr> | 2011-02-07 Stephane Letz <letz@grame.fr> | ||||
| * Valerio Pilo second CAS for ARMv7 patch. | * Valerio Pilo second CAS for ARMv7 patch. | ||||
| @@ -1,21 +1,21 @@ | |||||
| /* | /* | ||||
| Copyright (C) 2001 Paul Davis | Copyright (C) 2001 Paul Davis | ||||
| Copyright (C) 2004-2008 Grame | Copyright (C) 2004-2008 Grame | ||||
| This program is free software; you can redistribute it and/or modify | This program is free software; you can redistribute it and/or modify | ||||
| it under the terms of the GNU General Public License as published by | it under the terms of the GNU General Public License as published by | ||||
| the Free Software Foundation; either version 2 of the License, or | the Free Software Foundation; either version 2 of the License, or | ||||
| (at your option) any later version. | (at your option) any later version. | ||||
| This program is distributed in the hope that it will be useful, | This program is distributed in the hope that it will be useful, | ||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
| GNU General Public License for more details. | GNU General Public License for more details. | ||||
| You should have received a copy of the GNU General Public License | You should have received a copy of the GNU 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., 675 Mass Ave, Cambridge, MA 02139, USA. | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
| */ | */ | ||||
| #ifndef __JackDriver__ | #ifndef __JackDriver__ | ||||
| @@ -30,27 +30,27 @@ | |||||
| namespace Jack | namespace Jack | ||||
| { | { | ||||
| class JackLockedEngine; | class JackLockedEngine; | ||||
| class JackGraphManager; | class JackGraphManager; | ||||
| struct JackEngineControl; | struct JackEngineControl; | ||||
| /*! | /*! | ||||
| \brief The base interface for drivers. | \brief The base interface for drivers. | ||||
| */ | */ | ||||
| class SERVER_EXPORT JackDriverInterface | class SERVER_EXPORT JackDriverInterface | ||||
| { | { | ||||
| public: | public: | ||||
| JackDriverInterface() | JackDriverInterface() | ||||
| {} | {} | ||||
| virtual ~JackDriverInterface() | virtual ~JackDriverInterface() | ||||
| {} | {} | ||||
| virtual int Open() = 0; | virtual int Open() = 0; | ||||
| virtual int Open (bool capturing, | virtual int Open (bool capturing, | ||||
| bool playing, | bool playing, | ||||
| int inchannels, | int inchannels, | ||||
| @@ -60,7 +60,7 @@ class SERVER_EXPORT JackDriverInterface | |||||
| const char* playback_driver_name, | const char* playback_driver_name, | ||||
| jack_nframes_t capture_latency, | jack_nframes_t capture_latency, | ||||
| jack_nframes_t playback_latency) = 0; | jack_nframes_t playback_latency) = 0; | ||||
| virtual int Open(jack_nframes_t buffer_size, | virtual int Open(jack_nframes_t buffer_size, | ||||
| jack_nframes_t samplerate, | jack_nframes_t samplerate, | ||||
| bool capturing, | bool capturing, | ||||
| @@ -72,30 +72,30 @@ class SERVER_EXPORT JackDriverInterface | |||||
| const char* playback_driver_name, | const char* playback_driver_name, | ||||
| jack_nframes_t capture_latency, | jack_nframes_t capture_latency, | ||||
| jack_nframes_t playback_latency) = 0; | jack_nframes_t playback_latency) = 0; | ||||
| virtual int Attach() = 0; | virtual int Attach() = 0; | ||||
| virtual int Detach() = 0; | virtual int Detach() = 0; | ||||
| virtual int Read() = 0; | virtual int Read() = 0; | ||||
| virtual int Write() = 0; | virtual int Write() = 0; | ||||
| virtual int Start() = 0; | virtual int Start() = 0; | ||||
| virtual int Stop() = 0; | virtual int Stop() = 0; | ||||
| virtual bool IsFixedBufferSize() = 0; | virtual bool IsFixedBufferSize() = 0; | ||||
| virtual int SetBufferSize(jack_nframes_t buffer_size) = 0; | virtual int SetBufferSize(jack_nframes_t buffer_size) = 0; | ||||
| virtual int SetSampleRate(jack_nframes_t sample_rate) = 0; | virtual int SetSampleRate(jack_nframes_t sample_rate) = 0; | ||||
| virtual int Process() = 0; | virtual int Process() = 0; | ||||
| virtual int ProcessNull() = 0; | virtual int ProcessNull() = 0; | ||||
| virtual void SetMaster(bool onoff) = 0; | virtual void SetMaster(bool onoff) = 0; | ||||
| virtual bool GetMaster() = 0; | virtual bool GetMaster() = 0; | ||||
| virtual void AddSlave(JackDriverInterface* slave) = 0; | virtual void AddSlave(JackDriverInterface* slave) = 0; | ||||
| virtual void RemoveSlave(JackDriverInterface* slave) = 0; | virtual void RemoveSlave(JackDriverInterface* slave) = 0; | ||||
| virtual std::list<JackDriverInterface*> GetSlaves() = 0; | virtual std::list<JackDriverInterface*> GetSlaves() = 0; | ||||
| virtual int ProcessSlaves() = 0; | virtual int ProcessSlaves() = 0; | ||||
| virtual bool IsRealTime() const = 0; | virtual bool IsRealTime() const = 0; | ||||
| }; | }; | ||||
| @@ -109,16 +109,16 @@ class SERVER_EXPORT JackDriverClientInterface : public JackDriverInterface, publ | |||||
| /*! | /*! | ||||
| \brief The base class for drivers. | \brief The base class for drivers. | ||||
| */ | */ | ||||
| #define CaptureDriverFlags static_cast<JackPortFlags>(JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal | JackPortIsActive) | |||||
| #define PlaybackDriverFlags static_cast<JackPortFlags>(JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal | JackPortIsActive) | |||||
| #define MonitorDriverFlags static_cast<JackPortFlags>(JackPortIsOutput | JackPortIsActive) | |||||
| #define CaptureDriverFlags static_cast<JackPortFlags>(JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal) | |||||
| #define PlaybackDriverFlags static_cast<JackPortFlags>(JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal) | |||||
| #define MonitorDriverFlags static_cast<JackPortFlags>(JackPortIsOutput) | |||||
| class SERVER_EXPORT JackDriver : public JackDriverClientInterface | class SERVER_EXPORT JackDriver : public JackDriverClientInterface | ||||
| { | { | ||||
| protected: | protected: | ||||
| char fCaptureDriverName[JACK_CLIENT_NAME_SIZE + 1]; | char fCaptureDriverName[JACK_CLIENT_NAME_SIZE + 1]; | ||||
| char fPlaybackDriverName[JACK_CLIENT_NAME_SIZE + 1]; | char fPlaybackDriverName[JACK_CLIENT_NAME_SIZE + 1]; | ||||
| char fAliasName[JACK_CLIENT_NAME_SIZE + 1]; | char fAliasName[JACK_CLIENT_NAME_SIZE + 1]; | ||||
| @@ -134,27 +134,27 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface | |||||
| JackClientControl fClientControl; | JackClientControl fClientControl; | ||||
| std::list<JackDriverInterface*> fSlaveList; | std::list<JackDriverInterface*> fSlaveList; | ||||
| bool fIsMaster; | bool fIsMaster; | ||||
| void CycleIncTime(); | void CycleIncTime(); | ||||
| void CycleTakeBeginTime(); | void CycleTakeBeginTime(); | ||||
| void CycleTakeEndTime(); | void CycleTakeEndTime(); | ||||
| void SetupDriverSync(int ref, bool freewheel); | void SetupDriverSync(int ref, bool freewheel); | ||||
| void NotifyXRun(jack_time_t callback_usecs, float delayed_usecs); // XRun notification sent by the driver | void NotifyXRun(jack_time_t callback_usecs, float delayed_usecs); // XRun notification sent by the driver | ||||
| void NotifyBufferSize(jack_nframes_t buffer_size); // BufferSize notification sent by the driver | void NotifyBufferSize(jack_nframes_t buffer_size); // BufferSize notification sent by the driver | ||||
| void NotifySampleRate(jack_nframes_t sample_rate); // SampleRate notification sent by the driver | void NotifySampleRate(jack_nframes_t sample_rate); // SampleRate notification sent by the driver | ||||
| void NotifyFailure(int code, const char* reason); // Failure notification sent by the driver | void NotifyFailure(int code, const char* reason); // Failure notification sent by the driver | ||||
| public: | public: | ||||
| JackDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); | JackDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); | ||||
| JackDriver(); | JackDriver(); | ||||
| virtual ~JackDriver(); | virtual ~JackDriver(); | ||||
| void SetMaster(bool onoff); | void SetMaster(bool onoff); | ||||
| bool GetMaster(); | bool GetMaster(); | ||||
| void AddSlave(JackDriverInterface* slave); | void AddSlave(JackDriverInterface* slave); | ||||
| void RemoveSlave(JackDriverInterface* slave); | void RemoveSlave(JackDriverInterface* slave); | ||||
| std::list<JackDriverInterface*> GetSlaves() | std::list<JackDriverInterface*> GetSlaves() | ||||
| @@ -162,9 +162,9 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface | |||||
| return fSlaveList; | return fSlaveList; | ||||
| } | } | ||||
| int ProcessSlaves(); | int ProcessSlaves(); | ||||
| virtual int Open(); | virtual int Open(); | ||||
| virtual int Open (bool capturing, | virtual int Open (bool capturing, | ||||
| bool playing, | bool playing, | ||||
| int inchannels, | int inchannels, | ||||
| @@ -174,7 +174,7 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface | |||||
| const char* playback_driver_name, | const char* playback_driver_name, | ||||
| jack_nframes_t capture_latency, | jack_nframes_t capture_latency, | ||||
| jack_nframes_t playback_latency); | jack_nframes_t playback_latency); | ||||
| virtual int Open(jack_nframes_t buffer_size, | virtual int Open(jack_nframes_t buffer_size, | ||||
| jack_nframes_t samplerate, | jack_nframes_t samplerate, | ||||
| bool capturing, | bool capturing, | ||||
| @@ -187,31 +187,31 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface | |||||
| jack_nframes_t capture_latency, | jack_nframes_t capture_latency, | ||||
| jack_nframes_t playback_latency); | jack_nframes_t playback_latency); | ||||
| virtual int Close(); | virtual int Close(); | ||||
| virtual int Process(); | virtual int Process(); | ||||
| virtual int ProcessNull(); | virtual int ProcessNull(); | ||||
| virtual int Attach(); | virtual int Attach(); | ||||
| virtual int Detach(); | virtual int Detach(); | ||||
| virtual int Read(); | virtual int Read(); | ||||
| virtual int Write(); | virtual int Write(); | ||||
| virtual int Start(); | virtual int Start(); | ||||
| virtual int Stop(); | virtual int Stop(); | ||||
| virtual bool IsFixedBufferSize(); | virtual bool IsFixedBufferSize(); | ||||
| 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); | virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); | ||||
| virtual JackClientControl* GetClientControl() const; | virtual JackClientControl* GetClientControl() const; | ||||
| virtual bool IsRealTime() const; | virtual bool IsRealTime() const; | ||||
| virtual bool Initialize(); // To be called by the wrapping thread Init method when the driver is a "blocking" one | |||||
| virtual bool Initialize(); // To be called by the wrapping thread Init method when the driver is a "blocking" one | |||||
| }; | }; | ||||
| } // end of namespace | } // end of namespace | ||||
| #endif | #endif | ||||
| @@ -708,14 +708,6 @@ int JackEngine::ClientActivate(int refnum, bool is_real_time) | |||||
| fGraphManager->GetInputPorts(refnum, input_ports); | fGraphManager->GetInputPorts(refnum, input_ports); | ||||
| fGraphManager->GetOutputPorts(refnum, output_ports); | fGraphManager->GetOutputPorts(refnum, output_ports); | ||||
| // First add port state to JackPortIsActive | |||||
| for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { | |||||
| fGraphManager->ActivatePort(input_ports[i]); | |||||
| } | |||||
| for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (output_ports[i] != EMPTY); i++) { | |||||
| fGraphManager->ActivatePort(output_ports[i]); | |||||
| } | |||||
| // Notify client | // Notify client | ||||
| NotifyActivate(refnum); | NotifyActivate(refnum); | ||||
| @@ -745,11 +737,9 @@ int JackEngine::ClientDeactivate(int refnum) | |||||
| // First disconnect all ports and remove their JackPortIsActive state | // First disconnect all ports and remove their JackPortIsActive state | ||||
| for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { | for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { | ||||
| PortDisconnect(refnum, input_ports[i], ALL_PORTS); | PortDisconnect(refnum, input_ports[i], ALL_PORTS); | ||||
| fGraphManager->DeactivatePort(input_ports[i]); | |||||
| } | } | ||||
| for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (output_ports[i] != EMPTY); i++) { | for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (output_ports[i] != EMPTY); i++) { | ||||
| PortDisconnect(refnum, output_ports[i], ALL_PORTS); | PortDisconnect(refnum, output_ports[i], ALL_PORTS); | ||||
| fGraphManager->DeactivatePort(output_ports[i]); | |||||
| } | } | ||||
| // Then issue port registration notification | // Then issue port registration notification | ||||
| @@ -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. | ||||
| */ | */ | ||||
| @@ -37,7 +37,7 @@ static void AssertBufferSize(jack_nframes_t buffer_size) | |||||
| assert(buffer_size <= BUFFER_SIZE_MAX); | assert(buffer_size <= BUFFER_SIZE_MAX); | ||||
| } | } | ||||
| } | } | ||||
| void JackGraphManager::AssertPort(jack_port_id_t port_index) | void JackGraphManager::AssertPort(jack_port_id_t port_index) | ||||
| { | { | ||||
| if (port_index >= fPortMax) { | if (port_index >= fPortMax) { | ||||
| @@ -45,7 +45,7 @@ void JackGraphManager::AssertPort(jack_port_id_t port_index) | |||||
| assert(port_index < fPortMax); | assert(port_index < fPortMax); | ||||
| } | } | ||||
| } | } | ||||
| JackGraphManager* JackGraphManager::Allocate(int port_max) | JackGraphManager* JackGraphManager::Allocate(int port_max) | ||||
| { | { | ||||
| // Using "Placement" new | // Using "Placement" new | ||||
| @@ -59,18 +59,18 @@ void JackGraphManager::Destroy(JackGraphManager* manager) | |||||
| manager->~JackGraphManager(); | manager->~JackGraphManager(); | ||||
| JackShmMem::operator delete(manager); | JackShmMem::operator delete(manager); | ||||
| } | } | ||||
| JackGraphManager::JackGraphManager(int port_max) | |||||
| JackGraphManager::JackGraphManager(int port_max) | |||||
| { | { | ||||
| assert(port_max <= PORT_NUM_MAX); | assert(port_max <= PORT_NUM_MAX); | ||||
| for (int i = 0; i < port_max; i++) { | for (int i = 0; i < port_max; i++) { | ||||
| fPortArray[i].Release(); | fPortArray[i].Release(); | ||||
| } | } | ||||
| fPortMax = port_max; | fPortMax = port_max; | ||||
| } | } | ||||
| JackPort* JackGraphManager::GetPort(jack_port_id_t port_index) | JackPort* JackGraphManager::GetPort(jack_port_id_t port_index) | ||||
| { | { | ||||
| AssertPort(port_index); | AssertPort(port_index); | ||||
| @@ -176,14 +176,14 @@ void* JackGraphManager::GetBuffer(jack_port_id_t port_index, jack_nframes_t buff | |||||
| jack_int_t len = manager->Connections(port_index); | jack_int_t len = manager->Connections(port_index); | ||||
| // No connections : return a zero-filled buffer | // No connections : return a zero-filled buffer | ||||
| if (len == 0) { | |||||
| if (len == 0) { | |||||
| port->ClearBuffer(buffer_size); | port->ClearBuffer(buffer_size); | ||||
| return port->GetBuffer(); | return port->GetBuffer(); | ||||
| // One connection | // One connection | ||||
| } else if (len == 1) { | |||||
| } else if (len == 1) { | |||||
| jack_port_id_t src_index = manager->GetPort(port_index, 0); | jack_port_id_t src_index = manager->GetPort(port_index, 0); | ||||
| // Ports in same client : copy the buffer | // Ports in same client : copy the buffer | ||||
| if (GetPort(src_index)->GetRefNum() == port->GetRefNum()) { | if (GetPort(src_index)->GetRefNum() == port->GetRefNum()) { | ||||
| void* buffers[1]; | void* buffers[1]; | ||||
| @@ -194,10 +194,10 @@ void* JackGraphManager::GetBuffer(jack_port_id_t port_index, jack_nframes_t buff | |||||
| } else { | } else { | ||||
| return GetBuffer(src_index, buffer_size); | return GetBuffer(src_index, buffer_size); | ||||
| } | } | ||||
| // Multiple connections : mix all buffers | // Multiple connections : mix all buffers | ||||
| } else { | |||||
| } else { | |||||
| const jack_int_t* connections = manager->GetConnections(port_index); | const jack_int_t* connections = manager->GetConnections(port_index); | ||||
| void* buffers[CONNECTION_NUM_FOR_PORT]; | void* buffers[CONNECTION_NUM_FOR_PORT]; | ||||
| jack_port_id_t src_index; | jack_port_id_t src_index; | ||||
| @@ -220,10 +220,10 @@ int JackGraphManager::RequestMonitor(jack_port_id_t port_index, bool onoff) // C | |||||
| JackPort* port = GetPort(port_index); | JackPort* port = GetPort(port_index); | ||||
| /** | /** | ||||
| 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; | ||||
| */ | */ | ||||
| @@ -376,18 +376,6 @@ int JackGraphManager::ReleasePort(int refnum, jack_port_id_t port_index) | |||||
| return res; | return res; | ||||
| } | } | ||||
| void JackGraphManager::ActivatePort(jack_port_id_t port_index) | |||||
| { | |||||
| JackPort* port = GetPort(port_index); | |||||
| port->fFlags = (JackPortFlags)(port->fFlags | JackPortIsActive); | |||||
| } | |||||
| void JackGraphManager::DeactivatePort(jack_port_id_t port_index) | |||||
| { | |||||
| JackPort* port = GetPort(port_index); | |||||
| port->fFlags = (JackPortFlags)(port->fFlags & ~JackPortIsActive); | |||||
| } | |||||
| void JackGraphManager::GetInputPorts(int refnum, jack_int_t* res) | void JackGraphManager::GetInputPorts(int refnum, jack_int_t* res) | ||||
| { | { | ||||
| JackConnectionManager* manager = WriteNextStateStart(); | JackConnectionManager* manager = WriteNextStateStart(); | ||||
| @@ -430,7 +418,7 @@ void JackGraphManager::RemoveAllPorts(int refnum) | |||||
| jack_error("JackGraphManager::RemoveAllPorts failure ref = %ld port_index = %ld", refnum, port_index); | jack_error("JackGraphManager::RemoveAllPorts failure ref = %ld port_index = %ld", refnum, port_index); | ||||
| assert(true); | assert(true); | ||||
| break; | break; | ||||
| } | |||||
| } | |||||
| } | } | ||||
| WriteNextStateStop(); | WriteNextStateStop(); | ||||
| @@ -717,7 +705,7 @@ void JackGraphManager::GetConnectionsAux(JackConnectionManager* manager, const c | |||||
| const jack_int_t* connections = manager->GetConnections(port_index); | const jack_int_t* connections = manager->GetConnections(port_index); | ||||
| jack_int_t index; | jack_int_t index; | ||||
| int i; | int i; | ||||
| // Cleanup connection array | // Cleanup connection array | ||||
| memset(res, 0, sizeof(char*) * CONNECTION_NUM_FOR_PORT); | memset(res, 0, sizeof(char*) * CONNECTION_NUM_FOR_PORT); | ||||
| @@ -740,7 +728,7 @@ const char** JackGraphManager::GetConnections(jack_port_id_t port_index) | |||||
| { | { | ||||
| const char** res = (const char**)malloc(sizeof(char*) * CONNECTION_NUM_FOR_PORT); | const char** res = (const char**)malloc(sizeof(char*) * CONNECTION_NUM_FOR_PORT); | ||||
| UInt16 cur_index, next_index; | UInt16 cur_index, next_index; | ||||
| if (!res) | if (!res) | ||||
| return NULL; | return NULL; | ||||
| @@ -763,7 +751,7 @@ void JackGraphManager::GetPortsAux(const char** matching_ports, const char* port | |||||
| { | { | ||||
| int match_cnt = 0; | int match_cnt = 0; | ||||
| regex_t port_regex, type_regex; | regex_t port_regex, type_regex; | ||||
| if (port_name_pattern && port_name_pattern[0]) { | if (port_name_pattern && port_name_pattern[0]) { | ||||
| regcomp(&port_regex, port_name_pattern, REG_EXTENDED | REG_NOSUB); | regcomp(&port_regex, port_name_pattern, REG_EXTENDED | REG_NOSUB); | ||||
| } | } | ||||
| @@ -823,15 +811,15 @@ const char** JackGraphManager::GetPorts(const char* port_name_pattern, const cha | |||||
| { | { | ||||
| const char** res = (const char**)malloc(sizeof(char*) * fPortMax); | const char** res = (const char**)malloc(sizeof(char*) * fPortMax); | ||||
| UInt16 cur_index, next_index; | UInt16 cur_index, next_index; | ||||
| if (!res) | if (!res) | ||||
| return NULL; | return NULL; | ||||
| do { | do { | ||||
| cur_index = GetCurrentIndex(); | cur_index = GetCurrentIndex(); | ||||
| GetPortsAux(res, port_name_pattern, type_name_pattern, flags); | GetPortsAux(res, port_name_pattern, type_name_pattern, flags); | ||||
| next_index = GetCurrentIndex(); | next_index = GetCurrentIndex(); | ||||
| } while (cur_index != next_index); // Until a coherent state has been read | |||||
| } while (cur_index != next_index); // Until a coherent state has been read | |||||
| if (res[0]) { // at least one port | if (res[0]) { // at least one port | ||||
| return res; | return res; | ||||
| @@ -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. | ||||
| */ | */ | ||||
| @@ -36,7 +36,7 @@ namespace Jack | |||||
| /*! | /*! | ||||
| \brief Graph manager: contains the connection manager and the port array. | \brief Graph manager: contains the connection manager and the port array. | ||||
| */ | */ | ||||
| class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState<JackConnectionManager> | class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState<JackConnectionManager> | ||||
| { | { | ||||
| @@ -65,8 +65,6 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState | |||||
| // Ports management | // Ports management | ||||
| jack_port_id_t AllocatePort(int refnum, const char* port_name, const char* port_type, JackPortFlags flags, jack_nframes_t buffer_size); | jack_port_id_t AllocatePort(int refnum, const char* port_name, const char* port_type, JackPortFlags flags, jack_nframes_t buffer_size); | ||||
| int ReleasePort(int refnum, jack_port_id_t port_index); | int ReleasePort(int refnum, jack_port_id_t port_index); | ||||
| void ActivatePort(jack_port_id_t port_index); | |||||
| void DeactivatePort(jack_port_id_t port_index); | |||||
| void GetInputPorts(int refnum, jack_int_t* res); | void GetInputPorts(int refnum, jack_int_t* res); | ||||
| void GetOutputPorts(int refnum, jack_int_t* res); | void GetOutputPorts(int refnum, jack_int_t* res); | ||||
| void RemoveAllPorts(int refnum); | void RemoveAllPorts(int refnum); | ||||
| @@ -77,7 +75,7 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState | |||||
| int ComputeTotalLatency(jack_port_id_t port_index); | int ComputeTotalLatency(jack_port_id_t port_index); | ||||
| int ComputeTotalLatencies(); | int ComputeTotalLatencies(); | ||||
| int RequestMonitor(jack_port_id_t port_index, bool onoff); | int RequestMonitor(jack_port_id_t port_index, bool onoff); | ||||
| // Connections management | // Connections management | ||||
| int Connect(jack_port_id_t src_index, jack_port_id_t dst_index); | int Connect(jack_port_id_t src_index, jack_port_id_t dst_index); | ||||
| int Disconnect(jack_port_id_t src_index, jack_port_id_t dst_index); | int Disconnect(jack_port_id_t src_index, jack_port_id_t dst_index); | ||||
| @@ -130,7 +128,7 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState | |||||
| void Save(JackConnectionManager* dst); | void Save(JackConnectionManager* dst); | ||||
| void Restore(JackConnectionManager* src); | void Restore(JackConnectionManager* src); | ||||
| static JackGraphManager* Allocate(int port_max); | static JackGraphManager* Allocate(int port_max); | ||||
| static void Destroy(JackGraphManager* manager); | static void Destroy(JackGraphManager* manager); | ||||
| @@ -214,7 +214,7 @@ typedef void (*JackFreewheelCallback)(int starting, void *arg); | |||||
| /** | /** | ||||
| * Prototype for the client supplied function that is called | * Prototype for the client supplied function that is called | ||||
| * whenever jackd is shutdown. Note that after server shutdown, | |||||
| * whenever jackd is shutdown. Note that after server shutdown, | |||||
| * the client pointer is *not* deallocated by libjack, | * the client pointer is *not* deallocated by libjack, | ||||
| * the application is responsible to properly use jack_client_close() | * the application is responsible to properly use jack_client_close() | ||||
| * to release client ressources. Warning: jack_client_close() cannot be | * to release client ressources. Warning: jack_client_close() cannot be | ||||
| @@ -295,14 +295,7 @@ enum JackPortFlags { | |||||
| * their ports. | * their ports. | ||||
| */ | */ | ||||
| JackPortIsTerminal = 0x10, | JackPortIsTerminal = 0x10, | ||||
| /** | |||||
| * JackPortIsActive means the port has been registered and the | |||||
| * client is "active", that is jack_activate has been called | |||||
| * | |||||
| * JackPortIsActive is on between jack_activate and jack_deactivate. | |||||
| */ | |||||
| JackPortIsActive = 0x20 | |||||
| }; | }; | ||||
| /** | /** | ||||
| @@ -432,12 +425,12 @@ enum JackStatus { | |||||
| * Client's protocol version does not match | * Client's protocol version does not match | ||||
| */ | */ | ||||
| JackVersionError = 0x400, | JackVersionError = 0x400, | ||||
| /** | /** | ||||
| * Backend error | * Backend error | ||||
| */ | */ | ||||
| JackBackendError = 0x800, | JackBackendError = 0x800, | ||||
| /** | /** | ||||
| * Client zombified failure | * Client zombified failure | ||||
| */ | */ | ||||
| @@ -476,7 +469,7 @@ typedef enum { | |||||
| JackBBTFrameOffset = 0x40, /**< Frame offset of BBT information */ | JackBBTFrameOffset = 0x40, /**< Frame offset of BBT information */ | ||||
| JackAudioVideoRatio = 0x80, /**< audio frames per video frame */ | JackAudioVideoRatio = 0x80, /**< audio frames per video frame */ | ||||
| JackVideoFrameOffset = 0x100 /**< frame offset of first video frame */ | JackVideoFrameOffset = 0x100 /**< frame offset of first video frame */ | ||||
| } jack_position_bits_t; | } jack_position_bits_t; | ||||
| /** all valid position bits */ | /** all valid position bits */ | ||||
| @@ -668,13 +661,13 @@ typedef struct { | |||||
| /** | /** | ||||
| * Prototype for the client supplied function that is called | * Prototype for the client supplied function that is called | ||||
| * whenever jackd is shutdown. Note that after server shutdown, | |||||
| * whenever jackd is shutdown. Note that after server shutdown, | |||||
| * the client pointer is *not* deallocated by libjack, | * the client pointer is *not* deallocated by libjack, | ||||
| * the application is responsible to properly use jack_client_close() | * the application is responsible to properly use jack_client_close() | ||||
| * to release client ressources. Warning: jack_client_close() cannot be | * to release client ressources. Warning: jack_client_close() cannot be | ||||
| * safely used inside the shutdown callback and has to be called outside of | * safely used inside the shutdown callback and has to be called outside of | ||||
| * the callback context. | * the callback context. | ||||
| * @param code a status word, formed by OR-ing together the relevant @ref JackStatus bits. | * @param code a status word, formed by OR-ing together the relevant @ref JackStatus bits. | ||||
| * @param reason a string describing the shutdown reason (backend failure, server crash... etc...) | * @param reason a string describing the shutdown reason (backend failure, server crash... etc...) | ||||
| * @param arg pointer to a client supplied structure | * @param arg pointer to a client supplied structure | ||||
| @@ -72,7 +72,7 @@ main (int argc, char *argv[]) | |||||
| char* aliases[2]; | char* aliases[2]; | ||||
| char *server_name = NULL; | char *server_name = NULL; | ||||
| jack_port_t *port; | jack_port_t *port; | ||||
| struct option long_options[] = { | struct option long_options[] = { | ||||
| { "server", 1, 0, 's' }, | { "server", 1, 0, 's' }, | ||||
| { "aliases", 0, 0, 'A' }, | { "aliases", 0, 0, 'A' }, | ||||
| @@ -152,7 +152,7 @@ main (int argc, char *argv[]) | |||||
| } | } | ||||
| ports = jack_get_ports (client, NULL, NULL, 0); | ports = jack_get_ports (client, NULL, NULL, 0); | ||||
| if (!ports) | |||||
| if (!ports) | |||||
| goto error; | goto error; | ||||
| for (i = 0; ports && ports[i]; ++i) { | for (i = 0; ports && ports[i]; ++i) { | ||||
| @@ -177,14 +177,14 @@ main (int argc, char *argv[]) | |||||
| printf (" %s\n", aliases[i]); | printf (" %s\n", aliases[i]); | ||||
| } | } | ||||
| } | } | ||||
| if (show_con) { | if (show_con) { | ||||
| if ((connections = jack_port_get_all_connections (client, jack_port_by_name(client, ports[i]))) != 0) { | if ((connections = jack_port_get_all_connections (client, jack_port_by_name(client, ports[i]))) != 0) { | ||||
| for (j = 0; connections[j]; j++) { | for (j = 0; connections[j]; j++) { | ||||
| printf (" %s\n", connections[j]); | printf (" %s\n", connections[j]); | ||||
| } | } | ||||
| free (connections); | free (connections); | ||||
| } | |||||
| } | |||||
| } | } | ||||
| if (show_port_latency) { | if (show_port_latency) { | ||||
| if (port) { | if (port) { | ||||
| @@ -217,12 +217,7 @@ main (int argc, char *argv[]) | |||||
| if (flags & JackPortIsTerminal) { | if (flags & JackPortIsTerminal) { | ||||
| fputs ("terminal,", stdout); | fputs ("terminal,", stdout); | ||||
| } | } | ||||
| if (flags & JackPortIsActive) { | |||||
| fputs ("active,", stdout); | |||||
| } else { | |||||
| fputs ("non-active,", stdout); | |||||
| } | |||||
| putc ('\n', stdout); | putc ('\n', stdout); | ||||
| } | } | ||||
| } | } | ||||
| @@ -234,7 +229,7 @@ main (int argc, char *argv[]) | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| error: | error: | ||||
| if (ports) | if (ports) | ||||
| jack_free (ports); | jack_free (ports); | ||||
| @@ -104,7 +104,7 @@ typedef struct input_port_t { | |||||
| // jack | // jack | ||||
| midi_unpack_t unpack; | midi_unpack_t unpack; | ||||
| // midi | // midi | ||||
| int overruns; | int overruns; | ||||
| } input_port_t; | } input_port_t; | ||||
| @@ -114,7 +114,7 @@ typedef struct output_port_t { | |||||
| // jack | // jack | ||||
| midi_pack_t packer; | midi_pack_t packer; | ||||
| // midi | // midi | ||||
| event_head_t next_event; | event_head_t next_event; | ||||
| int todo; | int todo; | ||||
| @@ -425,16 +425,16 @@ static | |||||
| inline int midi_port_open_jack(alsa_rawmidi_t *midi, midi_port_t *port, int type, const char *alias) | inline int midi_port_open_jack(alsa_rawmidi_t *midi, midi_port_t *port, int type, const char *alias) | ||||
| { | { | ||||
| char name[128]; | char name[128]; | ||||
| if (type & JackPortIsOutput) | if (type & JackPortIsOutput) | ||||
| snprintf(name, sizeof(name) - 1, "system:midi_capture_%d", ++midi->midi_in_cnt); | snprintf(name, sizeof(name) - 1, "system:midi_capture_%d", ++midi->midi_in_cnt); | ||||
| else | |||||
| else | |||||
| snprintf(name, sizeof(name) - 1, "system:midi_playback_%d", ++midi->midi_out_cnt); | snprintf(name, sizeof(name) - 1, "system:midi_playback_%d", ++midi->midi_out_cnt); | ||||
| port->jack = jack_port_register(midi->client, name, JACK_DEFAULT_MIDI_TYPE, | port->jack = jack_port_register(midi->client, name, JACK_DEFAULT_MIDI_TYPE, | ||||
| type | JackPortIsPhysical | JackPortIsTerminal | JackPortIsActive, 0); | |||||
| if (port->jack) | |||||
| type | JackPortIsPhysical | JackPortIsTerminal, 0); | |||||
| if (port->jack) | |||||
| jack_port_set_alias(port->jack, alias); | jack_port_set_alias(port->jack, alias); | ||||
| return port->jack == NULL; | return port->jack == NULL; | ||||
| } | } | ||||
| @@ -455,7 +455,7 @@ int midi_port_open(alsa_rawmidi_t *midi, midi_port_t *port) | |||||
| out = &port->rawmidi; | out = &port->rawmidi; | ||||
| type = JackPortIsInput; | type = JackPortIsInput; | ||||
| } | } | ||||
| if ((err = snd_rawmidi_open(in, out, port->dev, SND_RAWMIDI_NONBLOCK))<0) | if ((err = snd_rawmidi_open(in, out, port->dev, SND_RAWMIDI_NONBLOCK))<0) | ||||
| return err; | return err; | ||||
| @@ -749,7 +749,7 @@ void* scan_thread(void *arg) | |||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| /* | |||||
| /* | |||||
| * ------------------------------- Input/Output ------------------------------ | * ------------------------------- Input/Output ------------------------------ | ||||
| */ | */ | ||||
| @@ -836,7 +836,7 @@ void *midi_thread(void *arg) | |||||
| npfds = 1; | npfds = 1; | ||||
| if (jack_is_realtime(midi->client)) | if (jack_is_realtime(midi->client)) | ||||
| set_threaded_log_function(); | |||||
| set_threaded_log_function(); | |||||
| //debug_log("midi_thread(%s): enter", str->name); | //debug_log("midi_thread(%s): enter", str->name); | ||||
| @@ -978,7 +978,7 @@ int midi_update_pfds(process_midi_t *proc) | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| /* | |||||
| /* | |||||
| * ------------------------------------ Input ------------------------------ | * ------------------------------------ Input ------------------------------ | ||||
| */ | */ | ||||
| @@ -1083,7 +1083,7 @@ int do_midi_input(process_midi_t *proc) | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| /* | |||||
| /* | |||||
| * ------------------------------------ Output ------------------------------ | * ------------------------------------ Output ------------------------------ | ||||
| */ | */ | ||||
| @@ -1149,7 +1149,7 @@ int do_midi_output(process_midi_t *proc) | |||||
| } else | } else | ||||
| debug_log("midi_out: at %ld got %d bytes for %ld", (long)proc->cur_time, (int)port->next_event.size, (long)port->next_event.time); | debug_log("midi_out: at %ld got %d bytes for %ld", (long)proc->cur_time, (int)port->next_event.size, (long)port->next_event.time); | ||||
| } | } | ||||
| if (port->todo) | if (port->todo) | ||||
| debug_log("midi_out: todo = %d at %ld", (int)port->todo, (long)proc->cur_time); | debug_log("midi_out: todo = %d at %ld", (int)port->todo, (long)proc->cur_time); | ||||
| @@ -285,7 +285,7 @@ int alsa_seqmidi_attach(alsa_midi_t *m) | |||||
| self->client_id = snd_seq_client_id(self->seq); | self->client_id = snd_seq_client_id(self->seq); | ||||
| self->queue = snd_seq_alloc_queue(self->seq); | self->queue = snd_seq_alloc_queue(self->seq); | ||||
| snd_seq_start_queue(self->seq, self->queue, 0); | |||||
| snd_seq_start_queue(self->seq, self->queue, 0); | |||||
| stream_attach(self, PORT_INPUT); | stream_attach(self, PORT_INPUT); | ||||
| stream_attach(self, PORT_OUTPUT); | stream_attach(self, PORT_OUTPUT); | ||||
| @@ -488,14 +488,14 @@ port_t* port_create(alsa_seqmidi_t *self, int type, snd_seq_addr_t addr, const s | |||||
| /* mark anything that looks like a hardware port as physical&terminal */ | /* mark anything that looks like a hardware port as physical&terminal */ | ||||
| if (snd_seq_port_info_get_type (info) & (SND_SEQ_PORT_TYPE_HARDWARE|SND_SEQ_PORT_TYPE_PORT|SND_SEQ_PORT_TYPE_SPECIFIC)) { | if (snd_seq_port_info_get_type (info) & (SND_SEQ_PORT_TYPE_HARDWARE|SND_SEQ_PORT_TYPE_PORT|SND_SEQ_PORT_TYPE_SPECIFIC)) { | ||||
| jack_caps |= (JackPortIsPhysical | JackPortIsTerminal | JackPortIsActive); | |||||
| jack_caps |= (JackPortIsPhysical | JackPortIsTerminal); | |||||
| } | } | ||||
| if (jack_caps & JackPortIsOutput) | if (jack_caps & JackPortIsOutput) | ||||
| snprintf(name, sizeof(name) - 1, "system:midi_capture_%d", ++self->midi_in_cnt); | snprintf(name, sizeof(name) - 1, "system:midi_capture_%d", ++self->midi_in_cnt); | ||||
| else | |||||
| else | |||||
| snprintf(name, sizeof(name) - 1, "system:midi_playback_%d", ++self->midi_out_cnt); | snprintf(name, sizeof(name) - 1, "system:midi_playback_%d", ++self->midi_out_cnt); | ||||
| port->jack_port = jack_port_register(self->jack, | port->jack_port = jack_port_register(self->jack, | ||||
| name, JACK_DEFAULT_MIDI_TYPE, jack_caps, 0); | name, JACK_DEFAULT_MIDI_TYPE, jack_caps, 0); | ||||
| if (!port->jack_port) | if (!port->jack_port) | ||||
| @@ -588,7 +588,7 @@ void update_ports(alsa_seqmidi_t *self) | |||||
| snd_seq_port_info_alloca(&info); | snd_seq_port_info_alloca(&info); | ||||
| while ((size = jack_ringbuffer_read(self->port_add, (char*)&addr, sizeof(addr)))) { | while ((size = jack_ringbuffer_read(self->port_add, (char*)&addr, sizeof(addr)))) { | ||||
| int err; | int err; | ||||
| assert (size == sizeof(addr)); | assert (size == sizeof(addr)); | ||||
| @@ -666,7 +666,7 @@ void set_process_info(struct process_info *info, alsa_seqmidi_t *self, int dir, | |||||
| info->alsa_time = alsa_time->tv_sec * NSEC_PER_SEC + alsa_time->tv_nsec; | info->alsa_time = alsa_time->tv_sec * NSEC_PER_SEC + alsa_time->tv_nsec; | ||||
| if (info->period_start + info->nframes < info->cur_frames) { | if (info->period_start + info->nframes < info->cur_frames) { | ||||
| int periods_lost = (info->cur_frames - info->period_start) / info->nframes; | |||||
| int periods_lost = (info->cur_frames - info->period_start) / info->nframes; | |||||
| info->period_start += periods_lost * info->nframes; | info->period_start += periods_lost * info->nframes; | ||||
| debug_log("xrun detected: %d periods lost\n", periods_lost); | debug_log("xrun detected: %d periods lost\n", periods_lost); | ||||
| } | } | ||||
| @@ -805,7 +805,7 @@ void input_event(alsa_seqmidi_t *self, snd_seq_event_t *alsa_event, struct proce | |||||
| ev.size = size; | ev.size = size; | ||||
| jack_ringbuffer_write(port->early_events, (char*)&ev, sizeof(ev)); | jack_ringbuffer_write(port->early_events, (char*)&ev, sizeof(ev)); | ||||
| jack_ringbuffer_write(port->early_events, (char*)data, size); | jack_ringbuffer_write(port->early_events, (char*)data, size); | ||||
| debug_log("postponed to next frame +%d", (int) (event_frame - info->nframes)); | |||||
| debug_log("postponed to next frame +%d", (int) (event_frame - info->nframes)); | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -829,7 +829,7 @@ void alsa_seqmidi_read(alsa_midi_t *m, jack_nframes_t nframes) | |||||
| return; | return; | ||||
| set_process_info(&info, self, PORT_INPUT, nframes); | set_process_info(&info, self, PORT_INPUT, nframes); | ||||
| jack_process(self, &info); | |||||
| jack_process(self, &info); | |||||
| while ((res = snd_seq_event_input(self->seq, &event))>0) { | while ((res = snd_seq_event_input(self->seq, &event))>0) { | ||||
| if (event->source.client == SND_SEQ_CLIENT_SYSTEM) | if (event->source.client == SND_SEQ_CLIENT_SYSTEM) | ||||
| @@ -184,9 +184,9 @@ OSStatus JackCoreAudioAdapter::DeviceNotificationCallback(AudioDeviceID inDevice | |||||
| AudioDevicePropertyID inPropertyID, | AudioDevicePropertyID inPropertyID, | ||||
| void* inClientData) | void* inClientData) | ||||
| { | { | ||||
| switch (inPropertyID) { | switch (inPropertyID) { | ||||
| case kAudioDeviceProcessorOverload: { | case kAudioDeviceProcessorOverload: { | ||||
| jack_error("JackCoreAudioAdapter::DeviceNotificationCallback kAudioDeviceProcessorOverload"); | jack_error("JackCoreAudioAdapter::DeviceNotificationCallback kAudioDeviceProcessorOverload"); | ||||
| break; | break; | ||||
| @@ -196,12 +196,12 @@ OSStatus JackCoreAudioAdapter::DeviceNotificationCallback(AudioDeviceID inDevice | |||||
| jack_error("Cannot handle kAudioDevicePropertyStreamConfiguration"); | jack_error("Cannot handle kAudioDevicePropertyStreamConfiguration"); | ||||
| return kAudioHardwareUnsupportedOperationError; | return kAudioHardwareUnsupportedOperationError; | ||||
| } | } | ||||
| case kAudioDevicePropertyNominalSampleRate: { | case kAudioDevicePropertyNominalSampleRate: { | ||||
| jack_error("Cannot handle kAudioDevicePropertyNominalSampleRate"); | jack_error("Cannot handle kAudioDevicePropertyNominalSampleRate"); | ||||
| return kAudioHardwareUnsupportedOperationError; | return kAudioHardwareUnsupportedOperationError; | ||||
| } | } | ||||
| } | } | ||||
| return noErr; | return noErr; | ||||
| } | } | ||||
| @@ -217,7 +217,7 @@ int JackCoreAudioAdapter::AddListeners() | |||||
| printError(err); | printError(err); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioHardwarePropertyDevices, DeviceNotificationCallback, this); | err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioHardwarePropertyDevices, DeviceNotificationCallback, this); | ||||
| if (err != noErr) { | if (err != noErr) { | ||||
| jack_error("Error calling AudioDeviceAddPropertyListener with kAudioHardwarePropertyDevices"); | jack_error("Error calling AudioDeviceAddPropertyListener with kAudioHardwarePropertyDevices"); | ||||
| @@ -275,17 +275,17 @@ OSStatus JackCoreAudioAdapter::Render(void *inRefCon, | |||||
| { | { | ||||
| JackCoreAudioAdapter* adapter = static_cast<JackCoreAudioAdapter*>(inRefCon); | JackCoreAudioAdapter* adapter = static_cast<JackCoreAudioAdapter*>(inRefCon); | ||||
| AudioUnitRender(adapter->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, adapter->fInputData); | AudioUnitRender(adapter->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, adapter->fInputData); | ||||
| float* inputBuffer[adapter->fCaptureChannels]; | float* inputBuffer[adapter->fCaptureChannels]; | ||||
| float* outputBuffer[adapter->fPlaybackChannels]; | float* outputBuffer[adapter->fPlaybackChannels]; | ||||
| for (int i = 0; i < adapter->fCaptureChannels; i++) { | for (int i = 0; i < adapter->fCaptureChannels; i++) { | ||||
| inputBuffer[i] = (float*)adapter->fInputData->mBuffers[i].mData; | inputBuffer[i] = (float*)adapter->fInputData->mBuffers[i].mData; | ||||
| } | } | ||||
| for (int i = 0; i < adapter->fPlaybackChannels; i++) { | for (int i = 0; i < adapter->fPlaybackChannels; i++) { | ||||
| outputBuffer[i] = (float*)ioData->mBuffers[i].mData; | outputBuffer[i] = (float*)ioData->mBuffers[i].mData; | ||||
| } | } | ||||
| adapter->PushAndPull((float**)inputBuffer, (float**)outputBuffer, inNumberFrames); | adapter->PushAndPull((float**)inputBuffer, (float**)outputBuffer, inNumberFrames); | ||||
| return noErr; | return noErr; | ||||
| } | } | ||||
| @@ -302,16 +302,16 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra | |||||
| fCaptureUID[0] = 0; | fCaptureUID[0] = 0; | ||||
| fPlaybackUID[0] = 0; | fPlaybackUID[0] = 0; | ||||
| fClockDriftCompensate = false; | fClockDriftCompensate = false; | ||||
| // Default values | // Default values | ||||
| fCaptureChannels = -1; | fCaptureChannels = -1; | ||||
| fPlaybackChannels = -1; | fPlaybackChannels = -1; | ||||
| SInt32 major; | SInt32 major; | ||||
| SInt32 minor; | SInt32 minor; | ||||
| Gestalt(gestaltSystemVersionMajor, &major); | Gestalt(gestaltSystemVersionMajor, &major); | ||||
| Gestalt(gestaltSystemVersionMinor, &minor); | Gestalt(gestaltSystemVersionMinor, &minor); | ||||
| // Starting with 10.6 systems, the HAL notification thread is created internally | // Starting with 10.6 systems, the HAL notification thread is created internally | ||||
| if (major == 10 && minor >= 6) { | if (major == 10 && minor >= 6) { | ||||
| CFRunLoopRef theRunLoop = NULL; | CFRunLoopRef theRunLoop = NULL; | ||||
| @@ -321,7 +321,7 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra | |||||
| jack_error("JackCoreAudioAdapter::Open kAudioHardwarePropertyRunLoop error"); | jack_error("JackCoreAudioAdapter::Open kAudioHardwarePropertyRunLoop error"); | ||||
| } | } | ||||
| } | } | ||||
| for (node = params; node; node = jack_slist_next(node)) { | for (node = params; node; node = jack_slist_next(node)) { | ||||
| param = (const jack_driver_param_t*) node->data; | param = (const jack_driver_param_t*) node->data; | ||||
| @@ -348,7 +348,7 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra | |||||
| fPlaying = true; | fPlaying = true; | ||||
| strncpy(fPlaybackUID, param->value.str, 256); | strncpy(fPlaybackUID, param->value.str, 256); | ||||
| break; | break; | ||||
| case 'd': | case 'd': | ||||
| strncpy(fCaptureUID, param->value.str, 256); | strncpy(fCaptureUID, param->value.str, 256); | ||||
| strncpy(fPlaybackUID, param->value.str, 256); | strncpy(fPlaybackUID, param->value.str, 256); | ||||
| @@ -365,51 +365,51 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra | |||||
| case 'p': | case 'p': | ||||
| SetAdaptedBufferSize(param->value.ui); | SetAdaptedBufferSize(param->value.ui); | ||||
| break; | break; | ||||
| case 'l': | case 'l': | ||||
| DisplayDeviceNames(); | DisplayDeviceNames(); | ||||
| break; | break; | ||||
| case 'q': | case 'q': | ||||
| fQuality = param->value.ui; | fQuality = param->value.ui; | ||||
| break; | break; | ||||
| case 'g': | case 'g': | ||||
| fRingbufferCurSize = param->value.ui; | fRingbufferCurSize = param->value.ui; | ||||
| fAdaptative = false; | fAdaptative = false; | ||||
| break; | break; | ||||
| case 's': | case 's': | ||||
| fClockDriftCompensate = true; | fClockDriftCompensate = true; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| /* duplex is the default */ | /* duplex is the default */ | ||||
| if (!fCapturing && !fPlaying) { | if (!fCapturing && !fPlaying) { | ||||
| fCapturing = true; | fCapturing = true; | ||||
| fPlaying = true; | fPlaying = true; | ||||
| } | } | ||||
| if (SetupDevices(fCaptureUID, fPlaybackUID, captureName, playbackName, fAdaptedSampleRate) < 0) | if (SetupDevices(fCaptureUID, fPlaybackUID, captureName, playbackName, fAdaptedSampleRate) < 0) | ||||
| throw -1; | throw -1; | ||||
| if (SetupChannels(fCapturing, fPlaying, fCaptureChannels, fPlaybackChannels, in_nChannels, out_nChannels, true) < 0) | if (SetupChannels(fCapturing, fPlaying, fCaptureChannels, fPlaybackChannels, in_nChannels, out_nChannels, true) < 0) | ||||
| throw -1; | throw -1; | ||||
| if (SetupBufferSize(fAdaptedBufferSize) < 0) | if (SetupBufferSize(fAdaptedBufferSize) < 0) | ||||
| throw -1; | throw -1; | ||||
| if (SetupSampleRate(fAdaptedSampleRate) < 0) | if (SetupSampleRate(fAdaptedSampleRate) < 0) | ||||
| throw -1; | throw -1; | ||||
| if (OpenAUHAL(fCapturing, fPlaying, fCaptureChannels, fPlaybackChannels, in_nChannels, out_nChannels, fAdaptedBufferSize, fAdaptedSampleRate) < 0) | |||||
| if (OpenAUHAL(fCapturing, fPlaying, fCaptureChannels, fPlaybackChannels, in_nChannels, out_nChannels, fAdaptedBufferSize, fAdaptedSampleRate) < 0) | |||||
| throw -1; | throw -1; | ||||
| if (fCapturing && fCaptureChannels > 0) | if (fCapturing && fCaptureChannels > 0) | ||||
| if (SetupBuffers(fCaptureChannels) < 0) | if (SetupBuffers(fCaptureChannels) < 0) | ||||
| throw -1; | throw -1; | ||||
| if (AddListeners() < 0) | if (AddListeners() < 0) | ||||
| throw -1; | throw -1; | ||||
| } | } | ||||
| @@ -488,6 +488,10 @@ OSStatus JackCoreAudioAdapter::GetDefaultInputDevice(AudioDeviceID* id) | |||||
| if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) | if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) | ||||
| return res; | return res; | ||||
| if (inDefault == 0) { | |||||
| jack_error("Error : input device is 0, please select a correct one !!"); | |||||
| return -1; | |||||
| } | |||||
| jack_log("GetDefaultInputDevice: input = %ld ", inDefault); | jack_log("GetDefaultInputDevice: input = %ld ", inDefault); | ||||
| *id = inDefault; | *id = inDefault; | ||||
| return noErr; | return noErr; | ||||
| @@ -502,6 +506,10 @@ OSStatus JackCoreAudioAdapter::GetDefaultOutputDevice(AudioDeviceID* id) | |||||
| if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) | if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) | ||||
| return res; | return res; | ||||
| if (outDefault == 0) { | |||||
| jack_error("Error : output device is 0, please select a correct one !!"); | |||||
| return -1; | |||||
| } | |||||
| jack_log("GetDefaultOutputDevice: output = %ld", outDefault); | jack_log("GetDefaultOutputDevice: output = %ld", outDefault); | ||||
| *id = outDefault; | *id = outDefault; | ||||
| return noErr; | return noErr; | ||||
| @@ -525,10 +533,10 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, | |||||
| // Duplex | // Duplex | ||||
| if (strcmp(capture_driver_uid, "") != 0 && strcmp(playback_driver_uid, "") != 0) { | if (strcmp(capture_driver_uid, "") != 0 && strcmp(playback_driver_uid, "") != 0) { | ||||
| // Same device for capture and playback... | // Same device for capture and playback... | ||||
| if (strcmp(capture_driver_uid, playback_driver_uid) == 0) { | if (strcmp(capture_driver_uid, playback_driver_uid) == 0) { | ||||
| if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) { | if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) { | ||||
| jack_log("Will take default in/out"); | jack_log("Will take default in/out"); | ||||
| if (GetDefaultDevice(&fDeviceID) != noErr) { | if (GetDefaultDevice(&fDeviceID) != noErr) { | ||||
| @@ -540,12 +548,12 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, | |||||
| jack_error("Cannot get device name from device ID"); | jack_error("Cannot get device name from device ID"); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| } else { | } else { | ||||
| // Creates aggregate device | // Creates aggregate device | ||||
| AudioDeviceID captureID, playbackID; | AudioDeviceID captureID, playbackID; | ||||
| if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { | if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { | ||||
| jack_log("Will take default input"); | jack_log("Will take default input"); | ||||
| if (GetDefaultInputDevice(&captureID) != noErr) { | if (GetDefaultInputDevice(&captureID) != noErr) { | ||||
| @@ -553,7 +561,7 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, | |||||
| return -1; | return -1; | ||||
| } | } | ||||
| } | } | ||||
| if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) { | if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) { | ||||
| jack_log("Will take default output"); | jack_log("Will take default output"); | ||||
| if (GetDefaultOutputDevice(&playbackID) != noErr) { | if (GetDefaultOutputDevice(&playbackID) != noErr) { | ||||
| @@ -561,7 +569,7 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, | |||||
| return -1; | return -1; | ||||
| } | } | ||||
| } | } | ||||
| if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) | if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| @@ -599,10 +607,10 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, | |||||
| jack_log("JackCoreAudioDriver::Open default driver"); | jack_log("JackCoreAudioDriver::Open default driver"); | ||||
| if (GetDefaultDevice(&fDeviceID) != noErr) { | if (GetDefaultDevice(&fDeviceID) != noErr) { | ||||
| jack_error("Cannot open default device in duplex mode, so aggregate default input and default output"); | jack_error("Cannot open default device in duplex mode, so aggregate default input and default output"); | ||||
| // Creates aggregate device | // Creates aggregate device | ||||
| AudioDeviceID captureID, playbackID; | AudioDeviceID captureID, playbackID; | ||||
| if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { | if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { | ||||
| jack_log("Will take default input"); | jack_log("Will take default input"); | ||||
| if (GetDefaultInputDevice(&captureID) != noErr) { | if (GetDefaultInputDevice(&captureID) != noErr) { | ||||
| @@ -610,7 +618,7 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, | |||||
| return -1; | return -1; | ||||
| } | } | ||||
| } | } | ||||
| if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) { | if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) { | ||||
| jack_log("Will take default output"); | jack_log("Will take default output"); | ||||
| if (GetDefaultOutputDevice(&playbackID) != noErr) { | if (GetDefaultOutputDevice(&playbackID) != noErr) { | ||||
| @@ -618,7 +626,7 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, | |||||
| return -1; | return -1; | ||||
| } | } | ||||
| } | } | ||||
| if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) | if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| @@ -680,7 +688,7 @@ int JackCoreAudioAdapter::SetupChannels(bool capturing, | |||||
| jack_log("Setup max out channels = %ld", out_nChannels); | jack_log("Setup max out channels = %ld", out_nChannels); | ||||
| outchannels = out_nChannels; | outchannels = out_nChannels; | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -694,7 +702,7 @@ int JackCoreAudioAdapter::SetupBufferSize(jack_nframes_t buffer_size) | |||||
| printError(err); | printError(err); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -708,7 +716,7 @@ int JackCoreAudioAdapter::SetupSampleRateAux(AudioDeviceID inDevice, jack_nframe | |||||
| OSStatus err = noErr; | OSStatus err = noErr; | ||||
| UInt32 outSize; | UInt32 outSize; | ||||
| Float64 sampleRate; | Float64 sampleRate; | ||||
| // Get sample rate | // Get sample rate | ||||
| outSize = sizeof(Float64); | outSize = sizeof(Float64); | ||||
| err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); | err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); | ||||
| @@ -716,12 +724,14 @@ int JackCoreAudioAdapter::SetupSampleRateAux(AudioDeviceID inDevice, jack_nframe | |||||
| jack_error("Cannot get current sample rate"); | jack_error("Cannot get current sample rate"); | ||||
| printError(err); | printError(err); | ||||
| return -1; | return -1; | ||||
| } else { | |||||
| jack_log("Current sample rate = %f", sampleRate); | |||||
| } | } | ||||
| // If needed, set new sample rate | // If needed, set new sample rate | ||||
| if (samplerate != (jack_nframes_t)sampleRate) { | if (samplerate != (jack_nframes_t)sampleRate) { | ||||
| sampleRate = (Float64)samplerate; | sampleRate = (Float64)samplerate; | ||||
| // To get SR change notification | // To get SR change notification | ||||
| err = AudioDeviceAddPropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback, this); | err = AudioDeviceAddPropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback, this); | ||||
| if (err != noErr) { | if (err != noErr) { | ||||
| @@ -735,18 +745,18 @@ int JackCoreAudioAdapter::SetupSampleRateAux(AudioDeviceID inDevice, jack_nframe | |||||
| printError(err); | printError(err); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| // Waiting for SR change notification | // Waiting for SR change notification | ||||
| int count = 0; | int count = 0; | ||||
| while (!fState && count++ < WAIT_COUNTER) { | while (!fState && count++ < WAIT_COUNTER) { | ||||
| usleep(100000); | usleep(100000); | ||||
| jack_log("Wait count = %d", count); | jack_log("Wait count = %d", count); | ||||
| } | } | ||||
| // Remove SR change notification | // Remove SR change notification | ||||
| AudioDeviceRemovePropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback); | AudioDeviceRemovePropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback); | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -796,7 +806,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, | |||||
| jack_error("No input and output channels..."); | jack_error("No input and output channels..."); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| // AUHAL | // AUHAL | ||||
| ComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0}; | ComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0}; | ||||
| Component HALOutput = FindNextComponent(NULL, &cd); | Component HALOutput = FindNextComponent(NULL, &cd); | ||||
| @@ -823,7 +833,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, | |||||
| enableIO = 0; | enableIO = 0; | ||||
| jack_log("Setup AUHAL input off"); | jack_log("Setup AUHAL input off"); | ||||
| } | } | ||||
| err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO)); | err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO)); | ||||
| if (err1 != noErr) { | if (err1 != noErr) { | ||||
| jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input"); | jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input"); | ||||
| @@ -838,14 +848,14 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, | |||||
| enableIO = 0; | enableIO = 0; | ||||
| jack_log("Setup AUHAL output off"); | jack_log("Setup AUHAL output off"); | ||||
| } | } | ||||
| err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO)); | err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO)); | ||||
| if (err1 != noErr) { | if (err1 != noErr) { | ||||
| jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO,kAudioUnitScope_Output"); | jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO,kAudioUnitScope_Output"); | ||||
| printError(err1); | printError(err1); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| size = sizeof(AudioDeviceID); | size = sizeof(AudioDeviceID); | ||||
| err1 = AudioUnitGetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &currAudioDeviceID, &size); | err1 = AudioUnitGetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &currAudioDeviceID, &size); | ||||
| if (err1 != noErr) { | if (err1 != noErr) { | ||||
| @@ -863,7 +873,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, | |||||
| printError(err1); | printError(err1); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| // Set buffer size | // Set buffer size | ||||
| if (capturing && inchannels > 0) { | if (capturing && inchannels > 0) { | ||||
| err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&buffer_size, sizeof(UInt32)); | err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&buffer_size, sizeof(UInt32)); | ||||
| @@ -918,7 +928,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, | |||||
| // Setup stream converters | // Setup stream converters | ||||
| if (capturing && inchannels > 0) { | if (capturing && inchannels > 0) { | ||||
| size = sizeof(AudioStreamBasicDescription); | size = sizeof(AudioStreamBasicDescription); | ||||
| err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &srcFormat, &size); | err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &srcFormat, &size); | ||||
| if (err1 != noErr) { | if (err1 != noErr) { | ||||
| @@ -927,7 +937,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, | |||||
| goto error; | goto error; | ||||
| } | } | ||||
| PrintStreamDesc(&srcFormat); | PrintStreamDesc(&srcFormat); | ||||
| jack_log("Setup AUHAL input stream converter SR = %ld", samplerate); | jack_log("Setup AUHAL input stream converter SR = %ld", samplerate); | ||||
| srcFormat.mSampleRate = samplerate; | srcFormat.mSampleRate = samplerate; | ||||
| srcFormat.mFormatID = kAudioFormatLinearPCM; | srcFormat.mFormatID = kAudioFormatLinearPCM; | ||||
| @@ -938,9 +948,9 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, | |||||
| srcFormat.mChannelsPerFrame = inchannels; | srcFormat.mChannelsPerFrame = inchannels; | ||||
| srcFormat.mBitsPerChannel = 32; | srcFormat.mBitsPerChannel = 32; | ||||
| PrintStreamDesc(&srcFormat); | PrintStreamDesc(&srcFormat); | ||||
| err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription)); | err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription)); | ||||
| if (err1 != noErr) { | if (err1 != noErr) { | ||||
| jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); | jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); | ||||
| printError(err1); | printError(err1); | ||||
| @@ -949,7 +959,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, | |||||
| } | } | ||||
| if (playing && outchannels > 0) { | if (playing && outchannels > 0) { | ||||
| size = sizeof(AudioStreamBasicDescription); | size = sizeof(AudioStreamBasicDescription); | ||||
| err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 1, &dstFormat, &size); | err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 1, &dstFormat, &size); | ||||
| if (err1 != noErr) { | if (err1 != noErr) { | ||||
| @@ -958,7 +968,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, | |||||
| goto error; | goto error; | ||||
| } | } | ||||
| PrintStreamDesc(&dstFormat); | PrintStreamDesc(&dstFormat); | ||||
| jack_log("Setup AUHAL output stream converter SR = %ld", samplerate); | jack_log("Setup AUHAL output stream converter SR = %ld", samplerate); | ||||
| dstFormat.mSampleRate = samplerate; | dstFormat.mSampleRate = samplerate; | ||||
| dstFormat.mFormatID = kAudioFormatLinearPCM; | dstFormat.mFormatID = kAudioFormatLinearPCM; | ||||
| @@ -969,9 +979,9 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, | |||||
| dstFormat.mChannelsPerFrame = outchannels; | dstFormat.mChannelsPerFrame = outchannels; | ||||
| dstFormat.mBitsPerChannel = 32; | dstFormat.mBitsPerChannel = 32; | ||||
| PrintStreamDesc(&dstFormat); | PrintStreamDesc(&dstFormat); | ||||
| err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription)); | err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription)); | ||||
| if (err1 != noErr) { | if (err1 != noErr) { | ||||
| jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); | jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); | ||||
| printError(err1); | printError(err1); | ||||
| @@ -1003,13 +1013,13 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, | |||||
| } | } | ||||
| return 0; | return 0; | ||||
| error: | error: | ||||
| CloseAUHAL(); | CloseAUHAL(); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| OSStatus JackCoreAudioAdapter::DestroyAggregateDevice() | |||||
| OSStatus JackCoreAudioAdapter::DestroyAggregateDevice() | |||||
| { | { | ||||
| OSStatus osErr = noErr; | OSStatus osErr = noErr; | ||||
| AudioObjectPropertyAddress pluginAOPA; | AudioObjectPropertyAddress pluginAOPA; | ||||
| @@ -1017,21 +1027,21 @@ OSStatus JackCoreAudioAdapter::DestroyAggregateDevice() | |||||
| pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; | pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; | ||||
| pluginAOPA.mElement = kAudioObjectPropertyElementMaster; | pluginAOPA.mElement = kAudioObjectPropertyElementMaster; | ||||
| UInt32 outDataSize; | UInt32 outDataSize; | ||||
| osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); | osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); | ||||
| if (osErr != noErr) { | if (osErr != noErr) { | ||||
| jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyDataSize error"); | jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyDataSize error"); | ||||
| printError(osErr); | printError(osErr); | ||||
| return osErr; | return osErr; | ||||
| } | } | ||||
| osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, 0, NULL, &outDataSize, &fDeviceID); | osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, 0, NULL, &outDataSize, &fDeviceID); | ||||
| if (osErr != noErr) { | if (osErr != noErr) { | ||||
| jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyData error"); | jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyData error"); | ||||
| printError(osErr); | printError(osErr); | ||||
| return osErr; | return osErr; | ||||
| } | } | ||||
| return noErr; | return noErr; | ||||
| } | } | ||||
| @@ -1043,15 +1053,15 @@ static CFStringRef GetDeviceName(AudioDeviceID id) | |||||
| return (err == noErr) ? UIname : NULL; | return (err == noErr) ? UIname : NULL; | ||||
| } | } | ||||
| OSStatus JackCoreAudioAdapter::CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice) | |||||
| OSStatus JackCoreAudioAdapter::CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice) | |||||
| { | { | ||||
| OSStatus err = noErr; | OSStatus err = noErr; | ||||
| AudioObjectID sub_device[32]; | AudioObjectID sub_device[32]; | ||||
| UInt32 outSize = sizeof(sub_device); | UInt32 outSize = sizeof(sub_device); | ||||
| err = AudioDeviceGetProperty(captureDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); | err = AudioDeviceGetProperty(captureDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); | ||||
| vector<AudioDeviceID> captureDeviceIDArray; | vector<AudioDeviceID> captureDeviceIDArray; | ||||
| if (err != noErr) { | if (err != noErr) { | ||||
| jack_log("Input device does not have subdevices"); | jack_log("Input device does not have subdevices"); | ||||
| captureDeviceIDArray.push_back(captureDeviceID); | captureDeviceIDArray.push_back(captureDeviceID); | ||||
| @@ -1062,10 +1072,10 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDevice(AudioDeviceID captureDevice | |||||
| captureDeviceIDArray.push_back(sub_device[i]); | captureDeviceIDArray.push_back(sub_device[i]); | ||||
| } | } | ||||
| } | } | ||||
| err = AudioDeviceGetProperty(playbackDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); | |||||
| err = AudioDeviceGetProperty(playbackDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); | |||||
| vector<AudioDeviceID> playbackDeviceIDArray; | vector<AudioDeviceID> playbackDeviceIDArray; | ||||
| if (err != noErr) { | if (err != noErr) { | ||||
| jack_log("Output device does not have subdevices"); | jack_log("Output device does not have subdevices"); | ||||
| playbackDeviceIDArray.push_back(playbackDeviceID); | playbackDeviceIDArray.push_back(playbackDeviceID); | ||||
| @@ -1076,16 +1086,16 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDevice(AudioDeviceID captureDevice | |||||
| playbackDeviceIDArray.push_back(sub_device[i]); | playbackDeviceIDArray.push_back(sub_device[i]); | ||||
| } | } | ||||
| } | } | ||||
| return CreateAggregateDeviceAux(captureDeviceIDArray, playbackDeviceIDArray, samplerate, outAggregateDevice); | return CreateAggregateDeviceAux(captureDeviceIDArray, playbackDeviceIDArray, samplerate, outAggregateDevice); | ||||
| } | } | ||||
| OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> captureDeviceID, vector<AudioDeviceID> playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice) | |||||
| OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> captureDeviceID, vector<AudioDeviceID> playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice) | |||||
| { | { | ||||
| OSStatus osErr = noErr; | OSStatus osErr = noErr; | ||||
| UInt32 outSize; | UInt32 outSize; | ||||
| Boolean outWritable; | Boolean outWritable; | ||||
| // Prepare sub-devices for clock drift compensation | // Prepare sub-devices for clock drift compensation | ||||
| // Workaround for bug in the HAL : until 10.6.2 | // Workaround for bug in the HAL : until 10.6.2 | ||||
| AudioObjectPropertyAddress theAddressOwned = { kAudioObjectPropertyOwnedObjects, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; | AudioObjectPropertyAddress theAddressOwned = { kAudioObjectPropertyOwnedObjects, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; | ||||
| @@ -1094,7 +1104,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||||
| AudioClassID inClass = kAudioSubDeviceClassID; | AudioClassID inClass = kAudioSubDeviceClassID; | ||||
| void* theQualifierData = &inClass; | void* theQualifierData = &inClass; | ||||
| UInt32 subDevicesNum = 0; | UInt32 subDevicesNum = 0; | ||||
| //--------------------------------------------------------------------------- | //--------------------------------------------------------------------------- | ||||
| // Setup SR of both devices otherwise creating AD may fail... | // Setup SR of both devices otherwise creating AD may fail... | ||||
| //--------------------------------------------------------------------------- | //--------------------------------------------------------------------------- | ||||
| @@ -1102,18 +1112,18 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||||
| UInt32 clockdomain = 0; | UInt32 clockdomain = 0; | ||||
| outSize = sizeof(UInt32); | outSize = sizeof(UInt32); | ||||
| bool need_clock_drift_compensation = false; | bool need_clock_drift_compensation = false; | ||||
| for (UInt32 i = 0; i < captureDeviceID.size(); i++) { | for (UInt32 i = 0; i < captureDeviceID.size(); i++) { | ||||
| if (SetupSampleRateAux(captureDeviceID[i], samplerate) < 0) { | if (SetupSampleRateAux(captureDeviceID[i], samplerate) < 0) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of input device"); | jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of input device"); | ||||
| } else { | } else { | ||||
| // Check clock domain | // Check clock domain | ||||
| osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); | |||||
| osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); | |||||
| if (osErr != 0) { | if (osErr != 0) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); | jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); | ||||
| printError(osErr); | printError(osErr); | ||||
| } else { | } else { | ||||
| keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; | |||||
| keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; | |||||
| jack_log("JackCoreAudioDriver::CreateAggregateDevice : input clockdomain = %d", clockdomain); | jack_log("JackCoreAudioDriver::CreateAggregateDevice : input clockdomain = %d", clockdomain); | ||||
| if (clockdomain != 0 && clockdomain != keptclockdomain) { | if (clockdomain != 0 && clockdomain != keptclockdomain) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); | jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); | ||||
| @@ -1122,18 +1132,18 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { | for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { | ||||
| if (SetupSampleRateAux(playbackDeviceID[i], samplerate) < 0) { | if (SetupSampleRateAux(playbackDeviceID[i], samplerate) < 0) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of output device"); | jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of output device"); | ||||
| } else { | } else { | ||||
| // Check clock domain | // Check clock domain | ||||
| osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); | |||||
| osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); | |||||
| if (osErr != 0) { | if (osErr != 0) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); | jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); | ||||
| printError(osErr); | printError(osErr); | ||||
| } else { | } else { | ||||
| keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; | |||||
| keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; | |||||
| jack_log("JackCoreAudioDriver::CreateAggregateDevice : output clockdomain = %d", clockdomain); | jack_log("JackCoreAudioDriver::CreateAggregateDevice : output clockdomain = %d", clockdomain); | ||||
| if (clockdomain != 0 && clockdomain != keptclockdomain) { | if (clockdomain != 0 && clockdomain != keptclockdomain) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); | jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); | ||||
| @@ -1142,74 +1152,74 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| // If no valid clock domain was found, then assume we have to compensate... | // If no valid clock domain was found, then assume we have to compensate... | ||||
| if (keptclockdomain == 0) { | if (keptclockdomain == 0) { | ||||
| need_clock_drift_compensation = true; | need_clock_drift_compensation = true; | ||||
| } | } | ||||
| //--------------------------------------------------------------------------- | //--------------------------------------------------------------------------- | ||||
| // Start to create a new aggregate by getting the base audio hardware plugin | // Start to create a new aggregate by getting the base audio hardware plugin | ||||
| //--------------------------------------------------------------------------- | //--------------------------------------------------------------------------- | ||||
| char device_name[256]; | char device_name[256]; | ||||
| for (UInt32 i = 0; i < captureDeviceID.size(); i++) { | for (UInt32 i = 0; i < captureDeviceID.size(); i++) { | ||||
| GetDeviceNameFromID(captureDeviceID[i], device_name); | GetDeviceNameFromID(captureDeviceID[i], device_name); | ||||
| jack_info("Separated input = '%s' ", device_name); | jack_info("Separated input = '%s' ", device_name); | ||||
| } | } | ||||
| for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { | for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { | ||||
| GetDeviceNameFromID(playbackDeviceID[i], device_name); | GetDeviceNameFromID(playbackDeviceID[i], device_name); | ||||
| jack_info("Separated output = '%s' ", device_name); | jack_info("Separated output = '%s' ", device_name); | ||||
| } | } | ||||
| osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable); | osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable); | ||||
| if (osErr != noErr) { | if (osErr != noErr) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error"); | jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error"); | ||||
| printError(osErr); | printError(osErr); | ||||
| return osErr; | return osErr; | ||||
| } | } | ||||
| AudioValueTranslation pluginAVT; | AudioValueTranslation pluginAVT; | ||||
| CFStringRef inBundleRef = CFSTR("com.apple.audio.CoreAudio"); | CFStringRef inBundleRef = CFSTR("com.apple.audio.CoreAudio"); | ||||
| pluginAVT.mInputData = &inBundleRef; | pluginAVT.mInputData = &inBundleRef; | ||||
| pluginAVT.mInputDataSize = sizeof(inBundleRef); | pluginAVT.mInputDataSize = sizeof(inBundleRef); | ||||
| pluginAVT.mOutputData = &fPluginID; | pluginAVT.mOutputData = &fPluginID; | ||||
| pluginAVT.mOutputDataSize = sizeof(fPluginID); | pluginAVT.mOutputDataSize = sizeof(fPluginID); | ||||
| osErr = AudioHardwareGetProperty(kAudioHardwarePropertyPlugInForBundleID, &outSize, &pluginAVT); | osErr = AudioHardwareGetProperty(kAudioHardwarePropertyPlugInForBundleID, &outSize, &pluginAVT); | ||||
| if (osErr != noErr) { | if (osErr != noErr) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioHardwareGetProperty kAudioHardwarePropertyPlugInForBundleID error"); | jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioHardwareGetProperty kAudioHardwarePropertyPlugInForBundleID error"); | ||||
| printError(osErr); | printError(osErr); | ||||
| return osErr; | return osErr; | ||||
| } | } | ||||
| //------------------------------------------------- | //------------------------------------------------- | ||||
| // Create a CFDictionary for our aggregate device | // Create a CFDictionary for our aggregate device | ||||
| //------------------------------------------------- | //------------------------------------------------- | ||||
| CFMutableDictionaryRef aggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); | CFMutableDictionaryRef aggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); | ||||
| CFStringRef AggregateDeviceNameRef = CFSTR("JackDuplex"); | CFStringRef AggregateDeviceNameRef = CFSTR("JackDuplex"); | ||||
| CFStringRef AggregateDeviceUIDRef = CFSTR("com.grame.JackDuplex"); | CFStringRef AggregateDeviceUIDRef = CFSTR("com.grame.JackDuplex"); | ||||
| // add the name of the device to the dictionary | // add the name of the device to the dictionary | ||||
| CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceNameKey), AggregateDeviceNameRef); | CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceNameKey), AggregateDeviceNameRef); | ||||
| // add our choice of UID for the aggregate device to the dictionary | // add our choice of UID for the aggregate device to the dictionary | ||||
| CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceUIDKey), AggregateDeviceUIDRef); | CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceUIDKey), AggregateDeviceUIDRef); | ||||
| // add a "private aggregate key" to the dictionary | // add a "private aggregate key" to the dictionary | ||||
| int value = 1; | int value = 1; | ||||
| CFNumberRef AggregateDeviceNumberRef = CFNumberCreate(NULL, kCFNumberIntType, &value); | CFNumberRef AggregateDeviceNumberRef = CFNumberCreate(NULL, kCFNumberIntType, &value); | ||||
| SInt32 system; | SInt32 system; | ||||
| Gestalt(gestaltSystemVersion, &system); | Gestalt(gestaltSystemVersion, &system); | ||||
| jack_log("JackCoreAudioDriver::CreateAggregateDevice : system version = %x limit = %x", system, 0x00001054); | jack_log("JackCoreAudioDriver::CreateAggregateDevice : system version = %x limit = %x", system, 0x00001054); | ||||
| // Starting with 10.5.4 systems, the AD can be internal... (better) | // Starting with 10.5.4 systems, the AD can be internal... (better) | ||||
| if (system < 0x00001054) { | if (system < 0x00001054) { | ||||
| jack_log("JackCoreAudioDriver::CreateAggregateDevice : public aggregate device...."); | jack_log("JackCoreAudioDriver::CreateAggregateDevice : public aggregate device...."); | ||||
| @@ -1217,16 +1227,16 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||||
| jack_log("JackCoreAudioDriver::CreateAggregateDevice : private aggregate device...."); | jack_log("JackCoreAudioDriver::CreateAggregateDevice : private aggregate device...."); | ||||
| CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef); | CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef); | ||||
| } | } | ||||
| // Prepare sub-devices for clock drift compensation | // Prepare sub-devices for clock drift compensation | ||||
| CFMutableArrayRef subDevicesArrayClock = NULL; | CFMutableArrayRef subDevicesArrayClock = NULL; | ||||
| /* | /* | ||||
| if (fClockDriftCompensate) { | if (fClockDriftCompensate) { | ||||
| if (need_clock_drift_compensation) { | if (need_clock_drift_compensation) { | ||||
| jack_info("Clock drift compensation activated..."); | jack_info("Clock drift compensation activated..."); | ||||
| subDevicesArrayClock = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); | subDevicesArrayClock = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); | ||||
| for (UInt32 i = 0; i < captureDeviceID.size(); i++) { | for (UInt32 i = 0; i < captureDeviceID.size(); i++) { | ||||
| CFStringRef UID = GetDeviceName(captureDeviceID[i]); | CFStringRef UID = GetDeviceName(captureDeviceID[i]); | ||||
| if (UID) { | if (UID) { | ||||
| @@ -1237,7 +1247,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||||
| CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); | CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); | ||||
| } | } | ||||
| } | } | ||||
| for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { | for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { | ||||
| CFStringRef UID = GetDeviceName(playbackDeviceID[i]); | CFStringRef UID = GetDeviceName(playbackDeviceID[i]); | ||||
| if (UID) { | if (UID) { | ||||
| @@ -1248,7 +1258,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||||
| CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); | CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); | ||||
| } | } | ||||
| } | } | ||||
| // add sub-device clock array for the aggregate device to the dictionary | // add sub-device clock array for the aggregate device to the dictionary | ||||
| CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceSubDeviceListKey), subDevicesArrayClock); | CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceSubDeviceListKey), subDevicesArrayClock); | ||||
| } else { | } else { | ||||
| @@ -1256,14 +1266,14 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||||
| } | } | ||||
| } | } | ||||
| */ | */ | ||||
| //------------------------------------------------- | //------------------------------------------------- | ||||
| // Create a CFMutableArray for our sub-device list | // Create a CFMutableArray for our sub-device list | ||||
| //------------------------------------------------- | //------------------------------------------------- | ||||
| // we need to append the UID for each device to a CFMutableArray, so create one here | // we need to append the UID for each device to a CFMutableArray, so create one here | ||||
| CFMutableArrayRef subDevicesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); | CFMutableArrayRef subDevicesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); | ||||
| vector<CFStringRef> captureDeviceUID; | vector<CFStringRef> captureDeviceUID; | ||||
| for (UInt32 i = 0; i < captureDeviceID.size(); i++) { | for (UInt32 i = 0; i < captureDeviceID.size(); i++) { | ||||
| CFStringRef ref = GetDeviceName(captureDeviceID[i]); | CFStringRef ref = GetDeviceName(captureDeviceID[i]); | ||||
| @@ -1273,7 +1283,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||||
| // input sub-devices in this example, so append the sub-device's UID to the CFArray | // input sub-devices in this example, so append the sub-device's UID to the CFArray | ||||
| CFArrayAppendValue(subDevicesArray, ref); | CFArrayAppendValue(subDevicesArray, ref); | ||||
| } | } | ||||
| vector<CFStringRef> playbackDeviceUID; | vector<CFStringRef> playbackDeviceUID; | ||||
| for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { | for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { | ||||
| CFStringRef ref = GetDeviceName(playbackDeviceID[i]); | CFStringRef ref = GetDeviceName(playbackDeviceID[i]); | ||||
| @@ -1283,39 +1293,39 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||||
| // output sub-devices in this example, so append the sub-device's UID to the CFArray | // output sub-devices in this example, so append the sub-device's UID to the CFArray | ||||
| CFArrayAppendValue(subDevicesArray, ref); | CFArrayAppendValue(subDevicesArray, ref); | ||||
| } | } | ||||
| //----------------------------------------------------------------------- | //----------------------------------------------------------------------- | ||||
| // Feed the dictionary to the plugin, to create a blank aggregate device | // Feed the dictionary to the plugin, to create a blank aggregate device | ||||
| //----------------------------------------------------------------------- | //----------------------------------------------------------------------- | ||||
| AudioObjectPropertyAddress pluginAOPA; | AudioObjectPropertyAddress pluginAOPA; | ||||
| pluginAOPA.mSelector = kAudioPlugInCreateAggregateDevice; | pluginAOPA.mSelector = kAudioPlugInCreateAggregateDevice; | ||||
| pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; | pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; | ||||
| pluginAOPA.mElement = kAudioObjectPropertyElementMaster; | pluginAOPA.mElement = kAudioObjectPropertyElementMaster; | ||||
| UInt32 outDataSize; | UInt32 outDataSize; | ||||
| osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); | osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); | ||||
| if (osErr != noErr) { | if (osErr != noErr) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectGetPropertyDataSize error"); | jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectGetPropertyDataSize error"); | ||||
| printError(osErr); | printError(osErr); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice); | osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice); | ||||
| if (osErr != noErr) { | if (osErr != noErr) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectGetPropertyData error"); | jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectGetPropertyData error"); | ||||
| printError(osErr); | printError(osErr); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| // pause for a bit to make sure that everything completed correctly | // pause for a bit to make sure that everything completed correctly | ||||
| // this is to work around a bug in the HAL where a new aggregate device seems to disappear briefly after it is created | // this is to work around a bug in the HAL where a new aggregate device seems to disappear briefly after it is created | ||||
| CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); | CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); | ||||
| //------------------------- | //------------------------- | ||||
| // Set the sub-device list | // Set the sub-device list | ||||
| //------------------------- | //------------------------- | ||||
| pluginAOPA.mSelector = kAudioAggregateDevicePropertyFullSubDeviceList; | pluginAOPA.mSelector = kAudioAggregateDevicePropertyFullSubDeviceList; | ||||
| pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; | pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; | ||||
| pluginAOPA.mElement = kAudioObjectPropertyElementMaster; | pluginAOPA.mElement = kAudioObjectPropertyElementMaster; | ||||
| @@ -1326,14 +1336,14 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||||
| printError(osErr); | printError(osErr); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| // pause again to give the changes time to take effect | // pause again to give the changes time to take effect | ||||
| CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); | CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); | ||||
| //----------------------- | //----------------------- | ||||
| // Set the master device | // Set the master device | ||||
| //----------------------- | //----------------------- | ||||
| // set the master device manually (this is the device which will act as the master clock for the aggregate device) | // set the master device manually (this is the device which will act as the master clock for the aggregate device) | ||||
| // pass in the UID of the device you want to use | // pass in the UID of the device you want to use | ||||
| pluginAOPA.mSelector = kAudioAggregateDevicePropertyMasterSubDevice; | pluginAOPA.mSelector = kAudioAggregateDevicePropertyMasterSubDevice; | ||||
| @@ -1346,36 +1356,36 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||||
| printError(osErr); | printError(osErr); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| // pause again to give the changes time to take effect | // pause again to give the changes time to take effect | ||||
| CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); | CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); | ||||
| // Prepare sub-devices for clock drift compensation | // Prepare sub-devices for clock drift compensation | ||||
| // Workaround for bug in the HAL : until 10.6.2 | // Workaround for bug in the HAL : until 10.6.2 | ||||
| if (fClockDriftCompensate) { | if (fClockDriftCompensate) { | ||||
| if (need_clock_drift_compensation) { | if (need_clock_drift_compensation) { | ||||
| jack_info("Clock drift compensation activated..."); | jack_info("Clock drift compensation activated..."); | ||||
| // Get the property data size | // Get the property data size | ||||
| osErr = AudioObjectGetPropertyDataSize(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize); | osErr = AudioObjectGetPropertyDataSize(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize); | ||||
| if (osErr != noErr) { | if (osErr != noErr) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); | jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); | ||||
| printError(osErr); | printError(osErr); | ||||
| } | } | ||||
| // Calculate the number of object IDs | // Calculate the number of object IDs | ||||
| subDevicesNum = outSize / sizeof(AudioObjectID); | subDevicesNum = outSize / sizeof(AudioObjectID); | ||||
| jack_info("JackCoreAudioDriver::CreateAggregateDevice clock drift compensation, number of sub-devices = %d", subDevicesNum); | jack_info("JackCoreAudioDriver::CreateAggregateDevice clock drift compensation, number of sub-devices = %d", subDevicesNum); | ||||
| AudioObjectID subDevices[subDevicesNum]; | AudioObjectID subDevices[subDevicesNum]; | ||||
| outSize = sizeof(subDevices); | outSize = sizeof(subDevices); | ||||
| osErr = AudioObjectGetPropertyData(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize, subDevices); | osErr = AudioObjectGetPropertyData(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize, subDevices); | ||||
| if (osErr != noErr) { | if (osErr != noErr) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); | jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); | ||||
| printError(osErr); | printError(osErr); | ||||
| } | } | ||||
| // Set kAudioSubDevicePropertyDriftCompensation property... | // Set kAudioSubDevicePropertyDriftCompensation property... | ||||
| for (UInt32 index = 0; index < subDevicesNum; ++index) { | for (UInt32 index = 0; index < subDevicesNum; ++index) { | ||||
| UInt32 theDriftCompensationValue = 1; | UInt32 theDriftCompensationValue = 1; | ||||
| @@ -1388,50 +1398,50 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca | |||||
| } else { | } else { | ||||
| jack_info("Clock drift compensation was asked but is not needed (devices use the same clock domain)"); | jack_info("Clock drift compensation was asked but is not needed (devices use the same clock domain)"); | ||||
| } | } | ||||
| } | |||||
| } | |||||
| // pause again to give the changes time to take effect | // pause again to give the changes time to take effect | ||||
| CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); | CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); | ||||
| //---------- | //---------- | ||||
| // Clean up | // Clean up | ||||
| //---------- | //---------- | ||||
| // release the private AD key | // release the private AD key | ||||
| CFRelease(AggregateDeviceNumberRef); | CFRelease(AggregateDeviceNumberRef); | ||||
| // release the CF objects we have created - we don't need them any more | // release the CF objects we have created - we don't need them any more | ||||
| CFRelease(aggDeviceDict); | CFRelease(aggDeviceDict); | ||||
| CFRelease(subDevicesArray); | CFRelease(subDevicesArray); | ||||
| if (subDevicesArrayClock) | if (subDevicesArrayClock) | ||||
| CFRelease(subDevicesArrayClock); | CFRelease(subDevicesArrayClock); | ||||
| // release the device UID | // release the device UID | ||||
| for (UInt32 i = 0; i < captureDeviceUID.size(); i++) { | for (UInt32 i = 0; i < captureDeviceUID.size(); i++) { | ||||
| CFRelease(captureDeviceUID[i]); | CFRelease(captureDeviceUID[i]); | ||||
| } | } | ||||
| for (UInt32 i = 0; i < playbackDeviceUID.size(); i++) { | for (UInt32 i = 0; i < playbackDeviceUID.size(); i++) { | ||||
| CFRelease(playbackDeviceUID[i]); | CFRelease(playbackDeviceUID[i]); | ||||
| } | } | ||||
| jack_log("New aggregate device %ld", *outAggregateDevice); | jack_log("New aggregate device %ld", *outAggregateDevice); | ||||
| return noErr; | return noErr; | ||||
| error: | error: | ||||
| DestroyAggregateDevice(); | DestroyAggregateDevice(); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| bool JackCoreAudioAdapter::IsAggregateDevice(AudioDeviceID device) | bool JackCoreAudioAdapter::IsAggregateDevice(AudioDeviceID device) | ||||
| { | { | ||||
| OSStatus err = noErr; | OSStatus err = noErr; | ||||
| AudioObjectID sub_device[32]; | AudioObjectID sub_device[32]; | ||||
| UInt32 outSize = sizeof(sub_device); | UInt32 outSize = sizeof(sub_device); | ||||
| err = AudioDeviceGetProperty(device, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); | err = AudioDeviceGetProperty(device, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); | ||||
| if (err != noErr) { | if (err != noErr) { | ||||
| jack_log("Device does not have subdevices"); | jack_log("Device does not have subdevices"); | ||||
| return false; | return false; | ||||
| @@ -1494,7 +1504,7 @@ extern "C" | |||||
| strcpy(desc->name, "audioadapter"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 | strcpy(desc->name, "audioadapter"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 | ||||
| strcpy(desc->desc, "netjack audio <==> net backend adapter"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 | strcpy(desc->desc, "netjack audio <==> net backend adapter"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 | ||||
| desc->nparams = 13; | desc->nparams = 13; | ||||
| desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); | desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); | ||||
| @@ -1574,7 +1584,7 @@ extern "C" | |||||
| desc->params[i].value.i = TRUE; | desc->params[i].value.i = TRUE; | ||||
| strcpy(desc->params[i].short_desc, "Display available CoreAudio devices"); | strcpy(desc->params[i].short_desc, "Display available CoreAudio devices"); | ||||
| strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | ||||
| i++; | i++; | ||||
| strcpy(desc->params[i].name, "quality"); | strcpy(desc->params[i].name, "quality"); | ||||
| desc->params[i].character = 'q'; | desc->params[i].character = 'q'; | ||||
| @@ -1582,7 +1592,7 @@ extern "C" | |||||
| desc->params[i].value.ui = 0; | desc->params[i].value.ui = 0; | ||||
| strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)"); | strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)"); | ||||
| strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | ||||
| i++; | i++; | ||||
| strcpy(desc->params[i].name, "ring-buffer"); | strcpy(desc->params[i].name, "ring-buffer"); | ||||
| desc->params[i].character = 'g'; | desc->params[i].character = 'g'; | ||||
| @@ -1590,7 +1600,7 @@ extern "C" | |||||
| desc->params[i].value.ui = 32768; | desc->params[i].value.ui = 32768; | ||||
| strcpy(desc->params[i].short_desc, "Fixed ringbuffer size"); | strcpy(desc->params[i].short_desc, "Fixed ringbuffer size"); | ||||
| strcpy(desc->params[i].long_desc, "Fixed ringbuffer size (if not set => automatic adaptative)"); | strcpy(desc->params[i].long_desc, "Fixed ringbuffer size (if not set => automatic adaptative)"); | ||||
| i++; | i++; | ||||
| strcpy(desc->params[i].name, "clock-drift"); | strcpy(desc->params[i].name, "clock-drift"); | ||||
| desc->params[i].character = 's'; | desc->params[i].character = 's'; | ||||
| @@ -1598,7 +1608,7 @@ extern "C" | |||||
| desc->params[i].value.i = FALSE; | desc->params[i].value.i = FALSE; | ||||
| strcpy(desc->params[i].short_desc, "Clock drift compensation"); | strcpy(desc->params[i].short_desc, "Clock drift compensation"); | ||||
| strcpy(desc->params[i].long_desc, "Whether to compensate clock drift in dynamically created aggregate device"); | strcpy(desc->params[i].long_desc, "Whether to compensate clock drift in dynamically created aggregate device"); | ||||
| return desc; | return desc; | ||||
| } | } | ||||
| @@ -39,7 +39,7 @@ static void Print4CharCode(const char* msg, long c) | |||||
| { | { | ||||
| UInt32 __4CC_number = (c); | UInt32 __4CC_number = (c); | ||||
| char __4CC_string[5]; | char __4CC_string[5]; | ||||
| *((SInt32*)__4CC_string) = EndianU32_NtoB(__4CC_number); | |||||
| *((SInt32*)__4CC_string) = EndianU32_NtoB(__4CC_number); | |||||
| __4CC_string[4] = 0; | __4CC_string[4] = 0; | ||||
| jack_log("%s'%s'", (msg), __4CC_string); | jack_log("%s'%s'", (msg), __4CC_string); | ||||
| } | } | ||||
| @@ -194,22 +194,22 @@ OSStatus JackCoreAudioDriver::Render(void *inRefCon, | |||||
| driver->fActionFags = ioActionFlags; | driver->fActionFags = ioActionFlags; | ||||
| driver->fCurrentTime = (AudioTimeStamp *)inTimeStamp; | driver->fCurrentTime = (AudioTimeStamp *)inTimeStamp; | ||||
| driver->fDriverOutputData = ioData; | driver->fDriverOutputData = ioData; | ||||
| // Setup threadded based log function once... | // Setup threadded based log function once... | ||||
| if (set_threaded_log_function()) { | if (set_threaded_log_function()) { | ||||
| jack_log("set_threaded_log_function"); | jack_log("set_threaded_log_function"); | ||||
| JackMachThread::GetParams(pthread_self(), &driver->fEngineControl->fPeriod, &driver->fEngineControl->fComputation, &driver->fEngineControl->fConstraint); | JackMachThread::GetParams(pthread_self(), &driver->fEngineControl->fPeriod, &driver->fEngineControl->fComputation, &driver->fEngineControl->fConstraint); | ||||
| if (driver->fComputationGrain > 0) { | if (driver->fComputationGrain > 0) { | ||||
| jack_log("JackCoreAudioDriver::Render : RT thread computation setup to %d percent of period", int(driver->fComputationGrain * 100)); | jack_log("JackCoreAudioDriver::Render : RT thread computation setup to %d percent of period", int(driver->fComputationGrain * 100)); | ||||
| driver->fEngineControl->fComputation = driver->fEngineControl->fPeriod * driver->fComputationGrain; | driver->fEngineControl->fComputation = driver->fEngineControl->fPeriod * driver->fComputationGrain; | ||||
| } | } | ||||
| // Signal waiting start function... | // Signal waiting start function... | ||||
| driver->fState = true; | driver->fState = true; | ||||
| } | } | ||||
| driver->CycleTakeBeginTime(); | driver->CycleTakeBeginTime(); | ||||
| return driver->Process(); | return driver->Process(); | ||||
| } | } | ||||
| @@ -276,9 +276,9 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, | |||||
| void* inClientData) | void* inClientData) | ||||
| { | { | ||||
| JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData; | JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData; | ||||
| switch (inPropertyID) { | switch (inPropertyID) { | ||||
| case kAudioDevicePropertyDeviceIsRunning: { | case kAudioDevicePropertyDeviceIsRunning: { | ||||
| UInt32 isrunning = 0; | UInt32 isrunning = 0; | ||||
| UInt32 outsize = sizeof(UInt32); | UInt32 outsize = sizeof(UInt32); | ||||
| @@ -287,14 +287,14 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, | |||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case kAudioDeviceProcessorOverload: { | case kAudioDeviceProcessorOverload: { | ||||
| jack_error("JackCoreAudioDriver::DeviceNotificationCallback kAudioDeviceProcessorOverload"); | jack_error("JackCoreAudioDriver::DeviceNotificationCallback kAudioDeviceProcessorOverload"); | ||||
| jack_time_t cur_time = GetMicroSeconds(); | jack_time_t cur_time = GetMicroSeconds(); | ||||
| driver->NotifyXRun(cur_time, float(cur_time - driver->fBeginDateUst)); // Better this value than nothing... | |||||
| driver->NotifyXRun(cur_time, float(cur_time - driver->fBeginDateUst)); // Better this value than nothing... | |||||
| break; | break; | ||||
| } | } | ||||
| case kAudioDevicePropertyStreamConfiguration: { | case kAudioDevicePropertyStreamConfiguration: { | ||||
| jack_error("Cannot handle kAudioDevicePropertyStreamConfiguration : server will quit..."); | jack_error("Cannot handle kAudioDevicePropertyStreamConfiguration : server will quit..."); | ||||
| driver->NotifyFailure(JackBackendError, "Another application has changed the device configuration."); // Message length limited to JACK_MESSAGE_SIZE | driver->NotifyFailure(JackBackendError, "Another application has changed the device configuration."); // Message length limited to JACK_MESSAGE_SIZE | ||||
| @@ -302,25 +302,25 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, | |||||
| kill(JackTools::GetPID(), SIGINT); | kill(JackTools::GetPID(), SIGINT); | ||||
| return kAudioHardwareUnsupportedOperationError; | return kAudioHardwareUnsupportedOperationError; | ||||
| } | } | ||||
| case kAudioDevicePropertyNominalSampleRate: { | case kAudioDevicePropertyNominalSampleRate: { | ||||
| Float64 sampleRate = 0; | Float64 sampleRate = 0; | ||||
| UInt32 outsize = sizeof(Float64); | UInt32 outsize = sizeof(Float64); | ||||
| OSStatus err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sampleRate); | OSStatus err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sampleRate); | ||||
| if (err != noErr) | if (err != noErr) | ||||
| return kAudioHardwareUnsupportedOperationError; | return kAudioHardwareUnsupportedOperationError; | ||||
| char device_name[256]; | char device_name[256]; | ||||
| const char* digidesign_name = "Digidesign"; | const char* digidesign_name = "Digidesign"; | ||||
| driver->GetDeviceNameFromID(driver->fDeviceID, device_name); | driver->GetDeviceNameFromID(driver->fDeviceID, device_name); | ||||
| if (sampleRate != driver->fEngineControl->fSampleRate) { | if (sampleRate != driver->fEngineControl->fSampleRate) { | ||||
| // Digidesign hardware, so "special" code : change the SR again here | // Digidesign hardware, so "special" code : change the SR again here | ||||
| if (strncmp(device_name, digidesign_name, sizeof(digidesign_name)) == 0) { | if (strncmp(device_name, digidesign_name, sizeof(digidesign_name)) == 0) { | ||||
| jack_log("Digidesign HW = %s", device_name); | jack_log("Digidesign HW = %s", device_name); | ||||
| // Set sample rate again... | // Set sample rate again... | ||||
| sampleRate = driver->fEngineControl->fSampleRate; | sampleRate = driver->fEngineControl->fSampleRate; | ||||
| err = AudioDeviceSetProperty(driver->fDeviceID, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outsize, &sampleRate); | err = AudioDeviceSetProperty(driver->fDeviceID, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outsize, &sampleRate); | ||||
| @@ -330,7 +330,7 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, | |||||
| } else { | } else { | ||||
| jack_log("Set sample rate = %f", sampleRate); | jack_log("Set sample rate = %f", sampleRate); | ||||
| } | } | ||||
| // Check new sample rate again... | // Check new sample rate again... | ||||
| outsize = sizeof(Float64); | outsize = sizeof(Float64); | ||||
| err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sampleRate); | err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sampleRate); | ||||
| @@ -341,7 +341,7 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, | |||||
| jack_log("Checked sample rate = %f", sampleRate); | jack_log("Checked sample rate = %f", sampleRate); | ||||
| } | } | ||||
| return noErr; | return noErr; | ||||
| } else { | } else { | ||||
| driver->NotifyFailure(JackBackendError, "Another application has changed the sample rate."); // Message length limited to JACK_MESSAGE_SIZE | driver->NotifyFailure(JackBackendError, "Another application has changed the sample rate."); // Message length limited to JACK_MESSAGE_SIZE | ||||
| driver->CloseAUHAL(); | driver->CloseAUHAL(); | ||||
| @@ -350,7 +350,7 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return noErr; | return noErr; | ||||
| } | } | ||||
| @@ -405,6 +405,10 @@ OSStatus JackCoreAudioDriver::GetDefaultInputDevice(AudioDeviceID* id) | |||||
| if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) | if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) | ||||
| return res; | return res; | ||||
| if (inDefault == 0) { | |||||
| jack_error("Error : input device is 0, please select a correct one !!"); | |||||
| return -1; | |||||
| } | |||||
| jack_log("GetDefaultInputDevice: input = %ld ", inDefault); | jack_log("GetDefaultInputDevice: input = %ld ", inDefault); | ||||
| *id = inDefault; | *id = inDefault; | ||||
| return noErr; | return noErr; | ||||
| @@ -419,6 +423,10 @@ OSStatus JackCoreAudioDriver::GetDefaultOutputDevice(AudioDeviceID* id) | |||||
| if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) | if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) | ||||
| return res; | return res; | ||||
| if (outDefault == 0) { | |||||
| jack_error("Error : output device is 0, please select a correct one !!"); | |||||
| return -1; | |||||
| } | |||||
| jack_log("GetDefaultOutputDevice: output = %ld", outDefault); | jack_log("GetDefaultOutputDevice: output = %ld", outDefault); | ||||
| *id = outDefault; | *id = outDefault; | ||||
| return noErr; | return noErr; | ||||
| @@ -435,7 +443,7 @@ OSStatus JackCoreAudioDriver::GetTotalChannels(AudioDeviceID device, int& channe | |||||
| OSStatus err = noErr; | OSStatus err = noErr; | ||||
| UInt32 outSize; | UInt32 outSize; | ||||
| Boolean outWritable; | Boolean outWritable; | ||||
| channelCount = 0; | channelCount = 0; | ||||
| err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, &outWritable); | err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, &outWritable); | ||||
| if (err == noErr) { | if (err == noErr) { | ||||
| @@ -450,11 +458,11 @@ OSStatus JackCoreAudioDriver::GetTotalChannels(AudioDeviceID device, int& channe | |||||
| } | } | ||||
| JackCoreAudioDriver::JackCoreAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) | JackCoreAudioDriver::JackCoreAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) | ||||
| : JackAudioDriver(name, alias, engine, table), | |||||
| fJackInputData(NULL), | |||||
| fDriverOutputData(NULL), | |||||
| fPluginID(0), | |||||
| fState(false), | |||||
| : JackAudioDriver(name, alias, engine, table), | |||||
| fJackInputData(NULL), | |||||
| fDriverOutputData(NULL), | |||||
| fPluginID(0), | |||||
| fState(false), | |||||
| fHogged(false), | fHogged(false), | ||||
| fIOUsage(1.f), | fIOUsage(1.f), | ||||
| fComputationGrain(-1.f), | fComputationGrain(-1.f), | ||||
| @@ -464,7 +472,7 @@ JackCoreAudioDriver::JackCoreAudioDriver(const char* name, const char* alias, Ja | |||||
| JackCoreAudioDriver::~JackCoreAudioDriver() | JackCoreAudioDriver::~JackCoreAudioDriver() | ||||
| {} | {} | ||||
| OSStatus JackCoreAudioDriver::DestroyAggregateDevice() | |||||
| OSStatus JackCoreAudioDriver::DestroyAggregateDevice() | |||||
| { | { | ||||
| OSStatus osErr = noErr; | OSStatus osErr = noErr; | ||||
| AudioObjectPropertyAddress pluginAOPA; | AudioObjectPropertyAddress pluginAOPA; | ||||
| @@ -472,37 +480,37 @@ OSStatus JackCoreAudioDriver::DestroyAggregateDevice() | |||||
| pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; | pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; | ||||
| pluginAOPA.mElement = kAudioObjectPropertyElementMaster; | pluginAOPA.mElement = kAudioObjectPropertyElementMaster; | ||||
| UInt32 outDataSize; | UInt32 outDataSize; | ||||
| if (fPluginID > 0) { | if (fPluginID > 0) { | ||||
| osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); | osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); | ||||
| if (osErr != noErr) { | if (osErr != noErr) { | ||||
| jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyDataSize error"); | jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyDataSize error"); | ||||
| printError(osErr); | printError(osErr); | ||||
| return osErr; | return osErr; | ||||
| } | } | ||||
| osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, 0, NULL, &outDataSize, &fDeviceID); | osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, 0, NULL, &outDataSize, &fDeviceID); | ||||
| if (osErr != noErr) { | if (osErr != noErr) { | ||||
| jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyData error"); | jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyData error"); | ||||
| printError(osErr); | printError(osErr); | ||||
| return osErr; | return osErr; | ||||
| } | } | ||||
| } | } | ||||
| return noErr; | return noErr; | ||||
| } | } | ||||
| OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice) | |||||
| OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice) | |||||
| { | { | ||||
| OSStatus err = noErr; | OSStatus err = noErr; | ||||
| AudioObjectID sub_device[32]; | AudioObjectID sub_device[32]; | ||||
| UInt32 outSize = sizeof(sub_device); | UInt32 outSize = sizeof(sub_device); | ||||
| err = AudioDeviceGetProperty(captureDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); | err = AudioDeviceGetProperty(captureDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); | ||||
| vector<AudioDeviceID> captureDeviceIDArray; | vector<AudioDeviceID> captureDeviceIDArray; | ||||
| if (err != noErr) { | if (err != noErr) { | ||||
| jack_log("Input device does not have subdevices"); | jack_log("Input device does not have subdevices"); | ||||
| captureDeviceIDArray.push_back(captureDeviceID); | captureDeviceIDArray.push_back(captureDeviceID); | ||||
| @@ -513,10 +521,10 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI | |||||
| captureDeviceIDArray.push_back(sub_device[i]); | captureDeviceIDArray.push_back(sub_device[i]); | ||||
| } | } | ||||
| } | } | ||||
| err = AudioDeviceGetProperty(playbackDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); | |||||
| err = AudioDeviceGetProperty(playbackDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); | |||||
| vector<AudioDeviceID> playbackDeviceIDArray; | vector<AudioDeviceID> playbackDeviceIDArray; | ||||
| if (err != noErr) { | if (err != noErr) { | ||||
| jack_log("Output device does not have subdevices"); | jack_log("Output device does not have subdevices"); | ||||
| playbackDeviceIDArray.push_back(playbackDeviceID); | playbackDeviceIDArray.push_back(playbackDeviceID); | ||||
| @@ -527,16 +535,16 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI | |||||
| playbackDeviceIDArray.push_back(sub_device[i]); | playbackDeviceIDArray.push_back(sub_device[i]); | ||||
| } | } | ||||
| } | } | ||||
| return CreateAggregateDeviceAux(captureDeviceIDArray, playbackDeviceIDArray, samplerate, outAggregateDevice); | return CreateAggregateDeviceAux(captureDeviceIDArray, playbackDeviceIDArray, samplerate, outAggregateDevice); | ||||
| } | } | ||||
| OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> captureDeviceID, vector<AudioDeviceID> playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice) | |||||
| OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> captureDeviceID, vector<AudioDeviceID> playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice) | |||||
| { | { | ||||
| OSStatus osErr = noErr; | OSStatus osErr = noErr; | ||||
| UInt32 outSize; | UInt32 outSize; | ||||
| Boolean outWritable; | Boolean outWritable; | ||||
| // Prepare sub-devices for clock drift compensation | // Prepare sub-devices for clock drift compensation | ||||
| // Workaround for bug in the HAL : until 10.6.2 | // Workaround for bug in the HAL : until 10.6.2 | ||||
| AudioObjectPropertyAddress theAddressOwned = { kAudioObjectPropertyOwnedObjects, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; | AudioObjectPropertyAddress theAddressOwned = { kAudioObjectPropertyOwnedObjects, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; | ||||
| @@ -545,7 +553,7 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap | |||||
| AudioClassID inClass = kAudioSubDeviceClassID; | AudioClassID inClass = kAudioSubDeviceClassID; | ||||
| void* theQualifierData = &inClass; | void* theQualifierData = &inClass; | ||||
| UInt32 subDevicesNum = 0; | UInt32 subDevicesNum = 0; | ||||
| //--------------------------------------------------------------------------- | //--------------------------------------------------------------------------- | ||||
| // Setup SR of both devices otherwise creating AD may fail... | // Setup SR of both devices otherwise creating AD may fail... | ||||
| //--------------------------------------------------------------------------- | //--------------------------------------------------------------------------- | ||||
| @@ -553,18 +561,18 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap | |||||
| UInt32 clockdomain = 0; | UInt32 clockdomain = 0; | ||||
| outSize = sizeof(UInt32); | outSize = sizeof(UInt32); | ||||
| bool need_clock_drift_compensation = false; | bool need_clock_drift_compensation = false; | ||||
| for (UInt32 i = 0; i < captureDeviceID.size(); i++) { | for (UInt32 i = 0; i < captureDeviceID.size(); i++) { | ||||
| if (SetupSampleRateAux(captureDeviceID[i], samplerate) < 0) { | if (SetupSampleRateAux(captureDeviceID[i], samplerate) < 0) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of input device"); | jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of input device"); | ||||
| } else { | } else { | ||||
| // Check clock domain | // Check clock domain | ||||
| osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); | |||||
| osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); | |||||
| if (osErr != 0) { | if (osErr != 0) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); | jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); | ||||
| printError(osErr); | printError(osErr); | ||||
| } else { | } else { | ||||
| keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; | |||||
| keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; | |||||
| jack_log("JackCoreAudioDriver::CreateAggregateDevice : input clockdomain = %d", clockdomain); | jack_log("JackCoreAudioDriver::CreateAggregateDevice : input clockdomain = %d", clockdomain); | ||||
| if (clockdomain != 0 && clockdomain != keptclockdomain) { | if (clockdomain != 0 && clockdomain != keptclockdomain) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); | jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); | ||||
| @@ -573,18 +581,18 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { | for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { | ||||
| if (SetupSampleRateAux(playbackDeviceID[i], samplerate) < 0) { | if (SetupSampleRateAux(playbackDeviceID[i], samplerate) < 0) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of output device"); | jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of output device"); | ||||
| } else { | } else { | ||||
| // Check clock domain | // Check clock domain | ||||
| osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); | |||||
| osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); | |||||
| if (osErr != 0) { | if (osErr != 0) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); | jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); | ||||
| printError(osErr); | printError(osErr); | ||||
| } else { | } else { | ||||
| keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; | |||||
| keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; | |||||
| jack_log("JackCoreAudioDriver::CreateAggregateDevice : output clockdomain = %d", clockdomain); | jack_log("JackCoreAudioDriver::CreateAggregateDevice : output clockdomain = %d", clockdomain); | ||||
| if (clockdomain != 0 && clockdomain != keptclockdomain) { | if (clockdomain != 0 && clockdomain != keptclockdomain) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); | jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); | ||||
| @@ -593,7 +601,7 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| // If no valid clock domain was found, then assume we have to compensate... | // If no valid clock domain was found, then assume we have to compensate... | ||||
| if (keptclockdomain == 0) { | if (keptclockdomain == 0) { | ||||
| need_clock_drift_compensation = true; | need_clock_drift_compensation = true; | ||||
| @@ -602,18 +610,18 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap | |||||
| //--------------------------------------------------------------------------- | //--------------------------------------------------------------------------- | ||||
| // Start to create a new aggregate by getting the base audio hardware plugin | // Start to create a new aggregate by getting the base audio hardware plugin | ||||
| //--------------------------------------------------------------------------- | //--------------------------------------------------------------------------- | ||||
| char device_name[256]; | char device_name[256]; | ||||
| for (UInt32 i = 0; i < captureDeviceID.size(); i++) { | for (UInt32 i = 0; i < captureDeviceID.size(); i++) { | ||||
| GetDeviceNameFromID(captureDeviceID[i], device_name); | GetDeviceNameFromID(captureDeviceID[i], device_name); | ||||
| jack_info("Separated input = '%s' ", device_name); | jack_info("Separated input = '%s' ", device_name); | ||||
| } | } | ||||
| for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { | for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { | ||||
| GetDeviceNameFromID(playbackDeviceID[i], device_name); | GetDeviceNameFromID(playbackDeviceID[i], device_name); | ||||
| jack_info("Separated output = '%s' ", device_name); | jack_info("Separated output = '%s' ", device_name); | ||||
| } | } | ||||
| osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable); | osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable); | ||||
| if (osErr != noErr) { | if (osErr != noErr) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error"); | jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error"); | ||||
| @@ -624,7 +632,7 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap | |||||
| AudioValueTranslation pluginAVT; | AudioValueTranslation pluginAVT; | ||||
| CFStringRef inBundleRef = CFSTR("com.apple.audio.CoreAudio"); | CFStringRef inBundleRef = CFSTR("com.apple.audio.CoreAudio"); | ||||
| pluginAVT.mInputData = &inBundleRef; | pluginAVT.mInputData = &inBundleRef; | ||||
| pluginAVT.mInputDataSize = sizeof(inBundleRef); | pluginAVT.mInputDataSize = sizeof(inBundleRef); | ||||
| pluginAVT.mOutputData = &fPluginID; | pluginAVT.mOutputData = &fPluginID; | ||||
| @@ -645,22 +653,22 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap | |||||
| CFStringRef AggregateDeviceNameRef = CFSTR("JackDuplex"); | CFStringRef AggregateDeviceNameRef = CFSTR("JackDuplex"); | ||||
| CFStringRef AggregateDeviceUIDRef = CFSTR("com.grame.JackDuplex"); | CFStringRef AggregateDeviceUIDRef = CFSTR("com.grame.JackDuplex"); | ||||
| // add the name of the device to the dictionary | // add the name of the device to the dictionary | ||||
| CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceNameKey), AggregateDeviceNameRef); | CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceNameKey), AggregateDeviceNameRef); | ||||
| // add our choice of UID for the aggregate device to the dictionary | // add our choice of UID for the aggregate device to the dictionary | ||||
| CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceUIDKey), AggregateDeviceUIDRef); | CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceUIDKey), AggregateDeviceUIDRef); | ||||
| // add a "private aggregate key" to the dictionary | // add a "private aggregate key" to the dictionary | ||||
| int value = 1; | int value = 1; | ||||
| CFNumberRef AggregateDeviceNumberRef = CFNumberCreate(NULL, kCFNumberIntType, &value); | CFNumberRef AggregateDeviceNumberRef = CFNumberCreate(NULL, kCFNumberIntType, &value); | ||||
| SInt32 system; | SInt32 system; | ||||
| Gestalt(gestaltSystemVersion, &system); | Gestalt(gestaltSystemVersion, &system); | ||||
| jack_log("JackCoreAudioDriver::CreateAggregateDevice : system version = %x limit = %x", system, 0x00001054); | jack_log("JackCoreAudioDriver::CreateAggregateDevice : system version = %x limit = %x", system, 0x00001054); | ||||
| // Starting with 10.5.4 systems, the AD can be internal... (better) | // Starting with 10.5.4 systems, the AD can be internal... (better) | ||||
| if (system < 0x00001054) { | if (system < 0x00001054) { | ||||
| jack_log("JackCoreAudioDriver::CreateAggregateDevice : public aggregate device...."); | jack_log("JackCoreAudioDriver::CreateAggregateDevice : public aggregate device...."); | ||||
| @@ -668,16 +676,16 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap | |||||
| jack_log("JackCoreAudioDriver::CreateAggregateDevice : private aggregate device...."); | jack_log("JackCoreAudioDriver::CreateAggregateDevice : private aggregate device...."); | ||||
| CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef); | CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef); | ||||
| } | } | ||||
| // Prepare sub-devices for clock drift compensation | // Prepare sub-devices for clock drift compensation | ||||
| CFMutableArrayRef subDevicesArrayClock = NULL; | CFMutableArrayRef subDevicesArrayClock = NULL; | ||||
| /* | /* | ||||
| if (fClockDriftCompensate) { | if (fClockDriftCompensate) { | ||||
| if (need_clock_drift_compensation) { | if (need_clock_drift_compensation) { | ||||
| jack_info("Clock drift compensation activated..."); | jack_info("Clock drift compensation activated..."); | ||||
| subDevicesArrayClock = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); | subDevicesArrayClock = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); | ||||
| for (UInt32 i = 0; i < captureDeviceID.size(); i++) { | for (UInt32 i = 0; i < captureDeviceID.size(); i++) { | ||||
| CFStringRef UID = GetDeviceName(captureDeviceID[i]); | CFStringRef UID = GetDeviceName(captureDeviceID[i]); | ||||
| if (UID) { | if (UID) { | ||||
| @@ -688,7 +696,7 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap | |||||
| CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); | CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); | ||||
| } | } | ||||
| } | } | ||||
| for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { | for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { | ||||
| CFStringRef UID = GetDeviceName(playbackDeviceID[i]); | CFStringRef UID = GetDeviceName(playbackDeviceID[i]); | ||||
| if (UID) { | if (UID) { | ||||
| @@ -699,7 +707,7 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap | |||||
| CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); | CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); | ||||
| } | } | ||||
| } | } | ||||
| // add sub-device clock array for the aggregate device to the dictionary | // add sub-device clock array for the aggregate device to the dictionary | ||||
| CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceSubDeviceListKey), subDevicesArrayClock); | CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceSubDeviceListKey), subDevicesArrayClock); | ||||
| } else { | } else { | ||||
| @@ -707,14 +715,14 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap | |||||
| } | } | ||||
| } | } | ||||
| */ | */ | ||||
| //------------------------------------------------- | //------------------------------------------------- | ||||
| // Create a CFMutableArray for our sub-device list | // Create a CFMutableArray for our sub-device list | ||||
| //------------------------------------------------- | //------------------------------------------------- | ||||
| // we need to append the UID for each device to a CFMutableArray, so create one here | // we need to append the UID for each device to a CFMutableArray, so create one here | ||||
| CFMutableArrayRef subDevicesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); | CFMutableArrayRef subDevicesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); | ||||
| vector<CFStringRef> captureDeviceUID; | vector<CFStringRef> captureDeviceUID; | ||||
| for (UInt32 i = 0; i < captureDeviceID.size(); i++) { | for (UInt32 i = 0; i < captureDeviceID.size(); i++) { | ||||
| CFStringRef ref = GetDeviceName(captureDeviceID[i]); | CFStringRef ref = GetDeviceName(captureDeviceID[i]); | ||||
| @@ -724,7 +732,7 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap | |||||
| // input sub-devices in this example, so append the sub-device's UID to the CFArray | // input sub-devices in this example, so append the sub-device's UID to the CFArray | ||||
| CFArrayAppendValue(subDevicesArray, ref); | CFArrayAppendValue(subDevicesArray, ref); | ||||
| } | } | ||||
| vector<CFStringRef> playbackDeviceUID; | vector<CFStringRef> playbackDeviceUID; | ||||
| for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { | for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { | ||||
| CFStringRef ref = GetDeviceName(playbackDeviceID[i]); | CFStringRef ref = GetDeviceName(playbackDeviceID[i]); | ||||
| @@ -734,11 +742,11 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap | |||||
| // output sub-devices in this example, so append the sub-device's UID to the CFArray | // output sub-devices in this example, so append the sub-device's UID to the CFArray | ||||
| CFArrayAppendValue(subDevicesArray, ref); | CFArrayAppendValue(subDevicesArray, ref); | ||||
| } | } | ||||
| //----------------------------------------------------------------------- | //----------------------------------------------------------------------- | ||||
| // Feed the dictionary to the plugin, to create a blank aggregate device | // Feed the dictionary to the plugin, to create a blank aggregate device | ||||
| //----------------------------------------------------------------------- | //----------------------------------------------------------------------- | ||||
| AudioObjectPropertyAddress pluginAOPA; | AudioObjectPropertyAddress pluginAOPA; | ||||
| pluginAOPA.mSelector = kAudioPlugInCreateAggregateDevice; | pluginAOPA.mSelector = kAudioPlugInCreateAggregateDevice; | ||||
| pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; | pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; | ||||
| @@ -751,7 +759,7 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap | |||||
| printError(osErr); | printError(osErr); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice); | osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice); | ||||
| if (osErr != noErr) { | if (osErr != noErr) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectGetPropertyData error"); | jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectGetPropertyData error"); | ||||
| @@ -777,10 +785,10 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap | |||||
| printError(osErr); | printError(osErr); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| // pause again to give the changes time to take effect | // pause again to give the changes time to take effect | ||||
| CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); | CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); | ||||
| //----------------------- | //----------------------- | ||||
| // Set the master device | // Set the master device | ||||
| //----------------------- | //----------------------- | ||||
| @@ -797,36 +805,36 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap | |||||
| printError(osErr); | printError(osErr); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| // pause again to give the changes time to take effect | // pause again to give the changes time to take effect | ||||
| CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); | CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); | ||||
| // Prepare sub-devices for clock drift compensation | // Prepare sub-devices for clock drift compensation | ||||
| // Workaround for bug in the HAL : until 10.6.2 | // Workaround for bug in the HAL : until 10.6.2 | ||||
| if (fClockDriftCompensate) { | if (fClockDriftCompensate) { | ||||
| if (need_clock_drift_compensation) { | if (need_clock_drift_compensation) { | ||||
| jack_info("Clock drift compensation activated..."); | jack_info("Clock drift compensation activated..."); | ||||
| // Get the property data size | // Get the property data size | ||||
| osErr = AudioObjectGetPropertyDataSize(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize); | osErr = AudioObjectGetPropertyDataSize(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize); | ||||
| if (osErr != noErr) { | if (osErr != noErr) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); | jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); | ||||
| printError(osErr); | printError(osErr); | ||||
| } | } | ||||
| // Calculate the number of object IDs | // Calculate the number of object IDs | ||||
| subDevicesNum = outSize / sizeof(AudioObjectID); | subDevicesNum = outSize / sizeof(AudioObjectID); | ||||
| jack_info("JackCoreAudioDriver::CreateAggregateDevice clock drift compensation, number of sub-devices = %d", subDevicesNum); | jack_info("JackCoreAudioDriver::CreateAggregateDevice clock drift compensation, number of sub-devices = %d", subDevicesNum); | ||||
| AudioObjectID subDevices[subDevicesNum]; | AudioObjectID subDevices[subDevicesNum]; | ||||
| outSize = sizeof(subDevices); | outSize = sizeof(subDevices); | ||||
| osErr = AudioObjectGetPropertyData(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize, subDevices); | osErr = AudioObjectGetPropertyData(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize, subDevices); | ||||
| if (osErr != noErr) { | if (osErr != noErr) { | ||||
| jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); | jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); | ||||
| printError(osErr); | printError(osErr); | ||||
| } | } | ||||
| // Set kAudioSubDevicePropertyDriftCompensation property... | // Set kAudioSubDevicePropertyDriftCompensation property... | ||||
| for (UInt32 index = 0; index < subDevicesNum; ++index) { | for (UInt32 index = 0; index < subDevicesNum; ++index) { | ||||
| UInt32 theDriftCompensationValue = 1; | UInt32 theDriftCompensationValue = 1; | ||||
| @@ -839,22 +847,22 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap | |||||
| } else { | } else { | ||||
| jack_info("Clock drift compensation was asked but is not needed (devices use the same clock domain)"); | jack_info("Clock drift compensation was asked but is not needed (devices use the same clock domain)"); | ||||
| } | } | ||||
| } | |||||
| } | |||||
| // pause again to give the changes time to take effect | // pause again to give the changes time to take effect | ||||
| CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); | CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); | ||||
| //---------- | //---------- | ||||
| // Clean up | // Clean up | ||||
| //---------- | //---------- | ||||
| // release the private AD key | // release the private AD key | ||||
| CFRelease(AggregateDeviceNumberRef); | CFRelease(AggregateDeviceNumberRef); | ||||
| // release the CF objects we have created - we don't need them any more | // release the CF objects we have created - we don't need them any more | ||||
| CFRelease(aggDeviceDict); | CFRelease(aggDeviceDict); | ||||
| CFRelease(subDevicesArray); | CFRelease(subDevicesArray); | ||||
| if (subDevicesArrayClock) | if (subDevicesArrayClock) | ||||
| CFRelease(subDevicesArrayClock); | CFRelease(subDevicesArrayClock); | ||||
| @@ -862,35 +870,35 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap | |||||
| for (UInt32 i = 0; i < captureDeviceUID.size(); i++) { | for (UInt32 i = 0; i < captureDeviceUID.size(); i++) { | ||||
| CFRelease(captureDeviceUID[i]); | CFRelease(captureDeviceUID[i]); | ||||
| } | } | ||||
| for (UInt32 i = 0; i < playbackDeviceUID.size(); i++) { | for (UInt32 i = 0; i < playbackDeviceUID.size(); i++) { | ||||
| CFRelease(playbackDeviceUID[i]); | CFRelease(playbackDeviceUID[i]); | ||||
| } | } | ||||
| jack_log("New aggregate device %ld", *outAggregateDevice); | jack_log("New aggregate device %ld", *outAggregateDevice); | ||||
| return noErr; | return noErr; | ||||
| error: | error: | ||||
| DestroyAggregateDevice(); | DestroyAggregateDevice(); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, | |||||
| const char* playback_driver_uid, | |||||
| char* capture_driver_name, | |||||
| char* playback_driver_name, | |||||
| int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, | |||||
| const char* playback_driver_uid, | |||||
| char* capture_driver_name, | |||||
| char* playback_driver_name, | |||||
| jack_nframes_t samplerate) | jack_nframes_t samplerate) | ||||
| { | { | ||||
| capture_driver_name[0] = 0; | capture_driver_name[0] = 0; | ||||
| playback_driver_name[0] = 0; | playback_driver_name[0] = 0; | ||||
| // Duplex | // Duplex | ||||
| if (strcmp(capture_driver_uid, "") != 0 && strcmp(playback_driver_uid, "") != 0) { | if (strcmp(capture_driver_uid, "") != 0 && strcmp(playback_driver_uid, "") != 0) { | ||||
| jack_log("JackCoreAudioDriver::Open duplex"); | jack_log("JackCoreAudioDriver::Open duplex"); | ||||
| // Same device for capture and playback... | // Same device for capture and playback... | ||||
| if (strcmp(capture_driver_uid, playback_driver_uid) == 0) { | if (strcmp(capture_driver_uid, playback_driver_uid) == 0) { | ||||
| if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) { | if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) { | ||||
| jack_log("Will take default in/out"); | jack_log("Will take default in/out"); | ||||
| if (GetDefaultDevice(&fDeviceID) != noErr) { | if (GetDefaultDevice(&fDeviceID) != noErr) { | ||||
| @@ -902,12 +910,12 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, | |||||
| jack_error("Cannot get device name from device ID"); | jack_error("Cannot get device name from device ID"); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| } else { | } else { | ||||
| // Creates aggregate device | // Creates aggregate device | ||||
| AudioDeviceID captureID, playbackID; | AudioDeviceID captureID, playbackID; | ||||
| if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { | if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { | ||||
| jack_log("Will take default input"); | jack_log("Will take default input"); | ||||
| if (GetDefaultInputDevice(&captureID) != noErr) { | if (GetDefaultInputDevice(&captureID) != noErr) { | ||||
| @@ -963,10 +971,10 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, | |||||
| jack_log("JackCoreAudioDriver::Open default driver"); | jack_log("JackCoreAudioDriver::Open default driver"); | ||||
| if (GetDefaultDevice(&fDeviceID) != noErr) { | if (GetDefaultDevice(&fDeviceID) != noErr) { | ||||
| jack_error("Cannot open default device in duplex mode, so aggregate default input and default output"); | jack_error("Cannot open default device in duplex mode, so aggregate default input and default output"); | ||||
| // Creates aggregate device | // Creates aggregate device | ||||
| AudioDeviceID captureID, playbackID; | AudioDeviceID captureID, playbackID; | ||||
| if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { | if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { | ||||
| jack_log("Will take default input"); | jack_log("Will take default input"); | ||||
| if (GetDefaultInputDevice(&captureID) != noErr) { | if (GetDefaultInputDevice(&captureID) != noErr) { | ||||
| @@ -974,7 +982,7 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, | |||||
| return -1; | return -1; | ||||
| } | } | ||||
| } | } | ||||
| if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) { | if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) { | ||||
| jack_log("Will take default output"); | jack_log("Will take default output"); | ||||
| if (GetDefaultOutputDevice(&playbackID) != noErr) { | if (GetDefaultOutputDevice(&playbackID) != noErr) { | ||||
| @@ -982,12 +990,12 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, | |||||
| return -1; | return -1; | ||||
| } | } | ||||
| } | } | ||||
| if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) | if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| } | } | ||||
| if (fHogged) { | if (fHogged) { | ||||
| if (TakeHog()) { | if (TakeHog()) { | ||||
| jack_info("Device = %ld has been hogged", fDeviceID); | jack_info("Device = %ld has been hogged", fDeviceID); | ||||
| @@ -1111,7 +1119,7 @@ int JackCoreAudioDriver::SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes | |||||
| usleep(100000); | usleep(100000); | ||||
| jack_log("Wait count = %d", count); | jack_log("Wait count = %d", count); | ||||
| } | } | ||||
| // Check new sample rate | // Check new sample rate | ||||
| outSize = sizeof(Float64); | outSize = sizeof(Float64); | ||||
| err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); | err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); | ||||
| @@ -1150,7 +1158,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, | |||||
| jack_error("No input and output channels..."); | jack_error("No input and output channels..."); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| // AUHAL | // AUHAL | ||||
| ComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0}; | ComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0}; | ||||
| Component HALOutput = FindNextComponent(NULL, &cd); | Component HALOutput = FindNextComponent(NULL, &cd); | ||||
| @@ -1177,7 +1185,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, | |||||
| enableIO = 0; | enableIO = 0; | ||||
| jack_log("Setup AUHAL input off"); | jack_log("Setup AUHAL input off"); | ||||
| } | } | ||||
| err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO)); | err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO)); | ||||
| if (err1 != noErr) { | if (err1 != noErr) { | ||||
| jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input"); | jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input"); | ||||
| @@ -1192,14 +1200,14 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, | |||||
| enableIO = 0; | enableIO = 0; | ||||
| jack_log("Setup AUHAL output off"); | jack_log("Setup AUHAL output off"); | ||||
| } | } | ||||
| err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO)); | err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO)); | ||||
| if (err1 != noErr) { | if (err1 != noErr) { | ||||
| jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO,kAudioUnitScope_Output"); | jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO,kAudioUnitScope_Output"); | ||||
| printError(err1); | printError(err1); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| size = sizeof(AudioDeviceID); | size = sizeof(AudioDeviceID); | ||||
| err1 = AudioUnitGetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &currAudioDeviceID, &size); | err1 = AudioUnitGetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &currAudioDeviceID, &size); | ||||
| if (err1 != noErr) { | if (err1 != noErr) { | ||||
| @@ -1217,7 +1225,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, | |||||
| printError(err1); | printError(err1); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| // Set buffer size | // Set buffer size | ||||
| if (capturing && inchannels > 0) { | if (capturing && inchannels > 0) { | ||||
| err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&buffer_size, sizeof(UInt32)); | err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&buffer_size, sizeof(UInt32)); | ||||
| @@ -1272,7 +1280,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, | |||||
| // Setup stream converters | // Setup stream converters | ||||
| if (capturing && inchannels > 0) { | if (capturing && inchannels > 0) { | ||||
| size = sizeof(AudioStreamBasicDescription); | size = sizeof(AudioStreamBasicDescription); | ||||
| err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, &size); | err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, &size); | ||||
| if (err1 != noErr) { | if (err1 != noErr) { | ||||
| @@ -1281,7 +1289,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, | |||||
| goto error; | goto error; | ||||
| } | } | ||||
| PrintStreamDesc(&srcFormat); | PrintStreamDesc(&srcFormat); | ||||
| jack_log("Setup AUHAL input stream converter SR = %ld", samplerate); | jack_log("Setup AUHAL input stream converter SR = %ld", samplerate); | ||||
| srcFormat.mSampleRate = samplerate; | srcFormat.mSampleRate = samplerate; | ||||
| srcFormat.mFormatID = kAudioFormatLinearPCM; | srcFormat.mFormatID = kAudioFormatLinearPCM; | ||||
| @@ -1292,7 +1300,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, | |||||
| srcFormat.mChannelsPerFrame = inchannels; | srcFormat.mChannelsPerFrame = inchannels; | ||||
| srcFormat.mBitsPerChannel = 32; | srcFormat.mBitsPerChannel = 32; | ||||
| PrintStreamDesc(&srcFormat); | PrintStreamDesc(&srcFormat); | ||||
| err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription)); | err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription)); | ||||
| if (err1 != noErr) { | if (err1 != noErr) { | ||||
| jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); | jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); | ||||
| @@ -1302,7 +1310,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, | |||||
| } | } | ||||
| if (playing && outchannels > 0) { | if (playing && outchannels > 0) { | ||||
| size = sizeof(AudioStreamBasicDescription); | size = sizeof(AudioStreamBasicDescription); | ||||
| err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, &size); | err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, &size); | ||||
| if (err1 != noErr) { | if (err1 != noErr) { | ||||
| @@ -1311,7 +1319,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, | |||||
| goto error; | goto error; | ||||
| } | } | ||||
| PrintStreamDesc(&dstFormat); | PrintStreamDesc(&dstFormat); | ||||
| jack_log("Setup AUHAL output stream converter SR = %ld", samplerate); | jack_log("Setup AUHAL output stream converter SR = %ld", samplerate); | ||||
| dstFormat.mSampleRate = samplerate; | dstFormat.mSampleRate = samplerate; | ||||
| dstFormat.mFormatID = kAudioFormatLinearPCM; | dstFormat.mFormatID = kAudioFormatLinearPCM; | ||||
| @@ -1322,7 +1330,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, | |||||
| dstFormat.mChannelsPerFrame = outchannels; | dstFormat.mChannelsPerFrame = outchannels; | ||||
| dstFormat.mBitsPerChannel = 32; | dstFormat.mBitsPerChannel = 32; | ||||
| PrintStreamDesc(&dstFormat); | PrintStreamDesc(&dstFormat); | ||||
| err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription)); | err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription)); | ||||
| if (err1 != noErr) { | if (err1 != noErr) { | ||||
| jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); | jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); | ||||
| @@ -1355,7 +1363,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, | |||||
| } | } | ||||
| return 0; | return 0; | ||||
| error: | error: | ||||
| CloseAUHAL(); | CloseAUHAL(); | ||||
| return -1; | return -1; | ||||
| @@ -1486,12 +1494,12 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, | |||||
| fComputationGrain = float(computation_grain) / 100.f; | fComputationGrain = float(computation_grain) / 100.f; | ||||
| fHogged = hogged; | fHogged = hogged; | ||||
| fClockDriftCompensate = clock_drift; | fClockDriftCompensate = clock_drift; | ||||
| SInt32 major; | SInt32 major; | ||||
| SInt32 minor; | SInt32 minor; | ||||
| Gestalt(gestaltSystemVersionMajor, &major); | Gestalt(gestaltSystemVersionMajor, &major); | ||||
| Gestalt(gestaltSystemVersionMinor, &minor); | Gestalt(gestaltSystemVersionMinor, &minor); | ||||
| // Starting with 10.6 systems, the HAL notification thread is created internally | // Starting with 10.6 systems, the HAL notification thread is created internally | ||||
| if (major == 10 && minor >= 6) { | if (major == 10 && minor >= 6) { | ||||
| CFRunLoopRef theRunLoop = NULL; | CFRunLoopRef theRunLoop = NULL; | ||||
| @@ -1515,10 +1523,10 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, | |||||
| if (SetupBufferSize(buffer_size) < 0) | if (SetupBufferSize(buffer_size) < 0) | ||||
| goto error; | goto error; | ||||
| if (SetupSampleRate(samplerate) < 0) | if (SetupSampleRate(samplerate) < 0) | ||||
| goto error; | goto error; | ||||
| if (OpenAUHAL(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, buffer_size, samplerate) < 0) | if (OpenAUHAL(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, buffer_size, samplerate) < 0) | ||||
| goto error; | goto error; | ||||
| @@ -1528,7 +1536,7 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, | |||||
| if (AddListeners() < 0) | if (AddListeners() < 0) | ||||
| goto error; | goto error; | ||||
| // Core driver may have changed the in/out values | // Core driver may have changed the in/out values | ||||
| fCaptureChannels = inchannels; | fCaptureChannels = inchannels; | ||||
| fPlaybackChannels = outchannels; | fPlaybackChannels = outchannels; | ||||
| @@ -1561,7 +1569,7 @@ int JackCoreAudioDriver::Attach() | |||||
| char channel_name[64]; | char channel_name[64]; | ||||
| char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; | char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; | ||||
| char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; | char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; | ||||
| jack_log("JackCoreAudioDriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); | jack_log("JackCoreAudioDriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); | ||||
| for (int i = 0; i < fCaptureChannels; i++) { | for (int i = 0; i < fCaptureChannels; i++) { | ||||
| @@ -1670,7 +1678,7 @@ int JackCoreAudioDriver::Start() | |||||
| OSStatus err = AudioOutputUnitStart(fAUHAL); | OSStatus err = AudioOutputUnitStart(fAUHAL); | ||||
| if (err != noErr) | if (err != noErr) | ||||
| return -1; | return -1; | ||||
| // Waiting for Measure callback to be called (= driver has started) | // Waiting for Measure callback to be called (= driver has started) | ||||
| fState = false; | fState = false; | ||||
| int count = 0; | int count = 0; | ||||
| @@ -1678,7 +1686,7 @@ int JackCoreAudioDriver::Start() | |||||
| usleep(100000); | usleep(100000); | ||||
| jack_log("JackCoreAudioDriver::Start wait count = %d", count); | jack_log("JackCoreAudioDriver::Start wait count = %d", count); | ||||
| } | } | ||||
| if (count < WAIT_COUNTER) { | if (count < WAIT_COUNTER) { | ||||
| jack_info("CoreAudio driver is running..."); | jack_info("CoreAudio driver is running..."); | ||||
| return 0; | return 0; | ||||
| @@ -1738,17 +1746,17 @@ bool JackCoreAudioDriver::TakeHogAux(AudioDeviceID deviceID, bool isInput) | |||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| bool JackCoreAudioDriver::TakeHog() | bool JackCoreAudioDriver::TakeHog() | ||||
| { | { | ||||
| OSStatus err = noErr; | OSStatus err = noErr; | ||||
| AudioObjectID sub_device[32]; | AudioObjectID sub_device[32]; | ||||
| UInt32 outSize = sizeof(sub_device); | UInt32 outSize = sizeof(sub_device); | ||||
| err = AudioDeviceGetProperty(fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); | err = AudioDeviceGetProperty(fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); | ||||
| if (err != noErr) { | if (err != noErr) { | ||||
| jack_log("Device does not have subdevices"); | jack_log("Device does not have subdevices"); | ||||
| return TakeHogAux(fDeviceID, true); | return TakeHogAux(fDeviceID, true); | ||||
| @@ -1763,12 +1771,12 @@ bool JackCoreAudioDriver::TakeHog() | |||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| bool JackCoreAudioDriver::IsAggregateDevice(AudioDeviceID device) | bool JackCoreAudioDriver::IsAggregateDevice(AudioDeviceID device) | ||||
| { | { | ||||
| UInt32 deviceType, outSize = sizeof(UInt32); | UInt32 deviceType, outSize = sizeof(UInt32); | ||||
| OSStatus err = AudioDeviceGetProperty(device, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyTransportType, &outSize, &deviceType); | OSStatus err = AudioDeviceGetProperty(device, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyTransportType, &outSize, &deviceType); | ||||
| if (err != noErr) { | if (err != noErr) { | ||||
| jack_log("JackCoreAudioDriver::IsAggregateDevice kAudioDevicePropertyTransportType error"); | jack_log("JackCoreAudioDriver::IsAggregateDevice kAudioDevicePropertyTransportType error"); | ||||
| return false; | return false; | ||||
| @@ -1786,7 +1794,7 @@ extern "C" | |||||
| { | { | ||||
| #endif | #endif | ||||
| SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() | |||||
| SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() | |||||
| { | { | ||||
| jack_driver_desc_t *desc; | jack_driver_desc_t *desc; | ||||
| unsigned int i; | unsigned int i; | ||||
| @@ -1794,7 +1802,7 @@ extern "C" | |||||
| strcpy(desc->name, "coreaudio"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 | strcpy(desc->name, "coreaudio"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 | ||||
| strcpy(desc->desc, "Apple CoreAudio API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 | strcpy(desc->desc, "Apple CoreAudio API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 | ||||
| desc->nparams = 17; | desc->nparams = 17; | ||||
| desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); | desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); | ||||
| @@ -1898,7 +1906,7 @@ extern "C" | |||||
| desc->params[i].value.i = FALSE; | desc->params[i].value.i = FALSE; | ||||
| strcpy(desc->params[i].short_desc, "Display available CoreAudio devices"); | strcpy(desc->params[i].short_desc, "Display available CoreAudio devices"); | ||||
| strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | ||||
| i++; | i++; | ||||
| strcpy(desc->params[i].name, "hog"); | strcpy(desc->params[i].name, "hog"); | ||||
| desc->params[i].character = 'H'; | desc->params[i].character = 'H'; | ||||
| @@ -1906,7 +1914,7 @@ extern "C" | |||||
| desc->params[i].value.i = FALSE; | desc->params[i].value.i = FALSE; | ||||
| strcpy(desc->params[i].short_desc, "Take exclusive access of the audio device"); | strcpy(desc->params[i].short_desc, "Take exclusive access of the audio device"); | ||||
| strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | ||||
| i++; | i++; | ||||
| strcpy(desc->params[i].name, "async-latency"); | strcpy(desc->params[i].name, "async-latency"); | ||||
| desc->params[i].character = 'L'; | desc->params[i].character = 'L'; | ||||
| @@ -1914,7 +1922,7 @@ extern "C" | |||||
| desc->params[i].value.i = 100; | desc->params[i].value.i = 100; | ||||
| strcpy(desc->params[i].short_desc, "Extra output latency in asynchronous mode (percent)"); | strcpy(desc->params[i].short_desc, "Extra output latency in asynchronous mode (percent)"); | ||||
| strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | ||||
| i++; | i++; | ||||
| strcpy(desc->params[i].name, "grain"); | strcpy(desc->params[i].name, "grain"); | ||||
| desc->params[i].character = 'G'; | desc->params[i].character = 'G'; | ||||
| @@ -1922,7 +1930,7 @@ extern "C" | |||||
| desc->params[i].value.i = 100; | desc->params[i].value.i = 100; | ||||
| strcpy(desc->params[i].short_desc, "Computation grain in RT thread (percent)"); | strcpy(desc->params[i].short_desc, "Computation grain in RT thread (percent)"); | ||||
| strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | ||||
| i++; | i++; | ||||
| strcpy(desc->params[i].name, "clock-drift"); | strcpy(desc->params[i].name, "clock-drift"); | ||||
| desc->params[i].character = 's'; | desc->params[i].character = 's'; | ||||
| @@ -1934,7 +1942,7 @@ extern "C" | |||||
| return desc; | return desc; | ||||
| } | } | ||||
| SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) | |||||
| SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) | |||||
| { | { | ||||
| jack_nframes_t srate = 44100; | jack_nframes_t srate = 44100; | ||||
| jack_nframes_t frames_per_interrupt = 128; | jack_nframes_t frames_per_interrupt = 128; | ||||
| @@ -1953,10 +1961,10 @@ extern "C" | |||||
| int computation_grain = -1; | int computation_grain = -1; | ||||
| bool hogged = false; | bool hogged = false; | ||||
| bool clock_drift = false; | bool clock_drift = false; | ||||
| for (node = params; node; node = jack_slist_next(node)) { | for (node = params; node; node = jack_slist_next(node)) { | ||||
| param = (const jack_driver_param_t *) node->data; | param = (const jack_driver_param_t *) node->data; | ||||
| switch (param->character) { | switch (param->character) { | ||||
| case 'd': | case 'd': | ||||
| @@ -2018,19 +2026,19 @@ extern "C" | |||||
| case 'l': | case 'l': | ||||
| Jack::DisplayDeviceNames(); | Jack::DisplayDeviceNames(); | ||||
| break; | break; | ||||
| case 'H': | case 'H': | ||||
| hogged = true; | hogged = true; | ||||
| break; | break; | ||||
| case 'L': | case 'L': | ||||
| async_output_latency = param->value.ui; | async_output_latency = param->value.ui; | ||||
| break; | break; | ||||
| case 'G': | case 'G': | ||||
| computation_grain = param->value.ui; | computation_grain = param->value.ui; | ||||
| break; | break; | ||||
| case 's': | case 's': | ||||
| clock_drift = true; | clock_drift = true; | ||||
| break; | break; | ||||
| @@ -2044,7 +2052,7 @@ extern "C" | |||||
| } | } | ||||
| Jack::JackCoreAudioDriver* driver = new Jack::JackCoreAudioDriver("system", "coreaudio", engine, table); | Jack::JackCoreAudioDriver* driver = new Jack::JackCoreAudioDriver("system", "coreaudio", engine, table); | ||||
| if (driver->Open(frames_per_interrupt, srate, capture, playback, chan_in, chan_out, monitor, capture_driver_uid, | |||||
| if (driver->Open(frames_per_interrupt, srate, capture, playback, chan_in, chan_out, monitor, capture_driver_uid, | |||||
| playback_driver_uid, systemic_input_latency, systemic_output_latency, async_output_latency, computation_grain, hogged, clock_drift) == 0) { | playback_driver_uid, systemic_input_latency, systemic_output_latency, async_output_latency, computation_grain, hogged, clock_drift) == 0) { | ||||
| return driver; | return driver; | ||||
| } else { | } else { | ||||
| @@ -33,47 +33,47 @@ namespace Jack | |||||
| \brief Mutex abstraction. | \brief Mutex abstraction. | ||||
| */ | */ | ||||
| class JackBasePosixMutex | class JackBasePosixMutex | ||||
| { | { | ||||
| protected: | protected: | ||||
| pthread_mutex_t fMutex; | pthread_mutex_t fMutex; | ||||
| public: | public: | ||||
| JackBasePosixMutex() | JackBasePosixMutex() | ||||
| { | { | ||||
| pthread_mutex_init(&fMutex, NULL); | |||||
| pthread_mutex_init(&fMutex, NULL); | |||||
| } | } | ||||
| virtual ~JackBasePosixMutex() | virtual ~JackBasePosixMutex() | ||||
| { | { | ||||
| pthread_mutex_destroy(&fMutex); | pthread_mutex_destroy(&fMutex); | ||||
| } | } | ||||
| void Lock() | void Lock() | ||||
| { | { | ||||
| int res = pthread_mutex_lock(&fMutex); | int res = pthread_mutex_lock(&fMutex); | ||||
| if (res != 0) | if (res != 0) | ||||
| jack_error("JackBasePosixMutex::Lock res = %d", res); | |||||
| jack_log("JackBasePosixMutex::Lock res = %d", res); | |||||
| } | } | ||||
| bool Trylock() | bool Trylock() | ||||
| { | { | ||||
| return (pthread_mutex_trylock(&fMutex) == 0); | return (pthread_mutex_trylock(&fMutex) == 0); | ||||
| } | } | ||||
| void Unlock() | void Unlock() | ||||
| { | { | ||||
| int res = pthread_mutex_unlock(&fMutex); | int res = pthread_mutex_unlock(&fMutex); | ||||
| if (res != 0) | if (res != 0) | ||||
| jack_error("JackBasePosixMutex::Unlock res = %d", res); | |||||
| jack_log("JackBasePosixMutex::Unlock res = %d", res); | |||||
| } | } | ||||
| }; | }; | ||||
| class JackPosixMutex | class JackPosixMutex | ||||
| { | { | ||||
| @@ -97,7 +97,7 @@ class JackPosixMutex | |||||
| res = pthread_mutexattr_destroy(&mutex_attr); | res = pthread_mutexattr_destroy(&mutex_attr); | ||||
| assert(res == 0); | assert(res == 0); | ||||
| } | } | ||||
| virtual ~JackPosixMutex() | virtual ~JackPosixMutex() | ||||
| { | { | ||||
| pthread_mutex_destroy(&fMutex); | pthread_mutex_destroy(&fMutex); | ||||
| @@ -107,7 +107,7 @@ class JackPosixMutex | |||||
| { | { | ||||
| int res = pthread_mutex_lock(&fMutex); | int res = pthread_mutex_lock(&fMutex); | ||||
| if (res != 0) | if (res != 0) | ||||
| jack_error("JackPosixMutex::Lock res = %d", res); | |||||
| jack_log("JackPosixMutex::Lock res = %d", res); | |||||
| return (res == 0); | return (res == 0); | ||||
| } | } | ||||
| @@ -120,7 +120,7 @@ class JackPosixMutex | |||||
| { | { | ||||
| int res = pthread_mutex_unlock(&fMutex); | int res = pthread_mutex_unlock(&fMutex); | ||||
| if (res != 0) | if (res != 0) | ||||
| jack_error("JackPosixMutex::Unlock res = %d", res); | |||||
| jack_log("JackPosixMutex::Unlock res = %d", res); | |||||
| return (res == 0); | return (res == 0); | ||||
| } | } | ||||