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

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

* Remove JackPortIsActive flag.

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

* 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) 2004-2008 Grame
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef __JackDriver__
@@ -30,27 +30,27 @@

namespace Jack
{
class JackLockedEngine;
class JackGraphManager;
struct JackEngineControl;
/*!
\brief The base interface for drivers.
*/
class SERVER_EXPORT JackDriverInterface
{

public:
JackDriverInterface()
{}
virtual ~JackDriverInterface()
{}
virtual int Open() = 0;
virtual int Open (bool capturing,
bool playing,
int inchannels,
@@ -60,7 +60,7 @@ class SERVER_EXPORT JackDriverInterface
const char* playback_driver_name,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency) = 0;
virtual int Open(jack_nframes_t buffer_size,
jack_nframes_t samplerate,
bool capturing,
@@ -72,30 +72,30 @@ class SERVER_EXPORT JackDriverInterface
const char* playback_driver_name,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency) = 0;
virtual int Attach() = 0;
virtual int Detach() = 0;
virtual int Read() = 0;
virtual int Write() = 0;
virtual int Start() = 0;
virtual int Stop() = 0;
virtual bool IsFixedBufferSize() = 0;
virtual int SetBufferSize(jack_nframes_t buffer_size) = 0;
virtual int SetSampleRate(jack_nframes_t sample_rate) = 0;
virtual int Process() = 0;
virtual int ProcessNull() = 0;
virtual void SetMaster(bool onoff) = 0;
virtual bool GetMaster() = 0;
virtual void AddSlave(JackDriverInterface* slave) = 0;
virtual void RemoveSlave(JackDriverInterface* slave) = 0;
virtual std::list<JackDriverInterface*> GetSlaves() = 0;
virtual int ProcessSlaves() = 0;
virtual bool IsRealTime() const = 0;
};

@@ -109,16 +109,16 @@ class SERVER_EXPORT JackDriverClientInterface : public JackDriverInterface, publ
/*!
\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
{
protected:
char fCaptureDriverName[JACK_CLIENT_NAME_SIZE + 1];
char fPlaybackDriverName[JACK_CLIENT_NAME_SIZE + 1];
char fAliasName[JACK_CLIENT_NAME_SIZE + 1];
@@ -134,27 +134,27 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface
JackClientControl fClientControl;
std::list<JackDriverInterface*> fSlaveList;
bool fIsMaster;
void CycleIncTime();
void CycleTakeBeginTime();
void CycleTakeEndTime();
void SetupDriverSync(int ref, bool freewheel);
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 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
public:
JackDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table);
JackDriver();
virtual ~JackDriver();
void SetMaster(bool onoff);
bool GetMaster();
void AddSlave(JackDriverInterface* slave);
void RemoveSlave(JackDriverInterface* slave);
std::list<JackDriverInterface*> GetSlaves()
@@ -162,9 +162,9 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface
return fSlaveList;
}
int ProcessSlaves();
virtual int Open();
virtual int Open (bool capturing,
bool playing,
int inchannels,
@@ -174,7 +174,7 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface
const char* playback_driver_name,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency);
virtual int Open(jack_nframes_t buffer_size,
jack_nframes_t samplerate,
bool capturing,
@@ -187,31 +187,31 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface
jack_nframes_t capture_latency,
jack_nframes_t playback_latency);
virtual int Close();
virtual int Process();
virtual int ProcessNull();
virtual int Attach();
virtual int Detach();
virtual int Read();
virtual int Write();
virtual int Start();
virtual int Stop();
virtual bool IsFixedBufferSize();
virtual int SetBufferSize(jack_nframes_t buffer_size);
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 JackClientControl* GetClientControl() 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

#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->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
NotifyActivate(refnum);

@@ -745,11 +737,9 @@ int JackEngine::ClientDeactivate(int refnum)
// First disconnect all ports and remove their JackPortIsActive state
for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) {
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++) {
PortDisconnect(refnum, output_ports[i], ALL_PORTS);
fGraphManager->DeactivatePort(output_ports[i]);
}

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

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.

*/
@@ -37,7 +37,7 @@ static void AssertBufferSize(jack_nframes_t buffer_size)
assert(buffer_size <= BUFFER_SIZE_MAX);
}
}
void JackGraphManager::AssertPort(jack_port_id_t port_index)
{
if (port_index >= fPortMax) {
@@ -45,7 +45,7 @@ void JackGraphManager::AssertPort(jack_port_id_t port_index)
assert(port_index < fPortMax);
}
}
JackGraphManager* JackGraphManager::Allocate(int port_max)
{
// Using "Placement" new
@@ -59,18 +59,18 @@ void JackGraphManager::Destroy(JackGraphManager* manager)
manager->~JackGraphManager();
JackShmMem::operator delete(manager);
}
JackGraphManager::JackGraphManager(int port_max)
JackGraphManager::JackGraphManager(int port_max)
{
assert(port_max <= PORT_NUM_MAX);
for (int i = 0; i < port_max; i++) {
fPortArray[i].Release();
}
fPortMax = port_max;
}
JackPort* JackGraphManager::GetPort(jack_port_id_t 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);

// No connections : return a zero-filled buffer
if (len == 0) {
if (len == 0) {
port->ClearBuffer(buffer_size);
return port->GetBuffer();
// One connection
} else if (len == 1) {
} else if (len == 1) {
jack_port_id_t src_index = manager->GetPort(port_index, 0);
// Ports in same client : copy the buffer
if (GetPort(src_index)->GetRefNum() == port->GetRefNum()) {
void* buffers[1];
@@ -194,10 +194,10 @@ void* JackGraphManager::GetBuffer(jack_port_id_t port_index, jack_nframes_t buff
} else {
return GetBuffer(src_index, buffer_size);
}
// Multiple connections : mix all buffers
} else {
} else {
const jack_int_t* connections = manager->GetConnections(port_index);
void* buffers[CONNECTION_NUM_FOR_PORT];
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);

/**
jackd.h
jackd.h
* If @ref JackPortCanMonitor is set for this @a port, turn input
* monitoring on or off. Otherwise, do nothing.
if (!(fFlags & JackPortCanMonitor))
return -1;
*/
@@ -376,18 +376,6 @@ int JackGraphManager::ReleasePort(int refnum, jack_port_id_t port_index)
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)
{
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);
assert(true);
break;
}
}
}

WriteNextStateStop();
@@ -717,7 +705,7 @@ void JackGraphManager::GetConnectionsAux(JackConnectionManager* manager, const c
const jack_int_t* connections = manager->GetConnections(port_index);
jack_int_t index;
int i;
// Cleanup connection array
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);
UInt16 cur_index, next_index;
if (!res)
return NULL;

