diff --git a/ChangeLog b/ChangeLog index 97b434d7..503e436f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -34,6 +34,10 @@ Valerio Pilo Jackdmp changes log --------------------------- +2011-02-09 Stephane Letz + + * Remove JackPortIsActive flag. + 2011-02-07 Stephane Letz * Valerio Pilo second CAS for ARMv7 patch. diff --git a/common/JackDriver.h b/common/JackDriver.h index 901e6bf3..6f230831 100644 --- a/common/JackDriver.h +++ b/common/JackDriver.h @@ -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 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(JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal | JackPortIsActive) -#define PlaybackDriverFlags static_cast(JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal | JackPortIsActive) -#define MonitorDriverFlags static_cast(JackPortIsOutput | JackPortIsActive) + +#define CaptureDriverFlags static_cast(JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal) +#define PlaybackDriverFlags static_cast(JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal) +#define MonitorDriverFlags static_cast(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 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 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 diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index 94e530bc..564c8fcb 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -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 diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index 1a92191c..684a0dfe 100644 --- a/common/JackGraphManager.cpp +++ b/common/JackGraphManager.cpp @@ -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; diff --git a/common/JackGraphManager.h b/common/JackGraphManager.h index 93b09ff9..98e95b82 100644 --- a/common/JackGraphManager.h +++ b/common/JackGraphManager.h @@ -13,7 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software +along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ @@ -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 { @@ -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); diff --git a/common/jack/types.h b/common/jack/types.h index 65c930d7..f75b83fc 100644 --- a/common/jack/types.h +++ b/common/jack/types.h @@ -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 diff --git a/example-clients/lsp.c b/example-clients/lsp.c index dc00dc68..5aa7c7e1 100644 --- a/example-clients/lsp.c +++ b/example-clients/lsp.c @@ -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); diff --git a/linux/alsa/alsa_rawmidi.c b/linux/alsa/alsa_rawmidi.c index 62e18cd7..ba378c4e 100644 --- a/linux/alsa/alsa_rawmidi.c +++ b/linux/alsa/alsa_rawmidi.c @@ -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); diff --git a/linux/alsa/alsa_seqmidi.c b/linux/alsa/alsa_seqmidi.c index 0abc52a9..c3d8239f 100644 --- a/linux/alsa/alsa_seqmidi.c +++ b/linux/alsa/alsa_seqmidi.c @@ -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) diff --git a/macosx/coreaudio/JackCoreAudioAdapter.cpp b/macosx/coreaudio/JackCoreAudioAdapter.cpp index 8e25b58d..d7e5edea 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.cpp +++ b/macosx/coreaudio/JackCoreAudioAdapter.cpp @@ -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(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 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 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 captureDeviceID, vector playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice) + +OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector captureDeviceID, vector 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 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 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 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 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 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 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 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 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 captureDeviceUID; for (UInt32 i = 0; i < captureDeviceID.size(); i++) { CFStringRef ref = GetDeviceName(captureDeviceID[i]); @@ -1273,7 +1283,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector ca // input sub-devices in this example, so append the sub-device's UID to the CFArray CFArrayAppendValue(subDevicesArray, ref); } - + vector playbackDeviceUID; for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { CFStringRef ref = GetDeviceName(playbackDeviceID[i]); @@ -1283,39 +1293,39 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector 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 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 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 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; } diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 3b02ae9c..1995edbb 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -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 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 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 captureDeviceID, vector playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice) +OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector captureDeviceID, vector 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 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 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 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 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 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 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 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 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 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 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 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 captureDeviceUID; for (UInt32 i = 0; i < captureDeviceID.size(); i++) { CFStringRef ref = GetDeviceName(captureDeviceID[i]); @@ -724,7 +732,7 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector cap // input sub-devices in this example, so append the sub-device's UID to the CFArray CFArrayAppendValue(subDevicesArray, ref); } - + vector playbackDeviceUID; for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { CFStringRef ref = GetDeviceName(playbackDeviceID[i]); @@ -734,11 +742,11 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector 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 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 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 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 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 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 { diff --git a/posix/JackPosixMutex.h b/posix/JackPosixMutex.h index ddf89553..a8607780 100644 --- a/posix/JackPosixMutex.h +++ b/posix/JackPosixMutex.h @@ -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); }