Browse Source

Remove JackPortIsActive flag.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4120 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/1.9.7
sletz 14 years ago
parent
commit
4f249a336f
12 changed files with 430 additions and 444 deletions
  1. +4
    -0
      ChangeLog
  2. +44
    -44
      common/JackDriver.h
  3. +0
    -10
      common/JackEngine.cpp
  4. +24
    -36
      common/JackGraphManager.cpp
  5. +4
    -6
      common/JackGraphManager.h
  6. +7
    -14
      common/jack/types.h
  7. +6
    -11
      example-clients/lsp.c
  8. +13
    -13
      linux/alsa/alsa_rawmidi.c
  9. +8
    -8
      linux/alsa/alsa_seqmidi.c
  10. +152
    -142
      macosx/coreaudio/JackCoreAudioAdapter.cpp
  11. +151
    -143
      macosx/coreaudio/JackCoreAudioDriver.cpp
  12. +17
    -17
      posix/JackPosixMutex.h

+ 4
- 0
ChangeLog View File

@@ -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.


+ 44
- 44
common/JackDriver.h View File

@@ -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

+ 0
- 10
common/JackEngine.cpp View File

@@ -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


+ 24
- 36
common/JackGraphManager.cpp View File

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


You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


*/ */
@@ -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;


+ 4
- 6
common/JackGraphManager.h View File

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


You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


*/ */
@@ -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);




+ 7
- 14
common/jack/types.h View File

@@ -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


+ 6
- 11
example-clients/lsp.c View File

@@ -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);


+ 13
- 13
linux/alsa/alsa_rawmidi.c View File

@@ -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);




+ 8
- 8
linux/alsa/alsa_seqmidi.c View File

@@ -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)


+ 152
- 142
macosx/coreaudio/JackCoreAudioAdapter.cpp View File

@@ -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;
} }




+ 151
- 143
macosx/coreaudio/JackCoreAudioDriver.cpp View File

@@ -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 {


+ 17
- 17
posix/JackPosixMutex.h View File

@@ -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);
} }




Loading…
Cancel
Save