@@ -763,7 +751,7 @@ void JackGraphManager::GetPortsAux(const char** matching_ports, const char* port
{
int match_cnt = 0;
regex_t port_regex, type_regex;
if (port_name_pattern && port_name_pattern[0]) {
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);
UInt16 cur_index, next_index;
if (!res)
return NULL;
do {
cur_index = GetCurrentIndex();
GetPortsAux(res, port_name_pattern, type_name_pattern, flags);
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
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.

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.

*/
@@ -36,7 +36,7 @@ namespace Jack
/*!
\brief Graph manager: contains the connection manager and the port array.
*/
class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState<JackConnectionManager>
{

@@ -65,8 +65,6 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState
// Ports management
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);
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 GetOutputPorts(int refnum, jack_int_t* res);
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 ComputeTotalLatencies();
int RequestMonitor(jack_port_id_t port_index, bool onoff);
// Connections management
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);
@@ -130,7 +128,7 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState

void Save(JackConnectionManager* dst);
void Restore(JackConnectionManager* src);
static JackGraphManager* Allocate(int port_max);
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
* 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 application is responsible to properly use jack_client_close()
* to release client ressources. Warning: jack_client_close() cannot be
@@ -295,14 +295,7 @@ enum JackPortFlags {
* their ports.
*/
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
*/
JackVersionError = 0x400,
/**
* Backend error
*/
JackBackendError = 0x800,
/**
* Client zombified failure
*/
@@ -476,7 +469,7 @@ typedef enum {
JackBBTFrameOffset = 0x40, /**< Frame offset of BBT information */
JackAudioVideoRatio = 0x80, /**< audio frames per video frame */
JackVideoFrameOffset = 0x100 /**< frame offset of first video frame */
} jack_position_bits_t;

/** all valid position bits */
@@ -668,13 +661,13 @@ typedef struct {

/**
* 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 application is responsible to properly use jack_client_close()
* to release client ressources. Warning: jack_client_close() cannot be
* safely used inside the shutdown callback and has to be called outside of
* the callback context.
* @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 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 *server_name = NULL;
jack_port_t *port;
struct option long_options[] = {
{ "server", 1, 0, 's' },
{ "aliases", 0, 0, 'A' },
@@ -152,7 +152,7 @@ main (int argc, char *argv[])
}

ports = jack_get_ports (client, NULL, NULL, 0);
if (!ports)
if (!ports)
goto error;

for (i = 0; ports && ports[i]; ++i) {
@@ -177,14 +177,14 @@ main (int argc, char *argv[])
printf (" %s\n", aliases[i]);
}
}
if (show_con) {
if ((connections = jack_port_get_all_connections (client, jack_port_by_name(client, ports[i]))) != 0) {
for (j = 0; connections[j]; j++) {
printf (" %s\n", connections[j]);
}
free (connections);
}
}
}
if (show_port_latency) {
if (port) {
@@ -217,12 +217,7 @@ main (int argc, char *argv[])
if (flags & JackPortIsTerminal) {
fputs ("terminal,", stdout);
}
if (flags & JackPortIsActive) {
fputs ("active,", stdout);
} else {
fputs ("non-active,", stdout);
}

putc ('\n', stdout);
}
}
@@ -234,7 +229,7 @@ main (int argc, char *argv[])
}
}
}
error:
if (ports)
jack_free (ports);


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

@@ -104,7 +104,7 @@ typedef struct input_port_t {

// jack
midi_unpack_t unpack;
// midi
int overruns;
} input_port_t;
@@ -114,7 +114,7 @@ typedef struct output_port_t {

// jack
midi_pack_t packer;
// midi
event_head_t next_event;
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)
{
char name[128];
if (type & JackPortIsOutput)
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);

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);
return port->jack == NULL;
}
@@ -455,7 +455,7 @@ int midi_port_open(alsa_rawmidi_t *midi, midi_port_t *port)
out = &port->rawmidi;
type = JackPortIsInput;
}
if ((err = snd_rawmidi_open(in, out, port->dev, SND_RAWMIDI_NONBLOCK))<0)
return err;

@@ -749,7 +749,7 @@ void* scan_thread(void *arg)
return NULL;
}

/*
/*
* ------------------------------- Input/Output ------------------------------
*/

@@ -836,7 +836,7 @@ void *midi_thread(void *arg)
npfds = 1;

if (jack_is_realtime(midi->client))
set_threaded_log_function();
set_threaded_log_function();

//debug_log("midi_thread(%s): enter", str->name);

@@ -978,7 +978,7 @@ int midi_update_pfds(process_midi_t *proc)
return 1;
}

/*
/*
* ------------------------------------ Input ------------------------------
*/

@@ -1083,7 +1083,7 @@ int do_midi_input(process_midi_t *proc)
return 1;
}

/*
/*
* ------------------------------------ Output ------------------------------
*/

@@ -1149,7 +1149,7 @@ int do_midi_output(process_midi_t *proc)
} 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);
}
if (port->todo)
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->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_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 */

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)
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);
port->jack_port = jack_port_register(self->jack,
name, JACK_DEFAULT_MIDI_TYPE, jack_caps, 0);
if (!port->jack_port)
@@ -588,7 +588,7 @@ void update_ports(alsa_seqmidi_t *self)
snd_seq_port_info_alloca(&info);

while ((size = jack_ringbuffer_read(self->port_add, (char*)&addr, sizeof(addr)))) {
int err;

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;

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;
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;
jack_ringbuffer_write(port->early_events, (char*)&ev, sizeof(ev));
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;
}

@@ -829,7 +829,7 @@ void alsa_seqmidi_read(alsa_midi_t *m, jack_nframes_t nframes)
return;

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) {
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,
void* inClientData)
{
switch (inPropertyID) {
case kAudioDeviceProcessorOverload: {
jack_error("JackCoreAudioAdapter::DeviceNotificationCallback kAudioDeviceProcessorOverload");
break;
@@ -196,12 +196,12 @@ OSStatus JackCoreAudioAdapter::DeviceNotificationCallback(AudioDeviceID inDevice
jack_error("Cannot handle kAudioDevicePropertyStreamConfiguration");
return kAudioHardwareUnsupportedOperationError;
}
case kAudioDevicePropertyNominalSampleRate: {
jack_error("Cannot handle kAudioDevicePropertyNominalSampleRate");
return kAudioHardwareUnsupportedOperationError;
}
}
return noErr;
}
@@ -217,7 +217,7 @@ int JackCoreAudioAdapter::AddListeners()
printError(err);
return -1;
}
err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioHardwarePropertyDevices, DeviceNotificationCallback, this);
if (err != noErr) {
jack_error("Error calling AudioDeviceAddPropertyListener with kAudioHardwarePropertyDevices");
@@ -275,17 +275,17 @@ OSStatus JackCoreAudioAdapter::Render(void *inRefCon,
{
JackCoreAudioAdapter* adapter = static_cast<JackCoreAudioAdapter*>(inRefCon);
AudioUnitRender(adapter->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, adapter->fInputData);
float* inputBuffer[adapter->fCaptureChannels];
float* outputBuffer[adapter->fPlaybackChannels];
for (int i = 0; i < adapter->fCaptureChannels; i++) {
inputBuffer[i] = (float*)adapter->fInputData->mBuffers[i].mData;
}
for (int i = 0; i < adapter->fPlaybackChannels; i++) {
outputBuffer[i] = (float*)ioData->mBuffers[i].mData;
}
adapter->PushAndPull((float**)inputBuffer, (float**)outputBuffer, inNumberFrames);
return noErr;
}
@@ -302,16 +302,16 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra
fCaptureUID[0] = 0;
fPlaybackUID[0] = 0;
fClockDriftCompensate = false;
// Default values
fCaptureChannels = -1;
fPlaybackChannels = -1;
SInt32 major;
SInt32 minor;
Gestalt(gestaltSystemVersionMajor, &major);
Gestalt(gestaltSystemVersionMinor, &minor);
// Starting with 10.6 systems, the HAL notification thread is created internally
if (major == 10 && minor >= 6) {
CFRunLoopRef theRunLoop = NULL;
@@ -321,7 +321,7 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra
jack_error("JackCoreAudioAdapter::Open kAudioHardwarePropertyRunLoop error");
}
}
for (node = params; node; node = jack_slist_next(node)) {
param = (const jack_driver_param_t*) node->data;

@@ -348,7 +348,7 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra
fPlaying = true;
strncpy(fPlaybackUID, param->value.str, 256);
break;
case 'd':
strncpy(fCaptureUID, 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':
SetAdaptedBufferSize(param->value.ui);
break;
case 'l':
DisplayDeviceNames();
break;
case 'q':
fQuality = param->value.ui;
break;
case 'g':
fRingbufferCurSize = param->value.ui;
fAdaptative = false;
break;
case 's':
fClockDriftCompensate = true;
break;
}
}
/* duplex is the default */
if (!fCapturing && !fPlaying) {
fCapturing = true;
fPlaying = true;
}
if (SetupDevices(fCaptureUID, fPlaybackUID, captureName, playbackName, fAdaptedSampleRate) < 0)
throw -1;
if (SetupChannels(fCapturing, fPlaying, fCaptureChannels, fPlaybackChannels, in_nChannels, out_nChannels, true) < 0)
throw -1;
if (SetupBufferSize(fAdaptedBufferSize) < 0)
throw -1;
if (SetupSampleRate(fAdaptedSampleRate) < 0)
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;
if (fCapturing && fCaptureChannels > 0)
if (SetupBuffers(fCaptureChannels) < 0)
throw -1;
if (AddListeners() < 0)
throw -1;
}
@@ -488,6 +488,10 @@ OSStatus JackCoreAudioAdapter::GetDefaultInputDevice(AudioDeviceID* id)
if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr)
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);
*id = inDefault;
return noErr;
@@ -502,6 +506,10 @@ OSStatus JackCoreAudioAdapter::GetDefaultOutputDevice(AudioDeviceID* id)
if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr)
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);
*id = outDefault;
return noErr;
@@ -525,10 +533,10 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid,

// Duplex
if (strcmp(capture_driver_uid, "") != 0 && strcmp(playback_driver_uid, "") != 0) {
// Same device for capture and playback...
if (strcmp(capture_driver_uid, playback_driver_uid) == 0) {
if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) {
jack_log("Will take default in/out");
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");
return -1;
}
} else {
// Creates aggregate device
AudioDeviceID captureID, playbackID;
if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) {
jack_log("Will take default input");
if (GetDefaultInputDevice(&captureID) != noErr) {
@@ -553,7 +561,7 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid,
return -1;
}
}
if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) {
jack_log("Will take default output");
if (GetDefaultOutputDevice(&playbackID) != noErr) {
@@ -561,7 +569,7 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid,
return -1;
}
}
if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr)
return -1;
}
@@ -599,10 +607,10 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid,
jack_log("JackCoreAudioDriver::Open default driver");
if (GetDefaultDevice(&fDeviceID) != noErr) {
jack_error("Cannot open default device in duplex mode, so aggregate default input and default output");
// Creates aggregate device
AudioDeviceID captureID, playbackID;
if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) {
jack_log("Will take default input");
if (GetDefaultInputDevice(&captureID) != noErr) {
@@ -610,7 +618,7 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid,
return -1;
}
}
if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) {
jack_log("Will take default output");
if (GetDefaultOutputDevice(&playbackID) != noErr) {
@@ -618,7 +626,7 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid,
return -1;
}
}
if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr)
return -1;
}
@@ -680,7 +688,7 @@ int JackCoreAudioAdapter::SetupChannels(bool capturing,
jack_log("Setup max out channels = %ld", out_nChannels);
outchannels = out_nChannels;
}
return 0;
}

@@ -694,7 +702,7 @@ int JackCoreAudioAdapter::SetupBufferSize(jack_nframes_t buffer_size)
printError(err);
return -1;
}
return 0;
}

@@ -708,7 +716,7 @@ int JackCoreAudioAdapter::SetupSampleRateAux(AudioDeviceID inDevice, jack_nframe
OSStatus err = noErr;
UInt32 outSize;
Float64 sampleRate;
// Get sample rate
outSize = sizeof(Float64);
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");
printError(err);
return -1;
} else {
jack_log("Current sample rate = %f", sampleRate);
}
// If needed, set new sample rate
if (samplerate != (jack_nframes_t)sampleRate) {
sampleRate = (Float64)samplerate;
// To get SR change notification
err = AudioDeviceAddPropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback, this);
if (err != noErr) {
@@ -735,18 +745,18 @@ int JackCoreAudioAdapter::SetupSampleRateAux(AudioDeviceID inDevice, jack_nframe
printError(err);
return -1;
}
// Waiting for SR change notification
int count = 0;
while (!fState && count++ < WAIT_COUNTER) {
usleep(100000);
jack_log("Wait count = %d", count);
}
// Remove SR change notification
AudioDeviceRemovePropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback);
}
return 0;
}

@@ -796,7 +806,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing,
jack_error("No input and output channels...");
return -1;
}
// AUHAL
ComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0};
Component HALOutput = FindNextComponent(NULL, &cd);
@@ -823,7 +833,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing,
enableIO = 0;
jack_log("Setup AUHAL input off");
}
err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO));
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input");
@@ -838,14 +848,14 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing,
enableIO = 0;
jack_log("Setup AUHAL output off");
}
err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO));
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO,kAudioUnitScope_Output");
printError(err1);
goto error;
}
size = sizeof(AudioDeviceID);
err1 = AudioUnitGetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &currAudioDeviceID, &size);
if (err1 != noErr) {
@@ -863,7 +873,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing,
printError(err1);
goto error;
}
// Set buffer size
if (capturing && inchannels > 0) {
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
if (capturing && inchannels > 0) {
size = sizeof(AudioStreamBasicDescription);
err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &srcFormat, &size);
if (err1 != noErr) {
@@ -927,7 +937,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing,
goto error;
}
PrintStreamDesc(&srcFormat);
jack_log("Setup AUHAL input stream converter SR = %ld", samplerate);
srcFormat.mSampleRate = samplerate;
srcFormat.mFormatID = kAudioFormatLinearPCM;
@@ -938,9 +948,9 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing,
srcFormat.mChannelsPerFrame = inchannels;
srcFormat.mBitsPerChannel = 32;
PrintStreamDesc(&srcFormat);
err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription));
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input");
printError(err1);
@@ -949,7 +959,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing,
}

if (playing && outchannels > 0) {
size = sizeof(AudioStreamBasicDescription);
err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 1, &dstFormat, &size);
if (err1 != noErr) {
@@ -958,7 +968,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing,
goto error;
}
PrintStreamDesc(&dstFormat);
jack_log("Setup AUHAL output stream converter SR = %ld", samplerate);
dstFormat.mSampleRate = samplerate;
dstFormat.mFormatID = kAudioFormatLinearPCM;
@@ -969,9 +979,9 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing,
dstFormat.mChannelsPerFrame = outchannels;
dstFormat.mBitsPerChannel = 32;
PrintStreamDesc(&dstFormat);
err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription));
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output");
printError(err1);
@@ -1003,13 +1013,13 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing,
}

return 0;
error:
CloseAUHAL();
return -1;
}

OSStatus JackCoreAudioAdapter::DestroyAggregateDevice()
OSStatus JackCoreAudioAdapter::DestroyAggregateDevice()
{
OSStatus osErr = noErr;
AudioObjectPropertyAddress pluginAOPA;
@@ -1017,21 +1027,21 @@ OSStatus JackCoreAudioAdapter::DestroyAggregateDevice()
pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal;
pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
UInt32 outDataSize;
osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize);
if (osErr != noErr) {
jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyDataSize error");
printError(osErr);
return osErr;
}
osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, 0, NULL, &outDataSize, &fDeviceID);
if (osErr != noErr) {
jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyData error");
printError(osErr);
return osErr;
}
return noErr;
}

@@ -1043,15 +1053,15 @@ static CFStringRef GetDeviceName(AudioDeviceID id)
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;
AudioObjectID sub_device[32];
UInt32 outSize = sizeof(sub_device);
err = AudioDeviceGetProperty(captureDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device);
vector<AudioDeviceID> captureDeviceIDArray;
if (err != noErr) {
jack_log("Input device does not have subdevices");
captureDeviceIDArray.push_back(captureDeviceID);
@@ -1062,10 +1072,10 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDevice(AudioDeviceID captureDevice
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;
if (err != noErr) {
jack_log("Output device does not have subdevices");
playbackDeviceIDArray.push_back(playbackDeviceID);
@@ -1076,16 +1086,16 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDevice(AudioDeviceID captureDevice
playbackDeviceIDArray.push_back(sub_device[i]);
}
}
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;
UInt32 outSize;
Boolean outWritable;
// Prepare sub-devices for clock drift compensation
// Workaround for bug in the HAL : until 10.6.2
AudioObjectPropertyAddress theAddressOwned = { kAudioObjectPropertyOwnedObjects, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
@@ -1094,7 +1104,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca
AudioClassID inClass = kAudioSubDeviceClassID;
void* theQualifierData = &inClass;
UInt32 subDevicesNum = 0;
//---------------------------------------------------------------------------
// Setup SR of both devices otherwise creating AD may fail...
//---------------------------------------------------------------------------
@@ -1102,18 +1112,18 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca
UInt32 clockdomain = 0;
outSize = sizeof(UInt32);
bool need_clock_drift_compensation = false;
for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
if (SetupSampleRateAux(captureDeviceID[i], samplerate) < 0) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of input device");
} else {
// Check clock domain
osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain);
osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain);
if (osErr != 0) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error");
printError(osErr);
} else {
keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain;
keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain;
jack_log("JackCoreAudioDriver::CreateAggregateDevice : input clockdomain = %d", clockdomain);
if (clockdomain != 0 && clockdomain != keptclockdomain) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed...");
@@ -1122,18 +1132,18 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca
}
}
}
for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
if (SetupSampleRateAux(playbackDeviceID[i], samplerate) < 0) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of output device");
} else {
// Check clock domain
osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain);
osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain);
if (osErr != 0) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error");
printError(osErr);
} else {
keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain;
keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain;
jack_log("JackCoreAudioDriver::CreateAggregateDevice : output clockdomain = %d", clockdomain);
if (clockdomain != 0 && clockdomain != keptclockdomain) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed...");
@@ -1142,74 +1152,74 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca
}
}
}
// If no valid clock domain was found, then assume we have to compensate...
if (keptclockdomain == 0) {
need_clock_drift_compensation = true;
}
//---------------------------------------------------------------------------
// Start to create a new aggregate by getting the base audio hardware plugin
//---------------------------------------------------------------------------
char device_name[256];
for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
GetDeviceNameFromID(captureDeviceID[i], device_name);
jack_info("Separated input = '%s' ", device_name);
}
for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
GetDeviceNameFromID(playbackDeviceID[i], device_name);
jack_info("Separated output = '%s' ", device_name);
}
osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable);
if (osErr != noErr) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error");
printError(osErr);
return osErr;
}
AudioValueTranslation pluginAVT;
CFStringRef inBundleRef = CFSTR("com.apple.audio.CoreAudio");
pluginAVT.mInputData = &inBundleRef;
pluginAVT.mInputDataSize = sizeof(inBundleRef);
pluginAVT.mOutputData = &fPluginID;
pluginAVT.mOutputDataSize = sizeof(fPluginID);
osErr = AudioHardwareGetProperty(kAudioHardwarePropertyPlugInForBundleID, &outSize, &pluginAVT);
if (osErr != noErr) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioHardwareGetProperty kAudioHardwarePropertyPlugInForBundleID error");
printError(osErr);
return osErr;
}
//-------------------------------------------------
// Create a CFDictionary for our aggregate device
//-------------------------------------------------
CFMutableDictionaryRef aggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFStringRef AggregateDeviceNameRef = CFSTR("JackDuplex");
CFStringRef AggregateDeviceUIDRef = CFSTR("com.grame.JackDuplex");
// add the name of the device to the dictionary
CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceNameKey), AggregateDeviceNameRef);
// add our choice of UID for the aggregate device to the dictionary
CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceUIDKey), AggregateDeviceUIDRef);
// add a "private aggregate key" to the dictionary
int value = 1;
CFNumberRef AggregateDeviceNumberRef = CFNumberCreate(NULL, kCFNumberIntType, &value);
SInt32 system;
Gestalt(gestaltSystemVersion, &system);
jack_log("JackCoreAudioDriver::CreateAggregateDevice : system version = %x limit = %x", system, 0x00001054);
// Starting with 10.5.4 systems, the AD can be internal... (better)
if (system < 0x00001054) {
jack_log("JackCoreAudioDriver::CreateAggregateDevice : public aggregate device....");
@@ -1217,16 +1227,16 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca
jack_log("JackCoreAudioDriver::CreateAggregateDevice : private aggregate device....");
CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef);
}
// Prepare sub-devices for clock drift compensation
CFMutableArrayRef subDevicesArrayClock = NULL;
/*
if (fClockDriftCompensate) {
if (need_clock_drift_compensation) {
jack_info("Clock drift compensation activated...");
subDevicesArrayClock = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
CFStringRef UID = GetDeviceName(captureDeviceID[i]);
if (UID) {
@@ -1237,7 +1247,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca
CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict);
}
}
for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
CFStringRef UID = GetDeviceName(playbackDeviceID[i]);
if (UID) {
@@ -1248,7 +1258,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca
CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict);
}
}
// add sub-device clock array for the aggregate device to the dictionary
CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceSubDeviceListKey), subDevicesArrayClock);
} else {
@@ -1256,14 +1266,14 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca
}
}
*/
//-------------------------------------------------
// Create a CFMutableArray for our sub-device list
//-------------------------------------------------
// we need to append the UID for each device to a CFMutableArray, so create one here
CFMutableArrayRef subDevicesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
vector<CFStringRef> captureDeviceUID;
for (UInt32 i = 0; i < captureDeviceID.size(); 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
CFArrayAppendValue(subDevicesArray, ref);
}
vector<CFStringRef> playbackDeviceUID;
for (UInt32 i = 0; i < playbackDeviceID.size(); 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
CFArrayAppendValue(subDevicesArray, ref);
}
//-----------------------------------------------------------------------
// Feed the dictionary to the plugin, to create a blank aggregate device
//-----------------------------------------------------------------------
AudioObjectPropertyAddress pluginAOPA;
pluginAOPA.mSelector = kAudioPlugInCreateAggregateDevice;
pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal;
pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
UInt32 outDataSize;
osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize);
if (osErr != noErr) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectGetPropertyDataSize error");
printError(osErr);
goto error;
}
osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice);
if (osErr != noErr) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectGetPropertyData error");
printError(osErr);
goto error;
}
// 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
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false);
//-------------------------
// Set the sub-device list
//-------------------------
pluginAOPA.mSelector = kAudioAggregateDevicePropertyFullSubDeviceList;
pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal;
pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
@@ -1326,14 +1336,14 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca
printError(osErr);
goto error;
}
// pause again to give the changes time to take effect
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false);
//-----------------------
// Set the master 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
pluginAOPA.mSelector = kAudioAggregateDevicePropertyMasterSubDevice;
@@ -1346,36 +1356,36 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca
printError(osErr);
goto error;
}
// pause again to give the changes time to take effect
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false);
// Prepare sub-devices for clock drift compensation
// Workaround for bug in the HAL : until 10.6.2
if (fClockDriftCompensate) {
if (need_clock_drift_compensation) {
jack_info("Clock drift compensation activated...");
// Get the property data size
osErr = AudioObjectGetPropertyDataSize(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize);
if (osErr != noErr) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error");
printError(osErr);
}
// Calculate the number of object IDs
subDevicesNum = outSize / sizeof(AudioObjectID);
jack_info("JackCoreAudioDriver::CreateAggregateDevice clock drift compensation, number of sub-devices = %d", subDevicesNum);
AudioObjectID subDevices[subDevicesNum];
outSize = sizeof(subDevices);
osErr = AudioObjectGetPropertyData(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize, subDevices);
if (osErr != noErr) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error");
printError(osErr);
}
// Set kAudioSubDevicePropertyDriftCompensation property...
for (UInt32 index = 0; index < subDevicesNum; ++index) {
UInt32 theDriftCompensationValue = 1;
@@ -1388,50 +1398,50 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca
} else {
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
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false);
//----------
// Clean up
//----------
// release the private AD key
CFRelease(AggregateDeviceNumberRef);
// release the CF objects we have created - we don't need them any more
CFRelease(aggDeviceDict);
CFRelease(subDevicesArray);
if (subDevicesArrayClock)
CFRelease(subDevicesArrayClock);
// release the device UID
for (UInt32 i = 0; i < captureDeviceUID.size(); i++) {
CFRelease(captureDeviceUID[i]);
}
for (UInt32 i = 0; i < playbackDeviceUID.size(); i++) {
CFRelease(playbackDeviceUID[i]);
}
jack_log("New aggregate device %ld", *outAggregateDevice);
return noErr;
error:
DestroyAggregateDevice();
return -1;
}
bool JackCoreAudioAdapter::IsAggregateDevice(AudioDeviceID device)
{
OSStatus err = noErr;
AudioObjectID sub_device[32];
UInt32 outSize = sizeof(sub_device);
err = AudioDeviceGetProperty(device, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device);
if (err != noErr) {
jack_log("Device does not have subdevices");
return false;
@@ -1494,7 +1504,7 @@ extern "C"

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
desc->nparams = 13;
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;
strcpy(desc->params[i].short_desc, "Display available CoreAudio devices");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
i++;
strcpy(desc->params[i].name, "quality");
desc->params[i].character = 'q';
@@ -1582,7 +1592,7 @@ extern "C"
desc->params[i].value.ui = 0;
strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
i++;
strcpy(desc->params[i].name, "ring-buffer");
desc->params[i].character = 'g';
@@ -1590,7 +1600,7 @@ extern "C"
desc->params[i].value.ui = 32768;
strcpy(desc->params[i].short_desc, "Fixed ringbuffer size");
strcpy(desc->params[i].long_desc, "Fixed ringbuffer size (if not set => automatic adaptative)");
i++;
strcpy(desc->params[i].name, "clock-drift");
desc->params[i].character = 's';
@@ -1598,7 +1608,7 @@ extern "C"
desc->params[i].value.i = FALSE;
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");
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);
char __4CC_string[5];
*((SInt32*)__4CC_string) = EndianU32_NtoB(__4CC_number);
*((SInt32*)__4CC_string) = EndianU32_NtoB(__4CC_number);
__4CC_string[4] = 0;
jack_log("%s'%s'", (msg), __4CC_string);
}
@@ -194,22 +194,22 @@ OSStatus JackCoreAudioDriver::Render(void *inRefCon,
driver->fActionFags = ioActionFlags;
driver->fCurrentTime = (AudioTimeStamp *)inTimeStamp;
driver->fDriverOutputData = ioData;
// Setup threadded based log function once...
if (set_threaded_log_function()) {
jack_log("set_threaded_log_function");
JackMachThread::GetParams(pthread_self(), &driver->fEngineControl->fPeriod, &driver->fEngineControl->fComputation, &driver->fEngineControl->fConstraint);
if (driver->fComputationGrain > 0) {
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;
}
// Signal waiting start function...
driver->fState = true;
}
driver->CycleTakeBeginTime();
return driver->Process();
}
@@ -276,9 +276,9 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice,
void* inClientData)
{
JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData;
switch (inPropertyID) {
case kAudioDevicePropertyDeviceIsRunning: {
UInt32 isrunning = 0;
UInt32 outsize = sizeof(UInt32);
@@ -287,14 +287,14 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice,
}
break;
}
case kAudioDeviceProcessorOverload: {
jack_error("JackCoreAudioDriver::DeviceNotificationCallback kAudioDeviceProcessorOverload");
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;
}
case kAudioDevicePropertyStreamConfiguration: {
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
@@ -302,25 +302,25 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice,
kill(JackTools::GetPID(), SIGINT);
return kAudioHardwareUnsupportedOperationError;
}
case kAudioDevicePropertyNominalSampleRate: {
Float64 sampleRate = 0;
UInt32 outsize = sizeof(Float64);
OSStatus err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sampleRate);
if (err != noErr)
return kAudioHardwareUnsupportedOperationError;
char device_name[256];
const char* digidesign_name = "Digidesign";
driver->GetDeviceNameFromID(driver->fDeviceID, device_name);
if (sampleRate != driver->fEngineControl->fSampleRate) {
// Digidesign hardware, so "special" code : change the SR again here
if (strncmp(device_name, digidesign_name, sizeof(digidesign_name)) == 0) {
jack_log("Digidesign HW = %s", device_name);
// Set sample rate again...
sampleRate = driver->fEngineControl->fSampleRate;
err = AudioDeviceSetProperty(driver->fDeviceID, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outsize, &sampleRate);
@@ -330,7 +330,7 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice,
} else {
jack_log("Set sample rate = %f", sampleRate);
}
// Check new sample rate again...
outsize = sizeof(Float64);
err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sampleRate);
@@ -341,7 +341,7 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice,
jack_log("Checked sample rate = %f", sampleRate);
}
return noErr;
} else {
driver->NotifyFailure(JackBackendError, "Another application has changed the sample rate."); // Message length limited to JACK_MESSAGE_SIZE
driver->CloseAUHAL();
@@ -350,7 +350,7 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice,
}
}
}
}
return noErr;
}
@@ -405,6 +405,10 @@ OSStatus JackCoreAudioDriver::GetDefaultInputDevice(AudioDeviceID* id)
if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr)
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);
*id = inDefault;
return noErr;
@@ -419,6 +423,10 @@ OSStatus JackCoreAudioDriver::GetDefaultOutputDevice(AudioDeviceID* id)
if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr)
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);
*id = outDefault;
return noErr;
@@ -435,7 +443,7 @@ OSStatus JackCoreAudioDriver::GetTotalChannels(AudioDeviceID device, int& channe
OSStatus err = noErr;
UInt32 outSize;
Boolean outWritable;
channelCount = 0;
err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, &outWritable);
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)
: 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),
fIOUsage(1.f),
fComputationGrain(-1.f),
@@ -464,7 +472,7 @@ JackCoreAudioDriver::JackCoreAudioDriver(const char* name, const char* alias, Ja
JackCoreAudioDriver::~JackCoreAudioDriver()
{}

OSStatus JackCoreAudioDriver::DestroyAggregateDevice()
OSStatus JackCoreAudioDriver::DestroyAggregateDevice()
{
OSStatus osErr = noErr;
AudioObjectPropertyAddress pluginAOPA;
@@ -472,37 +480,37 @@ OSStatus JackCoreAudioDriver::DestroyAggregateDevice()
pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal;
pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
UInt32 outDataSize;
if (fPluginID > 0) {
osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize);
if (osErr != noErr) {
jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyDataSize error");
printError(osErr);
return osErr;
}
osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, 0, NULL, &outDataSize, &fDeviceID);
if (osErr != noErr) {
jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyData error");
printError(osErr);
return osErr;
}
}
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;
AudioObjectID sub_device[32];
UInt32 outSize = sizeof(sub_device);
err = AudioDeviceGetProperty(captureDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device);
vector<AudioDeviceID> captureDeviceIDArray;
if (err != noErr) {
jack_log("Input device does not have subdevices");
captureDeviceIDArray.push_back(captureDeviceID);
@@ -513,10 +521,10 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI
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;
if (err != noErr) {
jack_log("Output device does not have subdevices");
playbackDeviceIDArray.push_back(playbackDeviceID);
@@ -527,16 +535,16 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI
playbackDeviceIDArray.push_back(sub_device[i]);
}
}
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;
UInt32 outSize;
Boolean outWritable;
// Prepare sub-devices for clock drift compensation
// Workaround for bug in the HAL : until 10.6.2
AudioObjectPropertyAddress theAddressOwned = { kAudioObjectPropertyOwnedObjects, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
@@ -545,7 +553,7 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
AudioClassID inClass = kAudioSubDeviceClassID;
void* theQualifierData = &inClass;
UInt32 subDevicesNum = 0;
//---------------------------------------------------------------------------
// Setup SR of both devices otherwise creating AD may fail...
//---------------------------------------------------------------------------
@@ -553,18 +561,18 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
UInt32 clockdomain = 0;
outSize = sizeof(UInt32);
bool need_clock_drift_compensation = false;
for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
if (SetupSampleRateAux(captureDeviceID[i], samplerate) < 0) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of input device");
} else {
// Check clock domain
osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain);
osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain);
if (osErr != 0) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error");
printError(osErr);
} else {
keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain;
keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain;
jack_log("JackCoreAudioDriver::CreateAggregateDevice : input clockdomain = %d", clockdomain);
if (clockdomain != 0 && clockdomain != keptclockdomain) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed...");
@@ -573,18 +581,18 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
}
}
}
for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
if (SetupSampleRateAux(playbackDeviceID[i], samplerate) < 0) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of output device");
} else {
// Check clock domain
osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain);
osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain);
if (osErr != 0) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error");
printError(osErr);
} else {
keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain;
keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain;
jack_log("JackCoreAudioDriver::CreateAggregateDevice : output clockdomain = %d", clockdomain);
if (clockdomain != 0 && clockdomain != keptclockdomain) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed...");
@@ -593,7 +601,7 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
}
}
}
// If no valid clock domain was found, then assume we have to compensate...
if (keptclockdomain == 0) {
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
//---------------------------------------------------------------------------
char device_name[256];
for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
GetDeviceNameFromID(captureDeviceID[i], device_name);
jack_info("Separated input = '%s' ", device_name);
}
for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
GetDeviceNameFromID(playbackDeviceID[i], device_name);
jack_info("Separated output = '%s' ", device_name);
}
osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable);
if (osErr != noErr) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error");
@@ -624,7 +632,7 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
AudioValueTranslation pluginAVT;

CFStringRef inBundleRef = CFSTR("com.apple.audio.CoreAudio");
pluginAVT.mInputData = &inBundleRef;
pluginAVT.mInputDataSize = sizeof(inBundleRef);
pluginAVT.mOutputData = &fPluginID;
@@ -645,22 +653,22 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap

CFStringRef AggregateDeviceNameRef = CFSTR("JackDuplex");
CFStringRef AggregateDeviceUIDRef = CFSTR("com.grame.JackDuplex");
// add the name of the device to the dictionary
CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceNameKey), AggregateDeviceNameRef);

// add our choice of UID for the aggregate device to the dictionary
CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceUIDKey), AggregateDeviceUIDRef);
// add a "private aggregate key" to the dictionary
int value = 1;
CFNumberRef AggregateDeviceNumberRef = CFNumberCreate(NULL, kCFNumberIntType, &value);
SInt32 system;
Gestalt(gestaltSystemVersion, &system);
jack_log("JackCoreAudioDriver::CreateAggregateDevice : system version = %x limit = %x", system, 0x00001054);
// Starting with 10.5.4 systems, the AD can be internal... (better)
if (system < 0x00001054) {
jack_log("JackCoreAudioDriver::CreateAggregateDevice : public aggregate device....");
@@ -668,16 +676,16 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
jack_log("JackCoreAudioDriver::CreateAggregateDevice : private aggregate device....");
CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef);
}
// Prepare sub-devices for clock drift compensation
CFMutableArrayRef subDevicesArrayClock = NULL;
/*
if (fClockDriftCompensate) {
if (need_clock_drift_compensation) {
jack_info("Clock drift compensation activated...");
subDevicesArrayClock = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
CFStringRef UID = GetDeviceName(captureDeviceID[i]);
if (UID) {
@@ -688,7 +696,7 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict);
}
}
for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
CFStringRef UID = GetDeviceName(playbackDeviceID[i]);
if (UID) {
@@ -699,7 +707,7 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict);
}
}
// add sub-device clock array for the aggregate device to the dictionary
CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceSubDeviceListKey), subDevicesArrayClock);
} else {
@@ -707,14 +715,14 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
}
}
*/
//-------------------------------------------------
// Create a CFMutableArray for our sub-device list
//-------------------------------------------------
// we need to append the UID for each device to a CFMutableArray, so create one here
CFMutableArrayRef subDevicesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
vector<CFStringRef> captureDeviceUID;
for (UInt32 i = 0; i < captureDeviceID.size(); 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
CFArrayAppendValue(subDevicesArray, ref);
}
vector<CFStringRef> playbackDeviceUID;
for (UInt32 i = 0; i < playbackDeviceID.size(); 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
CFArrayAppendValue(subDevicesArray, ref);
}
//-----------------------------------------------------------------------
// Feed the dictionary to the plugin, to create a blank aggregate device
//-----------------------------------------------------------------------
AudioObjectPropertyAddress pluginAOPA;
pluginAOPA.mSelector = kAudioPlugInCreateAggregateDevice;
pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal;
@@ -751,7 +759,7 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
printError(osErr);
goto error;
}
osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice);
if (osErr != noErr) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectGetPropertyData error");
@@ -777,10 +785,10 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
printError(osErr);
goto error;
}
// pause again to give the changes time to take effect
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false);
//-----------------------
// Set the master device
//-----------------------
@@ -797,36 +805,36 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
printError(osErr);
goto error;
}
// pause again to give the changes time to take effect
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false);
// Prepare sub-devices for clock drift compensation
// Workaround for bug in the HAL : until 10.6.2
if (fClockDriftCompensate) {
if (need_clock_drift_compensation) {
jack_info("Clock drift compensation activated...");
// Get the property data size
osErr = AudioObjectGetPropertyDataSize(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize);
if (osErr != noErr) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error");
printError(osErr);
}
// Calculate the number of object IDs
subDevicesNum = outSize / sizeof(AudioObjectID);
jack_info("JackCoreAudioDriver::CreateAggregateDevice clock drift compensation, number of sub-devices = %d", subDevicesNum);
AudioObjectID subDevices[subDevicesNum];
outSize = sizeof(subDevices);
osErr = AudioObjectGetPropertyData(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize, subDevices);
if (osErr != noErr) {
jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error");
printError(osErr);
}
// Set kAudioSubDevicePropertyDriftCompensation property...
for (UInt32 index = 0; index < subDevicesNum; ++index) {
UInt32 theDriftCompensationValue = 1;
@@ -839,22 +847,22 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
} else {
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
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false);
//----------
// Clean up
//----------
// release the private AD key
CFRelease(AggregateDeviceNumberRef);

// release the CF objects we have created - we don't need them any more
CFRelease(aggDeviceDict);
CFRelease(subDevicesArray);
if (subDevicesArrayClock)
CFRelease(subDevicesArrayClock);

@@ -862,35 +870,35 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
for (UInt32 i = 0; i < captureDeviceUID.size(); i++) {
CFRelease(captureDeviceUID[i]);
}
for (UInt32 i = 0; i < playbackDeviceUID.size(); i++) {
CFRelease(playbackDeviceUID[i]);
}
jack_log("New aggregate device %ld", *outAggregateDevice);
return noErr;
error:
DestroyAggregateDevice();
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)
{
capture_driver_name[0] = 0;
playback_driver_name[0] = 0;
// Duplex
if (strcmp(capture_driver_uid, "") != 0 && strcmp(playback_driver_uid, "") != 0) {
jack_log("JackCoreAudioDriver::Open duplex");
// Same device for capture and playback...
if (strcmp(capture_driver_uid, playback_driver_uid) == 0) {
if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) {
jack_log("Will take default in/out");
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");
return -1;
}
} else {
// Creates aggregate device
AudioDeviceID captureID, playbackID;
if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) {
jack_log("Will take default input");
if (GetDefaultInputDevice(&captureID) != noErr) {
@@ -963,10 +971,10 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid,
jack_log("JackCoreAudioDriver::Open default driver");
if (GetDefaultDevice(&fDeviceID) != noErr) {
jack_error("Cannot open default device in duplex mode, so aggregate default input and default output");
// Creates aggregate device
AudioDeviceID captureID, playbackID;
if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) {
jack_log("Will take default input");
if (GetDefaultInputDevice(&captureID) != noErr) {
@@ -974,7 +982,7 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid,
return -1;
}
}
if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) {
jack_log("Will take default output");
if (GetDefaultOutputDevice(&playbackID) != noErr) {
@@ -982,12 +990,12 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid,
return -1;
}
}
if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr)
return -1;
}
}
if (fHogged) {
if (TakeHog()) {
jack_info("Device = %ld has been hogged", fDeviceID);
@@ -1111,7 +1119,7 @@ int JackCoreAudioDriver::SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes
usleep(100000);
jack_log("Wait count = %d", count);
}
// Check new sample rate
outSize = sizeof(Float64);
err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate);
@@ -1150,7 +1158,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
jack_error("No input and output channels...");
return -1;
}
// AUHAL
ComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0};
Component HALOutput = FindNextComponent(NULL, &cd);
@@ -1177,7 +1185,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
enableIO = 0;
jack_log("Setup AUHAL input off");
}
err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO));
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input");
@@ -1192,14 +1200,14 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
enableIO = 0;
jack_log("Setup AUHAL output off");
}
err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO));
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO,kAudioUnitScope_Output");
printError(err1);
goto error;
}
size = sizeof(AudioDeviceID);
err1 = AudioUnitGetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &currAudioDeviceID, &size);
if (err1 != noErr) {
@@ -1217,7 +1225,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
printError(err1);
goto error;
}
// Set buffer size
if (capturing && inchannels > 0) {
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
if (capturing && inchannels > 0) {
size = sizeof(AudioStreamBasicDescription);
err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, &size);
if (err1 != noErr) {
@@ -1281,7 +1289,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
goto error;
}
PrintStreamDesc(&srcFormat);
jack_log("Setup AUHAL input stream converter SR = %ld", samplerate);
srcFormat.mSampleRate = samplerate;
srcFormat.mFormatID = kAudioFormatLinearPCM;
@@ -1292,7 +1300,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
srcFormat.mChannelsPerFrame = inchannels;
srcFormat.mBitsPerChannel = 32;
PrintStreamDesc(&srcFormat);
err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription));
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output");
@@ -1302,7 +1310,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
}

if (playing && outchannels > 0) {
size = sizeof(AudioStreamBasicDescription);
err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, &size);
if (err1 != noErr) {
@@ -1311,7 +1319,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
goto error;
}
PrintStreamDesc(&dstFormat);
jack_log("Setup AUHAL output stream converter SR = %ld", samplerate);
dstFormat.mSampleRate = samplerate;
dstFormat.mFormatID = kAudioFormatLinearPCM;
@@ -1322,7 +1330,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
dstFormat.mChannelsPerFrame = outchannels;
dstFormat.mBitsPerChannel = 32;
PrintStreamDesc(&dstFormat);
err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription));
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input");
@@ -1355,7 +1363,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
}

return 0;
error:
CloseAUHAL();
return -1;
@@ -1486,12 +1494,12 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,
fComputationGrain = float(computation_grain) / 100.f;
fHogged = hogged;
fClockDriftCompensate = clock_drift;
SInt32 major;
SInt32 minor;
Gestalt(gestaltSystemVersionMajor, &major);
Gestalt(gestaltSystemVersionMinor, &minor);
// Starting with 10.6 systems, the HAL notification thread is created internally
if (major == 10 && minor >= 6) {
CFRunLoopRef theRunLoop = NULL;
@@ -1515,10 +1523,10 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,

if (SetupBufferSize(buffer_size) < 0)
goto error;
if (SetupSampleRate(samplerate) < 0)
goto error;
if (OpenAUHAL(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, buffer_size, samplerate) < 0)
goto error;

@@ -1528,7 +1536,7 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,

if (AddListeners() < 0)
goto error;
// Core driver may have changed the in/out values
fCaptureChannels = inchannels;
fPlaybackChannels = outchannels;
@@ -1561,7 +1569,7 @@ int JackCoreAudioDriver::Attach()
char channel_name[64];
char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE];
char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE];
jack_log("JackCoreAudioDriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate);

for (int i = 0; i < fCaptureChannels; i++) {
@@ -1670,7 +1678,7 @@ int JackCoreAudioDriver::Start()
OSStatus err = AudioOutputUnitStart(fAUHAL);
if (err != noErr)
return -1;
// Waiting for Measure callback to be called (= driver has started)
fState = false;
int count = 0;
@@ -1678,7 +1686,7 @@ int JackCoreAudioDriver::Start()
usleep(100000);
jack_log("JackCoreAudioDriver::Start wait count = %d", count);
}
if (count < WAIT_COUNTER) {
jack_info("CoreAudio driver is running...");
return 0;
@@ -1738,17 +1746,17 @@ bool JackCoreAudioDriver::TakeHogAux(AudioDeviceID deviceID, bool isInput)
return false;
}
}
return true;
}
bool JackCoreAudioDriver::TakeHog()
{
OSStatus err = noErr;
AudioObjectID sub_device[32];
UInt32 outSize = sizeof(sub_device);
err = AudioDeviceGetProperty(fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device);
if (err != noErr) {
jack_log("Device does not have subdevices");
return TakeHogAux(fDeviceID, true);
@@ -1763,12 +1771,12 @@ bool JackCoreAudioDriver::TakeHog()
return true;
}
}
bool JackCoreAudioDriver::IsAggregateDevice(AudioDeviceID device)
{
UInt32 deviceType, outSize = sizeof(UInt32);
OSStatus err = AudioDeviceGetProperty(device, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyTransportType, &outSize, &deviceType);
if (err != noErr) {
jack_log("JackCoreAudioDriver::IsAggregateDevice kAudioDevicePropertyTransportType error");
return false;
@@ -1786,7 +1794,7 @@ extern "C"
{
#endif

SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor()
SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor()
{
jack_driver_desc_t *desc;
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->desc, "Apple CoreAudio API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1
desc->nparams = 17;
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;
strcpy(desc->params[i].short_desc, "Display available CoreAudio devices");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
i++;
strcpy(desc->params[i].name, "hog");
desc->params[i].character = 'H';
@@ -1906,7 +1914,7 @@ extern "C"
desc->params[i].value.i = FALSE;
strcpy(desc->params[i].short_desc, "Take exclusive access of the audio device");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
i++;
strcpy(desc->params[i].name, "async-latency");
desc->params[i].character = 'L';
@@ -1914,7 +1922,7 @@ extern "C"
desc->params[i].value.i = 100;
strcpy(desc->params[i].short_desc, "Extra output latency in asynchronous mode (percent)");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
i++;
strcpy(desc->params[i].name, "grain");
desc->params[i].character = 'G';
@@ -1922,7 +1930,7 @@ extern "C"
desc->params[i].value.i = 100;
strcpy(desc->params[i].short_desc, "Computation grain in RT thread (percent)");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
i++;
strcpy(desc->params[i].name, "clock-drift");
desc->params[i].character = 's';
@@ -1934,7 +1942,7 @@ extern "C"
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 frames_per_interrupt = 128;
@@ -1953,10 +1961,10 @@ extern "C"
int computation_grain = -1;
bool hogged = false;
bool clock_drift = false;
for (node = params; node; node = jack_slist_next(node)) {
param = (const jack_driver_param_t *) node->data;
switch (param->character) {

case 'd':
@@ -2018,19 +2026,19 @@ extern "C"
case 'l':
Jack::DisplayDeviceNames();
break;
case 'H':
hogged = true;
break;
case 'L':
async_output_latency = param->value.ui;
break;
case 'G':
computation_grain = param->value.ui;
break;
case 's':
clock_drift = true;
break;
@@ -2044,7 +2052,7 @@ extern "C"
}

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) {
return driver;
} else {


+ 17
- 17
posix/JackPosixMutex.h View File

@@ -33,47 +33,47 @@ namespace Jack
\brief Mutex abstraction.
*/

class JackBasePosixMutex
{
protected:
pthread_mutex_t fMutex;
public:
JackBasePosixMutex()
{
pthread_mutex_init(&fMutex, NULL);
pthread_mutex_init(&fMutex, NULL);
}
virtual ~JackBasePosixMutex()
{
pthread_mutex_destroy(&fMutex);
}
void Lock()
{
int res = pthread_mutex_lock(&fMutex);
if (res != 0)
jack_error("JackBasePosixMutex::Lock res = %d", res);
jack_log("JackBasePosixMutex::Lock res = %d", res);
}
bool Trylock()
{
return (pthread_mutex_trylock(&fMutex) == 0);
}
void Unlock()
{
int res = pthread_mutex_unlock(&fMutex);
if (res != 0)
jack_error("JackBasePosixMutex::Unlock res = %d", res);
jack_log("JackBasePosixMutex::Unlock res = %d", res);
}
};
class JackPosixMutex
{

@@ -97,7 +97,7 @@ class JackPosixMutex
res = pthread_mutexattr_destroy(&mutex_attr);
assert(res == 0);
}
virtual ~JackPosixMutex()
{
pthread_mutex_destroy(&fMutex);
@@ -107,7 +107,7 @@ class JackPosixMutex
{
int res = pthread_mutex_lock(&fMutex);
if (res != 0)
jack_error("JackPosixMutex::Lock res = %d", res);
jack_log("JackPosixMutex::Lock res = %d", res);
return (res == 0);
}

@@ -120,7 +120,7 @@ class JackPosixMutex
{
int res = pthread_mutex_unlock(&fMutex);
if (res != 0)
jack_error("JackPosixMutex::Unlock res = %d", res);
jack_log("JackPosixMutex::Unlock res = %d", res);
return (res == 0);
}



Loading…
Cancel
Save