From 926a25f6c66d0bcf17327b9e2cbf9c65e4c3a829 Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 24 Feb 2009 12:09:21 +0000 Subject: [PATCH 002/472] New libjacknet library with net.h and JackNetAPI.cpp files. New netmaster.c and netmaster.c examples. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3337 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 4 + common/JackNetAPI.cpp | 1029 +++++++++++++++++++++++++++++++++++ common/jack/net.h | 300 ++++++++++ common/wscript | 25 + example-clients/netmaster.c | 165 ++++++ example-clients/netslave.c | 160 ++++++ example-clients/wscript | 9 +- 7 files changed, 1691 insertions(+), 1 deletion(-) create mode 100644 common/JackNetAPI.cpp create mode 100644 common/jack/net.h create mode 100644 example-clients/netmaster.c create mode 100644 example-clients/netslave.c diff --git a/ChangeLog b/ChangeLog index ef1336e4..632cec72 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,10 @@ Michael Voigt Jackdmp changes log --------------------------- +2009-02-24 Stephane Letz + + * New libjacknet library with net.h and JackNetAPI.cpp files. New netmaster.c and netmaster.c examples. + 2009-02-23 Stephane Letz * Another fix in systemdeps.h and types.h: jack_time_t now uniquely defined in types.h. diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp new file mode 100644 index 00000000..300357ac --- /dev/null +++ b/common/JackNetAPI.cpp @@ -0,0 +1,1029 @@ +/* +Copyright (C) 2009 Grame + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include +#include "JackNetInterface.h" +#include "JackPlatformPlug.h" +#include "JackError.h" +#include "JackTime.h" +#include "JackException.h" + +#include "JackAudioAdapterInterface.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + // NetJack common API + + #define MASTER_NAME_SIZE 256 + + enum JackNetMode { + + JackFastMode = 'f', + JackNormalMode = 'n', + JackSlowMode = 's', + }; + + typedef struct { + + int audio_input; + int audio_output; + int midi_input; + int midi_ouput; + int mtu; + int time_out; // in millisecond, -1 means in infinite + char mode; + + } jack_slave_t; + + typedef struct { + + jack_nframes_t buffer_size; + jack_nframes_t sample_rate; + char master_name[MASTER_NAME_SIZE]; + + } jack_master_t; + + // NetJack slave API + + typedef struct _jack_net_slave jack_net_slave_t; + + typedef int (* JackNetSlaveProcessCallback) (jack_nframes_t buffer_size, + int audio_input, + float** audio_input_buffer, + int midi_input, + void** midi_input_buffer, + int audio_output, + float** audio_output_buffer, + int midi_output, + void** midi_output_buffer, + void* data); + + typedef int (*JackNetSlaveBufferSizeCallback) (jack_nframes_t nframes, void *arg); + typedef int (*JackNetSlaveSampleRateCallback) (jack_nframes_t nframes, void *arg); + typedef void (*JackNetSlaveShutdownCallback) (void* data); + + SERVER_EXPORT jack_net_slave_t* jack_net_slave_open(const char* ip, int port, const char* name, jack_slave_t* request, jack_master_t* result); + SERVER_EXPORT int jack_net_slave_close(jack_net_slave_t* net); + + SERVER_EXPORT int jack_net_slave_activate(jack_net_slave_t* net); + SERVER_EXPORT int jack_net_slave_deactivate(jack_net_slave_t* net); + + SERVER_EXPORT int jack_set_net_slave_process_callback(jack_net_slave_t * net, JackNetSlaveProcessCallback net_callback, void *arg); + SERVER_EXPORT int jack_set_net_slave_buffer_size_callback(jack_net_slave_t *net, JackNetSlaveBufferSizeCallback bufsize_callback, void *arg); + SERVER_EXPORT int jack_set_net_slave_sample_rate_callback(jack_net_slave_t *net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg); + SERVER_EXPORT int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, JackNetSlaveShutdownCallback shutdown_callback, void *arg); + + // NetJack master API + + typedef struct _jack_net_master jack_net_master_t; + + SERVER_EXPORT jack_net_master_t* jack_net_master_open(const char* ip, int port, const char* name, jack_master_t* request, jack_slave_t* result); + SERVER_EXPORT int jack_net_master_close(jack_net_master_t* net); + + SERVER_EXPORT int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer); + SERVER_EXPORT int jack_net_master_send(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer); + + // NetJack adapter API + + typedef struct _jack_adapter jack_adapter_t; + + SERVER_EXPORT jack_adapter_t* jack_create_adapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate); + SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter); + + SERVER_EXPORT int jack_adapter_push_input(jack_adapter_t* adapter, int channels, float** buffers); + SERVER_EXPORT int jack_adapter_pull_input(jack_adapter_t* adapter, int channels, float** buffers); + + SERVER_EXPORT int jack_adapter_push_output(jack_adapter_t* adapter, int channels, float** buffers); + SERVER_EXPORT int jack_adapter_pull_output(jack_adapter_t* adapter, int channels, float** buffers); + +#ifdef __cplusplus +} +#endif + +namespace Jack +{ + +struct JackNetExtMaster : public JackNetMasterInterface { + + //sample buffers + float** fAudioCaptureBuffer; + float** fAudioPlaybackBuffer; + + JackMidiBuffer** fMidiCaptureBuffer; + JackMidiBuffer** fMidiPlaybackBuffer; + + jack_master_t fRequest; + + JackNetExtMaster(const char* ip, + int port, + const char* name, + jack_master_t* request) + { + fRunning = true; + assert(strlen(ip) < 32); + strcpy(fMulticastIP, ip); + fSocket.SetPort(port); + fRequest.buffer_size = request->buffer_size; + fRequest.sample_rate = request->sample_rate; + } + + virtual ~JackNetExtMaster() + {} + + int Open(jack_slave_t* result) + { + // Init socket API (win32) + if (SocketAPIInit() < 0) { + fprintf(stderr, "Can't init Socket API, exiting...\n"); + return -1; + } + + // Request socket + if (fSocket.NewSocket() == SOCKET_ERROR) { + fprintf(stderr, "Can't create the network management input socket : %s\n", StrError(NET_ERROR_CODE)); + return -1; + } + + // Bind the socket to the local port + if (fSocket.Bind() == SOCKET_ERROR) { + fprintf(stderr, "Can't bind the network manager socket : %s\n", StrError(NET_ERROR_CODE)); + fSocket.Close(); + return -1; + } + + // Join multicast group + if (fSocket.JoinMCastGroup(fMulticastIP) == SOCKET_ERROR) + fprintf(stderr, "Can't join multicast group : %s\n", StrError(NET_ERROR_CODE)); + + // Local loop + if (fSocket.SetLocalLoop() == SOCKET_ERROR) + fprintf(stderr, "Can't set local loop : %s\n", StrError(NET_ERROR_CODE)); + + // Set a timeout on the multicast receive (the thread can now be cancelled) + if (fSocket.SetTimeOut(2000000) == SOCKET_ERROR) + fprintf(stderr, "Can't set timeout : %s\n", StrError(NET_ERROR_CODE)); + + //main loop, wait for data, deal with it and wait again + //utility variables + int attempt = 0; + int rx_bytes = 0; + + do + { + session_params_t net_params; + rx_bytes = fSocket.CatchHost(&net_params, sizeof(session_params_t), 0); + SessionParamsNToH(&net_params, &fParams); + + if ((rx_bytes == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) { + fprintf(stderr, "Error in receive : %s\n", StrError(NET_ERROR_CODE)); + if (++attempt == 10) { + fprintf(stderr, "Can't receive on the socket, exiting net manager.\n" ); + goto error; + } + } + + if (rx_bytes == sizeof(session_params_t )) { + + switch (GetPacketType(&fParams)) { + + case SLAVE_AVAILABLE: + if (MasterInit() == 0) { + SessionParamsDisplay(&fParams); + fRunning = false; + } else { + fprintf(stderr, "Can't init new net master...\n"); + goto error; + } + break; + + case KILL_MASTER: + break; + + default: + break; + } + } + } + while (fRunning); + + // Set result paramaters + result->audio_input = fParams.fSendAudioChannels; + result->audio_output = fParams.fReturnAudioChannels; + result->midi_input = fParams.fSendMidiChannels; + result->midi_ouput = fParams.fReturnMidiChannels; + result->midi_ouput = fParams.fMtu; + result->mode = fParams.fNetworkMode; + return 0; + + error: + fSocket.Close(); + return -1; + } + + int MasterInit() + { + // Check MASTER <<==> SLAVE network protocol coherency + if (fParams.fProtocolVersion != MASTER_PROTOCOL) { + fprintf(stderr, "Error : slave is running with a different protocol %s\n", fParams.fName); + return -1; + } + + // Settings + fSocket.GetName(fParams.fMasterNetName); + fParams.fID = 1; + fParams.fBitdepth = 0; + fParams.fPeriodSize = fRequest.buffer_size; + fParams.fSampleRate = fRequest.sample_rate; + + // Close request socket + fSocket.Close(); + + // Network slave init + if (!JackNetMasterInterface::Init()) + return -1; + + // Set global parameters + SetParams(); + AllocPorts(); + return 0; + } + + int Close() + { + fSocket.Close(); + FreePorts(); + return 0; + } + + void AllocPorts() + { + unsigned int port_index; + + // Set buffers + fAudioPlaybackBuffer = new float*[fParams.fSendAudioChannels]; + for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) { + fAudioPlaybackBuffer[port_index] = new float[fParams.fPeriodSize]; + fNetAudioPlaybackBuffer->SetBuffer(port_index, fAudioPlaybackBuffer[port_index]); + } + + fMidiPlaybackBuffer = new JackMidiBuffer*[fParams.fSendMidiChannels]; + for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) { + fMidiPlaybackBuffer[port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize]; + fNetMidiPlaybackBuffer->SetBuffer(port_index, fMidiPlaybackBuffer[port_index]); + } + + fAudioCaptureBuffer = new float*[fParams.fReturnAudioChannels]; + for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) { + fAudioCaptureBuffer[port_index] = new float[fParams.fPeriodSize]; + fNetAudioCaptureBuffer->SetBuffer(port_index, fAudioCaptureBuffer[port_index]); + } + + fMidiCaptureBuffer = new JackMidiBuffer*[fParams.fReturnMidiChannels]; + for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) { + fMidiCaptureBuffer[port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize]; + fNetMidiCaptureBuffer->SetBuffer(port_index, fMidiCaptureBuffer[port_index]); + } + } + + void FreePorts() + { + unsigned int port_index; + + if (fAudioPlaybackBuffer) { + for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) + delete[] fAudioPlaybackBuffer[port_index]; + delete[] fAudioPlaybackBuffer; + fAudioPlaybackBuffer = NULL; + } + + if (fMidiPlaybackBuffer) { + for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) + delete[] (fMidiPlaybackBuffer[port_index]); + delete[] fMidiPlaybackBuffer; + fMidiPlaybackBuffer = NULL; + } + + if (fAudioCaptureBuffer) { + for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) + delete[] fAudioCaptureBuffer[port_index]; + delete[] fAudioCaptureBuffer; + fAudioCaptureBuffer = NULL; + } + + if (fMidiCaptureBuffer) { + for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) + delete[] fMidiCaptureBuffer[port_index]; + delete[] fMidiCaptureBuffer; + fMidiCaptureBuffer = NULL; + } + } + + int Read(int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer) + { + assert((unsigned int)audio_input == fParams.fSendAudioChannels); + int port_index; + + for (port_index = 0; port_index < audio_input; port_index++) { + fNetAudioPlaybackBuffer->SetBuffer(port_index, audio_input_buffer[port_index]); + } + + for (port_index = 0; port_index < midi_input; port_index++) { + fNetMidiPlaybackBuffer->SetBuffer(port_index, ((JackMidiBuffer**)midi_input_buffer)[port_index]); + } + + if (SyncRecv() == SOCKET_ERROR) + return 0; + + if (DecodeSyncPacket() < 0) + return 0; + + return DataRecv(); + } + + int Write(int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer) + { + assert((unsigned int)audio_output == fParams.fReturnAudioChannels); + int port_index; + + for (port_index = 0; port_index < audio_output; port_index++) { + fNetAudioCaptureBuffer->SetBuffer(port_index, audio_output_buffer[port_index]); + } + + for (port_index = 0; port_index < midi_output; port_index++) { + fNetMidiCaptureBuffer->SetBuffer(port_index, ((JackMidiBuffer**)midi_output_buffer)[port_index]); + } + + if (EncodeSyncPacket() < 0) + return 0; + + if (SyncSend() == SOCKET_ERROR) + return SOCKET_ERROR; + + return DataSend(); + } + + // Transport + int EncodeTransportData() + { + return 0; + } + + int DecodeTransportData() + { + return 0; + } + + +}; + +struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterface { + + JackThread fThread; + + JackNetSlaveProcessCallback fProcessCallback; + void* fProcessArg; + + JackNetSlaveShutdownCallback fShutdownCallback; + void* fShutdownArg; + + JackNetSlaveBufferSizeCallback fBufferSizeCallback; + void* fBufferSizeArg; + + JackNetSlaveSampleRateCallback fSampleRateCallback; + void* fSampleRateArg; + + //sample buffers + float** fAudioCaptureBuffer; + float** fAudioPlaybackBuffer; + + JackMidiBuffer** fMidiCaptureBuffer; + JackMidiBuffer** fMidiPlaybackBuffer; + + JackNetExtSlave(const char* ip, + int port, + const char* name, + jack_slave_t* request) + :fThread(this), + fProcessCallback(NULL),fProcessArg(NULL), + fShutdownCallback(NULL), fShutdownArg(NULL), + fBufferSizeCallback(NULL), fBufferSizeArg(NULL), + fSampleRateCallback(NULL), fSampleRateArg(NULL), + fAudioCaptureBuffer(NULL), fAudioPlaybackBuffer(NULL), + fMidiCaptureBuffer(NULL), fMidiPlaybackBuffer(NULL) + { + char host_name[JACK_CLIENT_NAME_SIZE]; + + // Request parameters + assert(strlen(ip) < 32); + strcpy(fMulticastIP, ip); + + fParams.fMtu = request->mtu; + fParams.fTransportSync = 0; + fParams.fSendAudioChannels = request->audio_input; + fParams.fReturnAudioChannels = request->audio_output; + fParams.fSendMidiChannels = request->midi_input; + fParams.fReturnMidiChannels = request->midi_ouput; + fParams.fNetworkMode = request->mode; + fParams.fSlaveSyncMode = 1; + + // Create name with hostname and client name + GetHostName(host_name, JACK_CLIENT_NAME_SIZE); + snprintf(fParams.fName, JACK_CLIENT_NAME_SIZE, "%s_%s", host_name, name); + fSocket.GetName(fParams.fSlaveNetName); + + // Set the socket parameters + fSocket.SetPort(port); + fSocket.SetAddress(fMulticastIP, port); + } + + virtual ~JackNetExtSlave() + {} + + int Open(jack_master_t* result) + { + // Init network connection + if (!JackNetSlaveInterface::InitConnection()){ + return -1; + } + + // Then set global parameters + SetParams(); + + // Set result + if (result != NULL) { + result->buffer_size = fParams.fPeriodSize; + result->sample_rate = fParams.fSampleRate; + strcpy(result->master_name, fParams.fMasterNetName); + } + + AllocPorts(); + return 0; + } + + int Restart() + { + // If shutdown cb is set, then call it + if (fShutdownCallback) + fShutdownCallback(fShutdownArg); + + // Init complete network connection + if (!JackNetSlaveInterface::Init()) + return -1; + + // Then set global parameters + SetParams(); + + // We need to notify possibly new buffer size and sample rate (see Execute) + if (fBufferSizeCallback) + fBufferSizeCallback(fParams.fPeriodSize, fBufferSizeArg); + + if (fSampleRateCallback) + fSampleRateCallback(fParams.fSampleRate, fSampleRateArg); + + AllocPorts(); + return 0; + } + + int Close() + { + fSocket.Close(); + FreePorts(); + return 0; + } + + void AllocPorts() + { + unsigned int port_index; + + // Set buffers + fAudioCaptureBuffer = new float*[fParams.fSendAudioChannels]; + for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) { + fAudioCaptureBuffer[port_index] = new float[fParams.fPeriodSize]; + fNetAudioCaptureBuffer->SetBuffer(port_index, fAudioCaptureBuffer[port_index]); + } + + fMidiCaptureBuffer = new JackMidiBuffer*[fParams.fSendMidiChannels]; + for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) { + fMidiCaptureBuffer[port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize]; + fNetMidiCaptureBuffer->SetBuffer(port_index, fMidiCaptureBuffer[port_index]); + } + + fAudioPlaybackBuffer = new float*[fParams.fReturnAudioChannels]; + for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) { + fAudioPlaybackBuffer[port_index] = new float[fParams.fPeriodSize]; + fNetAudioPlaybackBuffer->SetBuffer(port_index, fAudioPlaybackBuffer[port_index]); + } + + fMidiPlaybackBuffer = new JackMidiBuffer*[fParams.fReturnMidiChannels]; + for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) { + fMidiPlaybackBuffer[port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize]; + fNetMidiPlaybackBuffer->SetBuffer(port_index, fMidiPlaybackBuffer[port_index]); + } + } + + void FreePorts() + { + unsigned int port_index; + + if (fAudioCaptureBuffer) { + for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) + delete[] fAudioCaptureBuffer[port_index]; + delete[] fAudioCaptureBuffer; + fAudioCaptureBuffer = NULL; + } + + if (fMidiCaptureBuffer) { + for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) + delete[] (fMidiCaptureBuffer[port_index]); + delete[] fMidiCaptureBuffer; + fMidiCaptureBuffer = NULL; + } + + if (fAudioPlaybackBuffer) { + for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) + delete[] fAudioPlaybackBuffer[port_index]; + delete[] fAudioPlaybackBuffer; + fAudioPlaybackBuffer = NULL; + } + + if (fMidiPlaybackBuffer) { + for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) + delete[] fMidiPlaybackBuffer[port_index]; + delete[] fMidiPlaybackBuffer; + fMidiPlaybackBuffer = NULL; + } + } + + // Transport + int EncodeTransportData() + { + return 0; + } + + int DecodeTransportData() + { + return 0; + } + + bool Init() + { + // Will do "something" on OSX only... + fThread.SetParams(float(fParams.fPeriodSize) / float(fParams.fSampleRate) * 1000000, 100 * 1000, 500 * 1000); + return (fThread.AcquireRealTime(80) == 0); // TODO: get a value from the server + } + + bool Execute() + { + try { + // Keep running even in case of error + while (fThread.GetStatus() == JackThread::kRunning) { + if (Process() == SOCKET_ERROR) + return false; + } + return false; + } catch (JackNetException& e) { + + // Otherwise just restart... + e.PrintMessage(); + fThread.DropRealTime(); + fThread.SetStatus(JackThread::kIniting); + FreePorts(); + Restart(); + if (Init()) { + fThread.SetStatus(JackThread::kRunning); + return true; + } else { + return false; + } + } + } + + int Read() + { + // Don't return -1 in case of sync recv failure + // we need the process to continue for network error detection + if (SyncRecv() == SOCKET_ERROR) + return 0; + + if (DecodeSyncPacket() < 0) + return 0; + + return DataRecv(); + } + + int Write() + { + if (EncodeSyncPacket() < 0) + return 0; + + if (SyncSend() == SOCKET_ERROR) + return SOCKET_ERROR; + + return DataSend(); + } + + int Process() + { + // Read data from the network + // in case of fatal network error, stop the process + if (Read() == SOCKET_ERROR) + return SOCKET_ERROR; + + fProcessCallback(fParams.fPeriodSize, + fParams.fSendAudioChannels, + fAudioCaptureBuffer, + fParams.fSendMidiChannels, + (void**)fMidiCaptureBuffer, + fParams.fReturnAudioChannels, + fAudioPlaybackBuffer, + fParams.fReturnMidiChannels, + (void**)fMidiPlaybackBuffer, + fProcessArg); + + // Then write data to network + // in case of failure, stop process + if (Write() == SOCKET_ERROR) + return SOCKET_ERROR; + + return 0; + } + + int Start() + { + // Finish connection.. + if (!JackNetSlaveInterface::InitRendering()) { + return -1; + } + + return (fProcessCallback == 0) ? -1 : fThread.StartSync(); + } + + int Stop() + { + return (fProcessCallback == 0) ? -1 : fThread.Kill(); + } + + // Callback + int SetProcessCallback(JackNetSlaveProcessCallback net_callback, void *arg) + { + if (fThread.GetStatus() == JackThread::kRunning) { + return -1; + } else { + fProcessCallback = net_callback; + fProcessArg = arg; + return 0; + } + } + + int SetShutdownCallback(JackNetSlaveShutdownCallback shutdown_callback, void *arg) + { + if (fThread.GetStatus() == JackThread::kRunning) { + return -1; + } else { + fShutdownCallback = shutdown_callback; + fShutdownArg = arg; + return 0; + } + } + + int SetBufferSizeCallback(JackNetSlaveBufferSizeCallback bufsize_callback, void *arg) + { + if (fThread.GetStatus() == JackThread::kRunning) { + return -1; + } else { + fBufferSizeCallback = bufsize_callback; + fBufferSizeArg = arg; + return 0; + } + } + + int SetSampleRateCallback(JackNetSlaveSampleRateCallback samplerate_callback, void *arg) + { + if (fThread.GetStatus() == JackThread::kRunning) { + return -1; + } else { + fSampleRateCallback = samplerate_callback; + fSampleRateArg = arg; + return 0; + } + } + +}; + +struct JackNetAdapter : public JackAudioAdapterInterface { + + + JackNetAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate) + :JackAudioAdapterInterface(buffer_size, sample_rate) + { + fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; + fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; + + /* + for (i = 0; i < fCaptureChannels; i++) + fCaptureRingBuffer[i] = new JackLibSampleRateResampler(fAudioAdapter->GetQuality()); + for (i = 0; i < fPlaybackChannels; i++) + fPlaybackRingBuffer[i] = new JackLibSampleRateResampler(fAudioAdapter->GetQuality()); + */ + + int i; + for (i = 0; i < fCaptureChannels; i++) + fCaptureRingBuffer[i] = new JackResampler(); + for (i = 0; i < fPlaybackChannels; i++) + fPlaybackRingBuffer[i] = new JackResampler(); + } + + virtual ~JackNetAdapter() + { + int i; + for (i = 0; i < fCaptureChannels; i++) + delete (fCaptureRingBuffer[i]); + for (i = 0; i < fPlaybackChannels; i++) + delete(fPlaybackRingBuffer[i] ); + + delete[] fCaptureRingBuffer; + delete[] fPlaybackRingBuffer; + } + + void Reset() + { + int i; + for (i = 0; i < fCaptureChannels; i++) + fCaptureRingBuffer[i]->Reset(); + for (i = 0; i < fPlaybackChannels; i++) + fPlaybackRingBuffer[i]->Reset(); + } + + int PushInput(int audio_input, float** audio_input_buffer) + { + bool failure = false; + int port_index; + + // Get the resample factor, + jack_nframes_t time1, time2; + ResampleFactor(time1, time2); + + // Resample input data, + for (port_index = 0; port_index < audio_input; port_index++) { + fCaptureRingBuffer[port_index]->SetRatio(time1, time2); + if (fCaptureRingBuffer[port_index]->WriteResample(audio_input_buffer[port_index], fAdaptedBufferSize) < fAdaptedBufferSize) + failure = true; + } + + if (failure) { + ResetRingBuffers(); + return -1; + } + + return 0; + } + + int PullInput(int audio_input, float** audio_input_buffer) + { + bool failure = false; + int port_index; + + // DLL + SetCallbackTime(GetMicroSeconds()); + + // Push/pull from ringbuffer + for (port_index = 0; port_index < audio_input; port_index++) { + if (fCaptureRingBuffer[port_index]->Read(audio_input_buffer[port_index], fHostBufferSize) < fHostBufferSize) + failure = true; + } + + // Reset all ringbuffers in case of failure + if (failure) { + Reset(); + return -1; + } + + return 0; + } + + int PushOutput(int audio_input, float** audio_input_buffer) + { + bool failure = false; + int port_index; + + // DLL + SetCallbackTime(GetMicroSeconds()); + + // Push/pull from ringbuffer + for (port_index = 0; port_index < audio_input; port_index++) { + if (fPlaybackRingBuffer[port_index]->Write(audio_input_buffer[port_index], fHostBufferSize) < fHostBufferSize) + failure = true; + } + + // Reset all ringbuffers in case of failure + if (failure) { + Reset(); + return -1; + } + + return 0; + } + + int PullOutput(int audio_output, float** audio_output_buffer) + { + bool failure = false; + int port_index; + + //get the resample factor, + jack_nframes_t time1, time2; + ResampleFactor(time1, time2); + + //resample output data, + for (port_index = 0; port_index < fPlaybackChannels; port_index++) { + fPlaybackRingBuffer[port_index]->SetRatio(time2, time1); + if (fPlaybackRingBuffer[port_index]->ReadResample(audio_output_buffer[port_index], fAdaptedBufferSize) < fAdaptedBufferSize) + failure = true; + } + + if (failure) { + ResetRingBuffers(); + return -1; + } + + return 0; + } + +}; + + +} // end of namespace + +using namespace Jack; + +SERVER_EXPORT jack_net_slave_t* jack_net_slave_open(const char* ip, int port, const char* name, jack_slave_t* request, jack_master_t* result) +{ + JackNetExtSlave* slave = new JackNetExtSlave(ip, port, name, request); + if (slave->Open(result) == 0) { + return (jack_net_slave_t*)slave; + } else { + delete slave; + return NULL; + } +} + +SERVER_EXPORT int jack_net_slave_close(jack_net_slave_t* net) +{ + JackNetExtSlave* slave = (JackNetExtSlave*)net; + slave->Close(); + delete slave; + return 0; +} + +SERVER_EXPORT int jack_set_net_slave_process_callback(jack_net_slave_t* net, JackNetSlaveProcessCallback net_callback, void *arg) +{ + JackNetExtSlave* slave = (JackNetExtSlave*)net; + return slave->SetProcessCallback(net_callback, arg); +} + +SERVER_EXPORT int jack_net_slave_activate(jack_net_slave_t* net) +{ + JackNetExtSlave* slave = (JackNetExtSlave*)net; + return slave->Start(); +} + +SERVER_EXPORT int jack_net_slave_deactivate(jack_net_slave_t* net) +{ + JackNetExtSlave* slave = (JackNetExtSlave*)net; + return slave->Stop(); +} + +SERVER_EXPORT int jack_set_net_slave_buffer_size_callback(jack_net_slave_t *net, JackNetSlaveBufferSizeCallback bufsize_callback, void *arg) +{ + JackNetExtSlave* slave = (JackNetExtSlave*)net; + return slave->SetBufferSizeCallback(bufsize_callback, arg); +} + +SERVER_EXPORT int jack_set_net_slave_sample_rate_callback(jack_net_slave_t *net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg) +{ + JackNetExtSlave* slave = (JackNetExtSlave*)net; + return slave->SetSampleRateCallback(samplerate_callback, arg); +} + +SERVER_EXPORT int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, JackNetSlaveShutdownCallback shutdown_callback, void *arg) +{ + JackNetExtSlave* slave = (JackNetExtSlave*)net; + return slave->SetShutdownCallback(shutdown_callback, arg); +} + +// Master API + +SERVER_EXPORT jack_net_master_t* jack_net_master_open(const char* ip, int port, const char* name, jack_master_t* request, jack_slave_t* result) +{ + JackNetExtMaster* master = new JackNetExtMaster(ip, port, name, request); + if (master->Open(result) == 0) { + return (jack_net_master_t*)master; + } else { + delete master; + return NULL; + } +} + +SERVER_EXPORT int jack_net_master_close(jack_net_master_t* net) +{ + JackNetExtMaster* master = (JackNetExtMaster*)net; + master->Close(); + delete master; + return 0; +} +SERVER_EXPORT int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer) +{ + JackNetExtMaster* slave = (JackNetExtMaster*)net; + return slave->Read(audio_input, audio_input_buffer, midi_input, midi_input_buffer); +} + +SERVER_EXPORT int jack_net_master_send(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer) +{ + JackNetExtMaster* slave = (JackNetExtMaster*)net; + return slave->Write(audio_output, audio_output_buffer, midi_output, midi_output_buffer); +} + +// Adapter API + +SERVER_EXPORT jack_adapter_t* jack_create_adapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate) +{ + return (jack_adapter_t*)new JackNetAdapter(buffer_size, sample_rate); +} + +SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter) +{ + delete((JackNetAdapter*)adapter); + return 0; +} + +SERVER_EXPORT int jack_adapter_push_input(jack_adapter_t * adapter, int channels, float** buffers) +{ + JackNetAdapter* slave = (JackNetAdapter*)adapter; + return slave->PushInput(channels, buffers); +} + +SERVER_EXPORT int jack_adapter_pull_input(jack_adapter_t * adapter, int channels, float** buffers) +{ + JackNetAdapter* slave = (JackNetAdapter*)adapter; + return slave->PullInput(channels, buffers); +} + +SERVER_EXPORT int jack_adapter_push_output(jack_adapter_t * adapter, int channels, float** buffers) +{ + JackNetAdapter* slave = (JackNetAdapter*)adapter; + return slave->PushOutput(channels, buffers); +} + +SERVER_EXPORT int jack_adapter_pull_output(jack_adapter_t * adapter, int channels, float** buffers) +{ + JackNetAdapter* slave = (JackNetAdapter*)adapter; + return slave->PullOutput(channels, buffers); +} + + +// Empty code for now.. +//#ifdef TARGET_OS_IPHONE + +SERVER_EXPORT void jack_error(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + // TODO + va_end(ap); +} + +SERVER_EXPORT void jack_info(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + // TODO + va_end(ap); +} + +SERVER_EXPORT void jack_log(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + // TODO + va_end(ap); +} + +//#endif diff --git a/common/jack/net.h b/common/jack/net.h new file mode 100644 index 00000000..c8671608 --- /dev/null +++ b/common/jack/net.h @@ -0,0 +1,300 @@ +/* + Copyright (C) 2009 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __net_h__ +#define __net_h__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include + +#define DEFAULT_MULTICAST_IP "225.3.19.154" +#define DEFAULT_PORT 19000 +#define DEFAULT_MTU 1500 +#define MASTER_NAME_SIZE 256 + +#define SOCKET_ERROR -1 + + enum JackNetMode { + + JackFastMode = 'f', + JackNormalMode = 'n', + JackSlowMode = 's', +}; + +typedef struct { + + int audio_input; + int audio_output; + int midi_input; + int midi_ouput; + int mtu; + int time_out; // in millisecond, -1 means in infinite + char mode; + +} jack_slave_t; + +typedef struct { + + jack_nframes_t buffer_size; + jack_nframes_t sample_rate; + char master_name[MASTER_NAME_SIZE]; + +} jack_master_t; + +/** + * jack_net_t is an opaque type. You may only access it using the + * API provided. + */ +typedef struct _jack_net_slave jack_net_slave_t; + + /** + * Open a network connection with the master machine. + * @param ip the multicast address of the master + * @param port the connection port + * @param request a connection request structure + * @param result a connection result structure + * + * @return Opaque net handle if successful or NULL in case of error. + */ +jack_net_slave_t* jack_net_slave_open(const char* ip, int port, const char* name, jack_slave_t* request, jack_master_t* result); + +/** + * Close the network connection with the master machine. + * @param net the network connection to be closed + * + * @return 0 on success, otherwise a non-zero error code + */ +int jack_net_slave_close(jack_net_slave_t* net); + +/** + * Prototype for Process callback. + * @param nframes buffer size + * @param audio_input number of audio inputs + * @param audio_input_buffer an array of audio input buffers + * @param midi_input number of MIDI inputs + * @param midi_input_buffer an array of MIDI input buffers + * @param audio_output number of audio outputs + * @param audio_output_buffer an array of audio output buffers + * @param midi_output number of MIDI outputs + * @param midi_output_buffer an array of MIDI output buffers + * @param arg pointer to a client supplied structure supplied by jack_set_net_process_callback(). + * + * @return zero on success, non-zero on error + */ +typedef int (* JackNetSlaveProcessCallback) (jack_nframes_t buffer_size, + int audio_input, + float** audio_input_buffer, + int midi_input, + void** midi_input_buffer, + int audio_output, + float** audio_output_buffer, + int midi_output, + void** midi_output_buffer, + void* data); + +/** + * Set network process callback. + * @param net the network connection + * @param net_callback the process callback + * @param arg pointer to a client supplied structure + * + * @return 0 on success, otherwise a non-zero error code + */ +int jack_set_net_slave_process_callback(jack_net_slave_t * net, JackNetSlaveProcessCallback net_callback, void *arg); + +/** + * Start processing thread, the net_callback will start to be called. + * @param net the network connection + * + * @return 0 on success, otherwise a non-zero error code + */ +int jack_net_slave_activate(jack_net_slave_t* net); + +/** + * Stop processing thread. + * @param net the network connection + * + * @return 0 on success, otherwise a non-zero error code + */ +int jack_net_slave_deactivate(jack_net_slave_t* net); + +/** + * Prototype for BufferSize callback. + * @param nframes buffer size + * @param arg pointer to a client supplied structure supplied by jack_set_net_buffer_size_callback(). + * + * @return zero on success, non-zero on error + */ +typedef int (*JackNetSlaveBufferSizeCallback)(jack_nframes_t nframes, void *arg); + +/** + * Prototype for SampleRate callback + * @param nframes sample rate + * @param arg pointer to a client supplied structure supplied by jack_set_net_sample_rate_callback(). + * + * @return zero on success, non-zero on error + */ +typedef int (*JackNetSlaveSampleRateCallback)(jack_nframes_t nframes, void *arg); + +/** + * Set network buffer size callback. + * @param net the network connection + * @param bufsize_callback the buffer size callback + * @param arg pointer to a client supplied structure + * + * @return 0 on success, otherwise a non-zero error code + */ +int jack_set_net_slave_buffer_size_callback(jack_net_slave_t *net, JackNetSlaveBufferSizeCallback bufsize_callback, void *arg); + +/** + * Set network sample rate callback. + * @param net the network connection + * @param samplerate_callback the sample rate callback + * @param arg pointer to a client supplied structure + * + * @return 0 on success, otherwise a non-zero error code + */ +int jack_set_net_slave_sample_rate_callback(jack_net_slave_t *net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg); + +/** + * Prototype for server Shutdown callback (if not set, the client will just restart, waiting for an available master again.) + * @param arg pointer to a client supplied structure supplied by jack_set_net_shutdown_callback(). + */ +typedef void (*JackNetSlaveShutdownCallback)(void* data); + +/** + * Set network shutdown callback. + * @param net the network connection + * @param shutdown_callback the shutdown callback + * @param arg pointer to a client supplied structure + * + * @return 0 on success, otherwise a non-zero error code + */ +int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, JackNetSlaveShutdownCallback shutdown_callback, void *arg); + +/** + * jack_net_t is an opaque type. You may only access it using the + * API provided. + */ +typedef struct _jack_net_master jack_net_master_t; + + /** + * Open a network connection with the slave machine. + * @param ip the multicast address of the master + * @param port the connection port + * @param request a connection request structure + * @param result a connection result structure + * + * @return Opaque net handle if successful or NULL in case of error. + */ +jack_net_master_t* jack_net_master_open(const char* ip, int port, const char* name, jack_master_t* request, jack_slave_t* result); + +/** + * Close the network connection with the master machine. + * @param net the network connection to be closed + * + * @return 0 on success, otherwise a non-zero error code + */ +int jack_net_master_close(jack_net_master_t* net); + +/** + * Receive sync and data from the network + * @param net the network connection + * @param audio_input number of audio inputs + * @param audio_input_buffer an array of audio input buffers + * @param midi_input number of MIDI inputs + * @param midi_input_buffer an array of MIDI input buffers + * + * @return zero on success, non-zero on error + */ +int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer); + +/** + * Send sync and data to the network + * @param net the network connection + * @param audio_output number of audio ouputs + * @param audio_output_buffer an array of audio output buffers + * @param midi_output number of MIDI ouputs + * @param midi_output_buffer an array of MIDI output buffers + * + * @return zero on success, non-zero on error + */ +int jack_net_master_send(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer); + +// Experimental Adapter API + +/** + * jack_adapter_t is an opaque type. You may only access it using the + * API provided. + */ +typedef struct _jack_adapter jack_adapter_t; + +/** + * Create an adapter. + * + * @return 0 on success, otherwise a non-zero error code + */ +jack_adapter_t* jack_create_adapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate); + +/** + * Destroy an adapter. + * + * @return 0 on success, otherwise a non-zero error code + */ +int jack_destroy_adapter(jack_adapter_t* adapter); + +/** + * Push input to ringbuffer + * + * @return 0 on success, otherwise a non-zero error code + */ +int jack_adapter_push_input(jack_adapter_t * adapter, int channels, float** buffers); + +/** + * Pull input from ringbuffer + * + * @return 0 on success, otherwise a non-zero error code + */ +int jack_adapter_pull_input(jack_adapter_t * adapter, int channels, float** buffers); + +/** + * Push output to ringbuffer + * + * @return error code. + */ +int jack_adapter_push_output(jack_adapter_t * adapter, int channels, float** buffers); + +/** + * Pull output from ringbuffer + * + * @return 0 on success, otherwise a non-zero error code + */ +int jack_adapter_pull_output(jack_adapter_t * adapter, int channels, float** buffers); + + +#ifdef __cplusplus +} +#endif + +#endif /* __net_h__ */ diff --git a/common/wscript b/common/wscript index 8c576a15..df784d79 100644 --- a/common/wscript +++ b/common/wscript @@ -173,6 +173,31 @@ def build(bld): if bld.env['IS_SUN']: serverlib.env.append_value("LINKFLAGS", "-lnsl -lsocket") + netlib = bld.new_task_gen('cxx', 'shlib') + netlib.features.append('cc') + netlib.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] + netlib.includes = includes + netlib.name = 'netlib' + netlib.target = 'jacknet' + netlib.uselib = uselib + netlib.install_path = '${LIBDIR}' + netlib.source = ['JackNetAPI.cpp', 'JackNetInterface.cpp', 'JackNetTool.cpp', 'JackAudioAdapterInterface.cpp', 'JackResampler.cpp', 'ringbuffer.c'] + + if bld.env['IS_LINUX']: + netlib.source += ['./posix/JackNetUnixSocket.cpp','./posix/JackPosixThread.cpp'] + netlib.env.append_value("CPPFLAGS", "-fvisibility=hidden") + + if bld.env['IS_SUN']: + netlib.source += ['./posix/JackNetUnixSocket.cpp','./posix/JackPosixThread.cpp'] + netlib.env.append_value("CPPFLAGS", "-fvisibility=hidden") + + + if bld.env['IS_MACOSX']: + netlib.source += ['../posix/JackNetUnixSocket.cpp','../posix/JackPosixThread.cpp', '../macosx/JackMachThread.cpp', '../macosx/JackMachTime.c'] + netlib.env.append_value("LINKFLAGS", "-framework CoreAudio -single_module") + + netlib.vnum = bld.env['JACK_API_VERSION'] + clientlib = bld.new_task_gen('cxx', 'shlib') clientlib.features.append('cc') clientlib.defines = 'HAVE_CONFIG_H' diff --git a/example-clients/netmaster.c b/example-clients/netmaster.c new file mode 100644 index 00000000..863715df --- /dev/null +++ b/example-clients/netmaster.c @@ -0,0 +1,165 @@ +/* + Copyright (C) 2009 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. +*/ + +#include +#include +#include +#ifndef WIN32 +#include +#endif +#include +#include +#include +#include + +#include + +jack_net_master_t* net; + +#define BUFFER_SIZE 512 +#define SAMPLE_RATE 44100 + +static void signal_handler(int sig) +{ + jack_net_master_close(net); + fprintf(stderr, "signal received, exiting ...\n"); + exit(0); +} + +static void +usage () +{ + fprintf (stderr, "\n" +"usage: jack_net_master \n" +" [ -b buffer size (default = %d) ]\n" +" [ -r sample rate (default = %d) ]\n" +" [ -a hostname (default = %s) ]\n" +" [ -p port (default = %d) ]\n", BUFFER_SIZE, SAMPLE_RATE, DEFAULT_MULTICAST_IP, DEFAULT_PORT); +} + +int +main (int argc, char *argv[]) +{ + int buffer_size = BUFFER_SIZE; + int sample_rate = SAMPLE_RATE; + int port = DEFAULT_PORT; + char* multicast_ip = DEFAULT_MULTICAST_IP; + const char *options = "b:r:a:p:"; + int option_index; + int opt; + + struct option long_options[] = + { + {"buffer size", 1, 0, 'b'}, + {"sample rate", 1, 0, 'r'}, + {"hostname", 1, 0, 'a'}, + {"port", 1, 0, 'p'}, + {0, 0, 0, 0} + }; + + while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) { + + switch (opt) { + + case 'b': + buffer_size = atoi(optarg); + break; + + case 'r': + sample_rate = atoi(optarg); + break; + + case 'a': + multicast_ip = strdup(optarg); + break; + + case 'p': + port = atoi(optarg); + break; + + case 'h': + usage(); + return -1; + } + } + + int i; + jack_master_t request = { buffer_size, sample_rate, "master" }; + jack_slave_t result; + float** audio_input_buffer; + float** audio_output_buffer; + int wait_usec = (int) ((((float)buffer_size) * 1000000) / ((float)sample_rate)); + + printf("Waiting for a slave...\n"); + + if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "net_master", &request, &result)) == 0) { + fprintf(stderr, "jack server not running?\n"); + return 1; + } + + /* install a signal handler to properly quits jack client */ +#ifdef WIN32 + signal(SIGINT, signal_handler); + signal(SIGABRT, signal_handler); + signal(SIGTERM, signal_handler); +#else + signal(SIGQUIT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGHUP, signal_handler); + signal(SIGINT, signal_handler); +#endif + + // Allocate buffers + audio_input_buffer = calloc(result.audio_input, sizeof(float*)); + for (i = 0; i < result.audio_input; i++) { + audio_input_buffer[i] = calloc(buffer_size, sizeof(float)); + } + + audio_output_buffer = calloc(result.audio_output, sizeof(float*)); + for (i = 0; i < result.audio_output; i++) { + audio_output_buffer[i] = calloc(buffer_size, sizeof(float)); + } + + // Run until interrupted + while (1) { + + // Copy input to output + for (i = 0; i < result.audio_input; i++) { + memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); + } + + jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL); + jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL); + usleep(wait_usec); + }; + + // Wait for application end + jack_net_master_close(net); + + for (i = 0; i < result.audio_input; i++) { + free(audio_input_buffer[i]); + } + free(audio_input_buffer); + + for (i = 0; i < result.audio_output; i++) { + free(audio_output_buffer[i]); + } + free(audio_output_buffer); + + exit (0); +} diff --git a/example-clients/netslave.c b/example-clients/netslave.c new file mode 100644 index 00000000..165e334f --- /dev/null +++ b/example-clients/netslave.c @@ -0,0 +1,160 @@ +/* + Copyright (C) 2009 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. +*/ + +#include +#include +#include +#ifndef WIN32 +#include +#endif +#include +#include +#include +#include + +#include + +jack_net_slave_t* net; + +static void signal_handler(int sig) +{ + jack_net_slave_close(net); + fprintf(stderr, "signal received, exiting ...\n"); + exit(0); +} + +static void +usage () +{ + fprintf (stderr, "\n" +"usage: jack_net_slave \n" +" [ -C capture channels (default = 2)]\n" +" [ -P playback channels (default = 2) ]\n" +" [ -a hostname (default = %s) ]\n" +" [ -p port (default = %d)]\n", DEFAULT_MULTICAST_IP, DEFAULT_PORT); +} + + +static int net_process(jack_nframes_t buffer_size, + int audio_input, + float** audio_input_buffer, + int midi_input, + void** midi_input_buffer, + int audio_output, + float** audio_output_buffer, + int midi_output, + void** midi_output_buffer, + void* data) +{ + int i; + + // Copy input to output + for (i = 0; i < audio_input; i++) { + memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); + } + return 0; +} + +int +main (int argc, char *argv[]) +{ + int audio_input = 2; + int audio_output = 2; + int port = DEFAULT_PORT; + char* multicast_ip = DEFAULT_MULTICAST_IP; + const char *options = "C:P:a:p:"; + int option_index; + int opt; + + struct option long_options[] = + { + {"audio input", 1, 0, 'C'}, + {"audio output", 1, 0, 'P'}, + {"hostname", 1, 0, 'a'}, + {"port", 1, 0, 'p'}, + {0, 0, 0, 0} + }; + + while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) { + + switch (opt) { + + case 'C': + audio_input = atoi(optarg); + break; + + case 'P': + audio_output = atoi(optarg); + break; + + case 'a': + multicast_ip = strdup(optarg); + break; + + case 'p': + port = atoi(optarg); + break; + + case 'h': + usage(); + return -1; + } + } + + jack_slave_t request = { audio_input, audio_output, 0, 0, DEFAULT_MTU, -1, JackSlowMode }; + jack_master_t result; + + printf("Waiting for a master...\n"); + + if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "net_slave", &request, &result)) == 0) { + fprintf(stderr, "jack server not running?\n"); + return 1; + } + + jack_set_net_slave_process_callback(net, net_process, NULL); + if (jack_net_slave_activate(net) != 0) { + fprintf(stderr, "Cannot sactivate client\n"); + return 1; + } + + /* install a signal handler to properly quits jack client */ +#ifdef WIN32 + signal(SIGINT, signal_handler); + signal(SIGABRT, signal_handler); + signal(SIGTERM, signal_handler); +#else + signal(SIGQUIT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGHUP, signal_handler); + signal(SIGINT, signal_handler); +#endif + + /* run until interrupted */ + while (1) { + #ifdef WIN32 + Sleep(1000); + #else + sleep(1); + #endif + }; + + // Wait for application end + jack_net_slave_deactivate(net); + jack_net_slave_close(net); + exit (0); +} diff --git a/example-clients/wscript b/example-clients/wscript index 03886af4..1a5dcd69 100644 --- a/example-clients/wscript +++ b/example-clients/wscript @@ -21,6 +21,8 @@ example_programs = { 'jack_thru' : 'thru_client.c', 'jack_cpu_load' : 'cpu_load.c', 'jack_server_control' : 'server_control.cpp', + 'jack_net_slave' : 'netslave.c', + 'jack_net_master' : 'netmaster.c', } example_libs = { @@ -69,8 +71,13 @@ def build(bld): prog.env.append_value("LINKFLAGS", "-lm") if example_program == 'jack_server_control': prog.uselib_local = 'serverlib' + elif example_program == 'jack_net_slave': + prog.uselib_local = 'netlib' + elif example_program == 'jack_net_master': + prog.uselib_local = 'netlib' else: - prog.uselib_local = 'clientlib' + prog.uselib_local = 'clientlib' + prog.target = example_program #if bld.env['BUILD_EXAMPLE_CLIENT_TRANSPORT'] From f40ead1ba0394aedd97b237df2be4e9bbb4beb37 Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 24 Feb 2009 12:25:15 +0000 Subject: [PATCH 003/472] Now running on Linux. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3338 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetAPI.cpp | 11 +---------- common/wscript | 4 ++-- example-clients/netmaster.c | 2 ++ example-clients/netslave.c | 2 ++ 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 300357ac..7e41e8c8 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -1004,26 +1004,17 @@ SERVER_EXPORT int jack_adapter_pull_output(jack_adapter_t * adapter, int channel SERVER_EXPORT void jack_error(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); // TODO - va_end(ap); } SERVER_EXPORT void jack_info(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - // TODO - va_end(ap); + // TODO } SERVER_EXPORT void jack_log(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); // TODO - va_end(ap); } //#endif diff --git a/common/wscript b/common/wscript index df784d79..026ec5c8 100644 --- a/common/wscript +++ b/common/wscript @@ -184,11 +184,11 @@ def build(bld): netlib.source = ['JackNetAPI.cpp', 'JackNetInterface.cpp', 'JackNetTool.cpp', 'JackAudioAdapterInterface.cpp', 'JackResampler.cpp', 'ringbuffer.c'] if bld.env['IS_LINUX']: - netlib.source += ['./posix/JackNetUnixSocket.cpp','./posix/JackPosixThread.cpp'] + netlib.source += ['../posix/JackNetUnixSocket.cpp','../posix/JackPosixThread.cpp', '../linux/JackLinuxTime.c'] netlib.env.append_value("CPPFLAGS", "-fvisibility=hidden") if bld.env['IS_SUN']: - netlib.source += ['./posix/JackNetUnixSocket.cpp','./posix/JackPosixThread.cpp'] + netlib.source += ['../posix/JackNetUnixSocket.cpp','../posix/JackPosixThread.cpp', '../solaris/JackSolarisTime.c'] netlib.env.append_value("CPPFLAGS", "-fvisibility=hidden") diff --git a/example-clients/netmaster.c b/example-clients/netmaster.c index 863715df..ebfdfdb6 100644 --- a/example-clients/netmaster.c +++ b/example-clients/netmaster.c @@ -111,6 +111,8 @@ main (int argc, char *argv[]) fprintf(stderr, "jack server not running?\n"); return 1; } + + printf("Slave is running...\n"); /* install a signal handler to properly quits jack client */ #ifdef WIN32 diff --git a/example-clients/netslave.c b/example-clients/netslave.c index 165e334f..7c83ece0 100644 --- a/example-clients/netslave.c +++ b/example-clients/netslave.c @@ -126,6 +126,8 @@ main (int argc, char *argv[]) return 1; } + printf("Slave is found and running...\n"); + jack_set_net_slave_process_callback(net, net_process, NULL); if (jack_net_slave_activate(net) != 0) { fprintf(stderr, "Cannot sactivate client\n"); From 07d8c8f32b64175b35475dfc27374fe8c28b361c Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 24 Feb 2009 12:42:28 +0000 Subject: [PATCH 004/472] Add sources and project for iPhone. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3339 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 1 + macosx/JackMachThread.cpp | 15 + macosx/JackMachThread.h | 2 + macosx/coreaudio/JackAudioQueueAdapter.cpp | 162 ++++ macosx/coreaudio/JackAudioQueueAdapter.h | 85 ++ macosx/iphone/Info.plist | 30 + macosx/iphone/MainWindow.xib | 180 +++++ macosx/iphone/freeverb.mm | 730 ++++++++++++++++++ .../iPhoneNet.xcodeproj/project.pbxproj | 705 +++++++++++++++++ macosx/iphone/iPhoneNetAppDelegate.h | 23 + macosx/iphone/iPhoneNetAppDelegate.m | 32 + macosx/iphone/iPhoneNet_Prefix.pch | 8 + macosx/iphone/main_master.mm | 105 +++ macosx/iphone/main_slave.mm | 66 ++ 14 files changed, 2144 insertions(+) create mode 100644 macosx/coreaudio/JackAudioQueueAdapter.cpp create mode 100644 macosx/coreaudio/JackAudioQueueAdapter.h create mode 100644 macosx/iphone/Info.plist create mode 100644 macosx/iphone/MainWindow.xib create mode 100644 macosx/iphone/freeverb.mm create mode 100755 macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj create mode 100644 macosx/iphone/iPhoneNetAppDelegate.h create mode 100644 macosx/iphone/iPhoneNetAppDelegate.m create mode 100644 macosx/iphone/iPhoneNet_Prefix.pch create mode 100644 macosx/iphone/main_master.mm create mode 100644 macosx/iphone/main_slave.mm diff --git a/ChangeLog b/ChangeLog index 632cec72..eda5a137 100644 --- a/ChangeLog +++ b/ChangeLog @@ -26,6 +26,7 @@ Michael Voigt 2009-02-24 Stephane Letz * New libjacknet library with net.h and JackNetAPI.cpp files. New netmaster.c and netmaster.c examples. + * Add iPhone sources and project. 2009-02-23 Stephane Letz diff --git a/macosx/JackMachThread.cpp b/macosx/JackMachThread.cpp index 2d809c2a..7b45d239 100644 --- a/macosx/JackMachThread.cpp +++ b/macosx/JackMachThread.cpp @@ -18,6 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + #include "JackMachThread.h" #include "JackError.h" @@ -30,9 +31,16 @@ int JackMachThread::SetThreadToPriority(pthread_t thread, UInt32 inPriority, Boo // REAL-TIME / TIME-CONSTRAINT THREAD thread_time_constraint_policy_data_t theTCPolicy; +#ifdef TARGET_OS_IPHONE + theTCPolicy.period = 0; + theTCPolicy.computation = 0; + theTCPolicy.constraint = 0; +#else theTCPolicy.period = AudioConvertNanosToHostTime(period); theTCPolicy.computation = AudioConvertNanosToHostTime(computation); theTCPolicy.constraint = AudioConvertNanosToHostTime(constraint); + +#endif theTCPolicy.preemptible = true; kern_return_t res = thread_policy_set(pthread_mach_thread_np(thread), THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t) & theTCPolicy, THREAD_TIME_CONSTRAINT_POLICY_COUNT); jack_log("JackMachThread::thread_policy_set res = %ld", res); @@ -130,9 +138,16 @@ int JackMachThread::GetParams(UInt64* period, UInt64* computation, UInt64* const &count, &get_default); if (res == KERN_SUCCESS) { + #ifdef TARGET_OS_IPHONE + *period = 0; + *computation = 0; + *constraint = 0; + #else *period = AudioConvertHostTimeToNanos(theTCPolicy.period); *computation = AudioConvertHostTimeToNanos(theTCPolicy.computation); *constraint = AudioConvertHostTimeToNanos(theTCPolicy.constraint); + #endif + jack_log("JackMachThread::GetParams period = %ld computation = %ld constraint = %ld", long(*period / 1000.0f), long(*computation / 1000.0f), long(*constraint / 1000.0f)); return 0; } else { diff --git a/macosx/JackMachThread.h b/macosx/JackMachThread.h index 4e17959b..4dc8d509 100644 --- a/macosx/JackMachThread.h +++ b/macosx/JackMachThread.h @@ -66,7 +66,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include +#ifndef TARGET_OS_IPHONE #include +#endif #define THREAD_SET_PRIORITY 0 #define THREAD_SCHEDULED_PRIORITY 1 diff --git a/macosx/coreaudio/JackAudioQueueAdapter.cpp b/macosx/coreaudio/JackAudioQueueAdapter.cpp new file mode 100644 index 00000000..3cb9e9af --- /dev/null +++ b/macosx/coreaudio/JackAudioQueueAdapter.cpp @@ -0,0 +1,162 @@ +/* +Copyright (C) 2009 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. + +*/ + +#include "JackAudioQueueAdapter.h" +#include + +namespace Jack +{ + +// NOT YET WORKING.... + +static void Print4CharCode(char* msg, long c) +{ + UInt32 __4CC_number = (c); + char __4CC_string[5]; + *((SInt32*)__4CC_string) = EndianU32_NtoB(__4CC_number); + __4CC_string[4] = 0; + //printf("%s'%s'\n", (msg), __4CC_string); + snprintf(__4CC_string, 5, "%s'%s'\n", (msg), __4CC_string); +} + +void JackAudioQueueAdapter::CaptureCallback(void * inUserData, + AudioQueueRef inAQ, + AudioQueueBufferRef inBuffer, + const AudioTimeStamp * inStartTime, + UInt32 inNumPackets, + const AudioStreamPacketDescription *inPacketDesc) +{ + JackAudioQueueAdapter* adapter = (JackAudioQueueAdapter*)inUserData; + + printf("JackAudioQueueAdapter::CaptureCallback\n"); + + if (AudioQueueEnqueueBuffer(adapter->fCaptureQueue, inBuffer, 0, NULL) != noErr) { + printf("JackAudioQueueAdapter::CaptureCallback error\n"); + } + + // Use the adapter to communicate with audio callback + // jack_adapter_push_input(adapter, audio_output, audio_output_buffer); +} + +void JackAudioQueueAdapter::PlaybackCallback(void * inUserData, + AudioQueueRef inAQ, + AudioQueueBufferRef inCompleteAQBuffer) +{ + JackAudioQueueAdapter* adapter = (JackAudioQueueAdapter*)inUserData; + + printf("JackAudioQueueAdapter::PlaybackCallback\n"); + + if (AudioQueueEnqueueBuffer(adapter->fPlaybackQueue, inCompleteAQBuffer, 0, &adapter->fPlaybackPacketDescs) != noErr) { + printf("JackAudioQueueAdapter::PlaybackCallback error\n"); + } + + + // Use the adapter to communicate with audio callback + // jack_adapter_pull_output(adapter, audio_input, audio_input_buffer); +} + + +JackAudioQueueAdapter::JackAudioQueueAdapter(int inchan, int outchan, jack_nframes_t buffer_size, jack_nframes_t sample_rate, jack_adapter_t* adapter) + :fCaptureChannels(inchan), fPlaybackChannels(outchan), fBufferSize(buffer_size), fSampleRate(sample_rate), fAdapter(adapter) +{} + +JackAudioQueueAdapter::~JackAudioQueueAdapter() +{} + +int JackAudioQueueAdapter::Open() +{ + OSStatus err; + AudioStreamBasicDescription captureDataFormat; + + /* + captureDataFormat.mSampleRate = fSampleRate; + captureDataFormat.mFormatID = kAudioFormatLinearPCM; + //captureDataFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; + captureDataFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked; + captureDataFormat.mBytesPerPacket = sizeof(float); + captureDataFormat.mFramesPerPacket = 1; + captureDataFormat.mBytesPerFrame = sizeof(float); + captureDataFormat.mChannelsPerFrame = fCaptureChannels; + captureDataFormat.mBitsPerChannel = 32; + */ + + captureDataFormat.mSampleRate = fSampleRate; + captureDataFormat.mFormatID = kAudioFormatLinearPCM; + captureDataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; + captureDataFormat.mBytesPerPacket = 4; + captureDataFormat.mFramesPerPacket = 1; // this means each packet in the AQ has two samples, one for each channel -> 4 bytes/frame/packet + captureDataFormat.mBytesPerFrame = 4; + captureDataFormat.mChannelsPerFrame = 2; + captureDataFormat.mBitsPerChannel = 16; + + if ((err = AudioQueueNewInput(&captureDataFormat, CaptureCallback, this, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &fCaptureQueue)) != noErr) { + Print4CharCode("error code : unknown", err); + return -1; + } + + //AudioQueueSetProperty(fCaptureQueue, kAudioQueueProperty_MagicCookie, cookie, size) + //AudioQueueSetProperty(fCaptureQueue, kAudioQueueProperty_ChannelLayout, acl, size + + AudioStreamBasicDescription playbackDataFormat; + + playbackDataFormat.mSampleRate = fSampleRate; + playbackDataFormat.mFormatID = kAudioFormatLinearPCM; + playbackDataFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; + playbackDataFormat.mBytesPerPacket = sizeof(float); + playbackDataFormat.mFramesPerPacket = 1; + playbackDataFormat.mBytesPerFrame = sizeof(float); + playbackDataFormat.mChannelsPerFrame = fPlaybackChannels; + playbackDataFormat.mBitsPerChannel = 32; + + if ((err = AudioQueueNewOutput(&playbackDataFormat, PlaybackCallback, this, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &fPlaybackQueue)) != noErr) { + Print4CharCode("error code : unknown", err); + return -1; + } + + + //AudioQueueSetProperty(fPlaybackQueue, kAudioQueueProperty_MagicCookie, cookie, size); + //AudioQueueSetProperty(fPlaybackQueue, kAudioQueueProperty_ChannelLayout, acl, size); + //AudioQueueSetParameter(fPlaybackQueue, kAudioQueueParam_Volume, volume + + //AudioQueueStart(fCaptureQueue, NULL); + AudioQueueStart(fPlaybackQueue, NULL); + + return 0; +} +int JackAudioQueueAdapter::Close() +{ + AudioQueueStop(fCaptureQueue, true); + AudioQueueStop(fPlaybackQueue, true); + + AudioQueueDispose(fCaptureQueue, true); + AudioQueueDispose(fPlaybackQueue, true); + return 0; +} + +int JackAudioQueueAdapter::SetSampleRate(jack_nframes_t sample_rate) +{ + return 0; +} + +int JackAudioQueueAdapter::SetBufferSize(jack_nframes_t buffer_size) +{ + return 0; +} + +}; diff --git a/macosx/coreaudio/JackAudioQueueAdapter.h b/macosx/coreaudio/JackAudioQueueAdapter.h new file mode 100644 index 00000000..1de09959 --- /dev/null +++ b/macosx/coreaudio/JackAudioQueueAdapter.h @@ -0,0 +1,85 @@ +/* +Copyright (C) 2009 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 __JackAudioQueueAdapter__ +#define __JackAudioQueueAdapter__ + +#include +#include + +#include + +namespace Jack +{ + +/*! +\brief Audio adapter using AudioQueue API. +*/ + +static const int kNumberBuffers = 3; + +class JackAudioQueueAdapter +{ + + private: + + AudioQueueRef fCaptureQueue; + AudioQueueBufferRef fCaptureQueueBuffers[kNumberBuffers]; + + AudioQueueRef fPlaybackQueue; + AudioQueueBufferRef fPlaybackQueueBuffers[kNumberBuffers]; + AudioStreamPacketDescription fPlaybackPacketDescs; + + + jack_nframes_t fBufferSize; + jack_nframes_t fSampleRate; + + int fCaptureChannels; + int fPlaybackChannels; + + jack_adapter_t* fAdapter; + + static void CaptureCallback(void * inUserData, + AudioQueueRef inAQ, + AudioQueueBufferRef inBuffer, + const AudioTimeStamp * inStartTime, + UInt32 inNumPackets, + const AudioStreamPacketDescription *inPacketDesc); + + + static void PlaybackCallback(void * inUserData, + AudioQueueRef inAQ, + AudioQueueBufferRef inCompleteAQBuffer); + + public: + + JackAudioQueueAdapter(int inchan, int outchan, jack_nframes_t buffer_size, jack_nframes_t sample_rate, jack_adapter_t* adapter); + ~JackAudioQueueAdapter(); + + virtual int Open(); + virtual int Close(); + + virtual int SetSampleRate(jack_nframes_t sample_rate); + virtual int SetBufferSize(jack_nframes_t buffer_size); + +}; + +} + +#endif diff --git a/macosx/iphone/Info.plist b/macosx/iphone/Info.plist new file mode 100644 index 00000000..fdf83406 --- /dev/null +++ b/macosx/iphone/Info.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/macosx/iphone/MainWindow.xib b/macosx/iphone/MainWindow.xib new file mode 100644 index 00000000..175cb7bd --- /dev/null +++ b/macosx/iphone/MainWindow.xib @@ -0,0 +1,180 @@ + + + + 528 + 9E17 + 672 + 949.33 + 352.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + {320, 480} + + + 1 + MSAxIDEAA + + NO + NO + + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{438, 320}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + iPhoneNetAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 9 + + + + YES + + iPhoneNetAppDelegate + NSObject + + window + UIWindow + + + IBProjectSource + Classes/iPhoneNetAppDelegate.h + + + + iPhoneNetAppDelegate + NSObject + + IBUserSource + + + + + + 0 + iPhoneNet.xcodeproj + 3 + + diff --git a/macosx/iphone/freeverb.mm b/macosx/iphone/freeverb.mm new file mode 100644 index 00000000..9b7832f7 --- /dev/null +++ b/macosx/iphone/freeverb.mm @@ -0,0 +1,730 @@ +//----------------------------------------------------- +// name: "freeverb" +// version: "1.0" +// author: "Grame" +// license: "BSD" +// copyright: "(c)GRAME 2006" +// +// Code generated with Faust 0.9.9.5b2 (http://faust.grame.fr) +//----------------------------------------------------- +/* link with */ + +/* link with */ +#include +/* link with */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +// On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero) +// flags to avoid costly denormals +#ifdef __SSE__ + #include + #ifdef __SSE2__ + #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040) + #else + #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000) + #endif +#else + #define AVOIDDENORMALS +#endif + +//#define BENCHMARKMODE + +struct Meta : map +{ + void declare (const char* key, const char* value) { (*this)[key]=value; } +}; + + +#define max(x,y) (((x)>(y)) ? (x) : (y)) +#define min(x,y) (((x)<(y)) ? (x) : (y)) + +inline int lsr (int x, int n) { return int(((unsigned int)x) >> n); } +inline int int2pow2 (int x) { int r=0; while ((1< fPrefix; + map fKeyParam; + + void addOption(const char* label, float* zone, float min, float max) + { + string fullname = fPrefix.top() + label; + fKeyParam.insert(make_pair(fullname, param(zone, min, max))); + } + + void openAnyBox(const char* label) + { + string prefix; + + if (label && label[0]) { + prefix = fPrefix.top() + "-" + label; + } else { + prefix = fPrefix.top(); + } + fPrefix.push(prefix); + } + +public: + + CMDUI(int argc, char *argv[]) : UI(), fArgc(argc), fArgv(argv) { fPrefix.push("--"); } + virtual ~CMDUI() {} + + virtual void addButton(const char* label, float* zone) {}; + virtual void addToggleButton(const char* label, float* zone) {}; + virtual void addCheckButton(const char* label, float* zone) {}; + + virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) + { + addOption(label,zone,min,max); + } + + virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) + { + addOption(label,zone,min,max); + } + + virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) + { + addOption(label,zone,min,max); + } + + // -- passive widgets + + virtual void addNumDisplay(const char* label, float* zone, int precision) {} + virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) {} + virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) {} + virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) {} + + virtual void openFrameBox(const char* label) { openAnyBox(label); } + virtual void openTabBox(const char* label) { openAnyBox(label); } + virtual void openHorizontalBox(const char* label) { openAnyBox(label); } + virtual void openVerticalBox(const char* label) { openAnyBox(label); } + + virtual void closeBox() { fPrefix.pop(); } + + virtual void show() {} + virtual void run() + { + char c; + printf("Type 'q' to quit\n"); + while ((c = getchar()) != 'q') { + sleep(1); + } + } + + void print() + { + map::iterator i; + cout << fArgc << "\n"; + cout << fArgv[0] << " option list : "; + for (i = fKeyParam.begin(); i != fKeyParam.end(); i++) { + cout << "[ " << i->first << " " << i->second.fMin << ".." << i->second.fMax <<" ] "; + } + } + + void process_command() + { + map::iterator p; + for (int i = 1; i < fArgc; i++) { + if (fArgv[i][0] == '-') { + p = fKeyParam.find(fArgv[i]); + if (p == fKeyParam.end()) { + cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n"; + print(); + exit(1); + } + char* end; + *(p->second.fZone) = float(strtod(fArgv[i+1], &end)); + i++; + } + } + } + + void process_init() + { + map::iterator p; + for (int i = 1; i < fArgc; i++) { + if (fArgv[i][0] == '-') { + p = fKeyParam.find(fArgv[i]); + if (p == fKeyParam.end()) { + cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n"; + exit(1); + } + char* end; + *(p->second.fZone) = float(strtod(fArgv[i+1], &end)); + i++; + } + } + } +}; + + +//---------------------------------------------------------------- +// Signal processor definition +//---------------------------------------------------------------- + +class dsp { + protected: + int fSamplingFreq; + public: + dsp() {} + virtual ~dsp() {} + + virtual int getNumInputs() = 0; + virtual int getNumOutputs() = 0; + virtual void buildUserInterface(UI* interface) = 0; + virtual void init(int samplingRate) = 0; + virtual void compute(int len, float** inputs, float** outputs) = 0; + virtual void conclude() {} +}; + + +//---------------------------------------------------------------------------- +// FAUST generated code +//---------------------------------------------------------------------------- + + +class mydsp : public dsp { + private: + float fslider0; + float fRec9[2]; + float fslider1; + int IOTA; + float fVec0[2048]; + float fRec8[2]; + float fRec11[2]; + float fVec1[2048]; + float fRec10[2]; + float fRec13[2]; + float fVec2[2048]; + float fRec12[2]; + float fRec15[2]; + float fVec3[2048]; + float fRec14[2]; + float fRec17[2]; + float fVec4[2048]; + float fRec16[2]; + float fRec19[2]; + float fVec5[2048]; + float fRec18[2]; + float fRec21[2]; + float fVec6[2048]; + float fRec20[2]; + float fRec23[2]; + float fVec7[2048]; + float fRec22[2]; + float fVec8[1024]; + float fRec6[2]; + float fVec9[512]; + float fRec4[2]; + float fVec10[512]; + float fRec2[2]; + float fVec11[256]; + float fRec0[2]; + float fslider2; + float fRec33[2]; + float fVec12[2048]; + float fRec32[2]; + float fRec35[2]; + float fVec13[2048]; + float fRec34[2]; + float fRec37[2]; + float fVec14[2048]; + float fRec36[2]; + float fRec39[2]; + float fVec15[2048]; + float fRec38[2]; + float fRec41[2]; + float fVec16[2048]; + float fRec40[2]; + float fRec43[2]; + float fVec17[2048]; + float fRec42[2]; + float fRec45[2]; + float fVec18[2048]; + float fRec44[2]; + float fRec47[2]; + float fVec19[2048]; + float fRec46[2]; + float fVec20[1024]; + float fRec30[2]; + float fVec21[512]; + float fRec28[2]; + float fVec22[512]; + float fRec26[2]; + float fVec23[256]; + float fRec24[2]; + public: + static void metadata(Meta* m) { + m->declare("name", "freeverb"); + m->declare("version", "1.0"); + m->declare("author", "Grame"); + m->declare("license", "BSD"); + m->declare("copyright", "(c)GRAME 2006"); + } + + virtual int getNumInputs() { return 2; } + virtual int getNumOutputs() { return 2; } + static void classInit(int samplingFreq) { + } + virtual void instanceInit(int samplingFreq) { + fSamplingFreq = samplingFreq; + fslider0 = 0.5f; + for (int i=0; i<2; i++) fRec9[i] = 0; + fslider1 = 0.8f; + IOTA = 0; + for (int i=0; i<2048; i++) fVec0[i] = 0; + for (int i=0; i<2; i++) fRec8[i] = 0; + for (int i=0; i<2; i++) fRec11[i] = 0; + for (int i=0; i<2048; i++) fVec1[i] = 0; + for (int i=0; i<2; i++) fRec10[i] = 0; + for (int i=0; i<2; i++) fRec13[i] = 0; + for (int i=0; i<2048; i++) fVec2[i] = 0; + for (int i=0; i<2; i++) fRec12[i] = 0; + for (int i=0; i<2; i++) fRec15[i] = 0; + for (int i=0; i<2048; i++) fVec3[i] = 0; + for (int i=0; i<2; i++) fRec14[i] = 0; + for (int i=0; i<2; i++) fRec17[i] = 0; + for (int i=0; i<2048; i++) fVec4[i] = 0; + for (int i=0; i<2; i++) fRec16[i] = 0; + for (int i=0; i<2; i++) fRec19[i] = 0; + for (int i=0; i<2048; i++) fVec5[i] = 0; + for (int i=0; i<2; i++) fRec18[i] = 0; + for (int i=0; i<2; i++) fRec21[i] = 0; + for (int i=0; i<2048; i++) fVec6[i] = 0; + for (int i=0; i<2; i++) fRec20[i] = 0; + for (int i=0; i<2; i++) fRec23[i] = 0; + for (int i=0; i<2048; i++) fVec7[i] = 0; + for (int i=0; i<2; i++) fRec22[i] = 0; + for (int i=0; i<1024; i++) fVec8[i] = 0; + for (int i=0; i<2; i++) fRec6[i] = 0; + for (int i=0; i<512; i++) fVec9[i] = 0; + for (int i=0; i<2; i++) fRec4[i] = 0; + for (int i=0; i<512; i++) fVec10[i] = 0; + for (int i=0; i<2; i++) fRec2[i] = 0; + for (int i=0; i<256; i++) fVec11[i] = 0; + for (int i=0; i<2; i++) fRec0[i] = 0; + fslider2 = 0.8f; + for (int i=0; i<2; i++) fRec33[i] = 0; + for (int i=0; i<2048; i++) fVec12[i] = 0; + for (int i=0; i<2; i++) fRec32[i] = 0; + for (int i=0; i<2; i++) fRec35[i] = 0; + for (int i=0; i<2048; i++) fVec13[i] = 0; + for (int i=0; i<2; i++) fRec34[i] = 0; + for (int i=0; i<2; i++) fRec37[i] = 0; + for (int i=0; i<2048; i++) fVec14[i] = 0; + for (int i=0; i<2; i++) fRec36[i] = 0; + for (int i=0; i<2; i++) fRec39[i] = 0; + for (int i=0; i<2048; i++) fVec15[i] = 0; + for (int i=0; i<2; i++) fRec38[i] = 0; + for (int i=0; i<2; i++) fRec41[i] = 0; + for (int i=0; i<2048; i++) fVec16[i] = 0; + for (int i=0; i<2; i++) fRec40[i] = 0; + for (int i=0; i<2; i++) fRec43[i] = 0; + for (int i=0; i<2048; i++) fVec17[i] = 0; + for (int i=0; i<2; i++) fRec42[i] = 0; + for (int i=0; i<2; i++) fRec45[i] = 0; + for (int i=0; i<2048; i++) fVec18[i] = 0; + for (int i=0; i<2; i++) fRec44[i] = 0; + for (int i=0; i<2; i++) fRec47[i] = 0; + for (int i=0; i<2048; i++) fVec19[i] = 0; + for (int i=0; i<2; i++) fRec46[i] = 0; + for (int i=0; i<1024; i++) fVec20[i] = 0; + for (int i=0; i<2; i++) fRec30[i] = 0; + for (int i=0; i<512; i++) fVec21[i] = 0; + for (int i=0; i<2; i++) fRec28[i] = 0; + for (int i=0; i<512; i++) fVec22[i] = 0; + for (int i=0; i<2; i++) fRec26[i] = 0; + for (int i=0; i<256; i++) fVec23[i] = 0; + for (int i=0; i<2; i++) fRec24[i] = 0; + } + virtual void init(int samplingFreq) { + classInit(samplingFreq); + instanceInit(samplingFreq); + } + virtual void buildUserInterface(UI* interface) { + interface->openVerticalBox("Freeverb"); + interface->addHorizontalSlider("Damp", &fslider0, 0.5f, 0.0f, 1.0f, 2.500000e-02f); + interface->addHorizontalSlider("RoomSize", &fslider1, 0.8f, 0.0f, 1.0f, 2.500000e-02f); + interface->addHorizontalSlider("Wet", &fslider2, 0.8f, 0.0f, 1.0f, 2.500000e-02f); + interface->closeBox(); + } + virtual void compute (int count, float** input, float** output) { + float fSlow0 = (0.4f * fslider0); + float fSlow1 = (1 - fSlow0); + float fSlow2 = (0.7f + (0.28f * fslider1)); + float fSlow3 = fslider2; + float fSlow4 = (1 - fSlow3); + float* input0 = input[0]; + float* input1 = input[1]; + float* output0 = output[0]; + float* output1 = output[1]; + for (int i=0; ihi) hi = m; + tot += m; + } + cout << low << ' ' << tot/(mesure-KSKIP) << ' ' << hi << endl; + + } else { + + for (int i = KSKIP+1; ihi) hi = m; + tot += m; + } + cout << low << ' ' << tot/(KMESURE-KSKIP) << ' ' << hi << endl; + + } +} + +#else + +#define STARTMESURE +#define STOPMESURE + +#endif + +static int net_process(jack_nframes_t buffer_size, + int audio_input, + float** audio_input_buffer, + int midi_input, + void** midi_input_buffer, + int audio_output, + float** audio_output_buffer, + int midi_output, + void** midi_output_buffer, + void* data) +{ + AVOIDDENORMALS; + STARTMESURE + DSP.compute(buffer_size, audio_input_buffer, audio_output_buffer); + STOPMESURE + return 0; +} + +/****************************************************************************** +******************************************************************************* + + MAIN PLAY THREAD + +******************************************************************************* +*******************************************************************************/ + +//------------------------------------------------------------------------- +// MAIN +//------------------------------------------------------------------------- + +int main(int argc, char *argv[]) { + + UI* interface = new CMDUI(argc, argv); + jack_net_slave_t* net; + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + gNumInChans = DSP.getNumInputs(); + gNumOutChans = DSP.getNumOutputs(); + + jack_slave_t request = { gNumInChans, gNumOutChans, 0, 0, DEFAULT_MTU, -1, JackSlowMode }; + jack_master_t result; + + if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { + fprintf(stderr, "jack remote server not running ?\n"); + return 1; + } + + jack_set_net_slave_process_callback(net, net_process, NULL); + + // We want to restart (that is "wait for available master" again) + //jack_set_net_shutdown_callback(net, net_shutdown, 0); + + DSP.init(result.sample_rate); + DSP.buildUserInterface(interface); + + if (jack_net_slave_activate(net) != 0) { + fprintf(stderr, "cannot activate net"); + return 1; + } + + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + + // Wait for application end + jack_net_slave_deactivate(net); + jack_net_slave_close(net); + return retVal; +} diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj new file mode 100755 index 00000000..d137323b --- /dev/null +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -0,0 +1,705 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; + 4B0772210F54018C000DC657 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; + 4B0772240F54018C000DC657 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; }; + 4B0772250F54018C000DC657 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93870F49B0E300D3626B /* JackMachTime.c */; }; + 4B0772260F54018C000DC657 /* JackNetAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */; }; + 4B0772270F54018C000DC657 /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */; }; + 4B0772280F54018C000DC657 /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; + 4B0772290F54018C000DC657 /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; + 4B07722A0F54018C000DC657 /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; + 4B07722B0F54018C000DC657 /* JackAudioQueueAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */; }; + 4B07722C0F54018C000DC657 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; + 4B07722D0F54018C000DC657 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; }; + 4B07722E0F54018C000DC657 /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; + 4B0772310F54018C000DC657 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 4B0772320F54018C000DC657 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 4B0772330F54018C000DC657 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 4B0772340F54018C000DC657 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; + 4B07724A0F54021B000DC657 /* main_slave.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B0772490F54021B000DC657 /* main_slave.mm */; }; + 4B0772510F54022D000DC657 /* main_master.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B0772500F54022D000DC657 /* main_master.mm */; }; + 4B0773860F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */; }; + 4B0773870F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */; }; + 4B0773880F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */; }; + 4B1A94140F49BE2C00D3626B /* iPhoneNet_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 32CA4F630368D1EE00C91783 /* iPhoneNet_Prefix.pch */; }; + 4B1A94150F49BE2F00D3626B /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; }; + 4B1A94160F49BE3000D3626B /* JackMachThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1A93540F49ACFC00D3626B /* JackMachThread.h */; }; + 4B1A94170F49BE3100D3626B /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93870F49B0E300D3626B /* JackMachTime.c */; }; + 4B1A94180F49BE3100D3626B /* JackNetAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */; }; + 4B1A94190F49BE3300D3626B /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */; }; + 4B1A941A0F49BE3300D3626B /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; + 4B1A941B0F49BE3400D3626B /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; + 4B1A941C0F49BE3500D3626B /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1A93520F49ACF300D3626B /* JackNetUnixSocket.h */; }; + 4B1A941D0F49BE3500D3626B /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; + 4B1A941E0F49BE3600D3626B /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1A933C0F49AC4500D3626B /* JackPosixThread.h */; }; + 4B1A94540F49C03300D3626B /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; }; + 4B1A94550F49C03300D3626B /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93870F49B0E300D3626B /* JackMachTime.c */; }; + 4B1A94560F49C03400D3626B /* JackNetAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */; }; + 4B1A94570F49C03500D3626B /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */; }; + 4B1A94580F49C03600D3626B /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; + 4B1A94590F49C03600D3626B /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; + 4B1A945A0F49C03600D3626B /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; + 4B1A947F0F49C42300D3626B /* JackAudioQueueAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */; }; + 4B1A95760F49CEAB00D3626B /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; + 4BBDC8FA0F5420C000465F9C /* freeverb.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BBDC8F90F5420C000465F9C /* freeverb.mm */; }; + 4BF1360F0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; + 4BF136100F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; + 4BF136130F4B0B5E00218A3F /* JackAudioAdapterInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */; }; + 4BF1364D0F4B0F7700218A3F /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; }; + 4BF1364E0F4B0F7700218A3F /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; }; + 4BF1364F0F4B0F7700218A3F /* JackResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF1364C0F4B0F7700218A3F /* JackResampler.h */; }; + 4BF136550F4B0F9F00218A3F /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; + 4BF136560F4B0F9F00218A3F /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; + 4BFF45600F4D5D9700106083 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; + 4BFF45630F4D5D9700106083 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; }; + 4BFF45640F4D5D9700106083 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93870F49B0E300D3626B /* JackMachTime.c */; }; + 4BFF45650F4D5D9700106083 /* JackNetAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */; }; + 4BFF45660F4D5D9700106083 /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */; }; + 4BFF45670F4D5D9700106083 /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; + 4BFF45680F4D5D9700106083 /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; + 4BFF45690F4D5D9700106083 /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; + 4BFF456A0F4D5D9700106083 /* JackAudioQueueAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */; }; + 4BFF456B0F4D5D9700106083 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; + 4BFF456C0F4D5D9700106083 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; }; + 4BFF456D0F4D5D9700106083 /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; + 4BFF45700F4D5D9700106083 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 4BFF45710F4D5D9700106083 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 4BFF45720F4D5D9700106083 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 4BFF45730F4D5D9700106083 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* iPhoneNetSlave.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneNetSlave.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* iPhoneNet_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iPhoneNet_Prefix.pch; sourceTree = ""; }; + 4B0772380F54018C000DC657 /* iPhoneNetMaster.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneNetMaster.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B0772490F54021B000DC657 /* main_slave.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main_slave.mm; sourceTree = SOURCE_ROOT; }; + 4B0772500F54022D000DC657 /* main_master.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main_master.mm; sourceTree = SOURCE_ROOT; }; + 4B0773840F541EE2000DC657 /* iPhoneNetAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iPhoneNetAppDelegate.h; sourceTree = ""; }; + 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iPhoneNetAppDelegate.m; sourceTree = ""; }; + 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetAPI.cpp; path = ../../common/JackNetAPI.cpp; sourceTree = SOURCE_ROOT; }; + 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetInterface.cpp; path = ../../common/JackNetInterface.cpp; sourceTree = SOURCE_ROOT; }; + 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetTool.cpp; path = ../../common/JackNetTool.cpp; sourceTree = SOURCE_ROOT; }; + 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackPosixThread.cpp; path = ../../posix/JackPosixThread.cpp; sourceTree = SOURCE_ROOT; }; + 4B1A933C0F49AC4500D3626B /* JackPosixThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackPosixThread.h; path = ../../posix/JackPosixThread.h; sourceTree = SOURCE_ROOT; }; + 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetUnixSocket.cpp; path = ../../posix/JackNetUnixSocket.cpp; sourceTree = SOURCE_ROOT; }; + 4B1A93520F49ACF300D3626B /* JackNetUnixSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackNetUnixSocket.h; path = ../../posix/JackNetUnixSocket.h; sourceTree = SOURCE_ROOT; }; + 4B1A93540F49ACFC00D3626B /* JackMachThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMachThread.h; path = ../JackMachThread.h; sourceTree = SOURCE_ROOT; }; + 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMachThread.cpp; path = ../JackMachThread.cpp; sourceTree = SOURCE_ROOT; }; + 4B1A93870F49B0E300D3626B /* JackMachTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = JackMachTime.c; path = ../JackMachTime.c; sourceTree = SOURCE_ROOT; }; + 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioQueueAdapter.cpp; path = ../coreaudio/JackAudioQueueAdapter.cpp; sourceTree = SOURCE_ROOT; }; + 4B1A947E0F49C42300D3626B /* JackAudioQueueAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioQueueAdapter.h; path = ../coreaudio/JackAudioQueueAdapter.h; sourceTree = SOURCE_ROOT; }; + 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.1.sdk/System/Library/Frameworks/AudioToolbox.framework; sourceTree = ""; }; + 4BBDC8F90F5420C000465F9C /* freeverb.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = freeverb.mm; sourceTree = SOURCE_ROOT; }; + 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; }; + 4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioAdapterInterface.h; path = ../../common/JackAudioAdapterInterface.h; sourceTree = SOURCE_ROOT; }; + 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackResampler.cpp; path = ../../common/JackResampler.cpp; sourceTree = SOURCE_ROOT; }; + 4BF1364C0F4B0F7700218A3F /* JackResampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackResampler.h; path = ../../common/JackResampler.h; sourceTree = SOURCE_ROOT; }; + 4BF136540F4B0F9F00218A3F /* ringbuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ringbuffer.c; path = ../../common/ringbuffer.c; sourceTree = SOURCE_ROOT; }; + 4BFF45120F4D59DB00106083 /* libjacknet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjacknet.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, + 4B1A95760F49CEAB00D3626B /* AudioToolbox.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B0772300F54018C000DC657 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B0772310F54018C000DC657 /* Foundation.framework in Frameworks */, + 4B0772320F54018C000DC657 /* UIKit.framework in Frameworks */, + 4B0772330F54018C000DC657 /* CoreGraphics.framework in Frameworks */, + 4B0772340F54018C000DC657 /* AudioToolbox.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B1A940E0F49BDE000D3626B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BFF456F0F4D5D9700106083 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BFF45700F4D5D9700106083 /* Foundation.framework in Frameworks */, + 4BFF45710F4D5D9700106083 /* UIKit.framework in Frameworks */, + 4BFF45720F4D5D9700106083 /* CoreGraphics.framework in Frameworks */, + 4BFF45730F4D5D9700106083 /* AudioToolbox.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* iPhoneNetSlave.app */, + 4BFF45120F4D59DB00106083 /* libjacknet.a */, + 4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */, + 4B0772380F54018C000DC657 /* iPhoneNetMaster.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 4BBDC8F90F5420C000465F9C /* freeverb.mm */, + 4B0773840F541EE2000DC657 /* iPhoneNetAppDelegate.h */, + 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */, + 4BF136540F4B0F9F00218A3F /* ringbuffer.c */, + 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */, + 4BF1364C0F4B0F7700218A3F /* JackResampler.h */, + 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */, + 4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */, + 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */, + 4B1A947E0F49C42300D3626B /* JackAudioQueueAdapter.h */, + 4B1A93870F49B0E300D3626B /* JackMachTime.c */, + 4B1A93540F49ACFC00D3626B /* JackMachThread.h */, + 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */, + 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */, + 4B1A93520F49ACF300D3626B /* JackNetUnixSocket.h */, + 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */, + 4B1A933C0F49AC4500D3626B /* JackPosixThread.h */, + 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */, + 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */, + 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */, + 32CA4F630368D1EE00C91783 /* iPhoneNet_Prefix.pch */, + 4B0772490F54021B000DC657 /* main_slave.mm */, + 4B0772500F54022D000DC657 /* main_master.mm */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 28AD733E0D9D9553002E5188 /* MainWindow.xib */, + 8D1107310486CEB800E47090 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765FC0DF74451002DB57D /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 4B1A940C0F49BDE000D3626B /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B1A94140F49BE2C00D3626B /* iPhoneNet_Prefix.pch in Headers */, + 4B1A94160F49BE3000D3626B /* JackMachThread.h in Headers */, + 4B1A941C0F49BE3500D3626B /* JackNetUnixSocket.h in Headers */, + 4B1A941E0F49BE3600D3626B /* JackPosixThread.h in Headers */, + 4BF136130F4B0B5E00218A3F /* JackAudioAdapterInterface.h in Headers */, + 4BF1364F0F4B0F7700218A3F /* JackResampler.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* iPhoneNetSlave */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "iPhoneNetSlave" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = iPhoneNetSlave; + productName = iPhoneNet; + productReference = 1D6058910D05DD3D006BFB54 /* iPhoneNetSlave.app */; + productType = "com.apple.product-type.application"; + }; + 4B07721F0F54018C000DC657 /* iPhoneNetMaster */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B0772350F54018C000DC657 /* Build configuration list for PBXNativeTarget "iPhoneNetMaster" */; + buildPhases = ( + 4B0772200F54018C000DC657 /* Resources */, + 4B0772220F54018C000DC657 /* Sources */, + 4B0772300F54018C000DC657 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = iPhoneNetMaster; + productName = iPhoneNet; + productReference = 4B0772380F54018C000DC657 /* iPhoneNetMaster.app */; + productType = "com.apple.product-type.application"; + }; + 4B1A940F0F49BDE000D3626B /* jacknet */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B1A94130F49BDFF00D3626B /* Build configuration list for PBXNativeTarget "jacknet" */; + buildPhases = ( + 4B1A940C0F49BDE000D3626B /* Headers */, + 4B1A940D0F49BDE000D3626B /* Sources */, + 4B1A940E0F49BDE000D3626B /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = jacknet; + productName = jacknet; + productReference = 4BFF45120F4D59DB00106083 /* libjacknet.a */; + productType = "com.apple.product-type.library.static"; + }; + 4BFF455E0F4D5D9700106083 /* iPhoneFaustNet */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4BFF45740F4D5D9700106083 /* Build configuration list for PBXNativeTarget "iPhoneFaustNet" */; + buildPhases = ( + 4BFF455F0F4D5D9700106083 /* Resources */, + 4BFF45610F4D5D9700106083 /* Sources */, + 4BFF456F0F4D5D9700106083 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = iPhoneFaustNet; + productName = iPhoneNet; + productReference = 4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "iPhoneNet" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 4B07721F0F54018C000DC657 /* iPhoneNetMaster */, + 1D6058900D05DD3D006BFB54 /* iPhoneNetSlave */, + 4BFF455E0F4D5D9700106083 /* iPhoneFaustNet */, + 4B1A940F0F49BDE000D3626B /* jacknet */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B0772200F54018C000DC657 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B0772210F54018C000DC657 /* MainWindow.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BFF455F0F4D5D9700106083 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BFF45600F4D5D9700106083 /* MainWindow.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B1A94540F49C03300D3626B /* JackMachThread.cpp in Sources */, + 4B1A94550F49C03300D3626B /* JackMachTime.c in Sources */, + 4B1A94560F49C03400D3626B /* JackNetAPI.cpp in Sources */, + 4B1A94570F49C03500D3626B /* JackNetInterface.cpp in Sources */, + 4B1A94580F49C03600D3626B /* JackNetTool.cpp in Sources */, + 4B1A94590F49C03600D3626B /* JackNetUnixSocket.cpp in Sources */, + 4B1A945A0F49C03600D3626B /* JackPosixThread.cpp in Sources */, + 4B1A947F0F49C42300D3626B /* JackAudioQueueAdapter.cpp in Sources */, + 4BF1360F0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */, + 4BF1364D0F4B0F7700218A3F /* JackResampler.cpp in Sources */, + 4BF136550F4B0F9F00218A3F /* ringbuffer.c in Sources */, + 4B07724A0F54021B000DC657 /* main_slave.mm in Sources */, + 4B0773870F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B0772220F54018C000DC657 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B0772240F54018C000DC657 /* JackMachThread.cpp in Sources */, + 4B0772250F54018C000DC657 /* JackMachTime.c in Sources */, + 4B0772260F54018C000DC657 /* JackNetAPI.cpp in Sources */, + 4B0772270F54018C000DC657 /* JackNetInterface.cpp in Sources */, + 4B0772280F54018C000DC657 /* JackNetTool.cpp in Sources */, + 4B0772290F54018C000DC657 /* JackNetUnixSocket.cpp in Sources */, + 4B07722A0F54018C000DC657 /* JackPosixThread.cpp in Sources */, + 4B07722B0F54018C000DC657 /* JackAudioQueueAdapter.cpp in Sources */, + 4B07722C0F54018C000DC657 /* JackAudioAdapterInterface.cpp in Sources */, + 4B07722D0F54018C000DC657 /* JackResampler.cpp in Sources */, + 4B07722E0F54018C000DC657 /* ringbuffer.c in Sources */, + 4B0772510F54022D000DC657 /* main_master.mm in Sources */, + 4B0773860F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B1A940D0F49BDE000D3626B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B1A94150F49BE2F00D3626B /* JackMachThread.cpp in Sources */, + 4B1A94170F49BE3100D3626B /* JackMachTime.c in Sources */, + 4B1A94180F49BE3100D3626B /* JackNetAPI.cpp in Sources */, + 4B1A94190F49BE3300D3626B /* JackNetInterface.cpp in Sources */, + 4B1A941A0F49BE3300D3626B /* JackNetTool.cpp in Sources */, + 4B1A941B0F49BE3400D3626B /* JackNetUnixSocket.cpp in Sources */, + 4B1A941D0F49BE3500D3626B /* JackPosixThread.cpp in Sources */, + 4BF136100F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */, + 4BF1364E0F4B0F7700218A3F /* JackResampler.cpp in Sources */, + 4BF136560F4B0F9F00218A3F /* ringbuffer.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BFF45610F4D5D9700106083 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BFF45630F4D5D9700106083 /* JackMachThread.cpp in Sources */, + 4BFF45640F4D5D9700106083 /* JackMachTime.c in Sources */, + 4BFF45650F4D5D9700106083 /* JackNetAPI.cpp in Sources */, + 4BFF45660F4D5D9700106083 /* JackNetInterface.cpp in Sources */, + 4BFF45670F4D5D9700106083 /* JackNetTool.cpp in Sources */, + 4BFF45680F4D5D9700106083 /* JackNetUnixSocket.cpp in Sources */, + 4BFF45690F4D5D9700106083 /* JackPosixThread.cpp in Sources */, + 4BFF456A0F4D5D9700106083 /* JackAudioQueueAdapter.cpp in Sources */, + 4BFF456B0F4D5D9700106083 /* JackAudioAdapterInterface.cpp in Sources */, + 4BFF456C0F4D5D9700106083 /* JackResampler.cpp in Sources */, + 4BFF456D0F4D5D9700106083 /* ringbuffer.c in Sources */, + 4B0773880F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, + 4BBDC8FA0F5420C000465F9C /* freeverb.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + HEADER_SEARCH_PATHS = ( + ../../macosx, + ../../posix, + ../../common/jack, + ../../common, + ); + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/build/Debug-iphonesimulator\"", + ); + OTHER_LDFLAGS = ""; + PRODUCT_NAME = iPhoneNetSlave; + SDKROOT = iphoneos2.2.1; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + HEADER_SEARCH_PATHS = ( + ../../common/jack, + ../../common, + ../../posix, + ../../macosx, + ); + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/build/Debug-iphonesimulator\"", + ); + PRODUCT_NAME = iPhoneNetSlave; + }; + name = Release; + }; + 4B0772360F54018C000DC657 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + HEADER_SEARCH_PATHS = ( + ../../macosx, + ../../posix, + ../../common/jack, + ../../common, + ); + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\"", + ); + OTHER_LDFLAGS = ""; + PRODUCT_NAME = iPhoneNetMaster; + SDKROOT = iphoneos2.2.1; + }; + name = Debug; + }; + 4B0772370F54018C000DC657 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + HEADER_SEARCH_PATHS = ( + ../../common/jack, + ../../common, + ../../posix, + ../../macosx, + ); + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\"", + ); + PRODUCT_NAME = iPhoneNetMaster; + }; + name = Release; + }; + 4B1A94110F49BDE100D3626B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ( + ../../common/jack, + ../../common, + ../../posix, + ../../macosx, + ); + MACH_O_TYPE = staticlib; + PREBINDING = NO; + PRODUCT_NAME = jacknet; + STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = static; + }; + name = Debug; + }; + 4B1A94120F49BDE100D3626B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + PREBINDING = NO; + PRODUCT_NAME = jacknet; + ZERO_LINK = NO; + }; + name = Release; + }; + 4BFF45750F4D5D9700106083 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + HEADER_SEARCH_PATHS = ( + ../../macosx, + ../../posix, + ../../common/jack, + ../../common, + ); + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\"", + ); + OTHER_LDFLAGS = ""; + PRODUCT_NAME = iPhoneFaustNet; + SDKROOT = iphoneos2.2.1; + }; + name = Debug; + }; + 4BFF45760F4D5D9700106083 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + HEADER_SEARCH_PATHS = ( + ../../macosx, + ../../common/jack, + ../../common, + ../../posix, + ); + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\"", + ); + ONLY_ACTIVE_ARCH = NO; + PRODUCT_NAME = iPhoneFaustNet; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos2.2.1; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = iphoneos2.2.1; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "iPhoneNetSlave" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4B0772350F54018C000DC657 /* Build configuration list for PBXNativeTarget "iPhoneNetMaster" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B0772360F54018C000DC657 /* Debug */, + 4B0772370F54018C000DC657 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4B1A94130F49BDFF00D3626B /* Build configuration list for PBXNativeTarget "jacknet" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B1A94110F49BDE100D3626B /* Debug */, + 4B1A94120F49BDE100D3626B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4BFF45740F4D5D9700106083 /* Build configuration list for PBXNativeTarget "iPhoneFaustNet" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4BFF45750F4D5D9700106083 /* Debug */, + 4BFF45760F4D5D9700106083 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "iPhoneNet" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/macosx/iphone/iPhoneNetAppDelegate.h b/macosx/iphone/iPhoneNetAppDelegate.h new file mode 100644 index 00000000..9fcda5bb --- /dev/null +++ b/macosx/iphone/iPhoneNetAppDelegate.h @@ -0,0 +1,23 @@ +// +// iPhoneNetAppDelegate.h +// iPhoneNet +// +// Created by Stéphane LETZ on 16/02/09. +// Copyright Grame 2009. All rights reserved. +// + +#import + +@interface iPhoneNetAppDelegate : NSObject { + // UIWindow *window; + + IBOutlet UIWindow *window; + IBOutlet UINavigationController *navigationController; +} + +//@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) UIWindow *window; +@property (nonatomic, retain) UINavigationController *navigationController; + +@end + diff --git a/macosx/iphone/iPhoneNetAppDelegate.m b/macosx/iphone/iPhoneNetAppDelegate.m new file mode 100644 index 00000000..e867730d --- /dev/null +++ b/macosx/iphone/iPhoneNetAppDelegate.m @@ -0,0 +1,32 @@ +// +// iPhoneNetAppDelegate.m +// iPhoneNet +// +// Created by Stéphane LETZ on 16/02/09. +// Copyright Grame 2009. All rights reserved. +// + +#import "iPhoneNetAppDelegate.h" + +@implementation iPhoneNetAppDelegate + +@synthesize window, navigationController; + + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + + // Override point for customization after application launch + // add the navigation controller's view to the window + [window addSubview: navigationController.view]; + [window makeKeyAndVisible]; +} + + +- (void)dealloc { + [navigationController release]; + [window release]; + [super dealloc]; +} + + +@end diff --git a/macosx/iphone/iPhoneNet_Prefix.pch b/macosx/iphone/iPhoneNet_Prefix.pch new file mode 100644 index 00000000..8de611d5 --- /dev/null +++ b/macosx/iphone/iPhoneNet_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'iPhoneNet' target in the 'iPhoneNet' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/macosx/iphone/main_master.mm b/macosx/iphone/main_master.mm new file mode 100644 index 00000000..00bc73a9 --- /dev/null +++ b/macosx/iphone/main_master.mm @@ -0,0 +1,105 @@ +// +// main.m +// iPhoneNet +// +// Created by Stéphane LETZ on 16/02/09. +// Copyright Grame 2009. All rights reserved. +// + +#import +#include + +#include "JackAudioQueueAdapter.h" + +#define NUM_INPUT 2 +#define NUM_OUTPUT 2 + +jack_net_master_t* net; +jack_adapter_t* adapter; + +Jack::JackAudioQueueAdapter* audio; + +static int net_process(jack_nframes_t buffer_size, + int audio_input, + float** audio_input_buffer, + int midi_input, + void** midi_input_buffer, + int audio_output, + float** audio_output_buffer, + int midi_output, + void** midi_output_buffer, + void* data) +{ + // Process input, produce output + if (audio_input == audio_output) { + // Copy input to output + for (int i = 0; i < audio_input; i++) { + memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); + } + } + return 0; +} + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + int i; + int buffer_size = 512; + int sample_rate = 44100; + jack_master_t request = { buffer_size, sample_rate, "master" }; + jack_slave_t result; + float** audio_input_buffer; + float** audio_output_buffer; + int wait_usec = (int) ((((float)buffer_size) * 1000000) / ((float)sample_rate)); + + if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { + return -1; + } + + // Allocate buffers + audio_input_buffer = (float**)calloc(result.audio_input, sizeof(float*)); + for (i = 0; i < result.audio_input; i++) { + audio_input_buffer[i] = (float*)(calloc(buffer_size, sizeof(float))); + } + + audio_output_buffer = (float**)calloc(result.audio_output, sizeof(float*)); + for (i = 0; i < result.audio_output; i++) { + audio_output_buffer[i] = (float*)(calloc(buffer_size, sizeof(float))); + } + + // Quite brutal way, the application actually does not start completely, the netjack audio processing loop is used instead... + + // Run until interrupted + while (1) { + + // Copy input to output + for (i = 0; i < result.audio_input; i++) { + memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); + } + + jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL); + jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL); + usleep(wait_usec); + }; + + // Wait for application end + jack_net_master_close(net); + + for (i = 0; i < result.audio_input; i++) { + free(audio_input_buffer[i]); + } + free(audio_input_buffer); + + for (i = 0; i < result.audio_output; i++) { + free(audio_output_buffer[i]); + } + free(audio_output_buffer); + + + //int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + + //return retVal; + return 0; +} diff --git a/macosx/iphone/main_slave.mm b/macosx/iphone/main_slave.mm new file mode 100644 index 00000000..f899d823 --- /dev/null +++ b/macosx/iphone/main_slave.mm @@ -0,0 +1,66 @@ +// +// main.m +// iPhoneNet +// +// Created by Stéphane LETZ on 16/02/09. +// Copyright Grame 2009. All rights reserved. +// + +#import +#include + +#include "JackAudioQueueAdapter.h" + +#define NUM_INPUT 2 +#define NUM_OUTPUT 2 + +jack_net_slave_t* net; +jack_adapter_t* adapter; + +Jack::JackAudioQueueAdapter* audio; + +static int net_process(jack_nframes_t buffer_size, + int audio_input, + float** audio_input_buffer, + int midi_input, + void** midi_input_buffer, + int audio_output, + float** audio_output_buffer, + int midi_output, + void** midi_output_buffer, + void* data) +{ + // Process input, produce output + if (audio_input == audio_output) { + // Copy input to output + for (int i = 0; i < audio_input; i++) { + memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); + } + } + return 0; +} + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + jack_slave_t request = { NUM_INPUT, NUM_OUTPUT, 0, 0, DEFAULT_MTU, -1, JackSlowMode }; + jack_master_t result; + + if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { + return -1; + } + + jack_set_net_slave_process_callback(net, net_process, NULL); + if (jack_net_slave_activate(net) != 0) { + return -1; + } + + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + + // Wait for application end + jack_net_slave_deactivate(net); + jack_net_slave_close(net); + return retVal; +} From 44cd5a315431118f8dda8f10fe0ffc77baf10c17 Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 24 Feb 2009 13:53:37 +0000 Subject: [PATCH 005/472] More error checking in netslave and netmaster clients. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3340 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 2 +- example-clients/netmaster.c | 12 ++++++++++-- example-clients/netslave.c | 6 ++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index eda5a137..f60b58e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -26,7 +26,7 @@ Michael Voigt 2009-02-24 Stephane Letz * New libjacknet library with net.h and JackNetAPI.cpp files. New netmaster.c and netmaster.c examples. - * Add iPhone sources and project. + * Add sources and project for iPhone. 2009-02-23 Stephane Letz diff --git a/example-clients/netmaster.c b/example-clients/netmaster.c index ebfdfdb6..c9d5be48 100644 --- a/example-clients/netmaster.c +++ b/example-clients/netmaster.c @@ -145,8 +145,16 @@ main (int argc, char *argv[]) memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); } - jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL); - jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL); + if (jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) { + printf("jack_net_master_send failure, exiting\n"); + break; + } + + if (jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { + printf("jack_net_master_recv failure, exiting\n"); + break; + } + usleep(wait_usec); }; diff --git a/example-clients/netslave.c b/example-clients/netslave.c index 7c83ece0..6390743d 100644 --- a/example-clients/netslave.c +++ b/example-clients/netslave.c @@ -49,6 +49,10 @@ usage () " [ -p port (default = %d)]\n", DEFAULT_MULTICAST_IP, DEFAULT_PORT); } +static void net_shutdown(void* data) +{ + printf("Restarting...\n"); +} static int net_process(jack_nframes_t buffer_size, int audio_input, @@ -129,6 +133,8 @@ main (int argc, char *argv[]) printf("Slave is found and running...\n"); jack_set_net_slave_process_callback(net, net_process, NULL); + jack_set_net_slave_shutdown_callback(net, net_shutdown, NULL); + if (jack_net_slave_activate(net) != 0) { fprintf(stderr, "Cannot sactivate client\n"); return 1; From 669fbd80a52e9008f13c82838fb6ff2807bdc08a Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 24 Feb 2009 13:59:57 +0000 Subject: [PATCH 006/472] More error checking in iPhoneNetMaster example. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3341 0c269be4-1314-0410-8aa9-9f06e86f4224 --- macosx/iphone/main_master.mm | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/macosx/iphone/main_master.mm b/macosx/iphone/main_master.mm index 00bc73a9..00c3bff7 100644 --- a/macosx/iphone/main_master.mm +++ b/macosx/iphone/main_master.mm @@ -78,8 +78,13 @@ int main(int argc, char *argv[]) { memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); } - jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL); - jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL); + if (jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) { + break; + } + + if (jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { + break; + } usleep(wait_usec); }; @@ -95,7 +100,6 @@ int main(int argc, char *argv[]) { free(audio_output_buffer[i]); } free(audio_output_buffer); - //int retVal = UIApplicationMain(argc, argv, nil, nil); [pool release]; From 3ef112b3dec2e57416818d2d1f928da8a889032b Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 25 Feb 2009 12:26:26 +0000 Subject: [PATCH 007/472] rebase from trunk 3336:3353 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3354 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 12 +- common/JackAudioAdapterInterface.h | 1 + common/JackControlAPI.cpp | 4 +- common/JackInternalClient.cpp | 15 +- common/JackNetAPI.cpp | 9 +- common/JackNetDriver.cpp | 47 ++- common/JackNetDriver.h | 6 +- common/JackWaitThreadedDriver.h | 2 +- common/wscript | 3 + dbus/audio_reserve.c | 93 +++++ dbus/audio_reserve.h | 39 ++ dbus/reserve.c | 635 +++++++++++++++++++++++++++++ dbus/reserve.h | 69 ++++ linux/alsa/JackAlsaDriver.cpp | 47 ++- linux/alsa/JackAlsaDriver.h | 8 +- linux/wscript | 4 +- 16 files changed, 948 insertions(+), 46 deletions(-) create mode 100644 dbus/audio_reserve.c create mode 100644 dbus/audio_reserve.h create mode 100644 dbus/reserve.c create mode 100644 dbus/reserve.h diff --git a/ChangeLog b/ChangeLog index f60b58e0..3762f4fc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,7 +22,12 @@ Michael Voigt --------------------------- Jackdmp changes log --------------------------- - + +2009-02-25 Stephane Letz + + * Fix JackNetDriver::Close method. + * For audio device reservation, add card_to_num function. + 2009-02-24 Stephane Letz * New libjacknet library with net.h and JackNetAPI.cpp files. New netmaster.c and netmaster.c examples. @@ -30,13 +35,14 @@ Michael Voigt 2009-02-23 Stephane Letz - * Another fix in systemdeps.h and types.h: jack_time_t now uniquely defined in types.h. + * Another fix in systemdeps.h and types.h: jack_time_t now uniquely defined in types.h. * Move generic code and data in JackNetInterface and JackNetMasterInterface classes. + * First version of D-Bus based audio device rerservation. 2009-02-20 Stephane Letz * Add InitConnection and InitRendering methods in JackNetSlaveInterface, better packet type checking in JackNetSlaveInterface::SyncRecv. - * Change fMulticastIP handling in JackNetInterface. + * Change fMulticastIP handling in JackNetInterface. * Cleanup systemdeps.h on Windows. 2009-02-17 Stephane Letz diff --git a/common/JackAudioAdapterInterface.h b/common/JackAudioAdapterInterface.h index 07366d8c..83b15109 100644 --- a/common/JackAudioAdapterInterface.h +++ b/common/JackAudioAdapterInterface.h @@ -22,6 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackResampler.h" #include "JackFilters.h" +#include "JackConstants.h" namespace Jack { diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index 7fd71a0d..0bec8906 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -576,8 +576,8 @@ jackctl_wait_signals(sigset_t signals) // driver exit waiting = false; break; - case SIGTTOU: - break; + case SIGTTOU: + break; default: waiting = false; break; diff --git a/common/JackInternalClient.cpp b/common/JackInternalClient.cpp index d7d377ef..45350802 100644 --- a/common/JackInternalClient.cpp +++ b/common/JackInternalClient.cpp @@ -179,20 +179,20 @@ int JackLoadableInternalClient::Init(const char* so_name) fHandle = LoadJackModule(path_to_so); jack_log("JackLoadableInternalClient::JackLoadableInternalClient path_to_so = %s", path_to_so); - if (fHandle == 0) { + if (fHandle == NULL) { PrintLoadError(so_name); return -1; } fFinish = (FinishCallback)GetJackProc(fHandle, "jack_finish"); - if (!fFinish) { + if (fFinish == NULL) { UnloadJackModule(fHandle); jack_error("symbol jack_finish cannot be found in %s", so_name); return -1; } fDescriptor = (JackDriverDescFunction)GetJackProc(fHandle, "jack_get_descriptor"); - if (!fDescriptor) { + if (fDescriptor == NULL) { jack_info("No jack_get_descriptor entry-point for %s", so_name); } return 0; @@ -205,7 +205,7 @@ int JackLoadableInternalClient1::Init(const char* so_name) } fInitialize = (InitializeCallback)GetJackProc(fHandle, "jack_initialize"); - if (!fInitialize) { + if (fInitialize == NULL) { UnloadJackModule(fHandle); jack_error("symbol jack_initialize cannot be found in %s", so_name); return -1; @@ -221,7 +221,7 @@ int JackLoadableInternalClient2::Init(const char* so_name) } fInitialize = (InternalInitializeCallback)GetJackProc(fHandle, "jack_internal_initialize"); - if (!fInitialize) { + if (fInitialize == NULL) { UnloadJackModule(fHandle); jack_error("symbol jack_internal_initialize cannot be found in %s", so_name); return -1; @@ -244,9 +244,10 @@ JackLoadableInternalClient2::JackLoadableInternalClient2(JackServer* server, Jac JackLoadableInternalClient::~JackLoadableInternalClient() { - if (fFinish) + if (fFinish != NULL) fFinish(fProcessArg); - UnloadJackModule(fHandle); + if (fHandle != NULL) + UnloadJackModule(fHandle); } int JackLoadableInternalClient1::Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status) diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 7e41e8c8..8c2addc6 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -124,7 +124,7 @@ namespace Jack struct JackNetExtMaster : public JackNetMasterInterface { - //sample buffers + // Data buffers float** fAudioCaptureBuffer; float** fAudioPlaybackBuffer; @@ -142,8 +142,8 @@ struct JackNetExtMaster : public JackNetMasterInterface { assert(strlen(ip) < 32); strcpy(fMulticastIP, ip); fSocket.SetPort(port); - fRequest.buffer_size = request->buffer_size; - fRequest.sample_rate = request->sample_rate; + fRequest.buffer_size = request->buffer_size; + fRequest.sample_rate = request->sample_rate; } virtual ~JackNetExtMaster() @@ -391,8 +391,7 @@ struct JackNetExtMaster : public JackNetMasterInterface { { return 0; } - - + }; struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterface { diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index 5b17afb4..7b17ac90 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -91,14 +91,15 @@ namespace Jack } } -#ifdef JACK_MONITOR int JackNetDriver::Close() { +#ifdef JACK_MONITOR if ( fNetTimeMon ) fNetTimeMon->Save(); +#endif + FreeAll(); return JackDriver::Close(); } -#endif // Attach and Detach are defined as empty methods: port allocation is done when driver actually start (that is in Init) int JackNetDriver::Attach() @@ -122,8 +123,10 @@ namespace Jack jack_log ( "JackNetDriver::Init()" ); //new loading, but existing socket, restart the driver - if ( fSocket.IsSocket() ) - Restart(); + if (fSocket.IsSocket()) { + jack_info( "Restarting driver..." ); + FreeAll(); + } //set the parameters to send fParams.fSendAudioChannels = fCaptureChannels; @@ -206,28 +209,28 @@ namespace Jack return true; } - void JackNetDriver::Restart() + void JackNetDriver::FreeAll() { - jack_log ( "JackNetDriver::Restart" ); - - jack_info ( "Restarting driver..." ); + FreePorts(); + delete[] fTxBuffer; - fTxBuffer = NULL; delete[] fRxBuffer; - fRxBuffer = NULL; delete fNetAudioCaptureBuffer; - fNetAudioCaptureBuffer = NULL; delete fNetAudioPlaybackBuffer; - fNetAudioPlaybackBuffer = NULL; delete fNetMidiCaptureBuffer; - fNetMidiCaptureBuffer = NULL; delete fNetMidiPlaybackBuffer; - fNetMidiPlaybackBuffer = NULL; - FreePorts(); delete[] fMidiCapturePortList; - fMidiCapturePortList = NULL; delete[] fMidiPlaybackPortList; + + fTxBuffer = NULL; + fRxBuffer = NULL; + fNetAudioCaptureBuffer = NULL; + fNetAudioPlaybackBuffer = NULL; + fNetMidiCaptureBuffer = NULL; + fNetMidiPlaybackBuffer = NULL; + fMidiCapturePortList = NULL; fMidiPlaybackPortList = NULL; + #ifdef JACK_MONITOR delete fNetTimeMon; fNetTimeMon = NULL; @@ -353,13 +356,17 @@ namespace Jack int audio_port_index; uint midi_port_index; for ( audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++ ) - fGraphManager->ReleasePort ( fClientControl.fRefNum, fCapturePortList[audio_port_index] ); + if (fCapturePortList[audio_port_index] > 0) + fGraphManager->ReleasePort ( fClientControl.fRefNum, fCapturePortList[audio_port_index] ); for ( audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++ ) - fGraphManager->ReleasePort ( fClientControl.fRefNum, fPlaybackPortList[audio_port_index] ); + if (fPlaybackPortList[audio_port_index] > 0) + fGraphManager->ReleasePort ( fClientControl.fRefNum, fPlaybackPortList[audio_port_index] ); for ( midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++ ) - fGraphManager->ReleasePort ( fClientControl.fRefNum, fMidiCapturePortList[midi_port_index] ); + if (fMidiCapturePortList[midi_port_index] > 0) + fGraphManager->ReleasePort ( fClientControl.fRefNum, fMidiCapturePortList[midi_port_index] ); for ( midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++ ) - fGraphManager->ReleasePort ( fClientControl.fRefNum, fMidiPlaybackPortList[midi_port_index] ); + if (fMidiPlaybackPortList[midi_port_index] > 0) + fGraphManager->ReleasePort ( fClientControl.fRefNum, fMidiPlaybackPortList[midi_port_index] ); return 0; } diff --git a/common/JackNetDriver.h b/common/JackNetDriver.h index 9aced551..af432084 100644 --- a/common/JackNetDriver.h +++ b/common/JackNetDriver.h @@ -51,7 +51,8 @@ namespace Jack #endif bool Init(); - void Restart(); + void FreeAll(); + int AllocPorts(); int FreePorts(); @@ -71,10 +72,7 @@ namespace Jack int Open ( jack_nframes_t frames_per_cycle, jack_nframes_t rate, bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency ); - -#ifdef JACK_MONITOR int Close(); -#endif int Attach(); int Detach(); diff --git a/common/JackWaitThreadedDriver.h b/common/JackWaitThreadedDriver.h index 93dc3536..876b6551 100644 --- a/common/JackWaitThreadedDriver.h +++ b/common/JackWaitThreadedDriver.h @@ -31,7 +31,7 @@ namespace Jack \brief To be used as a wrapper of JackNetDriver. The idea is to behave as the "dummy" driver, until the network connection is really started and processing starts. -The Execute method will call the ProcessNull() methods until the decorated driver Init method returns. +The Execute method will call the ProcessNull method until the decorated driver Init method returns. A helper JackDriverStarter thread is used for that purpose. */ diff --git a/common/wscript b/common/wscript index 026ec5c8..0156c274 100644 --- a/common/wscript +++ b/common/wscript @@ -139,6 +139,9 @@ def build(bld): '../posix/JackSocketServerNotifyChannel.cpp', '../posix/JackNetUnixSocket.cpp', ] + + if bld.env['IS_LINUX'] and bld.env['BUILD_JACKDBUS']: + serverlib.source += ['../dbus/reserve.c', '../dbus/audio_reserve.c'] if bld.env['IS_SUN']: serverlib.source += [ diff --git a/dbus/audio_reserve.c b/dbus/audio_reserve.c new file mode 100644 index 00000000..cae5eac9 --- /dev/null +++ b/dbus/audio_reserve.c @@ -0,0 +1,93 @@ +/* + Copyright (C) 2009 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. + + 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. + +*/ + +#include +#include +#include +#include +#include +#include + +#include "reserve.h" +#include "audio_reserve.h" +#include "JackError.h" + +static DBusConnection* connection = NULL; + +SERVER_EXPORT int audio_reservation_init() +{ + DBusError error; + + dbus_error_init(&error); + + if (!(connection = dbus_bus_get(DBUS_BUS_SESSION, &error))) { + jack_error("Failed to connect to session bus for device reservation %s\n", error.message); + return -1; + } + + return 0; +} + +SERVER_EXPORT int audio_reservation_finish() +{ + if (connection) + dbus_connection_unref(connection); + return 0; +} + +SERVER_EXPORT void* audio_acquire(int num) +{ + DBusError error; + rd_device* device; + char audio_name[32]; + int e; + + snprintf(audio_name, sizeof(audio_name) - 1, "Audio%d", num); + if ((e = rd_acquire( + &device, + connection, + audio_name, + "Jack audio server", + INT32_MAX, + NULL, + &error)) < 0) { + + jack_error ("Failed to acquire device: %s\n", error.message ? error.message : strerror(-e)); + return NULL; + } + + jack_info("Acquire audio card %s", audio_name); + return (void*)device; +} + +SERVER_EXPORT void audio_reserve_loop() +{ + if (connection) { + while (dbus_connection_read_write_dispatch (connection, -1)) + ; // empty loop body + } +} + +SERVER_EXPORT void audio_release(void* dev) +{ + rd_device* device = (rd_device*)dev; + if (device) { + jack_info("Release audio card"); + rd_release(device); + } +} diff --git a/dbus/audio_reserve.h b/dbus/audio_reserve.h new file mode 100644 index 00000000..9a5c34c5 --- /dev/null +++ b/dbus/audio_reserve.h @@ -0,0 +1,39 @@ +/* + Copyright (C) 2009 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. + + 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 __audio_reserve__ +#define __audio_reserve__ + +#include "JackCompilerDeps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +SERVER_EXPORT int audio_reservation_init(); +SERVER_EXPORT int audio_reservation_finish(); + +SERVER_EXPORT void* audio_acquire(int num); +SERVER_EXPORT void audio_release(void* dev); +SERVER_EXPORT void audio_reserve_loop(); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/dbus/reserve.c b/dbus/reserve.c new file mode 100644 index 00000000..9a9591d2 --- /dev/null +++ b/dbus/reserve.c @@ -0,0 +1,635 @@ +/*** + Copyright 2009 Lennart Poettering + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +***/ + +#include +#include +#include +#include +#include +#include + +#include "reserve.h" + +struct rd_device { + int ref; + + char *device_name; + char *application_name; + char *application_device_name; + char *service_name; + char *object_path; + int32_t priority; + + DBusConnection *connection; + + int owning:1; + int registered:1; + int filtering:1; + int gave_up:1; + + rd_request_cb_t request_cb; + void *userdata; +}; + + +#define SERVICE_PREFIX "org.freedesktop.ReserveDevice1." +#define OBJECT_PREFIX "/org/freedesktop/ReserveDevice1/" + +static const char introspection[] = + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE + "" + " \n" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + +static dbus_bool_t add_variant( + DBusMessage *m, + int type, + const void *data) { + + DBusMessageIter iter, sub; + char t[2]; + + t[0] = (char) type; + t[1] = 0; + + dbus_message_iter_init_append(m, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, t, &sub)) + return FALSE; + + if (!dbus_message_iter_append_basic(&sub, type, data)) + return FALSE; + + if (!dbus_message_iter_close_container(&iter, &sub)) + return FALSE; + + return TRUE; +} + +static DBusHandlerResult object_handler( + DBusConnection *c, + DBusMessage *m, + void *userdata) { + + rd_device *d; + DBusError error; + DBusMessage *reply = NULL; + + dbus_error_init(&error); + + d = userdata; + assert(d->ref >= 1); + + if (dbus_message_is_method_call( + m, + "org.freedesktop.ReserveDevice1", + "RequestRelease")) { + + int32_t priority; + dbus_bool_t ret; + + if (!dbus_message_get_args( + m, + &error, + DBUS_TYPE_INT32, &priority, + DBUS_TYPE_INVALID)) + goto invalid; + + ret = FALSE; + + if (priority > d->priority && d->request_cb) { + d->ref++; + + if (d->request_cb(d, 0) > 0) { + ret = TRUE; + d->gave_up = 1; + } + + rd_release(d); + } + + if (!(reply = dbus_message_new_method_return(m))) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_BOOLEAN, &ret, + DBUS_TYPE_INVALID)) + goto oom; + + if (!dbus_connection_send(c, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_HANDLED; + + } else if (dbus_message_is_method_call( + m, + "org.freedesktop.DBus.Properties", + "Get")) { + + const char *interface, *property; + + if (!dbus_message_get_args( + m, + &error, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID)) + goto invalid; + + if (strcmp(interface, "org.freedesktop.ReserveDevice1") == 0) { + const char *empty = ""; + + if (strcmp(property, "ApplicationName") == 0 && d->application_name) { + if (!(reply = dbus_message_new_method_return(m))) + goto oom; + + if (!add_variant( + reply, + DBUS_TYPE_STRING, + d->application_name ? (const char**) &d->application_name : &empty)) + goto oom; + + } else if (strcmp(property, "ApplicationDeviceName") == 0) { + if (!(reply = dbus_message_new_method_return(m))) + goto oom; + + if (!add_variant( + reply, + DBUS_TYPE_STRING, + d->application_device_name ? (const char**) &d->application_device_name : &empty)) + goto oom; + + } else if (strcmp(property, "Priority") == 0) { + if (!(reply = dbus_message_new_method_return(m))) + goto oom; + + if (!add_variant( + reply, + DBUS_TYPE_INT32, + &d->priority)) + goto oom; + } else { + if (!(reply = dbus_message_new_error_printf( + m, + DBUS_ERROR_UNKNOWN_METHOD, + "Unknown property %s", + property))) + goto oom; + } + + if (!dbus_connection_send(c, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_HANDLED; + } + + } else if (dbus_message_is_method_call( + m, + "org.freedesktop.DBus.Introspectable", + "Introspect")) { + const char *i = introspection; + + if (!(reply = dbus_message_new_method_return(m))) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_STRING, + &i, + DBUS_TYPE_INVALID)) + goto oom; + + if (!dbus_connection_send(c, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + +invalid: + if (reply) + dbus_message_unref(reply); + + if (!(reply = dbus_message_new_error( + m, + DBUS_ERROR_INVALID_ARGS, + "Invalid arguments"))) + goto oom; + + if (!dbus_connection_send(c, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static DBusHandlerResult filter_handler( + DBusConnection *c, + DBusMessage *m, + void *userdata) { + + DBusMessage *reply; + rd_device *d; + DBusError error; + + dbus_error_init(&error); + + d = userdata; + + if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameLost")) { + const char *name; + + if (!dbus_message_get_args( + m, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + goto invalid; + + if (strcmp(name, d->service_name) == 0 && d->owning) { + d->owning = 0; + + if (!d->gave_up) { + d->ref++; + + if (d->request_cb) + d->request_cb(d, 1); + d->gave_up = 1; + + rd_release(d); + } + + return DBUS_HANDLER_RESULT_HANDLED; + } + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + +invalid: + if (!(reply = dbus_message_new_error( + m, + DBUS_ERROR_INVALID_ARGS, + "Invalid arguments"))) + goto oom; + + if (!dbus_connection_send(c, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + + +static const struct DBusObjectPathVTable vtable ={ + .message_function = object_handler +}; + +int rd_acquire( + rd_device **_d, + DBusConnection *connection, + const char *device_name, + const char *application_name, + int32_t priority, + rd_request_cb_t request_cb, + DBusError *error) { + + rd_device *d = NULL; + int r, k; + DBusError _error; + DBusMessage *m = NULL, *reply = NULL; + dbus_bool_t good; + + if (!error) + error = &_error; + + dbus_error_init(error); + + if (!_d) + return -EINVAL; + + if (!connection) + return -EINVAL; + + if (!device_name) + return -EINVAL; + + if (!request_cb && priority != INT32_MAX) + return -EINVAL; + + if (!(d = calloc(sizeof(rd_device), 1))) + return -ENOMEM; + + d->ref = 1; + + if (!(d->device_name = strdup(device_name))) { + r = -ENOMEM; + goto fail; + } + + if (!(d->application_name = strdup(application_name))) { + r = -ENOMEM; + goto fail; + } + + d->priority = priority; + d->connection = dbus_connection_ref(connection); + d->request_cb = request_cb; + + if (!(d->service_name = malloc(sizeof(SERVICE_PREFIX) + strlen(device_name)))) { + r = -ENOMEM; + goto fail; + } + sprintf(d->service_name, SERVICE_PREFIX "%s", d->device_name); + + if (!(d->object_path = malloc(sizeof(OBJECT_PREFIX) + strlen(device_name)))) { + r = -ENOMEM; + goto fail; + } + sprintf(d->object_path, OBJECT_PREFIX "%s", d->device_name); + + if ((k = dbus_bus_request_name( + d->connection, + d->service_name, + DBUS_NAME_FLAG_DO_NOT_QUEUE| + (priority < INT32_MAX ? DBUS_NAME_FLAG_ALLOW_REPLACEMENT : 0), + error)) < 0) { + r = -EIO; + goto fail; + } + + if (k == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) + goto success; + + if (k != DBUS_REQUEST_NAME_REPLY_EXISTS) { + r = -EIO; + goto fail; + } + + if (priority <= INT32_MIN) { + r = -EBUSY; + goto fail; + } + + if (!(m = dbus_message_new_method_call( + d->service_name, + d->object_path, + "org.freedesktop.ReserveDevice1", + "RequestRelease"))) { + r = -ENOMEM; + goto fail; + } + + if (!dbus_message_append_args( + m, + DBUS_TYPE_INT32, &d->priority, + DBUS_TYPE_INVALID)) { + r = -ENOMEM; + goto fail; + } + + if (!(reply = dbus_connection_send_with_reply_and_block( + d->connection, + m, + 5000, /* 5s */ + error))) { + + if (dbus_error_has_name(error, DBUS_ERROR_TIMED_OUT) || + dbus_error_has_name(error, DBUS_ERROR_UNKNOWN_METHOD) || + dbus_error_has_name(error, DBUS_ERROR_NO_REPLY)) { + /* This must be treated as denied. */ + r = -EBUSY; + goto fail; + } + + r = -EIO; + goto fail; + } + + if (!dbus_message_get_args( + reply, + error, + DBUS_TYPE_BOOLEAN, &good, + DBUS_TYPE_INVALID)) { + r = -EIO; + goto fail; + } + + if (!good) { + r = -EBUSY; + goto fail; + } + + if ((k = dbus_bus_request_name( + d->connection, + d->service_name, + DBUS_NAME_FLAG_DO_NOT_QUEUE| + (priority < INT32_MAX ? DBUS_NAME_FLAG_ALLOW_REPLACEMENT : 0)| + DBUS_NAME_FLAG_REPLACE_EXISTING, + error)) < 0) { + r = -EIO; + goto fail; + } + + if (k != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + r = -EIO; + goto fail; + } + +success: + d->owning = 1; + + if (!(dbus_connection_register_object_path( + d->connection, + d->object_path, + &vtable, + d))) { + r = -ENOMEM; + goto fail; + } + + d->registered = 1; + + if (!dbus_connection_add_filter( + d->connection, + filter_handler, + d, + NULL)) { + r = -ENOMEM; + goto fail; + } + + d->filtering = 1; + + *_d = d; + return 0; + +fail: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + if (&_error == error) + dbus_error_free(&_error); + + if (d) + rd_release(d); + + return r; +} + +void rd_release( + rd_device *d) { + + if (!d) + return; + + assert(d->ref > 0); + + if (--d->ref) + return; + + + if (d->filtering) + dbus_connection_remove_filter( + d->connection, + filter_handler, + d); + + if (d->registered) + dbus_connection_unregister_object_path( + d->connection, + d->object_path); + + if (d->owning) { + DBusError error; + dbus_error_init(&error); + + dbus_bus_release_name( + d->connection, + d->service_name, + &error); + + dbus_error_free(&error); + } + + free(d->device_name); + free(d->application_name); + free(d->application_device_name); + free(d->service_name); + free(d->object_path); + + if (d->connection) + dbus_connection_unref(d->connection); + + free(d); +} + +int rd_set_application_device_name(rd_device *d, const char *n) { + char *t; + + if (!d) + return -EINVAL; + + assert(d->ref > 0); + + if (!(t = strdup(n))) + return -ENOMEM; + + free(d->application_device_name); + d->application_device_name = t; + return 0; +} + +void rd_set_userdata(rd_device *d, void *userdata) { + + if (!d) + return; + + assert(d->ref > 0); + d->userdata = userdata; +} + +void* rd_get_userdata(rd_device *d) { + + if (!d) + return NULL; + + assert(d->ref > 0); + + return d->userdata; +} diff --git a/dbus/reserve.h b/dbus/reserve.h new file mode 100644 index 00000000..b315a08c --- /dev/null +++ b/dbus/reserve.h @@ -0,0 +1,69 @@ +#ifndef fooreservehfoo +#define fooreservehfoo + +/*** + Copyright 2009 Lennart Poettering + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +***/ + +#include +#include + +typedef struct rd_device rd_device; + +/* Prototype for a function that is called whenever someone else wants + * your application to release the device it has locked. A return + * value <= 0 denies the request, a positive return value agrees to + * it. Before returning your application should close the device in + * question completely to make sure the new application may access + * it. */ +typedef int (*rd_request_cb_t)( + rd_device *d, + int forced); /* Non-zero if an application forcibly took the lock away without asking. If this is the case then the return value of this call is ignored. */ + +/* Try to lock the device. Returns 0 on success, a negative errno + * style return value on error. The DBus error might be set as well if + * the error was caused D-Bus. */ +int rd_acquire( + rd_device **d, /* On success a pointer to the newly allocated rd_device object will be filled in here */ + DBusConnection *connection, + const char *device_name, /* The device to lock, e.g. "Audio0" */ + const char *application_name, /* A human readable name of the application, e.g. "PulseAudio Sound Server" */ + int32_t priority, /* The priority for this application. If unsure use 0 */ + rd_request_cb_t request_cb, /* Will be called whenever someone requests that this device shall be released. May be NULL if priority is INT32_MAX */ + DBusError *error); /* If we fail due to a D-Bus related issue the error will be filled in here. May be NULL. */ + +/* Unlock (if needed) and destroy an rd_device object again */ +void rd_release(rd_device *d); + +/* Set the application device name for an rd_device object. Returns 0 + * on success, a negative errno style return value on error. */ +int rd_set_application_device_name(rd_device *d, const char *name); + +/* Attach a userdata pointer to an rd_device */ +void rd_set_userdata(rd_device *d, void *userdata); + +/* Query the userdata pointer from an rd_device. Returns NULL if no + * userdata was set. */ +void* rd_get_userdata(rd_device *d); + +#endif diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index 04d85b02..455f73ca 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -49,7 +49,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "generic.h" #include "memops.h" - +#include "audio_reserve.h" namespace Jack { @@ -2138,6 +2138,23 @@ int JackAlsaDriver::Detach() return JackAudioDriver::Detach(); } +#if defined(JACK_DBUS) +static int card_to_num(const char* device) +{ + const char* t; + int i; + + if ((t = strchr(device, ':'))) + device = t + 1; + + if ((i = snd_card_get_index(device)) < 0) { + i = atoi(device); + } + + return i; +} +#endif + int JackAlsaDriver::Open(jack_nframes_t nframes, jack_nframes_t user_nperiods, jack_nframes_t samplerate, @@ -2170,6 +2187,29 @@ int JackAlsaDriver::Open(jack_nframes_t nframes, else if (strcmp(midi_driver_name, "raw") == 0) midi = alsa_rawmidi_new((jack_client_t*)this); +#if defined(JACK_DBUS) + if (audio_reservation_init() < 0) { + jack_error("Audio device reservation service not available...."); + } else if (strcmp(capture_driver_name, playback_driver_name) == 0) { // Same device for input and output + fReservedCaptureDevice = audio_acquire(card_to_num(capture_driver_name)); + if (fReservedCaptureDevice == NULL) { + jack_error("Error audio device %s not available...", capture_driver_name); + return -1; + } + } else { + fReservedCaptureDevice = audio_acquire(card_to_num(capture_driver_name)); + if (fReservedCaptureDevice == NULL) { + jack_error("Error capture audio device %s not available...", capture_driver_name); + return -1; + } + fReservedPlaybackDevice = audio_acquire(card_to_num(playback_driver_name)); + if (fReservedPlaybackDevice == NULL) { + jack_error("Error playback audio device %s not available...", playback_driver_name); + return -1; + } + } +#endif + fDriver = alsa_driver_new ("alsa_pcm", (char*)playback_driver_name, (char*)capture_driver_name, NULL, nframes, @@ -2203,6 +2243,11 @@ int JackAlsaDriver::Close() { JackAudioDriver::Close(); alsa_driver_delete((alsa_driver_t*)fDriver); +#if defined(JACK_DBUS) + audio_release(fReservedCaptureDevice); + audio_release(fReservedPlaybackDevice); + audio_reservation_finish(); +#endif return 0; } diff --git a/linux/alsa/JackAlsaDriver.h b/linux/alsa/JackAlsaDriver.h index c6debff2..6fab0baf 100644 --- a/linux/alsa/JackAlsaDriver.h +++ b/linux/alsa/JackAlsaDriver.h @@ -40,6 +40,8 @@ class JackAlsaDriver : public JackAudioDriver private: jack_driver_t* fDriver; + void* fReservedCaptureDevice; + void* fReservedPlaybackDevice; void alsa_driver_release_channel_dependent_memory(alsa_driver_t *driver); int alsa_driver_check_capabilities(alsa_driver_t *driver); @@ -116,7 +118,11 @@ class JackAlsaDriver : public JackAudioDriver public: - JackAlsaDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table): JackAudioDriver(name, alias, engine, table) + JackAlsaDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) + : JackAudioDriver(name, alias, engine, table) + ,fDriver(NULL) + ,fReservedCaptureDevice(NULL) + ,fReservedPlaybackDevice(NULL) {} virtual ~JackAlsaDriver() {} diff --git a/linux/wscript b/linux/wscript index 0df5e866..5751bf60 100644 --- a/linux/wscript +++ b/linux/wscript @@ -16,7 +16,7 @@ def create_jack_driver_obj(bld, target, sources, uselib = None): driver.features.append('cc') driver.env['shlib_PATTERN'] = 'jack_%s.so' driver.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] - driver.includes = ['.', '../linux', '../posix', '../common', '../common/jack'] + driver.includes = ['.', '../linux', '../posix', '../common', '../common/jack', '../dbus'] driver.target = target driver.source = sources driver.install_path = '${ADDON_DIR}/' @@ -26,7 +26,7 @@ def create_jack_driver_obj(bld, target, sources, uselib = None): def build(bld): jackd = bld.new_task_gen('cxx', 'program') - jackd.includes = ['../linux', '../posix', '../common/jack', '../common'] + jackd.includes = ['../linux', '../posix', '../common/jack', '../common', '../dbus'] jackd.defines = 'HAVE_CONFIG_H' jackd.source = ['../common/Jackdmp.cpp'] jackd.uselib = 'PTHREAD DL RT' From 2376d98b0651a7b9a6a086609bfbea555fcd7adf Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 2 Mar 2009 09:53:13 +0000 Subject: [PATCH 008/472] Improve C adapter API. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3366 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackAudioAdapterInterface.h | 30 +++++++++++++++++++++++------- common/JackNetAPI.cpp | 19 ++++++++++++++----- common/JackNetAdapter.cpp | 2 +- common/jack/net.h | 5 ++++- 4 files changed, 42 insertions(+), 14 deletions(-) diff --git a/common/JackAudioAdapterInterface.h b/common/JackAudioAdapterInterface.h index 83b15109..81b6cc87 100644 --- a/common/JackAudioAdapterInterface.h +++ b/common/JackAudioAdapterInterface.h @@ -95,15 +95,31 @@ namespace Jack public: - JackAudioAdapterInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ) : + JackAudioAdapterInterface ( jack_nframes_t host_buffer_size, + jack_nframes_t host_sample_rate) : fCaptureChannels ( 0 ), fPlaybackChannels ( 0 ), - fHostBufferSize ( buffer_size ), - fHostSampleRate ( sample_rate ), - fAdaptedBufferSize ( buffer_size), - fAdaptedSampleRate ( sample_rate ), - fHostDLL ( buffer_size, sample_rate ), - fAdaptedDLL ( buffer_size, sample_rate ), + fHostBufferSize ( host_buffer_size ), + fHostSampleRate ( host_sample_rate ), + fAdaptedBufferSize ( host_buffer_size), + fAdaptedSampleRate ( host_sample_rate ), + fHostDLL ( host_buffer_size, host_sample_rate ), + fAdaptedDLL ( host_buffer_size, host_sample_rate ), + fQuality(0), + fRunning ( false ) + {} + JackAudioAdapterInterface ( jack_nframes_t host_buffer_size, + jack_nframes_t host_sample_rate, + jack_nframes_t adapted_buffer_size, + jack_nframes_t adapted_sample_rate ) : + fCaptureChannels ( 0 ), + fPlaybackChannels ( 0 ), + fHostBufferSize ( host_buffer_size ), + fHostSampleRate ( host_sample_rate ), + fAdaptedBufferSize ( adapted_buffer_size), + fAdaptedSampleRate ( adapted_sample_rate ), + fHostDLL ( host_buffer_size, host_sample_rate ), + fAdaptedDLL ( adapted_buffer_size, adapted_sample_rate ), fQuality(0), fRunning ( false ) {} diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 8c2addc6..a0fb8d89 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -106,7 +106,10 @@ extern "C" typedef struct _jack_adapter jack_adapter_t; - SERVER_EXPORT jack_adapter_t* jack_create_adapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate); + SERVER_EXPORT jack_adapter_t* jack_create_adapter(jack_nframes_t host_buffer_size, + jack_nframes_t host_sample_rate, + jack_nframes_t adapted_buffer_size, + jack_nframes_t adapted_sample_rate); SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter); SERVER_EXPORT int jack_adapter_push_input(jack_adapter_t* adapter, int channels, float** buffers); @@ -731,8 +734,11 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf struct JackNetAdapter : public JackAudioAdapterInterface { - JackNetAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate) - :JackAudioAdapterInterface(buffer_size, sample_rate) + JackNetAdapter(jack_nframes_t host_buffer_size, + jack_nframes_t host_sample_rate, + jack_nframes_t adapted_buffer_size, + jack_nframes_t adapted_sample_rate) + :JackAudioAdapterInterface(host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate) { fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; @@ -962,9 +968,12 @@ SERVER_EXPORT int jack_net_master_send(jack_net_master_t* net, int audio_output, // Adapter API -SERVER_EXPORT jack_adapter_t* jack_create_adapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate) +SERVER_EXPORT jack_adapter_t* jack_create_adapter(jack_nframes_t host_buffer_size, + jack_nframes_t host_sample_rate, + jack_nframes_t adapted_buffer_size, + jack_nframes_t adapted_sample_rate) { - return (jack_adapter_t*)new JackNetAdapter(buffer_size, sample_rate); + return (jack_adapter_t*)new JackNetAdapter(host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate); } SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter) diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index e1f16bde..3c088eb7 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -26,7 +26,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { JackNetAdapter::JackNetAdapter ( jack_client_t* jack_client, jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params ) - : JackAudioAdapterInterface ( buffer_size, sample_rate ), JackNetSlaveInterface(), fThread ( this ) + : JackAudioAdapterInterface ( buffer_size, sample_rate), JackNetSlaveInterface(), fThread ( this ) { jack_log ( "JackNetAdapter::JackNetAdapter" ); diff --git a/common/jack/net.h b/common/jack/net.h index c8671608..940a0692 100644 --- a/common/jack/net.h +++ b/common/jack/net.h @@ -255,7 +255,10 @@ typedef struct _jack_adapter jack_adapter_t; * * @return 0 on success, otherwise a non-zero error code */ -jack_adapter_t* jack_create_adapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate); +jack_adapter_t* jack_create_adapter(jack_nframes_t host_buffer_size, + jack_nframes_t host_sample_rate, + jack_nframes_t adapted_buffer_size, + jack_nframes_t adapted_sample_rate); /** * Destroy an adapter. From 6926652401696c38e61206bee2f25ba0e222c0c3 Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 2 Mar 2009 11:16:21 +0000 Subject: [PATCH 009/472] rebase from trunk 3353:3367 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3368 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 13 +- common/JackAudioAdapter.cpp | 107 ++++-------- common/JackAudioAdapter.h | 6 - common/JackAudioAdapterInterface.cpp | 173 ++++++++++++++++++-- common/JackAudioAdapterInterface.h | 50 +++--- common/JackLibSampleRateResampler.cpp | 4 +- common/JackLibSampleRateResampler.h | 4 +- common/JackNetAPI.cpp | 182 ++++----------------- common/JackNetAdapter.cpp | 2 +- common/JackResampler.cpp | 10 +- common/JackResampler.h | 4 +- common/jack/net.h | 25 +-- common/wscript | 10 +- linux/alsa/JackAlsaAdapter.cpp | 57 +++---- linux/alsa/JackAlsaAdapter.h | 29 +++- macosx/coreaudio/JackCoreAudioAdapter.cpp | 50 +++--- solaris/oss/JackOSSAdapter.cpp | 49 +++--- solaris/oss/JackOSSAdapter.h | 2 +- windows/portaudio/JackPortAudioAdapter.cpp | 65 +++----- 19 files changed, 388 insertions(+), 454 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3762f4fc..c2361d74 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,11 +22,22 @@ Michael Voigt --------------------------- Jackdmp changes log --------------------------- + +2009-02-27 Stephane Letz + + * Improve generated gnuplot files for adapting code. + +2009-02-25 Stephane Letz + + * Major cleanup in adapter code. 2009-02-25 Stephane Letz * Fix JackNetDriver::Close method. * For audio device reservation, add card_to_num function. + * Fix buffer size and sample rate handling in JackAlsaAdapter. + * Add control for adapter ringbuffer size. + * Fix JackAlsaAdapter.h for 64 bits compilation. 2009-02-24 Stephane Letz @@ -37,7 +48,7 @@ Michael Voigt * Another fix in systemdeps.h and types.h: jack_time_t now uniquely defined in types.h. * Move generic code and data in JackNetInterface and JackNetMasterInterface classes. - * First version of D-Bus based audio device rerservation. + * First version of D-Bus based audio device reservation. 2009-02-20 Stephane Letz diff --git a/common/JackAudioAdapter.cpp b/common/JackAudioAdapter.cpp index bffc6323..06f7e0f1 100644 --- a/common/JackAudioAdapter.cpp +++ b/common/JackAudioAdapter.cpp @@ -18,7 +18,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackAudioAdapter.h" -#include "JackLibSampleRateResampler.h" #include "JackError.h" #include "JackCompilerDeps.h" #include "JackTools.h" @@ -34,40 +33,22 @@ namespace Jack { //static methods *********************************************************** - int JackAudioAdapter::Process ( jack_nframes_t frames, void* arg ) + int JackAudioAdapter::Process (jack_nframes_t frames, void* arg) { - JackAudioAdapter* adapter = static_cast ( arg ); - float* buffer; - bool failure = false; - int i; - - if ( !adapter->fAudioAdapter->IsRunning() ) + JackAudioAdapter* adapter = static_cast(arg); + if (!adapter->fAudioAdapter->IsRunning()) return 0; - - // DLL - adapter->fAudioAdapter->SetCallbackTime (GetMicroSeconds()); - - // Push/pull from ringbuffer - for ( i = 0; i < adapter->fCaptureChannels; i++ ) - { - buffer = static_cast ( jack_port_get_buffer ( adapter->fCapturePortList[i], frames ) ); - if ( adapter->fCaptureRingBuffer[i]->Read ( buffer, frames ) < frames ) - failure = true; + + float* inputBuffer[adapter->fAudioAdapter->GetInputs()]; + float* outputBuffer[adapter->fAudioAdapter->GetOutputs()]; + for (int i = 0; i < adapter->fAudioAdapter->GetInputs(); i++) { + inputBuffer[i] = (float*)jack_port_get_buffer(adapter->fCapturePortList[i], frames); } - - for ( i = 0; i < adapter->fPlaybackChannels; i++ ) - { - buffer = static_cast ( jack_port_get_buffer ( adapter->fPlaybackPortList[i], frames ) ); - if ( adapter->fPlaybackRingBuffer[i]->Write ( buffer, frames ) < frames ) - failure = true; - } - - // Reset all ringbuffers in case of failure - if ( failure ) - { - jack_error ( "JackCallbackAudioAdapter::Process ringbuffer failure... reset" ); - adapter->Reset(); + for (int i = 0; i < adapter->fAudioAdapter->GetOutputs(); i++) { + outputBuffer[i] = (float*)jack_port_get_buffer(adapter->fPlaybackPortList[i], frames); } + + adapter->fAudioAdapter->PullAndPush(inputBuffer, outputBuffer, frames); return 0; } @@ -91,24 +72,15 @@ namespace Jack JackAudioAdapter::~JackAudioAdapter() { // When called, Close has already been used for the client, thus ports are already unregistered. - int i; - for ( i = 0; i < fCaptureChannels; i++ ) - delete ( fCaptureRingBuffer[i] ); - for ( i = 0; i < fPlaybackChannels; i++ ) - delete ( fPlaybackRingBuffer[i] ); - - delete[] fCaptureRingBuffer; - delete[] fPlaybackRingBuffer; delete fAudioAdapter; } void JackAudioAdapter::FreePorts() { - int i; - for ( i = 0; i < fCaptureChannels; i++ ) + for (int i = 0; i < fAudioAdapter->GetInputs(); i++ ) if ( fCapturePortList[i] ) jack_port_unregister ( fJackClient, fCapturePortList[i] ); - for ( i = 0; i < fCaptureChannels; i++ ) + for (int i = 0; i < fAudioAdapter->GetOutputs(); i++ ) if ( fPlaybackPortList[i] ) jack_port_unregister ( fJackClient, fPlaybackPortList[i] ); @@ -118,52 +90,30 @@ namespace Jack void JackAudioAdapter::Reset() { - int i; - for ( i = 0; i < fCaptureChannels; i++ ) - fCaptureRingBuffer[i]->Reset(); - for ( i = 0; i < fPlaybackChannels; i++ ) - fPlaybackRingBuffer[i]->Reset(); fAudioAdapter->Reset(); } int JackAudioAdapter::Open() { - int i; char name[32]; - - fCaptureChannels = fAudioAdapter->GetInputs(); - fPlaybackChannels = fAudioAdapter->GetOutputs(); - - jack_log ( "JackAudioAdapter::Open fCaptureChannels %d fPlaybackChannels %d", fCaptureChannels, fPlaybackChannels ); - - //ringbuffers - fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; - fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; - for ( i = 0; i < fCaptureChannels; i++ ) - fCaptureRingBuffer[i] = new JackLibSampleRateResampler(fAudioAdapter->GetQuality()); - for ( i = 0; i < fPlaybackChannels; i++ ) - fPlaybackRingBuffer[i] = new JackLibSampleRateResampler(fAudioAdapter->GetQuality()); - fAudioAdapter->SetRingBuffers ( fCaptureRingBuffer, fPlaybackRingBuffer ); - if (fCaptureChannels > 0) - jack_log ( "ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace() ); - if (fPlaybackChannels > 0) - jack_log ( "WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace() ); - + jack_log("JackAudioAdapter::Open fCaptureChannels %d fPlaybackChannels %d", fAudioAdapter->GetInputs(), fAudioAdapter->GetOutputs()); + fAudioAdapter->Create(); + //jack ports - fCapturePortList = new jack_port_t* [fCaptureChannels]; - fPlaybackPortList = new jack_port_t* [fPlaybackChannels]; + fCapturePortList = new jack_port_t*[fAudioAdapter->GetInputs()]; + fPlaybackPortList = new jack_port_t*[fAudioAdapter->GetOutputs()]; - for ( i = 0; i < fCaptureChannels; i++ ) + for (int i = 0; i < fAudioAdapter->GetInputs(); i++) { - sprintf ( name, "capture_%d", i+1 ); - if ( ( fCapturePortList[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ) ) == NULL ) + sprintf(name, "capture_%d", i + 1); + if ((fCapturePortList[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL) goto fail; } - for ( i = 0; i < fPlaybackChannels; i++ ) + for (int i = 0; i < fAudioAdapter->GetOutputs(); i++) { - sprintf ( name, "playback_%d", i+1 ); - if ( ( fPlaybackPortList[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 ) ) == NULL ) + sprintf(name, "playback_%d", i + 1); + if ((fPlaybackPortList[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 )) == NULL) goto fail; } @@ -177,17 +127,20 @@ namespace Jack if ( jack_activate ( fJackClient ) < 0 ) goto fail; - //ringbuffers and jack clients are ok, we can now open the adapter driver interface + // Ring buffer are now allocated.. return fAudioAdapter->Open(); fail: FreePorts(); + fAudioAdapter->Destroy(); return -1; } int JackAudioAdapter::Close() { - return fAudioAdapter->Close(); + fAudioAdapter->Close(); + fAudioAdapter->Destroy(); + return 0; } } //namespace diff --git a/common/JackAudioAdapter.h b/common/JackAudioAdapter.h index eab6ba3d..1a15c2a0 100644 --- a/common/JackAudioAdapter.h +++ b/common/JackAudioAdapter.h @@ -37,12 +37,6 @@ namespace Jack static int BufferSize ( jack_nframes_t buffer_size, void *arg ); static int SampleRate ( jack_nframes_t sample_rate, void *arg ); - int fCaptureChannels; - int fPlaybackChannels; - - JackResampler** fCaptureRingBuffer; - JackResampler** fPlaybackRingBuffer; - jack_port_t** fCapturePortList; jack_port_t** fPlaybackPortList; diff --git a/common/JackAudioAdapterInterface.cpp b/common/JackAudioAdapterInterface.cpp index b3401b03..21bef7f0 100644 --- a/common/JackAudioAdapterInterface.cpp +++ b/common/JackAudioAdapterInterface.cpp @@ -18,6 +18,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackAudioAdapter.h" +#include +#ifndef TARGET_OS_IPHONE +#include "JackLibSampleRateResampler.h" +#endif #include "JackTime.h" #include @@ -37,7 +41,7 @@ namespace Jack fTable[pos].pos2 = pos2; } - void MeasureTable::Save() + void MeasureTable::Save(unsigned int fHostBufferSize, unsigned int fHostSampleRate, unsigned int fAdaptedSampleRate, unsigned int fAdaptedBufferSize) { char buffer[1024]; FILE* file = fopen("JackAudioAdapter.log", "w"); @@ -54,6 +58,22 @@ namespace Jack // Adapter timing 1 file = fopen("AdapterTiming1.plot", "w"); + fprintf(file, "set multiplot\n"); + fprintf(file, "set grid\n"); + fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n" + ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize); + fprintf(file, "set xlabel \"audio cycles\"\n"); + fprintf(file, "set ylabel \"frames\"\n"); + fprintf(file, "plot "); + sprintf(buffer, "\"JackAudioAdapter.log\" using 2 title \"Consumer interrupt period\" with lines,"); + fprintf(file, buffer); + sprintf(buffer, "\"JackAudioAdapter.log\" using 3 title \"Producer interrupt period\" with lines"); + fprintf(file, buffer); + + fprintf(file, "\n unset multiplot\n"); + fprintf(file, "set output 'AdapterTiming1.pdf\n"); + fprintf(file, "set terminal pdf\n"); + fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); fprintf(file, "set title \"Audio adapter timing\"\n"); @@ -64,10 +84,27 @@ namespace Jack fprintf(file, buffer); sprintf(buffer, "\"JackAudioAdapter.log\" using 3 title \"Producer interrupt period\" with lines"); fprintf(file, buffer); + fclose(file); // Adapter timing 2 file = fopen("AdapterTiming2.plot", "w"); + fprintf(file, "set multiplot\n"); + fprintf(file, "set grid\n"); + fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n" + ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize); + fprintf(file, "set xlabel \"audio cycles\"\n"); + fprintf(file, "set ylabel \"resampling ratio\"\n"); + fprintf(file, "plot "); + sprintf(buffer, "\"JackAudioAdapter.log\" using 4 title \"Ratio 1\" with lines,"); + fprintf(file, buffer); + sprintf(buffer, "\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with lines"); + fprintf(file, buffer); + + fprintf(file, "\n unset multiplot\n"); + fprintf(file, "set output 'AdapterTiming2.pdf\n"); + fprintf(file, "set terminal pdf\n"); + fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); fprintf(file, "set title \"Audio adapter timing\"\n"); @@ -78,10 +115,27 @@ namespace Jack fprintf(file, buffer); sprintf(buffer, "\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with lines"); fprintf(file, buffer); + fclose(file); // Adapter timing 3 file = fopen("AdapterTiming3.plot", "w"); + fprintf(file, "set multiplot\n"); + fprintf(file, "set grid\n"); + fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n" + ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize); + fprintf(file, "set xlabel \"audio cycles\"\n"); + fprintf(file, "set ylabel \"frames\"\n"); + fprintf(file, "plot "); + sprintf(buffer, "\"JackAudioAdapter.log\" using 6 title \"Frames position in consumer ringbuffer\" with lines,"); + fprintf(file, buffer); + sprintf(buffer, "\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with lines"); + fprintf(file, buffer); + + fprintf(file, "\n unset multiplot\n"); + fprintf(file, "set output 'AdapterTiming3.pdf\n"); + fprintf(file, "set terminal pdf\n"); + fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); fprintf(file, "set title \"Audio adapter timing\"\n"); @@ -92,35 +146,32 @@ namespace Jack fprintf(file, buffer); sprintf(buffer, "\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with lines"); fprintf(file, buffer); + fclose(file); } #endif - + void JackAudioAdapterInterface::ResetRingBuffers() { - int i; - for (i = 0; i < fCaptureChannels; i++) + for (int i = 0; i < fCaptureChannels; i++) fCaptureRingBuffer[i]->Reset(); - for (i = 0; i < fPlaybackChannels; i++) + for (int i = 0; i < fPlaybackChannels; i++) fPlaybackRingBuffer[i]->Reset(); } - void JackAudioAdapterInterface::ResampleFactor ( jack_nframes_t& frame1, jack_nframes_t& frame2 ) + void JackAudioAdapterInterface::ResampleFactor ( jack_time_t& frame1, jack_time_t& frame2 ) { jack_time_t time = GetMicroSeconds(); - if ( !fRunning ) - { + if (!fRunning) { // Init DLL fRunning = true; - fHostDLL.Init ( time ); - fAdaptedDLL.Init ( time ); + fHostDLL.Init(time); + fAdaptedDLL.Init(time); frame1 = 1; frame2 = 1; - } - else - { + } else { // DLL fAdaptedDLL.IncFrame(time); jack_nframes_t time1 = fHostDLL.Time2Frames(time); @@ -131,15 +182,103 @@ namespace Jack long(time1), long(time2), double(time1) / double(time2), double(time2) / double(time1)); } } + + void JackAudioAdapterInterface::Reset() + { + ResetRingBuffers(); + fRunning = false; + } + +#ifdef TARGET_OS_IPHONE + void JackAudioAdapterInterface::Create() + {} +#else + void JackAudioAdapterInterface::Create() + { + //ringbuffers + fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; + fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; + for (int i = 0; i < fCaptureChannels; i++ ) + fCaptureRingBuffer[i] = new JackLibSampleRateResampler(fQuality, fRingbufferSize); + for (int i = 0; i < fPlaybackChannels; i++ ) + fPlaybackRingBuffer[i] = new JackLibSampleRateResampler(fQuality, fRingbufferSize); + + if (fCaptureChannels > 0) + jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace()); + if (fPlaybackChannels > 0) + jack_log("WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace()); + } +#endif + + void JackAudioAdapterInterface::Destroy() + { + for (int i = 0; i < fCaptureChannels; i++ ) + delete ( fCaptureRingBuffer[i] ); + for (int i = 0; i < fPlaybackChannels; i++ ) + delete ( fPlaybackRingBuffer[i] ); - int JackAudioAdapterInterface::Open() + delete[] fCaptureRingBuffer; + delete[] fPlaybackRingBuffer; + } + + int JackAudioAdapterInterface::PushAndPull(float** inputBuffer, float** outputBuffer, unsigned int frames) { - return 0; + bool failure = false; + jack_time_t time1, time2; + ResampleFactor(time1, time2); + + // Push/pull from ringbuffer + for (int i = 0; i < fCaptureChannels; i++) { + fCaptureRingBuffer[i]->SetRatio(time1, time2); + if (fCaptureRingBuffer[i]->WriteResample(inputBuffer[i], frames) < frames) + failure = true; + } + + for (int i = 0; i < fPlaybackChannels; i++) { + fPlaybackRingBuffer[i]->SetRatio(time2, time1); + if (fPlaybackRingBuffer[i]->ReadResample(outputBuffer[i], frames) < frames) + failure = true; + } + + #ifdef JACK_MONITOR + fTable.Write(time1, time2, double(time1) / double(time2), double(time2) / double(time1), + fCaptureRingBuffer[0]->ReadSpace(), fPlaybackRingBuffer[0]->WriteSpace()); + #endif + + // Reset all ringbuffers in case of failure + if (failure) { + jack_error("JackAudioAdapterInterface::PushAndPull ringbuffer failure... reset"); + ResetRingBuffers(); + return -1; + } else { + return 0; + } } - int JackAudioAdapterInterface::Close() + int JackAudioAdapterInterface::PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int frames) { - return 0; + bool failure = false; + fHostDLL.IncFrame(GetMicroSeconds()); + + // Push/pull from ringbuffer + for (int i = 0; i < fCaptureChannels; i++) { + if (fCaptureRingBuffer[i]->Read(inputBuffer[i], frames) < frames) + failure = true; + } + + for (int i = 0; i < fPlaybackChannels; i++) { + if (fPlaybackRingBuffer[i]->Write(outputBuffer[i], frames) < frames) + failure = true; + } + + // Reset all ringbuffers in case of failure + if (failure) { + jack_error("JackCallbackAudioAdapter::PullAndPush ringbuffer failure... reset"); + Reset(); + return -1; + } else { + return 0; + } } } // namespace diff --git a/common/JackAudioAdapterInterface.h b/common/JackAudioAdapterInterface.h index 81b6cc87..4b06d0d3 100644 --- a/common/JackAudioAdapterInterface.h +++ b/common/JackAudioAdapterInterface.h @@ -51,8 +51,8 @@ namespace Jack MeasureTable() :fCount ( 0 ) {} - void Write ( int time1, int time2, float r1, float r2, int pos1, int pos2 ); - void Save(); + void Write(int time1, int time2, float r1, float r2, int pos1, int pos2); + void Save(unsigned int fHostBufferSize, unsigned int fHostSampleRate, unsigned int fAdaptedSampleRate, unsigned int fAdaptedBufferSize); }; @@ -90,9 +90,13 @@ namespace Jack JackResampler** fPlaybackRingBuffer; unsigned int fQuality; - + unsigned int fRingbufferSize; + bool fRunning; - + + void ResetRingBuffers(); + void ResampleFactor ( jack_time_t& frame1, jack_time_t& frame2 ); + public: JackAudioAdapterInterface ( jack_nframes_t host_buffer_size, @@ -106,6 +110,7 @@ namespace Jack fHostDLL ( host_buffer_size, host_sample_rate ), fAdaptedDLL ( host_buffer_size, host_sample_rate ), fQuality(0), + fRingbufferSize(DEFAULT_RB_SIZE), fRunning ( false ) {} JackAudioAdapterInterface ( jack_nframes_t host_buffer_size, @@ -121,38 +126,33 @@ namespace Jack fHostDLL ( host_buffer_size, host_sample_rate ), fAdaptedDLL ( adapted_buffer_size, adapted_sample_rate ), fQuality(0), + fRingbufferSize(DEFAULT_RB_SIZE), fRunning ( false ) {} virtual ~JackAudioAdapterInterface() {} - void SetRingBuffers ( JackResampler** input, JackResampler** output ) - { - fCaptureRingBuffer = input; - fPlaybackRingBuffer = output; - } - bool IsRunning() { return fRunning; } - virtual void Reset() + virtual void Reset(); + + virtual void Create(); + virtual void Destroy(); + + virtual int Open() { - fRunning = false; + return 0; } - - void ResetRingBuffers(); - unsigned int GetQuality() + virtual int Close() { - return fQuality; + return 0; } - virtual int Open(); - virtual int Close(); - virtual int SetHostBufferSize ( jack_nframes_t buffer_size ) { fHostBufferSize = buffer_size; @@ -194,14 +194,7 @@ namespace Jack SetAdaptedSampleRate ( sample_rate ); return 0; } - - virtual void SetCallbackTime ( jack_time_t callback_usec ) - { - fHostDLL.IncFrame ( callback_usec ); - } - - void ResampleFactor ( jack_nframes_t& frame1, jack_nframes_t& frame2 ); - + void SetInputs ( int inputs ) { jack_log ( "JackAudioAdapterInterface::SetInputs %d", inputs ); @@ -225,6 +218,9 @@ namespace Jack jack_log ( "JackAudioAdapterInterface::GetOutputs %d", fPlaybackChannels ); return fPlaybackChannels; } + + int PushAndPull(float** inputBuffer, float** outputBuffer, unsigned int frames); + int PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int frames); }; diff --git a/common/JackLibSampleRateResampler.cpp b/common/JackLibSampleRateResampler.cpp index f7d90154..a2dfb472 100644 --- a/common/JackLibSampleRateResampler.cpp +++ b/common/JackLibSampleRateResampler.cpp @@ -31,8 +31,8 @@ JackLibSampleRateResampler::JackLibSampleRateResampler() jack_error("JackLibSampleRateResampler::JackLibSampleRateResampler err = %s", src_strerror(error)); } -JackLibSampleRateResampler::JackLibSampleRateResampler(unsigned int quality) - :JackResampler(),fRatio(1) +JackLibSampleRateResampler::JackLibSampleRateResampler(unsigned int quality, unsigned int ringbuffer_size) + :JackResampler(ringbuffer_size),fRatio(1) { switch (quality) { case 0: diff --git a/common/JackLibSampleRateResampler.h b/common/JackLibSampleRateResampler.h index 480097c9..bbb85cba 100644 --- a/common/JackLibSampleRateResampler.h +++ b/common/JackLibSampleRateResampler.h @@ -46,7 +46,7 @@ class JackLibSampleRateResampler : public JackResampler public: JackLibSampleRateResampler(); - JackLibSampleRateResampler(unsigned int quality); + JackLibSampleRateResampler(unsigned int quality, unsigned int ringbuffer_size); virtual ~JackLibSampleRateResampler(); unsigned int ReadResample(float* buffer, unsigned int frames); @@ -55,7 +55,7 @@ class JackLibSampleRateResampler : public JackResampler void SetRatio(unsigned int num, unsigned int denom) { JackResampler::SetRatio(num, denom); - fRatio = Range(0.25f, 4.0f, (double(num) / double(denom))); + fRatio = Range(0.25, 4.0, (double(num) / double(denom))); } void Reset(); diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index a0fb8d89..668ea4af 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -106,18 +106,16 @@ extern "C" typedef struct _jack_adapter jack_adapter_t; - SERVER_EXPORT jack_adapter_t* jack_create_adapter(jack_nframes_t host_buffer_size, + SERVER_EXPORT jack_adapter_t* jack_create_adapter(int input, int output, + jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_sample_rate); SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter); - SERVER_EXPORT int jack_adapter_push_input(jack_adapter_t* adapter, int channels, float** buffers); - SERVER_EXPORT int jack_adapter_pull_input(jack_adapter_t* adapter, int channels, float** buffers); - - SERVER_EXPORT int jack_adapter_push_output(jack_adapter_t* adapter, int channels, float** buffers); - SERVER_EXPORT int jack_adapter_pull_output(jack_adapter_t* adapter, int channels, float** buffers); - + SERVER_EXPORT int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); + SERVER_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); + #ifdef __cplusplus } #endif @@ -734,144 +732,39 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf struct JackNetAdapter : public JackAudioAdapterInterface { - JackNetAdapter(jack_nframes_t host_buffer_size, + JackNetAdapter(int input, int output, + jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_sample_rate) :JackAudioAdapterInterface(host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate) { - fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; - fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; - - /* - for (i = 0; i < fCaptureChannels; i++) - fCaptureRingBuffer[i] = new JackLibSampleRateResampler(fAudioAdapter->GetQuality()); - for (i = 0; i < fPlaybackChannels; i++) - fPlaybackRingBuffer[i] = new JackLibSampleRateResampler(fAudioAdapter->GetQuality()); - */ - - int i; - for (i = 0; i < fCaptureChannels; i++) - fCaptureRingBuffer[i] = new JackResampler(); - for (i = 0; i < fPlaybackChannels; i++) - fPlaybackRingBuffer[i] = new JackResampler(); - } - - virtual ~JackNetAdapter() - { - int i; - for (i = 0; i < fCaptureChannels; i++) - delete (fCaptureRingBuffer[i]); - for (i = 0; i < fPlaybackChannels; i++) - delete(fPlaybackRingBuffer[i] ); - - delete[] fCaptureRingBuffer; - delete[] fPlaybackRingBuffer; - } - - void Reset() - { - int i; - for (i = 0; i < fCaptureChannels; i++) - fCaptureRingBuffer[i]->Reset(); - for (i = 0; i < fPlaybackChannels; i++) - fPlaybackRingBuffer[i]->Reset(); - } - - int PushInput(int audio_input, float** audio_input_buffer) - { - bool failure = false; - int port_index; - - // Get the resample factor, - jack_nframes_t time1, time2; - ResampleFactor(time1, time2); - - // Resample input data, - for (port_index = 0; port_index < audio_input; port_index++) { - fCaptureRingBuffer[port_index]->SetRatio(time1, time2); - if (fCaptureRingBuffer[port_index]->WriteResample(audio_input_buffer[port_index], fAdaptedBufferSize) < fAdaptedBufferSize) - failure = true; - } - - if (failure) { - ResetRingBuffers(); - return -1; - } - - return 0; + fCaptureChannels = input; + fPlaybackChannels = output; + Create(); } - int PullInput(int audio_input, float** audio_input_buffer) + void JackNetAdapter::Create() { - bool failure = false; - int port_index; - - // DLL - SetCallbackTime(GetMicroSeconds()); - - // Push/pull from ringbuffer - for (port_index = 0; port_index < audio_input; port_index++) { - if (fCaptureRingBuffer[port_index]->Read(audio_input_buffer[port_index], fHostBufferSize) < fHostBufferSize) - failure = true; - } - - // Reset all ringbuffers in case of failure - if (failure) { - Reset(); - return -1; - } - - return 0; - } - - int PushOutput(int audio_input, float** audio_input_buffer) - { - bool failure = false; - int port_index; - - // DLL - SetCallbackTime(GetMicroSeconds()); + //ringbuffers + fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; + fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; + for (int i = 0; i < fCaptureChannels; i++ ) + fCaptureRingBuffer[i] = new JackResampler(fRingbufferSize); + for (int i = 0; i < fPlaybackChannels; i++ ) + fPlaybackRingBuffer[i] = new JackResampler(fRingbufferSize); - // Push/pull from ringbuffer - for (port_index = 0; port_index < audio_input; port_index++) { - if (fPlaybackRingBuffer[port_index]->Write(audio_input_buffer[port_index], fHostBufferSize) < fHostBufferSize) - failure = true; - } - - // Reset all ringbuffers in case of failure - if (failure) { - Reset(); - return -1; - } - - return 0; + if (fCaptureChannels > 0) + jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace()); + if (fPlaybackChannels > 0) + jack_log("WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace()); } - int PullOutput(int audio_output, float** audio_output_buffer) + virtual ~JackNetAdapter() { - bool failure = false; - int port_index; - - //get the resample factor, - jack_nframes_t time1, time2; - ResampleFactor(time1, time2); - - //resample output data, - for (port_index = 0; port_index < fPlaybackChannels; port_index++) { - fPlaybackRingBuffer[port_index]->SetRatio(time2, time1); - if (fPlaybackRingBuffer[port_index]->ReadResample(audio_output_buffer[port_index], fAdaptedBufferSize) < fAdaptedBufferSize) - failure = true; - } - - if (failure) { - ResetRingBuffers(); - return -1; - } - - return 0; + Destroy(); } - + }; @@ -968,12 +861,13 @@ SERVER_EXPORT int jack_net_master_send(jack_net_master_t* net, int audio_output, // Adapter API -SERVER_EXPORT jack_adapter_t* jack_create_adapter(jack_nframes_t host_buffer_size, +SERVER_EXPORT jack_adapter_t* jack_create_adapter(int input, int output, + jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_sample_rate) { - return (jack_adapter_t*)new JackNetAdapter(host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate); + return (jack_adapter_t*)new JackNetAdapter(input, output, host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate); } SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter) @@ -982,30 +876,18 @@ SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter) return 0; } -SERVER_EXPORT int jack_adapter_push_input(jack_adapter_t * adapter, int channels, float** buffers) +SERVER_EXPORT int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames) { JackNetAdapter* slave = (JackNetAdapter*)adapter; - return slave->PushInput(channels, buffers); + return slave->PushAndPull(input, output, frames); } -SERVER_EXPORT int jack_adapter_pull_input(jack_adapter_t * adapter, int channels, float** buffers) +SERVER_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames) { JackNetAdapter* slave = (JackNetAdapter*)adapter; - return slave->PullInput(channels, buffers); -} - -SERVER_EXPORT int jack_adapter_push_output(jack_adapter_t * adapter, int channels, float** buffers) -{ - JackNetAdapter* slave = (JackNetAdapter*)adapter; - return slave->PushOutput(channels, buffers); + return slave->PullAndPush(input, output, frames); } -SERVER_EXPORT int jack_adapter_pull_output(jack_adapter_t * adapter, int channels, float** buffers) -{ - JackNetAdapter* slave = (JackNetAdapter*)adapter; - return slave->PullOutput(channels, buffers); -} - // Empty code for now.. //#ifdef TARGET_OS_IPHONE diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index 3c088eb7..a5b85b63 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -367,7 +367,7 @@ namespace Jack return SOCKET_ERROR; //get the resample factor, - jack_nframes_t time1, time2; + jack_time_t time1, time2; ResampleFactor ( time1, time2 ); //resample input data, diff --git a/common/JackResampler.cpp b/common/JackResampler.cpp index f09b0413..19945adf 100644 --- a/common/JackResampler.cpp +++ b/common/JackResampler.cpp @@ -18,6 +18,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackResampler.h" +#include namespace Jack { @@ -28,6 +29,12 @@ JackResampler::JackResampler():fNum(1),fDenom(1) jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * DEFAULT_RB_SIZE) / 2); } +JackResampler::JackResampler(unsigned int ringbuffer_size):fNum(1),fDenom(1),fRingBufferSize(ringbuffer_size) +{ + fRingBuffer = jack_ringbuffer_create(sizeof(float) * fRingBufferSize); + jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize) / 2); +} + JackResampler::~JackResampler() { if (fRingBuffer) @@ -36,7 +43,8 @@ JackResampler::~JackResampler() void JackResampler::Reset() { - jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * DEFAULT_RB_SIZE) / 2); + jack_ringbuffer_reset(fRingBuffer); + jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize) / 2); } unsigned int JackResampler::ReadSpace() diff --git a/common/JackResampler.h b/common/JackResampler.h index d656d59d..fb6e30f2 100644 --- a/common/JackResampler.h +++ b/common/JackResampler.h @@ -40,10 +40,12 @@ class JackResampler jack_ringbuffer_t* fRingBuffer; unsigned int fNum; unsigned int fDenom; - + unsigned int fRingBufferSize; + public: JackResampler(); + JackResampler(unsigned int ringbuffer_size); virtual ~JackResampler(); virtual void Reset(); diff --git a/common/jack/net.h b/common/jack/net.h index 940a0692..ba1dd0dc 100644 --- a/common/jack/net.h +++ b/common/jack/net.h @@ -255,7 +255,8 @@ typedef struct _jack_adapter jack_adapter_t; * * @return 0 on success, otherwise a non-zero error code */ -jack_adapter_t* jack_create_adapter(jack_nframes_t host_buffer_size, +jack_adapter_t* jack_create_adapter(int input, int output, + jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_sample_rate); @@ -268,32 +269,18 @@ jack_adapter_t* jack_create_adapter(jack_nframes_t host_buffer_size, int jack_destroy_adapter(jack_adapter_t* adapter); /** - * Push input to ringbuffer + * Push input to and pull output from ringbuffer * * @return 0 on success, otherwise a non-zero error code */ -int jack_adapter_push_input(jack_adapter_t * adapter, int channels, float** buffers); +int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); /** - * Pull input from ringbuffer + * Pull input to and push output from ringbuffer * * @return 0 on success, otherwise a non-zero error code */ -int jack_adapter_pull_input(jack_adapter_t * adapter, int channels, float** buffers); - -/** - * Push output to ringbuffer - * - * @return error code. - */ -int jack_adapter_push_output(jack_adapter_t * adapter, int channels, float** buffers); - -/** - * Pull output from ringbuffer - * - * @return 0 on success, otherwise a non-zero error code - */ -int jack_adapter_pull_output(jack_adapter_t * adapter, int channels, float** buffers); +int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); #ifdef __cplusplus diff --git a/common/wscript b/common/wscript index 0156c274..adddc27a 100644 --- a/common/wscript +++ b/common/wscript @@ -182,9 +182,15 @@ def build(bld): netlib.includes = includes netlib.name = 'netlib' netlib.target = 'jacknet' - netlib.uselib = uselib + netlib.uselib = 'SAMPLERATE' netlib.install_path = '${LIBDIR}' - netlib.source = ['JackNetAPI.cpp', 'JackNetInterface.cpp', 'JackNetTool.cpp', 'JackAudioAdapterInterface.cpp', 'JackResampler.cpp', 'ringbuffer.c'] + netlib.source = ['JackNetAPI.cpp', + 'JackNetInterface.cpp', + 'JackNetTool.cpp', + 'JackAudioAdapterInterface.cpp', + 'JackLibSampleRateResampler.cpp', + 'JackResampler.cpp', + 'ringbuffer.c'] if bld.env['IS_LINUX']: netlib.source += ['../posix/JackNetUnixSocket.cpp','../posix/JackPosixThread.cpp', '../linux/JackLinuxTime.c'] diff --git a/linux/alsa/JackAlsaAdapter.cpp b/linux/alsa/JackAlsaAdapter.cpp index 66de67af..b12e4ccd 100644 --- a/linux/alsa/JackAlsaAdapter.cpp +++ b/linux/alsa/JackAlsaAdapter.cpp @@ -66,14 +66,19 @@ namespace Jack fAudioInterface.fCardName = strdup ( param->value.str ); break; case 'r': + fAudioInterface.fFrequency = param->value.ui; SetAdaptedSampleRate ( param->value.ui ); break; case 'p': + fAudioInterface.fBuffering = param->value.ui; SetAdaptedBufferSize ( param->value.ui ); break; case 'q': fQuality = param->value.ui; break; + case 'g': + fRingbufferSize = param->value.ui; + break; } } @@ -106,7 +111,7 @@ namespace Jack int JackAlsaAdapter::Close() { #ifdef JACK_MONITOR - fTable.Save(); + fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize); #endif switch ( fThread.GetStatus() ) { @@ -147,46 +152,15 @@ namespace Jack bool JackAlsaAdapter::Execute() { //read data from audio interface - if ( fAudioInterface.read() < 0 ) + if (fAudioInterface.read() < 0) return false; - - bool failure = false; - - //compute resampling factor - jack_nframes_t time1, time2; - ResampleFactor ( time1, time2 ); - - //resample inputs - for ( int i = 0; i < fCaptureChannels; i++ ) - { - fCaptureRingBuffer[i]->SetRatio ( time1, time2 ); - if ( fCaptureRingBuffer[i]->WriteResample ( fAudioInterface.fInputSoftChannels[i], fAdaptedBufferSize ) < fAdaptedBufferSize ) - failure = true; - } - //resample outputs - for ( int i = 0; i < fPlaybackChannels; i++ ) - { - fPlaybackRingBuffer[i]->SetRatio ( time2, time1 ); - if ( fPlaybackRingBuffer[i]->ReadResample ( fAudioInterface.fOutputSoftChannels[i], fAdaptedBufferSize ) < fAdaptedBufferSize ) - failure = true; - } - -#ifdef JACK_MONITOR - fTable.Write ( time1, time2, double ( time1 ) / double ( time2 ), double ( time2 ) / double ( time1 ), - fCaptureRingBuffer[0]->ReadSpace(), fPlaybackRingBuffer[0]->WriteSpace() ); -#endif + + PushAndPull(fAudioInterface.fInputSoftChannels, fAudioInterface.fOutputSoftChannels, fAdaptedBufferSize); //write data to audio interface - if ( fAudioInterface.write() < 0 ) + if (fAudioInterface.write() < 0) return false; - //reset all ringbuffers in case of failure - if ( failure ) - { - jack_error ( "JackAlsaAdapter::Execute ringbuffer failure... reset" ); - ResetRingBuffers(); - } - return true; } @@ -220,7 +194,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 = 10; + desc->nparams = 11; desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) ); i = 0; @@ -299,7 +273,6 @@ extern "C" strcpy ( desc->params[i].short_desc, "Number of playback channels (defaults to hardware max)" ); strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); - i++; strcpy(desc->params[i].name, "quality"); @@ -308,6 +281,14 @@ 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'; + desc->params[i].type = JackDriverParamInt; + desc->params[i].value.ui = 0; + strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 32768)"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); return desc; } diff --git a/linux/alsa/JackAlsaAdapter.h b/linux/alsa/JackAlsaAdapter.h index 65431db2..8cdde0ee 100644 --- a/linux/alsa/JackAlsaAdapter.h +++ b/linux/alsa/JackAlsaAdapter.h @@ -182,6 +182,17 @@ namespace Jack fInputParams = 0; fOutputParams = 0; fPeriod = 2; + + fInputCardBuffer = 0; + fOutputCardBuffer = 0; + + for ( int i = 0; i < 256; i++ ) + { + fInputCardChannels[i] = 0; + fOutputCardChannels[i] = 0; + fInputSoftChannels[i] = 0; + fOutputSoftChannels[i] = 0; + } } AudioInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ) : @@ -369,10 +380,10 @@ namespace Jack } else // SND_PCM_FORMAT_S32 { - long* buffer32b = ( long* ) fInputCardBuffer; + int32_t* buffer32b = ( int32_t* ) fInputCardBuffer; for ( s = 0; s < fBuffering; s++ ) for ( c = 0; c < fCardInputs; c++ ) - fInputSoftChannels[c][s] = float ( buffer32b[c + s*fCardInputs] ) * ( 1.0/float ( LONG_MAX ) ); + fInputSoftChannels[c][s] = float ( buffer32b[c + s*fCardInputs] ) * ( 1.0/float ( INT_MAX ) ); } break; case SND_PCM_ACCESS_RW_NONINTERLEAVED : @@ -394,12 +405,12 @@ namespace Jack } else // SND_PCM_FORMAT_S32 { - long* chan32b; + int32_t* chan32b; for ( c = 0; c < fCardInputs; c++ ) { - chan32b = ( long* ) fInputCardChannels[c]; + chan32b = ( int32_t* ) fInputCardChannels[c]; for ( s = 0; s < fBuffering; s++ ) - fInputSoftChannels[c][s] = float ( chan32b[s] ) * ( 1.0/float ( LONG_MAX ) ); + fInputSoftChannels[c][s] = float ( chan32b[s] ) * ( 1.0/float ( INT_MAX ) ); } } break; @@ -436,13 +447,13 @@ namespace Jack } else // SND_PCM_FORMAT_S32 { - long* buffer32b = ( long* ) fOutputCardBuffer; + int32_t* buffer32b = ( int32_t* ) fOutputCardBuffer; for ( f = 0; f < fBuffering; f++ ) { for ( unsigned int c = 0; c < fCardOutputs; c++ ) { float x = fOutputSoftChannels[c][f]; - buffer32b[c + f * fCardOutputs] = long ( max ( min ( x, 1.0 ), -1.0 ) * float ( LONG_MAX ) ); + buffer32b[c + f * fCardOutputs] = int32_t ( max ( min ( x, 1.0 ), -1.0 ) * float ( INT_MAX ) ); } } } @@ -472,11 +483,11 @@ namespace Jack { for ( c = 0; c < fCardOutputs; c++ ) { - long* chan32b = ( long* ) fOutputCardChannels[c]; + int32_t* chan32b = ( int32_t* ) fOutputCardChannels[c]; for ( f = 0; f < fBuffering; f++ ) { float x = fOutputSoftChannels[c][f]; - chan32b[f] = long ( max ( min ( x,1.0 ),-1.0 ) * float ( LONG_MAX ) ) ; + chan32b[f] = int32_t ( max ( min ( x,1.0 ),-1.0 ) * float ( INT_MAX ) ) ; } } } diff --git a/macosx/coreaudio/JackCoreAudioAdapter.cpp b/macosx/coreaudio/JackCoreAudioAdapter.cpp index f222e3e9..18882f9b 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.cpp +++ b/macosx/coreaudio/JackCoreAudioAdapter.cpp @@ -293,38 +293,22 @@ OSStatus JackCoreAudioAdapter::Render(void *inRefCon, { JackCoreAudioAdapter* adapter = static_cast(inRefCon); AudioUnitRender(adapter->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, adapter->fInputData); - bool failure = false; - - jack_nframes_t time1, time2; - adapter->ResampleFactor(time1, time2); - + + float* inputBuffer[adapter->fCaptureChannels]; + float* outputBuffer[adapter->fPlaybackChannels]; + for (int i = 0; i < adapter->fCaptureChannels; i++) { - adapter->fCaptureRingBuffer[i]->SetRatio(time1, time2); - if (adapter->fCaptureRingBuffer[i]->WriteResample((float*)adapter->fInputData->mBuffers[i].mData, inNumberFrames) < inNumberFrames) - failure = true; + inputBuffer[i] = (float*)adapter->fInputData->mBuffers[i].mData; } - for (int i = 0; i < adapter->fPlaybackChannels; i++) { - adapter->fPlaybackRingBuffer[i]->SetRatio(time2, time1); - if (adapter->fPlaybackRingBuffer[i]->ReadResample((float*)ioData->mBuffers[i].mData, inNumberFrames) < inNumberFrames) - failure = true; - } - -#ifdef JACK_MONITOR - adapter->fTable.Write(time1, time2, double(time1) / double(time2), double(time2) / double(time1), - adapter->fCaptureRingBuffer[0]->ReadSpace(), adapter->fPlaybackRingBuffer[0]->WriteSpace()); -#endif - - // Reset all ringbuffers in case of failure - if (failure) { - jack_error("JackCoreAudioAdapter::Render ringbuffer failure... reset"); - adapter->ResetRingBuffers(); + outputBuffer[i] = (float*)ioData->mBuffers[i].mData; } - + + adapter->PushAndPull((float**)inputBuffer, (float**)outputBuffer, inNumberFrames); return noErr; } - JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params) +JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params) :JackAudioAdapterInterface(buffer_size, sample_rate), fInputData(0), fCapturing(false), fPlaying(false), fState(false) { @@ -392,6 +376,10 @@ OSStatus JackCoreAudioAdapter::Render(void *inRefCon, case 'q': fQuality = param->value.ui; break; + + case 'g': + fRingbufferSize = param->value.ui; + break; } } @@ -960,7 +948,7 @@ int JackCoreAudioAdapter::Open() int JackCoreAudioAdapter::Close() { #ifdef JACK_MONITOR - fTable.Save(); + fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize); #endif AudioOutputUnitStop(fAUHAL); DisposeBuffers(); @@ -997,7 +985,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 = 11; + desc->nparams = 12; desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); i = 0; @@ -1087,6 +1075,14 @@ 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'; + desc->params[i].type = JackDriverParamInt; + desc->params[i].value.ui = 0; + strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 32768)"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); return desc; } diff --git a/solaris/oss/JackOSSAdapter.cpp b/solaris/oss/JackOSSAdapter.cpp index e74b7430..69a59ec7 100644 --- a/solaris/oss/JackOSSAdapter.cpp +++ b/solaris/oss/JackOSSAdapter.cpp @@ -181,6 +181,10 @@ JackOSSAdapter::JackOSSAdapter(jack_nframes_t buffer_size, jack_nframes_t sample case 'q': fQuality = param->value.ui; break; + + case 'g': + fRingbufferSize = param->value.ui; + break; } } @@ -502,10 +506,9 @@ error: int JackOSSAdapter::Close() { -#ifdef DEBUG - fTable.Save(); +#ifdef JACK_MONITOR + fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize); #endif - fThread.Stop(); CloseAux(); return 0; @@ -600,38 +603,16 @@ int JackOSSAdapter::Write() bool JackOSSAdapter::Execute() { + //read data from audio interface if (Read() < 0) return false; - - bool failure = false; - jack_nframes_t time1, time2; - ResampleFactor(time1, time2); - - for (int i = 0; i < fCaptureChannels; i++) { - fCaptureRingBuffer[i]->SetRatio(time1, time2); - if (fCaptureRingBuffer[i]->WriteResample(fInputSampleBuffer[i], fAdaptedBufferSize) < fAdaptedBufferSize) - failure = true; - } - - for (int i = 0; i < fPlaybackChannels; i++) { - fPlaybackRingBuffer[i]->SetRatio(time2, time1); - if (fPlaybackRingBuffer[i]->ReadResample(fOutputSampleBuffer[i], fAdaptedBufferSize) < fAdaptedBufferSize) - failure = true; - } - -#ifdef DEBUG - fTable.Write(time1, time2, double(time1) / double(time2), double(time2) / double(time1), - fCaptureRingBuffer[0]->ReadSpace(), fPlaybackRingBuffer[0]->WriteSpace()); -#endif + PushAndPull(fInputSampleBuffer, fOutputSampleBuffer, fAdaptedBufferSize); + + //write data to audio interface if (Write() < 0) return false; - - // Reset all ringbuffers in case of failure - if (failure) { - jack_error("JackOSSAdapter::Execute ringbuffer failure... reset"); - ResetRingBuffers(); - } + return true; } @@ -756,6 +737,14 @@ 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'; + desc->params[i].type = JackDriverParamInt; + desc->params[i].value.ui = 0; + strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 32768)"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); return desc; } diff --git a/solaris/oss/JackOSSAdapter.h b/solaris/oss/JackOSSAdapter.h index 1a6dbe21..6e739f88 100644 --- a/solaris/oss/JackOSSAdapter.h +++ b/solaris/oss/JackOSSAdapter.h @@ -34,7 +34,7 @@ namespace Jack typedef jack_default_audio_sample_t jack_sample_t; -#define OSS_DRIVER_N_PARAMS 12 +#define OSS_DRIVER_N_PARAMS 13 #define OSS_DRIVER_DEF_DEV "/dev/dsp" #define OSS_DRIVER_DEF_FS 48000 #define OSS_DRIVER_DEF_BLKSIZE 1024 diff --git a/windows/portaudio/JackPortAudioAdapter.cpp b/windows/portaudio/JackPortAudioAdapter.cpp index 2f3ba46e..a5beb232 100644 --- a/windows/portaudio/JackPortAudioAdapter.cpp +++ b/windows/portaudio/JackPortAudioAdapter.cpp @@ -27,47 +27,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { - int JackPortAudioAdapter::Render ( const void* inputBuffer, - void* outputBuffer, - unsigned long framesPerBuffer, - const PaStreamCallbackTimeInfo* timeInfo, - PaStreamCallbackFlags statusFlags, - void* userData) + int JackPortAudioAdapter::Render(const void* inputBuffer, + void* outputBuffer, + unsigned long framesPerBuffer, + const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags, + void* userData) { JackPortAudioAdapter* adapter = static_cast(userData); - float** paBuffer; - bool failure = false; - - jack_nframes_t time1, time2; - adapter->ResampleFactor ( time1, time2 ); - - paBuffer = (float**)inputBuffer; - for ( int i = 0; i < adapter->fCaptureChannels; i++ ) - { - adapter->fCaptureRingBuffer[i]->SetRatio ( time1, time2 ); - if (adapter->fCaptureRingBuffer[i]->WriteResample ( (float*)paBuffer[i], framesPerBuffer ) < framesPerBuffer ) - failure = true; - } - - paBuffer = (float**)outputBuffer; - for ( int i = 0; i < adapter->fPlaybackChannels; i++ ) - { - adapter->fPlaybackRingBuffer[i]->SetRatio ( time2, time1 ); - if ( adapter->fPlaybackRingBuffer[i]->ReadResample ( (float*)paBuffer[i], framesPerBuffer ) < framesPerBuffer ) - failure = true; - } - -#ifdef JACK_MONITOR - adapter->fTable.Write ( time1, time2, double(time1) / double(time2), double(time2) / double(time1), - adapter->fCaptureRingBuffer[0]->ReadSpace(), adapter->fPlaybackRingBuffer[0]->WriteSpace() ); -#endif - - // Reset all ringbuffers in case of failure - if ( failure ) - { - jack_error ( "JackPortAudioAdapter::Render ringbuffer failure... reset" ); - adapter->ResetRingBuffers(); - } + adapter->PushAndPull((float**)inputBuffer, (float**)outputBuffer, framesPerBuffer); return paContinue; } @@ -128,6 +96,9 @@ namespace Jack case 'q': fQuality = param->value.ui; break; + case 'g': + fRingbufferSize = param->value.ui; + break; } } @@ -207,7 +178,7 @@ namespace Jack int JackPortAudioAdapter::Close() { #ifdef JACK_MONITOR - fTable.Save(); + fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize); #endif jack_log ( "JackPortAudioAdapter::Close" ); Pa_StopStream ( fStream ); @@ -246,8 +217,8 @@ 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 = 9; + + desc->nparams = 10; desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); i = 0; @@ -314,7 +285,7 @@ extern "C" desc->params[i].value.i = TRUE; strcpy(desc->params[i].short_desc, "Display available PortAudio devices"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); - + i++; strcpy(desc->params[i].name, "quality"); desc->params[i].character = 'q'; @@ -323,6 +294,14 @@ extern "C" 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'; + desc->params[i].type = JackDriverParamInt; + desc->params[i].value.ui = 0; + strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 32768)"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + return desc; } From aa1570327c05c002cf5061100dfed1bc5d4daae9 Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 2 Mar 2009 13:43:58 +0000 Subject: [PATCH 010/472] Compiles on Linux again. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3369 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackAudioAdapterInterface.cpp | 2 ++ common/JackNetAPI.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/common/JackAudioAdapterInterface.cpp b/common/JackAudioAdapterInterface.cpp index 21bef7f0..0e666f3b 100644 --- a/common/JackAudioAdapterInterface.cpp +++ b/common/JackAudioAdapterInterface.cpp @@ -18,7 +18,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackAudioAdapter.h" +#ifdef __APPLE__ #include +#endif #ifndef TARGET_OS_IPHONE #include "JackLibSampleRateResampler.h" #endif diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 668ea4af..19bfdc8a 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -744,7 +744,7 @@ struct JackNetAdapter : public JackAudioAdapterInterface { Create(); } - void JackNetAdapter::Create() + void Create() { //ringbuffers fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; From 62966c288cfe8b948434cd05d09083a15ff7a5a4 Mon Sep 17 00:00:00 2001 From: sletz Date: Thu, 5 Mar 2009 16:07:14 +0000 Subject: [PATCH 011/472] rebase form trunk 3367:3401 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3402 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 13 +++ common/JackAudioAdapter.cpp | 42 ++++++++ common/JackAudioAdapter.h | 7 +- common/JackConstants.h | 2 +- common/JackEngineProfiling.cpp | 186 ++++++++++++++++++--------------- common/JackEngineProfiling.h | 42 +++++++- common/JackNetAPI.cpp | 44 +++----- common/JackNetAdapter.cpp | 66 ++++-------- common/JackNetAdapter.h | 4 +- common/JackNetDriver.cpp | 21 ++-- common/JackNetDriver.h | 4 +- common/JackNetInterface.cpp | 60 +++++------ common/JackNetInterface.h | 16 +-- common/JackNetManager.cpp | 91 ++++++++++------ common/JackNetManager.h | 16 +-- common/JackNetTool.cpp | 59 +++++++++++ common/JackNetTool.h | 13 +++ common/JackProfiler.cpp | 6 +- solaris/oss/JackOSSDriver.cpp | 57 +--------- windows/README | 12 ++- windows/Setup/jack.ci | 4 +- windows/Setup/src/README | 2 +- wscript | 4 +- 23 files changed, 440 insertions(+), 331 deletions(-) diff --git a/ChangeLog b/ChangeLog index c2361d74..e23d51ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,19 @@ Michael Voigt Jackdmp changes log --------------------------- +2009-03-05 Stephane Letz + + * Support for BIG_ENDIAN machines in NetJack2 for transport data. + * Add auto_connect parameter in netmanager and netadapter. + +2009-03-03 Stephane Letz + + * More robust profiling tools when clients come and go. + +2009-03-01 Stephane Letz + + * Raise default port number to 1024. + 2009-02-27 Stephane Letz * Improve generated gnuplot files for adapting code. diff --git a/common/JackAudioAdapter.cpp b/common/JackAudioAdapter.cpp index 06f7e0f1..6961a06f 100644 --- a/common/JackAudioAdapter.cpp +++ b/common/JackAudioAdapter.cpp @@ -69,6 +69,24 @@ namespace Jack } //JackAudioAdapter ********************************************************* + + JackAudioAdapter::JackAudioAdapter (jack_client_t* jack_client, JackAudioAdapterInterface* audio_io, const JSList* params, bool system) + :fJackClient(jack_client), fAudioAdapter(audio_io) + { + const JSList* node; + const jack_driver_param_t* param; + fAutoConnect = false; + + for (node = params; node; node = jack_slist_next(node)) { + param = (const jack_driver_param_t*) node->data; + switch (param->character) { + case 'c': + fAutoConnect = param->value.i; + break; + } + } + } + JackAudioAdapter::~JackAudioAdapter() { // When called, Close has already been used for the client, thus ports are already unregistered. @@ -87,6 +105,27 @@ namespace Jack delete[] fCapturePortList; delete[] fPlaybackPortList; } + + void JackAudioAdapter::ConnectPorts() + { + const char **ports; + + ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput); + if (ports != NULL) { + for (int i = 0; i < fAudioAdapter->GetInputs() && ports[i]; i++) { + jack_connect(fJackClient,jack_port_name(fCapturePortList[i]), ports[i]); + } + free(ports); + } + + ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); + if (ports != NULL) { + for (int i = 0; i < fAudioAdapter->GetOutputs() && ports[i]; i++) { + jack_connect(fJackClient, ports[i], jack_port_name(fPlaybackPortList[i])); + } + free(ports); + } + } void JackAudioAdapter::Reset() { @@ -126,6 +165,9 @@ namespace Jack goto fail; if ( jack_activate ( fJackClient ) < 0 ) goto fail; + + if (fAutoConnect) + ConnectPorts(); // Ring buffer are now allocated.. return fAudioAdapter->Open(); diff --git a/common/JackAudioAdapter.h b/common/JackAudioAdapter.h index 1a15c2a0..0eb93eed 100644 --- a/common/JackAudioAdapter.h +++ b/common/JackAudioAdapter.h @@ -21,6 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #define __JackAudioAdapter__ #include "JackAudioAdapterInterface.h" +#include "driver_interface.h" namespace Jack { @@ -42,15 +43,15 @@ namespace Jack jack_client_t* fJackClient; JackAudioAdapterInterface* fAudioAdapter; + bool fAutoConnect; void FreePorts(); + void ConnectPorts(); void Reset(); public: - JackAudioAdapter ( jack_client_t* jack_client, JackAudioAdapterInterface* audio_io ) : - fJackClient ( jack_client ), fAudioAdapter ( audio_io ) - {} + JackAudioAdapter(jack_client_t* jack_client, JackAudioAdapterInterface* audio_io, const JSList* params = NULL, bool system = false); ~JackAudioAdapter(); int Open(); diff --git a/common/JackConstants.h b/common/JackConstants.h index ce785601..d2af693e 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -34,7 +34,7 @@ #define JACK_CLIENT_NAME_SIZE 64 #ifndef PORT_NUM -#define PORT_NUM 512 +#define PORT_NUM 1024 #endif #define DRIVER_PORT_NUM 256 diff --git a/common/JackEngineProfiling.cpp b/common/JackEngineProfiling.cpp index f9f29727..a0c81afe 100644 --- a/common/JackEngineProfiling.cpp +++ b/common/JackEngineProfiling.cpp @@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -JackEngineProfiling::JackEngineProfiling():fAudioCycle(0) +JackEngineProfiling::JackEngineProfiling():fAudioCycle(0),fMeasuredClient(0) { jack_info("Engine profiling activated, beware %ld MBytes are needed to record profiling points...", sizeof(fProfileTable) / (1024 * 1024)); @@ -36,66 +36,59 @@ JackEngineProfiling::JackEngineProfiling():fAudioCycle(0) JackEngineProfiling::~JackEngineProfiling() { - // Window monitoring - int max_client = 0; - char buffer[1024]; - char* nameTable[CLIENT_NUM]; FILE* file = fopen("JackEngineProfiling.log", "w"); + char buffer[1024]; jack_info("Write server and clients timing data..."); if (file == NULL) { jack_error("JackEngineProfiling::Save cannot open JackEngineProfiling.log file"); } else { - + + // For each measured point for (int i = 2; i < TIME_POINTS; i++) { - bool header = true; - bool printed = false; - int count = 0; - for (int j = REAL_REFNUM; j < CLIENT_NUM; j++) { - if (fProfileTable[i].fClientTable[j].fRefNum > 0) { - long d1 = long(fProfileTable[i - 1].fCurCycleBegin - fProfileTable[i - 2].fCurCycleBegin); - long d2 = long(fProfileTable[i].fPrevCycleEnd - fProfileTable[i - 1].fCurCycleBegin); - if (d1 > 0 && fProfileTable[i].fClientTable[j].fStatus != NotTriggered) { // Valid cycle - count++; - nameTable[count] = fNameTable[fProfileTable[i].fClientTable[j].fRefNum]; - - // driver delta and end cycle - if (header) { - fprintf(file, "%ld \t %ld \t", d1, d2); - header = false; - } - long d5 = long(fProfileTable[i].fClientTable[j].fSignaledAt - fProfileTable[i - 1].fCurCycleBegin); - long d6 = long(fProfileTable[i].fClientTable[j].fAwakeAt - fProfileTable[i - 1].fCurCycleBegin); - long d7 = long(fProfileTable[i].fClientTable[j].fFinishedAt - fProfileTable[i - 1].fCurCycleBegin); - - // ref, signal, start, end, scheduling, duration, status - fprintf(file, "%d \t %ld \t %ld \t %ld \t %ld \t %ld \t %d \t", - fProfileTable[i].fClientTable[j].fRefNum, - ((d5 > 0) ? d5 : 0), - ((d6 > 0) ? d6 : 0), - ((d7 > 0) ? d7 : 0), - ((d6 > 0 && d5 > 0) ? (d6 - d5) : 0), - ((d7 > 0 && d6 > 0) ? (d7 - d6) : 0), - fProfileTable[i].fClientTable[j].fStatus); - printed = true; - } - } - max_client = (count > max_client) ? count : max_client; - } - if (printed) { - fprintf(file, "\n"); - } else if (fProfileTable[i].fAudioCycle > 0) { // Driver timing only - long d1 = long(fProfileTable[i].fCurCycleBegin - fProfileTable[i - 1].fCurCycleBegin); - long d2 = long(fProfileTable[i].fPrevCycleEnd - fProfileTable[i - 1].fCurCycleBegin); - if (d1 > 0) { // Valid cycle - fprintf(file, "%ld \t %ld \n", d1, d2); + + // Driver timing values + long d1 = long(fProfileTable[i].fCurCycleBegin - fProfileTable[i - 1].fCurCycleBegin); + long d2 = long(fProfileTable[i].fPrevCycleEnd - fProfileTable[i - 1].fCurCycleBegin); + + if (d1 <= 0 || fProfileTable[i].fAudioCycle <= 0) + continue; // Skip non valid cycles + + // Print driver delta and end cycle + fprintf(file, "%ld \t %ld \t", d1, d2); + + // For each measured client + for (unsigned int j = 0; j < fMeasuredClient; j++) { + + int ref = fIntervalTable[j].fRefNum; + + // Is valid client cycle + if (fProfileTable[i].fClientTable[ref].fStatus != NotTriggered) { + + long d5 = long(fProfileTable[i].fClientTable[ref].fSignaledAt - fProfileTable[i - 1].fCurCycleBegin); + long d6 = long(fProfileTable[i].fClientTable[ref].fAwakeAt - fProfileTable[i - 1].fCurCycleBegin); + long d7 = long(fProfileTable[i].fClientTable[ref].fFinishedAt - fProfileTable[i - 1].fCurCycleBegin); + + // Print ref, signal, start, end, scheduling, duration, status + fprintf(file, "%d \t %ld \t %ld \t %ld \t %ld \t %ld \t %d \t", + ref, + ((d5 > 0) ? d5 : 0), + ((d6 > 0) ? d6 : 0), + ((d7 > 0) ? d7 : 0), + ((d6 > 0 && d5 > 0) ? (d6 - d5) : 0), + ((d7 > 0 && d6 > 0) ? (d7 - d6) : 0), + fProfileTable[i].fClientTable[ref].fStatus); + } else { // Print tabs + fprintf(file, "\t \t \t \t \t \t \t"); } } + + // Terminate line + fprintf(file, "\n"); } - fclose(file); } - + // Driver period file = fopen("Timing1.plot", "w"); @@ -145,9 +138,9 @@ JackEngineProfiling::~JackEngineProfiling() fclose(file); } - + // Clients end date - if (max_client > 0) { + if (fMeasuredClient > 0) { file = fopen("Timing3.plot", "w"); if (file == NULL) { jack_error("JackEngineProfiling::Save cannot open Timing3.log file"); @@ -158,21 +151,20 @@ JackEngineProfiling::~JackEngineProfiling() fprintf(file, "set title \"Clients end date\"\n"); fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot "); - for (int i = 0; i < max_client; i++) { + for (unsigned int i = 0; i < fMeasuredClient; i++) { if (i == 0) { - if ((i + 1) == max_client) { + if (i + 1 == fMeasuredClient) { // Last client sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines", - ((i + 1) * 7) - 1 , nameTable[(i + 1)]); + ((i + 1) * 7) - 1 , fIntervalTable[i].fName); } else { sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", - ((i + 1) * 7) - 1 , nameTable[(i + 1)]); + ((i + 1) * 7) - 1 , fIntervalTable[i].fName); } - } else if ((i + 1) == max_client) { // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) - 1 , nameTable[(i + 1)]); + } else if (i + 1 == fMeasuredClient) { // Last client + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) - 1 , fIntervalTable[i].fName); } else { - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) - 1, nameTable[(i + 1)]); + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) - 1, fIntervalTable[i].fName); } fprintf(file, buffer); } @@ -187,28 +179,29 @@ JackEngineProfiling::~JackEngineProfiling() fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"usec\"\n"); fprintf(file, "plot "); - for (int i = 0; i < max_client; i++) { + for (unsigned int i = 0; i < fMeasuredClient; i++) { if (i == 0) { - if ((i + 1) == max_client) { + if ((i + 1) == fMeasuredClient) { // Last client sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines", - ((i + 1) * 7) - 1 , nameTable[(i + 1)]); + ((i + 1) * 7) - 1 , fIntervalTable[i].fName); } else { sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", - ((i + 1) * 7) - 1 , nameTable[(i + 1)]); + ((i + 1) * 7) - 1 , fIntervalTable[i].fName); } - } else if ((i + 1) == max_client) { // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) - 1 , nameTable[(i + 1)]); + } else if ((i + 1) == fMeasuredClient) { // Last client + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) - 1 , fIntervalTable[i].fName); } else { - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) - 1, nameTable[(i + 1)]); + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) - 1, fIntervalTable[i].fName); } fprintf(file, buffer); } + fclose(file); } } - + // Clients scheduling - if (max_client > 0) { + if (fMeasuredClient > 0) { file = fopen("Timing4.plot", "w"); if (file == NULL) { @@ -221,11 +214,11 @@ JackEngineProfiling::~JackEngineProfiling() fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"usec\"\n"); fprintf(file, "plot "); - for (int i = 0; i < max_client; i++) { - if ((i + 1) == max_client) // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7), nameTable[(i + 1)]); + for (unsigned int i = 0; i < fMeasuredClient; i++) { + if ((i + 1) == fMeasuredClient) // Last client + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7), fIntervalTable[i].fName); else - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7), nameTable[(i + 1)]); + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7), fIntervalTable[i].fName); fprintf(file, buffer); } @@ -239,11 +232,11 @@ JackEngineProfiling::~JackEngineProfiling() fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"usec\"\n"); fprintf(file, "plot "); - for (int i = 0; i < max_client; i++) { - if ((i + 1) == max_client) // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7), nameTable[(i + 1)]); + for (unsigned int i = 0; i < fMeasuredClient; i++) { + if ((i + 1) == fMeasuredClient) // Last client + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7), fIntervalTable[i].fName); else - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7), nameTable[(i + 1)]); + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7), fIntervalTable[i].fName); fprintf(file, buffer); } fclose(file); @@ -251,7 +244,7 @@ JackEngineProfiling::~JackEngineProfiling() } // Clients duration - if (max_client > 0) { + if (fMeasuredClient > 0) { file = fopen("Timing5.plot", "w"); if (file == NULL) { @@ -264,11 +257,11 @@ JackEngineProfiling::~JackEngineProfiling() fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"usec\"\n"); fprintf(file, "plot "); - for (int i = 0; i < max_client; i++) { - if ((i + 1) == max_client) // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) + 1, nameTable[(i + 1)]); + for (unsigned int i = 0; i < fMeasuredClient; i++) { + if ((i + 1) == fMeasuredClient) // Last client + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) + 1, fIntervalTable[i].fName); else - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) + 1, nameTable[(i + 1)]); + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) + 1, fIntervalTable[i].fName); fprintf(file, buffer); } @@ -282,11 +275,11 @@ JackEngineProfiling::~JackEngineProfiling() fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"usec\"\n"); fprintf(file, "plot "); - for (int i = 0; i < max_client; i++) { - if ((i + 1) == max_client) // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) + 1, nameTable[(i + 1)]); + for (unsigned int i = 0; i < fMeasuredClient; i++) { + if ((i + 1) == fMeasuredClient) // Last client + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) + 1, fIntervalTable[i].fName); else - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) + 1, nameTable[(i + 1)]); + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) + 1, fIntervalTable[i].fName); fprintf(file, buffer); } fclose(file); @@ -294,6 +287,17 @@ JackEngineProfiling::~JackEngineProfiling() } } +bool JackEngineProfiling::CheckClient(const char* name, int cur_point) +{ + for (int i = 0; i < MEASURED_CLIENTS; i++) { + if (strcmp(fIntervalTable[i].fName, name) == 0) { + fIntervalTable[i].fEndInterval = cur_point; + return true; + } + } + return false; +} + void JackEngineProfiling::Profile(JackClientInterface** table, JackGraphManager* manager, jack_time_t period_usecs, @@ -311,8 +315,16 @@ void JackEngineProfiling::Profile(JackClientInterface** table, for (int i = REAL_REFNUM; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; JackClientTiming* timing = manager->GetClientTiming(i); - if (client && client->GetClientControl()->fActive) { - strcpy(fNameTable[i], client->GetClientControl()->fName); + if (client && client->GetClientControl()->fActive && client->GetClientControl()->fCallback[kRealTimeCallback]) { + + if (!CheckClient(client->GetClientControl()->fName, fAudioCycle)) { + // Keep new measured client + fIntervalTable[fMeasuredClient].fRefNum = i; + strcpy(fIntervalTable[fMeasuredClient].fName, client->GetClientControl()->fName); + fIntervalTable[fMeasuredClient].fBeginInterval = fAudioCycle; + fIntervalTable[fMeasuredClient].fEndInterval = fAudioCycle; + fMeasuredClient++; + } fProfileTable[fAudioCycle].fClientTable[i].fRefNum = i; fProfileTable[fAudioCycle].fClientTable[i].fSignaledAt = timing->fSignaledAt; fProfileTable[fAudioCycle].fClientTable[i].fAwakeAt = timing->fAwakeAt; diff --git a/common/JackEngineProfiling.h b/common/JackEngineProfiling.h index 43888e76..71abca1b 100644 --- a/common/JackEngineProfiling.h +++ b/common/JackEngineProfiling.h @@ -31,6 +31,7 @@ namespace Jack #define TIME_POINTS 250000 #define FAILURE_TIME_POINTS 10000 #define FAILURE_WINDOW 10 +#define MEASURED_CLIENTS 32 /*! \brief Timing stucture for a client. @@ -43,6 +44,32 @@ struct JackTimingMeasureClient jack_time_t fAwakeAt; jack_time_t fFinishedAt; jack_client_state_t fStatus; + + JackTimingMeasureClient() + :fRefNum(-1), + fSignaledAt(0), + fAwakeAt(0), + fFinishedAt(0), + fStatus((jack_client_state_t)0) + {} +}; + +/*! +\brief Timing interval in the global table for a given client +*/ + +struct JackTimingClientInterval +{ + int fRefNum; + char fName[JACK_CLIENT_NAME_SIZE + 1]; + int fBeginInterval; + int fEndInterval; + + JackTimingClientInterval() + :fRefNum(-1), + fBeginInterval(-1), + fEndInterval(-1) + {} }; /*! @@ -56,6 +83,13 @@ struct JackTimingMeasure jack_time_t fCurCycleBegin; jack_time_t fPrevCycleEnd; JackTimingMeasureClient fClientTable[CLIENT_NUM]; + + JackTimingMeasure() + :fAudioCycle(0), + fPeriodUsecs(0), + fCurCycleBegin(0), + fPrevCycleEnd(0) + {} }; /*! @@ -71,9 +105,13 @@ class SERVER_EXPORT JackEngineProfiling private: JackTimingMeasure fProfileTable[TIME_POINTS]; - char fNameTable[CLIENT_NUM][JACK_CLIENT_NAME_SIZE + 1]; + JackTimingClientInterval fIntervalTable[MEASURED_CLIENTS]; + unsigned int fAudioCycle; - + unsigned int fMeasuredClient; + + bool CheckClient(const char* name, int cur_point); + public: JackEngineProfiling(); diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 19bfdc8a..6d9b1c1b 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -354,9 +354,8 @@ struct JackNetExtMaster : public JackNetMasterInterface { if (SyncRecv() == SOCKET_ERROR) return 0; - if (DecodeSyncPacket() < 0) - return 0; - + DecodeSyncPacket(); + return DataRecv(); } @@ -373,9 +372,8 @@ struct JackNetExtMaster : public JackNetMasterInterface { fNetMidiCaptureBuffer->SetBuffer(port_index, ((JackMidiBuffer**)midi_output_buffer)[port_index]); } - if (EncodeSyncPacket() < 0) - return 0; - + EncodeSyncPacket(); + if (SyncSend() == SOCKET_ERROR) return SOCKET_ERROR; @@ -383,15 +381,11 @@ struct JackNetExtMaster : public JackNetMasterInterface { } // Transport - int EncodeTransportData() - { - return 0; - } + void EncodeTransportData() + {} - int DecodeTransportData() - { - return 0; - } + void DecodeTransportData() + {} }; @@ -574,15 +568,11 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf } // Transport - int EncodeTransportData() - { - return 0; - } + void EncodeTransportData() + {} - int DecodeTransportData() - { - return 0; - } + void DecodeTransportData() + {} bool Init() { @@ -624,17 +614,15 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf if (SyncRecv() == SOCKET_ERROR) return 0; - if (DecodeSyncPacket() < 0) - return 0; - + DecodeSyncPacket(); + return DataRecv(); } int Write() { - if (EncodeSyncPacket() < 0) - return 0; - + EncodeSyncPacket(); + if (SyncSend() == SOCKET_ERROR) return SOCKET_ERROR; diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index a5b85b63..2ce50cbf 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -260,7 +260,7 @@ namespace Jack } //transport--------------------------------------------------------------------------- - int JackNetAdapter::DecodeTransportData() + void JackNetAdapter::DecodeTransportData() { //TODO : we need here to get the actual timebase master to eventually release it from its duty (see JackNetDriver) @@ -288,11 +288,9 @@ namespace Jack break; } } - - return 0; } - int JackNetAdapter::EncodeTransportData() + void JackNetAdapter::EncodeTransportData() { //is there a timebase master change ? int refnum = -1; @@ -326,8 +324,6 @@ namespace Jack if ( fReturnTransportData.fNewState ) jack_info ( "Sending transport state '%s'.", GetTransportState ( fReturnTransportData.fState ) ); fLastTransportState = fReturnTransportData.fState; - - return 0; } //read/write operations--------------------------------------------------------------- @@ -338,17 +334,14 @@ namespace Jack if ( SyncRecv() == SOCKET_ERROR ) return 0; - if ( DecodeSyncPacket() < 0 ) - return 0; - + DecodeSyncPacket(); return DataRecv(); } int JackNetAdapter::Write() { - if ( EncodeSyncPacket() < 0 ) - return 0; - + EncodeSyncPacket(); + if ( SyncSend() == SOCKET_ERROR ) return SOCKET_ERROR; @@ -358,48 +351,21 @@ namespace Jack //process----------------------------------------------------------------------------- int JackNetAdapter::Process() { - bool failure = false; - int port_index; - //read data from the network //in case of fatal network error, stop the process - if ( Read() == SOCKET_ERROR ) + if (Read() == SOCKET_ERROR) return SOCKET_ERROR; - - //get the resample factor, - jack_time_t time1, time2; - ResampleFactor ( time1, time2 ); - - //resample input data, - for ( port_index = 0; port_index < fCaptureChannels; port_index++ ) - { - fCaptureRingBuffer[port_index]->SetRatio ( time1, time2 ); - if ( fCaptureRingBuffer[port_index]->WriteResample ( fSoftCaptureBuffer[port_index], fAdaptedBufferSize ) < fAdaptedBufferSize ) - failure = true; - } - - //and output data, - for ( port_index = 0; port_index < fPlaybackChannels; port_index++ ) - { - fPlaybackRingBuffer[port_index]->SetRatio ( time2, time1 ); - if ( fPlaybackRingBuffer[port_index]->ReadResample ( fSoftPlaybackBuffer[port_index], fAdaptedBufferSize ) < fAdaptedBufferSize ) - failure = true; - } + + PushAndPull(fSoftCaptureBuffer, fSoftPlaybackBuffer, fAdaptedBufferSize); //then write data to network //in case of failure, stop process - if ( Write() == SOCKET_ERROR ) + if (Write() == SOCKET_ERROR) return SOCKET_ERROR; - //if there was any ringbuffer failure during resampling, reset - if ( failure ) - { - jack_error ( "JackNetAdapter::Execute ringbuffer failure...reset." ); - ResetRingBuffers(); - } - return 0; } + } // namespace Jack //loader------------------------------------------------------------------------------ @@ -420,7 +386,7 @@ extern "C" strcpy(desc->name, "netadapter"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->desc, "netjack net <==> audio backend adapter"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - desc->nparams = 9; + desc->nparams = 10; desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) ); int i = 0; @@ -494,6 +460,14 @@ 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, "auto_connect" ); + desc->params[i].character = 'c'; + desc->params[i].type = JackDriverParamBool; + desc->params[i].value.i = false; + strcpy ( desc->params[i].short_desc, "Auto connect netmaster to system ports" ); + strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); return desc; } @@ -508,7 +482,7 @@ extern "C" try { - adapter = new Jack::JackAudioAdapter ( jack_client, new Jack::JackNetAdapter ( jack_client, buffer_size, sample_rate, params ) ); + adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackNetAdapter(jack_client, buffer_size, sample_rate, params), params, false); assert ( adapter ); if ( adapter->Open() == 0 ) diff --git a/common/JackNetAdapter.h b/common/JackNetAdapter.h index 7f120e28..f6b7675b 100644 --- a/common/JackNetAdapter.h +++ b/common/JackNetAdapter.h @@ -48,8 +48,8 @@ namespace Jack JackThread fThread; //transport - int EncodeTransportData(); - int DecodeTransportData(); + void EncodeTransportData(); + void DecodeTransportData(); public: diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index 7b17ac90..d34c7db5 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -381,7 +381,7 @@ namespace Jack } //transport--------------------------------------------------------------------------- - int JackNetDriver::DecodeTransportData() + void JackNetDriver::DecodeTransportData() { //is there a new timebase master on the net master ? // - release timebase master only if it's a non-conditional request @@ -397,9 +397,10 @@ namespace Jack jack_info ( "The NetMaster is now the new timebase master." ); } - //is there a tranport state change to handle ? + //is there a transport state change to handle ? if ( fSendTransportData.fNewState && ( fSendTransportData.fState != fEngineControl->fTransport.GetState() ) ) { + switch ( fSendTransportData.fState ) { case JackTransportStopped : @@ -419,11 +420,9 @@ namespace Jack break; } } - - return 0; } - int JackNetDriver::EncodeTransportData() + void JackNetDriver::EncodeTransportData() { //is there a timebase master change ? int refnum; @@ -457,8 +456,6 @@ namespace Jack if ( fReturnTransportData.fNewState ) jack_info ( "Sending '%s'.", GetTransportState ( fReturnTransportData.fState ) ); fLastTransportState = fReturnTransportData.fState; - - return 0; } //driver processes-------------------------------------------------------------------- @@ -486,9 +483,8 @@ namespace Jack //decode sync //if there is an error, don't return -1, it will skip Write() and the network error probably won't be identified - if ( DecodeSyncPacket() < 0 ) - return 0; - + DecodeSyncPacket(); + #ifdef JACK_MONITOR fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - JackDriver::fBeginDateUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); #endif @@ -519,9 +515,8 @@ namespace Jack #endif //sync - if ( EncodeSyncPacket() < 0 ) - return 0; - + EncodeSyncPacket(); + //send sync if ( SyncSend() == SOCKET_ERROR ) return SOCKET_ERROR; diff --git a/common/JackNetDriver.h b/common/JackNetDriver.h index af432084..058489a1 100644 --- a/common/JackNetDriver.h +++ b/common/JackNetDriver.h @@ -57,8 +57,8 @@ namespace Jack int FreePorts(); //transport - int EncodeTransportData(); - int DecodeTransportData(); + void EncodeTransportData(); + void DecodeTransportData(); JackMidiBuffer* GetMidiInputBuffer ( int port_index ); JackMidiBuffer* GetMidiOutputBuffer ( int port_index ); diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 299c4588..27495c18 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -565,39 +565,35 @@ namespace Jack return rx_bytes; } - int JackNetMasterInterface::EncodeSyncPacket() + void JackNetMasterInterface::EncodeSyncPacket() { //this method contains every step of sync packet informations coding //first of all, reset sync packet memset ( fTxData, 0, fPayloadSize ); //then, first step : transport - if ( fParams.fTransportSync ) - { - if ( EncodeTransportData() < 0 ) - return -1; + if (fParams.fTransportSync) { + EncodeTransportData(); + TransportDataHToN( &fSendTransportData, &fSendTransportData); //copy to TxBuffer memcpy ( fTxData, &fSendTransportData, sizeof ( net_transport_data_t ) ); } //then others (freewheel etc.) //... - return 0; } - int JackNetMasterInterface::DecodeSyncPacket() + void JackNetMasterInterface::DecodeSyncPacket() { //this method contains every step of sync packet informations decoding process //first : transport - if ( fParams.fTransportSync ) - { + if (fParams.fTransportSync) { //copy received transport data to transport data structure memcpy ( &fReturnTransportData, fRxData, sizeof ( net_transport_data_t ) ); - if ( DecodeTransportData() < 0 ) - return -1; + TransportDataNToH( &fReturnTransportData, &fReturnTransportData); + DecodeTransportData(); } //then others //... - return 0; } // JackNetSlaveInterface ************************************************************************************************ @@ -955,38 +951,34 @@ namespace Jack } //network sync------------------------------------------------------------------------ - int JackNetSlaveInterface::DecodeSyncPacket() - { - //this method contains every step of sync packet informations decoding process - //first : transport - if ( fParams.fTransportSync ) - { - //copy received transport data to transport data structure - memcpy ( &fSendTransportData, fRxData, sizeof ( net_transport_data_t ) ); - if ( DecodeTransportData() < 0 ) - return -1; - } - //then others - //... - return 0; - } - - int JackNetSlaveInterface::EncodeSyncPacket() + void JackNetSlaveInterface::EncodeSyncPacket() { //this method contains every step of sync packet informations coding //first of all, reset sync packet memset ( fTxData, 0, fPayloadSize ); //then first step : transport - if ( fParams.fTransportSync ) - { - if ( EncodeTransportData() < 0 ) - return -1; + if (fParams.fTransportSync) { + EncodeTransportData(); + TransportDataHToN( &fReturnTransportData, &fReturnTransportData); //copy to TxBuffer memcpy ( fTxData, &fReturnTransportData, sizeof ( net_transport_data_t ) ); } //then others //... - return 0; + } + + void JackNetSlaveInterface::DecodeSyncPacket() + { + //this method contains every step of sync packet informations decoding process + //first : transport + if (fParams.fTransportSync) { + //copy received transport data to transport data structure + memcpy ( &fSendTransportData, fRxData, sizeof ( net_transport_data_t ) ); + TransportDataNToH( &fSendTransportData, &fSendTransportData); + DecodeTransportData(); + } + //then others + //... } } diff --git a/common/JackNetInterface.h b/common/JackNetInterface.h index 9d2c95c2..c655a3b0 100644 --- a/common/JackNetInterface.h +++ b/common/JackNetInterface.h @@ -73,12 +73,12 @@ namespace Jack virtual bool Init() = 0; //transport - virtual int EncodeTransportData() = 0; - virtual int DecodeTransportData() = 0; + virtual void EncodeTransportData() = 0; + virtual void DecodeTransportData() = 0; //sync packet - virtual int EncodeSyncPacket() = 0; - virtual int DecodeSyncPacket() = 0; + virtual void EncodeSyncPacket() = 0; + virtual void DecodeSyncPacket() = 0; virtual int SyncRecv() = 0; virtual int SyncSend() = 0; @@ -119,8 +119,8 @@ namespace Jack int DataSend(); //sync packet - int EncodeSyncPacket(); - int DecodeSyncPacket(); + void EncodeSyncPacket(); + void DecodeSyncPacket(); int Send ( size_t size, int flags ); int Recv ( size_t size, int flags ); @@ -163,8 +163,8 @@ namespace Jack int DataSend(); //sync packet - int EncodeSyncPacket(); - int DecodeSyncPacket(); + void EncodeSyncPacket(); + void DecodeSyncPacket(); int Recv ( size_t size, int flags ); int Send ( size_t size, int flags ); diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index b935d252..5f723b99 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -26,7 +26,7 @@ namespace Jack { //JackNetMaster****************************************************************************************************** - JackNetMaster::JackNetMaster ( JackNetSocket& socket, session_params_t& params, const char* multicast_ip ) + JackNetMaster::JackNetMaster ( JackNetSocket& socket, session_params_t& params, const char* multicast_ip) : JackNetMasterInterface ( params, socket, multicast_ip ) { jack_log ( "JackNetMaster::JackNetMaster" ); @@ -107,7 +107,7 @@ namespace Jack #endif } //init-------------------------------------------------------------------------------- - bool JackNetMaster::Init() + bool JackNetMaster::Init(bool auto_connect) { //network init if ( !JackNetMasterInterface::Init() ) @@ -141,9 +141,10 @@ namespace Jack jack_error ( "Can't activate jack client." ); goto fail; } - + + if (auto_connect) + ConnectPorts(); jack_info ( "New NetMaster started." ); - return true; fail: @@ -156,27 +157,26 @@ namespace Jack //jack ports-------------------------------------------------------------------------- int JackNetMaster::AllocPorts() { - jack_log ( "JackNetMaster::AllocPorts" ); - uint i; char name[24]; jack_nframes_t port_latency = jack_get_buffer_size ( fJackClient ); - unsigned long port_flags; + + jack_log ( "JackNetMaster::AllocPorts" ); + //audio - port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; for ( i = 0; i < fParams.fSendAudioChannels; i++ ) { sprintf ( name, "to_slave_%d", i+1 ); - if ( ( fAudioCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0 ) ) == NULL ) + if ( ( fAudioCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput | JackPortIsTerminal, 0 ) ) == NULL ) return -1; //port latency jack_port_set_latency ( fAudioCapturePorts[i], 0 ); } - port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; + for ( i = 0; i < fParams.fReturnAudioChannels; i++ ) { sprintf ( name, "from_slave_%d", i+1 ); - if ( ( fAudioPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0 ) ) == NULL ) + if ( ( fAudioPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput | JackPortIsTerminal, 0 ) ) == NULL ) return -1; //port latency switch ( fParams.fNetworkMode ) @@ -192,21 +192,21 @@ namespace Jack break; } } + + //midi - port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; for ( i = 0; i < fParams.fSendMidiChannels; i++ ) { sprintf ( name, "midi_to_slave_%d", i+1 ); - if ( ( fMidiCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, port_flags, 0 ) ) == NULL ) + if ( ( fMidiCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput | JackPortIsTerminal, 0 ) ) == NULL ) return -1; //port latency jack_port_set_latency ( fMidiCapturePorts[i], 0 ); } - port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; for ( i = 0; i < fParams.fReturnMidiChannels; i++ ) { sprintf ( name, "midi_from_slave_%d", i+1 ); - if ( ( fMidiPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, port_flags, 0 ) ) == NULL ) + if ( ( fMidiPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput | JackPortIsTerminal, 0 ) ) == NULL ) return -1; //port latency switch ( fParams.fNetworkMode ) @@ -224,6 +224,27 @@ namespace Jack } return 0; } + + void JackNetMaster::ConnectPorts() + { + const char **ports; + + ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); + if (ports != NULL) { + for (unsigned int i = 0; i < fParams.fSendAudioChannels && ports[i]; i++) { + jack_connect(fJackClient, ports[i], jack_port_name(fAudioCapturePorts[i])); + } + free(ports); + } + + ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput); + if (ports != NULL) { + for (unsigned int i = 0; i < fParams.fReturnAudioChannels && ports[i]; i++) { + jack_connect(fJackClient, jack_port_name(fAudioPlaybackPorts[i]), ports[i]); + } + free(ports); + } + } void JackNetMaster::FreePorts() { @@ -245,7 +266,7 @@ namespace Jack } //transport--------------------------------------------------------------------------- - int JackNetMaster::EncodeTransportData() + void JackNetMaster::EncodeTransportData() { //is there a new timebase master ? //TODO : check if any timebase callback has been called (and if it's conditional or not) and set correct value... @@ -260,11 +281,9 @@ namespace Jack if ( fSendTransportData.fNewState ) jack_info ( "Sending '%s' to '%s'.", GetTransportState ( fSendTransportData.fState ), fParams.fName ); fLastTransportState = fSendTransportData.fState; + } - return 0; - } - - int JackNetMaster::DecodeTransportData() + void JackNetMaster::DecodeTransportData() { //is there timebase master change ? if ( fReturnTransportData.fTimebaseMaster != NO_CHANGE ) @@ -322,7 +341,6 @@ namespace Jack break; } } - return 0; } void JackNetMaster::SetTimebaseCallback ( jack_transport_state_t state, jack_nframes_t nframes, jack_position_t* pos, int new_pos, void* arg ) @@ -385,9 +403,8 @@ namespace Jack if (IsSynched()) { // only send if connection is "synched" //encode the first packet - if ( EncodeSyncPacket() < 0 ) - return 0; - + EncodeSyncPacket(); + //send sync if ( SyncSend() == SOCKET_ERROR ) return SOCKET_ERROR; @@ -418,9 +435,8 @@ namespace Jack #endif //decode sync - if ( DecodeSyncPacket() < 0 ) - return 0; - + DecodeSyncPacket(); + //receive data res = DataRecv(); if ( ( res == 0 ) || ( res == SOCKET_ERROR ) ) @@ -444,6 +460,7 @@ namespace Jack fSocket.SetPort ( DEFAULT_PORT ); fGlobalID = 0; fRunning = true; + fAutoConnect = false; const JSList* node; const jack_driver_param_t* param; @@ -458,8 +475,14 @@ namespace Jack else jack_error("Can't use multicast address %s, using default %s", param->value.ui, DEFAULT_MULTICAST_IP); break; + case 'p': fSocket.SetPort ( param->value.ui ); + break; + + case 'c': + fAutoConnect = param->value.i; + break; } } @@ -618,8 +641,8 @@ namespace Jack SetSlaveName ( params ); //create a new master and add it to the list - JackNetMaster* master = new JackNetMaster ( fSocket, params, fMulticastIP ); - if ( master->Init() ) + JackNetMaster* master = new JackNetMaster(fSocket, params, fMulticastIP); + if ( master->Init(fAutoConnect) ) { fMasterList.push_back ( master ); return master; @@ -679,7 +702,7 @@ extern "C" strcpy ( desc->name, "netmanager" ); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy ( desc->desc, "netjack multi-cast master component" ); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - desc->nparams = 2; + desc->nparams = 3; desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) ); int i = 0; @@ -697,6 +720,14 @@ extern "C" desc->params[i].value.i = DEFAULT_PORT; strcpy ( desc->params[i].short_desc, "UDP port" ); strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); + + i++; + strcpy ( desc->params[i].name, "auto_connect" ); + desc->params[i].character = 'c'; + desc->params[i].type = JackDriverParamBool; + desc->params[i].value.i = false; + strcpy ( desc->params[i].short_desc, "Auto connect netmaster to system ports" ); + strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); return desc; } diff --git a/common/JackNetManager.h b/common/JackNetManager.h index 9d748d34..6e05759f 100644 --- a/common/JackNetManager.h +++ b/common/JackNetManager.h @@ -53,29 +53,28 @@ namespace Jack //sync and transport int fLastTransportState; - net_transport_data_t fSendTransportData; - net_transport_data_t fReturnTransportData; - + //monitoring #ifdef JACK_MONITOR jack_time_t fPeriodUsecs; JackGnuPlotMonitor* fNetTimeMon; #endif - bool Init(); + bool Init(bool auto_connect); int AllocPorts(); void FreePorts(); void Exit(); //transport - int EncodeTransportData(); - int DecodeTransportData(); + void EncodeTransportData(); + void DecodeTransportData(); int Process(); void TimebaseCallback ( jack_position_t* pos ); + void ConnectPorts(); public: - JackNetMaster ( JackNetSocket& socket, session_params_t& params, const char* multicast_ip ); + JackNetMaster ( JackNetSocket& socket, session_params_t& params, const char* multicast_ip); ~JackNetMaster (); bool IsSlaveReadyToRoll(); @@ -103,6 +102,7 @@ namespace Jack master_list_t fMasterList; uint32_t fGlobalID; bool fRunning; + bool fAutoConnect; void Run(); JackNetMaster* MasterInit ( session_params_t& params ); @@ -112,7 +112,7 @@ namespace Jack int SyncCallback ( jack_transport_state_t state, jack_position_t* pos ); public: - JackNetMasterManager ( jack_client_t* jack_client, const JSList* params ); + JackNetMasterManager ( jack_client_t* jack_client, const JSList* params); ~JackNetMasterManager(); }; } diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index 50010287..b35af904 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -377,6 +377,15 @@ namespace Jack jack_info ( "**********************************************" ); } + SERVER_EXPORT void NetTransportDataDisplay ( net_transport_data_t* data ) + { + jack_info ( "********************Network Transport********************" ); + jack_info ( "Transport new state : %u", data->fNewState ); + jack_info ( "Transport timebase master : %u", data->fTimebaseMaster ); + jack_info ( "Transport cycle state : %u", data->fState ); + jack_info ( "**********************************************" ); + } + SERVER_EXPORT void MidiBufferHToN ( JackMidiBuffer* src_buffer, JackMidiBuffer* dst_buffer ) { dst_buffer->magic = htonl(src_buffer->magic); @@ -398,6 +407,56 @@ namespace Jack dst_buffer->lost_events = ntohl(src_buffer->lost_events); dst_buffer->mix_index = ntohl(src_buffer->mix_index); } + + SERVER_EXPORT void TransportDataHToN ( net_transport_data_t* src_params, net_transport_data_t* dst_params ) + { + dst_params->fNewState = htonl(src_params->fNewState); + dst_params->fTimebaseMaster = htonl(src_params->fTimebaseMaster); + dst_params->fState = htonl(src_params->fState); + dst_params->fPosition.unique_1 = htonll(src_params->fPosition.unique_1); + dst_params->fPosition.usecs = htonl(src_params->fPosition.usecs); + dst_params->fPosition.frame_rate = htonl(src_params->fPosition.frame_rate); + dst_params->fPosition.frame = htonl(src_params->fPosition.frame); + dst_params->fPosition.bar = htonl(src_params->fPosition.bar); + dst_params->fPosition.beat = htonl(src_params->fPosition.beat); + dst_params->fPosition.tick = htonl(src_params->fPosition.tick); + dst_params->fPosition.bar_start_tick = htonll((uint64_t)src_params->fPosition.bar_start_tick); + dst_params->fPosition.beats_per_bar = htonl(src_params->fPosition.beats_per_bar); + dst_params->fPosition.beat_type = htonl(src_params->fPosition.beat_type); + dst_params->fPosition.ticks_per_beat = htonll((uint64_t)src_params->fPosition.ticks_per_beat); + dst_params->fPosition.beats_per_minute = htonll((uint64_t)src_params->fPosition.beats_per_minute); + dst_params->fPosition.frame_time = htonll((uint64_t)src_params->fPosition.frame_time); + dst_params->fPosition.next_time = htonll((uint64_t)src_params->fPosition.next_time); + dst_params->fPosition.bbt_offset = htonl(src_params->fPosition.bbt_offset); + dst_params->fPosition.audio_frames_per_video_frame = htonl(src_params->fPosition.audio_frames_per_video_frame); + dst_params->fPosition.video_offset = htonl(src_params->fPosition.video_offset); + dst_params->fPosition.unique_2 = htonll(src_params->fPosition.unique_2); + } + + SERVER_EXPORT void TransportDataNToH ( net_transport_data_t* src_params, net_transport_data_t* dst_params ) + { + dst_params->fNewState = ntohl(src_params->fNewState); + dst_params->fTimebaseMaster = ntohl(src_params->fTimebaseMaster); + dst_params->fState = ntohl(src_params->fState); + dst_params->fPosition.unique_1 = ntohll(src_params->fPosition.unique_1); + dst_params->fPosition.usecs = ntohl(src_params->fPosition.usecs); + dst_params->fPosition.frame_rate = ntohl(src_params->fPosition.frame_rate); + dst_params->fPosition.frame = ntohl(src_params->fPosition.frame); + dst_params->fPosition.bar = ntohl(src_params->fPosition.bar); + dst_params->fPosition.beat = ntohl(src_params->fPosition.beat); + dst_params->fPosition.tick = ntohl(src_params->fPosition.tick); + dst_params->fPosition.bar_start_tick = ntohll((uint64_t)src_params->fPosition.bar_start_tick); + dst_params->fPosition.beats_per_bar = ntohl(src_params->fPosition.beats_per_bar); + dst_params->fPosition.beat_type = ntohl(src_params->fPosition.beat_type); + dst_params->fPosition.ticks_per_beat = ntohll((uint64_t)src_params->fPosition.ticks_per_beat); + dst_params->fPosition.beats_per_minute = ntohll((uint64_t)src_params->fPosition.beats_per_minute); + dst_params->fPosition.frame_time = ntohll((uint64_t)src_params->fPosition.frame_time); + dst_params->fPosition.next_time = ntohll((uint64_t)src_params->fPosition.next_time); + dst_params->fPosition.bbt_offset = ntohl(src_params->fPosition.bbt_offset); + dst_params->fPosition.audio_frames_per_video_frame = ntohl(src_params->fPosition.audio_frames_per_video_frame); + dst_params->fPosition.video_offset = ntohl(src_params->fPosition.video_offset); + dst_params->fPosition.unique_2 = ntohll(src_params->fPosition.unique_2); + } // Utility ******************************************************************************************************* diff --git a/common/JackNetTool.h b/common/JackNetTool.h index e7c0e8d6..cb6f494f 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -29,6 +29,16 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. using namespace std; +#ifndef htonll +#ifdef __BIG_ENDIAN__ +#define htonll(x) (x) +#define ntohll(x) (x) +#else +#define htonll(x) ((((uint64_t)htonl(x)) << 32) + htonl(x >> 32)) +#define ntohll(x) ((((uint64_t)ntohl(x)) << 32) + ntohl(x >> 32)) +#endif +#endif + namespace Jack { typedef struct _session_params session_params_t; @@ -282,6 +292,8 @@ namespace Jack SERVER_EXPORT void PacketHeaderNToH ( packet_header_t* src_header, packet_header_t* dst_header ); SERVER_EXPORT void MidiBufferHToN ( JackMidiBuffer* src_buffer, JackMidiBuffer* dst_buffer ); SERVER_EXPORT void MidiBufferNToH ( JackMidiBuffer* src_buffer, JackMidiBuffer* dst_buffer ); + SERVER_EXPORT void TransportDataHToN ( net_transport_data_t* src_params, net_transport_data_t* dst_params ); + SERVER_EXPORT void TransportDataNToH ( net_transport_data_t* src_params, net_transport_data_t* dst_params ); //display session parameters SERVER_EXPORT void SessionParamsDisplay ( session_params_t* params ); //display packet header @@ -292,4 +304,5 @@ namespace Jack SERVER_EXPORT int SetPacketType ( session_params_t* params, sync_packet_type_t packet_type ); //transport utility SERVER_EXPORT const char* GetTransportState ( int transport_state ); + SERVER_EXPORT void NetTransportDataDisplay ( net_transport_data_t* data ); } diff --git a/common/JackProfiler.cpp b/common/JackProfiler.cpp index f4fa904b..b74abc13 100644 --- a/common/JackProfiler.cpp +++ b/common/JackProfiler.cpp @@ -218,7 +218,7 @@ extern "C" strcpy(desc->params[i].name, "cpu-load"); desc->params[i].character = 'c'; desc->params[i].type = JackDriverParamBool; - desc->params[i].value.i = TRUE; + desc->params[i].value.i = FALSE; strcpy(desc->params[i].short_desc, "Show DSP CPU load"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); @@ -226,7 +226,7 @@ extern "C" strcpy(desc->params[i].name, "driver-period"); desc->params[i].character = 'p'; desc->params[i].type = JackDriverParamBool; - desc->params[i].value.i = TRUE; + desc->params[i].value.i = FALSE; strcpy(desc->params[i].short_desc, "Show driver period"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); @@ -234,7 +234,7 @@ extern "C" strcpy(desc->params[i].name, "driver-end-time"); desc->params[i].character = 'e'; desc->params[i].type = JackDriverParamBool; - desc->params[i].value.i = TRUE; + desc->params[i].value.i = FALSE; strcpy(desc->params[i].short_desc, "Show driver end time"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); diff --git a/solaris/oss/JackOSSDriver.cpp b/solaris/oss/JackOSSDriver.cpp index f70aaaac..46a2871a 100644 --- a/solaris/oss/JackOSSDriver.cpp +++ b/solaris/oss/JackOSSDriver.cpp @@ -223,34 +223,7 @@ void JackOSSDriver::DisplayDeviceInfo() if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); } } - /* - TODO - - ai_in.dev = fInFD; - jack_log("JackOSSDriver::DisplayDeviceInfo input fInFD = %d", ai_in.dev); - if (ioctl(fInFD, SNDCTL_AUDIOINFO, &ai_in) != -1) { - jack_info("Using audio engine %d = %s for input", ai_in.dev, ai_in.name); - if (ai_in.iformats & AFMT_S24_NE) - jack_info("Available input format : AFMT_S24_NE"); - if (ai_in.iformats & AFMT_S16_NE) - jack_info("Available input format : AFMT_S16_NE"); - if (ai_in.iformats & AFMT_S32_NE) - jack_info("Available input format : AFMT_S32_NE"); - } - - ai_out.dev = fOutFD; - jack_log("JackOSSDriver::DisplayDeviceInfo output fOutFD = %d", ai_out.dev); - if (ioctl(fOutFD, SNDCTL_AUDIOINFO, &ai_out) != -1) { - jack_info("Using audio engine %d = %s for output", ai_out.dev, ai_out.name); - if (ai_out.oformats & AFMT_S24_NE) - jack_info("Available output format : AFMT_S24_NE"); - if (ai_out.oformats & AFMT_S16_NE) - jack_info("Available output format : AFMT_S16_NE"); - if (ai_out.oformats & AFMT_S32_NE) - jack_info("Available output format : AFMT_S32_NE"); - } - */ - + if (ai_in.rate_source != ai_out.rate_source) { jack_info("Warning : input and output are not necessarily driven by the same clock!"); } @@ -541,7 +514,7 @@ int JackOSSDriver::OpenAux() // In duplex mode, check that input and output use the same buffer size /* - // 10/02/09 : desactivated for now, needs more check (only needed when *same* device is used for input and output ??) + 10/02/09 : desactivated for now, needs more check (only needed when *same* device is used for input and output ??) if ((fRWMode & kRead) && (fRWMode & kWrite) && (fInputBufferSize != fOutputBufferSize)) { jack_error("JackOSSDriver::OpenAux input and output buffer size are not the same!!"); @@ -583,32 +556,6 @@ int JackOSSDriver::Read() } ssize_t count; -/* - // Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html - if (fFirstCycle) { - - fFirstCycle = false; - memset(fOutputBuffer, 0, fOutputBufferSize); - - // Prefill ouput buffer - for (int i = 0; i < fNperiods; i++) { - count = ::write(fOutFD, fOutputBuffer, fOutputBufferSize); - if (count < fOutputBufferSize) { - jack_error("JackOSSDriver::Write error bytes written = %ld", count); - return -1; - } - } - - int delay; - if (ioctl(fOutFD, SNDCTL_DSP_GETODELAY, &delay) == -1) { - jack_error("JackOSSDriver::Write error get out delay : %s@%i, errno = %d", __FILE__, __LINE__, errno); - return -1; - } - - delay /= fSampleSize * fPlaybackChannels; - jack_info("JackOSSDriver::Write output latency frames = %ld", delay); - } -*/ #ifdef JACK_MONITOR gCycleTable.fTable[gCycleCount].fBeforeRead = GetMicroSeconds(); diff --git a/windows/README b/windows/README index ab94a3a3..f7cbebb7 100644 --- a/windows/README +++ b/windows/README @@ -1,5 +1,5 @@ ------------------------------- -Jackmp on windows +Jackmp on Windows ------------------------------- This folder contains all the windows specific sources. @@ -34,11 +34,11 @@ You can make a small installer ('setup.exe') with CreateInstallFree, a little fr A binary version of qjackctl is also included. ------------------------------- -Running Jack on windows +Running Jack on Windows ------------------------------- You can use two drivers : PortAudio and NetDriver. -The PortAudio backend allow the use of many soundcards, using ASIO or WMME drivers (any ASIO driver can be seen by PortAudio). +The PortAudio backend allow the use of many soundcards, using ASIO, DirectSound or WMME drivers (any ASIO driver can be seen by PortAudio). The NetDriver allow you to use NetJack2 on windows. Thus you can easily exchange midi and audio streams bitween computers (Linux, MacOSX or Windows). In both cases, you have to use the minimalist : 'jackd -R -d ...' @@ -46,7 +46,11 @@ In both cases, you have to use the minimalist : 'jackd -R -S -d portaudio -l' Other options still stay the same. -You can also pick a binary of Qjackctl, but this is still in development. +You can also pick a binary of Qjackctl, but this is still in development. + +------------------------------- +Running Jack on windows +------------------------------- More information at : 'http://www.grame.fr/~letz/jackdmp.html'. diff --git a/windows/Setup/jack.ci b/windows/Setup/jack.ci index 437b8fd0..ee1c96ca 100644 --- a/windows/Setup/jack.ci +++ b/windows/Setup/jack.ci @@ -66,8 +66,8 @@ <_>..\Release\bin\jack_metro.exeinstovernewer0 <_>..\Release\bin\jack_unload.exeinstovernewer0 <_>..\Release\bin\jackd.exeinstovernewer0 -<_>..\Release\bin\libjack.dllinstovernewer0 -<_>..\Release\bin\libjackserver.dllinstovernewer0 +<_>..\Release\bin\libjack.dllsysovernewer0 +<_>..\Release\bin\libjackserver.dllsysovernewer0 <_>..\Release\bin\libsamplerate-0.dllinstovernewer0 <_>..\Release\bin\portaudio_x86.dllinstovernewer0 <_>..\Release\bin\jack\jack_net.dllinstjackovernewer0 diff --git a/windows/Setup/src/README b/windows/Setup/src/README index 589d874d..eef08432 100644 --- a/windows/Setup/src/README +++ b/windows/Setup/src/README @@ -28,7 +28,7 @@ It is compiled from the latest CVS version which is using QT4 framework. To uses - quit qjackctl.exe and start is again, it should now launch the jack server. Quitting the qjackctl.exe will now close the jack server. Starting the jack server with another audio device installed on the machine (like an ASIO card) can now be done directly in qjackctl. -A ">" button at the right of the interface button allows to list the name of all available devices, driven either by "MME", "Direct Sound", or "ASIO". +A ">" button at the right of the interface button allows to list the name of all available devices, driven either by "MME", "DirectSound", or "ASIO". Alternatively using the following command allows to display the names of available devices: - jackd -d portaudio -l to display the entire list of available audio devices. (jackd -d portaudio -h will display all portaudio driver features) diff --git a/wscript b/wscript index cb44a74a..c4d28c9e 100644 --- a/wscript +++ b/wscript @@ -65,9 +65,9 @@ def set_options(opt): opt.add_option('--doxygen', action='store_true', default=False, help='Enable build of doxygen documentation') opt.add_option('--profile', action='store_true', default=False, help='Build with engine profiling') opt.add_option('--clients', default=64, type="int", dest="clients", help='Maximum number of JACK clients') - opt.add_option('--ports', default=512, type="int", dest="ports", help='Maximum number of ports') + opt.add_option('--ports', default=1024, type="int", dest="ports", help='Maximum number of ports') opt.add_option('--clients', default=64, type="int", dest="clients", help='Maximum number of JACK clients') - opt.add_option('--ports', default=512, type="int", dest="ports", help='Maximum number of ports') + opt.add_option('--ports', default=1024, type="int", dest="ports", help='Maximum number of ports') opt.sub_options('dbus') def configure(conf): From b63e6a8feb002d9fd6b58be9cdc03702e855378c Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 10 Mar 2009 11:56:47 +0000 Subject: [PATCH 012/472] rebase from trunk 3401:3420 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3421 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 11 +- common/JackAudioAdapterInterface.cpp | 51 ++++------ common/JackAudioAdapterInterface.h | 42 ++++---- common/JackEngineProfiling.h | 2 +- common/JackFilters.h | 112 +++++++++++++++++++++ common/JackGraphManager.cpp | 6 +- common/JackLibSampleRateResampler.cpp | 4 +- common/JackLibSampleRateResampler.h | 12 --- common/JackNetAdapter.cpp | 29 ++++-- common/JackNetTool.cpp | 12 +-- common/JackResampler.cpp | 10 +- common/JackResampler.h | 26 +++-- common/memops.c | 2 +- linux/alsa/JackAlsaAdapter.cpp | 2 +- macosx/coreaudio/JackCoreAudioAdapter.cpp | 4 +- solaris/oss/JackOSSAdapter.cpp | 2 +- windows/JackNetWinSocket.cpp | 8 +- windows/Setup/src/README | 4 +- windows/portaudio/JackPortAudioAdapter.cpp | 2 +- 19 files changed, 231 insertions(+), 110 deletions(-) diff --git a/ChangeLog b/ChangeLog index e23d51ba..f650afa5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,12 +17,21 @@ Nedko Arnaudov Fernando Lopez-Lezcano Romain Moret Florian Faber -Michael Voigt +Michael Voigt +Torben Hohn --------------------------- Jackdmp changes log --------------------------- +2009-03-10 Stephane Letz + + * Add -g (ring-buffer) parameter to netadapter. + +2009-03-09 Stephane Letz + + * Use Torben Hohn PI controler code for adapters (in progress). + 2009-03-05 Stephane Letz * Support for BIG_ENDIAN machines in NetJack2 for transport data. diff --git a/common/JackAudioAdapterInterface.cpp b/common/JackAudioAdapterInterface.cpp index 0e666f3b..364e70f5 100644 --- a/common/JackAudioAdapterInterface.cpp +++ b/common/JackAudioAdapterInterface.cpp @@ -58,6 +58,7 @@ namespace Jack } fclose(file); + /* No used for now // Adapter timing 1 file = fopen("AdapterTiming1.plot", "w"); fprintf(file, "set multiplot\n"); @@ -88,6 +89,7 @@ namespace Jack fprintf(file, buffer); fclose(file); + */ // Adapter timing 2 file = fopen("AdapterTiming2.plot", "w"); @@ -162,30 +164,7 @@ namespace Jack fPlaybackRingBuffer[i]->Reset(); } - void JackAudioAdapterInterface::ResampleFactor ( jack_time_t& frame1, jack_time_t& frame2 ) - { - jack_time_t time = GetMicroSeconds(); - - if (!fRunning) { - // Init DLL - fRunning = true; - fHostDLL.Init(time); - fAdaptedDLL.Init(time); - frame1 = 1; - frame2 = 1; - } else { - // DLL - fAdaptedDLL.IncFrame(time); - jack_nframes_t time1 = fHostDLL.Time2Frames(time); - jack_nframes_t time2 = fAdaptedDLL.Time2Frames(time); - frame1 = time1; - frame2 = time2; - jack_log("JackAudioAdapterInterface::ResampleFactor time1 = %ld time2 = %ld src_ratio_input = %f src_ratio_output = %f", - long(time1), long(time2), double(time1) / double(time2), double(time2) / double(time1)); - } - } - - void JackAudioAdapterInterface::Reset() + void JackAudioAdapterInterface::Reset() { ResetRingBuffers(); fRunning = false; @@ -226,25 +205,31 @@ namespace Jack int JackAudioAdapterInterface::PushAndPull(float** inputBuffer, float** outputBuffer, unsigned int frames) { bool failure = false; - jack_time_t time1, time2; - ResampleFactor(time1, time2); - + fRunning = true; + + /* + Finer estimation of the position in the ringbuffer ?? + int delta_frames = (int)(float(long(GetMicroSeconds() - fPullAndPushTime)) * float(fAdaptedSampleRate)) / 1000000.f; + double ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetOffset() - delta_frames); + */ + + double ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetOffset()); + // Push/pull from ringbuffer for (int i = 0; i < fCaptureChannels; i++) { - fCaptureRingBuffer[i]->SetRatio(time1, time2); + fCaptureRingBuffer[i]->SetRatio(ratio); if (fCaptureRingBuffer[i]->WriteResample(inputBuffer[i], frames) < frames) failure = true; } for (int i = 0; i < fPlaybackChannels; i++) { - fPlaybackRingBuffer[i]->SetRatio(time2, time1); + fPlaybackRingBuffer[i]->SetRatio(1 / ratio); if (fPlaybackRingBuffer[i]->ReadResample(outputBuffer[i], frames) < frames) failure = true; } #ifdef JACK_MONITOR - fTable.Write(time1, time2, double(time1) / double(time2), double(time2) / double(time1), - fCaptureRingBuffer[0]->ReadSpace(), fPlaybackRingBuffer[0]->WriteSpace()); + fTable.Write(0, 0, ratio, 1/ratio, fCaptureRingBuffer[0]->ReadSpace(), fPlaybackRingBuffer[0]->WriteSpace()); #endif // Reset all ringbuffers in case of failure @@ -260,8 +245,8 @@ namespace Jack int JackAudioAdapterInterface::PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int frames) { bool failure = false; - fHostDLL.IncFrame(GetMicroSeconds()); - + fPullAndPushTime = GetMicroSeconds(); + // Push/pull from ringbuffer for (int i = 0; i < fCaptureChannels; i++) { if (fCaptureRingBuffer[i]->Read(inputBuffer[i], frames) < frames) diff --git a/common/JackAudioAdapterInterface.h b/common/JackAudioAdapterInterface.h index 4b06d0d3..e843a453 100644 --- a/common/JackAudioAdapterInterface.h +++ b/common/JackAudioAdapterInterface.h @@ -82,36 +82,34 @@ namespace Jack jack_nframes_t fAdaptedBufferSize; jack_nframes_t fAdaptedSampleRate; - //delay locked loop - JackAtomicDelayLockedLoop fHostDLL; - JackAtomicDelayLockedLoop fAdaptedDLL; + //PI controler + JackPIControler fPIControler; JackResampler** fCaptureRingBuffer; JackResampler** fPlaybackRingBuffer; unsigned int fQuality; unsigned int fRingbufferSize; + jack_time_t fPullAndPushTime; bool fRunning; void ResetRingBuffers(); - void ResampleFactor ( jack_time_t& frame1, jack_time_t& frame2 ); public: - JackAudioAdapterInterface ( jack_nframes_t host_buffer_size, - jack_nframes_t host_sample_rate) : - fCaptureChannels ( 0 ), - fPlaybackChannels ( 0 ), - fHostBufferSize ( host_buffer_size ), - fHostSampleRate ( host_sample_rate ), - fAdaptedBufferSize ( host_buffer_size), - fAdaptedSampleRate ( host_sample_rate ), - fHostDLL ( host_buffer_size, host_sample_rate ), - fAdaptedDLL ( host_buffer_size, host_sample_rate ), - fQuality(0), - fRingbufferSize(DEFAULT_RB_SIZE), - fRunning ( false ) + JackAudioAdapterInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ): + fCaptureChannels ( 0 ), + fPlaybackChannels ( 0 ), + fHostBufferSize ( buffer_size ), + fHostSampleRate ( sample_rate ), + fAdaptedBufferSize ( buffer_size), + fAdaptedSampleRate ( sample_rate ), + fPIControler(sample_rate / sample_rate, 256), + fCaptureRingBuffer(NULL), fPlaybackRingBuffer(NULL), + fQuality(0), fRingbufferSize(DEFAULT_RB_SIZE), + fPullAndPushTime(0), + fRunning(false) {} JackAudioAdapterInterface ( jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, @@ -123,10 +121,10 @@ namespace Jack fHostSampleRate ( host_sample_rate ), fAdaptedBufferSize ( adapted_buffer_size), fAdaptedSampleRate ( adapted_sample_rate ), - fHostDLL ( host_buffer_size, host_sample_rate ), - fAdaptedDLL ( adapted_buffer_size, adapted_sample_rate ), + fPIControler(host_sample_rate / host_sample_rate, 256), fQuality(0), fRingbufferSize(DEFAULT_RB_SIZE), + fPullAndPushTime(0), fRunning ( false ) {} @@ -156,14 +154,12 @@ namespace Jack virtual int SetHostBufferSize ( jack_nframes_t buffer_size ) { fHostBufferSize = buffer_size; - fHostDLL.Init ( fHostBufferSize, fHostSampleRate ); return 0; } virtual int SetAdaptedBufferSize ( jack_nframes_t buffer_size ) { fAdaptedBufferSize = buffer_size; - fAdaptedDLL.Init ( fAdaptedBufferSize, fAdaptedSampleRate ); return 0; } @@ -177,14 +173,14 @@ namespace Jack virtual int SetHostSampleRate ( jack_nframes_t sample_rate ) { fHostSampleRate = sample_rate; - fHostDLL.Init ( fHostBufferSize, fHostSampleRate ); + fPIControler.Init(double(fHostSampleRate) / double(fAdaptedSampleRate)); return 0; } virtual int SetAdaptedSampleRate ( jack_nframes_t sample_rate ) { fAdaptedSampleRate = sample_rate; - fAdaptedDLL.Init ( fAdaptedBufferSize, fAdaptedSampleRate ); + fPIControler.Init(double(fHostSampleRate) / double(fAdaptedSampleRate)); return 0; } diff --git a/common/JackEngineProfiling.h b/common/JackEngineProfiling.h index 71abca1b..bc82627f 100644 --- a/common/JackEngineProfiling.h +++ b/common/JackEngineProfiling.h @@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -#define TIME_POINTS 250000 +#define TIME_POINTS 125000 #define FAILURE_TIME_POINTS 10000 #define FAILURE_WINDOW 10 #define MEASURED_CLIENTS 32 diff --git a/common/JackFilters.h b/common/JackFilters.h index a7fb3366..dada7204 100644 --- a/common/JackFilters.h +++ b/common/JackFilters.h @@ -23,6 +23,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "jack.h" #include "JackAtomicState.h" #include +#include namespace Jack { @@ -201,6 +202,117 @@ namespace Jack return res; } }; + + /* + Torben Hohn PI controler from JACK1 + */ + + struct JackPIControler { + + double resample_mean; + double static_resample_factor; + + double* offset_array; + double* window_array; + int offset_differential_index; + + double offset_integral; + + double catch_factor; + double catch_factor2; + double pclamp; + double controlquant; + int smooth_size; + + double hann(double x) + { + return 0.5 * (1.0 - cos(2 * M_PI * x)); + } + + JackPIControler(double resample_factor, int fir_size) + { + resample_mean = resample_factor; + static_resample_factor = resample_factor; + offset_array = new double[fir_size]; + window_array = new double[fir_size]; + offset_differential_index = 0; + offset_integral = 0.0; + smooth_size = fir_size; + + for (int i = 0; i < fir_size; i++) { + offset_array[i] = 0.0; + window_array[i] = hann(double(i) / (double(fir_size) - 1.0)); + } + + // These values could be configurable + catch_factor = 100000; + catch_factor2 = 10000; + pclamp = 15.0; + controlquant = 10000.0; + } + + ~JackPIControler() + { + delete[] offset_array; + delete[] window_array; + } + + void Init(double resample_factor) + { + resample_mean = resample_factor; + static_resample_factor = resample_factor; + } + + double GetRatio(int fill_level) + { + double offset = fill_level; + + // Save offset. + offset_array[(offset_differential_index++) % smooth_size] = offset; + + // Build the mean of the windowed offset array basically fir lowpassing. + double smooth_offset = 0.0; + for (int i = 0; i < smooth_size; i++) { + smooth_offset += offset_array[(i + offset_differential_index - 1) % smooth_size] * window_array[i]; + } + smooth_offset /= double(smooth_size); + + // This is the integral of the smoothed_offset + offset_integral += smooth_offset; + + // Clamp offset : the smooth offset still contains unwanted noise which would go straigth onto the resample coeff. + // It only used in the P component and the I component is used for the fine tuning anyways. + if (fabs(smooth_offset) < pclamp) + smooth_offset = 0.0; + + // Ok, now this is the PI controller. + // u(t) = K * (e(t) + 1/T \int e(t') dt') + // Kp = 1/catch_factor and T = catch_factor2 Ki = Kp/T + double current_resample_factor + = static_resample_factor - smooth_offset / catch_factor - offset_integral / catch_factor / catch_factor2; + + // Now quantize this value around resample_mean, so that the noise which is in the integral component doesnt hurt. + current_resample_factor = floor((current_resample_factor - resample_mean) * controlquant + 0.5) / controlquant + resample_mean; + + // Calculate resample_mean so we can init ourselves to saner values. + resample_mean = 0.9999 * resample_mean + 0.0001 * current_resample_factor; + return current_resample_factor; + } + + void OurOfBounds() + { + int i; + // Set the resample_rate... we need to adjust the offset integral, to do this. + // first look at the PI controller, this code is just a special case, which should never execute once + // everything is swung in. + offset_integral = - (resample_mean - static_resample_factor) * catch_factor * catch_factor2; + // Also clear the array. we are beginning a new control cycle. + for (i = 0; i < smooth_size; i++) { + offset_array[i] = 0.0; + } + } + + }; } diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index 922b9b5b..c34ea5d4 100644 --- a/common/JackGraphManager.cpp +++ b/common/JackGraphManager.cpp @@ -542,7 +542,7 @@ int JackGraphManager::Connect(jack_port_id_t port_src, jack_port_id_t port_dst) jack_error("JackGraphManager::Connect failed port_src = %ld port_dst = %ld", port_src, port_dst); goto end; } - manager->Connect(port_dst, port_src); + res = manager->Connect(port_dst, port_src); if (res < 0) { jack_error("JackGraphManager::Connect failed port_dst = %ld port_src = %ld", port_dst, port_src); goto end; @@ -583,12 +583,12 @@ int JackGraphManager::Disconnect(jack_port_id_t port_src, jack_port_id_t port_ds goto end; } - manager->Disconnect(port_src, port_dst); + res = manager->Disconnect(port_src, port_dst); if (res < 0) { jack_error("JackGraphManager::Disconnect failed port_src = %ld port_dst = %ld", port_src, port_dst); goto end; } - manager->Disconnect(port_dst, port_src); + res = manager->Disconnect(port_dst, port_src); if (res < 0) { jack_error("JackGraphManager::Disconnect failed port_dst = %ld port_src = %ld", port_dst, port_src); goto end; diff --git a/common/JackLibSampleRateResampler.cpp b/common/JackLibSampleRateResampler.cpp index a2dfb472..e2486749 100644 --- a/common/JackLibSampleRateResampler.cpp +++ b/common/JackLibSampleRateResampler.cpp @@ -23,7 +23,7 @@ namespace Jack { JackLibSampleRateResampler::JackLibSampleRateResampler() - :JackResampler(),fRatio(1) + :JackResampler() { int error; fResampler = src_new(SRC_LINEAR, 1, &error); @@ -32,7 +32,7 @@ JackLibSampleRateResampler::JackLibSampleRateResampler() } JackLibSampleRateResampler::JackLibSampleRateResampler(unsigned int quality, unsigned int ringbuffer_size) - :JackResampler(ringbuffer_size),fRatio(1) + :JackResampler(ringbuffer_size) { switch (quality) { case 0: diff --git a/common/JackLibSampleRateResampler.h b/common/JackLibSampleRateResampler.h index bbb85cba..3abc1619 100644 --- a/common/JackLibSampleRateResampler.h +++ b/common/JackLibSampleRateResampler.h @@ -26,11 +26,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { -inline float Range(float min, float max, float val) -{ - return (val < min) ? min : ((val > max) ? max : val); -} - /*! \brief Resampler using "libsamplerate" (http://www.mega-nerd.com/SRC/). */ @@ -41,7 +36,6 @@ class JackLibSampleRateResampler : public JackResampler private: SRC_STATE* fResampler; - double fRatio; public: @@ -51,12 +45,6 @@ class JackLibSampleRateResampler : public JackResampler unsigned int ReadResample(float* buffer, unsigned int frames); unsigned int WriteResample(float* buffer, unsigned int frames); - - void SetRatio(unsigned int num, unsigned int denom) - { - JackResampler::SetRatio(num, denom); - fRatio = Range(0.25, 4.0, (double(num) / double(denom))); - } void Reset(); diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index 2ce50cbf..f5512eb5 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -95,6 +95,9 @@ namespace Jack case 'q': fQuality = param->value.ui; break; + case 'g': + fRingbufferSize = param->value.ui; + break; } } @@ -151,6 +154,10 @@ namespace Jack { jack_log ( "JackNetAdapter::Close" ); +#ifdef JACK_MONITOR + fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize); +#endif + switch ( fThread.GetStatus() ) { // Kill the thread in Init phase @@ -386,7 +393,7 @@ extern "C" strcpy(desc->name, "netadapter"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->desc, "netjack net <==> audio backend adapter"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - desc->nparams = 10; + desc->nparams = 11; desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) ); int i = 0; @@ -414,7 +421,7 @@ extern "C" strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); i++; - strcpy ( desc->params[i].name, "input_ports" ); + strcpy ( desc->params[i].name, "input-ports" ); desc->params[i].character = 'C'; desc->params[i].type = JackDriverParamInt; desc->params[i].value.i = 2; @@ -422,7 +429,7 @@ extern "C" strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); i++; - strcpy ( desc->params[i].name, "output_ports" ); + strcpy ( desc->params[i].name, "output-ports" ); desc->params[i].character = 'P'; desc->params[i].type = JackDriverParamInt; desc->params[i].value.i = 2; @@ -430,7 +437,7 @@ extern "C" strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); i++; - strcpy ( desc->params[i].name, "client_name" ); + strcpy ( desc->params[i].name, "client-name" ); desc->params[i].character = 'n'; desc->params[i].type = JackDriverParamString; strcpy ( desc->params[i].value.str, "'hostname'" ); @@ -438,7 +445,7 @@ extern "C" strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); i++; - strcpy ( desc->params[i].name, "transport_sync" ); + strcpy ( desc->params[i].name, "transport-sync" ); desc->params[i].character = 't'; desc->params[i].type = JackDriverParamUInt; desc->params[i].value.ui = 1U; @@ -462,13 +469,21 @@ extern "C" strcpy(desc->params[i].long_desc, desc->params[i].short_desc); i++; - strcpy ( desc->params[i].name, "auto_connect" ); + strcpy(desc->params[i].name, "ring-buffer"); + desc->params[i].character = 'g'; + desc->params[i].type = JackDriverParamInt; + desc->params[i].value.ui = 0; + strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 16384)"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy ( desc->params[i].name, "auto-connect" ); desc->params[i].character = 'c'; desc->params[i].type = JackDriverParamBool; desc->params[i].value.i = false; strcpy ( desc->params[i].short_desc, "Auto connect netmaster to system ports" ); strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); - + return desc; } diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index b35af904..0d63f33d 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -421,14 +421,14 @@ namespace Jack dst_params->fPosition.beat = htonl(src_params->fPosition.beat); dst_params->fPosition.tick = htonl(src_params->fPosition.tick); dst_params->fPosition.bar_start_tick = htonll((uint64_t)src_params->fPosition.bar_start_tick); - dst_params->fPosition.beats_per_bar = htonl(src_params->fPosition.beats_per_bar); - dst_params->fPosition.beat_type = htonl(src_params->fPosition.beat_type); + dst_params->fPosition.beats_per_bar = htonl((uint32_t)src_params->fPosition.beats_per_bar); + dst_params->fPosition.beat_type = htonl((uint32_t)src_params->fPosition.beat_type); dst_params->fPosition.ticks_per_beat = htonll((uint64_t)src_params->fPosition.ticks_per_beat); dst_params->fPosition.beats_per_minute = htonll((uint64_t)src_params->fPosition.beats_per_minute); dst_params->fPosition.frame_time = htonll((uint64_t)src_params->fPosition.frame_time); dst_params->fPosition.next_time = htonll((uint64_t)src_params->fPosition.next_time); dst_params->fPosition.bbt_offset = htonl(src_params->fPosition.bbt_offset); - dst_params->fPosition.audio_frames_per_video_frame = htonl(src_params->fPosition.audio_frames_per_video_frame); + dst_params->fPosition.audio_frames_per_video_frame = htonl((uint32_t)src_params->fPosition.audio_frames_per_video_frame); dst_params->fPosition.video_offset = htonl(src_params->fPosition.video_offset); dst_params->fPosition.unique_2 = htonll(src_params->fPosition.unique_2); } @@ -446,14 +446,14 @@ namespace Jack dst_params->fPosition.beat = ntohl(src_params->fPosition.beat); dst_params->fPosition.tick = ntohl(src_params->fPosition.tick); dst_params->fPosition.bar_start_tick = ntohll((uint64_t)src_params->fPosition.bar_start_tick); - dst_params->fPosition.beats_per_bar = ntohl(src_params->fPosition.beats_per_bar); - dst_params->fPosition.beat_type = ntohl(src_params->fPosition.beat_type); + dst_params->fPosition.beats_per_bar = ntohl((uint32_t)src_params->fPosition.beats_per_bar); + dst_params->fPosition.beat_type = ntohl((uint32_t)src_params->fPosition.beat_type); dst_params->fPosition.ticks_per_beat = ntohll((uint64_t)src_params->fPosition.ticks_per_beat); dst_params->fPosition.beats_per_minute = ntohll((uint64_t)src_params->fPosition.beats_per_minute); dst_params->fPosition.frame_time = ntohll((uint64_t)src_params->fPosition.frame_time); dst_params->fPosition.next_time = ntohll((uint64_t)src_params->fPosition.next_time); dst_params->fPosition.bbt_offset = ntohl(src_params->fPosition.bbt_offset); - dst_params->fPosition.audio_frames_per_video_frame = ntohl(src_params->fPosition.audio_frames_per_video_frame); + dst_params->fPosition.audio_frames_per_video_frame = ntohl((uint32_t)src_params->fPosition.audio_frames_per_video_frame); dst_params->fPosition.video_offset = ntohl(src_params->fPosition.video_offset); dst_params->fPosition.unique_2 = ntohll(src_params->fPosition.unique_2); } diff --git a/common/JackResampler.cpp b/common/JackResampler.cpp index 19945adf..86798d9e 100644 --- a/common/JackResampler.cpp +++ b/common/JackResampler.cpp @@ -23,13 +23,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { -JackResampler::JackResampler():fNum(1),fDenom(1) +JackResampler::JackResampler() + :fRatio(1),fRingBufferSize(DEFAULT_RB_SIZE) { - fRingBuffer = jack_ringbuffer_create(sizeof(float) * DEFAULT_RB_SIZE); - jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * DEFAULT_RB_SIZE) / 2); + fRingBuffer = jack_ringbuffer_create(sizeof(float) * fRingBufferSize); + jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize) / 2); } -JackResampler::JackResampler(unsigned int ringbuffer_size):fNum(1),fDenom(1),fRingBufferSize(ringbuffer_size) +JackResampler::JackResampler(unsigned int ringbuffer_size) + :fRatio(1),fRingBufferSize(ringbuffer_size) { fRingBuffer = jack_ringbuffer_create(sizeof(float) * fRingBufferSize); jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize) / 2); diff --git a/common/JackResampler.h b/common/JackResampler.h index fb6e30f2..d8d2e42c 100644 --- a/common/JackResampler.h +++ b/common/JackResampler.h @@ -26,8 +26,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { -#define DEFAULT_RB_SIZE 16384 * 2 +#define DEFAULT_RB_SIZE 16384 +inline float Range(float min, float max, float val) +{ + return (val < min) ? min : ((val > max) ? max : val); +} + /*! \brief Base class for Resampler. */ @@ -38,8 +43,7 @@ class JackResampler protected: jack_ringbuffer_t* fRingBuffer; - unsigned int fNum; - unsigned int fDenom; + double fRatio; unsigned int fRingBufferSize; public: @@ -58,16 +62,20 @@ class JackResampler virtual unsigned int ReadSpace(); virtual unsigned int WriteSpace(); + + unsigned int GetOffset() + { + return (jack_ringbuffer_read_space(fRingBuffer) / sizeof(float)) - (fRingBufferSize / 2); + } - virtual void SetRatio(unsigned int num, unsigned int denom) + void SetRatio(double ratio) { - fNum = num; - fDenom = denom; + fRatio = Range(0.25, 4.0, ratio); } - virtual void GetRatio(unsigned int& num, unsigned int& denom) + + double GetRatio() { - num = fNum; - denom = fDenom; + return fRatio; } }; diff --git a/common/memops.c b/common/memops.c index fff41f1f..520b3dc8 100644 --- a/common/memops.c +++ b/common/memops.c @@ -342,7 +342,7 @@ void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigne int i4 = *((int *) src); src+= src_skip; - __m128i src = _mm_set_epi32(i1, i2, i3, i4); + __m128i src = _mm_set_epi32(i4, i3, i2, i1); __m128i shifted = _mm_srai_epi32(src, 8); __m128 as_float = _mm_cvtepi32_ps(shifted); diff --git a/linux/alsa/JackAlsaAdapter.cpp b/linux/alsa/JackAlsaAdapter.cpp index b12e4ccd..0e9fb4ce 100644 --- a/linux/alsa/JackAlsaAdapter.cpp +++ b/linux/alsa/JackAlsaAdapter.cpp @@ -287,7 +287,7 @@ extern "C" desc->params[i].character = 'g'; desc->params[i].type = JackDriverParamInt; desc->params[i].value.ui = 0; - strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 32768)"); + strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 16384)"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); return desc; diff --git a/macosx/coreaudio/JackCoreAudioAdapter.cpp b/macosx/coreaudio/JackCoreAudioAdapter.cpp index 18882f9b..dd238b7b 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.cpp +++ b/macosx/coreaudio/JackCoreAudioAdapter.cpp @@ -377,7 +377,7 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra fQuality = param->value.ui; break; - case 'g': + case 'g': fRingbufferSize = param->value.ui; break; } @@ -1081,7 +1081,7 @@ extern "C" desc->params[i].character = 'g'; desc->params[i].type = JackDriverParamInt; desc->params[i].value.ui = 0; - strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 32768)"); + strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 16384)"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); return desc; diff --git a/solaris/oss/JackOSSAdapter.cpp b/solaris/oss/JackOSSAdapter.cpp index 69a59ec7..cbb3e549 100644 --- a/solaris/oss/JackOSSAdapter.cpp +++ b/solaris/oss/JackOSSAdapter.cpp @@ -743,7 +743,7 @@ extern "C" desc->params[i].character = 'g'; desc->params[i].type = JackDriverParamInt; desc->params[i].value.ui = 0; - strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 32768)"); + strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 16384)"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); return desc; diff --git a/windows/JackNetWinSocket.cpp b/windows/JackNetWinSocket.cpp index c154ea65..30420b49 100644 --- a/windows/JackNetWinSocket.cpp +++ b/windows/JackNetWinSocket.cpp @@ -286,7 +286,13 @@ namespace Jack //local loop********************************************************************************************************* int JackNetWinSocket::SetLocalLoop() { - char disable = 0; + //char disable = 0; + /* + see http://msdn.microsoft.com/en-us/library/aa916098.aspx + Default value is TRUE. When TRUE, data that is sent from the local interface to the multicast group to + which the socket is joined, including data sent from the same socket, will be echoed to its receive buffer. + */ + char disable = 1; return SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof ( disable ) ); } diff --git a/windows/Setup/src/README b/windows/Setup/src/README index eef08432..eafc21ae 100644 --- a/windows/Setup/src/README +++ b/windows/Setup/src/README @@ -50,10 +50,10 @@ JackRouter is an ASIO driver that allows any ASIO compatible application to beco ============================================= -Known problems: +Known problems ============================================= -- starting/stopping the server several times in QJACKCTL does not work correctly. You'll have to quit qjacckctl and launch it again. +- starting/stopping the server several times in QJACKCTL does not work correctly. You'll have to quit qjackctl and launch it again. ============================================= diff --git a/windows/portaudio/JackPortAudioAdapter.cpp b/windows/portaudio/JackPortAudioAdapter.cpp index a5beb232..17972e6b 100644 --- a/windows/portaudio/JackPortAudioAdapter.cpp +++ b/windows/portaudio/JackPortAudioAdapter.cpp @@ -299,7 +299,7 @@ extern "C" desc->params[i].character = 'g'; desc->params[i].type = JackDriverParamInt; desc->params[i].value.ui = 0; - strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 32768)"); + strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 16384)"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); return desc; From 51fbf0cf719645d0d0f532f25072d949958c359f Mon Sep 17 00:00:00 2001 From: sletz Date: Thu, 19 Mar 2009 10:38:23 +0000 Subject: [PATCH 013/472] rebase from trunk 3420:3447 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3448 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 43 ++++--- common/JackAPI.cpp | 17 ++- common/JackAudioAdapter.cpp | 29 ++--- common/JackAudioAdapterInterface.cpp | 109 +++++++++++------- common/JackAudioAdapterInterface.h | 26 +++-- common/JackClient.cpp | 2 - common/JackConnectionManager.cpp | 5 - common/JackConnectionManager.h | 7 +- common/JackEngineControl.cpp | 43 ------- common/JackEngineControl.h | 44 +++++-- common/JackEngineProfiling.h | 2 +- common/JackFilters.h | 24 +++- common/JackFrameTimer.h | 2 +- common/JackGlobals.cpp | 6 +- common/JackGlobals.h | 7 +- common/JackGraphManager.cpp | 5 - common/JackGraphManager.h | 6 +- common/JackLibSampleRateResampler.cpp | 8 +- common/JackLibSampleRateResampler.h | 4 +- common/JackNetAPI.cpp | 4 +- common/JackNetAdapter.cpp | 34 +++--- common/JackNetDriver.cpp | 5 +- common/JackNetManager.cpp | 9 +- common/JackResampler.cpp | 14 +-- common/JackResampler.h | 8 +- common/JackThreadedDriver.cpp | 1 + common/JackTransportEngine.cpp | 6 - common/JackTransportEngine.h | 6 +- common/JackWaitThreadedDriver.cpp | 3 +- common/jack/ringbuffer.h | 10 ++ common/jack/thread.h | 35 +++++- common/ringbuffer.c | 14 +++ common/wscript | 1 + linux/alsa/JackAlsaAdapter.cpp | 12 +- linux/wscript | 1 + macosx/coreaudio/JackCoreAudioAdapter.cpp | 9 +- .../iPhoneNet.xcodeproj/project.pbxproj | 10 ++ posix/JackFifo.cpp | 6 +- posix/JackPosixThread.cpp | 3 +- posix/JackSocket.cpp | 100 ++-------------- posix/JackSocket.h | 7 +- posix/JackTypes_os.h | 2 + solaris/oss/JackOSSAdapter.cpp | 22 ++-- windows/portaudio/JackPortAudioAdapter.cpp | 11 +- 44 files changed, 390 insertions(+), 332 deletions(-) diff --git a/ChangeLog b/ChangeLog index f650afa5..e29fb0e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,38 +17,55 @@ Nedko Arnaudov Fernando Lopez-Lezcano Romain Moret Florian Faber -Michael Voigt +Michael Voigt Torben Hohn --------------------------- Jackdmp changes log ---------------------------- +--------------------------- -2009-03-10 Stephane Letz +2009-03-19 Stephane Letz + + * Tim Blechmann optimization patch (inlining some heavy used methods). + +2009-03-12 Stephane Letz - * Add -g (ring-buffer) parameter to netadapter. + * Virtualize and allow overriding of thread creation function, to allow Wine support (from JACK1). +2009-03-12 Stephane Letz + + * Try automatic adaptative mode in adapters. + +2009-03-11 Stephane Letz + + * Client incorrect re-naming fixed : now done at socket level also. + +2009-03-10 Stephane Letz + + * Add -g (ring-buffer) parameter to netadapter. + * Automatic adaptative ringbuffer size mode when -g = 0. + 2009-03-09 Stephane Letz - * Use Torben Hohn PI controler code for adapters (in progress). - + * Use Torben Hohn PI controler code for adapters (in progress). + 2009-03-05 Stephane Letz - * Support for BIG_ENDIAN machines in NetJack2 for transport data. + * Support for BIG_ENDIAN machines in NetJack2 for transport data. * Add auto_connect parameter in netmanager and netadapter. - + 2009-03-03 Stephane Letz * More robust profiling tools when clients come and go. - + 2009-03-01 Stephane Letz * Raise default port number to 1024. - + 2009-02-27 Stephane Letz * Improve generated gnuplot files for adapting code. - + 2009-02-25 Stephane Letz * Major cleanup in adapter code. @@ -57,8 +74,8 @@ Torben Hohn * Fix JackNetDriver::Close method. * For audio device reservation, add card_to_num function. - * Fix buffer size and sample rate handling in JackAlsaAdapter. - * Add control for adapter ringbuffer size. + * Fix buffer size and sample rate handling in JackAlsaAdapter. + * Add control for adapter ringbuffer size. * Fix JackAlsaAdapter.h for 64 bits compilation. 2009-02-24 Stephane Letz diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index 02b8ff8d..fa7b4f22 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -219,10 +219,12 @@ extern "C" thread_routine routine, void *arg); EXPORT int jack_drop_real_time_scheduling (pthread_t thread); - + EXPORT int jack_client_stop_thread (jack_client_t* client, pthread_t thread); EXPORT int jack_client_kill_thread (jack_client_t* client, pthread_t thread); - +#ifndef WIN32 + EXPORT void jack_set_thread_creator (jack_thread_creator_t jtc); +#endif EXPORT char * jack_get_internal_client_name (jack_client_t *client, jack_intclient_t intclient); EXPORT jack_intclient_t jack_internal_client_handle (jack_client_t *client, @@ -1759,8 +1761,8 @@ EXPORT int jack_client_max_real_time_priority(jack_client_t* ext_client) JackEngineControl* control = GetEngineControl(); return (control->fRealTime) ? control->fMaxClientPriority : -1; } -} - +} + EXPORT int jack_acquire_real_time_scheduling(pthread_t thread, int priority) { JackEngineControl* control = GetEngineControl(); @@ -1792,6 +1794,13 @@ EXPORT int jack_client_kill_thread(jack_client_t* client, pthread_t thread) return JackThread::KillImp(thread); } +#ifndef WIN32 +EXPORT void jack_set_thread_creator (jack_thread_creator_t jtc) +{ + JackGlobals::fJackThreadCreator = jtc; +} +#endif + // intclient.h EXPORT int jack_internal_client_new (const char *client_name, const char *load_name, diff --git a/common/JackAudioAdapter.cpp b/common/JackAudioAdapter.cpp index 6961a06f..03f4605f 100644 --- a/common/JackAudioAdapter.cpp +++ b/common/JackAudioAdapter.cpp @@ -36,20 +36,21 @@ namespace Jack int JackAudioAdapter::Process (jack_nframes_t frames, void* arg) { JackAudioAdapter* adapter = static_cast(arg); - if (!adapter->fAudioAdapter->IsRunning()) - return 0; - float* inputBuffer[adapter->fAudioAdapter->GetInputs()]; float* outputBuffer[adapter->fAudioAdapter->GetOutputs()]; + + // Always clear output for (int i = 0; i < adapter->fAudioAdapter->GetInputs(); i++) { inputBuffer[i] = (float*)jack_port_get_buffer(adapter->fCapturePortList[i], frames); + memset(inputBuffer[i], 0, frames * sizeof(float)); } + for (int i = 0; i < adapter->fAudioAdapter->GetOutputs(); i++) { outputBuffer[i] = (float*)jack_port_get_buffer(adapter->fPlaybackPortList[i], frames); } - + adapter->fAudioAdapter->PullAndPush(inputBuffer, outputBuffer, frames); - return 0; + return 0; } int JackAudioAdapter::BufferSize ( jack_nframes_t buffer_size, void* arg ) @@ -70,23 +71,23 @@ namespace Jack //JackAudioAdapter ********************************************************* - JackAudioAdapter::JackAudioAdapter (jack_client_t* jack_client, JackAudioAdapterInterface* audio_io, const JSList* params, bool system) + JackAudioAdapter::JackAudioAdapter (jack_client_t* jack_client, JackAudioAdapterInterface* audio_io, const JSList* params, bool system) :fJackClient(jack_client), fAudioAdapter(audio_io) { const JSList* node; const jack_driver_param_t* param; fAutoConnect = false; - + for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t*) node->data; switch (param->character) { case 'c': - fAutoConnect = param->value.i; + fAutoConnect = true; break; } } } - + JackAudioAdapter::~JackAudioAdapter() { // When called, Close has already been used for the client, thus ports are already unregistered. @@ -105,11 +106,11 @@ namespace Jack delete[] fCapturePortList; delete[] fPlaybackPortList; } - + void JackAudioAdapter::ConnectPorts() { const char **ports; - + ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput); if (ports != NULL) { for (int i = 0; i < fAudioAdapter->GetInputs() && ports[i]; i++) { @@ -117,7 +118,7 @@ namespace Jack } free(ports); } - + ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); if (ports != NULL) { for (int i = 0; i < fAudioAdapter->GetOutputs() && ports[i]; i++) { @@ -137,7 +138,7 @@ namespace Jack char name[32]; jack_log("JackAudioAdapter::Open fCaptureChannels %d fPlaybackChannels %d", fAudioAdapter->GetInputs(), fAudioAdapter->GetOutputs()); fAudioAdapter->Create(); - + //jack ports fCapturePortList = new jack_port_t*[fAudioAdapter->GetInputs()]; fPlaybackPortList = new jack_port_t*[fAudioAdapter->GetOutputs()]; @@ -165,7 +166,7 @@ namespace Jack goto fail; if ( jack_activate ( fJackClient ) < 0 ) goto fail; - + if (fAutoConnect) ConnectPorts(); diff --git a/common/JackAudioAdapterInterface.cpp b/common/JackAudioAdapterInterface.cpp index 364e70f5..47425d40 100644 --- a/common/JackAudioAdapterInterface.cpp +++ b/common/JackAudioAdapterInterface.cpp @@ -52,13 +52,12 @@ namespace Jack for (int i = 1; i < max; i++) { fprintf(file, "%d \t %d \t %d \t %f \t %f \t %d \t %d \n", - fTable[i].delta, fTable[i+1].time1 - fTable[i].time1, - fTable[i+1].time2 - fTable[i].time2, + fTable[i].delta, fTable[i].time1, fTable[i].time2, fTable[i].r1, fTable[i].r2, fTable[i].pos1, fTable[i].pos2); } fclose(file); - /* No used for now + // No used for now // Adapter timing 1 file = fopen("AdapterTiming1.plot", "w"); fprintf(file, "set multiplot\n"); @@ -68,9 +67,9 @@ namespace Jack fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"frames\"\n"); fprintf(file, "plot "); - sprintf(buffer, "\"JackAudioAdapter.log\" using 2 title \"Consumer interrupt period\" with lines,"); + sprintf(buffer, "\"JackAudioAdapter.log\" using 2 title \"Ringbuffer error\" with lines,"); fprintf(file, buffer); - sprintf(buffer, "\"JackAudioAdapter.log\" using 3 title \"Producer interrupt period\" with lines"); + sprintf(buffer, "\"JackAudioAdapter.log\" using 3 title \"Ringbuffer error with timing correction\" with lines"); fprintf(file, buffer); fprintf(file, "\n unset multiplot\n"); @@ -89,8 +88,7 @@ namespace Jack fprintf(file, buffer); fclose(file); - */ - + // Adapter timing 2 file = fopen("AdapterTiming2.plot", "w"); fprintf(file, "set multiplot\n"); @@ -155,16 +153,32 @@ namespace Jack } #endif + + void JackAudioAdapterInterface::GrowRingBufferSize() + { + fRingbufferCurSize *= 2; + } + + void JackAudioAdapterInterface::AdaptRingBufferSize() + { + if (fHostBufferSize > fAdaptedBufferSize) + fRingbufferCurSize = 4 * fHostBufferSize; + else + fRingbufferCurSize = 4 * fAdaptedBufferSize; + } void JackAudioAdapterInterface::ResetRingBuffers() { + if (fRingbufferCurSize > DEFAULT_RB_SIZE) + fRingbufferCurSize = DEFAULT_RB_SIZE; + for (int i = 0; i < fCaptureChannels; i++) - fCaptureRingBuffer[i]->Reset(); + fCaptureRingBuffer[i]->Reset(fRingbufferCurSize); for (int i = 0; i < fPlaybackChannels; i++) - fPlaybackRingBuffer[i]->Reset(); + fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize); } - - void JackAudioAdapterInterface::Reset() + + void JackAudioAdapterInterface::Reset() { ResetRingBuffers(); fRunning = false; @@ -179,11 +193,25 @@ namespace Jack //ringbuffers fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; - for (int i = 0; i < fCaptureChannels; i++ ) - fCaptureRingBuffer[i] = new JackLibSampleRateResampler(fQuality, fRingbufferSize); - for (int i = 0; i < fPlaybackChannels; i++ ) - fPlaybackRingBuffer[i] = new JackLibSampleRateResampler(fQuality, fRingbufferSize); - + + if (fAdaptative) { + AdaptRingBufferSize(); + jack_info("Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize); + } else { + if (fRingbufferCurSize > DEFAULT_RB_SIZE) + fRingbufferCurSize = DEFAULT_RB_SIZE; + jack_info("Fixed ringbuffer size = %d frames", fRingbufferCurSize); + } + + for (int i = 0; i < fCaptureChannels; i++ ) { + fCaptureRingBuffer[i] = new JackLibSampleRateResampler(fQuality); + fCaptureRingBuffer[i]->Reset(fRingbufferCurSize); + } + for (int i = 0; i < fPlaybackChannels; i++ ) { + fPlaybackRingBuffer[i] = new JackLibSampleRateResampler(fQuality); + fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize); + } + if (fCaptureChannels > 0) jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace()); if (fPlaybackChannels > 0) @@ -206,14 +234,14 @@ namespace Jack { bool failure = false; fRunning = true; + + // Finer estimation of the position in the ringbuffer + int delta_frames = (fPullAndPushTime > 0) ? (int)((float(long(GetMicroSeconds() - fPullAndPushTime)) * float(fAdaptedSampleRate)) / 1000000.f) : 0; + double ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetError() - delta_frames); - /* - Finer estimation of the position in the ringbuffer ?? - int delta_frames = (int)(float(long(GetMicroSeconds() - fPullAndPushTime)) * float(fAdaptedSampleRate)) / 1000000.f; - double ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetOffset() - delta_frames); - */ - - double ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetOffset()); + #ifdef JACK_MONITOR + fTable.Write(fCaptureRingBuffer[0]->GetError(), fCaptureRingBuffer[0]->GetError() - delta_frames, ratio, 1/ratio, fCaptureRingBuffer[0]->ReadSpace(), fCaptureRingBuffer[0]->ReadSpace()); + #endif // Push/pull from ringbuffer for (int i = 0; i < fCaptureChannels; i++) { @@ -223,18 +251,17 @@ namespace Jack } for (int i = 0; i < fPlaybackChannels; i++) { - fPlaybackRingBuffer[i]->SetRatio(1 / ratio); + fPlaybackRingBuffer[i]->SetRatio(1/ratio); if (fPlaybackRingBuffer[i]->ReadResample(outputBuffer[i], frames) < frames) failure = true; } - - #ifdef JACK_MONITOR - fTable.Write(0, 0, ratio, 1/ratio, fCaptureRingBuffer[0]->ReadSpace(), fPlaybackRingBuffer[0]->WriteSpace()); - #endif - // Reset all ringbuffers in case of failure if (failure) { jack_error("JackAudioAdapterInterface::PushAndPull ringbuffer failure... reset"); + if (fAdaptative) { + GrowRingBufferSize(); + jack_info("Ringbuffer size = %d frames", fRingbufferCurSize); + } ResetRingBuffers(); return -1; } else { @@ -244,28 +271,24 @@ namespace Jack int JackAudioAdapterInterface::PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int frames) { - bool failure = false; fPullAndPushTime = GetMicroSeconds(); - + if (!fRunning) + return 0; + + int res = 0; + // Push/pull from ringbuffer for (int i = 0; i < fCaptureChannels; i++) { if (fCaptureRingBuffer[i]->Read(inputBuffer[i], frames) < frames) - failure = true; + res = -1; } for (int i = 0; i < fPlaybackChannels; i++) { if (fPlaybackRingBuffer[i]->Write(outputBuffer[i], frames) < frames) - failure = true; - } - - // Reset all ringbuffers in case of failure - if (failure) { - jack_error("JackCallbackAudioAdapter::PullAndPush ringbuffer failure... reset"); - Reset(); - return -1; - } else { - return 0; + res = -1; } + + return res; } - + } // namespace diff --git a/common/JackAudioAdapterInterface.h b/common/JackAudioAdapterInterface.h index e843a453..acf2b400 100644 --- a/common/JackAudioAdapterInterface.h +++ b/common/JackAudioAdapterInterface.h @@ -23,6 +23,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackResampler.h" #include "JackFilters.h" #include "JackConstants.h" +#include namespace Jack { @@ -89,12 +90,15 @@ namespace Jack JackResampler** fPlaybackRingBuffer; unsigned int fQuality; - unsigned int fRingbufferSize; + unsigned int fRingbufferCurSize; jack_time_t fPullAndPushTime; - + bool fRunning; + bool fAdaptative; void ResetRingBuffers(); + void AdaptRingBufferSize(); + void GrowRingBufferSize(); public: @@ -107,9 +111,11 @@ namespace Jack fAdaptedSampleRate ( sample_rate ), fPIControler(sample_rate / sample_rate, 256), fCaptureRingBuffer(NULL), fPlaybackRingBuffer(NULL), - fQuality(0), fRingbufferSize(DEFAULT_RB_SIZE), + fQuality(0), + fRingbufferCurSize(DEFAULT_ADAPTATIVE_SIZE), fPullAndPushTime(0), - fRunning(false) + fRunning(false), + fAdaptative(true) {} JackAudioAdapterInterface ( jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, @@ -123,7 +129,6 @@ namespace Jack fAdaptedSampleRate ( adapted_sample_rate ), fPIControler(host_sample_rate / host_sample_rate, 256), fQuality(0), - fRingbufferSize(DEFAULT_RB_SIZE), fPullAndPushTime(0), fRunning ( false ) {} @@ -131,11 +136,6 @@ namespace Jack virtual ~JackAudioAdapterInterface() {} - bool IsRunning() - { - return fRunning; - } - virtual void Reset(); virtual void Create(); @@ -154,12 +154,16 @@ namespace Jack virtual int SetHostBufferSize ( jack_nframes_t buffer_size ) { fHostBufferSize = buffer_size; + if (fAdaptative) + AdaptRingBufferSize(); return 0; } virtual int SetAdaptedBufferSize ( jack_nframes_t buffer_size ) { fAdaptedBufferSize = buffer_size; + if (fAdaptative) + AdaptRingBufferSize(); return 0; } @@ -217,7 +221,7 @@ namespace Jack int PushAndPull(float** inputBuffer, float** outputBuffer, unsigned int frames); int PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int frames); - + }; } diff --git a/common/JackClient.cpp b/common/JackClient.cpp index 88d363e3..3599547e 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -674,13 +674,11 @@ int JackClient::TransportReposition(jack_position_t* pos) jack_transport_state_t JackClient::TransportQuery(jack_position_t* pos) { - jack_log("TransportQuery"); return GetEngineControl()->fTransport.Query(pos); } jack_nframes_t JackClient::GetCurrentTransportFrame() { - jack_log("GetCurrentTransportFrame"); return GetEngineControl()->fTransport.GetCurrentFrame(); } diff --git a/common/JackConnectionManager.cpp b/common/JackConnectionManager.cpp index c84f535e..5108ddcd 100644 --- a/common/JackConnectionManager.cpp +++ b/common/JackConnectionManager.cpp @@ -83,11 +83,6 @@ bool JackConnectionManager::IsLoopPathAux(int ref1, int ref2) const // External API //-------------- -int JackConnectionManager::GetActivation(int refnum) const -{ - return fInputCounter[refnum].GetValue(); -} - /*! \brief Connect port_src to port_dst. */ diff --git a/common/JackConnectionManager.h b/common/JackConnectionManager.h index 94af4c0d..b95261d6 100644 --- a/common/JackConnectionManager.h +++ b/common/JackConnectionManager.h @@ -440,7 +440,12 @@ class SERVER_EXPORT JackConnectionManager void DirectConnect(int ref1, int ref2); void DirectDisconnect(int ref1, int ref2); - int GetActivation(int refnum) const; + int GetActivation(int refnum) const + { + return fInputCounter[refnum].GetValue(); + } + + // Graph void ResetGraph(JackClientTiming* timing); diff --git a/common/JackEngineControl.cpp b/common/JackEngineControl.cpp index b75dcf25..41cf71ef 100644 --- a/common/JackEngineControl.cpp +++ b/common/JackEngineControl.cpp @@ -33,44 +33,6 @@ static inline jack_time_t JACK_MAX(jack_time_t a, jack_time_t b) return (a < b) ? b : a; } -void JackEngineControl::CycleIncTime(jack_time_t callback_usecs) -{ - // Timer - fFrameTimer.IncFrameTime(fBufferSize, callback_usecs, fPeriodUsecs); -} - -void JackEngineControl::CycleBegin(JackClientInterface** table, - JackGraphManager* manager, - jack_time_t cur_cycle_begin, - jack_time_t prev_cycle_end) -{ - fTransport.CycleBegin(fSampleRate, cur_cycle_begin); - CalcCPULoad(table, manager, cur_cycle_begin, prev_cycle_end); -#ifdef JACK_MONITOR - fProfiler.Profile(table, manager, fPeriodUsecs, cur_cycle_begin, prev_cycle_end); -#endif -} - -void JackEngineControl::CycleEnd(JackClientInterface** table) -{ - fTransport.CycleEnd(table, fSampleRate, fBufferSize); -} - -void JackEngineControl::InitFrameTime() -{ - fFrameTimer.InitFrameTime(); -} - -void JackEngineControl::ResetFrameTime(jack_time_t cur_cycle_begin) -{ - fFrameTimer.ResetFrameTime(fSampleRate, cur_cycle_begin, fPeriodUsecs); -} - -void JackEngineControl::ReadFrameTime(JackTimer* timer) -{ - fFrameTimer.ReadFrameTime(timer); -} - void JackEngineControl::CalcCPULoad(JackClientInterface** table, JackGraphManager* manager, jack_time_t cur_cycle_begin, @@ -126,9 +88,4 @@ void JackEngineControl::NotifyXRun(float delayed_usecs) fMaxDelayedUsecs = delayed_usecs; } -void JackEngineControl::ResetXRun() -{ - fMaxDelayedUsecs = 0.f; -} - } // end of namespace diff --git a/common/JackEngineControl.h b/common/JackEngineControl.h index e8d6c8e5..a4e2adcd 100644 --- a/common/JackEngineControl.h +++ b/common/JackEngineControl.h @@ -119,18 +119,48 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem {} // Cycle - void CycleIncTime(jack_time_t callback_usecs); - void CycleBegin(JackClientInterface** table, JackGraphManager* manager, jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end); - void CycleEnd(JackClientInterface** table); + void CycleIncTime(jack_time_t callback_usecs) + { + // Timer + fFrameTimer.IncFrameTime(fBufferSize, callback_usecs, fPeriodUsecs); + } + + void CycleBegin(JackClientInterface** table, JackGraphManager* manager, jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end) + { + fTransport.CycleBegin(fSampleRate, cur_cycle_begin); + CalcCPULoad(table, manager, cur_cycle_begin, prev_cycle_end); +#ifdef JACK_MONITOR + fProfiler.Profile(table, manager, fPeriodUsecs, cur_cycle_begin, prev_cycle_end); +#endif + } + + void CycleEnd(JackClientInterface** table) + { + fTransport.CycleEnd(table, fSampleRate, fBufferSize); + } // Timer - void InitFrameTime(); - void ResetFrameTime(jack_time_t callback_usecs); - void ReadFrameTime(JackTimer* timer); + void InitFrameTime() + { + fFrameTimer.InitFrameTime(); + } + + void ResetFrameTime(jack_time_t callback_usecs) + { + fFrameTimer.ResetFrameTime(fSampleRate, callback_usecs, fPeriodUsecs); + } + + void ReadFrameTime(JackTimer* timer) + { + fFrameTimer.ReadFrameTime(timer); + } // XRun void NotifyXRun(float delayed_usecs); - void ResetXRun(); + void ResetXRun() + { + fMaxDelayedUsecs = 0.f; + } // Private void CalcCPULoad(JackClientInterface** table, JackGraphManager* manager, jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end); diff --git a/common/JackEngineProfiling.h b/common/JackEngineProfiling.h index bc82627f..62c4b86e 100644 --- a/common/JackEngineProfiling.h +++ b/common/JackEngineProfiling.h @@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -#define TIME_POINTS 125000 +#define TIME_POINTS 100000 #define FAILURE_TIME_POINTS 10000 #define FAILURE_WINDOW 10 #define MEASURED_CLIENTS 32 diff --git a/common/JackFilters.h b/common/JackFilters.h index dada7204..2af946d2 100644 --- a/common/JackFilters.h +++ b/common/JackFilters.h @@ -263,20 +263,21 @@ namespace Jack static_resample_factor = resample_factor; } + /* double GetRatio(int fill_level) { double offset = fill_level; // Save offset. offset_array[(offset_differential_index++) % smooth_size] = offset; - + // Build the mean of the windowed offset array basically fir lowpassing. double smooth_offset = 0.0; for (int i = 0; i < smooth_size; i++) { smooth_offset += offset_array[(i + offset_differential_index - 1) % smooth_size] * window_array[i]; } smooth_offset /= double(smooth_size); - + // This is the integral of the smoothed_offset offset_integral += smooth_offset; @@ -284,13 +285,13 @@ namespace Jack // It only used in the P component and the I component is used for the fine tuning anyways. if (fabs(smooth_offset) < pclamp) smooth_offset = 0.0; - + // Ok, now this is the PI controller. // u(t) = K * (e(t) + 1/T \int e(t') dt') // Kp = 1/catch_factor and T = catch_factor2 Ki = Kp/T double current_resample_factor = static_resample_factor - smooth_offset / catch_factor - offset_integral / catch_factor / catch_factor2; - + // Now quantize this value around resample_mean, so that the noise which is in the integral component doesnt hurt. current_resample_factor = floor((current_resample_factor - resample_mean) * controlquant + 0.5) / controlquant + resample_mean; @@ -298,6 +299,21 @@ namespace Jack resample_mean = 0.9999 * resample_mean + 0.0001 * current_resample_factor; return current_resample_factor; } + */ + + + double GetRatio(int error) + { + double smooth_offset = error; + + // This is the integral of the smoothed_offset + offset_integral += smooth_offset; + + // Ok, now this is the PI controller. + // u(t) = K * (e(t) + 1/T \int e(t') dt') + // Kp = 1/catch_factor and T = catch_factor2 Ki = Kp/T + return static_resample_factor - smooth_offset/catch_factor - offset_integral/catch_factor/catch_factor2; + } void OurOfBounds() { diff --git a/common/JackFrameTimer.h b/common/JackFrameTimer.h index fb5ee934..703a90be 100644 --- a/common/JackFrameTimer.h +++ b/common/JackFrameTimer.h @@ -73,7 +73,7 @@ class SERVER_EXPORT JackTimer \brief A class using the JackAtomicState to manage jack time. */ -class JackFrameTimer : public JackAtomicState +class SERVER_EXPORT JackFrameTimer : public JackAtomicState { private: diff --git a/common/JackGlobals.cpp b/common/JackGlobals.cpp index ef005b9e..599523db 100644 --- a/common/JackGlobals.cpp +++ b/common/JackGlobals.cpp @@ -12,7 +12,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. */ @@ -32,4 +32,8 @@ JackMutex* JackGlobals::fOpenMutex = new JackMutex(); bool JackGlobals::fServerRunning = false; JackClient* JackGlobals::fClientTable[CLIENT_NUM] = {}; +#ifndef WIN32 +jack_thread_creator_t JackGlobals::fJackThreadCreator = pthread_create; +#endif + } // end of namespace diff --git a/common/JackGlobals.h b/common/JackGlobals.h index 5b109ed9..8495c062 100644 --- a/common/JackGlobals.h +++ b/common/JackGlobals.h @@ -12,7 +12,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,10 @@ struct JackGlobals { static JackMutex* fOpenMutex; static bool fServerRunning; static JackClient* fClientTable[]; - +#ifndef WIN32 + static jack_thread_creator_t fJackThreadCreator; +#endif + }; } // end of namespace diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index c34ea5d4..ae5f3351 100644 --- a/common/JackGraphManager.cpp +++ b/common/JackGraphManager.cpp @@ -101,11 +101,6 @@ int JackGraphManager::SuspendRefNum(JackClientControl* control, JackSynchro* tab return manager->SuspendRefNum(control, table, fClientTiming, usec); } -JackClientTiming* JackGraphManager::GetClientTiming(int ref) -{ - return &fClientTiming[ref]; -} - // Server void JackGraphManager::DirectConnect(int ref1, int ref2) { diff --git a/common/JackGraphManager.h b/common/JackGraphManager.h index ed32041a..67d482e7 100644 --- a/common/JackGraphManager.h +++ b/common/JackGraphManager.h @@ -120,7 +120,11 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState int ResumeRefNum(JackClientControl* control, JackSynchro* table); int SuspendRefNum(JackClientControl* control, JackSynchro* table, long usecs); - JackClientTiming* GetClientTiming(int refnum); + JackClientTiming* GetClientTiming(int refnum) + { + return &fClientTiming[refnum]; + } + void Save(JackConnectionManager* dst); void Restore(JackConnectionManager* src); diff --git a/common/JackLibSampleRateResampler.cpp b/common/JackLibSampleRateResampler.cpp index e2486749..7475282a 100644 --- a/common/JackLibSampleRateResampler.cpp +++ b/common/JackLibSampleRateResampler.cpp @@ -31,8 +31,8 @@ JackLibSampleRateResampler::JackLibSampleRateResampler() jack_error("JackLibSampleRateResampler::JackLibSampleRateResampler err = %s", src_strerror(error)); } -JackLibSampleRateResampler::JackLibSampleRateResampler(unsigned int quality, unsigned int ringbuffer_size) - :JackResampler(ringbuffer_size) +JackLibSampleRateResampler::JackLibSampleRateResampler(unsigned int quality) + :JackResampler() { switch (quality) { case 0: @@ -67,9 +67,9 @@ JackLibSampleRateResampler::~JackLibSampleRateResampler() src_delete(fResampler); } -void JackLibSampleRateResampler::Reset() +void JackLibSampleRateResampler::Reset(unsigned int new_size) { - JackResampler::Reset(); + JackResampler::Reset(new_size); src_reset(fResampler); } diff --git a/common/JackLibSampleRateResampler.h b/common/JackLibSampleRateResampler.h index 3abc1619..e51a7442 100644 --- a/common/JackLibSampleRateResampler.h +++ b/common/JackLibSampleRateResampler.h @@ -40,13 +40,13 @@ class JackLibSampleRateResampler : public JackResampler public: JackLibSampleRateResampler(); - JackLibSampleRateResampler(unsigned int quality, unsigned int ringbuffer_size); + JackLibSampleRateResampler(unsigned int quality); virtual ~JackLibSampleRateResampler(); unsigned int ReadResample(float* buffer, unsigned int frames); unsigned int WriteResample(float* buffer, unsigned int frames); - void Reset(); + void Reset(unsigned int new_size); }; } diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 6d9b1c1b..dd19f904 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -738,9 +738,9 @@ struct JackNetAdapter : public JackAudioAdapterInterface { fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; for (int i = 0; i < fCaptureChannels; i++ ) - fCaptureRingBuffer[i] = new JackResampler(fRingbufferSize); + fCaptureRingBuffer[i] = new JackResampler(); for (int i = 0; i < fPlaybackChannels; i++ ) - fPlaybackRingBuffer[i] = new JackResampler(fRingbufferSize); + fPlaybackRingBuffer[i] = new JackResampler(); if (fCaptureChannels > 0) jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace()); diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index f5512eb5..7164e637 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -96,7 +96,8 @@ namespace Jack fQuality = param->value.ui; break; case 'g': - fRingbufferSize = param->value.ui; + fRingbufferCurSize = param->value.ui; + fAdaptative = false; break; } } @@ -242,27 +243,24 @@ namespace Jack bool JackNetAdapter::Execute() { - try - { + try { // Keep running even in case of error - while ( fThread.GetStatus() == JackThread::kRunning ) - if ( Process() == SOCKET_ERROR ) + while (fThread.GetStatus() == JackThread::kRunning) + if (Process() == SOCKET_ERROR) return false; return false; - } - catch ( JackNetException& e ) - { + } catch (JackNetException& e) { e.PrintMessage(); - jack_log ( "NetAdapter is restarted." ); + jack_info("NetAdapter is restarted."); + Reset(); fThread.DropRealTime(); - fThread.SetStatus ( JackThread::kIniting ); - if ( Init() ) - { - fThread.SetStatus ( JackThread::kRunning ); + fThread.SetStatus(JackThread::kIniting); + if (Init()) { + fThread.SetStatus(JackThread::kRunning); return true; - } - else + } else { return false; + } } } @@ -472,9 +470,9 @@ extern "C" strcpy(desc->params[i].name, "ring-buffer"); desc->params[i].character = 'g'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; - strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 16384)"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + 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, "auto-connect" ); diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index d34c7db5..c949001d 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -45,6 +45,9 @@ namespace Jack fSocket.GetName ( fParams.fSlaveNetName ); fParams.fTransportSync = transport_sync; fParams.fNetworkMode = network_mode; + fSendTransportData.fState = -1; + fReturnTransportData.fState = -1; + fLastTransportState = -1; fLastTimebaseMaster = -1; fMidiCapturePortList = NULL; fMidiPlaybackPortList = NULL; @@ -411,7 +414,7 @@ namespace Jack case JackTransportStarting : fEngineControl->fTransport.RequestNewPos ( &fSendTransportData.fPosition ); fEngineControl->fTransport.SetCommand ( TransportCommandStart ); - jack_info ( "Master starts transport." ); + jack_info ( "Master starts transport frame = %d", fSendTransportData.fPosition.frame); break; case JackTransportRolling : diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index 5f723b99..1b8b9c72 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -34,6 +34,9 @@ namespace Jack //settings fClientName = const_cast ( fParams.fName ); fJackClient = NULL; + fSendTransportData.fState = -1; + fReturnTransportData.fState = -1; + fLastTransportState = -1; uint port_index; //jack audio ports @@ -279,7 +282,7 @@ namespace Jack fSendTransportData.fNewState = ( ( fSendTransportData.fState != fLastTransportState ) && ( fSendTransportData.fState != fReturnTransportData.fState ) ); if ( fSendTransportData.fNewState ) - jack_info ( "Sending '%s' to '%s'.", GetTransportState ( fSendTransportData.fState ), fParams.fName ); + jack_info ( "Sending '%s' to '%s' frame = %ld", GetTransportState ( fSendTransportData.fState ), fParams.fName, fSendTransportData.fPosition.frame ); fLastTransportState = fSendTransportData.fState; } @@ -328,10 +331,10 @@ namespace Jack jack_info ( "'%s' stops transport.", fParams.fName ); break; case JackTransportStarting : - if ( jack_transport_reposition ( fJackClient, &fReturnTransportData.fPosition ) < 0 ) + if ( jack_transport_reposition ( fJackClient, &fReturnTransportData.fPosition ) == EINVAL ) jack_error ( "Can't set new position." ); jack_transport_start ( fJackClient ); - jack_info ( "'%s' starts transport.", fParams.fName ); + jack_info ( "'%s' starts transport frame = %d", fParams.fName, fReturnTransportData.fPosition.frame); break; case JackTransportNetStarting : jack_info ( "'%s' is ready to roll..", fParams.fName ); diff --git a/common/JackResampler.cpp b/common/JackResampler.cpp index 86798d9e..fb1793d4 100644 --- a/common/JackResampler.cpp +++ b/common/JackResampler.cpp @@ -30,23 +30,17 @@ JackResampler::JackResampler() jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize) / 2); } -JackResampler::JackResampler(unsigned int ringbuffer_size) - :fRatio(1),fRingBufferSize(ringbuffer_size) -{ - fRingBuffer = jack_ringbuffer_create(sizeof(float) * fRingBufferSize); - jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize) / 2); -} - JackResampler::~JackResampler() { if (fRingBuffer) jack_ringbuffer_free(fRingBuffer); } -void JackResampler::Reset() +void JackResampler::Reset(unsigned int new_size) { - jack_ringbuffer_reset(fRingBuffer); - jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize) / 2); + fRingBufferSize = new_size; + jack_ringbuffer_reset_size(fRingBuffer, sizeof(float) * fRingBufferSize); + jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize / 2)); } unsigned int JackResampler::ReadSpace() diff --git a/common/JackResampler.h b/common/JackResampler.h index d8d2e42c..521f5139 100644 --- a/common/JackResampler.h +++ b/common/JackResampler.h @@ -26,7 +26,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { -#define DEFAULT_RB_SIZE 16384 +#define DEFAULT_RB_SIZE 32768 +#define DEFAULT_ADAPTATIVE_SIZE 2048 inline float Range(float min, float max, float val) { @@ -49,10 +50,9 @@ class JackResampler public: JackResampler(); - JackResampler(unsigned int ringbuffer_size); virtual ~JackResampler(); - virtual void Reset(); + virtual void Reset(unsigned int new_size); virtual unsigned int ReadResample(float* buffer, unsigned int frames); virtual unsigned int WriteResample(float* buffer, unsigned int frames); @@ -63,7 +63,7 @@ class JackResampler virtual unsigned int ReadSpace(); virtual unsigned int WriteSpace(); - unsigned int GetOffset() + unsigned int GetError() { return (jack_ringbuffer_read_space(fRingBuffer) / sizeof(float)) - (fRingBufferSize / 2); } diff --git a/common/JackThreadedDriver.cpp b/common/JackThreadedDriver.cpp index ca8dde69..590d9575 100644 --- a/common/JackThreadedDriver.cpp +++ b/common/JackThreadedDriver.cpp @@ -209,6 +209,7 @@ bool JackThreadedDriver::Init() if (fDriver->IsRealTime()) { jack_log("JackThreadedDriver::Init IsRealTime"); // Will do "something" on OSX only... + GetEngineControl()->fPeriod = GetEngineControl()->fConstraint = GetEngineControl()->fPeriodUsecs * 1000; fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); if (fThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { jack_error("AcquireRealTime error"); diff --git a/common/JackTransportEngine.cpp b/common/JackTransportEngine.cpp index 861b123e..66f96cf2 100644 --- a/common/JackTransportEngine.cpp +++ b/common/JackTransportEngine.cpp @@ -86,12 +86,6 @@ int JackTransportEngine::SetTimebaseMaster(int refnum, bool conditionnal) } } -void JackTransportEngine::GetTimebaseMaster(int& refnum, bool& conditionnal) -{ - refnum = fTimeBaseMaster; - conditionnal = fConditionnal; -} - // RT bool JackTransportEngine::CheckAllRolling(JackClientInterface** table) { diff --git a/common/JackTransportEngine.h b/common/JackTransportEngine.h index 1d201f66..9602516d 100644 --- a/common/JackTransportEngine.h +++ b/common/JackTransportEngine.h @@ -144,7 +144,11 @@ class SERVER_EXPORT JackTransportEngine : public JackAtomicArrayStateIsRealTime()) { jack_log("JackWaitThreadedDriver::Init IsRealTime"); // Will do "something" on OSX only... + GetEngineControl()->fPeriod = GetEngineControl()->fConstraint = GetEngineControl()->fPeriodUsecs * 1000; fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); if (fThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { jack_error("AcquireRealTime error"); @@ -61,7 +62,7 @@ bool JackWaitThreadedDriver::Execute() return false; } catch (JackNetException& e) { e.PrintMessage(); - jack_log("Driver is restarted"); + jack_info("Driver is restarted"); fThread.DropRealTime(); // Thread in kIniting status again... fThread.SetStatus(JackThread::kIniting); diff --git a/common/jack/ringbuffer.h b/common/jack/ringbuffer.h index a4bd824f..cb0ca942 100644 --- a/common/jack/ringbuffer.h +++ b/common/jack/ringbuffer.h @@ -192,6 +192,16 @@ int jack_ringbuffer_mlock(jack_ringbuffer_t *rb); */ void jack_ringbuffer_reset(jack_ringbuffer_t *rb); +/** + * Reset the internal "available" size, and read and write pointers, making an empty buffer. + * + * This is not thread safe. + * + * @param rb a pointer to the ringbuffer structure. + * @param sz the new size, that must be less than allocated size. + */ +void jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz); + /** * Write data into the ringbuffer. * diff --git a/common/jack/thread.h b/common/jack/thread.h index 9ff84b98..c09c6ca2 100644 --- a/common/jack/thread.h +++ b/common/jack/thread.h @@ -33,15 +33,15 @@ extern "C" * clients. These interfaces hide some system variations in the * handling of realtime scheduling and associated privileges. */ - + /** * @defgroup ClientThreads Creating and managing client threads * @{ */ - + /** * @returns if JACK is running with realtime scheduling, this returns - * the priority that any JACK-created client threads will run at. + * the priority that any JACK-created client threads will run at. * Otherwise returns -1. */ @@ -114,8 +114,35 @@ int jack_client_stop_thread(jack_client_t* client, pthread_t thread); * @param thread POSIX thread ID. * * @returns 0, if successful; otherwise an error number. - */ + */ int jack_client_kill_thread(jack_client_t* client, pthread_t thread); + +#ifndef WIN32 + + typedef int (*jack_thread_creator_t)(pthread_t*, + const pthread_attr_t*, + void* (*function)(void*), + void* arg); +/** + * This function can be used in very very specialized cases + * where it is necessary that client threads created by JACK + * are created by something other than pthread_create(). After + * it is used, any threads that JACK needs for the client will + * will be created by calling the function passed to this + * function. + * + * No normal application/client should consider calling this. + * The specific case for which it was created involves running + * win32/x86 plugins under Wine on Linux, where it is necessary + * that all threads that might call win32 functions are known + * to Wine. + * + * @param creator a function that creates a new thread + * + */ +void jack_set_thread_creator (jack_thread_creator_t creator); + +#endif /* @} */ diff --git a/common/ringbuffer.c b/common/ringbuffer.c index 72559594..a7209a2b 100644 --- a/common/ringbuffer.c +++ b/common/ringbuffer.c @@ -55,6 +55,7 @@ EXPORT void jack_ringbuffer_read_advance(jack_ringbuffer_t *rb, size_t cnt); EXPORT size_t jack_ringbuffer_read_space(const jack_ringbuffer_t *rb); EXPORT int jack_ringbuffer_mlock(jack_ringbuffer_t *rb); EXPORT void jack_ringbuffer_reset(jack_ringbuffer_t *rb); +EXPORT void jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz); EXPORT size_t jack_ringbuffer_write(jack_ringbuffer_t *rb, const char *src, size_t cnt); void jack_ringbuffer_write_advance(jack_ringbuffer_t *rb, size_t cnt); @@ -123,6 +124,19 @@ jack_ringbuffer_reset (jack_ringbuffer_t * rb) rb->write_ptr = 0; } +/* Reset the read and write pointers to zero. This is not thread + safe. */ + +EXPORT void +jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz) +{ + rb->size = sz; + rb->size_mask = rb->size; + rb->size_mask -= 1; + rb->read_ptr = 0; + rb->write_ptr = 0; +} + /* Return the number of bytes available for reading. This is the number of bytes in front of the read pointer and behind the write pointer. */ diff --git a/common/wscript b/common/wscript index adddc27a..2bd56828 100644 --- a/common/wscript +++ b/common/wscript @@ -190,6 +190,7 @@ def build(bld): 'JackAudioAdapterInterface.cpp', 'JackLibSampleRateResampler.cpp', 'JackResampler.cpp', + 'JackGlobals.cpp', 'ringbuffer.c'] if bld.env['IS_LINUX']: diff --git a/linux/alsa/JackAlsaAdapter.cpp b/linux/alsa/JackAlsaAdapter.cpp index 0e9fb4ce..a046e1f2 100644 --- a/linux/alsa/JackAlsaAdapter.cpp +++ b/linux/alsa/JackAlsaAdapter.cpp @@ -77,7 +77,8 @@ namespace Jack fQuality = param->value.ui; break; case 'g': - fRingbufferSize = param->value.ui; + fRingbufferCurSize = param->value.ui; + fAdaptative = false; break; } } @@ -104,7 +105,6 @@ namespace Jack //turn the thread realtime fThread.AcquireRealTime ( JackServerGlobals::fInstance->GetEngineControl()->fClientPriority ); - return 0; } @@ -251,7 +251,7 @@ extern "C" strcpy ( desc->params[i].name, "duplex" ); desc->params[i].character = 'D'; desc->params[i].type = JackDriverParamBool; - desc->params[i].value.i = 1; + desc->params[i].value.i = true; strcpy ( desc->params[i].short_desc, "Provide both capture and playback ports" ); strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); @@ -286,9 +286,9 @@ extern "C" strcpy(desc->params[i].name, "ring-buffer"); desc->params[i].character = 'g'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; - strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 16384)"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + 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)"); return desc; } diff --git a/linux/wscript b/linux/wscript index 5751bf60..46af1bc9 100644 --- a/linux/wscript +++ b/linux/wscript @@ -22,6 +22,7 @@ def create_jack_driver_obj(bld, target, sources, uselib = None): driver.install_path = '${ADDON_DIR}/' if uselib: driver.uselib = uselib + driver.uselib_local = 'serverlib' return driver def build(bld): diff --git a/macosx/coreaudio/JackCoreAudioAdapter.cpp b/macosx/coreaudio/JackCoreAudioAdapter.cpp index dd238b7b..a0222cab 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.cpp +++ b/macosx/coreaudio/JackCoreAudioAdapter.cpp @@ -378,7 +378,8 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra break; case 'g': - fRingbufferSize = param->value.ui; + fRingbufferCurSize = param->value.ui; + fAdaptative = false; break; } } @@ -1080,9 +1081,9 @@ extern "C" strcpy(desc->params[i].name, "ring-buffer"); desc->params[i].character = 'g'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; - strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 16384)"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + 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)"); return desc; } diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj index d137323b..8ce87173 100755 --- a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -52,6 +52,10 @@ 4B1A945A0F49C03600D3626B /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; 4B1A947F0F49C42300D3626B /* JackAudioQueueAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */; }; 4B1A95760F49CEAB00D3626B /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; + 4B2791880F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; + 4B2791890F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; + 4B27918A0F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; + 4B27918B0F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; 4BBDC8FA0F5420C000465F9C /* freeverb.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BBDC8F90F5420C000465F9C /* freeverb.mm */; }; 4BF1360F0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; 4BF136100F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; @@ -104,6 +108,7 @@ 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioQueueAdapter.cpp; path = ../coreaudio/JackAudioQueueAdapter.cpp; sourceTree = SOURCE_ROOT; }; 4B1A947E0F49C42300D3626B /* JackAudioQueueAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioQueueAdapter.h; path = ../coreaudio/JackAudioQueueAdapter.h; sourceTree = SOURCE_ROOT; }; 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.1.sdk/System/Library/Frameworks/AudioToolbox.framework; sourceTree = ""; }; + 4B2791870F72570C000536B7 /* JackGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackGlobals.cpp; path = ../../common/JackGlobals.cpp; sourceTree = SOURCE_ROOT; }; 4BBDC8F90F5420C000465F9C /* freeverb.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = freeverb.mm; sourceTree = SOURCE_ROOT; }; 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; }; 4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioAdapterInterface.h; path = ../../common/JackAudioAdapterInterface.h; sourceTree = SOURCE_ROOT; }; @@ -204,6 +209,7 @@ 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */, 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */, 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */, + 4B2791870F72570C000536B7 /* JackGlobals.cpp */, 32CA4F630368D1EE00C91783 /* iPhoneNet_Prefix.pch */, 4B0772490F54021B000DC657 /* main_slave.mm */, 4B0772500F54022D000DC657 /* main_master.mm */, @@ -383,6 +389,7 @@ 4BF136550F4B0F9F00218A3F /* ringbuffer.c in Sources */, 4B07724A0F54021B000DC657 /* main_slave.mm in Sources */, 4B0773870F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, + 4B27918A0F72570C000536B7 /* JackGlobals.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -403,6 +410,7 @@ 4B07722E0F54018C000DC657 /* ringbuffer.c in Sources */, 4B0772510F54022D000DC657 /* main_master.mm in Sources */, 4B0773860F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, + 4B27918B0F72570C000536B7 /* JackGlobals.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -420,6 +428,7 @@ 4BF136100F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */, 4BF1364E0F4B0F7700218A3F /* JackResampler.cpp in Sources */, 4BF136560F4B0F9F00218A3F /* ringbuffer.c in Sources */, + 4B2791890F72570C000536B7 /* JackGlobals.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -440,6 +449,7 @@ 4BFF456D0F4D5D9700106083 /* ringbuffer.c in Sources */, 4B0773880F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, 4BBDC8FA0F5420C000465F9C /* freeverb.mm in Sources */, + 4B2791880F72570C000536B7 /* JackGlobals.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/posix/JackFifo.cpp b/posix/JackFifo.cpp index 94d76fcf..8f927dea 100644 --- a/posix/JackFifo.cpp +++ b/posix/JackFifo.cpp @@ -30,9 +30,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -void JackFifo::BuildName(const char* name, const char* server_name, char* res) +void JackFifo::BuildName(const char* client_name, const char* server_name, char* res) { - sprintf(res, "%s/jack_fifo.%d_%s_%s", jack_client_dir, JackTools::GetUID(), server_name, name); + char ext_client_name[JACK_CLIENT_NAME_SIZE + 1]; + JackTools::RewriteName(client_name, ext_client_name); + sprintf(res, "%s/jack_fifo.%d_%s_%s", jack_client_dir, JackTools::GetUID(), server_name, ext_client_name); } bool JackFifo::Signal() diff --git a/posix/JackPosixThread.cpp b/posix/JackPosixThread.cpp index a1ac219e..aa1d0fbd 100644 --- a/posix/JackPosixThread.cpp +++ b/posix/JackPosixThread.cpp @@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackPosixThread.h" #include "JackError.h" #include "JackTime.h" +#include "JackGlobals.h" #include // for memset #include // for _POSIX_PRIORITY_SCHEDULING check @@ -139,7 +140,7 @@ int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, voi return -1; } - if ((res = pthread_create(thread, &attributes, start_routine, arg))) { + if ((res = JackGlobals::fJackThreadCreator(thread, &attributes, start_routine, arg))) { jack_error("Cannot create thread res = %d err = %s", res, strerror(errno)); return -1; } diff --git a/posix/JackSocket.cpp b/posix/JackSocket.cpp index 989d6b55..ec891acb 100644 --- a/posix/JackSocket.cpp +++ b/posix/JackSocket.cpp @@ -29,6 +29,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { +static void BuildName(const char* client_name, char* res, const char* dir, int which) +{ + char ext_client_name[JACK_CLIENT_NAME_SIZE + 1]; + JackTools::RewriteName(client_name, ext_client_name); + sprintf(res, "%s/jack_%s_%d_%d", dir, ext_client_name, JackTools::GetUID(), which); +} + JackClientSocket::JackClientSocket(int socket): fSocket(socket),fTimeOut(0) {} @@ -112,36 +119,7 @@ int JackClientSocket::Connect(const char* dir, const char* name, int which) // A } addr.sun_family = AF_UNIX; - snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s/jack_%s_%d_%d", dir, name, JackTools::GetUID(), which); - jack_log("Connect: addr.sun_path %s", addr.sun_path); - - if (connect(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) { - jack_error("Cannot connect to server socket err = %s", strerror(errno)); - close(fSocket); - return -1; - } - -#ifdef __APPLE__ - int on = 1 ; - if (setsockopt(fSocket, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) { - jack_log("setsockopt SO_NOSIGPIPE fd = %ld err = %s", fSocket, strerror(errno)); - } -#endif - - return 0; -} - -int JackClientSocket::Connect(const char* dir, int which) -{ - struct sockaddr_un addr; - - if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { - jack_error("Cannot create socket err = %s", strerror(errno)); - return -1; - } - - addr.sun_family = AF_UNIX; - snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s/jack_%d_%d", dir, JackTools::GetUID(), which); + BuildName(name, addr.sun_path, dir, which); jack_log("Connect: addr.sun_path %s", addr.sun_path); if (connect(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) { @@ -271,67 +249,9 @@ int JackServerSocket::Bind(const char* dir, const char* name, int which) // A re } addr.sun_family = AF_UNIX; - - // TO CORRECT: always reuse the same name for now... - snprintf(fName, sizeof(addr.sun_path) - 1, "%s/jack_%s_%d_%d", dir, name, JackTools::GetUID(), which); + BuildName(name, fName, dir, which); strncpy(addr.sun_path, fName, sizeof(addr.sun_path) - 1); - /* - if (access(addr.sun_path, F_OK) == 0) { - goto error; - } - */ - - jack_log("Bind: addr.sun_path %s", addr.sun_path); - unlink(fName); // Security... - - if (bind(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) { - jack_error("Cannot bind server to socket err = %s", strerror(errno)); - goto error; - } - - if (listen(fSocket, 1) < 0) { - jack_error("Cannot enable listen on server socket err = %s", strerror(errno)); - goto error; - } - - return 0; - -error: - unlink(fName); - close(fSocket); - return -1; -} - -int JackServerSocket::Bind(const char* dir, int which) // A revoir : utilisation de "which" -{ - struct sockaddr_un addr; - - if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { - jack_error("Cannot create server socket err = %s", strerror(errno)); - return -1; - } - - addr.sun_family = AF_UNIX; - - /* - for (int i = 0; i < 999; i++) { - snprintf(addr.sun_path, sizeof(addr.sun_path) - 1,"%s/jack_%d", dir, i); - snprintf(fName, sizeof(addr.sun_path) - 1,"%s/jack_%d", dir, i); - if (access(addr.sun_path, F_OK) != 0) { - break; - } - } - */ - - // TO CORRECT: always reuse the same name for now... - snprintf(fName, sizeof(addr.sun_path) - 1, "%s/jack_%d_%d", dir, JackTools::GetUID(), which); - strncpy(addr.sun_path, fName, sizeof(addr.sun_path) - 1); - /* - if (access(addr.sun_path, F_OK) == 0) { - goto error; - } - */ - + jack_log("Bind: addr.sun_path %s", addr.sun_path); unlink(fName); // Security... diff --git a/posix/JackSocket.h b/posix/JackSocket.h index 2ccaf06d..0382bd84 100644 --- a/posix/JackSocket.h +++ b/posix/JackSocket.h @@ -50,7 +50,6 @@ class JackClientSocket {} JackClientSocket(int socket); - int Connect(const char* dir, int which); int Connect(const char* dir, const char* name, int which); int Close(); int Read(void* data, int len); @@ -69,13 +68,16 @@ class JackClientSocket \brief Server socket. */ +#define SOCKET_MAX_NAME_SIZE 256 + + class JackServerSocket { private: int fSocket; - char fName[256]; + char fName[SOCKET_MAX_NAME_SIZE]; public: @@ -84,7 +86,6 @@ class JackServerSocket ~JackServerSocket() {} - int Bind(const char* dir, int which); int Bind(const char* dir, const char* name, int which); JackClientSocket* Accept(); int Close(); diff --git a/posix/JackTypes_os.h b/posix/JackTypes_os.h index 84307c15..01e6c9b9 100644 --- a/posix/JackTypes_os.h +++ b/posix/JackTypes_os.h @@ -26,4 +26,6 @@ typedef unsigned long long UInt64; typedef pthread_key_t jack_tls_key; +typedef int (*jack_thread_creator_t)(pthread_t*, const pthread_attr_t*, void* (*function)(void*), void* arg); + #endif diff --git a/solaris/oss/JackOSSAdapter.cpp b/solaris/oss/JackOSSAdapter.cpp index cbb3e549..7bdfec96 100644 --- a/solaris/oss/JackOSSAdapter.cpp +++ b/solaris/oss/JackOSSAdapter.cpp @@ -183,7 +183,8 @@ JackOSSAdapter::JackOSSAdapter(jack_nframes_t buffer_size, jack_nframes_t sample break; case 'g': - fRingbufferSize = param->value.ui; + fRingbufferCurSize = param->value.ui; + fAdaptative = false; break; } @@ -494,9 +495,16 @@ int JackOSSAdapter::Open() } DisplayDeviceInfo(); - + + //start adapter thread + if (fThread.StartSync() < 0) { + jack_error ( "Cannot start audioadapter thread" ); + return -1; + } + + //turn the thread realtime fThread.AcquireRealTime(JackServerGlobals::fInstance->GetEngineControl()->fClientPriority); - return fThread.StartSync(); + return 0; error: CloseAux(); @@ -742,10 +750,10 @@ extern "C" strcpy(desc->params[i].name, "ring-buffer"); desc->params[i].character = 'g'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; - strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 16384)"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); - + 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)"); + return desc; } diff --git a/windows/portaudio/JackPortAudioAdapter.cpp b/windows/portaudio/JackPortAudioAdapter.cpp index 17972e6b..0f5e161b 100644 --- a/windows/portaudio/JackPortAudioAdapter.cpp +++ b/windows/portaudio/JackPortAudioAdapter.cpp @@ -97,7 +97,8 @@ namespace Jack fQuality = param->value.ui; break; case 'g': - fRingbufferSize = param->value.ui; + fRingbufferCurSize = param->value.ui; + fAdaptative = false; break; } } @@ -282,7 +283,7 @@ extern "C" strcpy(desc->params[i].name, "list-devices"); desc->params[i].character = 'l'; desc->params[i].type = JackDriverParamBool; - desc->params[i].value.i = TRUE; + desc->params[i].value.i = true; strcpy(desc->params[i].short_desc, "Display available PortAudio devices"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); @@ -298,9 +299,9 @@ extern "C" strcpy(desc->params[i].name, "ring-buffer"); desc->params[i].character = 'g'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; - strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 16384)"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + 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)"); return desc; } From 31bb3bc2a90f5fa906ca5edd1c312e83c0840287 Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 23 Mar 2009 14:17:00 +0000 Subject: [PATCH 014/472] rebase from trunk 3447:3455 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3456 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 4 ++++ README | 1 + common/JackConstants.h | 2 +- common/Jackdmp.cpp | 2 +- common/wscript | 2 +- doxyfile | 2 +- macosx/Jack-Info.plist | 2 +- windows/Setup/JackRouter.dll | Bin 32768 -> 32768 bytes windows/jackaudioadapter.rc | 8 ++++---- windows/jackd.rc | 8 ++++---- windows/jacknetadapter.rc | 8 ++++---- windows/jacknetdriver.rc | 8 ++++---- windows/jacknetmanager.rc | 8 ++++---- windows/jackportaudio.rc | 8 ++++---- windows/libjack.rc | 8 ++++---- windows/libjackserver.rc | 8 ++++---- windows/portaudio/JackPortAudioDevices.cpp | 6 ++++-- windows/resource.rc | 10 +++++----- wscript | 2 +- 19 files changed, 52 insertions(+), 45 deletions(-) diff --git a/ChangeLog b/ChangeLog index e29fb0e2..94b97df0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24,6 +24,10 @@ Torben Hohn Jackdmp changes log --------------------------- +2009-03-23 Stephane Letz + + * Version 1.9.3 started. + 2009-03-19 Stephane Letz * Tim Blechmann optimization patch (inlining some heavy used methods). diff --git a/README b/README index d9a8dfa2..33e7285d 100644 --- a/README +++ b/README @@ -196,6 +196,7 @@ Note : To experiment with the -S option, jackdmp must be launched in a console. 0.71 : Add port register/unregister notification in JackAlsaDriver. Correct JACK_port_unregister in MIDI backend. Add TimeCallback in JackDebugClient class. Correct jack_get_time propotype. Correct JackSocketClientChannel::ClientClose to use ServerSyncCall instead of ServerAsyncCall. Better documentation in jack.h. libjackdmp.so renamed to libjackservermp.so and same for OSX framework. Define an internal jack_client_open_aux needed for library wrapper feature. Remove unneeded jack_port_connect API. Correct jack_port_get_connections function (should return NULL when no connections). In thread model, execute a dummy cycle to be sure thread has the correct properties (ensure thread creation is finished). Fix engine real-time notification (was broken since ??). Implements wrapper layer. Correct jack_port_get_total_latency. Correct all backend playback port latency in case of "asynchronous" mode (1 buffer more). Add test for jack_cycle_wait, jack_cycle_wait and jack_set_process_thread API. RT scheduling for OSX thread (when used in dummy driver). Add -L (extra output latency in aynchronous mode) in CoreAudio driver. New JackLockedEngine decorator class to serialize access from ALSA Midi thread, command thread and in-server clients. Use engine in JackAlsaDriver::port_register and JackAlsaDriver::port_unregister. Fix connect notification to deliver *one* notification only. Correct JackClient::Activate so that first kGraphOrderCallback can be received by the client notification thread. New jack_server_control client to test notifications when linked to the server library. Synchronise transport.h with latest jackd version (Video handling). Transport timebase fix. Dmitry Baikov patch for alsa_rawmidi driver. Pieter Palmers patch for FFADO driver. Add an Init method for blocking drivers to be decorated using JackThreadedDriver class. Correct PortRegister, port name checking must be done on server side. Correct a missing parameter in the usage message of jack_midiseq. New SetNonBlocking method for JackSocket. Correct a dirty port array issue in JackGraphManager::GetPortsAux. 1.9.0 : Waf based build system : Nedko Arnaudov, Grame for preliminary OSX support. Control API, dbus based server control access : Nedko Arnaudov, Grame. NetJack2 components (in progress) : jack_net backend, netmanager, audioadapter, netadapter : Romain Moret, Grame. Code restructuring to help port on other architectures : Michael Voigt. Code cleanup/optimization : Tim Blechmann. Improve handling of server internal clients that can now be loaded/unloaded using the new server control API : Grame. A lot of bug fix and improvements. 1.9.1 : Fix jackctl_server_unload_internal. Filter SIGPIPE to avoid having client get a SIGPIPE when trying to access a died server. Libjack shutdown handler does not "deactivate" (fActive = false) the client anymore, so that jack_deactivate correctly does the job later on. Better isolation of server and clients system resources to allow starting the server in several user account at the same time. Report ringbuffer.c fixes from jack1. Client and library global context cleanup in case of incorrect shutdown handling (that is applications not correctly closing client after server has shutdown). Use JACK_DRIVER_DIR variable in internal clients loader. For ALSA driver, synchronize with latest jack1 memops functions. Synchronize jack2 public headers with jack1 ones. Implement jack_client_real_time_priority and jack_client_max_real_time_priority API. Use up to BUFFER_SIZE_MAX frames in midi ports, fix for ticket #117. Cleanup server starting code for clients directly linked with libjackserver.so. JackMessageBuffer was using thread "Stop" scheme in destructor, now use the safer thread "Kill" way. Synchronize ALSA backend code with JACK1 one. Set default mode to 'slow' in JackNetDriver and JackNetAdapter. Simplify audio packet order verification. Fix JackNetInterface::SetNetBufferSize for socket buffer size computation and JackNetMasterInterface::DataRecv if synch packet is received, various cleanup. Better recovery of network overload situations, now "resynchronize" by skipping cycles.". Support for BIG_ENDIAN machines in NetJack2. Support for BIG_ENDIAN machines in NetJack2 for MIDI ports. Support for "-h" option in internal clients to print the parameters. In NetJack2, fix a bug when capture or playback only channels are used. Add a JACK_INTERNAL_DIR environment variable to be used for internal clients. Add a resample quality parameter in audioadapter. Now correctly return an error if JackServer::SetBufferSize could not change the buffer size (and was just restoring the current one). Use PRIu32 kind of macro in JackAlsaDriver again. Add a resample quality parameter in netadapter. +1.9.2 : Solaris version. New "profiling" tools. Rework the mutex/signal classes. Support for BIG_ENDIAN machines in NetJack2. D-BUS based device reservation to better coexist with PulseAudio on Linux. Add auto_connect parameter in netmanager and netadapter. Use Torben Hohn PI controler code for adapters. Client incorrect re-naming fixed : now done at socket and fifo level. Virtualize and allow overriding of thread creation function, to allow Wine support (from JACK1). This is a work in progress but the implementation is now stable enough to be tested. jackdmp has been used successfully with the following applications : Ardour, Hydrogen, Jamin, Qjackctl, Jack-Rack, SooperLooper, AlsaPlayer... diff --git a/common/JackConstants.h b/common/JackConstants.h index d2af693e..71288d11 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -24,7 +24,7 @@ #include "config.h" #endif -#define VERSION "1.9.2" +#define VERSION "1.9.3" #define BUFFER_SIZE_MAX 8192 diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index eaeca361..227cf402 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -83,7 +83,7 @@ static void copyright(FILE* file) { fprintf(file, "jackdmp " VERSION "\n" "Copyright 2001-2005 Paul Davis and others.\n" - "Copyright 2004-2008 Grame.\n" + "Copyright 2004-2009 Grame.\n" "jackdmp comes with ABSOLUTELY NO WARRANTY\n" "This is free software, and you are welcome to redistribute it\n" "under certain conditions; see the file COPYING for details\n"); diff --git a/common/wscript b/common/wscript index 2bd56828..9847c0de 100644 --- a/common/wscript +++ b/common/wscript @@ -289,7 +289,7 @@ def build(bld): process.env.append_value("LINKFLAGS", "-framework CoreAudio -framework AudioUnit -framework AudioToolbox -framework CoreServices") process.uselib = 'SAMPLERATE' - if bld.env['BUILD_ADAPTER'] and bld.env['IS_LINUX']: + if bld.env['BUILD_ADAPTER'] and bld.env['IS_LINUX'] and bld.env['BUILD_DRIVER_ALSA']: audio_adapter_sources += ['../linux/alsa/JackAlsaAdapter.cpp'] process = create_jack_process_obj(bld, 'audioadapter', audio_adapter_sources, serverlib) process.uselib = ['ALSA', 'SAMPLERATE'] diff --git a/doxyfile b/doxyfile index c86bb5dd..84f79166 100644 --- a/doxyfile +++ b/doxyfile @@ -23,7 +23,7 @@ PROJECT_NAME = "Jack2" # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 1.9.1 +PROJECT_NUMBER = 1.9.3 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/macosx/Jack-Info.plist b/macosx/Jack-Info.plist index ac3ef818..ea2a9e42 100644 --- a/macosx/Jack-Info.plist +++ b/macosx/Jack-Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable Jackservermp CFBundleGetInfoString - Jackdmp 1.9.2, @03-09 Paul Davis, Grame + Jackdmp 1.9.3, @03-09 Paul Davis, Grame CFBundleIdentifier com.grame.Jackmp CFBundleInfoDictionaryVersion diff --git a/windows/Setup/JackRouter.dll b/windows/Setup/JackRouter.dll index 9e4444e65ce3b19dacd682f8c3411fa042ffe453..4f2ada62f24aca423bfe88ee7ce08e1fb6a73265 100644 GIT binary patch delta 143 zcmZo@U}|V!n(%?y!{gA#&p+)=KQJ&fYz1OwMuvuSKzbh#e*N&zInM%q%i=gYA{~_ delta 143 zcmZo@U}|V!n(%=+f8nf+pMTn$eqmr}*a^h!j0_Ezfb=0C{sqL6K>k-Cy$^^t1Mwdq ez6ivpfq2tqMaN(kGPSOB{mlllee-gkNMiu`05N|6 diff --git a/windows/jackaudioadapter.rc b/windows/jackaudioadapter.rc index b176621e..31718f12 100644 --- a/windows/jackaudioadapter.rc +++ b/windows/jackaudioadapter.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,2,0 - PRODUCTVERSION 1,9,2,0 + FILEVERSION 1,9,3,0 + PRODUCTVERSION 1,9,3,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Audio Adapter for Windows\0" - VALUE "FileVersion", "1, 9, 2, 0\0" + VALUE "FileVersion", "1, 9, 3, 0\0" VALUE "InternalName", "audioadapter\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "audioadapter.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "audioadapter\0" - VALUE "ProductVersion", "1, 9, 2, 0\0" + VALUE "ProductVersion", "1, 9, 3, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackd.rc b/windows/jackd.rc index adeb4401..0208994a 100644 --- a/windows/jackd.rc +++ b/windows/jackd.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,2,0 - PRODUCTVERSION 1,9,2,0 + FILEVERSION 1,9,3,0 + PRODUCTVERSION 1,9,3,0 FILEOS VOS_UNKNOWN FILETYPE VFT_APP BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack server for Windows\0" - VALUE "FileVersion", "1, 9, 2, 0\0" + VALUE "FileVersion", "1, 9, 3, 0\0" VALUE "InternalName", "jackd\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jackd.exe\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jackd\0" - VALUE "ProductVersion", "1, 9, 2, 0\0" + VALUE "ProductVersion", "1, 9, 3, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetadapter.rc b/windows/jacknetadapter.rc index 89d5d905..cdfb78e9 100644 --- a/windows/jacknetadapter.rc +++ b/windows/jacknetadapter.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,2,0 - PRODUCTVERSION 1,9,2,0 + FILEVERSION 1,9,3,0 + PRODUCTVERSION 1,9,3,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Adapter for Windows\0" - VALUE "FileVersion", "1, 9, 2, 0\0" + VALUE "FileVersion", "1, 9, 3, 0\0" VALUE "InternalName", "netadapter\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "netadapter.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "netadapter\0" - VALUE "ProductVersion", "1, 9, 2, 0\0" + VALUE "ProductVersion", "1, 9, 3, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetdriver.rc b/windows/jacknetdriver.rc index b0531e03..40e7ab94 100644 --- a/windows/jacknetdriver.rc +++ b/windows/jacknetdriver.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,2,0 - PRODUCTVERSION 1,9,2,0 + FILEVERSION 1,9,3,0 + PRODUCTVERSION 1,9,3,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Driver for Windows\0" - VALUE "FileVersion", "1, 9, 2, 0\0" + VALUE "FileVersion", "1, 9, 3, 0\0" VALUE "InternalName", "jack_netdriver\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_netdriver.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_netdriver\0" - VALUE "ProductVersion", "1, 9, 2, 0\0" + VALUE "ProductVersion", "1, 9, 3, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetmanager.rc b/windows/jacknetmanager.rc index e668ab3d..b9c35e01 100644 --- a/windows/jacknetmanager.rc +++ b/windows/jacknetmanager.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,2,0 - PRODUCTVERSION 1,9,2,0 + FILEVERSION 1,9,3,0 + PRODUCTVERSION 1,9,3,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Manager for Windows\0" - VALUE "FileVersion", "1, 9, 2, 0\0" + VALUE "FileVersion", "1, 9, 3, 0\0" VALUE "InternalName", "netmanager\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "netmanager.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "netmanager\0" - VALUE "ProductVersion", "1, 9, 2, 0\0" + VALUE "ProductVersion", "1, 9, 3, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackportaudio.rc b/windows/jackportaudio.rc index 0f08d1e9..03ad53fd 100644 --- a/windows/jackportaudio.rc +++ b/windows/jackportaudio.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,2,0 - PRODUCTVERSION 1,9,2,0 + FILEVERSION 1,9,3,0 + PRODUCTVERSION 1,9,3,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp PortAudio Driver for Windows\0" - VALUE "FileVersion", "1, 9, 2, 0\0" + VALUE "FileVersion", "1, 9, 3, 0\0" VALUE "InternalName", "jack_portaudio\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_portaudio.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_portaudio\0" - VALUE "ProductVersion", "1, 9, 2, 0\0" + VALUE "ProductVersion", "1, 9, 3, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/libjack.rc b/windows/libjack.rc index bbface17..200ad086 100644 --- a/windows/libjack.rc +++ b/windows/libjack.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,2,0 - PRODUCTVERSION 1,9,2,0 + FILEVERSION 1,9,3,0 + PRODUCTVERSION 1,9,3,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack client library for Windows\0" - VALUE "FileVersion", "1, 9, 2, 0\0" + VALUE "FileVersion", "1, 9, 3, 0\0" VALUE "InternalName", "libjack\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjack.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjack\0" - VALUE "ProductVersion", "1, 9, 2, 0\0" + VALUE "ProductVersion", "1, 9, 3, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/libjackserver.rc b/windows/libjackserver.rc index ccefd710..3b38efcc 100644 --- a/windows/libjackserver.rc +++ b/windows/libjackserver.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,2,0 - PRODUCTVERSION 1,9,2,0 + FILEVERSION 1,9,3,0 + PRODUCTVERSION 1,9,3,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack server library for Windows\0" - VALUE "FileVersion", "1, 9, 2, 0\0" + VALUE "FileVersion", "1, 9, 3, 0\0" VALUE "InternalName", "libjackserver\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjackserver.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjackserver\0" - VALUE "ProductVersion", "1, 9, 2, 0\0" + VALUE "ProductVersion", "1, 9, 3, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/portaudio/JackPortAudioDevices.cpp b/windows/portaudio/JackPortAudioDevices.cpp index 37640ad0..2adb35e0 100644 --- a/windows/portaudio/JackPortAudioDevices.cpp +++ b/windows/portaudio/JackPortAudioDevices.cpp @@ -43,8 +43,10 @@ PortAudioDevices::PortAudioDevices() } PortAudioDevices::~PortAudioDevices() -{ - Pa_Terminate(); +{ + // Desactivate for now: crash the server.. + //Pa_Terminate(); + delete[] fDeviceInfo; delete[] fHostName; } diff --git a/windows/resource.rc b/windows/resource.rc index 2b41be69..0ea97e52 100644 --- a/windows/resource.rc +++ b/windows/resource.rc @@ -14,8 +14,8 @@ LANGUAGE LANG_FRENCH, SUBLANG_FRENCH #ifndef _MAC VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,9,2,0 - PRODUCTVERSION 1,9,2,0 + FILEVERSION 1,9,3,0 + PRODUCTVERSION 1,9,3,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -33,14 +33,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp for Windows\0" - VALUE "FileVersion", "1, 9, 2, 0\0" + VALUE "FileVersion", "1, 9, 3, 0\0" VALUE "InternalName", "libjackmp\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2008\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjackmp.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjackmp\0" - VALUE "ProductVersion", "1, 9, 2, 0\0" + VALUE "ProductVersion", "1, 9, 3, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/wscript b/wscript index c4d28c9e..4fef3251 100644 --- a/wscript +++ b/wscript @@ -11,7 +11,7 @@ import Task import re import Logs -VERSION='1.9.2' +VERSION='1.9.3' APPNAME='jack' JACK_API_VERSION = '0.1.0' From 416928c200245fe6174e9a83ddef304e061327f3 Mon Sep 17 00:00:00 2001 From: sletz Date: Fri, 3 Apr 2009 08:10:40 +0000 Subject: [PATCH 015/472] rebase from trunk 3455:3482 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3483 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 24 +- README | 38 +- common/JackAPI.cpp | 3 +- common/JackClient.cpp | 78 ++- common/JackClient.h | 18 +- common/JackClientControl.h | 2 +- common/JackConnectionManager.h | 5 +- common/JackConstants.h | 6 +- common/JackDebugClient.cpp | 6 - common/JackDebugClient.h | 3 - common/JackDriverLoader.cpp | 7 +- common/JackEngine.cpp | 42 +- common/JackEngineControl.h | 2 +- common/JackEngineProfiling.h | 11 +- common/JackFrameTimer.h | 3 +- common/JackGlobals.h | 7 +- common/JackGraphManager.h | 3 +- common/JackInternalClient.cpp | 58 +- common/JackInternalClient.h | 21 +- common/JackLibClient.cpp | 2 +- common/JackNetAdapter.cpp | 6 +- common/JackNetInterface.cpp | 9 +- common/JackNetManager.cpp | 15 +- common/JackNetManager.h | 4 +- common/JackPort.cpp | 20 +- common/JackPort.h | 12 +- common/JackRequest.h | 85 ++- common/JackShmMem.cpp | 8 +- common/JackShmMem.h | 26 +- common/JackThreadedDriver.cpp | 1 - common/JackTools.cpp | 57 ++ common/JackTools.h | 4 + common/JackTransportEngine.cpp | 10 +- common/JackTransportEngine.h | 2 +- common/shm.c | 145 +++-- common/shm.h | 27 +- example-clients/impulse_grabber.c | 2 +- example-clients/wscript | 2 + posix/JackCompilerDeps_os.h | 27 +- posix/JackSocket.h | 2 +- posix/JackSystemDeps_os.h | 7 +- solaris/oss/JackBoomerDriver.cpp | 1001 +++++++++++++++++++++++++++++ solaris/oss/JackBoomerDriver.h | 135 ++++ solaris/oss/JackOSSDriver.cpp | 2 +- solaris/wscript | 2 + tests/test.cpp | 96 +-- windows/JackCompilerDeps_os.h | 21 +- windows/JackSystemDeps_os.h | 8 +- windows/Setup/jack.ci | 4 +- windows/Setup/src/README | 2 +- wscript | 5 + 51 files changed, 1667 insertions(+), 419 deletions(-) create mode 100644 solaris/oss/JackBoomerDriver.cpp create mode 100644 solaris/oss/JackBoomerDriver.h diff --git a/ChangeLog b/ChangeLog index 94b97df0..2d11462c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,12 +18,34 @@ Fernando Lopez-Lezcano Romain Moret Florian Faber Michael Voigt -Torben Hohn +Torben Hohn +Paul Davis --------------------------- Jackdmp changes log --------------------------- +2009-04-03 Stephane Letz + + * Simplify JackClient RT code, jack_thread_wait API marked deprecated." + +2009-03-29 Stephane Letz + + * Cleanup JackInternalClient code. + +2009-03-27 Stephane Letz + + * Add a buffer size callback for netmaster that just remove the client (it will be recreated with the new parameters). + +2009-03-26 Stephane Letz + + * First working JackBoomerDriver two threads version. + +2009-03-24 Stephane Letz + + * New JackBoomerDriver class for Boomer driver on Solaris. + * Add mixed 32/64 bits mode (off by default). + 2009-03-23 Stephane Letz * Version 1.9.3 started. diff --git a/README b/README index 33e7285d..f11e26f9 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ --------------------------------------- -jackdmp for Linux, MacOSX and Windows --------------------------------------- +----------------------------------------------- +jackdmp for Linux, MacOSX, Windows and Solaris +----------------------------------------------- jackdmp is a C++ version of the JACK low-latency audio server for multi-processor machines. It is a new implementation of the JACK server core features that aims in removing some limitations of the current design. The activation system has been changed for a data flow model and lock-free programming techniques for graph access have been used to have a more dynamic and robust system. @@ -36,12 +36,40 @@ Important compilation options : - the --dbus flag must be defined at configure time to compile the jackdbus executable. If the "automatic start server option" is used by clients, jackd server will be started using the dbus service. - ---------------------------- Known problems, limitations ---------------------------- - use of POSIX named semaphore is currently unstable and not recommended yet. + + +---------------- +Solaris version +---------------- + +The published version uses fifos for server/client synchronization. Sockets are used for server/client communications. An OSS backend is used. To build jackdmp, a "waf" (http://code.google.com/p/waf/) based compilation system is available. The code has to be compiled on a machine where OSS 4.0 headers and libraries are corrected installed. + +In the top folder do : + +./waf configure +./waf build +sudo ./waf install + +(Note : you may have to use "pfexec" instead of "sudo" on systems where sudo is not there.) + +Various compilation options can be seen using ./waf --help. + +Important compilation options : + +- if the "automatic start server option" is used by clients, jackd server will be started using the old fork + exe system. + +- the --dbus flag must be defined at configure time to compile the jackdbus executable. If the "automatic start server option" is used by clients, jackd server will be started using the dbus service. + +Starting the server : + +- for best performances, the server has to be started with privileges that allows to use "real-time" threads, for example using the "pfexec" command (or configurating the system with "priocntl" first), for instance : pfexec jackd -R -S -P59 -d oss + +- audio cards info can be retrieved using "ossinfo" tool (for instance ossinfo -v3). Some card needs to be configurated first using "ossxmix" then the correct buffer size has to be used, for instance : pfexec jackd -R -S -P59 -d oss -p 512 ------------ OSX version @@ -95,7 +123,7 @@ The binary elements are : - jack_portaudio.dll : the PortAudio based backend. The backend components (currently "jack_portaudio.dll" only) are searched for in a "jackmp" folder located with the "jackdmp.exe" server. -- jack_dummy.dll : the "dummy" driver. +- jack_dummy.dll : the "dummy" driver. - jack_net.dll : the NetJack driver. diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index fa7b4f22..519cb4c5 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -842,7 +842,8 @@ EXPORT jack_nframes_t jack_thread_wait(jack_client_t* ext_client, int status) jack_error("jack_thread_wait called with a NULL client"); return 0; } else { - return client->Wait(status); + jack_error("jack_thread_wait: deprecated, use jack_cycle_wait/jack_cycle_signal"); + return -1; } } diff --git a/common/JackClient.cpp b/common/JackClient.cpp index 3599547e..310b3c78 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -355,6 +355,7 @@ int JackClient::StartThread() /*! \brief RT thread. */ + bool JackClient::Execute() { if (!jack_tls_set(JackGlobals::fRealTime, this)) @@ -362,73 +363,59 @@ bool JackClient::Execute() if (GetEngineControl()->fRealTime) set_threaded_log_function(); - + + // Execute a dummy cycle to be sure thread has the correct properties + DummyCycle(); + if (fThreadFun) { - // Execute a dummy cycle to be sure thread has the correct properties (ensure thread creation is finished) - WaitSync(); - SignalSync(); fThreadFun(fThreadFunArg); } else { - if (WaitFirstSync()) - ExecuteThread(); + ExecuteThread(); } return false; } -inline bool JackClient::WaitFirstSync() +void JackClient::DummyCycle() { - while (true) { - // Start first cycle - WaitSync(); - if (IsActive()) { - CallSyncCallback(); - // Finish first cycle - if (Wait(CallProcessCallback()) != GetEngineControl()->fBufferSize) - return false; - return true; - } else { - jack_log("Process called for an inactive client"); - } - SignalSync(); - } - return false; + WaitSync(); + SignalSync(); } inline void JackClient::ExecuteThread() { - while (Wait(CallProcessCallback()) == GetEngineControl()->fBufferSize); + while (true) { + CycleWaitAux(); + CycleSignalAux(CallProcessCallback()); + } } -jack_nframes_t JackClient::Wait(int status) -{ - if (status == 0) - CallTimebaseCallback(); - SignalSync(); - if (status != 0) - End(); // Terminates the thread - if (!WaitSync()) - Error(); // Terminates the thread - CallSyncCallback(); - return GetEngineControl()->fBufferSize; -} - -jack_nframes_t JackClient::CycleWait() +inline jack_nframes_t JackClient::CycleWaitAux() { if (!WaitSync()) Error(); // Terminates the thread - CallSyncCallback(); + CallSyncCallbackAux(); return GetEngineControl()->fBufferSize; } -void JackClient::CycleSignal(int status) +inline void JackClient::CycleSignalAux(int status) { if (status == 0) - CallTimebaseCallback(); + CallTimebaseCallbackAux(); SignalSync(); if (status != 0) End(); // Terminates the thread } +jack_nframes_t JackClient::CycleWait() +{ + return CycleWaitAux(); +} + +void JackClient::CycleSignal(int status) +{ + CycleSignalAux(status); +} + inline int JackClient::CallProcessCallback() { return (fProcess != NULL) ? fProcess(GetEngineControl()->fBufferSize, fProcessArg) : 0; @@ -696,7 +683,13 @@ void JackClient::TransportStop() // Never called concurently with the server // TODO check concurrency with SetSyncCallback + void JackClient::CallSyncCallback() +{ + CallSyncCallbackAux(); +} + +inline void JackClient::CallSyncCallbackAux() { if (GetClientControl()->fTransportSync) { @@ -717,6 +710,11 @@ void JackClient::CallSyncCallback() } void JackClient::CallTimebaseCallback() +{ + CallTimebaseCallbackAux(); +} + +inline void JackClient::CallTimebaseCallbackAux() { JackTransportEngine& transport = GetEngineControl()->fTransport; int master; diff --git a/common/JackClient.h b/common/JackClient.h index f9addd6e..f41d734f 100644 --- a/common/JackClient.h +++ b/common/JackClient.h @@ -97,14 +97,18 @@ class JackClient : public JackClientInterface, public JackRunnableInterface virtual int ClientNotifyImp(int refnum, const char* name, int notify, int sync, int value1, int value); - inline bool WaitFirstSync(); + inline void DummyCycle(); inline void ExecuteThread(); inline bool WaitSync(); inline void SignalSync(); inline int CallProcessCallback(); inline void End(); inline void Error(); - + inline jack_nframes_t CycleWaitAux(); + inline void CycleSignalAux(int status); + inline void CallSyncCallbackAux(); + inline void CallTimebaseCallbackAux(); + public: JackClient(); @@ -172,10 +176,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface virtual int InternalClientLoad(const char* client_name, jack_options_t options, jack_status_t* status, jack_varargs_t* va); virtual void InternalClientUnload(int ref, jack_status_t* status); - // Fons Adriaensen thread model - virtual jack_nframes_t Wait(int status); - - virtual jack_nframes_t CycleWait(); + jack_nframes_t CycleWait(); void CycleSignal(int status); int SetProcessThread(JackThreadCallback fun, void *arg); @@ -184,11 +185,6 @@ class JackClient : public JackClientInterface, public JackRunnableInterface bool Execute(); }; -// Each "side" server and client will implement this to get the shared graph manager, engine control and inter-process synchro table. -extern JackGraphManager* GetGraphManager(); -extern JackEngineControl* GetEngineControl(); -extern JackSynchro* GetSynchroTable(); - } // end of namespace #endif diff --git a/common/JackClientControl.h b/common/JackClientControl.h index 4aa31b0c..a82313c7 100644 --- a/common/JackClientControl.h +++ b/common/JackClientControl.h @@ -79,7 +79,7 @@ struct JackClientControl : public JackShmMemAble fActive = false; } -}; +} POST_PACKED_STRUCTURE; } // end of namespace diff --git a/common/JackConnectionManager.h b/common/JackConnectionManager.h index b95261d6..bb972e31 100644 --- a/common/JackConnectionManager.h +++ b/common/JackConnectionManager.h @@ -356,7 +356,7 @@ struct JackClientTiming {} ~JackClientTiming() {} -}; +} POST_PACKED_STRUCTURE; /*! \brief Connection manager. @@ -445,12 +445,11 @@ class SERVER_EXPORT JackConnectionManager return fInputCounter[refnum].GetValue(); } - - // Graph void ResetGraph(JackClientTiming* timing); int ResumeRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing); int SuspendRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing, long time_out_usec); + }; } // end of namespace diff --git a/common/JackConstants.h b/common/JackConstants.h index 71288d11..5d4a136e 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -83,11 +83,7 @@ #define ALL_CLIENTS -1 // for notification -#if defined(__ppc64__) || defined(__x86_64__) -#define JACK_PROTOCOL_VERSION 6 -#else -#define JACK_PROTOCOL_VERSION 5 -#endif +#define JACK_PROTOCOL_VERSION 7 #define SOCKET_TIME_OUT 5 // in sec #define DRIVER_OPEN_TIMEOUT 5 // in sec diff --git a/common/JackDebugClient.cpp b/common/JackDebugClient.cpp index 3ff29b7d..74566c5e 100644 --- a/common/JackDebugClient.cpp +++ b/common/JackDebugClient.cpp @@ -521,11 +521,5 @@ void JackDebugClient::InternalClientUnload(int ref, jack_status_t* status) fClient->InternalClientUnload(ref, status); } -jack_nframes_t JackDebugClient::Wait(int status) -{ - CheckClient(); - return fClient->Wait(status); -} - } // end of namespace diff --git a/common/JackDebugClient.h b/common/JackDebugClient.h index d8625998..430c9610 100644 --- a/common/JackDebugClient.h +++ b/common/JackDebugClient.h @@ -127,9 +127,6 @@ class JackDebugClient : public JackClient int InternalClientLoad(const char* client_name, jack_options_t options, jack_status_t* status, jack_varargs_t* va); void InternalClientUnload(int ref, jack_status_t* status); - // Fons Adriaensen thread model - jack_nframes_t Wait(int status); - JackClientControl* GetClientControl() const; void CheckClient() const; diff --git a/common/JackDriverLoader.cpp b/common/JackDriverLoader.cpp index 79069642..37ac7479 100644 --- a/common/JackDriverLoader.cpp +++ b/common/JackDriverLoader.cpp @@ -432,8 +432,7 @@ jack_get_descriptor (JSList * drivers, const char * sofile, const char * symbol) return NULL; } - so_get_descriptor = (JackDriverDescFunction) - GetProc(dlhandle, symbol); + so_get_descriptor = (JackDriverDescFunction)GetDriverProc(dlhandle, symbol); #ifdef WIN32 if ((so_get_descriptor == NULL) && (dlerr = GetLastError()) != 0) { @@ -513,7 +512,7 @@ static bool check_symbol(const char* sofile, const char* symbol) jack_error ("could not open component .so '%s': %s", filename, dlerror()); #endif } else { - res = (GetProc(dlhandle, symbol)) ? true : false; + res = (GetDriverProc(dlhandle, symbol)) ? true : false; UnloadDriverModule(dlhandle); } @@ -791,7 +790,7 @@ Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver return NULL; } - fInitialize = (driverInitialize)GetProc(fHandle, "driver_initialize"); + fInitialize = (driverInitialize)GetDriverProc(fHandle, "driver_initialize"); #ifdef WIN32 if ((fInitialize == NULL) && (errstr = GetLastError ()) != 0) { diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index 03d7f91b..16c75589 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -69,7 +69,7 @@ int JackEngine::Close() { jack_log("JackEngine::Close"); fChannel.Close(); - + // Close remaining clients (RT is stopped) for (int i = REAL_REFNUM; i < CLIENT_NUM; i++) { if (JackLoadableInternalClient* loadable_client = dynamic_cast(fClientTable[i])) { @@ -85,10 +85,10 @@ int JackEngine::Close() fClientTable[i] = NULL; } } - + return 0; } - + //----------------------------- // Client ressource management //----------------------------- @@ -147,7 +147,7 @@ void JackEngine::ProcessCurrent(jack_time_t cur_cycle_begin) bool JackEngine::Process(jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end) { bool res = true; - + // Cycle begin fEngineControl->CycleBegin(fClientTable, fGraphManager, cur_cycle_begin, prev_cycle_end); @@ -213,7 +213,7 @@ void JackEngine::NotifyClient(int refnum, int event, int sync, int value1, int v jack_log("JackEngine::NotifyClient: client not available anymore"); } else if (client->GetClientControl()->fCallback[event]) { if (client->ClientNotify(refnum, client->GetClientControl()->fName, event, sync, value1, value2) < 0) - jack_error("NotifyClient fails name = %s event = %ld = val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2); + jack_error("NotifyClient fails name = %s event = %ld val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2); } else { jack_log("JackEngine::NotifyClient: no callback for event = %ld", event); } @@ -226,7 +226,7 @@ void JackEngine::NotifyClients(int event, int sync, int value1, int value2) if (client) { if (client->GetClientControl()->fCallback[event]) { if (client->ClientNotify(i, client->GetClientControl()->fName, event, sync, value1, value2) < 0) - jack_error("NotifyClient fails name = %s event = %ld = val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2); + jack_error("NotifyClient fails name = %s event = %ld val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2); } else { jack_log("JackEngine::NotifyClients: no callback for event = %ld", event); } @@ -461,7 +461,7 @@ int JackEngine::GetClientPID(const char* name) if (client && (strcmp(client->GetClientControl()->fName, name) == 0)) return client->GetClientControl()->fPID; } - + return 0; } @@ -472,7 +472,7 @@ int JackEngine::GetClientRefNum(const char* name) if (client && (strcmp(client->GetClientControl()->fName, name) == 0)) return client->GetClientControl()->fRefNum; } - + return -1; } @@ -511,7 +511,7 @@ int JackEngine::ClientExternalOpen(const char* name, int pid, int* ref, int* sha jack_error("Cannot notify add client"); goto error; } - + fGraphManager->InitRefNum(refnum); fEngineControl->ResetRollingUsecs(); *shared_engine = fEngineControl->GetShmIndex(); @@ -576,7 +576,7 @@ int JackEngine::ClientExternalClose(int refnum) { AssertRefnum(refnum); JackClientInterface* client = fClientTable[refnum]; - + if (client) { fEngineControl->fTransport.ResetTimebase(refnum); int res = ClientCloseAux(refnum, client, true); @@ -613,7 +613,7 @@ int JackEngine::ClientCloseAux(int refnum, JackClientInterface* client, bool wai for (i = 0; (i < PORT_NUM_FOR_CLIENT) && (ports[i] != EMPTY) ; i++) { PortUnRegister(refnum, ports[i]); } - + // Remove the client from the table ReleaseRefnum(refnum); @@ -641,11 +641,11 @@ int JackEngine::ClientActivate(int refnum, bool state) AssertRefnum(refnum); JackClientInterface* client = fClientTable[refnum]; assert(fClientTable[refnum]); - + jack_log("JackEngine::ClientActivate ref = %ld name = %s", refnum, client->GetClientControl()->fName); - if (state) + if (state) fGraphManager->Activate(refnum); - + // Wait for graph state change to be effective if (!fSignal.LockedTimedWait(fEngineControl->fTimeOutUsecs * 10)) { jack_error("JackEngine::ClientActivate wait error ref = %ld name = %s", refnum, client->GetClientControl()->fName); @@ -665,11 +665,11 @@ int JackEngine::ClientDeactivate(int refnum) return -1; jack_log("JackEngine::ClientDeactivate ref = %ld name = %s", refnum, client->GetClientControl()->fName); - + // Disconnect all ports ==> notifications are sent jack_int_t ports[PORT_NUM_FOR_CLIENT]; int i; - + fGraphManager->GetInputPorts(refnum, ports); for (i = 0; (i < PORT_NUM_FOR_CLIENT) && (ports[i] != EMPTY) ; i++) { PortDisconnect(refnum, ports[i], ALL_PORTS); @@ -679,7 +679,7 @@ int JackEngine::ClientDeactivate(int refnum) for (i = 0; (i < PORT_NUM_FOR_CLIENT) && (ports[i] != EMPTY) ; i++) { PortDisconnect(refnum, ports[i], ALL_PORTS); } - + fGraphManager->Deactivate(refnum); fLastSwitchUsecs = 0; // Force switch to occur next cycle, even when called with "dead" clients @@ -701,11 +701,11 @@ int JackEngine::PortRegister(int refnum, const char* name, const char *type, uns jack_log("JackEngine::PortRegister ref = %ld name = %s type = %s flags = %d buffer_size = %d", refnum, name, type, flags, buffer_size); AssertRefnum(refnum); assert(fClientTable[refnum]); - + // Check if port name already exists if (fGraphManager->GetPort(name) != NO_PORT) { jack_error("port_name \"%s\" already exists", name); - return -1; + return -1; } *port_index = fGraphManager->AllocatePort(refnum, name, type, (JackPortFlags)flags, fEngineControl->fBufferSize); @@ -722,7 +722,7 @@ int JackEngine::PortUnRegister(int refnum, jack_port_id_t port_index) jack_log("JackEngine::PortUnRegister ref = %ld port_index = %ld", refnum, port_index); AssertRefnum(refnum); assert(fClientTable[refnum]); - + // Disconnect port ==> notification is sent PortDisconnect(refnum, port_index, ALL_PORTS); @@ -775,7 +775,7 @@ int JackEngine::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst) } int res = fGraphManager->Connect(src, dst); - if (res == 0) + if (res == 0) NotifyPortConnect(src, dst, true); return res; } diff --git a/common/JackEngineControl.h b/common/JackEngineControl.h index a4e2adcd..5f8b604b 100644 --- a/common/JackEngineControl.h +++ b/common/JackEngineControl.h @@ -166,7 +166,7 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem void CalcCPULoad(JackClientInterface** table, JackGraphManager* manager, jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end); void ResetRollingUsecs(); -}; +} POST_PACKED_STRUCTURE; } // end of namespace diff --git a/common/JackEngineProfiling.h b/common/JackEngineProfiling.h index 62c4b86e..c06487a0 100644 --- a/common/JackEngineProfiling.h +++ b/common/JackEngineProfiling.h @@ -52,7 +52,8 @@ struct JackTimingMeasureClient fFinishedAt(0), fStatus((jack_client_state_t)0) {} -}; + +} POST_PACKED_STRUCTURE; /*! \brief Timing interval in the global table for a given client @@ -70,7 +71,8 @@ struct JackTimingClientInterval fBeginInterval(-1), fEndInterval(-1) {} -}; + +} POST_PACKED_STRUCTURE; /*! \brief Timing stucture for a table of clients. @@ -90,7 +92,8 @@ struct JackTimingMeasure fCurCycleBegin(0), fPrevCycleEnd(0) {} -}; + +} POST_PACKED_STRUCTURE; /*! \brief Client timing monitoring. @@ -125,7 +128,7 @@ class SERVER_EXPORT JackEngineProfiling JackTimingMeasure* GetCurMeasure(); -}; +} POST_PACKED_STRUCTURE; } // end of namespace diff --git a/common/JackFrameTimer.h b/common/JackFrameTimer.h index 703a90be..1468f1b5 100644 --- a/common/JackFrameTimer.h +++ b/common/JackFrameTimer.h @@ -93,7 +93,8 @@ class SERVER_EXPORT JackFrameTimer : public JackAtomicState void ResetFrameTime(jack_nframes_t frames_rate, jack_time_t callback_usecs, jack_time_t period_usecs); void IncFrameTime(jack_nframes_t buffer_size, jack_time_t callback_usecs, jack_time_t period_usecs); void ReadFrameTime(JackTimer* timer); -}; + +} POST_PACKED_STRUCTURE; } // end of namespace diff --git a/common/JackGlobals.h b/common/JackGlobals.h index 8495c062..f5516f73 100644 --- a/common/JackGlobals.h +++ b/common/JackGlobals.h @@ -22,13 +22,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackPlatformPlug.h" #include "JackConstants.h" -#include "JackClient.h" namespace Jack { // Globals used for client management on server or libray side. - struct JackGlobals { static jack_tls_key fRealTime; @@ -42,6 +40,11 @@ struct JackGlobals { }; +// Each "side" server and client will implement this to get the shared graph manager, engine control and inter-process synchro table. +extern EXPORT JackGraphManager* GetGraphManager(); +extern EXPORT JackEngineControl* GetEngineControl(); +extern EXPORT JackSynchro* GetSynchroTable(); + } // end of namespace #endif diff --git a/common/JackGraphManager.h b/common/JackGraphManager.h index 67d482e7..575e3752 100644 --- a/common/JackGraphManager.h +++ b/common/JackGraphManager.h @@ -125,11 +125,10 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState return &fClientTiming[refnum]; } - void Save(JackConnectionManager* dst); void Restore(JackConnectionManager* src); -}; +} POST_PACKED_STRUCTURE; } // end of namespace diff --git a/common/JackInternalClient.cpp b/common/JackInternalClient.cpp index 45350802..1150a5e9 100644 --- a/common/JackInternalClient.cpp +++ b/common/JackInternalClient.cpp @@ -34,73 +34,21 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { -#ifdef WIN32 - -static void BuildClientPath(char* path_to_so, int path_len, const char* so_name) -{ - snprintf(path_to_so, path_len, ADDON_DIR "/%s.dll", so_name); -} - -static void PrintLoadError(const char* so_name) -{ - // Retrieve the system error message for the last-error code - LPVOID lpMsgBuf; - LPVOID lpDisplayBuf; - DWORD dw = GetLastError(); - - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - dw, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &lpMsgBuf, - 0, NULL ); - - // Display the error message and exit the process - lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, - (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)so_name) + 40) * sizeof(TCHAR)); - _snprintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR), - TEXT("error loading %s err = %s"), so_name, lpMsgBuf); - - jack_error((LPCTSTR)lpDisplayBuf); - - LocalFree(lpMsgBuf); - LocalFree(lpDisplayBuf); -} - -#else - -static void BuildClientPath(char* path_to_so, int path_len, const char* so_name) -{ - const char* internal_dir; - if ((internal_dir = getenv("JACK_INTERNAL_DIR")) == 0) { - if ((internal_dir = getenv("JACK_DRIVER_DIR")) == 0) { - internal_dir = ADDON_DIR; - } - } - - snprintf(path_to_so, path_len, "%s/%s.so", internal_dir, so_name); -} - -#endif - JackGraphManager* JackInternalClient::fGraphManager = NULL; JackEngineControl* JackInternalClient::fEngineControl = NULL; // Used for external C API (JackAPI.cpp) -JackGraphManager* GetGraphManager() +EXPORT JackGraphManager* GetGraphManager() { return JackServerGlobals::fInstance->GetGraphManager(); } -JackEngineControl* GetEngineControl() +EXPORT JackEngineControl* GetEngineControl() { return JackServerGlobals::fInstance->GetEngineControl(); } -JackSynchro* GetSynchroTable() +EXPORT JackSynchro* GetSynchroTable() { return JackServerGlobals::fInstance->GetSynchroTable(); } diff --git a/common/JackInternalClient.h b/common/JackInternalClient.h index 1e0d5559..fe398139 100644 --- a/common/JackInternalClient.h +++ b/common/JackInternalClient.h @@ -60,25 +60,6 @@ class JackInternalClient : public JackClient \brief Loadable internal clients in the server. */ -#ifdef WIN32 - -#include -#define HANDLE HINSTANCE -#define LoadJackModule(name) LoadLibrary((name)); -#define UnloadJackModule(handle) FreeLibrary((handle)); -#define GetJackProc(handle, name) GetProcAddress((handle), (name)); - -#else - -#include -#define HANDLE void* -#define LoadJackModule(name) dlopen((name), RTLD_NOW | RTLD_LOCAL); -#define UnloadJackModule(handle) dlclose((handle)); -#define GetJackProc(handle, name) dlsym((handle), (name)); -#define PrintLoadError(so_name) jack_log("error loading %s err = %s", so_name, dlerror()); - -#endif - typedef int (*InitializeCallback)(jack_client_t*, const char*); typedef int (*InternalInitializeCallback)(jack_client_t*, const JSList* params); typedef void (*FinishCallback)(void *); @@ -89,7 +70,7 @@ class JackLoadableInternalClient : public JackInternalClient protected: - HANDLE fHandle; + JACK_HANDLE fHandle; FinishCallback fFinish; JackDriverDescFunction fDescriptor; diff --git a/common/JackLibClient.cpp b/common/JackLibClient.cpp index ed6a0ba1..f65148e9 100644 --- a/common/JackLibClient.cpp +++ b/common/JackLibClient.cpp @@ -106,7 +106,7 @@ int JackLibClient::Open(const char* server_name, const char* name, jack_options_ } SetupDriverSync(false); - + // Connect shared synchro : the synchro must be usable in I/O mode when several clients live in the same process if (!fSynchroTable[GetClientControl()->fRefNum].Connect(name_res, fServerName)) { jack_error("Cannot ConnectSemaphore %s client", name_res); diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index 7164e637..c1817848 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -226,11 +226,9 @@ namespace Jack SetAdaptedSampleRate ( fParams.fSampleRate ); // Will do "something" on OSX only... - fThread.SetParams(JackServerGlobals::fInstance->GetEngineControl()->fPeriod, - JackServerGlobals::fInstance->GetEngineControl()->fComputation, - JackServerGlobals::fInstance->GetEngineControl()->fConstraint); + fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); - if (fThread.AcquireRealTime ( JackServerGlobals::fInstance->GetEngineControl()->fClientPriority ) < 0) { + if (fThread.AcquireRealTime(GetEngineControl()->fClientPriority) < 0) { jack_error("AcquireRealTime error"); } else { set_threaded_log_function(); diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 27495c18..78e9dbb9 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -329,9 +329,6 @@ namespace Jack jack_error ( "Can't send suicide request : %s", StrError ( NET_ERROR_CODE ) ); mcast_socket.Close(); - - // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine. - ThreadExit(); } int JackNetMasterInterface::Recv ( size_t size, int flags ) @@ -349,6 +346,9 @@ namespace Jack jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) ); //ask to the manager to properly remove the master Exit(); + + // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine. + ThreadExit(); } else jack_error ( "Error in master receive : %s", StrError ( NET_ERROR_CODE ) ); @@ -373,6 +373,9 @@ namespace Jack //fatal connection issue, exit jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) ); Exit(); + + // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine. + ThreadExit(); } else jack_error ( "Error in master send : %s", StrError ( NET_ERROR_CODE ) ); diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index 1b8b9c72..86d23522 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -127,7 +127,11 @@ namespace Jack return false; } - jack_set_process_callback ( fJackClient, SetProcess, this ); + if (jack_set_process_callback(fJackClient, SetProcess, this ) < 0) + goto fail; + + if (jack_set_buffer_size_callback(fJackClient, SetBufferSize, this) < 0) + goto fail; if ( AllocPorts() != 0 ) { @@ -334,7 +338,7 @@ namespace Jack if ( jack_transport_reposition ( fJackClient, &fReturnTransportData.fPosition ) == EINVAL ) jack_error ( "Can't set new position." ); jack_transport_start ( fJackClient ); - jack_info ( "'%s' starts transport frame = %d", fParams.fName, fReturnTransportData.fPosition.frame); + jack_info ( "'%s' starts transport frame = %d frame = %d", fParams.fName, fReturnTransportData.fPosition.frame); break; case JackTransportNetStarting : jack_info ( "'%s' is ready to roll..", fParams.fName ); @@ -369,6 +373,13 @@ namespace Jack { return ( fReturnTransportData.fState == JackTransportNetStarting ); } + + int JackNetMaster::SetBufferSize (jack_nframes_t nframes, void* arg) + { + jack_error("Cannot handle bufer size change, so proxy will be removed..."); + static_cast ( arg )->Exit(); + return 0; + } //process----------------------------------------------------------------------------- int JackNetMaster::SetProcess ( jack_nframes_t nframes, void* arg ) diff --git a/common/JackNetManager.h b/common/JackNetManager.h index 6e05759f..b6ad7857 100644 --- a/common/JackNetManager.h +++ b/common/JackNetManager.h @@ -39,6 +39,7 @@ namespace Jack friend class JackNetMasterManager; private: static int SetProcess ( jack_nframes_t nframes, void* arg ); + static int SetBufferSize (jack_nframes_t nframes, void* arg); static void SetTimebaseCallback ( jack_transport_state_t state, jack_nframes_t nframes, jack_position_t* pos, int new_pos, void* arg ); //jack client @@ -63,8 +64,7 @@ namespace Jack bool Init(bool auto_connect); int AllocPorts(); void FreePorts(); - void Exit(); - + //transport void EncodeTransportData(); void DecodeTransportData(); diff --git a/common/JackPort.cpp b/common/JackPort.cpp index 2afec24b..42b5fb2e 100644 --- a/common/JackPort.cpp +++ b/common/JackPort.cpp @@ -109,12 +109,12 @@ int JackPort::RequestMonitor(bool onoff) { /** jackd.h - * If @ref JackPortCanMonitor is set for this @a port, turn input - * monitoring on or off. Otherwise, do nothing. + * If @ref JackPortCanMonitor is set for this @a port, turn input + * monitoring on or off. Otherwise, do nothing. - if (!(fFlags & JackPortCanMonitor)) + if (!(fFlags & JackPortCanMonitor)) return -1; - */ + */ if (onoff) { fMonitorRequests++; @@ -129,12 +129,12 @@ int JackPort::EnsureMonitor(bool onoff) { /** jackd.h - * If @ref JackPortCanMonitor is set for this @a port, turn input - * monitoring on or off. Otherwise, do nothing. + * If @ref JackPortCanMonitor is set for this @a port, turn input + * monitoring on or off. Otherwise, do nothing. - if (!(fFlags & JackPortCanMonitor)) + if (!(fFlags & JackPortCanMonitor)) return -1; - */ + */ if (onoff) { if (fMonitorRequests == 0) { @@ -247,13 +247,13 @@ int JackPort::UnsetAlias(const char* alias) void JackPort::ClearBuffer(jack_nframes_t frames) { const JackPortType* type = GetPortType(fTypeId); - (type->init)(fBuffer, frames * sizeof(float), frames); + (type->init)(GetBuffer(), frames * sizeof(float), frames); } void JackPort::MixBuffers(void** src_buffers, int src_count, jack_nframes_t buffer_size) { const JackPortType* type = GetPortType(fTypeId); - (type->mixdown)(fBuffer, src_buffers, src_count, buffer_size); + (type->mixdown)(GetBuffer(), src_buffers, src_count, buffer_size); } } // end of namespace diff --git a/common/JackPort.h b/common/JackPort.h index 4951ffa9..45f90733 100644 --- a/common/JackPort.h +++ b/common/JackPort.h @@ -55,9 +55,8 @@ class SERVER_EXPORT JackPort bool fInUse; jack_port_id_t fTied; // Locally tied source port - - MEM_ALIGN(float fBuffer[BUFFER_SIZE_MAX], 64); // 16 bytes alignment for vector code, 64 bytes better for cache loads/stores - + float fBuffer[BUFFER_SIZE_MAX + 4]; + bool IsUsed() const { return fInUse; @@ -99,14 +98,15 @@ class SERVER_EXPORT JackPort return (fMonitorRequests > 0); } + // Since we are in shared memory, the resulting pointer cannot be cached, so align it here... float* GetBuffer() { - return fBuffer; + return (float*)((long)fBuffer & ~15L) + 4; } int GetRefNum() const; -}; - + +} POST_PACKED_STRUCTURE; } // end of namespace diff --git a/common/JackRequest.h b/common/JackRequest.h index 03cfea4f..e6243b7b 100644 --- a/common/JackRequest.h +++ b/common/JackRequest.h @@ -116,6 +116,7 @@ struct JackResult { return trans->Write(&fResult, sizeof(int)); } + }; /*! @@ -151,7 +152,8 @@ struct JackClientCheckRequest : public JackRequest CheckRes(trans->Write(&fProtocol, sizeof(int))); return trans->Write(&fOptions, sizeof(int)); } -}; + +} POST_PACKED_STRUCTURE; /*! \brief CheckClient result. @@ -186,7 +188,8 @@ struct JackClientCheckResult : public JackResult CheckRes(trans->Write(&fStatus, sizeof(int))); return 0; } -}; + +} POST_PACKED_STRUCTURE; /*! \brief NewClient request. @@ -218,7 +221,8 @@ struct JackClientOpenRequest : public JackRequest CheckRes(trans->Write(&fPID, sizeof(int))); return trans->Write(&fName, JACK_CLIENT_NAME_SIZE + 1); } -}; + +} POST_PACKED_STRUCTURE; /*! \brief NewClient result. @@ -255,7 +259,8 @@ struct JackClientOpenResult : public JackResult CheckRes(trans->Write(&fSharedGraph, sizeof(int))); return 0; } -}; + +} POST_PACKED_STRUCTURE; /*! \brief CloseClient request. @@ -281,7 +286,8 @@ struct JackClientCloseRequest : public JackRequest CheckRes(JackRequest::Write(trans)); return trans->Write(&fRefNum, sizeof(int)); } -}; + +} POST_PACKED_STRUCTURE; /*! \brief Activate request. @@ -312,7 +318,7 @@ struct JackActivateRequest : public JackRequest return trans->Write(&fState, sizeof(int)); } -}; +} POST_PACKED_STRUCTURE; /*! \brief Deactivate request. @@ -339,7 +345,7 @@ struct JackDeactivateRequest : public JackRequest return trans->Write(&fRefNum, sizeof(int)); } -}; +} POST_PACKED_STRUCTURE; /*! \brief PortRegister request. @@ -383,7 +389,8 @@ struct JackPortRegisterRequest : public JackRequest CheckRes(trans->Write(&fBufferSize, sizeof(unsigned int))); return 0; } -}; + +} POST_PACKED_STRUCTURE; /*! \brief PortRegister result. @@ -408,7 +415,8 @@ struct JackPortRegisterResult : public JackResult CheckRes(JackResult::Write(trans)); return trans->Write(&fPortIndex, sizeof(jack_port_id_t)); } -}; + +} POST_PACKED_STRUCTURE; /*! \brief PortUnregister request. @@ -440,7 +448,8 @@ struct JackPortUnRegisterRequest : public JackRequest CheckRes(trans->Write(&fPortIndex, sizeof(jack_port_id_t))); return 0; } -}; + +} POST_PACKED_STRUCTURE; /*! \brief PortConnectName request. @@ -479,7 +488,8 @@ struct JackPortConnectNameRequest : public JackRequest CheckRes(trans->Write(&fDst, JACK_PORT_NAME_SIZE + 1)); return 0; } -}; + +} POST_PACKED_STRUCTURE; /*! \brief PortDisconnectName request. @@ -517,7 +527,8 @@ struct JackPortDisconnectNameRequest : public JackRequest CheckRes(trans->Write(&fDst, JACK_PORT_NAME_SIZE + 1)); return 0; } -}; + +} POST_PACKED_STRUCTURE; /*! \brief PortConnect request. @@ -552,8 +563,8 @@ struct JackPortConnectRequest : public JackRequest CheckRes(trans->Write(&fDst, sizeof(jack_port_id_t))); return 0; } -}; - + +} POST_PACKED_STRUCTURE; /*! \brief PortDisconnect request. @@ -589,7 +600,8 @@ struct JackPortDisconnectRequest : public JackRequest return 0; } -}; + +} POST_PACKED_STRUCTURE; /*! \brief PortRename request. @@ -627,7 +639,8 @@ struct JackPortRenameRequest : public JackRequest return 0; } -}; + +} POST_PACKED_STRUCTURE; /*! \brief SetBufferSize request. @@ -654,7 +667,8 @@ struct JackSetBufferSizeRequest : public JackRequest CheckRes(JackRequest::Write(trans)); return trans->Write(&fBufferSize, sizeof(jack_nframes_t)); } -}; + +} POST_PACKED_STRUCTURE; /*! \brief SetFreeWheel request. @@ -681,7 +695,8 @@ struct JackSetFreeWheelRequest : public JackRequest CheckRes(JackRequest::Write(trans)); return trans->Write(&fOnOff, sizeof(int)); } -}; + +} POST_PACKED_STRUCTURE; /*! \brief ReleaseTimebase request. @@ -708,7 +723,8 @@ struct JackReleaseTimebaseRequest : public JackRequest CheckRes(JackRequest::Write(trans)); return trans->Write(&fRefNum, sizeof(int)); } -}; + +} POST_PACKED_STRUCTURE; /*! \brief SetTimebaseCallback request. @@ -738,7 +754,8 @@ struct JackSetTimebaseCallbackRequest : public JackRequest CheckRes(trans->Write(&fRefNum, sizeof(int))); return trans->Write(&fConditionnal, sizeof(int)); } -}; + +} POST_PACKED_STRUCTURE; /*! \brief GetInternalClientName request. @@ -768,7 +785,8 @@ struct JackGetInternalClientNameRequest : public JackRequest CheckRes(trans->Write(&fRefNum, sizeof(int))); return trans->Write(&fIntRefNum, sizeof(int)); } -}; + +} POST_PACKED_STRUCTURE; /*! \brief GetInternalClient result. @@ -800,7 +818,8 @@ struct JackGetInternalClientNameResult : public JackResult CheckRes(trans->Write(&fName, JACK_CLIENT_NAME_SIZE + 1)); return 0; } -}; + +} POST_PACKED_STRUCTURE; /*! \brief InternalClientHandle request. @@ -832,7 +851,8 @@ struct JackInternalClientHandleRequest : public JackRequest CheckRes(trans->Write(&fRefNum, sizeof(int))); return trans->Write(&fName, JACK_CLIENT_NAME_SIZE + 1); } -}; + +} POST_PACKED_STRUCTURE; /*! \brief InternalClientHandle result. @@ -865,7 +885,8 @@ struct JackInternalClientHandleResult : public JackResult CheckRes(trans->Write(&fIntRefNum, sizeof(int))); return 0; } -}; + +} POST_PACKED_STRUCTURE; /*! \brief InternalClientLoad request. @@ -912,7 +933,8 @@ struct JackInternalClientLoadRequest : public JackRequest CheckRes(trans->Write(&fLoadInitName, JACK_LOAD_INIT_LIMIT + 1)); return trans->Write(&fOptions, sizeof(int)); } -}; + +} POST_PACKED_STRUCTURE; /*! \brief InternalClientLoad result. @@ -945,7 +967,8 @@ struct JackInternalClientLoadResult : public JackResult CheckRes(trans->Write(&fIntRefNum, sizeof(int))); return 0; } -}; + +} POST_PACKED_STRUCTURE; /*! \brief InternalClientUnload request. @@ -975,8 +998,7 @@ struct JackInternalClientUnloadRequest : public JackRequest CheckRes(trans->Write(&fRefNum, sizeof(int))); return trans->Write(&fIntRefNum, sizeof(int)); } -}; - +} POST_PACKED_STRUCTURE; /*! \brief InternalClientLoad result. @@ -1006,7 +1028,8 @@ struct JackInternalClientUnloadResult : public JackResult CheckRes(trans->Write(&fStatus, sizeof(int))); return 0; } -}; + +} POST_PACKED_STRUCTURE; /*! \brief ClientNotification request. @@ -1042,7 +1065,7 @@ struct JackClientNotificationRequest : public JackRequest return 0; } -}; +} POST_PACKED_STRUCTURE; /*! \brief ClientNotification. @@ -1087,7 +1110,7 @@ struct JackClientNotification return 0; } -}; +} POST_PACKED_STRUCTURE; } // end of namespace diff --git a/common/JackShmMem.cpp b/common/JackShmMem.cpp index a6ec3159..5d68b86e 100644 --- a/common/JackShmMem.cpp +++ b/common/JackShmMem.cpp @@ -37,7 +37,7 @@ JackShmMem::JackShmMem() void JackShmMemAble::Init() { fInfo.index = gInfo.index; - fInfo.attached_at = gInfo.attached_at; + fInfo.ptr.attached_at = gInfo.ptr.attached_at; fInfo.size = gInfo.size; } @@ -71,9 +71,9 @@ void* JackShmMem::operator new(size_t size) // so use an intermediate global data gInfo.index = info.index; gInfo.size = size; - gInfo.attached_at = info.attached_at; + gInfo.ptr.attached_at = info.ptr.attached_at; - jack_log("JackShmMem::new index = %ld attached = %x size = %ld ", info.index, info.attached_at, size); + jack_log("JackShmMem::new index = %ld attached = %x size = %ld ", info.index, info.ptr.attached_at, size); return obj; error: @@ -86,7 +86,7 @@ void JackShmMem::operator delete(void* p, size_t size) jack_shm_info_t info; JackShmMem* obj = (JackShmMem*)p; info.index = obj->fInfo.index; - info.attached_at = obj->fInfo.attached_at; + info.ptr.attached_at = obj->fInfo.ptr.attached_at; jack_log("JackShmMem::delete size = %ld index = %ld", size, info.index); diff --git a/common/JackShmMem.h b/common/JackShmMem.h index 6a6261a2..5976c96d 100644 --- a/common/JackShmMem.h +++ b/common/JackShmMem.h @@ -102,7 +102,7 @@ class JackShmMemAble char* GetShmAddress() { - return (char*)fInfo.attached_at; + return (char*)fInfo.ptr.attached_at; } void LockMemory() @@ -173,7 +173,7 @@ class JackShmReadWritePtr JackShmReadWritePtr() { fInfo.index = -1; - fInfo.attached_at = NULL; + fInfo.ptr.attached_at = (char*)NULL; } JackShmReadWritePtr(int index, const char* server_name) @@ -192,12 +192,12 @@ class JackShmReadWritePtr T* operator->() const { - return (T*)fInfo.attached_at; + return (T*)fInfo.ptr.attached_at; } operator T*() const { - return (T*)fInfo.attached_at; + return (T*)fInfo.ptr.attached_at; } JackShmReadWritePtr& operator=(int index) @@ -218,7 +218,7 @@ class JackShmReadWritePtr T* GetShmAddress() { - return (T*)fInfo.attached_at; + return (T*)fInfo.ptr.attached_at; } }; @@ -259,7 +259,7 @@ class JackShmReadWritePtr1 JackShmReadWritePtr1() { fInfo.index = -1; - fInfo.attached_at = NULL; + fInfo.ptr.attached_at = NULL; } JackShmReadWritePtr1(int index, const char* server_name) @@ -278,12 +278,12 @@ class JackShmReadWritePtr1 T* operator->() const { - return (T*)fInfo.attached_at; + return (T*)fInfo.ptr.attached_at; } operator T*() const { - return (T*)fInfo.attached_at; + return (T*)fInfo.ptr.attached_at; } JackShmReadWritePtr1& operator=(int index) @@ -304,7 +304,7 @@ class JackShmReadWritePtr1 T* GetShmAddress() { - return (T*)fInfo.attached_at; + return (T*)fInfo.ptr.attached_at; } }; @@ -339,7 +339,7 @@ class JackShmReadPtr JackShmReadPtr() { fInfo.index = -1; - fInfo.attached_at = NULL; + fInfo.ptr.attached_at = NULL; } JackShmReadPtr(int index, const char* server_name) @@ -358,12 +358,12 @@ class JackShmReadPtr T* operator->() const { - return (T*)fInfo.attached_at; + return (T*)fInfo.ptr.attached_at; } operator T*() const { - return (T*)fInfo.attached_at; + return (T*)fInfo.ptr.attached_at; } JackShmReadPtr& operator=(int index) @@ -384,7 +384,7 @@ class JackShmReadPtr T* GetShmAddress() { - return (T*)fInfo.attached_at; + return (T*)fInfo.ptr.attached_at; } }; diff --git a/common/JackThreadedDriver.cpp b/common/JackThreadedDriver.cpp index 590d9575..45fb1dc9 100644 --- a/common/JackThreadedDriver.cpp +++ b/common/JackThreadedDriver.cpp @@ -22,7 +22,6 @@ #include "JackThreadedDriver.h" #include "JackError.h" #include "JackGlobals.h" -#include "JackClient.h" #include "JackEngineControl.h" namespace Jack diff --git a/common/JackTools.cpp b/common/JackTools.cpp index 75209ede..cc8c67c3 100644 --- a/common/JackTools.cpp +++ b/common/JackTools.cpp @@ -212,6 +212,63 @@ namespace Jack { } new_name[i] = '\0'; } + +#ifdef WIN32 + +void BuildClientPath(char* path_to_so, int path_len, const char* so_name) +{ + snprintf(path_to_so, path_len, ADDON_DIR "/%s.dll", so_name); +} + +void PrintLoadError(const char* so_name) +{ + // Retrieve the system error message for the last-error code + LPVOID lpMsgBuf; + LPVOID lpDisplayBuf; + DWORD dw = GetLastError(); + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dw, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, + 0, NULL ); + + // Display the error message and exit the process + lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, + (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)so_name) + 40) * sizeof(TCHAR)); + _snprintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR), + TEXT("error loading %s err = %s"), so_name, lpMsgBuf); + + jack_error((LPCTSTR)lpDisplayBuf); + + LocalFree(lpMsgBuf); + LocalFree(lpDisplayBuf); +} + +#else +void PrintLoadError(const char* so_name) +{ + jack_log("error loading %s err = %s", so_name, dlerror()); } +void BuildClientPath(char* path_to_so, int path_len, const char* so_name) +{ + const char* internal_dir; + if ((internal_dir = getenv("JACK_INTERNAL_DIR")) == 0) { + if ((internal_dir = getenv("JACK_DRIVER_DIR")) == 0) { + internal_dir = ADDON_DIR; + } + } + + snprintf(path_to_so, path_len, "%s/%s.so", internal_dir, so_name); +} + +#endif + +} // end of namespace + diff --git a/common/JackTools.h b/common/JackTools.h index 9f3cb5fa..820f91ba 100644 --- a/common/JackTools.h +++ b/common/JackTools.h @@ -201,6 +201,10 @@ namespace Jack return 0; } }; + + void BuildClientPath(char* path_to_so, int path_len, const char* so_name); + void PrintLoadError(const char* so_name); + } #endif diff --git a/common/JackTransportEngine.cpp b/common/JackTransportEngine.cpp index 66f96cf2..b0d100dc 100644 --- a/common/JackTransportEngine.cpp +++ b/common/JackTransportEngine.cpp @@ -174,29 +174,29 @@ void JackTransportEngine::CycleEnd(JackClientInterface** table, jack_nframes_t f case JackTransportStopped: // Set a JackTransportStarting for the current cycle, if all clients are ready (no slow_sync) ==> JackTransportRolling next state if (cmd == TransportCommandStart) { - jack_log("transport stopped ==> starting"); + jack_log("transport stopped ==> starting frame = %d", ReadCurrentState()->frame); fTransportState = JackTransportStarting; MakeAllStartingLocating(table); SyncTimeout(frame_rate, buffer_size); } else if (fPendingPos) { - jack_log("transport stopped ==> stopped (locating)"); + jack_log("transport stopped ==> stopped (locating) frame = %d", ReadCurrentState()->frame); MakeAllLocating(table); } break; case JackTransportStarting: if (cmd == TransportCommandStop) { - jack_log("transport starting ==> stopped"); + jack_log("transport starting ==> stopped frame = %d", ReadCurrentState()->frame); fTransportState = JackTransportStopped; MakeAllStopping(table); } else if (fPendingPos) { - jack_log("transport starting ==> starting"); + jack_log("transport starting ==> starting frame = %d"), ReadCurrentState()->frame; fTransportState = JackTransportStarting; MakeAllStartingLocating(table); SyncTimeout(frame_rate, buffer_size); } else if (--fSyncTimeLeft == 0 || CheckAllRolling(table)) { // Slow clients may still catch up if (fNetworkSync) { - jack_log("transport starting ==> netstarting"); + jack_log("transport starting ==> netstarting frame = %d"); fTransportState = JackTransportNetStarting; } else { jack_log("transport starting ==> rolling fSyncTimeLeft = %ld", fSyncTimeLeft); diff --git a/common/JackTransportEngine.h b/common/JackTransportEngine.h index 9602516d..2adac8b1 100644 --- a/common/JackTransportEngine.h +++ b/common/JackTransportEngine.h @@ -193,7 +193,7 @@ class SERVER_EXPORT JackTransportEngine : public JackAtomicArrayState +#include +#include #else #include @@ -57,7 +58,7 @@ #include "shm.h" #include "JackError.h" -static int GetUID() +static int GetUID() { #ifdef WIN32 return _getpid(); @@ -67,7 +68,7 @@ static int GetUID() #endif } -static int GetPID() +static int GetPID() { #ifdef WIN32 return _getpid(); @@ -105,13 +106,13 @@ static jack_shm_id_t registry_id; /* SHM id for the registry */ #ifdef WIN32 static jack_shm_info_t registry_info = {/* SHM info for the registry */ - JACK_SHM_NULL_INDEX, + JACK_SHM_NULL_INDEX, NULL -}; +}; #else static jack_shm_info_t registry_info = { /* SHM info for the registry */ .index = JACK_SHM_NULL_INDEX, - .attached_at = MAP_FAILED + .ptr.attached_at = MAP_FAILED }; #endif @@ -142,7 +143,7 @@ static char jack_shm_server_prefix[JACK_SERVER_NAME_SIZE] = ""; static int semid = -1; -#ifdef WIN32 +#ifdef WIN32 static void semaphore_init () {} @@ -167,7 +168,7 @@ semaphore_init () struct sembuf sbuf; int create_flags = IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; - + /* Get semaphore ID associated with this key. */ if ((semid = semget(semkey, 0, 0)) == -1) { @@ -188,7 +189,7 @@ semaphore_init () } } else { - semaphore_error ("semget creation"); + semaphore_error ("semget creation"); } } } @@ -208,7 +209,7 @@ semaphore_add (int value) #endif -static void +static void jack_shm_lock_registry (void) { if (semid == -1) @@ -217,7 +218,7 @@ jack_shm_lock_registry (void) semaphore_add (-1); } -static void +static void jack_shm_unlock_registry (void) { semaphore_add (1); @@ -232,7 +233,7 @@ jack_shm_init_registry () memset (jack_shm_header, 0, JACK_SHM_REGISTRY_SIZE); jack_shm_header->magic = JACK_SHM_MAGIC; - //jack_shm_header->protocol = JACK_PROTOCOL_VERSION; + //jack_shm_header->protocol = JACK_PROTOCOL_VERSION; jack_shm_header->type = jack_shmtype; jack_shm_header->size = JACK_SHM_REGISTRY_SIZE; jack_shm_header->hdr_len = sizeof (jack_shm_header_t); @@ -249,7 +250,7 @@ jack_shm_validate_registry () /* registry must be locked */ if ((jack_shm_header->magic == JACK_SHM_MAGIC) - //&& (jack_shm_header->protocol == JACK_PROTOCOL_VERSION) + //&& (jack_shm_header->protocol == JACK_PROTOCOL_VERSION) && (jack_shm_header->type == jack_shmtype) && (jack_shm_header->size == JACK_SHM_REGISTRY_SIZE) && (jack_shm_header->hdr_len == sizeof (jack_shm_header_t)) @@ -281,7 +282,7 @@ static void jack_set_server_prefix (const char *server_name) { snprintf (jack_shm_server_prefix, sizeof (jack_shm_server_prefix), - "jack-%d:%s:", GetUID(), server_name); + "jack-%d:%s:", GetUID(), server_name); } /* gain server addressability to shared memory registration segment @@ -299,7 +300,7 @@ jack_server_initialize_shm (int new_registry) jack_shm_lock_registry (); rc = jack_access_registry (®istry_info); - + if (new_registry) { jack_remove_shm (®istry_id); rc = ENOENT; @@ -365,9 +366,9 @@ jack_initialize_shm (const char *server_name) } -char* jack_shm_addr (jack_shm_info_t* si) +char* jack_shm_addr (jack_shm_info_t* si) { - return (char*)si->attached_at; + return (char*)si->ptr.attached_at; } void @@ -393,7 +394,7 @@ jack_get_free_shm_info () break; } } - + if (i < MAX_SHM_ID) { si = &jack_shm_registry[i]; } @@ -422,7 +423,7 @@ jack_release_shm_info (jack_shm_registry_index_t index) } } -/* Claim server_name for this process. +/* Claim server_name for this process. * * returns 0 if successful * EEXIST if server_name was already active for this user @@ -485,7 +486,7 @@ jack_register_server (const char *server_name, int new_registry) strncpy (jack_shm_header->server[i].name, jack_shm_server_prefix, JACK_SERVER_NAME_SIZE); - + unlock: jack_shm_unlock_registry (); return 0; @@ -517,10 +518,10 @@ jack_cleanup_shm () jack_shm_info_t copy; jack_shm_lock_registry (); - + for (i = 0; i < MAX_SHM_ID; i++) { jack_shm_registry_t* r; - + r = &jack_shm_registry[i]; memcpy (©, r, sizeof (jack_shm_info_t)); destroy = FALSE; @@ -532,7 +533,7 @@ jack_cleanup_shm () /* is this my shm segment? */ if (r->allocator == GetPID()) { - /* allocated by this process, so unattach + /* allocated by this process, so unattach and destroy. */ jack_release_shm (©); destroy = TRUE; @@ -638,7 +639,7 @@ jack_access_registry (jack_shm_info_t *ri) return rc; } - if ((ri->attached_at = mmap (0, JACK_SHM_REGISTRY_SIZE, + if ((ri->ptr.attached_at = mmap (0, JACK_SHM_REGISTRY_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0)) == MAP_FAILED) { jack_error ("Cannot mmap shm registry segment (%s)", @@ -649,9 +650,9 @@ jack_access_registry (jack_shm_info_t *ri) /* set up global pointers */ ri->index = JACK_SHM_REGISTRY_INDEX; - jack_shm_header = ri->attached_at; + jack_shm_header = ri->ptr.attached_at; jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1); - + close (shm_fd); // steph return 0; } @@ -668,7 +669,7 @@ jack_create_registry (jack_shm_info_t *ri) { /* registry must be locked */ int shm_fd; - + strncpy (registry_id, "/jack-shm-registry", sizeof (registry_id)); if ((shm_fd = shm_open (registry_id, O_RDWR|O_CREAT, 0666)) < 0) { @@ -677,10 +678,10 @@ jack_create_registry (jack_shm_info_t *ri) strerror (errno)); return rc; } - + /* Previous shm_open result depends of the actual value of umask, force correct file permisssion here */ if (fchmod(shm_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) < 0) { - jack_log("Cannot chmod jack-shm-registry (%s) %d %d", strerror (errno)); + jack_log("Cannot chmod jack-shm-registry (%s) %d %d", strerror (errno)); } /* Set the desired segment size. NOTE: the non-conformant Mac @@ -694,7 +695,7 @@ jack_create_registry (jack_shm_info_t *ri) return rc; } - if ((ri->attached_at = mmap (0, JACK_SHM_REGISTRY_SIZE, + if ((ri->ptr.attached_at = mmap (0, JACK_SHM_REGISTRY_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0)) == MAP_FAILED) { jack_error ("Cannot mmap shm registry segment (%s)", @@ -706,7 +707,7 @@ jack_create_registry (jack_shm_info_t *ri) /* set up global pointers */ ri->index = JACK_SHM_REGISTRY_INDEX; - jack_shm_header = ri->attached_at; + jack_shm_header = ri->ptr.attached_at; jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1); /* initialize registry contents */ @@ -726,8 +727,8 @@ void jack_release_shm (jack_shm_info_t* si) { /* registry may or may not be locked */ - if (si->attached_at != MAP_FAILED) { - munmap (si->attached_at, jack_shm_registry[si->index].size); + if (si->ptr.attached_at != MAP_FAILED) { + munmap (si->ptr.attached_at, jack_shm_registry[si->index].size); } } @@ -781,7 +782,7 @@ jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* si) strncpy (registry->id, name, sizeof (registry->id)); registry->allocator = getpid(); si->index = registry->index; - si->attached_at = MAP_FAILED; /* not attached */ + si->ptr.attached_at = MAP_FAILED; /* not attached */ rc = 0; /* success */ unlock: @@ -802,9 +803,9 @@ jack_attach_shm (jack_shm_info_t* si) return -1; } - if ((si->attached_at = mmap (0, registry->size, PROT_READ|PROT_WRITE, + if ((si->ptr.attached_at = mmap (0, registry->size, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0)) == MAP_FAILED) { - jack_error ("Cannot mmap shm segment %s (%s)", + jack_error ("Cannot mmap shm segment %s (%s)", registry->id, strerror (errno)); close (shm_fd); @@ -828,9 +829,9 @@ jack_attach_shm_read (jack_shm_info_t* si) return -1; } - if ((si->attached_at = mmap (0, registry->size, PROT_READ, + if ((si->ptr.attached_at = mmap (0, registry->size, PROT_READ, MAP_SHARED, shm_fd, 0)) == MAP_FAILED) { - jack_error ("Cannot mmap shm segment %s (%s)", + jack_error ("Cannot mmap shm segment %s (%s)", registry->id, strerror (errno)); close (shm_fd); @@ -848,12 +849,10 @@ jack_access_registry (jack_shm_info_t *ri) { /* registry must be locked */ HANDLE shm_fd; - LPSECURITY_ATTRIBUTES sec = 0; - strncpy (registry_id, "jack-shm-registry", sizeof (registry_id)); /* try to open an existing segment */ - + if ((shm_fd = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, registry_id)) == NULL) { int rc = GetLastError(); if (rc != ERROR_FILE_NOT_FOUND) { @@ -862,7 +861,7 @@ jack_access_registry (jack_shm_info_t *ri) return rc; } - if ((ri->attached_at = MapViewOfFile (shm_fd, FILE_MAP_ALL_ACCESS, 0, 0, JACK_SHM_REGISTRY_SIZE)) == NULL) { + if ((ri->ptr.attached_at = MapViewOfFile (shm_fd, FILE_MAP_ALL_ACCESS, 0, 0, JACK_SHM_REGISTRY_SIZE)) == NULL) { jack_error ("Cannot mmap shm registry segment (%ld)", GetLastError()); jack_remove_shm (®istry_id); CloseHandle (shm_fd); @@ -871,7 +870,7 @@ jack_access_registry (jack_shm_info_t *ri) /* set up global pointers */ ri->index = JACK_SHM_REGISTRY_INDEX; - jack_shm_header = ri->attached_at; + jack_shm_header = ri->ptr.attached_at; jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1); //CloseHandle(shm_fd); // TO CHECK @@ -886,16 +885,16 @@ jack_create_registry (jack_shm_info_t *ri) strncpy (registry_id, "jack-shm-registry", sizeof (registry_id)); - if ((shm_fd = CreateFileMapping(INVALID_HANDLE_VALUE, - 0, PAGE_READWRITE, - 0, JACK_SHM_REGISTRY_SIZE, + if ((shm_fd = CreateFileMapping(INVALID_HANDLE_VALUE, + 0, PAGE_READWRITE, + 0, JACK_SHM_REGISTRY_SIZE, registry_id)) == NULL || (shm_fd == INVALID_HANDLE_VALUE)) { int rc = GetLastError(); jack_error ("Cannot create shm registry segment (%ld)", rc); return rc; } - if ((ri->attached_at = MapViewOfFile (shm_fd, FILE_MAP_ALL_ACCESS, 0, 0, JACK_SHM_REGISTRY_SIZE)) == NULL) { + if ((ri->ptr.attached_at = MapViewOfFile (shm_fd, FILE_MAP_ALL_ACCESS, 0, 0, JACK_SHM_REGISTRY_SIZE)) == NULL) { jack_error ("Cannot mmap shm registry segment (%ld)", GetLastError()); jack_remove_shm (®istry_id); CloseHandle (shm_fd); @@ -904,7 +903,7 @@ jack_create_registry (jack_shm_info_t *ri) /* set up global pointers */ ri->index = JACK_SHM_REGISTRY_INDEX; - jack_shm_header = ri->attached_at; + jack_shm_header = ri->ptr.attached_at; jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1); /* initialize registry contents */ @@ -924,8 +923,8 @@ void jack_release_shm (jack_shm_info_t* si) { /* registry may or may not be locked */ - if (si->attached_at != NULL) { - UnmapViewOfFile (si->attached_at); + if (si->ptr.attached_at != NULL) { + UnmapViewOfFile (si->ptr.attached_at); } } @@ -951,9 +950,9 @@ jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* si) goto unlock; } - if ((shm_fd = CreateFileMapping(INVALID_HANDLE_VALUE, - 0, PAGE_READWRITE, - 0, size, + if ((shm_fd = CreateFileMapping(INVALID_HANDLE_VALUE, + 0, PAGE_READWRITE, + 0, size, name)) == NULL || (shm_fd == INVALID_HANDLE_VALUE)) { int rc = GetLastError(); jack_error ("Cannot create shm segment (%ld)",rc); @@ -966,7 +965,7 @@ jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* si) strncpy (registry->id, name, sizeof (registry->id)); registry->allocator = _getpid(); si->index = registry->index; - si->attached_at = NULL; /* not attached */ + si->ptr.attached_at = NULL; /* not attached */ rc = 0; /* success */ unlock: @@ -986,7 +985,7 @@ jack_attach_shm (jack_shm_info_t* si) return -1; } - if ((si->attached_at = MapViewOfFile (shm_fd, FILE_MAP_ALL_ACCESS, 0, 0, registry->size)) == NULL) { + if ((si->ptr.attached_at = MapViewOfFile (shm_fd, FILE_MAP_ALL_ACCESS, 0, 0, registry->size)) == NULL) { jack_error ("Cannot mmap shm segment (%ld)", GetLastError()); jack_remove_shm (®istry_id); CloseHandle (shm_fd); @@ -1009,10 +1008,10 @@ jack_attach_shm_read (jack_shm_info_t* si) return -1; } - if ((si->attached_at = MapViewOfFile (shm_fd, FILE_MAP_READ, 0, 0, registry->size)) == NULL) { - jack_error ("Cannot mmap shm segment (%ld)", GetLastError()); - jack_remove_shm (®istry_id); - CloseHandle (shm_fd); + if ((si->ptr.attached_at = MapViewOfFile (shm_fd, FILE_MAP_READ, 0, 0, registry->size)) == NULL) { + jack_error("Cannot mmap shm segment (%ld)", GetLastError()); + jack_remove_shm(®istry_id); + CloseHandle(shm_fd); return -1; } @@ -1127,7 +1126,7 @@ jack_release_shm (jack_shm_info_t* si) int jack_shmalloc (const char* name_not_used, jack_shmsize_t size, - jack_shm_info_t* si) + jack_shm_info_t* si) { int shmflags; int shmid; diff --git a/common/shm.h b/common/shm.h index a3d9f34f..4a7d15c6 100644 --- a/common/shm.h +++ b/common/shm.h @@ -35,15 +35,15 @@ extern "C" #ifndef SHM_NAME_MAX #define SHM_NAME_MAX NAME_MAX #endif - typedef char shm_name_t[SHM_NAME_MAX]; + typedef char shm_name_t[SHM_NAME_MAX]; typedef shm_name_t jack_shm_id_t; -#elif WIN32 // steph TO CHECK +#elif WIN32 // TO CHECK #define NAME_MAX 255 #ifndef SHM_NAME_MAX #define SHM_NAME_MAX NAME_MAX #endif - typedef char shm_name_t[SHM_NAME_MAX]; + typedef char shm_name_t[SHM_NAME_MAX]; typedef shm_name_t jack_shm_id_t; #else @@ -73,7 +73,6 @@ extern "C" #ifdef WIN32 int pid; /* process ID */ #else - pid_t pid; /* process ID */ #endif @@ -96,10 +95,8 @@ extern "C" jack_shm_registry_index_t index; /* offset into the registry */ #ifdef WIN32 - int allocator; /* PID that created shm segment */ #else - pid_t allocator; /* PID that created shm segment */ #endif @@ -118,12 +115,16 @@ extern "C" * indicating where the shared memory has been * attached to the address space. */ + typedef struct _jack_shm_info { jack_shm_registry_index_t index; /* offset into the registry */ - size_t size; - void *attached_at; /* address where attached */ + uint32_t size; + union { + void *attached_at; /* address where attached */ + char ptr_size[8]; + } ptr; /* a "pointer" that has the same 8 bytes size when compling in 32 or 64 bits */ } - jack_shm_info_t; + POST_PACKED_STRUCTURE jack_shm_info_t; /* utility functions used only within JACK */ @@ -132,15 +133,15 @@ extern "C" void jack_shm_copy_to_registry (jack_shm_info_t*, jack_shm_registry_index_t*); void jack_release_shm_info (jack_shm_registry_index_t); - char* jack_shm_addr (jack_shm_info_t* si); // steph + char* jack_shm_addr (jack_shm_info_t* si); // here begin the API int jack_register_server (const char *server_name, int new_registry); void jack_unregister_server (const char *server_name); int jack_initialize_shm (const char *server_name); - int jack_initialize_shm_server (void); // steph - int jack_initialize_shm_client (void); // steph + int jack_initialize_shm_server (void); + int jack_initialize_shm_client (void); int jack_cleanup_shm (void); int jack_shmalloc (const char *shm_name, jack_shmsize_t size, @@ -148,7 +149,7 @@ extern "C" void jack_release_shm (jack_shm_info_t*); void jack_destroy_shm (jack_shm_info_t*); int jack_attach_shm (jack_shm_info_t*); - int jack_attach_shm_read (jack_shm_info_t*); // steph + int jack_attach_shm_read (jack_shm_info_t*); int jack_resize_shm (jack_shm_info_t*, jack_shmsize_t size); #ifdef __cplusplus diff --git a/example-clients/impulse_grabber.c b/example-clients/impulse_grabber.c index cb36da85..0a1fd706 100644 --- a/example-clients/impulse_grabber.c +++ b/example-clients/impulse_grabber.c @@ -95,7 +95,7 @@ main (int argc, char *argv[]) int c; extern int optind, opterr; int show_usage = 0; - char *optstring = "d:f"; + char *optstring = "d:f:h"; struct option long_options[] = { { "help", 1, 0, 'h' }, { "duration", 1, 0, 'd' }, diff --git a/example-clients/wscript b/example-clients/wscript index 1a5dcd69..c8310d41 100644 --- a/example-clients/wscript +++ b/example-clients/wscript @@ -107,6 +107,8 @@ def build(bld): prog.uselib = 'SNDFILE' if bld.env['IS_LINUX']: prog.uselib = 'RT SNDFILE' + if bld.env['IS_SUN']: + prog.uselib = 'RT SNDFILE' prog.uselib_local = 'clientlib' prog.target = 'jack_rec' diff --git a/posix/JackCompilerDeps_os.h b/posix/JackCompilerDeps_os.h index d7d10992..767674e1 100644 --- a/posix/JackCompilerDeps_os.h +++ b/posix/JackCompilerDeps_os.h @@ -20,23 +20,42 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifndef __JackCompilerDeps_POSIX__ #define __JackCompilerDeps_POSIX__ +#include "JackConstants.h" + #if __GNUC__ + #ifndef POST_PACKED_STRUCTURE + /* POST_PACKED_STRUCTURE needs to be a macro which + expands into a compiler directive. The directive must + tell the compiler to arrange the preceding structure + declaration so that it is packed on byte-boundaries rather + than use the natural alignment of the processor and/or + compiler. + */ + #if (__GNUC__< 4) /* Does not seem to work with GCC 3.XX serie */ + #define POST_PACKED_STRUCTURE + #elif defined(JACK_32_64) + #define POST_PACKED_STRUCTURE __attribute__((__packed__)) + #else + #define POST_PACKED_STRUCTURE + #endif + #endif #define MEM_ALIGN(x,y) x __attribute__((aligned(y))) #define EXPORT __attribute__((visibility("default"))) #ifdef SERVER_SIDE #if (__GNUC__< 4) - #define SERVER_EXPORT + #define SERVER_EXPORT #else #define SERVER_EXPORT __attribute__((visibility("default"))) - #endif + #endif #else #define SERVER_EXPORT #endif -#else +#else #define MEM_ALIGN(x,y) x #define EXPORT #define SERVER_EXPORT + /* Add other things here for non-gcc platforms for POST_PACKED_STRUCTURE */ #endif - + #endif diff --git a/posix/JackSocket.h b/posix/JackSocket.h index 0382bd84..01e49539 100644 --- a/posix/JackSocket.h +++ b/posix/JackSocket.h @@ -20,8 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __JackSocket__ #define __JackSocket__ -#include #include +#include #include #include #include diff --git a/posix/JackSystemDeps_os.h b/posix/JackSystemDeps_os.h index dae9f6fd..cbddb0b1 100644 --- a/posix/JackSystemDeps_os.h +++ b/posix/JackSystemDeps_os.h @@ -28,7 +28,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #define DRIVER_HANDLE void* #define LoadDriverModule(name) dlopen((name), RTLD_NOW | RTLD_GLOBAL) #define UnloadDriverModule(handle) dlclose((handle)) -#define GetProc(handle, name) dlsym((handle), (name)) +#define GetDriverProc(handle, name) dlsym((handle), (name)) + +#define JACK_HANDLE void* +#define LoadJackModule(name) dlopen((name), RTLD_NOW | RTLD_LOCAL); +#define UnloadJackModule(handle) dlclose((handle)); +#define GetJackProc(handle, name) dlsym((handle), (name)); #define JACK_DEBUG (getenv("JACK_CLIENT_DEBUG") && strcmp(getenv("JACK_CLIENT_DEBUG"), "on") == 0) diff --git a/solaris/oss/JackBoomerDriver.cpp b/solaris/oss/JackBoomerDriver.cpp new file mode 100644 index 00000000..3080dcde --- /dev/null +++ b/solaris/oss/JackBoomerDriver.cpp @@ -0,0 +1,1001 @@ +/* +Copyright (C) 2009 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. + +*/ + +#include "driver_interface.h" +#include "JackThreadedDriver.h" +#include "JackDriverLoader.h" +#include "JackBoomerDriver.h" +#include "JackEngineControl.h" +#include "JackGraphManager.h" +#include "JackError.h" +#include "JackTime.h" +#include "JackShmMem.h" +#include "JackGlobals.h" +#include "memops.h" + +#include +#include +#include +#include +#include +#include + +using namespace std; + +namespace Jack +{ + +#ifdef JACK_MONITOR + +#define CYCLE_POINTS 500000 + +struct OSSCycle { + jack_time_t fBeforeRead; + jack_time_t fAfterRead; + jack_time_t fAfterReadConvert; + jack_time_t fBeforeWrite; + jack_time_t fAfterWrite; + jack_time_t fBeforeWriteConvert; +}; + +struct OSSCycleTable { + jack_time_t fBeforeFirstWrite; + jack_time_t fAfterFirstWrite; + OSSCycle fTable[CYCLE_POINTS]; +}; + +OSSCycleTable gCycleTable; +int gCycleCount = 0; + +#endif + +inline int int2pow2(int x) { int r = 0; while ((1 << r) < x) r++; return r; } + +static inline void CopyAndConvertIn(jack_sample_t *dst, void *src, size_t nframes, int channel, int chcount, int bits) +{ + switch (bits) { + + case 16: { + signed short *s16src = (signed short*)src; + s16src += channel; + sample_move_dS_s16(dst, (char*)s16src, nframes, chcount<<1); + break; + } + case 24: { + signed short *s32src = (signed short*)src; + s32src += channel; + sample_move_dS_s24(dst, (char*)s32src, nframes, chcount<<2); + break; + } + case 32: { + signed short *s32src = (signed short*)src; + s32src += channel; + sample_move_dS_s32u24(dst, (char*)s32src, nframes, chcount<<2); + break; + } + } +} + +static inline void CopyAndConvertOut(void *dst, jack_sample_t *src, size_t nframes, int channel, int chcount, int bits) +{ + switch (bits) { + + case 16: { + signed short *s16dst = (signed short*)dst; + s16dst += channel; + sample_move_d16_sS((char*)s16dst, src, nframes, chcount<<1, NULL); // No dithering for now... + break; + } + case 24: { + signed int *s32dst = (signed int*)dst; + s32dst += channel; + sample_move_d24_sS((char*)s32dst, src, nframes, chcount<<2, NULL); // No dithering for now... + break; + } + case 32: { + signed int *s32dst = (signed int*)dst; + s32dst += channel; + sample_move_d32u24_sS((char*)s32dst, src, nframes, chcount<<2, NULL); + break; + } + } +} + +void JackBoomerDriver::SetSampleFormat() +{ + switch (fBits) { + + case 24: /* native-endian LSB aligned 24-bits in 32-bits integer */ + fSampleFormat = AFMT_S24_NE; + fSampleSize = sizeof(int); + break; + case 32: /* native-endian 32-bit integer */ + fSampleFormat = AFMT_S32_NE; + fSampleSize = sizeof(int); + break; + case 16: /* native-endian 16-bit integer */ + default: + fSampleFormat = AFMT_S16_NE; + fSampleSize = sizeof(short); + break; + } +} + +void JackBoomerDriver::DisplayDeviceInfo() +{ + audio_buf_info info; + oss_audioinfo ai_in, ai_out; + memset(&info, 0, sizeof(audio_buf_info)); + int cap = 0; + + // Duplex cards : http://manuals.opensound.com/developer/full_duplex.html + jack_info("Audio Interface Description :"); + jack_info("Sampling Frequency : %d, Sample Format : %d, Mode : %d", fEngineControl->fSampleRate, fSampleFormat, fRWMode); + + if (fRWMode & kWrite) { + + oss_sysinfo si; + if (ioctl(fOutFD, OSS_SYSINFO, &si) == -1) { + jack_error("JackBoomerDriver::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); + } else { + jack_info("OSS product %s", si.product); + jack_info("OSS version %s", si.version); + jack_info("OSS version num %d", si.versionnum); + jack_info("OSS numaudios %d", si.numaudios); + jack_info("OSS numaudioengines %d", si.numaudioengines); + jack_info("OSS numcards %d", si.numcards); + } + + jack_info("Output capabilities - %d channels : ", fPlaybackChannels); + jack_info("Output block size = %d", fOutputBufferSize); + + if (ioctl(fOutFD, SNDCTL_DSP_GETOSPACE, &info) == -1) { + jack_error("JackBoomerDriver::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); + } else { + jack_info("output space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", + info.fragments, info.fragstotal, info.fragsize, info.bytes); + } + + if (ioctl(fOutFD, SNDCTL_DSP_GETCAPS, &cap) == -1) { + jack_error("JackBoomerDriver::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); + } else { + if (cap & DSP_CAP_DUPLEX) jack_info(" DSP_CAP_DUPLEX"); + if (cap & DSP_CAP_REALTIME) jack_info(" DSP_CAP_REALTIME"); + if (cap & DSP_CAP_BATCH) jack_info(" DSP_CAP_BATCH"); + if (cap & DSP_CAP_COPROC) jack_info(" DSP_CAP_COPROC"); + if (cap & DSP_CAP_TRIGGER) jack_info(" DSP_CAP_TRIGGER"); + if (cap & DSP_CAP_MMAP) jack_info(" DSP_CAP_MMAP"); + if (cap & DSP_CAP_MULTI) jack_info(" DSP_CAP_MULTI"); + if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); + } + } + + if (fRWMode & kRead) { + + oss_sysinfo si; + if (ioctl(fInFD, OSS_SYSINFO, &si) == -1) { + jack_error("JackBoomerDriver::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); + } else { + jack_info("OSS product %s", si.product); + jack_info("OSS version %s", si.version); + jack_info("OSS version num %d", si.versionnum); + jack_info("OSS numaudios %d", si.numaudios); + jack_info("OSS numaudioengines %d", si.numaudioengines); + jack_info("OSS numcards %d", si.numcards); + } + + jack_info("Input capabilities - %d channels : ", fCaptureChannels); + jack_info("Input block size = %d", fInputBufferSize); + + if (ioctl(fInFD, SNDCTL_DSP_GETISPACE, &info) == -1) { + jack_error("JackBoomerDriver::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); + } else { + jack_info("input space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", + info.fragments, info.fragstotal, info.fragsize, info.bytes); + } + + if (ioctl(fInFD, SNDCTL_DSP_GETCAPS, &cap) == -1) { + jack_error("JackBoomerDriver::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); + } else { + if (cap & DSP_CAP_DUPLEX) jack_info(" DSP_CAP_DUPLEX"); + if (cap & DSP_CAP_REALTIME) jack_info(" DSP_CAP_REALTIME"); + if (cap & DSP_CAP_BATCH) jack_info(" DSP_CAP_BATCH"); + if (cap & DSP_CAP_COPROC) jack_info(" DSP_CAP_COPROC"); + if (cap & DSP_CAP_TRIGGER) jack_info(" DSP_CAP_TRIGGER"); + if (cap & DSP_CAP_MMAP) jack_info(" DSP_CAP_MMAP"); + if (cap & DSP_CAP_MULTI) jack_info(" DSP_CAP_MULTI"); + if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); + } + } + + if (ai_in.rate_source != ai_out.rate_source) { + jack_info("Warning : input and output are not necessarily driven by the same clock!"); + } +} + +int JackBoomerDriver::OpenInput() +{ + int flags = 0; + int gFragFormat; + int cur_capture_channels; + int cur_sample_format; + jack_nframes_t cur_sample_rate; + + if (fCaptureChannels == 0) fCaptureChannels = 2; + + if ((fInFD = open(fCaptureDriverName, O_RDONLY | ((fExcl) ? O_EXCL : 0))) < 0) { + jack_error("JackBoomerDriver::OpenInput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); + return -1; + } + + jack_log("JackBoomerDriver::OpenInput input fInFD = %d", fInFD); + + if (fExcl) { + if (ioctl(fInFD, SNDCTL_DSP_COOKEDMODE, &flags) == -1) { + jack_error("JackBoomerDriver::OpenInput failed to set cooked mode : %s@%i, errno = %d", __FILE__, __LINE__, errno); + goto error; + } + } + + gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fCaptureChannels); + if (ioctl(fInFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { + jack_error("JackBoomerDriver::OpenInput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); + goto error; + } + + cur_sample_format = fSampleFormat; + if (ioctl(fInFD, SNDCTL_DSP_SETFMT, &fSampleFormat) == -1) { + jack_error("JackBoomerDriver::OpenInput failed to set format : %s@%i, errno = %d", __FILE__, __LINE__, errno); + goto error; + } + if (cur_sample_format != fSampleFormat) { + jack_info("JackBoomerDriver::OpenInput driver forced the sample format %ld", fSampleFormat); + } + + cur_capture_channels = fCaptureChannels; + if (ioctl(fInFD, SNDCTL_DSP_CHANNELS, &fCaptureChannels) == -1) { + jack_error("JackBoomerDriver::OpenInput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); + goto error; + } + if (cur_capture_channels != fCaptureChannels) { + jack_info("JackBoomerDriver::OpenInput driver forced the number of capture channels %ld", fCaptureChannels); + } + + cur_sample_rate = fEngineControl->fSampleRate; + if (ioctl(fInFD, SNDCTL_DSP_SPEED, &fEngineControl->fSampleRate) == -1) { + jack_error("JackBoomerDriver::OpenInput failed to set sample rate : %s@%i, errno = %d", __FILE__, __LINE__, errno); + goto error; + } + if (cur_sample_rate != fEngineControl->fSampleRate) { + jack_info("JackBoomerDriver::OpenInput driver forced the sample rate %ld", fEngineControl->fSampleRate); + } + + // Just set the read size to the value we want... + fInputBufferSize = fEngineControl->fBufferSize * fSampleSize * fCaptureChannels; + + fInputBuffer = (void*)calloc(fInputBufferSize, 1); + assert(fInputBuffer); + return 0; + +error: + ::close(fInFD); + return -1; +} + +int JackBoomerDriver::OpenOutput() +{ + int flags = 0; + int gFragFormat; + int cur_sample_format; + int cur_playback_channels; + jack_nframes_t cur_sample_rate; + + if (fPlaybackChannels == 0) fPlaybackChannels = 2; + + if ((fOutFD = open(fPlaybackDriverName, O_WRONLY | ((fExcl) ? O_EXCL : 0))) < 0) { + jack_error("JackBoomerDriver::OpenOutput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); + return -1; + } + + jack_log("JackBoomerDriver::OpenOutput output fOutFD = %d", fOutFD); + + if (fExcl) { + if (ioctl(fOutFD, SNDCTL_DSP_COOKEDMODE, &flags) == -1) { + jack_error("JackBoomerDriver::OpenOutput failed to set cooked mode : %s@%i, errno = %d", __FILE__, __LINE__, errno); + goto error; + } + } + + gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels); + if (ioctl(fOutFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { + jack_error("JackBoomerDriver::OpenOutput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); + goto error; + } + + cur_sample_format = fSampleFormat; + if (ioctl(fOutFD, SNDCTL_DSP_SETFMT, &fSampleFormat) == -1) { + jack_error("JackBoomerDriver::OpenOutput failed to set format : %s@%i, errno = %d", __FILE__, __LINE__, errno); + goto error; + } + if (cur_sample_format != fSampleFormat) { + jack_info("JackBoomerDriver::OpenOutput driver forced the sample format %ld", fSampleFormat); + } + + cur_playback_channels = fPlaybackChannels; + if (ioctl(fOutFD, SNDCTL_DSP_CHANNELS, &fPlaybackChannels) == -1) { + jack_error("JackBoomerDriver::OpenOutput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); + goto error; + } + if (cur_playback_channels != fPlaybackChannels) { + jack_info("JackBoomerDriver::OpenOutput driver forced the number of playback channels %ld", fPlaybackChannels); + } + + cur_sample_rate = fEngineControl->fSampleRate; + if (ioctl(fOutFD, SNDCTL_DSP_SPEED, &fEngineControl->fSampleRate) == -1) { + jack_error("JackBoomerDriver::OpenOutput failed to set sample rate : %s@%i, errno = %d", __FILE__, __LINE__, errno); + goto error; + } + if (cur_sample_rate != fEngineControl->fSampleRate) { + jack_info("JackBoomerDriver::OpenInput driver forced the sample rate %ld", fEngineControl->fSampleRate); + } + + // Just set the write size to the value we want... + fOutputBufferSize = fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels; + + fOutputBuffer = (void*)calloc(fOutputBufferSize, 1); + assert(fOutputBuffer); + return 0; + +error: + ::close(fOutFD); + return -1; +} + +int JackBoomerDriver::Open(jack_nframes_t nframes, + int user_nperiods, + jack_nframes_t samplerate, + bool capturing, + bool playing, + int inchannels, + int outchannels, + bool excl, + bool monitor, + const char* capture_driver_uid, + const char* playback_driver_uid, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency, + int bits, + bool ignorehwbuf) +{ + + if (playing && !capturing) { + jack_error("Playback only mode is not yet supported, use duplex instead"); + return -1; + } + + // Generic JackAudioDriver Open + if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, + capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) { + return -1; + } else { + + if (fEngineControl->fSyncMode) { + jack_error("Cannot run in synchronous mode, remove the -S parameter for jackd"); + return -1; + } + + fRWMode |= ((capturing) ? kRead : 0); + fRWMode |= ((playing) ? kWrite : 0); + fBits = bits; + fIgnoreHW = ignorehwbuf; + fNperiods = user_nperiods; + fExcl = excl; + + #ifdef JACK_MONITOR + // Force memory page in + memset(&gCycleTable, 0, sizeof(gCycleTable)); + #endif + + if (OpenAux() < 0) { + Close(); + return -1; + } else { + return 0; + } + } +} + +int JackBoomerDriver::Close() +{ + #ifdef JACK_MONITOR + FILE* file = fopen("OSSProfiling.log", "w"); + + if (file) { + jack_info("Writing OSS driver timing data...."); + for (int i = 1; i < gCycleCount; i++) { + int d1 = gCycleTable.fTable[i].fAfterRead - gCycleTable.fTable[i].fBeforeRead; + int d2 = gCycleTable.fTable[i].fAfterReadConvert - gCycleTable.fTable[i].fAfterRead; + int d3 = gCycleTable.fTable[i].fAfterWrite - gCycleTable.fTable[i].fBeforeWrite; + int d4 = gCycleTable.fTable[i].fBeforeWrite - gCycleTable.fTable[i].fBeforeWriteConvert; + fprintf(file, "%d \t %d \t %d \t %d \t \n", d1, d2, d3, d4); + } + fclose(file); + } else { + jack_error("JackBoomerDriver::Close : cannot open OSSProfiling.log file"); + } + + file = fopen("TimingOSS.plot", "w"); + + if (file == NULL) { + jack_error("JackBoomerDriver::Close cannot open TimingOSS.plot file"); + } else { + + fprintf(file, "set grid\n"); + fprintf(file, "set title \"OSS audio driver timing\"\n"); + fprintf(file, "set xlabel \"audio cycles\"\n"); + fprintf(file, "set ylabel \"usec\"\n"); + fprintf(file, "plot \"OSSProfiling.log\" using 1 title \"Driver read wait\" with lines, \ + \"OSSProfiling.log\" using 2 title \"Driver read convert duration\" with lines, \ + \"OSSProfiling.log\" using 3 title \"Driver write wait\" with lines, \ + \"OSSProfiling.log\" using 4 title \"Driver write convert duration\" with lines\n"); + + fprintf(file, "set output 'TimingOSS.pdf\n"); + fprintf(file, "set terminal pdf\n"); + + fprintf(file, "set grid\n"); + fprintf(file, "set title \"OSS audio driver timing\"\n"); + fprintf(file, "set xlabel \"audio cycles\"\n"); + fprintf(file, "set ylabel \"usec\"\n"); + fprintf(file, "plot \"OSSProfiling.log\" using 1 title \"Driver read wait\" with lines, \ + \"OSSProfiling.log\" using 2 title \"Driver read convert duration\" with lines, \ + \"OSSProfiling.log\" using 3 title \"Driver write wait\" with lines, \ + \"OSSProfiling.log\" using 4 title \"Driver write convert duration\" with lines\n"); + + fclose(file); + } + #endif + int res = JackAudioDriver::Close(); + CloseAux(); + return res; +} + +int JackBoomerDriver::OpenAux() +{ + SetSampleFormat(); + + if ((fRWMode & kRead) && (OpenInput() < 0)) { + return -1; + } + + if ((fRWMode & kWrite) && (OpenOutput() < 0)) { + return -1; + } + + // Prepare ringbuffers used for output + if (fPlaybackChannels > 0) { + fRingBuffer = new jack_ringbuffer_t*[fPlaybackChannels]; + for (int i = 0; i < fPlaybackChannels; i++) { + fRingBuffer[i] = jack_ringbuffer_create(fOutputBufferSize * 2); + jack_ringbuffer_read_advance(fRingBuffer[i], fOutputBufferSize); + } + } + + DisplayDeviceInfo(); + return 0; +} + +void JackBoomerDriver::CloseAux() +{ + if (fRWMode & kRead && fInFD > 0) { + close(fInFD); + fInFD = -1; + } + + if (fRWMode & kWrite && fOutFD > 0) { + close(fOutFD); + fOutFD = -1; + } + + if (fInputBuffer) + free(fInputBuffer); + fInputBuffer = NULL; + + if (fOutputBuffer) + free(fOutputBuffer); + fOutputBuffer = NULL; + + for (int i = 0; i < fPlaybackChannels; i++) { + if (fRingBuffer[i]) + jack_ringbuffer_free(fRingBuffer[i]); + fRingBuffer[i] = NULL; + } + + delete [] fRingBuffer; + fRingBuffer = NULL; +} + +int JackBoomerDriver::Start() +{ + jack_log("JackBoomerDriver::Start"); + + // Start output thread only when needed + if (fOutFD > 0) { + if (fThread.StartSync() < 0) { + jack_error("Cannot start thread"); + return -1; + } + } + + return 0; +} + +int JackBoomerDriver::Stop() +{ + // Stop output thread only when needed + if (fOutFD > 0) { + return fThread.Kill(); + } else { + return 0; + } +} + +int JackBoomerDriver::Read() +{ + if (fInFD < 0) { + // Keep begin cycle time + JackDriver::CycleTakeBeginTime(); + return 0; + } + +#ifdef JACK_MONITOR + gCycleTable.fTable[gCycleCount].fBeforeRead = GetMicroSeconds(); +#endif + + audio_errinfo ei_in; + ssize_t count = ::read(fInFD, fInputBuffer, fInputBufferSize); + +#ifdef JACK_MONITOR + if (count > 0 && count != (int)fInputBufferSize) + jack_log("JackBoomerDriver::Read count = %ld", count / (fSampleSize * fCaptureChannels)); + gCycleTable.fTable[gCycleCount].fAfterRead = GetMicroSeconds(); +#endif + + // XRun detection + if (ioctl(fInFD, SNDCTL_DSP_GETERROR, &ei_in) == 0) { + + if (ei_in.rec_overruns > 0 ) { + jack_error("JackBoomerDriver::Read overruns"); + jack_time_t cur_time = GetMicroSeconds(); + NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... + } + + if (ei_in.rec_errorcount > 0 && ei_in.rec_lasterror != 0) { + jack_error("%d OSS rec event(s), last=%05d:%d", ei_in.rec_errorcount, ei_in.rec_lasterror, ei_in.rec_errorparm); + } + } + + if (count < 0) { + jack_log("JackBoomerDriver::Read error = %s", strerror(errno)); + return -1; + } else if (count < (int)fInputBufferSize) { + jack_error("JackBoomerDriver::Read error bytes read = %ld", count); + return -1; + } else { + + // Keep begin cycle time + JackDriver::CycleTakeBeginTime(); + for (int i = 0; i < fCaptureChannels; i++) { + if (fGraphManager->GetConnectionsNum(fCapturePortList[i]) > 0) { + CopyAndConvertIn(GetInputBuffer(i), fInputBuffer, fEngineControl->fBufferSize, i, fCaptureChannels, fBits); + } + } + + #ifdef JACK_MONITOR + gCycleTable.fTable[gCycleCount].fAfterReadConvert = GetMicroSeconds(); + #endif + + return 0; + } +} + +int JackBoomerDriver::Write() +{ + for (int i = 0; i < fPlaybackChannels; i++) { + if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) { + if (jack_ringbuffer_write(fRingBuffer[i], (char*)GetOutputBuffer(i), fOutputBufferSize) < fOutputBufferSize) { + jack_log("JackBoomerDriver::Write ringbuffer full"); + } + } + } + + return 0; +} + +bool JackBoomerDriver::Init() +{ + if (IsRealTime()) { + jack_log("JackBoomerDriver::Init IsRealTime"); + if (fThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { + jack_error("AcquireRealTime error"); + } else { + set_threaded_log_function(); + } + } + + // Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html + memset(fOutputBuffer, 0, fOutputBufferSize); + + // Prefill ouput buffer + if (fOutFD > 0) { + for (int i = 0; i < fNperiods; i++) { + ssize_t count = ::write(fOutFD, fOutputBuffer, fOutputBufferSize); + if (count < (int)fOutputBufferSize) { + jack_error("JackBoomerDriver::Write error bytes written = %ld", count); + } + } + + int delay; + if (ioctl(fOutFD, SNDCTL_DSP_GETODELAY, &delay) == -1) { + jack_error("JackBoomerDriver::Write error get out delay : %s@%i, errno = %d", __FILE__, __LINE__, errno); + } + + delay /= fSampleSize * fPlaybackChannels; + jack_info("JackBoomerDriver::Write output latency frames = %ld", delay); + } + + return true; +} + +bool JackBoomerDriver::Execute() +{ + memset(fOutputBuffer, 0, fOutputBufferSize); + + for (int i = 0; i < fPlaybackChannels; i++) { + if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) { + + jack_ringbuffer_data_t ring_buffer_data[2]; + jack_ringbuffer_get_read_vector(fRingBuffer[i], ring_buffer_data); + + unsigned int available_frames = (ring_buffer_data[0].len + ring_buffer_data[1].len) / sizeof(float); + jack_log("Output available = %ld", available_frames); + + unsigned int needed_bytes = fOutputBufferSize; + float* output = (float*)fOutputBuffer; + + for (int j = 0; j < 2; j++) { + unsigned int consumed_bytes = std::min(needed_bytes, ring_buffer_data[j].len); + CopyAndConvertOut(output, (float*)ring_buffer_data[j].buf, consumed_bytes / sizeof(float), i, fPlaybackChannels, fBits); + output += consumed_bytes / sizeof(float); + needed_bytes -= consumed_bytes; + } + + if (needed_bytes > 0) { + jack_error("JackBoomerDriver::Execute missing frames = %ld", needed_bytes / sizeof(float)); + } + + jack_ringbuffer_read_advance(fRingBuffer[i], fOutputBufferSize - needed_bytes); + } + } + +#ifdef JACK_MONITOR + gCycleTable.fTable[gCycleCount].fBeforeWrite = GetMicroSeconds(); +#endif + + // Keep end cycle time + JackDriver::CycleTakeEndTime(); + ssize_t count = ::write(fOutFD, fOutputBuffer, fOutputBufferSize); + +#ifdef JACK_MONITOR + if (count > 0 && count != (int)fOutputBufferSize) + jack_log("JackBoomerDriver::Execute count = %ld", count / (fSampleSize * fPlaybackChannels)); + gCycleTable.fTable[gCycleCount].fAfterWrite = GetMicroSeconds(); + gCycleCount = (gCycleCount == CYCLE_POINTS - 1) ? gCycleCount: gCycleCount + 1; +#endif + + // XRun detection + audio_errinfo ei_out; + if (ioctl(fOutFD, SNDCTL_DSP_GETERROR, &ei_out) == 0) { + + if (ei_out.play_underruns > 0) { + jack_error("JackBoomerDriver::Execute underruns"); + jack_time_t cur_time = GetMicroSeconds(); + NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... + } + + if (ei_out.play_errorcount > 0 && ei_out.play_lasterror != 0) { + jack_error("%d OSS play event(s), last=%05d:%d",ei_out.play_errorcount, ei_out.play_lasterror, ei_out.play_errorparm); + } + } + + if (count < 0) { + jack_log("JackBoomerDriver::Execute error = %s", strerror(errno)); + } else if (count < (int)fOutputBufferSize) { + jack_error("JackBoomerDriver::Execute error bytes written = %ld", count); + } + + return true; +} + +int JackBoomerDriver::SetBufferSize(jack_nframes_t buffer_size) +{ + CloseAux(); + JackAudioDriver::SetBufferSize(buffer_size); // never fails + return OpenAux(); +} + +int JackBoomerDriver::ProcessAsync() +{ + // Read input buffers for the current cycle + if (Read() < 0) { + jack_error("JackBoomerDriver::ProcessAsync: read error, skip cycle"); + return 0; // Skip cycle, but continue processing... + } + + // Write output buffers from the previous cycle + if (Write() < 0) { + jack_error("JackBoomerDriver::ProcessAsync: write error, skip cycle"); + return 0; // Skip cycle, but continue processing... + } + + if (fIsMaster) { + ProcessGraphAsync(); + } else { + fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); + } + + // Keep end cycle time + JackDriver::CycleTakeEndTime(); + return 0; +} + +} // end of namespace + +#ifdef __cplusplus +extern "C" +{ +#endif + +SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() +{ + jack_driver_desc_t *desc; + unsigned int i; + desc = (jack_driver_desc_t*)calloc(1, sizeof(jack_driver_desc_t)); + + strcpy(desc->name, "boomer"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 + strcpy(desc->desc, "Boomer/OSS API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 + + desc->nparams = OSS_DRIVER_N_PARAMS; + desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); + + i = 0; + strcpy(desc->params[i].name, "rate"); + desc->params[i].character = 'r'; + desc->params[i].type = JackDriverParamUInt; + desc->params[i].value.ui = OSS_DRIVER_DEF_FS; + strcpy(desc->params[i].short_desc, "Sample rate"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy(desc->params[i].name, "period"); + desc->params[i].character = 'p'; + desc->params[i].type = JackDriverParamUInt; + desc->params[i].value.ui = OSS_DRIVER_DEF_BLKSIZE; + strcpy(desc->params[i].short_desc, "Frames per period"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy(desc->params[i].name, "nperiods"); + desc->params[i].character = 'n'; + desc->params[i].type = JackDriverParamUInt; + desc->params[i].value.ui = OSS_DRIVER_DEF_NPERIODS; + strcpy(desc->params[i].short_desc, "Number of periods to prefill output buffer"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy(desc->params[i].name, "wordlength"); + desc->params[i].character = 'w'; + desc->params[i].type = JackDriverParamInt; + desc->params[i].value.i = OSS_DRIVER_DEF_BITS; + strcpy(desc->params[i].short_desc, "Word length"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy(desc->params[i].name, "inchannels"); + desc->params[i].character = 'i'; + desc->params[i].type = JackDriverParamUInt; + desc->params[i].value.ui = OSS_DRIVER_DEF_INS; + strcpy(desc->params[i].short_desc, "Capture channels"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy(desc->params[i].name, "outchannels"); + desc->params[i].character = 'o'; + desc->params[i].type = JackDriverParamUInt; + desc->params[i].value.ui = OSS_DRIVER_DEF_OUTS; + strcpy(desc->params[i].short_desc, "Playback channels"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy(desc->params[i].name, "excl"); + desc->params[i].character = 'e'; + desc->params[i].type = JackDriverParamBool; + desc->params[i].value.i = false; + strcpy(desc->params[i].short_desc, "Exclusif (O_EXCL) access mode"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy(desc->params[i].name, "capture"); + desc->params[i].character = 'C'; + desc->params[i].type = JackDriverParamString; + strcpy(desc->params[i].value.str, OSS_DRIVER_DEF_DEV); + strcpy(desc->params[i].short_desc, "Input device"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy(desc->params[i].name, "playback"); + desc->params[i].character = 'P'; + desc->params[i].type = JackDriverParamString; + strcpy(desc->params[i].value.str, OSS_DRIVER_DEF_DEV); + strcpy(desc->params[i].short_desc, "Output device"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy (desc->params[i].name, "device"); + desc->params[i].character = 'd'; + desc->params[i].type = JackDriverParamString; + strcpy(desc->params[i].value.str, OSS_DRIVER_DEF_DEV); + strcpy(desc->params[i].short_desc, "OSS device name"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy(desc->params[i].name, "ignorehwbuf"); + desc->params[i].character = 'b'; + desc->params[i].type = JackDriverParamBool; + desc->params[i].value.i = false; + strcpy(desc->params[i].short_desc, "Ignore hardware period size"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy(desc->params[i].name, "input-latency"); + desc->params[i].character = 'I'; + desc->params[i].type = JackDriverParamUInt; + desc->params[i].value.i = 0; + strcpy(desc->params[i].short_desc, "Extra input latency"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy(desc->params[i].name, "output-latency"); + desc->params[i].character = 'O'; + desc->params[i].type = JackDriverParamUInt; + desc->params[i].value.i = 0; + strcpy(desc->params[i].short_desc, "Extra output latency"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + return desc; +} + +EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) +{ + int bits = OSS_DRIVER_DEF_BITS; + jack_nframes_t srate = OSS_DRIVER_DEF_FS; + jack_nframes_t frames_per_interrupt = OSS_DRIVER_DEF_BLKSIZE; + const char* capture_pcm_name = OSS_DRIVER_DEF_DEV; + const char* playback_pcm_name = OSS_DRIVER_DEF_DEV; + bool capture = false; + bool playback = false; + int chan_in = 0; + int chan_out = 0; + bool monitor = false; + bool excl = false; + unsigned int nperiods = OSS_DRIVER_DEF_NPERIODS; + const JSList *node; + const jack_driver_param_t *param; + bool ignorehwbuf = false; + jack_nframes_t systemic_input_latency = 0; + jack_nframes_t systemic_output_latency = 0; + + for (node = params; node; node = jack_slist_next(node)) { + + param = (const jack_driver_param_t *)node->data; + + switch (param->character) { + + case 'r': + srate = param->value.ui; + break; + + case 'p': + frames_per_interrupt = (unsigned int)param->value.ui; + break; + + case 'n': + nperiods = (unsigned int)param->value.ui; + break; + + case 'w': + bits = param->value.i; + break; + + case 'i': + chan_in = (int)param->value.ui; + break; + + case 'o': + chan_out = (int)param->value.ui; + break; + + case 'C': + capture = true; + if (strcmp(param->value.str, "none") != 0) { + capture_pcm_name = strdup(param->value.str); + } + break; + + case 'P': + playback = true; + if (strcmp(param->value.str, "none") != 0) { + playback_pcm_name = strdup(param->value.str); + } + break; + + case 'd': + playback_pcm_name = strdup (param->value.str); + capture_pcm_name = strdup (param->value.str); + break; + + case 'b': + ignorehwbuf = true; + break; + + case 'e': + excl = true; + break; + + case 'I': + systemic_input_latency = param->value.ui; + break; + + case 'O': + systemic_output_latency = param->value.ui; + break; + } + } + + // duplex is the default + if (!capture && !playback) { + capture = true; + playback = true; + } + + Jack::JackBoomerDriver* boomer_driver = new Jack::JackBoomerDriver("system", "boomer", engine, table); + Jack::JackDriverClientInterface* threaded_driver = new Jack::JackThreadedDriver(boomer_driver); + + // Special open for OSS driver... + if (boomer_driver->Open(frames_per_interrupt, nperiods, srate, capture, playback, chan_in, chan_out, + excl, monitor, capture_pcm_name, playback_pcm_name, systemic_input_latency, systemic_output_latency, bits, ignorehwbuf) == 0) { + return threaded_driver; + } else { + delete threaded_driver; // Delete the decorated driver + return NULL; + } +} + +#ifdef __cplusplus +} +#endif diff --git a/solaris/oss/JackBoomerDriver.h b/solaris/oss/JackBoomerDriver.h new file mode 100644 index 00000000..1861e8d8 --- /dev/null +++ b/solaris/oss/JackBoomerDriver.h @@ -0,0 +1,135 @@ +/* +Copyright (C) 2009 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 __JackBoomerDriver__ +#define __JackBoomerDriver__ + +#include "JackAudioDriver.h" +#include "JackPlatformPlug.h" +#include "ringbuffer.h" +//#include "JackThread.h" + +namespace Jack +{ + +typedef jack_default_audio_sample_t jack_sample_t; + +#define OSS_DRIVER_N_PARAMS 13 +#define OSS_DRIVER_DEF_DEV "/dev/dsp" +#define OSS_DRIVER_DEF_FS 48000 +#define OSS_DRIVER_DEF_BLKSIZE 1024 +#define OSS_DRIVER_DEF_NPERIODS 1 +#define OSS_DRIVER_DEF_BITS 16 +#define OSS_DRIVER_DEF_INS 2 +#define OSS_DRIVER_DEF_OUTS 2 + +/*! +\brief The Boomer driver. +*/ + +class JackBoomerDriver : public JackAudioDriver, public JackRunnableInterface +{ + + enum { kRead = 1, kWrite = 2, kReadWrite = 3 }; + + private: + + int fInFD; + int fOutFD; + + int fBits; + int fSampleFormat; + int fNperiods; + unsigned int fSampleSize; + int fRWMode; + bool fExcl; + bool fIgnoreHW; + + unsigned int fInputBufferSize; + unsigned int fOutputBufferSize; + + void* fInputBuffer; + void* fOutputBuffer; + jack_ringbuffer_t** fRingBuffer; + JackThread fThread; + + int OpenInput(); + int OpenOutput(); + int OpenAux(); + void CloseAux(); + void SetSampleFormat(); + void DisplayDeviceInfo(); + + // Redefining since timing for CPU load is specific + int ProcessAsync(); + + public: + + JackBoomerDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) + : JackAudioDriver(name, alias, engine, table), + fInFD(-1), fOutFD(-1), fBits(0), + fSampleFormat(0), fNperiods(0), fRWMode(0), fExcl(false), fIgnoreHW(true), + fInputBufferSize(0), fOutputBufferSize(0), + fInputBuffer(NULL), fOutputBuffer(NULL), + fRingBuffer(NULL), fThread(this) + {} + + virtual ~JackBoomerDriver() + {} + + int Open(jack_nframes_t frames_per_cycle, + int user_nperiods, + jack_nframes_t rate, + bool capturing, + bool playing, + int chan_in, + int chan_out, + bool vmix, + bool monitor, + const char* capture_driver_name, + const char* playback_driver_name, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency, + int bits, + bool ignorehwbuf); + + int Close(); + + int Start(); + int Stop(); + + int Read(); + int Write(); + + // BufferSize can be changed + bool IsFixedBufferSize() + { + return false; + } + + int SetBufferSize(jack_nframes_t buffer_size); + + bool Init(); + bool Execute(); + +}; + +} // end of namespace + +#endif diff --git a/solaris/oss/JackOSSDriver.cpp b/solaris/oss/JackOSSDriver.cpp index 46a2871a..ad44a43c 100644 --- a/solaris/oss/JackOSSDriver.cpp +++ b/solaris/oss/JackOSSDriver.cpp @@ -828,7 +828,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() strcpy(desc->params[i].name, "ignorehwbuf"); desc->params[i].character = 'b'; desc->params[i].type = JackDriverParamBool; - desc->params[i].value.i = TRUE; + desc->params[i].value.i = false; strcpy(desc->params[i].short_desc, "Ignore hardware period size"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); diff --git a/solaris/wscript b/solaris/wscript index 06bbe5b9..9e7ce920 100644 --- a/solaris/wscript +++ b/solaris/wscript @@ -28,6 +28,8 @@ def build(bld): create_jack_driver_obj(bld, 'oss', ['oss/JackOSSDriver.cpp', '../common/memops.c']) + create_jack_driver_obj(bld, 'boomer', ['oss/JackBoomerDriver.cpp', '../common/memops.c']) + create_jack_driver_obj(bld, 'dummy', '../common/JackDummyDriver.cpp') create_jack_driver_obj(bld, 'net', '../common/JackNetDriver.cpp') diff --git a/tests/test.cpp b/tests/test.cpp index 9ae3963f..2358a891 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2005 Samuel TRACOL for 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 @@ -20,7 +20,7 @@ /** @file jack_test.c * * @brief This client test the jack API. - * + * */ #include @@ -38,7 +38,7 @@ #include -#ifdef WIN32 +#if defined(WIN32) && !defined(M_PI) #define M_PI 3.151592653 #endif @@ -122,9 +122,9 @@ int client_register = 0; /** *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* - + Callbacks & basics functions - + *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* */ @@ -266,9 +266,9 @@ int Jack_Sync_Callback(jack_transport_state_t state, jack_position_t *pos, void /** *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* - + processing functions - + *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* * Proccess1 is for client1 @@ -370,7 +370,7 @@ int process2(jack_nframes_t nframes, void *arg) } } } - + if (process2_activated == 2) { // envoie de signal1 pour test tie mode et le r�cup�re direct + latence de la boucle jack... out2 = (jack_default_audio_sample_t *) jack_port_get_buffer (output_port2, nframes); in2 = (jack_default_audio_sample_t *) jack_port_get_buffer (input_port2, nframes); @@ -389,7 +389,7 @@ int process2(jack_nframes_t nframes, void *arg) } } } - + if (process2_activated == 3) { // envoie de -signal1 pour sommation en oppo de phase par jack in2 = (jack_default_audio_sample_t *) jack_port_get_buffer (input_port2, nframes); @@ -416,14 +416,14 @@ static int _process (jack_nframes_t nframes) out = (jack_default_audio_sample_t *)jack_port_get_buffer (output_port1, nframes); memcpy (out, in, sizeof (jack_default_audio_sample_t) * nframes); - return 0; + return 0; } -static void* jack_thread(void *arg) +static void* jack_thread(void *arg) { jack_client_t* client = (jack_client_t*) arg; jack_nframes_t last_thread_time = jack_frame_time(client); - + while (1) { jack_nframes_t frames = jack_cycle_wait (client); jack_nframes_t current_thread_time = jack_frame_time(client); @@ -433,7 +433,7 @@ static void* jack_thread(void *arg) last_thread_time = current_thread_time; jack_cycle_signal (client, status); } - + return 0; } @@ -441,7 +441,7 @@ static void* jack_thread(void *arg) int process3(jack_nframes_t nframes, void *arg) { static int process3_call = 0; - + if (process3_call++ > 10) { Log("process3 callback : exiting...\n"); return -1; @@ -457,15 +457,15 @@ int process4(jack_nframes_t nframes, void *arg) static jack_nframes_t last_time = jack_frame_time(client); static jack_nframes_t tolerance = (jack_nframes_t)(cur_buffer_size * 0.1f); - + jack_nframes_t cur_time = jack_frame_time(client); jack_nframes_t delta_time = cur_time - last_time; - + Log("calling process4 callback : jack_frame_time = %ld delta_time = %ld\n", cur_time, delta_time); if (delta_time > 0 && (unsigned int)abs(delta_time - cur_buffer_size) > tolerance) { printf("!!! ERROR !!! jack_frame_time seems to return incorrect values cur_buffer_size = %d, delta_time = %d\n", cur_buffer_size, delta_time); } - + last_time = cur_time; return 0; } @@ -525,7 +525,7 @@ int main (int argc, char *argv[]) int is_mine = 0; // to test jack_port_is_mine function... const char *options = "kRnqvt:"; float ratio; // for speed calculation in freewheel mode - jack_options_t jack_options = JackNullOption; + jack_options_t jack_options = JackNullOption; struct option long_options[] = { {"realtime", 0, 0, 'R'}, {"non-realtime", 0, 0, 'n'}, @@ -602,8 +602,8 @@ int main (int argc, char *argv[]) printf("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*--*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\n"); /** - * Register a client... - * + * Register a client... + * */ Log("Register a client using jack_client_open()...\n"); client1 = jack_client_open(client_name1, jack_options, &status, server_name); @@ -618,7 +618,7 @@ int main (int argc, char *argv[]) if (status & JackServerStarted) { fprintf(stderr, "JACK server started\n"); } - + /** * try to register another one with the same name... * @@ -631,7 +631,7 @@ int main (int argc, char *argv[]) printf("!!! ERROR !!! Jackd server has accepted multiples client with the same name !\n"); jack_client_close(client2); } - + /** * try to register another one with the same name using jack_client_open ==> since JackUseExactName is not used, an new client should be opened... * @@ -644,7 +644,7 @@ int main (int argc, char *argv[]) } else { printf("!!! ERROR !!! Jackd server automatic renaming feature does not work!\n"); } - + /** * testing client name... * Verify that the name sended at registration and the one returned by jack server is the same... @@ -683,31 +683,31 @@ int main (int argc, char *argv[]) if (jack_set_buffer_size_callback(client1, Jack_Update_Buffer_Size, 0) != 0) { printf("Error when calling buffer_size_callback !\n"); } - + if (jack_set_graph_order_callback(client1, Jack_Graph_Order_Callback, 0) != 0) { printf("Error when calling Jack_Graph_Order_Callback() !\n"); } - + if (jack_set_xrun_callback(client1, Jack_XRun_Callback, 0 ) != 0) { printf("Error when calling jack_set_xrun_callback() !\n"); } - + if (jack_set_sample_rate_callback(client1, Jack_Sample_Rate_Callback, 0 ) != 0) { printf("Error when calling Jack_Sample_Rate_Callback() !\n"); } - + if (jack_set_port_registration_callback(client1, Jack_Port_Register, 0) != 0) { printf("Error when calling jack_set_port_registration_callback() !\n"); } - + if (jack_set_port_connect_callback(client1, Jack_Port_Connect, 0) != 0) { printf("Error when calling jack_set_port_connect_callback() !\n"); } - + if (jack_set_client_registration_callback(client1, Jack_Client_Registration_Callback, 0) != 0) { printf("Error when calling jack_set_client_registration_callback() !\n"); } - + jack_set_error_function(Jack_Error_Callback); /** @@ -747,7 +747,7 @@ int main (int argc, char *argv[]) printf("!!! ERROR !!! Can't register any port for the client !\n"); exit(1); } - + /** * Test port type of the just registered port. * @@ -811,7 +811,7 @@ int main (int argc, char *argv[]) printf ("Fatal error : cannot activate client1\n"); exit(1); } - + /** * Test if init callback initThread have been called. * @@ -925,7 +925,7 @@ int main (int argc, char *argv[]) /** * remove the output port previously created * no more ports should subsist here for our client. - * + * */ if (jack_port_unregister(client1, output_port1) != 0) { printf("!!! ERROR !!! while unregistering port %s.\n", jack_port_name(output_port1)); @@ -933,7 +933,7 @@ int main (int argc, char *argv[]) /** * list all in ports - * + * */ inports = jack_get_ports(client1, NULL, NULL, 0); @@ -1133,7 +1133,7 @@ int main (int argc, char *argv[]) } free(inports); // free array of ports (as mentionned in the doc of jack_get_ports) - + /** *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* @@ -1157,7 +1157,7 @@ int main (int argc, char *argv[]) } exit(1); } - + // Check client registration callback jack_sleep(1000); if (client_register == 0) @@ -1368,7 +1368,7 @@ int main (int argc, char *argv[]) } /** - * Test TIE MODE + * Test TIE MODE * (This mode seems to be problematic in standard jack version 0.100. It seems that nobody * is used to apply this mode because the tie mode doesn't work at all. A patch seems difficult to produce * in this version of jack. Tie mode work well in MP version.) @@ -1468,7 +1468,7 @@ int main (int argc, char *argv[]) * So, the result must be zero... * See process1 for details about steps of this test * - */ + */ // fprintf(file, "Sum test\n"); Log("Checking summation capabilities of patching...\n"); output_port1b = jack_port_register(client1, "out1b", @@ -1565,7 +1565,7 @@ int main (int argc, char *argv[]) outports = jack_get_ports(client1, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); if (inports[0] != NULL) { output_ext_latency = jack_port_get_latency (jack_port_by_name(client1, inports[0])); // from client to out driver (which has "inputs" ports..) - input_ext_latency = jack_port_get_latency (jack_port_by_name(client1, outports[0])); // from in driver (which has "output" ports..) to client + input_ext_latency = jack_port_get_latency (jack_port_by_name(client1, outports[0])); // from in driver (which has "output" ports..) to client if (output_ext_latency != jack_port_get_total_latency(client1, jack_port_by_name(client1, inports[0]))) { t_error = 1; printf("!!! ERROR !!! get_latency & get_all_latency for a PHY device (unconnected) didn't return the same value !\n"); @@ -1641,7 +1641,7 @@ int main (int argc, char *argv[]) jack_port_disconnect(client1, input_port2); jack_port_disconnect(client1, output_port1); jack_port_disconnect(client1, output_port2); - + jack_sleep(1000); free(inports); @@ -1836,23 +1836,23 @@ int main (int argc, char *argv[]) jack_sleep (1 * 1000); time_before_exit--; } - + if (jack_deactivate(client2) != 0) { printf("!!! ERROR !!! jack_deactivate does not return 0 for client2 !\n"); } if (jack_deactivate(client1) != 0) { printf("!!! ERROR !!! jack_deactivate does not return 0 for client1 !\n"); } - + /** * Checking jack_frame_time. */ Log("Testing jack_frame_time...\n"); jack_set_process_callback(client1, process4, client1); jack_activate(client1); - jack_sleep(2 * 1000); - - + jack_sleep(2 * 1000); + + /** * Checking alternate thread model */ @@ -1862,7 +1862,7 @@ int main (int argc, char *argv[]) jack_set_process_thread(client1, jack_thread, client1); jack_activate(client1); jack_sleep(2 * 1000); - + /** * Checking callback exiting : when the return code is != 0, the client is desactivated. */ @@ -1871,8 +1871,8 @@ int main (int argc, char *argv[]) jack_set_process_thread(client1, NULL, NULL); // remove thread callback jack_set_process_callback(client1, process3, 0); jack_activate(client1); - jack_sleep(3 * 1000); - + jack_sleep(3 * 1000); + /** *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* diff --git a/windows/JackCompilerDeps_os.h b/windows/JackCompilerDeps_os.h index f98dba9c..82fae18e 100644 --- a/windows/JackCompilerDeps_os.h +++ b/windows/JackCompilerDeps_os.h @@ -18,9 +18,25 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackCompilerDeps_WIN32__ -#define __JackCompilerDeps_WIN32__ +#define __JackCompilerDeps_WIN32__ -#if __GNUC__ +#if __GNUC__ + #ifndef POST_PACKED_STRUCTURE + /* POST_PACKED_STRUCTURE needs to be a macro which + expands into a compiler directive. The directive must + tell the compiler to arrange the preceding structure + declaration so that it is packed on byte-boundaries rather + than use the natural alignment of the processor and/or + compiler. + */ + #if (__GNUC__< 4) /* Does not seem to work with GCC 3.XX serie */ + #define POST_PACKED_STRUCTURE + #elif defined(JACK_32_64) + #define POST_PACKED_STRUCTURE __attribute__((__packed__)) + #else + #define POST_PACKED_STRUCTURE + #endif + #endif #define MEM_ALIGN(x,y) x __attribute__((aligned(y))) #define EXPORT __declspec(dllexport) #ifdef SERVER_SIDE @@ -29,7 +45,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #define SERVER_EXPORT #endif #else - //#define MEM_ALIGN(x,y) __declspec(align(y)) x #define MEM_ALIGN(x,y) x #define EXPORT __declspec(dllexport) #ifdef SERVER_SIDE diff --git a/windows/JackSystemDeps_os.h b/windows/JackSystemDeps_os.h index 78cccdc7..69b842b3 100644 --- a/windows/JackSystemDeps_os.h +++ b/windows/JackSystemDeps_os.h @@ -25,10 +25,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #define DRIVER_HANDLE HINSTANCE #define LoadDriverModule(name) LoadLibrary((name)) #define UnloadDriverModule(handle) (FreeLibrary(((HMODULE)handle))) -#define GetProc(handle, name) GetProcAddress(((HMODULE)handle),(name)) +#define GetDriverProc(handle, name) GetProcAddress(((HMODULE)handle), (name)) -#define ENOBUFS 55 +#define JACK_HANDLE HINSTANCE +#define LoadJackModule(name) LoadLibrary((name)); +#define UnloadJackModule(handle) FreeLibrary((handle)); +#define GetJackProc(handle, name) GetProcAddress((handle), (name)); +#define ENOBUFS 55 #define JACK_DEBUG false #endif diff --git a/windows/Setup/jack.ci b/windows/Setup/jack.ci index ee1c96ca..213bcc82 100644 --- a/windows/Setup/jack.ci +++ b/windows/Setup/jack.ci @@ -1,9 +1,9 @@ <*project version = 4 civer = "Free v4.14.3" winver = "2.6/5.1.2600" > . - Jack_v1.9.2_setup.exe + Jack_v1.9.3_setup.exe - Jack v1.9.2 + Jack v1.9.3 Default - 2 diff --git a/windows/Setup/src/README b/windows/Setup/src/README index eafc21ae..5ba3bc3a 100644 --- a/windows/Setup/src/README +++ b/windows/Setup/src/README @@ -8,7 +8,7 @@ This installer will install everything to use Jack Audio Connection Kit (JACK) ( Microsoft Runtime Libraries ============================================= -In order to use this software, you will need the Microsoft Vusual C++ 2008 redistributable package. This package is freely available on the Microsoft download center. Please be sure you install the correct version (2008). This package is required by portaudio to run windows specific audio drivers (MME, DSound and ASIO). +In order to use this software, you will need the Microsoft Visual C++ 2008 redistributable package. This package is freely available on the Microsoft download center. Please be sure you install the correct version (2008). This package is required by portaudio to run windows specific audio drivers (MME, DSound and ASIO). ============================================= QJACKCTL on Windows diff --git a/wscript b/wscript index 4fef3251..659a1a26 100644 --- a/wscript +++ b/wscript @@ -64,6 +64,7 @@ def set_options(opt): opt.add_option('--dbus', action='store_true', default=False, help='Enable D-Bus JACK (jackdbus)') opt.add_option('--doxygen', action='store_true', default=False, help='Enable build of doxygen documentation') opt.add_option('--profile', action='store_true', default=False, help='Build with engine profiling') + opt.add_option('--mixed', action='store_true', default=False, help='Build with 32/64 bits mixed mode') opt.add_option('--clients', default=64, type="int", dest="clients", help='Maximum number of JACK clients') opt.add_option('--ports', default=1024, type="int", dest="ports", help='Maximum number of ports') opt.add_option('--clients', default=64, type="int", dest="clients", help='Maximum number of JACK clients') @@ -120,6 +121,7 @@ def configure(conf): conf.env['BUILD_DOXYGEN_DOCS'] = Options.options.doxygen conf.env['BUILD_WITH_PROFILE'] = Options.options.profile + conf.env['BUILD_WITH_32_64'] = Options.options.mixed if Options.options.libdir: conf.env['LIBDIR'] = Options.options.libdir @@ -137,6 +139,8 @@ def configure(conf): conf.define('JACK_DBUS', 1) if conf.env['BUILD_WITH_PROFILE'] == True: conf.define('JACK_MONITOR', 1) + if conf.env['BUILD_WITH_32_64'] == True: + conf.define('JACK_32_64', 1) conf.write_config_header('config.h') svnrev = None @@ -163,6 +167,7 @@ def configure(conf): display_msg("Drivers directory", conf.env['ADDON_DIR'], 'CYAN') display_feature('Build doxygen documentation', conf.env['BUILD_DOXYGEN_DOCS']) display_feature('Build with engine profiling', conf.env['BUILD_WITH_PROFILE']) + display_feature('Build with 32/64 bits mixed mode', conf.env['BUILD_WITH_32_64']) if conf.env['IS_LINUX']: From 522fd2b7f852a214593fb4ba4defcfdd76c857f9 Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 7 Apr 2009 13:53:13 +0000 Subject: [PATCH 016/472] rebase from trunk 3482:3502 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3503 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 4 + common/JackAudioAdapterInterface.cpp | 9 +- common/JackAudioDriver.cpp | 2 +- common/JackClient.cpp | 4 +- common/JackConnectionManager.cpp | 4 +- common/JackConstants.h | 8 +- common/JackControlAPI.cpp | 21 + common/JackControlAPI.h | 7 + common/JackDriver.cpp | 44 +- common/JackDriver.h | 22 + common/JackDriverLoader.cpp | 5 +- common/JackDriverLoader.h | 6 + common/JackMidiDriver.cpp | 181 ++++++++ common/JackMidiDriver.h | 79 ++++ common/JackMidiPort.cpp | 6 +- common/JackMidiPort.h | 3 +- common/JackServer.cpp | 53 +-- common/JackServer.h | 6 +- common/JackThreadedDriver.h | 13 + common/Jackdmp.cpp | 108 +++-- common/jack/control.h | 8 + common/wscript | 3 +- example-clients/midisine.c | 20 +- macosx/Jackdmp.xcodeproj/project.pbxproj | 249 ++++++++++- macosx/coremidi/JackCoreMidiDriver.cpp | 426 +++++++++++++++++++ macosx/coremidi/JackCoreMidiDriver.h | 80 ++++ macosx/wscript | 17 + windows/jack_winmme.cbp | 121 ++++++ windows/jackd.workspace | 3 +- windows/jackwinmme.rc | 41 ++ windows/libjackserver.cbp | 399 +++++++++--------- windows/winmme/JackWinMMEDriver.cpp | 501 +++++++++++++++++++++++ windows/winmme/JackWinMMEDriver.h | 87 ++++ 33 files changed, 2242 insertions(+), 298 deletions(-) create mode 100644 common/JackMidiDriver.cpp create mode 100644 common/JackMidiDriver.h create mode 100644 macosx/coremidi/JackCoreMidiDriver.cpp create mode 100644 macosx/coremidi/JackCoreMidiDriver.h create mode 100644 windows/jack_winmme.cbp create mode 100644 windows/jackwinmme.rc create mode 100644 windows/winmme/JackWinMMEDriver.cpp create mode 100644 windows/winmme/JackWinMMEDriver.h diff --git a/ChangeLog b/ChangeLog index 2d11462c..910775b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,6 +25,10 @@ Paul Davis Jackdmp changes log --------------------------- +2009-04-08 Stephane Letz + + * Native MIDI backend (JackCoreMidiDriver, JackWinMMEDriver) in progress. + 2009-04-03 Stephane Letz * Simplify JackClient RT code, jack_thread_wait API marked deprecated." diff --git a/common/JackAudioAdapterInterface.cpp b/common/JackAudioAdapterInterface.cpp index 47425d40..ece82fc7 100644 --- a/common/JackAudioAdapterInterface.cpp +++ b/common/JackAudioAdapterInterface.cpp @@ -78,7 +78,8 @@ namespace Jack fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); - fprintf(file, "set title \"Audio adapter timing\"\n"); + fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n" + ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize); fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"frames\"\n"); fprintf(file, "plot "); @@ -109,7 +110,8 @@ namespace Jack fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); - fprintf(file, "set title \"Audio adapter timing\"\n"); + fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n" + ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize); fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"resampling ratio\"\n"); fprintf(file, "plot "); @@ -140,7 +142,8 @@ namespace Jack fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); - fprintf(file, "set title \"Audio adapter timing\"\n"); + fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n" + ,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize); fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"frames\"\n"); fprintf(file, "plot "); diff --git a/common/JackAudioDriver.cpp b/common/JackAudioDriver.cpp index 943571f0..fc753123 100644 --- a/common/JackAudioDriver.cpp +++ b/common/JackAudioDriver.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2001 Paul Davis -Copyright (C) 2004-2008 GramefClientControl. +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 diff --git a/common/JackClient.cpp b/common/JackClient.cpp index 310b3c78..5bc45334 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -120,12 +120,12 @@ void JackClient::SetupDriverSync(bool freewheel) jack_log("JackClient::SetupDriverSync driver sem in flush mode"); fSynchroTable[AUDIO_DRIVER_REFNUM].SetFlush(true); fSynchroTable[FREEWHEEL_DRIVER_REFNUM].SetFlush(true); - fSynchroTable[LOOPBACK_DRIVER_REFNUM].SetFlush(true); + fSynchroTable[MIDI_DRIVER_REFNUM].SetFlush(true); } else { jack_log("JackClient::SetupDriverSync driver sem in normal mode"); fSynchroTable[AUDIO_DRIVER_REFNUM].SetFlush(false); fSynchroTable[FREEWHEEL_DRIVER_REFNUM].SetFlush(false); - fSynchroTable[LOOPBACK_DRIVER_REFNUM].SetFlush(false); + fSynchroTable[MIDI_DRIVER_REFNUM].SetFlush(false); } } diff --git a/common/JackConnectionManager.cpp b/common/JackConnectionManager.cpp index 5108ddcd..08fa92ca 100644 --- a/common/JackConnectionManager.cpp +++ b/common/JackConnectionManager.cpp @@ -58,8 +58,8 @@ bool JackConnectionManager::IsLoopPathAux(int ref1, int ref2) const || ref2 == AUDIO_DRIVER_REFNUM || ref1 == FREEWHEEL_DRIVER_REFNUM || ref2 == FREEWHEEL_DRIVER_REFNUM - || ref1 == LOOPBACK_DRIVER_REFNUM - || ref2 == LOOPBACK_DRIVER_REFNUM) { + || ref1 == MIDI_DRIVER_REFNUM + || ref2 == MIDI_DRIVER_REFNUM) { return false; } else if (ref1 == ref2) { // Same refnum return true; diff --git a/common/JackConstants.h b/common/JackConstants.h index 5d4a136e..fbc552a7 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -47,10 +47,10 @@ #define CLIENT_NUM 64 #endif -#define AUDIO_DRIVER_REFNUM 0 // Audio driver is initialized first, it will get the refnum 0 -#define FREEWHEEL_DRIVER_REFNUM 1 // Freewheel driver is initialized second, it will get the refnum 1 -#define LOOPBACK_DRIVER_REFNUM 2 // Loopback driver is initialized third, it will get the refnum 2 -#define REAL_REFNUM LOOPBACK_DRIVER_REFNUM + 1 // Real clients start at LOOPBACK_DRIVER_REFNUM + 1 +#define AUDIO_DRIVER_REFNUM 0 // Audio driver is initialized first, it will get the refnum 0 +#define FREEWHEEL_DRIVER_REFNUM 1 // Freewheel driver is initialized second, it will get the refnum 1 +#define MIDI_DRIVER_REFNUM 2 // Loopback driver is initialized third, it will get the refnum 2 +#define REAL_REFNUM MIDI_DRIVER_REFNUM + 1 // Real clients start at MIDI_DRIVER_REFNUM + 1 #define JACK_DEFAULT_SERVER_NAME "default" diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index 0bec8906..8a0a36b6 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -42,6 +42,7 @@ #include "JackControlAPI.h" #include "JackLockedEngine.h" #include "JackConstants.h" +#include "JackDriverLoader.h" using namespace Jack; @@ -95,6 +96,7 @@ struct jackctl_driver jack_driver_desc_t * desc_ptr; JSList * parameters; JSList * set_parameters; + JackDriverInfo* info; }; struct jackctl_internal @@ -1161,4 +1163,23 @@ EXPORT bool jackctl_server_unload_internal( } } +EXPORT bool jackctl_server_load_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr) +{ + if (server_ptr->engine != NULL) { + driver_ptr->info = server_ptr->engine->AddSlave(driver_ptr->desc_ptr, driver_ptr->set_parameters); + return (driver_ptr->info != 0); + } else { + return false; + } +} + +EXPORT bool jackctl_server_unload_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr) +{ + if (server_ptr->engine != NULL) { + server_ptr->engine->RemoveSlave(driver_ptr->info); + return true; + } else { + return false; + } +} diff --git a/common/JackControlAPI.h b/common/JackControlAPI.h index 7fc73243..54be6f3f 100644 --- a/common/JackControlAPI.h +++ b/common/JackControlAPI.h @@ -219,6 +219,13 @@ EXPORT bool jackctl_server_load_internal( EXPORT bool jackctl_server_unload_internal( jackctl_server * server, jackctl_internal * internal); + +EXPORT bool jackctl_server_load_slave(jackctl_server_t * server, + jackctl_driver_t * driver); + +EXPORT bool jackctl_server_unload_slave(jackctl_server_t * server, + jackctl_driver_t * driver); + #if 0 { /* Adjust editor indent */ diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index 682b6f78..f5098771 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -68,7 +68,7 @@ int JackDriver::Open() int refnum = -1; if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) { - jack_error("Cannot allocate internal client for audio driver"); + jack_error("Cannot allocate internal client for driver"); return -1; } @@ -79,6 +79,46 @@ int JackDriver::Open() return 0; } +int JackDriver::Open (bool capturing, + bool playing, + int inchannels, + int outchannels, + bool monitor, + const char* capture_driver_name, + const char* playback_driver_name, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency) +{ + jack_log("JackDriver::Open capture_driver_name = %s", capture_driver_name); + jack_log("JackDriver::Open playback_driver_name = %s", playback_driver_name); + int refnum = -1; + + if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) { + jack_error("Cannot allocate internal client for driver"); + return -1; + } + + fClientControl.fRefNum = refnum; + fClientControl.fActive = true; + fCaptureLatency = capture_latency; + fPlaybackLatency = playback_latency; + + assert(strlen(capture_driver_name) < JACK_CLIENT_NAME_SIZE); + assert(strlen(playback_driver_name) < JACK_CLIENT_NAME_SIZE); + + strcpy(fCaptureDriverName, capture_driver_name); + strcpy(fPlaybackDriverName, playback_driver_name); + + fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec + if (!fEngineControl->fTimeOut) + fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs); + + //fGraphManager->SetBufferSize(fEngineControl->fBufferSize); + fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum); // Connect driver to itself for "sync" mode + SetupDriverSync(fClientControl.fRefNum, false); + return 0; +} + int JackDriver::Open(jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, @@ -96,7 +136,7 @@ int JackDriver::Open(jack_nframes_t buffer_size, int refnum = -1; if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) { - jack_error("Cannot allocate internal client for audio driver"); + jack_error("Cannot allocate internal client for driver"); return -1; } diff --git a/common/JackDriver.h b/common/JackDriver.h index a6027905..9c99d7c4 100644 --- a/common/JackDriver.h +++ b/common/JackDriver.h @@ -50,6 +50,17 @@ class SERVER_EXPORT JackDriverInterface {} virtual int Open() = 0; + + virtual int Open (bool capturing, + bool playing, + int inchannels, + int outchannels, + bool monitor, + const char* capture_driver_name, + 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, @@ -142,6 +153,17 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface int ProcessSlaves(); virtual int Open(); + + virtual int Open (bool capturing, + bool playing, + int inchannels, + int outchannels, + bool monitor, + const char* capture_driver_name, + 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, diff --git a/common/JackDriverLoader.cpp b/common/JackDriverLoader.cpp index 37ac7479..52c4aeed 100644 --- a/common/JackDriverLoader.cpp +++ b/common/JackDriverLoader.cpp @@ -800,7 +800,8 @@ Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver jack_error("no initialize function in shared object %s\n", driver_desc->file); return NULL; } - - return fInitialize(engine, synchro, params); + + fBackend = fInitialize(engine, synchro, params); + return fBackend; } diff --git a/common/JackDriverLoader.h b/common/JackDriverLoader.h index c72183ac..f68fb041 100644 --- a/common/JackDriverLoader.h +++ b/common/JackDriverLoader.h @@ -42,6 +42,7 @@ class JackDriverInfo driverInitialize fInitialize; DRIVER_HANDLE fHandle; + Jack::JackDriverClientInterface* fBackend; public: @@ -54,6 +55,11 @@ class JackDriverInfo } Jack::JackDriverClientInterface* Open(jack_driver_desc_t* driver_desc, Jack::JackLockedEngine*, Jack::JackSynchro*, const JSList*); + + Jack::JackDriverClientInterface* GetBackend() + { + return fBackend; + } }; diff --git a/common/JackMidiDriver.cpp b/common/JackMidiDriver.cpp new file mode 100644 index 00000000..b5bfd4c4 --- /dev/null +++ b/common/JackMidiDriver.cpp @@ -0,0 +1,181 @@ +/* +Copyright (C) 2009 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 +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 +(at your option) any later version. + +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. + +*/ + +#include "JackSystemDeps.h" +#include "JackMidiDriver.h" +#include "JackTime.h" +#include "JackError.h" +#include "JackEngineControl.h" +#include "JackPort.h" +#include "JackGraphManager.h" +#include "JackException.h" +#include + +namespace Jack +{ + +JackMidiDriver::JackMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) + : JackDriver(name, alias, engine, table), + fCaptureChannels(0), + fPlaybackChannels(0) +{ + for (int i = 0; i < DRIVER_PORT_NUM; i++) { + fRingBuffer[i] = NULL; + } +} + +JackMidiDriver::~JackMidiDriver() +{ + for (int i = 0; i < fCaptureChannels; i++) { + if (fRingBuffer[i]) + jack_ringbuffer_free(fRingBuffer[i]); + } +} + +int JackMidiDriver::Open(bool capturing, + bool playing, + int inchannels, + int outchannels, + bool monitor, + const char* capture_driver_name, + const char* playback_driver_name, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency) +{ + fCaptureChannels = inchannels; + fPlaybackChannels = outchannels; + + for (int i = 0; i < fCaptureChannels; i++) { + fRingBuffer[i] = jack_ringbuffer_create(sizeof(float) * BUFFER_SIZE_MAX); + } + + return JackDriver::Open(capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); +} + +int JackMidiDriver::Attach() +{ + JackPort* port; + jack_port_id_t port_index; + char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + unsigned long port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; + int i; + + jack_log("JackMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); + + for (i = 0; i < fCaptureChannels; i++) { + snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); + snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { + jack_error("driver: cannot register port for %s", name); + return -1; + } + port = fGraphManager->GetPort(port_index); + port->SetAlias(alias); + fCapturePortList[i] = port_index; + jack_log("JackMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index); + } + + port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; + + for (i = 0; i < fPlaybackChannels; i++) { + snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); + snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { + jack_error("driver: cannot register port for %s", name); + return -1; + } + port = fGraphManager->GetPort(port_index); + port->SetAlias(alias); + fPlaybackPortList[i] = port_index; + jack_log("JackMidiDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); + } + + return 0; +} + +int JackMidiDriver::Detach() +{ + int i; + jack_log("JackMidiDriver::Detach"); + + for (i = 0; i < fCaptureChannels; i++) { + fGraphManager->ReleasePort(fClientControl.fRefNum, fCapturePortList[i]); + } + + for (i = 0; i < fPlaybackChannels; i++) { + fGraphManager->ReleasePort(fClientControl.fRefNum, fPlaybackPortList[i]); + } + + return 0; +} + +int JackMidiDriver::Read() +{ + return 0; +} + +int JackMidiDriver::Write() +{ + return 0; +} + +int JackMidiDriver::ProcessNull() +{ + return 0; +} + +int JackMidiDriver::Process() +{ + // Read input buffers for the current cycle + if (Read() < 0) { + jack_error("JackMidiDriver::Process: read error, skip cycle"); + return 0; // Skip cycle, but continue processing... + } + + fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); + if (fEngineControl->fSyncMode) { + if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, fEngineControl->fTimeOutUsecs) < 0) { + jack_error("JackFreewheelDriver::ProcessSync SuspendRefNum error"); + return -1; + } + } + + // Write output buffers for the current cycle + if (Write() < 0) { + jack_error("JackMidiDriver::Process: write error, skip cycle"); + return 0; // Skip cycle, but continue processing... + } + + return 0; +} + +JackMidiBuffer* JackMidiDriver::GetInputBuffer(int port_index) +{ + assert(fCapturePortList[port_index]); + return (JackMidiBuffer*)fGraphManager->GetBuffer(fCapturePortList[port_index], fEngineControl->fBufferSize); +} + +JackMidiBuffer* JackMidiDriver::GetOutputBuffer(int port_index) +{ + assert(fPlaybackPortList[port_index]); + return (JackMidiBuffer*)fGraphManager->GetBuffer(fPlaybackPortList[port_index], fEngineControl->fBufferSize); +} + +} // end of namespace diff --git a/common/JackMidiDriver.h b/common/JackMidiDriver.h new file mode 100644 index 00000000..7c5bc5e0 --- /dev/null +++ b/common/JackMidiDriver.h @@ -0,0 +1,79 @@ +/* +Copyright (C) 2009 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 __JackMidiDriver__ +#define __JackMidiDriver__ + +#include "JackDriver.h" +#include "JackMidiPort.h" +#include "JackLockedEngine.h" +#include "ringbuffer.h" + +namespace Jack +{ + +/*! +\brief The base class for MIDI drivers: drivers with MIDI ports. +*/ + +class SERVER_EXPORT JackMidiDriver : public JackDriver +{ + + protected: + + int fCaptureChannels; + int fPlaybackChannels; + + jack_ringbuffer_t* fRingBuffer[DRIVER_PORT_NUM]; + + jack_port_id_t fCapturePortList[DRIVER_PORT_NUM]; + jack_port_id_t fPlaybackPortList[DRIVER_PORT_NUM]; + + JackMidiBuffer* GetInputBuffer(int port_index); + JackMidiBuffer* GetOutputBuffer(int port_index); + + public: + + JackMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); + virtual ~JackMidiDriver(); + + virtual int Open(bool capturing, + bool playing, + int inchannels, + int outchannels, + bool monitor, + const char* capture_driver_name, + const char* playback_driver_name, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency); + + virtual int Process(); + virtual int ProcessNull(); + + virtual int Attach(); + virtual int Detach(); + + virtual int Read(); + virtual int Write(); + +}; + +} // end of namespace + +#endif diff --git a/common/JackMidiPort.cpp b/common/JackMidiPort.cpp index 41dcb151..fb933c85 100644 --- a/common/JackMidiPort.cpp +++ b/common/JackMidiPort.cpp @@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -void JackMidiBuffer::Reset(jack_nframes_t nframes) +SERVER_EXPORT void JackMidiBuffer::Reset(jack_nframes_t nframes) { /* This line ate 1 hour of my life... dsbaikov */ this->nframes = nframes; @@ -37,7 +37,7 @@ void JackMidiBuffer::Reset(jack_nframes_t nframes) mix_index = 0; } -jack_shmsize_t JackMidiBuffer::MaxEventSize() const +SERVER_EXPORT jack_shmsize_t JackMidiBuffer::MaxEventSize() const { assert (((jack_shmsize_t) - 1) < 0); // jack_shmsize_t should be signed jack_shmsize_t left = buffer_size - (sizeof(JackMidiBuffer) + sizeof(JackMidiEvent) * (event_count + 1) + write_pos); @@ -48,7 +48,7 @@ jack_shmsize_t JackMidiBuffer::MaxEventSize() const return left; } -jack_midi_data_t* JackMidiBuffer::ReserveEvent(jack_nframes_t time, jack_shmsize_t size) +SERVER_EXPORT jack_midi_data_t* JackMidiBuffer::ReserveEvent(jack_nframes_t time, jack_shmsize_t size) { jack_shmsize_t space = MaxEventSize(); if (space == 0 || size > space) { diff --git a/common/JackMidiPort.h b/common/JackMidiPort.h index 0b22944c..0dbfcb9a 100644 --- a/common/JackMidiPort.h +++ b/common/JackMidiPort.h @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "types.h" #include "JackConstants.h" +#include "JackPlatformPlug.h" #include /** Type for raw event data contained in @ref jack_midi_event_t. */ @@ -42,7 +43,7 @@ struct jack_midi_event_t namespace Jack { -struct JackMidiEvent +struct SERVER_EXPORT JackMidiEvent { // Most MIDI events are < 4 bytes in size, so we can save a lot, storing them inplace. enum { INLINE_SIZE_MAX = sizeof(jack_shmsize_t) }; diff --git a/common/JackServer.cpp b/common/JackServer.cpp index 8dcf2bfb..a1f60edf 100644 --- a/common/JackServer.cpp +++ b/common/JackServer.cpp @@ -22,7 +22,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackServerGlobals.h" #include "JackTime.h" #include "JackFreewheelDriver.h" -#include "JackLoopbackDriver.h" #include "JackThreadedDriver.h" #include "JackGlobals.h" #include "JackLockedEngine.h" @@ -50,10 +49,8 @@ JackServer::JackServer(bool sync, bool temporary, long timeout, bool rt, long pr fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, server_name); fEngine = new JackLockedEngine(fGraphManager, GetSynchroTable(), fEngineControl); fFreewheelDriver = new JackThreadedDriver(new JackFreewheelDriver(fEngine, GetSynchroTable())); - fLoopbackDriver = new JackLoopbackDriver(fEngine, GetSynchroTable()); fAudioDriver = NULL; fFreewheel = false; - fLoopback = loopback; JackServerGlobals::fInstance = this; // Unique instance JackServerGlobals::fUserCount = 1; // One user jack_verbose = verbose; @@ -64,7 +61,6 @@ JackServer::~JackServer() delete fGraphManager; delete fAudioDriver; delete fFreewheelDriver; - delete fLoopbackDriver; delete fEngine; delete fEngineControl; } @@ -94,35 +90,17 @@ int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params) goto fail_close4; } - if (fLoopbackDriver->Open(fEngineControl->fBufferSize, fEngineControl->fSampleRate, 1, 1, fLoopback, fLoopback, false, "loopback", "loopback", 0, 0) != 0) { - jack_error("Cannot open driver"); - goto fail_close5; - } - if (fAudioDriver->Attach() != 0) { jack_error("Cannot attach audio driver"); - goto fail_close6; - } - - if (fLoopback > 0 && fLoopbackDriver->Attach() != 0) { - jack_error("Cannot attach loopback driver"); - goto fail_close7; + goto fail_close5; } fFreewheelDriver->SetMaster(false); fAudioDriver->SetMaster(true); - if (fLoopback > 0) - fAudioDriver->AddSlave(fLoopbackDriver); fAudioDriver->AddSlave(fFreewheelDriver); // After ??? InitTime(); return 0; - -fail_close7: - fAudioDriver->Detach(); -fail_close6: - fLoopbackDriver->Close(); - fail_close5: fFreewheelDriver->Close(); @@ -145,11 +123,8 @@ int JackServer::Close() jack_log("JackServer::Close"); fChannel.Close(); fAudioDriver->Detach(); - if (fLoopback > 0) - fLoopbackDriver->Detach(); fAudioDriver->Close(); fFreewheelDriver->Close(); - fLoopbackDriver->Close(); fEngine->Close(); // TODO: move that in reworked JackServerGlobals::Destroy() JackMessageBuffer::Destroy(); @@ -305,6 +280,32 @@ void JackServer::ClientKill(int refnum) } } +//---------------------- +// Backend management +//---------------------- + +JackDriverInfo* JackServer::AddSlave(jack_driver_desc_t* driver_desc, JSList* driver_params) +{ + JackDriverInfo* info = new JackDriverInfo(); + JackDriverClientInterface* backend = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params); + if (backend == NULL) { + delete info; + return NULL; + } else { + backend->Attach(); + fAudioDriver->AddSlave(backend); + return info; + } +} + +void JackServer::RemoveSlave(JackDriverInfo* info) +{ + JackDriverClientInterface* backend = info->GetBackend(); + fAudioDriver->RemoveSlave(info->GetBackend()); + backend->Detach(); + backend->Close(); +} + //---------------------- // Transport management //---------------------- diff --git a/common/JackServer.h b/common/JackServer.h index d802965a..fb88101a 100644 --- a/common/JackServer.h +++ b/common/JackServer.h @@ -50,7 +50,6 @@ class SERVER_EXPORT JackServer JackDriverInfo fDriverInfo; JackDriverClientInterface* fAudioDriver; JackDriverClientInterface* fFreewheelDriver; - JackDriverClientInterface* fLoopbackDriver; JackLockedEngine* fEngine; JackEngineControl* fEngineControl; JackGraphManager* fGraphManager; @@ -58,7 +57,6 @@ class SERVER_EXPORT JackServer JackConnectionManager fConnectionState; JackSynchro fSynchroTable[CLIENT_NUM]; bool fFreewheel; - long fLoopback; int InternalClientLoadAux(JackLoadableInternalClient* client, const char* so_name, const char* client_name, int options, int* int_ref, int* status); @@ -86,6 +84,10 @@ class SERVER_EXPORT JackServer // Transport management int ReleaseTimebase(int refnum); int SetTimebaseCallback(int refnum, int conditional); + + // Backend management + JackDriverInfo* AddSlave(jack_driver_desc_t* driver_desc, JSList* driver_params); + void RemoveSlave(JackDriverInfo* info); // Object access JackLockedEngine* GetEngine(); diff --git a/common/JackThreadedDriver.h b/common/JackThreadedDriver.h index abd9f0d4..8705e2c4 100644 --- a/common/JackThreadedDriver.h +++ b/common/JackThreadedDriver.h @@ -45,6 +45,19 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi virtual ~JackThreadedDriver(); virtual int Open(); + + virtual int Open (bool capturing, + bool playing, + int inchannels, + int outchannels, + bool monitor, + const char* capture_driver_name, + const char* playback_driver_name, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency) + { + return -1; + } virtual int Open(jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index 227cf402..8662a278 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -33,7 +33,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackDriverLoader.h" /* -This is a simple port of the old jackdmp.cpp file to use the new Jack 2.0 control API. Available options for the server +This is a simple port of the old jackdmp.cpp file to use the new Jack 2.0 control API. Available options for the server are "hard-coded" in the source. A much better approach would be to use the control API to: - dynamically retrieve available server parameters and then prepare to parse them - get available drivers and their possible parameters, then prepare to parse them. @@ -58,7 +58,7 @@ static void notify_server_start(const char* server_name) static void notify_server_stop(const char* server_name) { // Send notification to be used in the JackRouter plugin - CFStringRef ref1 = CFStringCreateWithCString(NULL, server_name, kCFStringEncodingMacRoman); + CFStringRef ref1 = CFStringCreateWithCString(NULL, server_name, kCFStringEncodingMacRoman); CFNotificationCenterPostNotificationWithOptions(CFNotificationCenterGetDistributedCenter(), CFSTR("com.grame.jackserver.stop"), ref1, @@ -95,14 +95,14 @@ static void usage(FILE* file) "usage: jackdmp [ --realtime OR -R [ --realtime-priority OR -P priority ] ]\n" " [ --name OR -n server-name ]\n" " [ --timeout OR -t client-timeout-in-msecs ]\n" - " [ --loopback OR -L loopback-port-number ]\n" + " [ --midi OR -X midi-driver ]\n" " [ --verbose OR -v ]\n" " [ --replace-registry OR -r ]\n" " [ --silent OR -s ]\n" " [ --sync OR -S ]\n" " [ --temporary OR -T ]\n" " [ --version OR -V ]\n" - " -d driver [ ... driver args ... ]\n" + " -d audio-driver [ ... driver args ... ]\n" " where driver can be `alsa', `coreaudio', 'portaudio' or `dummy'\n" " jackdmp -d driver --help\n" " to display options for each driver\n\n"); @@ -154,10 +154,12 @@ int main(int argc, char* argv[]) jackctl_server_t * server_ctl; const JSList * server_parameters; const char* server_name = "default"; - jackctl_driver_t * driver_ctl; - const char *options = "-ad:P:uvrshVRL:STFl:t:mn:p:"; + jackctl_driver_t * audio_driver_ctl; + jackctl_driver_t * midi_driver_ctl; + const char *options = "-ad:X:P:uvrshVRL:STFl:t:mn:p:"; struct option long_options[] = { - { "driver", 1, 0, 'd' }, + { "audio-driver", 1, 0, 'd' }, + { "midi-driver", 1, 0, 'X' }, { "verbose", 0, 0, 'v' }, { "help", 0, 0, 'h' }, { "port-max", 1, 0, 'p' }, @@ -177,10 +179,14 @@ int main(int argc, char* argv[]) }; int i,opt = 0; int option_index = 0; - bool seen_driver = false; - char *driver_name = NULL; - char **driver_args = NULL; - int driver_nargs = 1; + bool seen_audio_driver = false; + bool seen_midi_driver = false; + char *audio_driver_name = NULL; + char **audio_driver_args = NULL; + int audio_driver_nargs = 1; + char *midi_driver_name = NULL; + char **midi_driver_args = NULL; + int midi_driver_nargs = 1; int port_max = 512; int do_mlock = 1; int do_unlock = 0; @@ -190,34 +196,39 @@ int main(int argc, char* argv[]) union jackctl_parameter_value value; copyright(stdout); - + server_ctl = jackctl_server_create(); if (server_ctl == NULL) { fprintf(stderr, "Failed to create server object\n"); return -1; } - + server_parameters = jackctl_server_get_parameters(server_ctl); opterr = 0; - while (!seen_driver && + while (!seen_audio_driver && (opt = getopt_long(argc, argv, options, long_options, &option_index)) != EOF) { switch (opt) { case 'd': - seen_driver = true; - driver_name = optarg; + seen_audio_driver = true; + audio_driver_name = optarg; break; - + + case 'X': + seen_midi_driver = true; + midi_driver_name = optarg; + break; + case 'p': port_max = (unsigned int)atol(optarg); break; - + case 'm': do_mlock = 0; break; - + case 'u': do_unlock = 1; break; @@ -306,6 +317,7 @@ int main(int argc, char* argv[]) default: fprintf(stderr, "unknown option character %c\n", optopt); /*fallthru*/ + case 'h': usage(stdout); goto fail_free; @@ -313,61 +325,77 @@ int main(int argc, char* argv[]) } if (show_version) { - printf("jackdmp version" VERSION - "\n"); + printf( "jackdmp version " VERSION + " tmpdir " jack_server_dir + " protocol %d" + "\n", JACK_PROTOCOL_VERSION); return -1; } - - if (!seen_driver) { + + if (!seen_audio_driver) { usage(stderr); goto fail_free; } - driver_ctl = jackctl_server_get_driver(server_ctl, driver_name); - if (driver_ctl == NULL) { - fprintf(stderr, "Unkown driver \"%s\"\n", driver_name); + // Audio driver + audio_driver_ctl = jackctl_server_get_driver(server_ctl, audio_driver_name); + if (audio_driver_ctl == NULL) { + fprintf(stderr, "Unkown driver \"%s\"\n", audio_driver_name); goto fail_free; } if (optind < argc) { - driver_nargs = 1 + argc - optind; + audio_driver_nargs = 1 + argc - optind; } else { - driver_nargs = 1; + audio_driver_nargs = 1; } - if (driver_nargs == 0) { + if (audio_driver_nargs == 0) { fprintf(stderr, "No driver specified ... hmm. JACK won't do" " anything when run like this.\n"); goto fail_free; } - driver_args = (char **) malloc(sizeof(char *) * driver_nargs); - driver_args[0] = driver_name; + audio_driver_args = (char **) malloc(sizeof(char *) * audio_driver_nargs); + audio_driver_args[0] = audio_driver_name; - for (i = 1; i < driver_nargs; i++) { - driver_args[i] = argv[optind++]; + for (i = 1; i < audio_driver_nargs; i++) { + audio_driver_args[i] = argv[optind++]; } - if (jackctl_parse_driver_params(driver_ctl, driver_nargs, driver_args)) { + if (jackctl_parse_driver_params(audio_driver_ctl, audio_driver_nargs, audio_driver_args)) { goto fail_free; } - - if (!jackctl_server_start(server_ctl, driver_ctl)) { + + // Start server + if (!jackctl_server_start(server_ctl, audio_driver_ctl)) { fprintf(stderr, "Failed to start server\n"); goto fail_free; } - + + // MIDI driver + if (seen_midi_driver) { + + midi_driver_ctl = jackctl_server_get_driver(server_ctl, midi_driver_name); + if (midi_driver_ctl == NULL) { + fprintf(stderr, "Unkown driver \"%s\"\n", midi_driver_name); + goto fail_free; + } + + jackctl_server_load_slave(server_ctl, midi_driver_ctl); + } + notify_server_start(server_name); // Waits for signal signals = jackctl_setup_signals(0); jackctl_wait_signals(signals); - + if (!jackctl_server_stop(server_ctl)) fprintf(stderr, "Cannot stop server...\n"); - + fail_free: - + jackctl_server_destroy(server_ctl); notify_server_stop(server_name); return 1; diff --git a/common/jack/control.h b/common/jack/control.h index 17436f07..87d62e72 100644 --- a/common/jack/control.h +++ b/common/jack/control.h @@ -510,6 +510,14 @@ jack_log( /* @} */ +bool +jackctl_server_load_slave(jackctl_server_t * server, + jackctl_driver_t * driver); + +bool +jackctl_server_unload_slave(jackctl_server_t * server, + jackctl_driver_t * driver); + #if 0 { /* Adjust editor indent */ #endif diff --git a/common/wscript b/common/wscript index 9847c0de..78641f48 100644 --- a/common/wscript +++ b/common/wscript @@ -113,6 +113,7 @@ def build(bld): serverlib.source = [] + common_libsources serverlib.source += [ 'JackAudioDriver.cpp', + 'JackMidiDriver.cpp', 'JackDriver.cpp', 'JackEngine.cpp', 'JackExternalClient.cpp', @@ -170,7 +171,7 @@ def build(bld): serverlib.env.append_value("CPPFLAGS", "-fvisibility=hidden") serverlib.env.append_value("CPPFLAGS", "-mmacosx-version-min=10.4 -arch i386 -arch ppc") #serverlib.env.append_value("LINKFLAGS", "-framework CoreAudio -framework vecLib -single_module -arch i386 -arch ppc") - serverlib.env.append_value("LINKFLAGS", "-framework CoreAudio -framework vecLib -single_module") + serverlib.env.append_value("LINKFLAGS", "-framework CoreAudio -framework CoreFoundation -framework vecLib -single_module") serverlib.env.append_value("LINKFLAGS", "-compatibility_version 1 -current_version 1") if bld.env['IS_SUN']: diff --git a/example-clients/midisine.c b/example-clients/midisine.c index 38299138..89ff7f75 100644 --- a/example-clients/midisine.c +++ b/example-clients/midisine.c @@ -71,17 +71,21 @@ static int process(jack_nframes_t nframes, void *arg) /* printf("1st byte of 1st event addr is %p\n", in_events[0].buffer);*/ } jack_midi_event_get(&in_event, port_buf, 0); - for(i=0; i +#include +#include +#include +#include + +namespace Jack +{ + +static MIDITimeStamp MIDIGetCurrentHostTime() +{ + return mach_absolute_time(); +} + +void JackCoreMidiDriver::ReadProcAux(const MIDIPacketList *pktlist, jack_ringbuffer_t* ringbuffer) +{ + // Write the number of packets + size_t size = jack_ringbuffer_write(ringbuffer, (char*)&pktlist->numPackets, sizeof(UInt32)); + if (size != sizeof(UInt32)) { + jack_error("ReadProc : ring buffer is full, skip events..."); + return; + } + + for (unsigned int i = 0; i < pktlist->numPackets; ++i) { + + MIDIPacket *packet = (MIDIPacket *)pktlist->packet; + + // TODO : use timestamp + + // Write length of each packet first + size = jack_ringbuffer_write(ringbuffer, (char*)&packet->length, sizeof(UInt16)); + if (size != sizeof(UInt16)) { + jack_error("ReadProc : ring buffer is full, skip events..."); + return; + } + // Write event actual data + size = jack_ringbuffer_write(ringbuffer, (char*)packet->data, packet->length); + if (size != packet->length) { + jack_error("ReadProc : ring buffer is full, skip events..."); + return; + } + + packet = MIDIPacketNext(packet); + } +} + +void JackCoreMidiDriver::ReadProc(const MIDIPacketList *pktlist, void *refCon, void *connRefCon) +{ + jack_ringbuffer_t* ringbuffer = (jack_ringbuffer_t*)connRefCon; + ReadProcAux(pktlist, ringbuffer); +} + +void JackCoreMidiDriver::ReadVirtualProc(const MIDIPacketList *pktlist, void *refCon, void *connRefCon) +{ + jack_ringbuffer_t* ringbuffer = (jack_ringbuffer_t*)refCon; + ReadProcAux(pktlist, ringbuffer); +} + +void JackCoreMidiDriver::NotifyProc(const MIDINotification *message, void *refCon) +{ + jack_info("NotifyProc %d", message->messageID); +} + +JackCoreMidiDriver::JackCoreMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) + : JackMidiDriver(name, alias, engine, table), fMidiClient(NULL), fInputPort(NULL), fOutputPort(NULL), fRealCaptureChannels(0), fRealPlaybackChannels(0) +{} + +JackCoreMidiDriver::~JackCoreMidiDriver() +{} + +int JackCoreMidiDriver::Open(bool capturing, + bool playing, + int inchannels, + int outchannels, + bool monitor, + const char* capture_driver_name, + const char* playback_driver_name, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency) + { + OSStatus err; + CFStringRef coutputStr; + std::string str; + + // Get real input/output number + fRealCaptureChannels = MIDIGetNumberOfSources(); + fRealPlaybackChannels = MIDIGetNumberOfDestinations(); + + // Generic JackMidiDriver Open + if (JackMidiDriver::Open(capturing, playing, inchannels + fRealCaptureChannels, outchannels + fRealPlaybackChannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0) + return -1; + + coutputStr = CFStringCreateWithCString(0, "JackMidi", CFStringGetSystemEncoding()); + err = MIDIClientCreate(coutputStr, NotifyProc, this, &fMidiClient); + CFRelease(coutputStr); + if (!fMidiClient) { + jack_error("Cannot create CoreMidi client"); + goto error; + } + + err = MIDIInputPortCreate(fMidiClient, CFSTR("Input port"), ReadProc, this, &fInputPort); + if (!fInputPort) { + jack_error("Cannot open CoreMidi in port\n"); + goto error; + } + + err = MIDIOutputPortCreate(fMidiClient, CFSTR("Output port"), &fOutputPort); + if (!fOutputPort) { + jack_error("Cannot open CoreMidi out port\n"); + goto error; + } + + fMidiDestination = new MIDIEndpointRef[inchannels + fRealCaptureChannels]; + assert(fMidiDestination); + + // Virtual input + for (int i = 0; i < inchannels; i++) { + std::stringstream num; + num << i; + str = "JackMidi" + num.str(); + coutputStr = CFStringCreateWithCString(0, str.c_str(), CFStringGetSystemEncoding()); + err = MIDIDestinationCreate(fMidiClient, coutputStr, ReadVirtualProc, fRingBuffer[i], &fMidiDestination[i]); + CFRelease(coutputStr); + if (!fMidiDestination[i]) { + jack_error("Cannot create CoreMidi destination"); + goto error; + } + } + + // Real input + for (int i = 0; i < fRealCaptureChannels; i++) { + fMidiDestination[i + inchannels] = MIDIGetSource(i); + MIDIPortConnectSource(fInputPort, fMidiDestination[i + inchannels], fRingBuffer[i + inchannels]); + } + + fMidiSource = new MIDIEndpointRef[outchannels + fRealPlaybackChannels]; + assert(fMidiSource); + + // Virtual output + for (int i = 0; i < outchannels; i++) { + std::stringstream num; + num << i; + str = "JackMidi" + num.str(); + coutputStr = CFStringCreateWithCString(0, str.c_str(), CFStringGetSystemEncoding()); + err = MIDISourceCreate(fMidiClient, coutputStr, &fMidiSource[i]); + CFRelease(coutputStr); + if (!fMidiSource[i]) { + jack_error("Cannot create CoreMidi source"); + goto error; + } + } + + // Real output + for (int i = 0; i < fRealPlaybackChannels; i++) { + fMidiSource[i + outchannels] = MIDIGetDestination(i); + } + + return 0; + +error: + Close(); + return -1; +} + +int JackCoreMidiDriver::Close() +{ + if (fInputPort) + MIDIPortDispose(fInputPort); + + if (fOutputPort) + MIDIPortDispose(fOutputPort); + + // Only dispose "virtual" endpoints + for (int i = 0; i < fCaptureChannels - fRealCaptureChannels; i++) { + if (fMidiDestination) + MIDIEndpointDispose(fMidiDestination[i]); + } + delete[] fMidiDestination; + + // Only dispose "virtual" endpoints + for (int i = 0; i < fPlaybackChannels - fRealPlaybackChannels; i++) { + if (fMidiSource[i]) + MIDIEndpointDispose(fMidiSource[i]); + } + delete[] fMidiSource; + + if (fMidiClient) + MIDIClientDispose(fMidiClient); + + return 0; +} + +int JackCoreMidiDriver::Attach() +{ + OSStatus err; + JackPort* port; + CFStringRef pname; + jack_port_id_t port_index; + char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + char endpoint_name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + unsigned long port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; + int i; + + jack_log("JackCoreMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); + + for (i = 0; i < fCaptureChannels; i++) { + + err = MIDIObjectGetStringProperty(fMidiDestination[i], kMIDIPropertyName, &pname); + if (err == noErr) { + CFStringGetCString(pname, endpoint_name, sizeof(endpoint_name), 0); + CFRelease(pname); + snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, endpoint_name, i + 1); + } else { + snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); + } + + snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { + jack_error("driver: cannot register port for %s", name); + return -1; + } + port = fGraphManager->GetPort(port_index); + port->SetAlias(alias); + fCapturePortList[i] = port_index; + jack_log("JackCoreMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index); + } + + port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; + + for (i = 0; i < fPlaybackChannels; i++) { + + err = MIDIObjectGetStringProperty(fMidiSource[i], kMIDIPropertyName, &pname); + if (err == noErr) { + CFStringGetCString(pname, endpoint_name, sizeof(endpoint_name), 0); + CFRelease(pname); + snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, endpoint_name, i + 1); + } else { + snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); + } + + snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { + jack_error("driver: cannot register port for %s", name); + return -1; + } + port = fGraphManager->GetPort(port_index); + port->SetAlias(alias); + fPlaybackPortList[i] = port_index; + jack_log("JackCoreMidiDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); + } + + return 0; +} +int JackCoreMidiDriver::Read() +{ + for (int chan = 0; chan < fCaptureChannels; chan++) { + + if (fGraphManager->GetConnectionsNum(fCapturePortList[chan]) > 0) { + + // Get JACK port + JackMidiBuffer* midi_buffer = GetInputBuffer(chan); + + if (jack_ringbuffer_read_space(fRingBuffer[chan]) == 0) { + // Reset buffer + midi_buffer->Reset(midi_buffer->nframes); + } else { + + while (jack_ringbuffer_read_space(fRingBuffer[chan]) > 0) { + + // Read event number + int ev_count = 0; + jack_ringbuffer_read(fRingBuffer[chan], (char*)&ev_count, sizeof(int)); + + for (int j = 0; j < ev_count; j++) { + // Read event length + UInt16 event_len; + jack_ringbuffer_read(fRingBuffer[chan], (char*)&event_len, sizeof(UInt16)); + // Read event actual data + jack_midi_data_t* dest = midi_buffer->ReserveEvent(0, event_len); + jack_ringbuffer_read(fRingBuffer[chan], (char*)dest, event_len); + } + } + } + + } else { + // Consume ring buffer + jack_ringbuffer_read_advance(fRingBuffer[chan], jack_ringbuffer_read_space(fRingBuffer[chan])); + } + } + return 0; +} + +int JackCoreMidiDriver::Write() +{ + MIDIPacketList* pktlist = (MIDIPacketList*)fMIDIBuffer; + + for (int chan = 0; chan < fPlaybackChannels; chan++) { + + if (fGraphManager->GetConnectionsNum(fPlaybackPortList[chan]) > 0) { + + MIDIPacket* packet = MIDIPacketListInit(pktlist); + JackMidiBuffer* midi_buffer = GetOutputBuffer(chan); + + // TODO : use timestamp + + for (unsigned int j = 0; j < midi_buffer->event_count; j++) { + JackMidiEvent* ev = &midi_buffer->events[j]; + packet = MIDIPacketListAdd(pktlist, sizeof(fMIDIBuffer), packet, MIDIGetCurrentHostTime(), ev->size, ev->GetData(midi_buffer)); + } + + if (packet) { + if (chan < fPlaybackChannels - fRealPlaybackChannels) { + OSStatus err = MIDIReceived(fMidiSource[chan], pktlist); + if (err != noErr) + jack_error("MIDIReceived error"); + } else { + OSStatus err = MIDISend(fOutputPort, fMidiSource[chan], pktlist); + if (err != noErr) + jack_error("MIDISend error"); + } + } + } + } + + return 0; +} + +} // end of namespace + +#ifdef __cplusplus +extern "C" +{ +#endif + + SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor() + { + jack_driver_desc_t * desc; + unsigned int i; + + desc = (jack_driver_desc_t*)calloc (1, sizeof (jack_driver_desc_t)); + strcpy(desc->name, "coremidi"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 + strcpy(desc->desc, "Apple CoreMIDI API based MIDI backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 + + desc->nparams = 2; + desc->params = (jack_driver_param_desc_t*)calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); + + i = 0; + strcpy(desc->params[i].name, "inchannels"); + desc->params[i].character = 'i'; + desc->params[i].type = JackDriverParamInt; + desc->params[i].value.ui = 0; + strcpy(desc->params[i].short_desc, "CoreMIDI virtual bus"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy(desc->params[i].name, "outchannels"); + desc->params[i].character = 'o'; + desc->params[i].type = JackDriverParamInt; + desc->params[i].value.ui = 0; + strcpy(desc->params[i].short_desc, "CoreMIDI virtual bus"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + return desc; + } + + SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) + { + const JSList * node; + const jack_driver_param_t * param; + int virtual_in = 0; + int virtual_out = 0; + + for (node = params; node; node = jack_slist_next (node)) { + param = (const jack_driver_param_t *) node->data; + + switch (param->character) { + + case 'i': + virtual_in = param->value.ui; + break; + + case 'o': + virtual_out = param->value.ui; + break; + } + } + + Jack::JackDriverClientInterface* driver = new Jack::JackCoreMidiDriver("system_midi", "coremidi", engine, table); + if (driver->Open(1, 1, virtual_in, virtual_out, false, "in", "out", 0, 0) == 0) { + return driver; + } else { + delete driver; + return NULL; + } + } + +#ifdef __cplusplus +} +#endif + diff --git a/macosx/coremidi/JackCoreMidiDriver.h b/macosx/coremidi/JackCoreMidiDriver.h new file mode 100644 index 00000000..190e9cd2 --- /dev/null +++ b/macosx/coremidi/JackCoreMidiDriver.h @@ -0,0 +1,80 @@ +/* +Copyright (C) 2009 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 __JackCoreMidiDriver__ +#define __JackCoreMidiDriver__ + +#include +#include "JackMidiDriver.h" +#include "JackTime.h" + +namespace Jack +{ + +/*! +\brief The CoreMidi driver. +*/ + +class JackCoreMidiDriver : public JackMidiDriver +{ + + private: + + MIDIClientRef fMidiClient; + MIDIPortRef fInputPort; + MIDIPortRef fOutputPort; + MIDIEndpointRef* fMidiDestination; + MIDIEndpointRef* fMidiSource; + + char fMIDIBuffer[BUFFER_SIZE_MAX * sizeof(float)]; + + int fRealCaptureChannels; + int fRealPlaybackChannels; + + static void ReadProcAux(const MIDIPacketList *pktlist, jack_ringbuffer_t* ringbuffer); + static void ReadProc(const MIDIPacketList *pktlist, void *refCon, void *connRefCon); + static void ReadVirtualProc(const MIDIPacketList *pktlist, void *refCon, void *connRefCon); + static void NotifyProc(const MIDINotification *message, void *refCon); + + public: + + JackCoreMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); + virtual ~JackCoreMidiDriver(); + + int Open( bool capturing, + bool playing, + int chan_in, + int chan_out, + bool monitor, + const char* capture_driver_name, + const char* playback_driver_name, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency); + int Close(); + + int Attach(); + + int Read(); + int Write(); + +}; + +} // end of namespace + +#endif diff --git a/macosx/wscript b/macosx/wscript index a67869c0..198edef6 100644 --- a/macosx/wscript +++ b/macosx/wscript @@ -30,6 +30,21 @@ def create_jack_audio_driver_obj(bld, target, sources, uselib = None): driver.uselib = uselib return driver +def create_jack_midi_driver_obj(bld, target, sources, uselib = None): + driver = bld.new_task_gen('cxx', 'shlib') + driver.features.append('cc') + driver.env['shlib_PATTERN'] = 'jack_%s.so' + driver.defines = 'HAVE_CONFIG_H' + driver.includes = ['.', '../macosx', '../posix', '../common', '../common/jack'] + driver.target = target + driver.source = sources + driver.install_path = '${ADDON_DIR}/' + driver.uselib_local = 'serverlib' + driver.env.append_value("LINKFLAGS", "-framework CoreMIDI -framework CoreServices -framework AudioUnit") + if uselib: + driver.uselib = uselib + return driver + def build(bld): jackd = bld.new_task_gen('cxx', 'program') jackd.includes = ['.', '../macosx', '../posix', '../common', '../common/jack'] @@ -43,6 +58,8 @@ def build(bld): create_jack_driver_obj(bld, 'dummy', '../common/JackDummyDriver.cpp') create_jack_audio_driver_obj(bld, 'coreaudio', 'coreaudio/JackCoreAudioDriver.cpp') + + create_jack_midi_driver_obj(bld, 'coremidi', 'coremidi/JackCoreMidiDriver.cpp') portaudio_src = [ '../windows/JackPortAudioDriver.cpp', diff --git a/windows/jack_winmme.cbp b/windows/jack_winmme.cbp new file mode 100644 index 00000000..2c6d8bbe --- /dev/null +++ b/windows/jack_winmme.cbp @@ -0,0 +1,121 @@ + + + + + + diff --git a/windows/jackd.workspace b/windows/jackd.workspace index e92ff780..615bae3f 100644 --- a/windows/jackd.workspace +++ b/windows/jackd.workspace @@ -1,7 +1,7 @@ - + @@ -46,5 +46,6 @@ + diff --git a/windows/jackwinmme.rc b/windows/jackwinmme.rc new file mode 100644 index 00000000..57187d6c --- /dev/null +++ b/windows/jackwinmme.rc @@ -0,0 +1,41 @@ +// Generated by ResEdit 1.4.3 +// Copyright (C) 2006-2008 +// http://www.resedit.net + +#include "resource.h" +#include "afxres.h" + + +// +// Version Information resources +// +LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT +1 VERSIONINFO + FILEVERSION 1,9,3,0 + PRODUCTVERSION 1,9,3,0 + FILEOS VOS_UNKNOWN + FILETYPE VFT_DLL +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040c04b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "Grame\0" + VALUE "FileDescription", "Jackmp WinMMEo Driver for Windows\0" + VALUE "FileVersion", "1, 9, 3, 0\0" + VALUE "InternalName", "jack_portaudio\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "jack_winmme.dll\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "jack_winmme\0" + VALUE "ProductVersion", "1, 9, 3, 0\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 1036, 1200 + END +END diff --git a/windows/libjackserver.cbp b/windows/libjackserver.cbp index ef0bc173..8a82c34b 100644 --- a/windows/libjackserver.cbp +++ b/windows/libjackserver.cbp @@ -1,199 +1,200 @@ - - - - - - + + + + + + diff --git a/windows/winmme/JackWinMMEDriver.cpp b/windows/winmme/JackWinMMEDriver.cpp new file mode 100644 index 00000000..d803f707 --- /dev/null +++ b/windows/winmme/JackWinMMEDriver.cpp @@ -0,0 +1,501 @@ +/* +Copyright (C) 2009 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. + +*/ + +#include "JackWinMMEDriver.h" +#include "JackGraphManager.h" +#include "JackEngineControl.h" +#include "JackDriverLoader.h" + +#include +#include +#include +#include + +#include +#include +#include + +namespace Jack +{ + +static bool InitHeaders(MidiSlot* slot) +{ + slot->fHeader = (LPMIDIHDR)GlobalAllocPtr(GMEM_MOVEABLE|GMEM_SHARE|GMEM_ZEROINIT, sizeof(MIDIHDR) + kBuffSize); + if (!slot->fHeader) + return false; + + slot->fHeader->lpData = (LPSTR)((LPBYTE)slot->fHeader + sizeof(MIDIHDR)); + slot->fHeader->dwBufferLength = kBuffSize; + slot->fHeader->dwFlags = 0; + slot->fHeader->dwUser = 0; + slot->fHeader->lpNext = 0; + slot->fHeader->dwBytesRecorded = 0; + return true; +} + +void CALLBACK JackWinMMEDriver::MidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD userData, DWORD dwParam1, DWORD dwParam2) +{ + jack_ringbuffer_t* ringbuffer = (jack_ringbuffer_t*)userData; + //jack_info("JackWinMMEDriver::MidiInProc 0\n"); + + switch (wMsg) { + case MIM_OPEN: + break; + + case MIM_ERROR: + case MIM_DATA: { + + //jack_info("JackWinMMEDriver::MidiInProc"); + + // One event + unsigned int num_packet = 1; + jack_ringbuffer_write(ringbuffer, (char*)&num_packet, sizeof(unsigned int)); + + // Write event actual data + jack_ringbuffer_write(ringbuffer, (char*)&dwParam1, 3); + break; + } + + case MIM_LONGERROR: + case MIM_LONGDATA: + /* + Nothing for now + */ + break; + } +} + +JackWinMMEDriver::JackWinMMEDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) + : JackMidiDriver(name, alias, engine, table), + fRealCaptureChannels(0), + fRealPlaybackChannels(0), + fMidiSource(NULL), + fMidiDestination(NULL) +{} + +JackWinMMEDriver::~JackWinMMEDriver() +{} + +int JackWinMMEDriver::Open(bool capturing, + bool playing, + int inchannels, + int outchannels, + bool monitor, + const char* capture_driver_name, + const char* playback_driver_name, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency) +{ + + jack_log("JackWinMMEDriver::Open"); + + fRealCaptureChannels = midiInGetNumDevs(); + fRealPlaybackChannels = midiOutGetNumDevs (); + + // Generic JackMidiDriver Open + if (JackMidiDriver::Open(capturing, playing, inchannels + fRealCaptureChannels, outchannels + fRealPlaybackChannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0) + return -1; + + fMidiDestination = new MidiSlot[fRealCaptureChannels]; + assert(fMidiDestination); + + // Real input + for (int i = 0; i < fRealCaptureChannels; i++) { + + HMIDIIN handle; + fMidiDestination[i].fIndex = i; + MMRESULT ret = midiInOpen(&handle, fMidiDestination[i].fIndex, (DWORD)MidiInProc, (DWORD)fRingBuffer[i], CALLBACK_FUNCTION); + + if (ret == MMSYSERR_NOERROR) { + fMidiDestination[i].fHandle = handle; + if (!InitHeaders(&fMidiDestination[i])) { + jack_error("memory allocation failed"); + midiInClose(handle); + goto error; + //continue; + } + ret = midiInPrepareHeader(handle, fMidiDestination[i].fHeader, sizeof(MIDIHDR)); + + if (ret == MMSYSERR_NOERROR) { + fMidiDestination[i].fHeader->dwUser = 1; + ret = midiInAddBuffer(handle, fMidiDestination[i].fHeader, sizeof(MIDIHDR)); + if (ret == MMSYSERR_NOERROR) { + ret = midiInStart(handle); + if (ret != MMSYSERR_NOERROR) { + jack_error("midiInStart error"); + CloseInput(&fMidiDestination[i]); + goto error; + } + } else { + jack_error ("midiInAddBuffer error"); + CloseInput(&fMidiDestination[i]); + goto error; + } + } else { + jack_error("midiInPrepareHeader error"); + midiInClose(handle); + goto error; + } + } else { + jack_error ("midiInOpen error"); + goto error; + } + } + + fMidiSource = new MidiSlot[fRealPlaybackChannels]; + assert(fMidiSource); + + // Real output + for (int i = 0; i < fRealPlaybackChannels; i++) { + MMRESULT res; + HMIDIOUT handle; + fMidiSource[i].fIndex = i; + UINT ret = midiOutOpen(&handle, fMidiSource[i].fIndex, 0L, 0L, CALLBACK_NULL); + if (ret == MMSYSERR_NOERROR) { + fMidiSource[i].fHandle = handle; + if (!InitHeaders(&fMidiSource[i])) { + jack_error("memory allocation failed"); + midiOutClose(handle); + //continue; + goto error; + } + res = midiOutPrepareHeader(handle, fMidiSource[i].fHeader, sizeof(MIDIHDR)); + if (res != MMSYSERR_NOERROR) { + jack_error("midiOutPrepareHeader error %d %d %d", i, handle, res); + //continue; + goto error; + } else { + fMidiSource[i].fHeader->dwUser = 1; + } + } else { + jack_error("midiOutOpen error"); + goto error; + } + } + + return 0; + +error: + Close(); + return -1; +} + +void JackWinMMEDriver::CloseInput(MidiSlot* slot) +{ + MMRESULT res; + int retry = 0; + + if (slot->fHandle == 0) + return; + + HMIDIIN handle = (HMIDIIN)slot->fHandle; + slot->fHeader->dwUser = 0; + res = midiInStop(handle); + if (res != MMSYSERR_NOERROR) { + jack_error("midiInStop error"); + } + res = midiInReset(handle); + if (res != MMSYSERR_NOERROR) { + jack_error("midiInReset error"); + } + res = midiInUnprepareHeader(handle, slot->fHeader, sizeof(MIDIHDR)); + if (res != MMSYSERR_NOERROR) { + jack_error("midiInUnprepareHeader error"); + } + do { + res = midiInClose(handle); + if (res != MMSYSERR_NOERROR) { + jack_error("midiInClose error"); + } + if (res == MIDIERR_STILLPLAYING) + midiInReset(handle); + Sleep (10); + retry++; + } while ((res == MIDIERR_STILLPLAYING) && (retry < 10)); + + if (slot->fHeader) { + GlobalFreePtr(slot->fHeader); + } +} + +void JackWinMMEDriver::CloseOutput(MidiSlot* slot) +{ + MMRESULT res; + int retry = 0; + + if (slot->fHandle == 0) + return; + + HMIDIOUT handle = (HMIDIOUT)slot->fHandle; + res = midiOutReset(handle); + if (res != MMSYSERR_NOERROR) + jack_error("midiOutReset error"); + midiOutUnprepareHeader(handle, slot->fHeader, sizeof(MIDIHDR)); + do { + res = midiOutClose(handle); + if (res != MMSYSERR_NOERROR) + jack_error("midiOutClose error"); + Sleep(10); + retry++; + } while ((res == MIDIERR_STILLPLAYING) && (retry < 10)); + + if (slot->fHeader) { + GlobalFreePtr(slot->fHeader); + } +} + +int JackWinMMEDriver::Close() +{ + jack_log("JackWinMMEDriver::Close"); + + // Close input + if (fMidiDestination) { + for (int i = 0; i < fRealCaptureChannels; i++) { + CloseInput(&fMidiDestination[i]); + } + delete[] fMidiDestination; + } + + // Close output + if (fMidiSource) { + for (int i = 0; i < fRealPlaybackChannels; i++) { + CloseOutput(&fMidiSource[i]); + } + delete[] fMidiSource; + } + + return 0; +} + +int JackWinMMEDriver::Attach() +{ + JackPort* port; + jack_port_id_t port_index; + char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + unsigned long port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; + MMRESULT res; + int i; + + jack_log("JackMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); + + for (i = 0; i < fCaptureChannels; i++) { + MIDIINCAPS caps; + res = midiInGetDevCaps(i, &caps, sizeof(caps)); + if (res == MMSYSERR_NOERROR) { + snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, caps.szPname, i + 1); + } else { + snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); + } + snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); + + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { + jack_error("driver: cannot register port for %s", name); + return -1; + } + port = fGraphManager->GetPort(port_index); + port->SetAlias(alias); + fCapturePortList[i] = port_index; + jack_log("JackMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index); + } + + port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; + + for (i = 0; i < fPlaybackChannels; i++) { + MIDIOUTCAPS caps; + res = midiOutGetDevCaps(i, &caps, sizeof(caps)); + if (res == MMSYSERR_NOERROR) { + snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, caps.szPname, i + 1); + } else { + snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fPlaybackDriverName, i + 1); + } + snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); + + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { + jack_error("driver: cannot register port for %s", name); + return -1; + } + port = fGraphManager->GetPort(port_index); + port->SetAlias(alias); + fPlaybackPortList[i] = port_index; + jack_log("JackMidiDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); + } + + return 0; +} + +int JackWinMMEDriver::Read() +{ + size_t size; + + for (int chan = 0; chan < fCaptureChannels; chan++) { + + if (fGraphManager->GetConnectionsNum(fCapturePortList[chan]) > 0) { + + JackMidiBuffer* midi_buffer = GetInputBuffer(chan); + + if (jack_ringbuffer_read_space (fRingBuffer[chan]) == 0) { + // Reset buffer + midi_buffer->Reset(midi_buffer->nframes); + } else { + + while ((size = jack_ringbuffer_read_space (fRingBuffer[chan])) > 0) { + + //jack_info("jack_ringbuffer_read_space %d", size); + int ev_count = 0; + jack_ringbuffer_read(fRingBuffer[chan], (char*)&ev_count, sizeof(int)); + + if (ev_count > 0) { + for (int j = 0; j < ev_count; j++) { + unsigned int event_len = 3; + // Read event actual data + jack_midi_data_t* dest = midi_buffer->ReserveEvent(0, event_len); + jack_ringbuffer_read(fRingBuffer[chan], (char*)dest, event_len); + } + } + } + } + } else { + //jack_info("Consume ring buffer"); + jack_ringbuffer_read_advance(fRingBuffer[chan], jack_ringbuffer_read_space(fRingBuffer[chan])); + } + } + return 0; +} + +int JackWinMMEDriver::Write() +{ + for (int chan = 0; chan < fPlaybackChannels; chan++) { + + if (fGraphManager->GetConnectionsNum(fPlaybackPortList[chan]) > 0) { + + JackMidiBuffer* midi_buffer = GetOutputBuffer(chan); + + // TODO : use timestamp + + for (unsigned int j = 0; j < midi_buffer->event_count; j++) { + JackMidiEvent* ev = &midi_buffer->events[j]; + if (ev->size <= 3) { + MMRESULT res = midiOutShortMsg((HMIDIOUT)fMidiSource[chan].fHandle, *((DWORD*)ev->GetData(midi_buffer))); + if (res != MMSYSERR_NOERROR) + jack_error ("midiOutShortMsg error res %d", res); + } else { + + } + } + } + } + + return 0; +} + +} // end of namespace + +#ifdef __cplusplus +extern "C" +{ +#endif + + SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor() + { + jack_driver_desc_t * desc; + unsigned int i; + + desc = (jack_driver_desc_t*)calloc (1, sizeof (jack_driver_desc_t)); + strcpy(desc->name, "winmme"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 + strcpy(desc->desc, "WinMME API based MIDI backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 + + desc->nparams = 0; + desc->params = (jack_driver_param_desc_t*)calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); + + return desc; + } + + SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) + { + /* + unsigned int capture_ports = 2; + unsigned int playback_ports = 2; + unsigned long wait_time = 0; + const JSList * node; + const jack_driver_param_t * param; + bool monitor = false; + + for (node = params; node; node = jack_slist_next (node)) { + param = (const jack_driver_param_t *) node->data; + + switch (param->character) { + + case 'C': + capture_ports = param->value.ui; + break; + + case 'P': + playback_ports = param->value.ui; + break; + + case 'r': + sample_rate = param->value.ui; + break; + + case 'p': + period_size = param->value.ui; + break; + + case 'w': + wait_time = param->value.ui; + break; + + case 'm': + monitor = param->value.i; + break; + } + } + */ + + Jack::JackDriverClientInterface* driver = new Jack::JackWinMMEDriver("system_midi", "winmme", engine, table); + if (driver->Open(1, 1, 0, 0, false, "in", "out", 0, 0) == 0) { + return driver; + } else { + delete driver; + return NULL; + } + } + +#ifdef __cplusplus +} +#endif + + +/* +jack_connect system:midi_capture_1 system_midi:playback_1 +jack_connect system:midi_capture_1 system_midi:playback_2 + +jack_connect system:midi_capture_1 system_midi:playback_1 + +jack_connect system:midi_capture_1 system_midi:playback_1 + +jack_connect system:midi_capture_1 system_midi:playback_1 + +jack_connect system_midi:capture_1 system:midi_playback_1 +jack_connect system_midi:capture_2 system:midi_playback_1 + +jack_connect system_midi:capture_1 system_midi:playback_1 + +*/ diff --git a/windows/winmme/JackWinMMEDriver.h b/windows/winmme/JackWinMMEDriver.h new file mode 100644 index 00000000..6c28a0ef --- /dev/null +++ b/windows/winmme/JackWinMMEDriver.h @@ -0,0 +1,87 @@ +/* +Copyright (C) 2009 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 __JackWinMMEDriver__ +#define __JackWinMMEDriver__ + +#include "JackMidiDriver.h" +#include "JackTime.h" + +namespace Jack +{ + +/*! +\brief The WinMME driver. +*/ + +#define kBuffSize 512 + +struct MidiSlot { + + LPVOID fHandle; // MMSystem handler + short fIndex; // MMSystem dev index + LPMIDIHDR fHeader; // for long msg output + + MidiSlot():fHandle(0),fIndex(0) + {} + +}; + +class JackWinMMEDriver : public JackMidiDriver +{ + + private: + + int fRealCaptureChannels; + int fRealPlaybackChannels; + + MidiSlot* fMidiSource; + MidiSlot* fMidiDestination; + + void CloseInput(MidiSlot* slot); + void CloseOutput(MidiSlot* slot); + + static void CALLBACK MidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2); + + public: + + JackWinMMEDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); + virtual ~JackWinMMEDriver(); + + int Open(bool capturing, + bool playing, + int chan_in, + int chan_out, + bool monitor, + const char* capture_driver_name, + const char* playback_driver_name, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency); + int Close(); + + int Attach(); + + int Read(); + int Write(); + +}; + +} // end of namespace + +#endif From b4f737eb1b5b9fea320cb3b5a47b6f90efaa4c2f Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 6 May 2009 09:58:04 +0000 Subject: [PATCH 017/472] rebase from trunk 3502:3528 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3529 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 69 ++++-- common/JackAPI.cpp | 2 +- common/JackClient.cpp | 53 +++-- common/JackClient.h | 1 + common/JackConnectionManager.cpp | 13 +- common/JackConstants.h | 2 - common/JackControlAPI.cpp | 33 ++- common/JackControlAPI.h | 7 +- common/JackDriver.cpp | 7 +- common/JackDriver.h | 6 + common/JackEngine.cpp | 8 +- common/JackEngineControl.cpp | 2 +- common/JackEngineControl.h | 8 +- common/JackEngineProfiling.cpp | 4 +- common/JackLibClient.cpp | 1 + common/JackServer.cpp | 75 ++++-- common/JackServer.h | 8 +- common/JackServerGlobals.cpp | 23 +- common/JackServerGlobals.h | 7 +- common/JackThreadedDriver.cpp | 5 + common/JackThreadedDriver.h | 1 + common/JackTime.h | 9 +- common/JackTransportEngine.cpp | 10 +- common/JackTypes.h | 11 +- common/Jackdmp.cpp | 37 ++- common/jack/control.h | 33 ++- common/wscript | 1 + dbus/audio_reserve.c | 4 +- dbus/controller.c | 16 ++ dbus/controller_iface_control.c | 15 ++ dbus/controller_internal.h | 5 + example-clients/jack_control | 4 + example-clients/server_control.cpp | 47 +++- linux/JackLinuxTime.c | 289 ++++++++++++++++++----- linux/alsa/JackAlsaDriver.cpp | 22 +- linux/cycles.h | 14 ++ macosx/JackMacEngineRPC.cpp | 2 +- macosx/JackMachTime.c | 9 + macosx/Jackdmp.xcodeproj/project.pbxproj | 4 + macosx/coreaudio/JackCoreAudioDriver.cpp | 180 +++++++++++++- macosx/coreaudio/JackCoreAudioDriver.h | 1 + solaris/JackSolarisTime.c | 8 + windows/JackTypes_os.h | 6 +- windows/JackWinNamedPipe.cpp | 2 +- windows/JackWinTime.c | 18 +- windows/jackd.workspace | 4 +- 46 files changed, 888 insertions(+), 198 deletions(-) diff --git a/ChangeLog b/ChangeLog index 910775b0..c0598e0d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,50 +18,71 @@ Fernando Lopez-Lezcano Romain Moret Florian Faber Michael Voigt -Torben Hohn +Torben Hohn Paul Davis --------------------------- Jackdmp changes log ---------------------------- - -2009-04-08 Stephane Letz +--------------------------- - * Native MIDI backend (JackCoreMidiDriver, JackWinMMEDriver) in progress. +2009-05-06 Stephane Letz + + * Fix transport callback (timebase master, sync) issue when used after jack_activate (RT thread was not running). -2009-04-03 Stephane Letz +2009-05-05 Stephane Letz + + * First working version of native MIDI backend (JackCoreMidiDriver, JackWinMMEDriver). - * Simplify JackClient RT code, jack_thread_wait API marked deprecated." +2009-04-22 Stephane Letz + + * jackctl_server_load_master renamed to jackctl_server_switch_master, jackctl_server_unload_master is removed. +2009-04-21 Stephane Letz + + * Add jackctl_server_load_master/jackctl_server_unload_master API. + +2009-04-20 Stephane Letz + + * In ALSA audio card reservation code, tries to open the card even if reservation fails. + * Clock source setting on Linux. + +2009-04-08 Stephane Letz + + * Native MIDI backend (JackCoreMidiDriver, JackWinMMEDriver) in progress. + +2009-04-03 Stephane Letz + + * Simplify JackClient RT code, jack_thread_wait API marked deprecated." + 2009-03-29 Stephane Letz - - * Cleanup JackInternalClient code. - + + * Cleanup JackInternalClient code. + 2009-03-27 Stephane Letz - - * Add a buffer size callback for netmaster that just remove the client (it will be recreated with the new parameters). - + + * Add a buffer size callback for netmaster that just remove the client (it will be recreated with the new parameters). + 2009-03-26 Stephane Letz - - * First working JackBoomerDriver two threads version. - + + * First working JackBoomerDriver two threads version. + 2009-03-24 Stephane Letz - - * New JackBoomerDriver class for Boomer driver on Solaris. + + * New JackBoomerDriver class for Boomer driver on Solaris. * Add mixed 32/64 bits mode (off by default). - + 2009-03-23 Stephane Letz - + * Version 1.9.3 started. - + 2009-03-19 Stephane Letz - + * Tim Blechmann optimization patch (inlining some heavy used methods). - + 2009-03-12 Stephane Letz * Virtualize and allow overriding of thread creation function, to allow Wine support (from JACK1). - + 2009-03-12 Stephane Letz * Try automatic adaptative mode in adapters. diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index 519cb4c5..c8a85f1b 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -843,7 +843,7 @@ EXPORT jack_nframes_t jack_thread_wait(jack_client_t* ext_client, int status) return 0; } else { jack_error("jack_thread_wait: deprecated, use jack_cycle_wait/jack_cycle_signal"); - return -1; + return 0; } } diff --git a/common/JackClient.cpp b/common/JackClient.cpp index 5bc45334..75beefbc 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -118,14 +118,13 @@ void JackClient::SetupDriverSync(bool freewheel) { if (!freewheel && !GetEngineControl()->fSyncMode) { jack_log("JackClient::SetupDriverSync driver sem in flush mode"); - fSynchroTable[AUDIO_DRIVER_REFNUM].SetFlush(true); - fSynchroTable[FREEWHEEL_DRIVER_REFNUM].SetFlush(true); - fSynchroTable[MIDI_DRIVER_REFNUM].SetFlush(true); + for (int i = 0; i < GetEngineControl()->fDriverNum; i++) { + fSynchroTable[i].SetFlush(true); + } } else { jack_log("JackClient::SetupDriverSync driver sem in normal mode"); - fSynchroTable[AUDIO_DRIVER_REFNUM].SetFlush(false); - fSynchroTable[FREEWHEEL_DRIVER_REFNUM].SetFlush(false); - fSynchroTable[MIDI_DRIVER_REFNUM].SetFlush(false); + for (int i = 0; i < GetEngineControl()->fDriverNum; i++) + fSynchroTable[i].SetFlush(false); } } @@ -338,7 +337,7 @@ int JackClient::StartThread() // Will do "something" on OSX only... fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); - if (fThread.Start() < 0) { + if (fThread.StartSync() < 0) { jack_error("Start thread error"); return -1; } @@ -593,6 +592,27 @@ void JackClient::ShutDown() // Transport management //---------------------- +inline int JackClient::ActivateAux() +{ + // If activated without RT thread... + if (IsActive() && fThread.GetStatus() != JackThread::kRunning) { + + jack_log("ActivateAux"); + + // RT thread is started + if (StartThread() < 0) + return -1; + + int result = -1; + GetClientControl()->fCallback[kRealTimeCallback] = IsRealTime(); + fChannel->ClientActivate(GetClientControl()->fRefNum, IsRealTime(), &result); + return result; + + } else { + return 0; + } +} + int JackClient::ReleaseTimebase() { int result = -1; @@ -611,29 +631,30 @@ int JackClient::SetSyncCallback(JackSyncCallback sync_callback, void* arg) GetClientControl()->fTransportSync = (fSync != NULL); fSyncArg = arg; fSync = sync_callback; - return 0; -} - -int JackClient::SetSyncTimeout(jack_time_t timeout) -{ - GetEngineControl()->fTransport.SetSyncTimeout(timeout); - return 0; + return ActivateAux(); } int JackClient::SetTimebaseCallback(int conditional, JackTimebaseCallback timebase_callback, void* arg) { int result = -1; fChannel->SetTimebaseCallback(GetClientControl()->fRefNum, conditional, &result); - jack_log("SetTimebaseCallback result = %ld", result); + if (result == 0) { GetClientControl()->fTransportTimebase = true; fTimebase = timebase_callback; fTimebaseArg = arg; + return ActivateAux(); } else { fTimebase = NULL; fTimebaseArg = NULL; + return -1; } - return result; +} + +int JackClient::SetSyncTimeout(jack_time_t timeout) +{ + GetEngineControl()->fTransport.SetSyncTimeout(timeout); + return 0; } // Must be RT safe diff --git a/common/JackClient.h b/common/JackClient.h index f41d734f..73ee17fc 100644 --- a/common/JackClient.h +++ b/common/JackClient.h @@ -108,6 +108,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface inline void CycleSignalAux(int status); inline void CallSyncCallbackAux(); inline void CallTimebaseCallbackAux(); + inline int ActivateAux(); public: diff --git a/common/JackConnectionManager.cpp b/common/JackConnectionManager.cpp index 08fa92ca..043b0c81 100644 --- a/common/JackConnectionManager.cpp +++ b/common/JackConnectionManager.cpp @@ -17,11 +17,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include -#include #include "JackConnectionManager.h" #include "JackClientControl.h" +#include "JackEngineControl.h" +#include "JackGlobals.h" #include "JackError.h" +#include +#include namespace Jack { @@ -54,12 +56,7 @@ bool JackConnectionManager::IsLoopPathAux(int ref1, int ref2) const { jack_log("JackConnectionManager::IsLoopPathAux ref1 = %ld ref2 = %ld", ref1, ref2); - if (ref1 == AUDIO_DRIVER_REFNUM // Driver is reached - || ref2 == AUDIO_DRIVER_REFNUM - || ref1 == FREEWHEEL_DRIVER_REFNUM - || ref2 == FREEWHEEL_DRIVER_REFNUM - || ref1 == MIDI_DRIVER_REFNUM - || ref2 == MIDI_DRIVER_REFNUM) { + if (ref1 < GetEngineControl()->fDriverNum || ref2 < GetEngineControl()->fDriverNum) { return false; } else if (ref1 == ref2) { // Same refnum return true; diff --git a/common/JackConstants.h b/common/JackConstants.h index fbc552a7..0e05c058 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -49,8 +49,6 @@ #define AUDIO_DRIVER_REFNUM 0 // Audio driver is initialized first, it will get the refnum 0 #define FREEWHEEL_DRIVER_REFNUM 1 // Freewheel driver is initialized second, it will get the refnum 1 -#define MIDI_DRIVER_REFNUM 2 // Loopback driver is initialized third, it will get the refnum 2 -#define REAL_REFNUM MIDI_DRIVER_REFNUM + 1 // Real clients start at MIDI_DRIVER_REFNUM + 1 #define JACK_DEFAULT_SERVER_NAME "default" diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index 8a0a36b6..6199b13d 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -81,6 +81,10 @@ struct jackctl_server /* uint32_t, ports of the loopback driver */ union jackctl_parameter_value loopback_ports; union jackctl_parameter_value default_loopback_ports; + + /* uint32_t, clock source type */ + union jackctl_parameter_value clock_source; + union jackctl_parameter_value default_clock_source; /* bool */ union jackctl_parameter_value replace_registry; @@ -733,6 +737,20 @@ EXPORT jackctl_server_t * jackctl_server_create() { goto fail_free_parameters; } + + value.ui = 0; + if (jackctl_add_parameter( + &server_ptr->parameters, + "clock-source", + "Clocksource type : c(ycle) | h(pet) | s(ystem)", + "", + JackParamUInt, + &server_ptr->clock_source, + &server_ptr->default_clock_source, + value) == NULL) + { + goto fail_free_parameters; + } value.b = false; if (jackctl_add_parameter( @@ -864,6 +882,7 @@ jackctl_server_start( server_ptr->realtime_priority.i, server_ptr->loopback_ports.ui, server_ptr->verbose.b, + (jack_timer_type_t)server_ptr->clock_source.ui, server_ptr->name.str); if (server_ptr->engine == NULL) { @@ -1163,7 +1182,7 @@ EXPORT bool jackctl_server_unload_internal( } } -EXPORT bool jackctl_server_load_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr) +EXPORT bool jackctl_server_add_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr) { if (server_ptr->engine != NULL) { driver_ptr->info = server_ptr->engine->AddSlave(driver_ptr->desc_ptr, driver_ptr->set_parameters); @@ -1173,13 +1192,23 @@ EXPORT bool jackctl_server_load_slave(jackctl_server * server_ptr, jackctl_drive } } -EXPORT bool jackctl_server_unload_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr) +EXPORT bool jackctl_server_remove_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr) { if (server_ptr->engine != NULL) { server_ptr->engine->RemoveSlave(driver_ptr->info); + delete driver_ptr->info; return true; } else { return false; } } +EXPORT bool jackctl_server_switch_master(jackctl_server * server_ptr, jackctl_driver * driver_ptr) +{ + if (server_ptr->engine != NULL) { + return (server_ptr->engine->SwitchMaster(driver_ptr->desc_ptr, driver_ptr->set_parameters) == 0); + } else { + return false; + } +} + diff --git a/common/JackControlAPI.h b/common/JackControlAPI.h index 54be6f3f..8046c63d 100644 --- a/common/JackControlAPI.h +++ b/common/JackControlAPI.h @@ -220,12 +220,15 @@ EXPORT bool jackctl_server_unload_internal( jackctl_server * server, jackctl_internal * internal); -EXPORT bool jackctl_server_load_slave(jackctl_server_t * server, +EXPORT bool jackctl_server_add_slave(jackctl_server_t * server, jackctl_driver_t * driver); -EXPORT bool jackctl_server_unload_slave(jackctl_server_t * server, +EXPORT bool jackctl_server_remove_slave(jackctl_server_t * server, jackctl_driver_t * driver); +EXPORT bool +jackctl_server_switch_master(jackctl_server_t * server, + jackctl_driver_t * driver); #if 0 { /* Adjust editor indent */ diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index f5098771..5a2092c8 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -47,7 +47,7 @@ JackDriver::JackDriver(const char* name, const char* alias, JackLockedEngine* en fBeginDateUst = 0; fDelayedUsecs = 0.f; fIsMaster = true; -} + } JackDriver::JackDriver() { @@ -74,6 +74,7 @@ int JackDriver::Open() fClientControl.fRefNum = refnum; fClientControl.fActive = true; + fEngineControl->fDriverNum++; fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum); // Connect driver to itself for "sync" mode SetupDriverSync(fClientControl.fRefNum, false); return 0; @@ -100,6 +101,7 @@ int JackDriver::Open (bool capturing, fClientControl.fRefNum = refnum; fClientControl.fActive = true; + fEngineControl->fDriverNum++; fCaptureLatency = capture_latency; fPlaybackLatency = playback_latency; @@ -113,7 +115,6 @@ int JackDriver::Open (bool capturing, if (!fEngineControl->fTimeOut) fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs); - //fGraphManager->SetBufferSize(fEngineControl->fBufferSize); fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum); // Connect driver to itself for "sync" mode SetupDriverSync(fClientControl.fRefNum, false); return 0; @@ -142,6 +143,7 @@ int JackDriver::Open(jack_nframes_t buffer_size, fClientControl.fRefNum = refnum; fClientControl.fActive = true; + fEngineControl->fDriverNum++; fEngineControl->fBufferSize = buffer_size; fEngineControl->fSampleRate = samplerate; fCaptureLatency = capture_latency; @@ -168,6 +170,7 @@ int JackDriver::Close() jack_log("JackDriver::Close"); fGraphManager->DirectDisconnect(fClientControl.fRefNum, fClientControl.fRefNum); // Disconnect driver from itself for sync fClientControl.fActive = false; + fEngineControl->fDriverNum--; return fEngine->ClientInternalClose(fClientControl.fRefNum, false); } diff --git a/common/JackDriver.h b/common/JackDriver.h index 9c99d7c4..c7e9ff72 100644 --- a/common/JackDriver.h +++ b/common/JackDriver.h @@ -93,6 +93,7 @@ class SERVER_EXPORT JackDriverInterface 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; @@ -148,8 +149,13 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface void SetMaster(bool onoff); bool GetMaster(); + void AddSlave(JackDriverInterface* slave); void RemoveSlave(JackDriverInterface* slave); + std::list GetSlaves() + { + return fSlaveList; + } int ProcessSlaves(); virtual int Open(); diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index 16c75589..7e94e42f 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -27,6 +27,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackInternalClient.h" #include "JackEngineControl.h" #include "JackClientControl.h" +#include "JackServerGlobals.h" #include "JackGlobals.h" #include "JackChannel.h" #include "JackError.h" @@ -71,7 +72,7 @@ int JackEngine::Close() fChannel.Close(); // Close remaining clients (RT is stopped) - for (int i = REAL_REFNUM; i < CLIENT_NUM; i++) { + for (int i = fEngineControl->fDriverNum; i < CLIENT_NUM; i++) { if (JackLoadableInternalClient* loadable_client = dynamic_cast(fClientTable[i])) { jack_log("JackEngine::Close loadable client = %s", loadable_client->GetClientControl()->fName); loadable_client->Close(); @@ -110,7 +111,7 @@ void JackEngine::ReleaseRefnum(int ref) if (fEngineControl->fTemporary) { int i; - for (i = REAL_REFNUM; i < CLIENT_NUM; i++) { + for (i = fEngineControl->fDriverNum; i < CLIENT_NUM; i++) { if (fClientTable[i]) break; } @@ -180,7 +181,7 @@ correctly mixed in the time window: callbackUsecs <==> Read <==> Write. void JackEngine::CheckXRun(jack_time_t callback_usecs) // REVOIR les conditions de fin { - for (int i = REAL_REFNUM; i < CLIENT_NUM; i++) { + for (int i = fEngineControl->fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = fClientTable[i]; if (client && client->GetClientControl()->fActive) { JackClientTiming* timing = fGraphManager->GetClientTiming(i); @@ -236,6 +237,7 @@ void JackEngine::NotifyClients(int event, int sync, int value1, int value2) int JackEngine::NotifyAddClient(JackClientInterface* new_client, const char* name, int refnum) { + jack_log("JackEngine::NotifyAddClient: name = %s", name); // Notify existing clients of the new client and new client of existing clients. for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* old_client = fClientTable[i]; diff --git a/common/JackEngineControl.cpp b/common/JackEngineControl.cpp index 41cf71ef..872dcd32 100644 --- a/common/JackEngineControl.cpp +++ b/common/JackEngineControl.cpp @@ -44,7 +44,7 @@ void JackEngineControl::CalcCPULoad(JackClientInterface** table, // In Asynchronous mode, last cycle end is the max of client end dates if (!fSyncMode) { - for (int i = REAL_REFNUM; i < CLIENT_NUM; i++) { + for (int i = fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; JackClientTiming* timing = manager->GetClientTiming(i); if (client && client->GetClientControl()->fActive && timing->fStatus == Finished) diff --git a/common/JackEngineControl.h b/common/JackEngineControl.h index 5f8b604b..41c9c5b8 100644 --- a/common/JackEngineControl.h +++ b/common/JackEngineControl.h @@ -63,6 +63,8 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem int fMaxClientPriority; char fServerName[64]; JackTransportEngine fTransport; + jack_timer_type_t fClockSource; + int fDriverNum; bool fVerbose; // CPU Load @@ -88,7 +90,7 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem JackEngineProfiling fProfiler; #endif - JackEngineControl(bool sync, bool temporary, long timeout, bool rt, long priority, bool verbose, const char* server_name) + JackEngineControl(bool sync, bool temporary, long timeout, bool rt, long priority, bool verbose, jack_timer_type_t clock, const char* server_name) { fBufferSize = 512; fSampleRate = 48000; @@ -113,7 +115,9 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem fConstraint = 0; fMaxDelayedUsecs = 0.f; fXrunDelayedUsecs = 0.f; - } + fClockSource = clock; + fDriverNum = 0; + } ~JackEngineControl() {} diff --git a/common/JackEngineProfiling.cpp b/common/JackEngineProfiling.cpp index a0c81afe..b0a1b441 100644 --- a/common/JackEngineProfiling.cpp +++ b/common/JackEngineProfiling.cpp @@ -20,7 +20,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackEngineProfiling.h" #include "JackGraphManager.h" #include "JackClientControl.h" +#include "JackEngineControl.h" #include "JackClientInterface.h" +#include "JackGlobals.h" #include "JackTime.h" namespace Jack @@ -312,7 +314,7 @@ void JackEngineProfiling::Profile(JackClientInterface** table, fProfileTable[fAudioCycle].fPrevCycleEnd = prev_cycle_end; fProfileTable[fAudioCycle].fAudioCycle = fAudioCycle; - for (int i = REAL_REFNUM; i < CLIENT_NUM; i++) { + for (int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; JackClientTiming* timing = manager->GetClientTiming(i); if (client && client->GetClientControl()->fActive && client->GetClientControl()->fCallback[kRealTimeCallback]) { diff --git a/common/JackLibClient.cpp b/common/JackLibClient.cpp index f65148e9..ff6055e5 100644 --- a/common/JackLibClient.cpp +++ b/common/JackLibClient.cpp @@ -115,6 +115,7 @@ int JackLibClient::Open(const char* server_name, const char* name, jack_options_ JackGlobals::fClientTable[GetClientControl()->fRefNum] = this; JackGlobals::fServerRunning = true; + SetClockSource(GetEngineControl()->fClockSource); jack_log("JackLibClient::Open name = %s refnum = %ld", name_res, GetClientControl()->fRefNum); return 0; diff --git a/common/JackServer.cpp b/common/JackServer.cpp index a1f60edf..dd521a99 100644 --- a/common/JackServer.cpp +++ b/common/JackServer.cpp @@ -22,6 +22,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackServerGlobals.h" #include "JackTime.h" #include "JackFreewheelDriver.h" +#include "JackLoopbackDriver.h" +#include "JackDummyDriver.h" #include "JackThreadedDriver.h" #include "JackGlobals.h" #include "JackLockedEngine.h" @@ -37,7 +39,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { -JackServer::JackServer(bool sync, bool temporary, long timeout, bool rt, long priority, long loopback, bool verbose, const char* server_name) +JackServer::JackServer(bool sync, bool temporary, long timeout, bool rt, long priority, long loopback, bool verbose, jack_timer_type_t clock, const char* server_name) { if (rt) { jack_info("JACK server starting in realtime mode with priority %ld", priority); @@ -46,11 +48,13 @@ JackServer::JackServer(bool sync, bool temporary, long timeout, bool rt, long pr } fGraphManager = new JackGraphManager(); - fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, server_name); + fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, clock, server_name); fEngine = new JackLockedEngine(fGraphManager, GetSynchroTable(), fEngineControl); fFreewheelDriver = new JackThreadedDriver(new JackFreewheelDriver(fEngine, GetSynchroTable())); + fDriverInfo = new JackDriverInfo(); fAudioDriver = NULL; fFreewheel = false; + fLoopback = loopback; JackServerGlobals::fInstance = this; // Unique instance JackServerGlobals::fUserCount = 1; // One user jack_verbose = verbose; @@ -60,6 +64,7 @@ JackServer::~JackServer() { delete fGraphManager; delete fAudioDriver; + delete fDriverInfo; delete fFreewheelDriver; delete fEngine; delete fEngineControl; @@ -80,7 +85,7 @@ int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params) goto fail_close2; } - if ((fAudioDriver = fDriverInfo.Open(driver_desc, fEngine, GetSynchroTable(), driver_params)) == NULL) { + if ((fAudioDriver = fDriverInfo->Open(driver_desc, fEngine, GetSynchroTable(), driver_params)) == NULL) { jack_error("Cannot initialize driver"); goto fail_close3; } @@ -89,18 +94,19 @@ int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params) jack_error("Cannot open driver"); goto fail_close4; } - + if (fAudioDriver->Attach() != 0) { jack_error("Cannot attach audio driver"); goto fail_close5; } - + fFreewheelDriver->SetMaster(false); fAudioDriver->SetMaster(true); fAudioDriver->AddSlave(fFreewheelDriver); // After ??? InitTime(); + SetClockSource(fEngineControl->fClockSource); return 0; - + fail_close5: fFreewheelDriver->Close(); @@ -287,23 +293,64 @@ void JackServer::ClientKill(int refnum) JackDriverInfo* JackServer::AddSlave(jack_driver_desc_t* driver_desc, JSList* driver_params) { JackDriverInfo* info = new JackDriverInfo(); - JackDriverClientInterface* backend = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params); - if (backend == NULL) { + JackDriverClientInterface* slave = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params); + if (slave == NULL) { delete info; return NULL; } else { - backend->Attach(); - fAudioDriver->AddSlave(backend); + slave->Attach(); + fAudioDriver->AddSlave(slave); return info; } } void JackServer::RemoveSlave(JackDriverInfo* info) { - JackDriverClientInterface* backend = info->GetBackend(); - fAudioDriver->RemoveSlave(info->GetBackend()); - backend->Detach(); - backend->Close(); + JackDriverClientInterface* slave = info->GetBackend(); + fAudioDriver->RemoveSlave(slave); + slave->Detach(); + slave->Close(); +} + +int JackServer::SwitchMaster(jack_driver_desc_t* driver_desc, JSList* driver_params) +{ + /// Remove current master + fAudioDriver->Stop(); + fAudioDriver->Detach(); + fAudioDriver->Close(); + + // Open new master + JackDriverInfo* info = new JackDriverInfo(); + JackDriverClientInterface* master = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params); + + if (master == NULL || info == NULL) { + delete info; + delete master; + return -1; + } else { + + // Get slaves list + std::list slave_list = fAudioDriver->GetSlaves(); + std::list::const_iterator it; + + // Move slaves in new master + for (it = slave_list.begin(); it != slave_list.end(); it++) { + JackDriverInterface* slave = *it; + master->AddSlave(slave); + } + + // Delete old master + delete fAudioDriver; + delete fDriverInfo; + + // Activate master + fAudioDriver = master; + fDriverInfo = info; + fEngineControl->InitFrameTime(); + fAudioDriver->Attach(); + fAudioDriver->SetMaster(true); + return fAudioDriver->Start(); + } } //---------------------- diff --git a/common/JackServer.h b/common/JackServer.h index fb88101a..79e2fd40 100644 --- a/common/JackServer.h +++ b/common/JackServer.h @@ -47,7 +47,7 @@ class SERVER_EXPORT JackServer private: - JackDriverInfo fDriverInfo; + JackDriverInfo* fDriverInfo; JackDriverClientInterface* fAudioDriver; JackDriverClientInterface* fFreewheelDriver; JackLockedEngine* fEngine; @@ -57,12 +57,13 @@ class SERVER_EXPORT JackServer JackConnectionManager fConnectionState; JackSynchro fSynchroTable[CLIENT_NUM]; bool fFreewheel; + long fLoopback; int InternalClientLoadAux(JackLoadableInternalClient* client, const char* so_name, const char* client_name, int options, int* int_ref, int* status); public: - JackServer(bool sync, bool temporary, long timeout, bool rt, long priority, long loopback, bool verbose, const char* server_name); + JackServer(bool sync, bool temporary, long timeout, bool rt, long priority, long loopback, bool verbose, jack_timer_type_t clock, const char* server_name); ~JackServer(); int Open(jack_driver_desc_t* driver_desc, JSList* driver_params); @@ -88,7 +89,8 @@ class SERVER_EXPORT JackServer // Backend management JackDriverInfo* AddSlave(jack_driver_desc_t* driver_desc, JSList* driver_params); void RemoveSlave(JackDriverInfo* info); - + int SwitchMaster(jack_driver_desc_t* driver_desc, JSList* driver_params); + // Object access JackLockedEngine* GetEngine(); JackEngineControl* GetEngineControl(); diff --git a/common/JackServerGlobals.cpp b/common/JackServerGlobals.cpp index 612e3dc5..0dbe0cf2 100644 --- a/common/JackServerGlobals.cpp +++ b/common/JackServerGlobals.cpp @@ -40,10 +40,11 @@ int JackServerGlobals::Start(const char* server_name, int rt, int priority, int loopback, - int verbose) + int verbose, + jack_timer_type_t clock) { jack_log("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld ", sync, time_out_ms, rt, priority, verbose); - new JackServer(sync, temporary, time_out_ms, rt, priority, loopback, verbose, server_name); // Will setup fInstance and fUserCount globals + new JackServer(sync, temporary, time_out_ms, rt, priority, loopback, verbose, clock, server_name); // Will setup fInstance and fUserCount globals int res = fInstance->Open(driver_desc, driver_params); return (res < 0) ? res : fInstance->Start(); } @@ -92,6 +93,7 @@ bool JackServerGlobals::Init() char buffer[255]; int argc = 0; char* argv[32]; + jack_timer_type_t clock_source = JACK_TIMER_SYSTEM_CLOCK; // First user starts the server if (fUserCount++ == 0) { @@ -99,8 +101,9 @@ bool JackServerGlobals::Init() jack_log("JackServerGlobals Init"); jack_driver_desc_t* driver_desc; - const char *options = "-ad:P:uvshVRL:STFl:t:mn:p:"; + const char *options = "-ad:P:uvshVRL:STFl:t:mn:p:c:"; static struct option long_options[] = { + { "clock-source", 1, 0, 'c' }, { "driver", 1, 0, 'd' }, { "verbose", 0, 0, 'v' }, { "help", 0, 0, 'h' }, @@ -155,6 +158,18 @@ bool JackServerGlobals::Init() (opt = getopt_long(argc, argv, options, long_options, &option_index)) != EOF) { switch (opt) { + + case 'c': + if (tolower (optarg[0]) == 'h') { + clock_source = JACK_TIMER_HPET; + } else if (tolower (optarg[0]) == 'c') { + clock_source = JACK_TIMER_CYCLE_COUNTER; + } else if (tolower (optarg[0]) == 's') { + clock_source = JACK_TIMER_SYSTEM_CLOCK; + } else { + jack_error("unknown option character %c", optopt); + } + break; case 'd': seen_driver = 1; @@ -281,7 +296,7 @@ bool JackServerGlobals::Init() free(argv[i]); } - int res = Start(server_name, driver_desc, driver_params, sync, temporary, client_timeout, realtime, realtime_priority, loopback, verbose_aux); + int res = Start(server_name, driver_desc, driver_params, sync, temporary, client_timeout, realtime, realtime_priority, loopback, verbose_aux, clock_source); if (res < 0) { jack_error("Cannot start server... exit"); Delete(); diff --git a/common/JackServerGlobals.h b/common/JackServerGlobals.h index 736f9608..d2db8960 100644 --- a/common/JackServerGlobals.h +++ b/common/JackServerGlobals.h @@ -22,8 +22,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "driver_interface.h" #include "JackDriverLoader.h" +#include "JackCompilerDeps.h" #include "JackServer.h" -#include namespace Jack { @@ -44,7 +44,7 @@ struct SERVER_EXPORT JackServerGlobals static bool Init(); static void Destroy(); - static int Start(const char* server_name, + static int Start (const char* server_name, jack_driver_desc_t* driver_desc, JSList* driver_params, int sync, @@ -53,7 +53,8 @@ struct SERVER_EXPORT JackServerGlobals int rt, int priority, int loopback, - int verbose); + int verbose, + jack_timer_type_t clock); static void Stop(); static void Delete(); }; diff --git a/common/JackThreadedDriver.cpp b/common/JackThreadedDriver.cpp index 45fb1dc9..a1e16556 100644 --- a/common/JackThreadedDriver.cpp +++ b/common/JackThreadedDriver.cpp @@ -132,6 +132,11 @@ int JackThreadedDriver::ProcessSlaves() return fDriver->ProcessSlaves(); } +std::list JackThreadedDriver::GetSlaves() +{ + return fDriver->GetSlaves(); +} + int JackThreadedDriver::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2) { return fDriver->ClientNotify(refnum, name, notify, sync, value1, value2); diff --git a/common/JackThreadedDriver.h b/common/JackThreadedDriver.h index 8705e2c4..5949472d 100644 --- a/common/JackThreadedDriver.h +++ b/common/JackThreadedDriver.h @@ -91,6 +91,7 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi virtual bool GetMaster(); virtual void AddSlave(JackDriverInterface* slave); virtual void RemoveSlave(JackDriverInterface* slave); + virtual std::list GetSlaves(); virtual int ProcessSlaves(); virtual int ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2); diff --git a/common/JackTime.h b/common/JackTime.h index 77cc1894..10ef1e8c 100644 --- a/common/JackTime.h +++ b/common/JackTime.h @@ -23,15 +23,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "types.h" #include "JackCompilerDeps.h" +#include "JackTypes.h" #ifdef __cplusplus extern "C" { #endif - SERVER_EXPORT void InitTime(); - SERVER_EXPORT jack_time_t GetMicroSeconds(); - SERVER_EXPORT void JackSleep(long usec); + SERVER_EXPORT void InitTime(); + SERVER_EXPORT jack_time_t GetMicroSeconds(void); + SERVER_EXPORT void JackSleep(long usec); + SERVER_EXPORT void SetClockSource(jack_timer_type_t source); + SERVER_EXPORT const char* ClockSourceName(jack_timer_type_t source); #ifdef __cplusplus } diff --git a/common/JackTransportEngine.cpp b/common/JackTransportEngine.cpp index b0d100dc..40671af0 100644 --- a/common/JackTransportEngine.cpp +++ b/common/JackTransportEngine.cpp @@ -21,6 +21,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackTransportEngine.h" #include "JackClientInterface.h" #include "JackClientControl.h" +#include "JackEngineControl.h" +#include "JackGlobals.h" #include "JackError.h" #include "JackTime.h" #include @@ -89,7 +91,7 @@ int JackTransportEngine::SetTimebaseMaster(int refnum, bool conditionnal) // RT bool JackTransportEngine::CheckAllRolling(JackClientInterface** table) { - for (int i = REAL_REFNUM; i < CLIENT_NUM; i++) { + for (int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; if (client && client->GetClientControl()->fTransportState != JackTransportRolling) { jack_log("CheckAllRolling ref = %ld is not rolling", i); @@ -103,7 +105,7 @@ bool JackTransportEngine::CheckAllRolling(JackClientInterface** table) // RT void JackTransportEngine::MakeAllStartingLocating(JackClientInterface** table) { - for (int i = REAL_REFNUM; i < CLIENT_NUM; i++) { + for (int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; if (client) { JackClientControl* control = client->GetClientControl(); @@ -119,7 +121,7 @@ void JackTransportEngine::MakeAllStartingLocating(JackClientInterface** table) // RT void JackTransportEngine::MakeAllStopping(JackClientInterface** table) { - for (int i = REAL_REFNUM; i < CLIENT_NUM; i++) { + for (int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; if (client) { JackClientControl* control = client->GetClientControl(); @@ -134,7 +136,7 @@ void JackTransportEngine::MakeAllStopping(JackClientInterface** table) // RT void JackTransportEngine::MakeAllLocating(JackClientInterface** table) { - for (int i = REAL_REFNUM; i < CLIENT_NUM; i++) { + for (int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; if (client) { JackClientControl* control = client->GetClientControl(); diff --git a/common/JackTypes.h b/common/JackTypes.h index 00c09aad..234be17a 100644 --- a/common/JackTypes.h +++ b/common/JackTypes.h @@ -21,6 +21,8 @@ #ifndef __JackTypes__ #define __JackTypes__ +#include "JackCompilerDeps.h" + typedef unsigned short UInt16; #if __LP64__ typedef unsigned int UInt32; @@ -34,8 +36,11 @@ typedef signed long SInt32; typedef uint16_t jack_int_t; // Internal type for ports and refnum -namespace Jack -{ +typedef enum { + JACK_TIMER_SYSTEM_CLOCK, + JACK_TIMER_CYCLE_COUNTER, + JACK_TIMER_HPET, +} jack_timer_type_t; typedef enum { NotTriggered, @@ -44,6 +49,4 @@ typedef enum { Finished, } jack_client_state_t; -} - #endif diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index 8662a278..bd6a1230 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -97,6 +97,9 @@ static void usage(FILE* file) " [ --timeout OR -t client-timeout-in-msecs ]\n" " [ --midi OR -X midi-driver ]\n" " [ --verbose OR -v ]\n" +#ifdef __linux__ + " [ --clocksource OR -c [ c(ycle) | h(pet) | s(ystem) ]\n" +#endif " [ --replace-registry OR -r ]\n" " [ --silent OR -s ]\n" " [ --sync OR -S ]\n" @@ -156,8 +159,17 @@ int main(int argc, char* argv[]) const char* server_name = "default"; jackctl_driver_t * audio_driver_ctl; jackctl_driver_t * midi_driver_ctl; + +#ifdef __linux__ + const char *options = "-ad:X:P:uvrshVRL:STFl:t:mn:p:c:"; +#else const char *options = "-ad:X:P:uvrshVRL:STFl:t:mn:p:"; +#endif + struct option long_options[] = { +#ifdef __linux__ + { "clock-source", 1, 0, 'c' }, +#endif { "audio-driver", 1, 0, 'd' }, { "midi-driver", 1, 0, 'X' }, { "verbose", 0, 0, 'v' }, @@ -177,6 +189,7 @@ int main(int argc, char* argv[]) { "sync", 0, 0, 'S' }, { 0, 0, 0, 0 } }; + int i,opt = 0; int option_index = 0; bool seen_audio_driver = false; @@ -204,13 +217,33 @@ int main(int argc, char* argv[]) } server_parameters = jackctl_server_get_parameters(server_ctl); - opterr = 0; while (!seen_audio_driver && (opt = getopt_long(argc, argv, options, long_options, &option_index)) != EOF) { switch (opt) { + #ifdef __linux__ + case 'c': + param = jackctl_get_parameter(server_parameters, "clock-source"); + if (param != NULL) { + if (tolower (optarg[0]) == 'h') { + value.ui = JACK_TIMER_HPET; + jackctl_parameter_set_value(param, &value); + } else if (tolower (optarg[0]) == 'c') { + value.ui = JACK_TIMER_CYCLE_COUNTER; + jackctl_parameter_set_value(param, &value); + } else if (tolower (optarg[0]) == 's') { + value.ui = JACK_TIMER_SYSTEM_CLOCK; + jackctl_parameter_set_value(param, &value); + } else { + usage(stdout); + goto fail_free; + } + } + break; + #endif + case 'd': seen_audio_driver = true; audio_driver_name = optarg; @@ -382,7 +415,7 @@ int main(int argc, char* argv[]) goto fail_free; } - jackctl_server_load_slave(server_ctl, midi_driver_ctl); + jackctl_server_add_slave(server_ctl, midi_driver_ctl); } notify_server_start(server_name); diff --git a/common/jack/control.h b/common/jack/control.h index 87d62e72..a4935dff 100644 --- a/common/jack/control.h +++ b/common/jack/control.h @@ -510,13 +510,42 @@ jack_log( /* @} */ +/** + * Call this function to add a slave in the driver slave list. + * + * @param server server object handle + * @param driver driver to add in the driver slave list. + * + * @return success status: true - success, false - fail + */ +bool +jackctl_server_add_slave(jackctl_server_t * server, + jackctl_driver_t * driver); + +/** + * Call this function to remove a slave from the driver slave list. + * + * @param server server object handle + * @param driver driver to remove from the driver slave list. + * + * @return success status: true - success, false - fail + */ bool -jackctl_server_load_slave(jackctl_server_t * server, +jackctl_server_remove_slave(jackctl_server_t * server, jackctl_driver_t * driver); +/** + * Call this function to switch master driver. + * + * @param server server object handle + * @param driver driver to switch to + * + * @return success status: true - success, false - fail + */ bool -jackctl_server_unload_slave(jackctl_server_t * server, +jackctl_server_switch_master(jackctl_server_t * server, jackctl_driver_t * driver); + #if 0 { /* Adjust editor indent */ diff --git a/common/wscript b/common/wscript index 78641f48..ab59d7fa 100644 --- a/common/wscript +++ b/common/wscript @@ -131,6 +131,7 @@ def build(bld): 'JackNetTool.cpp', 'JackNetInterface.cpp', 'JackArgParser.cpp', + 'JackDummyDriver.cpp', ] if bld.env['IS_LINUX']: diff --git a/dbus/audio_reserve.c b/dbus/audio_reserve.c index cae5eac9..00412130 100644 --- a/dbus/audio_reserve.c +++ b/dbus/audio_reserve.c @@ -67,7 +67,7 @@ SERVER_EXPORT void* audio_acquire(int num) NULL, &error)) < 0) { - jack_error ("Failed to acquire device: %s\n", error.message ? error.message : strerror(-e)); + jack_error("Failed to acquire device name : %s error : %s", audio_name, (error.message ? error.message : strerror(-e))); return NULL; } @@ -89,5 +89,7 @@ SERVER_EXPORT void audio_release(void* dev) if (device) { jack_info("Release audio card"); rd_release(device); + } else { + jack_info("No audio card to release..."); } } diff --git a/dbus/controller.c b/dbus/controller.c index 110bf5d9..bd1c6a9b 100644 --- a/dbus/controller.c +++ b/dbus/controller.c @@ -263,6 +263,22 @@ jack_controller_stop_server( return TRUE; } +bool +jack_controller_switch_master( + struct jack_controller * controller_ptr, + void *dbus_call_context_ptr) +{ + if (!jackctl_server_switch_master( + controller_ptr->server, + controller_ptr->driver)) + { + jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to switch master"); + return FALSE; + } + + return TRUE; +} + void * jack_controller_create( DBusConnection *connection) diff --git a/dbus/controller_iface_control.c b/dbus/controller_iface_control.c index 5ad68391..fb0dab75 100644 --- a/dbus/controller_iface_control.c +++ b/dbus/controller_iface_control.c @@ -105,6 +105,17 @@ jack_control_run_method( jack_controller_control_send_signal_server_stopped(); } } + else if (strcmp (call->method_name, "SwitchMaster") == 0) + { + if (!jack_controller_switch_master(controller_ptr, call)) + { + jack_error ("Failed to switch master"); + } + else + { + jack_controller_control_send_signal_server_stopped(); + } + } else if (strcmp (call->method_name, "GetLoad") == 0) { if (!controller_ptr->started) @@ -252,6 +263,9 @@ JACK_DBUS_METHOD_ARGUMENTS_END JACK_DBUS_METHOD_ARGUMENTS_BEGIN(StopServer) JACK_DBUS_METHOD_ARGUMENTS_END +JACK_DBUS_METHOD_ARGUMENTS_BEGIN(SwitchMaster) +JACK_DBUS_METHOD_ARGUMENTS_END + JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetLoad) JACK_DBUS_METHOD_ARGUMENT("load", "d", true) JACK_DBUS_METHOD_ARGUMENTS_END @@ -295,6 +309,7 @@ JACK_DBUS_METHODS_BEGIN JACK_DBUS_METHOD_DESCRIBE(IsStarted, NULL) JACK_DBUS_METHOD_DESCRIBE(StartServer, NULL) JACK_DBUS_METHOD_DESCRIBE(StopServer, NULL) + JACK_DBUS_METHOD_DESCRIBE(SwitchMaster, NULL) JACK_DBUS_METHOD_DESCRIBE(GetLoad, NULL) JACK_DBUS_METHOD_DESCRIBE(GetXruns, NULL) JACK_DBUS_METHOD_DESCRIBE(GetSampleRate, NULL) diff --git a/dbus/controller_internal.h b/dbus/controller_internal.h index 4c4c9ed5..a4cef0f6 100644 --- a/dbus/controller_internal.h +++ b/dbus/controller_internal.h @@ -81,6 +81,11 @@ jack_controller_stop_server( struct jack_controller *controller_ptr, void *dbus_call_context_ptr); +bool +jack_controller_switch_master( + struct jack_controller *controller_ptr, + void *dbus_call_context_ptr); + bool jack_controller_select_driver( struct jack_controller *controller_ptr, diff --git a/example-clients/jack_control b/example-clients/jack_control index 42c1fc3c..c7b2dab5 100755 --- a/example-clients/jack_control +++ b/example-clients/jack_control @@ -109,6 +109,7 @@ def main(): print " status - check whether jack server is started, return value is 0 if runing and 1 otherwise" print " start - start jack server if not currently started" print " stop - stop jack server if currenly started" + print " sm - switch master to currently selected driver" print " dl - get list of available drivers" print " dg - get currently selected driver" print " ds - select driver" @@ -155,6 +156,9 @@ def main(): elif arg == 'stop': print "--- stop" control_iface.StopServer() + elif arg == 'sm': + print "--- switch master driver" + control_iface.SwitchMaster() elif arg == 'ism': if control_iface.IsManuallyActivated(): print "Manually activated" diff --git a/example-clients/server_control.cpp b/example-clients/server_control.cpp index 5be97531..c21492a3 100644 --- a/example-clients/server_control.cpp +++ b/example-clients/server_control.cpp @@ -53,6 +53,24 @@ static jackctl_internal_t * jackctl_server_get_internal(jackctl_server_t *server return NULL; } +static jackctl_parameter_t * +jackctl_get_parameter( + const JSList * parameters_list, + const char * parameter_name) +{ + while (parameters_list) + { + if (strcmp(jackctl_parameter_get_name((jackctl_parameter_t *)parameters_list->data), parameter_name) == 0) + { + return (jackctl_parameter_t *)parameters_list->data; + } + + parameters_list = jack_slist_next(parameters_list); + } + + return NULL; +} + static void print_value(union jackctl_parameter_value value, jackctl_param_type_t type) { switch (type) { @@ -152,6 +170,16 @@ int main(int argc, char *argv[]) server = jackctl_server_create(); parameters = jackctl_server_get_parameters(server); + /* + jackctl_parameter_t* param; + union jackctl_parameter_value value; + param = jackctl_get_parameter(parameters, "verbose"); + if (param != NULL) { + value.b = true; + jackctl_parameter_set_value(param, &value); + } + */ + printf("\n========================== \n"); printf("List of server parameters \n"); printf("========================== \n"); @@ -182,7 +210,24 @@ int main(int argc, char *argv[]) jackctl_server_start(server, jackctl_server_get_driver(server, driver_name)); jackctl_server_load_internal(server, jackctl_server_get_internal(server, client_name)); - + + /* + // Switch master test + + jackctl_driver_t* master; + + usleep(5000000); + printf("jackctl_server_load_master\n"); + master = jackctl_server_get_driver(server, "coreaudio"); + jackctl_server_switch_master(server, master); + + usleep(5000000); + printf("jackctl_server_load_master\n"); + master = jackctl_server_get_driver(server, "dummy"); + jackctl_server_switch_master(server, master); + + */ + signals = jackctl_setup_signals(0); jackctl_wait_signals(signals); diff --git a/linux/JackLinuxTime.c b/linux/JackLinuxTime.c index b6499d05..9679da6d 100644 --- a/linux/JackLinuxTime.c +++ b/linux/JackLinuxTime.c @@ -18,84 +18,249 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#if defined(HAVE_CONFIG_H) -#include "config.h" -#endif - +#include "JackConstants.h" #include "JackTime.h" +#include "JackTypes.h" +#include "JackError.h" +#include "cycles.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include -SERVER_EXPORT void JackSleep(long usec) +static jack_time_t __jack_cpu_mhz = 0; +jack_time_t (*_jack_get_microseconds)(void) = 0; + +#if defined(__gnu_linux__) && (defined(__i386__) || defined(__x86_64__)) +#define HPET_SUPPORT +#define HPET_MMAP_SIZE 1024 +#define HPET_CAPS 0x000 +#define HPET_PERIOD 0x004 +#define HPET_COUNTER 0x0f0 +#define HPET_CAPS_COUNTER_64BIT (1 << 13) +#if defined(__x86_64__) +typedef uint64_t hpet_counter_t; +#else +typedef uint32_t hpet_counter_t; +#endif +static int hpet_fd; +static unsigned char *hpet_ptr; +static uint32_t hpet_period; /* period length in femto secs */ +static uint64_t hpet_offset = 0; +static uint64_t hpet_wrap; +static hpet_counter_t hpet_previous = 0; +#endif /* defined(__gnu_linux__) && (__i386__ || __x86_64__) */ + +#ifdef HPET_SUPPORT + +static int jack_hpet_init () { - usleep(usec); + uint32_t hpet_caps; + + hpet_fd = open("/dev/hpet", O_RDONLY); + if (hpet_fd < 0) { + jack_error ("This system has no accessible HPET device (%s)", strerror (errno)); + return -1; + } + + hpet_ptr = (unsigned char *) mmap(NULL, HPET_MMAP_SIZE, + PROT_READ, MAP_SHARED, hpet_fd, 0); + if (hpet_ptr == MAP_FAILED) { + jack_error ("This system has no mappable HPET device (%s)", strerror (errno)); + close (hpet_fd); + return -1; + } + + /* this assumes period to be constant. if needed, + it can be moved to the clock access function + */ + hpet_period = *((uint32_t *) (hpet_ptr + HPET_PERIOD)); + hpet_caps = *((uint32_t *) (hpet_ptr + HPET_CAPS)); + hpet_wrap = ((hpet_caps & HPET_CAPS_COUNTER_64BIT) && + (sizeof(hpet_counter_t) == sizeof(uint64_t))) ? + 0 : ((uint64_t) 1 << 32); + + return 0; +} + +static jack_time_t jack_get_microseconds_from_hpet (void) +{ + hpet_counter_t hpet_counter; + long double hpet_time; + + hpet_counter = *((hpet_counter_t *) (hpet_ptr + HPET_COUNTER)); + if (hpet_counter < hpet_previous) + hpet_offset += hpet_wrap; + hpet_previous = hpet_counter; + hpet_time = (long double) (hpet_offset + hpet_counter) * + (long double) hpet_period * (long double) 1e-9; + return ((jack_time_t) (hpet_time + 0.5)); } -#ifdef GETCYCLE_TIME +#else + +static int jack_hpet_init () +{ + jack_error ("This version of JACK or this computer does not have HPET support.\n" + "Please choose a different clock source."); + return -1; +} + +static jack_time_t jack_get_microseconds_from_hpet (void) +{ + /* never called */ + return 0; +} + +#endif /* HPET_SUPPORT */ + +static jack_time_t jack_get_microseconds_from_cycles (void) { + return get_cycles() / __jack_cpu_mhz; +} - #include - #include "cycles.h" +/* + * This is another kludge. It looks CPU-dependent, but actually it + * reflects the lack of standards for the Linux kernel formatting of + * /proc/cpuinfo. + */ - static jack_time_t __jack_cpu_mhz; +static jack_time_t jack_get_mhz (void) +{ + FILE *f = fopen("/proc/cpuinfo", "r"); + if (f == 0) + { + perror("can't open /proc/cpuinfo\n"); + exit(1); + } - static inline jack_time_t GetMhz(void) + for ( ; ; ) { - FILE *f = fopen("/proc/cpuinfo", "r"); - if (f == 0) { - perror("can't open /proc/cpuinfo\n"); + jack_time_t mhz; + int ret; + char buf[1000]; + + if (fgets(buf, sizeof(buf), f) == NULL) { + jack_error ("FATAL: cannot locate cpu MHz in " + "/proc/cpuinfo\n"); exit(1); } - - for (;;) { - jack_time_t mhz; - int ret; - char buf[1000]; - - if (fgets(buf, sizeof(buf), f) == NULL) { - jack_error("FATAL: cannot locate cpu MHz in /proc/cpuinfo\n"); - exit(1); - } - - #if defined(__powerpc__) - ret = sscanf(buf, "clock\t: %" SCNu64 "MHz", &mhz); - #elif defined( __i386__ ) || defined (__hppa__) || defined (__ia64__) || \ - defined(__x86_64__) - ret = sscanf(buf, "cpu MHz : %" SCNu64, &mhz); - #elif defined( __sparc__ ) - ret = sscanf(buf, "Cpu0Bogo : %" SCNu64, &mhz); - #elif defined( __mc68000__ ) - ret = sscanf(buf, "Clocking: %" SCNu64, &mhz); - #elif defined( __s390__ ) - ret = sscanf(buf, "bogomips per cpu: %" SCNu64, &mhz); - #else /* MIPS, ARM, alpha */ - ret = sscanf(buf, "BogoMIPS : %" SCNu64, &mhz); - #endif - if (ret == 1) { - fclose(f); - return (jack_time_t)mhz; - } + +#if defined(__powerpc__) + ret = sscanf(buf, "clock\t: %" SCNu64 "MHz", &mhz); +#elif defined( __i386__ ) || defined (__hppa__) || defined (__ia64__) || \ + defined(__x86_64__) + ret = sscanf(buf, "cpu MHz : %" SCNu64, &mhz); +#elif defined( __sparc__ ) + ret = sscanf(buf, "Cpu0Bogo : %" SCNu64, &mhz); +#elif defined( __mc68000__ ) + ret = sscanf(buf, "Clocking: %" SCNu64, &mhz); +#elif defined( __s390__ ) + ret = sscanf(buf, "bogomips per cpu: %" SCNu64, &mhz); +#else /* MIPS, ARM, alpha */ + ret = sscanf(buf, "BogoMIPS : %" SCNu64, &mhz); +#endif + + if (ret == 1) + { + fclose(f); + return (jack_time_t)mhz; } } +} + +#define HAVE_CLOCK_GETTIME 1 + +#ifndef HAVE_CLOCK_GETTIME + +static jack_time_t jack_get_microseconds_from_system (void) +{ + jack_time_t jackTime; + struct timeval tv; + + gettimeofday (&tv, NULL); + jackTime = (jack_time_t) tv.tv_sec * 1000000 + (jack_time_t) tv.tv_usec; + return jackTime; +} - SERVER_EXPORT void InitTime() - { - __jack_cpu_mhz = GetMhz(); - } - - SERVER_EXPORT jack_time_t GetMicroSeconds(void) - { - return get_cycles() / __jack_cpu_mhz; - } #else - #include - SERVER_EXPORT void InitTime() - {} - - SERVER_EXPORT jack_time_t GetMicroSeconds(void) +static jack_time_t jack_get_microseconds_from_system (void) +{ + jack_time_t jackTime; + struct timespec time; + + clock_gettime(CLOCK_MONOTONIC, &time); + jackTime = (jack_time_t) time.tv_sec * 1e6 + + (jack_time_t) time.tv_nsec / 1e3; + return jackTime; +} + +#endif /* HAVE_CLOCK_GETTIME */ + + +SERVER_EXPORT void JackSleep(long usec) +{ + usleep(usec); +} + +SERVER_EXPORT void InitTime() +{ + __jack_cpu_mhz = jack_get_mhz (); +} + +SERVER_EXPORT void SetClockSource(jack_timer_type_t source) +{ + jack_log("Clock source : %s", ClockSourceName(source)); + + switch (source) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (jack_time_t)ts.tv_sec * 1000000 + ts.tv_nsec / 1000; + case JACK_TIMER_CYCLE_COUNTER: + _jack_get_microseconds = jack_get_microseconds_from_cycles; + break; + + case JACK_TIMER_HPET: + if (jack_hpet_init () == 0) { + _jack_get_microseconds = jack_get_microseconds_from_hpet; + } else { + _jack_get_microseconds = jack_get_microseconds_from_system; + } + break; + + case JACK_TIMER_SYSTEM_CLOCK: + default: + _jack_get_microseconds = jack_get_microseconds_from_system; + break; } - -#endif +} + +SERVER_EXPORT const char* ClockSourceName(jack_timer_type_t source) +{ + switch (source) { + case JACK_TIMER_CYCLE_COUNTER: + return "cycle counter"; + case JACK_TIMER_HPET: + return "hpet"; + case JACK_TIMER_SYSTEM_CLOCK: +#ifdef HAVE_CLOCK_GETTIME + return "system clock via clock_gettime"; +#else + return "system clock via gettimeofday"; +#endif + } + + /* what is wrong with gcc ? */ + return "unknown"; +} + +SERVER_EXPORT jack_time_t GetMicroSeconds() +{ + return _jack_get_microseconds(); +} diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index 455f73ca..7ed400d4 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -51,6 +51,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "audio_reserve.h" +//#define DEBUG_WAKEUP 1 + namespace Jack { @@ -1346,6 +1348,9 @@ JackAlsaDriver::alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *stat /* if POLLIN was the only bit set, we're OK */ *status = 0; + if (driver->pfd[nfds-1].revents == POLLIN) { + jack_error("driver->pfd[nfds-1].revents == POLLIN"); + } return (driver->pfd[nfds-1].revents == POLLIN) ? 0 : -1; } @@ -2191,21 +2196,18 @@ int JackAlsaDriver::Open(jack_nframes_t nframes, if (audio_reservation_init() < 0) { jack_error("Audio device reservation service not available...."); } else if (strcmp(capture_driver_name, playback_driver_name) == 0) { // Same device for input and output - fReservedCaptureDevice = audio_acquire(card_to_num(capture_driver_name)); - if (fReservedCaptureDevice == NULL) { - jack_error("Error audio device %s not available...", capture_driver_name); - return -1; + fReservedCaptureDevice = audio_acquire(card_to_num(capture_driver_name)); + if (fReservedCaptureDevice == NULL) { + jack_error("Error audio device %s cannot be acquired, trying to open it anyway...", capture_driver_name); } } else { fReservedCaptureDevice = audio_acquire(card_to_num(capture_driver_name)); if (fReservedCaptureDevice == NULL) { - jack_error("Error capture audio device %s not available...", capture_driver_name); - return -1; - } + jack_error("Error capture audio device %s cannot be acquired, trying to open it anyway...", capture_driver_name); + } fReservedPlaybackDevice = audio_acquire(card_to_num(playback_driver_name)); if (fReservedPlaybackDevice == NULL) { - jack_error("Error playback audio device %s not available...", playback_driver_name); - return -1; + jack_error("Error playback audio device %s cannot be acquired, trying to open it anyway...", playback_driver_name); } } #endif @@ -2277,7 +2279,7 @@ int JackAlsaDriver::Read() /* we detected an xrun and restarted: notify * clients about the delay. */ - jack_log("ALSA XRun"); + jack_log("ALSA XRun wait_status = %d", wait_status); NotifyXRun(fBeginDateUst, fDelayedUsecs); return -1; } diff --git a/linux/cycles.h b/linux/cycles.h index 2913b1da..51be192f 100644 --- a/linux/cycles.h +++ b/linux/cycles.h @@ -39,6 +39,20 @@ #ifdef __linux__ +#ifdef __x86_64__ + +typedef unsigned long cycles_t; +extern cycles_t cacheflush_time; + +static inline unsigned long get_cycles(void) +{ + unsigned int hi, lo; + __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); + return (((unsigned long)hi)<<32) | ((unsigned long)lo); +} + +#endif + #ifdef __PPC__ /* PowerPC */ diff --git a/macosx/JackMacEngineRPC.cpp b/macosx/JackMacEngineRPC.cpp index 0303eb77..7d28b619 100644 --- a/macosx/JackMacEngineRPC.cpp +++ b/macosx/JackMacEngineRPC.cpp @@ -42,7 +42,7 @@ rpc_type server_rpc_jack_client_check(mach_port_t private_port, client_name_t na rpc_type server_rpc_jack_client_open(mach_port_t server_port, client_name_t name, int pid, mach_port_t* private_port, int* shared_engine, int* shared_client, int* shared_graph, int* result) { - jack_log("rpc_jack_client_opne name = %s", name); + jack_log("rpc_jack_client_open name = %s", name); JackMachServerChannel* channel = JackMachServerChannel::fPortTable[server_port]; assert(channel); channel->ClientOpen((char*)name, pid, private_port, shared_engine, shared_client, shared_graph, result); diff --git a/macosx/JackMachTime.c b/macosx/JackMachTime.c index bd8237a6..c24ae313 100644 --- a/macosx/JackMachTime.c +++ b/macosx/JackMachTime.c @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackTime.h" #include "JackError.h" +#include "JackTypes.h" #include #include @@ -42,3 +43,11 @@ SERVER_EXPORT jack_time_t GetMicroSeconds(void) { return (jack_time_t) (mach_absolute_time () * __jack_time_ratio); } + +SERVER_EXPORT void SetClockSource(jack_timer_type_t source) +{} + +SERVER_EXPORT const char* ClockSourceName(jack_timer_type_t source) +{ + return ""; +} diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index b950f913..32ac3988 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -577,6 +577,8 @@ 4BF284190F31B4BC00B05BE3 /* JackArgParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF284170F31B4BC00B05BE3 /* JackArgParser.h */; }; 4BF2841A0F31B4BC00B05BE3 /* JackArgParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF284160F31B4BC00B05BE3 /* JackArgParser.cpp */; }; 4BF2841B0F31B4BC00B05BE3 /* JackArgParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF284170F31B4BC00B05BE3 /* JackArgParser.h */; }; + 4BF2F4210F9F4DA300B3FFAD /* JackDummyDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3988908B3CF6C00B6F371 /* JackDummyDriver.cpp */; }; + 4BF2F4220F9F4DA700B3FFAD /* JackDummyDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3988908B3CF6C00B6F371 /* JackDummyDriver.cpp */; }; 4BF339160F8B86DC0080FB5B /* JackCoreMidiDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF339140F8B86DC0080FB5B /* JackCoreMidiDriver.h */; }; 4BF339170F8B86DC0080FB5B /* JackCoreMidiDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF339150F8B86DC0080FB5B /* JackCoreMidiDriver.cpp */; }; 4BF339180F8B86DC0080FB5B /* JackCoreMidiDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF339140F8B86DC0080FB5B /* JackCoreMidiDriver.h */; }; @@ -5475,6 +5477,7 @@ 4BECB2FB0F4451C10091B70A /* JackProcessSync.cpp in Sources */, 4BF339190F8B86DC0080FB5B /* JackCoreMidiDriver.cpp in Sources */, 4BF339210F8B873E0080FB5B /* JackMidiDriver.cpp in Sources */, + 4BF2F4220F9F4DA700B3FFAD /* JackDummyDriver.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5855,6 +5858,7 @@ 4BBAE4110F42FA6100B8BD3F /* JackEngineProfiling.cpp in Sources */, 4BECB2F50F4451C10091B70A /* JackProcessSync.cpp in Sources */, 4BF339230F8B873E0080FB5B /* JackMidiDriver.cpp in Sources */, + 4BF2F4210F9F4DA300B3FFAD /* JackDummyDriver.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 1b2a3bfb..43655ad9 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -157,6 +157,14 @@ error: return err; } +static CFStringRef GetDeviceName(AudioDeviceID id) +{ + UInt32 size = sizeof(CFStringRef); + CFStringRef UIname; + OSStatus err = AudioDeviceGetProperty(id, 0, false, kAudioDevicePropertyDeviceUID, &size, &UIname); + return (err == noErr) ? UIname : NULL; +} + OSStatus JackCoreAudioDriver::Render(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, @@ -434,6 +442,136 @@ JackCoreAudioDriver::JackCoreAudioDriver(const char* name, const char* alias, Ja JackCoreAudioDriver::~JackCoreAudioDriver() {} +OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, AudioDeviceID* outAggregateDevice) +{ + OSStatus osErr = noErr; + UInt32 outSize; + Boolean outWritable; + + //----------------------- + // Start to create a new aggregate by getting the base audio hardware plugin + //----------------------- + + osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable); + if (osErr != noErr) + return osErr; + + AudioValueTranslation pluginAVT; + + CFStringRef inBundleRef = CFSTR("com.apple.audio.CoreAudio"); + AudioObjectID pluginID; + + pluginAVT.mInputData = &inBundleRef; + pluginAVT.mInputDataSize = sizeof(inBundleRef); + pluginAVT.mOutputData = &pluginID; + pluginAVT.mOutputDataSize = sizeof(pluginID); + + osErr = AudioHardwareGetProperty(kAudioHardwarePropertyPlugInForBundleID, &outSize, &pluginAVT); + if (osErr != noErr) + 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); + + //------------------------------------------------- + // Create a CFMutableArray for our sub-device list + //------------------------------------------------- + + CFStringRef captureDeviceUID = GetDeviceName(captureDeviceID); + CFStringRef playbackDeviceUID = GetDeviceName(playbackDeviceID); + + if (captureDeviceUID == NULL || playbackDeviceUID == NULL) + return -1; + + // we need to append the UID for each device to a CFMutableArray, so create one here + CFMutableArrayRef subDevicesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + + // two sub-devices in this example, so append the sub-device's UID to the CFArray + CFArrayAppendValue(subDevicesArray, captureDeviceUID); + CFArrayAppendValue(subDevicesArray, playbackDeviceUID); + + //----------------------------------------------------------------------- + // 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(pluginID, &pluginAOPA, 0, NULL, &outDataSize); + if (osErr != noErr) + return osErr; + + osErr = AudioObjectGetPropertyData(pluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice); + if (osErr != noErr) + return osErr; + + // 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; + outDataSize = sizeof(CFMutableArrayRef); + osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &subDevicesArray); + if (osErr != noErr) + return osErr; + + // 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; + pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; + pluginAOPA.mElement = kAudioObjectPropertyElementMaster; + outDataSize = sizeof(CFStringRef); + osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID); // capture is master... + if (osErr != noErr) + return osErr; + + // pause again to give the changes time to take effect + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); + + //---------- + // Clean up + //---------- + + // release the CF objects we have created - we don't need them any more + CFRelease(aggDeviceDict); + CFRelease(subDevicesArray); + + // release the device UID + CFRelease(captureDeviceUID); + CFRelease(playbackDeviceUID); + + jack_log("New aggregate device %ld", *outAggregateDevice); + return noErr; +} + int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, const char* playback_driver_uid, char* capture_driver_name, char* playback_driver_name) { capture_driver_name[0] = 0; @@ -442,16 +580,42 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, const char // Duplex if (strcmp(capture_driver_uid, "") != 0 && strcmp(playback_driver_uid, "") != 0) { jack_log("JackCoreAudioDriver::Open duplex"); - if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) { - jack_log("Will take default in/out"); - if (GetDefaultDevice(&fDeviceID) != noErr) { - jack_error("Cannot open default device"); + + /* + AudioDeviceID captureID, playbackID; + if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) + return -1; + if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) + return -1; + if (CreateAggregateDevice(captureID, playbackID, &fDeviceID) != noErr) + return -1; + */ + + // 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) { + jack_error("Cannot open default device"); + return -1; + } + } + if (GetDeviceNameFromID(fDeviceID, capture_driver_name) != noErr || GetDeviceNameFromID(fDeviceID, playback_driver_name) != noErr) { + jack_error("Cannot get device name from device ID"); return -1; } - } - if (GetDeviceNameFromID(fDeviceID, capture_driver_name) != noErr || GetDeviceNameFromID(fDeviceID, playback_driver_name) != noErr) { - jack_error("Cannot get device name from device ID"); - return -1; + + } else { + + // Creates agregate device + AudioDeviceID captureID, playbackID; + if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) + return -1; + if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) + return -1; + if (CreateAggregateDevice(captureID, playbackID, &fDeviceID) != noErr) + return -1; } // Capture only diff --git a/macosx/coreaudio/JackCoreAudioDriver.h b/macosx/coreaudio/JackCoreAudioDriver.h index f682c3c2..62de09fb 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.h +++ b/macosx/coreaudio/JackCoreAudioDriver.h @@ -115,6 +115,7 @@ class JackCoreAudioDriver : public JackAudioDriver OSStatus GetTotalChannels(AudioDeviceID device, int& channelCount, bool isInput); // Setup + OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, AudioDeviceID* outAggregateDevice); int SetupDevices(const char* capture_driver_uid, const char* playback_driver_uid, char* capture_driver_name, diff --git a/solaris/JackSolarisTime.c b/solaris/JackSolarisTime.c index 0cff5fff..46fa0fcf 100644 --- a/solaris/JackSolarisTime.c +++ b/solaris/JackSolarisTime.c @@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "JackTime.h" +#include "JackTypes.h" #include #include @@ -35,3 +36,10 @@ SERVER_EXPORT jack_time_t GetMicroSeconds(void) return (jack_time_t)(gethrtime() / 1000); } +SERVER_EXPORT void SetClockSource(jack_timer_type_t source) +{} + +SERVER_EXPORT const char* ClockSourceName(jack_timer_type_t source) +{ + return ""; +} diff --git a/windows/JackTypes_os.h b/windows/JackTypes_os.h index 9f8057b5..88a8bd8a 100644 --- a/windows/JackTypes_os.h +++ b/windows/JackTypes_os.h @@ -20,12 +20,12 @@ #ifndef __JackTypes_WIN32__ #define __JackTypes_WIN32__ -#include +#include +#include "types.h" typedef ULONGLONG UInt64; typedef unsigned short uint16_t; -typedef DWORD jack_tls_key; -typedef HANDLE pthread_t; +typedef DWORD jack_tls_key; #endif diff --git a/windows/JackWinNamedPipe.cpp b/windows/JackWinNamedPipe.cpp index c0279479..d3329055 100644 --- a/windows/JackWinNamedPipe.cpp +++ b/windows/JackWinNamedPipe.cpp @@ -119,7 +119,7 @@ JackWinAsyncNamedPipeClient::JackWinAsyncNamedPipeClient() fOverlap.hEvent = CreateEvent(NULL, // default security attribute TRUE, // manual-reset event TRUE, // initial state = signaled - NULL); // unnamed event object + NULL); // unnamed event object } JackWinAsyncNamedPipeClient::JackWinAsyncNamedPipeClient(HANDLE pipe, bool pending) diff --git a/windows/JackWinTime.c b/windows/JackWinTime.c index 4434f577..54da0411 100644 --- a/windows/JackWinTime.c +++ b/windows/JackWinTime.c @@ -13,18 +13,16 @@ 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. */ -#include #include "JackTime.h" -#include "JackError.h" static LARGE_INTEGER _jack_freq; -SERVER_EXPORT void JackSleep(long usec) +SERVER_EXPORT void JackSleep(long usec) { Sleep(usec / 1000); } @@ -35,9 +33,17 @@ SERVER_EXPORT void InitTime() _jack_freq.QuadPart = _jack_freq.QuadPart / 1000000; // by usec } -SERVER_EXPORT jack_time_t GetMicroSeconds(void) +SERVER_EXPORT jack_time_t GetMicroSeconds(void) { LARGE_INTEGER t1; QueryPerformanceCounter(&t1); - return (jack_time_t)(((double)t1.QuadPart) / ((double)_jack_freq.QuadPart)); + return (jack_time_t)(((double)t1.QuadPart) / ((double)_jack_freq.QuadPart)); +} + +SERVER_EXPORT void SetClockSource(jack_timer_type_t source) +{} + +SERVER_EXPORT const char* ClockSourceName(jack_timer_type_t source) +{ + return ""; } diff --git a/windows/jackd.workspace b/windows/jackd.workspace index 615bae3f..f8291cd2 100644 --- a/windows/jackd.workspace +++ b/windows/jackd.workspace @@ -1,7 +1,7 @@ - + @@ -46,6 +46,6 @@ - + From 7ca13a6b254d6d41930740a6087650f488550b59 Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 25 May 2009 13:04:22 +0000 Subject: [PATCH 018/472] rebase from trunk 3528:3550 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3551 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 24 ++- common/JackAPI.cpp | 6 + common/JackControlAPI.cpp | 31 +-- common/JackDriver.cpp | 1 + common/JackServer.cpp | 9 +- common/JackServer.h | 3 +- common/JackServerGlobals.cpp | 11 +- common/JackServerGlobals.h | 1 - common/jack/control.h | 229 +++++++++++----------- common/jack/jack.h | 10 + dbus/controller.c | 38 ++++ dbus/controller_iface_control.c | 49 +++++ dbus/controller_iface_patchbay.c | 6 +- dbus/controller_internal.h | 10 + linux/JackLinuxTime.c | 1 + linux/alsa/JackAlsaDriver.cpp | 1 + linux/firewire/JackFFADODriver.cpp | 71 +++---- linux/freebob/JackFreebobDriver.cpp | 1 + linux/wscript | 15 +- macosx/JackMachNotifyChannel.h | 1 - macosx/JackMachServerChannel.h | 1 - macosx/wscript | 17 +- posix/JackPosixServerLaunch.cpp | 34 ++-- posix/JackSocketServerChannel.h | 3 +- posix/JackSocketServerNotifyChannel.h | 1 - solaris/oss/JackBoomerDriver.cpp | 1 + windows/JackWinNamedPipeClientChannel.cpp | 5 +- windows/JackWinNamedPipeNotifyChannel.h | 1 - windows/JackWinNamedPipeServerChannel.h | 1 - windows/JackWinSemaphore.cpp | 6 +- windows/JackWinTime.c | 3 +- windows/Setup/JackRouter.dll | Bin 32768 -> 32768 bytes windows/winmme/JackWinMMEDriver.cpp | 4 +- wscript | 13 +- 34 files changed, 362 insertions(+), 246 deletions(-) diff --git a/ChangeLog b/ChangeLog index c0598e0d..ff7e9a47 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,9 +25,31 @@ Paul Davis Jackdmp changes log --------------------------- +2009-05-18 Stephane Letz + + * Correct wcsript files to create jackdbus only (and not create jackd anymore) when compiled in --dbus mode, add a --classic option. Both options are possible but issue a warning. + +2009-05-15 Stephane Letz + + * Move InitFrameTime in JackDriver::Start method. + +2009-05-13 Stephane Letz + + * Reworked Torben Hohn fix for server restart issue on Windows. + +2009-05-11 Stephane Letz + + * New jack_free function added in jack.h. + * Torben Hohn fix for InitTime and GetMicroSeconds in JackWinTime.c. + +2009-05-07 Stephane Letz + + * Cleanup "loopback" stuff in server. + 2009-05-06 Stephane Letz - * Fix transport callback (timebase master, sync) issue when used after jack_activate (RT thread was not running). + * Fix transport callback (timebase master, sync) issue when used after jack_activate (RT thread was not running). + * D-Bus access for jackctl_server_add_slave/jackctl_server_remove_slave API. 2009-05-05 Stephane Letz diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index c8a85f1b..3312c9f1 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -241,6 +241,7 @@ extern "C" EXPORT jack_status_t jack_internal_client_unload (jack_client_t *client, jack_intclient_t intclient); + EXPORT void jack_free(void* ptr); #ifdef __cplusplus } @@ -1930,3 +1931,8 @@ jack_get_version_string() { return VERSION; } + +EXPORT void jack_free(void* ptr) +{ + free(ptr); +} diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index 6199b13d..abd6d28a 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -77,10 +77,6 @@ struct jackctl_server /* int32_t, msecs; if zero, use period size. */ union jackctl_parameter_value client_timeout; union jackctl_parameter_value default_client_timeout; - - /* uint32_t, ports of the loopback driver */ - union jackctl_parameter_value loopback_ports; - union jackctl_parameter_value default_loopback_ports; /* uint32_t, clock source type */ union jackctl_parameter_value clock_source; @@ -643,7 +639,7 @@ EXPORT jackctl_server_t * jackctl_server_create() if (jackctl_add_parameter( &server_ptr->parameters, "name", - "server name to use", + "Server name to use.", "", JackParamString, &server_ptr->name, @@ -657,7 +653,7 @@ EXPORT jackctl_server_t * jackctl_server_create() if (jackctl_add_parameter( &server_ptr->parameters, "realtime", - "Whether to use realtime mode", + "Whether to use realtime mode.", "Use realtime scheduling. This is needed for reliable low-latency performance. On most systems, it requires JACK to run with special scheduler and memory allocation privileges, which may be obtained in several ways. On Linux you should use PAM.", JackParamBool, &server_ptr->realtime, @@ -714,7 +710,7 @@ EXPORT jackctl_server_t * jackctl_server_create() if (jackctl_add_parameter( &server_ptr->parameters, "client-timeout", - "Client timeout limit in milliseconds", + "Client timeout limit in milliseconds.", "", JackParamInt, &server_ptr->client_timeout, @@ -724,25 +720,11 @@ EXPORT jackctl_server_t * jackctl_server_create() goto fail_free_parameters; } - value.ui = 0; - if (jackctl_add_parameter( - &server_ptr->parameters, - "loopback-ports", - "Number of loopback ports", - "", - JackParamUInt, - &server_ptr->loopback_ports, - &server_ptr->default_loopback_ports, - value) == NULL) - { - goto fail_free_parameters; - } - value.ui = 0; if (jackctl_add_parameter( &server_ptr->parameters, "clock-source", - "Clocksource type : c(ycle) | h(pet) | s(ystem)", + "Clocksource type : c(ycle) | h(pet) | s(ystem).", "", JackParamUInt, &server_ptr->clock_source, @@ -756,7 +738,7 @@ EXPORT jackctl_server_t * jackctl_server_create() if (jackctl_add_parameter( &server_ptr->parameters, "replace-registry", - "Replace registry", + "Replace shared memory registry.", "", JackParamBool, &server_ptr->replace_registry, @@ -770,7 +752,7 @@ EXPORT jackctl_server_t * jackctl_server_create() if (jackctl_add_parameter( &server_ptr->parameters, "sync", - "Use synchronous mode", + "Use server synchronous mode.", "", JackParamBool, &server_ptr->sync, @@ -880,7 +862,6 @@ jackctl_server_start( server_ptr->client_timeout.i, server_ptr->realtime.b, server_ptr->realtime_priority.i, - server_ptr->loopback_ports.ui, server_ptr->verbose.b, (jack_timer_type_t)server_ptr->clock_source.ui, server_ptr->name.str); diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index 5a2092c8..609952dc 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -315,6 +315,7 @@ int JackDriver::Write() int JackDriver::Start() { + fEngineControl->InitFrameTime(); return 0; } diff --git a/common/JackServer.cpp b/common/JackServer.cpp index dd521a99..081e743b 100644 --- a/common/JackServer.cpp +++ b/common/JackServer.cpp @@ -22,7 +22,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackServerGlobals.h" #include "JackTime.h" #include "JackFreewheelDriver.h" -#include "JackLoopbackDriver.h" #include "JackDummyDriver.h" #include "JackThreadedDriver.h" #include "JackGlobals.h" @@ -39,7 +38,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { -JackServer::JackServer(bool sync, bool temporary, long timeout, bool rt, long priority, long loopback, bool verbose, jack_timer_type_t clock, const char* server_name) +JackServer::JackServer(bool sync, bool temporary, long timeout, bool rt, long priority, bool verbose, jack_timer_type_t clock, const char* server_name) { if (rt) { jack_info("JACK server starting in realtime mode with priority %ld", priority); @@ -54,7 +53,6 @@ JackServer::JackServer(bool sync, bool temporary, long timeout, bool rt, long pr fDriverInfo = new JackDriverInfo(); fAudioDriver = NULL; fFreewheel = false; - fLoopback = loopback; JackServerGlobals::fInstance = this; // Unique instance JackServerGlobals::fUserCount = 1; // One user jack_verbose = verbose; @@ -170,7 +168,6 @@ int JackServer::InternalClientLoadAux(JackLoadableInternalClient* client, const int JackServer::Start() { jack_log("JackServer::Start"); - fEngineControl->InitFrameTime(); return fAudioDriver->Start(); } @@ -203,13 +200,11 @@ int JackServer::SetBufferSize(jack_nframes_t buffer_size) if (fAudioDriver->SetBufferSize(buffer_size) == 0) { fFreewheelDriver->SetBufferSize(buffer_size); fEngine->NotifyBufferSize(buffer_size); - fEngineControl->InitFrameTime(); return fAudioDriver->Start(); } else { // Failure: try to restore current value jack_error("Cannot SetBufferSize for audio driver, restore current value %ld", current_buffer_size); fAudioDriver->SetBufferSize(current_buffer_size); fFreewheelDriver->SetBufferSize(current_buffer_size); - fEngineControl->InitFrameTime(); fAudioDriver->Start(); // SetBufferSize actually failed, so return an error... return -1; @@ -241,7 +236,6 @@ int JackServer::SetFreewheel(bool onoff) fGraphManager->Restore(&fConnectionState); // Restore previous connection state fEngine->NotifyFreewheel(onoff); fFreewheelDriver->SetMaster(false); - fEngineControl->InitFrameTime(); return fAudioDriver->Start(); } } else { @@ -346,7 +340,6 @@ int JackServer::SwitchMaster(jack_driver_desc_t* driver_desc, JSList* driver_par // Activate master fAudioDriver = master; fDriverInfo = info; - fEngineControl->InitFrameTime(); fAudioDriver->Attach(); fAudioDriver->SetMaster(true); return fAudioDriver->Start(); diff --git a/common/JackServer.h b/common/JackServer.h index 79e2fd40..325237de 100644 --- a/common/JackServer.h +++ b/common/JackServer.h @@ -57,13 +57,12 @@ class SERVER_EXPORT JackServer JackConnectionManager fConnectionState; JackSynchro fSynchroTable[CLIENT_NUM]; bool fFreewheel; - long fLoopback; int InternalClientLoadAux(JackLoadableInternalClient* client, const char* so_name, const char* client_name, int options, int* int_ref, int* status); public: - JackServer(bool sync, bool temporary, long timeout, bool rt, long priority, long loopback, bool verbose, jack_timer_type_t clock, const char* server_name); + JackServer(bool sync, bool temporary, long timeout, bool rt, long priority, bool verbose, jack_timer_type_t clock, const char* server_name); ~JackServer(); int Open(jack_driver_desc_t* driver_desc, JSList* driver_params); diff --git a/common/JackServerGlobals.cpp b/common/JackServerGlobals.cpp index 0dbe0cf2..815d5330 100644 --- a/common/JackServerGlobals.cpp +++ b/common/JackServerGlobals.cpp @@ -39,12 +39,11 @@ int JackServerGlobals::Start(const char* server_name, int time_out_ms, int rt, int priority, - int loopback, int verbose, jack_timer_type_t clock) { jack_log("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld ", sync, time_out_ms, rt, priority, verbose); - new JackServer(sync, temporary, time_out_ms, rt, priority, loopback, verbose, clock, server_name); // Will setup fInstance and fUserCount globals + new JackServer(sync, temporary, time_out_ms, rt, priority, verbose, clock, server_name); // Will setup fInstance and fUserCount globals int res = fInstance->Open(driver_desc, driver_params); return (res < 0) ? res : fInstance->Start(); } @@ -71,7 +70,6 @@ bool JackServerGlobals::Init() int verbose_aux = 0; int do_mlock = 1; unsigned int port_max = 128; - int loopback = 0; int do_unlock = 0; int temporary = 0; @@ -112,7 +110,6 @@ bool JackServerGlobals::Init() { "name", 0, 0, 'n' }, { "unlock", 0, 0, 'u' }, { "realtime", 0, 0, 'R' }, - { "loopback", 0, 0, 'L' }, { "realtime-priority", 1, 0, 'P' }, { "timeout", 1, 0, 't' }, { "temporary", 0, 0, 'T' }, @@ -204,10 +201,6 @@ bool JackServerGlobals::Init() realtime = 1; break; - case 'L': - loopback = atoi(optarg); - break; - case 'T': temporary = 1; break; @@ -296,7 +289,7 @@ bool JackServerGlobals::Init() free(argv[i]); } - int res = Start(server_name, driver_desc, driver_params, sync, temporary, client_timeout, realtime, realtime_priority, loopback, verbose_aux, clock_source); + int res = Start(server_name, driver_desc, driver_params, sync, temporary, client_timeout, realtime, realtime_priority, verbose_aux, clock_source); if (res < 0) { jack_error("Cannot start server... exit"); Delete(); diff --git a/common/JackServerGlobals.h b/common/JackServerGlobals.h index d2db8960..c972a9bf 100644 --- a/common/JackServerGlobals.h +++ b/common/JackServerGlobals.h @@ -52,7 +52,6 @@ struct SERVER_EXPORT JackServerGlobals int time_out_ms, int rt, int priority, - int loopback, int verbose, jack_timer_type_t clock); static void Stop(); diff --git a/common/jack/control.h b/common/jack/control.h index a4935dff..b3f5756e 100644 --- a/common/jack/control.h +++ b/common/jack/control.h @@ -31,6 +31,7 @@ #include #include +#include /** Parameter types, intentionally similar to jack_driver_param_type_t */ typedef enum @@ -124,19 +125,6 @@ void jackctl_server_destroy( jackctl_server_t * server); -/** - * Call this function to get list of available drivers. List node data - * pointers is a driver object handle (::jackctl_driver_t). - * - * @param server server object handle to get drivers for - * - * @return Single linked list of driver object handles. Must not be - * modified. Always same for same server object. - */ -const JSList * -jackctl_server_get_drivers_list( - jackctl_server_t * server); - /** * Call this function to start JACK server * @@ -161,6 +149,19 @@ bool jackctl_server_stop( jackctl_server_t * server); +/** + * Call this function to get list of available drivers. List node data + * pointers is a driver object handle (::jackctl_driver_t). + * + * @param server server object handle to get drivers for + * + * @return Single linked list of driver object handles. Must not be + * modified. Always same for same server object. + */ +const JSList * +jackctl_server_get_drivers_list( + jackctl_server_t * server); + /** * Call this function to get list of server parameters. List node data * pointers is a parameter object handle (::jackctl_parameter_t). @@ -174,6 +175,82 @@ const JSList * jackctl_server_get_parameters( jackctl_server_t * server); +/** + * Call this function to get list of available internal clients. List node data + * pointers is a internal client object handle (::jackctl_internal_t). + * + * @param server server object handle to get internal clients for + * + * @return Single linked list of internal client object handles. Must not be + * modified. Always same for same server object. + */ +const JSList * +jackctl_server_get_internals_list( + jackctl_server_t * server); + +/** + * Call this function to load one internal client. + * + * @param server server object handle + * @param internal internal to use + * + * @return success status: true - success, false - fail + */ +bool +jackctl_server_load_internal( + jackctl_server_t * server, + jackctl_internal_t * internal); + +/** + * Call this function to unload one internal client. + * + * @param server server object handle + * @param internal internal to unload + * + * @return success status: true - success, false - fail + */ +bool +jackctl_server_unload_internal( + jackctl_server_t * server, + jackctl_internal_t * internal); + +/** + * Call this function to add a slave in the driver slave list. + * + * @param server server object handle + * @param driver driver to add in the driver slave list. + * + * @return success status: true - success, false - fail + */ +bool +jackctl_server_add_slave(jackctl_server_t * server, + jackctl_driver_t * driver); + +/** + * Call this function to remove a slave from the driver slave list. + * + * @param server server object handle + * @param driver driver to remove from the driver slave list. + * + * @return success status: true - success, false - fail + */ +bool +jackctl_server_remove_slave(jackctl_server_t * server, + jackctl_driver_t * driver); + +/** + * Call this function to switch master driver. + * + * @param server server object handle + * @param driver driver to switch to + * + * @return success status: true - success, false - fail + */ +bool +jackctl_server_switch_master(jackctl_server_t * server, + jackctl_driver_t * driver); + + /** * Call this function to get name of driver. * @@ -199,6 +276,31 @@ const JSList * jackctl_driver_get_parameters( jackctl_driver_t * driver); +/** + * Call this function to get name of internal client. + * + * @param internal internal object handle to get name of + * + * @return internal name. Must not be modified. Always same for same + * internal object. + */ +const char * +jackctl_internal_get_name( + jackctl_internal_t * internal); + +/** + * Call this function to get list of internal parameters. List node data + * pointers is a parameter object handle (::jackctl_parameter_t). + * + * @param internal internal object handle to get parameters for + * + * @return Single linked list of parameter object handles. Must not be + * modified. Always same for same internal object. + */ +const JSList * +jackctl_internal_get_parameters( + jackctl_internal_t * internal); + /** * Call this function to get parameter name. * @@ -413,70 +515,6 @@ bool jackctl_parameter_constraint_is_fake_value( jackctl_parameter_t * parameter); -/** - * Call this function to get list of available internal clients. List node data - * pointers is a internal client object handle (::jackctl_internal_t). - * - * @param server server object handle to get internal clients for - * - * @return Single linked list of internal client object handles. Must not be - * modified. Always same for same server object. - */ -const JSList * -jackctl_server_get_internals_list( - jackctl_server_t * server); - -/** - * Call this function to get name of internal client. - * - * @param internal internal object handle to get name of - * - * @return internal name. Must not be modified. Always same for same - * internal object. - */ -const char * -jackctl_internal_get_name( - jackctl_internal_t * internal); - -/** - * Call this function to get list of internal parameters. List node data - * pointers is a parameter object handle (::jackctl_parameter_t). - * - * @param internal internal object handle to get parameters for - * - * @return Single linked list of parameter object handles. Must not be - * modified. Always same for same internal object. - */ -const JSList * -jackctl_internal_get_parameters( - jackctl_internal_t * internal); - -/** - * Call this function to load one internal client. - * - * @param server server object handle - * @param internal internal to use - * - * @return success status: true - success, false - fail - */ -bool -jackctl_server_load_internal( - jackctl_server_t * server, - jackctl_internal_t * internal); - -/** - * Call this function to unload one internal client. - * - * @param server server object handle - * @param internal internal to unload - * - * @return success status: true - success, false - fail - */ -bool -jackctl_server_unload_internal( - jackctl_server_t * server, - jackctl_internal_t * internal); - /** * Call this function to log an error message. * @@ -510,43 +548,6 @@ jack_log( /* @} */ -/** - * Call this function to add a slave in the driver slave list. - * - * @param server server object handle - * @param driver driver to add in the driver slave list. - * - * @return success status: true - success, false - fail - */ -bool -jackctl_server_add_slave(jackctl_server_t * server, - jackctl_driver_t * driver); - -/** - * Call this function to remove a slave from the driver slave list. - * - * @param server server object handle - * @param driver driver to remove from the driver slave list. - * - * @return success status: true - success, false - fail - */ -bool -jackctl_server_remove_slave(jackctl_server_t * server, - jackctl_driver_t * driver); - -/** - * Call this function to switch master driver. - * - * @param server server object handle - * @param driver driver to switch to - * - * @return success status: true - success, false - fail - */ -bool -jackctl_server_switch_master(jackctl_server_t * server, - jackctl_driver_t * driver); - - #if 0 { /* Adjust editor indent */ #endif diff --git a/common/jack/jack.h b/common/jack/jack.h index a0b0e397..f9d8d4e0 100644 --- a/common/jack/jack.h +++ b/common/jack/jack.h @@ -1070,6 +1070,16 @@ void jack_set_info_function (void (*func)(const char *)); /*@}*/ +/** + * The free function to be used on memory returned by jack_port_get_connections, + * jack_port_get_all_connections and jack_get_ports functions. + * This is MANDATORY on Windows when otherwise all nasty runtime version related crashes can occur. + * Developers are strongly encouraged to use this function instead of the standard "free" function in new code. + * + */ +void jack_free(void* ptr); + + #ifdef __cplusplus } #endif diff --git a/dbus/controller.c b/dbus/controller.c index bd1c6a9b..f5c53f69 100644 --- a/dbus/controller.c +++ b/dbus/controller.c @@ -391,6 +391,44 @@ fail: return NULL; } +bool +jack_controller_add_slave( + struct jack_controller *controller_ptr, + const char * driver_name) +{ + jackctl_driver_t *driver; + + driver = jack_controller_find_driver(controller_ptr->server, driver_name); + + if (driver == NULL) + { + return false; + } + + jack_info("driver \"%s\" selected", driver_name); + + return jackctl_server_add_slave(controller_ptr->server, driver); +} + +bool +jack_controller_remove_slave( + struct jack_controller *controller_ptr, + const char * driver_name) +{ + jackctl_driver_t *driver; + + driver = jack_controller_find_driver(controller_ptr->server, driver_name); + + if (driver == NULL) + { + return false; + } + + jack_info("driver \"%s\" selected", driver_name); + + return jackctl_server_remove_slave(controller_ptr->server, driver); +} + bool jack_controller_load_internal( struct jack_controller *controller_ptr, diff --git a/dbus/controller_iface_control.c b/dbus/controller_iface_control.c index fb0dab75..f55fb608 100644 --- a/dbus/controller_iface_control.c +++ b/dbus/controller_iface_control.c @@ -215,6 +215,44 @@ jack_control_run_method( "jack_controller_load_internal failed for internal (%s)", internal_name); } } + else if (strcmp (call->method_name, "AddSlave") == 0) + { + const char *driver_name; + + if (!jack_dbus_get_method_args(call, DBUS_TYPE_STRING, &driver_name, DBUS_TYPE_INVALID)) + { + /* The method call had invalid arguments meaning that + * get_method_args() has constructed an error for us. + */ + goto exit; + } + + if (!jack_controller_add_slave(controller_ptr, driver_name)) { + jack_dbus_error( + call, + JACK_DBUS_ERROR_GENERIC, + "jack_controller_add_slave failed for driver (%s)", driver_name); + } + } + else if (strcmp (call->method_name, "RemoveSlave") == 0) + { + const char *driver_name; + + if (!jack_dbus_get_method_args(call, DBUS_TYPE_STRING, &driver_name, DBUS_TYPE_INVALID)) + { + /* The method call had invalid arguments meaning that + * get_method_args() has constructed an error for us. + */ + goto exit; + } + + if (!jack_controller_remove_slave(controller_ptr, driver_name)) { + jack_dbus_error( + call, + JACK_DBUS_ERROR_GENERIC, + "jack_controller_remove_slave failed for driver (%s)", driver_name); + } + } else if (strcmp (call->method_name, "UnloadInternal") == 0) { const char *internal_name; @@ -234,6 +272,7 @@ jack_control_run_method( "jack_controller_unload_internal failed for internal (%s)", internal_name); } } + else { return false; @@ -305,6 +344,14 @@ JACK_DBUS_METHOD_ARGUMENTS_BEGIN(UnlooadInternal) JACK_DBUS_METHOD_ARGUMENT("internal", "s", false) JACK_DBUS_METHOD_ARGUMENTS_END +JACK_DBUS_METHOD_ARGUMENTS_BEGIN(AddSlave) + JACK_DBUS_METHOD_ARGUMENT("internal", "s", false) +JACK_DBUS_METHOD_ARGUMENTS_END + +JACK_DBUS_METHOD_ARGUMENTS_BEGIN(RemoveSlave) + JACK_DBUS_METHOD_ARGUMENT("internal", "s", false) +JACK_DBUS_METHOD_ARGUMENTS_END + JACK_DBUS_METHODS_BEGIN JACK_DBUS_METHOD_DESCRIBE(IsStarted, NULL) JACK_DBUS_METHOD_DESCRIBE(StartServer, NULL) @@ -320,6 +367,8 @@ JACK_DBUS_METHODS_BEGIN JACK_DBUS_METHOD_DESCRIBE(ResetXruns, NULL) JACK_DBUS_METHOD_DESCRIBE(LoadInternal, NULL) JACK_DBUS_METHOD_DESCRIBE(UnlooadInternal, NULL) + JACK_DBUS_METHOD_DESCRIBE(AddSlave, NULL) + JACK_DBUS_METHOD_DESCRIBE(RemoveSlave, NULL) JACK_DBUS_METHODS_END JACK_DBUS_SIGNAL_ARGUMENTS_BEGIN(ServerStarted) diff --git a/dbus/controller_iface_patchbay.c b/dbus/controller_iface_patchbay.c index 84391404..6c9763a7 100644 --- a/dbus/controller_iface_patchbay.c +++ b/dbus/controller_iface_patchbay.c @@ -423,7 +423,7 @@ jack_controller_patchbay_new_port( const char *port_short_name; size_t client_name_len; - //jack_info("name: %s", port_full_name); + //jack_info("new port: %s", port_full_name); port_short_name = strchr(port_full_name, ':'); if (port_short_name == NULL) @@ -489,6 +489,8 @@ jack_controller_patchbay_remove_port( struct jack_controller_patchbay *patchbay_ptr, struct jack_graph_port *port_ptr) { + //jack_info("remove port: %s", port_ptr->name); + pthread_mutex_lock(&patchbay_ptr->lock); list_del(&port_ptr->siblings_client); list_del(&port_ptr->siblings_graph); @@ -1604,7 +1606,7 @@ jack_controller_port_connect_callback( } else { - jack_info("Disonnecting '%s' from '%s'", port1_name, port2_name); + jack_info("Disconnecting '%s' from '%s'", port1_name, port2_name); connection_ptr = jack_controller_patchbay_find_connection(patchbay_ptr, port1_ptr, port2_ptr); if (connection_ptr == NULL) { diff --git a/dbus/controller_internal.h b/dbus/controller_internal.h index a4cef0f6..a7711a8d 100644 --- a/dbus/controller_internal.h +++ b/dbus/controller_internal.h @@ -85,6 +85,16 @@ bool jack_controller_switch_master( struct jack_controller *controller_ptr, void *dbus_call_context_ptr); + +bool +jack_controller_add_slave( + struct jack_controller *controller_ptr, + const char * driver_name); + +bool +jack_controller_remove_slave( + struct jack_controller *controller_ptr, + const char * driver_name); bool jack_controller_select_driver( diff --git a/linux/JackLinuxTime.c b/linux/JackLinuxTime.c index 9679da6d..37ae9fb0 100644 --- a/linux/JackLinuxTime.c +++ b/linux/JackLinuxTime.c @@ -1,5 +1,6 @@ /* Copyright (C) 2001-2003 Paul Davis +Copyright (C) 2005 Jussi Laako Copyright (C) 2004-2008 Grame This program is free software; you can redistribute it and/or modify diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index 7ed400d4..59743dc9 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -2255,6 +2255,7 @@ int JackAlsaDriver::Close() int JackAlsaDriver::Start() { + JackAudioDriver::Start(); return alsa_driver_start((alsa_driver_t *)fDriver); } diff --git a/linux/firewire/JackFFADODriver.cpp b/linux/firewire/JackFFADODriver.cpp index b89a0cf8..b6080d69 100644 --- a/linux/firewire/JackFFADODriver.cpp +++ b/linux/firewire/JackFFADODriver.cpp @@ -48,9 +48,6 @@ namespace Jack #define jack_get_microseconds GetMicroSeconds -#define SAMPLE_MAX_24BIT 8388608.0f -#define SAMPLE_MAX_16BIT 32768.0f - int JackFFADODriver::ffado_driver_read (ffado_driver_t * driver, jack_nframes_t nframes) { @@ -250,10 +247,10 @@ JackFFADODriver::ffado_driver_wait (ffado_driver_t *driver, int extra_fd, int *s wait_enter = jack_get_microseconds (); if (wait_enter > driver->wait_next) { /* - * This processing cycle was delayed past the - * next due interrupt! Do not account this as - * a wakeup delay: - */ + * This processing cycle was delayed past the + * next due interrupt! Do not account this as + * a wakeup delay: + */ driver->wait_next = 0; driver->wait_late++; } @@ -270,7 +267,7 @@ JackFFADODriver::ffado_driver_wait (ffado_driver_t *driver, int extra_fd, int *s } driver->wait_last = wait_ret; driver->wait_next = wait_ret + driver->period_usecs; -// driver->engine->transport_cycle_start (driver->engine, wait_ret); +// driver->engine->transport_cycle_start (driver->engine, wait_ret); if(response == ffado_wait_ok) { // all good @@ -344,8 +341,8 @@ JackFFADODriver::SetBufferSize (jack_nframes_t nframes) /* driver->period_size = nframes; driver->period_usecs = - (jack_time_t) floor ((((float) nframes) / driver->sample_rate) - * 1000000.0f); + (jack_time_t) floor ((((float) nframes) / driver->sample_rate) + * 1000000.0f); */ /* tell the engine to change its buffer size */ @@ -376,16 +373,16 @@ JackFFADODriver::ffado_driver_new (const char *name, /* Setup the jack interfaces */ jack_driver_nt_init ((jack_driver_nt_t *) driver); - /* driver->nt_attach = (JackDriverNTAttachFunction) ffado_driver_attach; - driver->nt_detach = (JackDriverNTDetachFunction) ffado_driver_detach; - driver->nt_start = (JackDriverNTStartFunction) ffado_driver_start; - driver->nt_stop = (JackDriverNTStopFunction) ffado_driver_stop; - driver->nt_run_cycle = (JackDriverNTRunCycleFunction) ffado_driver_run_cycle; - driver->null_cycle = (JackDriverNullCycleFunction) ffado_driver_null_cycle; - driver->write = (JackDriverReadFunction) ffado_driver_write; - driver->read = (JackDriverReadFunction) ffado_driver_read; - driver->nt_bufsize = (JackDriverNTBufSizeFunction) ffado_driver_bufsize; - */ + /* driver->nt_attach = (JackDriverNTAttachFunction) ffado_driver_attach; + driver->nt_detach = (JackDriverNTDetachFunction) ffado_driver_detach; + driver->nt_start = (JackDriverNTStartFunction) ffado_driver_start; + driver->nt_stop = (JackDriverNTStopFunction) ffado_driver_stop; + driver->nt_run_cycle = (JackDriverNTRunCycleFunction) ffado_driver_run_cycle; + driver->null_cycle = (JackDriverNullCycleFunction) ffado_driver_null_cycle; + driver->write = (JackDriverReadFunction) ffado_driver_write; + driver->read = (JackDriverReadFunction) ffado_driver_read; + driver->nt_bufsize = (JackDriverNTBufSizeFunction) ffado_driver_bufsize; + */ /* copy command line parameter contents to the driver structure */ memcpy(&driver->settings, params, sizeof(ffado_jack_settings_t)); @@ -398,7 +395,7 @@ JackFFADODriver::ffado_driver_new (const char *name, driver->period_usecs = (jack_time_t) floor ((((float) driver->period_size) * 1000000.0f) / driver->sample_rate); -// driver->client = client; +// driver->client = client; driver->engine = NULL; memset(&driver->device_options, 0, sizeof(driver->device_options)); @@ -709,6 +706,7 @@ int JackFFADODriver::Close() int JackFFADODriver::Start() { + JackAudioDriver::Start(); return ffado_driver_start((ffado_driver_t *)fDriver); } @@ -918,6 +916,8 @@ extern "C" ffado_jack_settings_t cmlparams; + char *device_name="hw:0"; + cmlparams.period_size_set = 0; cmlparams.sample_rate_set = 0; cmlparams.buffer_size_set = 0; @@ -941,6 +941,9 @@ extern "C" param = (jack_driver_param_t *) node->data; switch (param->character) { + case 'd': + device_name = strdup (param->value.str); + break; case 'p': cmlparams.period_size = param->value.ui; cmlparams.period_size_set = 1; @@ -953,15 +956,11 @@ extern "C" cmlparams.sample_rate = param->value.ui; cmlparams.sample_rate_set = 1; break; - case 'C': - cmlparams.capture_ports = 1; - break; - case 'P': - cmlparams.playback_ports = 1; + case 'i': + cmlparams.capture_ports = param->value.ui; break; - case 'D': - cmlparams.capture_ports = 1; - cmlparams.playback_ports = 1; + case 'o': + cmlparams.playback_ports = param->value.ui; break; case 'I': cmlparams.capture_frame_latency = param->value.ui; @@ -969,10 +968,11 @@ extern "C" case 'O': cmlparams.playback_frame_latency = param->value.ui; break; - // ignore these for now - case 'i': + case 'x': + cmlparams.slave_mode = param->value.ui; break; - case 'o': + case 'X': + cmlparams.snoop_mode = param->value.ui; break; case 'v': cmlparams.verbose_level = param->value.ui; @@ -981,10 +981,13 @@ extern "C" /* duplex is the default */ if (!cmlparams.playback_ports && !cmlparams.capture_ports) { - cmlparams.playback_ports = TRUE; - cmlparams.capture_ports = TRUE; + cmlparams.playback_ports = 1; + cmlparams.capture_ports = 1; } + // temporary + cmlparams.device_info = device_name; + Jack::JackFFADODriver* ffado_driver = new Jack::JackFFADODriver("system", "firewire_pcm", engine, table); Jack::JackDriverClientInterface* threaded_driver = new Jack::JackThreadedDriver(ffado_driver); // Special open for FFADO driver... diff --git a/linux/freebob/JackFreebobDriver.cpp b/linux/freebob/JackFreebobDriver.cpp index 04076b92..c5d5770a 100644 --- a/linux/freebob/JackFreebobDriver.cpp +++ b/linux/freebob/JackFreebobDriver.cpp @@ -841,6 +841,7 @@ int JackFreebobDriver::Close() int JackFreebobDriver::Start() { + JackAudioDriver::Start(); return freebob_driver_start((freebob_driver_t *)fDriver); } diff --git a/linux/wscript b/linux/wscript index 46af1bc9..b9383b16 100644 --- a/linux/wscript +++ b/linux/wscript @@ -26,13 +26,14 @@ def create_jack_driver_obj(bld, target, sources, uselib = None): return driver def build(bld): - jackd = bld.new_task_gen('cxx', 'program') - jackd.includes = ['../linux', '../posix', '../common/jack', '../common', '../dbus'] - jackd.defines = 'HAVE_CONFIG_H' - jackd.source = ['../common/Jackdmp.cpp'] - jackd.uselib = 'PTHREAD DL RT' - jackd.uselib_local = 'serverlib' - jackd.target = 'jackd' + if bld.env['BUILD_JACKD'] == True: + jackd = bld.new_task_gen('cxx', 'program') + jackd.includes = ['../linux', '../posix', '../common/jack', '../common', '../dbus'] + jackd.defines = 'HAVE_CONFIG_H' + jackd.source = ['../common/Jackdmp.cpp'] + jackd.uselib = 'PTHREAD DL RT' + jackd.uselib_local = 'serverlib' + jackd.target = 'jackd' create_jack_driver_obj(bld, 'dummy', '../common/JackDummyDriver.cpp') diff --git a/macosx/JackMachNotifyChannel.h b/macosx/JackMachNotifyChannel.h index 0cae49dd..14afeb3f 100644 --- a/macosx/JackMachNotifyChannel.h +++ b/macosx/JackMachNotifyChannel.h @@ -20,7 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __JackMachNotifyChannel__ #define __JackMachNotifyChannel__ -#include "JackChannel.h" #include "JackMachPort.h" namespace Jack diff --git a/macosx/JackMachServerChannel.h b/macosx/JackMachServerChannel.h index a6b351c7..9e5ac35f 100644 --- a/macosx/JackMachServerChannel.h +++ b/macosx/JackMachServerChannel.h @@ -20,7 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __JackMachServerChannel__ #define __JackMachServerChannel__ -#include "JackChannel.h" #include "JackPlatformPlug.h" #include "JackMachPort.h" #include diff --git a/macosx/wscript b/macosx/wscript index 198edef6..ade18b4a 100644 --- a/macosx/wscript +++ b/macosx/wscript @@ -46,14 +46,15 @@ def create_jack_midi_driver_obj(bld, target, sources, uselib = None): return driver def build(bld): - jackd = bld.new_task_gen('cxx', 'program') - jackd.includes = ['.', '../macosx', '../posix', '../common', '../common/jack'] - jackd.defines = 'HAVE_CONFIG_H' - jackd.source = ['../common/Jackdmp.cpp'] - jackd.uselib = 'PTHREAD DL' - jackd.uselib_local = 'serverlib' - jackd.env.append_value("LINKFLAGS", "-framework CoreFoundation") - jackd.target = 'jackd' + if bld.env['BUILD_JACKD'] == True: + jackd = bld.new_task_gen('cxx', 'program') + jackd.includes = ['.', '../macosx', '../posix', '../common', '../common/jack'] + jackd.defines = 'HAVE_CONFIG_H' + jackd.source = ['../common/Jackdmp.cpp'] + jackd.uselib = 'PTHREAD DL' + jackd.uselib_local = 'serverlib' + jackd.env.append_value("LINKFLAGS", "-framework CoreFoundation") + jackd.target = 'jackd' create_jack_driver_obj(bld, 'dummy', '../common/JackDummyDriver.cpp') diff --git a/posix/JackPosixServerLaunch.cpp b/posix/JackPosixServerLaunch.cpp index 99aa4f05..1931474d 100644 --- a/posix/JackPosixServerLaunch.cpp +++ b/posix/JackPosixServerLaunch.cpp @@ -26,8 +26,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. using namespace Jack; -#ifndef WIN32 - #if defined(JACK_DBUS) #include @@ -75,10 +73,10 @@ static int start_server_dbus(const char* server_name) return 0; } -#else +#endif /* Exec the JACK server in this process. Does not return. */ -static void start_server_aux(const char* server_name) +static void start_server_classic_aux(const char* server_name) { FILE* fp = 0; char filename[255]; @@ -161,18 +159,8 @@ static void start_server_aux(const char* server_name) fprintf(stderr, "exec of JACK server (command = \"%s\") failed: %s\n", command, strerror(errno)); } -#endif - -static int start_server(const char* server_name, jack_options_t options) +static int start_server_classic(const char* server_name) { - if ((options & JackNoStartServer) || getenv("JACK_NO_START_SERVER")) { - return 1; - } - -#if defined(JACK_DBUS) - return start_server_dbus(server_name); -#else - /* The double fork() forces the server to become a child of * init, which will always clean up zombie process state on * termination. This even works in cases where the server @@ -186,7 +174,7 @@ static int start_server(const char* server_name, jack_options_t options) case 0: /* child process */ switch (fork()) { case 0: /* grandchild process */ - start_server_aux(server_name); + start_server_classic_aux(server_name); _exit(99); /* exec failed */ case - 1: _exit(98); @@ -199,6 +187,18 @@ static int start_server(const char* server_name, jack_options_t options) /* only the original parent process goes here */ return 0; /* (probably) successful */ +} + +static int start_server(const char* server_name, jack_options_t options) +{ + if ((options & JackNoStartServer) || getenv("JACK_NO_START_SERVER")) { + return 1; + } + +#if defined(JACK_DBUS) + return start_server_dbus(server_name); +#else + return start_server_classic(server_name); #endif } @@ -234,5 +234,3 @@ int try_start_server(jack_varargs_t* va, jack_options_t options, jack_status_t* return 0; } - -#endif diff --git a/posix/JackSocketServerChannel.h b/posix/JackSocketServerChannel.h index d0c1ba64..98a812aa 100644 --- a/posix/JackSocketServerChannel.h +++ b/posix/JackSocketServerChannel.h @@ -20,7 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __JackSocketServerChannel__ #define __JackSocketServerChannel__ -#include "JackChannel.h" #include "JackSocket.h" #include "JackPlatformPlug.h" #include @@ -29,6 +28,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { +class JackServer; + /*! \brief JackServerChannel using sockets. */ diff --git a/posix/JackSocketServerNotifyChannel.h b/posix/JackSocketServerNotifyChannel.h index 4d8afa54..d8687dfa 100644 --- a/posix/JackSocketServerNotifyChannel.h +++ b/posix/JackSocketServerNotifyChannel.h @@ -20,7 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __JackSocketServerNotifyChannel__ #define __JackSocketServerNotifyChannel__ -#include "JackChannel.h" #include "JackSocket.h" namespace Jack diff --git a/solaris/oss/JackBoomerDriver.cpp b/solaris/oss/JackBoomerDriver.cpp index 3080dcde..b77e7747 100644 --- a/solaris/oss/JackBoomerDriver.cpp +++ b/solaris/oss/JackBoomerDriver.cpp @@ -533,6 +533,7 @@ void JackBoomerDriver::CloseAux() int JackBoomerDriver::Start() { jack_log("JackBoomerDriver::Start"); + JackAudioDriver::Start(); // Start output thread only when needed if (fOutFD > 0) { diff --git a/windows/JackWinNamedPipeClientChannel.cpp b/windows/JackWinNamedPipeClientChannel.cpp index 35755b45..b36f03e1 100644 --- a/windows/JackWinNamedPipeClientChannel.cpp +++ b/windows/JackWinNamedPipeClientChannel.cpp @@ -311,7 +311,6 @@ bool JackWinNamedPipeClientChannel::Execute() JackResult res; if (event.Read(&fNotificationListenPipe) < 0) { - fNotificationListenPipe.Close(); jack_error("JackWinNamedPipeClientChannel read fail"); goto error; } @@ -320,7 +319,6 @@ bool JackWinNamedPipeClientChannel::Execute() if (event.fSync) { if (res.Write(&fNotificationListenPipe) < 0) { - fNotificationListenPipe.Close(); jack_error("JackWinNamedPipeClientChannel write fail"); goto error; } @@ -328,6 +326,9 @@ bool JackWinNamedPipeClientChannel::Execute() return true; error: + // Close the pipes, server wont be able to create them otherwise. + fNotificationListenPipe.Close(); + fRequestPipe.Close(); fClient->ShutDown(); return false; } diff --git a/windows/JackWinNamedPipeNotifyChannel.h b/windows/JackWinNamedPipeNotifyChannel.h index 5d3b9488..0ade63d1 100644 --- a/windows/JackWinNamedPipeNotifyChannel.h +++ b/windows/JackWinNamedPipeNotifyChannel.h @@ -20,7 +20,6 @@ Copyright (C) 2004-2006 Grame #ifndef __JackWinNamedPipeNotifyChannel__ #define __JackWinNamedPipeNotifyChannel__ -#include "JackChannel.h" #include "JackWinNamedPipe.h" namespace Jack diff --git a/windows/JackWinNamedPipeServerChannel.h b/windows/JackWinNamedPipeServerChannel.h index 74ea7cca..adb6941b 100644 --- a/windows/JackWinNamedPipeServerChannel.h +++ b/windows/JackWinNamedPipeServerChannel.h @@ -20,7 +20,6 @@ Copyright (C) 2004-2006 Grame #ifndef __JackWinNamedPipeServerChannel__ #define __JackWinNamedPipeServerChannel__ -#include "JackChannel.h" #include "JackWinNamedPipe.h" #include "JackPlatformPlug.h" #include diff --git a/windows/JackWinSemaphore.cpp b/windows/JackWinSemaphore.cpp index 88236d49..8ce52d62 100644 --- a/windows/JackWinSemaphore.cpp +++ b/windows/JackWinSemaphore.cpp @@ -137,9 +137,9 @@ bool JackWinSemaphore::Allocate(const char* name, const char* server_name, int v return false; } else if (GetLastError() == ERROR_ALREADY_EXISTS) { jack_error("Allocate: named semaphore already exist name = %s", fName); - CloseHandle(fSemaphore); - fSemaphore = NULL; - return false; + // Try to open it + fSemaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, fName); + return (fSemaphore != NULL); } else { return true; } diff --git a/windows/JackWinTime.c b/windows/JackWinTime.c index 54da0411..bd950806 100644 --- a/windows/JackWinTime.c +++ b/windows/JackWinTime.c @@ -30,14 +30,13 @@ SERVER_EXPORT void JackSleep(long usec) SERVER_EXPORT void InitTime() { QueryPerformanceFrequency(&_jack_freq); - _jack_freq.QuadPart = _jack_freq.QuadPart / 1000000; // by usec } SERVER_EXPORT jack_time_t GetMicroSeconds(void) { LARGE_INTEGER t1; QueryPerformanceCounter(&t1); - return (jack_time_t)(((double)t1.QuadPart) / ((double)_jack_freq.QuadPart)); + return (jack_time_t)(((double)t1.QuadPart) / ((double)_jack_freq.QuadPart) * 1000000.0); } SERVER_EXPORT void SetClockSource(jack_timer_type_t source) diff --git a/windows/Setup/JackRouter.dll b/windows/Setup/JackRouter.dll index 4f2ada62f24aca423bfe88ee7ce08e1fb6a73265..92e743e05a03509a61eafd2bf65531633377cdf5 100644 GIT binary patch delta 4000 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 RcCbg-Ugw*&tly)w@?R!>nSuZS delta 3936 zcmeH~jbBt%8pqFp0Wm=@DDQ6r3=Hx*bML(0J9j`w90lcqVuB^1I! z6Yc0>+blE6cD0Q)b<#!GY*1EoW0OtYCBvdJ8(&IHD?Vw?KKC*d?e_V!f54v4=X;-X ze)rtxob#OLo;y=tA5dQ(;Cj5St@f4E-zZ1PI(1X|DzpoGhm;*)v)tfF z%4=ZX>b<0V32b5Sb*W$Y+1tupQu~f_H`wwO%N*h}$X|pR2$kR;a4_PI0=QHy{(fK>bUl$p z^D%=kEAJ=6J|FX5&kR%#t(GNJPw;B@J<cn5PWYeu_dgB4Lz1{ zY+`!>?8a~_bQTtPXOXtVyYa{5a^k$nEr|#@pIQjp)6!H4(Jk|?Awp7om?s`l<>$9o zivgcbo=8%LCA?=OvLQdDeACx%^VZt4p}sLK9WcPKQa93fYdGVo3kkz9sL zNlmgAPbSYMXW&hwE4dQ?l_bem;HBC>_x+B#oK}U*)-Zh6 z!|6UnqmAS#v!kR0=E)G@hZf(!GI=hdKW6rVds#u0{RCCUKhDX;IeUaN> zcZoSG1)m~SS&`;iafs~$FoZKu^fFs=y*B&@uC*Xau2Z4n9F`^%C_rxP&1#7LmpHv5 znbRg~!L22V%mz??y- zqLq-=t4MoZj`lGzj!$(%!ZN@9Ps_7BfS@ znXP4J2s}mW+sPVsdL0EB=}W%~G4rL%r24Q_PmtM^ZgRx`s;E80or4y8F6x?SyNuzxdJ*L#x5;xf@1X8|tf7$O3(lZSEot zW4w*n%=_TbzGXIreEhA?x9C{sFNv8?gtL1wUx3@mHr^22`Hs)mIYiF!#ZfWS5p^j5 zI`;Oq&N<^te*|22ItXh?n%wY(&nLcE&N)MV-9=Ve+DJQ=*Ih0`=p4`s9091A2+4sw z;5M|yB7m(03V*gVA}x?Afy6mh^o#&6oT`V z0z~`$a6ekN{8WdZxKE0vO@kcUJ1stpf{&^^h{OiNQaz%gRe>TdoCk}+&ISwLZ8RS& zoCoM$uyE|5`@xD&ihU@8r^ko6{EFzyAS&8EP{gn9yMFtj-(L3H8-9BW?5MA1$roiA zQN)q=h)SIb6lkDAupL&hHd2~lw-p5lRr^y>RQG|_4_fn>e!Q3spzRsc&kkB;Ct* z&fPWR`G9fufS*0Md^sXZZ0YVNY+15dqd)1tftZSk7v$#zvl6m_<5lM zE|?L@pM#JECi5T zsxnoRYO`vI`a|{S>Iixby@BqbZ_y#l6U;6qU1QO#(`?pE)MjcIYZLW0eTiPsSLhe& zEA`d-8ofimO21m4YFKA@($HquZ#Z3NSZ;jOxYfAVc))nv_^I)hG0xOs>NX9UhD~=& zfvlQk*;2NHoyYxxBivSQ7uUu0aR1~6x%$&oh0@SteLBK@+Dj!m5fjO_~=qf6%<9>DQdsT+-a7ourM?8nlI4LAy-r z(5}(8X}4;BuRW+etBuiFbt`m_=yvJe)cs9&T6a_Ttu8^IqR-MVfH*AGKd%3^-lgx? zf2vQeGfXv<8fpwH4F?S$8Lk!)|9^X8*|U zVGpo}*`w?U_HFhIdyXAsFS1wJFW6!B4lCm#xEL;-%i+}Ae2CVI+)miuHz8tYxpUkH z+y(9$cbf|~$D5VrTyv>;sd?TT=5yvj^JnI7%)xvDU&NR5c77$lj^Dr^(=Y^r/lib]") + opt.add_option('--classic', action='store_true', default=False, help='Enable standard JACK (jackd)') opt.add_option('--dbus', action='store_true', default=False, help='Enable D-Bus JACK (jackdbus)') opt.add_option('--doxygen', action='store_true', default=False, help='Enable build of doxygen documentation') opt.add_option('--profile', action='store_true', default=False, help='Build with engine profiling') @@ -122,6 +123,8 @@ def configure(conf): conf.env['BUILD_DOXYGEN_DOCS'] = Options.options.doxygen conf.env['BUILD_WITH_PROFILE'] = Options.options.profile conf.env['BUILD_WITH_32_64'] = Options.options.mixed + conf.env['BUILD_JACKDBUS'] = Options.options.dbus + conf.env['BUILD_JACKD'] = Options.options.classic if Options.options.libdir: conf.env['LIBDIR'] = Options.options.libdir @@ -168,13 +171,19 @@ def configure(conf): display_feature('Build doxygen documentation', conf.env['BUILD_DOXYGEN_DOCS']) display_feature('Build with engine profiling', conf.env['BUILD_WITH_PROFILE']) display_feature('Build with 32/64 bits mixed mode', conf.env['BUILD_WITH_32_64']) - + if conf.env['BUILD_JACKDBUS'] and conf.env['BUILD_JACKD']: + display_feature('Build standard (jackd) and D-Bus JACK (jackdbus) : WARNING !! mixing both program may cause issues...', True) + elif conf.env['BUILD_JACKDBUS']: + display_feature('Build D-Bus JACK (jackdbus)', True) + else: + conf.env['BUILD_JACKD'] = True; # jackd is always built be default + display_feature('Build standard JACK (jackd)', True) if conf.env['IS_LINUX']: display_feature('Build with ALSA support', conf.env['BUILD_DRIVER_ALSA'] == True) display_feature('Build with FireWire (FreeBob) support', conf.env['BUILD_DRIVER_FREEBOB'] == True) display_feature('Build with FireWire (FFADO) support', conf.env['BUILD_DRIVER_FFADO'] == True) - display_feature('Build D-Bus JACK (jackdbus)', conf.env['BUILD_JACKDBUS'] == True) + if conf.env['BUILD_JACKDBUS'] == True: display_msg('D-Bus service install directory', conf.env['DBUS_SERVICES_DIR'], 'CYAN') #display_msg('Settings persistence', xxx) From e040bf80ae9702725c73e4eedfc8ce8c8c38e0da Mon Sep 17 00:00:00 2001 From: sletz Date: Fri, 19 Jun 2009 11:09:10 +0000 Subject: [PATCH 019/472] rebase from trunk 3550:3563 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3564 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 50 ++++--- common/JackAPI.cpp | 6 +- common/JackEngine.cpp | 29 ++-- common/JackError.cpp | 10 +- common/JackError.h | 10 +- common/JackGraphManager.cpp | 4 +- common/JackGraphManager.h | 2 +- common/JackTransportEngine.cpp | 1 + common/JackWeakAPI.cpp | 168 ++++++++++++++++++++++++ common/Jackdmp.cpp | 13 +- common/jack/jack.h | 5 + common/jack/thread.h | 10 +- common/wscript | 3 - dbus/controller_iface_patchbay.c | 4 +- linux/wscript | 26 ++-- posix/JackFifo.cpp | 12 +- windows/JackWinNamedPipeServerChannel.h | 2 + wscript | 22 ++-- 18 files changed, 294 insertions(+), 83 deletions(-) create mode 100644 common/JackWeakAPI.cpp diff --git a/ChangeLog b/ChangeLog index ff7e9a47..f7cd2b5d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,42 +23,58 @@ Paul Davis --------------------------- Jackdmp changes log ---------------------------- - +--------------------------- + +2009-06-19 Stephane Letz + + * Correct JackTransportEngine::MakeAllLocating, sync callback has to be called in this case also. + +2009-06-17 Stephane Letz + + * Move DBus based audio device reservation code in ALSA backend compilation. + +2009-06-16 Stephane Letz + + * Correct JackFifo::TimedWait for EINTR handling. + +2009-06-05 Stephane Letz + + * Correct jack_set_error_function, jack_set_info_function and jack_set_thread_creator functions. + 2009-05-18 Stephane Letz - * Correct wcsript files to create jackdbus only (and not create jackd anymore) when compiled in --dbus mode, add a --classic option. Both options are possible but issue a warning. - + * Correct wcsript files to create jackdbus only (and not create jackd anymore) when compiled in --dbus mode, add a --classic option. Both options are possible but issue a warning. + 2009-05-15 Stephane Letz - * Move InitFrameTime in JackDriver::Start method. - + * Move InitFrameTime in JackDriver::Start method. + 2009-05-13 Stephane Letz - * Reworked Torben Hohn fix for server restart issue on Windows. - + * Reworked Torben Hohn fix for server restart issue on Windows. + 2009-05-11 Stephane Letz - * New jack_free function added in jack.h. - * Torben Hohn fix for InitTime and GetMicroSeconds in JackWinTime.c. - + * New jack_free function added in jack.h. + * Torben Hohn fix for InitTime and GetMicroSeconds in JackWinTime.c. + 2009-05-07 Stephane Letz - * Cleanup "loopback" stuff in server. - + * Cleanup "loopback" stuff in server. + 2009-05-06 Stephane Letz - * Fix transport callback (timebase master, sync) issue when used after jack_activate (RT thread was not running). + * Fix transport callback (timebase master, sync) issue when used after jack_activate (RT thread was not running). * D-Bus access for jackctl_server_add_slave/jackctl_server_remove_slave API. - + 2009-05-05 Stephane Letz * First working version of native MIDI backend (JackCoreMidiDriver, JackWinMMEDriver). - + 2009-04-22 Stephane Letz * jackctl_server_load_master renamed to jackctl_server_switch_master, jackctl_server_unload_master is removed. - + 2009-04-21 Stephane Letz * Add jackctl_server_load_master/jackctl_server_unload_master API. diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index 3312c9f1..4eadc797 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -278,12 +278,12 @@ static inline void WaitGraphChange() EXPORT void jack_set_error_function (print_function func) { - jack_error_callback = func; + jack_error_callback = (func == NULL) ? &default_jack_error_callback : func; } EXPORT void jack_set_info_function (print_function func) { - jack_info_callback = func; + jack_info_callback = (func == NULL) ? &default_jack_info_callback : func; } EXPORT jack_client_t* jack_client_new(const char* client_name) @@ -1799,7 +1799,7 @@ EXPORT int jack_client_kill_thread(jack_client_t* client, pthread_t thread) #ifndef WIN32 EXPORT void jack_set_thread_creator (jack_thread_creator_t jtc) { - JackGlobals::fJackThreadCreator = jtc; + JackGlobals::fJackThreadCreator = (jtc == NULL) ? pthread_create : jtc; } #endif diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index 7e94e42f..20b8f16b 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -739,9 +739,10 @@ int JackEngine::PortUnRegister(int refnum, jack_port_id_t port_index) int JackEngine::PortConnect(int refnum, const char* src, const char* dst) { jack_log("JackEngine::PortConnect src = %s dst = %s", src, dst); + AssertRefnum(refnum); jack_port_id_t port_src, port_dst; - return (fGraphManager->CheckPorts(src, dst, &port_src, &port_dst) < 0) + return (fGraphManager->GetTwoPorts(src, dst, &port_src, &port_dst) < 0) ? -1 : PortConnect(refnum, port_src, port_dst); } @@ -788,14 +789,9 @@ int JackEngine::PortDisconnect(int refnum, const char* src, const char* dst) AssertRefnum(refnum); jack_port_id_t port_src, port_dst; - if (fGraphManager->CheckPorts(src, dst, &port_src, &port_dst) < 0) { - return -1; - } else if (fGraphManager->Disconnect(port_src, port_dst) == 0) { - NotifyPortConnect(port_src, port_dst, false); - return 0; - } else { - return -1; - } + return (fGraphManager->GetTwoPorts(src, dst, &port_src, &port_dst) < 0) + ? -1 + : PortDisconnect(refnum, port_src, port_dst); } int JackEngine::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst) @@ -808,21 +804,23 @@ int JackEngine::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t ds jack_int_t connections[CONNECTION_NUM_FOR_PORT]; fGraphManager->GetConnections(src, connections); - // Notifications JackPort* port = fGraphManager->GetPort(src); + int ret = 0; if (port->GetFlags() & JackPortIsOutput) { for (int i = 0; (i < CONNECTION_NUM_FOR_PORT) && (connections[i] != EMPTY); i++) { - jack_log("NotifyPortConnect src = %ld dst = %ld false", src, connections[i]); - NotifyPortConnect(src, connections[i], false); + if (PortDisconnect(refnum, src, connections[i]) != 0) { + ret = -1; + } } } else { for (int i = 0; (i < CONNECTION_NUM_FOR_PORT) && (connections[i] != EMPTY); i++) { - jack_log("NotifyPortConnect src = %ld dst = %ld false", connections[i], src); - NotifyPortConnect(connections[i], src, false); + if (PortDisconnect(refnum, connections[i], src) != 0) { + ret = -1; + } } } - return fGraphManager->DisconnectAll(src); + return ret; } else if (fGraphManager->CheckPorts(src, dst) < 0) { return -1; } else if (fGraphManager->Disconnect(src, dst) == 0) { @@ -836,6 +834,7 @@ int JackEngine::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t ds int JackEngine::PortRename(int refnum, jack_port_id_t port, const char* name) { + AssertRefnum(refnum); fGraphManager->GetPort(port)->SetName(name); NotifyPortRename(port); return 0; diff --git a/common/JackError.cpp b/common/JackError.cpp index 1ed928c0..aad72327 100644 --- a/common/JackError.cpp +++ b/common/JackError.cpp @@ -118,17 +118,23 @@ SERVER_EXPORT void jack_log(const char *fmt,...) } } -static void default_jack_error_callback(const char *desc) +SERVER_EXPORT void default_jack_error_callback(const char *desc) { fprintf(stderr, "%s\n", desc); fflush(stderr); } -static void default_jack_info_callback (const char *desc) +SERVER_EXPORT void default_jack_info_callback(const char *desc) { fprintf(stdout, "%s\n", desc); fflush(stdout); } +SERVER_EXPORT void silent_jack_error_callback(const char *desc) +{} + +SERVER_EXPORT void silent_jack_info_callback(const char *desc) +{} + SERVER_EXPORT void (*jack_error_callback)(const char *desc) = &default_jack_error_callback; SERVER_EXPORT void (*jack_info_callback)(const char *desc) = &default_jack_info_callback; diff --git a/common/JackError.h b/common/JackError.h index 62ad1b92..fca6ec30 100644 --- a/common/JackError.h +++ b/common/JackError.h @@ -45,6 +45,12 @@ extern "C" SERVER_EXPORT extern void (*jack_error_callback)(const char *desc); SERVER_EXPORT extern void (*jack_info_callback)(const char *desc); + + SERVER_EXPORT extern void default_jack_error_callback(const char *desc); + SERVER_EXPORT extern void default_jack_info_callback(const char *desc); + + SERVER_EXPORT extern void silent_jack_error_callback(const char *desc); + SERVER_EXPORT extern void silent_jack_info_callback(const char *desc); typedef void (* jack_log_function_t)(int level, const char *message); @@ -52,8 +58,8 @@ extern "C" void jack_log_function(int level, const char *message); SERVER_EXPORT void set_threaded_log_function(); - - extern int jack_verbose; + + extern int jack_verbose; #ifdef __cplusplus } diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index ae5f3351..f6aae030 100644 --- a/common/JackGraphManager.cpp +++ b/common/JackGraphManager.cpp @@ -627,7 +627,7 @@ int JackGraphManager::CheckPorts(jack_port_id_t port_src, jack_port_id_t port_ds return 0; } -int JackGraphManager::CheckPorts(const char* src_name, const char* dst_name, jack_port_id_t* port_src, jack_port_id_t* port_dst) +int JackGraphManager::GetTwoPorts(const char* src_name, const char* dst_name, jack_port_id_t* port_src, jack_port_id_t* port_dst) { jack_log("JackGraphManager::CheckConnect src_name = %s dst_name = %s", src_name, dst_name); @@ -641,7 +641,7 @@ int JackGraphManager::CheckPorts(const char* src_name, const char* dst_name, jac return -1; } - return CheckPorts(*port_src, *port_dst); + return 0; } // Client : port array diff --git a/common/JackGraphManager.h b/common/JackGraphManager.h index 575e3752..0fdd3c82 100644 --- a/common/JackGraphManager.h +++ b/common/JackGraphManager.h @@ -91,7 +91,7 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState void GetConnections(jack_port_id_t port_index, jack_int_t* connections); // TODO const char** GetPorts(const char* port_name_pattern, const char* type_name_pattern, unsigned long flags); - int CheckPorts(const char* src, const char* dst, jack_port_id_t* src_index, jack_port_id_t* dst_index); + int GetTwoPorts(const char* src, const char* dst, jack_port_id_t* src_index, jack_port_id_t* dst_index); int CheckPorts(jack_port_id_t port_src, jack_port_id_t port_dst); void DisconnectAllInput(jack_port_id_t port_index); diff --git a/common/JackTransportEngine.cpp b/common/JackTransportEngine.cpp index 40671af0..418d1180 100644 --- a/common/JackTransportEngine.cpp +++ b/common/JackTransportEngine.cpp @@ -141,6 +141,7 @@ void JackTransportEngine::MakeAllLocating(JackClientInterface** table) if (client) { JackClientControl* control = client->GetClientControl(); control->fTransportState = JackTransportStopped; + control->fTransportSync = true; control->fTransportTimebase = true; jack_log("MakeAllLocating ref = %ld", i); } diff --git a/common/JackWeakAPI.cpp b/common/JackWeakAPI.cpp new file mode 100644 index 00000000..2715922b --- /dev/null +++ b/common/JackWeakAPI.cpp @@ -0,0 +1,168 @@ +/* +Copyright (C) 2009 Grame + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +/* + Completed from Julien Pommier (PianoTeq : http://www.pianoteq.com/) code. +*/ + +#include "jack.h" +#include +#include +#include +#include +#include + +/* dynamically load libjack and forward all registered calls to libjack + (similar to what relaytool is trying to do, but more portably..) +*/ + +using std::cerr; + +int libjack_is_present = 0; // public symbol, similar to what relaytool does. +static void *libjack_handle = 0; + +static void __attribute__((constructor)) tryload_libjack() +{ + if (getenv("SKIP_LIBJACK") == 0) { // just in case libjack is causing troubles.. + libjack_handle = dlopen("libjack.so.0", RTLD_LAZY); + } + libjack_is_present = (libjack_handle != 0); +} + +void *load_jack_function(const char *fn_name) +{ + void *fn = 0; + if (!libjack_handle) { + std::cerr << "libjack not found, so do not try to load " << fn_name << " ffs !\n"; + return 0; + } + fn = dlsym(libjack_handle, fn_name); + if (!fn) { + std::cerr << "could not dlsym(" << libjack_handle << "), " << dlerror() << "\n"; + } + return fn; +} + +#define DECL_FUNCTION(return_type, fn_name, arguments_types, arguments) \ + typedef return_type (*fn_name##_ptr_t)arguments_types; \ + return_type fn_name arguments_types { \ + static fn_name##_ptr_t fn = 0; \ + if (fn == 0) { fn = (fn_name##_ptr_t)load_jack_function(#fn_name); } \ + if (fn) return (*fn)arguments; \ + else return 0; \ + } + +#define DECL_VOID_FUNCTION(fn_name, arguments_types, arguments) \ + typedef void (*fn_name##_ptr_t)arguments_types; \ + void fn_name arguments_types { \ + static fn_name##_ptr_t fn = 0; \ + if (fn == 0) { fn = (fn_name##_ptr_t)load_jack_function(#fn_name); } \ + if (fn) (*fn)arguments; \ + } + +DECL_VOID_FUNCTION(jack_get_version, (int *major_ptr, int *minor_ptr, int *micro_ptr, int *proto_ptr), (major_ptr, minor_ptr, micro_ptr, proto_ptr)); +DECL_FUNCTION(const char *, jack_get_version_string, (), ()); +DECL_FUNCTION(jack_client_t *, jack_client_open, (const char *client_name, jack_options_t options, jack_status_t *status, ...), + (client_name, options, status)); +DECL_FUNCTION(int, jack_client_close, (jack_client_t *client), (client)); +DECL_FUNCTION(int, jack_client_new, (const char *client_name), (client_name)); +DECL_FUNCTION(int, jack_client_name_size, (), ()); +DECL_FUNCTION(char*, jack_get_client_name, (jack_client_t *client), (client)); +DECL_FUNCTION(int, jack_internal_client_new, (const char *client_name, + const char *load_name, + const char *load_init), (client_name, load_name, load_init)); +DECL_VOID_FUNCTION(jack_internal_client_close, (const char *client_name), (client_name)); +DECL_FUNCTION(int, jack_is_realtime, (jack_client_t *client), (client)); +DECL_VOID_FUNCTION(jack_on_shutdown, (jack_client_t *client, JackShutdownCallback shutdown_callback, void *arg), (client, function, arg)); +DECL_FUNCTION(int, jack_set_process_callback, (jack_client_t *client, + JackProcessCallback process_callback, + void *arg), (client, process_callback, arg)); +DECL_FUNCTION(jack_nframes_t, jack_thread_wait, (jack_client_t *client, int status), (client, status)); + +// +DECL_FUNCTION(jack_nframes_t, jack_cycle_wait, (jack_client_t *client), (client)); +DECL_VOID_FUNCTION(jack_cycle_signal, (jack_client_t *client, , int status), (client, status)); +DECL_FUNCTION(int, jack_set_process_thread, (jack_client_t *client, + JackThreadCallback fun, + void *arg), (client, fun, arg)); +DECL_FUNCTION(int, jack_set_thread_init_callback, (jack_client_t *client, + JackThreadInitCallback thread_init_callback, + void *arg), (client, thread_init_callback, arg)); +DECL_FUNCTION(int, jack_set_freewheel_callback, (jack_client_t *client, + JackFreewheelCallback freewheel_callback, + void *arg), (client, freewheel_callback, arg)); +DECL_FUNCTION(int, jack_set_freewheel, (jack_client_t *client, int onoff), (client, onoff)); +DECL_FUNCTION(int, jack_set_buffer_size, (jack_client_t *client, jack_nframes_t nframes), (client, nframes)); +DECL_FUNCTION(int, jack_set_buffer_size_callback, (jack_client_t *client, + JackBufferSizeCallback bufsize_callback, + void *arg), (client, bufsize_callback, arg)); +DECL_FUNCTION(int, jack_set_sample_rate_callback, (jack_client_t *client, + JackSampleRateCallback srate_callback, + void *arg), (client, srate_callback, arg)); +DECL_FUNCTION(int, jack_set_client_registration_callback, (jack_client_t *client, + JackClientRegistrationCallback registration_callback, + void *arg), (client, registration_callback, arg)); +DECL_FUNCTION(int, jack_set_port_registration_callback, (jack_client_t *client, + JackPortRegistrationCallback registration_callback, + void *arg), (client, registration_callback, arg)); +DECL_FUNCTION(int, jack_set_port_connect_callback, (jack_client_t *client, + JackPortConnectCallback connect_callback, + void *arg), (client, connect_callback, arg)); +DECL_FUNCTION(int, jack_set_port_rename_callback, (jack_client_t *client, + JackPortRenameCallback rename_callback, + void *arg), (client, rename_callback, arg)); +DECL_FUNCTION(int, jack_set_graph_order_callback, (jack_client_t *client, + JackGraphOrderCallback graph_callback, + void *arg), (client, graph_callback, arg)); +DECL_FUNCTION(int, jack_set_xrun_callback, (jack_client_t *client, + JackXRunCallback xrun_callback, + void *arg), (client, xrun_callback, arg)); +DECL_FUNCTION(int, jack_activate, (jack_client_t *client), (client)); +DECL_FUNCTION(int, jack_deactivate, (jack_client_t *client), (client)); +DECL_FUNCTION(jack_port_t *, jack_port_register, (jack_client_t *client, const char *port_name, const char *port_type, + unsigned long flags, unsigned long buffer_size), + (client, port_name, port_type, flags, buffer_size)); +DECL_FUNCTION(int, jack_port_unregister, (jack_client_t *client, jack_port_t* port), (client, port)); +DECL_FUNCTION(void *, jack_port_get_buffer, (jack_port_t *port, jack_nframes_t nframes), (port, nframes)); +DECL_FUNCTION(const char*, jack_port_name, (const jack_port_t *port), (port)); +DECL_FUNCTION(const char*, jack_port_short_name, (const jack_port_t *port), (port)); +DECL_FUNCTION(int, jack_port_flags, (const jack_port_t *port), (port)); +DECL_FUNCTION(const char*, jack_port_type, (const jack_port_t *port), (port)); +DECL_FUNCTION(jack_port_type_id_t, jack_port_type_id, (const jack_port_t *port), (port)); +DECL_FUNCTION(int, jack_port_is_mine, (const jack_client_t *client, const jack_port_t* port), (client, port)); +DECL_FUNCTION(int, jack_port_connected, (const jack_port_t *port), (port)); +DECL_FUNCTION(int, jack_port_connected_to, (const jack_port_t *port, const char *port_name), (port, port_name)); +DECL_FUNCTION(const char**, jack_port_get_connections, (const jack_port_t *port), (port)); +DECL_FUNCTION(const char**, jack_port_get_all_connections, (const jack_port_t *port), (port)); +DECL_FUNCTION(int, jack_port_tie, (jack_port_t *src, jack_port_t *dst), (src, dst)); +DECL_FUNCTION(int, jack_port_untie, (jack_port_t *port), (port)); + + +DECL_FUNCTION(jack_nframes_t, jack_get_buffer_size, (jack_client_t *client), (client)); +DECL_FUNCTION(jack_nframes_t, jack_get_sample_rate, (jack_client_t *client), (client)); +DECL_FUNCTION(jack_nframes_t, jack_port_get_total_latency, (jack_client_t *client, jack_port_t *port), (client, port)); +DECL_VOID_FUNCTION(jack_set_error_function, (void (*func)(const char *)), (func)); + + +DECL_FUNCTION(const char**, jack_get_ports, (jack_client_t *client, const char *port_name_pattern, const char * type_name_pattern, + unsigned long flags), (client, port_name_pattern, type_name_pattern, flags)); +DECL_FUNCTION(int, jack_connect, (jack_client_t *client, const char *source_port, const char *destination_port), (client, source_port, destination_port)); +DECL_FUNCTION(int, jack_set_port_connect_callback, (jack_client_t *client, JackPortConnectCallback connect_callback, void *arg), + (client, connect_callback, arg)); +DECL_FUNCTION(jack_port_t *, jack_port_by_id, (jack_client_t *client, jack_port_id_t port_id), (client, port_id)); diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index bd6a1230..e2bf6b8f 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -76,9 +76,6 @@ static void notify_server_stop(const char* server_name) #endif -static void silent_jack_error_callback(const char *desc) -{} - static void copyright(FILE* file) { fprintf(file, "jackdmp " VERSION "\n" @@ -208,7 +205,7 @@ int main(int argc, char* argv[]) jackctl_parameter_t* param; union jackctl_parameter_value value; - copyright(stdout); + copyright(stdout); server_ctl = jackctl_server_create(); if (server_ctl == NULL) { @@ -359,10 +356,10 @@ int main(int argc, char* argv[]) if (show_version) { printf( "jackdmp version " VERSION - " tmpdir " jack_server_dir - " protocol %d" - "\n", JACK_PROTOCOL_VERSION); - return -1; + " tmpdir " jack_server_dir + " protocol %d" + "\n", JACK_PROTOCOL_VERSION); + return -1; } if (!seen_audio_driver) { diff --git a/common/jack/jack.h b/common/jack/jack.h index f9d8d4e0..2a31cbaf 100644 --- a/common/jack/jack.h +++ b/common/jack/jack.h @@ -1047,6 +1047,7 @@ extern void (*jack_error_callback)(const char *msg); /** * Set the @ref jack_error_callback for error message display. + * Set it to NULL to restore default_jack_error_callback function. * * The JACK library provides two built-in callbacks for this purpose: * default_jack_error_callback() and silent_jack_error_callback(). @@ -1065,6 +1066,10 @@ extern void (*jack_info_callback)(const char *msg); /** * Set the @ref jack_info_callback for info message display. + * Set it to NULL to restore default_jack_info_callback function. + * + * The JACK library provides two built-in callbacks for this purpose: + * default_jack_info_callback() and silent_jack_info_callback(). */ void jack_set_info_function (void (*func)(const char *)); diff --git a/common/jack/thread.h b/common/jack/thread.h index c09c6ca2..48adf084 100644 --- a/common/jack/thread.h +++ b/common/jack/thread.h @@ -116,8 +116,8 @@ int jack_client_stop_thread(jack_client_t* client, pthread_t thread); * @returns 0, if successful; otherwise an error number. */ int jack_client_kill_thread(jack_client_t* client, pthread_t thread); - -#ifndef WIN32 + +#ifndef WIN32 typedef int (*jack_thread_creator_t)(pthread_t*, const pthread_attr_t*, @@ -137,11 +137,13 @@ int jack_client_stop_thread(jack_client_t* client, pthread_t thread); * that all threads that might call win32 functions are known * to Wine. * + * Set it to NULL to restore thread creation function. + * * @param creator a function that creates a new thread * */ -void jack_set_thread_creator (jack_thread_creator_t creator); - +void jack_set_thread_creator (jack_thread_creator_t creator); + #endif /* @} */ diff --git a/common/wscript b/common/wscript index ab59d7fa..2c7aa609 100644 --- a/common/wscript +++ b/common/wscript @@ -141,9 +141,6 @@ def build(bld): '../posix/JackSocketServerNotifyChannel.cpp', '../posix/JackNetUnixSocket.cpp', ] - - if bld.env['IS_LINUX'] and bld.env['BUILD_JACKDBUS']: - serverlib.source += ['../dbus/reserve.c', '../dbus/audio_reserve.c'] if bld.env['IS_SUN']: serverlib.source += [ diff --git a/dbus/controller_iface_patchbay.c b/dbus/controller_iface_patchbay.c index 6c9763a7..e89c7b3b 100644 --- a/dbus/controller_iface_patchbay.c +++ b/dbus/controller_iface_patchbay.c @@ -1352,14 +1352,14 @@ jack_controller_dbus_disconnect_ports_by_id( if (port1_ptr == NULL) { jack_dbus_error(call, JACK_DBUS_ERROR_INVALID_ARGS, "cannot find port %" PRIu64, port1_id); - return; + goto unlock; } port2_ptr = jack_controller_patchbay_find_port_by_id(patchbay_ptr, port2_id); if (port2_ptr == NULL) { jack_dbus_error(call, JACK_DBUS_ERROR_INVALID_ARGS, "cannot find port %" PRIu64, port2_id); - return; + goto unlock; } if (!jack_controller_patchbay_disconnect( diff --git a/linux/wscript b/linux/wscript index b9383b16..966a8ddf 100644 --- a/linux/wscript +++ b/linux/wscript @@ -36,18 +36,24 @@ def build(bld): jackd.target = 'jackd' create_jack_driver_obj(bld, 'dummy', '../common/JackDummyDriver.cpp') + + alsa_driver_src = ['alsa/JackAlsaDriver.cpp', + 'alsa/alsa_rawmidi.c', + 'alsa/alsa_seqmidi.c', + 'alsa/alsa_midi_jackmp.cpp', + '../common/memops.c', + 'alsa/generic_hw.c', + 'alsa/hdsp.c', + 'alsa/hammerfall.c', + 'alsa/ice1712.c' + ] + + if bld.env['BUILD_JACKDBUS']: + alsa_driver_src += ['../dbus/reserve.c', '../dbus/audio_reserve.c'] + if bld.env['BUILD_DRIVER_ALSA'] == True: - create_jack_driver_obj(bld, 'alsa', ['alsa/JackAlsaDriver.cpp', - 'alsa/alsa_rawmidi.c', - 'alsa/alsa_seqmidi.c', - 'alsa/alsa_midi_jackmp.cpp', - '../common/memops.c', - 'alsa/generic_hw.c', - 'alsa/hdsp.c', - 'alsa/hammerfall.c', - 'alsa/ice1712.c' - ], "ALSA") + create_jack_driver_obj(bld, 'alsa', alsa_driver_src, "ALSA") if bld.env['BUILD_DRIVER_FREEBOB'] == True: create_jack_driver_obj(bld, 'freebob', 'freebob/JackFreebobDriver.cpp', "LIBFREEBOB") diff --git a/posix/JackFifo.cpp b/posix/JackFifo.cpp index 8f927dea..1cd3e5d3 100644 --- a/posix/JackFifo.cpp +++ b/posix/JackFifo.cpp @@ -101,12 +101,16 @@ bool JackFifo::TimedWait(long usec) // Does not work on OSX ?? bool JackFifo::TimedWait(long usec) { - assert(fFifo >= 0); - - if ((poll(&fPoll, 1, usec / 1000) < 0) && (errno != EINTR)) { - jack_error("JackFifo::TimedWait name = %s err = %s", fName, strerror(errno)); + int res; + + if (fFifo < 0) { + jack_error("JackFifo::TimedWait name = %s already desallocated!!", fName); return false; } + + do { + res = poll(&fPoll, 1, usec / 1000); + } while (res < 0 && errno == EINTR); if (fPoll.revents & POLLIN) { return Wait(); diff --git a/windows/JackWinNamedPipeServerChannel.h b/windows/JackWinNamedPipeServerChannel.h index adb6941b..4026b541 100644 --- a/windows/JackWinNamedPipeServerChannel.h +++ b/windows/JackWinNamedPipeServerChannel.h @@ -27,6 +27,8 @@ Copyright (C) 2004-2006 Grame namespace Jack { +class JackServer; + class JackClientPipeThread : public JackRunnableInterface { diff --git a/wscript b/wscript index 68139cdf..c0499682 100644 --- a/wscript +++ b/wscript @@ -61,15 +61,13 @@ def set_options(opt): opt.tool_options('compiler_cc') opt.add_option('--libdir', type='string', help="Library directory [Default: /lib]") - opt.add_option('--classic', action='store_true', default=False, help='Enable standard JACK (jackd)') opt.add_option('--dbus', action='store_true', default=False, help='Enable D-Bus JACK (jackdbus)') + opt.add_option('--classic', action='store_true', default=False, help='Force enable standard JACK (jackd) even if D-Bus JACK (jackdbus) is enabled too') opt.add_option('--doxygen', action='store_true', default=False, help='Enable build of doxygen documentation') opt.add_option('--profile', action='store_true', default=False, help='Build with engine profiling') opt.add_option('--mixed', action='store_true', default=False, help='Build with 32/64 bits mixed mode') opt.add_option('--clients', default=64, type="int", dest="clients", help='Maximum number of JACK clients') opt.add_option('--ports', default=1024, type="int", dest="ports", help='Maximum number of ports') - opt.add_option('--clients', default=64, type="int", dest="clients", help='Maximum number of JACK clients') - opt.add_option('--ports', default=1024, type="int", dest="ports", help='Maximum number of ports') opt.sub_options('dbus') def configure(conf): @@ -124,7 +122,12 @@ def configure(conf): conf.env['BUILD_WITH_PROFILE'] = Options.options.profile conf.env['BUILD_WITH_32_64'] = Options.options.mixed conf.env['BUILD_JACKDBUS'] = Options.options.dbus - conf.env['BUILD_JACKD'] = Options.options.classic + conf.env['BUILD_CLASSIC'] = Options.options.classic + + if conf.env['BUILD_JACKDBUS']: + conf.env['BUILD_JACKD'] = conf.env['BUILD_CLASSIC'] + else: + conf.env['BUILD_JACKD'] = True if Options.options.libdir: conf.env['LIBDIR'] = Options.options.libdir @@ -171,13 +174,12 @@ def configure(conf): display_feature('Build doxygen documentation', conf.env['BUILD_DOXYGEN_DOCS']) display_feature('Build with engine profiling', conf.env['BUILD_WITH_PROFILE']) display_feature('Build with 32/64 bits mixed mode', conf.env['BUILD_WITH_32_64']) + + display_feature('Build standard JACK (jackd)', conf.env['BUILD_JACKD']) + display_feature('Build D-Bus JACK (jackdbus)', conf.env['BUILD_JACKDBUS']) + if conf.env['BUILD_JACKDBUS'] and conf.env['BUILD_JACKD']: - display_feature('Build standard (jackd) and D-Bus JACK (jackdbus) : WARNING !! mixing both program may cause issues...', True) - elif conf.env['BUILD_JACKDBUS']: - display_feature('Build D-Bus JACK (jackdbus)', True) - else: - conf.env['BUILD_JACKD'] = True; # jackd is always built be default - display_feature('Build standard JACK (jackd)', True) + print Logs.colors.RED + 'WARNING !! mixing both jackd and jackdbus may cause issues!' + Logs.colors.NORMAL if conf.env['IS_LINUX']: display_feature('Build with ALSA support', conf.env['BUILD_DRIVER_ALSA'] == True) From f385f2b058fe10bb878526ff1c829773a919c109 Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 24 Jun 2009 13:55:16 +0000 Subject: [PATCH 020/472] Add Windows project for libjacknet. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3567 0c269be4-1314-0410-8aa9-9f06e86f4224 --- windows/jackd.workspace | 3 +- windows/libjacknet.cbp | 149 ++++++++++++++++++++++++++++++++++++++++ windows/libjacknet.rc | 41 +++++++++++ 3 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 windows/libjacknet.cbp create mode 100644 windows/libjacknet.rc diff --git a/windows/jackd.workspace b/windows/jackd.workspace index f8291cd2..35bd3d44 100644 --- a/windows/jackd.workspace +++ b/windows/jackd.workspace @@ -1,7 +1,7 @@ - + @@ -47,5 +47,6 @@ + diff --git a/windows/libjacknet.cbp b/windows/libjacknet.cbp new file mode 100644 index 00000000..18b88c61 --- /dev/null +++ b/windows/libjacknet.cbp @@ -0,0 +1,149 @@ + + + + + + diff --git a/windows/libjacknet.rc b/windows/libjacknet.rc new file mode 100644 index 00000000..b6e11113 --- /dev/null +++ b/windows/libjacknet.rc @@ -0,0 +1,41 @@ +// Generated by ResEdit 1.4.3 +// Copyright (C) 2006-2008 +// http://www.resedit.net + +#include "resource.h" +#include "afxres.h" + + +// +// Version Information resources +// +LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT +1 VERSIONINFO + FILEVERSION 1,9,3,0 + PRODUCTVERSION 1,9,3,0 + FILEOS VOS_UNKNOWN + FILETYPE VFT_DLL +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040c04b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "Grame\0" + VALUE "FileDescription", "Jack Net library for Windows\0" + VALUE "FileVersion", "1, 9, 3, 0\0" + VALUE "InternalName", "libjacknet\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "libjacknet.dll\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "libjacknet\0" + VALUE "ProductVersion", "1, 9, 3, 0\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 1036, 1200 + END +END From 187a3aedfa5892c1d58c75081e278da1376a465b Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 21 Jul 2009 09:53:40 +0000 Subject: [PATCH 021/472] rebase from trunk 3563:3613 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3614 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 48 +- README | 13 +- common/JackAPI.cpp | 8 +- common/JackActivationCount.h | 2 +- common/JackAtomicArrayState.h | 5 +- common/JackAtomicState.h | 8 +- common/JackAudioDriver.cpp | 18 +- common/JackAudioDriver.h | 10 + common/JackConnectionManager.h | 12 +- common/JackConstants.h | 9 +- common/JackControlAPI.cpp | 8 +- common/JackControlAPI.h | 4 +- common/JackDriver.cpp | 2 +- common/JackDriver.h | 2 +- common/JackFilters.h | 8 +- common/JackFrameTimer.h | 4 +- common/JackFreewheelDriver.cpp | 2 +- common/JackLoopbackDriver.cpp | 63 +- common/JackNetDriver.cpp | 6 +- common/JackNetDriver.h | 2 +- common/JackNetInterface.cpp | 39 +- common/JackNetInterface.h | 2 +- common/JackNetManager.cpp | 6 +- common/JackNetManager.h | 2 +- common/JackServerGlobals.cpp | 2 + common/JackServerGlobals.h | 2 + common/JackThreadedDriver.cpp | 2 +- common/JackTransportEngine.h | 1 - common/JackWaitThreadedDriver.h | 2 +- common/JackWeakAPI.cpp | 96 +- common/Jackdmp.cpp | 46 +- common/jack/control.h | 7 +- common/jack/jack.h | 52 +- common/jack/midiport.h | 2 +- common/jack/types.h | 4 +- common/memops.c | 128 +- common/wscript | 7 +- dbus/audio_reserve.c | 97 +- dbus/audio_reserve.h | 5 +- dbus/controller.c | 65 +- dbus/jackdbus.h | 1 + dbus/reserve.c | 18 +- dbus/reserve.h | 15 + dbus/wscript | 7 +- doxyfile | 2 +- example-clients/server_control.cpp | 2 +- linux/alsa/JackAlsaDriver.cpp | 138 +- linux/alsa/JackAlsaDriver.h | 8 +- linux/alsa/hammerfall.c | 6 +- linux/wscript | 13 +- macosx/Jack-Info.plist | 2 +- macosx/JackMachSemaphore.h | 2 +- macosx/JackPlatformPlug_os.h | 4 +- macosx/Jackdmp.xcodeproj/project.pbxproj | 2161 ++++++++++++++++---- macosx/coreaudio/JackCoreAudioDriver.cpp | 11 +- macosx/install_jackdmp | 2 + macosx/wscript | 2 + posix/JackFifo.h | 2 +- posix/JackPosixSemaphore.h | 2 +- posix/JackPosixServerLaunch.cpp | 8 +- solaris/oss/JackBoomerDriver.cpp | 291 +-- solaris/oss/JackBoomerDriver.h | 69 +- solaris/oss/JackOSSDriver.cpp | 2 +- solaris/wscript | 1 + windows/JackCompilerDeps_os.h | 34 +- windows/JackNetWinSocket.cpp | 12 +- windows/JackTypes_os.h | 2 +- windows/JackWinProcessSync.cpp | 110 +- windows/JackWinSemaphore.h | 2 +- windows/JackWinServerLaunch.cpp | 52 +- windows/Setup/JackRouter.dll | Bin 32768 -> 32768 bytes windows/Setup/README | 6 +- windows/Setup/jack.ci | 10 +- windows/Setup/src/README | 17 +- windows/jack_loopback.cbp | 95 + windows/jackd.workspace | 1 + windows/portaudio/JackPortAudioDevices.cpp | 4 +- windows/portaudio/JackPortAudioDevices.h | 118 +- windows/resource_vc.h | 30 +- windows/winmme/JackWinMMEDriver.cpp | 1007 ++++----- wscript | 27 +- 81 files changed, 3585 insertions(+), 1512 deletions(-) create mode 100644 windows/jack_loopback.cbp diff --git a/ChangeLog b/ChangeLog index f7cd2b5d..e6d85017 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,11 +23,57 @@ Paul Davis --------------------------- Jackdmp changes log ---------------------------- +--------------------------- + +2009-07-17 Stephane Letz + + * Loopback backend reborn as a dynamically loadable separated backend. + * -L parameter for loopback backend activated again in jackd. + +2009-07-17 Stephane Letz + + * Big rewrite of Solaris boomer driver, seems to work in duplex mode at least. + +2009-07-16 Stephane Letz + + * In combined --dbus and --classic compilation code, use PulseAudio acquire/release code. + +2009-07-15 Stephane Letz + + * Rename JackDriver::Init method to JackDriver::Initialize (to avoid confusion with JackThread::Init method). + * Update Solaris boomer driver. + * Report some cleanup and documentation improvements done on JACK1 timing functions. + +2009-07-11 Stephane Letz + + * Raise drivers time out used in synchronous mode. + +2009-07-09 Stephane Letz + + * Use __attribute__((__packed__)) again, more fixes for 64/32 mixed mode. + * Torben Hohn changes for 64/32 mixed mode in wscripts. + * Add compile time option for maximum ports per application. + +2009-07-07 Stephane Letz + + * Use __attribute__((__aligned__(32))) instead of __attribute__((__packed__)) for 64/32 mixed mode. + +2009-07-03 Stephane Letz + + * Another Tim Bechmann memops.c optimization patch. + +2009-07-01 Stephane Letz + + * Tim Bechmann memops.c optimization patch. + +2009-06-30 Stephane Letz + + * Tim Bechmann patch : hammerfall, only release monitor thread, if it has been created. 2009-06-19 Stephane Letz * Correct JackTransportEngine::MakeAllLocating, sync callback has to be called in this case also. + * NetJack2 code : better error checkout, method renaming. 2009-06-17 Stephane Letz diff --git a/README b/README index f11e26f9..5e746d3d 100644 --- a/README +++ b/README @@ -137,8 +137,6 @@ The binary elements are : - JackRouter.dll : an ASIO/JACK driver that allows ASIO compatible applications to become JACK clients and access the JACK server. ASIO "jackified" applications appear with their names. Ableton Live, Samplitude, Reason, Arturia applications have been successfully tested. To install it, use "regsvr32 JackRouter.dll" in a terminal (use regsvr32 /u JackRouter.dll to uninstall). [VISTA special note: regsvr32 has to be used with "administrator" priviledges to properly register JackRouter.dll (Start Menu -> All Programs -> Accessories -> Right Click on Command Prompt -> Run As Administrator)]. A JackRouter.ini file is used by the driver to read parameters : an [IO] section allows to setup the number of input/output jack ports for the application and a [AUTO_CONNECT] section allows to setup jack ports autoconnection mode to machine input/output. -All dll are compiled in "release" mode. The "Debug" folder contains debug version of all dlls and libraries. MSVCRTD.dll and MSVCP60D.dll debug dll are also included. - WARNING !! WARNING !! Depending of the used interface and driver settings, the PortAudio layer may add additionnal buffering between the real card interrupt and the jack server callback. This usually result in *unregular* calls of the jack server callback (for example if jack server used a 256 frames buffer and the card used a 512 frames, the jack server callback will be called twice every card interrupt). For proper functionning of jack server and clients in this case, the jack server has to be started in "synchronous" mode, using the "-S" parameter. @@ -156,16 +154,6 @@ Automatic server launch Starting from the 0.64 version, automatic server launch from client is implemented : when the server is not yet running, and if the client uses the "jack_client_open" API, the server will be started automatically. The server configuration is saved in a ".jackdrc" file located in the user home folder. The Qjackctl tool allows to save its configuration in this . jackdrc (setting can be done in Qjackctl Setup/Misc). If no configuration file is found, a default setup will be used. WARNING : automatic server launch is not implemented on Windows - ----------------- -Loopback driver ----------------- - -An experimental loopback driver allows to manually "pipeline" applications connected in sequence, and thus parallelize sequential sub-graph. Lets say we have A ==> B graph, by using the loopback driver, it can be rewritten as : A ==> loopback driver ==> B. At each cycle, the loopback driver copy buffers received on its input ports (at the previous cycle) to its output ports. The resulting graph become parallel and thus can take profit of multi-processors machines, at each cycle A and B can be activated in parallel. Note that the loopback driver add a one buffer delay in the connection, which may be relevant in more complex graphs when having global synchronicity between clients is a desirable property. - -To activate loopback driver, use : - -- jackd (jackdmp) ... -L n ... where n is the number of input/output ports. ------------------ Validations tools @@ -225,6 +213,7 @@ Note : To experiment with the -S option, jackdmp must be launched in a console. 1.9.0 : Waf based build system : Nedko Arnaudov, Grame for preliminary OSX support. Control API, dbus based server control access : Nedko Arnaudov, Grame. NetJack2 components (in progress) : jack_net backend, netmanager, audioadapter, netadapter : Romain Moret, Grame. Code restructuring to help port on other architectures : Michael Voigt. Code cleanup/optimization : Tim Blechmann. Improve handling of server internal clients that can now be loaded/unloaded using the new server control API : Grame. A lot of bug fix and improvements. 1.9.1 : Fix jackctl_server_unload_internal. Filter SIGPIPE to avoid having client get a SIGPIPE when trying to access a died server. Libjack shutdown handler does not "deactivate" (fActive = false) the client anymore, so that jack_deactivate correctly does the job later on. Better isolation of server and clients system resources to allow starting the server in several user account at the same time. Report ringbuffer.c fixes from jack1. Client and library global context cleanup in case of incorrect shutdown handling (that is applications not correctly closing client after server has shutdown). Use JACK_DRIVER_DIR variable in internal clients loader. For ALSA driver, synchronize with latest jack1 memops functions. Synchronize jack2 public headers with jack1 ones. Implement jack_client_real_time_priority and jack_client_max_real_time_priority API. Use up to BUFFER_SIZE_MAX frames in midi ports, fix for ticket #117. Cleanup server starting code for clients directly linked with libjackserver.so. JackMessageBuffer was using thread "Stop" scheme in destructor, now use the safer thread "Kill" way. Synchronize ALSA backend code with JACK1 one. Set default mode to 'slow' in JackNetDriver and JackNetAdapter. Simplify audio packet order verification. Fix JackNetInterface::SetNetBufferSize for socket buffer size computation and JackNetMasterInterface::DataRecv if synch packet is received, various cleanup. Better recovery of network overload situations, now "resynchronize" by skipping cycles.". Support for BIG_ENDIAN machines in NetJack2. Support for BIG_ENDIAN machines in NetJack2 for MIDI ports. Support for "-h" option in internal clients to print the parameters. In NetJack2, fix a bug when capture or playback only channels are used. Add a JACK_INTERNAL_DIR environment variable to be used for internal clients. Add a resample quality parameter in audioadapter. Now correctly return an error if JackServer::SetBufferSize could not change the buffer size (and was just restoring the current one). Use PRIu32 kind of macro in JackAlsaDriver again. Add a resample quality parameter in netadapter. 1.9.2 : Solaris version. New "profiling" tools. Rework the mutex/signal classes. Support for BIG_ENDIAN machines in NetJack2. D-BUS based device reservation to better coexist with PulseAudio on Linux. Add auto_connect parameter in netmanager and netadapter. Use Torben Hohn PI controler code for adapters. Client incorrect re-naming fixed : now done at socket and fifo level. Virtualize and allow overriding of thread creation function, to allow Wine support (from JACK1). +1.9.3 : New JackBoomerDriver class for Boomer driver on Solaris. Add mixed 32/64 bits mode (off by default). Native MIDI backend (JackCoreMidiDriver, JackWinMMEDriver). In ALSA audio card reservation code, tries to open the card even if reservation fails. Clock source setting on Linux. Add jackctl_server_switch_master API. Fix transport callback (timebase master, sync) issue when used after jack_activate (RT thread was not running). D-Bus access for jackctl_server_add_slave/jackctl_server_remove_slave API. Cleanup "loopback" stuff in server. Torben Hohn fix for InitTime and GetMicroSeconds in JackWinTime.c. New jack_free function added in jack.h. Reworked Torben Hohn fix for server restart issue on Windows. Correct jack_set_error_function, jack_set_info_function and jack_set_thread_creator functions. Correct JackFifo::TimedWait for EINTR handling. Move DBus based audio device reservation code in ALSA backend compilation. Correct JackTransportEngine::MakeAllLocating, sync callback has to be called in this case also. NetJack2 code : better error checkout, method renaming. Tim Bechmann patch : hammerfall, only release monitor thread, if it has been created. Tim Bechmann memops.c optimization patches. In combined --dbus and --classic compilation code, use PulseAudio acquire/release code. Big rewrite of Solaris boomer driver, seems to work in duplex mode at least. Loopback backend reborn as a dynamically loadable separated backend. This is a work in progress but the implementation is now stable enough to be tested. jackdmp has been used successfully with the following applications : Ardour, Hydrogen, Jamin, Qjackctl, Jack-Rack, SooperLooper, AlsaPlayer... diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index 4eadc797..d609a915 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -1465,14 +1465,8 @@ EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t* ext_client) #ifdef __CLIENTDEBUG__ JackLibGlobals::CheckContext(); #endif - JackTimer timer; JackEngineControl* control = GetEngineControl(); - if (control) { - control->ReadFrameTime(&timer); - return timer.CurFrame(); - } else { - return 0; - } + return (control) ? control->fFrameTimer.ReadCurrentState()->CurFrame() : 0; } EXPORT float jack_cpu_load(jack_client_t* ext_client) diff --git a/common/JackActivationCount.h b/common/JackActivationCount.h index c9824937..8a22bc67 100644 --- a/common/JackActivationCount.h +++ b/common/JackActivationCount.h @@ -73,7 +73,7 @@ class JackActivationCount return fValue; } -}; +} POST_PACKED_STRUCTURE; } // end of namespace diff --git a/common/JackAtomicArrayState.h b/common/JackAtomicArrayState.h index 29adc592..8a0daf08 100644 --- a/common/JackAtomicArrayState.h +++ b/common/JackAtomicArrayState.h @@ -21,6 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #define __JackAtomicArrayState__ #include "JackAtomic.h" +#include "JackCompilerDeps.h" #include // for memcpy namespace Jack @@ -67,7 +68,7 @@ struct AtomicArrayCounter return *this; } -}; +} POST_PACKED_STRUCTURE; #define Counter1(e) (e).info.fLongVal #define GetIndex1(e, state) ((e).info.scounter.fByteVal[state]) @@ -247,7 +248,7 @@ class JackAtomicArrayState WriteNextStateStopAux(state); } -}; +} POST_PACKED_STRUCTURE; } // end of namespace diff --git a/common/JackAtomicState.h b/common/JackAtomicState.h index 5dbd1366..eaf164ee 100644 --- a/common/JackAtomicState.h +++ b/common/JackAtomicState.h @@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define __JackAtomicState__ #include "JackAtomic.h" +#include "JackCompilerDeps.h" #include // for memcpy namespace Jack @@ -68,7 +69,7 @@ struct AtomicCounter return *this; } -}; +} POST_PACKED_STRUCTURE; #define Counter(e) (e).info.fLongVal #define CurIndex(e) (e).info.scounter.fShortVal1 @@ -250,11 +251,10 @@ class JackAtomicState } while (cur_index != next_index); } */ -}; - + +} POST_PACKED_STRUCTURE; } // end of namespace - #endif diff --git a/common/JackAudioDriver.cpp b/common/JackAudioDriver.cpp index fc753123..505db38e 100644 --- a/common/JackAudioDriver.cpp +++ b/common/JackAudioDriver.cpp @@ -79,6 +79,22 @@ int JackAudioDriver::Open(jack_nframes_t buffer_size, return JackDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); } +int JackAudioDriver::Open(bool capturing, + bool playing, + int inchannels, + int outchannels, + bool monitor, + const char* capture_driver_name, + const char* playback_driver_name, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency) +{ + fCaptureChannels = inchannels; + fPlaybackChannels = outchannels; + fWithMonitorPorts = monitor; + return JackDriver::Open(capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); +} + int JackAudioDriver::Attach() { JackPort* port; @@ -269,7 +285,7 @@ void JackAudioDriver::ProcessGraphSync() fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); if (ProcessSlaves() < 0) jack_error("JackAudioDriver::ProcessSync ProcessSlaves error, engine may now behave abnormally!!"); - if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, fEngineControl->fTimeOutUsecs) < 0) + if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) jack_error("JackAudioDriver::ProcessSync SuspendRefNum error, engine may now behave abnormally!!"); } else { // Graph not finished: do not activate it jack_error("JackAudioDriver::ProcessSync: error"); diff --git a/common/JackAudioDriver.h b/common/JackAudioDriver.h index 93d6830d..6fb64e64 100644 --- a/common/JackAudioDriver.h +++ b/common/JackAudioDriver.h @@ -74,6 +74,16 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver jack_nframes_t capture_latency, jack_nframes_t playback_latency); + virtual int Open(bool capturing, + bool playing, + int inchannels, + int outchannels, + bool monitor, + const char* capture_driver_name, + const char* playback_driver_name, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency); + virtual int Process(); virtual int ProcessNull(); diff --git a/common/JackConnectionManager.h b/common/JackConnectionManager.h index bb972e31..47543038 100644 --- a/common/JackConnectionManager.h +++ b/common/JackConnectionManager.h @@ -116,7 +116,7 @@ class JackFixedArray return fCounter; } -}; +} POST_PACKED_STRUCTURE; /*! \brief Utility class. @@ -151,7 +151,8 @@ class JackFixedArray1 : public JackFixedArray return true; } } -}; + +} POST_PACKED_STRUCTURE; /*! \brief Utility class. @@ -226,7 +227,7 @@ class JackFixedMatrix return false; } -}; +} POST_PACKED_STRUCTURE; /*! \brief Utility class. @@ -339,7 +340,7 @@ class JackLoopFeedback return -1; } -}; +} POST_PACKED_STRUCTURE; /*! \brief For client timing measurements. @@ -356,6 +357,7 @@ struct JackClientTiming {} ~JackClientTiming() {} + } POST_PACKED_STRUCTURE; /*! @@ -450,7 +452,7 @@ class SERVER_EXPORT JackConnectionManager int ResumeRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing); int SuspendRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing, long time_out_usec); -}; +} POST_PACKED_STRUCTURE; } // end of namespace diff --git a/common/JackConstants.h b/common/JackConstants.h index 0e05c058..f5355afc 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -38,10 +38,14 @@ #endif #define DRIVER_PORT_NUM 256 -#define PORT_NUM_FOR_CLIENT 256 + +#ifndef PORT_NUM_FOR_CLIENT +#define PORT_NUM_FOR_CLIENT 512 +#endif + #define FIRST_AVAILABLE_PORT 1 -#define CONNECTION_NUM_FOR_PORT 256 +#define CONNECTION_NUM_FOR_PORT PORT_NUM_FOR_CLIENT #ifndef CLIENT_NUM #define CLIENT_NUM 64 @@ -86,6 +90,7 @@ #define SOCKET_TIME_OUT 5 // in sec #define DRIVER_OPEN_TIMEOUT 5 // in sec #define FREEWHEEL_DRIVER_TIMEOUT 10 // in sec +#define DRIVER_TIMEOUT_FACTOR 10 #define NO_PORT 0xFFFE diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index abd6d28a..488046c9 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -43,6 +43,7 @@ #include "JackLockedEngine.h" #include "JackConstants.h" #include "JackDriverLoader.h" +#include "JackServerGlobals.h" using namespace Jack; @@ -618,7 +619,9 @@ get_realtime_priority_constraint() return constraint_ptr; } -EXPORT jackctl_server_t * jackctl_server_create() +EXPORT jackctl_server_t * jackctl_server_create( + bool (* on_device_acquire)(const char * device_name), + void (* on_device_release)(const char * device_name)) { struct jackctl_server * server_ptr; union jackctl_parameter_value value; @@ -762,6 +765,9 @@ EXPORT jackctl_server_t * jackctl_server_create() goto fail_free_parameters; } + JackServerGlobals::on_device_acquire = on_device_acquire; + JackServerGlobals::on_device_release = on_device_release; + if (!jackctl_drivers_load(server_ptr)) { goto fail_free_parameters; diff --git a/common/JackControlAPI.h b/common/JackControlAPI.h index 8046c63d..cc07dcab 100644 --- a/common/JackControlAPI.h +++ b/common/JackControlAPI.h @@ -88,7 +88,9 @@ jackctl_wait_signals( sigset_t signals); EXPORT jackctl_server_t * -jackctl_server_create(); +jackctl_server_create( + bool (* on_device_acquire)(const char * device_name), + void (* on_device_release)(const char * device_name)); EXPORT void jackctl_server_destroy( diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index 609952dc..9fde4917 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -339,7 +339,7 @@ int JackDriver::SetSampleRate(jack_nframes_t sample_rate) return 0; } -bool JackDriver::Init() +bool JackDriver::Initialize() { return true; } diff --git a/common/JackDriver.h b/common/JackDriver.h index c7e9ff72..6b80dc33 100644 --- a/common/JackDriver.h +++ b/common/JackDriver.h @@ -203,7 +203,7 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface virtual JackClientControl* GetClientControl() const; virtual bool IsRealTime() const; - virtual bool Init(); // 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 }; diff --git a/common/JackFilters.h b/common/JackFilters.h index 2af946d2..76bf7ecd 100644 --- a/common/JackFilters.h +++ b/common/JackFilters.h @@ -54,7 +54,8 @@ namespace Jack mean += fTable[i]; return mean / MAX_SIZE; } - }; + + } POST_PACKED_STRUCTURE; class JackDelayLockedLoop { @@ -136,7 +137,7 @@ namespace Jack return fCurrentWakeup; } - }; + } POST_PACKED_STRUCTURE; class JackAtomicDelayLockedLoop : public JackAtomicState { @@ -201,7 +202,7 @@ namespace Jack return res; } - }; + } POST_PACKED_STRUCTURE; /* Torben Hohn PI controler from JACK1 @@ -301,7 +302,6 @@ namespace Jack } */ - double GetRatio(int error) { double smooth_offset = error; diff --git a/common/JackFrameTimer.h b/common/JackFrameTimer.h index 1468f1b5..aca70add 100644 --- a/common/JackFrameTimer.h +++ b/common/JackFrameTimer.h @@ -44,8 +44,8 @@ class SERVER_EXPORT JackTimer jack_time_t fCurrentCallback; jack_time_t fNextWakeUp; float fSecondOrderIntegrator; - bool fInitialized; float fFilterCoefficient; /* set once, never altered */ + bool fInitialized; public: @@ -67,7 +67,7 @@ class SERVER_EXPORT JackTimer return fCurrentWakeup; } -}; +} POST_PACKED_STRUCTURE; /*! \brief A class using the JackAtomicState to manage jack time. diff --git a/common/JackFreewheelDriver.cpp b/common/JackFreewheelDriver.cpp index 161c3897..c28e30c3 100644 --- a/common/JackFreewheelDriver.cpp +++ b/common/JackFreewheelDriver.cpp @@ -41,7 +41,7 @@ int JackFreewheelDriver::Process() } else { fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); // Signal all clients if (fEngineControl->fSyncMode) { - if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, fEngineControl->fTimeOutUsecs) < 0) { + if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) { jack_error("JackFreewheelDriver::ProcessSync SuspendRefNum error"); return -1; } diff --git a/common/JackLoopbackDriver.cpp b/common/JackLoopbackDriver.cpp index 3c9df5b0..48a9d253 100644 --- a/common/JackLoopbackDriver.cpp +++ b/common/JackLoopbackDriver.cpp @@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackSystemDeps.h" #include "JackLoopbackDriver.h" +#include "JackDriverLoader.h" #include "JackEngineControl.h" #include "JackGraphManager.h" #include "JackError.h" @@ -31,8 +32,6 @@ namespace Jack int JackLoopbackDriver::Process() { - assert(fCaptureChannels == fPlaybackChannels); - // Loopback copy for (int i = 0; i < fCaptureChannels; i++) { memcpy(GetInputBuffer(i), GetOutputBuffer(i), sizeof(float) * fEngineControl->fBufferSize); @@ -40,7 +39,7 @@ int JackLoopbackDriver::Process() fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); // Signal all clients if (fEngineControl->fSyncMode) { - if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, fEngineControl->fTimeOutUsecs) < 0) { + if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) { jack_error("JackLoopbackDriver::ProcessSync SuspendRefNum error"); return -1; } @@ -49,3 +48,61 @@ int JackLoopbackDriver::Process() } } // end of namespace + +#ifdef __cplusplus +extern "C" +{ +#endif + + SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor() + { + jack_driver_desc_t * desc; + unsigned int i; + + desc = (jack_driver_desc_t*)calloc (1, sizeof (jack_driver_desc_t)); + strcpy(desc->name, "loopback"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 + strcpy(desc->desc, "Loopback backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 + + desc->nparams = 1; + desc->params = (jack_driver_param_desc_t*)calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); + + i = 0; + strcpy(desc->params[i].name, "channels"); + desc->params[i].character = 'c'; + desc->params[i].type = JackDriverParamInt; + desc->params[i].value.ui = 0; + strcpy(desc->params[i].short_desc, "Maximum number of loopback ports"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + return desc; + } + + SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) + { + const JSList * node; + const jack_driver_param_t * param; + int channels = 2; + + for (node = params; node; node = jack_slist_next (node)) { + param = (const jack_driver_param_t *) node->data; + + switch (param->character) { + + case 'c': + channels = param->value.ui; + break; + } + } + + Jack::JackDriverClientInterface* driver = new Jack::JackLoopbackDriver(engine, table); + if (driver->Open(1, 1, channels, channels, false, "loopback", "loopback", 0, 0) == 0) { + return driver; + } else { + delete driver; + return NULL; + } + } + +#ifdef __cplusplus +} +#endif diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index c949001d..641c95c4 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -121,13 +121,13 @@ namespace Jack as a "dummy driver, until Init method returns. */ - bool JackNetDriver::Init() + bool JackNetDriver::Initialize() { - jack_log ( "JackNetDriver::Init()" ); + jack_log("JackNetDriver::Initialize()"); //new loading, but existing socket, restart the driver if (fSocket.IsSocket()) { - jack_info( "Restarting driver..." ); + jack_info("Restarting driver..."); FreeAll(); } diff --git a/common/JackNetDriver.h b/common/JackNetDriver.h index 058489a1..d8fb0bb2 100644 --- a/common/JackNetDriver.h +++ b/common/JackNetDriver.h @@ -50,7 +50,7 @@ namespace Jack JackGnuPlotMonitor* fNetTimeMon; #endif - bool Init(); + bool Initialize(); void FreeAll(); int AllocPorts(); diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 78e9dbb9..5131c98c 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -204,8 +204,7 @@ namespace Jack int rx_bytes = 0; //socket - if ( fSocket.NewSocket() == SOCKET_ERROR ) - { + if ( fSocket.NewSocket() == SOCKET_ERROR ) { jack_error ( "Can't create socket : %s", StrError ( NET_ERROR_CODE ) ); return false; } @@ -215,8 +214,7 @@ namespace Jack jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) ); //connect - if ( fSocket.Connect() == SOCKET_ERROR ) - { + if ( fSocket.Connect() == SOCKET_ERROR ) { jack_error ( "Can't connect : %s", StrError ( NET_ERROR_CODE ) ); return false; } @@ -245,22 +243,19 @@ namespace Jack SessionParamsNToH(&net_params, &host_params); } while ( ( GetPacketType ( &host_params ) != START_MASTER ) && ( ++attempt < SLAVE_SETUP_RETRY ) ); - if ( attempt == SLAVE_SETUP_RETRY ) - { + if ( attempt == SLAVE_SETUP_RETRY ) { jack_error ( "Slave doesn't respond, exiting." ); return false; } //set the new timeout for the socket - if ( SetRxTimeout() == SOCKET_ERROR ) - { + if ( SetRxTimeout() == SOCKET_ERROR ) { jack_error ( "Can't set rx timeout : %s", StrError ( NET_ERROR_CODE ) ); return false; } //set the new rx buffer size - if ( SetNetBufferSize() == SOCKET_ERROR ) - { + if ( SetNetBufferSize() == SOCKET_ERROR ) { jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) ); return false; } @@ -619,7 +614,7 @@ namespace Jack //first, get a master, do it until a valid connection is running do { - status = GetNetMaster(); + status = SendAvailableToMaster(); if ( status == NET_SOCKET_ERROR ) return false; } @@ -651,7 +646,7 @@ namespace Jack do { //get a master - status = GetNetMaster(); + status = SendAvailableToMaster(); if (status == NET_SOCKET_ERROR) return false; } @@ -678,26 +673,27 @@ namespace Jack return true; } - net_status_t JackNetSlaveInterface::GetNetMaster() + net_status_t JackNetSlaveInterface::SendAvailableToMaster() { - jack_log ( "JackNetSlaveInterface::GetNetMaster()" ); + jack_log ( "JackNetSlaveInterface::SendAvailableToMaster()" ); //utility session_params_t host_params; int rx_bytes = 0; //socket - if ( fSocket.NewSocket() == SOCKET_ERROR ) - { + if ( fSocket.NewSocket() == SOCKET_ERROR ) { jack_error ( "Fatal error : network unreachable - %s", StrError ( NET_ERROR_CODE ) ); return NET_SOCKET_ERROR; } //bind the socket - if ( fSocket.Bind() == SOCKET_ERROR ) + if ( fSocket.Bind() == SOCKET_ERROR ) { jack_error ( "Can't bind the socket : %s", StrError ( NET_ERROR_CODE ) ); + return NET_SOCKET_ERROR; + } //timeout on receive - if ( fSocket.SetTimeOut ( SLAVE_INIT_TIMEOUT ) == SOCKET_ERROR ) + if ( fSocket.SetTimeOut ( SLAVE_INIT_TIMEOUT ) == SOCKET_ERROR ) jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) ); //disable local loop @@ -730,12 +726,13 @@ namespace Jack fParams = host_params; //set the new buffer sizes - if ( SetNetBufferSize() == SOCKET_ERROR ) + if ( SetNetBufferSize() == SOCKET_ERROR ) { jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) ); + return NET_SOCKET_ERROR; + } //connect the socket - if ( fSocket.Connect() == SOCKET_ERROR ) - { + if ( fSocket.Connect() == SOCKET_ERROR ) { jack_error ( "Error in connect : %s", StrError ( NET_ERROR_CODE ) ); return NET_CONNECT_ERROR; } diff --git a/common/JackNetInterface.h b/common/JackNetInterface.h index c655a3b0..ca90875f 100644 --- a/common/JackNetInterface.h +++ b/common/JackNetInterface.h @@ -151,7 +151,7 @@ namespace Jack bool InitConnection(); bool InitRendering(); - net_status_t GetNetMaster(); + net_status_t SendAvailableToMaster(); net_status_t SendStartToMaster(); void SetParams(); diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index 86d23522..b4e45853 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -618,7 +618,7 @@ namespace Jack switch ( GetPacketType ( &host_params ) ) { case SLAVE_AVAILABLE: - if ( ( net_master = MasterInit ( host_params ) ) ) + if ( ( net_master = InitMaster ( host_params ) ) ) SessionParamsDisplay ( &net_master->fParams ); else jack_error ( "Can't init new net master..." ); @@ -636,9 +636,9 @@ namespace Jack while ( fRunning ); } - JackNetMaster* JackNetMasterManager::MasterInit ( session_params_t& params ) + JackNetMaster* JackNetMasterManager::InitMaster ( session_params_t& params ) { - jack_log ( "JackNetMasterManager::MasterInit, Slave : %s", params.fName ); + jack_log ( "JackNetMasterManager::InitMaster, Slave : %s", params.fName ); //check MASTER <<==> SLAVE network protocol coherency if (params.fProtocolVersion != MASTER_PROTOCOL) { diff --git a/common/JackNetManager.h b/common/JackNetManager.h index b6ad7857..29c8386d 100644 --- a/common/JackNetManager.h +++ b/common/JackNetManager.h @@ -105,7 +105,7 @@ namespace Jack bool fAutoConnect; void Run(); - JackNetMaster* MasterInit ( session_params_t& params ); + JackNetMaster* InitMaster ( session_params_t& params ); master_list_it_t FindMaster ( uint32_t client_id ); int KillMaster ( session_params_t* params ); void SetSlaveName ( session_params_t& params ); diff --git a/common/JackServerGlobals.cpp b/common/JackServerGlobals.cpp index 815d5330..7698c640 100644 --- a/common/JackServerGlobals.cpp +++ b/common/JackServerGlobals.cpp @@ -30,6 +30,8 @@ namespace Jack JackServer* JackServerGlobals::fInstance; unsigned int JackServerGlobals::fUserCount; +bool (* JackServerGlobals::on_device_acquire)(const char * device_name) = NULL; +void (* JackServerGlobals::on_device_release)(const char * device_name) = NULL; int JackServerGlobals::Start(const char* server_name, jack_driver_desc_t* driver_desc, diff --git a/common/JackServerGlobals.h b/common/JackServerGlobals.h index c972a9bf..fac85bd3 100644 --- a/common/JackServerGlobals.h +++ b/common/JackServerGlobals.h @@ -38,6 +38,8 @@ struct SERVER_EXPORT JackServerGlobals { static JackServer* fInstance; static unsigned int fUserCount; + static bool (* on_device_acquire)(const char * device_name); + static void (* on_device_release)(const char * device_name); JackServerGlobals(); ~JackServerGlobals(); diff --git a/common/JackThreadedDriver.cpp b/common/JackThreadedDriver.cpp index a1e16556..0ab139eb 100644 --- a/common/JackThreadedDriver.cpp +++ b/common/JackThreadedDriver.cpp @@ -209,7 +209,7 @@ bool JackThreadedDriver::Execute() bool JackThreadedDriver::Init() { - if (fDriver->Init()) { + if (fDriver->Initialize()) { if (fDriver->IsRealTime()) { jack_log("JackThreadedDriver::Init IsRealTime"); // Will do "something" on OSX only... diff --git a/common/JackTransportEngine.h b/common/JackTransportEngine.h index 2adac8b1..a1ff2b97 100644 --- a/common/JackTransportEngine.h +++ b/common/JackTransportEngine.h @@ -195,7 +195,6 @@ class SERVER_EXPORT JackTransportEngine : public JackAtomicArrayStateInit(); + fDriver->Initialize(); fRunning = true; return false; } diff --git a/common/JackWeakAPI.cpp b/common/JackWeakAPI.cpp index 2715922b..4888a92a 100644 --- a/common/JackWeakAPI.cpp +++ b/common/JackWeakAPI.cpp @@ -152,17 +152,91 @@ DECL_FUNCTION(const char**, jack_port_get_connections, (const jack_port_t *port) DECL_FUNCTION(const char**, jack_port_get_all_connections, (const jack_port_t *port), (port)); DECL_FUNCTION(int, jack_port_tie, (jack_port_t *src, jack_port_t *dst), (src, dst)); DECL_FUNCTION(int, jack_port_untie, (jack_port_t *port), (port)); - - -DECL_FUNCTION(jack_nframes_t, jack_get_buffer_size, (jack_client_t *client), (client)); +DECL_FUNCTION(jack_nframes_t, jack_port_get_latency, (jack_port_t *port)); +DECL_FUNCTION(jack_nframes_t, jack_port_get_total_latency ,(jack_client_t *), (jack_port_t *port)); +DECL_VOID_FUNCTION(jack_port_set_latency, (jack_port_t *), (jack_nframes_t)); +DECL_FUNCTION(int, jack_recompute_total_latency, (jack_client_t*), (jack_port_t* port)); +DECL_FUNCTION(int, jack_recompute_total_latencies, (jack_client_t*)); + +DECL_FUNCTION(int, jack_port_set_name, (jack_port_t *port), (const char *port_name)); +DECL_FUNCTION(int, jack_port_set_alias, (jack_port_t *port), (const char *alias)); +DECL_FUNCTION(int, jack_port_unset_alias, (jack_port_t *port), (const char *alias)); +DECL_FUNCTION(int, jack_port_get_aliases, (const jack_port_t *port), (char* const aliases[2])); +DECL_FUNCTION(int, jack_port_request_monitor, (jack_port_t *port), (int onoff)); +DECL_FUNCTION(int, jack_port_request_monitor_by_name, (jack_client_t *client), (const char *port_name), (int onoff)); +DECL_FUNCTION(int, jack_port_ensure_monitor, (jack_port_t *port), (int onoff)); +DECL_FUNCTION(int, jack_port_monitoring_input, (jack_port_t *port)); +DECL_FUNCTION(int, jack_connect, (jack_client_t *), (const char *source_port), (const char *destination_port)); +DECL_FUNCTION(int, jack_disconnect, (jack_client_t *), (const char *source_port), (const char *destination_port)); +DECL_FUNCTION(int, jack_port_disconnect, (jack_client_t *), (jack_port_t *)); +DECL_FUNCTION(int, jack_port_name_size,(void)); +DECL_FUNCTION(int, jack_port_type_size,(void)); + DECL_FUNCTION(jack_nframes_t, jack_get_sample_rate, (jack_client_t *client), (client)); -DECL_FUNCTION(jack_nframes_t, jack_port_get_total_latency, (jack_client_t *client, jack_port_t *port), (client, port)); -DECL_VOID_FUNCTION(jack_set_error_function, (void (*func)(const char *)), (func)); - - +DECL_FUNCTION(jack_nframes_t, jack_get_buffer_size, (jack_client_t *client), (client)); DECL_FUNCTION(const char**, jack_get_ports, (jack_client_t *client, const char *port_name_pattern, const char * type_name_pattern, unsigned long flags), (client, port_name_pattern, type_name_pattern, flags)); -DECL_FUNCTION(int, jack_connect, (jack_client_t *client, const char *source_port, const char *destination_port), (client, source_port, destination_port)); -DECL_FUNCTION(int, jack_set_port_connect_callback, (jack_client_t *client, JackPortConnectCallback connect_callback, void *arg), - (client, connect_callback, arg)); -DECL_FUNCTION(jack_port_t *, jack_port_by_id, (jack_client_t *client, jack_port_id_t port_id), (client, port_id)); +DECL_FUNCTION(jack_port_t *, jack_port_by_name, (jack_client_t *), (const char *port_name)); +DECL_FUNCTION(jack_port_t *, jack_port_by_id, (jack_client_t *client), (jack_port_id_t port_id)); + +DECL_FUNCTION(int, jack_engine_takeover_timebase, (jack_client_t *)); +DECL_FUNCTION(jack_nframes_t, jack_frames_since_cycle_start, (const jack_client_t *)); +DECL_FUNCTION(jack_time_t, jack_get_time()); +DECL_FUNCTION(jack_nframes_t, jack_time_to_frames, (const jack_client_t *client), (jack_time_t time)); +DECL_FUNCTION(jack_time_t, jack_frames_to_time, (const jack_client_t *client), (jack_nframes_t frames)); +DECL_FUNCTION(jack_nframes_t, jack_frame_time, (const jack_client_t *)); +DECL_FUNCTION(jack_nframes_t, jack_last_frame_time, (const jack_client_t *client)); +DECL_FUNCTION(float, jack_cpu_load, (jack_client_t *client)); +DECL_FUNCTION(pthread_t, jack_client_thread_id, (jack_client_t *)); +DECL_VOID_FUNCTION(jack_set_error_function, (print_function)); +DECL_VOID_FUNCTION(jack_set_info_function, (print_function)); + +DECL_FUNCTION(float, jack_get_max_delayed_usecs, (jack_client_t *client)); +DECL_FUNCTION(float, jack_get_xrun_delayed_usecs, (jack_client_t *client)); +DECL_VOID_FUNCTION(jack_reset_max_delayed_usecs, (jack_client_t *client)); + +DECL_FUNCTION(int, jack_release_timebase, (jack_client_t *client)); +DECL_FUNCTION(int, jack_set_sync_callback, (jack_client_t *client, (JackSyncCallback sync_callback), (void *arg)); +DECL_FUNCTION(int, jack_set_sync_timeout, (jack_client_t *client), (jack_time_t timeout)); +DECL_FUNCTION(int, jack_set_timebase_callback, (jack_client_t *client), (int conditional), (JackTimebaseCallback timebase_callback), (void *arg)); +DECL_FUNCTION(int, jack_transport_locate, (jack_client_t *client), (jack_nframes_t frame)); +DECL_FUNCTION(jack_transport_state_t, jack_transport_query, (const jack_client_t *client), (jack_position_t *pos)); +DECL_FUNCTION(jack_nframes_t, jack_get_current_transport_frame, (const jack_client_t *client)); +DECL_FUNCTION(int, jack_transport_reposition, (jack_client_t *client), (jack_position_t *pos)); +DECL_VOID_FUNCTION(jack_transport_start, (jack_client_t *client)); +DECL_VOID_FUNCTION(jack_transport_stop, (jack_client_t *client)); +DECL_VOID_FUNCTION(jack_get_transport_info, (jack_client_t *client), (jack_transport_info_t *tinfo)); +DECL_VOID_FUNCTION(jack_set_transport_info, (jack_client_t *client), (jack_transport_info_t *tinfo)); + +DECL_FUNCTION(int, jack_client_real_time_priority, (jack_client_t*)); +DECL_FUNCTION(int, jack_client_max_real_time_priority, (jack_client_t*)); +DECL_FUNCTION(int, jack_acquire_real_time_scheduling, (pthread_t thread), (int priority)); +DECL_FUNCTION(int, jack_client_create_thread, (jack_client_t* client), + (pthread_t *thread), + (int priority), + (int realtime), // boolean + (thread_routine routine), + (void *arg)); +DECL_FUNCTION(int, jack_drop_real_time_scheduling, (pthread_t thread)); + +DECL_FUNCTION(int, jack_client_stop_thread, (jack_client_t* client), (pthread_t thread)); +DECL_FUNCTION(int, jack_client_kill_thread, (jack_client_t* client), (pthread_t thread)); +#ifndef WIN32 +DECL_VOID_FUNCTION(jack_set_thread_creator, (jack_thread_creator_t jtc)); +#endif +DECL_FUNCTION(char *, jack_get_internal_client_name, (jack_client_t *client, (jack_intclient_t intclient)); +DECL_FUNCTION(jack_intclient_t, jack_internal_client_handle, (jack_client_t *client), (const char *client_name), (jack_status_t *status)); +DECL_FUNCTION(jack_intclient_t, jack_internal_client_load, (jack_client_t *client), (const char *client_name), (jack_options_t options), (jack_status_t *status), ...)); + +DECL_FUNCTION(jack_status_t, jack_internal_client_unload, (jack_client_t *client), jack_intclient_t intclient)); +DECL_VOID_FUNCTION(jack_free, (void* ptr)); + +// MIDI + +DECL_FUNCTION(jack_nframes_t, jack_midi_get_event_count, (void* port_buffer)); +DECL_FUNCTION(int jack_midi_event_get(jack_midi_event_t* event, void* port_buffer, jack_nframes_t event_index); +DECL_VOID_FUNCTION(jack_midi_clear_buffer, (void* port_buffer)); +DECL_FUNCTION(size_t, jack_midi_max_event_size, (void* port_buffer)); +DECL_FUNCTION(jack_midi_data_t*, jack_midi_event_reserve, (void* port_buffer), (jack_nframes_t time), (size_t data_size)); +DECL_FUNCTIO(int jack_midi_event_write, (void* port_buffer), (jack_nframes_t time), (const jack_midi_data_t* data), (size_t data_size)); +DECL_FUNCTION(jack_nframes_t, jack_midi_get_lost_event_count, (void* port_buffer)); diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index e2bf6b8f..53a10bb0 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -32,6 +32,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackConstants.h" #include "JackDriverLoader.h" +#if defined(JACK_DBUS) && defined(__linux__) +#include +#include "audio_reserve.h" +#endif + /* This is a simple port of the old jackdmp.cpp file to use the new Jack 2.0 control API. Available options for the server are "hard-coded" in the source. A much better approach would be to use the control API to: @@ -92,6 +97,7 @@ static void usage(FILE* file) "usage: jackdmp [ --realtime OR -R [ --realtime-priority OR -P priority ] ]\n" " [ --name OR -n server-name ]\n" " [ --timeout OR -t client-timeout-in-msecs ]\n" + " [ --loopback OR -L loopback-port-number ]\n" " [ --midi OR -X midi-driver ]\n" " [ --verbose OR -v ]\n" #ifdef __linux__ @@ -156,17 +162,19 @@ int main(int argc, char* argv[]) const char* server_name = "default"; jackctl_driver_t * audio_driver_ctl; jackctl_driver_t * midi_driver_ctl; + jackctl_driver_t * loopback_driver_ctl; #ifdef __linux__ - const char *options = "-ad:X:P:uvrshVRL:STFl:t:mn:p:c:"; + const char *options = "-ad:X:P:uvrshVRL:STFl:t:mn:p:c:L:"; #else - const char *options = "-ad:X:P:uvrshVRL:STFl:t:mn:p:"; + const char *options = "-ad:X:P:uvrshVRL:STFl:t:mn:p:L:"; #endif struct option long_options[] = { #ifdef __linux__ { "clock-source", 1, 0, 'c' }, #endif + { "loopback-driver", 1, 0, 'L' }, { "audio-driver", 1, 0, 'd' }, { "midi-driver", 1, 0, 'X' }, { "verbose", 0, 0, 'v' }, @@ -200,14 +208,18 @@ int main(int argc, char* argv[]) int port_max = 512; int do_mlock = 1; int do_unlock = 0; + int loopback = 0; bool show_version = false; sigset_t signals; jackctl_parameter_t* param; union jackctl_parameter_value value; copyright(stdout); - - server_ctl = jackctl_server_create(); +#if defined(JACK_DBUS) && defined(__linux__) + server_ctl = jackctl_server_create(audio_acquire, audio_release); +#else + server_ctl = jackctl_server_create(NULL, NULL); +#endif if (server_ctl == NULL) { fprintf(stderr, "Failed to create server object\n"); return -1; @@ -245,6 +257,10 @@ int main(int argc, char* argv[]) seen_audio_driver = true; audio_driver_name = optarg; break; + + case 'L': + loopback = atoi(optarg); + break; case 'X': seen_midi_driver = true; @@ -316,14 +332,6 @@ int main(int argc, char* argv[]) } break; - case 'L': - param = jackctl_get_parameter(server_parameters, "loopback-ports"); - if (param != NULL) { - value.ui = atoi(optarg); - jackctl_parameter_set_value(param, &value); - } - break; - case 'T': param = jackctl_get_parameter(server_parameters, "temporary"); if (param != NULL) { @@ -414,6 +422,20 @@ int main(int argc, char* argv[]) jackctl_server_add_slave(server_ctl, midi_driver_ctl); } + + // Loopback driver + if (loopback > 0) { + loopback_driver_ctl = jackctl_server_get_driver(server_ctl, "loopback"); + if (loopback_driver_ctl != NULL) { + const JSList * loopback_parameters = jackctl_driver_get_parameters(loopback_driver_ctl); + param = jackctl_get_parameter(loopback_parameters, "channels"); + if (param != NULL) { + value.ui = loopback; + jackctl_parameter_set_value(param, &value); + } + jackctl_server_add_slave(server_ctl, loopback_driver_ctl); + } + } notify_server_start(server_name); diff --git a/common/jack/control.h b/common/jack/control.h index b3f5756e..263af1d1 100644 --- a/common/jack/control.h +++ b/common/jack/control.h @@ -109,12 +109,17 @@ jackctl_wait_signals( /** * Call this function to create server object. * + * @param on_device_acquire - Optional callback to be called before device is acquired. If false is returned, device usage will fail + * @param on_device_release - Optional callback to be called after device is released. + * * @return server object handle, NULL if creation of server object * failed. Successfully created server object must be destroyed with * paired call to ::jackctl_server_destroy */ jackctl_server_t * -jackctl_server_create(); +jackctl_server_create( + bool (* on_device_acquire)(const char * device_name), + void (* on_device_release)(const char * device_name)); /** * Call this function to destroy server object. diff --git a/common/jack/jack.h b/common/jack/jack.h index 2a31cbaf..5dc6290e 100644 --- a/common/jack/jack.h +++ b/common/jack/jack.h @@ -108,6 +108,7 @@ jack_client_t * jack_client_open (const char *client_name, * \bold THIS FUNCTION IS DEPRECATED AND SHOULD NOT BE USED IN * NEW JACK CLIENTS * +* @deprecated Please use jack_client_open(). */ jack_client_t * jack_client_new (const char *client_name); @@ -212,8 +213,7 @@ int jack_is_realtime (jack_client_t *client); * \bold THIS FUNCTION IS DEPRECATED AND SHOULD NOT BE USED IN * NEW JACK CLIENTS. * - * It should be replace by use of @ jack_cycle_wait and @ jack_cycle_signal functions. - * + * @deprecated Please use jack_cycle_wait() and jack_cycle_signal() functions. */ jack_nframes_t jack_thread_wait (jack_client_t*, int status); @@ -236,7 +236,7 @@ void jack_cycle_signal (jack_client_t* client, int status); /** * Tell the Jack server to call @a thread_callback in the RT thread. - * Typical use are in conjunction with @a jack_cycle_wait and @ jack_cycle_signal functions. + * Typical use are in conjunction with @a jack_cycle_wait and @a jack_cycle_signal functions. * The code in the supplied function must be suitable for real-time * execution. That means that it cannot call functions that might * block for a long time. This includes malloc, free, printf, @@ -483,7 +483,7 @@ int jack_set_xrun_callback (jack_client_t *, /*@}*/ /** - * @defgroup ServerControl Controlling & querying JACK server operation + * @defgroup ServerClientControl Controlling & querying JACK server operation * @{ */ @@ -835,7 +835,7 @@ int jack_port_set_alias (jack_port_t *port, const char *alias); */ int jack_port_unset_alias (jack_port_t *port, const char *alias); -/* +/** * Get any aliases known for @port. * * @return the number of aliases discovered for the port @@ -984,47 +984,57 @@ jack_port_t * jack_port_by_id (jack_client_t *client, /** * @defgroup TimeFunctions Handling time * @{ - */ + * + * JACK time is in units of 'frames', according to the current sample rate. + * The absolute value of frame times is meaningless, frame times have meaning + * only relative to each other. + */ /** - * @return the time in frames that has passed since the JACK server - * began the current process cycle. + * @return the estimated time in frames that has passed since the JACK + * server began the current process cycle. */ jack_nframes_t jack_frames_since_cycle_start (const jack_client_t *); /** - * @return an estimate of the current time in frames. This is a - * running counter, no significance should be attached to its value, - * but it can be compared to a previously returned value. + * @return the estimated current time in frames. + * This function is intended for use in other threads (not the process + * callback). The return value can be compared with the value of + * jack_last_frame_time to relate time in other threads to JACK time. */ jack_nframes_t jack_frame_time (const jack_client_t *); /** - * @return the frame_time after the last processing of the graph - * this is only to be used from the process callback. - * - * This function can be used to put timestamps generated by - * jack_frame_time() in correlation to the current process cycle. + * @return the precise time at the start of the current process cycle. + * This function may only be used from the process callback, and can + * be used to interpret timestamps generated by jack_frame_time() in + * other threads with respect to the current process cycle. + * + * This is the only jack time function that returns exact time: + * when used during the process callback it always returns the same + * value (until the next process callback, where it will return + * that value + nframes, etc). The return value is guaranteed to be + * monotonic and linear in this fashion unless an xrun occurs. + * If an xrun occurs, clients must check this value again, as time + * may have advanced in a non-linear way (e.g. cycles may have been skipped). */ jack_nframes_t jack_last_frame_time (const jack_client_t *client); /** - * @return estimated time in microseconds of the specified frame time + * @return the estimated time in microseconds of the specified frame time */ jack_time_t jack_frames_to_time(const jack_client_t *client, jack_nframes_t); /** - * @return estimated time in frames for the specified system time. + * @return the estimated time in frames for the specified system time. */ jack_nframes_t jack_time_to_frames(const jack_client_t *client, jack_time_t); /** * @return return JACK's current system time in microseconds, - * using JACK clock source. + * using the JACK clock source. * * The value returned is guaranteed to be monotonic, but not linear. - * - * This function is a client version of @function jack_get_microseconds(). */ jack_time_t jack_get_time(); diff --git a/common/jack/midiport.h b/common/jack/midiport.h index 68841ccd..da0b940d 100644 --- a/common/jack/midiport.h +++ b/common/jack/midiport.h @@ -47,7 +47,7 @@ typedef struct _jack_midi_event * @{ */ -/* Get number of events in a port buffer. +/** Get number of events in a port buffer. * * @param port_buffer Port buffer from which to retrieve event. * @return number of events inside @a port_buffer diff --git a/common/jack/types.h b/common/jack/types.h index 595dd510..fa65ce5c 100644 --- a/common/jack/types.h +++ b/common/jack/types.h @@ -454,6 +454,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 */ @@ -641,7 +642,6 @@ typedef struct { double ticks_per_beat; double beats_per_minute; -} -jack_transport_info_t; +} jack_transport_info_t; #endif /* __jack_types_h__ */ diff --git a/common/memops.c b/common/memops.c index 520b3dc8..7112d40e 100644 --- a/common/memops.c +++ b/common/memops.c @@ -164,6 +164,32 @@ } +#if defined (__SSE2__) && !defined (__sun__) + +/* generates same as _mm_set_ps(1.f, 1.f, 1f., 1f) but faster */ +static inline __m128 gen_one(void) +{ + volatile __m128i x; + __m128i ones = _mm_cmpeq_epi32(x, x); + return (__m128)_mm_slli_epi32 (_mm_srli_epi32(ones, 25), 23); +} + +static inline __m128 clip(__m128 s, __m128 min, __m128 max) +{ + return _mm_min_ps(max, _mm_max_ps(s, min)); +} + +static inline __m128i float_24_sse(__m128 s) +{ + const __m128 upper_bound = gen_one(); /* NORMALIZED_FLOAT_MAX */ + const __m128 lower_bound = _mm_sub_ps(_mm_setzero_ps(), upper_bound); + + __m128 clipped = clip(s, lower_bound, upper_bound); + __m128 scaled = _mm_mul_ps(clipped, _mm_set1_ps(SAMPLE_24BIT_SCALING)); + return _mm_cvtps_epi32(scaled); +} +#endif + /* Linear Congruential noise generator. From the music-dsp list * less random than rand(), but good enough and 10x faster */ @@ -254,7 +280,7 @@ void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigne while (unrolled--) { __m128 in = _mm_load_ps(src); __m128 scaled = _mm_mul_ps(in, factor); - __m128 clipped = _mm_min_ps(int_max, _mm_max_ps(scaled, int_min)); + __m128 clipped = clip(scaled, int_min, int_max); __m128i y = _mm_cvttps_epi32(clipped); __m128i shifted = _mm_slli_epi32(y, 8); @@ -264,13 +290,11 @@ void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigne __m128i shuffled3 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(2, 1, 0, 3)); _mm_store_ss((float*)dst, (__m128)shifted); - dst += dst_skip; - _mm_store_ss((float*)dst, (__m128)shuffled1); - dst += dst_skip; - _mm_store_ss((float*)dst, (__m128)shuffled2); - dst += dst_skip; - _mm_store_ss((float*)dst, (__m128)shuffled3); - dst += dst_skip; + + _mm_store_ss((float*)(dst+dst_skip), (__m128)shuffled1); + _mm_store_ss((float*)(dst+2*dst_skip), (__m128)shuffled2); + _mm_store_ss((float*)(dst+3*dst_skip), (__m128)shuffled3); + dst += 4*dst_skip; src+= 4; } @@ -300,6 +324,8 @@ void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsign { /* ALERT: signed sign-extension portability !!! */ + const jack_default_audio_sample_t scaling = 1.0/SAMPLE_24BIT_SCALING; + while (nsamples--) { int x; #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -319,7 +345,7 @@ void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsign x <<= 8; x |= (unsigned char)(src[0]); #endif - *dst = (x >> 8) / SAMPLE_24BIT_SCALING; + *dst = (x >> 8) * scaling; dst++; src += src_skip; } @@ -357,8 +383,9 @@ void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigne /* ALERT: signed sign-extension portability !!! */ + const jack_default_audio_sample_t scaling = 1.0/SAMPLE_24BIT_SCALING; while (nsamples--) { - *dst = (*((int *) src) >> 8) / SAMPLE_24BIT_SCALING; + *dst = (*((int *) src) >> 8) * scaling; dst++; src += src_skip; } @@ -386,8 +413,38 @@ void sample_move_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { - int32_t z; - +#if defined (__SSE2__) && !defined (__sun__) + _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST); + while (nsamples >= 4) { + int i; + int32_t z[4]; + __m128 samples = _mm_loadu_ps(src); + __m128i converted = float_24_sse(samples); + + __m128i shuffled1 = _mm_shuffle_epi32(converted, _MM_SHUFFLE(0, 3, 2, 1)); + __m128i shuffled2 = _mm_shuffle_epi32(converted, _MM_SHUFFLE(1, 0, 3, 2)); + __m128i shuffled3 = _mm_shuffle_epi32(converted, _MM_SHUFFLE(2, 1, 0, 3)); + + _mm_store_ss((float*)z, (__m128)converted); + _mm_store_ss((float*)z+1, (__m128)shuffled1); + _mm_store_ss((float*)z+2, (__m128)shuffled2); + _mm_store_ss((float*)z+3, (__m128)shuffled3); + + for (i = 0; i != 4; ++i) { +#if __BYTE_ORDER == __LITTLE_ENDIAN + memcpy (dst, z+i, 3); +#elif __BYTE_ORDER == __BIG_ENDIAN + memcpy (dst, (float*)((char *)&z + 1)+i, 3); +#endif + dst += dst_skip; + } + nsamples -= 4; + src += 4; + } +#endif + + int32_t z; + while (nsamples--) { float_24 (*src, z); #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -398,12 +455,13 @@ void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned l dst += dst_skip; src++; } -} +} void sample_move_dS_s24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) { /* ALERT: signed sign-extension portability !!! */ + const jack_default_audio_sample_t scaling = 1.0/SAMPLE_24BIT_SCALING; while (nsamples--) { int x; #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -427,15 +485,43 @@ void sample_move_dS_s24s (jack_default_audio_sample_t *dst, char *src, unsigned x |= 0xff << 24; } #endif - *dst = x / SAMPLE_24BIT_SCALING; + *dst = x * scaling; dst++; src += src_skip; } -} +} void sample_move_dS_s24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) { - /* ALERT: signed sign-extension portability !!! */ + const jack_default_audio_sample_t scaling = 1.f/SAMPLE_24BIT_SCALING; + +#if defined (__SSE2__) && !defined (__sun__) + const __m128 scaling_block = _mm_set_ps1(scaling); + while (nsamples >= 4) { + int x0, x1, x2, x3; + +#if __BYTE_ORDER == __LITTLE_ENDIAN + memcpy((char*)&x0 + 1, src, 3); + memcpy((char*)&x1 + 1, src+src_skip, 3); + memcpy((char*)&x2 + 1, src+2*src_skip, 3); + memcpy((char*)&x3 + 1, src+3*src_skip, 3); +#elif __BYTE_ORDER == __BIG_ENDIAN + memcpy(&x0, src, 3); + memcpy(&x1, src+src_skip, 3); + memcpy(&x2, src+2*src_skip, 3); + memcpy(&x3, src+3*src_skip, 3); +#endif + src += 4 * src_skip; + + const __m128i block_i = _mm_set_epi32(x3, x2, x1, x0); + const __m128i shifted = _mm_srai_epi32(block_i, 8); + const __m128 converted = _mm_cvtepi32_ps (shifted); + const __m128 scaled = _mm_mul_ps(converted, scaling_block); + _mm_storeu_ps(dst, scaled); + dst += 4; + nsamples -= 4; + } +#endif while (nsamples--) { int x; @@ -445,11 +531,11 @@ void sample_move_dS_s24 (jack_default_audio_sample_t *dst, char *src, unsigned l memcpy(&x, src, 3); #endif x >>= 8; - *dst = x / SAMPLE_24BIT_SCALING; + *dst = x * scaling; dst++; src += src_skip; } -} +} void sample_move_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) @@ -636,6 +722,7 @@ void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_t * void sample_move_dS_s16s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) { short z; + const jack_default_audio_sample_t scaling = 1.0/SAMPLE_16BIT_SCALING; /* ALERT: signed sign-extension portability !!! */ while (nsamples--) { @@ -648,7 +735,7 @@ void sample_move_dS_s16s (jack_default_audio_sample_t *dst, char *src, unsigned z <<= 8; z |= (unsigned char)(src[0]); #endif - *dst = z / SAMPLE_16BIT_SCALING; + *dst = z * scaling; dst++; src += src_skip; } @@ -657,8 +744,9 @@ void sample_move_dS_s16s (jack_default_audio_sample_t *dst, char *src, unsigned void sample_move_dS_s16 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) { /* ALERT: signed sign-extension portability !!! */ + const jack_default_audio_sample_t scaling = 1.0/SAMPLE_16BIT_SCALING; while (nsamples--) { - *dst = (*((short *) src)) / SAMPLE_16BIT_SCALING; + *dst = (*((short *) src)) * scaling; dst++; src += src_skip; } diff --git a/common/wscript b/common/wscript index 2c7aa609..951ab68b 100644 --- a/common/wscript +++ b/common/wscript @@ -119,7 +119,6 @@ def build(bld): 'JackExternalClient.cpp', 'JackFreewheelDriver.cpp', 'JackInternalClient.cpp', - 'JackLoopbackDriver.cpp', 'JackServer.cpp', 'JackThreadedDriver.cpp', 'JackRestartThreadedDriver.cpp', @@ -212,7 +211,7 @@ def build(bld): clientlib.defines = 'HAVE_CONFIG_H' clientlib.uselib = uselib clientlib.install_path = '${LIBDIR}' - if bld.env['BUILD_JACKDBUS'] == True: + if bld.env['BUILD_JACKDBUS'] == True and bld.env['BUILD_JACKD'] == False: clientlib.uselib.append('DBUS-1') clientlib.includes = includes clientlib.name = 'clientlib' @@ -258,6 +257,10 @@ def build(bld): if bld.env['IS_SUN']: clientlib.env.append_value("LINKFLAGS", "-lnsl -lsocket") + if bld.env['BUILD_WITH_32_64']: + print "create 32bit lib..." + clientlib32bit = clientlib.clone('lib32') + create_jack_process_obj(bld, 'netmanager', 'JackNetManager.cpp', serverlib) create_jack_process_obj(bld, 'profiler', 'JackProfiler.cpp', serverlib) diff --git a/dbus/audio_reserve.c b/dbus/audio_reserve.c index 00412130..120db64f 100644 --- a/dbus/audio_reserve.c +++ b/dbus/audio_reserve.c @@ -22,74 +22,107 @@ #include #include #include +#include #include "reserve.h" #include "audio_reserve.h" #include "JackError.h" -static DBusConnection* connection = NULL; +#define DEVICE_MAX 2 + +typedef struct reserved_audio_device { + + char device_name[64]; + rd_device * reserved_device; + +} reserved_audio_device; + +static DBusConnection* gConnection = NULL; +static reserved_audio_device gReservedDevice[DEVICE_MAX]; +static int gReserveCount = 0; SERVER_EXPORT int audio_reservation_init() { DBusError error; - dbus_error_init(&error); - if (!(connection = dbus_bus_get(DBUS_BUS_SESSION, &error))) { + if (!(gConnection = dbus_bus_get(DBUS_BUS_SESSION, &error))) { jack_error("Failed to connect to session bus for device reservation %s\n", error.message); return -1; } + jack_info("audio_reservation_init"); return 0; } SERVER_EXPORT int audio_reservation_finish() { - if (connection) - dbus_connection_unref(connection); + if (gConnection) { + dbus_connection_unref(gConnection); + gConnection = NULL; + jack_info("audio_reservation_finish"); + } return 0; } -SERVER_EXPORT void* audio_acquire(int num) +SERVER_EXPORT bool audio_acquire(const char * device_name) { - DBusError error; - rd_device* device; - char audio_name[32]; - int e; - - snprintf(audio_name, sizeof(audio_name) - 1, "Audio%d", num); - if ((e = rd_acquire( - &device, - connection, - audio_name, + DBusError error; + int ret; + + // Open DBus connection first time + if (gReserveCount == 0) + audio_reservation_init(); + + assert(gReserveCount < DEVICE_MAX); + + if ((ret= rd_acquire( + &gReservedDevice[gReserveCount].reserved_device, + gConnection, + device_name, "Jack audio server", INT32_MAX, NULL, &error)) < 0) { - jack_error("Failed to acquire device name : %s error : %s", audio_name, (error.message ? error.message : strerror(-e))); - return NULL; + jack_error("Failed to acquire device name : %s error : %s", device_name, (error.message ? error.message : strerror(-ret))); + return false; } - jack_info("Acquire audio card %s", audio_name); - return (void*)device; + strcpy(gReservedDevice[gReserveCount].device_name, device_name); + gReserveCount++; + jack_info("Acquire audio card %s", device_name); + return true; } -SERVER_EXPORT void audio_reserve_loop() +SERVER_EXPORT void audio_release(const char * device_name) { - if (connection) { - while (dbus_connection_read_write_dispatch (connection, -1)) - ; // empty loop body + int i; + + // Look for corresponding reserved device + for (i = 0; i < DEVICE_MAX; i++) { + if (strcmp(gReservedDevice[i].device_name, device_name) == 0) + break; + } + + if (i < DEVICE_MAX) { + jack_info("Released audio card %s", device_name); + rd_release(gReservedDevice[i].reserved_device); + } else { + jack_error("Audio card %s not found!!", device_name); } + + // Close DBus connection last time + gReserveCount--; + if (gReserveCount == 0) + audio_reservation_finish(); } -SERVER_EXPORT void audio_release(void* dev) +SERVER_EXPORT void audio_reserve_loop() { - rd_device* device = (rd_device*)dev; - if (device) { - jack_info("Release audio card"); - rd_release(device); - } else { - jack_info("No audio card to release..."); - } + if (gConnection != NULL) { + while (dbus_connection_read_write_dispatch (gConnection, -1)) + ; // empty loop body + } } + diff --git a/dbus/audio_reserve.h b/dbus/audio_reserve.h index 9a5c34c5..db01f1ab 100644 --- a/dbus/audio_reserve.h +++ b/dbus/audio_reserve.h @@ -20,6 +20,7 @@ #define __audio_reserve__ #include "JackCompilerDeps.h" +#include #ifdef __cplusplus extern "C" { @@ -28,8 +29,8 @@ extern "C" { SERVER_EXPORT int audio_reservation_init(); SERVER_EXPORT int audio_reservation_finish(); -SERVER_EXPORT void* audio_acquire(int num); -SERVER_EXPORT void audio_release(void* dev); +SERVER_EXPORT bool audio_acquire(const char * device_name); +SERVER_EXPORT void audio_release(const char * device_name); SERVER_EXPORT void audio_reserve_loop(); #ifdef __cplusplus diff --git a/dbus/controller.c b/dbus/controller.c index f5c53f69..17b51fdf 100644 --- a/dbus/controller.c +++ b/dbus/controller.c @@ -29,6 +29,7 @@ #include "controller.h" #include "controller_internal.h" #include "xml.h" +#include "reserve.h" struct jack_dbus_interface_descriptor * g_jackcontroller_interfaces[] = { @@ -279,6 +280,68 @@ jack_controller_switch_master( return TRUE; } +#define DEVICE_MAX 2 + +typedef struct reserved_audio_device { + + char device_name[64]; + rd_device * reserved_device; + +} reserved_audio_device; + + +int g_device_count = 0; +static reserved_audio_device g_reserved_device[DEVICE_MAX]; + +static +bool +on_device_acquire(const char * device_name) +{ + int ret; + DBusError error; + + ret = rd_acquire( + &g_reserved_device[g_device_count].reserved_device, + g_connection, + device_name, + "Jack audio server", + INT32_MAX, + NULL, + &error); + if (ret < 0) + { + jack_error("Failed to acquire device name : %s error : %s", device_name, (error.message ? error.message : strerror(-ret))); + return false; + } + + strcpy(g_reserved_device[g_device_count].device_name, device_name); + g_device_count++; + jack_info("Acquired audio card %s", device_name); + return true; +} + +static +void +on_device_release(const char * device_name) +{ + int i; + + // Look for corresponding reserved device + for (i = 0; i < DEVICE_MAX; i++) { + if (strcmp(g_reserved_device[i].device_name, device_name) == 0) + break; + } + + if (i < DEVICE_MAX) { + jack_info("Released audio card %s", device_name); + rd_release(g_reserved_device[i].reserved_device); + } else { + jack_error("Audio card %s not found!!", device_name); + } + + g_device_count--; +} + void * jack_controller_create( DBusConnection *connection) @@ -303,7 +366,7 @@ jack_controller_create( goto fail; } - controller_ptr->server = jackctl_server_create(); + controller_ptr->server = jackctl_server_create(on_device_acquire, on_device_release); if (controller_ptr->server == NULL) { jack_error("Failed to create server object"); diff --git a/dbus/jackdbus.h b/dbus/jackdbus.h index 0c82de86..d94bc334 100644 --- a/dbus/jackdbus.h +++ b/dbus/jackdbus.h @@ -312,5 +312,6 @@ jack_dbus_send_signal( #define JACK_CONTROLLER_OBJECT_PATH "/org/jackaudio/Controller" extern struct jack_dbus_interface_descriptor * g_jackcontroller_interfaces[]; +extern DBusConnection * g_connection; #endif /* #ifndef DBUS_H__3DB2458F_44B2_43EA_882A_9F888DF71A88__INCLUDED */ diff --git a/dbus/reserve.c b/dbus/reserve.c index 9a9591d2..bc698a6a 100644 --- a/dbus/reserve.c +++ b/dbus/reserve.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "reserve.h" @@ -120,7 +121,7 @@ static DBusHandlerResult object_handler( dbus_error_init(&error); - d = userdata; + d = (rd_device*)userdata; assert(d->ref >= 1); if (dbus_message_is_method_call( @@ -296,7 +297,7 @@ static DBusHandlerResult filter_handler( dbus_error_init(&error); - d = userdata; + d = (rd_device*)userdata; if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameLost")) { const char *name; @@ -352,10 +353,7 @@ oom: return DBUS_HANDLER_RESULT_NEED_MEMORY; } - -static const struct DBusObjectPathVTable vtable ={ - .message_function = object_handler -}; +static DBusObjectPathVTable vtable; int rd_acquire( rd_device **_d, @@ -372,6 +370,8 @@ int rd_acquire( DBusMessage *m = NULL, *reply = NULL; dbus_bool_t good; + vtable.message_function = object_handler; + if (!error) error = &_error; @@ -389,7 +389,7 @@ int rd_acquire( if (!request_cb && priority != INT32_MAX) return -EINVAL; - if (!(d = calloc(sizeof(rd_device), 1))) + if (!(d = (rd_device *)calloc(sizeof(rd_device), 1))) return -ENOMEM; d->ref = 1; @@ -408,13 +408,13 @@ int rd_acquire( d->connection = dbus_connection_ref(connection); d->request_cb = request_cb; - if (!(d->service_name = malloc(sizeof(SERVICE_PREFIX) + strlen(device_name)))) { + if (!(d->service_name = (char*)malloc(sizeof(SERVICE_PREFIX) + strlen(device_name)))) { r = -ENOMEM; goto fail; } sprintf(d->service_name, SERVICE_PREFIX "%s", d->device_name); - if (!(d->object_path = malloc(sizeof(OBJECT_PREFIX) + strlen(device_name)))) { + if (!(d->object_path = (char*)malloc(sizeof(OBJECT_PREFIX) + strlen(device_name)))) { r = -ENOMEM; goto fail; } diff --git a/dbus/reserve.h b/dbus/reserve.h index b315a08c..6e16a07d 100644 --- a/dbus/reserve.h +++ b/dbus/reserve.h @@ -28,6 +28,13 @@ #include #include +# ifndef INT32_MIN +# define INT32_MIN (-2147483647-1) +# endif +# ifndef INT32_MAX +# define INT32_MAX (2147483647) +# endif + typedef struct rd_device rd_device; /* Prototype for a function that is called whenever someone else wants @@ -40,6 +47,10 @@ typedef int (*rd_request_cb_t)( rd_device *d, int forced); /* Non-zero if an application forcibly took the lock away without asking. If this is the case then the return value of this call is ignored. */ +#ifdef __cplusplus +extern "C" { +#endif + /* Try to lock the device. Returns 0 on success, a negative errno * style return value on error. The DBus error might be set as well if * the error was caused D-Bus. */ @@ -66,4 +77,8 @@ void rd_set_userdata(rd_device *d, void *userdata); * userdata was set. */ void* rd_get_userdata(rd_device *d); +#ifdef __cplusplus +} /* extern "C" */ +#endif + #endif diff --git a/dbus/wscript b/dbus/wscript index 8cef8baa..e23e67b0 100644 --- a/dbus/wscript +++ b/dbus/wscript @@ -32,10 +32,12 @@ def configure(conf): if conf.is_defined('HAVE_EXPAT'): conf.env['LIB_EXPAT'] = ['expat'] - conf.env['BUILD_JACKDBUS'] = conf.is_defined('HAVE_EXPAT') and conf.is_defined('HAVE_DBUS_1') + conf.env['BUILD_JACKDBUS1'] = conf.is_defined('HAVE_EXPAT') and conf.is_defined('HAVE_DBUS_1') + def build(bld): - if bld.env["BUILD_JACKDBUS"] != True: + + if bld.env['BUILD_JACKDBUS1'] != True: return obj = bld.new_task_gen('cc', 'program') @@ -59,6 +61,7 @@ def build(bld): #'xml_nop.c', 'xml_write_raw.c', 'sigsegv.c', + 'reserve.c', ] if bld.env['IS_LINUX']: obj.uselib = 'PTHREAD DL RT DBUS-1 EXPAT' diff --git a/doxyfile b/doxyfile index 84f79166..930b9eaf 100644 --- a/doxyfile +++ b/doxyfile @@ -304,7 +304,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = common posix macosx macosx/coreaudio/ linux linux/alsa windows windows/portaudio common/jack/control.h +INPUT = common posix macosx macosx/coreaudio/ linux linux/alsa windows windows/portaudio common/jack/ # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp diff --git a/example-clients/server_control.cpp b/example-clients/server_control.cpp index c21492a3..64ec977c 100644 --- a/example-clients/server_control.cpp +++ b/example-clients/server_control.cpp @@ -167,7 +167,7 @@ int main(int argc, char *argv[]) } } - server = jackctl_server_create(); + server = jackctl_server_create(NULL, NULL); parameters = jackctl_server_get_parameters(server); /* diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index 59743dc9..45486f53 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -48,8 +48,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "usx2y.h" #include "generic.h" #include "memops.h" +#include "JackServerGlobals.h" -#include "audio_reserve.h" //#define DEBUG_WAKEUP 1 @@ -104,31 +104,48 @@ JackAlsaDriver::alsa_driver_check_capabilities (alsa_driver_t *driver) return 0; } -int -JackAlsaDriver::alsa_driver_check_card_type (alsa_driver_t *driver) +static +char * +get_control_device_name (const char * device_name) { - int err; - snd_ctl_card_info_t *card_info; char * ctl_name; regex_t expression; - snd_ctl_card_info_alloca (&card_info); - regcomp(&expression, "(plug)?hw:[0-9](,[0-9])?", REG_ICASE | REG_EXTENDED); - if (!regexec(&expression, driver->alsa_name_playback, 0, NULL, 0)) { + if (!regexec(&expression, device_name, 0, NULL, 0)) { /* the user wants a hw or plughw device, the ctl name * should be hw:x where x is the card number */ char tmp[5]; - strncpy(tmp, strstr(driver->alsa_name_playback, "hw"), 4); + strncpy(tmp, strstr(device_name, "hw"), 4); tmp[4] = '\0'; - jack_log("control device %s", tmp); + //jack_log("control device %s", tmp); ctl_name = strdup(tmp); } else { - ctl_name = strdup(driver->alsa_name_playback); + ctl_name = strdup(device_name); } + regfree(&expression); + + if (ctl_name == NULL) { + jack_error("strdup(\"%s\") failed.", ctl_name); + } + + return ctl_name; +} + +int +JackAlsaDriver::alsa_driver_check_card_type (alsa_driver_t *driver) +{ + int err; + snd_ctl_card_info_t *card_info; + char * ctl_name; + + snd_ctl_card_info_alloca (&card_info); + + ctl_name = get_control_device_name(driver->alsa_name_playback); + // XXX: I don't know the "right" way to do this. Which to use // driver->alsa_name_playback or driver->alsa_name_capture. if ((err = snd_ctl_open (&driver->ctl_handle, ctl_name, 0)) < 0) { @@ -145,9 +162,8 @@ JackAlsaDriver::alsa_driver_check_card_type (alsa_driver_t *driver) } driver->alsa_driver = strdup(snd_ctl_card_info_get_driver (card_info)); - jack_info("Using ALSA driver %s running on %s", driver->alsa_driver, snd_ctl_card_info_get_longname(card_info)); + jack_info("Using ALSA driver %s running on card %i - %s", driver->alsa_driver, snd_ctl_card_info_get_card(card_info), snd_ctl_card_info_get_longname(card_info)); - regfree(&expression); free(ctl_name); return alsa_driver_check_capabilities (driver); @@ -2143,22 +2159,45 @@ int JackAlsaDriver::Detach() return JackAudioDriver::Detach(); } -#if defined(JACK_DBUS) static int card_to_num(const char* device) { - const char* t; - int i; + int err; + char* ctl_name; + snd_ctl_card_info_t *card_info; + snd_ctl_t* ctl_handle; + int i = -1; - if ((t = strchr(device, ':'))) - device = t + 1; + snd_ctl_card_info_alloca (&card_info); - if ((i = snd_card_get_index(device)) < 0) { - i = atoi(device); + ctl_name = get_control_device_name(device); + if (ctl_name == NULL) { + jack_error("get_control_device_name() failed."); + goto fail; } + if ((err = snd_ctl_open (&ctl_handle, ctl_name, 0)) < 0) { + jack_error ("control open \"%s\" (%s)", ctl_name, + snd_strerror(err)); + goto free; + } + + if ((err = snd_ctl_card_info(ctl_handle, card_info)) < 0) { + jack_error ("control hardware info \"%s\" (%s)", + device, snd_strerror (err)); + goto close; + } + + i = snd_ctl_card_info_get_card(card_info); + +close: + snd_ctl_close(ctl_handle); + +free: + free(ctl_name); + +fail: return i; } -#endif int JackAlsaDriver::Open(jack_nframes_t nframes, jack_nframes_t user_nperiods, @@ -2192,25 +2231,24 @@ int JackAlsaDriver::Open(jack_nframes_t nframes, else if (strcmp(midi_driver_name, "raw") == 0) midi = alsa_rawmidi_new((jack_client_t*)this); -#if defined(JACK_DBUS) - if (audio_reservation_init() < 0) { - jack_error("Audio device reservation service not available...."); - } else if (strcmp(capture_driver_name, playback_driver_name) == 0) { // Same device for input and output - fReservedCaptureDevice = audio_acquire(card_to_num(capture_driver_name)); - if (fReservedCaptureDevice == NULL) { - jack_error("Error audio device %s cannot be acquired, trying to open it anyway...", capture_driver_name); - } - } else { - fReservedCaptureDevice = audio_acquire(card_to_num(capture_driver_name)); - if (fReservedCaptureDevice == NULL) { - jack_error("Error capture audio device %s cannot be acquired, trying to open it anyway...", capture_driver_name); - } - fReservedPlaybackDevice = audio_acquire(card_to_num(playback_driver_name)); - if (fReservedPlaybackDevice == NULL) { - jack_error("Error playback audio device %s cannot be acquired, trying to open it anyway...", playback_driver_name); - } + if (JackServerGlobals::on_device_acquire != NULL) + { + int capture_card = card_to_num(capture_driver_name); + int playback_card = card_to_num(playback_driver_name); + char audio_name[32]; + + snprintf(audio_name, sizeof(audio_name) - 1, "Audio%d", capture_card); + if (!JackServerGlobals::on_device_acquire(audio_name)) { + jack_error("Audio device %s cannot be acquired, trying to open it anyway...", capture_driver_name); + } + + if (playback_card != capture_card) { + snprintf(audio_name, sizeof(audio_name) - 1, "Audio%d", playback_card); + if (!JackServerGlobals::on_device_acquire(audio_name)) { + jack_error("Audio device %s cannot be acquired, trying to open it anyway...", playback_driver_name); + } + } } -#endif fDriver = alsa_driver_new ("alsa_pcm", (char*)playback_driver_name, (char*)capture_driver_name, NULL, @@ -2245,11 +2283,23 @@ int JackAlsaDriver::Close() { JackAudioDriver::Close(); alsa_driver_delete((alsa_driver_t*)fDriver); -#if defined(JACK_DBUS) - audio_release(fReservedCaptureDevice); - audio_release(fReservedPlaybackDevice); - audio_reservation_finish(); -#endif + + if (JackServerGlobals::on_device_release != NULL) + { + char audio_name[32]; + int capture_card = card_to_num(fCaptureDriverName); + if (capture_card >= 0) { + snprintf(audio_name, sizeof(audio_name) - 1, "Audio%d", capture_card); + JackServerGlobals::on_device_release(audio_name); + } + + int playback_card = card_to_num(fPlaybackDriverName); + if (playback_card >= 0 && playback_card != capture_card) { + snprintf(audio_name, sizeof(audio_name) - 1, "Audio%d", playback_card); + JackServerGlobals::on_device_release(audio_name); + } + } + return 0; } diff --git a/linux/alsa/JackAlsaDriver.h b/linux/alsa/JackAlsaDriver.h index 6fab0baf..fc66195a 100644 --- a/linux/alsa/JackAlsaDriver.h +++ b/linux/alsa/JackAlsaDriver.h @@ -40,8 +40,8 @@ class JackAlsaDriver : public JackAudioDriver private: jack_driver_t* fDriver; - void* fReservedCaptureDevice; - void* fReservedPlaybackDevice; + int fReservedCaptureDevice; + int fReservedPlaybackDevice; void alsa_driver_release_channel_dependent_memory(alsa_driver_t *driver); int alsa_driver_check_capabilities(alsa_driver_t *driver); @@ -121,8 +121,8 @@ class JackAlsaDriver : public JackAudioDriver JackAlsaDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) : JackAudioDriver(name, alias, engine, table) ,fDriver(NULL) - ,fReservedCaptureDevice(NULL) - ,fReservedPlaybackDevice(NULL) + ,fReservedCaptureDevice(-1) + ,fReservedPlaybackDevice(-1) {} virtual ~JackAlsaDriver() {} diff --git a/linux/alsa/hammerfall.c b/linux/alsa/hammerfall.c index 74f7941e..c2e3efea 100644 --- a/linux/alsa/hammerfall.c +++ b/linux/alsa/hammerfall.c @@ -206,8 +206,10 @@ hammerfall_release (jack_hardware_t *hw) return; } - pthread_cancel (h->monitor_thread); - pthread_join (h->monitor_thread, &status); + if (h->monitor_thread) { + pthread_cancel (h->monitor_thread); + pthread_join (h->monitor_thread, &status); + } free (h); } diff --git a/linux/wscript b/linux/wscript index 966a8ddf..8e12b8ad 100644 --- a/linux/wscript +++ b/linux/wscript @@ -31,10 +31,14 @@ def build(bld): jackd.includes = ['../linux', '../posix', '../common/jack', '../common', '../dbus'] jackd.defines = 'HAVE_CONFIG_H' jackd.source = ['../common/Jackdmp.cpp'] - jackd.uselib = 'PTHREAD DL RT' + if bld.env['IS_LINUX'] and bld.env['BUILD_JACKDBUS']: + jackd.source += ['../dbus/reserve.c', '../dbus/audio_reserve.c'] + jackd.uselib = 'PTHREAD DL RT DBUS-1' + else: + jackd.uselib = 'PTHREAD DL RT' jackd.uselib_local = 'serverlib' jackd.target = 'jackd' - + create_jack_driver_obj(bld, 'dummy', '../common/JackDummyDriver.cpp') alsa_driver_src = ['alsa/JackAlsaDriver.cpp', @@ -47,10 +51,6 @@ def build(bld): 'alsa/hammerfall.c', 'alsa/ice1712.c' ] - - if bld.env['BUILD_JACKDBUS']: - alsa_driver_src += ['../dbus/reserve.c', '../dbus/audio_reserve.c'] - if bld.env['BUILD_DRIVER_ALSA'] == True: create_jack_driver_obj(bld, 'alsa', alsa_driver_src, "ALSA") @@ -63,3 +63,4 @@ def build(bld): create_jack_driver_obj(bld, 'net', '../common/JackNetDriver.cpp') + create_jack_driver_obj(bld, 'loopback', '../common/JackLoopbackDriver.cpp') diff --git a/macosx/Jack-Info.plist b/macosx/Jack-Info.plist index ea2a9e42..924e644a 100644 --- a/macosx/Jack-Info.plist +++ b/macosx/Jack-Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.9.2 + 1.9.3 diff --git a/macosx/JackMachSemaphore.h b/macosx/JackMachSemaphore.h index c82fa8d5..e87f0c5c 100644 --- a/macosx/JackMachSemaphore.h +++ b/macosx/JackMachSemaphore.h @@ -47,7 +47,7 @@ class SERVER_EXPORT JackMachSemaphore : public detail::JackSynchro public: - JackMachSemaphore(): fSemaphore(0) + JackMachSemaphore():JackSynchro(), fSemaphore(0) {} bool Signal(); diff --git a/macosx/JackPlatformPlug_os.h b/macosx/JackPlatformPlug_os.h index 24d94252..c52a259f 100644 --- a/macosx/JackPlatformPlug_os.h +++ b/macosx/JackPlatformPlug_os.h @@ -35,7 +35,7 @@ namespace Jack /* __JackPlatformMutex__ */ #include "JackPosixMutex.h" -namespace Jack {typedef JackPosixMutex JackMutex; } +namespace Jack { typedef JackPosixMutex JackMutex; } /* __JackPlatformThread__ */ #include "JackMachThread.h" @@ -47,8 +47,6 @@ namespace Jack { typedef JackMachSemaphore JackSynchro; } /* __JackPlatformProcessSync__ */ #include "JackProcessSync.h" -//#include "JackMachProcessSync.h" -//namespace Jack { typedef JackMachProcessSync JackProcessSync; } /* Only on windows a special JackProcessSync is used. It is directly defined by including JackProcessSync.h here */ /* __JackPlatformServerChannel__ */ diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index 32ac3988..e0839f84 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -19,6 +19,11 @@ 4B35C6AC0D4733B9000DE7AE /* PBXTargetDependency */, 4B35C6B00D4733B9000DE7AE /* PBXTargetDependency */, 4B35C6B20D4733B9000DE7AE /* PBXTargetDependency */, + 4BDCDC2C1002036100B15929 /* PBXTargetDependency */, + 4BDCDC2E1002036100B15929 /* PBXTargetDependency */, + 4BDCDC301002036100B15929 /* PBXTargetDependency */, + 4BDCDC39100203D500B15929 /* PBXTargetDependency */, + 4BDCDC3B100203D500B15929 /* PBXTargetDependency */, 4B35C6860D4733B9000DE7AE /* PBXTargetDependency */, 4B35C6880D4733B9000DE7AE /* PBXTargetDependency */, 4B35C68A0D4733B9000DE7AE /* PBXTargetDependency */, @@ -29,8 +34,6 @@ 4B35C6940D4733B9000DE7AE /* PBXTargetDependency */, 4B35C6960D4733B9000DE7AE /* PBXTargetDependency */, 4B0A29300D5210C4002EFF74 /* PBXTargetDependency */, - 4B35C6980D4733B9000DE7AE /* PBXTargetDependency */, - 4B35C69A0D4733B9000DE7AE /* PBXTargetDependency */, 4B35C69C0D4733B9000DE7AE /* PBXTargetDependency */, 4B35C69E0D4733B9000DE7AE /* PBXTargetDependency */, 4B35C6A00D4733B9000DE7AE /* PBXTargetDependency */, @@ -41,9 +44,7 @@ 4BFA83380DF6AB540087B4E1 /* PBXTargetDependency */, 4BFA833A0DF6AB540087B4E1 /* PBXTargetDependency */, 4BFA833C0DF6AB540087B4E1 /* PBXTargetDependency */, - 4B35C6A60D4733B9000DE7AE /* PBXTargetDependency */, - 4B35C6A80D4733B9000DE7AE /* PBXTargetDependency */, - 4B35C6AA0D4733B9000DE7AE /* PBXTargetDependency */, + 4B43A8E91014618D00E52943 /* PBXTargetDependency */, ); name = "All Universal 32/64 bits"; productName = All; @@ -61,6 +62,7 @@ 4BF339280F8B87800080FB5B /* PBXTargetDependency */, 4B699DBC097D421700A18468 /* PBXTargetDependency */, BA222AF20DC883F3001A17F4 /* PBXTargetDependency */, + 4B43A8CD1014607100E52943 /* PBXTargetDependency */, 4BD624D30CBCF55700DE782F /* PBXTargetDependency */, BA222AF00DC883EF001A17F4 /* PBXTargetDependency */, 4B19B32C0E23636E00DD4A82 /* PBXTargetDependency */, @@ -81,13 +83,7 @@ 4B0A28F40D520D11002EFF74 /* PBXTargetDependency */, 4B363DE50DEB037F001F72D9 /* PBXTargetDependency */, 4BFA99AC0AAAF41D009E916C /* PBXTargetDependency */, - 4BFA99500AAAED90009E916C /* PBXTargetDependency */, - 4BFA99520AAAED90009E916C /* PBXTargetDependency */, - 4B5F25B30DEEA2430041E486 /* PBXTargetDependency */, 4BFA99540AAAED90009E916C /* PBXTargetDependency */, - 4BFA99580AAAED90009E916C /* PBXTargetDependency */, - 4BFA995A0AAAED90009E916C /* PBXTargetDependency */, - 4BFA995C0AAAED90009E916C /* PBXTargetDependency */, 4B363E750DEB0838001F72D9 /* PBXTargetDependency */, 4B363E770DEB0838001F72D9 /* PBXTargetDependency */, 4B363EF20DEB0965001F72D9 /* PBXTargetDependency */, @@ -210,7 +206,6 @@ 4B35C4AE0D4731D1000DE7AE /* JackMachNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB298908AF450200D450D4 /* JackMachNotifyChannel.h */; }; 4B35C4AF0D4731D1000DE7AE /* JackMachServerChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB297808AF44ED00D450D4 /* JackMachServerChannel.h */; }; 4B35C4B00D4731D1000DE7AE /* JackMachServerNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB297A08AF44ED00D450D4 /* JackMachServerNotifyChannel.h */; }; - 4B35C4B10D4731D1000DE7AE /* JackLoopbackDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF70ACB0908EE95008B75AD /* JackLoopbackDriver.h */; }; 4B35C4B20D4731D1000DE7AE /* JackConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66A8580934964500A89560 /* JackConstants.h */; }; 4B35C4B30D4731D1000DE7AE /* JackTransportEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */; }; 4B35C4B40D4731D1000DE7AE /* JackServerGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC2168D0A444BED00BDA09F /* JackServerGlobals.h */; }; @@ -255,7 +250,6 @@ 4B35C4E70D4731D1000DE7AE /* JackMachNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB298808AF450200D450D4 /* JackMachNotifyChannel.cpp */; }; 4B35C4E80D4731D1000DE7AE /* JackMachServerChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB297908AF44ED00D450D4 /* JackMachServerChannel.cpp */; }; 4B35C4E90D4731D1000DE7AE /* JackMachServerNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB297708AF44ED00D450D4 /* JackMachServerNotifyChannel.cpp */; }; - 4B35C4EA0D4731D1000DE7AE /* JackLoopbackDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF70ACA0908EE95008B75AD /* JackLoopbackDriver.cpp */; }; 4B35C4EB0D4731D1000DE7AE /* JackTransportEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */; }; 4B35C4EC0D4731D1000DE7AE /* JackServerAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1F50834EFB000C94B91 /* JackServerAPI.cpp */; }; 4B35C4ED0D4731D1000DE7AE /* JackServerGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC216880A444BDE00BDA09F /* JackServerGlobals.cpp */; }; @@ -300,6 +294,10 @@ 4B363F3E0DEB0C31001F72D9 /* showtime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363F3D0DEB0C31001F72D9 /* showtime.c */; }; 4B363F760DEB0D7D001F72D9 /* impulse_grabber.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363F750DEB0D7D001F72D9 /* impulse_grabber.c */; }; 4B3F49080AD8503300491C6E /* cpu.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3F49070AD8503300491C6E /* cpu.c */; }; + 4B43A8CA1014605000E52943 /* JackLoopbackDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B43A8C81014605000E52943 /* JackLoopbackDriver.cpp */; }; + 4B43A8CB1014605000E52943 /* JackLoopbackDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B43A8C91014605000E52943 /* JackLoopbackDriver.h */; }; + 4B43A8DF1014615800E52943 /* JackLoopbackDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B43A8C91014605000E52943 /* JackLoopbackDriver.h */; }; + 4B43A8E11014615800E52943 /* JackLoopbackDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B43A8C81014605000E52943 /* JackLoopbackDriver.cpp */; }; 4B4CA9750E02CF9600F4BFDA /* JackRestartThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4CA9730E02CF9600F4BFDA /* JackRestartThreadedDriver.h */; }; 4B4CA9760E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4CA9740E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp */; }; 4B4CA9770E02CF9600F4BFDA /* JackRestartThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4CA9730E02CF9600F4BFDA /* JackRestartThreadedDriver.h */; }; @@ -415,7 +413,6 @@ 4B699C77097D421600A18468 /* JackMachNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB298908AF450200D450D4 /* JackMachNotifyChannel.h */; }; 4B699C78097D421600A18468 /* JackMachServerChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB297808AF44ED00D450D4 /* JackMachServerChannel.h */; }; 4B699C79097D421600A18468 /* JackMachServerNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB297A08AF44ED00D450D4 /* JackMachServerNotifyChannel.h */; }; - 4B699C7A097D421600A18468 /* JackLoopbackDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF70ACB0908EE95008B75AD /* JackLoopbackDriver.h */; }; 4B699C7B097D421600A18468 /* JackConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66A8580934964500A89560 /* JackConstants.h */; }; 4B699C7E097D421600A18468 /* JackMachPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B799AD607899652003F3F15 /* JackMachPort.cpp */; }; 4B699C7F097D421600A18468 /* JackShmMem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1880834EE7900C94B91 /* JackShmMem.cpp */; }; @@ -445,7 +442,6 @@ 4B699CA2097D421600A18468 /* JackMachNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB298808AF450200D450D4 /* JackMachNotifyChannel.cpp */; }; 4B699CA3097D421600A18468 /* JackMachServerChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB297908AF44ED00D450D4 /* JackMachServerChannel.cpp */; }; 4B699CA4097D421600A18468 /* JackMachServerNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB297708AF44ED00D450D4 /* JackMachServerNotifyChannel.cpp */; }; - 4B699CA5097D421600A18468 /* JackLoopbackDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF70ACA0908EE95008B75AD /* JackLoopbackDriver.cpp */; }; 4B699CB4097D421600A18468 /* metro.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D16B0834EDF000C94B91 /* metro.c */; }; 4B699CC4097D421600A18468 /* lsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1690834EDE600C94B91 /* lsp.c */; }; 4B699CF6097D421600A18468 /* freewheel.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1710834EE0F00C94B91 /* freewheel.c */; }; @@ -504,16 +500,11 @@ 4BA4ADB50E87AB2600F26C85 /* JackCoreAudioDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE5FECC0E725C090020B576 /* JackCoreAudioDriver.h */; }; 4BA692B30CBE4C2D00EAD520 /* ipload.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA692B20CBE4C2D00EAD520 /* ipload.c */; }; 4BA692D70CBE4CC600EAD520 /* ipunload.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA692D60CBE4CC600EAD520 /* ipunload.c */; }; - 4BA7BDCE0DC22F4500AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BA7BDCB0DC22F4500AA3457 /* Jackservermp.framework */; }; - 4BA7BDCF0DC22F4500AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BA7BDCB0DC22F4500AA3457 /* Jackservermp.framework */; }; - 4BA7BDD00DC22F4500AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BA7BDCB0DC22F4500AA3457 /* Jackservermp.framework */; }; - 4BA7BDD10DC22F4500AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BA7BDCB0DC22F4500AA3457 /* Jackservermp.framework */; }; - 4BA7BDD20DC22F4500AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BA7BDCB0DC22F4500AA3457 /* Jackservermp.framework */; }; - 4BA7BE0F0DC232A400AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; - 4BA7BE1A0DC2347500AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; - 4BA7BE200DC234FB00AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; - 4BA7BE240DC2350D00AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; - 4BA7BE270DC2352A00AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; + 4BA7BE0F0DC232A400AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; }; + 4BA7BE1A0DC2347500AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; }; + 4BA7BE200DC234FB00AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; }; + 4BA7BE240DC2350D00AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; }; + 4BA7BE270DC2352A00AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; }; 4BA7FECA0D8E76650017FF73 /* control.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA7FEC80D8E76650017FF73 /* control.c */; }; 4BAB95B80B9E20B800A0C723 /* JackPortType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */; }; 4BAB95B90B9E20B800A0C723 /* JackPortType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAB95B70B9E20B800A0C723 /* JackPortType.h */; }; @@ -554,6 +545,52 @@ 4BD4B4D809BACD9600750C0F /* JackTransportEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */; }; 4BD4B4D909BACD9600750C0F /* JackTransportEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */; }; 4BD6240D0CBCF16600DE782F /* inprocess.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BD6240C0CBCF16600DE782F /* inprocess.c */; }; + 4BDCDB951001FB9C00B15929 /* JackCoreMidiDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF339140F8B86DC0080FB5B /* JackCoreMidiDriver.h */; }; + 4BDCDB971001FB9C00B15929 /* JackCoreMidiDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF339150F8B86DC0080FB5B /* JackCoreMidiDriver.cpp */; }; + 4BDCDBB91001FCC000B15929 /* JackNetDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = BA222ADD0DC882A5001A17F4 /* JackNetDriver.h */; }; + 4BDCDBBA1001FCC000B15929 /* JackNetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B76C7690E5AB2DB00E2AC21 /* JackNetInterface.h */; }; + 4BDCDBBB1001FCC000B15929 /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */; }; + 4BDCDBBD1001FCC000B15929 /* JackNetDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA222ADC0DC882A5001A17F4 /* JackNetDriver.cpp */; }; + 4BDCDBBE1001FCC000B15929 /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B76C7680E5AB2DB00E2AC21 /* JackNetInterface.cpp */; }; + 4BDCDBBF1001FCC000B15929 /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */; }; + 4BDCDBD11001FD0100B15929 /* JackWaitThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBC93B80DF9736C002DF220 /* JackWaitThreadedDriver.cpp */; }; + 4BDCDBD21001FD0200B15929 /* JackWaitThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BBC93B90DF9736C002DF220 /* JackWaitThreadedDriver.h */; }; + 4BDCDBD91001FD2D00B15929 /* JackNetManager.h in Headers */ = {isa = PBXBuildFile; fileRef = BA222AEC0DC883B3001A17F4 /* JackNetManager.h */; }; + 4BDCDBDA1001FD2D00B15929 /* JackNetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B76C7690E5AB2DB00E2AC21 /* JackNetInterface.h */; }; + 4BDCDBDB1001FD2D00B15929 /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */; }; + 4BDCDBDC1001FD2D00B15929 /* JackArgParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF284170F31B4BC00B05BE3 /* JackArgParser.h */; }; + 4BDCDBDE1001FD2D00B15929 /* JackNetManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA222AEB0DC883B3001A17F4 /* JackNetManager.cpp */; }; + 4BDCDBDF1001FD2D00B15929 /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B76C7680E5AB2DB00E2AC21 /* JackNetInterface.cpp */; }; + 4BDCDBE01001FD2D00B15929 /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */; }; + 4BDCDBE11001FD2D00B15929 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; + 4BDCDBE21001FD2D00B15929 /* JackArgParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF284160F31B4BC00B05BE3 /* JackArgParser.cpp */; }; + 4BDCDBEE1001FD7300B15929 /* JackAudioAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3070E2362E700DD4A82 /* JackAudioAdapter.h */; }; + 4BDCDBEF1001FD7300B15929 /* JackAudioAdapterInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3090E2362E700DD4A82 /* JackAudioAdapterInterface.h */; }; + 4BDCDBF01001FD7300B15929 /* JackException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30C0E2362E700DD4A82 /* JackException.h */; }; + 4BDCDBF11001FD7300B15929 /* JackLibSampleRateResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */; }; + 4BDCDBF21001FD7300B15929 /* JackCoreAudioAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE5FED00E725C320020B576 /* JackCoreAudioAdapter.h */; }; + 4BDCDBF41001FD7300B15929 /* JackAudioAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3060E2362E700DD4A82 /* JackAudioAdapter.cpp */; }; + 4BDCDBF51001FD7300B15929 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3080E2362E700DD4A82 /* JackAudioAdapterInterface.cpp */; }; + 4BDCDBF61001FD7300B15929 /* JackLibSampleRateResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B30E0E2362E700DD4A82 /* JackLibSampleRateResampler.cpp */; }; + 4BDCDBF71001FD7300B15929 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */; }; + 4BDCDBF81001FD7300B15929 /* JackAudioAdapterFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF4BAB00E3480AB00403CDF /* JackAudioAdapterFactory.cpp */; }; + 4BDCDBF91001FD7300B15929 /* JackCoreAudioAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE5FECF0E725C320020B576 /* JackCoreAudioAdapter.cpp */; }; + 4BDCDC091001FDA800B15929 /* JackArgParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF284160F31B4BC00B05BE3 /* JackArgParser.cpp */; }; + 4BDCDC0A1001FDA800B15929 /* JackArgParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF284170F31B4BC00B05BE3 /* JackArgParser.h */; }; + 4BDCDC111001FDE300B15929 /* JackAudioAdapterInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3090E2362E700DD4A82 /* JackAudioAdapterInterface.h */; }; + 4BDCDC121001FDE300B15929 /* JackException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30C0E2362E700DD4A82 /* JackException.h */; }; + 4BDCDC131001FDE300B15929 /* JackLibSampleRateResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */; }; + 4BDCDC141001FDE300B15929 /* JackNetAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B5E08E00E5B676C00BEE4E0 /* JackNetAdapter.h */; }; + 4BDCDC151001FDE300B15929 /* JackNetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B76C7690E5AB2DB00E2AC21 /* JackNetInterface.h */; }; + 4BDCDC161001FDE300B15929 /* JackAudioAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3070E2362E700DD4A82 /* JackAudioAdapter.h */; }; + 4BDCDC171001FDE300B15929 /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */; }; + 4BDCDC191001FDE300B15929 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3080E2362E700DD4A82 /* JackAudioAdapterInterface.cpp */; }; + 4BDCDC1A1001FDE300B15929 /* JackLibSampleRateResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B30E0E2362E700DD4A82 /* JackLibSampleRateResampler.cpp */; }; + 4BDCDC1B1001FDE300B15929 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */; }; + 4BDCDC1C1001FDE300B15929 /* JackNetAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5E08DF0E5B676C00BEE4E0 /* JackNetAdapter.cpp */; }; + 4BDCDC1D1001FDE300B15929 /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B76C7680E5AB2DB00E2AC21 /* JackNetInterface.cpp */; }; + 4BDCDC1E1001FDE300B15929 /* JackAudioAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3060E2362E700DD4A82 /* JackAudioAdapter.cpp */; }; + 4BDCDC1F1001FDE300B15929 /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */; }; 4BE3225A0CC611EF00AFA640 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737F0CC60A6D001AFFD4 /* types.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BE3225B0CC611F500AFA640 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737F0CC60A6D001AFFD4 /* types.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BE4CC010CDA153400CCF5BB /* JackTools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4CBFF0CDA153400CCF5BB /* JackTools.cpp */; }; @@ -577,12 +614,6 @@ 4BF284190F31B4BC00B05BE3 /* JackArgParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF284170F31B4BC00B05BE3 /* JackArgParser.h */; }; 4BF2841A0F31B4BC00B05BE3 /* JackArgParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF284160F31B4BC00B05BE3 /* JackArgParser.cpp */; }; 4BF2841B0F31B4BC00B05BE3 /* JackArgParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF284170F31B4BC00B05BE3 /* JackArgParser.h */; }; - 4BF2F4210F9F4DA300B3FFAD /* JackDummyDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3988908B3CF6C00B6F371 /* JackDummyDriver.cpp */; }; - 4BF2F4220F9F4DA700B3FFAD /* JackDummyDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3988908B3CF6C00B6F371 /* JackDummyDriver.cpp */; }; - 4BF339160F8B86DC0080FB5B /* JackCoreMidiDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF339140F8B86DC0080FB5B /* JackCoreMidiDriver.h */; }; - 4BF339170F8B86DC0080FB5B /* JackCoreMidiDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF339150F8B86DC0080FB5B /* JackCoreMidiDriver.cpp */; }; - 4BF339180F8B86DC0080FB5B /* JackCoreMidiDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF339140F8B86DC0080FB5B /* JackCoreMidiDriver.h */; }; - 4BF339190F8B86DC0080FB5B /* JackCoreMidiDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF339150F8B86DC0080FB5B /* JackCoreMidiDriver.cpp */; }; 4BF3391A0F8B86DC0080FB5B /* JackCoreMidiDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF339140F8B86DC0080FB5B /* JackCoreMidiDriver.h */; }; 4BF3391B0F8B86DC0080FB5B /* JackCoreMidiDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF339150F8B86DC0080FB5B /* JackCoreMidiDriver.cpp */; }; 4BF339210F8B873E0080FB5B /* JackMidiDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF3391F0F8B873E0080FB5B /* JackMidiDriver.cpp */; }; @@ -598,7 +629,6 @@ 4BF5FBC90E878D24003D2374 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; 4BF5FBCA0E878D24003D2374 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; 4BF5FBCB0E878D24003D2374 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; - 4BFA5E920DEC4D9C00FA4CDB /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BA7BDCB0DC22F4500AA3457 /* Jackservermp.framework */; }; 4BFA5E9F0DEC4DD900FA4CDB /* testMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFA5E9E0DEC4DD900FA4CDB /* testMutex.cpp */; }; 4BFA82850DF6A9E40087B4E1 /* evmon.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363E200DEB0401001F72D9 /* evmon.c */; }; 4BFA82980DF6A9E40087B4E1 /* bufsize.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363E710DEB0808001F72D9 /* bufsize.c */; }; @@ -738,20 +768,6 @@ remoteGlobalIDString = 4B35C56C0D4731D2000DE7AE; remoteInfo = "jack_external_metro 64 bits"; }; - 4B35C6970D4733B9000DE7AE /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4B35C5780D4731D2000DE7AE; - remoteInfo = "testAtomic 64 bits"; - }; - 4B35C6990D4733B9000DE7AE /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4B35C5880D4731D2000DE7AE; - remoteInfo = "testSem 64 bits"; - }; 4B35C69B0D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; @@ -787,27 +803,6 @@ remoteGlobalIDString = 4B35C5CC0D4731D2000DE7AE; remoteInfo = "jack_unload 64 bits"; }; - 4B35C6A50D4733B9000DE7AE /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4B35C5D80D4731D2000DE7AE; - remoteInfo = "synchroServer 64 bits"; - }; - 4B35C6A70D4733B9000DE7AE /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4B35C5EC0D4731D2000DE7AE; - remoteInfo = "synchroClient 64 bits"; - }; - 4B35C6A90D4733B9000DE7AE /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4B35C6000D4731D2000DE7AE; - remoteInfo = "synchroServerClient 64 bits"; - }; 4B35C6AB0D4733B9000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; @@ -878,6 +873,20 @@ remoteGlobalIDString = 4B363F680DEB0D4E001F72D9; remoteInfo = "jack_impulse_grabber Universal"; }; + 4B43A8CC1014607100E52943 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B43A8B010145F6F00E52943; + remoteInfo = "jack_loopback Universal"; + }; + 4B43A8E81014618D00E52943 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B43A8DD1014615800E52943; + remoteInfo = "jack_loopback 64 bits"; + }; 4B5A1BCE0CD1CCC80005BF74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; @@ -892,13 +901,6 @@ remoteGlobalIDString = 4B5A1BD00CD1CCE10005BF74; remoteInfo = jack_midisine; }; - 4B5F25B20DEEA2430041E486 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4BFA5E8B0DEC4D9C00FA4CDB; - remoteInfo = "testMutex Universal"; - }; 4B699DB3097D421700A18468 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; @@ -969,6 +971,41 @@ remoteGlobalIDString = 4BD623ED0CBCF0F000DE782F; remoteInfo = inprocess; }; + 4BDCDC2B1002036100B15929 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4BDCDB931001FB9C00B15929; + remoteInfo = "jack_coremidi 64 bits"; + }; + 4BDCDC2D1002036100B15929 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4BDCDBB71001FCC000B15929; + remoteInfo = "jack_net 64 bits"; + }; + 4BDCDC2F1002036100B15929 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4BDCDBD71001FD2D00B15929; + remoteInfo = "netmanager 64 bits"; + }; + 4BDCDC38100203D500B15929 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4BDCDBEC1001FD7300B15929; + remoteInfo = "audioadapter 64 bits"; + }; + 4BDCDC3A100203D500B15929 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4BDCDC0F1001FDE300B15929; + remoteInfo = "netadapter 64 bits"; + }; 4BE99D620AD7A19100C59091 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; @@ -1060,20 +1097,6 @@ remoteGlobalIDString = 4B699D03097D421600A18468; remoteInfo = "jack_external_metro Universal"; }; - 4BFA994F0AAAED90009E916C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4B699D13097D421600A18468; - remoteInfo = "testAtomic Universal"; - }; - 4BFA99510AAAED90009E916C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4B699D27097D421600A18468; - remoteInfo = "testSem Universal"; - }; 4BFA99530AAAED90009E916C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; @@ -1088,27 +1111,6 @@ remoteGlobalIDString = 4BE6C6910A3E096F005A203A; remoteInfo = "jack_test Universal"; }; - 4BFA99570AAAED90009E916C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4B699D4F097D421600A18468; - remoteInfo = "synchroServer Universal"; - }; - 4BFA99590AAAED90009E916C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4B699D67097D421600A18468; - remoteInfo = "synchroClient Universal"; - }; - 4BFA995B0AAAED90009E916C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4B699D7F097D421700A18468; - remoteInfo = "synchroServerClient Universal"; - }; 4BFA99AB0AAAF41D009E916C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; @@ -1185,7 +1187,7 @@ 4B0A28E60D52073D002EFF74 /* jack_thread_wait */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_thread_wait; sourceTree = BUILT_PRODUCTS_DIR; }; 4B0A28EC0D520852002EFF74 /* tw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tw.c; path = "../example-clients/tw.c"; sourceTree = SOURCE_ROOT; }; 4B0A292D0D52108E002EFF74 /* jack_thread_wait */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_thread_wait; sourceTree = BUILT_PRODUCTS_DIR; }; - 4B19B3000E23620F00DD4A82 /* audioadapter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = audioadapter.so; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B19B3000E23620F00DD4A82 /* netmanager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netmanager.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B19B3060E2362E700DD4A82 /* JackAudioAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapter.cpp; path = ../common/JackAudioAdapter.cpp; sourceTree = SOURCE_ROOT; }; 4B19B3070E2362E700DD4A82 /* JackAudioAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioAdapter.h; path = ../common/JackAudioAdapter.h; sourceTree = SOURCE_ROOT; }; 4B19B3080E2362E700DD4A82 /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; }; @@ -1197,7 +1199,7 @@ 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackGlobals.cpp; path = ../common/JackGlobals.cpp; sourceTree = SOURCE_ROOT; }; 4B35C4250D4731D1000DE7AE /* jackdmp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jackdmp; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C4830D4731D1000DE7AE /* Jackmp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackmp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackservermp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackdmp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5140D4731D1000DE7AE /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5200D4731D1000DE7AE /* jack_midisine */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midisine; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C52C0D4731D1000DE7AE /* jack_metro */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_metro; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1221,25 +1223,29 @@ 4B35C6290D4731D2000DE7AE /* jack_portaudio.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_portaudio.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C6340D4731D2000DE7AE /* jack_dummy.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_dummy.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C63E0D4731D3000DE7AE /* inprocess.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = inprocess.so; sourceTree = BUILT_PRODUCTS_DIR; }; - 4B363DD80DEB02F6001F72D9 /* jack_alias */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_alias; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B363DD80DEB02F6001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363DDE0DEB034E001F72D9 /* alias.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = alias.c; path = "../example-clients/alias.c"; sourceTree = SOURCE_ROOT; }; - 4B363E1A0DEB03C5001F72D9 /* jack_evmon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_evmon; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B363E1A0DEB03C5001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363E200DEB0401001F72D9 /* evmon.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = evmon.c; path = "../example-clients/evmon.c"; sourceTree = SOURCE_ROOT; }; - 4B363E4E0DEB0775001F72D9 /* jack_bufsize */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_bufsize; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B363E4E0DEB0775001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363E710DEB0808001F72D9 /* bufsize.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bufsize.c; path = "../example-clients/bufsize.c"; sourceTree = SOURCE_ROOT; }; - 4B363EE90DEB091C001F72D9 /* jack_rec */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_rec; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B363EE90DEB091C001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363EED0DEB094B001F72D9 /* capture_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = capture_client.c; path = "../example-clients/capture_client.c"; sourceTree = SOURCE_ROOT; }; - 4B363F1E0DEB0A6A001F72D9 /* jack_monitor_client */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_monitor_client; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B363F1E0DEB0A6A001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363F220DEB0AB0001F72D9 /* monitor_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = monitor_client.c; path = "../example-clients/monitor_client.c"; sourceTree = SOURCE_ROOT; }; - 4B363F350DEB0BD1001F72D9 /* jack_showtime */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_showtime; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B363F350DEB0BD1001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363F3D0DEB0C31001F72D9 /* showtime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = showtime.c; path = "../example-clients/showtime.c"; sourceTree = SOURCE_ROOT; }; - 4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_impulse_grabber; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B363F720DEB0D4E001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363F750DEB0D7D001F72D9 /* impulse_grabber.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = impulse_grabber.c; path = "../example-clients/impulse_grabber.c"; sourceTree = SOURCE_ROOT; }; 4B37C20306DF1FBE0016E567 /* CALatencyLog.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CALatencyLog.cpp; path = /Developer/Examples/CoreAudio/PublicUtility/CALatencyLog.cpp; sourceTree = ""; }; 4B37C20406DF1FBE0016E567 /* CALatencyLog.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CALatencyLog.h; path = /Developer/Examples/CoreAudio/PublicUtility/CALatencyLog.h; sourceTree = ""; }; 4B37C20906DF1FE20016E567 /* latency.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = latency.c; path = /Developer/Examples/CoreAudio/PublicUtility/latency.c; sourceTree = ""; }; 4B3F49070AD8503300491C6E /* cpu.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpu.c; path = ../tests/cpu.c; sourceTree = SOURCE_ROOT; }; 4B4259E5076B635E00C1ECE1 /* JackMacEngineRPC.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMacEngineRPC.cpp; sourceTree = SOURCE_ROOT; }; + 4B43A8BA10145F6F00E52943 /* jack_dummy.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_dummy.so; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B43A8C81014605000E52943 /* JackLoopbackDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackLoopbackDriver.cpp; path = ../common/JackLoopbackDriver.cpp; sourceTree = SOURCE_ROOT; }; + 4B43A8C91014605000E52943 /* JackLoopbackDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackLoopbackDriver.h; path = ../common/JackLoopbackDriver.h; sourceTree = SOURCE_ROOT; }; + 4B43A8E71014615800E52943 /* jack_dummy.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_dummy.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B464301076CAC7700E5077C /* Jack-Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = "Jack-Info.plist"; sourceTree = SOURCE_ROOT; }; 4B4CA9730E02CF9600F4BFDA /* JackRestartThreadedDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackRestartThreadedDriver.h; path = ../common/JackRestartThreadedDriver.h; sourceTree = SOURCE_ROOT; }; 4B4CA9740E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackRestartThreadedDriver.cpp; path = ../common/JackRestartThreadedDriver.cpp; sourceTree = SOURCE_ROOT; }; @@ -1252,7 +1258,7 @@ 4B5A1BBD0CD1CC110005BF74 /* midiseq.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = midiseq.c; path = "../example-clients/midiseq.c"; sourceTree = SOURCE_ROOT; }; 4B5A1BDA0CD1CCE10005BF74 /* jack_midisine */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midisine; sourceTree = BUILT_PRODUCTS_DIR; }; 4B5A1BDC0CD1CD420005BF74 /* midisine.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = midisine.c; path = "../example-clients/midisine.c"; sourceTree = SOURCE_ROOT; }; - 4B5E08D50E5B66EE00BEE4E0 /* netadapter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netadapter.so; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B5E08D50E5B66EE00BEE4E0 /* netmanager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netmanager.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B5E08DF0E5B676C00BEE4E0 /* JackNetAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetAdapter.cpp; path = ../common/JackNetAdapter.cpp; sourceTree = SOURCE_ROOT; }; 4B5E08E00E5B676C00BEE4E0 /* JackNetAdapter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackNetAdapter.h; path = ../common/JackNetAdapter.h; sourceTree = SOURCE_ROOT; }; 4B5F253D0DEE9B8F0041E486 /* JackLockedEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackLockedEngine.h; path = ../common/JackLockedEngine.h; sourceTree = SOURCE_ROOT; }; @@ -1309,8 +1315,7 @@ 4BA692B20CBE4C2D00EAD520 /* ipload.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ipload.c; path = "../example-clients/ipload.c"; sourceTree = SOURCE_ROOT; }; 4BA692D40CBE4C9000EAD520 /* jack_unload */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_unload; sourceTree = BUILT_PRODUCTS_DIR; }; 4BA692D60CBE4CC600EAD520 /* ipunload.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ipunload.c; path = "../example-clients/ipunload.c"; sourceTree = SOURCE_ROOT; }; - 4BA7BDCB0DC22F4500AA3457 /* Jackservermp.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Jackservermp.framework; path = build/Development/Jackservermp.framework; sourceTree = SOURCE_ROOT; }; - 4BA7FEC30D8E76270017FF73 /* jack_server_control */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_server_control; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BA7FEC30D8E76270017FF73 /* jack_lsp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_lsp; sourceTree = BUILT_PRODUCTS_DIR; }; 4BA7FEC80D8E76650017FF73 /* control.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = control.c; path = "../example-clients/control.c"; sourceTree = SOURCE_ROOT; }; 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackPortType.cpp; path = ../common/JackPortType.cpp; sourceTree = SOURCE_ROOT; }; 4BAB95B70B9E20B800A0C723 /* JackPortType.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackPortType.h; path = ../common/JackPortType.h; sourceTree = SOURCE_ROOT; }; @@ -1352,6 +1357,11 @@ 4BD561C708EEB910006BBC2A /* JackSynchro.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackSynchro.h; path = ../common/JackSynchro.h; sourceTree = SOURCE_ROOT; }; 4BD623F70CBCF0F000DE782F /* inprocess.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = inprocess.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4BD6240C0CBCF16600DE782F /* inprocess.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = inprocess.c; path = "../example-clients/inprocess.c"; sourceTree = SOURCE_ROOT; }; + 4BDCDB9D1001FB9C00B15929 /* jack_coremidi.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_coremidi.so; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BDCDBC51001FCC000B15929 /* jack_net.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_net.so; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BDCDBE81001FD2D00B15929 /* netmanager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netmanager.so; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BDCDBFF1001FD7300B15929 /* netmanager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netmanager.so; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BDCDC251001FDE300B15929 /* netmanager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netmanager.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4BE4CBFF0CDA153400CCF5BB /* JackTools.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackTools.cpp; path = ../common/JackTools.cpp; sourceTree = SOURCE_ROOT; }; 4BE4CC000CDA153400CCF5BB /* JackTools.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackTools.h; path = ../common/JackTools.h; sourceTree = SOURCE_ROOT; }; 4BE5FECB0E725C090020B576 /* JackCoreAudioDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreAudioDriver.cpp; path = coreaudio/JackCoreAudioDriver.cpp; sourceTree = SOURCE_ROOT; }; @@ -1378,8 +1388,6 @@ 4BF5FBC80E878D24003D2374 /* JackMachTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = JackMachTime.c; sourceTree = SOURCE_ROOT; }; 4BF6C1D508ACE64C001E2013 /* JackMachSemaphore.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMachSemaphore.cpp; sourceTree = SOURCE_ROOT; }; 4BF6C1D608ACE64C001E2013 /* JackMachSemaphore.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JackMachSemaphore.h; sourceTree = SOURCE_ROOT; }; - 4BF70ACA0908EE95008B75AD /* JackLoopbackDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackLoopbackDriver.cpp; path = ../common/JackLoopbackDriver.cpp; sourceTree = SOURCE_ROOT; }; - 4BF70ACB0908EE95008B75AD /* JackLoopbackDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackLoopbackDriver.h; path = ../common/JackLoopbackDriver.h; sourceTree = SOURCE_ROOT; }; 4BF772FD08B3330F00149912 /* JackAtomic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackAtomic.h; path = ../common/JackAtomic.h; sourceTree = SOURCE_ROOT; }; 4BF8D1670834EDD900C94B91 /* zombie.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = zombie.c; path = "../example-clients/zombie.c"; sourceTree = SOURCE_ROOT; }; 4BF8D1690834EDE600C94B91 /* lsp.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lsp.c; path = "..//example-clients/lsp.c"; sourceTree = SOURCE_ROOT; }; @@ -1435,14 +1443,14 @@ 4BF8D2470834F20600C94B91 /* testSem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSem.cpp; path = ../tests/testSem.cpp; sourceTree = SOURCE_ROOT; }; 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackFrameTimer.cpp; path = ../common/JackFrameTimer.cpp; sourceTree = SOURCE_ROOT; }; 4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackFrameTimer.h; path = ../common/JackFrameTimer.h; sourceTree = SOURCE_ROOT; }; - 4BFA5E980DEC4D9C00FA4CDB /* testMutex */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testMutex; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BFA5E980DEC4D9C00FA4CDB /* testSem */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testSem; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA5E9E0DEC4DD900FA4CDB /* testMutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = testMutex.cpp; path = ../tests/testMutex.cpp; sourceTree = SOURCE_ROOT; }; - 4BFA828C0DF6A9E40087B4E1 /* jack_evmon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_evmon; sourceTree = BUILT_PRODUCTS_DIR; }; - 4BFA829F0DF6A9E40087B4E1 /* jack_bufsize */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_bufsize; sourceTree = BUILT_PRODUCTS_DIR; }; - 4BFA82AB0DF6A9E40087B4E1 /* jack_rec */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_rec; sourceTree = BUILT_PRODUCTS_DIR; }; - 4BFA82B70DF6A9E40087B4E1 /* jack_monitor_client */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_monitor_client; sourceTree = BUILT_PRODUCTS_DIR; }; - 4BFA82C30DF6A9E40087B4E1 /* jack_showtime */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_showtime; sourceTree = BUILT_PRODUCTS_DIR; }; - 4BFA82CF0DF6A9E40087B4E1 /* jack_impulse_grabber */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_impulse_grabber; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BFA828C0DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BFA829F0DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BFA82AB0DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BFA82B70DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BFA82C30DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BFA82CF0DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA99A20AAAF3B0009E916C /* jdelay */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jdelay; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA99A90AAAF40C009E916C /* jdelay.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = jdelay.cpp; path = ../tests/jdelay.cpp; sourceTree = SOURCE_ROOT; }; 4BFB297708AF44ED00D450D4 /* JackMachServerNotifyChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMachServerNotifyChannel.cpp; sourceTree = ""; }; @@ -1580,7 +1588,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4BA7BE0F0DC232A400AA3457 /* Jackservermp.framework in Frameworks */, + 4BA7BE0F0DC232A400AA3457 /* Jackdmp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1588,7 +1596,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4BA7BE1A0DC2347500AA3457 /* Jackservermp.framework in Frameworks */, + 4BA7BE1A0DC2347500AA3457 /* Jackdmp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1631,7 +1639,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4BA7BE200DC234FB00AA3457 /* Jackservermp.framework in Frameworks */, + 4BA7BE200DC234FB00AA3457 /* Jackdmp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1639,7 +1647,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4BA7BE240DC2350D00AA3457 /* Jackservermp.framework in Frameworks */, + 4BA7BE240DC2350D00AA3457 /* Jackdmp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1647,7 +1655,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4BA7BE270DC2352A00AA3457 /* Jackservermp.framework in Frameworks */, + 4BA7BE270DC2352A00AA3457 /* Jackdmp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1728,6 +1736,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B43A8B510145F6F00E52943 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B43A8E21014615800E52943 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B5A1BB50CD1CB9E0005BF74 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1818,7 +1840,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4BA7BDCE0DC22F4500AA3457 /* Jackservermp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1826,7 +1847,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4BA7BDCF0DC22F4500AA3457 /* Jackservermp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1841,7 +1861,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4BA7BDD00DC22F4500AA3457 /* Jackservermp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1849,7 +1868,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4BA7BDD10DC22F4500AA3457 /* Jackservermp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1857,7 +1875,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4BA7BDD20DC22F4500AA3457 /* Jackservermp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1910,6 +1927,41 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BDCDB981001FB9C00B15929 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BDCDBC01001FCC000B15929 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BDCDBE31001FD2D00B15929 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BDCDBFA1001FD7300B15929 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BDCDC201001FDE300B15929 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BE6C69D0A3E096F005A203A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1935,7 +1987,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4BFA5E920DEC4D9C00FA4CDB /* Jackservermp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2008,7 +2059,6 @@ 0249A662FF388D9811CA2CEA /* External Frameworks and Libraries */ = { isa = PBXGroup; children = ( - 4BA7BDCB0DC22F4500AA3457 /* Jackservermp.framework */, 4BCC87950D57168300A7FEB1 /* Accelerate.framework */, ); name = "External Frameworks and Libraries"; @@ -2079,7 +2129,7 @@ 4B5A1BDA0CD1CCE10005BF74 /* jack_midisine */, 4B35C4250D4731D1000DE7AE /* jackdmp */, 4B35C4830D4731D1000DE7AE /* Jackmp.framework */, - 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */, + 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */, 4B35C5140D4731D1000DE7AE /* jack_midiseq */, 4B35C5200D4731D1000DE7AE /* jack_midisine */, 4B35C52C0D4731D1000DE7AE /* jack_metro */, @@ -2106,27 +2156,34 @@ 4B0A28E60D52073D002EFF74 /* jack_thread_wait */, 4B0A292D0D52108E002EFF74 /* jack_thread_wait */, 4B57F5950D72C27900B4E719 /* jack_thread_wait */, - 4BA7FEC30D8E76270017FF73 /* jack_server_control */, + 4BA7FEC30D8E76270017FF73 /* jack_lsp */, BA222ACF0DC88132001A17F4 /* jack_net.so */, BA222AE90DC882DB001A17F4 /* netmanager.so */, - 4BA7FEC30D8E76270017FF73 /* jack_server_control */, - 4B363DD80DEB02F6001F72D9 /* jack_alias */, - 4B363E1A0DEB03C5001F72D9 /* jack_evmon */, - 4B363E4E0DEB0775001F72D9 /* jack_bufsize */, - 4B363EE90DEB091C001F72D9 /* jack_rec */, - 4B363F1E0DEB0A6A001F72D9 /* jack_monitor_client */, - 4B363F350DEB0BD1001F72D9 /* jack_showtime */, - 4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */, - 4BFA5E980DEC4D9C00FA4CDB /* testMutex */, - 4BFA828C0DF6A9E40087B4E1 /* jack_evmon */, - 4BFA829F0DF6A9E40087B4E1 /* jack_bufsize */, - 4BFA82AB0DF6A9E40087B4E1 /* jack_rec */, - 4BFA82B70DF6A9E40087B4E1 /* jack_monitor_client */, - 4BFA82C30DF6A9E40087B4E1 /* jack_showtime */, - 4BFA82CF0DF6A9E40087B4E1 /* jack_impulse_grabber */, - 4B19B3000E23620F00DD4A82 /* audioadapter.so */, - 4B5E08D50E5B66EE00BEE4E0 /* netadapter.so */, + 4BA7FEC30D8E76270017FF73 /* jack_lsp */, + 4B363DD80DEB02F6001F72D9 /* jack_midiseq */, + 4B363E1A0DEB03C5001F72D9 /* jack_midiseq */, + 4B363E4E0DEB0775001F72D9 /* jack_midiseq */, + 4B363EE90DEB091C001F72D9 /* jack_midiseq */, + 4B363F1E0DEB0A6A001F72D9 /* jack_midiseq */, + 4B363F350DEB0BD1001F72D9 /* jack_midiseq */, + 4B363F720DEB0D4E001F72D9 /* jack_midiseq */, + 4BFA5E980DEC4D9C00FA4CDB /* testSem */, + 4BFA828C0DF6A9E40087B4E1 /* jack_midiseq */, + 4BFA829F0DF6A9E40087B4E1 /* jack_midiseq */, + 4BFA82AB0DF6A9E40087B4E1 /* jack_midiseq */, + 4BFA82B70DF6A9E40087B4E1 /* jack_midiseq */, + 4BFA82C30DF6A9E40087B4E1 /* jack_midiseq */, + 4BFA82CF0DF6A9E40087B4E1 /* jack_midiseq */, + 4B19B3000E23620F00DD4A82 /* netmanager.so */, + 4B5E08D50E5B66EE00BEE4E0 /* netmanager.so */, 4BF3390C0F8B864B0080FB5B /* jack_coremidi.so */, + 4BDCDB9D1001FB9C00B15929 /* jack_coremidi.so */, + 4BDCDBC51001FCC000B15929 /* jack_net.so */, + 4BDCDBE81001FD2D00B15929 /* netmanager.so */, + 4BDCDBFF1001FD7300B15929 /* netmanager.so */, + 4BDCDC251001FDE300B15929 /* netmanager.so */, + 4B43A8BA10145F6F00E52943 /* jack_dummy.so */, + 4B43A8E71014615800E52943 /* jack_dummy.so */, ); name = Products; sourceTree = ""; @@ -2423,12 +2480,12 @@ isa = PBXGroup; children = ( 4B869B3D08C8D21C001CF041 /* driver_interface.h */, + 4B43A8C91014605000E52943 /* JackLoopbackDriver.h */, + 4B43A8C81014605000E52943 /* JackLoopbackDriver.cpp */, 4B869B4208C8D22F001CF041 /* JackDriverLoader.h */, 4B869D7F08C9CB00001CF041 /* JackDriverLoader.cpp */, 4BF8D1B50834EEE400C94B91 /* JackDriver.h */, 4BF8D1B60834EEE400C94B91 /* JackDriver.cpp */, - 4BF70ACB0908EE95008B75AD /* JackLoopbackDriver.h */, - 4BF70ACA0908EE95008B75AD /* JackLoopbackDriver.cpp */, 4BC3988A08B3CF6C00B6F371 /* JackDummyDriver.h */, 4BC3988908B3CF6C00B6F371 /* JackDummyDriver.cpp */, 4BF3390D0F8B86AF0080FB5B /* MIDI */, @@ -2729,7 +2786,6 @@ 4B4F9C910DC20C0400706CB0 /* JackMessageBuffer.h in Headers */, 4B93F19E0E87998400E4ECCD /* JackPosixThread.h in Headers */, 4BECB2FA0F4451C10091B70A /* JackProcessSync.h in Headers */, - 4BF339160F8B86DC0080FB5B /* JackCoreMidiDriver.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2769,7 +2825,6 @@ 4B35C4AE0D4731D1000DE7AE /* JackMachNotifyChannel.h in Headers */, 4B35C4AF0D4731D1000DE7AE /* JackMachServerChannel.h in Headers */, 4B35C4B00D4731D1000DE7AE /* JackMachServerNotifyChannel.h in Headers */, - 4B35C4B10D4731D1000DE7AE /* JackLoopbackDriver.h in Headers */, 4B35C4B20D4731D1000DE7AE /* JackConstants.h in Headers */, 4B35C4B30D4731D1000DE7AE /* JackTransportEngine.h in Headers */, 4B35C4B40D4731D1000DE7AE /* JackServerGlobals.h in Headers */, @@ -2794,8 +2849,9 @@ 4B93F19A0E87992200E4ECCD /* JackPosixThread.h in Headers */, 4BBAE4120F42FA6100B8BD3F /* JackEngineProfiling.h in Headers */, 4BECB2FC0F4451C10091B70A /* JackProcessSync.h in Headers */, - 4BF339180F8B86DC0080FB5B /* JackCoreMidiDriver.h in Headers */, 4BF339220F8B873E0080FB5B /* JackMidiDriver.h in Headers */, + 4BDCDBD21001FD0200B15929 /* JackWaitThreadedDriver.h in Headers */, + 4BDCDC0A1001FDA800B15929 /* JackArgParser.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3014,6 +3070,22 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B43A8B110145F6F00E52943 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B43A8CB1014605000E52943 /* JackLoopbackDriver.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B43A8DE1014615800E52943 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B43A8DF1014615800E52943 /* JackLoopbackDriver.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B5A1BB20CD1CB9E0005BF74 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -3134,7 +3206,6 @@ 4B699C77097D421600A18468 /* JackMachNotifyChannel.h in Headers */, 4B699C78097D421600A18468 /* JackMachServerChannel.h in Headers */, 4B699C79097D421600A18468 /* JackMachServerNotifyChannel.h in Headers */, - 4B699C7A097D421600A18468 /* JackLoopbackDriver.h in Headers */, 4B699C7B097D421600A18468 /* JackConstants.h in Headers */, 4BD4B4D809BACD9600750C0F /* JackTransportEngine.h in Headers */, 4BC2168E0A444BED00BDA09F /* JackServerGlobals.h in Headers */, @@ -3305,6 +3376,61 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BDCDB941001FB9C00B15929 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BDCDB951001FB9C00B15929 /* JackCoreMidiDriver.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BDCDBB81001FCC000B15929 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BDCDBB91001FCC000B15929 /* JackNetDriver.h in Headers */, + 4BDCDBBA1001FCC000B15929 /* JackNetInterface.h in Headers */, + 4BDCDBBB1001FCC000B15929 /* JackNetUnixSocket.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BDCDBD81001FD2D00B15929 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BDCDBD91001FD2D00B15929 /* JackNetManager.h in Headers */, + 4BDCDBDA1001FD2D00B15929 /* JackNetInterface.h in Headers */, + 4BDCDBDB1001FD2D00B15929 /* JackNetUnixSocket.h in Headers */, + 4BDCDBDC1001FD2D00B15929 /* JackArgParser.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BDCDBED1001FD7300B15929 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BDCDBEE1001FD7300B15929 /* JackAudioAdapter.h in Headers */, + 4BDCDBEF1001FD7300B15929 /* JackAudioAdapterInterface.h in Headers */, + 4BDCDBF01001FD7300B15929 /* JackException.h in Headers */, + 4BDCDBF11001FD7300B15929 /* JackLibSampleRateResampler.h in Headers */, + 4BDCDBF21001FD7300B15929 /* JackCoreAudioAdapter.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BDCDC101001FDE300B15929 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BDCDC111001FDE300B15929 /* JackAudioAdapterInterface.h in Headers */, + 4BDCDC121001FDE300B15929 /* JackException.h in Headers */, + 4BDCDC131001FDE300B15929 /* JackLibSampleRateResampler.h in Headers */, + 4BDCDC141001FDE300B15929 /* JackNetAdapter.h in Headers */, + 4BDCDC151001FDE300B15929 /* JackNetInterface.h in Headers */, + 4BDCDC161001FDE300B15929 /* JackAudioAdapter.h in Headers */, + 4BDCDC171001FDE300B15929 /* JackNetUnixSocket.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BE6C6920A3E096F005A203A /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -3445,9 +3571,9 @@ productReference = 4B0A292D0D52108E002EFF74 /* jack_thread_wait */; productType = "com.apple.product-type.tool"; }; - 4B19B2F60E23620F00DD4A82 /* audioadapter */ = { + 4B19B2F60E23620F00DD4A82 /* audioadapter Universal */ = { isa = PBXNativeTarget; - buildConfigurationList = 4B19B2FC0E23620F00DD4A82 /* Build configuration list for PBXNativeTarget "audioadapter" */; + buildConfigurationList = 4B19B2FC0E23620F00DD4A82 /* Build configuration list for PBXNativeTarget "audioadapter Universal" */; buildPhases = ( 4B19B2F70E23620F00DD4A82 /* Headers */, 4B19B2F90E23620F00DD4A82 /* Sources */, @@ -3457,9 +3583,9 @@ ); dependencies = ( ); - name = audioadapter; + name = "audioadapter Universal"; productName = jack_coreaudio; - productReference = 4B19B3000E23620F00DD4A82 /* audioadapter.so */; + productReference = 4B19B3000E23620F00DD4A82 /* netmanager.so */; productType = "com.apple.product-type.library.dynamic"; }; 4B35C41B0D4731D1000DE7AE /* jackdmp framework 64bits */ = { @@ -3516,7 +3642,7 @@ ); name = "Jackservermp.framework 64 bits"; productName = Jack; - productReference = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; + productReference = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; productType = "com.apple.product-type.framework"; }; 4B35C50A0D4731D1000DE7AE /* jack_midiseq 64 bits */ = { @@ -3965,7 +4091,7 @@ name = "jack_alias Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4B363DD80DEB02F6001F72D9 /* jack_alias */; + productReference = 4B363DD80DEB02F6001F72D9 /* jack_midiseq */; productType = "com.apple.product-type.tool"; }; 4B363E100DEB03C5001F72D9 /* jack_evmon Universal */ = { @@ -3984,7 +4110,7 @@ name = "jack_evmon Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4B363E1A0DEB03C5001F72D9 /* jack_evmon */; + productReference = 4B363E1A0DEB03C5001F72D9 /* jack_midiseq */; productType = "com.apple.product-type.tool"; }; 4B363E440DEB0775001F72D9 /* jack_bufsize Universal */ = { @@ -4003,7 +4129,7 @@ name = "jack_bufsize Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4B363E4E0DEB0775001F72D9 /* jack_bufsize */; + productReference = 4B363E4E0DEB0775001F72D9 /* jack_midiseq */; productType = "com.apple.product-type.tool"; }; 4B363EDF0DEB091C001F72D9 /* jack_rec Universal */ = { @@ -4022,7 +4148,7 @@ name = "jack_rec Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4B363EE90DEB091C001F72D9 /* jack_rec */; + productReference = 4B363EE90DEB091C001F72D9 /* jack_midiseq */; productType = "com.apple.product-type.tool"; }; 4B363F140DEB0A6A001F72D9 /* jack_monitor_client Universal */ = { @@ -4041,7 +4167,7 @@ name = "jack_monitor_client Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4B363F1E0DEB0A6A001F72D9 /* jack_monitor_client */; + productReference = 4B363F1E0DEB0A6A001F72D9 /* jack_midiseq */; productType = "com.apple.product-type.tool"; }; 4B363F2B0DEB0BD1001F72D9 /* jack_showtime Universal */ = { @@ -4060,7 +4186,7 @@ name = "jack_showtime Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4B363F350DEB0BD1001F72D9 /* jack_showtime */; + productReference = 4B363F350DEB0BD1001F72D9 /* jack_midiseq */; productType = "com.apple.product-type.tool"; }; 4B363F680DEB0D4E001F72D9 /* jack_impulse_grabber Universal */ = { @@ -4079,9 +4205,43 @@ name = "jack_impulse_grabber Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */; + productReference = 4B363F720DEB0D4E001F72D9 /* jack_midiseq */; productType = "com.apple.product-type.tool"; }; + 4B43A8B010145F6F00E52943 /* jack_loopback Universal */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B43A8B610145F6F00E52943 /* Build configuration list for PBXNativeTarget "jack_loopback Universal" */; + buildPhases = ( + 4B43A8B110145F6F00E52943 /* Headers */, + 4B43A8B310145F6F00E52943 /* Sources */, + 4B43A8B510145F6F00E52943 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "jack_loopback Universal"; + productName = jack_coreaudio; + productReference = 4B43A8BA10145F6F00E52943 /* jack_dummy.so */; + productType = "com.apple.product-type.library.dynamic"; + }; + 4B43A8DD1014615800E52943 /* jack_loopback 64 bits */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B43A8E31014615800E52943 /* Build configuration list for PBXNativeTarget "jack_loopback 64 bits" */; + buildPhases = ( + 4B43A8DE1014615800E52943 /* Headers */, + 4B43A8E01014615800E52943 /* Sources */, + 4B43A8E21014615800E52943 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "jack_loopback 64 bits"; + productName = jack_coreaudio; + productReference = 4B43A8E71014615800E52943 /* jack_dummy.so */; + productType = "com.apple.product-type.library.dynamic"; + }; 4B5A1BB10CD1CB9E0005BF74 /* jack_midiseq Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B5A1BB70CD1CB9E0005BF74 /* Build configuration list for PBXNativeTarget "jack_midiseq Universal" */; @@ -4120,9 +4280,9 @@ productReference = 4B5A1BDA0CD1CCE10005BF74 /* jack_midisine */; productType = "com.apple.product-type.tool"; }; - 4B5E08BF0E5B66EE00BEE4E0 /* netadapter */ = { + 4B5E08BF0E5B66EE00BEE4E0 /* netadapter Universal */ = { isa = PBXNativeTarget; - buildConfigurationList = 4B5E08D10E5B66EE00BEE4E0 /* Build configuration list for PBXNativeTarget "netadapter" */; + buildConfigurationList = 4B5E08D10E5B66EE00BEE4E0 /* Build configuration list for PBXNativeTarget "netadapter Universal" */; buildPhases = ( 4B5E08C00E5B66EE00BEE4E0 /* Headers */, 4B5E08C90E5B66EE00BEE4E0 /* Sources */, @@ -4132,9 +4292,9 @@ ); dependencies = ( ); - name = netadapter; + name = "netadapter Universal"; productName = jack_coreaudio; - productReference = 4B5E08D50E5B66EE00BEE4E0 /* netadapter.so */; + productReference = 4B5E08D50E5B66EE00BEE4E0 /* netmanager.so */; productType = "com.apple.product-type.library.dynamic"; }; 4B699BA7097D421600A18468 /* jackdmp framework Universal */ = { @@ -4528,12 +4688,12 @@ name = "jack_server_control Universal"; productInstallPath = /usr/local/bin; productName = jack_lsp; - productReference = 4BA7FEC30D8E76270017FF73 /* jack_server_control */; + productReference = 4BA7FEC30D8E76270017FF73 /* jack_lsp */; productType = "com.apple.product-type.tool"; }; - 4BD623ED0CBCF0F000DE782F /* inprocess */ = { + 4BD623ED0CBCF0F000DE782F /* inprocess Universal */ = { isa = PBXNativeTarget; - buildConfigurationList = 4BD623F30CBCF0F000DE782F /* Build configuration list for PBXNativeTarget "inprocess" */; + buildConfigurationList = 4BD623F30CBCF0F000DE782F /* Build configuration list for PBXNativeTarget "inprocess Universal" */; buildPhases = ( 4BD623EE0CBCF0F000DE782F /* Headers */, 4BD623F00CBCF0F000DE782F /* Sources */, @@ -4543,11 +4703,96 @@ ); dependencies = ( ); - name = inprocess; + name = "inprocess Universal"; productName = jack_coreaudio; productReference = 4BD623F70CBCF0F000DE782F /* inprocess.so */; productType = "com.apple.product-type.library.dynamic"; }; + 4BDCDB931001FB9C00B15929 /* jack_coremidi 64 bits */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4BDCDB991001FB9C00B15929 /* Build configuration list for PBXNativeTarget "jack_coremidi 64 bits" */; + buildPhases = ( + 4BDCDB941001FB9C00B15929 /* Headers */, + 4BDCDB961001FB9C00B15929 /* Sources */, + 4BDCDB981001FB9C00B15929 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "jack_coremidi 64 bits"; + productName = jack_coreaudio; + productReference = 4BDCDB9D1001FB9C00B15929 /* jack_coremidi.so */; + productType = "com.apple.product-type.library.dynamic"; + }; + 4BDCDBB71001FCC000B15929 /* jack_net 64 bits */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4BDCDBC11001FCC000B15929 /* Build configuration list for PBXNativeTarget "jack_net 64 bits" */; + buildPhases = ( + 4BDCDBB81001FCC000B15929 /* Headers */, + 4BDCDBBC1001FCC000B15929 /* Sources */, + 4BDCDBC01001FCC000B15929 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "jack_net 64 bits"; + productName = jack_coreaudio; + productReference = 4BDCDBC51001FCC000B15929 /* jack_net.so */; + productType = "com.apple.product-type.library.dynamic"; + }; + 4BDCDBD71001FD2D00B15929 /* netmanager 64 bits */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4BDCDBE41001FD2D00B15929 /* Build configuration list for PBXNativeTarget "netmanager 64 bits" */; + buildPhases = ( + 4BDCDBD81001FD2D00B15929 /* Headers */, + 4BDCDBDD1001FD2D00B15929 /* Sources */, + 4BDCDBE31001FD2D00B15929 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "netmanager 64 bits"; + productName = jack_coreaudio; + productReference = 4BDCDBE81001FD2D00B15929 /* netmanager.so */; + productType = "com.apple.product-type.library.dynamic"; + }; + 4BDCDBEC1001FD7300B15929 /* audioadapter 64 bits */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4BDCDBFB1001FD7300B15929 /* Build configuration list for PBXNativeTarget "audioadapter 64 bits" */; + buildPhases = ( + 4BDCDBED1001FD7300B15929 /* Headers */, + 4BDCDBF31001FD7300B15929 /* Sources */, + 4BDCDBFA1001FD7300B15929 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "audioadapter 64 bits"; + productName = jack_coreaudio; + productReference = 4BDCDBFF1001FD7300B15929 /* netmanager.so */; + productType = "com.apple.product-type.library.dynamic"; + }; + 4BDCDC0F1001FDE300B15929 /* netadapter 64 bits */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4BDCDC211001FDE300B15929 /* Build configuration list for PBXNativeTarget "netadapter 64 bits" */; + buildPhases = ( + 4BDCDC101001FDE300B15929 /* Headers */, + 4BDCDC181001FDE300B15929 /* Sources */, + 4BDCDC201001FDE300B15929 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "netadapter 64 bits"; + productName = jack_coreaudio; + productReference = 4BDCDC251001FDE300B15929 /* netmanager.so */; + productType = "com.apple.product-type.library.dynamic"; + }; 4BE6C6910A3E096F005A203A /* jack_test Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4BE6C69F0A3E096F005A203A /* Build configuration list for PBXNativeTarget "jack_test Universal" */; @@ -4619,7 +4864,7 @@ name = "testMutex Universal"; productInstallPath = /usr/local/bin; productName = testSem; - productReference = 4BFA5E980DEC4D9C00FA4CDB /* testMutex */; + productReference = 4BFA5E980DEC4D9C00FA4CDB /* testSem */; productType = "com.apple.product-type.tool"; }; 4BFA82820DF6A9E40087B4E1 /* jack_evmon 64 bits */ = { @@ -4638,7 +4883,7 @@ name = "jack_evmon 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4BFA828C0DF6A9E40087B4E1 /* jack_evmon */; + productReference = 4BFA828C0DF6A9E40087B4E1 /* jack_midiseq */; productType = "com.apple.product-type.tool"; }; 4BFA82950DF6A9E40087B4E1 /* jack_bufsize 64 bits */ = { @@ -4657,7 +4902,7 @@ name = "jack_bufsize 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4BFA829F0DF6A9E40087B4E1 /* jack_bufsize */; + productReference = 4BFA829F0DF6A9E40087B4E1 /* jack_midiseq */; productType = "com.apple.product-type.tool"; }; 4BFA82A10DF6A9E40087B4E1 /* jack_rec 64 bits */ = { @@ -4676,7 +4921,7 @@ name = "jack_rec 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4BFA82AB0DF6A9E40087B4E1 /* jack_rec */; + productReference = 4BFA82AB0DF6A9E40087B4E1 /* jack_midiseq */; productType = "com.apple.product-type.tool"; }; 4BFA82AD0DF6A9E40087B4E1 /* jack_monitor_client 64 bits */ = { @@ -4695,7 +4940,7 @@ name = "jack_monitor_client 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4BFA82B70DF6A9E40087B4E1 /* jack_monitor_client */; + productReference = 4BFA82B70DF6A9E40087B4E1 /* jack_midiseq */; productType = "com.apple.product-type.tool"; }; 4BFA82B90DF6A9E40087B4E1 /* jack_showtime 64 bits */ = { @@ -4714,7 +4959,7 @@ name = "jack_showtime 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4BFA82C30DF6A9E40087B4E1 /* jack_showtime */; + productReference = 4BFA82C30DF6A9E40087B4E1 /* jack_midiseq */; productType = "com.apple.product-type.tool"; }; 4BFA82C50DF6A9E40087B4E1 /* jack_impulse_grabber 64 bits */ = { @@ -4733,7 +4978,7 @@ name = "jack_impulse_grabber 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4BFA82CF0DF6A9E40087B4E1 /* jack_impulse_grabber */; + productReference = 4BFA82CF0DF6A9E40087B4E1 /* jack_midiseq */; productType = "com.apple.product-type.tool"; }; 4BFA99980AAAF3B0009E916C /* jdelay Universal */ = { @@ -4772,9 +5017,9 @@ productReference = BA222ACF0DC88132001A17F4 /* jack_net.so */; productType = "com.apple.product-type.library.dynamic"; }; - BA222AE00DC882DB001A17F4 /* netmanager */ = { + BA222AE00DC882DB001A17F4 /* netmanager Universal */ = { isa = PBXNativeTarget; - buildConfigurationList = BA222AE50DC882DB001A17F4 /* Build configuration list for PBXNativeTarget "netmanager" */; + buildConfigurationList = BA222AE50DC882DB001A17F4 /* Build configuration list for PBXNativeTarget "netmanager Universal" */; buildPhases = ( BA222AE10DC882DB001A17F4 /* Headers */, BA222AE20DC882DB001A17F4 /* Sources */, @@ -4784,7 +5029,7 @@ ); dependencies = ( ); - name = netmanager; + name = "netmanager Universal"; productName = jack_coreaudio; productReference = BA222AE90DC882DB001A17F4 /* netmanager.so */; productType = "com.apple.product-type.library.dynamic"; @@ -4838,12 +5083,13 @@ 4B699D97097D421700A18468 /* jack_coreaudio Universal */, 4B978DB10A31CF4A009E2DD1 /* jack_portaudio Universal */, 4BF339020F8B864B0080FB5B /* jack_coremidi Universal */, + 4B43A8B010145F6F00E52943 /* jack_loopback Universal */, 4B699DA6097D421700A18468 /* jack_dummy Universal */, BA222AC50DC88132001A17F4 /* jack_net Universal */, - 4BD623ED0CBCF0F000DE782F /* inprocess */, - BA222AE00DC882DB001A17F4 /* netmanager */, - 4B19B2F60E23620F00DD4A82 /* audioadapter */, - 4B5E08BF0E5B66EE00BEE4E0 /* netadapter */, + 4BD623ED0CBCF0F000DE782F /* inprocess Universal */, + BA222AE00DC882DB001A17F4 /* netmanager Universal */, + 4B19B2F60E23620F00DD4A82 /* audioadapter Universal */, + 4B5E08BF0E5B66EE00BEE4E0 /* netadapter Universal */, 4B35C41B0D4731D1000DE7AE /* jackdmp framework 64bits */, 4B35C4270D4731D1000DE7AE /* Jackmp.framework 64 bits */, 4B35C4850D4731D1000DE7AE /* Jackservermp.framework 64 bits */, @@ -4876,6 +5122,12 @@ 4B35C6140D4731D2000DE7AE /* jack_coreaudio 64 bits */, 4B35C61F0D4731D2000DE7AE /* jack_portaudio 64 bits */, 4B35C62A0D4731D2000DE7AE /* jack_dummy 64 bits */, + 4B43A8DD1014615800E52943 /* jack_loopback 64 bits */, + 4BDCDB931001FB9C00B15929 /* jack_coremidi 64 bits */, + 4BDCDBB71001FCC000B15929 /* jack_net 64 bits */, + 4BDCDBD71001FD2D00B15929 /* netmanager 64 bits */, + 4BDCDBEC1001FD7300B15929 /* audioadapter 64 bits */, + 4BDCDC0F1001FDE300B15929 /* netadapter 64 bits */, 4B35C6350D4731D3000DE7AE /* inprocess 64 bits */, ); }; @@ -5418,7 +5670,6 @@ 4B93F19D0E87998400E4ECCD /* JackPosixThread.cpp in Sources */, 4B93F1C00E87A35400E4ECCD /* JackMachTime.c in Sources */, 4BECB2F90F4451C10091B70A /* JackProcessSync.cpp in Sources */, - 4BF339170F8B86DC0080FB5B /* JackCoreMidiDriver.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5454,7 +5705,6 @@ 4B35C4E70D4731D1000DE7AE /* JackMachNotifyChannel.cpp in Sources */, 4B35C4E80D4731D1000DE7AE /* JackMachServerChannel.cpp in Sources */, 4B35C4E90D4731D1000DE7AE /* JackMachServerNotifyChannel.cpp in Sources */, - 4B35C4EA0D4731D1000DE7AE /* JackLoopbackDriver.cpp in Sources */, 4B35C4EB0D4731D1000DE7AE /* JackTransportEngine.cpp in Sources */, 4B35C4EC0D4731D1000DE7AE /* JackServerAPI.cpp in Sources */, 4B35C4ED0D4731D1000DE7AE /* JackServerGlobals.cpp in Sources */, @@ -5475,9 +5725,9 @@ 4B93F22B0E87A72500E4ECCD /* JackMachTime.c in Sources */, 4BBAE4130F42FA6100B8BD3F /* JackEngineProfiling.cpp in Sources */, 4BECB2FB0F4451C10091B70A /* JackProcessSync.cpp in Sources */, - 4BF339190F8B86DC0080FB5B /* JackCoreMidiDriver.cpp in Sources */, 4BF339210F8B873E0080FB5B /* JackMidiDriver.cpp in Sources */, - 4BF2F4220F9F4DA700B3FFAD /* JackDummyDriver.cpp in Sources */, + 4BDCDBD11001FD0100B15929 /* JackWaitThreadedDriver.cpp in Sources */, + 4BDCDC091001FDA800B15929 /* JackArgParser.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5723,6 +5973,22 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B43A8B310145F6F00E52943 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B43A8CA1014605000E52943 /* JackLoopbackDriver.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B43A8E01014615800E52943 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B43A8E11014615800E52943 /* JackLoopbackDriver.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B5A1BB30CD1CB9E0005BF74 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -5834,7 +6100,6 @@ 4B699CA2097D421600A18468 /* JackMachNotifyChannel.cpp in Sources */, 4B699CA3097D421600A18468 /* JackMachServerChannel.cpp in Sources */, 4B699CA4097D421600A18468 /* JackMachServerNotifyChannel.cpp in Sources */, - 4B699CA5097D421600A18468 /* JackLoopbackDriver.cpp in Sources */, 4BD4B4D909BACD9600750C0F /* JackTransportEngine.cpp in Sources */, 4BC216850A444BAD00BDA09F /* JackServerAPI.cpp in Sources */, 4BC216890A444BDE00BDA09F /* JackServerGlobals.cpp in Sources */, @@ -5858,7 +6123,6 @@ 4BBAE4110F42FA6100B8BD3F /* JackEngineProfiling.cpp in Sources */, 4BECB2F50F4451C10091B70A /* JackProcessSync.cpp in Sources */, 4BF339230F8B873E0080FB5B /* JackMidiDriver.cpp in Sources */, - 4BF2F4210F9F4DA300B3FFAD /* JackDummyDriver.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6014,59 +6278,116 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 4BE6C6950A3E096F005A203A /* Sources */ = { + 4BDCDB961001FB9C00B15929 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4BE6C6AD0A3E0A65005A203A /* test.cpp in Sources */, + 4BDCDB971001FB9C00B15929 /* JackCoreMidiDriver.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4BE99D280AD7A04800C59091 /* Sources */ = { + 4BDCDBBC1001FCC000B15929 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4B3F49080AD8503300491C6E /* cpu.c in Sources */, + 4BDCDBBD1001FCC000B15929 /* JackNetDriver.cpp in Sources */, + 4BDCDBBE1001FCC000B15929 /* JackNetInterface.cpp in Sources */, + 4BDCDBBF1001FCC000B15929 /* JackNetUnixSocket.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4BF339050F8B864B0080FB5B /* Sources */ = { + 4BDCDBDD1001FD2D00B15929 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4BF3391B0F8B86DC0080FB5B /* JackCoreMidiDriver.cpp in Sources */, + 4BDCDBDE1001FD2D00B15929 /* JackNetManager.cpp in Sources */, + 4BDCDBDF1001FD2D00B15929 /* JackNetInterface.cpp in Sources */, + 4BDCDBE01001FD2D00B15929 /* JackNetUnixSocket.cpp in Sources */, + 4BDCDBE11001FD2D00B15929 /* JackMachTime.c in Sources */, + 4BDCDBE21001FD2D00B15929 /* JackArgParser.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4BFA5E8D0DEC4D9C00FA4CDB /* Sources */ = { + 4BDCDBF31001FD7300B15929 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4BFA5E9F0DEC4DD900FA4CDB /* testMutex.cpp in Sources */, + 4BDCDBF41001FD7300B15929 /* JackAudioAdapter.cpp in Sources */, + 4BDCDBF51001FD7300B15929 /* JackAudioAdapterInterface.cpp in Sources */, + 4BDCDBF61001FD7300B15929 /* JackLibSampleRateResampler.cpp in Sources */, + 4BDCDBF71001FD7300B15929 /* JackResampler.cpp in Sources */, + 4BDCDBF81001FD7300B15929 /* JackAudioAdapterFactory.cpp in Sources */, + 4BDCDBF91001FD7300B15929 /* JackCoreAudioAdapter.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4BFA82840DF6A9E40087B4E1 /* Sources */ = { + 4BDCDC181001FDE300B15929 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4BFA82850DF6A9E40087B4E1 /* evmon.c in Sources */, + 4BDCDC191001FDE300B15929 /* JackAudioAdapterInterface.cpp in Sources */, + 4BDCDC1A1001FDE300B15929 /* JackLibSampleRateResampler.cpp in Sources */, + 4BDCDC1B1001FDE300B15929 /* JackResampler.cpp in Sources */, + 4BDCDC1C1001FDE300B15929 /* JackNetAdapter.cpp in Sources */, + 4BDCDC1D1001FDE300B15929 /* JackNetInterface.cpp in Sources */, + 4BDCDC1E1001FDE300B15929 /* JackAudioAdapter.cpp in Sources */, + 4BDCDC1F1001FDE300B15929 /* JackNetUnixSocket.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4BFA82970DF6A9E40087B4E1 /* Sources */ = { + 4BE6C6950A3E096F005A203A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4BFA82980DF6A9E40087B4E1 /* bufsize.c in Sources */, + 4BE6C6AD0A3E0A65005A203A /* test.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4BFA82A30DF6A9E40087B4E1 /* Sources */ = { + 4BE99D280AD7A04800C59091 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4BFA82A40DF6A9E40087B4E1 /* capture_client.c in Sources */, + 4B3F49080AD8503300491C6E /* cpu.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BF339050F8B864B0080FB5B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BF3391B0F8B86DC0080FB5B /* JackCoreMidiDriver.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BFA5E8D0DEC4D9C00FA4CDB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BFA5E9F0DEC4DD900FA4CDB /* testMutex.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BFA82840DF6A9E40087B4E1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BFA82850DF6A9E40087B4E1 /* evmon.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BFA82970DF6A9E40087B4E1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BFA82980DF6A9E40087B4E1 /* bufsize.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BFA82A30DF6A9E40087B4E1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BFA82A40DF6A9E40087B4E1 /* capture_client.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6139,12 +6460,12 @@ }; 4B19B32C0E23636E00DD4A82 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4B19B2F60E23620F00DD4A82 /* audioadapter */; + target = 4B19B2F60E23620F00DD4A82 /* audioadapter Universal */; targetProxy = 4B19B32B0E23636E00DD4A82 /* PBXContainerItemProxy */; }; 4B224B340E65BA330066BE5B /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4B5E08BF0E5B66EE00BEE4E0 /* netadapter */; + target = 4B5E08BF0E5B66EE00BEE4E0 /* netadapter Universal */; targetProxy = 4B224B330E65BA330066BE5B /* PBXContainerItemProxy */; }; 4B35C5530D4731D2000DE7AE /* PBXTargetDependency */ = { @@ -6212,16 +6533,6 @@ target = 4B35C56C0D4731D2000DE7AE /* jack_external_metro 64 bits */; targetProxy = 4B35C6950D4733B9000DE7AE /* PBXContainerItemProxy */; }; - 4B35C6980D4733B9000DE7AE /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4B35C5780D4731D2000DE7AE /* testAtomic 64 bits */; - targetProxy = 4B35C6970D4733B9000DE7AE /* PBXContainerItemProxy */; - }; - 4B35C69A0D4733B9000DE7AE /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4B35C5880D4731D2000DE7AE /* testSem 64 bits */; - targetProxy = 4B35C6990D4733B9000DE7AE /* PBXContainerItemProxy */; - }; 4B35C69C0D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C59C0D4731D2000DE7AE /* zombie 64 bits */; @@ -6247,21 +6558,6 @@ target = 4B35C5CC0D4731D2000DE7AE /* jack_unload 64 bits */; targetProxy = 4B35C6A30D4733B9000DE7AE /* PBXContainerItemProxy */; }; - 4B35C6A60D4733B9000DE7AE /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4B35C5D80D4731D2000DE7AE /* synchroServer 64 bits */; - targetProxy = 4B35C6A50D4733B9000DE7AE /* PBXContainerItemProxy */; - }; - 4B35C6A80D4733B9000DE7AE /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4B35C5EC0D4731D2000DE7AE /* synchroClient 64 bits */; - targetProxy = 4B35C6A70D4733B9000DE7AE /* PBXContainerItemProxy */; - }; - 4B35C6AA0D4733B9000DE7AE /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4B35C6000D4731D2000DE7AE /* synchroServerClient 64 bits */; - targetProxy = 4B35C6A90D4733B9000DE7AE /* PBXContainerItemProxy */; - }; 4B35C6AC0D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B35C6140D4731D2000DE7AE /* jack_coreaudio 64 bits */; @@ -6312,6 +6608,16 @@ target = 4B363F680DEB0D4E001F72D9 /* jack_impulse_grabber Universal */; targetProxy = 4B363F770DEB0D85001F72D9 /* PBXContainerItemProxy */; }; + 4B43A8CD1014607100E52943 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4B43A8B010145F6F00E52943 /* jack_loopback Universal */; + targetProxy = 4B43A8CC1014607100E52943 /* PBXContainerItemProxy */; + }; + 4B43A8E91014618D00E52943 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4B43A8DD1014615800E52943 /* jack_loopback 64 bits */; + targetProxy = 4B43A8E81014618D00E52943 /* PBXContainerItemProxy */; + }; 4B5A1BCF0CD1CCC80005BF74 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B5A1BB10CD1CB9E0005BF74 /* jack_midiseq Universal */; @@ -6322,11 +6628,6 @@ target = 4B5A1BD00CD1CCE10005BF74 /* jack_midisine Universal */; targetProxy = 4B5A1BE10CD1CD730005BF74 /* PBXContainerItemProxy */; }; - 4B5F25B30DEEA2430041E486 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4BFA5E8B0DEC4D9C00FA4CDB /* testMutex Universal */; - targetProxy = 4B5F25B20DEEA2430041E486 /* PBXContainerItemProxy */; - }; 4B699DB4097D421700A18468 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B699C4C097D421600A18468 /* Jackservermp.framework Universal */; @@ -6374,9 +6675,34 @@ }; 4BD624D30CBCF55700DE782F /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4BD623ED0CBCF0F000DE782F /* inprocess */; + target = 4BD623ED0CBCF0F000DE782F /* inprocess Universal */; targetProxy = 4BD624D20CBCF55700DE782F /* PBXContainerItemProxy */; }; + 4BDCDC2C1002036100B15929 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4BDCDB931001FB9C00B15929 /* jack_coremidi 64 bits */; + targetProxy = 4BDCDC2B1002036100B15929 /* PBXContainerItemProxy */; + }; + 4BDCDC2E1002036100B15929 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4BDCDBB71001FCC000B15929 /* jack_net 64 bits */; + targetProxy = 4BDCDC2D1002036100B15929 /* PBXContainerItemProxy */; + }; + 4BDCDC301002036100B15929 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4BDCDBD71001FD2D00B15929 /* netmanager 64 bits */; + targetProxy = 4BDCDC2F1002036100B15929 /* PBXContainerItemProxy */; + }; + 4BDCDC39100203D500B15929 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4BDCDBEC1001FD7300B15929 /* audioadapter 64 bits */; + targetProxy = 4BDCDC38100203D500B15929 /* PBXContainerItemProxy */; + }; + 4BDCDC3B100203D500B15929 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4BDCDC0F1001FDE300B15929 /* netadapter 64 bits */; + targetProxy = 4BDCDC3A100203D500B15929 /* PBXContainerItemProxy */; + }; 4BE99D630AD7A19100C59091 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BE99D260AD7A04800C59091 /* jack_cpu Universal */; @@ -6442,16 +6768,6 @@ target = 4B699D03097D421600A18468 /* jack_external_metro Universal */; targetProxy = 4BFA994D0AAAED90009E916C /* PBXContainerItemProxy */; }; - 4BFA99500AAAED90009E916C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4B699D13097D421600A18468 /* testAtomic Universal */; - targetProxy = 4BFA994F0AAAED90009E916C /* PBXContainerItemProxy */; - }; - 4BFA99520AAAED90009E916C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4B699D27097D421600A18468 /* testSem Universal */; - targetProxy = 4BFA99510AAAED90009E916C /* PBXContainerItemProxy */; - }; 4BFA99540AAAED90009E916C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B699D3F097D421600A18468 /* zombie Universal */; @@ -6462,21 +6778,6 @@ target = 4BE6C6910A3E096F005A203A /* jack_test Universal */; targetProxy = 4BFA99550AAAED90009E916C /* PBXContainerItemProxy */; }; - 4BFA99580AAAED90009E916C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4B699D4F097D421600A18468 /* synchroServer Universal */; - targetProxy = 4BFA99570AAAED90009E916C /* PBXContainerItemProxy */; - }; - 4BFA995A0AAAED90009E916C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4B699D67097D421600A18468 /* synchroClient Universal */; - targetProxy = 4BFA99590AAAED90009E916C /* PBXContainerItemProxy */; - }; - 4BFA995C0AAAED90009E916C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4B699D7F097D421700A18468 /* synchroServerClient Universal */; - targetProxy = 4BFA995B0AAAED90009E916C /* PBXContainerItemProxy */; - }; 4BFA99AC0AAAF41D009E916C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BFA99980AAAF3B0009E916C /* jdelay Universal */; @@ -6484,7 +6785,7 @@ }; BA222AF00DC883EF001A17F4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = BA222AE00DC882DB001A17F4 /* netmanager */; + target = BA222AE00DC882DB001A17F4 /* netmanager Universal */; targetProxy = BA222AEF0DC883EF001A17F4 /* PBXContainerItemProxy */; }; BA222AF20DC883F3001A17F4 /* PBXTargetDependency */ = { @@ -6856,10 +7157,12 @@ OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", + "-DJACK_32_64", ); OTHER_CPLUSPLUSFLAGS = ( "-DMACH_RPC_MACH_SEMA", "-D__SMP__", + "-DJACK_32_64", ); OTHER_LDFLAGS = ( "-framework", @@ -6914,10 +7217,12 @@ OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", + "-DJACK_32_64", ); OTHER_CPLUSPLUSFLAGS = ( "-DMACH_RPC_MACH_SEMA", "-D__SMP__", + "-DJACK_32_64", ); OTHER_LDFLAGS = ( "-framework", @@ -6967,10 +7272,12 @@ OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", "-D__SMP__", + "-DJACK_32_64", ); OTHER_CPLUSPLUSFLAGS = ( "-DMACH_RPC_MACH_SEMA", "-D__SMP__", + "-DJACK_32_64", ); OTHER_LDFLAGS = ( "-framework", @@ -7037,16 +7344,18 @@ LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", + "-DJACK_32_64", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DMACH_RPC_MACH_SEMA", "-D__SMP__", + "-DJACK_32_64", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; - OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\"\n"; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, @@ -7105,16 +7414,18 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", + "-DJACK_32_64", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DMACH_RPC_MACH_SEMA", + "-DJACK_32_64", "-D__SMP__", - "$(OTHER_CPLUSPLUSFLAGS_QUOTED_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); - OTHER_CPLUSPLUSFLAGS_QUOTED_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, @@ -7163,16 +7474,18 @@ LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; OTHER_CFLAGS = ( "-DUSE_POSIX_SHM", + "-DJACK_32_64", "-D__SMP__", ); OTHER_CPLUSPLUSFLAGS = ( "-DMACH_RPC_MACH_SEMA", + "-DJACK_32_64", "-D__SMP__", - "$(OTHER_CPLUSPLUSFLAGS_QUOTED_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); - OTHER_CPLUSPLUSFLAGS_QUOTED_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; - OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, @@ -7230,11 +7543,13 @@ LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; OTHER_CFLAGS = ( "-DSERVER_SIDE", + "-DJACK_32_64", "-D__SMP__", "-DUSE_POSIX_SHM", ); OTHER_CPLUSPLUSFLAGS = ( "-DSERVER_SIDE", + "-DJACK_32_64", "-D__SMP__", "-DMACH_RPC_MACH_SEMA", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", @@ -7298,19 +7613,20 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ( "-DSERVER_SIDE", + "-DJACK_32_64", "-D__SMP__", "-DUSE_POSIX_SHM", ); OTHER_CPLUSPLUSFLAGS = ( "-DSERVER_SIDE", + "-DJACK_32_64", "-D__SMP__", "-DMACH_RPC_MACH_SEMA", - "$(OTHER_CPLUSPLUSFLAGS_QUOTED_2)", - "$(OTHER_CPLUSPLUSFLAGS_QUOTED_3)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); - OTHER_CPLUSPLUSFLAGS_QUOTED_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; - OTHER_CPLUSPLUSFLAGS_QUOTED_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; - OTHER_CPLUSPLUSFLAGS_QUOTED_3 = "-DLIB_DIR=\\\"lib\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DLIB_DIR=\\\"lib\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, @@ -7359,17 +7675,18 @@ LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; OTHER_CFLAGS = ( "-D__SMP__", + "-DJACK_32_64", "-DUSE_POSIX_SHM", ); OTHER_CPLUSPLUSFLAGS = ( "-D__SMP__", + "-DJACK_32_64", "-DMACH_RPC_MACH_SEMA", - "$(OTHER_CPLUSPLUSFLAGS_QUOTED_2)", - "$(OTHER_CPLUSPLUSFLAGS_QUOTED_3)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); - OTHER_CPLUSPLUSFLAGS_QUOTED_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; - OTHER_CPLUSPLUSFLAGS_QUOTED_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; - OTHER_CPLUSPLUSFLAGS_QUOTED_3 = "-DLIB_DIR=\\\"lib\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DLIB_DIR=\\\"lib\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, @@ -9431,8 +9748,11 @@ LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; - OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_CFLAGS = "-DJACK_32_64"; + OTHER_CPLUSPLUSFLAGS = ( + "-DMACH_RPC_MACH_SEMA", + "-DJACK_32_64", + ); OTHER_LDFLAGS = ( "-framework", Jackservermp, @@ -9578,8 +9898,11 @@ LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; - OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_CFLAGS = "-DJACK_32_64"; + OTHER_CPLUSPLUSFLAGS = ( + "-DMACH_RPC_MACH_SEMA", + "-DJACK_32_64", + ); OTHER_LDFLAGS = ( libportaudio.a, "-framework", @@ -9734,17 +10057,16 @@ LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; - OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_CFLAGS = "-DJACK_32_64"; + OTHER_CPLUSPLUSFLAGS = ( + "-DMACH_RPC_MACH_SEMA", + "-DJACK_32_64", + ); OTHER_LDFLAGS = ( "-framework", Jackservermp, "-framework", - CoreAudio, - "-framework", CoreServices, - "-framework", - AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; @@ -9876,7 +10198,7 @@ LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; - OTHER_CFLAGS = ""; + OTHER_CFLAGS = "-DJACK_32_64"; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( "-framework", @@ -9976,7 +10298,7 @@ buildSettings = { COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; - OTHER_CFLAGS = ""; + OTHER_CFLAGS = "-DJACK_32_64"; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; PRODUCT_NAME = All; @@ -10698,7 +11020,7 @@ }; name = Default; }; - 4B5A1BB80CD1CB9E0005BF74 /* Development */ = { + 4B43A8B710145F6F00E52943 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( @@ -10706,22 +11028,39 @@ ppc, ); COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ""; + DEBUGGING_SYMBOLS = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; - HEADER_SEARCH_PATHS = ../common; + HEADER_SEARCH_PATHS = ( + ../common, + ../common/jack, + ., + ../posix, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", - Jackmp, + Jackservermp, "-framework", - CoreFoundation, + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midiseq; - REZ_EXECUTABLE = YES; + PREBINDING = NO; + PRODUCT_NAME = jack_dummy; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( @@ -10733,7 +11072,7 @@ }; name = Development; }; - 4B5A1BB90CD1CB9E0005BF74 /* Deployment */ = { + 4B43A8B810145F6F00E52943 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( @@ -10741,20 +11080,33 @@ ppc, ); COPY_PHASE_STRIP = YES; - FRAMEWORK_SEARCH_PATHS = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; - HEADER_SEARCH_PATHS = ../common; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + HEADER_SEARCH_PATHS = ( + ../common, + ../common/jack, + ., + ../posix, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", - Jackmp, + Jackservermp, "-framework", - CoreFoundation, + CoreServices, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midiseq; - REZ_EXECUTABLE = YES; + PREBINDING = NO; + PRODUCT_NAME = jack_loopback; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( @@ -10766,25 +11118,38 @@ }; name = Deployment; }; - 4B5A1BBA0CD1CB9E0005BF74 /* Default */ = { + 4B43A8B910145F6F00E52943 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); - FRAMEWORK_SEARCH_PATHS = ""; - HEADER_SEARCH_PATHS = ../common; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", - Jackmp, + Jackdmp, "-framework", - CoreFoundation, + AudioToolBox, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midiseq; - REZ_EXECUTABLE = YES; + PREBINDING = NO; + PRODUCT_NAME = jack_dummy; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( @@ -10795,7 +11160,7 @@ }; name = Default; }; - 4B5A1BD70CD1CCE10005BF74 /* Development */ = { + 4B43A8E41014615800E52943 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( @@ -10803,22 +11168,39 @@ ppc, ); COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ""; + DEBUGGING_SYMBOLS = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; - HEADER_SEARCH_PATHS = ../common; + HEADER_SEARCH_PATHS = ( + ../common, + ../common/jack, + ., + ../posix, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", - Jackmp, + Jackservermp, "-framework", - CoreFoundation, + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midisine; - REZ_EXECUTABLE = YES; + PREBINDING = NO; + PRODUCT_NAME = jack_dummy; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( @@ -10830,28 +11212,42 @@ }; name = Development; }; - 4B5A1BD80CD1CCE10005BF74 /* Deployment */ = { + 4B43A8E51014615800E52943 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - i386, - ppc, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "ppc i386 ppc64 x86_64"; COPY_PHASE_STRIP = YES; - FRAMEWORK_SEARCH_PATHS = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; GCC_ENABLE_FIX_AND_CONTINUE = NO; - HEADER_SEARCH_PATHS = ../common; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + HEADER_SEARCH_PATHS = ( + ../common, + ../common/jack, + ., + ../posix, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; - OTHER_CFLAGS = ""; + OTHER_CFLAGS = "-DJACK_32_64"; + OTHER_CPLUSPLUSFLAGS = ( + "-DMACH_RPC_MACH_SEMA", + "-DJACK_32_64", + ); OTHER_LDFLAGS = ( "-framework", - Jackmp, + Jackservermp, "-framework", - CoreFoundation, + CoreServices, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midisine; - REZ_EXECUTABLE = YES; + PREBINDING = NO; + PRODUCT_NAME = jack_loopback; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( @@ -10863,16 +11259,223 @@ }; name = Deployment; }; - 4B5A1BD90CD1CCE10005BF74 /* Default */ = { + 4B43A8E61014615800E52943 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); - FRAMEWORK_SEARCH_PATHS = ""; - HEADER_SEARCH_PATHS = ../common; - OTHER_CFLAGS = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + "-framework", + Jackdmp, + "-framework", + AudioToolBox, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_dummy; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4B5A1BB80CD1CB9E0005BF74 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midiseq; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4B5A1BB90CD1CB9E0005BF74 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + HEADER_SEARCH_PATHS = ../common; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midiseq; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B5A1BBA0CD1CB9E0005BF74 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + FRAMEWORK_SEARCH_PATHS = ""; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midiseq; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4B5A1BD70CD1CCE10005BF74 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midisine; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4B5A1BD80CD1CCE10005BF74 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + HEADER_SEARCH_PATHS = ../common; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midisine; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B5A1BD90CD1CCE10005BF74 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + FRAMEWORK_SEARCH_PATHS = ""; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", Jackmp, @@ -11361,11 +11964,11 @@ "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", "-D__SMP__", - "$(OTHER_CPLUSPLUSFLAGS_QUOTED_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); - OTHER_CPLUSPLUSFLAGS_QUOTED_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; - OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, @@ -11412,11 +12015,11 @@ OTHER_CPLUSPLUSFLAGS = ( "-DMACH_RPC_MACH_SEMA", "-D__SMP__", - "$(OTHER_CPLUSPLUSFLAGS_QUOTED_1)", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); - OTHER_CPLUSPLUSFLAGS_QUOTED_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; - OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, @@ -11536,12 +12139,11 @@ "-DSERVER_SIDE", "-D__SMP__", "-DMACH_RPC_MACH_SEMA", - "$(OTHER_CPLUSPLUSFLAGS_QUOTED_2)", - "$(OTHER_CPLUSPLUSFLAGS_QUOTED_3)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); - OTHER_CPLUSPLUSFLAGS_QUOTED_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; - OTHER_CPLUSPLUSFLAGS_QUOTED_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; - OTHER_CPLUSPLUSFLAGS_QUOTED_3 = "-DLIB_DIR=\\\"lib\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DLIB_DIR=\\\"lib\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, @@ -11588,12 +12190,11 @@ OTHER_CPLUSPLUSFLAGS = ( "-D__SMP__", "-DMACH_RPC_MACH_SEMA", - "$(OTHER_CPLUSPLUSFLAGS_QUOTED_2)", - "$(OTHER_CPLUSPLUSFLAGS_QUOTED_3)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); - OTHER_CPLUSPLUSFLAGS_QUOTED_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; - OTHER_CPLUSPLUSFLAGS_QUOTED_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; - OTHER_CPLUSPLUSFLAGS_QUOTED_3 = "-DLIB_DIR=\\\"lib\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DLIB_DIR=\\\"lib\\\""; OTHER_LDFLAGS = ( "-framework", Carbon, @@ -13131,11 +13732,7 @@ "-framework", Jackservermp, "-framework", - CoreAudio, - "-framework", CoreServices, - "-framework", - AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; @@ -13766,26 +14363,754 @@ }; name = Default; }; - 4BE6C6A00A3E096F005A203A /* Development */ = { + 4BDCDB9A1001FB9C00B15929 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( - ppc, i386, + ppc, ); COPY_PHASE_STRIP = NO; + DEBUGGING_SYMBOLS = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; - HEADER_SEARCH_PATHS = ../common; + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ( + ., + ../common/jack, + ../posix, + ../common, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", - Jackmp, + Jackservermp, + "-framework", + CoreMIDI, + "-framework", + CoreServices, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_test; + PREBINDING = NO; + PRODUCT_NAME = jack_coremidi; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4BDCDB9B1001FB9C00B15929 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "ppc i386 ppc64 x86_64"; + COPY_PHASE_STRIP = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ( + ., + ../common/jack, + ../posix, + ../common, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = "-DJACK_32_64"; + OTHER_CPLUSPLUSFLAGS = ( + "-DMACH_RPC_MACH_SEMA", + "-DJACK_32_64", + ); + OTHER_LDFLAGS = ( + "-framework", + Jackservermp, + "-framework", + CoreMIDI, + "-framework", + CoreServices, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_coremidi; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4BDCDB9C1001FB9C00B15929 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ../common; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + "-framework", + Jackdmp, + "-framework", + AudioToolBox, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_coreaudio; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4BDCDBC21001FCC000B15929 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + COPY_PHASE_STRIP = NO; + DEBUGGING_SYMBOLS = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G4; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ( + ../common, + ., + ../common/jack, + ../posix, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + "-framework", + Jackservermp, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_net; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4BDCDBC31001FCC000B15929 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "ppc i386 ppc64 x86_64"; + COPY_PHASE_STRIP = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + HEADER_SEARCH_PATHS = ( + ../common, + ., + ../common/jack, + ../posix, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = "-DJACK_32_64"; + OTHER_CPLUSPLUSFLAGS = ( + "-DMACH_RPC_MACH_SEMA", + "-DJACK_32_64", + ); + OTHER_LDFLAGS = ( + "-framework", + Jackservermp, + "-framework", + CoreServices, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_net; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4BDCDBC41001FCC000B15929 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + "-framework", + Jackdmp, + "-framework", + AudioToolBox, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_dummy; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4BDCDBE51001FD2D00B15929 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + COPY_PHASE_STRIP = NO; + DEBUGGING_SYMBOLS = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G4; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ( + ., + ../posix, + ../common/jack, + ../common, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_LDFLAGS = ( + "-framework", + Jackservermp, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = netmanager; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4BDCDBE61001FD2D00B15929 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "ppc i386 ppc64 x86_64"; + COPY_PHASE_STRIP = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ( + ., + ../posix, + ../common/jack, + ../common, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = "-DJACK_32_64"; + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_LDFLAGS = ( + "-framework", + Jackservermp, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = netmanager; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4BDCDBE71001FD2D00B15929 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ../common; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_LDFLAGS = ( + "-framework", + Jackdmp, + "-framework", + AudioToolBox, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = inprocess; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4BDCDBFC1001FD7300B15929 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = i386; + COPY_PHASE_STRIP = NO; + DEBUGGING_SYMBOLS = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G4; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ( + ., + ../posix, + ../common/jack, + ../common, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_LDFLAGS = ( + /usr/local/lib/libsamplerate.a, + "-framework", + Jackservermp, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = netmanager; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4BDCDBFD1001FD7300B15929 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; + COPY_PHASE_STRIP = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ( + ., + ../posix, + ../common/jack, + ../common, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = "-DJACK_32_64"; + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_LDFLAGS = ( + /opt/local/lib/libsamplerate.a, + "-framework", + Jackservermp, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = audioadapter; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4BDCDBFE1001FD7300B15929 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ../common; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_LDFLAGS = ( + "-framework", + Jackdmp, + "-framework", + AudioToolBox, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = inprocess; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4BDCDC221001FDE300B15929 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = i386; + COPY_PHASE_STRIP = NO; + DEBUGGING_SYMBOLS = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G4; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ( + ., + ../posix, + ../common/jack, + ../common, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + /usr/local/lib/libsamplerate.a, + "-framework", + Jackservermp, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = netmanager; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4BDCDC231001FDE300B15929 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; + COPY_PHASE_STRIP = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ( + ., + ../posix, + ../common, + ../common/jack, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = "-DJACK_32_64"; + OTHER_CPLUSPLUSFLAGS = ( + "-DMACH_RPC_MACH_SEMA", + "-DJACK_32_64", + ); + OTHER_LDFLAGS = ( + /opt/local/lib/libsamplerate.a, + "-framework", + Jackservermp, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = netadapter; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4BDCDC241001FDE300B15929 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ../common; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_LDFLAGS = ( + "-framework", + Jackdmp, + "-framework", + AudioToolBox, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = inprocess; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4BE6C6A00A3E096F005A203A /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_test; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -15003,11 +16328,7 @@ "-framework", Jackservermp, "-framework", - CoreAudio, - "-framework", CoreServices, - "-framework", - AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; @@ -15236,7 +16557,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; - 4B19B2FC0E23620F00DD4A82 /* Build configuration list for PBXNativeTarget "audioadapter" */ = { + 4B19B2FC0E23620F00DD4A82 /* Build configuration list for PBXNativeTarget "audioadapter Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B19B2FD0E23620F00DD4A82 /* Development */, @@ -15586,6 +16907,26 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; + 4B43A8B610145F6F00E52943 /* Build configuration list for PBXNativeTarget "jack_loopback Universal" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B43A8B710145F6F00E52943 /* Development */, + 4B43A8B810145F6F00E52943 /* Deployment */, + 4B43A8B910145F6F00E52943 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 4B43A8E31014615800E52943 /* Build configuration list for PBXNativeTarget "jack_loopback 64 bits" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B43A8E41014615800E52943 /* Development */, + 4B43A8E51014615800E52943 /* Deployment */, + 4B43A8E61014615800E52943 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; 4B5A1BB70CD1CB9E0005BF74 /* Build configuration list for PBXNativeTarget "jack_midiseq Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -15606,7 +16947,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; - 4B5E08D10E5B66EE00BEE4E0 /* Build configuration list for PBXNativeTarget "netadapter" */ = { + 4B5E08D10E5B66EE00BEE4E0 /* Build configuration list for PBXNativeTarget "netadapter Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B5E08D20E5B66EE00BEE4E0 /* Development */, @@ -15846,7 +17187,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; - 4BD623F30CBCF0F000DE782F /* Build configuration list for PBXNativeTarget "inprocess" */ = { + 4BD623F30CBCF0F000DE782F /* Build configuration list for PBXNativeTarget "inprocess Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BD623F40CBCF0F000DE782F /* Development */, @@ -15856,6 +17197,56 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; + 4BDCDB991001FB9C00B15929 /* Build configuration list for PBXNativeTarget "jack_coremidi 64 bits" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4BDCDB9A1001FB9C00B15929 /* Development */, + 4BDCDB9B1001FB9C00B15929 /* Deployment */, + 4BDCDB9C1001FB9C00B15929 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 4BDCDBC11001FCC000B15929 /* Build configuration list for PBXNativeTarget "jack_net 64 bits" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4BDCDBC21001FCC000B15929 /* Development */, + 4BDCDBC31001FCC000B15929 /* Deployment */, + 4BDCDBC41001FCC000B15929 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 4BDCDBE41001FD2D00B15929 /* Build configuration list for PBXNativeTarget "netmanager 64 bits" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4BDCDBE51001FD2D00B15929 /* Development */, + 4BDCDBE61001FD2D00B15929 /* Deployment */, + 4BDCDBE71001FD2D00B15929 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 4BDCDBFB1001FD7300B15929 /* Build configuration list for PBXNativeTarget "audioadapter 64 bits" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4BDCDBFC1001FD7300B15929 /* Development */, + 4BDCDBFD1001FD7300B15929 /* Deployment */, + 4BDCDBFE1001FD7300B15929 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 4BDCDC211001FDE300B15929 /* Build configuration list for PBXNativeTarget "netadapter 64 bits" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4BDCDC221001FDE300B15929 /* Development */, + 4BDCDC231001FDE300B15929 /* Deployment */, + 4BDCDC241001FDE300B15929 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; 4BE6C69F0A3E096F005A203A /* Build configuration list for PBXNativeTarget "jack_test Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -15976,7 +17367,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; - BA222AE50DC882DB001A17F4 /* Build configuration list for PBXNativeTarget "netmanager" */ = { + BA222AE50DC882DB001A17F4 /* Build configuration list for PBXNativeTarget "netmanager Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( BA222AE60DC882DB001A17F4 /* Development */, diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 43655ad9..6c2222e7 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -26,7 +26,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackDriverLoader.h" #include "JackGlobals.h" #include "JackCompilerDeps.h" + #include +#include namespace Jack { @@ -255,19 +257,22 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, switch (inPropertyID) { - case kAudioDeviceProcessorOverload: + 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... break; + } - case kAudioDevicePropertyStreamConfiguration: + case kAudioDevicePropertyStreamConfiguration: { jack_error("Cannot handle kAudioDevicePropertyStreamConfiguration : server may not work correctly anymore..."); return kAudioHardwareUnsupportedOperationError; + } - case kAudioDevicePropertyNominalSampleRate: + case kAudioDevicePropertyNominalSampleRate: { jack_error("Cannot handle kAudioDevicePropertyNominalSampleRate : server may not work correctly anymore..."); return kAudioHardwareUnsupportedOperationError; + } /* case kAudioDevicePropertyNominalSampleRate: { diff --git a/macosx/install_jackdmp b/macosx/install_jackdmp index 8ee9dd7c..7e171b76 100755 --- a/macosx/install_jackdmp +++ b/macosx/install_jackdmp @@ -15,7 +15,9 @@ sudo cp jackdmp /usr/local/bin # Copy drivers sudo install -d /usr/local/lib/jackmp sudo cp jack_coreaudio.so /usr/local/lib/jackmp +sudo cp jack_coremidi.so /usr/local/lib/jackmp sudo cp jack_dummy.so /usr/local/lib/jackmp +sudo cp jack_loopback.so /usr/local/lib/jackmp [ -f jack_net.so ] && sudo cp jack_net.so /usr/local/lib/jackmp # Copy tools diff --git a/macosx/wscript b/macosx/wscript index ade18b4a..843874bc 100644 --- a/macosx/wscript +++ b/macosx/wscript @@ -58,6 +58,8 @@ def build(bld): create_jack_driver_obj(bld, 'dummy', '../common/JackDummyDriver.cpp') + create_jack_driver_obj(bld, 'loopback', '../common/JackLoopbackDriver.cpp') + create_jack_audio_driver_obj(bld, 'coreaudio', 'coreaudio/JackCoreAudioDriver.cpp') create_jack_midi_driver_obj(bld, 'coremidi', 'coremidi/JackCoreMidiDriver.cpp') diff --git a/posix/JackFifo.h b/posix/JackFifo.h index be7d9b8a..8ac72591 100644 --- a/posix/JackFifo.h +++ b/posix/JackFifo.h @@ -48,7 +48,7 @@ class SERVER_EXPORT JackFifo : public detail::JackSynchro public: - JackFifo(): fFifo( -1) + JackFifo():JackSynchro(), fFifo(-1) {} bool Signal(); diff --git a/posix/JackPosixSemaphore.h b/posix/JackPosixSemaphore.h index 2052ff1c..226db2a1 100644 --- a/posix/JackPosixSemaphore.h +++ b/posix/JackPosixSemaphore.h @@ -46,7 +46,7 @@ class SERVER_EXPORT JackPosixSemaphore : public detail::JackSynchro public: - JackPosixSemaphore(): fSemaphore(NULL) + JackPosixSemaphore():JackSynchro(), fSemaphore(NULL) {} bool Signal(); diff --git a/posix/JackPosixServerLaunch.cpp b/posix/JackPosixServerLaunch.cpp index 1931474d..855a2c59 100644 --- a/posix/JackPosixServerLaunch.cpp +++ b/posix/JackPosixServerLaunch.cpp @@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. using namespace Jack; -#if defined(JACK_DBUS) +#if defined(USE_LIBDBUS_AUTOLAUNCH) #include @@ -73,7 +73,7 @@ static int start_server_dbus(const char* server_name) return 0; } -#endif +#else /* Exec the JACK server in this process. Does not return. */ static void start_server_classic_aux(const char* server_name) @@ -189,13 +189,15 @@ static int start_server_classic(const char* server_name) return 0; /* (probably) successful */ } +#endif + static int start_server(const char* server_name, jack_options_t options) { if ((options & JackNoStartServer) || getenv("JACK_NO_START_SERVER")) { return 1; } -#if defined(JACK_DBUS) +#if defined(USE_LIBDBUS_AUTOLAUNCH) return start_server_dbus(server_name); #else return start_server_classic(server_name); diff --git a/solaris/oss/JackBoomerDriver.cpp b/solaris/oss/JackBoomerDriver.cpp index b77e7747..96dc0a6a 100644 --- a/solaris/oss/JackBoomerDriver.cpp +++ b/solaris/oss/JackBoomerDriver.cpp @@ -61,7 +61,8 @@ struct OSSCycleTable { }; OSSCycleTable gCycleTable; -int gCycleCount = 0; +int gCycleReadCount = 0; +int gCycleWriteCount = 0; #endif @@ -229,6 +230,26 @@ void JackBoomerDriver::DisplayDeviceInfo() } } +JackBoomerDriver::JackBoomerDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) + : JackAudioDriver(name, alias, engine, table), + fInFD(-1), fOutFD(-1), fBits(0), + fSampleFormat(0), fNperiods(0), fRWMode(0), fExcl(false), fIgnoreHW(true), + fInputBufferSize(0), fOutputBufferSize(0), + fInputBuffer(NULL), fOutputBuffer(NULL), + fInputThread(&fInputHandler), fOutputThread(&fOutputHandler), + fInputHandler(this), fOutputHandler(this) + +{ + sem_init(&fReadSema, 0, 0); + sem_init(&fWriteSema, 0, 0); +} + +JackBoomerDriver::~JackBoomerDriver() +{ + sem_destroy(&fReadSema); + sem_destroy(&fWriteSema); +} + int JackBoomerDriver::OpenInput() { int flags = 0; @@ -395,11 +416,11 @@ int JackBoomerDriver::Open(jack_nframes_t nframes, return -1; } else { - if (fEngineControl->fSyncMode) { - jack_error("Cannot run in synchronous mode, remove the -S parameter for jackd"); + if (!fEngineControl->fSyncMode) { + jack_error("Cannot run in asynchronous mode, use the -S parameter for jackd"); return -1; } - + fRWMode |= ((capturing) ? kRead : 0); fRWMode |= ((playing) ? kWrite : 0); fBits = bits; @@ -428,7 +449,7 @@ int JackBoomerDriver::Close() if (file) { jack_info("Writing OSS driver timing data...."); - for (int i = 1; i < gCycleCount; i++) { + for (int i = 1; i < std::min(gCycleReadCount, gCycleWriteCount); i++) { int d1 = gCycleTable.fTable[i].fAfterRead - gCycleTable.fTable[i].fBeforeRead; int d2 = gCycleTable.fTable[i].fAfterReadConvert - gCycleTable.fTable[i].fAfterRead; int d3 = gCycleTable.fTable[i].fAfterWrite - gCycleTable.fTable[i].fBeforeWrite; @@ -487,15 +508,6 @@ int JackBoomerDriver::OpenAux() return -1; } - // Prepare ringbuffers used for output - if (fPlaybackChannels > 0) { - fRingBuffer = new jack_ringbuffer_t*[fPlaybackChannels]; - for (int i = 0; i < fPlaybackChannels; i++) { - fRingBuffer[i] = jack_ringbuffer_create(fOutputBufferSize * 2); - jack_ringbuffer_read_advance(fRingBuffer[i], fOutputBufferSize); - } - } - DisplayDeviceInfo(); return 0; } @@ -519,15 +531,6 @@ void JackBoomerDriver::CloseAux() if (fOutputBuffer) free(fOutputBuffer); fOutputBuffer = NULL; - - for (int i = 0; i < fPlaybackChannels; i++) { - if (fRingBuffer[i]) - jack_ringbuffer_free(fRingBuffer[i]); - fRingBuffer[i] = NULL; - } - - delete [] fRingBuffer; - fRingBuffer = NULL; } int JackBoomerDriver::Start() @@ -535,10 +538,18 @@ int JackBoomerDriver::Start() jack_log("JackBoomerDriver::Start"); JackAudioDriver::Start(); + // Start input thread only when needed + if (fInFD > 0) { + if (fInputThread.StartSync() < 0) { + jack_error("Cannot start input thread"); + return -1; + } + } + // Start output thread only when needed if (fOutFD > 0) { - if (fThread.StartSync() < 0) { - jack_error("Cannot start thread"); + if (fOutputThread.StartSync() < 0) { + jack_error("Cannot start output thread"); return -1; } } @@ -548,42 +559,81 @@ int JackBoomerDriver::Start() int JackBoomerDriver::Stop() { + // Stop input thread only when needed + if (fInFD > 0) { + fInputThread.Kill(); + } + // Stop output thread only when needed if (fOutFD > 0) { - return fThread.Kill(); - } else { - return 0; + fOutputThread.Kill(); } + + return 0; } int JackBoomerDriver::Read() { - if (fInFD < 0) { +/* + // Keep begin cycle time + JackDriver::CycleTakeBeginTime(); +*/ + + return 0; +} + +int JackBoomerDriver::Write() +{ +/* + // Keep begin cycle time + JackDriver::CycleTakeEndTime(); +*/ + + return 0; +} + +bool JackBoomerDriver::JackBoomerDriverInput::Init() +{ + if (fDriver->IsRealTime()) { + jack_log("JackBoomerDriverInput::Init IsRealTime"); + if (fDriver->fInputThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { + jack_error("AcquireRealTime error"); + } else { + set_threaded_log_function(); + } + } + + return true; +} + +bool JackBoomerDriver::JackBoomerDriverInput::Execute() +{ + if (fDriver->fInFD < 0) { // Keep begin cycle time - JackDriver::CycleTakeBeginTime(); - return 0; + fDriver->CycleTakeBeginTime(); + return true; } #ifdef JACK_MONITOR - gCycleTable.fTable[gCycleCount].fBeforeRead = GetMicroSeconds(); + gCycleTable.fTable[gCycleReadCount].fBeforeRead = GetMicroSeconds(); #endif audio_errinfo ei_in; - ssize_t count = ::read(fInFD, fInputBuffer, fInputBufferSize); + ssize_t count = ::read(fDriver->fInFD, fDriver->fInputBuffer, fDriver->fInputBufferSize); #ifdef JACK_MONITOR - if (count > 0 && count != (int)fInputBufferSize) - jack_log("JackBoomerDriver::Read count = %ld", count / (fSampleSize * fCaptureChannels)); - gCycleTable.fTable[gCycleCount].fAfterRead = GetMicroSeconds(); + if (count > 0 && count != (int)fDriver->fInputBufferSize) + jack_log("JackBoomerDriverInput::Execute count = %ld", count / (fDriver->fSampleSize * fDriver->fCaptureChannels)); + gCycleTable.fTable[gCycleReadCount].fAfterRead = GetMicroSeconds(); #endif // XRun detection - if (ioctl(fInFD, SNDCTL_DSP_GETERROR, &ei_in) == 0) { + if (ioctl(fDriver->fInFD, SNDCTL_DSP_GETERROR, &ei_in) == 0) { if (ei_in.rec_overruns > 0 ) { - jack_error("JackBoomerDriver::Read overruns"); + jack_error("JackBoomerDriverInput::Execute overruns"); jack_time_t cur_time = GetMicroSeconds(); - NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... + fDriver->NotifyXRun(cur_time, float(cur_time - fDriver->fBeginDateUst)); // Better this value than nothing... } if (ei_in.rec_errorcount > 0 && ei_in.rec_lasterror != 0) { @@ -592,47 +642,34 @@ int JackBoomerDriver::Read() } if (count < 0) { - jack_log("JackBoomerDriver::Read error = %s", strerror(errno)); - return -1; - } else if (count < (int)fInputBufferSize) { - jack_error("JackBoomerDriver::Read error bytes read = %ld", count); - return -1; + jack_log("JackBoomerDriverInput::Execute error = %s", strerror(errno)); + } else if (count < (int)fDriver->fInputBufferSize) { + jack_error("JackBoomerDriverInput::Execute error bytes read = %ld", count); } else { // Keep begin cycle time - JackDriver::CycleTakeBeginTime(); - for (int i = 0; i < fCaptureChannels; i++) { - if (fGraphManager->GetConnectionsNum(fCapturePortList[i]) > 0) { - CopyAndConvertIn(GetInputBuffer(i), fInputBuffer, fEngineControl->fBufferSize, i, fCaptureChannels, fBits); + fDriver->CycleTakeBeginTime(); + for (int i = 0; i < fDriver->fCaptureChannels; i++) { + if (fDriver->fGraphManager->GetConnectionsNum(fDriver->fCapturePortList[i]) > 0) { + CopyAndConvertIn(fDriver->GetInputBuffer(i), fDriver->fInputBuffer, fDriver->fEngineControl->fBufferSize, i, fDriver->fCaptureChannels, fDriver->fBits); } } #ifdef JACK_MONITOR - gCycleTable.fTable[gCycleCount].fAfterReadConvert = GetMicroSeconds(); + gCycleTable.fTable[gCycleReadCount].fAfterReadConvert = GetMicroSeconds(); + gCycleReadCount = (gCycleReadCount == CYCLE_POINTS - 1) ? gCycleReadCount: gCycleReadCount + 1; #endif - - return 0; } -} -int JackBoomerDriver::Write() -{ - for (int i = 0; i < fPlaybackChannels; i++) { - if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) { - if (jack_ringbuffer_write(fRingBuffer[i], (char*)GetOutputBuffer(i), fOutputBufferSize) < fOutputBufferSize) { - jack_log("JackBoomerDriver::Write ringbuffer full"); - } - } - } - - return 0; + fDriver->SynchronizeRead(); + return true; } -bool JackBoomerDriver::Init() +bool JackBoomerDriver::JackBoomerDriverOutput::Init() { - if (IsRealTime()) { - jack_log("JackBoomerDriver::Init IsRealTime"); - if (fThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { + if (fDriver->IsRealTime()) { + jack_log("JackBoomerDriverOutput::Init IsRealTime"); + if (fDriver->fOutputThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { jack_error("AcquireRealTime error"); } else { set_threaded_log_function(); @@ -640,83 +677,64 @@ bool JackBoomerDriver::Init() } // Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html - memset(fOutputBuffer, 0, fOutputBufferSize); + memset(fDriver->fOutputBuffer, 0, fDriver->fOutputBufferSize); // Prefill ouput buffer - if (fOutFD > 0) { - for (int i = 0; i < fNperiods; i++) { - ssize_t count = ::write(fOutFD, fOutputBuffer, fOutputBufferSize); - if (count < (int)fOutputBufferSize) { + if (fDriver->fOutFD > 0) { + for (int i = 0; i < fDriver->fNperiods; i++) { + ssize_t count = ::write(fDriver->fOutFD, fDriver->fOutputBuffer, fDriver->fOutputBufferSize); + if (count < (int)fDriver->fOutputBufferSize) { jack_error("JackBoomerDriver::Write error bytes written = %ld", count); } } int delay; - if (ioctl(fOutFD, SNDCTL_DSP_GETODELAY, &delay) == -1) { + if (ioctl(fDriver->fOutFD, SNDCTL_DSP_GETODELAY, &delay) == -1) { jack_error("JackBoomerDriver::Write error get out delay : %s@%i, errno = %d", __FILE__, __LINE__, errno); } - delay /= fSampleSize * fPlaybackChannels; + delay /= fDriver->fSampleSize * fDriver->fPlaybackChannels; jack_info("JackBoomerDriver::Write output latency frames = %ld", delay); } return true; } -bool JackBoomerDriver::Execute() +bool JackBoomerDriver::JackBoomerDriverOutput::Execute() { - memset(fOutputBuffer, 0, fOutputBufferSize); - - for (int i = 0; i < fPlaybackChannels; i++) { - if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) { - - jack_ringbuffer_data_t ring_buffer_data[2]; - jack_ringbuffer_get_read_vector(fRingBuffer[i], ring_buffer_data); + memset(fDriver->fOutputBuffer, 0, fDriver->fOutputBufferSize); - unsigned int available_frames = (ring_buffer_data[0].len + ring_buffer_data[1].len) / sizeof(float); - jack_log("Output available = %ld", available_frames); - - unsigned int needed_bytes = fOutputBufferSize; - float* output = (float*)fOutputBuffer; - - for (int j = 0; j < 2; j++) { - unsigned int consumed_bytes = std::min(needed_bytes, ring_buffer_data[j].len); - CopyAndConvertOut(output, (float*)ring_buffer_data[j].buf, consumed_bytes / sizeof(float), i, fPlaybackChannels, fBits); - output += consumed_bytes / sizeof(float); - needed_bytes -= consumed_bytes; - } - - if (needed_bytes > 0) { - jack_error("JackBoomerDriver::Execute missing frames = %ld", needed_bytes / sizeof(float)); - } - - jack_ringbuffer_read_advance(fRingBuffer[i], fOutputBufferSize - needed_bytes); +#ifdef JACK_MONITOR + gCycleTable.fTable[gCycleWriteCount].fBeforeWriteConvert = GetMicroSeconds(); +#endif + + for (int i = 0; i < fDriver->fPlaybackChannels; i++) { + if (fDriver->fGraphManager->GetConnectionsNum(fDriver->fPlaybackPortList[i]) > 0) { + CopyAndConvertOut(fDriver->fOutputBuffer, fDriver->GetOutputBuffer(i), fDriver->fEngineControl->fBufferSize, i, fDriver->fPlaybackChannels, fDriver->fBits); } } #ifdef JACK_MONITOR - gCycleTable.fTable[gCycleCount].fBeforeWrite = GetMicroSeconds(); + gCycleTable.fTable[gCycleWriteCount].fBeforeWrite = GetMicroSeconds(); #endif - // Keep end cycle time - JackDriver::CycleTakeEndTime(); - ssize_t count = ::write(fOutFD, fOutputBuffer, fOutputBufferSize); + ssize_t count = ::write(fDriver->fOutFD, fDriver->fOutputBuffer, fDriver->fOutputBufferSize); #ifdef JACK_MONITOR - if (count > 0 && count != (int)fOutputBufferSize) - jack_log("JackBoomerDriver::Execute count = %ld", count / (fSampleSize * fPlaybackChannels)); - gCycleTable.fTable[gCycleCount].fAfterWrite = GetMicroSeconds(); - gCycleCount = (gCycleCount == CYCLE_POINTS - 1) ? gCycleCount: gCycleCount + 1; + if (count > 0 && count != (int)fDriver->fOutputBufferSize) + jack_log("JackBoomerDriverOutput::Execute count = %ld", count / (fDriver->fSampleSize * fDriver->fPlaybackChannels)); + gCycleTable.fTable[gCycleWriteCount].fAfterWrite = GetMicroSeconds(); + gCycleWriteCount = (gCycleWriteCount == CYCLE_POINTS - 1) ? gCycleWriteCount: gCycleWriteCount + 1; #endif // XRun detection audio_errinfo ei_out; - if (ioctl(fOutFD, SNDCTL_DSP_GETERROR, &ei_out) == 0) { + if (ioctl(fDriver->fOutFD, SNDCTL_DSP_GETERROR, &ei_out) == 0) { if (ei_out.play_underruns > 0) { - jack_error("JackBoomerDriver::Execute underruns"); + jack_error("JackBoomerDriverOutput::Execute underruns"); jack_time_t cur_time = GetMicroSeconds(); - NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... + fDriver->NotifyXRun(cur_time, float(cur_time - fDriver->fBeginDateUst)); // Better this value than nothing... } if (ei_out.play_errorcount > 0 && ei_out.play_lasterror != 0) { @@ -725,14 +743,28 @@ bool JackBoomerDriver::Execute() } if (count < 0) { - jack_log("JackBoomerDriver::Execute error = %s", strerror(errno)); - } else if (count < (int)fOutputBufferSize) { - jack_error("JackBoomerDriver::Execute error bytes written = %ld", count); + jack_log("JackBoomerDriverOutput::Execute error = %s", strerror(errno)); + } else if (count < (int)fDriver->fOutputBufferSize) { + jack_error("JackBoomerDriverOutput::Execute error bytes written = %ld", count); } + fDriver->SynchronizeWrite(); return true; } +void JackBoomerDriver::SynchronizeRead() +{ + sem_wait(&fWriteSema); + Process(); + sem_post(&fReadSema); +} + +void JackBoomerDriver::SynchronizeWrite() +{ + sem_post(&fWriteSema); + sem_wait(&fReadSema); +} + int JackBoomerDriver::SetBufferSize(jack_nframes_t buffer_size) { CloseAux(); @@ -740,30 +772,6 @@ int JackBoomerDriver::SetBufferSize(jack_nframes_t buffer_size) return OpenAux(); } -int JackBoomerDriver::ProcessAsync() -{ - // Read input buffers for the current cycle - if (Read() < 0) { - jack_error("JackBoomerDriver::ProcessAsync: read error, skip cycle"); - return 0; // Skip cycle, but continue processing... - } - - // Write output buffers from the previous cycle - if (Write() < 0) { - jack_error("JackBoomerDriver::ProcessAsync: write error, skip cycle"); - return 0; // Skip cycle, but continue processing... - } - - if (fIsMaster) { - ProcessGraphAsync(); - } else { - fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); - } - - // Keep end cycle time - JackDriver::CycleTakeEndTime(); - return 0; -} } // end of namespace @@ -985,14 +993,13 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine } Jack::JackBoomerDriver* boomer_driver = new Jack::JackBoomerDriver("system", "boomer", engine, table); - Jack::JackDriverClientInterface* threaded_driver = new Jack::JackThreadedDriver(boomer_driver); - // Special open for OSS driver... + // Special open for Boomer driver... if (boomer_driver->Open(frames_per_interrupt, nperiods, srate, capture, playback, chan_in, chan_out, excl, monitor, capture_pcm_name, playback_pcm_name, systemic_input_latency, systemic_output_latency, bits, ignorehwbuf) == 0) { - return threaded_driver; + return boomer_driver; } else { - delete threaded_driver; // Delete the decorated driver + delete boomer_driver; // Delete the driver return NULL; } } diff --git a/solaris/oss/JackBoomerDriver.h b/solaris/oss/JackBoomerDriver.h index 1861e8d8..f688c7e1 100644 --- a/solaris/oss/JackBoomerDriver.h +++ b/solaris/oss/JackBoomerDriver.h @@ -23,7 +23,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackAudioDriver.h" #include "JackPlatformPlug.h" #include "ringbuffer.h" -//#include "JackThread.h" +#include namespace Jack { @@ -43,13 +43,47 @@ typedef jack_default_audio_sample_t jack_sample_t; \brief The Boomer driver. */ -class JackBoomerDriver : public JackAudioDriver, public JackRunnableInterface +class JackBoomerDriver : public JackAudioDriver { enum { kRead = 1, kWrite = 2, kReadWrite = 3 }; private: + + class JackBoomerDriverInput : public JackRunnableInterface { + + private: + + JackBoomerDriver* fDriver; + + public: + + JackBoomerDriverInput(JackBoomerDriver* driver): fDriver(driver) + {} + ~JackBoomerDriverInput() + {} + + bool Init(); + bool Execute(); + }; + + class JackBoomerDriverOutput : public JackRunnableInterface { + + private: + JackBoomerDriver* fDriver; + + public: + + JackBoomerDriverOutput(JackBoomerDriver* driver): fDriver(driver) + {} + ~JackBoomerDriverOutput() + {} + + bool Init(); + bool Execute(); + }; + int fInFD; int fOutFD; @@ -66,8 +100,15 @@ class JackBoomerDriver : public JackAudioDriver, public JackRunnableInterface void* fInputBuffer; void* fOutputBuffer; - jack_ringbuffer_t** fRingBuffer; - JackThread fThread; + + sem_t fReadSema; + sem_t fWriteSema; + + JackThread fInputThread; + JackThread fOutputThread; + + JackBoomerDriverInput fInputHandler; + JackBoomerDriverOutput fOutputHandler; int OpenInput(); int OpenOutput(); @@ -75,24 +116,14 @@ class JackBoomerDriver : public JackAudioDriver, public JackRunnableInterface void CloseAux(); void SetSampleFormat(); void DisplayDeviceInfo(); - - // Redefining since timing for CPU load is specific - int ProcessAsync(); + void SynchronizeRead(); + void SynchronizeWrite(); public: - JackBoomerDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) - : JackAudioDriver(name, alias, engine, table), - fInFD(-1), fOutFD(-1), fBits(0), - fSampleFormat(0), fNperiods(0), fRWMode(0), fExcl(false), fIgnoreHW(true), - fInputBufferSize(0), fOutputBufferSize(0), - fInputBuffer(NULL), fOutputBuffer(NULL), - fRingBuffer(NULL), fThread(this) - {} - - virtual ~JackBoomerDriver() - {} - + JackBoomerDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); + virtual ~JackBoomerDriver(); + int Open(jack_nframes_t frames_per_cycle, int user_nperiods, jack_nframes_t rate, diff --git a/solaris/oss/JackOSSDriver.cpp b/solaris/oss/JackOSSDriver.cpp index ad44a43c..f4d8507c 100644 --- a/solaris/oss/JackOSSDriver.cpp +++ b/solaris/oss/JackOSSDriver.cpp @@ -558,7 +558,7 @@ int JackOSSDriver::Read() ssize_t count; #ifdef JACK_MONITOR - gCycleTable.fTable[gCycleCount].fBeforeRead = GetMicroSeconds(); + gCycleTable.fTable[gCycleCount].fBeforeRead = GetMicroSeconds(); #endif audio_errinfo ei_in; diff --git a/solaris/wscript b/solaris/wscript index 9e7ce920..77838cf1 100644 --- a/solaris/wscript +++ b/solaris/wscript @@ -34,3 +34,4 @@ def build(bld): create_jack_driver_obj(bld, 'net', '../common/JackNetDriver.cpp') + create_jack_driver_obj(bld, 'loopback', '../common/JackLoopbackDriver.cpp') diff --git a/windows/JackCompilerDeps_os.h b/windows/JackCompilerDeps_os.h index 82fae18e..858cbd8f 100644 --- a/windows/JackCompilerDeps_os.h +++ b/windows/JackCompilerDeps_os.h @@ -18,24 +18,24 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JackCompilerDeps_WIN32__ -#define __JackCompilerDeps_WIN32__ +#define __JackCompilerDeps_WIN32__ -#if __GNUC__ - #ifndef POST_PACKED_STRUCTURE - /* POST_PACKED_STRUCTURE needs to be a macro which - expands into a compiler directive. The directive must - tell the compiler to arrange the preceding structure - declaration so that it is packed on byte-boundaries rather - than use the natural alignment of the processor and/or - compiler. - */ - #if (__GNUC__< 4) /* Does not seem to work with GCC 3.XX serie */ - #define POST_PACKED_STRUCTURE - #elif defined(JACK_32_64) - #define POST_PACKED_STRUCTURE __attribute__((__packed__)) - #else - #define POST_PACKED_STRUCTURE - #endif +#if __GNUC__ + #ifndef POST_PACKED_STRUCTURE + /* POST_PACKED_STRUCTURE needs to be a macro which + expands into a compiler directive. The directive must + tell the compiler to arrange the preceding structure + declaration so that it is packed on byte-boundaries rather + than use the natural alignment of the processor and/or + compiler. + */ + #if (__GNUC__< 4) /* Does not seem to work with GCC 3.XX serie */ + #define POST_PACKED_STRUCTURE + #elif defined(JACK_32_64) + #define POST_PACKED_STRUCTURE __attribute__((__packed__)) + #else + #define POST_PACKED_STRUCTURE + #endif #endif #define MEM_ALIGN(x,y) x __attribute__((aligned(y))) #define EXPORT __declspec(dllexport) diff --git a/windows/JackNetWinSocket.cpp b/windows/JackNetWinSocket.cpp index 30420b49..94390b4d 100644 --- a/windows/JackNetWinSocket.cpp +++ b/windows/JackNetWinSocket.cpp @@ -286,12 +286,12 @@ namespace Jack //local loop********************************************************************************************************* int JackNetWinSocket::SetLocalLoop() { - //char disable = 0; - /* - see http://msdn.microsoft.com/en-us/library/aa916098.aspx - Default value is TRUE. When TRUE, data that is sent from the local interface to the multicast group to - which the socket is joined, including data sent from the same socket, will be echoed to its receive buffer. - */ + //char disable = 0; + /* + see http://msdn.microsoft.com/en-us/library/aa916098.aspx + Default value is TRUE. When TRUE, data that is sent from the local interface to the multicast group to + which the socket is joined, including data sent from the same socket, will be echoed to its receive buffer. + */ char disable = 1; return SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof ( disable ) ); } diff --git a/windows/JackTypes_os.h b/windows/JackTypes_os.h index 88a8bd8a..13e67349 100644 --- a/windows/JackTypes_os.h +++ b/windows/JackTypes_os.h @@ -20,7 +20,7 @@ #ifndef __JackTypes_WIN32__ #define __JackTypes_WIN32__ -#include +#include #include "types.h" typedef ULONGLONG UInt64; diff --git a/windows/JackWinProcessSync.cpp b/windows/JackWinProcessSync.cpp index 5dc405b5..56171fba 100644 --- a/windows/JackWinProcessSync.cpp +++ b/windows/JackWinProcessSync.cpp @@ -32,7 +32,7 @@ void JackWinProcessSync::LockedSignal() { WaitForSingleObject(fMutex, INFINITE); SetEvent(fEvent); - ReleaseMutex(fMutex); + ReleaseMutex(fMutex); } void JackWinProcessSync::SignalAll() @@ -44,71 +44,71 @@ void JackWinProcessSync::LockedSignalAll() { WaitForSingleObject(fMutex, INFINITE); SetEvent(fEvent); - ReleaseMutex(fMutex); -} - -void JackWinProcessSync::Wait() -{ - ReleaseMutex(fMutex); - WaitForSingleObject(fEvent, INFINITE); -} - -void JackWinProcessSync::LockedWait() -{ - /* Does it make sense on Windows, use non-locked version for now... */ - Wait(); -} - -bool JackWinProcessSync::TimedWait(long usec) -{ - ReleaseMutex(fMutex); - DWORD res = WaitForSingleObject(fEvent, usec / 1000); - return (res == WAIT_OBJECT_0); -} - -bool JackWinProcessSync::LockedTimedWait(long usec) -{ - /* Does it make sense on Windows, use non-locked version for now...*/ - return TimedWait(usec); -} - -/* -Code from CAGuard.cpp : does ot sees to work as expected.. - -void JackWinProcessSync::Wait() -{ - ReleaseMutex(fMutex); - HANDLE handles[] = { fMutex, fEvent }; - DWORD res = WaitForMultipleObjects(2, handles, true, INFINITE); - if ((res != WAIT_OBJECT_0) && (res != WAIT_TIMEOUT)) - jack_error("Wait error err = %d", GetLastError()); - ResetEvent(fEvent); -} + ReleaseMutex(fMutex); +} + +void JackWinProcessSync::Wait() +{ + ReleaseMutex(fMutex); + WaitForSingleObject(fEvent, INFINITE); +} void JackWinProcessSync::LockedWait() -{ - WaitForSingleObject(fMutex, INFINITE); +{ + /* Does it make sense on Windows, use non-locked version for now... */ + Wait(); +} + +bool JackWinProcessSync::TimedWait(long usec) +{ + ReleaseMutex(fMutex); + DWORD res = WaitForSingleObject(fEvent, usec / 1000); + return (res == WAIT_OBJECT_0); +} + +bool JackWinProcessSync::LockedTimedWait(long usec) +{ + /* Does it make sense on Windows, use non-locked version for now...*/ + return TimedWait(usec); +} + +/* +Code from CAGuard.cpp : does ot sees to work as expected.. + +void JackWinProcessSync::Wait() +{ + ReleaseMutex(fMutex); + HANDLE handles[] = { fMutex, fEvent }; + DWORD res = WaitForMultipleObjects(2, handles, true, INFINITE); + if ((res != WAIT_OBJECT_0) && (res != WAIT_TIMEOUT)) + jack_error("Wait error err = %d", GetLastError()); + ResetEvent(fEvent); +} + +void JackWinProcessSync::LockedWait() +{ + WaitForSingleObject(fMutex, INFINITE); ReleaseMutex(fMutex); HANDLE handles[] = { fMutex, fEvent }; DWORD res = WaitForMultipleObjects(2, handles, true, INFINITE); if ((res != WAIT_OBJECT_0) && (res != WAIT_TIMEOUT)) jack_error("LockedWait error err = %d", GetLastError()); - ResetEvent(fEvent); + ResetEvent(fEvent); } - -bool JackWinProcessSync::TimedWait(long usec) -{ - ReleaseMutex(fMutex); - HANDLE handles[] = { fMutex, fEvent }; - DWORD res = WaitForMultipleObjects(2, handles, true, usec / 1000); - if ((res != WAIT_OBJECT_0) && (res != WAIT_TIMEOUT)) - jack_error("Wait error err = %d", GetLastError()); - ResetEvent(fEvent); + +bool JackWinProcessSync::TimedWait(long usec) +{ + ReleaseMutex(fMutex); + HANDLE handles[] = { fMutex, fEvent }; + DWORD res = WaitForMultipleObjects(2, handles, true, usec / 1000); + if ((res != WAIT_OBJECT_0) && (res != WAIT_TIMEOUT)) + jack_error("Wait error err = %d", GetLastError()); + ResetEvent(fEvent); } bool JackWinProcessSync::LockedTimedWait(long usec) -{ - WaitForSingleObject(fMutex, INFINITE); +{ + WaitForSingleObject(fMutex, INFINITE); ReleaseMutex(fMutex); HANDLE handles[] = { fMutex, fEvent }; DWORD res = WaitForMultipleObjects(2, handles, true, usec / 1000); diff --git a/windows/JackWinSemaphore.h b/windows/JackWinSemaphore.h index 45b84e08..d4330e5f 100644 --- a/windows/JackWinSemaphore.h +++ b/windows/JackWinSemaphore.h @@ -44,7 +44,7 @@ class JackWinSemaphore : public detail::JackSynchro public: - JackWinSemaphore(): fSemaphore(NULL) + JackWinSemaphore():JackSynchro(), fSemaphore(NULL) {} bool Signal(); diff --git a/windows/JackWinServerLaunch.cpp b/windows/JackWinServerLaunch.cpp index eeda81a8..895c9bdf 100644 --- a/windows/JackWinServerLaunch.cpp +++ b/windows/JackWinServerLaunch.cpp @@ -1,26 +1,26 @@ -/* -Copyright (C) 2001-2003 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 Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 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 -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "JackServerLaunch.h" - -int try_start_server(jack_varargs_t* va, jack_options_t options, jack_status_t* status) -{ - return 0; -} +/* +Copyright (C) 2001-2003 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 Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "JackServerLaunch.h" + +int try_start_server(jack_varargs_t* va, jack_options_t options, jack_status_t* status) +{ + return 0; +} diff --git a/windows/Setup/JackRouter.dll b/windows/Setup/JackRouter.dll index 92e743e05a03509a61eafd2bf65531633377cdf5..df435bed0c3e6d756bf89dea9b8fbf3f2c66ead3 100644 GIT binary patch delta 159 zcmZo@U}|V!n(%@7+18MapMToho?u{T_zlGSf%qa2-vnZ2Muvu+K>8yPGXmLvfb2?KztsEuLCh7BSXV>ApIVQ{{!(aAU*`d kazJq&Aif48JSStvAOr|WMvkZU$?_wh6a0I-iVX8-^I diff --git a/windows/Setup/README b/windows/Setup/README index d7f7eaf4..78588ece 100644 --- a/windows/Setup/README +++ b/windows/Setup/README @@ -1,7 +1,11 @@ This folder contains a script to create an installer for windows. It uses 'CreateInstall Free'(http://www.createinstall.com), a little software allowing to make simple installers. -You can use the 'jack.ci' script to make the installer. For that, you need to build the Code::Blocks workspace in order to have '.exe' and libraries. You also need 'qjackctl' binaries and libraries ('qjackctl.exe', 'mingwm10.dll', 'QtCore4.dll', 'QtGui.dll' and 'QtXml4.dll'). You can recompile qjackctl with qt4 or directly get the binaries. The five files are expected in the 'qjackctl' folder. +You can use the 'jack.ci' script to make the installer. For that, you need to build the Code::Blocks workspace in order to have '.exe' and libraries. +You also need 'qjackctl' binaries and libraries ('qjackctl.exe', 'mingwm10.dll', 'QtCore4.dll', 'QtGui.dll' and 'QtXml4.dll'). +You can recompile qjackctl with qt4 or directly get the binaries. The five files are expected in the 'qjackctl' folder. + +You also need the Microsoft Visual C++ 2008 Redistributable Package (x86) (the vcrdist_x86.exe file) to be in src folder. If you need libjack.lib and libjackserver.lib to link with in MS Visual Studio, you can use the MS Tool lib.exe to create the .lib file from de .def. Just use : 'lib /DEF:libjackserver.def /OUT:libjackserver.lib' and 'lib /DEF:libjack.def /OUT:libjack.lib' to create the lib file. diff --git a/windows/Setup/jack.ci b/windows/Setup/jack.ci index 213bcc82..a0ae1a66 100644 --- a/windows/Setup/jack.ci +++ b/windows/Setup/jack.ci @@ -1,5 +1,5 @@ <*project - version = 4 civer = "Free v4.14.3" winver = "2.6/5.1.2600" > + version = 4 civer = "Free v4.14.5" winver = "2.6/5.1.2600" > . Jack_v1.9.3_setup.exe @@ -38,7 +38,7 @@ over - 0 + 1 1 Uninstall - 2 1 @@ -54,6 +54,7 @@ <_>..\Release\bin\libjack.ainstlibovernewer0 +<_>.\src\vcredist_x86.exeinstovernewer0 <_>..\Release\bin\libjack.libinstlibovernewer0 <_>..\Release\bin\libjack.definstlibovernewer0 <_>..\Release\bin\libjackserver.ainstlibovernewer0 @@ -72,6 +73,8 @@ <_>..\Release\bin\portaudio_x86.dllinstovernewer0 <_>..\Release\bin\jack\jack_net.dllinstjackovernewer0 <_>..\Release\bin\jack\jack_dummy.dllinstjackovernewer0 +<_>..\Release\bin\jack\jack_loopback.dllinstjackovernewer0 +<_>..\Release\bin\jack\jack_winmme.dllinstjackovernewer0 <_>..\Release\bin\jack\jack_portaudio.dllinstjackovernewer0 <_>..\Release\bin\jack\netmanager.dllinstjackovernewer0 <_>..\Release\bin\jack\audioadapter.dllinstjackovernewer0 @@ -99,7 +102,8 @@ - + <_>appinstvcredist_x86.exe1instend + diff --git a/windows/Setup/src/README b/windows/Setup/src/README index 5ba3bc3a..e9424a26 100644 --- a/windows/Setup/src/README +++ b/windows/Setup/src/README @@ -4,11 +4,6 @@ JACK on Windows This installer will install everything to use Jack Audio Connection Kit (JACK) (www.jackaudio.org) on Windows. -============================================= -Microsoft Runtime Libraries -============================================= - -In order to use this software, you will need the Microsoft Visual C++ 2008 redistributable package. This package is freely available on the Microsoft download center. Please be sure you install the correct version (2008). This package is required by portaudio to run windows specific audio drivers (MME, DSound and ASIO). ============================================= QJACKCTL on Windows @@ -38,6 +33,16 @@ Then start jackd with the device you want, by using its name, for example: - jackd -R -S -d portaudio -d "ASIO::MOTU Audio ASIO", then start qjackctl. qjackctl will see the jackd server already running and then can be used normally. +============================================= +Jack MIDI +============================================= + +A first version of a JACK MIDI <==> Windows MIDI bridge (using Windows MME API) is available. +If can be activated using the -X parameter in jackd command line. So add "-X winmme" in QJACKCTL settings (something like "jackd -S -X winmme"). +The WinMME driver will scan MIDI input/output ports, open corresponding JACK MIDI ports and convert MIDI in/out into JACK MIDI messages. +QJACKCTL MIDI connection windows can then be used. + + ============================================= JackRouter JACK/ASIO driver ============================================= @@ -53,7 +58,7 @@ JackRouter is an ASIO driver that allows any ASIO compatible application to beco Known problems ============================================= -- starting/stopping the server several times in QJACKCTL does not work correctly. You'll have to quit qjackctl and launch it again. +- starting/stopping the server several times in QJACKCTL may not work correctly. You may have to quit QJACKCTL and launch it again. ============================================= diff --git a/windows/jack_loopback.cbp b/windows/jack_loopback.cbp new file mode 100644 index 00000000..87edea4f --- /dev/null +++ b/windows/jack_loopback.cbp @@ -0,0 +1,95 @@ + + + + + + diff --git a/windows/jackd.workspace b/windows/jackd.workspace index 35bd3d44..7e09eb88 100644 --- a/windows/jackd.workspace +++ b/windows/jackd.workspace @@ -48,5 +48,6 @@ + diff --git a/windows/portaudio/JackPortAudioDevices.cpp b/windows/portaudio/JackPortAudioDevices.cpp index 2adb35e0..d12cfca3 100644 --- a/windows/portaudio/JackPortAudioDevices.cpp +++ b/windows/portaudio/JackPortAudioDevices.cpp @@ -43,9 +43,9 @@ PortAudioDevices::PortAudioDevices() } PortAudioDevices::~PortAudioDevices() -{ +{ // Desactivate for now: crash the server.. - //Pa_Terminate(); + //Pa_Terminate(); delete[] fDeviceInfo; delete[] fHostName; diff --git a/windows/portaudio/JackPortAudioDevices.h b/windows/portaudio/JackPortAudioDevices.h index 92b8603e..c8ab656b 100644 --- a/windows/portaudio/JackPortAudioDevices.h +++ b/windows/portaudio/JackPortAudioDevices.h @@ -1,59 +1,59 @@ -/* -Copyright (C) 2008 Romain Moret at 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 __PortAudioDevices__ -#define __PortAudioDevices__ - -#include -#include - -#include "portaudio.h" -#include "pa_asio.h" - -/*! -\brief A PortAudio Devices manager. -*/ - -class PortAudioDevices -{ - private: - PaHostApiIndex fNumHostApi; //number of hosts - PaDeviceIndex fNumDevice; //number of devices - PaDeviceInfo** fDeviceInfo; //array of device info - std::string* fHostName; //array of host names (matched with host id's) - public: - PortAudioDevices(); - ~PortAudioDevices(); - - PaDeviceIndex GetNumDevice(); - PaDeviceInfo* GetDeviceInfo(PaDeviceIndex id); - std::string GetDeviceName(PaDeviceIndex id); - std::string GetHostFromDevice(PaDeviceInfo* device); - std::string GetHostFromDevice(PaDeviceIndex id); - std::string GetFullName(PaDeviceIndex id); - std::string GetFullName(std::string hostname, std::string devicename); - PaDeviceInfo* GetDeviceFromFullName(std::string fullname, PaDeviceIndex& id, bool isInput ); - void PrintSupportedStandardSampleRates(const PaStreamParameters* inputParameters, const PaStreamParameters* outputParameters); - int GetInputDeviceFromName(const char* name, PaDeviceIndex& device, int& in_max); - int GetOutputDeviceFromName(const char* name, PaDeviceIndex& device, int& out_max); - void DisplayDevicesNames(); - bool IsDuplex ( PaDeviceIndex id ); -}; - -#endif +/* +Copyright (C) 2008 Romain Moret at 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 __PortAudioDevices__ +#define __PortAudioDevices__ + +#include +#include + +#include "portaudio.h" +#include "pa_asio.h" + +/*! +\brief A PortAudio Devices manager. +*/ + +class PortAudioDevices +{ + private: + PaHostApiIndex fNumHostApi; //number of hosts + PaDeviceIndex fNumDevice; //number of devices + PaDeviceInfo** fDeviceInfo; //array of device info + std::string* fHostName; //array of host names (matched with host id's) + public: + PortAudioDevices(); + ~PortAudioDevices(); + + PaDeviceIndex GetNumDevice(); + PaDeviceInfo* GetDeviceInfo(PaDeviceIndex id); + std::string GetDeviceName(PaDeviceIndex id); + std::string GetHostFromDevice(PaDeviceInfo* device); + std::string GetHostFromDevice(PaDeviceIndex id); + std::string GetFullName(PaDeviceIndex id); + std::string GetFullName(std::string hostname, std::string devicename); + PaDeviceInfo* GetDeviceFromFullName(std::string fullname, PaDeviceIndex& id, bool isInput ); + void PrintSupportedStandardSampleRates(const PaStreamParameters* inputParameters, const PaStreamParameters* outputParameters); + int GetInputDeviceFromName(const char* name, PaDeviceIndex& device, int& in_max); + int GetOutputDeviceFromName(const char* name, PaDeviceIndex& device, int& out_max); + void DisplayDevicesNames(); + bool IsDuplex ( PaDeviceIndex id ); +}; + +#endif diff --git a/windows/resource_vc.h b/windows/resource_vc.h index 673206e6..9916ed38 100644 --- a/windows/resource_vc.h +++ b/windows/resource_vc.h @@ -1,15 +1,15 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by resource.rc -// - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resource.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/windows/winmme/JackWinMMEDriver.cpp b/windows/winmme/JackWinMMEDriver.cpp index 87b1e44e..65a7de65 100644 --- a/windows/winmme/JackWinMMEDriver.cpp +++ b/windows/winmme/JackWinMMEDriver.cpp @@ -1,501 +1,506 @@ -/* -Copyright (C) 2009 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. - -*/ - -#include "JackWinMMEDriver.h" -#include "JackGraphManager.h" -#include "JackEngineControl.h" -#include "JackDriverLoader.h" - -#include -#include -#include -#include - -#include -#include -#include - -namespace Jack -{ - -static bool InitHeaders(MidiSlot* slot) -{ - slot->fHeader = (LPMIDIHDR)GlobalAllocPtr(GMEM_MOVEABLE|GMEM_SHARE|GMEM_ZEROINIT, sizeof(MIDIHDR) + kBuffSize); - if (!slot->fHeader) - return false; - - slot->fHeader->lpData = (LPSTR)((LPBYTE)slot->fHeader + sizeof(MIDIHDR)); - slot->fHeader->dwBufferLength = kBuffSize; - slot->fHeader->dwFlags = 0; - slot->fHeader->dwUser = 0; - slot->fHeader->lpNext = 0; - slot->fHeader->dwBytesRecorded = 0; - return true; -} - -void CALLBACK JackWinMMEDriver::MidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD userData, DWORD dwParam1, DWORD dwParam2) -{ - jack_ringbuffer_t* ringbuffer = (jack_ringbuffer_t*)userData; - //jack_info("JackWinMMEDriver::MidiInProc 0\n"); - - switch (wMsg) { - case MIM_OPEN: - break; - - case MIM_ERROR: - case MIM_DATA: { - - //jack_info("JackWinMMEDriver::MidiInProc"); - - // One event - unsigned int num_packet = 1; - jack_ringbuffer_write(ringbuffer, (char*)&num_packet, sizeof(unsigned int)); - - // Write event actual data - jack_ringbuffer_write(ringbuffer, (char*)&dwParam1, 3); - break; - } - - case MIM_LONGERROR: - case MIM_LONGDATA: - /* - Nothing for now - */ - break; - } -} - -JackWinMMEDriver::JackWinMMEDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) - : JackMidiDriver(name, alias, engine, table), - fRealCaptureChannels(0), - fRealPlaybackChannels(0), - fMidiSource(NULL), - fMidiDestination(NULL) -{} - -JackWinMMEDriver::~JackWinMMEDriver() -{} - -int JackWinMMEDriver::Open(bool capturing, - bool playing, - int inchannels, - int outchannels, - bool monitor, - const char* capture_driver_name, - const char* playback_driver_name, - jack_nframes_t capture_latency, - jack_nframes_t playback_latency) -{ - - jack_log("JackWinMMEDriver::Open"); - - fRealCaptureChannels = midiInGetNumDevs(); - fRealPlaybackChannels = midiOutGetNumDevs(); - - // Generic JackMidiDriver Open - if (JackMidiDriver::Open(capturing, playing, fRealCaptureChannels, fRealPlaybackChannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0) - return -1; - - fMidiDestination = new MidiSlot[fRealCaptureChannels]; - assert(fMidiDestination); - - // Real input - for (int i = 0; i < fRealCaptureChannels; i++) { - - HMIDIIN handle; - fMidiDestination[i].fIndex = i; - MMRESULT ret = midiInOpen(&handle, fMidiDestination[i].fIndex, (DWORD)MidiInProc, (DWORD)fRingBuffer[i], CALLBACK_FUNCTION); - - if (ret == MMSYSERR_NOERROR) { - fMidiDestination[i].fHandle = handle; - if (!InitHeaders(&fMidiDestination[i])) { - jack_error("memory allocation failed"); - midiInClose(handle); - goto error; - //continue; - } - ret = midiInPrepareHeader(handle, fMidiDestination[i].fHeader, sizeof(MIDIHDR)); - - if (ret == MMSYSERR_NOERROR) { - fMidiDestination[i].fHeader->dwUser = 1; - ret = midiInAddBuffer(handle, fMidiDestination[i].fHeader, sizeof(MIDIHDR)); - if (ret == MMSYSERR_NOERROR) { - ret = midiInStart(handle); - if (ret != MMSYSERR_NOERROR) { - jack_error("midiInStart error"); - CloseInput(&fMidiDestination[i]); - goto error; - } - } else { - jack_error ("midiInAddBuffer error"); - CloseInput(&fMidiDestination[i]); - goto error; - } - } else { - jack_error("midiInPrepareHeader error"); - midiInClose(handle); - goto error; - } - } else { - jack_error ("midiInOpen error"); - goto error; - } - } - - fMidiSource = new MidiSlot[fRealPlaybackChannels]; - assert(fMidiSource); - - // Real output - for (int i = 0; i < fRealPlaybackChannels; i++) { - MMRESULT res; - HMIDIOUT handle; - fMidiSource[i].fIndex = i; - UINT ret = midiOutOpen(&handle, fMidiSource[i].fIndex, 0L, 0L, CALLBACK_NULL); - if (ret == MMSYSERR_NOERROR) { - fMidiSource[i].fHandle = handle; - if (!InitHeaders(&fMidiSource[i])) { - jack_error("memory allocation failed"); - midiOutClose(handle); - //continue; - goto error; - } - res = midiOutPrepareHeader(handle, fMidiSource[i].fHeader, sizeof(MIDIHDR)); - if (res != MMSYSERR_NOERROR) { - jack_error("midiOutPrepareHeader error %d %d %d", i, handle, res); - //continue; - goto error; - } else { - fMidiSource[i].fHeader->dwUser = 1; - } - } else { - jack_error("midiOutOpen error"); - goto error; - } - } - - return 0; - -error: - Close(); - return -1; -} - -void JackWinMMEDriver::CloseInput(MidiSlot* slot) -{ - MMRESULT res; - int retry = 0; - - if (slot->fHandle == 0) - return; - - HMIDIIN handle = (HMIDIIN)slot->fHandle; - slot->fHeader->dwUser = 0; - res = midiInStop(handle); - if (res != MMSYSERR_NOERROR) { - jack_error("midiInStop error"); - } - res = midiInReset(handle); - if (res != MMSYSERR_NOERROR) { - jack_error("midiInReset error"); - } - res = midiInUnprepareHeader(handle, slot->fHeader, sizeof(MIDIHDR)); - if (res != MMSYSERR_NOERROR) { - jack_error("midiInUnprepareHeader error"); - } - do { - res = midiInClose(handle); - if (res != MMSYSERR_NOERROR) { - jack_error("midiInClose error"); - } - if (res == MIDIERR_STILLPLAYING) - midiInReset(handle); - Sleep (10); - retry++; - } while ((res == MIDIERR_STILLPLAYING) && (retry < 10)); - - if (slot->fHeader) { - GlobalFreePtr(slot->fHeader); - } -} - -void JackWinMMEDriver::CloseOutput(MidiSlot* slot) -{ - MMRESULT res; - int retry = 0; - - if (slot->fHandle == 0) - return; - - HMIDIOUT handle = (HMIDIOUT)slot->fHandle; - res = midiOutReset(handle); - if (res != MMSYSERR_NOERROR) - jack_error("midiOutReset error"); - midiOutUnprepareHeader(handle, slot->fHeader, sizeof(MIDIHDR)); - do { - res = midiOutClose(handle); - if (res != MMSYSERR_NOERROR) - jack_error("midiOutClose error"); - Sleep(10); - retry++; - } while ((res == MIDIERR_STILLPLAYING) && (retry < 10)); - - if (slot->fHeader) { - GlobalFreePtr(slot->fHeader); - } -} - -int JackWinMMEDriver::Close() -{ - jack_log("JackWinMMEDriver::Close"); - - // Close input - if (fMidiDestination) { - for (int i = 0; i < fRealCaptureChannels; i++) { - CloseInput(&fMidiDestination[i]); - } - delete[] fMidiDestination; - } - - // Close output - if (fMidiSource) { - for (int i = 0; i < fRealPlaybackChannels; i++) { - CloseOutput(&fMidiSource[i]); - } - delete[] fMidiSource; - } - - return 0; -} - -int JackWinMMEDriver::Attach() -{ - JackPort* port; - jack_port_id_t port_index; - char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - unsigned long port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; - MMRESULT res; - int i; - - jack_log("JackMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); - - for (i = 0; i < fCaptureChannels; i++) { - MIDIINCAPS caps; - res = midiInGetDevCaps(i, &caps, sizeof(caps)); - if (res == MMSYSERR_NOERROR) { - snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, caps.szPname, i + 1); - } else { - snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); - } - snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); - - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { - jack_error("driver: cannot register port for %s", name); - return -1; - } - port = fGraphManager->GetPort(port_index); - port->SetAlias(alias); - fCapturePortList[i] = port_index; - jack_log("JackMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index); - } - - port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; - - for (i = 0; i < fPlaybackChannels; i++) { - MIDIOUTCAPS caps; - res = midiOutGetDevCaps(i, &caps, sizeof(caps)); - if (res == MMSYSERR_NOERROR) { - snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, caps.szPname, i + 1); - } else { - snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fPlaybackDriverName, i + 1); - } - snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); - - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { - jack_error("driver: cannot register port for %s", name); - return -1; - } - port = fGraphManager->GetPort(port_index); - port->SetAlias(alias); - fPlaybackPortList[i] = port_index; - jack_log("JackMidiDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); - } - - return 0; -} - -int JackWinMMEDriver::Read() -{ - size_t size; - - for (int chan = 0; chan < fCaptureChannels; chan++) { - - if (fGraphManager->GetConnectionsNum(fCapturePortList[chan]) > 0) { - - JackMidiBuffer* midi_buffer = GetInputBuffer(chan); - - if (jack_ringbuffer_read_space (fRingBuffer[chan]) == 0) { - // Reset buffer - midi_buffer->Reset(midi_buffer->nframes); - } else { - - while ((size = jack_ringbuffer_read_space (fRingBuffer[chan])) > 0) { - - //jack_info("jack_ringbuffer_read_space %d", size); - int ev_count = 0; - jack_ringbuffer_read(fRingBuffer[chan], (char*)&ev_count, sizeof(int)); - - if (ev_count > 0) { - for (int j = 0; j < ev_count; j++) { - unsigned int event_len = 3; - // Read event actual data - jack_midi_data_t* dest = midi_buffer->ReserveEvent(0, event_len); - jack_ringbuffer_read(fRingBuffer[chan], (char*)dest, event_len); - } - } - } - } - } else { - //jack_info("Consume ring buffer"); - jack_ringbuffer_read_advance(fRingBuffer[chan], jack_ringbuffer_read_space(fRingBuffer[chan])); - } - } - return 0; -} - -int JackWinMMEDriver::Write() -{ - for (int chan = 0; chan < fPlaybackChannels; chan++) { - - if (fGraphManager->GetConnectionsNum(fPlaybackPortList[chan]) > 0) { - - JackMidiBuffer* midi_buffer = GetOutputBuffer(chan); - - // TODO : use timestamp - - for (unsigned int j = 0; j < midi_buffer->event_count; j++) { - JackMidiEvent* ev = &midi_buffer->events[j]; - if (ev->size <= 3) { - MMRESULT res = midiOutShortMsg((HMIDIOUT)fMidiSource[chan].fHandle, *((DWORD*)ev->GetData(midi_buffer))); - if (res != MMSYSERR_NOERROR) - jack_error ("midiOutShortMsg error res %d", res); - } else { - - } - } - } - } - - return 0; -} - -} // end of namespace - -#ifdef __cplusplus -extern "C" -{ -#endif - - SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor() - { - jack_driver_desc_t * desc; - unsigned int i; - - desc = (jack_driver_desc_t*)calloc (1, sizeof (jack_driver_desc_t)); - strcpy(desc->name, "winmme"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 - strcpy(desc->desc, "WinMME API based MIDI backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - - desc->nparams = 0; - desc->params = (jack_driver_param_desc_t*)calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); - - return desc; - } - - SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) - { - /* - unsigned int capture_ports = 2; - unsigned int playback_ports = 2; - unsigned long wait_time = 0; - const JSList * node; - const jack_driver_param_t * param; - bool monitor = false; - - for (node = params; node; node = jack_slist_next (node)) { - param = (const jack_driver_param_t *) node->data; - - switch (param->character) { - - case 'C': - capture_ports = param->value.ui; - break; - - case 'P': - playback_ports = param->value.ui; - break; - - case 'r': - sample_rate = param->value.ui; - break; - - case 'p': - period_size = param->value.ui; - break; - - case 'w': - wait_time = param->value.ui; - break; - - case 'm': - monitor = param->value.i; - break; - } - } - */ - - Jack::JackDriverClientInterface* driver = new Jack::JackWinMMEDriver("system_midi", "winmme", engine, table); - if (driver->Open(1, 1, 0, 0, false, "in", "out", 0, 0) == 0) { - return driver; - } else { - delete driver; - return NULL; - } - } - -#ifdef __cplusplus -} -#endif - - -/* -jack_connect system:midi_capture_1 system_midi:playback_1 -jack_connect system:midi_capture_1 system_midi:playback_2 - -jack_connect system:midi_capture_1 system_midi:playback_1 - -jack_connect system:midi_capture_1 system_midi:playback_1 - -jack_connect system:midi_capture_1 system_midi:playback_1 - -jack_connect system_midi:capture_1 system:midi_playback_1 -jack_connect system_midi:capture_2 system:midi_playback_1 - -jack_connect system_midi:capture_1 system_midi:playback_1 - -*/ +/* +Copyright (C) 2009 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. + +*/ + +#include "JackWinMMEDriver.h" +#include "JackGraphManager.h" +#include "JackEngineControl.h" +#include "JackDriverLoader.h" + +#include +#include +#include +#include + +#include +#include +#include + +namespace Jack +{ + +static bool InitHeaders(MidiSlot* slot) +{ + slot->fHeader = (LPMIDIHDR)GlobalAllocPtr(GMEM_MOVEABLE|GMEM_SHARE|GMEM_ZEROINIT, sizeof(MIDIHDR) + kBuffSize); + if (!slot->fHeader) + return false; + + slot->fHeader->lpData = (LPSTR)((LPBYTE)slot->fHeader + sizeof(MIDIHDR)); + slot->fHeader->dwBufferLength = kBuffSize; + slot->fHeader->dwFlags = 0; + slot->fHeader->dwUser = 0; + slot->fHeader->lpNext = 0; + slot->fHeader->dwBytesRecorded = 0; + return true; +} + +void CALLBACK JackWinMMEDriver::MidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD userData, DWORD dwParam1, DWORD dwParam2) +{ + jack_ringbuffer_t* ringbuffer = (jack_ringbuffer_t*)userData; + //jack_info("JackWinMMEDriver::MidiInProc 0\n"); + + switch (wMsg) { + case MIM_OPEN: + break; + + case MIM_ERROR: + case MIM_DATA: { + + //jack_info("JackWinMMEDriver::MidiInProc"); + + // One event + unsigned int num_packet = 1; + jack_ringbuffer_write(ringbuffer, (char*)&num_packet, sizeof(unsigned int)); + + // Write event actual data + jack_ringbuffer_write(ringbuffer, (char*)&dwParam1, 3); + break; + } + + case MIM_LONGERROR: + case MIM_LONGDATA: + /* + Nothing for now + */ + break; + } +} + +JackWinMMEDriver::JackWinMMEDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) + : JackMidiDriver(name, alias, engine, table), + fRealCaptureChannels(0), + fRealPlaybackChannels(0), + fMidiSource(NULL), + fMidiDestination(NULL) +{} + +JackWinMMEDriver::~JackWinMMEDriver() +{} + +int JackWinMMEDriver::Open(bool capturing, + bool playing, + int inchannels, + int outchannels, + bool monitor, + const char* capture_driver_name, + const char* playback_driver_name, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency) +{ + + jack_log("JackWinMMEDriver::Open"); + + fRealCaptureChannels = midiInGetNumDevs(); + fRealPlaybackChannels = midiOutGetNumDevs(); + + // Generic JackMidiDriver Open + if (JackMidiDriver::Open(capturing, playing, fRealCaptureChannels, fRealPlaybackChannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0) + return -1; + + fMidiDestination = new MidiSlot[fRealCaptureChannels]; + assert(fMidiDestination); + + // Real input + int devindex = 0; + for (int i = 0; i < fRealCaptureChannels; i++) { + + HMIDIIN handle; + fMidiDestination[devindex].fIndex = i; + MMRESULT ret = midiInOpen(&handle, fMidiDestination[devindex].fIndex, (DWORD)MidiInProc, (DWORD)fRingBuffer[devindex], CALLBACK_FUNCTION); + + if (ret == MMSYSERR_NOERROR) { + fMidiDestination[devindex].fHandle = handle; + if (!InitHeaders(&fMidiDestination[devindex])) { + jack_error("memory allocation failed"); + midiInClose(handle); + continue; + } + ret = midiInPrepareHeader(handle, fMidiDestination[devindex].fHeader, sizeof(MIDIHDR)); + + if (ret == MMSYSERR_NOERROR) { + fMidiDestination[devindex].fHeader->dwUser = 1; + ret = midiInAddBuffer(handle, fMidiDestination[devindex].fHeader, sizeof(MIDIHDR)); + if (ret == MMSYSERR_NOERROR) { + ret = midiInStart(handle); + if (ret != MMSYSERR_NOERROR) { + jack_error("midiInStart error"); + CloseInput(&fMidiDestination[devindex]); + continue; + } + } else { + jack_error ("midiInAddBuffer error"); + CloseInput(&fMidiDestination[devindex]); + continue; + } + } else { + jack_error("midiInPrepareHeader error"); + midiInClose(handle); + continue; + } + } else { + jack_error ("midiInOpen error"); + continue; + } + devindex += 1; + } + fRealCaptureChannels = devindex; + fCaptureChannels = devindex; + + fMidiSource = new MidiSlot[fRealPlaybackChannels]; + assert(fMidiSource); + + // Real output + devindex = 0; + for (int i = 0; i < fRealPlaybackChannels; i++) { + MMRESULT res; + HMIDIOUT handle; + fMidiSource[devindex].fIndex = i; + UINT ret = midiOutOpen(&handle, fMidiSource[devindex].fIndex, 0L, 0L, CALLBACK_NULL); + if (ret == MMSYSERR_NOERROR) { + fMidiSource[devindex].fHandle = handle; + if (!InitHeaders(&fMidiSource[devindex])) { + jack_error("memory allocation failed"); + midiOutClose(handle); + continue; + } + res = midiOutPrepareHeader(handle, fMidiSource[devindex].fHeader, sizeof(MIDIHDR)); + if (res != MMSYSERR_NOERROR) { + jack_error("midiOutPrepareHeader error %d %d %d", i, handle, res); + continue; + } else { + fMidiSource[devindex].fHeader->dwUser = 1; + } + } else { + jack_error("midiOutOpen error"); + continue; + } + devindex += 1; + } + fRealPlaybackChannels = devindex; + fPlaybackChannels = devindex; + return 0; +} + +void JackWinMMEDriver::CloseInput(MidiSlot* slot) +{ + MMRESULT res; + int retry = 0; + + if (slot->fHandle == 0) + return; + + HMIDIIN handle = (HMIDIIN)slot->fHandle; + slot->fHeader->dwUser = 0; + res = midiInStop(handle); + if (res != MMSYSERR_NOERROR) { + jack_error("midiInStop error"); + } + res = midiInReset(handle); + if (res != MMSYSERR_NOERROR) { + jack_error("midiInReset error"); + } + res = midiInUnprepareHeader(handle, slot->fHeader, sizeof(MIDIHDR)); + if (res != MMSYSERR_NOERROR) { + jack_error("midiInUnprepareHeader error"); + } + do { + res = midiInClose(handle); + if (res != MMSYSERR_NOERROR) { + jack_error("midiInClose error"); + } + if (res == MIDIERR_STILLPLAYING) + midiInReset(handle); + Sleep (10); + retry++; + } while ((res == MIDIERR_STILLPLAYING) && (retry < 10)); + + if (slot->fHeader) { + GlobalFreePtr(slot->fHeader); + } +} + +void JackWinMMEDriver::CloseOutput(MidiSlot* slot) +{ + MMRESULT res; + int retry = 0; + + if (slot->fHandle == 0) + return; + + HMIDIOUT handle = (HMIDIOUT)slot->fHandle; + res = midiOutReset(handle); + if (res != MMSYSERR_NOERROR) + jack_error("midiOutReset error"); + midiOutUnprepareHeader(handle, slot->fHeader, sizeof(MIDIHDR)); + do { + res = midiOutClose(handle); + if (res != MMSYSERR_NOERROR) + jack_error("midiOutClose error"); + Sleep(10); + retry++; + } while ((res == MIDIERR_STILLPLAYING) && (retry < 10)); + + if (slot->fHeader) { + GlobalFreePtr(slot->fHeader); + } +} + +int JackWinMMEDriver::Close() +{ + jack_log("JackWinMMEDriver::Close"); + + // Close input + if (fMidiDestination) { + for (int i = 0; i < fRealCaptureChannels; i++) { + CloseInput(&fMidiDestination[i]); + } + delete[] fMidiDestination; + } + + // Close output + if (fMidiSource) { + for (int i = 0; i < fRealPlaybackChannels; i++) { + CloseOutput(&fMidiSource[i]); + } + delete[] fMidiSource; + } + + return 0; +} + +int JackWinMMEDriver::Attach() +{ + JackPort* port; + jack_port_id_t port_index; + char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + unsigned long port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; + MMRESULT res; + int i; + + jack_log("JackMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); + + for (i = 0; i < fCaptureChannels; i++) { + MIDIINCAPS caps; + res = midiInGetDevCaps(fMidiDestination[i].fIndex, &caps, sizeof(caps)); + if (res == MMSYSERR_NOERROR) { + snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, caps.szPname, i + 1); + } else { + snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); + } + snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); + + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { + jack_error("driver: cannot register port for %s", name); + return -1; + } + port = fGraphManager->GetPort(port_index); + port->SetAlias(alias); + fCapturePortList[i] = port_index; + jack_log("JackMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index); + } + + port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; + + for (i = 0; i < fPlaybackChannels; i++) { + MIDIOUTCAPS caps; + res = midiOutGetDevCaps(fMidiSource[i].fIndex, &caps, sizeof(caps)); + if (res == MMSYSERR_NOERROR) { + snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, caps.szPname, i + 1); + } else { + snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fPlaybackDriverName, i + 1); + } + snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); + + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { + jack_error("driver: cannot register port for %s", name); + return -1; + } + port = fGraphManager->GetPort(port_index); + port->SetAlias(alias); + fPlaybackPortList[i] = port_index; + jack_log("JackMidiDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); + } + + return 0; +} + +int JackWinMMEDriver::Read() +{ + size_t size; + + for (int chan = 0; chan < fCaptureChannels; chan++) { + + if (fGraphManager->GetConnectionsNum(fCapturePortList[chan]) > 0) { + + JackMidiBuffer* midi_buffer = GetInputBuffer(chan); + + if (jack_ringbuffer_read_space (fRingBuffer[chan]) == 0) { + // Reset buffer + midi_buffer->Reset(midi_buffer->nframes); + } else { + + while ((size = jack_ringbuffer_read_space (fRingBuffer[chan])) > 0) { + + //jack_info("jack_ringbuffer_read_space %d", size); + int ev_count = 0; + jack_ringbuffer_read(fRingBuffer[chan], (char*)&ev_count, sizeof(int)); + + if (ev_count > 0) { + for (int j = 0; j < ev_count; j++) { + unsigned int event_len = 3; + // Read event actual data + jack_midi_data_t* dest = midi_buffer->ReserveEvent(0, event_len); + jack_ringbuffer_read(fRingBuffer[chan], (char*)dest, event_len); + } + } + } + } + } else { + //jack_info("Consume ring buffer"); + jack_ringbuffer_read_advance(fRingBuffer[chan], jack_ringbuffer_read_space(fRingBuffer[chan])); + } + } + return 0; +} + +int JackWinMMEDriver::Write() +{ + for (int chan = 0; chan < fPlaybackChannels; chan++) { + + if (fGraphManager->GetConnectionsNum(fPlaybackPortList[chan]) > 0) { + + JackMidiBuffer* midi_buffer = GetOutputBuffer(chan); + + // TODO : use timestamp + + for (unsigned int j = 0; j < midi_buffer->event_count; j++) { + JackMidiEvent* ev = &midi_buffer->events[j]; + if (ev->size <= 3) { + jack_midi_data_t *d = ev->GetData(midi_buffer); + DWORD winev = 0; + if (ev->size > 0) winev |= d[0]; + if (ev->size > 1) winev |= (d[1] << 8); + if (ev->size > 2) winev |= (d[2] << 16); + MMRESULT res = midiOutShortMsg((HMIDIOUT)fMidiSource[chan].fHandle, winev); + if (res != MMSYSERR_NOERROR) + jack_error ("midiOutShortMsg error res %d", res); + } else { + + } + } + } + } + + return 0; +} + +} // end of namespace + +#ifdef __cplusplus +extern "C" +{ +#endif + + SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor() + { + jack_driver_desc_t * desc; + //unsigned int i; + + desc = (jack_driver_desc_t*)calloc (1, sizeof (jack_driver_desc_t)); + strcpy(desc->name, "winmme"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 + strcpy(desc->desc, "WinMME API based MIDI backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 + + desc->nparams = 0; + desc->params = (jack_driver_param_desc_t*)calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); + + return desc; + } + + SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) + { + /* + unsigned int capture_ports = 2; + unsigned int playback_ports = 2; + unsigned long wait_time = 0; + const JSList * node; + const jack_driver_param_t * param; + bool monitor = false; + + for (node = params; node; node = jack_slist_next (node)) { + param = (const jack_driver_param_t *) node->data; + + switch (param->character) { + + case 'C': + capture_ports = param->value.ui; + break; + + case 'P': + playback_ports = param->value.ui; + break; + + case 'r': + sample_rate = param->value.ui; + break; + + case 'p': + period_size = param->value.ui; + break; + + case 'w': + wait_time = param->value.ui; + break; + + case 'm': + monitor = param->value.i; + break; + } + } + */ + + Jack::JackDriverClientInterface* driver = new Jack::JackWinMMEDriver("system_midi", "winmme", engine, table); + if (driver->Open(1, 1, 0, 0, false, "in", "out", 0, 0) == 0) { + return driver; + } else { + delete driver; + return NULL; + } + } + +#ifdef __cplusplus +} +#endif + + +/* +jack_connect system:midi_capture_1 system_midi:playback_1 +jack_connect system:midi_capture_1 system_midi:playback_2 + +jack_connect system:midi_capture_1 system_midi:playback_1 + +jack_connect system:midi_capture_1 system_midi:playback_1 + +jack_connect system:midi_capture_1 system_midi:playback_1 + +jack_connect system_midi:capture_1 system:midi_playback_1 +jack_connect system_midi:capture_2 system:midi_playback_1 + +jack_connect system_midi:capture_1 system_midi:playback_1 + +*/ diff --git a/wscript b/wscript index c0499682..917208d0 100644 --- a/wscript +++ b/wscript @@ -61,6 +61,7 @@ def set_options(opt): opt.tool_options('compiler_cc') opt.add_option('--libdir', type='string', help="Library directory [Default: /lib]") + opt.add_option('--libdir32', type='string', help="32bit Library directory [Default: /lib32]") opt.add_option('--dbus', action='store_true', default=False, help='Enable D-Bus JACK (jackdbus)') opt.add_option('--classic', action='store_true', default=False, help='Force enable standard JACK (jackd) even if D-Bus JACK (jackdbus) is enabled too') opt.add_option('--doxygen', action='store_true', default=False, help='Enable build of doxygen documentation') @@ -68,6 +69,7 @@ def set_options(opt): opt.add_option('--mixed', action='store_true', default=False, help='Build with 32/64 bits mixed mode') opt.add_option('--clients', default=64, type="int", dest="clients", help='Maximum number of JACK clients') opt.add_option('--ports', default=1024, type="int", dest="ports", help='Maximum number of ports') + opt.add_option('--ports-per-application', default=512, type="int", dest="application_ports", help='Maximum number of ports per application') opt.sub_options('dbus') def configure(conf): @@ -130,12 +132,13 @@ def configure(conf): conf.env['BUILD_JACKD'] = True if Options.options.libdir: - conf.env['LIBDIR'] = Options.options.libdir + conf.env['LIBDIR'] = conf.env['PREFIX'] + Options.options.libdir else: - conf.env['LIBDIR'] = conf.env['PREFIX'] + '/lib/' + conf.env['LIBDIR'] = conf.env['PREFIX'] + '/lib' conf.define('CLIENT_NUM', Options.options.clients) - conf.define('PORT_NUM', Options.options. ports) + conf.define('PORT_NUM', Options.options.ports) + conf.define('PORT_NUM_FOR_CLIENT', Options.options.application_ports) conf.define('ADDON_DIR', os.path.normpath(os.path.join(conf.env['LIBDIR'], 'jack'))) conf.define('JACK_LOCATION', os.path.normpath(os.path.join(conf.env['PREFIX'], 'bin'))) @@ -143,6 +146,8 @@ def configure(conf): conf.define('JACKMP', 1) if conf.env['BUILD_JACKDBUS'] == True: conf.define('JACK_DBUS', 1) + if conf.env['BUILD_JACKD'] == False: + conf.define('USE_LIBDBUS_AUTOLAUNCH', 1) if conf.env['BUILD_WITH_PROFILE'] == True: conf.define('JACK_MONITOR', 1) if conf.env['BUILD_WITH_32_64'] == True: @@ -167,6 +172,7 @@ def configure(conf): print "Build with a maximum of %d JACK clients" % conf.env['CLIENT_NUM'] print "Build with a maximum of %d ports" % conf.env['PORT_NUM'] + print "Build with a maximum of %d ports per application" % conf.env['PORT_NUM_FOR_CLIENT'] display_msg("Install prefix", conf.env['PREFIX'], 'CYAN') display_msg("Library directory", conf.env['LIBDIR'], 'CYAN') @@ -204,7 +210,22 @@ def configure(conf): print Logs.colors.NORMAL, print + if Options.options.mixed == True: + env_variant2 = conf.env.copy() + conf.set_env_name('lib32', env_variant2) + env_variant2.set_variant('lib32') + conf.setenv('lib32') + conf.env.append_unique('CXXFLAGS', '-m32') + conf.env.append_unique('CCFLAGS', '-m32') + conf.env.append_unique('LINKFLAGS', '-m32') + conf.write_config_header('config.h') + if Options.options.libdir32: + conf.env['LIBDIR'] = conf.env['PREFIX'] + Options.options.libdir32 + else: + conf.env['LIBDIR'] = conf.env['PREFIX'] + '/lib32' + def build(bld): + print ("make[1]: Entering directory `" + os.getcwd() + "/" + blddir + "'" ) if not os.access('svnversion.h', os.R_OK): create_svnversion_task(bld) From 5d29fcff36b77a02e60b6177e957cdc52cb61ecc Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 8 Sep 2009 09:19:49 +0000 Subject: [PATCH 022/472] rebase from trunk 3613:3638 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3639 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 26 ++- README | 1 - common/JackAudioDriver.cpp | 3 +- common/JackConstants.h | 2 +- common/jack/control.h | 2 + common/memops.c | 2 +- dbus/audio_reserve.c | 4 +- dbus/controller_iface_patchbay.c | 3 +- doxyfile | 2 +- macosx/Jack-Info.plist | 4 +- macosx/JackMachThread.cpp | 6 +- macosx/JackMachThread.h | 2 +- macosx/Jackdmp.xcodeproj/project.pbxproj | 2 +- macosx/coreaudio/JackCoreAudioAdapter.cpp | 2 + macosx/coreaudio/JackCoreAudioDriver.cpp | 35 +++- macosx/coreaudio/JackCoreAudioDriver.h | 4 +- solaris/oss/JackBoomerDriver.cpp | 233 ++++++++++++---------- solaris/oss/JackBoomerDriver.h | 13 +- solaris/oss/JackOSSAdapter.cpp | 11 +- solaris/oss/JackOSSDriver.cpp | 4 +- windows/jackaudioadapter.rc | 8 +- windows/jackd.rc | 8 +- windows/jacknetadapter.rc | 8 +- windows/jacknetdriver.rc | 8 +- windows/jacknetmanager.rc | 8 +- windows/jackportaudio.rc | 8 +- windows/jackwinmme.rc | 8 +- windows/libjack.rc | 8 +- windows/libjackserver.rc | 8 +- windows/resource.rc | 8 +- wscript | 2 +- 31 files changed, 259 insertions(+), 184 deletions(-) diff --git a/ChangeLog b/ChangeLog index e6d85017..c6f6ec3f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,7 +23,31 @@ Paul Davis --------------------------- Jackdmp changes log ---------------------------- +--------------------------- + +2009-08-28 Stephane Letz + + * Correct monitor port naming in JackAudioDriver and JackCoreAudioDriver. + * Big endian bug fix in memops.c (http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=5;filename=11_be24bit.patch;att=1;bug=486308) + +2009-07-31 Stephane Letz + + * Use SNDCTL_DSP_SYNCGROUP/SNDCTL_DSP_SYNCSTART API to synchronize input and output in Solaris boomer backend. + + +2009-07-29 Stephane Letz + + * Add a -G parameter in CoreAudio backend (the computation value in RT thread expressed as percent of period). + +2009-07-28 Stephane Letz + + * Fix CopyAndConvertIn for Solaris backends. + +2009-07-22 Stephane Letz + + * Version 1.9.4 started. + * Solaris boomer backend now working in capture or playback only mode. + * Fix control.h for proper compilation on Solaris. 2009-07-17 Stephane Letz diff --git a/README b/README index 5e746d3d..88278c31 100644 --- a/README +++ b/README @@ -42,7 +42,6 @@ Known problems, limitations - use of POSIX named semaphore is currently unstable and not recommended yet. - ---------------- Solaris version ---------------- diff --git a/common/JackAudioDriver.cpp b/common/JackAudioDriver.cpp index 505db38e..3bcae9e9 100644 --- a/common/JackAudioDriver.cpp +++ b/common/JackAudioDriver.cpp @@ -139,12 +139,13 @@ int JackAudioDriver::Attach() // Monitor ports if (fWithMonitorPorts) { jack_log("Create monitor port "); - snprintf(name, sizeof(name) - 1, "%s:%s:monitor_%u", fAliasName, fPlaybackDriverName, i + 1); + snprintf(name, sizeof(name) - 1, "%s:monitor_%u", fClientControl.fName, i + 1); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("Cannot register monitor port for %s", name); return -1; } else { port = fGraphManager->GetPort(port_index); + port->SetAlias(alias); port->SetLatency(fEngineControl->fBufferSize); fMonitorPortList[i] = port_index; } diff --git a/common/JackConstants.h b/common/JackConstants.h index f5355afc..709aa364 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -24,7 +24,7 @@ #include "config.h" #endif -#define VERSION "1.9.3" +#define VERSION "1.9.4" #define BUFFER_SIZE_MAX 8192 diff --git a/common/jack/control.h b/common/jack/control.h index 263af1d1..6360d30a 100644 --- a/common/jack/control.h +++ b/common/jack/control.h @@ -31,7 +31,9 @@ #include #include +#if !defined (__sun__) #include +#endif /** Parameter types, intentionally similar to jack_driver_param_type_t */ typedef enum diff --git a/common/memops.c b/common/memops.c index 7112d40e..3731a682 100644 --- a/common/memops.c +++ b/common/memops.c @@ -481,7 +481,7 @@ void sample_move_dS_s24s (jack_default_audio_sample_t *dst, char *src, unsigned x <<= 8; x |= (unsigned char)(src[0]); /* correct sign bit and the rest of the top byte */ - if (src[0] & 0x80) { + if (src[2] & 0x80) { x |= 0xff << 24; } #endif diff --git a/dbus/audio_reserve.c b/dbus/audio_reserve.c index 120db64f..049826a5 100644 --- a/dbus/audio_reserve.c +++ b/dbus/audio_reserve.c @@ -106,10 +106,10 @@ SERVER_EXPORT void audio_release(const char * device_name) } if (i < DEVICE_MAX) { - jack_info("Released audio card %s", device_name); + jack_info("Released audio card %s", device_name); rd_release(gReservedDevice[i].reserved_device); } else { - jack_error("Audio card %s not found!!", device_name); + jack_error("Audio card %s not found!!", device_name); } // Close DBus connection last time diff --git a/dbus/controller_iface_patchbay.c b/dbus/controller_iface_patchbay.c index e89c7b3b..9adb7cfa 100644 --- a/dbus/controller_iface_patchbay.c +++ b/dbus/controller_iface_patchbay.c @@ -1763,7 +1763,8 @@ JACK_DBUS_METHOD_ARGUMENTS_BEGIN(DisconnectPortsByConnectionID) JACK_DBUS_METHOD_ARGUMENTS_END JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetClientPID) - JACK_DBUS_METHOD_ARGUMENT("client_id", DBUS_TYPE_INT64_AS_STRING, false) + JACK_DBUS_METHOD_ARGUMENT("client_id", DBUS_TYPE_UINT64_AS_STRING, false) + JACK_DBUS_METHOD_ARGUMENT("process_id", DBUS_TYPE_INT64_AS_STRING, true) JACK_DBUS_METHOD_ARGUMENTS_END JACK_DBUS_METHODS_BEGIN diff --git a/doxyfile b/doxyfile index 930b9eaf..0ba53fc0 100644 --- a/doxyfile +++ b/doxyfile @@ -23,7 +23,7 @@ PROJECT_NAME = "Jack2" # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 1.9.3 +PROJECT_NUMBER = 1.9.4 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/macosx/Jack-Info.plist b/macosx/Jack-Info.plist index 924e644a..1e5eb07e 100644 --- a/macosx/Jack-Info.plist +++ b/macosx/Jack-Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable Jackservermp CFBundleGetInfoString - Jackdmp 1.9.3, @03-09 Paul Davis, Grame + Jackdmp 1.9.4, @03-09 Paul Davis, Grame CFBundleIdentifier com.grame.Jackmp CFBundleInfoDictionaryVersion @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.9.3 + 1.9.4 diff --git a/macosx/JackMachThread.cpp b/macosx/JackMachThread.cpp index 7b45d239..fa836fb4 100644 --- a/macosx/JackMachThread.cpp +++ b/macosx/JackMachThread.cpp @@ -126,13 +126,13 @@ UInt32 JackMachThread::GetThreadPriority(pthread_t thread, int inWhichPriority) return 0; } -int JackMachThread::GetParams(UInt64* period, UInt64* computation, UInt64* constraint) +int JackMachThread::GetParams(pthread_t thread, UInt64* period, UInt64* computation, UInt64* constraint) { thread_time_constraint_policy_data_t theTCPolicy; mach_msg_type_number_t count = THREAD_TIME_CONSTRAINT_POLICY_COUNT; boolean_t get_default = false; - kern_return_t res = thread_policy_get(pthread_mach_thread_np(pthread_self()), + kern_return_t res = thread_policy_get(pthread_mach_thread_np(thread), THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t) & theTCPolicy, &count, @@ -187,7 +187,7 @@ int JackMachThread::AcquireRealTimeImp(pthread_t thread, UInt64 period, UInt64 c UInt64 int_period; UInt64 int_computation; UInt64 int_constraint; - GetParams(&int_period, &int_computation, &int_constraint); + GetParams(thread, &int_period, &int_computation, &int_constraint); return 0; } diff --git a/macosx/JackMachThread.h b/macosx/JackMachThread.h index 4dc8d509..e8105803 100644 --- a/macosx/JackMachThread.h +++ b/macosx/JackMachThread.h @@ -109,7 +109,7 @@ class SERVER_EXPORT JackMachThread : public JackPosixThread int AcquireRealTime(int priority); int DropRealTime(); void SetParams(UInt64 period, UInt64 computation, UInt64 constraint); - static int GetParams(UInt64* period, UInt64* computation, UInt64* constraint); + static int GetParams(pthread_t thread, UInt64* period, UInt64* computation, UInt64* constraint); static int SetThreadToPriority(pthread_t thread, UInt32 inPriority, Boolean inIsFixed, UInt64 period, UInt64 computation, UInt64 constraint); static int AcquireRealTimeImp(pthread_t thread, UInt64 period, UInt64 computation, UInt64 constraint); diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index e0839f84..d6c37727 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -10846,7 +10846,7 @@ CoreFoundation, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midiseq; + PRODUCT_NAME = jack_showtime; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; diff --git a/macosx/coreaudio/JackCoreAudioAdapter.cpp b/macosx/coreaudio/JackCoreAudioAdapter.cpp index a0222cab..60f187cb 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.cpp +++ b/macosx/coreaudio/JackCoreAudioAdapter.cpp @@ -21,6 +21,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackError.h" #include +#include + namespace Jack { diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 6c2222e7..d0815cd1 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -218,7 +218,12 @@ OSStatus JackCoreAudioDriver::MeasureCallback(AudioDeviceID inDevice, AudioDeviceStop(driver->fDeviceID, MeasureCallback); jack_log("JackCoreAudioDriver::MeasureCallback called"); - JackMachThread::GetParams(&driver->fEngineControl->fPeriod, &driver->fEngineControl->fComputation, &driver->fEngineControl->fConstraint); + JackMachThread::GetParams(pthread_self(), &driver->fEngineControl->fPeriod, &driver->fEngineControl->fComputation, &driver->fEngineControl->fConstraint); + + if (driver->fComputationGrain > 0) { + jack_log("JackCoreAudioDriver::MeasureCallback : RT thread computation setup to %ld percent of period", int(driver->fComputationGrain * 100)); + driver->fEngineControl->fComputation = driver->fEngineControl->fPeriod * driver->fComputationGrain; + } // Setup threadded based log function set_threaded_log_function(); @@ -441,7 +446,7 @@ 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), fState(false), fIOUsage(1.f) + : JackAudioDriver(name, alias, engine, table), fJackInputData(NULL), fDriverOutputData(NULL), fState(false), fIOUsage(1.f),fComputationGrain(-1.f) {} JackCoreAudioDriver::~JackCoreAudioDriver() @@ -1103,7 +1108,8 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, const char* playback_driver_uid, jack_nframes_t capture_latency, jack_nframes_t playback_latency, - int async_output_latency) + int async_output_latency, + int computation_grain) { int in_nChannels = 0; int out_nChannels = 0; @@ -1120,7 +1126,8 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, strcpy(fPlaybackUID, playback_driver_uid); fCaptureLatency = capture_latency; fPlaybackLatency = playback_latency; - fIOUsage = float(async_output_latency)/ 100.f; + fIOUsage = float(async_output_latency) / 100.f; + fComputationGrain = float(computation_grain) / 100.f; if (SetupDevices(capture_driver_uid, playback_driver_uid, capture_driver_name, playback_driver_name) < 0) return -1; @@ -1259,12 +1266,13 @@ int JackCoreAudioDriver::Attach() // Monitor ports if (fWithMonitorPorts) { jack_log("Create monitor port "); - snprintf(name, sizeof(name) - 1, "%s:%s:monitor_%u", fAliasName, fPlaybackDriverName, i + 1); + snprintf(name, sizeof(name) - 1, "%s:monitor_%u", fClientControl.fName, i + 1); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("Cannot register monitor port for %s", name); return -1; } else { port = fGraphManager->GetPort(port_index); + port->SetAlias(alias); port->SetLatency(fEngineControl->fBufferSize); fMonitorPortList[i] = port_index; } @@ -1364,7 +1372,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 = 14; + desc->nparams = 15; desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); i = 0; @@ -1478,6 +1486,14 @@ extern "C" desc->params[i].value.i = 100; strcpy(desc->params[i].short_desc, "Extra output latency in aynchronous 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'; + desc->params[i].type = JackDriverParamUInt; + 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); return desc; } @@ -1498,6 +1514,7 @@ extern "C" jack_nframes_t systemic_input_latency = 0; jack_nframes_t systemic_output_latency = 0; int async_output_latency = 100; + int computation_grain = -1; for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t *) node->data; @@ -1567,6 +1584,10 @@ extern "C" case 'L': async_output_latency = param->value.ui; break; + + case 'G': + computation_grain = param->value.ui; + break; } } @@ -1578,7 +1599,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, - playback_driver_uid, systemic_input_latency, systemic_output_latency, async_output_latency) == 0) { + playback_driver_uid, systemic_input_latency, systemic_output_latency, async_output_latency, computation_grain) == 0) { return driver; } else { delete driver; diff --git a/macosx/coreaudio/JackCoreAudioDriver.h b/macosx/coreaudio/JackCoreAudioDriver.h index 62de09fb..fb680b3f 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.h +++ b/macosx/coreaudio/JackCoreAudioDriver.h @@ -72,6 +72,7 @@ class JackCoreAudioDriver : public JackAudioDriver bool fMonitor; float fIOUsage; + float fComputationGrain; /* #ifdef MAC_OS_X_VERSION_10_5 @@ -164,7 +165,8 @@ class JackCoreAudioDriver : public JackAudioDriver const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency, - int async_output_latency); + int async_output_latency, + int computation_grain); int Close(); int Attach(); diff --git a/solaris/oss/JackBoomerDriver.cpp b/solaris/oss/JackBoomerDriver.cpp index 96dc0a6a..25056326 100644 --- a/solaris/oss/JackBoomerDriver.cpp +++ b/solaris/oss/JackBoomerDriver.cpp @@ -68,51 +68,51 @@ int gCycleWriteCount = 0; inline int int2pow2(int x) { int r = 0; while ((1 << r) < x) r++; return r; } -static inline void CopyAndConvertIn(jack_sample_t *dst, void *src, size_t nframes, int channel, int chcount, int bits) +static inline void CopyAndConvertIn(jack_sample_t *dst, void *src, size_t nframes, int channel, int byte_skip, int bits) { switch (bits) { case 16: { signed short *s16src = (signed short*)src; s16src += channel; - sample_move_dS_s16(dst, (char*)s16src, nframes, chcount<<1); + sample_move_dS_s16(dst, (char*)s16src, nframes, byte_skip); break; } case 24: { - signed short *s32src = (signed short*)src; + signed int *s32src = (signed int*)src; s32src += channel; - sample_move_dS_s24(dst, (char*)s32src, nframes, chcount<<2); + sample_move_dS_s24(dst, (char*)s32src, nframes, byte_skip); break; } case 32: { - signed short *s32src = (signed short*)src; + signed int *s32src = (signed int*)src; s32src += channel; - sample_move_dS_s32u24(dst, (char*)s32src, nframes, chcount<<2); + sample_move_dS_s32u24(dst, (char*)s32src, nframes, byte_skip); break; } } } -static inline void CopyAndConvertOut(void *dst, jack_sample_t *src, size_t nframes, int channel, int chcount, int bits) +static inline void CopyAndConvertOut(void *dst, jack_sample_t *src, size_t nframes, int channel, int byte_skip, int bits) { switch (bits) { case 16: { signed short *s16dst = (signed short*)dst; s16dst += channel; - sample_move_d16_sS((char*)s16dst, src, nframes, chcount<<1, NULL); // No dithering for now... + sample_move_d16_sS((char*)s16dst, src, nframes, byte_skip, NULL); // No dithering for now... break; } case 24: { signed int *s32dst = (signed int*)dst; s32dst += channel; - sample_move_d24_sS((char*)s32dst, src, nframes, chcount<<2, NULL); // No dithering for now... + sample_move_d24_sS((char*)s32dst, src, nframes, byte_skip, NULL); break; } case 32: { signed int *s32dst = (signed int*)dst; s32dst += channel; - sample_move_d32u24_sS((char*)s32dst, src, nframes, chcount<<2, NULL); + sample_move_d32u24_sS((char*)s32dst, src, nframes, byte_skip, NULL); break; } } @@ -124,16 +124,16 @@ void JackBoomerDriver::SetSampleFormat() case 24: /* native-endian LSB aligned 24-bits in 32-bits integer */ fSampleFormat = AFMT_S24_NE; - fSampleSize = sizeof(int); + fSampleSize = 4; break; case 32: /* native-endian 32-bit integer */ fSampleFormat = AFMT_S32_NE; - fSampleSize = sizeof(int); + fSampleSize = 4; break; case 16: /* native-endian 16-bit integer */ default: fSampleFormat = AFMT_S16_NE; - fSampleSize = sizeof(short); + fSampleSize = 2; break; } } @@ -171,6 +171,7 @@ void JackBoomerDriver::DisplayDeviceInfo() } else { jack_info("output space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", info.fragments, info.fragstotal, info.fragsize, info.bytes); + fFragmentSize = info.fragsize; } if (ioctl(fOutFD, SNDCTL_DSP_GETCAPS, &cap) == -1) { @@ -233,7 +234,8 @@ void JackBoomerDriver::DisplayDeviceInfo() JackBoomerDriver::JackBoomerDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) : JackAudioDriver(name, alias, engine, table), fInFD(-1), fOutFD(-1), fBits(0), - fSampleFormat(0), fNperiods(0), fRWMode(0), fExcl(false), fIgnoreHW(true), + fSampleFormat(0), fNperiods(0), fSampleSize(0), fFragmentSize(0), + fRWMode(0), fExcl(false), fSyncIO(false), fInputBufferSize(0), fOutputBufferSize(0), fInputBuffer(NULL), fOutputBuffer(NULL), fInputThread(&fInputHandler), fOutputThread(&fOutputHandler), @@ -401,15 +403,8 @@ int JackBoomerDriver::Open(jack_nframes_t nframes, const char* playback_driver_uid, jack_nframes_t capture_latency, jack_nframes_t playback_latency, - int bits, - bool ignorehwbuf) + int bits, bool syncio) { - - if (playing && !capturing) { - jack_error("Playback only mode is not yet supported, use duplex instead"); - return -1; - } - // Generic JackAudioDriver Open if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) { @@ -424,10 +419,10 @@ int JackBoomerDriver::Open(jack_nframes_t nframes, fRWMode |= ((capturing) ? kRead : 0); fRWMode |= ((playing) ? kWrite : 0); fBits = bits; - fIgnoreHW = ignorehwbuf; - fNperiods = user_nperiods; fExcl = excl; - + fNperiods = (user_nperiods == 0) ? 1 : user_nperiods ; + fSyncIO = syncio; + #ifdef JACK_MONITOR // Force memory page in memset(&gCycleTable, 0, sizeof(gCycleTable)); @@ -514,12 +509,12 @@ int JackBoomerDriver::OpenAux() void JackBoomerDriver::CloseAux() { - if (fRWMode & kRead && fInFD > 0) { + if (fRWMode & kRead && fInFD >= 0) { close(fInFD); fInFD = -1; } - if (fRWMode & kWrite && fOutFD > 0) { + if (fRWMode & kWrite && fOutFD >= 0) { close(fOutFD); fOutFD = -1; } @@ -538,8 +533,61 @@ int JackBoomerDriver::Start() jack_log("JackBoomerDriver::Start"); JackAudioDriver::Start(); + // Input/output synchronisation + if (fInFD >= 0 && fOutFD >= 0 && fSyncIO) { + + jack_log("JackBoomerDriver::Start sync input/output"); + + // Create and fill synch group + int id; + oss_syncgroup group; + group.id = 0; + + group.mode = PCM_ENABLE_INPUT; + if (ioctl(fInFD, SNDCTL_DSP_SYNCGROUP, &group) == -1) + jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCGROUP : %s@%i, errno = %d", __FILE__, __LINE__, errno); + + group.mode = PCM_ENABLE_OUTPUT; + if (ioctl(fOutFD, SNDCTL_DSP_SYNCGROUP, &group) == -1) + jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCGROUP : %s@%i, errno = %d", __FILE__, __LINE__, errno); + + // Prefill output buffer : 2 fragments of silence as described in http://manuals.opensound.com/developer/synctest.c.html#LOC6 + char* silence_buf = (char*)malloc(fFragmentSize); + memset(silence_buf, 0, fFragmentSize); + + jack_log ("JackBoomerDriver::Start prefill size = %d", fFragmentSize); + + for (int i = 0; i < 2; i++) { + ssize_t count = ::write(fOutFD, silence_buf, fFragmentSize); + if (count < (int)fFragmentSize) { + jack_error("JackBoomerDriver::Start error bytes written = %ld", count); + } + } + + free(silence_buf); + + // Start input/output in sync + id = group.id; + + if (ioctl(fInFD, SNDCTL_DSP_SYNCSTART, &id) == -1) + jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCSTART : %s@%i, errno = %d", __FILE__, __LINE__, errno); + + } else if (fOutFD >= 0) { + + // Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html + memset(fOutputBuffer, 0, fOutputBufferSize); + + // Prefill ouput buffer + for (int i = 0; i < fNperiods; i++) { + ssize_t count = ::write(fOutFD, fOutputBuffer, fOutputBufferSize); + if (count < (int)fOutputBufferSize) { + jack_error("JackBoomerDriver::Start error bytes written = %ld", count); + } + } + } + // Start input thread only when needed - if (fInFD > 0) { + if (fInFD >= 0) { if (fInputThread.StartSync() < 0) { jack_error("Cannot start input thread"); return -1; @@ -547,7 +595,7 @@ int JackBoomerDriver::Start() } // Start output thread only when needed - if (fOutFD > 0) { + if (fOutFD >= 0) { if (fOutputThread.StartSync() < 0) { jack_error("Cannot start output thread"); return -1; @@ -560,38 +608,18 @@ int JackBoomerDriver::Start() int JackBoomerDriver::Stop() { // Stop input thread only when needed - if (fInFD > 0) { + if (fInFD >= 0) { fInputThread.Kill(); } // Stop output thread only when needed - if (fOutFD > 0) { + if (fOutFD >= 0) { fOutputThread.Kill(); } return 0; } -int JackBoomerDriver::Read() -{ -/* - // Keep begin cycle time - JackDriver::CycleTakeBeginTime(); -*/ - - return 0; -} - -int JackBoomerDriver::Write() -{ -/* - // Keep begin cycle time - JackDriver::CycleTakeEndTime(); -*/ - - return 0; -} - bool JackBoomerDriver::JackBoomerDriverInput::Init() { if (fDriver->IsRealTime()) { @@ -602,18 +630,13 @@ bool JackBoomerDriver::JackBoomerDriverInput::Init() set_threaded_log_function(); } } - + return true; } bool JackBoomerDriver::JackBoomerDriverInput::Execute() { - if (fDriver->fInFD < 0) { - // Keep begin cycle time - fDriver->CycleTakeBeginTime(); - return true; - } - + #ifdef JACK_MONITOR gCycleTable.fTable[gCycleReadCount].fBeforeRead = GetMicroSeconds(); #endif @@ -651,7 +674,12 @@ bool JackBoomerDriver::JackBoomerDriverInput::Execute() fDriver->CycleTakeBeginTime(); for (int i = 0; i < fDriver->fCaptureChannels; i++) { if (fDriver->fGraphManager->GetConnectionsNum(fDriver->fCapturePortList[i]) > 0) { - CopyAndConvertIn(fDriver->GetInputBuffer(i), fDriver->fInputBuffer, fDriver->fEngineControl->fBufferSize, i, fDriver->fCaptureChannels, fDriver->fBits); + CopyAndConvertIn(fDriver->GetInputBuffer(i), + fDriver->fInputBuffer, + fDriver->fEngineControl->fBufferSize, + i, + fDriver->fCaptureChannels * fDriver->fSampleSize, + fDriver->fBits); } } @@ -661,7 +689,13 @@ bool JackBoomerDriver::JackBoomerDriverInput::Execute() #endif } - fDriver->SynchronizeRead(); + // Duplex : sync with write thread + if (fDriver->fInFD >= 0 && fDriver->fOutFD >= 0) { + fDriver->SynchronizeRead(); + } else { + // Otherwise direct process + fDriver->Process(); + } return true; } @@ -675,27 +709,14 @@ bool JackBoomerDriver::JackBoomerDriverOutput::Init() set_threaded_log_function(); } } - - // Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html - memset(fDriver->fOutputBuffer, 0, fDriver->fOutputBufferSize); - - // Prefill ouput buffer - if (fDriver->fOutFD > 0) { - for (int i = 0; i < fDriver->fNperiods; i++) { - ssize_t count = ::write(fDriver->fOutFD, fDriver->fOutputBuffer, fDriver->fOutputBufferSize); - if (count < (int)fDriver->fOutputBufferSize) { - jack_error("JackBoomerDriver::Write error bytes written = %ld", count); - } - } - - int delay; - if (ioctl(fDriver->fOutFD, SNDCTL_DSP_GETODELAY, &delay) == -1) { - jack_error("JackBoomerDriver::Write error get out delay : %s@%i, errno = %d", __FILE__, __LINE__, errno); - } - - delay /= fDriver->fSampleSize * fDriver->fPlaybackChannels; - jack_info("JackBoomerDriver::Write output latency frames = %ld", delay); + + int delay; + if (ioctl(fDriver->fOutFD, SNDCTL_DSP_GETODELAY, &delay) == -1) { + jack_error("JackBoomerDriverOutput::Init error get out delay : %s@%i, errno = %d", __FILE__, __LINE__, errno); } + + delay /= fDriver->fSampleSize * fDriver->fPlaybackChannels; + jack_info("JackBoomerDriverOutput::Init output latency frames = %ld", delay); return true; } @@ -710,7 +731,12 @@ bool JackBoomerDriver::JackBoomerDriverOutput::Execute() for (int i = 0; i < fDriver->fPlaybackChannels; i++) { if (fDriver->fGraphManager->GetConnectionsNum(fDriver->fPlaybackPortList[i]) > 0) { - CopyAndConvertOut(fDriver->fOutputBuffer, fDriver->GetOutputBuffer(i), fDriver->fEngineControl->fBufferSize, i, fDriver->fPlaybackChannels, fDriver->fBits); + CopyAndConvertOut(fDriver->fOutputBuffer, + fDriver->GetOutputBuffer(i), + fDriver->fEngineControl->fBufferSize, + i, + fDriver->fPlaybackChannels * fDriver->fSampleSize, + fDriver->fBits); } } @@ -748,7 +774,14 @@ bool JackBoomerDriver::JackBoomerDriverOutput::Execute() jack_error("JackBoomerDriverOutput::Execute error bytes written = %ld", count); } - fDriver->SynchronizeWrite(); + // Duplex : sync with read thread + if (fDriver->fInFD >= 0 && fDriver->fOutFD >= 0) { + fDriver->SynchronizeWrite(); + } else { + // Otherwise direct process + fDriver->CycleTakeBeginTime(); + fDriver->Process(); + } return true; } @@ -839,7 +872,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() desc->params[i].value.ui = OSS_DRIVER_DEF_OUTS; strcpy(desc->params[i].short_desc, "Playback channels"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); - + i++; strcpy(desc->params[i].name, "excl"); desc->params[i].character = 'e'; @@ -871,15 +904,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() strcpy(desc->params[i].value.str, OSS_DRIVER_DEF_DEV); strcpy(desc->params[i].short_desc, "OSS device name"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); - - i++; - strcpy(desc->params[i].name, "ignorehwbuf"); - desc->params[i].character = 'b'; - desc->params[i].type = JackDriverParamBool; - desc->params[i].value.i = false; - strcpy(desc->params[i].short_desc, "Ignore hardware period size"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); - + i++; strcpy(desc->params[i].name, "input-latency"); desc->params[i].character = 'I'; @@ -896,6 +921,14 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() strcpy(desc->params[i].short_desc, "Extra output latency"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + i++; + strcpy(desc->params[i].name, "sync-io"); + desc->params[i].character = 'S'; + desc->params[i].type = JackDriverParamBool; + desc->params[i].value.i = false; + strcpy(desc->params[i].short_desc, "In duplex mode, synchronize input and output"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + return desc; } @@ -912,10 +945,10 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine int chan_out = 0; bool monitor = false; bool excl = false; + bool syncio = false; unsigned int nperiods = OSS_DRIVER_DEF_NPERIODS; const JSList *node; const jack_driver_param_t *param; - bool ignorehwbuf = false; jack_nframes_t systemic_input_latency = 0; jack_nframes_t systemic_output_latency = 0; @@ -967,11 +1000,7 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine playback_pcm_name = strdup (param->value.str); capture_pcm_name = strdup (param->value.str); break; - - case 'b': - ignorehwbuf = true; - break; - + case 'e': excl = true; break; @@ -983,6 +1012,10 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine case 'O': systemic_output_latency = param->value.ui; break; + + case 'S': + syncio = true; + break; } } @@ -995,8 +1028,8 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine Jack::JackBoomerDriver* boomer_driver = new Jack::JackBoomerDriver("system", "boomer", engine, table); // Special open for Boomer driver... - if (boomer_driver->Open(frames_per_interrupt, nperiods, srate, capture, playback, chan_in, chan_out, - excl, monitor, capture_pcm_name, playback_pcm_name, systemic_input_latency, systemic_output_latency, bits, ignorehwbuf) == 0) { + if (boomer_driver->Open(frames_per_interrupt, nperiods, srate, capture, playback, chan_in, chan_out, excl, + monitor, capture_pcm_name, playback_pcm_name, systemic_input_latency, systemic_output_latency, bits, syncio) == 0) { return boomer_driver; } else { delete boomer_driver; // Delete the driver diff --git a/solaris/oss/JackBoomerDriver.h b/solaris/oss/JackBoomerDriver.h index f688c7e1..61fc5c50 100644 --- a/solaris/oss/JackBoomerDriver.h +++ b/solaris/oss/JackBoomerDriver.h @@ -91,10 +91,11 @@ class JackBoomerDriver : public JackAudioDriver int fSampleFormat; int fNperiods; unsigned int fSampleSize; + unsigned int fFragmentSize; int fRWMode; bool fExcl; - bool fIgnoreHW; - + bool fSyncIO; + unsigned int fInputBufferSize; unsigned int fOutputBufferSize; @@ -131,23 +132,19 @@ class JackBoomerDriver : public JackAudioDriver bool playing, int chan_in, int chan_out, - bool vmix, + bool excl, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency, - int bits, - bool ignorehwbuf); + int bits, bool syncio); int Close(); int Start(); int Stop(); - int Read(); - int Write(); - // BufferSize can be changed bool IsFixedBufferSize() { diff --git a/solaris/oss/JackOSSAdapter.cpp b/solaris/oss/JackOSSAdapter.cpp index 7bdfec96..de3fe89f 100644 --- a/solaris/oss/JackOSSAdapter.cpp +++ b/solaris/oss/JackOSSAdapter.cpp @@ -44,13 +44,13 @@ static inline void CopyAndConvertIn(jack_sample_t *dst, void *src, size_t nframe break; } case 24: { - signed short *s32src = (signed short*)src; + signed int *s32src = (signed int*)src; s32src += channel; sample_move_dS_s24(dst, (char*)s32src, nframes, chcount<<2); break; } case 32: { - signed short *s32src = (signed short*)src; + signed int *s32src = (signed int*)src; s32src += channel; sample_move_dS_s32u24(dst, (char*)s32src, nframes, chcount<<2); break; @@ -309,8 +309,6 @@ int JackOSSAdapter::OpenInput() return -1; } -jack_log("JackOSSAdapter::OpenInput input fInFD = %d", fInFD); - if (fExcl) { if (ioctl(fInFD, SNDCTL_DSP_COOKEDMODE, &flags) == -1) { jack_error("JackOSSAdapter::OpenInput failed to set cooked mode : %s@%i, errno = %d", __FILE__, __LINE__, errno); @@ -318,8 +316,6 @@ jack_log("JackOSSAdapter::OpenInput input fInFD = %d", fInFD); } } -printf("fAdaptedBufferSize %d %d %d %d %s\n", fExcl, fAdaptedBufferSize, fSampleSize, fCaptureChannels, fCaptureDriverName); - gFragFormat = (2 << 16) + int2pow2(fAdaptedBufferSize * fSampleSize * fCaptureChannels); if (ioctl(fInFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { jack_error("JackOSSAdapter::OpenInput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); @@ -406,9 +402,6 @@ int JackOSSAdapter::OpenOutput() } } -printf("fAdaptedBufferSize %d %d %d %d %s\n", fExcl, fAdaptedBufferSize, fSampleSize, fPlaybackChannels, fPlaybackDriverName); - - gFragFormat = (2 << 16) + int2pow2(fAdaptedBufferSize * fSampleSize * fPlaybackChannels); if (ioctl(fOutFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { jack_error("JackOSSAdapter::OpenOutput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); diff --git a/solaris/oss/JackOSSDriver.cpp b/solaris/oss/JackOSSDriver.cpp index f4d8507c..af0ed43b 100644 --- a/solaris/oss/JackOSSDriver.cpp +++ b/solaris/oss/JackOSSDriver.cpp @@ -78,13 +78,13 @@ static inline void CopyAndConvertIn(jack_sample_t *dst, void *src, size_t nframe break; } case 24: { - signed short *s32src = (signed short*)src; + signed int *s32src = (signed int*)src; s32src += channel; sample_move_dS_s24(dst, (char*)s32src, nframes, chcount<<2); break; } case 32: { - signed short *s32src = (signed short*)src; + signed int *s32src = (signed int*)src; s32src += channel; sample_move_dS_s32u24(dst, (char*)s32src, nframes, chcount<<2); break; diff --git a/windows/jackaudioadapter.rc b/windows/jackaudioadapter.rc index 31718f12..02d66940 100644 --- a/windows/jackaudioadapter.rc +++ b/windows/jackaudioadapter.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,3,0 - PRODUCTVERSION 1,9,3,0 + FILEVERSION 1,9,4,0 + PRODUCTVERSION 1,9,4,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Audio Adapter for Windows\0" - VALUE "FileVersion", "1, 9, 3, 0\0" + VALUE "FileVersion", "1, 9, 4, 0\0" VALUE "InternalName", "audioadapter\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "audioadapter.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "audioadapter\0" - VALUE "ProductVersion", "1, 9, 3, 0\0" + VALUE "ProductVersion", "1, 9, 4, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackd.rc b/windows/jackd.rc index 0208994a..5f909413 100644 --- a/windows/jackd.rc +++ b/windows/jackd.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,3,0 - PRODUCTVERSION 1,9,3,0 + FILEVERSION 1,9,4,0 + PRODUCTVERSION 1,9,4,0 FILEOS VOS_UNKNOWN FILETYPE VFT_APP BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack server for Windows\0" - VALUE "FileVersion", "1, 9, 3, 0\0" + VALUE "FileVersion", "1, 9, 4, 0\0" VALUE "InternalName", "jackd\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jackd.exe\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jackd\0" - VALUE "ProductVersion", "1, 9, 3, 0\0" + VALUE "ProductVersion", "1, 9, 4, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetadapter.rc b/windows/jacknetadapter.rc index cdfb78e9..62a7a3c0 100644 --- a/windows/jacknetadapter.rc +++ b/windows/jacknetadapter.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,3,0 - PRODUCTVERSION 1,9,3,0 + FILEVERSION 1,9,4,0 + PRODUCTVERSION 1,9,4,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Adapter for Windows\0" - VALUE "FileVersion", "1, 9, 3, 0\0" + VALUE "FileVersion", "1, 9, 4, 0\0" VALUE "InternalName", "netadapter\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "netadapter.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "netadapter\0" - VALUE "ProductVersion", "1, 9, 3, 0\0" + VALUE "ProductVersion", "1, 9, 4, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetdriver.rc b/windows/jacknetdriver.rc index 40e7ab94..8a7a1806 100644 --- a/windows/jacknetdriver.rc +++ b/windows/jacknetdriver.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,3,0 - PRODUCTVERSION 1,9,3,0 + FILEVERSION 1,9,4,0 + PRODUCTVERSION 1,9,4,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Driver for Windows\0" - VALUE "FileVersion", "1, 9, 3, 0\0" + VALUE "FileVersion", "1, 9, 4, 0\0" VALUE "InternalName", "jack_netdriver\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_netdriver.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_netdriver\0" - VALUE "ProductVersion", "1, 9, 3, 0\0" + VALUE "ProductVersion", "1, 9, 4, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetmanager.rc b/windows/jacknetmanager.rc index b9c35e01..ffc1dde8 100644 --- a/windows/jacknetmanager.rc +++ b/windows/jacknetmanager.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,3,0 - PRODUCTVERSION 1,9,3,0 + FILEVERSION 1,9,4,0 + PRODUCTVERSION 1,9,4,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Manager for Windows\0" - VALUE "FileVersion", "1, 9, 3, 0\0" + VALUE "FileVersion", "1, 9, 4, 0\0" VALUE "InternalName", "netmanager\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "netmanager.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "netmanager\0" - VALUE "ProductVersion", "1, 9, 3, 0\0" + VALUE "ProductVersion", "1, 9, 4, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackportaudio.rc b/windows/jackportaudio.rc index 03ad53fd..7e8429a0 100644 --- a/windows/jackportaudio.rc +++ b/windows/jackportaudio.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,3,0 - PRODUCTVERSION 1,9,3,0 + FILEVERSION 1,9,4,0 + PRODUCTVERSION 1,9,4,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp PortAudio Driver for Windows\0" - VALUE "FileVersion", "1, 9, 3, 0\0" + VALUE "FileVersion", "1, 9, 4, 0\0" VALUE "InternalName", "jack_portaudio\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_portaudio.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_portaudio\0" - VALUE "ProductVersion", "1, 9, 3, 0\0" + VALUE "ProductVersion", "1, 9, 4, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackwinmme.rc b/windows/jackwinmme.rc index 57187d6c..5a38e821 100644 --- a/windows/jackwinmme.rc +++ b/windows/jackwinmme.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,3,0 - PRODUCTVERSION 1,9,3,0 + FILEVERSION 1,9,4,0 + PRODUCTVERSION 1,9,4,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp WinMMEo Driver for Windows\0" - VALUE "FileVersion", "1, 9, 3, 0\0" + VALUE "FileVersion", "1, 9, 4, 0\0" VALUE "InternalName", "jack_portaudio\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_winmme.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_winmme\0" - VALUE "ProductVersion", "1, 9, 3, 0\0" + VALUE "ProductVersion", "1, 9, 4, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/libjack.rc b/windows/libjack.rc index 200ad086..b4e79369 100644 --- a/windows/libjack.rc +++ b/windows/libjack.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,3,0 - PRODUCTVERSION 1,9,3,0 + FILEVERSION 1,9,4,0 + PRODUCTVERSION 1,9,4,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack client library for Windows\0" - VALUE "FileVersion", "1, 9, 3, 0\0" + VALUE "FileVersion", "1, 9, 4, 0\0" VALUE "InternalName", "libjack\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjack.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjack\0" - VALUE "ProductVersion", "1, 9, 3, 0\0" + VALUE "ProductVersion", "1, 9, 4, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/libjackserver.rc b/windows/libjackserver.rc index 3b38efcc..dc0bbb6b 100644 --- a/windows/libjackserver.rc +++ b/windows/libjackserver.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,3,0 - PRODUCTVERSION 1,9,3,0 + FILEVERSION 1,9,4,0 + PRODUCTVERSION 1,9,4,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack server library for Windows\0" - VALUE "FileVersion", "1, 9, 3, 0\0" + VALUE "FileVersion", "1, 9, 4, 0\0" VALUE "InternalName", "libjackserver\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjackserver.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjackserver\0" - VALUE "ProductVersion", "1, 9, 3, 0\0" + VALUE "ProductVersion", "1, 9, 4, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/resource.rc b/windows/resource.rc index 0ea97e52..51ba4994 100644 --- a/windows/resource.rc +++ b/windows/resource.rc @@ -14,8 +14,8 @@ LANGUAGE LANG_FRENCH, SUBLANG_FRENCH #ifndef _MAC VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,9,3,0 - PRODUCTVERSION 1,9,3,0 + FILEVERSION 1,9,4,0 + PRODUCTVERSION 1,9,4,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -33,14 +33,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp for Windows\0" - VALUE "FileVersion", "1, 9, 3, 0\0" + VALUE "FileVersion", "1, 9, 4, 0\0" VALUE "InternalName", "libjackmp\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjackmp.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjackmp\0" - VALUE "ProductVersion", "1, 9, 3, 0\0" + VALUE "ProductVersion", "1, 9, 4, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/wscript b/wscript index 917208d0..f5b69855 100644 --- a/wscript +++ b/wscript @@ -11,7 +11,7 @@ import Task import re import Logs -VERSION='1.9.3' +VERSION='1.9.4' APPNAME='jack' JACK_API_VERSION = '0.1.0' From 224c41eb59c0a8d547bd7e322b0e1185a1558cde Mon Sep 17 00:00:00 2001 From: sletz Date: Fri, 30 Oct 2009 14:47:29 +0000 Subject: [PATCH 023/472] rebase from trunk 3638:3684 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3685 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 91 ++- common/JackAPI.cpp | 16 + common/JackAudioAdapterInterface.cpp | 12 +- common/JackChannel.h | 2 +- common/JackClient.cpp | 37 +- common/JackClient.h | 7 +- common/JackClientInterface.h | 2 +- common/JackConstants.h | 3 +- common/JackDebugClient.cpp | 10 +- common/JackDebugClient.h | 3 +- common/JackDriver.cpp | 21 +- common/JackDriver.h | 3 +- common/JackDriverLoader.cpp | 2 +- common/JackEngine.cpp | 51 +- common/JackEngine.h | 8 +- common/JackError.cpp | 4 +- common/JackError.h | 2 - common/JackExternalClient.cpp | 4 +- common/JackExternalClient.h | 2 +- common/JackGlobals.cpp | 2 + common/JackGlobals.h | 4 +- common/JackInternalClientChannel.h | 4 +- common/JackLibClient.cpp | 4 +- common/JackLibClient.h | 2 +- common/JackLockedEngine.h | 10 +- common/JackMessageBuffer.cpp | 17 +- common/JackMessageBuffer.h | 5 +- common/JackNetDriver.cpp | 32 +- common/JackNetDriver.h | 7 +- common/JackNetManager.cpp | 7 +- common/JackNetTool.cpp | 2 + common/JackNotification.h | 1 + common/JackRequest.h | 16 +- common/JackServer.cpp | 13 +- common/JackServerGlobals.cpp | 1 + common/JackServerGlobals.h | 3 +- common/JackThreadedDriver.cpp | 4 +- common/JackThreadedDriver.h | 2 +- common/Jackdmp.cpp | 30 +- common/jack/jack.h | 23 +- common/jack/types.h | 24 +- common/memops.c | 29 +- dbus/controller_iface_control.c | 4 +- macosx/JackMacEngineRPC.cpp | 10 +- macosx/JackMacLibClientRPC.cpp | 12 +- macosx/JackMachClientChannel.cpp | 4 +- macosx/JackMachClientChannel.h | 2 +- macosx/JackMachNotifyChannel.cpp | 6 +- macosx/JackMachNotifyChannel.h | 2 +- macosx/JackMachServerChannel.cpp | 20 +- macosx/JackMachServerChannel.h | 5 +- macosx/Jackdmp.xcodeproj/project.pbxproj | 327 +++-------- macosx/RPC/JackRPCClient.defs | 6 +- macosx/RPC/JackRPCClient.h | 6 +- macosx/RPC/JackRPCClientServer.c | 214 ++++++- macosx/RPC/JackRPCClientUser.c | 41 +- macosx/RPC/JackRPCEngine.defs | 6 +- macosx/RPC/JackRPCEngine.h | 2 +- macosx/RPC/JackRPCEngineServer.c | 221 +++++-- macosx/RPC/JackRPCEngineUser.c | 74 +-- macosx/RPC/Jackdefs.h | 3 +- macosx/coreaudio/JackCoreAudioAdapter.cpp | 620 ++++++++++++++------ macosx/coreaudio/JackCoreAudioAdapter.h | 21 +- macosx/coreaudio/JackCoreAudioDriver.cpp | 675 ++++++++++++++-------- macosx/coreaudio/JackCoreAudioDriver.h | 28 +- posix/JackPosixMutex.h | 41 ++ posix/JackPosixThread.cpp | 4 +- posix/JackProcessSync.cpp | 25 +- posix/JackProcessSync.h | 6 +- posix/JackSocketClientChannel.cpp | 6 +- posix/JackSocketClientChannel.h | 2 +- posix/JackSocketNotifyChannel.cpp | 4 +- posix/JackSocketNotifyChannel.h | 2 +- posix/JackSocketServerChannel.cpp | 38 +- posix/JackSocketServerChannel.h | 6 +- tests/test.cpp | 7 + windows/JackWinNamedPipeClientChannel.cpp | 6 +- windows/JackWinNamedPipeClientChannel.h | 2 +- windows/JackWinNamedPipeNotifyChannel.cpp | 4 +- windows/JackWinNamedPipeNotifyChannel.h | 2 +- windows/JackWinNamedPipeServerChannel.cpp | 57 +- windows/JackWinNamedPipeServerChannel.h | 12 +- windows/Setup/src/README | 10 +- wscript | 2 +- 84 files changed, 2001 insertions(+), 1066 deletions(-) diff --git a/ChangeLog b/ChangeLog index c6f6ec3f..f5aed4c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,35 +25,98 @@ Paul Davis Jackdmp changes log --------------------------- -2009-08-28 Stephane Letz +2009-10-30 Stephane Letz - * Correct monitor port naming in JackAudioDriver and JackCoreAudioDriver. - * Big endian bug fix in memops.c (http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=5;filename=11_be24bit.patch;att=1;bug=486308) + * In JackCoreAudioDriver, improve management of input/output channels: -1 is now used internally to indicate a wanted max value. + * In JackCoreAudioDriver::OpenAUHAL, correct stream format setup and cleanup. + * Correct crash bug in JackAudioAdapterInterface when not input is used in adapter (temporary fix...) + * Sync JackCoreAudioAdapter code on JackCoreAudioDriver one. + * JACK_SCHED_POLICY switched to SCHED_FIFO. -2009-07-31 Stephane Letz +2009-10-29 Stephane Letz - * Use SNDCTL_DSP_SYNCGROUP/SNDCTL_DSP_SYNCSTART API to synchronize input and output in Solaris boomer backend. + * In JackCoreAudioDriver::Start, wait for the audio driver to effectively start (use the MeasureCallback). +2009-10-28 Stephane Letz + + * In JackCoreAudioDriver, force the SR value to the wanted one *before* creating aggregate device (otherwise creation will fail). + * In JackCoreAudioDriver, better cleanup of AD when intermediate open failure. -2009-07-29 Stephane Letz +2009-10-27 Stephane Letz - * Add a -G parameter in CoreAudio backend (the computation value in RT thread expressed as percent of period). + * Dynamic system version detection in JackCoreAudioDriver to either create public or private aggregate device. -2009-07-28 Stephane Letz +2009-10-26 Stephane Letz - * Fix CopyAndConvertIn for Solaris backends. + * Implement "hog mode" (exclusive access of the audio device) in JackCoreAudioDriver. + * Fix jack_set_sample_rate_callback to have he same behavior as in JACK1. +2009-10-25 Stephane Letz + + * Improve aggregate device management in JackCoreAudioDriver : now a "private" device only and cleanup properly. + * Aggregate device code added to JackCoreAudioAdapter. + +2009-10-23 Stephane Letz + + * Correct JackProcessSync::LockedTimedWait. + * Correct JACK_MESSAGE_SIZE value, particularly in OSX RPC code. + * Now start server channel thread only when backend has been started (so in JackServer::Start). Should solve race conditions at start time. + * jack_verbose moved to JackGlobals class. + +2009-10-22 Stephane Letz + + * Correct jackdmp.cpp (failures case were not correct..). Improve JackCoreAudioDriver code. Raise default port number to 2048. + +2009-10-20 Stephane Letz + + * Add a string parameter to server ==> client notification, add a new JackInfoShutdownCallback type. + * CoreAudio backend now issue a JackInfoShutdownCallback when an unrecoverable error is detected (sampling rate change, stream configuration changeÉ) + +2009-10-17 Stephane Letz + + * Correct server temporary mode : now set a global and quit after server/client message handling is finished. + +2009-10-15 Stephane Letz + + * Change CoreAudio notification thread setup for OSX Snow Leopard. + +2009-09-18 Stephane Letz + + * Simplify transport in NetJack2: master only can control transport. + +2009-09-15 Stephane Letz + + * Correct CPU timing in JackNetDriver, now take cycle begin time after Read. + * Fix issues in JackNetDriver::DecodeTransportData and JackNetDriver::Initialize. + +2009-08-28 Stephane Letz + + * Correct monitor port naming in JackAudioDriver and JackCoreAudioDriver. + * Big endian bug fix in memops.c (http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=5;filename=11_be24bit.patch;att=1;bug=486308) + +2009-07-31 Stephane Letz + + * Use SNDCTL_DSP_SYNCGROUP/SNDCTL_DSP_SYNCSTART API to synchronize input and output in Solaris boomer backend. + +2009-07-29 Stephane Letz + + * Add a -G parameter in CoreAudio backend (the computation value in RT thread expressed as percent of period). + +2009-07-28 Stephane Letz + + * Fix CopyAndConvertIn for Solaris backends. + 2009-07-22 Stephane Letz - * Version 1.9.4 started. - * Solaris boomer backend now working in capture or playback only mode. + * Version 1.9.4 started. + * Solaris boomer backend now working in capture or playback only mode. * Fix control.h for proper compilation on Solaris. - + 2009-07-17 Stephane Letz - * Loopback backend reborn as a dynamically loadable separated backend. + * Loopback backend reborn as a dynamically loadable separated backend. * -L parameter for loopback backend activated again in jackd. - + 2009-07-17 Stephane Letz * Big rewrite of Solaris boomer driver, seems to work in duplex mode at least. diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index d609a915..34e591e4 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -72,6 +72,8 @@ extern "C" EXPORT int jack_is_realtime (jack_client_t *client); EXPORT void jack_on_shutdown (jack_client_t *client, JackShutdownCallback shutdown_callback, void *arg); + EXPORT void jack_on_info_shutdown (jack_client_t *client, + JackInfoShutdownCallback shutdown_callback, void *arg); EXPORT int jack_set_process_callback (jack_client_t *client, JackProcessCallback process_callback, void *arg); @@ -812,6 +814,7 @@ EXPORT void jack_on_shutdown(jack_client_t* ext_client, JackShutdownCallback cal JackLibGlobals::CheckContext(); #endif JackClient* client = (JackClient*)ext_client; + jack_error("jack_on_shutdown: deprecated, use jack_on_info_shutdown"); if (client == NULL) { jack_error("jack_on_shutdown called with a NULL client"); } else { @@ -819,6 +822,19 @@ EXPORT void jack_on_shutdown(jack_client_t* ext_client, JackShutdownCallback cal } } +EXPORT void jack_on_info_shutdown(jack_client_t* ext_client, JackInfoShutdownCallback callback, void* arg) +{ +#ifdef __CLIENTDEBUG__ + JackLibGlobals::CheckContext(); +#endif + JackClient* client = (JackClient*)ext_client; + if (client == NULL) { + jack_error("jack_on_info_shutdown called with a NULL client"); + } else { + client->OnInfoShutdown(callback, arg); + } +} + EXPORT int jack_set_process_callback(jack_client_t* ext_client, JackProcessCallback callback, void* arg) { #ifdef __CLIENTDEBUG__ diff --git a/common/JackAudioAdapterInterface.cpp b/common/JackAudioAdapterInterface.cpp index ece82fc7..a347ca12 100644 --- a/common/JackAudioAdapterInterface.cpp +++ b/common/JackAudioAdapterInterface.cpp @@ -240,10 +240,18 @@ namespace Jack // Finer estimation of the position in the ringbuffer int delta_frames = (fPullAndPushTime > 0) ? (int)((float(long(GetMicroSeconds() - fPullAndPushTime)) * float(fAdaptedSampleRate)) / 1000000.f) : 0; - double ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetError() - delta_frames); + + double ratio = 1; + + // TODO : done like this just to avoid crash when input only or output only... + if (fCaptureChannels > 0) + ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetError() - delta_frames); + else if (fPlaybackChannels > 0) + ratio = fPIControler.GetRatio(fPlaybackRingBuffer[0]->GetError() - delta_frames); #ifdef JACK_MONITOR - fTable.Write(fCaptureRingBuffer[0]->GetError(), fCaptureRingBuffer[0]->GetError() - delta_frames, ratio, 1/ratio, fCaptureRingBuffer[0]->ReadSpace(), fCaptureRingBuffer[0]->ReadSpace()); + if (fCaptureRingBuffer[0] != NULL) + fTable.Write(fCaptureRingBuffer[0]->GetError(), fCaptureRingBuffer[0]->GetError() - delta_frames, ratio, 1/ratio, fCaptureRingBuffer[0]->ReadSpace(), fCaptureRingBuffer[0]->ReadSpace()); #endif // Push/pull from ringbuffer diff --git a/common/JackChannel.h b/common/JackChannel.h index 654887ed..655e2bcf 100644 --- a/common/JackChannel.h +++ b/common/JackChannel.h @@ -82,7 +82,7 @@ class JackClientChannelInterface virtual void ClientClose(int refnum, int* result) {} - virtual void ClientActivate(int refnum, int state, int* result) + virtual void ClientActivate(int refnum, int is_real_time, int* result) {} virtual void ClientDeactivate(int refnum, int* result) {} diff --git a/common/JackClient.cpp b/common/JackClient.cpp index 75beefbc..7cfb50ef 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -49,6 +49,7 @@ JackClient::JackClient(JackSynchro* table):fThread(this) fGraphOrder = NULL; fXrun = NULL; fShutdown = NULL; + fInfoShutdown = NULL; fInit = NULL; fBufferSize = NULL; fClientRegistration = NULL; @@ -63,6 +64,7 @@ JackClient::JackClient(JackSynchro* table):fThread(this) fGraphOrderArg = NULL; fXrunArg = NULL; fShutdownArg = NULL; + fInfoShutdownArg = NULL; fInitArg = NULL; fBufferSizeArg = NULL; fFreewheelArg = NULL; @@ -132,12 +134,12 @@ void JackClient::SetupDriverSync(bool freewheel) \brief Notification received from the server. */ -int JackClient::ClientNotifyImp(int refnum, const char* name, int notify, int sync, int value1, int value2) +int JackClient::ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { return 0; } -int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2) +int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { int res = 0; @@ -145,11 +147,11 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, switch (notify) { case kAddClient: - res = ClientNotifyImp(refnum, name, notify, sync, value1, value2); + res = ClientNotifyImp(refnum, name, notify, sync, message, value1, value2); break; case kRemoveClient: - res = ClientNotifyImp(refnum, name, notify, sync, value1, value2); + res = ClientNotifyImp(refnum, name, notify, sync, message, value1, value2); break; case kActivateClient: @@ -247,6 +249,14 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, if (fXrun) res = fXrun(fXrunArg); break; + + case kShutDownCallback: + jack_log("JackClient::kShutDownCallback"); + if (fInfoShutdown) { + fInfoShutdown(value1, message, fInfoShutdownArg); + fInfoShutdown = NULL; + } + break; } } @@ -582,7 +592,10 @@ void JackClient::ShutDown() jack_log("ShutDown"); JackGlobals::fServerRunning = false; - if (fShutdown) { + if (fInfoShutdown) { + fInfoShutdown(JackFailure, "JACK server has been closed", fInfoShutdownArg); + fInfoShutdown = NULL; + } else if (fShutdown) { fShutdown(fShutdownArg); fShutdown = NULL; } @@ -772,6 +785,17 @@ void JackClient::OnShutdown(JackShutdownCallback callback, void *arg) fShutdown = callback; } } + +void JackClient::OnInfoShutdown(JackInfoShutdownCallback callback, void *arg) +{ + if (IsActive()) { + jack_error("You cannot set callbacks on an active client"); + } else { + GetClientControl()->fCallback[kShutDownCallback] = (callback != NULL); + fInfoShutdownArg = arg; + fInfoShutdown = callback; + } +} int JackClient::SetProcessCallback(JackProcessCallback callback, void *arg) { @@ -850,6 +874,9 @@ int JackClient::SetSampleRateCallback(JackSampleRateCallback callback, void *arg GetClientControl()->fCallback[kSampleRateCallback] = (callback != NULL); fSampleRateArg = arg; fSampleRate = callback; + // Now invoke it + if (callback) + callback(GetEngineControl()->fSampleRate, arg); return 0; } } diff --git a/common/JackClient.h b/common/JackClient.h index 73ee17fc..215098a0 100644 --- a/common/JackClient.h +++ b/common/JackClient.h @@ -54,6 +54,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface JackGraphOrderCallback fGraphOrder; JackXRunCallback fXrun; JackShutdownCallback fShutdown; + JackInfoShutdownCallback fInfoShutdown; JackThreadInitCallback fInit; JackBufferSizeCallback fBufferSize; JackSampleRateCallback fSampleRate; @@ -70,6 +71,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface void* fGraphOrderArg; void* fXrunArg; void* fShutdownArg; + void* fInfoShutdownArg; void* fInitArg; void* fBufferSizeArg; void* fSampleRateArg; @@ -95,7 +97,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface void CallSyncCallback(); void CallTimebaseCallback(); - virtual int ClientNotifyImp(int refnum, const char* name, int notify, int sync, int value1, int value); + virtual int ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value); inline void DummyCycle(); inline void ExecuteThread(); @@ -123,7 +125,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface virtual JackEngineControl* GetEngineControl() const = 0; // Notifications - virtual int ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2); + virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); virtual int Activate(); virtual int Deactivate(); @@ -159,6 +161,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface // Callbacks virtual void OnShutdown(JackShutdownCallback callback, void *arg); + virtual void OnInfoShutdown(JackInfoShutdownCallback callback, void *arg); virtual int SetProcessCallback(JackProcessCallback callback, void* arg); virtual int SetXRunCallback(JackXRunCallback callback, void* arg); virtual int SetInitCallback(JackThreadInitCallback callback, void* arg); diff --git a/common/JackClientInterface.h b/common/JackClientInterface.h index 1794328c..bd94ed38 100644 --- a/common/JackClientInterface.h +++ b/common/JackClientInterface.h @@ -44,7 +44,7 @@ class SERVER_EXPORT JackClientInterface virtual int Close() = 0; - virtual int ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2) = 0; + virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) = 0; virtual JackClientControl* GetClientControl() const = 0; }; diff --git a/common/JackConstants.h b/common/JackConstants.h index 709aa364..00a0be99 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -32,9 +32,10 @@ #define JACK_PORT_TYPE_SIZE 32 #define JACK_CLIENT_NAME_SIZE 64 +#define JACK_MESSAGE_SIZE 256 #ifndef PORT_NUM -#define PORT_NUM 1024 +#define PORT_NUM 2048 #endif #define DRIVER_PORT_NUM 256 diff --git a/common/JackDebugClient.cpp b/common/JackDebugClient.cpp index 74566c5e..a2a61d8d 100644 --- a/common/JackDebugClient.cpp +++ b/common/JackDebugClient.cpp @@ -139,10 +139,10 @@ JackEngineControl* JackDebugClient::GetEngineControl() const \brief Notification received from the server. */ -int JackDebugClient::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2) +int JackDebugClient::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { CheckClient(); - return fClient->ClientNotify( refnum, name, notify, sync, value1, value2); + return fClient->ClientNotify( refnum, name, notify, sync, message, value1, value2); } int JackDebugClient::Activate() @@ -416,6 +416,12 @@ void JackDebugClient::OnShutdown(JackShutdownCallback callback, void *arg) fClient->OnShutdown(callback, arg); } +void JackDebugClient::OnInfoShutdown(JackInfoShutdownCallback callback, void *arg) +{ + CheckClient(); + fClient->OnInfoShutdown(callback, arg); +} + int JackDebugClient::TimeCallback(jack_nframes_t nframes, void *arg) { JackDebugClient* client = (JackDebugClient*)arg; diff --git a/common/JackDebugClient.h b/common/JackDebugClient.h index 430c9610..0bb21b20 100644 --- a/common/JackDebugClient.h +++ b/common/JackDebugClient.h @@ -75,7 +75,7 @@ class JackDebugClient : public JackClient virtual JackEngineControl* GetEngineControl() const; // Notifications - int ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2); + int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); int Activate(); int Deactivate(); @@ -110,6 +110,7 @@ class JackDebugClient : public JackClient // Callbacks void OnShutdown(JackShutdownCallback callback, void *arg); + void OnInfoShutdown(JackInfoShutdownCallback callback, void *arg); int SetProcessCallback(JackProcessCallback callback, void* arg); int SetXRunCallback(JackXRunCallback callback, void* arg); int SetInitCallback(JackThreadInitCallback callback, void* arg); diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index 9fde4917..bab5db0f 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -167,11 +167,15 @@ int JackDriver::Open(jack_nframes_t buffer_size, int JackDriver::Close() { - jack_log("JackDriver::Close"); - fGraphManager->DirectDisconnect(fClientControl.fRefNum, fClientControl.fRefNum); // Disconnect driver from itself for sync - fClientControl.fActive = false; - fEngineControl->fDriverNum--; - return fEngine->ClientInternalClose(fClientControl.fRefNum, false); + if (fClientControl.fRefNum > 0) { + jack_log("JackDriver::Close"); + fGraphManager->DirectDisconnect(fClientControl.fRefNum, fClientControl.fRefNum); // Disconnect driver from itself for sync + fClientControl.fActive = false; + fEngineControl->fDriverNum--; + return fEngine->ClientInternalClose(fClientControl.fRefNum, false); + } else { + return -1; + } } /*! @@ -190,7 +194,7 @@ void JackDriver::SetupDriverSync(int ref, bool freewheel) } } -int JackDriver::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2) +int JackDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { switch (notify) { @@ -250,6 +254,11 @@ void JackDriver::NotifySampleRate(jack_nframes_t sample_rate) fEngine->NotifySampleRate(sample_rate); fEngineControl->InitFrameTime(); } + +void JackDriver::NotifyFailure(int code, const char* reason) +{ + fEngine->NotifyFailure(code, reason); +} void JackDriver::SetMaster(bool onoff) { diff --git a/common/JackDriver.h b/common/JackDriver.h index 6b80dc33..83f7e250 100644 --- a/common/JackDriver.h +++ b/common/JackDriver.h @@ -140,6 +140,7 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface 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: @@ -199,7 +200,7 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface 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, int value1, int value2); + virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); virtual JackClientControl* GetClientControl() const; virtual bool IsRealTime() const; diff --git a/common/JackDriverLoader.cpp b/common/JackDriverLoader.cpp index 52c4aeed..428d3ab0 100644 --- a/common/JackDriverLoader.cpp +++ b/common/JackDriverLoader.cpp @@ -62,7 +62,7 @@ SERVER_EXPORT void jack_print_driver_options (jack_driver_desc_t* desc, FILE* fi fprintf (file, "\t-%c, --%s \t%s (default: %s)\n", desc->params[i].character, desc->params[i].name, - desc->params[i].short_desc, + desc->params[i].long_desc, arg_default); } } diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index 20b8f16b..83a22ad4 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -119,9 +119,7 @@ void JackEngine::ReleaseRefnum(int ref) // last client and temporay case: quit the server jack_log("JackEngine::ReleaseRefnum server quit"); fEngineControl->fTemporary = false; -#ifndef WIN32 - exit(0); -#endif + JackServerGlobals::fKilled = true; } } } @@ -205,7 +203,7 @@ void JackEngine::CheckXRun(jack_time_t callback_usecs) // REVOIR les conditions // Notifications //--------------- -void JackEngine::NotifyClient(int refnum, int event, int sync, int value1, int value2) +void JackEngine::NotifyClient(int refnum, int event, int sync, const char* message, int value1, int value2) { JackClientInterface* client = fClientTable[refnum]; @@ -213,20 +211,20 @@ void JackEngine::NotifyClient(int refnum, int event, int sync, int value1, int v if (!client) { jack_log("JackEngine::NotifyClient: client not available anymore"); } else if (client->GetClientControl()->fCallback[event]) { - if (client->ClientNotify(refnum, client->GetClientControl()->fName, event, sync, value1, value2) < 0) + if (client->ClientNotify(refnum, client->GetClientControl()->fName, event, sync, message, value1, value2) < 0) jack_error("NotifyClient fails name = %s event = %ld val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2); } else { jack_log("JackEngine::NotifyClient: no callback for event = %ld", event); } } -void JackEngine::NotifyClients(int event, int sync, int value1, int value2) +void JackEngine::NotifyClients(int event, int sync, const char* message, int value1, int value2) { for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* client = fClientTable[i]; if (client) { if (client->GetClientControl()->fCallback[event]) { - if (client->ClientNotify(i, client->GetClientControl()->fName, event, sync, value1, value2) < 0) + if (client->ClientNotify(i, client->GetClientControl()->fName, event, sync, message, value1, value2) < 0) jack_error("NotifyClient fails name = %s event = %ld val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2); } else { jack_log("JackEngine::NotifyClients: no callback for event = %ld", event); @@ -242,11 +240,11 @@ int JackEngine::NotifyAddClient(JackClientInterface* new_client, const char* nam for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* old_client = fClientTable[i]; if (old_client) { - if (old_client->ClientNotify(refnum, name, kAddClient, true, 0, 0) < 0) { + if (old_client->ClientNotify(refnum, name, kAddClient, true, "", 0, 0) < 0) { jack_error("NotifyAddClient old_client fails name = %s", old_client->GetClientControl()->fName); return -1; } - if (new_client->ClientNotify(i, old_client->GetClientControl()->fName, kAddClient, true, 0, 0) < 0) { + if (new_client->ClientNotify(i, old_client->GetClientControl()->fName, kAddClient, true, "", 0, 0) < 0) { jack_error("NotifyAddClient new_client fails name = %s", name); return -1; } @@ -262,7 +260,7 @@ void JackEngine::NotifyRemoveClient(const char* name, int refnum) for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* client = fClientTable[i]; if (client) { - client->ClientNotify(refnum, name, kRemoveClient, true, 0, 0); + client->ClientNotify(refnum, name, kRemoveClient, true, "",0, 0); } } } @@ -279,51 +277,56 @@ void JackEngine::NotifyXRun(jack_time_t callback_usecs, float delayed_usecs) void JackEngine::NotifyXRun(int refnum) { if (refnum == ALL_CLIENTS) { - NotifyClients(kXRunCallback, false, 0, 0); + NotifyClients(kXRunCallback, false, "", 0, 0); } else { - NotifyClient(refnum, kXRunCallback, false, 0, 0); + NotifyClient(refnum, kXRunCallback, false, "", 0, 0); } } void JackEngine::NotifyGraphReorder() { - NotifyClients(kGraphOrderCallback, false, 0, 0); + NotifyClients(kGraphOrderCallback, false, "", 0, 0); } void JackEngine::NotifyBufferSize(jack_nframes_t buffer_size) { - NotifyClients(kBufferSizeCallback, true, buffer_size, 0); + NotifyClients(kBufferSizeCallback, true, "", buffer_size, 0); } void JackEngine::NotifySampleRate(jack_nframes_t sample_rate) { - NotifyClients(kSampleRateCallback, true, sample_rate, 0); + NotifyClients(kSampleRateCallback, true, "", sample_rate, 0); } +void JackEngine::NotifyFailure(int code, const char* reason) +{ + NotifyClients(kShutDownCallback, false, reason, code, 0); +} + void JackEngine::NotifyFreewheel(bool onoff) { fEngineControl->fRealTime = !onoff; - NotifyClients((onoff ? kStartFreewheelCallback : kStopFreewheelCallback), true, 0, 0); + NotifyClients((onoff ? kStartFreewheelCallback : kStopFreewheelCallback), true, "", 0, 0); } void JackEngine::NotifyPortRegistation(jack_port_id_t port_index, bool onoff) { - NotifyClients((onoff ? kPortRegistrationOnCallback : kPortRegistrationOffCallback), false, port_index, 0); + NotifyClients((onoff ? kPortRegistrationOnCallback : kPortRegistrationOffCallback), false, "", port_index, 0); } void JackEngine::NotifyPortRename(jack_port_id_t port) { - NotifyClients(kPortRenameCallback, false, port, 0); + NotifyClients(kPortRenameCallback, false, "", port, 0); } void JackEngine::NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst, bool onoff) { - NotifyClients((onoff ? kPortConnectCallback : kPortDisconnectCallback), false, src, dst); + NotifyClients((onoff ? kPortConnectCallback : kPortDisconnectCallback), false, "", src, dst); } void JackEngine::NotifyActivate(int refnum) { - NotifyClient(refnum, kActivateClient, true, 0, 0); + NotifyClient(refnum, kActivateClient, true, "", 0, 0); } //---------------------------- @@ -481,7 +484,7 @@ int JackEngine::GetClientRefNum(const char* name) // Used for external clients int JackEngine::ClientExternalOpen(const char* name, int pid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager) { - jack_log("JackEngine::ClientOpen: name = %s ", name); + jack_log("JackEngine::ClientExternalOpen: name = %s ", name); int refnum = AllocateRefnum(); if (refnum < 0) { @@ -533,7 +536,7 @@ error: // Used for server driver clients int JackEngine::ClientInternalOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, bool wait) { - jack_log("JackEngine::ClientInternalNew: name = %s", name); + jack_log("JackEngine::ClientInternalOpen: name = %s", name); int refnum = AllocateRefnum(); if (refnum < 0) { @@ -638,14 +641,14 @@ int JackEngine::ClientCloseAux(int refnum, JackClientInterface* client, bool wai return 0; } -int JackEngine::ClientActivate(int refnum, bool state) +int JackEngine::ClientActivate(int refnum, bool is_real_time) { AssertRefnum(refnum); JackClientInterface* client = fClientTable[refnum]; assert(fClientTable[refnum]); jack_log("JackEngine::ClientActivate ref = %ld name = %s", refnum, client->GetClientControl()->fName); - if (state) + if (is_real_time) fGraphManager->Activate(refnum); // Wait for graph state change to be effective diff --git a/common/JackEngine.h b/common/JackEngine.h index 9ec65124..8212daf9 100644 --- a/common/JackEngine.h +++ b/common/JackEngine.h @@ -64,8 +64,9 @@ class SERVER_EXPORT JackEngine int AllocateRefnum(); void ReleaseRefnum(int ref); - void NotifyClient(int refnum, int event, int sync, int value1, int value2); - void NotifyClients(int event, int sync, int value1, int value2); + void NotifyClient(int refnum, int event, int sync, const char* message, int value1, int value2); + void NotifyClients(int event, int sync, const char* message, int value1, int value2); + void NotifyPortRegistation(jack_port_id_t port_index, bool onoff); void NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst, bool onoff); void NotifyPortRename(jack_port_id_t src); @@ -87,7 +88,7 @@ class SERVER_EXPORT JackEngine int ClientExternalClose(int refnum); int ClientInternalClose(int refnum, bool wait); - int ClientActivate(int refnum, bool state); + int ClientActivate(int refnum, bool is_real_time); int ClientDeactivate(int refnum); int GetClientPID(const char* name); @@ -115,6 +116,7 @@ class SERVER_EXPORT JackEngine // Notifications void NotifyXRun(jack_time_t callback_usecs, float delayed_usecs); + void NotifyFailure(int code, const char* reason); void NotifyXRun(int refnum); void NotifyGraphReorder(); void NotifyBufferSize(jack_nframes_t buffer_size); diff --git a/common/JackError.cpp b/common/JackError.cpp index aad72327..3705c35c 100644 --- a/common/JackError.cpp +++ b/common/JackError.cpp @@ -25,8 +25,6 @@ #include "JackGlobals.h" #include "JackMessageBuffer.h" -int jack_verbose = 0; - using namespace Jack; void change_thread_log_function(jack_log_function_t log_function) @@ -110,7 +108,7 @@ SERVER_EXPORT void jack_info(const char *fmt, ...) SERVER_EXPORT void jack_log(const char *fmt,...) { - if (jack_verbose) { + if (JackGlobals::fVerbose) { va_list ap; va_start(ap, fmt); jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); diff --git a/common/JackError.h b/common/JackError.h index fca6ec30..403c55ae 100644 --- a/common/JackError.h +++ b/common/JackError.h @@ -58,8 +58,6 @@ extern "C" void jack_log_function(int level, const char *message); SERVER_EXPORT void set_threaded_log_function(); - - extern int jack_verbose; #ifdef __cplusplus } diff --git a/common/JackExternalClient.cpp b/common/JackExternalClient.cpp index c86f1d17..4d56557b 100644 --- a/common/JackExternalClient.cpp +++ b/common/JackExternalClient.cpp @@ -33,11 +33,11 @@ JackExternalClient::JackExternalClient(): fClientControl(NULL) JackExternalClient::~JackExternalClient() {} -int JackExternalClient::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2) +int JackExternalClient::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { int result = -1; jack_log("JackExternalClient::ClientNotify ref = %ld name = %s notify = %ld", refnum, name, notify); - fChannel.ClientNotify(refnum, name, notify, sync, value1, value2, &result); + fChannel.ClientNotify(refnum, name, notify, sync, message, value1, value2, &result); return result; } diff --git a/common/JackExternalClient.h b/common/JackExternalClient.h index daafb199..29e0f7d6 100644 --- a/common/JackExternalClient.h +++ b/common/JackExternalClient.h @@ -49,7 +49,7 @@ class JackExternalClient : public JackClientInterface int Open(const char* name, int pid, int refnum, int* shared_client); int Close(); - int ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2); + int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); JackClientControl* GetClientControl() const; }; diff --git a/common/JackGlobals.cpp b/common/JackGlobals.cpp index 599523db..c8c40545 100644 --- a/common/JackGlobals.cpp +++ b/common/JackGlobals.cpp @@ -22,6 +22,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { +bool JackGlobals::fVerbose = 0; + jack_tls_key JackGlobals::fRealTime; static bool gKeyRealtimeInitialized = jack_tls_allocate_key(&JackGlobals::fRealTime); diff --git a/common/JackGlobals.h b/common/JackGlobals.h index f5516f73..7586708e 100644 --- a/common/JackGlobals.h +++ b/common/JackGlobals.h @@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -// Globals used for client management on server or libray side. +// Globals used for client management on server or library side. struct JackGlobals { static jack_tls_key fRealTime; @@ -34,10 +34,10 @@ struct JackGlobals { static JackMutex* fOpenMutex; static bool fServerRunning; static JackClient* fClientTable[]; + static bool fVerbose; #ifndef WIN32 static jack_thread_creator_t fJackThreadCreator; #endif - }; // Each "side" server and client will implement this to get the shared graph manager, engine control and inter-process synchro table. diff --git a/common/JackInternalClientChannel.h b/common/JackInternalClientChannel.h index 59eaa8c9..93130ca5 100644 --- a/common/JackInternalClientChannel.h +++ b/common/JackInternalClientChannel.h @@ -63,9 +63,9 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface *result = fEngine->ClientInternalClose(refnum, true); } - void ClientActivate(int refnum, int state, int* result) + void ClientActivate(int refnum, int is_real_time, int* result) { - *result = fEngine->ClientActivate(refnum, state); + *result = fEngine->ClientActivate(refnum, is_real_time); } void ClientDeactivate(int refnum, int* result) { diff --git a/common/JackLibClient.cpp b/common/JackLibClient.cpp index ff6055e5..4c92e9e3 100644 --- a/common/JackLibClient.cpp +++ b/common/JackLibClient.cpp @@ -99,7 +99,7 @@ int JackLibClient::Open(const char* server_name, const char* name, jack_options_ JackLibGlobals::fGlobals->fEngineControl.SetShmIndex(shared_engine, fServerName); JackLibGlobals::fGlobals->fGraphManager.SetShmIndex(shared_graph, fServerName); fClientControl.SetShmIndex(shared_client, fServerName); - jack_verbose = GetEngineControl()->fVerbose; + JackGlobals::fVerbose = GetEngineControl()->fVerbose; } catch (int n) { jack_error("Map shared memory segments exception %d", n); goto error; @@ -128,7 +128,7 @@ error: // Notifications received from the server // TODO this should be done once for all clients in the process, when a shared notification channel // will be shared by all clients... -int JackLibClient::ClientNotifyImp(int refnum, const char* name, int notify, int sync, int value1, int value2) +int JackLibClient::ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { int res = 0; diff --git a/common/JackLibClient.h b/common/JackLibClient.h index 3ad9e3c9..0621ed15 100644 --- a/common/JackLibClient.h +++ b/common/JackLibClient.h @@ -46,7 +46,7 @@ class JackLibClient : public JackClient int Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status); - int ClientNotifyImp(int refnum, const char* name, int notify, int sync, int value1, int value2); + int ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); JackGraphManager* GetGraphManager() const; JackEngineControl* GetEngineControl() const; diff --git a/common/JackLockedEngine.h b/common/JackLockedEngine.h index c8799f49..d1d9d3d1 100644 --- a/common/JackLockedEngine.h +++ b/common/JackLockedEngine.h @@ -83,10 +83,10 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble return fEngine.ClientInternalClose(refnum, wait); } - int ClientActivate(int refnum, bool state) + int ClientActivate(int refnum, bool is_real_time) { JackLock lock(this); - return fEngine.ClientActivate(refnum, state); + return fEngine.ClientActivate(refnum, is_real_time); } int ClientDeactivate(int refnum) { @@ -191,6 +191,12 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble fEngine.NotifyFreewheel(onoff); } + void NotifyFailure(int code, const char* reason) + { + JackLock lock(this); + fEngine.NotifyFailure(code, reason); + } + int GetClientPID(const char* name) { JackLock lock(this); diff --git a/common/JackMessageBuffer.cpp b/common/JackMessageBuffer.cpp index 18e4d52f..bc380a52 100644 --- a/common/JackMessageBuffer.cpp +++ b/common/JackMessageBuffer.cpp @@ -29,13 +29,19 @@ namespace Jack JackMessageBuffer* JackMessageBuffer::fInstance = NULL; JackMessageBuffer::JackMessageBuffer() - :fThread(this),fInBuffer(0),fOutBuffer(0),fOverruns(0) + :fThread(this),fInBuffer(0),fOutBuffer(0),fOverruns(0),fRunning(false) +{} + +JackMessageBuffer::~JackMessageBuffer() +{} + +void JackMessageBuffer::Start() { fRunning = true; fThread.StartSync(); } -JackMessageBuffer::~JackMessageBuffer() +void JackMessageBuffer::Stop() { if (fOverruns > 0) { jack_error("WARNING: %d message buffer overruns!", fOverruns); @@ -49,7 +55,7 @@ JackMessageBuffer::~JackMessageBuffer() fThread.Stop(); Flush(); } - + void JackMessageBuffer::Flush() { while (fOutBuffer != fInBuffer) { @@ -86,12 +92,14 @@ void JackMessageBuffer::Create() { if (fInstance == NULL) { fInstance = new JackMessageBuffer(); + fInstance->Start(); } } void JackMessageBuffer::Destroy() { if (fInstance != NULL) { + fInstance->Stop(); delete fInstance; fInstance = NULL; } @@ -100,8 +108,7 @@ void JackMessageBuffer::Destroy() void JackMessageBufferAdd(int level, const char *message) { if (Jack::JackMessageBuffer::fInstance == NULL) { - /* Unable to print message with realtime safety. - * Complain and print it anyway. */ + /* Unable to print message with realtime safety. Complain and print it anyway. */ jack_log_function(LOG_LEVEL_ERROR, "messagebuffer not initialized, skip message"); } else { Jack::JackMessageBuffer::fInstance->AddMessage(level, message); diff --git a/common/JackMessageBuffer.h b/common/JackMessageBuffer.h index 23bb12a6..5e3472a5 100644 --- a/common/JackMessageBuffer.h +++ b/common/JackMessageBuffer.h @@ -66,10 +66,13 @@ class JackMessageBuffer : public JackRunnableInterface bool fRunning; void Flush(); + + void Start(); + void Stop(); public: - JackMessageBuffer(); + JackMessageBuffer(); ~JackMessageBuffer(); // JackRunnableInterface interface diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index 641c95c4..5f5af5db 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -53,6 +53,7 @@ namespace Jack fMidiPlaybackPortList = NULL; #ifdef JACK_MONITOR fNetTimeMon = NULL; + fRcvSyncUst = 0; #endif } @@ -208,7 +209,7 @@ namespace Jack JackDriver::NotifySampleRate ( fParams.fSampleRate ); //transport engine parametering - fEngineControl->fTransport.SetNetworkSync ( true ); + fEngineControl->fTransport.SetNetworkSync ( fParams.fTransportSync ); return true; } @@ -418,6 +419,7 @@ namespace Jack break; case JackTransportRolling : + //fEngineControl->fTransport.SetCommand ( TransportCommandStart ); fEngineControl->fTransport.SetState ( JackTransportRolling ); jack_info ( "Master is rolling." ); break; @@ -427,6 +429,7 @@ namespace Jack void JackNetDriver::EncodeTransportData() { + /* Desactivated //is there a timebase master change ? int refnum; bool conditional; @@ -449,12 +452,14 @@ namespace Jack } else fReturnTransportData.fTimebaseMaster = NO_CHANGE; - + */ + //update transport state and position fReturnTransportData.fState = fEngineControl->fTransport.Query ( &fReturnTransportData.fPosition ); - + //is it a new state (that the master need to know...) ? - fReturnTransportData.fNewState = ( ( fReturnTransportData.fState != fLastTransportState ) && + fReturnTransportData.fNewState = (( fReturnTransportData.fState == JackTransportNetStarting) && + ( fReturnTransportData.fState != fLastTransportState ) && ( fReturnTransportData.fState != fSendTransportData.fState ) ); if ( fReturnTransportData.fNewState ) jack_info ( "Sending '%s'.", GetTransportState ( fReturnTransportData.fState ) ); @@ -481,22 +486,27 @@ namespace Jack if ( SyncRecv() == SOCKET_ERROR ) return 0; - //take the time at the beginning of the cycle - JackDriver::CycleTakeBeginTime(); +#ifdef JACK_MONITOR + // For timing + fRcvSyncUst = GetMicroSeconds(); +#endif //decode sync //if there is an error, don't return -1, it will skip Write() and the network error probably won't be identified DecodeSyncPacket(); #ifdef JACK_MONITOR - fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - JackDriver::fBeginDateUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); + fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - fRcvSyncUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); #endif //audio, midi or sync if driver is late if ( DataRecv() == SOCKET_ERROR ) return SOCKET_ERROR; + //take the time at the beginning of the cycle + JackDriver::CycleTakeBeginTime(); + #ifdef JACK_MONITOR - fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - JackDriver::fBeginDateUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); + fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - fRcvSyncUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); #endif return 0; @@ -514,7 +524,7 @@ namespace Jack fNetAudioPlaybackBuffer->SetBuffer ( audio_port_index, GetOutputBuffer ( audio_port_index ) ); #ifdef JACK_MONITOR - fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - JackDriver::fBeginDateUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); + fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - fRcvSyncUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); #endif //sync @@ -525,7 +535,7 @@ namespace Jack return SOCKET_ERROR; #ifdef JACK_MONITOR - fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - JackDriver::fBeginDateUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); + fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - fRcvSyncUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); #endif //send data @@ -533,7 +543,7 @@ namespace Jack return SOCKET_ERROR; #ifdef JACK_MONITOR - fNetTimeMon->AddLast ( ( ( float ) ( GetMicroSeconds() - JackDriver::fBeginDateUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); + fNetTimeMon->AddLast ( ( ( float ) ( GetMicroSeconds() - fRcvSyncUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); #endif return 0; diff --git a/common/JackNetDriver.h b/common/JackNetDriver.h index d8fb0bb2..af137b43 100644 --- a/common/JackNetDriver.h +++ b/common/JackNetDriver.h @@ -40,15 +40,16 @@ namespace Jack //jack data jack_port_id_t* fMidiCapturePortList; jack_port_id_t* fMidiPlaybackPortList; - + //transport int fLastTransportState; int fLastTimebaseMaster; //monitoring -#ifdef JACK_MONITOR + #ifdef JACK_MONITOR JackGnuPlotMonitor* fNetTimeMon; -#endif + jack_time_t fRcvSyncUst; + #endif bool Initialize(); void FreeAll(); diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index b4e45853..b42d970e 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -305,6 +305,7 @@ namespace Jack else jack_info ( "'%s' isn't the timebase master anymore.", fParams.fName ); break; + case TIMEBASEMASTER : timebase = jack_set_timebase_callback ( fJackClient, 0, SetTimebaseCallback, this ); if ( timebase < 0 ) @@ -312,6 +313,7 @@ namespace Jack else jack_info ( "'%s' is the new timebase master.", fParams.fName ); break; + case CONDITIONAL_TIMEBASEMASTER : timebase = jack_set_timebase_callback ( fJackClient, 1, SetTimebaseCallback, this ); if ( timebase != EBUSY ) @@ -334,15 +336,18 @@ namespace Jack jack_transport_stop ( fJackClient ); jack_info ( "'%s' stops transport.", fParams.fName ); break; + case JackTransportStarting : if ( jack_transport_reposition ( fJackClient, &fReturnTransportData.fPosition ) == EINVAL ) jack_error ( "Can't set new position." ); jack_transport_start ( fJackClient ); - jack_info ( "'%s' starts transport frame = %d frame = %d", fParams.fName, fReturnTransportData.fPosition.frame); + jack_info ( "'%s' starts transport frame = %d", fParams.fName, fReturnTransportData.fPosition.frame); break; + case JackTransportNetStarting : jack_info ( "'%s' is ready to roll..", fParams.fName ); break; + case JackTransportRolling : jack_info ( "'%s' is rolling.", fParams.fName ); break; diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index 0d63f33d..81e2404f 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -417,6 +417,7 @@ namespace Jack dst_params->fPosition.usecs = htonl(src_params->fPosition.usecs); dst_params->fPosition.frame_rate = htonl(src_params->fPosition.frame_rate); dst_params->fPosition.frame = htonl(src_params->fPosition.frame); + dst_params->fPosition.valid = (jack_position_bits_t)htonl((uint32_t)src_params->fPosition.valid); dst_params->fPosition.bar = htonl(src_params->fPosition.bar); dst_params->fPosition.beat = htonl(src_params->fPosition.beat); dst_params->fPosition.tick = htonl(src_params->fPosition.tick); @@ -442,6 +443,7 @@ namespace Jack dst_params->fPosition.usecs = ntohl(src_params->fPosition.usecs); dst_params->fPosition.frame_rate = ntohl(src_params->fPosition.frame_rate); dst_params->fPosition.frame = ntohl(src_params->fPosition.frame); + dst_params->fPosition.valid = (jack_position_bits_t)ntohl((uint32_t)src_params->fPosition.valid); dst_params->fPosition.bar = ntohl(src_params->fPosition.bar); dst_params->fPosition.beat = ntohl(src_params->fPosition.beat); dst_params->fPosition.tick = ntohl(src_params->fPosition.tick); diff --git a/common/JackNotification.h b/common/JackNotification.h index 0667c1d5..43611a4f 100644 --- a/common/JackNotification.h +++ b/common/JackNotification.h @@ -43,6 +43,7 @@ enum NotificationType { kPortDisconnectCallback = 12, kPortRenameCallback = 13, kRealTimeCallback = 14, + kShutDownCallback = 15, kMaxNotification }; diff --git a/common/JackRequest.h b/common/JackRequest.h index e6243b7b..d366f69e 100644 --- a/common/JackRequest.h +++ b/common/JackRequest.h @@ -297,25 +297,25 @@ struct JackActivateRequest : public JackRequest { int fRefNum; - int fState; + int fIsRealTime; JackActivateRequest() {} - JackActivateRequest(int refnum, int state) - : JackRequest(JackRequest::kActivateClient), fRefNum(refnum), fState(state) + JackActivateRequest(int refnum, int is_real_time) + : JackRequest(JackRequest::kActivateClient), fRefNum(refnum), fIsRealTime(is_real_time) {} int Read(JackChannelTransaction* trans) { CheckRes(trans->Read(&fRefNum, sizeof(int))); - return trans->Read(&fState, sizeof(int)); + return trans->Read(&fIsRealTime, sizeof(int)); } int Write(JackChannelTransaction* trans) { CheckRes(JackRequest::Write(trans)); CheckRes(trans->Write(&fRefNum, sizeof(int))); - return trans->Write(&fState, sizeof(int)); + return trans->Write(&fIsRealTime, sizeof(int)); } } POST_PACKED_STRUCTURE; @@ -1079,13 +1079,15 @@ struct JackClientNotification int fValue1; int fValue2; int fSync; + char fMessage[JACK_MESSAGE_SIZE + 1]; JackClientNotification(): fNotify(-1), fValue1(-1), fValue2(-1) {} - JackClientNotification(const char* name, int refnum, int notify, int sync, int value1, int value2) + JackClientNotification(const char* name, int refnum, int notify, int sync, const char* message, int value1, int value2) : fRefNum(refnum), fNotify(notify), fValue1(value1), fValue2(value2), fSync(sync) { snprintf(fName, sizeof(fName), "%s", name); + snprintf(fMessage, sizeof(fMessage), "%s", message); } int Read(JackChannelTransaction* trans) @@ -1096,6 +1098,7 @@ struct JackClientNotification CheckRes(trans->Read(&fValue1, sizeof(int))); CheckRes(trans->Read(&fValue2, sizeof(int))); CheckRes(trans->Read(&fSync, sizeof(int))); + CheckRes(trans->Read(&fMessage, JACK_MESSAGE_SIZE + 1)); return 0; } @@ -1107,6 +1110,7 @@ struct JackClientNotification CheckRes(trans->Write(&fValue1, sizeof(int))); CheckRes(trans->Write(&fValue2, sizeof(int))); CheckRes(trans->Write(&fSync, sizeof(int))); + CheckRes(trans->Write(&fMessage, JACK_MESSAGE_SIZE + 1)); return 0; } diff --git a/common/JackServer.cpp b/common/JackServer.cpp index 081e743b..a260b47a 100644 --- a/common/JackServer.cpp +++ b/common/JackServer.cpp @@ -55,7 +55,7 @@ JackServer::JackServer(bool sync, bool temporary, long timeout, bool rt, long pr fFreewheel = false; JackServerGlobals::fInstance = this; // Unique instance JackServerGlobals::fUserCount = 1; // One user - jack_verbose = verbose; + JackGlobals::fVerbose = verbose; } JackServer::~JackServer() @@ -78,7 +78,7 @@ int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params) goto fail_close1; } - if (fEngine->Open() != 0) { + if (fEngine->Open() < 0) { jack_error("Cannot open engine"); goto fail_close2; } @@ -88,12 +88,12 @@ int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params) goto fail_close3; } - if (fFreewheelDriver->Open() != 0) { // before engine open + if (fFreewheelDriver->Open() < 0) { // before engine open jack_error("Cannot open driver"); goto fail_close4; } - if (fAudioDriver->Attach() != 0) { + if (fAudioDriver->Attach() < 0) { jack_error("Cannot attach audio driver"); goto fail_close5; } @@ -168,7 +168,10 @@ int JackServer::InternalClientLoadAux(JackLoadableInternalClient* client, const int JackServer::Start() { jack_log("JackServer::Start"); - return fAudioDriver->Start(); + if (fAudioDriver->Start() < 0) { + return -1; + } + return fChannel.Start(); } int JackServer::Stop() diff --git a/common/JackServerGlobals.cpp b/common/JackServerGlobals.cpp index 7698c640..18dfaf66 100644 --- a/common/JackServerGlobals.cpp +++ b/common/JackServerGlobals.cpp @@ -28,6 +28,7 @@ static char* server_name = NULL; namespace Jack { +bool JackServerGlobals::fKilled = false; JackServer* JackServerGlobals::fInstance; unsigned int JackServerGlobals::fUserCount; bool (* JackServerGlobals::on_device_acquire)(const char * device_name) = NULL; diff --git a/common/JackServerGlobals.h b/common/JackServerGlobals.h index fac85bd3..e037f69b 100644 --- a/common/JackServerGlobals.h +++ b/common/JackServerGlobals.h @@ -36,6 +36,7 @@ class JackClient; struct SERVER_EXPORT JackServerGlobals { + static bool fKilled; static JackServer* fInstance; static unsigned int fUserCount; static bool (* on_device_acquire)(const char * device_name); @@ -46,7 +47,7 @@ struct SERVER_EXPORT JackServerGlobals static bool Init(); static void Destroy(); - static int Start (const char* server_name, + static int Start(const char* server_name, jack_driver_desc_t* driver_desc, JSList* driver_params, int sync, diff --git a/common/JackThreadedDriver.cpp b/common/JackThreadedDriver.cpp index 0ab139eb..df2b6d27 100644 --- a/common/JackThreadedDriver.cpp +++ b/common/JackThreadedDriver.cpp @@ -137,9 +137,9 @@ std::list JackThreadedDriver::GetSlaves() return fDriver->GetSlaves(); } -int JackThreadedDriver::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2) +int JackThreadedDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { - return fDriver->ClientNotify(refnum, name, notify, sync, value1, value2); + return fDriver->ClientNotify(refnum, name, notify, sync, message, value1, value2); } JackClientControl* JackThreadedDriver::GetClientControl() const diff --git a/common/JackThreadedDriver.h b/common/JackThreadedDriver.h index 5949472d..f7bbf2d0 100644 --- a/common/JackThreadedDriver.h +++ b/common/JackThreadedDriver.h @@ -94,7 +94,7 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi virtual std::list GetSlaves(); virtual int ProcessSlaves(); - virtual int ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2); + virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); virtual JackClientControl* GetClientControl() const; virtual bool IsRealTime() const; diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index 53a10bb0..a414b8b4 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -247,7 +247,7 @@ int main(int argc, char* argv[]) jackctl_parameter_set_value(param, &value); } else { usage(stdout); - goto fail_free; + goto fail_free1; } } break; @@ -358,7 +358,7 @@ int main(int argc, char* argv[]) case 'h': usage(stdout); - goto fail_free; + goto fail_free1; } } @@ -372,14 +372,14 @@ int main(int argc, char* argv[]) if (!seen_audio_driver) { usage(stderr); - goto fail_free; + goto fail_free1; } // Audio driver audio_driver_ctl = jackctl_server_get_driver(server_ctl, audio_driver_name); if (audio_driver_ctl == NULL) { fprintf(stderr, "Unkown driver \"%s\"\n", audio_driver_name); - goto fail_free; + goto fail_free1; } if (optind < argc) { @@ -391,7 +391,7 @@ int main(int argc, char* argv[]) if (audio_driver_nargs == 0) { fprintf(stderr, "No driver specified ... hmm. JACK won't do" " anything when run like this.\n"); - goto fail_free; + goto fail_free1; } audio_driver_args = (char **) malloc(sizeof(char *) * audio_driver_nargs); @@ -402,13 +402,13 @@ int main(int argc, char* argv[]) } if (jackctl_parse_driver_params(audio_driver_ctl, audio_driver_nargs, audio_driver_args)) { - goto fail_free; + goto fail_free1; } // Start server if (!jackctl_server_start(server_ctl, audio_driver_ctl)) { fprintf(stderr, "Failed to start server\n"); - goto fail_free; + goto fail_free1; } // MIDI driver @@ -417,7 +417,7 @@ int main(int argc, char* argv[]) midi_driver_ctl = jackctl_server_get_driver(server_ctl, midi_driver_name); if (midi_driver_ctl == NULL) { fprintf(stderr, "Unkown driver \"%s\"\n", midi_driver_name); - goto fail_free; + goto fail_free2; } jackctl_server_add_slave(server_ctl, midi_driver_ctl); @@ -445,10 +445,18 @@ int main(int argc, char* argv[]) if (!jackctl_server_stop(server_ctl)) fprintf(stderr, "Cannot stop server...\n"); + + jackctl_server_destroy(server_ctl); + notify_server_stop(server_name); + return 0; -fail_free: - +fail_free1: + jackctl_server_destroy(server_ctl); + return -1; + +fail_free2: + jackctl_server_stop(server_ctl); jackctl_server_destroy(server_ctl); notify_server_stop(server_name); - return 1; + return -1; } diff --git a/common/jack/jack.h b/common/jack/jack.h index 5dc6290e..ebdded77 100644 --- a/common/jack/jack.h +++ b/common/jack/jack.h @@ -282,7 +282,7 @@ int jack_set_thread_init_callback (jack_client_t *client, * @param function The jack_shutdown function pointer. * @param arg The arguments for the jack_shutdown function. * - * Register a function (and argument) to be called if and when the + * @deprecated Register a function (and argument) to be called if and when the * JACK server shuts down the client thread. The function must * be written as if it were an asynchonrous POSIX signal * handler --- use only async-safe functions, and remember that it @@ -298,6 +298,27 @@ int jack_set_thread_init_callback (jack_client_t *client, void jack_on_shutdown (jack_client_t *client, JackShutdownCallback shutdown_callback, void *arg); +/** + * @param client pointer to JACK client structure. + * @param function The jack_shutdown function pointer. + * @param arg The arguments for the jack_shutdown function. + * + * Register a function (and argument) to be called if and when the + * JACK server shuts down the client thread. The function must + * be written as if it were an asynchonrous POSIX signal + * handler --- use only async-safe functions, and remember that it + * is executed from another thread. A typical function might + * set a flag or write to a pipe so that the rest of the + * application knows that the JACK client thread has shut + * down. + * + * NOTE: clients do not need to call this. It exists only + * to help more complex clients understand what is going + * on. It should be called before jack_client_activate(). + */ +void jack_on_info_shutdown (jack_client_t *client, + JackInfoShutdownCallback shutdown_callback, void *arg); + /** * Tell the Jack server to call @a process_callback whenever there is * work be done, passing @a arg as the second argument. diff --git a/common/jack/types.h b/common/jack/types.h index fa65ce5c..f7e03d3c 100644 --- a/common/jack/types.h +++ b/common/jack/types.h @@ -214,7 +214,7 @@ typedef int (*JackPortRenameCallback)(jack_port_id_t port, const char* new_name, typedef void (*JackFreewheelCallback)(int starting, void *arg); /** - * Prototype for the client supplied function that is called + * @deprecated Prototype for the client supplied function that is called * 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() @@ -226,6 +226,21 @@ typedef void (*JackFreewheelCallback)(int starting, void *arg); */ typedef void (*JackShutdownCallback)(void *arg); +/** + * Prototype for the client supplied function that is called + * 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 shuntdown code + * @param reason a string discribing the shuntdown reason (backend failure, server crash... etc...) + * @param arg pointer to a client supplied structure + */ +typedef void (*JackInfoShutdownCallback)(int code, const char* reason, void *arg); + /** * Used for the type argument of jack_port_register() for default * audio ports and midi ports. @@ -419,7 +434,12 @@ enum JackStatus { /** * Client's protocol version does not match */ - JackVersionError = 0x400 + JackVersionError = 0x400, + + /** + * Backend failure + */ + JackBackendError = 0x800 }; /** diff --git a/common/memops.c b/common/memops.c index 3731a682..8ef4f099 100644 --- a/common/memops.c +++ b/common/memops.c @@ -37,6 +37,9 @@ #if defined (__SSE2__) && !defined (__sun__) #include +#ifdef __SSE4_1__ +#include +#endif #endif /* Notes about these *_SCALING values. @@ -285,6 +288,12 @@ void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigne __m128i y = _mm_cvttps_epi32(clipped); __m128i shifted = _mm_slli_epi32(y, 8); +#ifdef __SSE4_1__ + *(int32_t*)dst = _mm_extract_epi32(shifted, 0); + *(int32_t*)(dst+dst_skip) = _mm_extract_epi32(shifted, 1); + *(int32_t*)(dst+2*dst_skip) = _mm_extract_epi32(shifted, 2); + *(int32_t*)(dst+3*dst_skip) = _mm_extract_epi32(shifted, 3); +#else __m128i shuffled1 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(0, 3, 2, 1)); __m128i shuffled2 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(1, 0, 3, 2)); __m128i shuffled3 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(2, 1, 0, 3)); @@ -294,6 +303,7 @@ void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigne _mm_store_ss((float*)(dst+dst_skip), (__m128)shuffled1); _mm_store_ss((float*)(dst+2*dst_skip), (__m128)shuffled2); _mm_store_ss((float*)(dst+3*dst_skip), (__m128)shuffled3); +#endif dst += 4*dst_skip; src+= 4; @@ -421,6 +431,12 @@ void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned l __m128 samples = _mm_loadu_ps(src); __m128i converted = float_24_sse(samples); +#ifdef __SSE4_1__ + z[0] = _mm_extract_epi32(converted, 0); + z[1] = _mm_extract_epi32(converted, 1); + z[2] = _mm_extract_epi32(converted, 2); + z[3] = _mm_extract_epi32(converted, 3); +#else __m128i shuffled1 = _mm_shuffle_epi32(converted, _MM_SHUFFLE(0, 3, 2, 1)); __m128i shuffled2 = _mm_shuffle_epi32(converted, _MM_SHUFFLE(1, 0, 3, 2)); __m128i shuffled3 = _mm_shuffle_epi32(converted, _MM_SHUFFLE(2, 1, 0, 3)); @@ -431,13 +447,11 @@ void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned l _mm_store_ss((float*)z+3, (__m128)shuffled3); for (i = 0; i != 4; ++i) { -#if __BYTE_ORDER == __LITTLE_ENDIAN memcpy (dst, z+i, 3); -#elif __BYTE_ORDER == __BIG_ENDIAN - memcpy (dst, (float*)((char *)&z + 1)+i, 3); -#endif dst += dst_skip; } +#endif + nsamples -= 4; src += 4; } @@ -500,17 +514,10 @@ void sample_move_dS_s24 (jack_default_audio_sample_t *dst, char *src, unsigned l while (nsamples >= 4) { int x0, x1, x2, x3; -#if __BYTE_ORDER == __LITTLE_ENDIAN memcpy((char*)&x0 + 1, src, 3); memcpy((char*)&x1 + 1, src+src_skip, 3); memcpy((char*)&x2 + 1, src+2*src_skip, 3); memcpy((char*)&x3 + 1, src+3*src_skip, 3); -#elif __BYTE_ORDER == __BIG_ENDIAN - memcpy(&x0, src, 3); - memcpy(&x1, src+src_skip, 3); - memcpy(&x2, src+2*src_skip, 3); - memcpy(&x3, src+3*src_skip, 3); -#endif src += 4 * src_skip; const __m128i block_i = _mm_set_epi32(x3, x2, x1, x0); diff --git a/dbus/controller_iface_control.c b/dbus/controller_iface_control.c index f55fb608..768c192f 100644 --- a/dbus/controller_iface_control.c +++ b/dbus/controller_iface_control.c @@ -340,7 +340,7 @@ JACK_DBUS_METHOD_ARGUMENTS_BEGIN(LoadInternal) JACK_DBUS_METHOD_ARGUMENT("internal", "s", false) JACK_DBUS_METHOD_ARGUMENTS_END -JACK_DBUS_METHOD_ARGUMENTS_BEGIN(UnlooadInternal) +JACK_DBUS_METHOD_ARGUMENTS_BEGIN(UnloadInternal) JACK_DBUS_METHOD_ARGUMENT("internal", "s", false) JACK_DBUS_METHOD_ARGUMENTS_END @@ -366,7 +366,7 @@ JACK_DBUS_METHODS_BEGIN JACK_DBUS_METHOD_DESCRIBE(IsRealtime, NULL) JACK_DBUS_METHOD_DESCRIBE(ResetXruns, NULL) JACK_DBUS_METHOD_DESCRIBE(LoadInternal, NULL) - JACK_DBUS_METHOD_DESCRIBE(UnlooadInternal, NULL) + JACK_DBUS_METHOD_DESCRIBE(UnloadInternal, NULL) JACK_DBUS_METHOD_DESCRIBE(AddSlave, NULL) JACK_DBUS_METHOD_DESCRIBE(RemoveSlave, NULL) JACK_DBUS_METHODS_END diff --git a/macosx/JackMacEngineRPC.cpp b/macosx/JackMacEngineRPC.cpp index 7d28b619..4ddb0b1c 100644 --- a/macosx/JackMacEngineRPC.cpp +++ b/macosx/JackMacEngineRPC.cpp @@ -59,12 +59,12 @@ rpc_type server_rpc_jack_client_close(mach_port_t private_port, int refnum, int* return KERN_SUCCESS; } -rpc_type server_rpc_jack_client_activate(mach_port_t private_port, int refnum, int state, int* result) +rpc_type server_rpc_jack_client_activate(mach_port_t private_port, int refnum, int is_real_time, int* result) { jack_log("rpc_jack_client_activate"); JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; assert(channel); - *result = channel->GetEngine()->ClientActivate(refnum, state); + *result = channel->GetEngine()->ClientActivate(refnum, is_real_time); return KERN_SUCCESS; } @@ -83,7 +83,7 @@ rpc_type server_rpc_jack_client_deactivate(mach_port_t private_port, int refnum, rpc_type server_rpc_jack_port_register(mach_port_t private_port, int refnum, client_port_name_t name, client_port_type_t type, unsigned int flags, unsigned int buffer_size, unsigned int* port_index, int* result) { - jack_log("rpc_jack_port_register ref = %ld name = %s", refnum, name); + jack_log("rpc_jack_port_register ref = %d name = %s", refnum, name); JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; assert(channel); *result = channel->GetEngine()->PortRegister(refnum, name, type, flags, buffer_size, port_index); @@ -92,7 +92,7 @@ rpc_type server_rpc_jack_port_register(mach_port_t private_port, int refnum, cli rpc_type server_rpc_jack_port_unregister(mach_port_t private_port, int refnum, int port, int* result) { - jack_log("rpc_jack_port_unregister ref = %ld port = %ld ", refnum, port); + jack_log("rpc_jack_port_unregister ref = %d port = %d ", refnum, port); JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; assert(channel); *result = channel->GetEngine()->PortUnRegister(refnum, port); @@ -234,7 +234,7 @@ rpc_type server_rpc_jack_internal_clientunload(mach_port_t private_port, int ref rpc_type server_rpc_jack_client_rt_notify(mach_port_t server_port, int refnum, int notify, int value) { - jack_log("rpc_jack_client_rt_notify ref = %ld notify = %ld value = %ld", refnum, notify, value); + jack_log("rpc_jack_client_rt_notify ref = %d notify = %d value = %d", refnum, notify, value); JackMachServerChannel* channel = JackMachServerChannel::fPortTable[server_port]; assert(channel); assert(channel->GetServer()); diff --git a/macosx/JackMacLibClientRPC.cpp b/macosx/JackMacLibClientRPC.cpp index 07f5e51c..b70878a1 100644 --- a/macosx/JackMacLibClientRPC.cpp +++ b/macosx/JackMacLibClientRPC.cpp @@ -27,21 +27,21 @@ using namespace Jack; #define rpc_type kern_return_t // for astyle -rpc_type rpc_jack_client_sync_notify(mach_port_t client_port, int refnum, client_name_t name, int notify, int value1, int value2, int* result) +rpc_type rpc_jack_client_sync_notify(mach_port_t client_port, int refnum, client_name_t name, int notify, message_t message, int value1, int value2, int* result) { - jack_log("rpc_jack_client_sync_notify ref = %ld name = %s notify = %ld val1 = %ld val2 = %ld", refnum, name, notify, value1, value2); + jack_log("rpc_jack_client_sync_notify ref = %ld name = %s notify = %ld message %s val1 = %ld val2 = %ld", refnum, name, notify, message, value1, value2); JackClient* client = gClientTable[client_port]; assert(client); - *result = client->ClientNotify(refnum, name, notify, true, value1, value2); + *result = client->ClientNotify(refnum, name, notify, true, message, value1, value2); return KERN_SUCCESS; } -rpc_type rpc_jack_client_async_notify(mach_port_t client_port, int refnum, client_name_t name, int notify, int value1, int value2) +rpc_type rpc_jack_client_async_notify(mach_port_t client_port, int refnum, client_name_t name, int notify, message_t message, int value1, int value2) { - jack_log("rpc_jack_client_async_notify ref = %ld name = %s notify = %ld val1 = %ld val2 = %ld", refnum, name, notify, value1, value2); + jack_log("rpc_jack_client_async_notify ref = %ld name = %s notify = %ld message %s val1 = %ld val2 = %ld", refnum, name, notify, message, value1, value2); JackClient* client = gClientTable[client_port]; assert(client); - client->ClientNotify(refnum, name, notify, false, value1, value2); + client->ClientNotify(refnum, name, notify, false, message, value1, value2); return KERN_SUCCESS; } diff --git a/macosx/JackMachClientChannel.cpp b/macosx/JackMachClientChannel.cpp index d3d81bdd..c666bbb3 100644 --- a/macosx/JackMachClientChannel.cpp +++ b/macosx/JackMachClientChannel.cpp @@ -154,9 +154,9 @@ void JackMachClientChannel::ClientClose(int refnum, int* result) } } -void JackMachClientChannel::ClientActivate(int refnum, int state, int* result) +void JackMachClientChannel::ClientActivate(int refnum, int is_real_time, int* result) { - kern_return_t res = rpc_jack_client_activate(fPrivatePort, refnum, state, result); + kern_return_t res = rpc_jack_client_activate(fPrivatePort, refnum, is_real_time, result); if (res != KERN_SUCCESS) { *result = -1; jack_error("JackMachClientChannel::ClientActivate err = %s", mach_error_string(res)); diff --git a/macosx/JackMachClientChannel.h b/macosx/JackMachClientChannel.h index 9e323cf5..379fb535 100644 --- a/macosx/JackMachClientChannel.h +++ b/macosx/JackMachClientChannel.h @@ -61,7 +61,7 @@ class JackMachClientChannel : public detail::JackClientChannelInterface, public {} void ClientClose(int refnum, int* result); - void ClientActivate(int refnum, int state, int* result); + void ClientActivate(int refnum, int is_real_time, int* result); void ClientDeactivate(int refnum, int* result); void PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result); diff --git a/macosx/JackMachNotifyChannel.cpp b/macosx/JackMachNotifyChannel.cpp index 86236304..56d6b425 100644 --- a/macosx/JackMachNotifyChannel.cpp +++ b/macosx/JackMachNotifyChannel.cpp @@ -49,11 +49,11 @@ void JackMachNotifyChannel::Close() fClientPort.DisconnectPort(); } -void JackMachNotifyChannel::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2, int* result) +void JackMachNotifyChannel::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2, int* result) { kern_return_t res = (sync) - ? rpc_jack_client_sync_notify(fClientPort.GetPort(), refnum, (char*)name, notify, value1, value2, result) - : rpc_jack_client_async_notify(fClientPort.GetPort(), refnum, (char*)name, notify, value1, value2); + ? rpc_jack_client_sync_notify(fClientPort.GetPort(), refnum, (char*)name, notify, (char*)message, value1, value2, result) + : rpc_jack_client_async_notify(fClientPort.GetPort(), refnum, (char*)name, notify, (char*)message, value1, value2); if (res == KERN_SUCCESS) { *result = 0; } else { diff --git a/macosx/JackMachNotifyChannel.h b/macosx/JackMachNotifyChannel.h index 14afeb3f..ab99fef4 100644 --- a/macosx/JackMachNotifyChannel.h +++ b/macosx/JackMachNotifyChannel.h @@ -44,7 +44,7 @@ class JackMachNotifyChannel int Open(const char* name); // Open the Server/Client connection void Close(); // Close the Server/Client connection - void ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2, int* result); + void ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2, int* result); }; } // end of namespace diff --git a/macosx/JackMachServerChannel.cpp b/macosx/JackMachServerChannel.cpp index 84d87b93..5b646c56 100644 --- a/macosx/JackMachServerChannel.cpp +++ b/macosx/JackMachServerChannel.cpp @@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackServer.h" #include "JackLockedEngine.h" #include "JackNotification.h" +#include "JackServerGlobals.h" using namespace std; @@ -49,11 +50,6 @@ int JackMachServerChannel::Open(const char* server_name, JackServer* server) return -1; } - if (fThread.Start() != 0) { - jack_error("Cannot start Jack server listener"); - return -1; - } - fServer = server; fPortTable[fServerPort.GetPort()] = this; return 0; @@ -65,6 +61,16 @@ void JackMachServerChannel::Close() fThread.Kill(); fServerPort.DestroyPort(); } + +int JackMachServerChannel::Start() +{ + if (fThread.Start() != 0) { + jack_error("Cannot start Jack server listener"); + return -1; + } + + return 0; +} JackLockedEngine* JackMachServerChannel::GetEngine() { @@ -137,6 +143,10 @@ boolean_t JackMachServerChannel::MessageHandler(mach_msg_header_t* Request, mach channel->ClientKill(Request->msgh_local_port); } else { JackRPCEngine_server(Request, Reply); + // Issued by JackEngine::ReleaseRefnum when temporary mode is used + if (JackServerGlobals::fKilled) { + kill(JackTools::GetPID(), SIGINT); + } } return true; } diff --git a/macosx/JackMachServerChannel.h b/macosx/JackMachServerChannel.h index 9e5ac35f..fc5a100b 100644 --- a/macosx/JackMachServerChannel.h +++ b/macosx/JackMachServerChannel.h @@ -53,7 +53,9 @@ class JackMachServerChannel : public JackRunnableInterface int Open(const char* server_name, JackServer* server); // Open the Server/Client connection void Close(); // Close the Server/Client connection - + + int Start(); + JackLockedEngine* GetEngine(); JackServer* GetServer(); @@ -64,6 +66,7 @@ class JackMachServerChannel : public JackRunnableInterface bool Execute(); + // Has to be public.. static std::map fPortTable; }; diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index d6c37727..4d5d42c8 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -86,7 +86,6 @@ 4BFA99540AAAED90009E916C /* PBXTargetDependency */, 4B363E750DEB0838001F72D9 /* PBXTargetDependency */, 4B363E770DEB0838001F72D9 /* PBXTargetDependency */, - 4B363EF20DEB0965001F72D9 /* PBXTargetDependency */, 4B363F250DEB0ABE001F72D9 /* PBXTargetDependency */, 4B363F530DEB0CFE001F72D9 /* PBXTargetDependency */, 4B363F780DEB0D85001F72D9 /* PBXTargetDependency */, @@ -845,13 +844,6 @@ remoteGlobalIDString = 4B363E440DEB0775001F72D9; remoteInfo = "jack_bufsize Universal"; }; - 4B363EF10DEB0965001F72D9 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4B363EDF0DEB091C001F72D9; - remoteInfo = "jack_rec Universal"; - }; 4B363F240DEB0ABE001F72D9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; @@ -1233,7 +1225,7 @@ 4B363EED0DEB094B001F72D9 /* capture_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = capture_client.c; path = "../example-clients/capture_client.c"; sourceTree = SOURCE_ROOT; }; 4B363F1E0DEB0A6A001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363F220DEB0AB0001F72D9 /* monitor_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = monitor_client.c; path = "../example-clients/monitor_client.c"; sourceTree = SOURCE_ROOT; }; - 4B363F350DEB0BD1001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B363F350DEB0BD1001F72D9 /* jack_showtime */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_showtime; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363F3D0DEB0C31001F72D9 /* showtime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = showtime.c; path = "../example-clients/showtime.c"; sourceTree = SOURCE_ROOT; }; 4B363F720DEB0D4E001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363F750DEB0D7D001F72D9 /* impulse_grabber.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = impulse_grabber.c; path = "../example-clients/impulse_grabber.c"; sourceTree = SOURCE_ROOT; }; @@ -2165,7 +2157,7 @@ 4B363E4E0DEB0775001F72D9 /* jack_midiseq */, 4B363EE90DEB091C001F72D9 /* jack_midiseq */, 4B363F1E0DEB0A6A001F72D9 /* jack_midiseq */, - 4B363F350DEB0BD1001F72D9 /* jack_midiseq */, + 4B363F350DEB0BD1001F72D9 /* jack_showtime */, 4B363F720DEB0D4E001F72D9 /* jack_midiseq */, 4BFA5E980DEC4D9C00FA4CDB /* testSem */, 4BFA828C0DF6A9E40087B4E1 /* jack_midiseq */, @@ -4186,7 +4178,7 @@ name = "jack_showtime Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4B363F350DEB0BD1001F72D9 /* jack_midiseq */; + productReference = 4B363F350DEB0BD1001F72D9 /* jack_showtime */; productType = "com.apple.product-type.tool"; }; 4B363F680DEB0D4E001F72D9 /* jack_impulse_grabber Universal */ = { @@ -6588,11 +6580,6 @@ target = 4B363E440DEB0775001F72D9 /* jack_bufsize Universal */; targetProxy = 4B363E760DEB0838001F72D9 /* PBXContainerItemProxy */; }; - 4B363EF20DEB0965001F72D9 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4B363EDF0DEB091C001F72D9 /* jack_rec Universal */; - targetProxy = 4B363EF10DEB0965001F72D9 /* PBXContainerItemProxy */; - }; 4B363F250DEB0ABE001F72D9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B363F140DEB0A6A001F72D9 /* jack_monitor_client Universal */; @@ -6923,12 +6910,8 @@ 4B0A292B0D52108E002EFF74 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - i386, - ppc, - ppc64, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; @@ -7130,12 +7113,8 @@ 4B35C4220D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; FRAMEWORK_SEARCH_PATHS = ""; @@ -7191,12 +7170,8 @@ 4B35C4230D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = dwarf; FRAMEWORK_SEARCH_PATHS = ""; @@ -7307,12 +7282,8 @@ 4B35C4800D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DEBUG_INFORMATION_FORMAT = dwarf; @@ -7375,12 +7346,8 @@ 4B35C4810D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; @@ -7506,12 +7473,8 @@ 4B35C4F90D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DEBUG_INFORMATION_FORMAT = dwarf; @@ -7574,12 +7537,8 @@ 4B35C4FA0D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; @@ -7744,12 +7703,8 @@ 4B35C5120D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -7847,12 +7802,8 @@ 4B35C51E0D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -7950,12 +7901,8 @@ 4B35C52A0D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -8051,12 +7998,8 @@ 4B35C5360D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -8148,12 +8091,8 @@ 4B35C5420D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; @@ -8244,12 +8183,8 @@ 4B35C54E0D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; @@ -8340,12 +8275,8 @@ 4B35C55C0D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; @@ -8439,12 +8370,8 @@ 4B35C5680D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -8539,12 +8466,8 @@ 4B35C5740D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -8650,12 +8573,8 @@ 4B35C5840D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -8763,12 +8682,8 @@ 4B35C5980D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; @@ -8865,12 +8780,8 @@ 4B35C5A40D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; @@ -8961,12 +8872,8 @@ 4B35C5B00D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; @@ -9057,12 +8964,8 @@ 4B35C5BC0D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; @@ -9153,12 +9056,8 @@ 4B35C5C80D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; @@ -9249,12 +9148,8 @@ 4B35C5D40D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; @@ -9354,12 +9249,8 @@ 4B35C5E80D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ( @@ -9474,12 +9365,8 @@ 4B35C5FC0D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ( @@ -9593,12 +9480,8 @@ 4B35C6100D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ( @@ -9724,12 +9607,8 @@ 4B35C61C0D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -9879,12 +9758,8 @@ 4B35C6270D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -10034,12 +9909,8 @@ 4B35C6320D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -10179,12 +10050,8 @@ 4B35C63C0D4731D3000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -10775,7 +10642,6 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( - "-lsndfile", "-framework", Jackmp, "-framework", @@ -10873,7 +10739,6 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( - "-lsndfile", "-framework", Jackmp, "-framework", @@ -10971,7 +10836,6 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( - "-lsndfile", "-framework", Jackmp, "-framework", @@ -11216,7 +11080,7 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "ppc i386 ppc64 x86_64"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -14419,7 +14283,7 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "ppc i386 ppc64 x86_64"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -14567,7 +14431,7 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "ppc i386 ppc64 x86_64"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -14709,7 +14573,7 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "ppc i386 ppc64 x86_64"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -14852,8 +14716,7 @@ 4BDCDBFD1001FD7300B15929 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -14997,8 +14860,7 @@ 4BDCDC231001FDE300B15929 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -15574,12 +15436,8 @@ 4BFA828A0DF6A9E40087B4E1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -15677,12 +15535,8 @@ 4BFA829D0DF6A9E40087B4E1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -15783,12 +15637,8 @@ 4BFA82A90DF6A9E40087B4E1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -15889,12 +15739,8 @@ 4BFA82B50DF6A9E40087B4E1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -15902,7 +15748,6 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( - "-lsndfile", "-framework", Jackmp, "-framework", @@ -15991,12 +15836,8 @@ 4BFA82C10DF6A9E40087B4E1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -16004,7 +15845,6 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( - "-lsndfile", "-framework", Jackmp, "-framework", @@ -16093,12 +15933,8 @@ 4BFA82CD0DF6A9E40087B4E1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -16106,7 +15942,6 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( - "-lsndfile", "-framework", Jackmp, "-framework", diff --git a/macosx/RPC/JackRPCClient.defs b/macosx/RPC/JackRPCClient.defs index ea5489ca..3c3eb515 100644 --- a/macosx/RPC/JackRPCClient.defs +++ b/macosx/RPC/JackRPCClient.defs @@ -24,14 +24,15 @@ subsystem JackRPCClient 1000; import "Jackdefs.h"; waittime 5000; -type client_name_t = c_string[128]; -type client_port_name_t = c_string[128]; +type client_name_t = c_string[64]; +type message_t = c_string[256]; routine rpc_jack_client_sync_notify( client_port : mach_port_t; refnum : int; client_name : client_name_t; notify : int; + message : message_t; value1 : int; value2 : int; out result : int); @@ -41,5 +42,6 @@ simpleroutine rpc_jack_client_async_notify( refnum : int; client_name : client_name_t; notify : int; + message : message_t; value1 : int; value2 : int); diff --git a/macosx/RPC/JackRPCClient.h b/macosx/RPC/JackRPCClient.h index 72c53fda..d4462479 100644 --- a/macosx/RPC/JackRPCClient.h +++ b/macosx/RPC/JackRPCClient.h @@ -21,7 +21,7 @@ typedef struct { char *name; function_ptr_t function; } function_table_entry; -typedef function_table_entry *function_table_t; +typedef function_table_entry *function_table_t; #endif /* FUNCTION_PTR_T */ #endif /* AUTOTEST */ @@ -55,6 +55,7 @@ kern_return_t rpc_jack_client_sync_notify int refnum, client_name_t client_name, int notify, + message_t message, int value1, int value2, int *result @@ -72,6 +73,7 @@ kern_return_t rpc_jack_client_async_notify int refnum, client_name_t client_name, int notify, + message_t message, int value1, int value2 ); @@ -103,6 +105,7 @@ __END_DECLS int refnum; client_name_t client_name; int notify; + message_t message; int value1; int value2; } __Request__rpc_jack_client_sync_notify_t; @@ -119,6 +122,7 @@ __END_DECLS int refnum; client_name_t client_name; int notify; + message_t message; int value1; int value2; } __Request__rpc_jack_client_async_notify_t; diff --git a/macosx/RPC/JackRPCClientServer.c b/macosx/RPC/JackRPCClientServer.c index efb4e9e9..7f5af274 100644 --- a/macosx/RPC/JackRPCClientServer.c +++ b/macosx/RPC/JackRPCClientServer.c @@ -1,7 +1,7 @@ /* * IDENTIFICATION: - * stub generated Mon Sep 1 17:42:27 2008 - * with a MiG generated Tue Feb 19 02:01:43 PST 2008 by root@b75.local + * stub generated Fri Oct 23 10:35:08 2009 + * with a MiG generated Mon May 18 09:59:33 PDT 2009 by root@sulitlana.apple.com * OPTIONS: */ @@ -113,6 +113,7 @@ int refnum; client_name_t client_name; int notify; + message_t message; int value1; int value2; } __Request__rpc_jack_client_sync_notify_t; @@ -129,6 +130,7 @@ int refnum; client_name_t client_name; int notify; + message_t message; int value1; int value2; } __Request__rpc_jack_client_async_notify_t; @@ -224,11 +226,11 @@ mig_internal novalue _Xrpc_jack_client_async_notify #elif defined(__NDR_convert__int_rep__JackRPCClient__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCClient__string(a, f, 128) + __NDR_convert__int_rep__JackRPCClient__string(a, f, 64) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) + __NDR_convert__int_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined */ @@ -252,6 +254,26 @@ mig_internal novalue _Xrpc_jack_client_async_notify #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify__defined */ +#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#if defined(__NDR_convert__int_rep__JackRPCClient__message_t__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__int_rep__JackRPCClient__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__int_rep__message_t__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__int_rep__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__int_rep__JackRPCClient__string__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__int_rep__JackRPCClient__string(a, f, 256) +#elif defined(__NDR_convert__int_rep__string__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__int_rep__string(a, f, 256) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined */ + #ifndef __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1__defined #if defined(__NDR_convert__int_rep__JackRPCClient__int__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1__defined @@ -324,11 +346,11 @@ mig_internal novalue _Xrpc_jack_client_async_notify #elif defined(__NDR_convert__char_rep__JackRPCClient__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCClient__string(a, f, 128) + __NDR_convert__char_rep__JackRPCClient__string(a, f, 64) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) + __NDR_convert__char_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined */ @@ -352,6 +374,26 @@ mig_internal novalue _Xrpc_jack_client_async_notify #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify__defined */ +#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#if defined(__NDR_convert__char_rep__JackRPCClient__message_t__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__char_rep__JackRPCClient__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__char_rep__message_t__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__char_rep__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__char_rep__JackRPCClient__string__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__char_rep__JackRPCClient__string(a, f, 256) +#elif defined(__NDR_convert__char_rep__string__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__char_rep__string(a, f, 256) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined */ + #ifndef __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1__defined #if defined(__NDR_convert__char_rep__JackRPCClient__int__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1__defined @@ -424,11 +466,11 @@ mig_internal novalue _Xrpc_jack_client_async_notify #elif defined(__NDR_convert__float_rep__JackRPCClient__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCClient__string(a, f, 128) + __NDR_convert__float_rep__JackRPCClient__string(a, f, 64) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) + __NDR_convert__float_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined */ @@ -452,6 +494,26 @@ mig_internal novalue _Xrpc_jack_client_async_notify #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify__defined */ +#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#if defined(__NDR_convert__float_rep__JackRPCClient__message_t__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__float_rep__JackRPCClient__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__float_rep__message_t__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__float_rep__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__float_rep__JackRPCClient__string__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__float_rep__JackRPCClient__string(a, f, 256) +#elif defined(__NDR_convert__float_rep__string__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__float_rep__string(a, f, 256) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined */ + #ifndef __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1__defined #if defined(__NDR_convert__float_rep__JackRPCClient__int__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1__defined @@ -503,9 +565,24 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_sync_notify_t(_ return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->client_name), 64); + if (( memchr(In0P->client_name, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + memchr_limit = min((msg_limit - In0P->message), 256); + if (( memchr(In0P->message, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #if defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify__defined) || \ + defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value2__defined) if (In0P->NDR.int_rep != NDR_record.int_rep) { @@ -518,6 +595,9 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_sync_notify_t(_ #if defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify__defined) __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify(&In0P->notify, In0P->NDR.int_rep); #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify__defined */ +#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined) + __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message(&In0P->message, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined */ #if defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1__defined) __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1(&In0P->value1, In0P->NDR.int_rep); #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1__defined */ @@ -530,6 +610,7 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_sync_notify_t(_ #if defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined) || \ defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined) || \ defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify__defined) || \ + defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined) || \ defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1__defined) || \ defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value2__defined) if (In0P->NDR.char_rep != NDR_record.char_rep) { @@ -542,6 +623,9 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_sync_notify_t(_ #if defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify__defined) __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify(&In0P->notify, In0P->NDR.char_rep); #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify__defined */ +#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined) + __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message(&In0P->message, In0P->NDR.char_rep); +#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined */ #if defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1__defined) __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1(&In0P->value1, In0P->NDR.char_rep); #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1__defined */ @@ -554,6 +638,7 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_sync_notify_t(_ #if defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined) || \ defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined) || \ defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify__defined) || \ + defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined) || \ defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1__defined) || \ defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value2__defined) if (In0P->NDR.float_rep != NDR_record.float_rep) { @@ -566,6 +651,9 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_sync_notify_t(_ #if defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify__defined) __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify(&In0P->notify, In0P->NDR.float_rep); #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify__defined */ +#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined) + __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message(&In0P->message, In0P->NDR.float_rep); +#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined */ #if defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1__defined) __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1(&In0P->value1, In0P->NDR.float_rep); #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1__defined */ @@ -594,6 +682,7 @@ kern_return_t rpc_jack_client_sync_notify int refnum, client_name_t client_name, int notify, + message_t message, int value1, int value2, int *result @@ -613,6 +702,7 @@ mig_internal novalue _Xrpc_jack_client_sync_notify int refnum; client_name_t client_name; int notify; + message_t message; int value1; int value2; mach_msg_trailer_t trailer; @@ -646,7 +736,7 @@ mig_internal novalue _Xrpc_jack_client_sync_notify { MIG_RETURN_ERROR(OutP, check_result); } #endif /* defined(__MIG_check__Request__rpc_jack_client_sync_notify_t__defined) */ - OutP->RetCode = rpc_jack_client_sync_notify(In0P->Head.msgh_request_port, In0P->refnum, In0P->client_name, In0P->notify, In0P->value1, In0P->value2, &OutP->result); + OutP->RetCode = rpc_jack_client_sync_notify(In0P->Head.msgh_request_port, In0P->refnum, In0P->client_name, In0P->notify, In0P->message, In0P->value1, In0P->value2, &OutP->result); if (OutP->RetCode != KERN_SUCCESS) { MIG_RETURN_ERROR(OutP, OutP->RetCode); } @@ -694,11 +784,11 @@ mig_internal novalue _Xrpc_jack_client_sync_notify #elif defined(__NDR_convert__int_rep__JackRPCClient__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCClient__string(a, f, 128) + __NDR_convert__int_rep__JackRPCClient__string(a, f, 64) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) + __NDR_convert__int_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name__defined */ @@ -722,6 +812,26 @@ mig_internal novalue _Xrpc_jack_client_sync_notify #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify__defined */ +#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined +#if defined(__NDR_convert__int_rep__JackRPCClient__message_t__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__int_rep__JackRPCClient__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__int_rep__message_t__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__int_rep__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__int_rep__JackRPCClient__string__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__int_rep__JackRPCClient__string(a, f, 256) +#elif defined(__NDR_convert__int_rep__string__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__int_rep__string(a, f, 256) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined */ + #ifndef __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1__defined #if defined(__NDR_convert__int_rep__JackRPCClient__int__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1__defined @@ -794,11 +904,11 @@ mig_internal novalue _Xrpc_jack_client_sync_notify #elif defined(__NDR_convert__char_rep__JackRPCClient__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCClient__string(a, f, 128) + __NDR_convert__char_rep__JackRPCClient__string(a, f, 64) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) + __NDR_convert__char_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name__defined */ @@ -822,6 +932,26 @@ mig_internal novalue _Xrpc_jack_client_sync_notify #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify__defined */ +#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined +#if defined(__NDR_convert__char_rep__JackRPCClient__message_t__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__char_rep__JackRPCClient__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__char_rep__message_t__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__char_rep__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__char_rep__JackRPCClient__string__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__char_rep__JackRPCClient__string(a, f, 256) +#elif defined(__NDR_convert__char_rep__string__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__char_rep__string(a, f, 256) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined */ + #ifndef __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1__defined #if defined(__NDR_convert__char_rep__JackRPCClient__int__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1__defined @@ -894,11 +1024,11 @@ mig_internal novalue _Xrpc_jack_client_sync_notify #elif defined(__NDR_convert__float_rep__JackRPCClient__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCClient__string(a, f, 128) + __NDR_convert__float_rep__JackRPCClient__string(a, f, 64) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) + __NDR_convert__float_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name__defined */ @@ -922,6 +1052,26 @@ mig_internal novalue _Xrpc_jack_client_sync_notify #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify__defined */ +#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined +#if defined(__NDR_convert__float_rep__JackRPCClient__message_t__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__float_rep__JackRPCClient__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__float_rep__message_t__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__float_rep__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__float_rep__JackRPCClient__string__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__float_rep__JackRPCClient__string(a, f, 256) +#elif defined(__NDR_convert__float_rep__string__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__float_rep__string(a, f, 256) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined */ + #ifndef __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1__defined #if defined(__NDR_convert__float_rep__JackRPCClient__int__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1__defined @@ -973,9 +1123,24 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_async_notify_t( return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->client_name), 64); + if (( memchr(In0P->client_name, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + memchr_limit = min((msg_limit - In0P->message), 256); + if (( memchr(In0P->message, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #if defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__refnum__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify__defined) || \ + defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value2__defined) if (In0P->NDR.int_rep != NDR_record.int_rep) { @@ -988,6 +1153,9 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_async_notify_t( #if defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify__defined) __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify(&In0P->notify, In0P->NDR.int_rep); #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify__defined */ +#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined) + __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message(&In0P->message, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined */ #if defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1__defined) __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1(&In0P->value1, In0P->NDR.int_rep); #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1__defined */ @@ -1000,6 +1168,7 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_async_notify_t( #if defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__refnum__defined) || \ defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name__defined) || \ defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify__defined) || \ + defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined) || \ defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1__defined) || \ defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value2__defined) if (In0P->NDR.char_rep != NDR_record.char_rep) { @@ -1012,6 +1181,9 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_async_notify_t( #if defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify__defined) __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify(&In0P->notify, In0P->NDR.char_rep); #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify__defined */ +#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined) + __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message(&In0P->message, In0P->NDR.char_rep); +#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined */ #if defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1__defined) __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1(&In0P->value1, In0P->NDR.char_rep); #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1__defined */ @@ -1024,6 +1196,7 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_async_notify_t( #if defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__refnum__defined) || \ defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name__defined) || \ defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify__defined) || \ + defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined) || \ defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1__defined) || \ defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value2__defined) if (In0P->NDR.float_rep != NDR_record.float_rep) { @@ -1036,6 +1209,9 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_async_notify_t( #if defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify__defined) __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify(&In0P->notify, In0P->NDR.float_rep); #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify__defined */ +#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined) + __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message(&In0P->message, In0P->NDR.float_rep); +#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined */ #if defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1__defined) __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1(&In0P->value1, In0P->NDR.float_rep); #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1__defined */ @@ -1064,6 +1240,7 @@ kern_return_t rpc_jack_client_async_notify int refnum, client_name_t client_name, int notify, + message_t message, int value1, int value2 ); @@ -1082,6 +1259,7 @@ mig_internal novalue _Xrpc_jack_client_async_notify int refnum; client_name_t client_name; int notify; + message_t message; int value1; int value2; mach_msg_trailer_t trailer; @@ -1115,7 +1293,7 @@ mig_internal novalue _Xrpc_jack_client_async_notify { MIG_RETURN_ERROR(OutP, check_result); } #endif /* defined(__MIG_check__Request__rpc_jack_client_async_notify_t__defined) */ - OutP->RetCode = rpc_jack_client_async_notify(In0P->Head.msgh_request_port, In0P->refnum, In0P->client_name, In0P->notify, In0P->value1, In0P->value2); + OutP->RetCode = rpc_jack_client_async_notify(In0P->Head.msgh_request_port, In0P->refnum, In0P->client_name, In0P->notify, In0P->message, In0P->value1, In0P->value2); __AfterRcvSimple(1001, "rpc_jack_client_async_notify") } @@ -1145,9 +1323,9 @@ const struct JackRPCClient_subsystem { (vm_address_t)0, { { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_sync_notify, 7, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_sync_notify_t)}, + (mig_stub_routine_t) _Xrpc_jack_client_sync_notify, 8, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_sync_notify_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_async_notify, 6, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_async_notify_t)}, + (mig_stub_routine_t) _Xrpc_jack_client_async_notify, 7, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_async_notify_t)}, } }; diff --git a/macosx/RPC/JackRPCClientUser.c b/macosx/RPC/JackRPCClientUser.c index 4dc66a10..e6fef35e 100644 --- a/macosx/RPC/JackRPCClientUser.c +++ b/macosx/RPC/JackRPCClientUser.c @@ -1,7 +1,7 @@ /* * IDENTIFICATION: - * stub generated Mon Sep 1 17:42:27 2008 - * with a MiG generated Tue Feb 19 02:01:43 PST 2008 by root@b75.local + * stub generated Fri Oct 23 10:35:08 2009 + * with a MiG generated Mon May 18 09:59:33 PDT 2009 by root@sulitlana.apple.com * OPTIONS: */ #define __MIG_check__Reply__JackRPCClient_subsystem__ 1 @@ -50,15 +50,15 @@ #ifndef __MachMsgErrorWithTimeout #define __MachMsgErrorWithTimeout(_R_) { \ switch (_R_) { \ - case MACH_SEND_INVALID_REPLY: \ - case MACH_RCV_INVALID_NAME: \ - case MACH_RCV_PORT_DIED: \ - case MACH_RCV_PORT_CHANGED: \ - case MACH_RCV_TIMED_OUT: \ - mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ + case MACH_SEND_INVALID_DATA: \ + case MACH_SEND_INVALID_DEST: \ + case MACH_SEND_INVALID_HEADER: \ + mig_put_reply_port(InP->Head.msgh_reply_port); \ break; \ + case MACH_SEND_TIMED_OUT: \ + case MACH_RCV_TIMED_OUT: \ default: \ - mig_put_reply_port(InP->Head.msgh_reply_port); \ + mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ } \ } #endif /* __MachMsgErrorWithTimeout */ @@ -66,14 +66,13 @@ #ifndef __MachMsgErrorWithoutTimeout #define __MachMsgErrorWithoutTimeout(_R_) { \ switch (_R_) { \ - case MACH_SEND_INVALID_REPLY: \ - case MACH_RCV_INVALID_NAME: \ - case MACH_RCV_PORT_DIED: \ - case MACH_RCV_PORT_CHANGED: \ - mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ + case MACH_SEND_INVALID_DATA: \ + case MACH_SEND_INVALID_DEST: \ + case MACH_SEND_INVALID_HEADER: \ + mig_put_reply_port(InP->Head.msgh_reply_port); \ break; \ default: \ - mig_put_reply_port(InP->Head.msgh_reply_port); \ + mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ } \ } #endif /* __MachMsgErrorWithoutTimeout */ @@ -265,6 +264,7 @@ mig_external kern_return_t rpc_jack_client_sync_notify int refnum, client_name_t client_name, int notify, + message_t message, int value1, int value2, int *result @@ -280,6 +280,7 @@ mig_external kern_return_t rpc_jack_client_sync_notify int refnum; client_name_t client_name; int notify; + message_t message; int value1; int value2; } Request; @@ -341,10 +342,12 @@ mig_external kern_return_t rpc_jack_client_sync_notify InP->refnum = refnum; - (void) mig_strncpy(InP->client_name, client_name, 128); + (void) mig_strncpy(InP->client_name, client_name, 64); InP->notify = notify; + (void) mig_strncpy(InP->message, message, 256); + InP->value1 = value1; InP->value2 = value2; @@ -387,6 +390,7 @@ mig_external kern_return_t rpc_jack_client_async_notify int refnum, client_name_t client_name, int notify, + message_t message, int value1, int value2 ) @@ -401,6 +405,7 @@ mig_external kern_return_t rpc_jack_client_async_notify int refnum; client_name_t client_name; int notify; + message_t message; int value1; int value2; } Request; @@ -433,10 +438,12 @@ mig_external kern_return_t rpc_jack_client_async_notify InP->refnum = refnum; - (void) mig_strncpy(InP->client_name, client_name, 128); + (void) mig_strncpy(InP->client_name, client_name, 64); InP->notify = notify; + (void) mig_strncpy(InP->message, message, 256); + InP->value1 = value1; InP->value2 = value2; diff --git a/macosx/RPC/JackRPCEngine.defs b/macosx/RPC/JackRPCEngine.defs index 63500f41..468b3775 100644 --- a/macosx/RPC/JackRPCEngine.defs +++ b/macosx/RPC/JackRPCEngine.defs @@ -25,11 +25,11 @@ import "Jackdefs.h"; ServerPrefix server_; -type client_name_t = c_string[128]; +type client_name_t = c_string[64]; type client_port_name_t = c_string[128]; type client_port_type_t = c_string[128]; -type so_name_t = c_string[1024]; -type objet_data_t = c_string[1024]; +type so_name_t = c_string[256]; +type objet_data_t = c_string[256]; routine rpc_jack_client_open( server_port : mach_port_t; diff --git a/macosx/RPC/JackRPCEngine.h b/macosx/RPC/JackRPCEngine.h index 8b4fddf4..b9ba07f0 100644 --- a/macosx/RPC/JackRPCEngine.h +++ b/macosx/RPC/JackRPCEngine.h @@ -21,7 +21,7 @@ typedef struct { char *name; function_ptr_t function; } function_table_entry; -typedef function_table_entry *function_table_t; +typedef function_table_entry *function_table_t; #endif /* FUNCTION_PTR_T */ #endif /* AUTOTEST */ diff --git a/macosx/RPC/JackRPCEngineServer.c b/macosx/RPC/JackRPCEngineServer.c index 16508dcf..7ef5d556 100644 --- a/macosx/RPC/JackRPCEngineServer.c +++ b/macosx/RPC/JackRPCEngineServer.c @@ -1,7 +1,7 @@ /* * IDENTIFICATION: - * stub generated Mon Sep 1 17:42:28 2008 - * with a MiG generated Tue Feb 19 02:01:43 PST 2008 by root@b75.local + * stub generated Fri Oct 23 10:35:08 2009 + * with a MiG generated Mon May 18 09:59:33 PDT 2009 by root@sulitlana.apple.com * OPTIONS: */ @@ -791,11 +791,11 @@ mig_internal novalue _Xrpc_jack_client_rt_notify #elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__int_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) + __NDR_convert__int_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name__defined */ @@ -831,11 +831,11 @@ mig_internal novalue _Xrpc_jack_client_rt_notify #elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__char_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) + __NDR_convert__char_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name__defined */ @@ -871,11 +871,11 @@ mig_internal novalue _Xrpc_jack_client_rt_notify #elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__float_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) + __NDR_convert__float_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name__defined */ @@ -910,6 +910,17 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_open_t(__attrib return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->client_name), 64); + if (( memchr(In0P->client_name, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #if defined(__NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_open_t__pid__defined) if (In0P->NDR.int_rep != NDR_record.int_rep) { @@ -1064,11 +1075,11 @@ mig_internal novalue _Xrpc_jack_client_open #elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__int_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) + __NDR_convert__int_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name__defined */ @@ -1124,11 +1135,11 @@ mig_internal novalue _Xrpc_jack_client_open #elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__char_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) + __NDR_convert__char_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name__defined */ @@ -1184,11 +1195,11 @@ mig_internal novalue _Xrpc_jack_client_open #elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__float_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) + __NDR_convert__float_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name__defined */ @@ -1243,6 +1254,17 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_check_t(__attri return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->client_name), 64); + if (( memchr(In0P->client_name, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #if defined(__NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_check_t__protocol__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_check_t__options__defined) @@ -2283,6 +2305,20 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_register_t(__attr return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->name), 128); + if (( memchr(In0P->name, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + memchr_limit = min((msg_limit - In0P->port_type), 128); + if (( memchr(In0P->port_type, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #if defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__refnum__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__name__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type__defined) || \ @@ -3526,6 +3562,20 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_connect_name_t(__ return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->src), 128); + if (( memchr(In0P->src, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + memchr_limit = min((msg_limit - In0P->dst), 128); + if (( memchr(In0P->dst, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #if defined(__NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__refnum__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__src__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__dst__defined) @@ -3848,6 +3898,20 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_disconnect_name_t return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->src), 128); + if (( memchr(In0P->src, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + memchr_limit = min((msg_limit - In0P->dst), 128); + if (( memchr(In0P->dst, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #if defined(__NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__src__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined) @@ -4170,6 +4234,17 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_rename_t(__attrib return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->name), 128); + if (( memchr(In0P->name, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #if defined(__NDR_convert__int_rep__Request__rpc_jack_port_rename_t__refnum__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_port_rename_t__src__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_port_rename_t__name__defined) @@ -5352,11 +5427,11 @@ mig_internal novalue _Xrpc_jack_get_internal_clientname #elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__int_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) + __NDR_convert__int_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined */ @@ -5392,11 +5467,11 @@ mig_internal novalue _Xrpc_jack_get_internal_clientname #elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__char_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) + __NDR_convert__char_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined */ @@ -5432,11 +5507,11 @@ mig_internal novalue _Xrpc_jack_get_internal_clientname #elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__float_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) + __NDR_convert__float_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined */ @@ -5451,6 +5526,17 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_internal_clienthandle_ return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->client_name), 64); + if (( memchr(In0P->client_name, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #if defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined) if (In0P->NDR.int_rep != NDR_record.int_rep) { @@ -5602,11 +5688,11 @@ mig_internal novalue _Xrpc_jack_internal_clienthandle #elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__int_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) + __NDR_convert__int_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name__defined */ @@ -5622,11 +5708,11 @@ mig_internal novalue _Xrpc_jack_internal_clienthandle #elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 1024) + __NDR_convert__int_rep__JackRPCEngine__string(a, f, 256) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 1024) + __NDR_convert__int_rep__string(a, f, 256) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name__defined */ @@ -5642,11 +5728,11 @@ mig_internal novalue _Xrpc_jack_internal_clienthandle #elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 1024) + __NDR_convert__int_rep__JackRPCEngine__string(a, f, 256) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__int_rep__string(a, f, 1024) + __NDR_convert__int_rep__string(a, f, 256) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined */ @@ -5702,11 +5788,11 @@ mig_internal novalue _Xrpc_jack_internal_clienthandle #elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__char_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) + __NDR_convert__char_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name__defined */ @@ -5722,11 +5808,11 @@ mig_internal novalue _Xrpc_jack_internal_clienthandle #elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 1024) + __NDR_convert__char_rep__JackRPCEngine__string(a, f, 256) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 1024) + __NDR_convert__char_rep__string(a, f, 256) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name__defined */ @@ -5742,11 +5828,11 @@ mig_internal novalue _Xrpc_jack_internal_clienthandle #elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 1024) + __NDR_convert__char_rep__JackRPCEngine__string(a, f, 256) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__char_rep__string(a, f, 1024) + __NDR_convert__char_rep__string(a, f, 256) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined */ @@ -5802,11 +5888,11 @@ mig_internal novalue _Xrpc_jack_internal_clienthandle #elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__float_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) + __NDR_convert__float_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name__defined */ @@ -5822,11 +5908,11 @@ mig_internal novalue _Xrpc_jack_internal_clienthandle #elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 1024) + __NDR_convert__float_rep__JackRPCEngine__string(a, f, 256) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 1024) + __NDR_convert__float_rep__string(a, f, 256) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name__defined */ @@ -5842,11 +5928,11 @@ mig_internal novalue _Xrpc_jack_internal_clienthandle #elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 1024) + __NDR_convert__float_rep__JackRPCEngine__string(a, f, 256) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__float_rep__string(a, f, 1024) + __NDR_convert__float_rep__string(a, f, 256) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined */ @@ -5881,6 +5967,23 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_internal_clientload_t( return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->client_name), 64); + if (( memchr(In0P->client_name, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + memchr_limit = min((msg_limit - In0P->so_name), 256); + if (( memchr(In0P->so_name, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + memchr_limit = min((msg_limit - In0P->objet_data), 256); + if (( memchr(In0P->objet_data, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #if defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__refnum__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name__defined) || \ @@ -6626,47 +6729,47 @@ const struct server_JackRPCEngine_subsystem { (vm_address_t)0, { { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_open, 8, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_open_t)}, + (mig_stub_routine_t) _Xrpc_jack_client_open, 8, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_open_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_check, 7, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_check_t)}, + (mig_stub_routine_t) _Xrpc_jack_client_check, 7, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_check_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_close, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_close_t)}, + (mig_stub_routine_t) _Xrpc_jack_client_close, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_close_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_activate, 4, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_activate_t)}, + (mig_stub_routine_t) _Xrpc_jack_client_activate, 4, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_activate_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_deactivate, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_deactivate_t)}, + (mig_stub_routine_t) _Xrpc_jack_client_deactivate, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_deactivate_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_port_register, 8, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_register_t)}, + (mig_stub_routine_t) _Xrpc_jack_port_register, 8, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_register_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_port_unregister, 4, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_unregister_t)}, + (mig_stub_routine_t) _Xrpc_jack_port_unregister, 4, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_unregister_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_port_connect, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_connect_t)}, + (mig_stub_routine_t) _Xrpc_jack_port_connect, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_connect_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_port_disconnect, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_disconnect_t)}, + (mig_stub_routine_t) _Xrpc_jack_port_disconnect, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_disconnect_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_port_connect_name, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_connect_name_t)}, + (mig_stub_routine_t) _Xrpc_jack_port_connect_name, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_connect_name_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_port_disconnect_name, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_disconnect_name_t)}, + (mig_stub_routine_t) _Xrpc_jack_port_disconnect_name, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_disconnect_name_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_port_rename, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_rename_t)}, + (mig_stub_routine_t) _Xrpc_jack_port_rename, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_rename_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_set_buffer_size, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_set_buffer_size_t)}, + (mig_stub_routine_t) _Xrpc_jack_set_buffer_size, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_set_buffer_size_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_set_freewheel, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_set_freewheel_t)}, + (mig_stub_routine_t) _Xrpc_jack_set_freewheel, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_set_freewheel_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_release_timebase, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_release_timebase_t)}, + (mig_stub_routine_t) _Xrpc_jack_release_timebase, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_release_timebase_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_set_timebase_callback, 4, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_set_timebase_callback_t)}, + (mig_stub_routine_t) _Xrpc_jack_set_timebase_callback, 4, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_set_timebase_callback_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_get_internal_clientname, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_get_internal_clientname_t)}, + (mig_stub_routine_t) _Xrpc_jack_get_internal_clientname, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_get_internal_clientname_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_internal_clienthandle, 6, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_internal_clienthandle_t)}, + (mig_stub_routine_t) _Xrpc_jack_internal_clienthandle, 6, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_internal_clienthandle_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_internal_clientload, 9, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_internal_clientload_t)}, + (mig_stub_routine_t) _Xrpc_jack_internal_clientload, 9, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_internal_clientload_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_internal_clientunload, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_internal_clientunload_t)}, + (mig_stub_routine_t) _Xrpc_jack_internal_clientunload, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_internal_clientunload_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_rt_notify, 4, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_rt_notify_t)}, + (mig_stub_routine_t) _Xrpc_jack_client_rt_notify, 4, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_rt_notify_t)}, } }; diff --git a/macosx/RPC/JackRPCEngineUser.c b/macosx/RPC/JackRPCEngineUser.c index f6e5b3f0..e86e8cfc 100644 --- a/macosx/RPC/JackRPCEngineUser.c +++ b/macosx/RPC/JackRPCEngineUser.c @@ -1,7 +1,7 @@ /* * IDENTIFICATION: - * stub generated Mon Sep 1 17:42:28 2008 - * with a MiG generated Tue Feb 19 02:01:43 PST 2008 by root@b75.local + * stub generated Fri Oct 23 10:35:08 2009 + * with a MiG generated Mon May 18 09:59:33 PDT 2009 by root@sulitlana.apple.com * OPTIONS: */ #define __MIG_check__Reply__JackRPCEngine_subsystem__ 1 @@ -50,15 +50,15 @@ #ifndef __MachMsgErrorWithTimeout #define __MachMsgErrorWithTimeout(_R_) { \ switch (_R_) { \ - case MACH_SEND_INVALID_REPLY: \ - case MACH_RCV_INVALID_NAME: \ - case MACH_RCV_PORT_DIED: \ - case MACH_RCV_PORT_CHANGED: \ - case MACH_RCV_TIMED_OUT: \ - mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ + case MACH_SEND_INVALID_DATA: \ + case MACH_SEND_INVALID_DEST: \ + case MACH_SEND_INVALID_HEADER: \ + mig_put_reply_port(InP->Head.msgh_reply_port); \ break; \ + case MACH_SEND_TIMED_OUT: \ + case MACH_RCV_TIMED_OUT: \ default: \ - mig_put_reply_port(InP->Head.msgh_reply_port); \ + mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ } \ } #endif /* __MachMsgErrorWithTimeout */ @@ -66,14 +66,13 @@ #ifndef __MachMsgErrorWithoutTimeout #define __MachMsgErrorWithoutTimeout(_R_) { \ switch (_R_) { \ - case MACH_SEND_INVALID_REPLY: \ - case MACH_RCV_INVALID_NAME: \ - case MACH_RCV_PORT_DIED: \ - case MACH_RCV_PORT_CHANGED: \ - mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ + case MACH_SEND_INVALID_DATA: \ + case MACH_SEND_INVALID_DEST: \ + case MACH_SEND_INVALID_HEADER: \ + mig_put_reply_port(InP->Head.msgh_reply_port); \ break; \ default: \ - mig_put_reply_port(InP->Head.msgh_reply_port); \ + mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ } \ } #endif /* __MachMsgErrorWithoutTimeout */ @@ -399,8 +398,9 @@ mig_internal kern_return_t __MIG_check__Reply__rpc_jack_client_open_t(__Reply__r #if __MigTypeCheck if (Out0P->private_port.type != MACH_MSG_PORT_DESCRIPTOR || - Out0P->private_port.disposition != 17) - { return MIG_TYPE_ERROR; } + Out0P->private_port.disposition != 17) { + return MIG_TYPE_ERROR; + } #endif /* __MigTypeCheck */ #if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_engine__defined) || \ @@ -561,7 +561,7 @@ mig_external kern_return_t rpc_jack_client_open InP->NDR = NDR_record; - (void) mig_strncpy(InP->client_name, client_name, 128); + (void) mig_strncpy(InP->client_name, client_name, 64); InP->pid = pid; @@ -628,11 +628,11 @@ mig_external kern_return_t rpc_jack_client_open #elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) #define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res__defined #define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__int_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res__defined #define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) + __NDR_convert__int_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res__defined */ @@ -692,11 +692,11 @@ mig_external kern_return_t rpc_jack_client_open #elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) #define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res__defined #define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__char_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res__defined #define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) + __NDR_convert__char_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res__defined */ @@ -756,11 +756,11 @@ mig_external kern_return_t rpc_jack_client_open #elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) #define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res__defined #define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__float_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res__defined #define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) + __NDR_convert__float_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res__defined */ @@ -983,7 +983,7 @@ mig_external kern_return_t rpc_jack_client_check InP->NDR = NDR_record; - (void) mig_strncpy(InP->client_name, client_name, 128); + (void) mig_strncpy(InP->client_name, client_name, 64); InP->protocol = protocol; @@ -1011,7 +1011,7 @@ mig_external kern_return_t rpc_jack_client_check { return check_result; } #endif /* defined(__MIG_check__Reply__rpc_jack_client_check_t__defined) */ - (void) mig_strncpy(client_name_res, Out0P->client_name_res, 128); + (void) mig_strncpy(client_name_res, Out0P->client_name_res, 64); *status = Out0P->status; @@ -4739,11 +4739,11 @@ mig_external kern_return_t rpc_jack_set_timebase_callback #elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) #define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined #define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__int_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined #define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) + __NDR_convert__int_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined */ @@ -4782,11 +4782,11 @@ mig_external kern_return_t rpc_jack_set_timebase_callback #elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) #define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined #define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__char_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined #define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) + __NDR_convert__char_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined */ @@ -4825,11 +4825,11 @@ mig_external kern_return_t rpc_jack_set_timebase_callback #elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) #define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined #define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__float_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined #define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) + __NDR_convert__float_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined */ @@ -5040,7 +5040,7 @@ mig_external kern_return_t rpc_jack_get_internal_clientname { return check_result; } #endif /* defined(__MIG_check__Reply__rpc_jack_get_internal_clientname_t__defined) */ - (void) mig_strncpy(client_name_res, Out0P->client_name_res, 128); + (void) mig_strncpy(client_name_res, Out0P->client_name_res, 64); *result = Out0P->result; @@ -5431,7 +5431,7 @@ mig_external kern_return_t rpc_jack_internal_clienthandle InP->refnum = refnum; - (void) mig_strncpy(InP->client_name, client_name, 128); + (void) mig_strncpy(InP->client_name, client_name, 64); InP->Head.msgh_bits = MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); @@ -5854,11 +5854,11 @@ mig_external kern_return_t rpc_jack_internal_clientload InP->refnum = refnum; - (void) mig_strncpy(InP->client_name, client_name, 128); + (void) mig_strncpy(InP->client_name, client_name, 64); - (void) mig_strncpy(InP->so_name, so_name, 1024); + (void) mig_strncpy(InP->so_name, so_name, 256); - (void) mig_strncpy(InP->objet_data, objet_data, 1024); + (void) mig_strncpy(InP->objet_data, objet_data, 256); InP->options = options; diff --git a/macosx/RPC/Jackdefs.h b/macosx/RPC/Jackdefs.h index 5636c37e..5e73d984 100644 --- a/macosx/RPC/Jackdefs.h +++ b/macosx/RPC/Jackdefs.h @@ -18,7 +18,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ typedef char client_name_t[64]; -typedef char client_port_name_t[256]; +typedef char client_port_name_t[128]; typedef char client_port_type_t[128]; typedef char so_name_t[256]; typedef char objet_data_t[256]; +typedef char message_t[256]; diff --git a/macosx/coreaudio/JackCoreAudioAdapter.cpp b/macosx/coreaudio/JackCoreAudioAdapter.cpp index 60f187cb..630366ec 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.cpp +++ b/macosx/coreaudio/JackCoreAudioAdapter.cpp @@ -26,6 +26,20 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { +static void PrintStreamDesc(AudioStreamBasicDescription *inDesc) +{ + jack_log("- - - - - - - - - - - - - - - - - - - -"); + jack_log(" Sample Rate:%f", inDesc->mSampleRate); + jack_log(" Format ID:%.*s", (int) sizeof(inDesc->mFormatID), (char*)&inDesc->mFormatID); + jack_log(" Format Flags:%lX", inDesc->mFormatFlags); + jack_log(" Bytes per Packet:%ld", inDesc->mBytesPerPacket); + jack_log(" Frames per Packet:%ld", inDesc->mFramesPerPacket); + jack_log(" Bytes per Frame:%ld", inDesc->mBytesPerFrame); + jack_log(" Channels per Frame:%ld", inDesc->mChannelsPerFrame); + jack_log(" Bits per Channel:%ld", inDesc->mBitsPerChannel); + jack_log("- - - - - - - - - - - - - - - - - - - -"); +} + static OSStatus DisplayDeviceNames() { UInt32 size; @@ -164,70 +178,30 @@ OSStatus JackCoreAudioAdapter::SRNotificationCallback(AudioDeviceID inDevice, } // A better implementation would try to recover in case of hardware device change (see HALLAB HLFilePlayerWindowControllerAudioDevicePropertyListenerProc code) - OSStatus JackCoreAudioAdapter::DeviceNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData) { - JackCoreAudioAdapter* driver = (JackCoreAudioAdapter*)inClientData; - + switch (inPropertyID) { + + case kAudioDeviceProcessorOverload: { + jack_error("JackCoreAudioAdapter::DeviceNotificationCallback kAudioDeviceProcessorOverload"); + break; + } - case kAudioDevicePropertyStreamConfiguration: + case kAudioDevicePropertyStreamConfiguration: { + jack_error("Cannot handle kAudioDevicePropertyStreamConfiguration"); + return kAudioHardwareUnsupportedOperationError; + } + case kAudioDevicePropertyNominalSampleRate: { - - UInt32 outSize = sizeof(Float64); - Float64 sampleRate; - int in_nChannels = 0; - int out_nChannels = 0; - char capture_driver_name[256]; - char playback_driver_name[256]; - - // Stop and restart - AudioOutputUnitStop(driver->fAUHAL); - driver->RemoveListeners(); - driver->CloseAUHAL(); - - OSStatus err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); - if (err != noErr) { - jack_error("Cannot get current sample rate"); - printError(err); - } - jack_log("JackCoreAudioDriver::DeviceNotificationCallback kAudioDevicePropertyNominalSampleRate %ld", long(sampleRate)); - - if (driver->SetupDevices(driver->fCaptureUID, driver->fPlaybackUID, capture_driver_name, playback_driver_name) < 0) - return -1; - - if (driver->SetupChannels(driver->fCapturing, driver->fPlaying, driver->fCaptureChannels, driver->fPlaybackChannels, in_nChannels, out_nChannels, false) < 0) - return -1; - - if (driver->SetupBufferSizeAndSampleRate(driver->fAdaptedBufferSize, sampleRate) < 0) - return -1; - - driver->SetAdaptedSampleRate(sampleRate); - - if (driver->OpenAUHAL(driver->fCapturing, - driver->fPlaying, - driver->fCaptureChannels, - driver->fPlaybackChannels, - in_nChannels, - out_nChannels, - driver->fAdaptedBufferSize, - sampleRate, - false) < 0) - goto error; - - if (driver->AddListeners() < 0) - goto error; - - AudioOutputUnitStart(driver->fAUHAL); - return noErr; -error: - driver->CloseAUHAL(); - break; + jack_error("Cannot handle kAudioDevicePropertyNominalSampleRate"); + return kAudioHardwareUnsupportedOperationError; } + } return noErr; } @@ -237,7 +211,13 @@ int JackCoreAudioAdapter::AddListeners() OSStatus err = noErr; // Add listeners - + err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDeviceProcessorOverload, DeviceNotificationCallback, this); + if (err != noErr) { + jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDeviceProcessorOverload"); + printError(err); + return -1; + } + err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioHardwarePropertyDevices, DeviceNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioHardwarePropertyDevices"); @@ -276,9 +256,9 @@ int JackCoreAudioAdapter::AddListeners() return 0; } - void JackCoreAudioAdapter::RemoveListeners() { + AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDeviceProcessorOverload, DeviceNotificationCallback); AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioHardwarePropertyDevices, DeviceNotificationCallback); AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, DeviceNotificationCallback); AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyDeviceIsRunning, DeviceNotificationCallback); @@ -313,19 +293,33 @@ OSStatus JackCoreAudioAdapter::Render(void *inRefCon, JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params) :JackAudioAdapterInterface(buffer_size, sample_rate), fInputData(0), fCapturing(false), fPlaying(false), fState(false) { - const JSList* node; const jack_driver_param_t* param; - + int in_nChannels = 0; + int out_nChannels = 0; char captureName[256]; char playbackName[256]; - fCaptureUID[0] = 0; fPlaybackUID[0] = 0; // Default values - fCaptureChannels = 0; - fPlaybackChannels = 0; + 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; + AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; + OSStatus theError = AudioObjectSetPropertyData (kAudioObjectSystemObject, &theAddress, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop); + if (theError != noErr) { + jack_error("JackCoreAudioAdapter::Open kAudioHardwarePropertyRunLoop error"); + } + } for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t*) node->data; @@ -391,26 +385,26 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra fCapturing = true; fPlaying = true; } - - int in_nChannels = 0; - int out_nChannels = 0; - if (SetupDevices(fCaptureUID, fPlaybackUID, captureName, playbackName) < 0) + 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 (SetupBufferSizeAndSampleRate(fAdaptedBufferSize, fAdaptedSampleRate) < 0) + if (SetupSampleRate(fAdaptedSampleRate) < 0) throw -1; - + + 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 (OpenAUHAL(fCapturing, fPlaying, fCaptureChannels, fPlaybackChannels, in_nChannels, out_nChannels, fAdaptedBufferSize, fAdaptedSampleRate, true) < 0) - throw -1; - + if (AddListeners() < 0) throw -1; } @@ -430,7 +424,7 @@ OSStatus JackCoreAudioAdapter::GetDefaultDevice(AudioDeviceID* id) jack_log("GetDefaultDevice: input = %ld output = %ld", inDefault, outDefault); - // Get the device only if default input and ouput are the same + // Get the device only if default input and output are the same if (inDefault == outDefault) { *id = inDefault; return noErr; @@ -518,26 +512,43 @@ OSStatus JackCoreAudioAdapter::GetDeviceNameFromID(AudioDeviceID id, char* name) int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, const char* playback_driver_uid, char* capture_driver_name, - char* playback_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("JackCoreAudioAdapter::Open duplex"); - if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) { - if (GetDefaultDevice(&fDeviceID) != noErr) { - jack_error("Cannot open default device"); + + // 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) { + jack_error("Cannot open default device"); + return -1; + } + } + if (GetDeviceNameFromID(fDeviceID, capture_driver_name) != noErr || GetDeviceNameFromID(fDeviceID, playback_driver_name) != noErr) { + jack_error("Cannot get device name from device ID"); return -1; } - } - if (GetDeviceNameFromID(fDeviceID, capture_driver_name) != noErr || GetDeviceNameFromID(fDeviceID, playback_driver_name) != noErr) { - 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) + return -1; + if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) + return -1; + if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) + return -1; } - // Capture only + // Capture only } else if (strcmp(capture_driver_uid, "") != 0) { jack_log("JackCoreAudioAdapter::Open capture only"); if (GetDeviceIDFromUID(capture_driver_uid, &fDeviceID) != noErr) { @@ -551,7 +562,7 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, return -1; } - // Playback only + // Playback only } else if (strcmp(playback_driver_uid, "") != 0) { jack_log("JackCoreAudioAdapter::Open playback only"); if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) { @@ -565,7 +576,7 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, return -1; } - // Use default driver in duplex mode + // Use default driver in duplex mode } else { jack_log("JackCoreAudioAdapter::Open default driver"); if (GetDefaultDevice(&fDeviceID) != noErr) { @@ -625,72 +636,82 @@ int JackCoreAudioAdapter::SetupChannels(bool capturing, return -1; } - if (inchannels == 0) { + if (inchannels == -1) { jack_log("Setup max in channels = %ld", in_nChannels); inchannels = in_nChannels; } - if (outchannels == 0) { + if (outchannels == -1) { jack_log("Setup max out channels = %ld", out_nChannels); outchannels = out_nChannels; } - + return 0; } -int JackCoreAudioAdapter::SetupBufferSizeAndSampleRate(jack_nframes_t nframes, jack_nframes_t samplerate) +int JackCoreAudioAdapter::SetupBufferSize(jack_nframes_t buffer_size) { - OSStatus err = noErr; - UInt32 outSize; - Float64 sampleRate; - // Setting buffer size - outSize = sizeof(UInt32); - err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, outSize, &nframes); + UInt32 outSize = sizeof(UInt32); + OSStatus err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, outSize, &buffer_size); if (err != noErr) { - jack_error("Cannot set buffer size %ld", nframes); + jack_error("Cannot set buffer size %ld", buffer_size); printError(err); return -1; } + + return 0; +} +int JackCoreAudioAdapter::SetupSampleRate(jack_nframes_t samplerate) +{ + return SetupSampleRateAux(fDeviceID, samplerate); +} + +int JackCoreAudioAdapter::SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes_t samplerate) +{ + OSStatus err = noErr; + UInt32 outSize; + Float64 sampleRate; + // Get sample rate outSize = sizeof(Float64); - err = AudioDeviceGetProperty(fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); + err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); if (err != noErr) { jack_error("Cannot get current sample rate"); printError(err); return -1; } - + // If needed, set new sample rate if (samplerate != (jack_nframes_t)sampleRate) { sampleRate = (Float64)samplerate; - + // To get SR change notification - err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback, this); + err = AudioDeviceAddPropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyNominalSampleRate"); printError(err); return -1; } - err = AudioDeviceSetProperty(fDeviceID, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outSize, &sampleRate); + err = AudioDeviceSetProperty(inDevice, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outSize, &sampleRate); if (err != noErr) { jack_error("Cannot set sample rate = %ld", samplerate); printError(err); return -1; } - + // Waiting for SR change notification int count = 0; - while (!fState && count++ < 100) { + while (!fState && count++ < WAIT_COUNTER) { usleep(100000); - jack_log("Wait count = %ld", count); + jack_log("Wait count = %d", count); } - + // Remove SR change notification - AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback); + AudioDeviceRemovePropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback); } - + return 0; } @@ -724,20 +745,21 @@ void JackCoreAudioAdapter::DisposeBuffers() } int JackCoreAudioAdapter::OpenAUHAL(bool capturing, - bool playing, - int inchannels, - int outchannels, - int in_nChannels, - int out_nChannels, - jack_nframes_t buffer_size, - jack_nframes_t samplerate, - bool strict) + bool playing, + int inchannels, + int outchannels, + int in_nChannels, + int out_nChannels, + jack_nframes_t buffer_size, + jack_nframes_t samplerate) { ComponentResult err1; UInt32 enableIO; AudioStreamBasicDescription srcFormat, dstFormat; + AudioDeviceID currAudioDeviceID; + UInt32 size; - jack_log("OpenAUHAL capturing = %ld playing = %ld inchannels = %ld outchannels = %ld in_nChannels = %ld out_nChannels = %ld ", capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels); + jack_log("OpenAUHAL capturing = %d playing = %d inchannels = %d outchannels = %d in_nChannels = %d out_nChannels = %d", capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels); if (inchannels == 0 && outchannels == 0) { jack_error("No input and output channels..."); @@ -752,14 +774,14 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling OpenAComponent"); printError(err1); - return -1; + goto error; } err1 = AudioUnitInitialize(fAUHAL); if (err1 != noErr) { jack_error("Cannot initialize AUHAL unit"); printError(err1); - return -1; + goto error; } // Start I/O @@ -775,8 +797,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input"); printError(err1); - if (strict) - return -1; + goto error; } if (playing && outchannels > 0) { @@ -791,18 +812,15 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO,kAudioUnitScope_Output"); printError(err1); - if (strict) - return -1; + goto error; } - AudioDeviceID currAudioDeviceID; - UInt32 size = sizeof(AudioDeviceID); + size = sizeof(AudioDeviceID); err1 = AudioUnitGetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &currAudioDeviceID, &size); if (err1 != noErr) { jack_error("Error calling AudioUnitGetProperty - kAudioOutputUnitProperty_CurrentDevice"); printError(err1); - if (strict) - return -1; + goto error; } else { jack_log("AudioUnitGetPropertyCurrentDevice = %d", currAudioDeviceID); } @@ -812,28 +830,16 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_CurrentDevice"); printError(err1); - if (strict) - return -1; + goto error; } - - err1 = AudioUnitGetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &currAudioDeviceID, &size); - if (err1 != noErr) { - jack_error("Error calling AudioUnitGetProperty - kAudioOutputUnitProperty_CurrentDevice"); - printError(err1); - if (strict) - return -1; - } else { - jack_log("AudioUnitGetPropertyCurrentDevice = %d", currAudioDeviceID); - } - + // Set buffer size if (capturing && inchannels > 0) { err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&buffer_size, sizeof(UInt32)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice"); printError(err1); - if (strict) - return -1; + goto error; } } @@ -842,8 +848,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice"); printError(err1); - if (strict) - return -1; + goto error; } } @@ -860,6 +865,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 1"); printError(err1); + goto error; } } @@ -875,40 +881,71 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 0"); printError(err1); + goto error; } } // Setup stream converters - jack_log("Setup AUHAL input stream converter SR = %ld", samplerate); - srcFormat.mSampleRate = samplerate; - srcFormat.mFormatID = kAudioFormatLinearPCM; - srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; - srcFormat.mBytesPerPacket = sizeof(float); - srcFormat.mFramesPerPacket = 1; - srcFormat.mBytesPerFrame = sizeof(float); - srcFormat.mChannelsPerFrame = outchannels; - srcFormat.mBitsPerChannel = 32; - - err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &srcFormat, sizeof(AudioStreamBasicDescription)); - if (err1 != noErr) { - jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); - printError(err1); + if (capturing && inchannels > 0) { + + size = sizeof(AudioStreamBasicDescription); + err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &srcFormat, &size); + if (err1 != noErr) { + jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); + printError(err1); + goto error; + } + PrintStreamDesc(&srcFormat); + + jack_log("Setup AUHAL input stream converter SR = %ld", samplerate); + srcFormat.mSampleRate = samplerate; + srcFormat.mFormatID = kAudioFormatLinearPCM; + srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; + srcFormat.mBytesPerPacket = sizeof(float); + srcFormat.mFramesPerPacket = 1; + srcFormat.mBytesPerFrame = sizeof(float); + 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); + goto error; + } } - jack_log("Setup AUHAL output stream converter SR = %ld", samplerate); - dstFormat.mSampleRate = samplerate; - dstFormat.mFormatID = kAudioFormatLinearPCM; - dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; - dstFormat.mBytesPerPacket = sizeof(float); - dstFormat.mFramesPerPacket = 1; - dstFormat.mBytesPerFrame = sizeof(float); - dstFormat.mChannelsPerFrame = inchannels; - dstFormat.mBitsPerChannel = 32; - - err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &dstFormat, sizeof(AudioStreamBasicDescription)); - if (err1 != noErr) { - jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); - printError(err1); + if (playing && outchannels > 0) { + + size = sizeof(AudioStreamBasicDescription); + err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 1, &dstFormat, &size); + if (err1 != noErr) { + jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); + printError(err1); + goto error; + } + PrintStreamDesc(&dstFormat); + + jack_log("Setup AUHAL output stream converter SR = %ld", samplerate); + dstFormat.mSampleRate = samplerate; + dstFormat.mFormatID = kAudioFormatLinearPCM; + dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; + dstFormat.mBytesPerPacket = sizeof(float); + dstFormat.mFramesPerPacket = 1; + dstFormat.mBytesPerFrame = sizeof(float); + 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); + goto error; + } } // Setup callbacks @@ -920,7 +957,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1"); printError(err1); - return -1; + goto error; } } else { AURenderCallbackStruct output; @@ -930,11 +967,236 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0"); printError(err1); - return -1; + goto error; } } return 0; + +error: + CloseAUHAL(); + return -1; +} + +OSStatus JackCoreAudioAdapter::DestroyAggregateDevice() +{ + OSStatus osErr = noErr; + AudioObjectPropertyAddress pluginAOPA; + pluginAOPA.mSelector = kAudioPlugInDestroyAggregateDevice; + 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; +} + +static CFStringRef GetDeviceName(AudioDeviceID id) +{ + UInt32 size = sizeof(CFStringRef); + CFStringRef UIname; + OSStatus err = AudioDeviceGetProperty(id, 0, false, kAudioDevicePropertyDeviceUID, &size, &UIname); + return (err == noErr) ? UIname : NULL; +} + +OSStatus JackCoreAudioAdapter::CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice) +{ + OSStatus osErr = noErr; + UInt32 outSize; + Boolean outWritable; + + // Check devices... + if (IsAggregateDevice(captureDeviceID) || IsAggregateDevice(playbackDeviceID)) { + jack_error("JackCoreAudioAdapter::CreateAggregateDevice : cannot agregate devices that are already aggregate devices..."); + return -1; + } + + //--------------------------------------------------------------------------- + // Setup SR of both devices otherwise creating AD may fail... + //--------------------------------------------------------------------------- + if (SetupSampleRateAux(captureDeviceID, samplerate) < 0) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of input device"); + } + if (SetupSampleRateAux(playbackDeviceID, samplerate) < 0) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of output device"); + } + + //--------------------------------------------------------------------------- + // Start to create a new aggregate by getting the base audio hardware plugin + //--------------------------------------------------------------------------- + + char capture_name[256]; + char playback_name[256]; + GetDeviceNameFromID(captureDeviceID, capture_name); + GetDeviceNameFromID(playbackDeviceID, playback_name); + jack_info("Separated input = '%s' and output = '%s' devices, create a private aggregate device to handle them...", capture_name, playback_name); + + osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable); + if (osErr != noErr) + 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) + 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...."); + } else { + jack_log("JackCoreAudioDriver::CreateAggregateDevice : private aggregate device...."); + CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef); + } + + //------------------------------------------------- + // Create a CFMutableArray for our sub-device list + //------------------------------------------------- + + CFStringRef captureDeviceUID = GetDeviceName(captureDeviceID); + CFStringRef playbackDeviceUID = GetDeviceName(playbackDeviceID); + + if (captureDeviceUID == NULL || playbackDeviceUID == NULL) + return -1; + + // we need to append the UID for each device to a CFMutableArray, so create one here + CFMutableArrayRef subDevicesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + + // two sub-devices in this example, so append the sub-device's UID to the CFArray + CFArrayAppendValue(subDevicesArray, captureDeviceUID); + CFArrayAppendValue(subDevicesArray, playbackDeviceUID); + + //----------------------------------------------------------------------- + // 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) + return osErr; + + osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice); + if (osErr != noErr) + return osErr; + + // 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; + outDataSize = sizeof(CFMutableArrayRef); + osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &subDevicesArray); + if (osErr != noErr) + return osErr; + + // 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; + pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; + pluginAOPA.mElement = kAudioObjectPropertyElementMaster; + outDataSize = sizeof(CFStringRef); + osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID); // capture is master... + if (osErr != noErr) + return osErr; + + // pause again to give the changes time to take effect + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); + + //---------- + // Clean up + //---------- + + CFRelease(AggregateDeviceNumberRef); + + // release the CF objects we have created - we don't need them any more + CFRelease(aggDeviceDict); + CFRelease(subDevicesArray); + + // release the device UID + CFRelease(captureDeviceUID); + CFRelease(playbackDeviceUID); + + jack_log("New aggregate device %ld", *outAggregateDevice); + return noErr; +} + +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; + } else { + int num_devices = outSize / sizeof(AudioObjectID); + jack_log("Device does has %d subdevices", num_devices); + return true; + } } void JackCoreAudioAdapter::CloseAUHAL() @@ -957,6 +1219,8 @@ int JackCoreAudioAdapter::Close() DisposeBuffers(); CloseAUHAL(); RemoveListeners(); + if (fPluginID > 0) + DestroyAggregateDevice(); return 0; } @@ -995,25 +1259,25 @@ extern "C" strcpy(desc->params[i].name, "channels"); desc->params[i].character = 'c'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; + desc->params[i].value.ui = -1; strcpy(desc->params[i].short_desc, "Maximum number of channels"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + strcpy(desc->params[i].long_desc, "Maximum number of channels. If -1, max possible number of channels will be used"); i++; strcpy(desc->params[i].name, "inchannels"); desc->params[i].character = 'i'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; + desc->params[i].value.ui = -1; strcpy(desc->params[i].short_desc, "Maximum number of input channels"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + strcpy(desc->params[i].long_desc, "Maximum number of input channels. If -1, max possible number of input channels will be used"); i++; strcpy(desc->params[i].name, "outchannels"); desc->params[i].character = 'o'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; + desc->params[i].value.ui = -1; strcpy(desc->params[i].short_desc, "Maximum number of output channels"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + strcpy(desc->params[i].long_desc, "Maximum number of output channels. If -1, max possible number of output channels will be used"); i++; strcpy(desc->params[i].name, "capture"); diff --git a/macosx/coreaudio/JackCoreAudioAdapter.h b/macosx/coreaudio/JackCoreAudioAdapter.h index b40f7b65..d2f61006 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.h +++ b/macosx/coreaudio/JackCoreAudioAdapter.h @@ -36,6 +36,8 @@ typedef UInt8 CAAudioHardwareDeviceSectionID; #define kAudioDeviceSectionGlobal ((CAAudioHardwareDeviceSectionID)0x00) #define kAudioDeviceSectionWildcard ((CAAudioHardwareDeviceSectionID)0xFF) +#define WAIT_COUNTER 60 + /*! \brief Audio adapter using CoreAudio API. */ @@ -54,7 +56,9 @@ class JackCoreAudioAdapter : public JackAudioAdapterInterface bool fCapturing; bool fPlaying; - AudioDeviceID fDeviceID; + AudioDeviceID fDeviceID; // Used "duplex" device + AudioObjectID fPluginID; // Used for aggregate device + bool fState; AudioUnitRenderActionFlags* fActionFags; @@ -86,10 +90,15 @@ class JackCoreAudioAdapter : public JackAudioAdapterInterface OSStatus GetDeviceNameFromID(AudioDeviceID id, char* name); // Setup + OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); + OSStatus DestroyAggregateDevice(); + bool IsAggregateDevice(AudioDeviceID device); + int SetupDevices(const char* capture_driver_uid, const char* playback_driver_uid, char* capture_driver_name, - char* playback_driver_name); + char* playback_driver_name, + jack_nframes_t samplerate); int SetupChannels(bool capturing, bool playing, @@ -106,10 +115,12 @@ class JackCoreAudioAdapter : public JackAudioAdapterInterface int in_nChannels, int out_nChannels, jack_nframes_t buffer_size, - jack_nframes_t samplerate, - bool strict); + jack_nframes_t samplerate); - int SetupBufferSizeAndSampleRate(jack_nframes_t buffer_size, jack_nframes_t samplerate); + int SetupBufferSize(jack_nframes_t buffer_size); + int SetupSampleRate(jack_nframes_t samplerate); + int SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes_t samplerate); + int SetupBuffers(int inchannels); void DisposeBuffers(); void CloseAUHAL(); diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index d0815cd1..3b2620cb 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -25,15 +25,17 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackClientControl.h" #include "JackDriverLoader.h" #include "JackGlobals.h" +#include "JackTools.h" #include "JackCompilerDeps.h" #include #include +#include namespace Jack { -static void Print4CharCode(char* msg, long c) +static void Print4CharCode(const char* msg, long c) { UInt32 __4CC_number = (c); char __4CC_string[5]; @@ -42,6 +44,20 @@ static void Print4CharCode(char* msg, long c) jack_log("%s'%s'", (msg), __4CC_string); } +static void PrintStreamDesc(AudioStreamBasicDescription *inDesc) +{ + jack_log("- - - - - - - - - - - - - - - - - - - -"); + jack_log(" Sample Rate:%f", inDesc->mSampleRate); + jack_log(" Format ID:%.*s", (int) sizeof(inDesc->mFormatID), (char*)&inDesc->mFormatID); + jack_log(" Format Flags:%lX", inDesc->mFormatFlags); + jack_log(" Bytes per Packet:%ld", inDesc->mBytesPerPacket); + jack_log(" Frames per Packet:%ld", inDesc->mFramesPerPacket); + jack_log(" Bytes per Frame:%ld", inDesc->mBytesPerFrame); + jack_log(" Channels per Frame:%ld", inDesc->mChannelsPerFrame); + jack_log(" Bits per Channel:%ld", inDesc->mBitsPerChannel); + jack_log("- - - - - - - - - - - - - - - - - - - -\n"); +} + static void printError(OSStatus err) { switch (err) { @@ -221,10 +237,13 @@ OSStatus JackCoreAudioDriver::MeasureCallback(AudioDeviceID inDevice, JackMachThread::GetParams(pthread_self(), &driver->fEngineControl->fPeriod, &driver->fEngineControl->fComputation, &driver->fEngineControl->fConstraint); if (driver->fComputationGrain > 0) { - jack_log("JackCoreAudioDriver::MeasureCallback : RT thread computation setup to %ld percent of period", int(driver->fComputationGrain * 100)); + jack_log("JackCoreAudioDriver::MeasureCallback : 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; + // Setup threadded based log function set_threaded_log_function(); return noErr; @@ -250,8 +269,7 @@ OSStatus JackCoreAudioDriver::SRNotificationCallback(AudioDeviceID inDevice, return noErr; } -// A better implementation would try to recover in case of hardware device change (see HALLAB HLFilePlayerWindowControllerAudioDevicePropertyListenerProc code) - +// A better implementation would possibly try to recover in case of hardware device change (see HALLAB HLFilePlayerWindowControllerAudioDevicePropertyListenerProc code) OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, @@ -261,87 +279,30 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData; switch (inPropertyID) { - + 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... break; - } - + } + case kAudioDevicePropertyStreamConfiguration: { - jack_error("Cannot handle kAudioDevicePropertyStreamConfiguration : server may not work correctly anymore..."); - return kAudioHardwareUnsupportedOperationError; - } - - case kAudioDevicePropertyNominalSampleRate: { - jack_error("Cannot handle kAudioDevicePropertyNominalSampleRate : server may not work correctly anymore..."); + jack_error("Cannot handle kAudioDevicePropertyStreamConfiguration : server will quit..."); + driver->NotifyFailure(JackBackendError, "Another application has changed the device configuration."); // Message length limited to JACK_MESSAGE_SIZE + driver->CloseAUHAL(); + kill(JackTools::GetPID(), SIGINT); return kAudioHardwareUnsupportedOperationError; - } - - /* + } + case kAudioDevicePropertyNominalSampleRate: { - - UInt32 outSize = sizeof(Float64); - Float64 sampleRate; - int in_nChannels = 0; - int out_nChannels = 0; - char capture_driver_name[256]; - char playback_driver_name[256]; - CFStringRef ref; - - // Stop and restart - driver->Stop(); - driver->RemoveListeners(); + jack_error("Cannot handle kAudioDevicePropertyNominalSampleRate : server will quit..."); + driver->NotifyFailure(JackBackendError, "Another application has changed the sample rate."); // Message length limited to JACK_MESSAGE_SIZE driver->CloseAUHAL(); - - OSStatus err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); - if (err != noErr) { - jack_error("Cannot get current sample rate"); - printError(err); - } - jack_log("JackCoreAudioDriver::DeviceNotificationCallback kAudioDevicePropertyNominalSampleRate %ld", long(sampleRate)); - - if (driver->SetupDevices(driver->fCaptureUID, driver->fPlaybackUID, capture_driver_name, playback_driver_name) < 0) - return -1; - - if (driver->SetupChannels(driver->fCapturing, driver->fPlaying, driver->fInChannels, driver->fOutChannels, in_nChannels, out_nChannels, false) < 0) - return -1; - - if (driver->SetupBufferSizeAndSampleRate(driver->fEngineControl->fBufferSize, sampleRate) < 0) - return -1; - - if (driver->OpenAUHAL(driver->fCapturing, - driver->fPlaying, - driver->fInChannels, - driver->fOutChannels, - in_nChannels, - out_nChannels, - driver->fEngineControl->fBufferSize, - sampleRate, - false) < 0) - goto error; - - if (driver->AddListeners() < 0) - goto error; - - driver->Start(); - - // Send notification to be used in JackPilot or JackRouter plugin - jack_error("Device restart..."); - ref = CFStringCreateWithCString(NULL, driver->fEngineControl->fServerName, kCFStringEncodingMacRoman); - CFNotificationCenterPostNotificationWithOptions(CFNotificationCenterGetDistributedCenter(), - CFSTR("com.grame.jackserver.restart"), - ref, - NULL, - kCFNotificationDeliverImmediately | kCFNotificationPostToAllSessions); - CFRelease(ref); - return noErr; -error: - driver->CloseAUHAL(); - break; - } - */ + kill(JackTools::GetPID(), SIGINT); + return kAudioHardwareUnsupportedOperationError; + } + } return noErr; } @@ -377,7 +338,7 @@ OSStatus JackCoreAudioDriver::GetDefaultDevice(AudioDeviceID* id) jack_log("GetDefaultDevice: input = %ld output = %ld", inDefault, outDefault); - // Get the device only if default input and ouput are the same + // Get the device only if default input and output are the same if (inDefault == outDefault) { *id = inDefault; return noErr; @@ -446,55 +407,136 @@ 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), fState(false), fIOUsage(1.f),fComputationGrain(-1.f) + : JackAudioDriver(name, alias, engine, table), + fJackInputData(NULL), + fDriverOutputData(NULL), + fPluginID(0), + fState(false), + fHogged(false), + fIOUsage(1.f), + fComputationGrain(-1.f) {} JackCoreAudioDriver::~JackCoreAudioDriver() {} -OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, AudioDeviceID* outAggregateDevice) +OSStatus JackCoreAudioDriver::DestroyAggregateDevice() +{ + OSStatus osErr = noErr; + AudioObjectPropertyAddress pluginAOPA; + pluginAOPA.mSelector = kAudioPlugInDestroyAggregateDevice; + 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 osErr = noErr; UInt32 outSize; Boolean outWritable; + + // Check devices... (TO IMPROVE) + if (IsAggregateDevice(captureDeviceID) || IsAggregateDevice(playbackDeviceID)) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot agregate devices that are already aggregate devices..."); + return -1; + } + + //--------------------------------------------------------------------------- + // Setup SR of both devices otherwise creating AD may fail... + //--------------------------------------------------------------------------- + if (SetupSampleRateAux(captureDeviceID, samplerate) < 0) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of input device"); + } + if (SetupSampleRateAux(playbackDeviceID, samplerate) < 0) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of output device"); + } - //----------------------- + //--------------------------------------------------------------------------- // Start to create a new aggregate by getting the base audio hardware plugin - //----------------------- - + //--------------------------------------------------------------------------- + + char capture_name[256]; + char playback_name[256]; + GetDeviceNameFromID(captureDeviceID, capture_name); + GetDeviceNameFromID(playbackDeviceID, playback_name); + jack_info("Separated input = '%s' and output = '%s' devices, create a private aggregate device to handle them...", capture_name, playback_name); + osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable); - if (osErr != noErr) + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error"); + printError(osErr); return osErr; + } AudioValueTranslation pluginAVT; CFStringRef inBundleRef = CFSTR("com.apple.audio.CoreAudio"); - AudioObjectID pluginID; - + pluginAVT.mInputData = &inBundleRef; pluginAVT.mInputDataSize = sizeof(inBundleRef); - pluginAVT.mOutputData = &pluginID; - pluginAVT.mOutputDataSize = sizeof(pluginID); + pluginAVT.mOutputData = &fPluginID; + pluginAVT.mOutputDataSize = sizeof(fPluginID); osErr = AudioHardwareGetProperty(kAudioHardwarePropertyPlugInForBundleID, &outSize, &pluginAVT); - if (osErr != noErr) + 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...."); + } else { + jack_log("JackCoreAudioDriver::CreateAggregateDevice : private aggregate device...."); + CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef); + } + //------------------------------------------------- // Create a CFMutableArray for our sub-device list //------------------------------------------------- @@ -522,13 +564,19 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI pluginAOPA.mElement = kAudioObjectPropertyElementMaster; UInt32 outDataSize; - osErr = AudioObjectGetPropertyDataSize(pluginID, &pluginAOPA, 0, NULL, &outDataSize); - if (osErr != noErr) - return osErr; - - osErr = AudioObjectGetPropertyData(pluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice); - if (osErr != noErr) - return osErr; + 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 @@ -543,9 +591,12 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI pluginAOPA.mElement = kAudioObjectPropertyElementMaster; outDataSize = sizeof(CFMutableArrayRef); osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &subDevicesArray); - if (osErr != noErr) - return osErr; - + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectSetPropertyData for sub-device list error"); + printError(osErr); + goto error; + } + // pause again to give the changes time to take effect CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); @@ -560,15 +611,21 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI pluginAOPA.mElement = kAudioObjectPropertyElementMaster; outDataSize = sizeof(CFStringRef); osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID); // capture is master... - if (osErr != noErr) - return osErr; - + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectSetPropertyData for master device error"); + printError(osErr); + goto error; + } + // 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); @@ -580,9 +637,17 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI 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; @@ -590,17 +655,7 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, const char // Duplex if (strcmp(capture_driver_uid, "") != 0 && strcmp(playback_driver_uid, "") != 0) { jack_log("JackCoreAudioDriver::Open duplex"); - - /* - AudioDeviceID captureID, playbackID; - if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) - return -1; - if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) - return -1; - if (CreateAggregateDevice(captureID, playbackID, &fDeviceID) != noErr) - return -1; - */ - + // Same device for capture and playback... if (strcmp(capture_driver_uid, playback_driver_uid) == 0) { @@ -618,17 +673,17 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, const char } else { - // Creates agregate device + // Creates aggregate device AudioDeviceID captureID, playbackID; if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) return -1; if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) return -1; - if (CreateAggregateDevice(captureID, playbackID, &fDeviceID) != noErr) + if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) return -1; } - // Capture only + // Capture only } else if (strcmp(capture_driver_uid, "") != 0) { jack_log("JackCoreAudioDriver::Open capture only"); if (GetDeviceIDFromUID(capture_driver_uid, &fDeviceID) != noErr) { @@ -643,7 +698,7 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, const char return -1; } - // Playback only + // Playback only } else if (strcmp(playback_driver_uid, "") != 0) { jack_log("JackCoreAudioDriver::Open playback only"); if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) { @@ -658,7 +713,7 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, const char return -1; } - // Use default driver in duplex mode + // Use default driver in duplex mode } else { jack_log("JackCoreAudioDriver::Open default driver"); if (GetDefaultDevice(&fDeviceID) != noErr) { @@ -670,6 +725,14 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, const char return -1; } } + + if (fHogged) { + if (TakeHog()) { + jack_info("Device = %ld has been hogged", fDeviceID); + } else { + jack_error("Cannot hog device = %ld", fDeviceID); + } + } return 0; } @@ -704,48 +767,58 @@ int JackCoreAudioDriver::SetupChannels(bool capturing, bool playing, int& inchan } if (inchannels > in_nChannels) { - jack_error("This device hasn't required input channels inchannels = %ld in_nChannels = %ld", inchannels, in_nChannels); + jack_error("This device hasn't required input channels inchannels = %d in_nChannels = %d", inchannels, in_nChannels); if (strict) return -1; } if (outchannels > out_nChannels) { - jack_error("This device hasn't required output channels outchannels = %ld out_nChannels = %ld", outchannels, out_nChannels); + jack_error("This device hasn't required output channels outchannels = %d out_nChannels = %d", outchannels, out_nChannels); if (strict) return -1; } - if (inchannels == 0) { - jack_log("Setup max in channels = %ld", in_nChannels); + if (inchannels == -1) { + jack_log("Setup max in channels = %d", in_nChannels); inchannels = in_nChannels; } - if (outchannels == 0) { - jack_log("Setup max out channels = %ld", out_nChannels); + if (outchannels == -1) { + jack_log("Setup max out channels = %d", out_nChannels); outchannels = out_nChannels; } return 0; } -int JackCoreAudioDriver::SetupBufferSizeAndSampleRate(jack_nframes_t buffer_size, jack_nframes_t samplerate) +int JackCoreAudioDriver::SetupBufferSize(jack_nframes_t buffer_size) { - OSStatus err = noErr; - UInt32 outSize; - Float64 sampleRate; - // Setting buffer size - outSize = sizeof(UInt32); - err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, outSize, &buffer_size); + UInt32 outSize = sizeof(UInt32); + OSStatus err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, outSize, &buffer_size); if (err != noErr) { jack_error("Cannot set buffer size %ld", buffer_size); printError(err); return -1; } + return 0; +} + +int JackCoreAudioDriver::SetupSampleRate(jack_nframes_t samplerate) +{ + return SetupSampleRateAux(fDeviceID, samplerate); +} + +int JackCoreAudioDriver::SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes_t samplerate) +{ + OSStatus err = noErr; + UInt32 outSize; + Float64 sampleRate; + // Get sample rate outSize = sizeof(Float64); - err = AudioDeviceGetProperty(fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); + err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); if (err != noErr) { jack_error("Cannot get current sample rate"); printError(err); @@ -757,13 +830,13 @@ int JackCoreAudioDriver::SetupBufferSizeAndSampleRate(jack_nframes_t buffer_size sampleRate = (Float64)samplerate; // To get SR change notification - err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback, this); + err = AudioDeviceAddPropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyNominalSampleRate"); printError(err); return -1; } - err = AudioDeviceSetProperty(fDeviceID, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outSize, &sampleRate); + err = AudioDeviceSetProperty(inDevice, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outSize, &sampleRate); if (err != noErr) { jack_error("Cannot set sample rate = %ld", samplerate); printError(err); @@ -772,13 +845,13 @@ int JackCoreAudioDriver::SetupBufferSizeAndSampleRate(jack_nframes_t buffer_size // Waiting for SR change notification int count = 0; - while (!fState && count++ < 100) { + while (!fState && count++ < WAIT_COUNTER) { usleep(100000); - jack_log("Wait count = %ld", count); + jack_log("Wait count = %d", count); } // Remove SR change notification - AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback); + AudioDeviceRemovePropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback); } return 0; @@ -791,14 +864,15 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, int in_nChannels, int out_nChannels, jack_nframes_t buffer_size, - jack_nframes_t samplerate, - bool strict) + jack_nframes_t samplerate) { ComponentResult err1; UInt32 enableIO; AudioStreamBasicDescription srcFormat, dstFormat; + AudioDeviceID currAudioDeviceID; + UInt32 size; - jack_log("OpenAUHAL capturing = %ld playing = %ld inchannels = %ld outchannels = %ld in_nChannels = %ld out_nChannels = %ld ", capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels); + jack_log("OpenAUHAL capturing = %d playing = %d inchannels = %d outchannels = %d in_nChannels = %d out_nChannels = %d", capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels); if (inchannels == 0 && outchannels == 0) { jack_error("No input and output channels..."); @@ -813,14 +887,14 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling OpenAComponent"); printError(err1); - return -1; + goto error; } err1 = AudioUnitInitialize(fAUHAL); if (err1 != noErr) { jack_error("Cannot initialize AUHAL unit"); printError(err1); - return -1; + goto error; } // Start I/O @@ -836,8 +910,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input"); printError(err1); - if (strict) - return -1; + goto error; } if (playing && outchannels > 0) { @@ -852,18 +925,15 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO,kAudioUnitScope_Output"); printError(err1); - if (strict) - return -1; + goto error; } - AudioDeviceID currAudioDeviceID; - UInt32 size = sizeof(AudioDeviceID); + size = sizeof(AudioDeviceID); err1 = AudioUnitGetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &currAudioDeviceID, &size); if (err1 != noErr) { jack_error("Error calling AudioUnitGetProperty - kAudioOutputUnitProperty_CurrentDevice"); printError(err1); - if (strict) - return -1; + goto error; } else { jack_log("AudioUnitGetPropertyCurrentDevice = %d", currAudioDeviceID); } @@ -873,28 +943,16 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_CurrentDevice"); printError(err1); - if (strict) - return -1; - } - - err1 = AudioUnitGetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &currAudioDeviceID, &size); - if (err1 != noErr) { - jack_error("Error calling AudioUnitGetProperty - kAudioOutputUnitProperty_CurrentDevice"); - printError(err1); - if (strict) - return -1; - } else { - jack_log("AudioUnitGetPropertyCurrentDevice = %d", currAudioDeviceID); + goto error; } - + // Set buffer size if (capturing && inchannels > 0) { err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&buffer_size, sizeof(UInt32)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice"); printError(err1); - if (strict) - return -1; + goto error; } } @@ -903,8 +961,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice"); printError(err1); - if (strict) - return -1; + goto error; } } @@ -921,6 +978,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 1"); printError(err1); + goto error; } } @@ -936,40 +994,71 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 0"); printError(err1); + goto error; } } // Setup stream converters - jack_log("Setup AUHAL input stream converter SR = %ld", samplerate); - srcFormat.mSampleRate = samplerate; - srcFormat.mFormatID = kAudioFormatLinearPCM; - srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; - srcFormat.mBytesPerPacket = sizeof(float); - srcFormat.mFramesPerPacket = 1; - srcFormat.mBytesPerFrame = sizeof(float); - srcFormat.mChannelsPerFrame = outchannels; - srcFormat.mBitsPerChannel = 32; - - err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &srcFormat, sizeof(AudioStreamBasicDescription)); - if (err1 != noErr) { - jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); - printError(err1); + if (capturing && inchannels > 0) { + + size = sizeof(AudioStreamBasicDescription); + err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &srcFormat, &size); + if (err1 != noErr) { + jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); + printError(err1); + goto error; + } + PrintStreamDesc(&srcFormat); + + jack_log("Setup AUHAL input stream converter SR = %ld", samplerate); + srcFormat.mSampleRate = samplerate; + srcFormat.mFormatID = kAudioFormatLinearPCM; + srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; + srcFormat.mBytesPerPacket = sizeof(float); + srcFormat.mFramesPerPacket = 1; + srcFormat.mBytesPerFrame = sizeof(float); + 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); + goto error; + } } - jack_log("Setup AUHAL output stream converter SR = %ld", samplerate); - dstFormat.mSampleRate = samplerate; - dstFormat.mFormatID = kAudioFormatLinearPCM; - dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; - dstFormat.mBytesPerPacket = sizeof(float); - dstFormat.mFramesPerPacket = 1; - dstFormat.mBytesPerFrame = sizeof(float); - dstFormat.mChannelsPerFrame = inchannels; - dstFormat.mBitsPerChannel = 32; - - err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &dstFormat, sizeof(AudioStreamBasicDescription)); - if (err1 != noErr) { - jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); - printError(err1); + if (playing && outchannels > 0) { + + size = sizeof(AudioStreamBasicDescription); + err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 1, &dstFormat, &size); + if (err1 != noErr) { + jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); + printError(err1); + goto error; + } + PrintStreamDesc(&dstFormat); + + jack_log("Setup AUHAL output stream converter SR = %ld", samplerate); + dstFormat.mSampleRate = samplerate; + dstFormat.mFormatID = kAudioFormatLinearPCM; + dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; + dstFormat.mBytesPerPacket = sizeof(float); + dstFormat.mFramesPerPacket = 1; + dstFormat.mBytesPerFrame = sizeof(float); + 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); + goto error; + } } // Setup callbacks @@ -981,7 +1070,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1"); printError(err1); - return -1; + goto error; } } else { AURenderCallbackStruct output; @@ -991,11 +1080,15 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0"); printError(err1); - return -1; + goto error; } } return 0; + +error: + CloseAUHAL(); + return -1; } int JackCoreAudioDriver::SetupBuffers(int inchannels) @@ -1109,7 +1202,8 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, jack_nframes_t capture_latency, jack_nframes_t playback_latency, int async_output_latency, - int computation_grain) + int computation_grain, + bool hogged) { int in_nChannels = 0; int out_nChannels = 0; @@ -1128,21 +1222,40 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, fPlaybackLatency = playback_latency; fIOUsage = float(async_output_latency) / 100.f; fComputationGrain = float(computation_grain) / 100.f; + fHogged = hogged; + + 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; + AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; + OSStatus theError = AudioObjectSetPropertyData (kAudioObjectSystemObject, &theAddress, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop); + if (theError != noErr) { + jack_error("JackCoreAudioDriver::Open kAudioHardwarePropertyRunLoop error"); + } + } - if (SetupDevices(capture_driver_uid, playback_driver_uid, capture_driver_name, playback_driver_name) < 0) - return -1; + if (SetupDevices(capture_driver_uid, playback_driver_uid, capture_driver_name, playback_driver_name, samplerate) < 0) + goto error; // Generic JackAudioDriver Open if (JackAudioDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0) - return -1; + goto error; if (SetupChannels(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, true) < 0) - return -1; - - if (SetupBufferSizeAndSampleRate(buffer_size, samplerate) < 0) - return -1; + goto error; - if (OpenAUHAL(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, buffer_size, samplerate, true) < 0) + 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; if (capturing && inchannels > 0) @@ -1151,7 +1264,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; @@ -1170,6 +1283,7 @@ int JackCoreAudioDriver::Close() RemoveListeners(); DisposeBuffers(); CloseAUHAL(); + DestroyAggregateDevice(); return 0; } @@ -1312,8 +1426,22 @@ int JackCoreAudioDriver::Start() printError(err); return -1; } - - return 0; + + // Waiting for Measure callback to be called ( = driver has started) + fState = false; + int count = 0; + while (!fState && count++ < WAIT_COUNTER) { + usleep(100000); + jack_log("JackCoreAudioDriver::Start wait count = %d", count); + } + + if (count < WAIT_COUNTER) { + jack_info("CoreAudio driver is running..."); + return 0; + } else { + jack_error("CoreAudio driver cannot start..."); + return -1; + } } int JackCoreAudioDriver::Stop() @@ -1355,6 +1483,66 @@ int JackCoreAudioDriver::SetBufferSize(jack_nframes_t buffer_size) return 0; } +bool JackCoreAudioDriver::TakeHogAux(AudioDeviceID deviceID, bool isInput) +{ + pid_t hog_pid; + OSStatus err; + + UInt32 propSize = sizeof(hog_pid); + err = AudioDeviceGetProperty(deviceID, 0, isInput, kAudioDevicePropertyHogMode, &propSize, &hog_pid); + if (err) { + jack_error("Cannot read hog state..."); + printError(err); + } + + if (hog_pid != getpid()) { + hog_pid = getpid(); + err = AudioDeviceSetProperty(deviceID, 0, 0, isInput, kAudioDevicePropertyHogMode, propSize, &hog_pid); + if (err != noErr) { + jack_error("Can't hog device = %d because it's being hogged by another program", deviceID); + 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); + } else { + int num_devices = outSize / sizeof(AudioObjectID); + jack_log("Device does has %d subdevices", num_devices); + for (int i = 0; i < num_devices; i++) { + if (!TakeHogAux(sub_device[i], true)) { + return false; + } + } + 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; + } else { + return (deviceType == kAudioDeviceTransportTypeAggregate); + } +} + + } // end of namespace @@ -1372,32 +1560,32 @@ 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 = 15; + desc->nparams = 16; desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); i = 0; strcpy(desc->params[i].name, "channels"); desc->params[i].character = 'c'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; + desc->params[i].value.ui = -1; strcpy(desc->params[i].short_desc, "Maximum number of channels"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + strcpy(desc->params[i].long_desc, "Maximum number of channels. If -1, max possible number of channels will be used"); i++; strcpy(desc->params[i].name, "inchannels"); desc->params[i].character = 'i'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; + desc->params[i].value.ui = -1; strcpy(desc->params[i].short_desc, "Maximum number of input channels"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + strcpy(desc->params[i].long_desc, "Maximum number of input channels. If -1, max possible number of input channels will be used"); i++; strcpy(desc->params[i].name, "outchannels"); desc->params[i].character = 'o'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; + desc->params[i].value.ui = -1; strcpy(desc->params[i].short_desc, "Maximum number of output channels"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + strcpy(desc->params[i].long_desc, "Maximum number of output channels. If -1, max possible number of output channels will be used"); i++; strcpy(desc->params[i].name, "capture"); @@ -1475,16 +1663,24 @@ extern "C" strcpy(desc->params[i].name, "list-devices"); desc->params[i].character = 'l'; desc->params[i].type = JackDriverParamBool; - desc->params[i].value.i = TRUE; + 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'; + desc->params[i].type = JackDriverParamBool; + 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'; desc->params[i].type = JackDriverParamUInt; desc->params[i].value.i = 100; - strcpy(desc->params[i].short_desc, "Extra output latency in aynchronous mode (percent)"); + strcpy(desc->params[i].short_desc, "Extra output latency in asynchronous mode (percent)"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); i++; @@ -1502,10 +1698,10 @@ extern "C" { jack_nframes_t srate = 44100; jack_nframes_t frames_per_interrupt = 128; - int capture = FALSE; - int playback = FALSE; - int chan_in = 0; - int chan_out = 0; + bool capture = false; + bool playback = false; + int chan_in = -1; // Default: if not explicitely set, then max possible will be used... + int chan_out = -1; // Default: ifà not explicitely set, then max possible will be used... bool monitor = false; const char* capture_driver_uid = ""; const char* playback_driver_uid = ""; @@ -1515,6 +1711,7 @@ extern "C" jack_nframes_t systemic_output_latency = 0; int async_output_latency = 100; int computation_grain = -1; + bool hogged = false; for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t *) node->data; @@ -1527,31 +1724,31 @@ extern "C" break; case 'D': - capture = TRUE; - playback = TRUE; + capture = true; + playback = true; break; case 'c': - chan_in = chan_out = (int) param->value.ui; + chan_in = chan_out = (int)param->value.ui; break; case 'i': - chan_in = (int) param->value.ui; + chan_in = (int)param->value.ui; break; case 'o': - chan_out = (int) param->value.ui; + chan_out = (int)param->value.ui; break; case 'C': - capture = TRUE; + capture = true; if (strcmp(param->value.str, "none") != 0) { capture_driver_uid = strdup(param->value.str); } break; case 'P': - playback = TRUE; + playback = true; if (strcmp(param->value.str, "none") != 0) { playback_driver_uid = strdup(param->value.str); } @@ -1566,7 +1763,7 @@ extern "C" break; case 'p': - frames_per_interrupt = (unsigned int) param->value.ui; + frames_per_interrupt = (unsigned int)param->value.ui; break; case 'I': @@ -1581,6 +1778,10 @@ extern "C" Jack::DisplayDeviceNames(); break; + case 'H': + hogged = true; + break; + case 'L': async_output_latency = param->value.ui; break; @@ -1593,13 +1794,13 @@ extern "C" /* duplex is the default */ if (!capture && !playback) { - capture = TRUE; - playback = TRUE; + capture = true; + playback = true; } 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, - playback_driver_uid, systemic_input_latency, systemic_output_latency, async_output_latency, computation_grain) == 0) { + playback_driver_uid, systemic_input_latency, systemic_output_latency, async_output_latency, computation_grain, hogged) == 0) { return driver; } else { delete driver; diff --git a/macosx/coreaudio/JackCoreAudioDriver.h b/macosx/coreaudio/JackCoreAudioDriver.h index fb680b3f..f3d909d2 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.h +++ b/macosx/coreaudio/JackCoreAudioDriver.h @@ -36,6 +36,8 @@ typedef UInt8 CAAudioHardwareDeviceSectionID; #define kAudioDeviceSectionOutput ((CAAudioHardwareDeviceSectionID)0x00) #define kAudioDeviceSectionGlobal ((CAAudioHardwareDeviceSectionID)0x00) #define kAudioDeviceSectionWildcard ((CAAudioHardwareDeviceSectionID)0xFF) + +#define WAIT_COUNTER 60 /*! \brief The CoreAudio driver. @@ -53,12 +55,14 @@ class JackCoreAudioDriver : public JackAudioDriver AudioBufferList* fJackInputData; AudioBufferList* fDriverOutputData; - AudioDeviceID fDeviceID; + AudioDeviceID fDeviceID; // Used "duplex" device + AudioObjectID fPluginID; // Used for aggregate device AudioUnitRenderActionFlags* fActionFags; AudioTimeStamp* fCurrentTime; bool fState; + bool fHogged; // Initial state bool fCapturing; @@ -101,7 +105,6 @@ class JackCoreAudioDriver : public JackAudioDriver AudioDevicePropertyID inPropertyID, void* inClientData); - static OSStatus SRNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, @@ -116,11 +119,15 @@ class JackCoreAudioDriver : public JackAudioDriver OSStatus GetTotalChannels(AudioDeviceID device, int& channelCount, bool isInput); // Setup - OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, AudioDeviceID* outAggregateDevice); + OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); + OSStatus DestroyAggregateDevice(); + bool IsAggregateDevice(AudioDeviceID device); + int SetupDevices(const char* capture_driver_uid, const char* playback_driver_uid, char* capture_driver_name, - char* playback_driver_name); + char* playback_driver_name, + jack_nframes_t samplerate); int SetupChannels(bool capturing, bool playing, @@ -133,7 +140,9 @@ class JackCoreAudioDriver : public JackAudioDriver int SetupBuffers(int inchannels); void DisposeBuffers(); - int SetupBufferSizeAndSampleRate(jack_nframes_t buffer_size, jack_nframes_t samplerate); + int SetupBufferSize(jack_nframes_t buffer_size); + int SetupSampleRate(jack_nframes_t samplerate); + int SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes_t samplerate); int OpenAUHAL(bool capturing, bool playing, @@ -142,12 +151,14 @@ class JackCoreAudioDriver : public JackAudioDriver int in_nChannels, int out_nChannels, jack_nframes_t nframes, - jack_nframes_t samplerate, - bool strict); + jack_nframes_t samplerate); void CloseAUHAL(); int AddListeners(); void RemoveListeners(); + + bool TakeHogAux(AudioDeviceID deviceID, bool isInput); + bool TakeHog(); public: @@ -166,7 +177,8 @@ class JackCoreAudioDriver : public JackAudioDriver jack_nframes_t capture_latency, jack_nframes_t playback_latency, int async_output_latency, - int computation_grain); + int computation_grain, + bool hogged); int Close(); int Attach(); diff --git a/posix/JackPosixMutex.h b/posix/JackPosixMutex.h index 8fc6ea06..91d21132 100644 --- a/posix/JackPosixMutex.h +++ b/posix/JackPosixMutex.h @@ -33,6 +33,47 @@ namespace Jack \brief Mutex abstraction. */ + +class JackBasePosixMutex +{ + + protected: + + pthread_mutex_t fMutex; + + public: + + JackBasePosixMutex() + { + 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); + } + + 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); + } + +}; + class JackPosixMutex { diff --git a/posix/JackPosixThread.cpp b/posix/JackPosixThread.cpp index aa1d0fbd..d61eb932 100644 --- a/posix/JackPosixThread.cpp +++ b/posix/JackPosixThread.cpp @@ -25,8 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include // for memset #include // for _POSIX_PRIORITY_SCHEDULING check -#define JACK_SCHED_POLICY SCHED_RR -//#define JACK_SCHED_POLICY SCHED_FIFO +//#define JACK_SCHED_POLICY SCHED_RR +#define JACK_SCHED_POLICY SCHED_FIFO namespace Jack { diff --git a/posix/JackProcessSync.cpp b/posix/JackProcessSync.cpp index 7c0763b4..2daa49b7 100644 --- a/posix/JackProcessSync.cpp +++ b/posix/JackProcessSync.cpp @@ -104,6 +104,7 @@ bool JackProcessSync::TimedWait(long usec) gettimeofday(&T1, 0); jack_log("JackProcessSync::TimedWait finished delta = %5.1lf", (1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec)); + return (res == 0); } @@ -112,11 +113,11 @@ bool JackProcessSync::LockedTimedWait(long usec) struct timeval T0, T1; timespec time; struct timeval now; - int res; + int res1, res2; - res = pthread_mutex_lock(&fMutex); - if (res != 0) - jack_error("JackProcessSync::LockedTimedWait error err = %s", usec, strerror(res)); + res1 = pthread_mutex_lock(&fMutex); + if (res1 != 0) + jack_error("JackProcessSync::LockedTimedWait error err = %s", usec, strerror(res1)); jack_log("JackProcessSync::TimedWait time out = %ld", usec); gettimeofday(&T0, 0); @@ -125,19 +126,19 @@ bool JackProcessSync::LockedTimedWait(long usec) unsigned int next_date_usec = now.tv_usec + usec; time.tv_sec = now.tv_sec + (next_date_usec / 1000000); time.tv_nsec = (next_date_usec % 1000000) * 1000; - res = pthread_cond_timedwait(&fCond, &fMutex, &time); - if (res != 0) - jack_error("JackProcessSync::LockedTimedWait error usec = %ld err = %s", usec, strerror(res)); + res2 = pthread_cond_timedwait(&fCond, &fMutex, &time); + if (res2 != 0) + jack_error("JackProcessSync::LockedTimedWait error usec = %ld err = %s", usec, strerror(res2)); gettimeofday(&T1, 0); - - res = pthread_mutex_unlock(&fMutex); - if (res != 0) - jack_error("JackProcessSync::LockedTimedWait error err = %s", usec, strerror(res)); + res1 = pthread_mutex_unlock(&fMutex); + if (res1 != 0) + jack_error("JackProcessSync::LockedTimedWait error err = %s", usec, strerror(res1)); jack_log("JackProcessSync::TimedWait finished delta = %5.1lf", (1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec)); - return (res == 0); + + return (res2 == 0); } diff --git a/posix/JackProcessSync.h b/posix/JackProcessSync.h index 4cf82850..5f45a01e 100644 --- a/posix/JackProcessSync.h +++ b/posix/JackProcessSync.h @@ -32,7 +32,7 @@ namespace Jack \brief A synchronization primitive built using a condition variable. */ -class JackProcessSync : public JackPosixMutex +class JackProcessSync : public JackBasePosixMutex { private: @@ -41,12 +41,12 @@ class JackProcessSync : public JackPosixMutex public: - JackProcessSync():JackPosixMutex() + JackProcessSync():JackBasePosixMutex() { pthread_cond_init(&fCond, NULL); } - ~JackProcessSync() + virtual ~JackProcessSync() { pthread_cond_destroy(&fCond); } diff --git a/posix/JackSocketClientChannel.cpp b/posix/JackSocketClientChannel.cpp index a14e4cc3..d2d4b676 100644 --- a/posix/JackSocketClientChannel.cpp +++ b/posix/JackSocketClientChannel.cpp @@ -168,9 +168,9 @@ void JackSocketClientChannel::ClientClose(int refnum, int* result) ServerSyncCall(&req, &res, result); } -void JackSocketClientChannel::ClientActivate(int refnum, int state, int* result) +void JackSocketClientChannel::ClientActivate(int refnum, int is_real_time, int* result) { - JackActivateRequest req(refnum, state); + JackActivateRequest req(refnum, is_real_time); JackResult res; ServerSyncCall(&req, &res, result); } @@ -320,7 +320,7 @@ bool JackSocketClientChannel::Execute() goto error; } - res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fValue1, event.fValue2); + res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fMessage, event.fValue1, event.fValue2); if (event.fSync) { if (res.Write(fNotificationSocket) < 0) { diff --git a/posix/JackSocketClientChannel.h b/posix/JackSocketClientChannel.h index d51857d8..c9004293 100644 --- a/posix/JackSocketClientChannel.h +++ b/posix/JackSocketClientChannel.h @@ -66,7 +66,7 @@ class JackSocketClientChannel : public detail::JackClientChannelInterface, publi {} void ClientClose(int refnum, int* result); - void ClientActivate(int refnum, int state, int* result); + void ClientActivate(int refnum, int is_real_time, int* result); void ClientDeactivate(int refnum, int* result); void PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result); diff --git a/posix/JackSocketNotifyChannel.cpp b/posix/JackSocketNotifyChannel.cpp index b0c44867..35737b0d 100644 --- a/posix/JackSocketNotifyChannel.cpp +++ b/posix/JackSocketNotifyChannel.cpp @@ -47,9 +47,9 @@ void JackSocketNotifyChannel::Close() fNotifySocket.Close(); } -void JackSocketNotifyChannel::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2, int* result) +void JackSocketNotifyChannel::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2, int* result) { - JackClientNotification event(name, refnum, notify, sync, value1, value2); + JackClientNotification event(name, refnum, notify, sync, message, value1, value2); JackResult res; // Send notification diff --git a/posix/JackSocketNotifyChannel.h b/posix/JackSocketNotifyChannel.h index 9a40bbcb..5d532919 100644 --- a/posix/JackSocketNotifyChannel.h +++ b/posix/JackSocketNotifyChannel.h @@ -45,7 +45,7 @@ class JackSocketNotifyChannel int Open(const char* name); // Open the Server/Client connection void Close(); // Close the Server/Client connection - void ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2, int* result); + void ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2, int* result); }; } // end of namespace diff --git a/posix/JackSocketServerChannel.cpp b/posix/JackSocketServerChannel.cpp index b04fdb0a..eb988aef 100644 --- a/posix/JackSocketServerChannel.cpp +++ b/posix/JackSocketServerChannel.cpp @@ -22,7 +22,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackServer.h" #include "JackLockedEngine.h" #include "JackGlobals.h" +#include "JackServerGlobals.h" #include "JackClient.h" +#include "JackTools.h" #include "JackNotification.h" #include #include @@ -46,9 +48,8 @@ JackSocketServerChannel::~JackSocketServerChannel() int JackSocketServerChannel::Open(const char* server_name, JackServer* server) { - jack_log("JackSocketServerChannel::Open "); - fServer = server; - + jack_log("JackSocketServerChannel::Open"); + // Prepare request socket if (fRequestListenSocket.Bind(jack_server_dir, server_name, 0) < 0) { jack_log("JackSocketServerChannel::Open : cannot create result listen socket"); @@ -57,18 +58,8 @@ int JackSocketServerChannel::Open(const char* server_name, JackServer* server) // Prepare for poll BuildPoolTable(); - - // Start listening - if (fThread.Start() != 0) { - jack_error("Cannot start Jack server listener"); - goto error; - } - + fServer = server; return 0; - -error: - fRequestListenSocket.Close(); - return -1; } void JackSocketServerChannel::Close() @@ -86,6 +77,16 @@ void JackSocketServerChannel::Close() delete socket; } } + +int JackSocketServerChannel::Start() +{ + if (fThread.Start() != 0) { + jack_error("Cannot start Jack server listener"); + return -1; + } + + return 0; +} void JackSocketServerChannel::ClientCreate() { @@ -201,7 +202,7 @@ bool JackSocketServerChannel::HandleRequest(int fd) JackResult res; jack_log("JackRequest::ActivateClient"); if (req.Read(socket) == 0) - res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fState); + res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fIsRealTime); if (res.Write(socket) < 0) jack_error("JackRequest::ActivateClient write error ref = %d", req.fRefNum); break; @@ -395,7 +396,12 @@ bool JackSocketServerChannel::HandleRequest(int fd) jack_error("Unknown request %ld", header.fType); break; } - + + // Issued by JackEngine::ReleaseRefnum when temporary mode is used + if (JackServerGlobals::fKilled) { + kill(JackTools::GetPID(), SIGINT); + } + return true; } diff --git a/posix/JackSocketServerChannel.h b/posix/JackSocketServerChannel.h index 98a812aa..60b86325 100644 --- a/posix/JackSocketServerChannel.h +++ b/posix/JackSocketServerChannel.h @@ -59,8 +59,10 @@ class JackSocketServerChannel : public JackRunnableInterface JackSocketServerChannel(); ~JackSocketServerChannel(); - int Open(const char* server_name, JackServer* server); // Open the Server/Client connection - void Close(); // Close the Server/Client connection + int Open(const char* server_name, JackServer* server); // Open the Server/Client connection + void Close(); // Close the Server/Client connection + + int Start(); // JackRunnableInterface interface bool Init(); diff --git a/tests/test.cpp b/tests/test.cpp index 2358a891..26d4eedf 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -220,6 +220,12 @@ void jack_shutdown(void *arg) exit(1); } +void jack_info_shutdown(int code, const char* reason, void *arg) +{ + printf("JACK server failure : %s\n", reason); + exit(1); +} + void Jack_Port_Register(jack_port_id_t port, int mode, void *arg) { port_callback_reg++; @@ -679,6 +685,7 @@ int main (int argc, char *argv[]) } jack_on_shutdown(client1, jack_shutdown, 0); + jack_on_info_shutdown(client1, jack_info_shutdown, 0); if (jack_set_buffer_size_callback(client1, Jack_Update_Buffer_Size, 0) != 0) { printf("Error when calling buffer_size_callback !\n"); diff --git a/windows/JackWinNamedPipeClientChannel.cpp b/windows/JackWinNamedPipeClientChannel.cpp index b36f03e1..fedc1095 100644 --- a/windows/JackWinNamedPipeClientChannel.cpp +++ b/windows/JackWinNamedPipeClientChannel.cpp @@ -167,9 +167,9 @@ void JackWinNamedPipeClientChannel::ClientClose(int refnum, int* result) ServerSyncCall(&req, &res, result); } -void JackWinNamedPipeClientChannel::ClientActivate(int refnum, int state, int* result) +void JackWinNamedPipeClientChannel::ClientActivate(int refnum, int is_real_time, int* result) { - JackActivateRequest req(refnum, state); + JackActivateRequest req(refnum, is_real_time); JackResult res; ServerSyncCall(&req, &res, result); } @@ -315,7 +315,7 @@ bool JackWinNamedPipeClientChannel::Execute() goto error; } - res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fValue1, event.fValue2); + res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fMessage, event.fValue1, event.fValue2); if (event.fSync) { if (res.Write(&fNotificationListenPipe) < 0) { diff --git a/windows/JackWinNamedPipeClientChannel.h b/windows/JackWinNamedPipeClientChannel.h index a2a3969b..32bf6a5d 100644 --- a/windows/JackWinNamedPipeClientChannel.h +++ b/windows/JackWinNamedPipeClientChannel.h @@ -64,7 +64,7 @@ class JackWinNamedPipeClientChannel : public detail::JackClientChannelInterface, {} void ClientClose(int refnum, int* result); - void ClientActivate(int refnum, int state, int* result); + void ClientActivate(int refnum, int is_real_time, int* result); void ClientDeactivate(int refnum, int* result); void PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result); diff --git a/windows/JackWinNamedPipeNotifyChannel.cpp b/windows/JackWinNamedPipeNotifyChannel.cpp index 991f260c..a7375085 100644 --- a/windows/JackWinNamedPipeNotifyChannel.cpp +++ b/windows/JackWinNamedPipeNotifyChannel.cpp @@ -46,9 +46,9 @@ void JackWinNamedPipeNotifyChannel::Close() fNotifyPipe.Close(); } -void JackWinNamedPipeNotifyChannel::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2, int* result) +void JackWinNamedPipeNotifyChannel::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2, int* result) { - JackClientNotification event(name, refnum, notify, sync, value1, value2); + JackClientNotification event(name, refnum, notify, sync, message, value1, value2); JackResult res; // Send notification diff --git a/windows/JackWinNamedPipeNotifyChannel.h b/windows/JackWinNamedPipeNotifyChannel.h index 0ade63d1..9d90e26b 100644 --- a/windows/JackWinNamedPipeNotifyChannel.h +++ b/windows/JackWinNamedPipeNotifyChannel.h @@ -44,7 +44,7 @@ class JackWinNamedPipeNotifyChannel int Open(const char* name); // Open the Server/Client connection void Close(); // Close the Server/Client connection - void ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2, int* result); + void ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2, int* result); }; } // end of namespace diff --git a/windows/JackWinNamedPipeServerChannel.cpp b/windows/JackWinNamedPipeServerChannel.cpp index f3f2c288..03d9effc 100644 --- a/windows/JackWinNamedPipeServerChannel.cpp +++ b/windows/JackWinNamedPipeServerChannel.cpp @@ -31,15 +31,17 @@ using namespace std; namespace Jack { -HANDLE JackClientPipeThread::fMutex = NULL; // never released.... +HANDLE JackClientPipeThread::fMutex = NULL; // Never released.... // fRefNum = -1 correspond to already removed client JackClientPipeThread::JackClientPipeThread(JackWinNamedPipeClient* pipe) - : fPipe(pipe), fServer(NULL), fThread(this), fRefNum(0) + :fPipe(pipe), fServer(NULL), fThread(this), fRefNum(0) { - if (fMutex == NULL) + // First one allocated the static fMutex + if (fMutex == NULL) { fMutex = CreateMutex(NULL, FALSE, NULL); + } } JackClientPipeThread::~JackClientPipeThread() @@ -50,15 +52,14 @@ JackClientPipeThread::~JackClientPipeThread() int JackClientPipeThread::Open(JackServer* server) // Open the Server/Client connection { - fServer = server; - // Start listening if (fThread.Start() != 0) { jack_error("Cannot start Jack server listener\n"); return -1; - } else { - return 0; } + + fServer = server; + return 0; } void JackClientPipeThread::Close() // Close the Server/Client connection @@ -74,7 +75,7 @@ void JackClientPipeThread::Close() // Close the Server/Client connection fPipe->Close(); fRefNum = -1; } - + bool JackClientPipeThread::Execute() { jack_log("JackClientPipeThread::Execute"); @@ -138,7 +139,7 @@ bool JackClientPipeThread::HandleRequest() JackResult res; jack_log("JackRequest::ActivateClient"); if (req.Read(fPipe) == 0) - res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fState); + res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fIsRealTime); res.Write(fPipe); break; } @@ -316,6 +317,13 @@ bool JackClientPipeThread::HandleRequest() break; } } + + /* TODO + // Issued by JackEngine::ReleaseRefnum when temporary mode is used + if (JackServerGlobals::fKilled) { + kill(JackTools::GetPID(), SIGINT); + } + */ // Unlock the global mutex ReleaseMutex(fMutex); @@ -371,29 +379,18 @@ JackWinNamedPipeServerChannel::~JackWinNamedPipeServerChannel() int JackWinNamedPipeServerChannel::Open(const char* server_name, JackServer* server) { jack_log("JackWinNamedPipeServerChannel::Open "); - - fServer = server; snprintf(fServerName, sizeof(fServerName), server_name); - + // Needed for internal connection from JackWinNamedPipeServerNotifyChannel object if (fRequestListenPipe.Bind(jack_server_dir, server_name, 0) < 0) { jack_error("JackWinNamedPipeServerChannel::Open : cannot create result listen pipe"); - return false; - } - - // Start listening - if (fThread.Start() != 0) { - jack_error("Cannot start Jack server listener\n"); - goto error; + return -1; } - + + fServer = server; return 0; - -error: - fRequestListenPipe.Close(); - return -1; } - + void JackWinNamedPipeServerChannel::Close() { /* TODO : solve WIN32 thread Kill issue @@ -408,6 +405,16 @@ void JackWinNamedPipeServerChannel::Close() fRequestListenPipe.Close(); } +int JackWinNamedPipeServerChannel::Start() +{ + if (fThread.Start() != 0) { + jack_error("Cannot start Jack server listener"); + return -1; + } + + return 0; +} + bool JackWinNamedPipeServerChannel::Init() { jack_log("JackWinNamedPipeServerChannel::Init "); diff --git a/windows/JackWinNamedPipeServerChannel.h b/windows/JackWinNamedPipeServerChannel.h index 4026b541..7404f04d 100644 --- a/windows/JackWinNamedPipeServerChannel.h +++ b/windows/JackWinNamedPipeServerChannel.h @@ -50,9 +50,9 @@ class JackClientPipeThread : public JackRunnableInterface JackClientPipeThread(JackWinNamedPipeClient* pipe); virtual ~JackClientPipeThread(); - int Open(JackServer* server); // Open the Server/Client connection - void Close(); // Close the Server/Client connection - + int Open(JackServer* server); // Open the Server/Client connection + void Close(); // Close the Server/Client connection + bool HandleRequest(); // JackRunnableInterface interface @@ -88,8 +88,10 @@ class JackWinNamedPipeServerChannel : public JackRunnableInterface JackWinNamedPipeServerChannel(); ~JackWinNamedPipeServerChannel(); - int Open(const char* server_name, JackServer* server); // Open the Server/Client connection - void Close(); // Close the Server/Client connection + int Open(const char* server_name, JackServer* server); // Open the Server/Client connection + void Close(); // Close the Server/Client connection + + int Start(); // JackRunnableInterface interface bool Init(); diff --git a/windows/Setup/src/README b/windows/Setup/src/README index e9424a26..a33ec512 100644 --- a/windows/Setup/src/README +++ b/windows/Setup/src/README @@ -20,9 +20,9 @@ It is compiled from the latest CVS version which is using QT4 framework. To uses - in Setup/Misc, check the "Start JACK audio server at application startup" box -- quit qjackctl.exe and start is again, it should now launch the jack server. Quitting the qjackctl.exe will now close the jack server. +- quit QJACKCTL and start is again, it should now launch the jack server. Quitting QJACKCTL will now close the jack server. -Starting the jack server with another audio device installed on the machine (like an ASIO card) can now be done directly in qjackctl. +Starting the jack server with another audio device installed on the machine (like an ASIO card) can now be done directly in QJACKCTL. A ">" button at the right of the interface button allows to list the name of all available devices, driven either by "MME", "DirectSound", or "ASIO". Alternatively using the following command allows to display the names of available devices: @@ -30,7 +30,7 @@ Alternatively using the following command allows to display the names of availab Then start jackd with the device you want, by using its name, for example: -- jackd -R -S -d portaudio -d "ASIO::MOTU Audio ASIO", then start qjackctl. qjackctl will see the jackd server already running and then can be used normally. +- jackd -R -S -d portaudio -d "ASIO::MOTU Audio ASIO", then start QJACKCTL. QJACKCTL will see the jackd server already running and then can be used normally. ============================================= @@ -47,9 +47,9 @@ QJACKCTL MIDI connection windows can then be used. JackRouter JACK/ASIO driver ============================================= -JackRouter is an ASIO driver that allows any ASIO compatible application to become a JACK client, thus exchange audio with any other "native" or "Jackified" application. This driver is registered in the system by the installer and becomes available in the list of ASIO drivers when the JACK server is running. A "JackRouter.ini" configuration file allows the application to confgiure how the JackRouter driver behaves. +JackRouter is an ASIO driver that allows any ASIO compatible application to become a JACK client, thus exchange audio with any other "native" or "Jackified" application. This driver is registered in the system by the installer and becomes available in the list of ASIO drivers when the JACK server is running. A "JackRouter.ini" configuration file allows the application to configure how the JackRouter driver behaves. - - [IO]: the application can obtain any number if JACK input/output ports (not necessarilly equal to the audio card input/output number). [Note that some applications force their input/output channel number]. + - [IO]: the application can obtain any number if JACK input/output ports (not necessarily equal to the audio card input/output number). [Note that some applications force their input/output channel number]. - [AUTO_CONNECT] : when 1, the application JACK port will automatically be connected to the machine input/output JACK ports. diff --git a/wscript b/wscript index f5b69855..6fb5c88c 100644 --- a/wscript +++ b/wscript @@ -68,7 +68,7 @@ def set_options(opt): opt.add_option('--profile', action='store_true', default=False, help='Build with engine profiling') opt.add_option('--mixed', action='store_true', default=False, help='Build with 32/64 bits mixed mode') opt.add_option('--clients', default=64, type="int", dest="clients", help='Maximum number of JACK clients') - opt.add_option('--ports', default=1024, type="int", dest="ports", help='Maximum number of ports') + opt.add_option('--ports', default=2048, type="int", dest="ports", help='Maximum number of ports') opt.add_option('--ports-per-application', default=512, type="int", dest="application_ports", help='Maximum number of ports per application') opt.sub_options('dbus') From 6b765f01687b55584eadb52bf51074a815f7e9b5 Mon Sep 17 00:00:00 2001 From: sletz Date: Thu, 19 Nov 2009 10:49:03 +0000 Subject: [PATCH 024/472] rebase from trunk 3684:3813 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3814 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 69 +- README | 1 + common/JackAPI.cpp | 31 +- common/JackArgParser.cpp | 4 + common/JackClient.cpp | 60 +- common/JackConstants.h | 2 +- common/JackControlAPI.cpp | 5 + common/JackEngine.cpp | 12 +- common/JackEngineControl.h | 2 + common/JackException.h | 20 +- common/JackGraphManager.cpp | 36 +- common/JackLibAPI.cpp | 24 +- common/JackLockedEngine.h | 89 +- common/JackMessageBuffer.cpp | 2 +- common/JackNetAdapter.cpp | 6 +- common/JackNetOneDriver.cpp | 1143 ++++++++++ common/JackNetOneDriver.h | 96 + common/JackRestartThreadedDriver.cpp | 2 +- common/JackServerAPI.cpp | 24 +- common/JackServerGlobals.cpp | 1 - common/JackServerGlobals.h | 1 - common/JackShmMem.cpp | 11 +- common/JackShmMem.h | 26 +- common/JackThread.h | 11 +- common/JackThreadedDriver.cpp | 4 +- common/JackTools.cpp | 42 +- common/JackTools.h | 9 +- common/JackTransportEngine.cpp | 3 +- common/JackWaitThreadedDriver.cpp | 6 +- common/JackWeakAPI.cpp | 187 +- common/Jackdmp.cpp | 58 +- common/jack/jack.h | 37 +- common/jack/jslist.h | 12 +- common/jack/types.h | 41 +- common/netjack.c | 746 +++++++ common/netjack.h | 147 ++ common/netjack_packet.c | 1520 +++++++++++++ common/netjack_packet.h | 165 ++ common/ringbuffer.c | 382 ++-- dbus/sigsegv.c | 4 +- example-clients/alsa_in.c | 757 +++++++ example-clients/alsa_out.c | 755 +++++++ example-clients/bufsize.c | 21 +- example-clients/internal_metro.cpp | 2 +- example-clients/netsource.c | 780 +++++++ example-clients/samplerate.c | 85 + example-clients/wait.c | 136 ++ example-clients/wscript | 48 +- example-clients/zombie.c | 3 +- linux/wscript | 10 +- macosx/JackMachServerChannel.cpp | 4 - macosx/JackMachServerNotifyChannel.cpp | 2 +- macosx/JackMachThread.cpp | 32 +- macosx/JackMachThread.h | 12 +- macosx/Jackdmp.xcodeproj/project.pbxproj | 1884 ++++++++++++++--- macosx/coreaudio/JackCoreAudioAdapter.cpp | 370 +++- macosx/coreaudio/JackCoreAudioAdapter.h | 6 + macosx/coreaudio/JackCoreAudioDriver.cpp | 330 ++- macosx/coreaudio/JackCoreAudioDriver.h | 11 +- macosx/install_jackdmp | 2 + macosx/wscript | 9 + posix/JackPosixThread.cpp | 50 +- posix/JackPosixThread.h | 11 +- posix/JackSocketServerChannel.cpp | 7 +- posix/JackSocketServerNotifyChannel.cpp | 2 +- tests/test.cpp | 2 +- windows/JackShmMem_os.h | 4 +- windows/JackWinNamedPipeServerChannel.cpp | 9 +- .../JackWinNamedPipeServerNotifyChannel.cpp | 2 +- windows/JackWinThread.cpp | 33 +- windows/JackWinThread.h | 13 +- windows/Setup/JackRouter.dll | Bin 32768 -> 32768 bytes windows/Setup/jack.ci | 4 +- wscript | 15 +- 74 files changed, 9452 insertions(+), 1000 deletions(-) create mode 100644 common/JackNetOneDriver.cpp create mode 100644 common/JackNetOneDriver.h create mode 100644 common/netjack.c create mode 100644 common/netjack.h create mode 100644 common/netjack_packet.c create mode 100644 common/netjack_packet.h create mode 100644 example-clients/alsa_in.c create mode 100644 example-clients/alsa_out.c create mode 100644 example-clients/netsource.c create mode 100644 example-clients/samplerate.c create mode 100644 example-clients/wait.c diff --git a/ChangeLog b/ChangeLog index f5aed4c9..00471db2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,6 +25,62 @@ Paul Davis Jackdmp changes log --------------------------- +2009-11-18 Stephane Letz + + * Sync JackCoreAudioAdapter code with JackCoreAudioDriver. + +2009-11-17 Stephane Letz + + * In JackCoreAudio driver, clock drift compensation in aggregated devices working. + * In JackCoreAudio driver, clock drift compensation semantic changed a bit : when on, does not activate if not needed (same clock domain). + +2009-11-16 Stephane Letz + + * In JackCoreAudio driver, (possibly) clock drift compensation when needed in aggregated devices. + +2009-11-14 Stephane Letz + + * Sync with JACK1 : -r parameter now used for no-realtime, realtime (-R) is now default, usable backend given vie platform. + +2009-11-13 Stephane Letz + + * Better memory allocation error checking in ringbuffer.c, weak import improvements. + * Memory allocation error checking for jack_client_new and jack_client_open (server and client side). + * Memory allocation error checking in server for RPC. + * Simplify server temporary mode : now use a JackTemporaryException. + * Lock/Unlock shared memory segments (to test...). + +2009-11-12 Stephane Letz + + * Better memory allocation error checking on client (library) side. + +2009-11-11 Stephane Letz + + * Correct JackCoreAudio driver when empty strings are given as -C, -P or -d parameter. + +2009-11-10 Stephane Letz + + * Correct JackInfoShutdownCallback prototype, two new JackClientProcessFailure and JackClientZombie JackStatus code. + +2009-11-09 Stephane Letz + + * Correct JackGraphManager::GetBuffer for the "client loop with one connection" case : buffer must be copied. + +2009-11-07 Stephane Letz + + * Fix AcquireRealTime and DropRealTime: now distinguish when called from another thread (AcquireRealTime/DropRealTime) and from the thread itself (AcquireSelfRealTime/DropSelfRealTime). + * Correct JackPosixThread::StartImp : thread priority setting now done in the RT case only. + +2009-11-06 Stephane Letz + + * Correctly save and restore RT mode state in freewheel mode. + * Correct freewheel code on client side. + +2009-11-05 Stephane Letz + + * No reason to make jack_on_shutdown deprecated, so revert the incorrect change. + * Thread AcquireRealTime and DropRealTime were (incorrectly) using fThread field. Use pthread_self()) (or GetCurrentThread() on Windows) to get the calling thread. + 2009-10-30 Stephane Letz * In JackCoreAudioDriver, improve management of input/output channels: -1 is now used internally to indicate a wanted max value. @@ -32,6 +88,7 @@ Paul Davis * Correct crash bug in JackAudioAdapterInterface when not input is used in adapter (temporary fix...) * Sync JackCoreAudioAdapter code on JackCoreAudioDriver one. * JACK_SCHED_POLICY switched to SCHED_FIFO. + * Now can aggregate device that are themselves AD. 2009-10-29 Stephane Letz @@ -398,12 +455,12 @@ Paul Davis 2009-01-05 Stephane Letz - * Synchronize jack2 public headers with jack1 ones. + * Synchronize jack2 public headers with JACK1 ones. * Implement jack_client_real_time_priority and jack_client_max_real_time_priority API. 2008-12-18 Stephane Letz - * For ALSA driver, synchronize with latest jack1 memops functions. + * For ALSA driver, synchronize with latest JACK1 memops functions. * Use memops functions in JackOSSDriver. * Use memops functions in JackOSSAdapter. @@ -437,13 +494,13 @@ Paul Davis 2008-11-27 Stephane Letz * Add timing profiling code in JackOSSDriver. - * Report ringbuffer.c fixes from jack1. + * Report ringbuffer.c fixes from JACK1. 2008-11-21 Stephane Letz - * Report ringbuffer.c fixes from jack1. - * Better isolation of server and clients system resources to allow starting the server in several user account at the same time. - * Correct ressource cleanup in case of driver open failure. + * Report ringbuffer.c fixes from JACK1. + * Better isolation of server and clients system resources to allow starting the server in several user account at the same time. + * Correct ressource cleanup in case of driver open failure. 2008-11-19 Stephane Letz diff --git a/README b/README index 88278c31..d9f58484 100644 --- a/README +++ b/README @@ -213,6 +213,7 @@ Note : To experiment with the -S option, jackdmp must be launched in a console. 1.9.1 : Fix jackctl_server_unload_internal. Filter SIGPIPE to avoid having client get a SIGPIPE when trying to access a died server. Libjack shutdown handler does not "deactivate" (fActive = false) the client anymore, so that jack_deactivate correctly does the job later on. Better isolation of server and clients system resources to allow starting the server in several user account at the same time. Report ringbuffer.c fixes from jack1. Client and library global context cleanup in case of incorrect shutdown handling (that is applications not correctly closing client after server has shutdown). Use JACK_DRIVER_DIR variable in internal clients loader. For ALSA driver, synchronize with latest jack1 memops functions. Synchronize jack2 public headers with jack1 ones. Implement jack_client_real_time_priority and jack_client_max_real_time_priority API. Use up to BUFFER_SIZE_MAX frames in midi ports, fix for ticket #117. Cleanup server starting code for clients directly linked with libjackserver.so. JackMessageBuffer was using thread "Stop" scheme in destructor, now use the safer thread "Kill" way. Synchronize ALSA backend code with JACK1 one. Set default mode to 'slow' in JackNetDriver and JackNetAdapter. Simplify audio packet order verification. Fix JackNetInterface::SetNetBufferSize for socket buffer size computation and JackNetMasterInterface::DataRecv if synch packet is received, various cleanup. Better recovery of network overload situations, now "resynchronize" by skipping cycles.". Support for BIG_ENDIAN machines in NetJack2. Support for BIG_ENDIAN machines in NetJack2 for MIDI ports. Support for "-h" option in internal clients to print the parameters. In NetJack2, fix a bug when capture or playback only channels are used. Add a JACK_INTERNAL_DIR environment variable to be used for internal clients. Add a resample quality parameter in audioadapter. Now correctly return an error if JackServer::SetBufferSize could not change the buffer size (and was just restoring the current one). Use PRIu32 kind of macro in JackAlsaDriver again. Add a resample quality parameter in netadapter. 1.9.2 : Solaris version. New "profiling" tools. Rework the mutex/signal classes. Support for BIG_ENDIAN machines in NetJack2. D-BUS based device reservation to better coexist with PulseAudio on Linux. Add auto_connect parameter in netmanager and netadapter. Use Torben Hohn PI controler code for adapters. Client incorrect re-naming fixed : now done at socket and fifo level. Virtualize and allow overriding of thread creation function, to allow Wine support (from JACK1). 1.9.3 : New JackBoomerDriver class for Boomer driver on Solaris. Add mixed 32/64 bits mode (off by default). Native MIDI backend (JackCoreMidiDriver, JackWinMMEDriver). In ALSA audio card reservation code, tries to open the card even if reservation fails. Clock source setting on Linux. Add jackctl_server_switch_master API. Fix transport callback (timebase master, sync) issue when used after jack_activate (RT thread was not running). D-Bus access for jackctl_server_add_slave/jackctl_server_remove_slave API. Cleanup "loopback" stuff in server. Torben Hohn fix for InitTime and GetMicroSeconds in JackWinTime.c. New jack_free function added in jack.h. Reworked Torben Hohn fix for server restart issue on Windows. Correct jack_set_error_function, jack_set_info_function and jack_set_thread_creator functions. Correct JackFifo::TimedWait for EINTR handling. Move DBus based audio device reservation code in ALSA backend compilation. Correct JackTransportEngine::MakeAllLocating, sync callback has to be called in this case also. NetJack2 code : better error checkout, method renaming. Tim Bechmann patch : hammerfall, only release monitor thread, if it has been created. Tim Bechmann memops.c optimization patches. In combined --dbus and --classic compilation code, use PulseAudio acquire/release code. Big rewrite of Solaris boomer driver, seems to work in duplex mode at least. Loopback backend reborn as a dynamically loadable separated backend. +1.9.4 : Solaris boomer backend now working in capture or playback only mode. Add a -G parameter in CoreAudio backend (the computation value in RT thread expressed as percent of period). Use SNDCTL_DSP_SYNCGROUP/SNDCTL_DSP_SYNCSTART API to synchronize input and output in Solaris boomer backend. Big endian bug fix in memops.c. Fix issues in JackNetDriver::DecodeTransportData and JackNetDriver::Initialize. Correct CPU timing in JackNetDriver, now take cycle begin time after Read. Simplify transport in NetJack2: master only can control transport. Change CoreAudio notification thread setup for OSX Snow Leopard. Correct server temporary mode : now set a global and quit after server/client message handling is finished. Add a string parameter to server ==> client notification, add a new JackInfoShutdownCallback type. CoreAudio backend now issue a JackInfoShutdownCallback when an unrecoverable error is detected (sampling rate change, stream configuration changeÉ). Correct jackdmp.cpp (failures case were not correct..). Improve JackCoreAudioDriver code. Raise default port number to 2048. Correct JackProcessSync::LockedTimedWait. Correct JACK_MESSAGE_SIZE value, particularly in OSX RPC code. Now start server channel thread only when backend has been started (so in JackServer::Start). Should solve race conditions at start time. jack_verbose moved to JackGlobals class. Improve aggregate device management in JackCoreAudioDriver : now a "private" device only and cleanup properly. Aggregate device code added to JackCoreAudioAdapter. Implement "hog mode" (exclusive access of the audio device) in JackCoreAudioDriver. Fix jack_set_sample_rate_callback to have he same behavior as in JACK1. Dynamic system version detection in JackCoreAudioDriver to either create public or private aggregate device. In JackCoreAudioDriver, force the SR value to the wanted one *before* creating aggregate device (otherwise creation will fail). In JackCoreAudioDriver, better cleanup of AD when intermediate open failure. In JackCoreAudioDriver::Start, wait for the audio driver to effectively start (use the MeasureCallback). In JackCoreAudioDriver, improve management of input/output channels: -1 is now used internally to indicate a wanted max value. In JackCoreAudioDriver::OpenAUHAL, correct stream format setup and cleanup. Correct crash bug in JackAudioAdapterInterface when not input is used in adapter (temporary fixÉ). Sync JackCoreAudioAdapter code on JackCoreAudioDriver one. JACK_SCHED_POLICY switched to SCHED_FIFO. Now can aggregate device that are themselves AD. No reason to make jack_on_shutdown deprecated, so revert the incorrect change. Thread AcquireRealTime and DropRealTime were (incorrectly) using fThread field. Use pthread_self()) (or GetCurrentThread() on Windows) to get the calling thread. Correctly save and restore RT mode state in freewheel mode. Correct freewheel code on client side. Fix AcquireRealTime and DropRealTime: now distinguish when called from another thread (AcquireRealTime/DropRealTime) and from the thread itself (AcquireSelfRealTime/DropSelfRealTime). Correct JackPosixThread::StartImp : thread priority setting now done in the RT case only. Correct JackGraphManager::GetBuffer for the "client loop with one connection" case : buffer must be copied. Correct JackInfoShutdownCallback prototype, two new JackClientProcessFailure and JackClientZombie JackStatus code. Correct JackCoreAudio driver when empty strings are given as -C, -P or -d parameter. Better memory allocation error checking on client (library) side. Better memory allocation error checking in ringbuffer.c, weak import improvements. Memory allocation error checking for jack_client_new and jack_client_open (server and client side). Memory allocation error checking in server for RPC. Simplify server temporary mode : now use a JackTemporaryException. Lock/Unlock shared memory segments (to test...). Sync with JACK1 : -r parameter now used for no-realtime, realtime (-R) is now default, usable backend given vie platform. In JackCoreAudio driver, (possibly) clock drift compensation when needed in aggregated devices. In JackCoreAudio driver, clock drift compensation in aggregated devices working. In JackCoreAudio driver, clock drift compensation semantic changed a bit : when on, does not activate if not needed (same clock domain). Sync JackCoreAudioAdapter code with JackCoreAudioDriver. This is a work in progress but the implementation is now stable enough to be tested. jackdmp has been used successfully with the following applications : Ardour, Hydrogen, Jamin, Qjackctl, Jack-Rack, SooperLooper, AlsaPlayer... diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index 34e591e4..97e58833 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -290,15 +290,23 @@ EXPORT void jack_set_info_function (print_function func) EXPORT jack_client_t* jack_client_new(const char* client_name) { - assert(JackGlobals::fOpenMutex); - JackGlobals::fOpenMutex->Lock(); - jack_error("jack_client_new: deprecated"); - int options = JackUseExactName; - if (getenv("JACK_START_SERVER") == NULL) - options |= JackNoStartServer; - jack_client_t* res = jack_client_open_aux(client_name, (jack_options_t)options, NULL, NULL); - JackGlobals::fOpenMutex->Unlock(); - return res; + try { + assert(JackGlobals::fOpenMutex); + JackGlobals::fOpenMutex->Lock(); + jack_error("jack_client_new: deprecated"); + int options = JackUseExactName; + if (getenv("JACK_START_SERVER") == NULL) + options |= JackNoStartServer; + jack_client_t* res = jack_client_open_aux(client_name, (jack_options_t)options, NULL, NULL); + JackGlobals::fOpenMutex->Unlock(); + return res; + } catch (std::bad_alloc& e) { + jack_error("Memory allocation error..."); + return NULL; + } catch (...) { + jack_error("Unknown error..."); + return NULL; + } } EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames) @@ -814,7 +822,6 @@ EXPORT void jack_on_shutdown(jack_client_t* ext_client, JackShutdownCallback cal JackLibGlobals::CheckContext(); #endif JackClient* client = (JackClient*)ext_client; - jack_error("jack_on_shutdown: deprecated, use jack_on_info_shutdown"); if (client == NULL) { jack_error("jack_on_shutdown called with a NULL client"); } else { @@ -1944,5 +1951,7 @@ jack_get_version_string() EXPORT void jack_free(void* ptr) { - free(ptr); + if (ptr) { + free(ptr); + } } diff --git a/common/JackArgParser.cpp b/common/JackArgParser.cpp index fcccaa23..e9b8f6f9 100644 --- a/common/JackArgParser.cpp +++ b/common/JackArgParser.cpp @@ -128,6 +128,10 @@ namespace Jack { return -1; //else allocate and fill it argv = (char**)calloc (fArgv.size(), sizeof(char*)); + if (argv == NULL) + { + return -1; + } for ( unsigned int i = 0; i < fArgv.size(); i++ ) { argv[i] = (char*)calloc(fArgv[i].length(), sizeof(char)); diff --git a/common/JackClient.cpp b/common/JackClient.cpp index 7cfb50ef..e6469267 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -170,90 +170,105 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, case kAddClient: jack_log("JackClient::kAddClient fName = %s name = %s", GetClientControl()->fName, name); - if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) // Don't call the callback for the registering client itself + if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) { // Don't call the callback for the registering client itself fClientRegistration(name, 1, fClientRegistrationArg); + } break; case kRemoveClient: jack_log("JackClient::kRemoveClient fName = %s name = %s", GetClientControl()->fName, name); - if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) // Don't call the callback for the registering client itself + if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) { // Don't call the callback for the registering client itself fClientRegistration(name, 0, fClientRegistrationArg); + } break; case kBufferSizeCallback: jack_log("JackClient::kBufferSizeCallback buffer_size = %ld", value1); - if (fBufferSize) + if (fBufferSize) { res = fBufferSize(value1, fBufferSizeArg); + } break; case kSampleRateCallback: jack_log("JackClient::kSampleRateCallback sample_rate = %ld", value1); - if (fSampleRate) + if (fSampleRate) { res = fSampleRate(value1, fSampleRateArg); + } break; case kGraphOrderCallback: jack_log("JackClient::kGraphOrderCallback"); - if (fGraphOrder) + if (fGraphOrder) { res = fGraphOrder(fGraphOrderArg); + } break; case kStartFreewheelCallback: jack_log("JackClient::kStartFreewheel"); SetupDriverSync(true); - fThread.DropRealTime(); - if (fFreewheel) + fThread.DropRealTime(); // Always done (JACK server in RT mode or not...) + if (fFreewheel) { fFreewheel(1, fFreewheelArg); + } break; case kStopFreewheelCallback: jack_log("JackClient::kStopFreewheel"); SetupDriverSync(false); - if (fFreewheel) + if (fFreewheel) { fFreewheel(0, fFreewheelArg); - fThread.AcquireRealTime(); + } + if (GetEngineControl()->fRealTime) { + fThread.AcquireRealTime(); + } break; case kPortRegistrationOnCallback: jack_log("JackClient::kPortRegistrationOn port_index = %ld", value1); - if (fPortRegistration) + if (fPortRegistration) { fPortRegistration(value1, 1, fPortRegistrationArg); + } break; case kPortRegistrationOffCallback: jack_log("JackClient::kPortRegistrationOff port_index = %ld ", value1); - if (fPortRegistration) + if (fPortRegistration) { fPortRegistration(value1, 0, fPortRegistrationArg); + } break; case kPortConnectCallback: jack_log("JackClient::kPortConnectCallback src = %ld dst = %ld", value1, value2); - if (fPortConnect) + if (fPortConnect) { fPortConnect(value1, value2, 1, fPortConnectArg); + } break; case kPortDisconnectCallback: jack_log("JackClient::kPortDisconnectCallback src = %ld dst = %ld", value1, value2); - if (fPortConnect) + if (fPortConnect) { fPortConnect(value1, value2, 0, fPortConnectArg); + } break; case kPortRenameCallback: jack_log("JackClient::kPortRenameCallback port = %ld"); - if (fPortRename) + if (fPortRename) { fPortRename(value1, GetGraphManager()->GetPort(value1)->GetName(), fPortRenameArg); + } break; case kXRunCallback: jack_log("JackClient::kXRunCallback"); - if (fXrun) + if (fXrun) { res = fXrun(fXrunArg); + } break; case kShutDownCallback: jack_log("JackClient::kShutDownCallback"); if (fInfoShutdown) { - fInfoShutdown(value1, message, fInfoShutdownArg); + fInfoShutdown((jack_status_t)value1, message, fInfoShutdownArg); fInfoShutdown = NULL; } break; @@ -454,7 +469,7 @@ inline void JackClient::End() jack_log("JackClient::Execute end name = %s", GetClientControl()->fName); // Hum... not sure about this, the following "close" code is called in the RT thread... int result; - fThread.DropRealTime(); + fThread.DropSelfRealTime(); GetClientControl()->fActive = false; fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result); fThread.Terminate(); @@ -465,7 +480,7 @@ inline void JackClient::Error() jack_error("JackClient::Execute error name = %s", GetClientControl()->fName); // Hum... not sure about this, the following "close" code is called in the RT thread... int result; - fThread.DropRealTime(); + fThread.DropSelfRealTime(); GetClientControl()->fActive = false; fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result); ShutDown(); @@ -973,14 +988,7 @@ char* JackClient::GetInternalClientName(int ref) char name_res[JACK_CLIENT_NAME_SIZE + 1]; int result = -1; fChannel->GetInternalClientName(GetClientControl()->fRefNum, ref, name_res, &result); - - if (result < 0) { - return NULL; - } else { - char* name = (char*)malloc(strlen(name_res)); - strcpy(name, name_res); - return name; - } + return (result < 0) ? NULL : strdup(name_res); } int JackClient::InternalClientHandle(const char* client_name, jack_status_t* status) diff --git a/common/JackConstants.h b/common/JackConstants.h index 00a0be99..aa6e0ce5 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -41,7 +41,7 @@ #define DRIVER_PORT_NUM 256 #ifndef PORT_NUM_FOR_CLIENT -#define PORT_NUM_FOR_CLIENT 512 +#define PORT_NUM_FOR_CLIENT 768 #endif #define FIRST_AVAILABLE_PORT 1 diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index 488046c9..37eeb88a 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -611,6 +611,11 @@ get_realtime_priority_constraint() //jack_info("realtime priority range is (%d,%d)", min, max); constraint_ptr = (jack_driver_param_constraint_desc_t *)calloc(1, sizeof(jack_driver_param_value_enum_t)); + if (constraint_ptr == NULL) + { + jack_error("Cannot allocate memory for jack_driver_param_constraint_desc_t structure."); + return NULL; + } constraint_ptr->flags = JACK_CONSTRAINT_FLAG_RANGE; constraint_ptr->constraint.range.min.i = min; diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index 83a22ad4..537c4160 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -119,7 +119,7 @@ void JackEngine::ReleaseRefnum(int ref) // last client and temporay case: quit the server jack_log("JackEngine::ReleaseRefnum server quit"); fEngineControl->fTemporary = false; - JackServerGlobals::fKilled = true; + throw JackTemporaryException(); } } } @@ -305,7 +305,15 @@ void JackEngine::NotifyFailure(int code, const char* reason) void JackEngine::NotifyFreewheel(bool onoff) { - fEngineControl->fRealTime = !onoff; + if (onoff) { + // Save RT state + fEngineControl->fSavedRealTime = fEngineControl->fRealTime; + fEngineControl->fRealTime = false; + } else { + // Restore RT state + fEngineControl->fRealTime = fEngineControl->fSavedRealTime; + fEngineControl->fSavedRealTime = false; + } NotifyClients((onoff ? kStartFreewheelCallback : kStopFreewheelCallback), true, "", 0, 0); } diff --git a/common/JackEngineControl.h b/common/JackEngineControl.h index 41c9c5b8..326e3b7f 100644 --- a/common/JackEngineControl.h +++ b/common/JackEngineControl.h @@ -58,6 +58,7 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem float fXrunDelayedUsecs; bool fTimeOut; bool fRealTime; + bool fSavedRealTime; // RT state saved and restored during Freewheel mode int fServerPriority; int fClientPriority; int fMaxClientPriority; @@ -100,6 +101,7 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem fTimeOut = (timeout > 0); fTimeOutUsecs = timeout * 1000; fRealTime = rt; + fSavedRealTime = false; fServerPriority = priority; fClientPriority = (rt) ? priority - 5 : 0; fMaxClientPriority = (rt) ? priority - 1 : 0; diff --git a/common/JackException.h b/common/JackException.h index af899b8a..3270f20a 100644 --- a/common/JackException.h +++ b/common/JackException.h @@ -58,7 +58,25 @@ class SERVER_EXPORT JackException : public std::runtime_error { }; /*! -\brief Exception possibly thrown by Net Slaves. + \brief Exception thrown by JackEngine in temporary mode. + */ + +class SERVER_EXPORT JackTemporaryException : public JackException { + + public: + + JackTemporaryException(const std::string& msg) : JackException(msg) + {} + JackTemporaryException(char* msg) : JackException(msg) + {} + JackTemporaryException(const char* msg) : JackException(msg) + {} + JackTemporaryException() : JackException("") + {} +}; + +/*! +\brief Exception possibly thrown by Net slaves. */ class SERVER_EXPORT JackNetException : public JackException { diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index f6aae030..d16becd6 100644 --- a/common/JackGraphManager.cpp +++ b/common/JackGraphManager.cpp @@ -135,8 +135,8 @@ void* JackGraphManager::GetBuffer(jack_port_id_t port_index, jack_nframes_t buff JackConnectionManager* manager = ReadCurrentState(); JackPort* port = GetPort(port_index); + // This happens when a port has just been unregistered and is still used by the RT code if (!port->IsUsed()) { - // This happens when a port has just been unregistered and is still used by the RT code. jack_log("JackGraphManager::GetBuffer : port = %ld is released state", port_index); return GetBuffer(0); // port_index 0 is not used } @@ -149,14 +149,29 @@ void* JackGraphManager::GetBuffer(jack_port_id_t port_index, jack_nframes_t buff // Input port jack_int_t len = manager->Connections(port_index); - if (len == 0) { // No connections: return a zero-filled buffer + // No connections : return a zero-filled buffer + if (len == 0) { port->ClearBuffer(buffer_size); return port->GetBuffer(); - } else if (len == 1) { // One connection: use zero-copy mode - just pass the buffer of the connected (output) port. - assert(manager->GetPort(port_index, 0) != port_index); // Check recursion - return GetBuffer(manager->GetPort(port_index, 0), buffer_size); - } else { // Multiple connections - + + // One connection + } 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]; + buffers[0] = GetBuffer(src_index, buffer_size); + port->MixBuffers(buffers, 1, buffer_size); + return port->GetBuffer(); + // Otherwise, use zero-copy mode, just pass the buffer of the connected (output) port. + } else { + return GetBuffer(src_index, buffer_size); + } + + // Multiple connections : mix all buffers + } else { + const jack_int_t* connections = manager->GetConnections(port_index); void* buffers[CONNECTION_NUM_FOR_PORT]; jack_port_id_t src_index; @@ -167,7 +182,6 @@ void* JackGraphManager::GetBuffer(jack_port_id_t port_index, jack_nframes_t buff buffers[i] = GetBuffer(src_index, buffer_size); } - JackPort* port = GetPort(port_index); port->MixBuffers(buffers, i, buffer_size); return port->GetBuffer(); } @@ -688,6 +702,9 @@ 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; do { cur_index = GetCurrentIndex(); @@ -768,6 +785,9 @@ const char** JackGraphManager::GetPorts(const char* port_name_pattern, const cha { const char** res = (const char**)malloc(sizeof(char*) * PORT_NUM); UInt16 cur_index, next_index; + + if (!res) + return NULL; do { cur_index = GetCurrentIndex(); diff --git a/common/JackLibAPI.cpp b/common/JackLibAPI.cpp index be6522f0..b2cce06f 100644 --- a/common/JackLibAPI.cpp +++ b/common/JackLibAPI.cpp @@ -111,14 +111,22 @@ EXPORT jack_client_t* jack_client_open_aux(const char* client_name, jack_options EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...) { - assert(JackGlobals::fOpenMutex); - JackGlobals::fOpenMutex->Lock(); - va_list ap; - va_start(ap, status); - jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap); - va_end(ap); - JackGlobals::fOpenMutex->Unlock(); - return res; + try { + assert(JackGlobals::fOpenMutex); + JackGlobals::fOpenMutex->Lock(); + va_list ap; + va_start(ap, status); + jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap); + va_end(ap); + JackGlobals::fOpenMutex->Unlock(); + return res; + } catch(std::bad_alloc& e) { + jack_error("Memory allocation error..."); + return NULL; + } catch (...) { + jack_error("Unknown error..."); + return NULL; + } } EXPORT int jack_client_close(jack_client_t* ext_client) diff --git a/common/JackLockedEngine.h b/common/JackLockedEngine.h index d1d9d3d1..c2de8512 100644 --- a/common/JackLockedEngine.h +++ b/common/JackLockedEngine.h @@ -22,10 +22,35 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackEngine.h" #include "JackMutex.h" +#include "JackTools.h" +#include "JackException.h" namespace Jack { +#define TRY_CALL \ + try { \ + +#define CATCH_EXCEPTION_RETURN \ + } catch(std::bad_alloc& e) { \ + jack_error("Memory allocation error..."); \ + return -1; \ + } catch(JackTemporaryException& e) { \ + jack_error("JackTemporaryException : now quits..."); \ + JackTools::KillServer(); \ + return -1; \ + } catch (...) { \ + jack_error("Unknown error..."); \ + return -1; \ + } \ + +#define CATCH_ENGINE_EXCEPTION \ + } catch(std::bad_alloc& e) { \ + jack_error("Memory allocation error..."); \ + } catch (...) { \ + jack_error("Unknown error..."); \ + } \ + /*! \brief Locked Engine, access to methods is serialized using a mutex. */ @@ -47,108 +72,146 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble int Open() { // No lock needed + TRY_CALL return fEngine.Open(); + CATCH_EXCEPTION_RETURN } int Close() { // No lock needed + TRY_CALL return fEngine.Close(); + CATCH_EXCEPTION_RETURN } // Client management int ClientCheck(const char* name, char* name_res, int protocol, int options, int* status) { + TRY_CALL JackLock lock(this); return fEngine.ClientCheck(name, name_res, protocol, options, status); + CATCH_EXCEPTION_RETURN } int ClientExternalOpen(const char* name, int pid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager) { + TRY_CALL JackLock lock(this); return fEngine.ClientExternalOpen(name, pid, ref, shared_engine, shared_client, shared_graph_manager); + CATCH_EXCEPTION_RETURN } int ClientInternalOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, bool wait) { + TRY_CALL JackLock lock(this); return fEngine.ClientInternalOpen(name, ref, shared_engine, shared_manager, client, wait); + CATCH_EXCEPTION_RETURN } int ClientExternalClose(int refnum) { + TRY_CALL JackLock lock(this); return fEngine.ClientExternalClose(refnum); + CATCH_EXCEPTION_RETURN } int ClientInternalClose(int refnum, bool wait) { + TRY_CALL JackLock lock(this); return fEngine.ClientInternalClose(refnum, wait); + CATCH_EXCEPTION_RETURN } int ClientActivate(int refnum, bool is_real_time) { + TRY_CALL JackLock lock(this); return fEngine.ClientActivate(refnum, is_real_time); + CATCH_EXCEPTION_RETURN } int ClientDeactivate(int refnum) { + TRY_CALL JackLock lock(this); return fEngine.ClientDeactivate(refnum); + CATCH_EXCEPTION_RETURN } // Internal client management int GetInternalClientName(int int_ref, char* name_res) { + TRY_CALL JackLock lock(this); return fEngine.GetInternalClientName(int_ref, name_res); + CATCH_EXCEPTION_RETURN } int InternalClientHandle(const char* client_name, int* status, int* int_ref) { + TRY_CALL JackLock lock(this); return fEngine.InternalClientHandle(client_name, status, int_ref); + CATCH_EXCEPTION_RETURN } int InternalClientUnload(int refnum, int* status) { + TRY_CALL JackLock lock(this); return fEngine.InternalClientUnload(refnum, status); + CATCH_EXCEPTION_RETURN } // Port management int PortRegister(int refnum, const char* name, const char *type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port) { + TRY_CALL JackLock lock(this); return fEngine.PortRegister(refnum, name, type, flags, buffer_size, port); + CATCH_EXCEPTION_RETURN } int PortUnRegister(int refnum, jack_port_id_t port) { + TRY_CALL JackLock lock(this); return fEngine.PortUnRegister(refnum, port); + CATCH_EXCEPTION_RETURN } int PortConnect(int refnum, const char* src, const char* dst) { + TRY_CALL JackLock lock(this); return fEngine.PortConnect(refnum, src, dst); + CATCH_EXCEPTION_RETURN } int PortDisconnect(int refnum, const char* src, const char* dst) { + TRY_CALL JackLock lock(this); return fEngine.PortDisconnect(refnum, src, dst); + CATCH_EXCEPTION_RETURN } int PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst) { + TRY_CALL JackLock lock(this); return fEngine.PortConnect(refnum, src, dst); + CATCH_EXCEPTION_RETURN } int PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst) { + TRY_CALL JackLock lock(this); return fEngine.PortDisconnect(refnum, src, dst); + CATCH_EXCEPTION_RETURN } - + int PortRename(int refnum, jack_port_id_t port, const char* name) { + TRY_CALL JackLock lock(this); return fEngine.PortRename(refnum, port, name); + CATCH_EXCEPTION_RETURN } // Graph @@ -167,48 +230,64 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble void NotifyXRun(int refnum) { + TRY_CALL JackLock lock(this); fEngine.NotifyXRun(refnum); + CATCH_ENGINE_EXCEPTION } void NotifyGraphReorder() { + TRY_CALL JackLock lock(this); fEngine.NotifyGraphReorder(); + CATCH_ENGINE_EXCEPTION } void NotifyBufferSize(jack_nframes_t buffer_size) { + TRY_CALL JackLock lock(this); fEngine.NotifyBufferSize(buffer_size); + CATCH_ENGINE_EXCEPTION } void NotifySampleRate(jack_nframes_t sample_rate) { + TRY_CALL JackLock lock(this); fEngine.NotifySampleRate(sample_rate); + CATCH_ENGINE_EXCEPTION } void NotifyFreewheel(bool onoff) { + TRY_CALL JackLock lock(this); fEngine.NotifyFreewheel(onoff); + CATCH_ENGINE_EXCEPTION } - + void NotifyFailure(int code, const char* reason) { + TRY_CALL JackLock lock(this); fEngine.NotifyFailure(code, reason); + CATCH_ENGINE_EXCEPTION } - + int GetClientPID(const char* name) { + TRY_CALL JackLock lock(this); return fEngine.GetClientPID(name); + CATCH_EXCEPTION_RETURN } - + int GetClientRefNum(const char* name) { + TRY_CALL JackLock lock(this); return fEngine.GetClientRefNum(name); + CATCH_EXCEPTION_RETURN } - + }; } // end of namespace diff --git a/common/JackMessageBuffer.cpp b/common/JackMessageBuffer.cpp index bc380a52..8dacfe67 100644 --- a/common/JackMessageBuffer.cpp +++ b/common/JackMessageBuffer.cpp @@ -46,7 +46,7 @@ void JackMessageBuffer::Stop() if (fOverruns > 0) { jack_error("WARNING: %d message buffer overruns!", fOverruns); } else { - jack_info("no message buffer overruns"); + jack_log("no message buffer overruns"); } fGuard.Lock(); fRunning = false; diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index c1817848..8eff6900 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -228,8 +228,8 @@ namespace Jack // Will do "something" on OSX only... fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); - if (fThread.AcquireRealTime(GetEngineControl()->fClientPriority) < 0) { - jack_error("AcquireRealTime error"); + if (fThread.AcquireSelfRealTime(GetEngineControl()->fClientPriority) < 0) { + jack_error("AcquireSelfRealTime error"); } else { set_threaded_log_function(); } @@ -251,7 +251,7 @@ namespace Jack e.PrintMessage(); jack_info("NetAdapter is restarted."); Reset(); - fThread.DropRealTime(); + fThread.DropSelfRealTime(); fThread.SetStatus(JackThread::kIniting); if (Init()) { fThread.SetStatus(JackThread::kRunning); diff --git a/common/JackNetOneDriver.cpp b/common/JackNetOneDriver.cpp new file mode 100644 index 00000000..bc0160bc --- /dev/null +++ b/common/JackNetOneDriver.cpp @@ -0,0 +1,1143 @@ +/* +Copyright (C) 2001 Paul Davis +Copyright (C) 2008 Romain Moret at 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. +*/ + +//#define HAVE_CELT 1 + +#ifdef WIN32 +#include +#endif + +#include "JackNetOneDriver.h" +#include "JackEngineControl.h" +#include "JackGraphManager.h" +#include "JackWaitThreadedDriver.h" +#include "JackTools.h" +#include "driver_interface.h" + +#include "netjack.h" +#include "netjack_packet.h" + +#if HAVE_SAMPLERATE +#include "samplerate.h" +#endif + +#if HAVE_CELT +#include "celt/celt.h" +#endif + +#define MIN(x,y) ((x)<(y) ? (x) : (y)) + +using namespace std; + +namespace Jack +{ + JackNetOneDriver::JackNetOneDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, + int port, int mtu, int capture_ports, int playback_ports, int midi_input_ports, int midi_output_ports, + int sample_rate, int period_size, int resample_factor, + const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig, + int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val ) + : JackAudioDriver ( name, alias, engine, table ) + { + jack_log ( "JackNetOneDriver::JackNetOneDriver port %d", port ); + +#ifdef WIN32 + WSADATA wsa; + int rc = WSAStartup(MAKEWORD(2,0),&wsa); +#endif + + netjack_init( & (this->netj), + NULL, // client + name, + capture_ports, + playback_ports, + midi_input_ports, + midi_output_ports, + sample_rate, + period_size, + port, + transport_sync, + resample_factor, + 0, + bitdepth, + use_autoconfig, + latency, + redundancy, + dont_htonl_floats, + always_deadline, + jitter_val); + } + + JackNetOneDriver::~JackNetOneDriver() + { + // No destructor yet. + } + +//open, close, attach and detach------------------------------------------------------ + int JackNetOneDriver::Open ( jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing, + int inchannels, int outchannels, bool monitor, + const char* capture_driver_name, const char* playback_driver_name, + jack_nframes_t capture_latency, jack_nframes_t playback_latency ) + { + if ( JackAudioDriver::Open ( buffer_size, + samplerate, + capturing, + playing, + inchannels, + outchannels, + monitor, + capture_driver_name, + playback_driver_name, + capture_latency, + playback_latency ) == 0 ) + { + fEngineControl->fPeriod = 0; + fEngineControl->fComputation = 500 * 1000; + fEngineControl->fConstraint = 500 * 1000; + return 0; + } + else + { + jack_error( "open fail" ); + return -1; + } + } + + int JackNetOneDriver::Close() + { + FreePorts(); + netjack_release( &netj ); + return JackDriver::Close(); + } + + int JackNetOneDriver::Attach() + { + return 0; + } + + int JackNetOneDriver::Detach() + { + return 0; + } + + int JackNetOneDriver::AllocPorts() + { + jack_port_id_t port_id; + char buf[64]; + unsigned int chn; + int port_flags; + + + //if (netj.handle_transport_sync) + // jack_set_sync_callback(netj.client, (JackSyncCallback) net_driver_sync_cb, NULL); + + port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; + + for (chn = 0; chn < netj.capture_channels_audio; chn++) { + snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); + + if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, + static_cast ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT ) + { + jack_error ( "driver: cannot register port for %s", buf ); + return -1; + } + //port = fGraphManager->GetPort ( port_id ); + + netj.capture_ports = + jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); + + if( netj.bitdepth == CELT_MODE ) { +#if HAVE_CELT +#if HAVE_CELT_API_0_7 + celt_int32 lookahead; + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); + netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); +#else + celt_int32_t lookahead; + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); + netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode ) ); +#endif + celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); + netj.codec_latency = 2*lookahead; +#endif + } else { +#if HAVE_SAMPLERATE + netj.capture_srcs = jack_slist_append(netj.capture_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); +#endif + } + } + for (chn = netj.capture_channels_audio; chn < netj.capture_channels; chn++) { + snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); + + if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, + static_cast ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT ) + { + jack_error ( "driver: cannot register port for %s", buf ); + return -1; + } + //port = fGraphManager->GetPort ( port_id ); + + netj.capture_ports = + jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); + } + + port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; + + for (chn = 0; chn < netj.playback_channels_audio; chn++) { + snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); + + if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, + static_cast ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT ) + { + jack_error ( "driver: cannot register port for %s", buf ); + return -1; + } + //port = fGraphManager->GetPort ( port_id ); + + netj.playback_ports = + jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); + + if( netj.bitdepth == CELT_MODE ) { +#if HAVE_CELT +#if HAVE_CELT_API_0_7 + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); + netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); +#else + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); + netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode ) ); +#endif +#endif + } else { +#if HAVE_SAMPLERATE + netj.playback_srcs = jack_slist_append(netj.playback_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); +#endif + } + } + for (chn = netj.playback_channels_audio; chn < netj.playback_channels; chn++) { + snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); + + if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, + static_cast ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT ) + { + jack_error ( "driver: cannot register port for %s", buf ); + return -1; + } + //port = fGraphManager->GetPort ( port_id ); + + netj.playback_ports = + jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); + } + return 0; + } + +//init and restart-------------------------------------------------------------------- + bool JackNetOneDriver::Initialize() + { + jack_log ( "JackNetOneDriver::Init()" ); + + if( global_packcache != NULL ) { + FreePorts(); + netjack_release( &netj ); + } + + //display some additional infos + jack_info ( "NetOne driver started" ); + if( netjack_startup( &netj ) ) { + return false; + } + + //register jack ports + if ( AllocPorts() != 0 ) + { + jack_error ( "Can't allocate ports." ); + return false; + } + + + //monitor + //driver parametering + JackAudioDriver::SetBufferSize ( netj.period_size ); + JackAudioDriver::SetSampleRate ( netj.sample_rate ); + + JackDriver::NotifyBufferSize ( netj.period_size ); + JackDriver::NotifySampleRate ( netj.sample_rate ); + + //transport engine parametering + fEngineControl->fTransport.SetNetworkSync ( true ); + return true; + } + + +//jack ports and buffers-------------------------------------------------------------- + +//driver processes-------------------------------------------------------------------- + int JackNetOneDriver::Read() + { + int delay; + delay = netjack_wait( &netj ); + if( delay ) { + NotifyXRun(fBeginDateUst, (float) delay); + jack_error( "netxruns... duration: %dms", delay/1000 ); + } + + if( (netj.num_lost_packets * netj.period_size / netj.sample_rate) > 2 ) + JackTools::ThrowJackNetException(); + + //netjack_read( &netj, netj.period_size ); + JackDriver::CycleTakeBeginTime(); + + jack_position_t local_trans_pos; + jack_transport_state_t local_trans_state; + + unsigned int *packet_buf, *packet_bufX; + + if( ! netj.packet_data_valid ) { + jack_log( "data not valid" ); + render_payload_to_jack_ports (netj.bitdepth, NULL, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats ); + return 0; + } + packet_buf = netj.rx_buf; + + jacknet_packet_header *pkthdr = (jacknet_packet_header *)packet_buf; + + packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); + + netj.reply_port = pkthdr->reply_port; + netj.latency = pkthdr->latency; + + // Special handling for latency=0 + if( netj.latency == 0 ) + netj.resync_threshold = 0; + else + netj.resync_threshold = MIN( 15, pkthdr->latency-1 ); + + // check whether, we should handle the transport sync stuff, or leave trnasports untouched. + if (netj.handle_transport_sync) { +#if 1 + unsigned int compensated_tranport_pos = (pkthdr->transport_frame + (pkthdr->latency * netj.period_size) + netj.codec_latency); + + // read local transport info.... + //local_trans_state = jack_transport_query(netj.client, &local_trans_pos); + + local_trans_state = fEngineControl->fTransport.Query ( &local_trans_pos ); + + // Now check if we have to start or stop local transport to sync to remote... + switch (pkthdr->transport_state) { + case JackTransportStarting: + // the master transport is starting... so we set our reply to the sync_callback; + if (local_trans_state == JackTransportStopped) { + fEngineControl->fTransport.SetCommand ( TransportCommandStart ); + //jack_transport_start(netj.client); + //last_transport_state = JackTransportStopped; + netj.sync_state = 0; + jack_info("locally stopped... starting..."); + } + + if (local_trans_pos.frame != compensated_tranport_pos) + { + jack_position_t new_pos = local_trans_pos; + new_pos.frame = compensated_tranport_pos + 2*netj.period_size; + new_pos.valid = (jack_position_bits_t) 0; + + + fEngineControl->fTransport.RequestNewPos ( &new_pos ); + //jack_transport_locate(netj.client, compensated_tranport_pos); + //last_transport_state = JackTransportRolling; + netj.sync_state = 0; + jack_info("starting locate to %d", compensated_tranport_pos ); + } + break; + case JackTransportStopped: + netj.sync_state = 1; + if (local_trans_pos.frame != (pkthdr->transport_frame)) { + jack_position_t new_pos = local_trans_pos; + new_pos.frame = pkthdr->transport_frame; + new_pos.valid = (jack_position_bits_t)0; + fEngineControl->fTransport.RequestNewPos ( &new_pos ); + //jack_transport_locate(netj.client, (pkthdr->transport_frame)); + jack_info("transport is stopped locate to %d", pkthdr->transport_frame); + } + if (local_trans_state != JackTransportStopped) + //jack_transport_stop(netj.client); + fEngineControl->fTransport.SetCommand ( TransportCommandStop ); + break; + case JackTransportRolling: + netj.sync_state = 1; +// if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * netj.period_size)) { +// jack_transport_locate(netj.client, (pkthdr->transport_frame + (pkthdr->latency + 2) * netj.period_size)); +// jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*netj.period_size); +// } + if (local_trans_state != JackTransportRolling) + fEngineControl->fTransport.SetState ( JackTransportRolling ); + + break; + + case JackTransportLooping: + break; + } +#endif + } + + render_payload_to_jack_ports (netj.bitdepth, packet_bufX, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats ); + packet_cache_release_packet(global_packcache, netj.expected_framecnt ); + return 0; + } + + int JackNetOneDriver::Write() + { + int syncstate = netj.sync_state | ((fEngineControl->fTransport.GetState() == JackTransportNetStarting) ? 1 : 0 ); + uint32_t *packet_buf, *packet_bufX; + + int packet_size = get_sample_size(netj.bitdepth) * netj.playback_channels * netj.net_period_up + sizeof(jacknet_packet_header); + jacknet_packet_header *pkthdr; + + packet_buf = (uint32_t *) alloca(packet_size); + pkthdr = (jacknet_packet_header *)packet_buf; + + if( netj.running_free ) { + return 0; + } + + // offset packet_bufX by the packetheader. + packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); + + pkthdr->sync_state = syncstate;; + pkthdr->latency = netj.time_to_deadline; + //printf( "time to deadline = %d goodness=%d\n", (int)netj.time_to_deadline, netj.deadline_goodness ); + pkthdr->framecnt = netj.expected_framecnt; + + + render_jack_ports_to_payload(netj.bitdepth, netj.playback_ports, netj.playback_srcs, netj.period_size, packet_bufX, netj.net_period_up, netj.dont_htonl_floats ); + + packet_header_hton(pkthdr); + if (netj.srcaddress_valid) + { + unsigned int r; + +#ifdef __APPLE__ + static const int flag = 0; +#else + static const int flag = 0; +#endif + + if (netj.reply_port) + netj.syncsource_address.sin_port = htons(netj.reply_port); + + for( r=0; rdata; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); + } + netj.capture_ports = NULL; + + node = netj.playback_ports; + while( node != NULL ) { + JSList *this_node = node; + jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); + } + netj.playback_ports = NULL; + + if( netj.bitdepth == CELT_MODE ) { +#if HAVE_CELT + node = netj.playback_srcs; + while( node != NULL ) { + JSList *this_node = node; + CELTEncoder *enc = (CELTEncoder *) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + celt_encoder_destroy( enc ); + } + netj.playback_srcs = NULL; + + node = netj.capture_srcs; + while( node != NULL ) { + JSList *this_node = node; + CELTDecoder *dec = (CELTDecoder *) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + celt_decoder_destroy( dec ); + } + netj.capture_srcs = NULL; +#endif + } else { +#if HAVE_SAMPLERATE + node = netj.playback_srcs; + while( node != NULL ) { + JSList *this_node = node; + SRC_STATE *state = (SRC_STATE *) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + src_delete( state ); + } + netj.playback_srcs = NULL; + + node = netj.capture_srcs; + while( node != NULL ) { + JSList *this_node = node; + SRC_STATE *state = (SRC_STATE *) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + src_delete( state ); + } + netj.capture_srcs = NULL; +#endif + } +} +//Render functions-------------------------------------------------------------------- + +// render functions for float +void +JackNetOneDriver::render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) +{ + uint32_t chn = 0; + JSList *node = capture_ports; +#if HAVE_SAMPLERATE + JSList *src_node = capture_srcs; +#endif + + uint32_t *packet_bufX = (uint32_t *)packet_payload; + + if( !packet_payload ) + return; + + while (node != NULL) + { + unsigned int i; + int_float_t val; +#if HAVE_SAMPLERATE + SRC_DATA src; +#endif + + jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; + JackPort *port = fGraphManager->GetPort( port_id ); + + jack_default_audio_sample_t* buf = + (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); + + const char *porttype = port->GetType(); + + if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) + { +#if HAVE_SAMPLERATE + // audio port, resample if necessary + if (net_period_down != nframes) + { + SRC_STATE *src_state = (SRC_STATE *)src_node->data; + for (i = 0; i < net_period_down; i++) + { + packet_bufX[i] = ntohl (packet_bufX[i]); + } + + src.data_in = (float *) packet_bufX; + src.input_frames = net_period_down; + + src.data_out = buf; + src.output_frames = nframes; + + src.src_ratio = (float) nframes / (float) net_period_down; + src.end_of_input = 0; + + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); + src_node = jack_slist_next (src_node); + } + else +#endif + { + if( dont_htonl_floats ) + { + memcpy( buf, packet_bufX, net_period_down*sizeof(jack_default_audio_sample_t)); + } + else + { + for (i = 0; i < net_period_down; i++) + { + val.i = packet_bufX[i]; + val.i = ntohl (val.i); + buf[i] = val.f; + } + } + } + } + else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) + { + // midi port, decode midi events + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_down; + uint32_t * buffer_uint32 = (uint32_t*)packet_bufX; + decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_down); + node = jack_slist_next (node); + chn++; + } +} + +void +JackNetOneDriver::render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ) +{ + uint32_t chn = 0; + JSList *node = playback_ports; +#if HAVE_SAMPLERATE + JSList *src_node = playback_srcs; +#endif + + uint32_t *packet_bufX = (uint32_t *) packet_payload; + + while (node != NULL) + { +#if HAVE_SAMPLERATE + SRC_DATA src; +#endif + unsigned int i; + int_float_t val; + jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; + JackPort *port = fGraphManager->GetPort( port_id ); + + jack_default_audio_sample_t* buf = + (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); + + const char *porttype = port->GetType(); + + if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) + { + // audio port, resample if necessary + +#if HAVE_SAMPLERATE + if (net_period_up != nframes) { + SRC_STATE *src_state = (SRC_STATE *) src_node->data; + src.data_in = buf; + src.input_frames = nframes; + + src.data_out = (float *) packet_bufX; + src.output_frames = net_period_up; + + src.src_ratio = (float) net_period_up / (float) nframes; + src.end_of_input = 0; + + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); + + for (i = 0; i < net_period_up; i++) + { + packet_bufX[i] = htonl (packet_bufX[i]); + } + src_node = jack_slist_next (src_node); + } + else +#endif + { + if( dont_htonl_floats ) + { + memcpy( packet_bufX, buf, net_period_up*sizeof(jack_default_audio_sample_t) ); + } + else + { + for (i = 0; i < net_period_up; i++) + { + val.f = buf[i]; + val.i = htonl (val.i); + packet_bufX[i] = val.i; + } + } + } + } + else if (strncmp(porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) + { + // encode midi events from port to packet + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_up; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_up); + node = jack_slist_next (node); + chn++; + } +} + +#if HAVE_CELT +// render functions for celt. +void +JackNetOneDriver::render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes) +{ + uint32_t chn = 0; + JSList *node = capture_ports; + JSList *src_node = capture_srcs; + + unsigned char *packet_bufX = (unsigned char *)packet_payload; + + while (node != NULL) + { + jack_port_id_t port_id = (jack_port_id_t) (intptr_t)node->data; + JackPort *port = fGraphManager->GetPort( port_id ); + + jack_default_audio_sample_t* buf = + (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); + + const char *portname = port->GetType(); + + + if (strncmp(portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) + { + // audio port, decode celt data. + + CELTDecoder *decoder = (CELTDecoder *)src_node->data; + if( !packet_payload ) + celt_decode_float( decoder, NULL, net_period_down, buf ); + else + celt_decode_float( decoder, packet_bufX, net_period_down, buf ); + + src_node = jack_slist_next (src_node); + } + else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) + { + // midi port, decode midi events + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_down / 2; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + if( packet_payload ) + decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_down); + node = jack_slist_next (node); + chn++; + } +} + +void +JackNetOneDriver::render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up) +{ + uint32_t chn = 0; + JSList *node = playback_ports; + JSList *src_node = playback_srcs; + + unsigned char *packet_bufX = (unsigned char *)packet_payload; + + while (node != NULL) + { + jack_port_id_t port_id = (jack_port_id_t) (intptr_t) node->data; + JackPort *port = fGraphManager->GetPort( port_id ); + + jack_default_audio_sample_t* buf = + (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); + + const char *portname = port->GetType(); + + if (strncmp (portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) + { + // audio port, encode celt data. + + int encoded_bytes; + float *floatbuf = (float *)alloca (sizeof(float) * nframes ); + memcpy( floatbuf, buf, nframes*sizeof(float) ); + CELTEncoder *encoder = (CELTEncoder *)src_node->data; + encoded_bytes = celt_encode_float( encoder, floatbuf, NULL, packet_bufX, net_period_up ); + if( encoded_bytes != (int)net_period_up ) + jack_error( "something in celt changed. netjack needs to be changed to handle this." ); + src_node = jack_slist_next( src_node ); + } + else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) + { + // encode midi events from port to packet + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_up / 2; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_up); + node = jack_slist_next (node); + chn++; + } +} + +#endif +/* Wrapper functions with bitdepth argument... */ +void +JackNetOneDriver::render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) +{ +#if HAVE_CELT + if (bitdepth == CELT_MODE) + render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); + else +#endif + render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats); +} + +void +JackNetOneDriver::render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats) +{ +#if HAVE_CELT + if (bitdepth == CELT_MODE) + render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); + else +#endif + render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats); +} + + + +//driver loader----------------------------------------------------------------------- + +#ifdef __cplusplus + extern "C" + { +#endif + SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor () + { + jack_driver_desc_t* desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) ); + jack_driver_param_desc_t * params; + + strcpy ( desc->name, "netone" ); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 + strcpy ( desc->desc, "netjack one slave backend component" ); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 + + desc->nparams = 18; + params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) ); + + int i = 0; + strcpy (params[i].name, "audio-ins"); + params[i].character = 'i'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 2U; + strcpy (params[i].short_desc, "Number of capture channels (defaults to 2)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "audio-outs"); + params[i].character = 'o'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 2U; + strcpy (params[i].short_desc, "Number of playback channels (defaults to 2)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "midi-ins"); + params[i].character = 'I'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, "Number of midi capture channels (defaults to 1)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "midi-outs"); + params[i].character = 'O'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, "Number of midi playback channels (defaults to 1)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "rate"); + params[i].character = 'r'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 48000U; + strcpy (params[i].short_desc, "Sample rate"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "period"); + params[i].character = 'p'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1024U; + strcpy (params[i].short_desc, "Frames per period"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "num-periods"); + params[i].character = 'n'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 5U; + strcpy (params[i].short_desc, + "Network latency setting in no. of periods"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "listen-port"); + params[i].character = 'l'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 3000U; + strcpy (params[i].short_desc, + "The socket port we are listening on for sync packets"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "factor"); + params[i].character = 'f'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, + "Factor for sample rate reduction"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "upstream-factor"); + params[i].character = 'u'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, + "Factor for sample rate reduction on the upstream"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "celt"); + params[i].character = 'c'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, + "sets celt encoding and number of kbits per channel"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "bit-depth"); + params[i].character = 'b'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, + "Sample bit-depth (0 for float, 8 for 8bit and 16 for 16bit)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "transport-sync"); + params[i].character = 't'; + params[i].type = JackDriverParamBool; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, + "Whether to slave the transport to the master transport"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "autoconf"); + params[i].character = 'a'; + params[i].type = JackDriverParamBool; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, + "Whether to use Autoconfig, or just start."); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "redundancy"); + params[i].character = 'R'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, + "Send packets N times"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "native-endian"); + params[i].character = 'e'; + params[i].type = JackDriverParamBool; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, + "Dont convert samples to network byte order."); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "jitterval"); + params[i].character = 'J'; + params[i].type = JackDriverParamInt; + params[i].value.i = 0; + strcpy (params[i].short_desc, + "attempted jitterbuffer microseconds on master"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "always-deadline"); + params[i].character = 'D'; + params[i].type = JackDriverParamBool; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, + "always use deadline"); + strcpy (params[i].long_desc, params[i].short_desc); + + desc->params = params; + + return desc; + } + + SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize ( Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params ) + { + jack_nframes_t sample_rate = 48000; + jack_nframes_t resample_factor = 1; + jack_nframes_t period_size = 1024; + unsigned int capture_ports = 2; + unsigned int playback_ports = 2; + unsigned int capture_ports_midi = 1; + unsigned int playback_ports_midi = 1; + unsigned int listen_port = 3000; + unsigned int resample_factor_up = 0; + unsigned int bitdepth = 0; + unsigned int handle_transport_sync = 1; + unsigned int use_autoconfig = 1; + unsigned int latency = 5; + unsigned int redundancy = 1; + unsigned int mtu = 1400; + int dont_htonl_floats = 0; + int always_deadline = 0; + int jitter_val = 0; + const JSList * node; + const jack_driver_param_t * param; + + + + for ( node = params; node; node = jack_slist_next ( node ) ) + { + param = ( const jack_driver_param_t* ) node->data; + switch ( param->character ) + { + case 'i': + capture_ports = param->value.ui; + break; + + case 'o': + playback_ports = param->value.ui; + break; + + case 'I': + capture_ports_midi = param->value.ui; + break; + + case 'O': + playback_ports_midi = param->value.ui; + break; + + case 'r': + sample_rate = param->value.ui; + break; + + case 'p': + period_size = param->value.ui; + break; + + case 'l': + listen_port = param->value.ui; + break; + + case 'f': + #if HAVE_SAMPLERATE + resample_factor = param->value.ui; + #else + jack_error( "not built with libsamplerate support" ); + return NULL; + #endif + break; + + case 'u': + #if HAVE_SAMPLERATE + resample_factor_up = param->value.ui; + #else + jack_error( "not built with libsamplerate support" ); + return NULL; + #endif + break; + + case 'b': + bitdepth = param->value.ui; + break; + + case 'c': + #if HAVE_CELT + bitdepth = CELT_MODE; + resample_factor = param->value.ui; + #else + jack_error( "not built with celt support" ); + return NULL; + #endif + break; + + case 't': + handle_transport_sync = param->value.ui; + break; + + case 'a': + use_autoconfig = param->value.ui; + break; + + case 'n': + latency = param->value.ui; + break; + + case 'R': + redundancy = param->value.ui; + break; + + case 'H': + dont_htonl_floats = param->value.ui; + break; + + case 'J': + jitter_val = param->value.i; + break; + + case 'D': + always_deadline = param->value.ui; + break; + } + } + + try + { + + Jack::JackDriverClientInterface* driver = + new Jack::JackWaitThreadedDriver ( + new Jack::JackNetOneDriver ( "system", "net_pcm", engine, table, listen_port, mtu, + capture_ports_midi, playback_ports_midi, capture_ports, playback_ports, + sample_rate, period_size, resample_factor, + "net_pcm", handle_transport_sync, bitdepth, use_autoconfig, latency, redundancy, + dont_htonl_floats, always_deadline, jitter_val ) ); + + if ( driver->Open ( period_size, sample_rate, 1, 1, capture_ports, playback_ports, + 0, "from_master_", "to_master_", 0, 0 ) == 0 ) + { + return driver; + } + else + { + delete driver; + return NULL; + } + + } + catch ( ... ) + { + return NULL; + } + } + +#ifdef __cplusplus + } +#endif +} diff --git a/common/JackNetOneDriver.h b/common/JackNetOneDriver.h new file mode 100644 index 00000000..b288c91f --- /dev/null +++ b/common/JackNetOneDriver.h @@ -0,0 +1,96 @@ +/* +Copyright (C) 2001 Paul Davis +Copyright (C) 2008 Romain Moret at 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 __JackNetDriver__ +#define __JackNetDriver__ + +#include "JackAudioDriver.h" +#include "netjack.h" +#include "netjack_packet.h" + +namespace Jack +{ + /** + \Brief This class describes the Net Backend + */ + + class JackNetOneDriver : public JackAudioDriver + { + private: + netjack_driver_state_t netj; + +void +render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats); +void +render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ); +#ifdef HAVE_CELT +void +render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes); +void +render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up); +#endif +void +render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats); +void +render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats); + + public: + JackNetOneDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, + int port, int mtu, int capture_ports, int playback_ports, int midi_input_ports, int midi_output_ports, + int sample_rate, int period_size, int resample_factor, + const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig, + int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val ); + ~JackNetOneDriver(); + + int Open ( jack_nframes_t frames_per_cycle, jack_nframes_t rate, bool capturing, bool playing, + int inchannels, int outchannels, bool monitor, const char* capture_driver_name, + const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency ); + + int Close(); + int Attach(); + int Detach(); + + int Read(); + int Write(); + + bool Initialize(); + int AllocPorts(); + void FreePorts(); + + // BufferSize can't be changed + bool IsFixedBufferSize() + { + return true; + } + + int SetBufferSize ( jack_nframes_t buffer_size ) + { + return -1; + } + + int SetSampleRate ( jack_nframes_t sample_rate ) + { + return -1; + } + + }; +} + +#endif diff --git a/common/JackRestartThreadedDriver.cpp b/common/JackRestartThreadedDriver.cpp index 125b1697..faf9eb33 100644 --- a/common/JackRestartThreadedDriver.cpp +++ b/common/JackRestartThreadedDriver.cpp @@ -36,7 +36,7 @@ bool JackRestartThreadedDriver::Execute() } catch (JackNetException& e) { e.PrintMessage(); jack_log("Driver is restarted"); - fThread.DropRealTime(); + fThread.DropSelfRealTime(); // Thread in kIniting status again... fThread.SetStatus(JackThread::kIniting); if (Init()) { diff --git a/common/JackServerAPI.cpp b/common/JackServerAPI.cpp index 1fe4d1c1..e8e6c021 100644 --- a/common/JackServerAPI.cpp +++ b/common/JackServerAPI.cpp @@ -105,14 +105,22 @@ EXPORT jack_client_t* jack_client_open_aux(const char* client_name, jack_options EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...) { - assert(JackGlobals::fOpenMutex); - JackGlobals::fOpenMutex->Lock(); - va_list ap; - va_start(ap, status); - jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap); - va_end(ap); - JackGlobals::fOpenMutex->Unlock(); - return res; + try { + assert(JackGlobals::fOpenMutex); + JackGlobals::fOpenMutex->Lock(); + va_list ap; + va_start(ap, status); + jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap); + va_end(ap); + JackGlobals::fOpenMutex->Unlock(); + return res; + } catch(std::bad_alloc& e) { + jack_error("Memory allocation error..."); + return NULL; + } catch (...) { + jack_error("Unknown error..."); + return NULL; + } } EXPORT int jack_client_close(jack_client_t* ext_client) diff --git a/common/JackServerGlobals.cpp b/common/JackServerGlobals.cpp index 18dfaf66..7698c640 100644 --- a/common/JackServerGlobals.cpp +++ b/common/JackServerGlobals.cpp @@ -28,7 +28,6 @@ static char* server_name = NULL; namespace Jack { -bool JackServerGlobals::fKilled = false; JackServer* JackServerGlobals::fInstance; unsigned int JackServerGlobals::fUserCount; bool (* JackServerGlobals::on_device_acquire)(const char * device_name) = NULL; diff --git a/common/JackServerGlobals.h b/common/JackServerGlobals.h index e037f69b..00d8b0ff 100644 --- a/common/JackServerGlobals.h +++ b/common/JackServerGlobals.h @@ -36,7 +36,6 @@ class JackClient; struct SERVER_EXPORT JackServerGlobals { - static bool fKilled; static JackServer* fInstance; static unsigned int fUserCount; static bool (* on_device_acquire)(const char * device_name); diff --git a/common/JackShmMem.cpp b/common/JackShmMem.cpp index 5d68b86e..90d42e7b 100644 --- a/common/JackShmMem.cpp +++ b/common/JackShmMem.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2001 Paul Davis -Copyright (C) 2004-2008 Grame +Copyright (C) 2004-2009 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 @@ -32,6 +32,12 @@ size_t JackMem::gSize = 0; JackShmMem::JackShmMem() { JackShmMemAble::Init(); + LockMemory(); +} + +JackShmMem::~JackShmMem() +{ + UnlockMemory(); } void JackShmMemAble::Init() @@ -96,8 +102,9 @@ void JackShmMem::operator delete(void* p, size_t size) void JackShmMem::operator delete(void* obj) { - if (obj) + if (obj) { JackShmMem::operator delete(obj, 0); + } } void LockMemoryImp(void* ptr, size_t size) diff --git a/common/JackShmMem.h b/common/JackShmMem.h index 5976c96d..0a00daa5 100644 --- a/common/JackShmMem.h +++ b/common/JackShmMem.h @@ -1,6 +1,6 @@ /* Copyright (C) 2001 Paul Davis -Copyright (C) 2004-2008 Grame +Copyright (C) 2004-2009 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 @@ -129,9 +129,8 @@ class SERVER_EXPORT JackShmMem : public JackShmMemAble protected: JackShmMem(); - ~JackShmMem() - {} - + ~JackShmMem(); + public: void* operator new(size_t size); @@ -162,9 +161,9 @@ class JackShmReadWritePtr throw - 1; fInfo.index = index; if (jack_attach_shm(&fInfo)) { - //jack_error("cannot attach shared memory segment", strerror(errno)); throw - 2; } + GetShmAddress()->LockMemory(); } } @@ -185,9 +184,10 @@ class JackShmReadWritePtr { if (fInfo.index >= 0) { jack_log("JackShmReadWritePtr::~JackShmReadWritePtr %ld", fInfo.index); + GetShmAddress()->UnlockMemory(); jack_release_shm(&fInfo); fInfo.index = -1; - } + } } T* operator->() const @@ -242,15 +242,15 @@ class JackShmReadWritePtr1 throw - 1; fInfo.index = index; if (jack_attach_shm(&fInfo)) { - //jack_error("cannot attach shared memory segment", strerror(errno)); throw - 2; } /* - nobody else needs to access this shared memory any more, so - destroy it. because we have our own attachment to it, it won't - vanish till we exit (and release it). - */ + nobody else needs to access this shared memory any more, so + destroy it. because we have our own attachment to it, it won't + vanish till we exit (and release it). + */ jack_destroy_shm(&fInfo); + GetShmAddress()->LockMemory(); } } @@ -271,6 +271,7 @@ class JackShmReadWritePtr1 { if (fInfo.index >= 0) { jack_log("JackShmReadWritePtr1::~JackShmReadWritePtr1 %ld", fInfo.index); + GetShmAddress()->UnlockMemory(); jack_release_shm(&fInfo); fInfo.index = -1; } @@ -328,9 +329,9 @@ class JackShmReadPtr throw - 1; fInfo.index = index; if (jack_attach_shm_read(&fInfo)) { - //jack_error("cannot attach shared memory segment", strerror(errno)); throw - 2; } + GetShmAddress()->LockMemory(); } } @@ -351,6 +352,7 @@ class JackShmReadPtr { if (fInfo.index >= 0) { jack_log("JackShmPtrRead::~JackShmPtrRead %ld", fInfo.index); + GetShmAddress()->UnlockMemory(); jack_release_shm(&fInfo); fInfo.index = -1; } diff --git a/common/JackThread.h b/common/JackThread.h index 56c62419..9517a303 100644 --- a/common/JackThread.h +++ b/common/JackThread.h @@ -96,9 +96,14 @@ class SERVER_EXPORT JackThreadInterface int Stop(); void Terminate(); - int AcquireRealTime(); - int AcquireRealTime(int priority); - int DropRealTime(); + int AcquireRealTime(); // Used when called from another thread + int AcquireSelfRealTime(); // Used when called from thread itself + + int AcquireRealTime(int priority); // Used when called from another thread + int AcquireSelfRealTime(int priority); // Used when called from thread itself + + int DropRealTime(); // Used when called from another thread + int DropSelfRealTime(); // Used when called from thread itself pthread_t GetThreadID(); diff --git a/common/JackThreadedDriver.cpp b/common/JackThreadedDriver.cpp index df2b6d27..52e49197 100644 --- a/common/JackThreadedDriver.cpp +++ b/common/JackThreadedDriver.cpp @@ -215,8 +215,8 @@ bool JackThreadedDriver::Init() // Will do "something" on OSX only... GetEngineControl()->fPeriod = GetEngineControl()->fConstraint = GetEngineControl()->fPeriodUsecs * 1000; fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); - if (fThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { - jack_error("AcquireRealTime error"); + if (fThread.AcquireSelfRealTime(GetEngineControl()->fServerPriority) < 0) { + jack_error("AcquireSelfRealTime error"); } else { set_threaded_log_function(); } diff --git a/common/JackTools.cpp b/common/JackTools.cpp index cc8c67c3..a7a7020e 100644 --- a/common/JackTools.cpp +++ b/common/JackTools.cpp @@ -33,10 +33,24 @@ using namespace std; namespace Jack { + void JackTools::KillServer() + { +#ifdef WIN32 + exit(1); +#else + kill(GetPID(), SIGINT); +#endif + } + + void JackTools::ThrowJackNetException() + { + throw JackNetException(); + } + #define DEFAULT_TMP_DIR "/tmp" char* jack_tmpdir = (char*)DEFAULT_TMP_DIR; - int JackTools::GetPID() + int JackTools::GetPID() { #ifdef WIN32 return _getpid(); @@ -45,7 +59,7 @@ namespace Jack { #endif } - int JackTools::GetUID() + int JackTools::GetUID() { #ifdef WIN32 return _getpid(); @@ -55,7 +69,7 @@ namespace Jack { #endif } - const char* JackTools::DefaultServerName() + const char* JackTools::DefaultServerName() { const char* server_name; if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL) @@ -66,25 +80,25 @@ namespace Jack { /* returns the name of the per-user subdirectory of jack_tmpdir */ #ifdef WIN32 - char* JackTools::UserDir() + char* JackTools::UserDir() { return ""; } - char* JackTools::ServerDir(const char* server_name, char* server_dir) + char* JackTools::ServerDir(const char* server_name, char* server_dir) { return ""; } void JackTools::CleanupFiles(const char* server_name) {} - int JackTools::GetTmpdir() + int JackTools::GetTmpdir() { return 0; } #else - char* JackTools::UserDir() + char* JackTools::UserDir() { static char user_dir[JACK_PATH_MAX + 1] = ""; @@ -101,7 +115,7 @@ namespace Jack { } /* returns the name of the per-server subdirectory of jack_user_dir() */ - char* JackTools::ServerDir(const char* server_name, char* server_dir) + char* JackTools::ServerDir(const char* server_name, char* server_dir) { /* format the path name into the suppled server_dir char array, * assuming that server_dir is at least as large as JACK_PATH_MAX + 1 */ @@ -110,7 +124,7 @@ namespace Jack { return server_dir; } - void JackTools::CleanupFiles(const char* server_name) + void JackTools::CleanupFiles(const char* server_name) { DIR* dir; struct dirent *dirent; @@ -169,7 +183,7 @@ namespace Jack { } } - int JackTools::GetTmpdir() + int JackTools::GetTmpdir() { FILE* in; size_t len; @@ -201,7 +215,7 @@ namespace Jack { } #endif - void JackTools::RewriteName(const char* name, char* new_name) + void JackTools::RewriteName(const char* name, char* new_name) { size_t i; for (i = 0; i < strlen(name); i++) { @@ -212,7 +226,7 @@ namespace Jack { } new_name[i] = '\0'; } - + #ifdef WIN32 void BuildClientPath(char* path_to_so, int path_len, const char* so_name) @@ -251,7 +265,7 @@ void PrintLoadError(const char* so_name) #else -void PrintLoadError(const char* so_name) +void PrintLoadError(const char* so_name) { jack_log("error loading %s err = %s", so_name, dlerror()); } @@ -264,7 +278,7 @@ void BuildClientPath(char* path_to_so, int path_len, const char* so_name) internal_dir = ADDON_DIR; } } - + snprintf(path_to_so, path_len, "%s/%s.so", internal_dir, so_name); } diff --git a/common/JackTools.h b/common/JackTools.h index 820f91ba..5960fed8 100644 --- a/common/JackTools.h +++ b/common/JackTools.h @@ -36,6 +36,7 @@ #include "driver_interface.h" #include "JackCompilerDeps.h" #include "JackError.h" +#include "JackException.h" #include #include @@ -55,12 +56,16 @@ namespace Jack static int GetPID(); static int GetUID(); + static void KillServer(); + static char* UserDir(); static char* ServerDir ( const char* server_name, char* server_dir ); static const char* DefaultServerName(); static void CleanupFiles ( const char* server_name ); static int GetTmpdir(); static void RewriteName ( const char* name, char* new_name ); + + static void ThrowJackNetException(); }; /*! @@ -201,10 +206,10 @@ namespace Jack return 0; } }; - + void BuildClientPath(char* path_to_so, int path_len, const char* so_name); void PrintLoadError(const char* so_name); - + } #endif diff --git a/common/JackTransportEngine.cpp b/common/JackTransportEngine.cpp index 418d1180..19168eea 100644 --- a/common/JackTransportEngine.cpp +++ b/common/JackTransportEngine.cpp @@ -38,7 +38,8 @@ JackTransportEngine::JackTransportEngine(): JackAtomicArrayStatefPeriod = GetEngineControl()->fConstraint = GetEngineControl()->fPeriodUsecs * 1000; fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); - if (fThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { - jack_error("AcquireRealTime error"); + if (fThread.AcquireSelfRealTime(GetEngineControl()->fServerPriority) < 0) { + jack_error("AcquireSelfRealTime error"); } else { set_threaded_log_function(); } @@ -63,7 +63,7 @@ bool JackWaitThreadedDriver::Execute() } catch (JackNetException& e) { e.PrintMessage(); jack_info("Driver is restarted"); - fThread.DropRealTime(); + fThread.DropSelfRealTime(); // Thread in kIniting status again... fThread.SetStatus(JackThread::kIniting); if (Init()) { diff --git a/common/JackWeakAPI.cpp b/common/JackWeakAPI.cpp index 4888a92a..81e21d35 100644 --- a/common/JackWeakAPI.cpp +++ b/common/JackWeakAPI.cpp @@ -21,7 +21,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Completed from Julien Pommier (PianoTeq : http://www.pianoteq.com/) code. */ -#include "jack.h" +#include +#include +#include #include #include #include @@ -32,6 +34,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. (similar to what relaytool is trying to do, but more portably..) */ +typedef void (*print_function)(const char *); +typedef void *(*thread_routine)(void*); + using std::cerr; int libjack_is_present = 0; // public symbol, similar to what relaytool does. @@ -40,7 +45,12 @@ static void *libjack_handle = 0; static void __attribute__((constructor)) tryload_libjack() { if (getenv("SKIP_LIBJACK") == 0) { // just in case libjack is causing troubles.. + #ifdef __APPLE__ + libjack_handle = dlopen("libjack.0.dylib", RTLD_LAZY); + #else libjack_handle = dlopen("libjack.so.0", RTLD_LAZY); + #endif + } libjack_is_present = (libjack_handle != 0); } @@ -65,7 +75,7 @@ void *load_jack_function(const char *fn_name) static fn_name##_ptr_t fn = 0; \ if (fn == 0) { fn = (fn_name##_ptr_t)load_jack_function(#fn_name); } \ if (fn) return (*fn)arguments; \ - else return 0; \ + else return (return_type)-1; \ } #define DECL_VOID_FUNCTION(fn_name, arguments_types, arguments) \ @@ -81,7 +91,7 @@ DECL_FUNCTION(const char *, jack_get_version_string, (), ()); DECL_FUNCTION(jack_client_t *, jack_client_open, (const char *client_name, jack_options_t options, jack_status_t *status, ...), (client_name, options, status)); DECL_FUNCTION(int, jack_client_close, (jack_client_t *client), (client)); -DECL_FUNCTION(int, jack_client_new, (const char *client_name), (client_name)); +DECL_FUNCTION(jack_client_t *, jack_client_new, (const char *client_name), (client_name)); DECL_FUNCTION(int, jack_client_name_size, (), ()); DECL_FUNCTION(char*, jack_get_client_name, (jack_client_t *client), (client)); DECL_FUNCTION(int, jack_internal_client_new, (const char *client_name, @@ -89,7 +99,8 @@ DECL_FUNCTION(int, jack_internal_client_new, (const char *client_name, const char *load_init), (client_name, load_name, load_init)); DECL_VOID_FUNCTION(jack_internal_client_close, (const char *client_name), (client_name)); DECL_FUNCTION(int, jack_is_realtime, (jack_client_t *client), (client)); -DECL_VOID_FUNCTION(jack_on_shutdown, (jack_client_t *client, JackShutdownCallback shutdown_callback, void *arg), (client, function, arg)); +DECL_VOID_FUNCTION(jack_on_shutdown, (jack_client_t *client, JackShutdownCallback shutdown_callback, void *arg), (client, shutdown_callback, arg)); +DECL_VOID_FUNCTION(jack_on_info_shutdown, (jack_client_t* client, JackInfoShutdownCallback shutdown_callback, void* arg), (client, shutdown_callback, arg)); DECL_FUNCTION(int, jack_set_process_callback, (jack_client_t *client, JackProcessCallback process_callback, void *arg), (client, process_callback, arg)); @@ -97,7 +108,7 @@ DECL_FUNCTION(jack_nframes_t, jack_thread_wait, (jack_client_t *client, int stat // DECL_FUNCTION(jack_nframes_t, jack_cycle_wait, (jack_client_t *client), (client)); -DECL_VOID_FUNCTION(jack_cycle_signal, (jack_client_t *client, , int status), (client, status)); +DECL_VOID_FUNCTION(jack_cycle_signal, (jack_client_t *client, int status), (client, status)); DECL_FUNCTION(int, jack_set_process_thread, (jack_client_t *client, JackThreadCallback fun, void *arg), (client, fun, arg)); @@ -149,94 +160,102 @@ DECL_FUNCTION(int, jack_port_is_mine, (const jack_client_t *client, const jack_p DECL_FUNCTION(int, jack_port_connected, (const jack_port_t *port), (port)); DECL_FUNCTION(int, jack_port_connected_to, (const jack_port_t *port, const char *port_name), (port, port_name)); DECL_FUNCTION(const char**, jack_port_get_connections, (const jack_port_t *port), (port)); -DECL_FUNCTION(const char**, jack_port_get_all_connections, (const jack_port_t *port), (port)); +DECL_FUNCTION(const char**, jack_port_get_all_connections, (const jack_client_t *client,const jack_port_t *port), (client, port)); DECL_FUNCTION(int, jack_port_tie, (jack_port_t *src, jack_port_t *dst), (src, dst)); DECL_FUNCTION(int, jack_port_untie, (jack_port_t *port), (port)); -DECL_FUNCTION(jack_nframes_t, jack_port_get_latency, (jack_port_t *port)); -DECL_FUNCTION(jack_nframes_t, jack_port_get_total_latency ,(jack_client_t *), (jack_port_t *port)); -DECL_VOID_FUNCTION(jack_port_set_latency, (jack_port_t *), (jack_nframes_t)); -DECL_FUNCTION(int, jack_recompute_total_latency, (jack_client_t*), (jack_port_t* port)); -DECL_FUNCTION(int, jack_recompute_total_latencies, (jack_client_t*)); - -DECL_FUNCTION(int, jack_port_set_name, (jack_port_t *port), (const char *port_name)); -DECL_FUNCTION(int, jack_port_set_alias, (jack_port_t *port), (const char *alias)); -DECL_FUNCTION(int, jack_port_unset_alias, (jack_port_t *port), (const char *alias)); -DECL_FUNCTION(int, jack_port_get_aliases, (const jack_port_t *port), (char* const aliases[2])); -DECL_FUNCTION(int, jack_port_request_monitor, (jack_port_t *port), (int onoff)); -DECL_FUNCTION(int, jack_port_request_monitor_by_name, (jack_client_t *client), (const char *port_name), (int onoff)); -DECL_FUNCTION(int, jack_port_ensure_monitor, (jack_port_t *port), (int onoff)); -DECL_FUNCTION(int, jack_port_monitoring_input, (jack_port_t *port)); -DECL_FUNCTION(int, jack_connect, (jack_client_t *), (const char *source_port), (const char *destination_port)); -DECL_FUNCTION(int, jack_disconnect, (jack_client_t *), (const char *source_port), (const char *destination_port)); -DECL_FUNCTION(int, jack_port_disconnect, (jack_client_t *), (jack_port_t *)); -DECL_FUNCTION(int, jack_port_name_size,(void)); -DECL_FUNCTION(int, jack_port_type_size,(void)); +DECL_FUNCTION(jack_nframes_t, jack_port_get_latency, (jack_port_t *port), (port)); +DECL_FUNCTION(jack_nframes_t, jack_port_get_total_latency ,(jack_client_t * client, jack_port_t *port), (client, port)); +DECL_VOID_FUNCTION(jack_port_set_latency, (jack_port_t * port, jack_nframes_t frames), (port, frames)); +DECL_FUNCTION(int, jack_recompute_total_latency, (jack_client_t* client, jack_port_t* port), (client, port)); +DECL_FUNCTION(int, jack_recompute_total_latencies, (jack_client_t* client),(client)); + +DECL_FUNCTION(int, jack_port_set_name, (jack_port_t *port, const char *port_name), (port, port_name)); +DECL_FUNCTION(int, jack_port_set_alias, (jack_port_t *port, const char *alias), (port, alias)); +DECL_FUNCTION(int, jack_port_unset_alias, (jack_port_t *port, const char *alias), (port, alias)); +DECL_FUNCTION(int, jack_port_get_aliases, (const jack_port_t *port, char* const aliases[2]), (port,aliases)); +DECL_FUNCTION(int, jack_port_request_monitor, (jack_port_t *port, int onoff), (port, onoff)); +DECL_FUNCTION(int, jack_port_request_monitor_by_name, (jack_client_t *client, const char *port_name, int onoff), (client, port_name, onoff)); +DECL_FUNCTION(int, jack_port_ensure_monitor, (jack_port_t *port, int onoff), (port, onoff)); +DECL_FUNCTION(int, jack_port_monitoring_input, (jack_port_t *port) ,(port)); +DECL_FUNCTION(int, jack_connect, (jack_client_t * client, const char *source_port, const char *destination_port), (client, source_port, destination_port)); +DECL_FUNCTION(int, jack_disconnect, (jack_client_t * client, const char *source_port, const char *destination_port), (client, source_port, destination_port)); +DECL_FUNCTION(int, jack_port_disconnect, (jack_client_t * client, jack_port_t * port), (client, port)); +DECL_FUNCTION(int, jack_port_name_size,(),()); +DECL_FUNCTION(int, jack_port_type_size,(),()); DECL_FUNCTION(jack_nframes_t, jack_get_sample_rate, (jack_client_t *client), (client)); DECL_FUNCTION(jack_nframes_t, jack_get_buffer_size, (jack_client_t *client), (client)); DECL_FUNCTION(const char**, jack_get_ports, (jack_client_t *client, const char *port_name_pattern, const char * type_name_pattern, unsigned long flags), (client, port_name_pattern, type_name_pattern, flags)); -DECL_FUNCTION(jack_port_t *, jack_port_by_name, (jack_client_t *), (const char *port_name)); -DECL_FUNCTION(jack_port_t *, jack_port_by_id, (jack_client_t *client), (jack_port_id_t port_id)); - -DECL_FUNCTION(int, jack_engine_takeover_timebase, (jack_client_t *)); -DECL_FUNCTION(jack_nframes_t, jack_frames_since_cycle_start, (const jack_client_t *)); -DECL_FUNCTION(jack_time_t, jack_get_time()); -DECL_FUNCTION(jack_nframes_t, jack_time_to_frames, (const jack_client_t *client), (jack_time_t time)); -DECL_FUNCTION(jack_time_t, jack_frames_to_time, (const jack_client_t *client), (jack_nframes_t frames)); -DECL_FUNCTION(jack_nframes_t, jack_frame_time, (const jack_client_t *)); -DECL_FUNCTION(jack_nframes_t, jack_last_frame_time, (const jack_client_t *client)); -DECL_FUNCTION(float, jack_cpu_load, (jack_client_t *client)); -DECL_FUNCTION(pthread_t, jack_client_thread_id, (jack_client_t *)); -DECL_VOID_FUNCTION(jack_set_error_function, (print_function)); -DECL_VOID_FUNCTION(jack_set_info_function, (print_function)); - -DECL_FUNCTION(float, jack_get_max_delayed_usecs, (jack_client_t *client)); -DECL_FUNCTION(float, jack_get_xrun_delayed_usecs, (jack_client_t *client)); -DECL_VOID_FUNCTION(jack_reset_max_delayed_usecs, (jack_client_t *client)); - -DECL_FUNCTION(int, jack_release_timebase, (jack_client_t *client)); -DECL_FUNCTION(int, jack_set_sync_callback, (jack_client_t *client, (JackSyncCallback sync_callback), (void *arg)); -DECL_FUNCTION(int, jack_set_sync_timeout, (jack_client_t *client), (jack_time_t timeout)); -DECL_FUNCTION(int, jack_set_timebase_callback, (jack_client_t *client), (int conditional), (JackTimebaseCallback timebase_callback), (void *arg)); -DECL_FUNCTION(int, jack_transport_locate, (jack_client_t *client), (jack_nframes_t frame)); -DECL_FUNCTION(jack_transport_state_t, jack_transport_query, (const jack_client_t *client), (jack_position_t *pos)); -DECL_FUNCTION(jack_nframes_t, jack_get_current_transport_frame, (const jack_client_t *client)); -DECL_FUNCTION(int, jack_transport_reposition, (jack_client_t *client), (jack_position_t *pos)); -DECL_VOID_FUNCTION(jack_transport_start, (jack_client_t *client)); -DECL_VOID_FUNCTION(jack_transport_stop, (jack_client_t *client)); -DECL_VOID_FUNCTION(jack_get_transport_info, (jack_client_t *client), (jack_transport_info_t *tinfo)); -DECL_VOID_FUNCTION(jack_set_transport_info, (jack_client_t *client), (jack_transport_info_t *tinfo)); - -DECL_FUNCTION(int, jack_client_real_time_priority, (jack_client_t*)); -DECL_FUNCTION(int, jack_client_max_real_time_priority, (jack_client_t*)); -DECL_FUNCTION(int, jack_acquire_real_time_scheduling, (pthread_t thread), (int priority)); -DECL_FUNCTION(int, jack_client_create_thread, (jack_client_t* client), - (pthread_t *thread), - (int priority), - (int realtime), // boolean - (thread_routine routine), - (void *arg)); -DECL_FUNCTION(int, jack_drop_real_time_scheduling, (pthread_t thread)); - -DECL_FUNCTION(int, jack_client_stop_thread, (jack_client_t* client), (pthread_t thread)); -DECL_FUNCTION(int, jack_client_kill_thread, (jack_client_t* client), (pthread_t thread)); +DECL_FUNCTION(jack_port_t *, jack_port_by_name, (jack_client_t * client, const char *port_name), (client, port_name)); +DECL_FUNCTION(jack_port_t *, jack_port_by_id, (jack_client_t *client, jack_port_id_t port_id), (client, port_id)); + +DECL_FUNCTION(int, jack_engine_takeover_timebase, (jack_client_t * client), (client)); +DECL_FUNCTION(jack_nframes_t, jack_frames_since_cycle_start, (const jack_client_t * client), (client)); +DECL_FUNCTION(jack_time_t, jack_get_time, (), ()); +DECL_FUNCTION(jack_nframes_t, jack_time_to_frames, (const jack_client_t *client, jack_time_t time), (client, time)); +DECL_FUNCTION(jack_time_t, jack_frames_to_time, (const jack_client_t *client, jack_nframes_t frames), (client, frames)); +DECL_FUNCTION(jack_nframes_t, jack_frame_time, (const jack_client_t *client), (client)); +DECL_FUNCTION(jack_nframes_t, jack_last_frame_time, (const jack_client_t *client), (client)); +DECL_FUNCTION(float, jack_cpu_load, (jack_client_t *client), (client)); +DECL_FUNCTION(pthread_t, jack_client_thread_id, (jack_client_t *client), (client)); +DECL_VOID_FUNCTION(jack_set_error_function, (print_function fun), (fun)); +DECL_VOID_FUNCTION(jack_set_info_function, (print_function fun), (fun)); + +DECL_FUNCTION(float, jack_get_max_delayed_usecs, (jack_client_t *client), (client)); +DECL_FUNCTION(float, jack_get_xrun_delayed_usecs, (jack_client_t *client), (client)); +DECL_VOID_FUNCTION(jack_reset_max_delayed_usecs, (jack_client_t *client), (client)); + +DECL_FUNCTION(int, jack_release_timebase, (jack_client_t *client), (client)); +DECL_FUNCTION(int, jack_set_sync_callback, (jack_client_t *client, JackSyncCallback sync_callback, void *arg), (client, sync_callback, arg)); +DECL_FUNCTION(int, jack_set_sync_timeout, (jack_client_t *client, jack_time_t timeout), (client, timeout)); +DECL_FUNCTION(int, jack_set_timebase_callback, (jack_client_t *client, + int conditional, + JackTimebaseCallback timebase_callback, + void *arg), (client, conditional, timebase_callback, arg)); +DECL_FUNCTION(int, jack_transport_locate, (jack_client_t *client, jack_nframes_t frame), (client, frame)); +DECL_FUNCTION(jack_transport_state_t, jack_transport_query, (const jack_client_t *client, jack_position_t *pos), (client, pos)); +DECL_FUNCTION(jack_nframes_t, jack_get_current_transport_frame, (const jack_client_t *client), (client)); +DECL_FUNCTION(int, jack_transport_reposition, (jack_client_t *client, jack_position_t *pos), (client, pos)); +DECL_VOID_FUNCTION(jack_transport_start, (jack_client_t *client), (client)); +DECL_VOID_FUNCTION(jack_transport_stop, (jack_client_t *client), (client)); +DECL_VOID_FUNCTION(jack_get_transport_info, (jack_client_t *client, jack_transport_info_t *tinfo), (client,tinfo)); +DECL_VOID_FUNCTION(jack_set_transport_info, (jack_client_t *client, jack_transport_info_t *tinfo), (client,tinfo)); + +DECL_FUNCTION(int, jack_client_real_time_priority, (jack_client_t* client), (client)); +DECL_FUNCTION(int, jack_client_max_real_time_priority, (jack_client_t* client), (client)); +DECL_FUNCTION(int, jack_acquire_real_time_scheduling, (pthread_t thread, int priority), (thread, priority)); +DECL_FUNCTION(int, jack_client_create_thread, (jack_client_t* client, + pthread_t *thread, + int priority, + int realtime, // boolean + thread_routine routine, + void *arg), (client, thread, priority, realtime, routine, arg)); +DECL_FUNCTION(int, jack_drop_real_time_scheduling, (pthread_t thread), (thread)); + +DECL_FUNCTION(int, jack_client_stop_thread, (jack_client_t* client, pthread_t thread), (client, thread)); +DECL_FUNCTION(int, jack_client_kill_thread, (jack_client_t* client, pthread_t thread), (client, thread)); #ifndef WIN32 -DECL_VOID_FUNCTION(jack_set_thread_creator, (jack_thread_creator_t jtc)); +DECL_VOID_FUNCTION(jack_set_thread_creator, (jack_thread_creator_t jtc), (jtc)); #endif -DECL_FUNCTION(char *, jack_get_internal_client_name, (jack_client_t *client, (jack_intclient_t intclient)); -DECL_FUNCTION(jack_intclient_t, jack_internal_client_handle, (jack_client_t *client), (const char *client_name), (jack_status_t *status)); -DECL_FUNCTION(jack_intclient_t, jack_internal_client_load, (jack_client_t *client), (const char *client_name), (jack_options_t options), (jack_status_t *status), ...)); - -DECL_FUNCTION(jack_status_t, jack_internal_client_unload, (jack_client_t *client), jack_intclient_t intclient)); -DECL_VOID_FUNCTION(jack_free, (void* ptr)); +DECL_FUNCTION(char *, jack_get_internal_client_name, (jack_client_t *client, jack_intclient_t intclient), (client, intclient)); +DECL_FUNCTION(jack_intclient_t, jack_internal_client_handle, (jack_client_t *client, const char *client_name, jack_status_t *status), (client, client_name, status)); +/* +DECL_FUNCTION(jack_intclient_t, jack_internal_client_load, (jack_client_t *client, + const char *client_name, + jack_options_t options, + jack_status_t *status + , ...), (client, client_name, options, status, ...)); +*/ +DECL_FUNCTION(jack_status_t, jack_internal_client_unload, (jack_client_t *client, jack_intclient_t intclient), (client, intclient)); +DECL_VOID_FUNCTION(jack_free, (void* ptr), (ptr)); // MIDI -DECL_FUNCTION(jack_nframes_t, jack_midi_get_event_count, (void* port_buffer)); -DECL_FUNCTION(int jack_midi_event_get(jack_midi_event_t* event, void* port_buffer, jack_nframes_t event_index); -DECL_VOID_FUNCTION(jack_midi_clear_buffer, (void* port_buffer)); -DECL_FUNCTION(size_t, jack_midi_max_event_size, (void* port_buffer)); -DECL_FUNCTION(jack_midi_data_t*, jack_midi_event_reserve, (void* port_buffer), (jack_nframes_t time), (size_t data_size)); -DECL_FUNCTIO(int jack_midi_event_write, (void* port_buffer), (jack_nframes_t time), (const jack_midi_data_t* data), (size_t data_size)); -DECL_FUNCTION(jack_nframes_t, jack_midi_get_lost_event_count, (void* port_buffer)); +DECL_FUNCTION(jack_nframes_t, jack_midi_get_event_count, (void* port_buffer), (port_buffer)); +DECL_FUNCTION(int, jack_midi_event_get, (jack_midi_event_t* event, void* port_buffer, jack_nframes_t event_index), (event, port_buffer, event_index)) ; +DECL_VOID_FUNCTION(jack_midi_clear_buffer, (void* port_buffer), (port_buffer)); +DECL_FUNCTION(size_t, jack_midi_max_event_size, (void* port_buffer), (port_buffer)); +DECL_FUNCTION(jack_midi_data_t*, jack_midi_event_reserve, (void* port_buffer, jack_nframes_t time, size_t data_size), (port_buffer, time, data_size)); +DECL_FUNCTION(int, jack_midi_event_write, (void* port_buffer, jack_nframes_t time, const jack_midi_data_t* data, size_t data_size), (port_buffer, time, data, data_size)); +DECL_FUNCTION(jack_nframes_t, jack_midi_get_lost_event_count, (void* port_buffer), (port_buffer)); diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index a414b8b4..9045827c 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -94,7 +94,9 @@ static void copyright(FILE* file) static void usage(FILE* file) { fprintf(file, "\n" - "usage: jackdmp [ --realtime OR -R [ --realtime-priority OR -P priority ] ]\n" + "usage: jackdmp [ --no-realtime OR -r ]\n" + " [ --realtime OR -R [ --realtime-priority OR -P priority ] ]\n" + " (the two previous arguments are mutually exclusive. The default is --realtime)\n" " [ --name OR -n server-name ]\n" " [ --timeout OR -t client-timeout-in-msecs ]\n" " [ --loopback OR -L loopback-port-number ]\n" @@ -103,15 +105,26 @@ static void usage(FILE* file) #ifdef __linux__ " [ --clocksource OR -c [ c(ycle) | h(pet) | s(ystem) ]\n" #endif - " [ --replace-registry OR -r ]\n" + " [ --replace-registry ]\n" " [ --silent OR -s ]\n" " [ --sync OR -S ]\n" " [ --temporary OR -T ]\n" " [ --version OR -V ]\n" - " -d audio-driver [ ... driver args ... ]\n" - " where driver can be `alsa', `coreaudio', 'portaudio' or `dummy'\n" - " jackdmp -d driver --help\n" - " to display options for each driver\n\n"); + " -d backend [ ... backend args ... ]\n" +#ifdef __APPLE__ + " Available backends may include: coreaudio, dummy or net.\n\n" +#endif +#ifdef WIN32 + " Available backends may include: portaudio, dummy or net.\n\n" +#endif +#ifdef __linux__ + " Available backends may include: alsa, dummy, freebob, firewire, net, oss or sun.\n\n" +#endif +#if defined(__sun__) || defined(sun) + " Available backends may include: boomer, oss, dummy or net.\n\n" +#endif + " jackdmp -d backend --help\n" + " to display options for each backend\n\n"); } // To put in the control.h interface?? @@ -163,11 +176,12 @@ int main(int argc, char* argv[]) jackctl_driver_t * audio_driver_ctl; jackctl_driver_t * midi_driver_ctl; jackctl_driver_t * loopback_driver_ctl; + int replace_registry = 0; #ifdef __linux__ - const char *options = "-ad:X:P:uvrshVRL:STFl:t:mn:p:c:L:"; + const char *options = "-ad:X:P:uvshVrRL:STFl:t:mn:p:c:L:"; #else - const char *options = "-ad:X:P:uvrshVRL:STFl:t:mn:p:L:"; + const char *options = "-ad:X:P:uvshVrRL:STFl:t:mn:p:L:"; #endif struct option long_options[] = { @@ -184,7 +198,8 @@ int main(int argc, char* argv[]) { "name", 0, 0, 'n' }, { "unlock", 0, 0, 'u' }, { "realtime", 0, 0, 'R' }, - { "replace-registry", 0, 0, 'r' }, + { "no-realtime", 0, 0, 'r' }, + { "replace-registry", 0, &replace_registry, 0 }, { "loopback", 0, 0, 'L' }, { "realtime-priority", 1, 0, 'P' }, { "timeout", 1, 0, 't' }, @@ -224,8 +239,16 @@ int main(int argc, char* argv[]) fprintf(stderr, "Failed to create server object\n"); return -1; } - + server_parameters = jackctl_server_get_parameters(server_ctl); + + // Default setting + param = jackctl_get_parameter(server_parameters, "realtime"); + if (param != NULL) { + value.b = true; + jackctl_parameter_set_value(param, &value); + } + opterr = 0; while (!seen_audio_driver && (opt = getopt_long(argc, argv, options, @@ -315,11 +338,11 @@ int main(int argc, char* argv[]) jackctl_parameter_set_value(param, &value); } break; - + case 'r': - param = jackctl_get_parameter(server_parameters, "replace-registry"); + param = jackctl_get_parameter(server_parameters, "realtime"); if (param != NULL) { - value.b = true; + value.b = false; jackctl_parameter_set_value(param, &value); } break; @@ -361,7 +384,14 @@ int main(int argc, char* argv[]) goto fail_free1; } } - + + // Long option with no letter so treated separately + param = jackctl_get_parameter(server_parameters, "replace-registry"); + if (param != NULL) { + value.b = replace_registry; + jackctl_parameter_set_value(param, &value); + } + if (show_version) { printf( "jackdmp version " VERSION " tmpdir " jack_server_dir diff --git a/common/jack/jack.h b/common/jack/jack.h index ebdded77..a5dc3aec 100644 --- a/common/jack/jack.h +++ b/common/jack/jack.h @@ -34,6 +34,25 @@ extern "C" * Note: More documentation can be found in jack/types.h. */ +/************************************************************* + * NOTE: JACK_WEAK_EXPORT ***MUST*** be used on every function + * added to the JACK API after the 0.116.2 release. + *************************************************************/ + +#ifndef JACK_WEAK_EXPORT +#ifdef __GNUC__ +/* JACK_WEAK_EXPORT needs to be a macro which + expands into a compiler directive. If non-null, the directive + must tell the compiler to arrange for weak linkage of + the symbol it used with. For this to work full may + require linker arguments in the client as well. +*/ +#define JACK_WEAK_EXPORT __attribute__((weak)) +#else +/* Add other things here for non-gcc platforms */ +#endif +#endif + /** * @defgroup ClientFunctions Creating & manipulating clients * @{ @@ -282,7 +301,7 @@ int jack_set_thread_init_callback (jack_client_t *client, * @param function The jack_shutdown function pointer. * @param arg The arguments for the jack_shutdown function. * - * @deprecated Register a function (and argument) to be called if and when the + * Register a function (and argument) to be called if and when the * JACK server shuts down the client thread. The function must * be written as if it were an asynchonrous POSIX signal * handler --- use only async-safe functions, and remember that it @@ -294,14 +313,19 @@ int jack_set_thread_init_callback (jack_client_t *client, * NOTE: clients do not need to call this. It exists only * to help more complex clients understand what is going * on. It should be called before jack_client_activate(). + * + * NOTE: if a client calls this AND jack_on_info_shutdown(), then + * the event of a client thread shutdown, the callback + * passed to this function will not be called, and the one passed to + * jack_on_info_shutdown() will. */ void jack_on_shutdown (jack_client_t *client, - JackShutdownCallback shutdown_callback, void *arg); + JackShutdownCallback shutdown_callback, void *arg) JACK_WEAK_EXPORT; /** * @param client pointer to JACK client structure. - * @param function The jack_shutdown function pointer. - * @param arg The arguments for the jack_shutdown function. + * @param function The jack_info_shutdown function pointer. + * @param arg The arguments for the jack_info_shutdown function. * * Register a function (and argument) to be called if and when the * JACK server shuts down the client thread. The function must @@ -315,6 +339,11 @@ void jack_on_shutdown (jack_client_t *client, * NOTE: clients do not need to call this. It exists only * to help more complex clients understand what is going * on. It should be called before jack_client_activate(). + * + * NOTE: if a client calls this AND jack_on_info_shutdown(), then + * the event of a client thread shutdown, the callback + * passed to this function will not be called, and the one passed to + * jack_on_info_shutdown() will. */ void jack_on_info_shutdown (jack_client_t *client, JackInfoShutdownCallback shutdown_callback, void *arg); diff --git a/common/jack/jslist.h b/common/jack/jslist.h index 18773708..3ec0ce92 100644 --- a/common/jack/jslist.h +++ b/common/jack/jslist.h @@ -48,8 +48,10 @@ jack_slist_alloc (void) JSList *new_list; new_list = (JSList*)malloc(sizeof(JSList)); - new_list->data = NULL; - new_list->next = NULL; + if (new_list) { + new_list->data = NULL; + new_list->next = NULL; + } return new_list; } @@ -61,8 +63,10 @@ jack_slist_prepend (JSList* list, void* data) JSList *new_list; new_list = (JSList*)malloc(sizeof(JSList)); - new_list->data = data; - new_list->next = list; + if (new_list) { + new_list->data = data; + new_list->next = list; + } return new_list; } diff --git a/common/jack/types.h b/common/jack/types.h index f7e03d3c..fd71ceac 100644 --- a/common/jack/types.h +++ b/common/jack/types.h @@ -214,7 +214,7 @@ typedef int (*JackPortRenameCallback)(jack_port_id_t port, const char* new_name, typedef void (*JackFreewheelCallback)(int starting, void *arg); /** - * @deprecated Prototype for the client supplied function that is called + * Prototype for the client supplied function that is called * whenever jackd is shutdown. Note that after server shutdown, * the client pointer is *not* deallocated by libjack, * the application is responsible to properly use jack_client_close() @@ -226,21 +226,6 @@ typedef void (*JackFreewheelCallback)(int starting, void *arg); */ typedef void (*JackShutdownCallback)(void *arg); -/** - * Prototype for the client supplied function that is called - * 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 shuntdown code - * @param reason a string discribing the shuntdown reason (backend failure, server crash... etc...) - * @param arg pointer to a client supplied structure - */ -typedef void (*JackInfoShutdownCallback)(int code, const char* reason, void *arg); - /** * Used for the type argument of jack_port_register() for default * audio ports and midi ports. @@ -437,9 +422,14 @@ enum JackStatus { JackVersionError = 0x400, /** - * Backend failure + * Backend error + */ + JackBackendError = 0x800, + + /** + * Client zombified failure */ - JackBackendError = 0x800 + JackClientZombie = 0x1000 }; /** @@ -664,4 +654,19 @@ typedef struct { } jack_transport_info_t; +/** + * Prototype for the client supplied function that is called + * 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 + */ +typedef void (*JackInfoShutdownCallback)(jack_status_t code, const char* reason, void *arg); + #endif /* __jack_types_h__ */ diff --git a/common/netjack.c b/common/netjack.c new file mode 100644 index 00000000..eb5f36b7 --- /dev/null +++ b/common/netjack.c @@ -0,0 +1,746 @@ + +/* -*- mode: c; c-file-style: "linux"; -*- */ +/* +NetJack Abstraction. + +Copyright (C) 2008 Pieter Palmers +Copyright (C) 2006 Torben Hohn +Copyright (C) 2003 Robert Ham +Copyright (C) 2001 Paul Davis + +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. + +$Id: net_driver.c,v 1.17 2006/04/16 20:16:10 torbenh Exp $ +*/ + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "jack/jslist.h" + +#include + +#ifdef WIN32 +#include +#include +#else +#include +#include +#endif + +#include "netjack.h" + +//#include "config.h" + +#if HAVE_SAMPLERATE +#include +#endif + +#if HAVE_CELT +#include +#endif + +#include "netjack.h" +#include "netjack_packet.h" + +// JACK2 +#include "jack/control.h" + +#define MIN(x,y) ((x)<(y) ? (x) : (y)) + +static int sync_state = 1; +static jack_transport_state_t last_transport_state; + +static int +net_driver_sync_cb(jack_transport_state_t state, jack_position_t *pos, void *data) +{ + int retval = sync_state; + + if (state == JackTransportStarting && last_transport_state != JackTransportStarting) { + retval = 0; + } +// if (state == JackTransportStarting) +// jack_info("Starting sync_state = %d", sync_state); + last_transport_state = state; + return retval; +} + +int netjack_wait( netjack_driver_state_t *netj ) +{ + int we_have_the_expected_frame = 0; + jack_nframes_t next_frame_avail; + jack_time_t packet_recv_time_stamp; + jacknet_packet_header *pkthdr; + + if( !netj->next_deadline_valid ) { + netj->next_deadline = jack_get_time() + netj->deadline_offset; + netj->next_deadline_valid = 1; + } + + // Increment expected frame here. + + if( netj->expected_framecnt_valid ) { + netj->expected_framecnt += 1; + } else { + // starting up.... lets look into the packetcache, and fetch the highest packet. + packet_cache_drain_socket( global_packcache, netj->sockfd ); + if( packet_cache_get_highest_available_framecnt( global_packcache, &next_frame_avail ) ) { + netj->expected_framecnt = next_frame_avail; + netj->expected_framecnt_valid = 1; + } else { + // no packets there... start normally. + netj->expected_framecnt = 0; + netj->expected_framecnt_valid = 1; + } + + } + + //jack_log( "expect %d", netj->expected_framecnt ); + // Now check if required packet is already in the cache. + // then poll (have deadline calculated) + // then drain socket, rinse and repeat. + while(1) { + if( packet_cache_get_next_available_framecnt( global_packcache, netj->expected_framecnt, &next_frame_avail) ) { + if( next_frame_avail == netj->expected_framecnt ) { + we_have_the_expected_frame = 1; + if( !netj->always_deadline ) + break; + } + } + if( ! netjack_poll_deadline( netj->sockfd, netj->next_deadline ) ) { + break; + } + + packet_cache_drain_socket( global_packcache, netj->sockfd ); + } + + // check if we know who to send our packets too. + if (!netj->srcaddress_valid) + if( global_packcache->master_address_valid ) { + memcpy (&(netj->syncsource_address), &(global_packcache->master_address), sizeof( struct sockaddr_in ) ); + netj->srcaddress_valid = 1; + } + + // XXX: switching mode unconditionally is stupid. + // if we were running free perhaps we like to behave differently + // ie. fastforward one packet etc. + // well... this is the first packet we see. hmm.... dunno ;S + // it works... so... + netj->running_free = 0; + + //if( !we_have_the_expected_frame ) + // jack_error( "netxrun... %d", netj->expected_framecnt ); + + if( we_have_the_expected_frame ) { + + jack_time_t now = jack_get_time(); + if( now < netj->next_deadline ) + netj->time_to_deadline = netj->next_deadline - now; + else + netj->time_to_deadline = 0; + + packet_cache_retreive_packet_pointer( global_packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize , &packet_recv_time_stamp); + pkthdr = (jacknet_packet_header *) netj->rx_buf; + packet_header_ntoh(pkthdr); + netj->deadline_goodness = (int)pkthdr->sync_state; + netj->packet_data_valid = 1; + + int want_deadline; + if( netj->jitter_val != 0 ) + want_deadline = netj->jitter_val; + else if( netj->latency < 4 ) + want_deadline = -netj->period_usecs/2; + else + want_deadline = (netj->period_usecs/4+10*(int)netj->period_usecs*netj->latency/100); + + if( netj->deadline_goodness != MASTER_FREEWHEELS ) { + if( netj->deadline_goodness < want_deadline ) { + netj->deadline_offset -= netj->period_usecs/100; + //jack_log( "goodness: %d, Adjust deadline: --- %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 ); + } + if( netj->deadline_goodness > want_deadline ) { + netj->deadline_offset += netj->period_usecs/100; + //jack_log( "goodness: %d, Adjust deadline: +++ %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 ); + } + } + if( netj->deadline_offset < (netj->period_usecs*70/100) ) { + jack_error( "master is forcing deadline_offset to below 70%% of period_usecs... increase latency setting on master" ); + netj->deadline_offset = (netj->period_usecs*90/100); + } + + netj->next_deadline = jack_get_time() + netj->deadline_offset; + } else { + netj->time_to_deadline = 0; + netj->next_deadline = jack_get_time() + netj->deadline_offset; + // bah... the packet is not there. + // either + // - it got lost. + // - its late + // - sync source is not sending anymore. + + // lets check if we have the next packets, we will just run a cycle without data. + // in that case. + + if( packet_cache_get_next_available_framecnt( global_packcache, netj->expected_framecnt, &next_frame_avail) ) + { + jack_nframes_t offset = next_frame_avail - netj->expected_framecnt; + + //XXX: hmm... i need to remember why resync_threshold wasnt right. + //if( offset < netj->resync_threshold ) + if( offset < 10 ) { + // ok. dont do nothing. we will run without data. + // this seems to be one or 2 lost packets. + // + // this can also be reordered packet jitter. + // (maybe this is not happening in real live) + // but it happens in netem. + + netj->packet_data_valid = 0; + + // I also found this happening, when the packet queue, is too full. + // but wtf ? use a smaller latency. this link can handle that ;S + if( packet_cache_get_fill( global_packcache, netj->expected_framecnt ) > 80.0 ) + netj->next_deadline -= netj->period_usecs/2; + + + } else { + // the diff is too high. but we have a packet in the future. + // lets resync. + netj->expected_framecnt = next_frame_avail; + packet_cache_retreive_packet_pointer( global_packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize, NULL ); + pkthdr = (jacknet_packet_header *) netj->rx_buf; + packet_header_ntoh(pkthdr); + //netj->deadline_goodness = 0; + netj->deadline_goodness = (int)pkthdr->sync_state - (int)netj->period_usecs * offset; + netj->next_deadline_valid = 0; + netj->packet_data_valid = 1; + } + + } else { + // no packets in buffer. + netj->packet_data_valid = 0; + + //printf( "frame %d No Packet in queue. num_lost_packets = %d \n", netj->expected_framecnt, netj->num_lost_packets ); + if( netj->num_lost_packets < 5 ) { + // ok. No Packet in queue. The packet was either lost, + // or we are running too fast. + // + // Adjusting the deadline unconditionally resulted in + // too many xruns on master. + // But we need to adjust for the case we are running too fast. + // So lets check if the last packet is there now. + // + // It would not be in the queue anymore, if it had been + // retrieved. This might break for redundancy, but + // i will make the packet cache drop redundant packets, + // that have already been retreived. + // + if( packet_cache_get_highest_available_framecnt( global_packcache, &next_frame_avail) ) { + if( next_frame_avail == (netj->expected_framecnt - 1) ) { + // Ok. the last packet is there now. + // and it had not been retrieved. + // + // TODO: We are still dropping 2 packets. + // perhaps we can adjust the deadline + // when (num_packets lost == 0) + + // This might still be too much. + netj->next_deadline += netj->period_usecs; + } + } + } else if( (netj->num_lost_packets <= 100) ) { + // lets try adjusting the deadline harder, for some packets, we might have just ran 2 fast. + netj->next_deadline += netj->period_usecs*netj->latency/8; + } else { + + // But now we can check for any new frame available. + // + if( packet_cache_get_highest_available_framecnt( global_packcache, &next_frame_avail) ) { + netj->expected_framecnt = next_frame_avail; + packet_cache_retreive_packet_pointer( global_packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize, NULL ); + pkthdr = (jacknet_packet_header *) netj->rx_buf; + packet_header_ntoh(pkthdr); + netj->deadline_goodness = pkthdr->sync_state; + netj->next_deadline_valid = 0; + netj->packet_data_valid = 1; + netj->running_free = 0; + jack_info( "resync after freerun... %d", netj->expected_framecnt ); + } else { + if( netj->num_lost_packets == 101 ) { + jack_info( "master seems gone... entering freerun mode", netj->expected_framecnt ); + } + + netj->running_free = 1; + + // when we really dont see packets. + // reset source address. and open possibility for new master. + // maybe dsl reconnect. Also restart of netsource without fix + // reply address changes port. + if (netj->num_lost_packets > 200 ) { + netj->srcaddress_valid = 0; + packet_cache_reset_master_address( global_packcache ); + } + } + } + } + } + + int retval = 0; + + if( !netj->packet_data_valid ) { + netj->num_lost_packets += 1; + if( netj->num_lost_packets == 1 ) + retval = netj->period_usecs; + } else { + if( (netj->num_lost_packets>1) && !netj->running_free ) + retval = (netj->num_lost_packets-1) * netj->period_usecs; + + netj->num_lost_packets = 0; + } + + return retval; +} + +void netjack_send_silence( netjack_driver_state_t *netj, int syncstate ) +{ + int tx_size = get_sample_size(netj->bitdepth) * netj->playback_channels * netj->net_period_up + sizeof(jacknet_packet_header); + unsigned int *packet_buf, *packet_bufX; + + packet_buf = alloca( tx_size); + jacknet_packet_header *tx_pkthdr = (jacknet_packet_header *)packet_buf; + jacknet_packet_header *rx_pkthdr = (jacknet_packet_header *)netj->rx_buf; + + //framecnt = rx_pkthdr->framecnt; + + netj->reply_port = rx_pkthdr->reply_port; + + // offset packet_bufX by the packetheader. + packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); + + tx_pkthdr->sync_state = syncstate; + tx_pkthdr->framecnt = netj->expected_framecnt; + + // memset 0 the payload. + int payload_size = get_sample_size(netj->bitdepth) * netj->playback_channels * netj->net_period_up; + memset(packet_bufX, 0, payload_size); + + packet_header_hton(tx_pkthdr); + if (netj->srcaddress_valid) + { + int r; + if (netj->reply_port) + netj->syncsource_address.sin_port = htons(netj->reply_port); + + for( r=0; rredundancy; r++ ) + netjack_sendto(netj->outsockfd, (char *)packet_buf, tx_size, + 0, (struct sockaddr*)&(netj->syncsource_address), sizeof(struct sockaddr_in), netj->mtu); + } +} + + +void netjack_attach( netjack_driver_state_t *netj ) +{ + //puts ("net_driver_attach"); + jack_port_t * port; + char buf[32]; + unsigned int chn; + int port_flags; + + + if (netj->handle_transport_sync) + jack_set_sync_callback(netj->client, (JackSyncCallback) net_driver_sync_cb, NULL); + + port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; + + for (chn = 0; chn < netj->capture_channels_audio; chn++) { + snprintf (buf, sizeof(buf) - 1, "capture_%u", chn + 1); + + port = jack_port_register (netj->client, buf, + JACK_DEFAULT_AUDIO_TYPE, + port_flags, 0); + if (!port) { + jack_error ("NET: cannot register port for %s", buf); + break; + } + + netj->capture_ports = + jack_slist_append (netj->capture_ports, port); + + if( netj->bitdepth == CELT_MODE ) { +#if HAVE_CELT +#if HAVE_CELT_API_0_7 + celt_int32 lookahead; + CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); + netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); +#else + celt_int32_t lookahead; + CELTMode *celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL ); + netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( celt_mode ) ); +#endif + celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); + netj->codec_latency = 2*lookahead; +#endif + } else { +#if HAVE_SAMPLERATE + netj->capture_srcs = jack_slist_append(netj->capture_srcs, src_new(SRC_LINEAR, 1, NULL)); +#endif + } + } + for (chn = netj->capture_channels_audio; chn < netj->capture_channels; chn++) { + snprintf (buf, sizeof(buf) - 1, "capture_%u", chn + 1); + + port = jack_port_register (netj->client, buf, + JACK_DEFAULT_MIDI_TYPE, + port_flags, 0); + if (!port) { + jack_error ("NET: cannot register port for %s", buf); + break; + } + + netj->capture_ports = + jack_slist_append (netj->capture_ports, port); + } + + port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; + + for (chn = 0; chn < netj->playback_channels_audio; chn++) { + snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1); + + port = jack_port_register (netj->client, buf, + JACK_DEFAULT_AUDIO_TYPE, + port_flags, 0); + + if (!port) { + jack_error ("NET: cannot register port for %s", buf); + break; + } + + netj->playback_ports = + jack_slist_append (netj->playback_ports, port); + if( netj->bitdepth == CELT_MODE ) { +#if HAVE_CELT +#if HAVE_CELT_API_0_7 + CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); + netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); +#else + CELTMode *celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL ); + netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode ) ); +#endif +#endif + } else { +#if HAVE_SAMPLERATE + netj->playback_srcs = jack_slist_append(netj->playback_srcs, src_new(SRC_LINEAR, 1, NULL)); +#endif + } + } + for (chn = netj->playback_channels_audio; chn < netj->playback_channels; chn++) { + snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1); + + port = jack_port_register (netj->client, buf, + JACK_DEFAULT_MIDI_TYPE, + port_flags, 0); + + if (!port) { + jack_error ("NET: cannot register port for %s", buf); + break; + } + + netj->playback_ports = + jack_slist_append (netj->playback_ports, port); + } + + jack_activate (netj->client); +} + + +void netjack_detach( netjack_driver_state_t *netj ) +{ + JSList * node; + + + for (node = netj->capture_ports; node; node = jack_slist_next (node)) + jack_port_unregister (netj->client, + ((jack_port_t *) node->data)); + + jack_slist_free (netj->capture_ports); + netj->capture_ports = NULL; + + for (node = netj->playback_ports; node; node = jack_slist_next (node)) + jack_port_unregister (netj->client, + ((jack_port_t *) node->data)); + + jack_slist_free (netj->playback_ports); + netj->playback_ports = NULL; +} + + +netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj, + jack_client_t * client, + const char *name, + unsigned int capture_ports, + unsigned int playback_ports, + unsigned int capture_ports_midi, + unsigned int playback_ports_midi, + jack_nframes_t sample_rate, + jack_nframes_t period_size, + unsigned int listen_port, + unsigned int transport_sync, + unsigned int resample_factor, + unsigned int resample_factor_up, + unsigned int bitdepth, + unsigned int use_autoconfig, + unsigned int latency, + unsigned int redundancy, + int dont_htonl_floats, + int always_deadline, + int jitter_val ) +{ + + // Fill in netj values. + // might be subject to autoconfig... + // so dont calculate anything with them... + + + netj->sample_rate = sample_rate; + netj->period_size = period_size; + netj->dont_htonl_floats = dont_htonl_floats; + + netj->listen_port = listen_port; + + netj->capture_channels = capture_ports + capture_ports_midi; + netj->capture_channels_audio = capture_ports; + netj->capture_channels_midi = capture_ports_midi; + netj->capture_ports = NULL; + netj->playback_channels = playback_ports + playback_ports_midi; + netj->playback_channels_audio = playback_ports; + netj->playback_channels_midi = playback_ports_midi; + netj->playback_ports = NULL; + netj->codec_latency = 0; + + netj->handle_transport_sync = transport_sync; + netj->mtu = 1400; + netj->latency = latency; + netj->redundancy = redundancy; + netj->use_autoconfig = use_autoconfig; + netj->always_deadline = always_deadline; + + + netj->client = client; + + + if ((bitdepth != 0) && (bitdepth != 8) && (bitdepth != 16) && (bitdepth != CELT_MODE)) + { + jack_info ("Invalid bitdepth: %d (8, 16 or 0 for float) !!!", bitdepth); + return NULL; + } + netj->bitdepth = bitdepth; + + + if (resample_factor_up == 0) + resample_factor_up = resample_factor; + + netj->resample_factor = resample_factor; + netj->resample_factor_up = resample_factor_up; + + + return netj; +} + +void netjack_release( netjack_driver_state_t *netj ) +{ + close( netj->sockfd ); + close( netj->outsockfd ); + + packet_cache_free( global_packcache ); + global_packcache = NULL; +} + +int +netjack_startup( netjack_driver_state_t *netj ) +{ + int first_pack_len; + struct sockaddr_in address; + // Now open the socket, and wait for the first packet to arrive... + netj->sockfd = socket (AF_INET, SOCK_DGRAM, 0); +#ifdef WIN32 + if (netj->sockfd == INVALID_SOCKET) +#else + if (netj->sockfd == -1) +#endif + { + jack_info ("socket error"); + return -1; + } + address.sin_family = AF_INET; + address.sin_port = htons(netj->listen_port); + address.sin_addr.s_addr = htonl(INADDR_ANY); + if (bind (netj->sockfd, (struct sockaddr *) &address, sizeof (address)) < 0) + { + jack_info("bind error"); + return -1; + } + + netj->outsockfd = socket (AF_INET, SOCK_DGRAM, 0); +#ifdef WIN32 + if (netj->outsockfd == INVALID_SOCKET) +#else + if (netj->outsockfd == -1) +#endif + { + jack_info ("socket error"); + return -1; + } + netj->srcaddress_valid = 0; + if (netj->use_autoconfig) + { + jacknet_packet_header *first_packet = alloca (sizeof (jacknet_packet_header)); +#ifdef WIN32 + int address_size = sizeof( struct sockaddr_in ); +#else + socklen_t address_size = sizeof (struct sockaddr_in); +#endif + //jack_info ("Waiting for an incoming packet !!!"); + //jack_info ("*** IMPORTANT *** Dont connect a client to jackd until the driver is attached to a clock source !!!"); + + while(1) { + first_pack_len = recvfrom (netj->sockfd, (char *)first_packet, sizeof (jacknet_packet_header), 0, (struct sockaddr*) & netj->syncsource_address, &address_size); +#ifdef WIN32 + if( first_pack_len == -1 ) { + first_pack_len = sizeof(jacknet_packet_header); + break; + } +#else + if (first_pack_len == sizeof (jacknet_packet_header)) + break; +#endif + } + netj->srcaddress_valid = 1; + + if (first_pack_len == sizeof (jacknet_packet_header)) + { + packet_header_ntoh (first_packet); + + jack_info ("AutoConfig Override !!!"); + if (netj->sample_rate != first_packet->sample_rate) + { + jack_info ("AutoConfig Override: Master JACK sample rate = %d", first_packet->sample_rate); + netj->sample_rate = first_packet->sample_rate; + } + + if (netj->period_size != first_packet->period_size) + { + jack_info ("AutoConfig Override: Master JACK period size is %d", first_packet->period_size); + netj->period_size = first_packet->period_size; + } + if (netj->capture_channels_audio != first_packet->capture_channels_audio) + { + jack_info ("AutoConfig Override: capture_channels_audio = %d", first_packet->capture_channels_audio); + netj->capture_channels_audio = first_packet->capture_channels_audio; + } + if (netj->capture_channels_midi != first_packet->capture_channels_midi) + { + jack_info ("AutoConfig Override: capture_channels_midi = %d", first_packet->capture_channels_midi); + netj->capture_channels_midi = first_packet->capture_channels_midi; + } + if (netj->playback_channels_audio != first_packet->playback_channels_audio) + { + jack_info ("AutoConfig Override: playback_channels_audio = %d", first_packet->playback_channels_audio); + netj->playback_channels_audio = first_packet->playback_channels_audio; + } + if (netj->playback_channels_midi != first_packet->playback_channels_midi) + { + jack_info ("AutoConfig Override: playback_channels_midi = %d", first_packet->playback_channels_midi); + netj->playback_channels_midi = first_packet->playback_channels_midi; + } + + netj->mtu = first_packet->mtu; + jack_info ("MTU is set to %d bytes", first_packet->mtu); + netj->latency = first_packet->latency; + } + } + netj->capture_channels = netj->capture_channels_audio + netj->capture_channels_midi; + netj->playback_channels = netj->playback_channels_audio + netj->playback_channels_midi; + + if( (netj->capture_channels * netj->period_size * netj->latency * 4) > 100000000 ) { + jack_error( "autoconfig requests more than 100MB packet cache... bailing out" ); + exit(1); + } + + if( netj->playback_channels > 1000 ) { + jack_error( "autoconfig requests more than 1000 playback channels... bailing out" ); + exit(1); + } + + + if( netj->mtu < (2*sizeof( jacknet_packet_header )) ) { + jack_error( "bullshit mtu requested by autoconfig" ); + exit(1); + } + + if( netj->sample_rate == 0 ) { + jack_error( "sample_rate 0 requested by autoconfig" ); + exit(1); + } + + // After possible Autoconfig: do all calculations... + netj->period_usecs = + (jack_time_t) floor ((((float) netj->period_size) / (float)netj->sample_rate) + * 1000000.0f); + + if( netj->latency == 0 ) + netj->deadline_offset = 50*netj->period_usecs; + else + netj->deadline_offset = netj->period_usecs + 10*netj->latency*netj->period_usecs/100; + + if( netj->bitdepth == CELT_MODE ) { + // celt mode. + // TODO: this is a hack. But i dont want to change the packet header. + netj->resample_factor = (netj->resample_factor * netj->period_size * 1024 / netj->sample_rate / 8)&(~1); + netj->resample_factor_up = (netj->resample_factor_up * netj->period_size * 1024 / netj->sample_rate / 8)&(~1); + + netj->net_period_down = netj->resample_factor; + netj->net_period_up = netj->resample_factor_up; + } else { + netj->net_period_down = (float) netj->period_size / (float) netj->resample_factor; + netj->net_period_up = (float) netj->period_size / (float) netj->resample_factor_up; + } + + netj->rx_bufsize = sizeof (jacknet_packet_header) + netj->net_period_down * netj->capture_channels * get_sample_size (netj->bitdepth); + netj->pkt_buf = malloc (netj->rx_bufsize); + global_packcache = packet_cache_new (netj->latency + 50, netj->rx_bufsize, netj->mtu); + + netj->expected_framecnt_valid = 0; + netj->num_lost_packets = 0; + netj->next_deadline_valid = 0; + netj->deadline_goodness = 0; + netj->time_to_deadline = 0; + + // Special handling for latency=0 + if( netj->latency == 0 ) + netj->resync_threshold = 0; + else + netj->resync_threshold = MIN( 15, netj->latency-1 ); + + netj->running_free = 0; + + return 0; +} diff --git a/common/netjack.h b/common/netjack.h new file mode 100644 index 00000000..91c81be5 --- /dev/null +++ b/common/netjack.h @@ -0,0 +1,147 @@ + +/* + Copyright (C) 2003 Robert Ham + Copyright (C) 2005 Torben Hohn + + 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 __NETJACK_H__ +#define __NETJACK_H__ + +#include + +#include +//#include +#include +#include + +#include "jack/jslist.h" + +//#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct _netjack_driver_state netjack_driver_state_t; + +struct _netjack_driver_state { + jack_nframes_t net_period_up; + jack_nframes_t net_period_down; + + jack_nframes_t sample_rate; + jack_nframes_t bitdepth; + jack_nframes_t period_size; + jack_time_t period_usecs; + int dont_htonl_floats; + int always_deadline; + + jack_nframes_t codec_latency; + + unsigned int listen_port; + + unsigned int capture_channels; + unsigned int playback_channels; + unsigned int capture_channels_audio; + unsigned int playback_channels_audio; + unsigned int capture_channels_midi; + unsigned int playback_channels_midi; + + JSList *capture_ports; + JSList *playback_ports; + JSList *playback_srcs; + JSList *capture_srcs; + + jack_client_t *client; + +#ifdef WIN32 + SOCKET sockfd; + SOCKET outsockfd; +#else + int sockfd; + int outsockfd; +#endif + + struct sockaddr_in syncsource_address; + + int reply_port; + int srcaddress_valid; + + int sync_state; + unsigned int handle_transport_sync; + + unsigned int *rx_buf; + unsigned int *pkt_buf; + unsigned int rx_bufsize; + //unsigned int tx_bufsize; + unsigned int mtu; + unsigned int latency; + unsigned int redundancy; + + jack_nframes_t expected_framecnt; + int expected_framecnt_valid; + unsigned int num_lost_packets; + jack_time_t next_deadline; + jack_time_t deadline_offset; + int next_deadline_valid; + int packet_data_valid; + int resync_threshold; + int running_free; + int deadline_goodness; + jack_time_t time_to_deadline; + unsigned int use_autoconfig; + unsigned int resample_factor; + unsigned int resample_factor_up; + int jitter_val; +}; + +int netjack_wait( netjack_driver_state_t *netj ); +void netjack_send_silence( netjack_driver_state_t *netj, int syncstate ); +void netjack_read( netjack_driver_state_t *netj, jack_nframes_t nframes ) ; +void netjack_write( netjack_driver_state_t *netj, jack_nframes_t nframes, int syncstate ); +void netjack_attach( netjack_driver_state_t *netj ); +void netjack_detach( netjack_driver_state_t *netj ); + +netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj, + jack_client_t * client, + const char *name, + unsigned int capture_ports, + unsigned int playback_ports, + unsigned int capture_ports_midi, + unsigned int playback_ports_midi, + jack_nframes_t sample_rate, + jack_nframes_t period_size, + unsigned int listen_port, + unsigned int transport_sync, + unsigned int resample_factor, + unsigned int resample_factor_up, + unsigned int bitdepth, + unsigned int use_autoconfig, + unsigned int latency, + unsigned int redundancy, + int dont_htonl_floats, + int always_deadline, + int jitter_val ); + +void netjack_release( netjack_driver_state_t *netj ); +int netjack_startup( netjack_driver_state_t *netj ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/common/netjack_packet.c b/common/netjack_packet.c new file mode 100644 index 00000000..4edbb2a3 --- /dev/null +++ b/common/netjack_packet.c @@ -0,0 +1,1520 @@ + +/* + * NetJack - Packet Handling functions + * + * used by the driver and the jacknet_client + * + * Copyright (C) 2008 Marc-Olivier Barre + * Copyright (C) 2008 Pieter Palmers + * Copyright (C) 2006 Torben Hohn + * + * 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. + * + * $Id: net_driver.c,v 1.16 2006/03/20 19:41:37 torbenh Exp $ + * + */ + +//#include "config.h" + +#ifdef __APPLE__ +#define _DARWIN_C_SOURCE +#endif + +#if HAVE_PPOLL +#define _GNU_SOURCE +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#ifdef WIN32 +#include +#include +#else +#include +#include +#include +#endif + +#include +#include + +#if HAVE_SAMPLERATE +#include +#endif + +#if HAVE_CELT +#include +#endif + +#include "netjack_packet.h" + +// JACK2 specific. +#include "jack/control.h" + +#ifdef NO_JACK_ERROR +#define jack_error printf +#endif + +int fraggo = 0; + +packet_cache *global_packcache = NULL; + +void +packet_header_hton (jacknet_packet_header *pkthdr) +{ + pkthdr->capture_channels_audio = htonl(pkthdr->capture_channels_audio); + pkthdr->playback_channels_audio = htonl(pkthdr->playback_channels_audio); + pkthdr->capture_channels_midi = htonl(pkthdr->capture_channels_midi); + pkthdr->playback_channels_midi = htonl(pkthdr->playback_channels_midi); + pkthdr->period_size = htonl(pkthdr->period_size); + pkthdr->sample_rate = htonl(pkthdr->sample_rate); + pkthdr->sync_state = htonl(pkthdr->sync_state); + pkthdr->transport_frame = htonl(pkthdr->transport_frame); + pkthdr->transport_state = htonl(pkthdr->transport_state); + pkthdr->framecnt = htonl(pkthdr->framecnt); + pkthdr->latency = htonl(pkthdr->latency); + pkthdr->reply_port = htonl(pkthdr->reply_port); + pkthdr->mtu = htonl(pkthdr->mtu); + pkthdr->fragment_nr = htonl(pkthdr->fragment_nr); +} + +void +packet_header_ntoh (jacknet_packet_header *pkthdr) +{ + pkthdr->capture_channels_audio = ntohl(pkthdr->capture_channels_audio); + pkthdr->playback_channels_audio = ntohl(pkthdr->playback_channels_audio); + pkthdr->capture_channels_midi = ntohl(pkthdr->capture_channels_midi); + pkthdr->playback_channels_midi = ntohl(pkthdr->playback_channels_midi); + pkthdr->period_size = ntohl(pkthdr->period_size); + pkthdr->sample_rate = ntohl(pkthdr->sample_rate); + pkthdr->sync_state = ntohl(pkthdr->sync_state); + pkthdr->transport_frame = ntohl(pkthdr->transport_frame); + pkthdr->transport_state = ntohl(pkthdr->transport_state); + pkthdr->framecnt = ntohl(pkthdr->framecnt); + pkthdr->latency = ntohl(pkthdr->latency); + pkthdr->reply_port = ntohl(pkthdr->reply_port); + pkthdr->mtu = ntohl(pkthdr->mtu); + pkthdr->fragment_nr = ntohl(pkthdr->fragment_nr); +} + +int get_sample_size (int bitdepth) +{ + if (bitdepth == 8) + return sizeof (int8_t); + if (bitdepth == 16) + return sizeof (int16_t); + //JN: why? is this for buffer sizes before or after encoding? + //JN: if the former, why not int16_t, if the latter, shouldn't it depend on -c N? + if( bitdepth == CELT_MODE ) + return sizeof( unsigned char ); + return sizeof (int32_t); +} + +int jack_port_is_audio(const char *porttype) +{ + return (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0); +} + +int jack_port_is_midi(const char *porttype) +{ + return (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0); +} + + +// fragment management functions. + +packet_cache +*packet_cache_new (int num_packets, int pkt_size, int mtu) +{ + int fragment_payload_size = mtu - sizeof (jacknet_packet_header); + int i, fragment_number; + + if( pkt_size == sizeof(jacknet_packet_header) ) + fragment_number = 1; + else + fragment_number = (pkt_size - sizeof (jacknet_packet_header) - 1) / fragment_payload_size + 1; + + packet_cache *pcache = malloc (sizeof (packet_cache)); + if (pcache == NULL) + { + jack_error ("could not allocate packet cache (1)"); + return NULL; + } + + pcache->size = num_packets; + pcache->packets = malloc (sizeof (cache_packet) * num_packets); + pcache->master_address_valid = 0; + pcache->last_framecnt_retreived = 0; + pcache->last_framecnt_retreived_valid = 0; + + if (pcache->packets == NULL) + { + jack_error ("could not allocate packet cache (2)"); + return NULL; + } + + for (i = 0; i < num_packets; i++) + { + pcache->packets[i].valid = 0; + pcache->packets[i].num_fragments = fragment_number; + pcache->packets[i].packet_size = pkt_size; + pcache->packets[i].mtu = mtu; + pcache->packets[i].framecnt = 0; + pcache->packets[i].fragment_array = malloc (sizeof (char) * fragment_number); + pcache->packets[i].packet_buf = malloc (pkt_size); + if ((pcache->packets[i].fragment_array == NULL) || (pcache->packets[i].packet_buf == NULL)) + { + jack_error ("could not allocate packet cache (3)"); + return NULL; + } + } + pcache->mtu = mtu; + + return pcache; +} + +void +packet_cache_free (packet_cache *pcache) +{ + int i; + if( pcache == NULL ) + return; + + for (i = 0; i < pcache->size; i++) + { + free (pcache->packets[i].fragment_array); + free (pcache->packets[i].packet_buf); + } + + free (pcache->packets); + free (pcache); +} + +cache_packet +*packet_cache_get_packet (packet_cache *pcache, jack_nframes_t framecnt) +{ + int i; + cache_packet *retval; + + for (i = 0; i < pcache->size; i++) + { + if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt)) + return &(pcache->packets[i]); + } + + // The Packet is not in the packet cache. + // find a free packet. + + retval = packet_cache_get_free_packet (pcache); + if (retval != NULL) + { + cache_packet_set_framecnt (retval, framecnt); + return retval; + } + + // No Free Packet available + // Get The Oldest packet and reset it. + + retval = packet_cache_get_oldest_packet (pcache); + //printf( "Dropping %d from Cache :S\n", retval->framecnt ); + cache_packet_reset (retval); + cache_packet_set_framecnt (retval, framecnt); + + return retval; +} + +// TODO: fix wrapping case... need to pass +// current expected frame here. +// +// or just save framecount into packet_cache. + +cache_packet +*packet_cache_get_oldest_packet (packet_cache *pcache) +{ + jack_nframes_t minimal_frame = JACK_MAX_FRAMES; + cache_packet *retval = &(pcache->packets[0]); + int i; + + for (i = 0; i < pcache->size; i++) + { + if (pcache->packets[i].valid && (pcache->packets[i].framecnt < minimal_frame)) + { + minimal_frame = pcache->packets[i].framecnt; + retval = &(pcache->packets[i]); + } + } + + return retval; +} + +cache_packet +*packet_cache_get_free_packet (packet_cache *pcache) +{ + int i; + + for (i = 0; i < pcache->size; i++) + { + if (pcache->packets[i].valid == 0) + return &(pcache->packets[i]); + } + + return NULL; +} + +void +cache_packet_reset (cache_packet *pack) +{ + int i; + pack->valid = 0; + + // XXX: i dont think this is necessary here... + // fragement array is cleared in _set_framecnt() + + for (i = 0; i < pack->num_fragments; i++) + pack->fragment_array[i] = 0; +} + +void +cache_packet_set_framecnt (cache_packet *pack, jack_nframes_t framecnt) +{ + int i; + + pack->framecnt = framecnt; + + for (i = 0; i < pack->num_fragments; i++) + pack->fragment_array[i] = 0; + + pack->valid = 1; +} + +void +cache_packet_add_fragment (cache_packet *pack, char *packet_buf, int rcv_len) +{ + jacknet_packet_header *pkthdr = (jacknet_packet_header *) packet_buf; + int fragment_payload_size = pack->mtu - sizeof (jacknet_packet_header); + char *packet_bufX = pack->packet_buf + sizeof (jacknet_packet_header); + char *dataX = packet_buf + sizeof (jacknet_packet_header); + + jack_nframes_t fragment_nr = ntohl (pkthdr->fragment_nr); + jack_nframes_t framecnt = ntohl (pkthdr->framecnt); + + if (framecnt != pack->framecnt) + { + jack_error ("errror. framecnts dont match"); + return; + } + + + if (fragment_nr == 0) + { + memcpy (pack->packet_buf, packet_buf, rcv_len); + pack->fragment_array[0] = 1; + + return; + } + + if ((fragment_nr < pack->num_fragments) && (fragment_nr > 0)) + { + if ((fragment_nr * fragment_payload_size + rcv_len - sizeof (jacknet_packet_header)) <= (pack->packet_size - sizeof (jacknet_packet_header))) + { + memcpy (packet_bufX + fragment_nr * fragment_payload_size, dataX, rcv_len - sizeof (jacknet_packet_header)); + pack->fragment_array[fragment_nr] = 1; + } + else + jack_error ("too long packet received..."); + } +} + +int +cache_packet_is_complete (cache_packet *pack) +{ + int i; + for (i = 0; i < pack->num_fragments; i++) + if (pack->fragment_array[i] == 0) + return 0; + + return 1; +} + +#ifndef WIN32 +// new poll using nanoseconds resolution and +// not waiting forever. +int +netjack_poll_deadline (int sockfd, jack_time_t deadline) +{ + struct pollfd fds; + int poll_err = 0; +#if HAVE_PPOLL + struct timespec timeout_spec = { 0, 0 }; +#else + int timeout; +#endif + + + jack_time_t now = jack_get_time(); + if( now >= deadline ) + return 0; + + if( (deadline-now) >= 1000000 ) { + jack_error( "deadline more than 1 second in the future, trimming it." ); + deadline = now+500000; + } +#if HAVE_PPOLL + timeout_spec.tv_nsec = (deadline - now) * 1000; +#else + timeout = (deadline - now + 500) / 1000; +#endif + + + fds.fd = sockfd; + fds.events = POLLIN; + +#if HAVE_PPOLL + poll_err = ppoll (&fds, 1, &timeout_spec, NULL); +#else + poll_err = poll (&fds, 1, timeout); +#endif + + if (poll_err == -1) + { + switch (errno) + { + case EBADF: + jack_error ("Error %d: An invalid file descriptor was given in one of the sets", errno); + break; + case EFAULT: + jack_error ("Error %d: The array given as argument was not contained in the calling program's address space", errno); + break; + case EINTR: + jack_error ("Error %d: A signal occurred before any requested event", errno); + break; + case EINVAL: + jack_error ("Error %d: The nfds value exceeds the RLIMIT_NOFILE value", errno); + break; + case ENOMEM: + jack_error ("Error %d: There was no space to allocate file descriptor tables", errno); + break; + } + } + return poll_err; +} + +int +netjack_poll (int sockfd, int timeout) +{ + struct pollfd fds; + int i, poll_err = 0; + sigset_t sigmask, rsigmask; + struct sigaction action; + + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGHUP); + sigaddset(&sigmask, SIGINT); + sigaddset(&sigmask, SIGQUIT); + sigaddset(&sigmask, SIGPIPE); + sigaddset(&sigmask, SIGTERM); + sigaddset(&sigmask, SIGUSR1); + sigaddset(&sigmask, SIGUSR2); + + action.sa_handler = SIG_DFL; + action.sa_mask = sigmask; + action.sa_flags = SA_RESTART; + + for (i = 1; i < NSIG; i++) + if (sigismember (&sigmask, i)) + sigaction (i, &action, 0); + + fds.fd = sockfd; + fds.events = POLLIN; + + sigprocmask(SIG_UNBLOCK, &sigmask, &rsigmask); + while (poll_err == 0) + { + poll_err = poll (&fds, 1, timeout); + } + sigprocmask(SIG_SETMASK, &rsigmask, NULL); + + if (poll_err == -1) + { + switch (errno) + { + case EBADF: + jack_error ("Error %d: An invalid file descriptor was given in one of the sets", errno); + break; + case EFAULT: + jack_error ("Error %d: The array given as argument was not contained in the calling program's address space", errno); + break; + case EINTR: + jack_error ("Error %d: A signal occurred before any requested event", errno); + break; + case EINVAL: + jack_error ("Error %d: The nfds value exceeds the RLIMIT_NOFILE value", errno); + break; + case ENOMEM: + jack_error ("Error %d: There was no space to allocate file descriptor tables", errno); + break; + } + return 0; + } + return 1; +} + +#else +int +netjack_poll (int sockfd, int timeout) +{ + jack_error( "netjack_poll not implemented" ); + return 0; +} +int +netjack_poll_deadline (int sockfd, jack_time_t deadline) +{ + fd_set fds; + FD_ZERO( &fds ); + FD_SET( sockfd, &fds ); + + struct timeval timeout; + while( 1 ) { + jack_time_t now = jack_get_time(); + if( now >= deadline ) + return 0; + + int timeout_usecs = (deadline - now); + //jack_error( "timeout = %d", timeout_usecs ); + timeout.tv_sec = 0; + timeout.tv_usec = (timeout_usecs < 500) ? 500 : timeout_usecs; + timeout.tv_usec = (timeout_usecs > 1000000) ? 500000 : timeout_usecs; + + int poll_err = select (0, &fds, NULL, NULL, &timeout); + if( poll_err != 0 ) + return poll_err; + } + + return 0; +} +#endif +// This now reads all a socket has into the cache. +// replacing netjack_recv functions. + +void +packet_cache_drain_socket( packet_cache *pcache, int sockfd ) +{ + char *rx_packet = alloca (pcache->mtu); + jacknet_packet_header *pkthdr = (jacknet_packet_header *) rx_packet; + int rcv_len; + jack_nframes_t framecnt; + cache_packet *cpack; + struct sockaddr_in sender_address; +#ifdef WIN32 + size_t senderlen = sizeof( struct sockaddr_in ); + u_long parm = 1; + ioctlsocket( sockfd, FIONBIO, &parm ); +#else + socklen_t senderlen = sizeof( struct sockaddr_in ); +#endif + while (1) + { +#ifdef WIN32 + rcv_len = recvfrom (sockfd, rx_packet, pcache->mtu, 0, + (struct sockaddr*) &sender_address, &senderlen); +#else + rcv_len = recvfrom (sockfd, rx_packet, pcache->mtu, MSG_DONTWAIT, + (struct sockaddr*) &sender_address, &senderlen); +#endif + if (rcv_len < 0) + return; + + if (pcache->master_address_valid) { + // Verify its from our master. + if (memcmp (&sender_address, &(pcache->master_address), senderlen) != 0) + continue; + } else { + // Setup this one as master + //printf( "setup master...\n" ); + memcpy ( &(pcache->master_address), &sender_address, senderlen ); + pcache->master_address_valid = 1; + } + + framecnt = ntohl (pkthdr->framecnt); + if( pcache->last_framecnt_retreived_valid && (framecnt <= pcache->last_framecnt_retreived )) + continue; + + cpack = packet_cache_get_packet (global_packcache, framecnt); + cache_packet_add_fragment (cpack, rx_packet, rcv_len); + cpack->recv_timestamp = jack_get_time(); + } +} + +void +packet_cache_reset_master_address( packet_cache *pcache ) +{ + pcache->master_address_valid = 0; + pcache->last_framecnt_retreived = 0; + pcache->last_framecnt_retreived_valid = 0; +} + +void +packet_cache_clear_old_packets (packet_cache *pcache, jack_nframes_t framecnt ) +{ + int i; + + for (i = 0; i < pcache->size; i++) + { + if (pcache->packets[i].valid && (pcache->packets[i].framecnt < framecnt)) + { + cache_packet_reset (&(pcache->packets[i])); + } + } +} + +int +packet_cache_retreive_packet_pointer( packet_cache *pcache, jack_nframes_t framecnt, char **packet_buf, int pkt_size, jack_time_t *timestamp ) +{ + int i; + cache_packet *cpack = NULL; + + + for (i = 0; i < pcache->size; i++) { + if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt)) { + cpack = &(pcache->packets[i]); + break; + } + } + + if( cpack == NULL ) { + //printf( "retreive packet: %d....not found\n", framecnt ); + return -1; + } + + if( !cache_packet_is_complete( cpack ) ) { + return -1; + } + + // ok. cpack is the one we want and its complete. + *packet_buf = cpack->packet_buf; + if( timestamp ) + *timestamp = cpack->recv_timestamp; + + pcache->last_framecnt_retreived_valid = 1; + pcache->last_framecnt_retreived = framecnt; + + return pkt_size; +} + +int +packet_cache_release_packet( packet_cache *pcache, jack_nframes_t framecnt ) +{ + int i; + cache_packet *cpack = NULL; + + + for (i = 0; i < pcache->size; i++) { + if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt)) { + cpack = &(pcache->packets[i]); + break; + } + } + + if( cpack == NULL ) { + //printf( "retreive packet: %d....not found\n", framecnt ); + return -1; + } + + if( !cache_packet_is_complete( cpack ) ) { + return -1; + } + + cache_packet_reset (cpack); + packet_cache_clear_old_packets( pcache, framecnt ); + + return 0; +} +float +packet_cache_get_fill( packet_cache *pcache, jack_nframes_t expected_framecnt ) +{ + int num_packets_before_us = 0; + int i; + + for (i = 0; i < pcache->size; i++) + { + cache_packet *cpack = &(pcache->packets[i]); + if (cpack->valid && cache_packet_is_complete( cpack )) + if( cpack->framecnt >= expected_framecnt ) + num_packets_before_us += 1; + } + + return 100.0 * (float)num_packets_before_us / (float)( pcache->size ) ; +} + +// Returns 0 when no valid packet is inside the cache. +int +packet_cache_get_next_available_framecnt( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt ) +{ + int i; + jack_nframes_t best_offset = JACK_MAX_FRAMES/2-1; + int retval = 0; + + for (i = 0; i < pcache->size; i++) + { + cache_packet *cpack = &(pcache->packets[i]); + //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); + + if (!cpack->valid || !cache_packet_is_complete( cpack )) { + //printf( "invalid\n" ); + continue; + } + + if( cpack->framecnt < expected_framecnt ) + continue; + + if( (cpack->framecnt - expected_framecnt) > best_offset ) { + continue; + } + + best_offset = cpack->framecnt - expected_framecnt; + retval = 1; + + if( best_offset == 0 ) + break; + } + if( retval && framecnt ) + *framecnt = expected_framecnt + best_offset; + + return retval; +} + +int +packet_cache_get_highest_available_framecnt( packet_cache *pcache, jack_nframes_t *framecnt ) +{ + int i; + jack_nframes_t best_value = 0; + int retval = 0; + + for (i = 0; i < pcache->size; i++) + { + cache_packet *cpack = &(pcache->packets[i]); + //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); + + if (!cpack->valid || !cache_packet_is_complete( cpack )) { + //printf( "invalid\n" ); + continue; + } + + if (cpack->framecnt < best_value) { + continue; + } + + best_value = cpack->framecnt; + retval = 1; + + } + if( retval && framecnt ) + *framecnt = best_value; + + return retval; +} + +// Returns 0 when no valid packet is inside the cache. +int +packet_cache_find_latency( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt ) +{ + int i; + jack_nframes_t best_offset = 0; + int retval = 0; + + for (i = 0; i < pcache->size; i++) + { + cache_packet *cpack = &(pcache->packets[i]); + //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); + + if (!cpack->valid || !cache_packet_is_complete( cpack )) { + //printf( "invalid\n" ); + continue; + } + + if( (cpack->framecnt - expected_framecnt) < best_offset ) { + continue; + } + + best_offset = cpack->framecnt - expected_framecnt; + retval = 1; + + if( best_offset == 0 ) + break; + } + if( retval && framecnt ) + *framecnt = JACK_MAX_FRAMES - best_offset; + + return retval; +} +// fragmented packet IO +int +netjack_recvfrom (int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, size_t *addr_size, int mtu) +{ + int retval; + socklen_t from_len = *addr_size; + if (pkt_size <= mtu) { + retval = recvfrom (sockfd, packet_buf, pkt_size, flags, addr, &from_len); + *addr_size = from_len; + return retval; + } + + char *rx_packet = alloca (mtu); + jacknet_packet_header *pkthdr = (jacknet_packet_header *) rx_packet; + int rcv_len; + jack_nframes_t framecnt; + cache_packet *cpack; + do + { + rcv_len = recvfrom (sockfd, rx_packet, mtu, 0, addr, &from_len); + if (rcv_len < 0) + return rcv_len; + framecnt = ntohl (pkthdr->framecnt); + cpack = packet_cache_get_packet (global_packcache, framecnt); + cache_packet_add_fragment (cpack, rx_packet, rcv_len); + } while (!cache_packet_is_complete (cpack)); + memcpy (packet_buf, cpack->packet_buf, pkt_size); + cache_packet_reset (cpack); + *addr_size = from_len; + return pkt_size; +} + +int +netjack_recv (int sockfd, char *packet_buf, int pkt_size, int flags, int mtu) +{ + if (pkt_size <= mtu) + return recv (sockfd, packet_buf, pkt_size, flags); + char *rx_packet = alloca (mtu); + jacknet_packet_header *pkthdr = (jacknet_packet_header *) rx_packet; + int rcv_len; + jack_nframes_t framecnt; + cache_packet *cpack; + do + { + rcv_len = recv (sockfd, rx_packet, mtu, flags); + if (rcv_len < 0) + return rcv_len; + framecnt = ntohl (pkthdr->framecnt); + cpack = packet_cache_get_packet (global_packcache, framecnt); + cache_packet_add_fragment (cpack, rx_packet, rcv_len); + } while (!cache_packet_is_complete (cpack)); + memcpy (packet_buf, cpack->packet_buf, pkt_size); + cache_packet_reset (cpack); + return pkt_size; +} + +void +netjack_sendto (int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, int addr_size, int mtu) +{ + int frag_cnt = 0; + char *tx_packet, *dataX; + jacknet_packet_header *pkthdr; + + tx_packet = alloca (mtu + 10); + dataX = tx_packet + sizeof (jacknet_packet_header); + pkthdr = (jacknet_packet_header *) tx_packet; + + int fragment_payload_size = mtu - sizeof (jacknet_packet_header); + + if (pkt_size <= mtu) { + int err; + pkthdr = (jacknet_packet_header *) packet_buf; + pkthdr->fragment_nr = htonl (0); + err = sendto(sockfd, packet_buf, pkt_size, flags, addr, addr_size); + if( err<0 ) { + //printf( "error in send\n" ); + perror( "send" ); + } + } + else + { + int err; + // Copy the packet header to the tx pack first. + memcpy(tx_packet, packet_buf, sizeof (jacknet_packet_header)); + + // Now loop and send all + char *packet_bufX = packet_buf + sizeof (jacknet_packet_header); + + while (packet_bufX < (packet_buf + pkt_size - fragment_payload_size)) + { + pkthdr->fragment_nr = htonl (frag_cnt++); + memcpy (dataX, packet_bufX, fragment_payload_size); + sendto (sockfd, tx_packet, mtu, flags, addr, addr_size); + packet_bufX += fragment_payload_size; + } + + int last_payload_size = packet_buf + pkt_size - packet_bufX; + memcpy (dataX, packet_bufX, last_payload_size); + pkthdr->fragment_nr = htonl (frag_cnt); + //jack_log("last fragment_count = %d, payload_size = %d\n", fragment_count, last_payload_size); + + // sendto(last_pack_size); + err = sendto(sockfd, tx_packet, last_payload_size + sizeof(jacknet_packet_header), flags, addr, addr_size); + if( err<0 ) { + //printf( "error in send\n" ); + perror( "send" ); + } + } +} + + +void +decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf) +{ + int i; + jack_midi_clear_buffer (buf); + for (i = 0; i < buffer_size_uint32 - 3;) + { + uint32_t payload_size; + payload_size = buffer_uint32[i]; + payload_size = ntohl (payload_size); + if (payload_size) + { + jack_midi_event_t event; + event.time = ntohl (buffer_uint32[i+1]); + event.size = ntohl (buffer_uint32[i+2]); + event.buffer = (jack_midi_data_t*) (&(buffer_uint32[i+3])); + jack_midi_event_write (buf, event.time, event.buffer, event.size); + + // skip to the next event + unsigned int nb_data_quads = (((event.size-1) & ~0x3) >> 2)+1; + i += 3+nb_data_quads; + } + else + break; // no events can follow an empty event, we're done + } +} + +void +encode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf) +{ + int i; + unsigned int written = 0; + // midi port, encode midi events + unsigned int nevents = jack_midi_get_event_count (buf); + for (i = 0; i < nevents; ++i) + { + jack_midi_event_t event; + jack_midi_event_get (&event, buf, i); + unsigned int nb_data_quads = (((event.size - 1) & ~0x3) >> 2) + 1; + unsigned int payload_size = 3 + nb_data_quads; + // only write if we have sufficient space for the event + // otherwise drop it + if (written + payload_size < buffer_size_uint32 - 1) + { + // write header + buffer_uint32[written]=htonl (payload_size); + written++; + buffer_uint32[written]=htonl (event.time); + written++; + buffer_uint32[written]=htonl (event.size); + written++; + + // write data + jack_midi_data_t* tmpbuff = (jack_midi_data_t*)(&(buffer_uint32[written])); + memcpy (tmpbuff, event.buffer, event.size); + written += nb_data_quads; + } + else + { + // buffer overflow + jack_error ("midi buffer overflow"); + break; + } + } + // now put a netjack_midi 'no-payload' event, signaling EOF + buffer_uint32[written]=0; +} + +// render functions for float +void +render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) +{ + int chn = 0; + JSList *node = capture_ports; +#if HAVE_SAMPLERATE + JSList *src_node = capture_srcs; +#endif + + uint32_t *packet_bufX = (uint32_t *)packet_payload; + + if( !packet_payload ) + return; + + while (node != NULL) + { + int i; + int_float_t val; +#if HAVE_SAMPLERATE + SRC_DATA src; +#endif + + jack_port_t *port = (jack_port_t *) node->data; + jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); + + const char *porttype = jack_port_type (port); + + if (jack_port_is_audio (porttype)) + { +#if HAVE_SAMPLERATE + // audio port, resample if necessary + if (net_period_down != nframes) + { + SRC_STATE *src_state = src_node->data; + for (i = 0; i < net_period_down; i++) + { + packet_bufX[i] = ntohl (packet_bufX[i]); + } + + src.data_in = (float *) packet_bufX; + src.input_frames = net_period_down; + + src.data_out = buf; + src.output_frames = nframes; + + src.src_ratio = (float) nframes / (float) net_period_down; + src.end_of_input = 0; + + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); + src_node = jack_slist_next (src_node); + } + else +#endif + { + if( dont_htonl_floats ) + { + memcpy( buf, packet_bufX, net_period_down*sizeof(jack_default_audio_sample_t)); + } + else + { + for (i = 0; i < net_period_down; i++) + { + val.i = packet_bufX[i]; + val.i = ntohl (val.i); + buf[i] = val.f; + } + } + } + } + else if (jack_port_is_midi (porttype)) + { + // midi port, decode midi events + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_down; + uint32_t * buffer_uint32 = (uint32_t*)packet_bufX; + decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_down); + node = jack_slist_next (node); + chn++; + } +} + +void +render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ) +{ + int chn = 0; + JSList *node = playback_ports; +#if HAVE_SAMPLERATE + JSList *src_node = playback_srcs; +#endif + + uint32_t *packet_bufX = (uint32_t *) packet_payload; + + while (node != NULL) + { +#if HAVE_SAMPLERATE + SRC_DATA src; +#endif + int i; + int_float_t val; + jack_port_t *port = (jack_port_t *) node->data; + jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); + + const char *porttype = jack_port_type (port); + + if (jack_port_is_audio (porttype)) + { + // audio port, resample if necessary + +#if HAVE_SAMPLERATE + if (net_period_up != nframes) { + SRC_STATE *src_state = src_node->data; + src.data_in = buf; + src.input_frames = nframes; + + src.data_out = (float *) packet_bufX; + src.output_frames = net_period_up; + + src.src_ratio = (float) net_period_up / (float) nframes; + src.end_of_input = 0; + + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); + + for (i = 0; i < net_period_up; i++) + { + packet_bufX[i] = htonl (packet_bufX[i]); + } + src_node = jack_slist_next (src_node); + } + else +#endif + { + if( dont_htonl_floats ) + { + memcpy( packet_bufX, buf, net_period_up*sizeof(jack_default_audio_sample_t) ); + } + else + { + for (i = 0; i < net_period_up; i++) + { + val.f = buf[i]; + val.i = htonl (val.i); + packet_bufX[i] = val.i; + } + } + } + } + else if (jack_port_is_midi (porttype)) + { + // encode midi events from port to packet + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_up; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_up); + node = jack_slist_next (node); + chn++; + } +} + +// render functions for 16bit +void +render_payload_to_jack_ports_16bit (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes) +{ + int chn = 0; + JSList *node = capture_ports; +#if HAVE_SAMPLERATE + JSList *src_node = capture_srcs; +#endif + + uint16_t *packet_bufX = (uint16_t *)packet_payload; + + if( !packet_payload ) + return; + + while (node != NULL) + { + int i; + //uint32_t val; +#if HAVE_SAMPLERATE + SRC_DATA src; +#endif + + jack_port_t *port = (jack_port_t *) node->data; + jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); + +#if HAVE_SAMPLERATE + float *floatbuf = alloca (sizeof(float) * net_period_down); +#endif + const char *porttype = jack_port_type (port); + + if (jack_port_is_audio (porttype)) + { + // audio port, resample if necessary + +#if HAVE_SAMPLERATE + if (net_period_down != nframes) + { + SRC_STATE *src_state = src_node->data; + for (i = 0; i < net_period_down; i++) + { + floatbuf[i] = ((float) ntohs(packet_bufX[i])) / 32767.0 - 1.0; + } + + src.data_in = floatbuf; + src.input_frames = net_period_down; + + src.data_out = buf; + src.output_frames = nframes; + + src.src_ratio = (float) nframes / (float) net_period_down; + src.end_of_input = 0; + + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); + src_node = jack_slist_next (src_node); + } + else +#endif + for (i = 0; i < net_period_down; i++) + buf[i] = ((float) ntohs (packet_bufX[i])) / 32768.0 - 1.0; + } + else if (jack_port_is_midi (porttype)) + { + // midi port, decode midi events + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_down / 2; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_down); + node = jack_slist_next (node); + chn++; + } +} + +void +render_jack_ports_to_payload_16bit (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up) +{ + int chn = 0; + JSList *node = playback_ports; +#if HAVE_SAMPLERATE + JSList *src_node = playback_srcs; +#endif + + uint16_t *packet_bufX = (uint16_t *)packet_payload; + + while (node != NULL) + { +#if HAVE_SAMPLERATE + SRC_DATA src; +#endif + int i; + jack_port_t *port = (jack_port_t *) node->data; + jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); + const char *porttype = jack_port_type (port); + + if (jack_port_is_audio (porttype)) + { + // audio port, resample if necessary + +#if HAVE_SAMPLERATE + if (net_period_up != nframes) + { + SRC_STATE *src_state = src_node->data; + + float *floatbuf = alloca (sizeof(float) * net_period_up); + + src.data_in = buf; + src.input_frames = nframes; + + src.data_out = floatbuf; + src.output_frames = net_period_up; + + src.src_ratio = (float) net_period_up / (float) nframes; + src.end_of_input = 0; + + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); + + for (i = 0; i < net_period_up; i++) + { + packet_bufX[i] = htons (((uint16_t)((floatbuf[i] + 1.0) * 32767.0))); + } + src_node = jack_slist_next (src_node); + } + else +#endif + for (i = 0; i < net_period_up; i++) + packet_bufX[i] = htons(((uint16_t)((buf[i] + 1.0) * 32767.0))); + } + else if (jack_port_is_midi (porttype)) + { + // encode midi events from port to packet + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_up / 2; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_up); + node = jack_slist_next (node); + chn++; + } +} + +// render functions for 8bit +void +render_payload_to_jack_ports_8bit (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes) +{ + int chn = 0; + JSList *node = capture_ports; + +#if HAVE_SAMPLERATE + JSList *src_node = capture_srcs; +#endif + + int8_t *packet_bufX = (int8_t *)packet_payload; + + if( !packet_payload ) + return; + + while (node != NULL) + { + int i; + //uint32_t val; +#if HAVE_SAMPLERATE + SRC_DATA src; +#endif + + jack_port_t *port = (jack_port_t *) node->data; + jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); + +#if HAVE_SAMPLERATE + float *floatbuf = alloca (sizeof (float) * net_period_down); +#endif + const char *porttype = jack_port_type (port); + + if (jack_port_is_audio(porttype)) + { +#if HAVE_SAMPLERATE + // audio port, resample if necessary + if (net_period_down != nframes) + { + SRC_STATE *src_state = src_node->data; + for (i = 0; i < net_period_down; i++) + floatbuf[i] = ((float) packet_bufX[i]) / 127.0; + + src.data_in = floatbuf; + src.input_frames = net_period_down; + + src.data_out = buf; + src.output_frames = nframes; + + src.src_ratio = (float) nframes / (float) net_period_down; + src.end_of_input = 0; + + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); + src_node = jack_slist_next (src_node); + } + else +#endif + for (i = 0; i < net_period_down; i++) + buf[i] = ((float) packet_bufX[i]) / 127.0; + } + else if (jack_port_is_midi (porttype)) + { + // midi port, decode midi events + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_down / 2; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_down); + node = jack_slist_next (node); + chn++; + } +} + +void +render_jack_ports_to_payload_8bit (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up) +{ + int chn = 0; + JSList *node = playback_ports; +#if HAVE_SAMPLERATE + JSList *src_node = playback_srcs; +#endif + + int8_t *packet_bufX = (int8_t *)packet_payload; + + while (node != NULL) + { +#if HAVE_SAMPLERATE + SRC_DATA src; +#endif + int i; + jack_port_t *port = (jack_port_t *) node->data; + + jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); + const char *porttype = jack_port_type (port); + + if (jack_port_is_audio (porttype)) + { +#if HAVE_SAMPLERATE + // audio port, resample if necessary + if (net_period_up != nframes) + { + + SRC_STATE *src_state = src_node->data; + + float *floatbuf = alloca (sizeof (float) * net_period_up); + + src.data_in = buf; + src.input_frames = nframes; + + src.data_out = floatbuf; + src.output_frames = net_period_up; + + src.src_ratio = (float) net_period_up / (float) nframes; + src.end_of_input = 0; + + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); + + for (i = 0; i < net_period_up; i++) + packet_bufX[i] = floatbuf[i] * 127.0; + src_node = jack_slist_next (src_node); + } + else +#endif + for (i = 0; i < net_period_up; i++) + packet_bufX[i] = buf[i] * 127.0; + } + else if (jack_port_is_midi (porttype)) + { + // encode midi events from port to packet + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_up / 4; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_up); + node = jack_slist_next (node); + chn++; + } +} + +#if HAVE_CELT +// render functions for celt. +void +render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes) +{ + int chn = 0; + JSList *node = capture_ports; + JSList *src_node = capture_srcs; + + unsigned char *packet_bufX = (unsigned char *)packet_payload; + + while (node != NULL) + { + jack_port_t *port = (jack_port_t *) node->data; + jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); + + const char *porttype = jack_port_type (port); + + if (jack_port_is_audio (porttype)) + { + // audio port, decode celt data. + + CELTDecoder *decoder = src_node->data; + if( !packet_payload ) + celt_decode_float( decoder, NULL, net_period_down, buf ); + else + celt_decode_float( decoder, packet_bufX, net_period_down, buf ); + + src_node = jack_slist_next (src_node); + } + else if (jack_port_is_midi (porttype)) + { + // midi port, decode midi events + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_down / 2; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + if( packet_payload ) + decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_down); + node = jack_slist_next (node); + chn++; + } +} + +void +render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up) +{ + int chn = 0; + JSList *node = playback_ports; + JSList *src_node = playback_srcs; + + unsigned char *packet_bufX = (unsigned char *)packet_payload; + + while (node != NULL) + { + jack_port_t *port = (jack_port_t *) node->data; + jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); + const char *porttype = jack_port_type (port); + + if (jack_port_is_audio (porttype)) + { + // audio port, encode celt data. + + int encoded_bytes; + float *floatbuf = alloca (sizeof(float) * nframes ); + memcpy( floatbuf, buf, nframes*sizeof(float) ); + CELTEncoder *encoder = src_node->data; + encoded_bytes = celt_encode_float( encoder, floatbuf, NULL, packet_bufX, net_period_up ); + if( encoded_bytes != net_period_up ) + printf( "something in celt changed. netjack needs to be changed to handle this.\n" ); + src_node = jack_slist_next( src_node ); + } + else if (jack_port_is_midi (porttype)) + { + // encode midi events from port to packet + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_up / 2; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_up); + node = jack_slist_next (node); + chn++; + } +} + +#endif +/* Wrapper functions with bitdepth argument... */ +void +render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) +{ + if (bitdepth == 8) + render_payload_to_jack_ports_8bit (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); + else if (bitdepth == 16) + render_payload_to_jack_ports_16bit (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); +#if HAVE_CELT + else if (bitdepth == CELT_MODE) + render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); +#endif + else + render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats); +} + +void +render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats) +{ + if (bitdepth == 8) + render_jack_ports_to_payload_8bit (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); + else if (bitdepth == 16) + render_jack_ports_to_payload_16bit (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); +#if HAVE_CELT + else if (bitdepth == CELT_MODE) + render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); +#endif + else + render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats); +} diff --git a/common/netjack_packet.h b/common/netjack_packet.h new file mode 100644 index 00000000..4617310e --- /dev/null +++ b/common/netjack_packet.h @@ -0,0 +1,165 @@ + +/* + * NetJack - Packet Handling functions + * + * used by the driver and the jacknet_client + * + * Copyright (C) 2006 Torben Hohn + * + * 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. + * + * $Id: net_driver.c,v 1.16 2006/03/20 19:41:37 torbenh Exp $ + * + */ + +#ifndef __JACK_NET_PACKET_H__ +#define __JACK_NET_PACKET_H__ + +#ifdef __cplusplus + extern "C" + { +#endif + +#include +#include +//#include +#include + +#include + +//#include +// The Packet Header. + +#define CELT_MODE 1000 // Magic bitdepth value that indicates CELT compression +#define MASTER_FREEWHEELS 0x80000000 + +typedef struct _jacknet_packet_header jacknet_packet_header; + +struct _jacknet_packet_header +{ + // General AutoConf Data + jack_nframes_t capture_channels_audio; + jack_nframes_t playback_channels_audio; + jack_nframes_t capture_channels_midi; + jack_nframes_t playback_channels_midi; + jack_nframes_t period_size; + jack_nframes_t sample_rate; + + // Transport Sync + jack_nframes_t sync_state; + jack_nframes_t transport_frame; + jack_nframes_t transport_state; + + // Packet loss Detection, and latency reduction + jack_nframes_t framecnt; + jack_nframes_t latency; + + jack_nframes_t reply_port; + jack_nframes_t mtu; + jack_nframes_t fragment_nr; +}; + +typedef union _int_float int_float_t; + +union _int_float +{ + uint32_t i; + float f; +}; + +// fragment reorder cache. +typedef struct _cache_packet cache_packet; + +struct _cache_packet +{ + int valid; + int num_fragments; + int packet_size; + int mtu; + jack_time_t recv_timestamp; + jack_nframes_t framecnt; + char * fragment_array; + char * packet_buf; +}; + +typedef struct _packet_cache packet_cache; + +struct _packet_cache +{ + int size; + cache_packet *packets; + int mtu; + struct sockaddr_in master_address; + int master_address_valid; + jack_nframes_t last_framecnt_retreived; + int last_framecnt_retreived_valid; +}; + +extern packet_cache *global_packcache; + +// fragment cache function prototypes +// XXX: Some of these are private. +packet_cache *packet_cache_new(int num_packets, int pkt_size, int mtu); +void packet_cache_free(packet_cache *pkt_cache); + +cache_packet *packet_cache_get_packet(packet_cache *pkt_cache, jack_nframes_t framecnt); +cache_packet *packet_cache_get_oldest_packet(packet_cache *pkt_cache); +cache_packet *packet_cache_get_free_packet(packet_cache *pkt_cache); + +void cache_packet_reset(cache_packet *pack); +void cache_packet_set_framecnt(cache_packet *pack, jack_nframes_t framecnt); +void cache_packet_add_fragment(cache_packet *pack, char *packet_buf, int rcv_len); +int cache_packet_is_complete(cache_packet *pack); + +void packet_cache_drain_socket( packet_cache *pcache, int sockfd ); +void packet_cache_reset_master_address( packet_cache *pcache ); +float packet_cache_get_fill( packet_cache *pcache, jack_nframes_t expected_framecnt ); +int packet_cache_retreive_packet_pointer( packet_cache *pcache, jack_nframes_t framecnt, char **packet_buf, int pkt_size, jack_time_t *timestamp ); +int packet_cache_release_packet( packet_cache *pcache, jack_nframes_t framecnt ); +int packet_cache_get_next_available_framecnt( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt ); +int packet_cache_get_highest_available_framecnt( packet_cache *pcache, jack_nframes_t *framecnt ); +int packet_cache_find_latency( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt ); +// Function Prototypes + +int netjack_poll_deadline (int sockfd, jack_time_t deadline); + +void netjack_sendto(int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, int addr_size, int mtu); + + +int get_sample_size(int bitdepth); +void packet_header_hton(jacknet_packet_header *pkthdr); + +void packet_header_ntoh(jacknet_packet_header *pkthdr); + +void render_payload_to_jack_ports(int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats ); + +void render_jack_ports_to_payload(int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ); + + +// XXX: This is sort of deprecated: +// This one waits forever. an is not using ppoll +int netjack_poll(int sockfd, int timeout); + +// TODO: these are deprecated. +//int netjack_recvfrom(int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, socklen_t *addr_size, int mtu); +//int netjack_recv(int sockfd, char *packet_buf, int pkt_size, int flags, int mtu); + +void decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf); +void encode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf); +#ifdef __cplusplus + } +#endif +#endif + diff --git a/common/ringbuffer.c b/common/ringbuffer.c index a7209a2b..f2096630 100644 --- a/common/ringbuffer.c +++ b/common/ringbuffer.c @@ -67,23 +67,27 @@ size_t jack_ringbuffer_write_space(const jack_ringbuffer_t *rb); EXPORT jack_ringbuffer_t * jack_ringbuffer_create (size_t sz) { - int power_of_two; - jack_ringbuffer_t *rb; - - rb = (jack_ringbuffer_t*)malloc (sizeof (jack_ringbuffer_t)); - - for (power_of_two = 1; 1 << power_of_two < sz; power_of_two++); - - rb->size = 1 << power_of_two; - rb->size_mask = rb->size; - rb->size_mask -= 1; - rb->write_ptr = 0; - rb->read_ptr = 0; - rb->buf = (char*)malloc (rb->size); - memset(rb->buf, 0, rb->size); - rb->mlocked = 0; - - return rb; + int power_of_two; + jack_ringbuffer_t *rb; + + if ((rb = malloc (sizeof (jack_ringbuffer_t))) == NULL) { + return NULL; + } + + for (power_of_two = 1; 1 << power_of_two < sz; power_of_two++); + + rb->size = 1 << power_of_two; + rb->size_mask = rb->size; + rb->size_mask -= 1; + rb->write_ptr = 0; + rb->read_ptr = 0; + if ((rb->buf = malloc (rb->size)) == NULL) { + free (rb); + return NULL; + } + rb->mlocked = 0; + + return rb; } /* Free all data associated with the ringbuffer `rb'. */ @@ -92,12 +96,12 @@ EXPORT void jack_ringbuffer_free (jack_ringbuffer_t * rb) { #ifdef USE_MLOCK - if (rb->mlocked) { - munlock (rb->buf, rb->size); - } + if (rb->mlocked) { + munlock (rb->buf, rb->size); + } #endif /* USE_MLOCK */ - free (rb->buf); - free (rb); + free (rb->buf); + free (rb); } /* Lock the data block of `rb' using the system call 'mlock'. */ @@ -106,12 +110,12 @@ EXPORT int jack_ringbuffer_mlock (jack_ringbuffer_t * rb) { #ifdef USE_MLOCK - if (mlock (rb->buf, rb->size)) { - return -1; - } + if (mlock (rb->buf, rb->size)) { + return -1; + } #endif /* USE_MLOCK */ - rb->mlocked = 1; - return 0; + rb->mlocked = 1; + return 0; } /* Reset the read and write pointers to zero. This is not thread @@ -120,8 +124,8 @@ jack_ringbuffer_mlock (jack_ringbuffer_t * rb) EXPORT void jack_ringbuffer_reset (jack_ringbuffer_t * rb) { - rb->read_ptr = 0; - rb->write_ptr = 0; + rb->read_ptr = 0; + rb->write_ptr = 0; } /* Reset the read and write pointers to zero. This is not thread @@ -130,11 +134,11 @@ jack_ringbuffer_reset (jack_ringbuffer_t * rb) EXPORT void jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz) { - rb->size = sz; - rb->size_mask = rb->size; - rb->size_mask -= 1; - rb->read_ptr = 0; - rb->write_ptr = 0; + rb->size = sz; + rb->size_mask = rb->size; + rb->size_mask -= 1; + rb->read_ptr = 0; + rb->write_ptr = 0; } /* Return the number of bytes available for reading. This is the @@ -144,16 +148,16 @@ jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz) EXPORT size_t jack_ringbuffer_read_space (const jack_ringbuffer_t * rb) { - size_t w, r; - - w = rb->write_ptr; - r = rb->read_ptr; - - if (w > r) { - return w - r; - } else { - return (w - r + rb->size) & rb->size_mask; - } + size_t w, r; + + w = rb->write_ptr; + r = rb->read_ptr; + + if (w > r) { + return w - r; + } else { + return (w - r + rb->size) & rb->size_mask; + } } /* Return the number of bytes available for writing. This is the @@ -163,18 +167,18 @@ jack_ringbuffer_read_space (const jack_ringbuffer_t * rb) EXPORT size_t jack_ringbuffer_write_space (const jack_ringbuffer_t * rb) { - size_t w, r; - - w = rb->write_ptr; - r = rb->read_ptr; - - if (w > r) { - return ((r - w + rb->size) & rb->size_mask) - 1; - } else if (w < r) { - return (r - w) - 1; - } else { - return rb->size - 1; - } + size_t w, r; + + w = rb->write_ptr; + r = rb->read_ptr; + + if (w > r) { + return ((r - w + rb->size) & rb->size_mask) - 1; + } else if (w < r) { + return (r - w) - 1; + } else { + return rb->size - 1; + } } /* The copying data reader. Copy at most `cnt' bytes from `rb' to @@ -183,77 +187,77 @@ jack_ringbuffer_write_space (const jack_ringbuffer_t * rb) EXPORT size_t jack_ringbuffer_read (jack_ringbuffer_t * rb, char *dest, size_t cnt) { - size_t free_cnt; - size_t cnt2; - size_t to_read; - size_t n1, n2; + size_t free_cnt; + size_t cnt2; + size_t to_read; + size_t n1, n2; - if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) { - return 0; - } + if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) { + return 0; + } - to_read = cnt > free_cnt ? free_cnt : cnt; + to_read = cnt > free_cnt ? free_cnt : cnt; - cnt2 = rb->read_ptr + to_read; + cnt2 = rb->read_ptr + to_read; - if (cnt2 > rb->size) { - n1 = rb->size - rb->read_ptr; - n2 = cnt2 & rb->size_mask; - } else { - n1 = to_read; - n2 = 0; - } + if (cnt2 > rb->size) { + n1 = rb->size - rb->read_ptr; + n2 = cnt2 & rb->size_mask; + } else { + n1 = to_read; + n2 = 0; + } - memcpy (dest, &(rb->buf[rb->read_ptr]), n1); - rb->read_ptr = (rb->read_ptr + n1) & rb->size_mask; + memcpy (dest, &(rb->buf[rb->read_ptr]), n1); + rb->read_ptr = (rb->read_ptr + n1) & rb->size_mask; - if (n2) { - memcpy (dest + n1, &(rb->buf[rb->read_ptr]), n2); - rb->read_ptr = (rb->read_ptr + n2) & rb->size_mask; - } + if (n2) { + memcpy (dest + n1, &(rb->buf[rb->read_ptr]), n2); + rb->read_ptr = (rb->read_ptr + n2) & rb->size_mask; + } - return to_read; + return to_read; } -/* The copying data reader w/o read pointer advance. Copy at most - `cnt' bytes from `rb' to `dest'. Returns the actual number of bytes -copied. */ +/* The copying data reader w/o read pointer advance. Copy at most + `cnt' bytes from `rb' to `dest'. Returns the actual number of bytes + copied. */ EXPORT size_t jack_ringbuffer_peek (jack_ringbuffer_t * rb, char *dest, size_t cnt) { - size_t free_cnt; - size_t cnt2; - size_t to_read; - size_t n1, n2; - size_t tmp_read_ptr; + size_t free_cnt; + size_t cnt2; + size_t to_read; + size_t n1, n2; + size_t tmp_read_ptr; - tmp_read_ptr = rb->read_ptr; + tmp_read_ptr = rb->read_ptr; - if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) { - return 0; - } + if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) { + return 0; + } - to_read = cnt > free_cnt ? free_cnt : cnt; + to_read = cnt > free_cnt ? free_cnt : cnt; - cnt2 = tmp_read_ptr + to_read; + cnt2 = tmp_read_ptr + to_read; - if (cnt2 > rb->size) { - n1 = rb->size - tmp_read_ptr; - n2 = cnt2 & rb->size_mask; - } else { - n1 = to_read; - n2 = 0; - } + if (cnt2 > rb->size) { + n1 = rb->size - tmp_read_ptr; + n2 = cnt2 & rb->size_mask; + } else { + n1 = to_read; + n2 = 0; + } - memcpy (dest, &(rb->buf[tmp_read_ptr]), n1); - tmp_read_ptr = (tmp_read_ptr + n1) & rb->size_mask; + memcpy (dest, &(rb->buf[tmp_read_ptr]), n1); + tmp_read_ptr = (tmp_read_ptr + n1) & rb->size_mask; - if (n2) { - memcpy (dest + n1, &(rb->buf[tmp_read_ptr]), n2); - } + if (n2) { + memcpy (dest + n1, &(rb->buf[tmp_read_ptr]), n2); + } - return to_read; + return to_read; } /* The copying data writer. Copy at most `cnt' bytes to `rb' from @@ -262,36 +266,36 @@ jack_ringbuffer_peek (jack_ringbuffer_t * rb, char *dest, size_t cnt) EXPORT size_t jack_ringbuffer_write (jack_ringbuffer_t * rb, const char *src, size_t cnt) { - size_t free_cnt; - size_t cnt2; - size_t to_write; - size_t n1, n2; + size_t free_cnt; + size_t cnt2; + size_t to_write; + size_t n1, n2; - if ((free_cnt = jack_ringbuffer_write_space (rb)) == 0) { - return 0; - } + if ((free_cnt = jack_ringbuffer_write_space (rb)) == 0) { + return 0; + } - to_write = cnt > free_cnt ? free_cnt : cnt; + to_write = cnt > free_cnt ? free_cnt : cnt; - cnt2 = rb->write_ptr + to_write; + cnt2 = rb->write_ptr + to_write; - if (cnt2 > rb->size) { - n1 = rb->size - rb->write_ptr; - n2 = cnt2 & rb->size_mask; - } else { - n1 = to_write; - n2 = 0; - } + if (cnt2 > rb->size) { + n1 = rb->size - rb->write_ptr; + n2 = cnt2 & rb->size_mask; + } else { + n1 = to_write; + n2 = 0; + } - memcpy (&(rb->buf[rb->write_ptr]), src, n1); - rb->write_ptr = (rb->write_ptr + n1) & rb->size_mask; + memcpy (&(rb->buf[rb->write_ptr]), src, n1); + rb->write_ptr = (rb->write_ptr + n1) & rb->size_mask; - if (n2) { - memcpy (&(rb->buf[rb->write_ptr]), src + n1, n2); - rb->write_ptr = (rb->write_ptr + n2) & rb->size_mask; - } + if (n2) { + memcpy (&(rb->buf[rb->write_ptr]), src + n1, n2); + rb->write_ptr = (rb->write_ptr + n2) & rb->size_mask; + } - return to_write; + return to_write; } /* Advance the read pointer `cnt' places. */ @@ -299,8 +303,8 @@ jack_ringbuffer_write (jack_ringbuffer_t * rb, const char *src, size_t cnt) EXPORT void jack_ringbuffer_read_advance (jack_ringbuffer_t * rb, size_t cnt) { - size_t tmp = (rb->read_ptr + cnt) & rb->size_mask; - rb->read_ptr = tmp; + size_t tmp = (rb->read_ptr + cnt) & rb->size_mask; + rb->read_ptr = tmp; } /* Advance the write pointer `cnt' places. */ @@ -308,8 +312,8 @@ jack_ringbuffer_read_advance (jack_ringbuffer_t * rb, size_t cnt) EXPORT void jack_ringbuffer_write_advance (jack_ringbuffer_t * rb, size_t cnt) { - size_t tmp = (rb->write_ptr + cnt) & rb->size_mask; - rb->write_ptr = tmp; + size_t tmp = (rb->write_ptr + cnt) & rb->size_mask; + rb->write_ptr = tmp; } /* The non-copying data reader. `vec' is an array of two places. Set @@ -321,39 +325,39 @@ EXPORT void jack_ringbuffer_get_read_vector (const jack_ringbuffer_t * rb, jack_ringbuffer_data_t * vec) { - size_t free_cnt; - size_t cnt2; - size_t w, r; + size_t free_cnt; + size_t cnt2; + size_t w, r; - w = rb->write_ptr; - r = rb->read_ptr; + w = rb->write_ptr; + r = rb->read_ptr; - if (w > r) { - free_cnt = w - r; - } else { - free_cnt = (w - r + rb->size) & rb->size_mask; - } + if (w > r) { + free_cnt = w - r; + } else { + free_cnt = (w - r + rb->size) & rb->size_mask; + } - cnt2 = r + free_cnt; + cnt2 = r + free_cnt; - if (cnt2 > rb->size) { + if (cnt2 > rb->size) { - /* Two part vector: the rest of the buffer after the current write - ptr, plus some from the start of the buffer. */ + /* Two part vector: the rest of the buffer after the current write + ptr, plus some from the start of the buffer. */ - vec[0].buf = &(rb->buf[r]); - vec[0].len = rb->size - r; - vec[1].buf = rb->buf; - vec[1].len = cnt2 & rb->size_mask; + vec[0].buf = &(rb->buf[r]); + vec[0].len = rb->size - r; + vec[1].buf = rb->buf; + vec[1].len = cnt2 & rb->size_mask; - } else { + } else { - /* Single part vector: just the rest of the buffer */ + /* Single part vector: just the rest of the buffer */ - vec[0].buf = &(rb->buf[r]); - vec[0].len = free_cnt; - vec[1].len = 0; - } + vec[0].buf = &(rb->buf[r]); + vec[0].len = free_cnt; + vec[1].len = 0; + } } /* The non-copying data writer. `vec' is an array of two places. Set @@ -365,35 +369,35 @@ EXPORT void jack_ringbuffer_get_write_vector (const jack_ringbuffer_t * rb, jack_ringbuffer_data_t * vec) { - size_t free_cnt; - size_t cnt2; - size_t w, r; - - w = rb->write_ptr; - r = rb->read_ptr; - - if (w > r) { - free_cnt = ((r - w + rb->size) & rb->size_mask) - 1; - } else if (w < r) { - free_cnt = (r - w) - 1; - } else { - free_cnt = rb->size - 1; - } - - cnt2 = w + free_cnt; - - if (cnt2 > rb->size) { - - /* Two part vector: the rest of the buffer after the current write - ptr, plus some from the start of the buffer. */ - - vec[0].buf = &(rb->buf[w]); - vec[0].len = rb->size - w; - vec[1].buf = rb->buf; - vec[1].len = cnt2 & rb->size_mask; - } else { - vec[0].buf = &(rb->buf[w]); - vec[0].len = free_cnt; - vec[1].len = 0; - } -} + size_t free_cnt; + size_t cnt2; + size_t w, r; + + w = rb->write_ptr; + r = rb->read_ptr; + + if (w > r) { + free_cnt = ((r - w + rb->size) & rb->size_mask) - 1; + } else if (w < r) { + free_cnt = (r - w) - 1; + } else { + free_cnt = rb->size - 1; + } + + cnt2 = w + free_cnt; + + if (cnt2 > rb->size) { + + /* Two part vector: the rest of the buffer after the current write + ptr, plus some from the start of the buffer. */ + + vec[0].buf = &(rb->buf[w]); + vec[0].len = rb->size - w; + vec[1].buf = rb->buf; + vec[1].len = cnt2 & rb->size_mask; + } else { + vec[0].buf = &(rb->buf[w]); + vec[0].len = free_cnt; + vec[1].len = 0; + } +} \ No newline at end of file diff --git a/dbus/sigsegv.c b/dbus/sigsegv.c index 46645408..26bc204f 100644 --- a/dbus/sigsegv.c +++ b/dbus/sigsegv.c @@ -26,12 +26,10 @@ #include #include #include -#include #include #include #include #ifndef NO_CPP_DEMANGLE -//#include char * __cxa_demangle(const char * __mangled_name, char * __output_buffer, size_t * __length, int * __status); #endif @@ -56,6 +54,8 @@ static void signal_segv(int signum, siginfo_t* info, void*ptr) #else +#include + static void signal_segv(int signum, siginfo_t* info, void*ptr) { static const char *si_codes[3] = {"", "SEGV_MAPERR", "SEGV_ACCERR"}; diff --git a/example-clients/alsa_in.c b/example-clients/alsa_in.c new file mode 100644 index 00000000..2a8b78c3 --- /dev/null +++ b/example-clients/alsa_in.c @@ -0,0 +1,757 @@ +/** @file simple_client.c + * + * @brief This simple client demonstrates the basic features of JACK + * as they would be used by many applications. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "alsa/asoundlib.h" + +#include + +// Here are the lists of the jack ports... + +JSList *capture_ports = NULL; +JSList *capture_srcs = NULL; +JSList *playback_ports = NULL; +JSList *playback_srcs = NULL; +jack_client_t *client; + +snd_pcm_t *alsa_handle; + +int jack_sample_rate; +int jack_buffer_size; + +int quit = 0; +double resample_mean = 1.0; +double static_resample_factor = 1.0; + +double *offset_array; +double *window_array; +int offset_differential_index = 0; + +double offset_integral = 0; + +// ------------------------------------------------------ commandline parameters + +int sample_rate = 0; /* stream rate */ +int num_channels = 2; /* count of channels */ +int period_size = 1024; +int num_periods = 2; + +int target_delay = 0; /* the delay which the program should try to approach. */ +int max_diff = 0; /* the diff value, when a hard readpointer skip should occur */ +int catch_factor = 100000; +int catch_factor2 = 10000; +double pclamp = 15.0; +double controlquant = 10000.0; +int smooth_size = 256; +int good_window=0; +int verbose = 0; +int instrument = 0; +int samplerate_quality = 2; + +// Debug stuff: + +volatile float output_resampling_factor = 1.0; +volatile int output_new_delay = 0; +volatile float output_offset = 0.0; +volatile float output_integral = 0.0; +volatile float output_diff = 0.0; + +snd_pcm_uframes_t real_buffer_size; +snd_pcm_uframes_t real_period_size; + +// format selection, and corresponding functions from memops in a nice set of structs. + +typedef struct alsa_format { + snd_pcm_format_t format_id; + size_t sample_size; + void (*jack_to_soundcard) (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); + void (*soundcard_to_jack) (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); + const char *name; +} alsa_format_t; + +alsa_format_t formats[] = { + { SND_PCM_FORMAT_FLOAT_LE, 4, sample_move_dS_floatLE, sample_move_floatLE_sSs, "float" }, + { SND_PCM_FORMAT_S32, 4, sample_move_d32u24_sS, sample_move_dS_s32u24, "32bit" }, + { SND_PCM_FORMAT_S24_3LE, 3, sample_move_d24_sS, sample_move_dS_s24, "24bit - real" }, + { SND_PCM_FORMAT_S24, 4, sample_move_d24_sS, sample_move_dS_s24, "24bit" }, + { SND_PCM_FORMAT_S16, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit" } +}; +#define NUMFORMATS (sizeof(formats)/sizeof(formats[0])) +int format=0; + +// Alsa stuff... i dont want to touch this bullshit in the next years.... please... + +static int xrun_recovery(snd_pcm_t *handle, int err) { +// printf( "xrun !!!.... %d\n", err ); + if (err == -EPIPE) { /* under-run */ + err = snd_pcm_prepare(handle); + if (err < 0) + printf("Can't recovery from underrun, prepare failed: %s\n", snd_strerror(err)); + return 0; + } else if (err == -EAGAIN) { + while ((err = snd_pcm_resume(handle)) == -EAGAIN) + usleep(100); /* wait until the suspend flag is released */ + if (err < 0) { + err = snd_pcm_prepare(handle); + if (err < 0) + printf("Can't recovery from suspend, prepare failed: %s\n", snd_strerror(err)); + } + return 0; + } + return err; +} + +static int set_hwformat( snd_pcm_t *handle, snd_pcm_hw_params_t *params ) +{ + int i; + int err; + + for( i=0; i (target_delay+max_diff) ) { + char *tmp = alloca( (delay-target_delay) * formats[format].sample_size * num_channels ); + snd_pcm_readi( alsa_handle, tmp, delay-target_delay ); + output_new_delay = (int) delay; + + delay = target_delay; + + // Set the resample_rate... we need to adjust the offset integral, to do this. + // first look at the PI controller, this code is just a special case, which should never execute once + // everything is swung in. + offset_integral = - (resample_mean - static_resample_factor) * catch_factor * catch_factor2; + // Also clear the array. we are beginning a new control cycle. + for( i=0; i 4 ) current_resample_factor = 4; + + // Now Calculate how many samples we need. + rlen = ceil( ((double)nframes) / current_resample_factor )+2; + assert( rlen > 2 ); + + // Calculate resample_mean so we can init ourselves to saner values. + resample_mean = 0.9999 * resample_mean + 0.0001 * current_resample_factor; + /* + * now this should do it... + */ + + outbuf = alloca( rlen * formats[format].sample_size * num_channels ); + + resampbuf = alloca( rlen * sizeof( float ) ); + + // get the data... +again: + err = snd_pcm_readi(alsa_handle, outbuf, rlen); + if( err < 0 ) { + printf( "err = %d\n", err ); + if (xrun_recovery(alsa_handle, err) < 0) { + //printf("Write error: %s\n", snd_strerror(err)); + //exit(EXIT_FAILURE); + } + goto again; + } + if( err != rlen ) { + //printf( "read = %d\n", rlen ); + } + + /* + * render jack ports to the outbuf... + */ + + int chn = 0; + JSList *node = capture_ports; + JSList *src_node = capture_srcs; + SRC_DATA src; + + while ( node != NULL) + { + jack_port_t *port = (jack_port_t *) node->data; + float *buf = jack_port_get_buffer (port, nframes); + + SRC_STATE *src_state = src_node->data; + + formats[format].soundcard_to_jack( resampbuf, outbuf + format[formats].sample_size * chn, rlen, num_channels*format[formats].sample_size ); + + src.data_in = resampbuf; + src.input_frames = rlen; + + src.data_out = buf; + src.output_frames = nframes; + src.end_of_input = 0; + + src.src_ratio = current_resample_factor; + + src_process( src_state, &src ); + + put_back_samples = rlen-src.input_frames_used; + + src_node = jack_slist_next (src_node); + node = jack_slist_next (node); + chn++; + } + + // Put back the samples libsamplerate did not consume. + //printf( "putback = %d\n", put_back_samples ); + snd_pcm_rewind( alsa_handle, put_back_samples ); + + return 0; +} + + +/** + * Allocate the necessary jack ports... + */ + +void alloc_ports( int n_capture, int n_playback ) { + + int port_flags = JackPortIsOutput; + int chn; + jack_port_t *port; + char buf[32]; + + capture_ports = NULL; + for (chn = 0; chn < n_capture; chn++) + { + snprintf (buf, sizeof(buf) - 1, "capture_%u", chn+1); + + port = jack_port_register (client, buf, + JACK_DEFAULT_AUDIO_TYPE, + port_flags, 0); + + if (!port) + { + printf( "jacknet_client: cannot register port for %s", buf); + break; + } + + capture_srcs = jack_slist_append( capture_srcs, src_new( 4-samplerate_quality, 1, NULL ) ); + capture_ports = jack_slist_append (capture_ports, port); + } + + port_flags = JackPortIsInput; + + playback_ports = NULL; + for (chn = 0; chn < n_playback; chn++) + { + snprintf (buf, sizeof(buf) - 1, "playback_%u", chn+1); + + port = jack_port_register (client, buf, + JACK_DEFAULT_AUDIO_TYPE, + port_flags, 0); + + if (!port) + { + printf( "jacknet_client: cannot register port for %s", buf); + break; + } + + playback_srcs = jack_slist_append( playback_srcs, src_new( 4-samplerate_quality, 1, NULL ) ); + playback_ports = jack_slist_append (playback_ports, port); + } +} + +/** + * This is the shutdown callback for this JACK application. + * It is called by JACK if the server ever shuts down or + * decides to disconnect the client. + */ + +void jack_shutdown (void *arg) { + + exit (1); +} + +/** + * be user friendly. + * be user friendly. + * be user friendly. + */ + +void printUsage() { +fprintf(stderr, "usage: alsa_out [options]\n" + "\n" + " -j - client name\n" + " -d \n" + " -c \n" + " -p \n" + " -n \n" + " -r \n" + " -q \n" + " -t \n" + " -i turns on instrumentation\n" + " -v turns on printouts\n" + "\n"); +} + + +/** + * the main function.... + */ + +void +sigterm_handler( int signal ) +{ + quit = 1; +} + + +int main (int argc, char *argv[]) { + char jack_name[30] = "alsa_in"; + char alsa_device[30] = "hw:0"; + + extern char *optarg; + extern int optind, optopt; + int errflg=0; + int c; + + while ((c = getopt(argc, argv, "ivj:r:c:p:n:d:q:m:t:f:F:C:Q:s:")) != -1) { + switch(c) { + case 'j': + strcpy(jack_name,optarg); + break; + case 'r': + sample_rate = atoi(optarg); + break; + case 'c': + num_channels = atoi(optarg); + break; + case 'p': + period_size = atoi(optarg); + break; + case 'n': + num_periods = atoi(optarg); + break; + case 'd': + strcpy(alsa_device,optarg); + break; + case 't': + target_delay = atoi(optarg); + break; + case 'q': + samplerate_quality = atoi(optarg); + break; + case 'm': + max_diff = atoi(optarg); + break; + case 'f': + catch_factor = atoi(optarg); + break; + case 'F': + catch_factor2 = atoi(optarg); + break; + case 'C': + pclamp = (double) atoi(optarg); + break; + case 'Q': + controlquant = (double) atoi(optarg); + break; + case 'v': + verbose = 1; + break; + case 'i': + instrument = 1; + break; + case 's': + smooth_size = atoi(optarg); + break; + case ':': + fprintf(stderr, + "Option -%c requires an operand\n", optopt); + errflg++; + break; + case '?': + fprintf(stderr, + "Unrecognized option: -%c\n", optopt); + errflg++; + } + } + if (errflg) { + printUsage(); + exit(2); + } + + if( (samplerate_quality < 0) || (samplerate_quality > 4) ) { + fprintf (stderr, "invalid samplerate quality\n"); + return 1; + } + if ((client = jack_client_open (jack_name, 0, NULL)) == 0) { + fprintf (stderr, "jack server not running?\n"); + return 1; + } + + /* tell the JACK server to call `process()' whenever + there is work to be done. + */ + + jack_set_process_callback (client, process, 0); + + /* tell the JACK server to call `jack_shutdown()' if + it ever shuts down, either entirely, or if it + just decides to stop calling us. + */ + + jack_on_shutdown (client, jack_shutdown, 0); + + + // get jack sample_rate + + jack_sample_rate = jack_get_sample_rate( client ); + + if( !sample_rate ) + sample_rate = jack_sample_rate; + + // now open the alsa fd... + alsa_handle = open_audiofd( alsa_device, 1, sample_rate, num_channels, period_size, num_periods); + if( alsa_handle == 0 ) + exit(20); + + printf( "selected sample format: %s\n", formats[format].name ); + + static_resample_factor = (double) jack_sample_rate / (double) sample_rate; + resample_mean = static_resample_factor; + + offset_array = malloc( sizeof(double) * smooth_size ); + if( offset_array == NULL ) { + fprintf( stderr, "no memory for offset_array !!!\n" ); + exit(20); + } + window_array = malloc( sizeof(double) * smooth_size ); + if( window_array == NULL ) { + fprintf( stderr, "no memory for window_array !!!\n" ); + exit(20); + } + int i; + for( i=0; i target_delay ) { + fprintf( stderr, "target_delay (%d) cant be smaller than max_diff(%d)\n", target_delay, max_diff ); + exit(20); + } + if( (target_delay+max_diff) > (num_periods*period_size) ) { + fprintf( stderr, "target_delay+max_diff (%d) cant be bigger than buffersize(%d)\n", target_delay+max_diff, num_periods*period_size ); + exit(20); + } + // alloc input ports, which are blasted out to alsa... + alloc_ports( num_channels, 0 ); + + + /* tell the JACK server that we are ready to roll */ + + if (jack_activate (client)) { + fprintf (stderr, "cannot activate client"); + return 1; + } + + signal( SIGTERM, sigterm_handler ); + signal( SIGINT, sigterm_handler ); + + if( verbose ) { + while(!quit) { + usleep(500000); + if( output_new_delay ) { + printf( "delay = %d\n", output_new_delay ); + output_new_delay = 0; + } + printf( "res: %f, \tdiff = %f, \toffset = %f \n", output_resampling_factor, output_diff, output_offset ); + } + } else if( instrument ) { + printf( "# n\tresamp\tdiff\toffseti\tintegral\n"); + int n=0; + while(!quit) { + usleep(1000); + printf( "%d\t%f\t%f\t%f\t%f\n", n++, output_resampling_factor, output_diff, output_offset, output_integral ); + } + } else { + while(!quit) + { + usleep(500000); + if( output_new_delay ) { + printf( "delay = %d\n", output_new_delay ); + output_new_delay = 0; + } + } + } + + jack_deactivate( client ); + jack_client_close (client); + exit (0); +} + diff --git a/example-clients/alsa_out.c b/example-clients/alsa_out.c new file mode 100644 index 00000000..2d34cd13 --- /dev/null +++ b/example-clients/alsa_out.c @@ -0,0 +1,755 @@ +/** @file simple_client.c + * + * @brief This simple client demonstrates the basic features of JACK + * as they would be used by many applications. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "alsa/asoundlib.h" + +#include + +// Here are the lists of the jack ports... + +JSList *capture_ports = NULL; +JSList *capture_srcs = NULL; +JSList *playback_ports = NULL; +JSList *playback_srcs = NULL; +jack_client_t *client; + +snd_pcm_t *alsa_handle; + +int jack_sample_rate; +int jack_buffer_size; + +double resample_mean = 1.0; +double static_resample_factor = 1.0; + +double *offset_array; +double *window_array; +int offset_differential_index = 0; + +double offset_integral = 0; +int quit = 0; + +// ------------------------------------------------------ commandline parameters + +int sample_rate = 0; /* stream rate */ +int num_channels = 2; /* count of channels */ +int period_size = 1024; +int num_periods = 2; + +int target_delay = 0; /* the delay which the program should try to approach. */ +int max_diff = 0; /* the diff value, when a hard readpointer skip should occur */ +int catch_factor = 100000; +int catch_factor2 = 10000; +double pclamp = 15.0; +double controlquant = 10000.0; +int smooth_size = 256; +int good_window=0; +int verbose = 0; +int instrument = 0; +int samplerate_quality = 2; + +// Debug stuff: + +volatile float output_resampling_factor = 1.0; +volatile int output_new_delay = 0; +volatile float output_offset = 0.0; +volatile float output_integral = 0.0; +volatile float output_diff = 0.0; + +snd_pcm_uframes_t real_buffer_size; +snd_pcm_uframes_t real_period_size; + +// format selection, and corresponding functions from memops in a nice set of structs. + +typedef struct alsa_format { + snd_pcm_format_t format_id; + size_t sample_size; + void (*jack_to_soundcard) (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); + void (*soundcard_to_jack) (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); + const char *name; +} alsa_format_t; + +alsa_format_t formats[] = { + { SND_PCM_FORMAT_FLOAT_LE, 4, sample_move_dS_floatLE, sample_move_floatLE_sSs, "float" }, + { SND_PCM_FORMAT_S32, 4, sample_move_d32u24_sS, sample_move_dS_s32u24, "32bit" }, + { SND_PCM_FORMAT_S24, 4, sample_move_d24_sS, sample_move_dS_s24, "24bit" }, + { SND_PCM_FORMAT_S16, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit" } +}; +#define NUMFORMATS (sizeof(formats)/sizeof(formats[0])) +int format=0; + +// Alsa stuff... i dont want to touch this bullshit in the next years.... please... + +static int xrun_recovery(snd_pcm_t *handle, int err) { +// printf( "xrun !!!.... %d\n", err ); + if (err == -EPIPE) { /* under-run */ + err = snd_pcm_prepare(handle); + if (err < 0) + printf("Can't recovery from underrun, prepare failed: %s\n", snd_strerror(err)); + return 0; + } else if (err == -EAGAIN) { + while ((err = snd_pcm_resume(handle)) == -EAGAIN) + usleep(100); /* wait until the suspend flag is released */ + if (err < 0) { + err = snd_pcm_prepare(handle); + if (err < 0) + printf("Can't recovery from suspend, prepare failed: %s\n", snd_strerror(err)); + } + return 0; + } + return err; +} + +static int set_hwformat( snd_pcm_t *handle, snd_pcm_hw_params_t *params ) +{ + int i; + int err; + + for( i=0; i (target_delay+max_diff) ) { + snd_pcm_rewind( alsa_handle, delay - target_delay ); + output_new_delay = (int) delay; + + delay = target_delay; + + // Set the resample_rate... we need to adjust the offset integral, to do this. + // first look at the PI controller, this code is just a special case, which should never execute once + // everything is swung in. + offset_integral = - (resample_mean - static_resample_factor) * catch_factor * catch_factor2; + // Also clear the array. we are beginning a new control cycle. + for( i=0; i 4 ) current_resample_factor = 4; + + // Now Calculate how many samples we need. + rlen = ceil( ((double)nframes) * current_resample_factor )+2; + assert( rlen > 2 ); + + // Calculate resample_mean so we can init ourselves to saner values. + resample_mean = 0.9999 * resample_mean + 0.0001 * current_resample_factor; + /* + * now this should do it... + */ + + outbuf = alloca( rlen * formats[format].sample_size * num_channels ); + + resampbuf = alloca( rlen * sizeof( float ) ); + /* + * render jack ports to the outbuf... + */ + + int chn = 0; + JSList *node = playback_ports; + JSList *src_node = playback_srcs; + SRC_DATA src; + + while ( node != NULL) + { + jack_port_t *port = (jack_port_t *) node->data; + float *buf = jack_port_get_buffer (port, nframes); + + SRC_STATE *src_state = src_node->data; + + src.data_in = buf; + src.input_frames = nframes; + + src.data_out = resampbuf; + src.output_frames = rlen; + src.end_of_input = 0; + + src.src_ratio = current_resample_factor; + + src_process( src_state, &src ); + + formats[format].jack_to_soundcard( outbuf + format[formats].sample_size * chn, resampbuf, src.output_frames_gen, num_channels*format[formats].sample_size, NULL); + + src_node = jack_slist_next (src_node); + node = jack_slist_next (node); + chn++; + } + + // now write the output... +again: + err = snd_pcm_writei(alsa_handle, outbuf, src.output_frames_gen); + //err = snd_pcm_writei(alsa_handle, outbuf, src.output_frames_gen); + if( err < 0 ) { + printf( "err = %d\n", err ); + if (xrun_recovery(alsa_handle, err) < 0) { + printf("Write error: %s\n", snd_strerror(err)); + exit(EXIT_FAILURE); + } + goto again; + } + + return 0; +} + + +/** + * Allocate the necessary jack ports... + */ + +void alloc_ports( int n_capture, int n_playback ) { + + int port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; + int chn; + jack_port_t *port; + char buf[32]; + + capture_ports = NULL; + for (chn = 0; chn < n_capture; chn++) + { + snprintf (buf, sizeof(buf) - 1, "capture_%u", chn+1); + + port = jack_port_register (client, buf, + JACK_DEFAULT_AUDIO_TYPE, + port_flags, 0); + + if (!port) + { + printf( "jacknet_client: cannot register port for %s", buf); + break; + } + + capture_srcs = jack_slist_append( capture_srcs, src_new( 4-samplerate_quality, 1, NULL ) ); + capture_ports = jack_slist_append (capture_ports, port); + } + + port_flags = JackPortIsInput; + + playback_ports = NULL; + for (chn = 0; chn < n_playback; chn++) + { + snprintf (buf, sizeof(buf) - 1, "playback_%u", chn+1); + + port = jack_port_register (client, buf, + JACK_DEFAULT_AUDIO_TYPE, + port_flags, 0); + + if (!port) + { + printf( "jacknet_client: cannot register port for %s", buf); + break; + } + + playback_srcs = jack_slist_append( playback_srcs, src_new( 4-samplerate_quality, 1, NULL ) ); + playback_ports = jack_slist_append (playback_ports, port); + } +} + +/** + * This is the shutdown callback for this JACK application. + * It is called by JACK if the server ever shuts down or + * decides to disconnect the client. + */ + +void jack_shutdown (void *arg) { + + exit (1); +} + +/** + * be user friendly. + * be user friendly. + * be user friendly. + */ + +void printUsage() { +fprintf(stderr, "usage: alsa_out [options]\n" + "\n" + " -j - client name\n" + " -d \n" + " -c \n" + " -p \n" + " -n \n" + " -r \n" + " -q \n" + " -t \n" + " -i turns on instrumentation\n" + " -v turns on printouts\n" + "\n"); +} + + +/** + * the main function.... + */ + +void +sigterm_handler( int signal ) +{ + quit = 1; +} + + +int main (int argc, char *argv[]) { + char jack_name[30] = "alsa_out"; + char alsa_device[30] = "hw:0"; + + extern char *optarg; + extern int optind, optopt; + int errflg=0; + int c; + + while ((c = getopt(argc, argv, "ivj:r:c:p:n:d:q:m:t:f:F:C:Q:s:")) != -1) { + switch(c) { + case 'j': + strcpy(jack_name,optarg); + break; + case 'r': + sample_rate = atoi(optarg); + break; + case 'c': + num_channels = atoi(optarg); + break; + case 'p': + period_size = atoi(optarg); + break; + case 'n': + num_periods = atoi(optarg); + break; + case 'd': + strcpy(alsa_device,optarg); + break; + case 't': + target_delay = atoi(optarg); + break; + case 'q': + samplerate_quality = atoi(optarg); + break; + case 'm': + max_diff = atoi(optarg); + break; + case 'f': + catch_factor = atoi(optarg); + break; + case 'F': + catch_factor2 = atoi(optarg); + break; + case 'C': + pclamp = (double) atoi(optarg); + break; + case 'Q': + controlquant = (double) atoi(optarg); + break; + case 'v': + verbose = 1; + break; + case 'i': + instrument = 1; + break; + case 's': + smooth_size = atoi(optarg); + break; + case ':': + fprintf(stderr, + "Option -%c requires an operand\n", optopt); + errflg++; + break; + case '?': + fprintf(stderr, + "Unrecognized option: -%c\n", optopt); + errflg++; + } + } + if (errflg) { + printUsage(); + exit(2); + } + + if( (samplerate_quality < 0) || (samplerate_quality > 4) ) { + fprintf (stderr, "invalid samplerate quality\n"); + return 1; + } + if ((client = jack_client_open (jack_name, 0, NULL)) == 0) { + fprintf (stderr, "jack server not running?\n"); + return 1; + } + + /* tell the JACK server to call `process()' whenever + there is work to be done. + */ + + jack_set_process_callback (client, process, 0); + + /* tell the JACK server to call `jack_shutdown()' if + it ever shuts down, either entirely, or if it + just decides to stop calling us. + */ + + jack_on_shutdown (client, jack_shutdown, 0); + + + // get jack sample_rate + + jack_sample_rate = jack_get_sample_rate( client ); + + if( !sample_rate ) + sample_rate = jack_sample_rate; + + static_resample_factor = (double) sample_rate / (double) jack_sample_rate; + resample_mean = static_resample_factor; + + offset_array = malloc( sizeof(double) * smooth_size ); + if( offset_array == NULL ) { + fprintf( stderr, "no memory for offset_array !!!\n" ); + exit(20); + } + window_array = malloc( sizeof(double) * smooth_size ); + if( window_array == NULL ) { + fprintf( stderr, "no memory for window_array !!!\n" ); + exit(20); + } + int i; + for( i=0; i target_delay ) { + fprintf( stderr, "target_delay (%d) cant be smaller than max_diff(%d)\n", target_delay, max_diff ); + exit(20); + } + if( (target_delay+max_diff) > (num_periods*period_size) ) { + fprintf( stderr, "target_delay+max_diff (%d) cant be bigger than buffersize(%d)\n", target_delay+max_diff, num_periods*period_size ); + exit(20); + } + // now open the alsa fd... + alsa_handle = open_audiofd( alsa_device, 0, sample_rate, num_channels, period_size, num_periods); + if( alsa_handle == 0 ) + exit(20); + + printf( "selected sample format: %s\n", formats[format].name ); + + // alloc input ports, which are blasted out to alsa... + alloc_ports( 0, num_channels ); + + + /* tell the JACK server that we are ready to roll */ + + if (jack_activate (client)) { + fprintf (stderr, "cannot activate client"); + return 1; + } + + signal( SIGTERM, sigterm_handler ); + signal( SIGINT, sigterm_handler ); + + if( verbose ) { + while(!quit) { + usleep(500000); + if( output_new_delay ) { + printf( "delay = %d\n", output_new_delay ); + output_new_delay = 0; + } + printf( "res: %f, \tdiff = %f, \toffset = %f \n", output_resampling_factor, output_diff, output_offset ); + } + } else if( instrument ) { + printf( "# n\tresamp\tdiff\toffseti\tintegral\n"); + int n=0; + while(!quit) { + usleep(1000); + printf( "%d\t%f\t%f\t%f\t%f\n", n++, output_resampling_factor, output_diff, output_offset, output_integral ); + } + } else { + while(!quit) + { + usleep(500000); + if( output_new_delay ) { + printf( "delay = %d\n", output_new_delay ); + output_new_delay = 0; + } + } + } + + jack_deactivate( client ); + jack_client_close (client); + exit (0); +} + diff --git a/example-clients/bufsize.c b/example-clients/bufsize.c index d867a9ea..72a0f9e8 100644 --- a/example-clients/bufsize.c +++ b/example-clients/bufsize.c @@ -30,6 +30,7 @@ char *package; /* program name */ jack_client_t *client; jack_nframes_t nframes; +int just_print_bufsize=0; void jack_shutdown(void *arg) { @@ -54,6 +55,10 @@ void parse_arguments(int argc, char *argv[]) else package++; + if (argc==1) { + just_print_bufsize = 1; + return; + } if (argc < 2) { fprintf(stderr, "usage: %s \n", package); exit(9); @@ -74,7 +79,7 @@ int main(int argc, char *argv[]) parse_arguments(argc, argv); /* become a JACK client */ - if ((client = jack_client_open(package, JackNullOption, NULL)) == 0) { + if ((client = jack_client_open(package, JackNullOption, NULL)) == 0) { fprintf(stderr, "JACK server not running?\n"); exit(1); } @@ -86,10 +91,16 @@ int main(int argc, char *argv[]) jack_on_shutdown(client, jack_shutdown, 0); - rc = jack_set_buffer_size(client, nframes); - if (rc) - fprintf(stderr, "jack_set_buffer_size(): %s\n", strerror(rc)); - + if (just_print_bufsize) { + fprintf(stdout, "%d\n", jack_get_buffer_size( client ) ); + rc=0; + } + else + { + rc = jack_set_buffer_size(client, nframes); + if (rc) + fprintf(stderr, "jack_set_buffer_size(): %s\n", strerror(rc)); + } jack_client_close(client); return rc; diff --git a/example-clients/internal_metro.cpp b/example-clients/internal_metro.cpp index 6591ec7c..59806c74 100644 --- a/example-clients/internal_metro.cpp +++ b/example-clients/internal_metro.cpp @@ -57,7 +57,7 @@ InternalMetro::InternalMetro(int freq, double max_amp, int dur_arg, int bpm, cha client_name = (char *) malloc (9 * sizeof (char)); strcpy (client_name, "metro"); } - if ((client = jack_client_new (client_name)) == 0) { + if ((client = jack_client_open (client_name, JackNullOption, NULL)) == 0) { fprintf (stderr, "jack server not running?\n"); return ; } diff --git a/example-clients/netsource.c b/example-clients/netsource.c new file mode 100644 index 00000000..ed4c1af0 --- /dev/null +++ b/example-clients/netsource.c @@ -0,0 +1,780 @@ +/* +NetJack Client + +Copyright (C) 2008 Marc-Olivier Barre +Copyright (C) 2008 Pieter Palmers +Copyright (C) 2006 Torben Hohn + +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. + +*/ + +/** @file netsource.c + * + * @brief This client connects a remote slave JACK to a local JACK server assumed to be the master + */ + + +#include +#include +#include +#include +#include +#include + +#ifdef WIN32 +#include +#include +#else +#include +#include +#include +#endif + +/* These two required by FreeBSD. */ +#include + + +#include + +//#include +#include +#if HAVE_SAMPLERATE +#include +#endif + +#if HAVE_CELT +#include +#endif + +#include + +JSList *capture_ports = NULL; +JSList *capture_srcs = NULL; +int capture_channels = 0; +int capture_channels_audio = 2; +int capture_channels_midi = 1; +JSList *playback_ports = NULL; +JSList *playback_srcs = NULL; +int playback_channels = 0; +int playback_channels_audio = 2; +int playback_channels_midi = 1; +int dont_htonl_floats = 0; + +int latency = 5; +jack_nframes_t factor = 1; +int bitdepth = 0; +int mtu = 1400; +int reply_port = 0; +int bind_port = 0; +int redundancy = 1; +jack_client_t *client; + +int state_connected = 0; +int state_latency = 0; +int state_netxruns = 0; +int state_currentframe = 0; +int state_recv_packet_queue_time = 0; + +int quit=0; + + +int outsockfd; +int insockfd; +#ifdef WIN32 +struct sockaddr_in destaddr; +struct sockaddr_in bindaddr; +#else +struct sockaddr destaddr; +struct sockaddr bindaddr; +#endif + +int sync_state; +jack_transport_state_t last_transport_state; + +int framecnt = 0; + +int cont_miss = 0; + +int freewheeling = 0; + +/** + * This Function allocates all the I/O Ports which are added the lists. + */ +void +alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int n_playback_midi) +{ + + int port_flags = JackPortIsOutput; + int chn; + jack_port_t *port; + char buf[32]; + + capture_ports = NULL; + /* Allocate audio capture channels */ + for (chn = 0; chn < n_capture_audio; chn++) + { + snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1); + port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0); + if (!port) + { + printf( "jack_netsource: cannot register %s port\n", buf); + break; + } + if( bitdepth == 1000 ) { +#if HAVE_CELT +#if HAVE_CELT_API_0_7 + CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL ); + capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); +#else + CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), 1, jack_get_buffer_size(client), NULL ); + capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode ) ); +#endif +#endif + } else { +#if HAVE_SAMPLERATE + capture_srcs = jack_slist_append (capture_srcs, src_new (SRC_LINEAR, 1, NULL)); +#endif + } + capture_ports = jack_slist_append (capture_ports, port); + } + + /* Allocate midi capture channels */ + for (chn = n_capture_audio; chn < n_capture_midi + n_capture_audio; chn++) + { + snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1); + port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0); + if (!port) + { + printf ("jack_netsource: cannot register %s port\n", buf); + break; + } + capture_ports = jack_slist_append(capture_ports, port); + } + + /* Allocate audio playback channels */ + port_flags = JackPortIsInput; + playback_ports = NULL; + for (chn = 0; chn < n_playback_audio; chn++) + { + snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1); + port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0); + if (!port) + { + printf ("jack_netsource: cannot register %s port\n", buf); + break; + } + if( bitdepth == 1000 ) { +#if HAVE_CELT +#if HAVE_CELT_API_0_7 + CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL ); + playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); +#else + CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), 1, jack_get_buffer_size(client), NULL ); + playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode ) ); +#endif +#endif + } else { +#if HAVE_SAMPLERATE + playback_srcs = jack_slist_append (playback_srcs, src_new (SRC_LINEAR, 1, NULL)); +#endif + } + playback_ports = jack_slist_append (playback_ports, port); + } + + /* Allocate midi playback channels */ + for (chn = n_playback_audio; chn < n_playback_midi + n_playback_audio; chn++) + { + snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1); + port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0); + if (!port) + { + printf ("jack_netsource: cannot register %s port\n", buf); + break; + } + playback_ports = jack_slist_append (playback_ports, port); + } +} + +/** + * The Sync callback... sync state is set elsewhere... + * we will see if this is working correctly. + * i dont really believe in it yet. + */ +int +sync_cb (jack_transport_state_t state, jack_position_t *pos, void *arg) +{ + static int latency_count = 0; + int retval = sync_state; + + if (latency_count) { + latency_count--; + retval = 0; + } + + else if (state == JackTransportStarting && last_transport_state != JackTransportStarting) + { + retval = 0; + latency_count = latency - 1; + } + + last_transport_state = state; + return retval; +} + +void +freewheel_cb (int starting, void *arg) +{ + freewheeling = starting; +} + + int deadline_goodness=0; +/** + * The process callback for this JACK application. + * It is called by JACK at the appropriate times. + */ +int +process (jack_nframes_t nframes, void *arg) +{ + jack_nframes_t net_period; + int rx_bufsize, tx_bufsize; + + jack_default_audio_sample_t *buf; + jack_port_t *port; + JSList *node; + int chn; + int size, i; + const char *porttype; + int input_fd; + + jack_position_t local_trans_pos; + + uint32_t *packet_buf, *packet_bufX; + uint32_t *rx_packet_ptr; + jack_time_t packet_recv_timestamp; + + if( bitdepth == 1000 ) + net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8)&(~1) ; + else + net_period = (float) nframes / (float) factor; + + rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header); + tx_bufsize = get_sample_size (bitdepth) * playback_channels * net_period + sizeof (jacknet_packet_header); + + + /* Allocate a buffer where both In and Out Buffer will fit */ + packet_buf = alloca ((rx_bufsize > tx_bufsize) ? rx_bufsize : tx_bufsize); + + jacknet_packet_header *pkthdr = (jacknet_packet_header *) packet_buf; + + /* + * for latency==0 we need to send out the packet before we wait on the reply. + * but this introduces a cycle of latency, when netsource is connected to itself. + * so we send out before read only in zero latency mode. + * + */ + + if( latency == 0 ) { + /* reset packet_bufX... */ + packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); + + /* ---------- Send ---------- */ + render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes, + packet_bufX, net_period, dont_htonl_floats); + + /* fill in packet hdr */ + pkthdr->transport_state = jack_transport_query (client, &local_trans_pos); + pkthdr->transport_frame = local_trans_pos.frame; + pkthdr->framecnt = framecnt; + pkthdr->latency = latency; + pkthdr->reply_port = reply_port; + pkthdr->sample_rate = jack_get_sample_rate (client); + pkthdr->period_size = nframes; + + /* playback for us is capture on the other side */ + pkthdr->capture_channels_audio = playback_channels_audio; + pkthdr->playback_channels_audio = capture_channels_audio; + pkthdr->capture_channels_midi = playback_channels_midi; + pkthdr->playback_channels_midi = capture_channels_midi; + pkthdr->mtu = mtu; + if( freewheeling!= 0 ) + pkthdr->sync_state = (jack_nframes_t)MASTER_FREEWHEELS; + else + pkthdr->sync_state = (jack_nframes_t)deadline_goodness; + //printf("goodness=%d\n", deadline_goodness ); + + packet_header_hton (pkthdr); + if (cont_miss < 3*latency+5) { + int r; + for( r=0; r 50+5*latency) + { + state_connected = 0; + packet_cache_reset_master_address( global_packcache ); + //printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss); + cont_miss = 0; + } + } + + /* + * ok... now the RECEIVE code. + * + */ + + /* reset packet_bufX... */ + packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); + + if( reply_port ) + input_fd = insockfd; + else + input_fd = outsockfd; + + // for latency == 0 we can poll. + if( (latency == 0) || (freewheeling!=0) ) { + jack_time_t deadline = jack_get_time() + 1000000 * jack_get_buffer_size(client)/jack_get_sample_rate(client); + // Now loop until we get the right packet. + while(1) { + jack_nframes_t got_frame; + if ( ! netjack_poll_deadline( input_fd, deadline ) ) + break; + + packet_cache_drain_socket(global_packcache, input_fd); + + if (packet_cache_get_next_available_framecnt( global_packcache, framecnt - latency, &got_frame )) + if( got_frame == (framecnt - latency) ) + break; + } + } else { + // normally: + // only drain socket. + packet_cache_drain_socket(global_packcache, input_fd); + } + + size = packet_cache_retreive_packet_pointer( global_packcache, framecnt - latency, (char**)&rx_packet_ptr, rx_bufsize, &packet_recv_timestamp ); + /* First alternative : we received what we expected. Render the data + * to the JACK ports so it can be played. */ + if (size == rx_bufsize) + { + packet_buf = rx_packet_ptr; + pkthdr = (jacknet_packet_header *) packet_buf; + packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); + // calculate how much time there would have been, if this packet was sent at the deadline. + + int recv_time_offset = (int) (jack_get_time() - packet_recv_timestamp); + packet_header_ntoh (pkthdr); + deadline_goodness = recv_time_offset - (int)pkthdr->latency; + //printf( "deadline goodness = %d ---> off: %d\n", deadline_goodness, recv_time_offset ); + + if (cont_miss) + { + //printf("Frame %d \tRecovered from dropouts\n", framecnt); + cont_miss = 0; + } + render_payload_to_jack_ports (bitdepth, packet_bufX, net_period, + capture_ports, capture_srcs, nframes, dont_htonl_floats); + + state_currentframe = framecnt; + state_recv_packet_queue_time = recv_time_offset; + state_connected = 1; + sync_state = pkthdr->sync_state; + packet_cache_release_packet( global_packcache, framecnt - latency ); + } + /* Second alternative : we've received something that's not + * as big as expected or we missed a packet. We render silence + * to the ouput ports */ + else + { + jack_nframes_t latency_estimate; + if( packet_cache_find_latency( global_packcache, framecnt, &latency_estimate ) ) + //if( (state_latency == 0) || (latency_estimate < state_latency) ) + state_latency = latency_estimate; + + // Set the counters up. + state_currentframe = framecnt; + //state_latency = framecnt - pkthdr->framecnt; + state_netxruns += 1; + + //printf ("Frame %d \tPacket missed or incomplete (expected: %d bytes, got: %d bytes)\n", framecnt, rx_bufsize, size); + //printf ("Frame %d \tPacket missed or incomplete\n", framecnt); + cont_miss += 1; + chn = 0; + node = capture_ports; + while (node != NULL) + { + port = (jack_port_t *) node->data; + buf = jack_port_get_buffer (port, nframes); + porttype = jack_port_type (port); + if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size ()) == 0) + for (i = 0; i < nframes; i++) + buf[i] = 0.0; + else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size ()) == 0) + jack_midi_clear_buffer (buf); + node = jack_slist_next (node); + chn++; + } + } + if( latency != 0 ) { + /* reset packet_bufX... */ + packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); + + /* ---------- Send ---------- */ + render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes, + packet_bufX, net_period, dont_htonl_floats); + + /* fill in packet hdr */ + pkthdr->transport_state = jack_transport_query (client, &local_trans_pos); + pkthdr->transport_frame = local_trans_pos.frame; + pkthdr->framecnt = framecnt; + pkthdr->latency = latency; + pkthdr->reply_port = reply_port; + pkthdr->sample_rate = jack_get_sample_rate (client); + pkthdr->period_size = nframes; + + /* playback for us is capture on the other side */ + pkthdr->capture_channels_audio = playback_channels_audio; + pkthdr->playback_channels_audio = capture_channels_audio; + pkthdr->capture_channels_midi = playback_channels_midi; + pkthdr->playback_channels_midi = capture_channels_midi; + pkthdr->mtu = mtu; + if( freewheeling!= 0 ) + pkthdr->sync_state = (jack_nframes_t)MASTER_FREEWHEELS; + else + pkthdr->sync_state = (jack_nframes_t)deadline_goodness; + //printf("goodness=%d\n", deadline_goodness ); + + packet_header_hton (pkthdr); + if (cont_miss < 3*latency+5) { + int r; + for( r=0; r 50+5*latency) + { + state_connected = 0; + packet_cache_reset_master_address( global_packcache ); + //printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss); + cont_miss = 0; + } + } + + framecnt++; + return 0; +} + +/** + * This is the shutdown callback for this JACK application. + * It is called by JACK if the server ever shuts down or + * decides to disconnect the client. + */ + +void +jack_shutdown (void *arg) +{ + exit (1); +} + +void +init_sockaddr_in (struct sockaddr_in *name , const char *hostname , uint16_t port) +{ + name->sin_family = AF_INET ; + name->sin_port = htons (port); + if (hostname) + { + struct hostent *hostinfo = gethostbyname (hostname); + if (hostinfo == NULL) { + fprintf (stderr, "init_sockaddr_in: unknown host: %s.\n", hostname); + fflush( stderr ); + } +#ifdef WIN32 + name->sin_addr.s_addr = inet_addr( hostname ); +#else + name->sin_addr = *(struct in_addr *) hostinfo->h_addr ; +#endif + } + else + name->sin_addr.s_addr = htonl (INADDR_ANY) ; + +} + +void +printUsage () +{ +fprintf (stderr, "usage: jack_netsource [options]\n" + "\n" + " -h this help text\n" + " -H - Host name of the slave JACK\n" + " -o - Number of audio playback channels\n" + " -i - Number of audio capture channels\n" + " -O - Number of midi playback channels\n" + " -I - Number of midi capture channels\n" + " -n - Network latency in JACK periods\n" + " -p - UDP port that the slave is listening on\n" + " -r - UDP port that we are listening on\n" + " -B - reply port, for use in NAT environments\n" + " -b - Set transport to use 16bit or 8bit\n" + " -c - Use CELT encoding with kbits per channel\n" + " -m - Assume this mtu for the link\n" + " -R - Redundancy: send out packets N times.\n" + " -e - skip host-to-network endianness conversion\n" + " -N - Reports a different name to jack\n" + " -s - The name of the local jack server\n" + "\n"); +} + +void +sigterm_handler( int signal ) +{ + quit = 1; +} + +int +main (int argc, char *argv[]) +{ + /* Some startup related basics */ + char *client_name, *server_name = NULL, *peer_ip; + int peer_port = 3000; + jack_options_t options = JackNullOption; + jack_status_t status; +#ifdef WIN32 + WSADATA wsa; + int rc = WSAStartup(MAKEWORD(2,0),&wsa); +#endif + /* Torben's famous state variables, aka "the reporting API" ! */ + /* heh ? these are only the copies of them ;) */ + int statecopy_connected, statecopy_latency, statecopy_netxruns; + jack_nframes_t net_period; + /* Argument parsing stuff */ + extern char *optarg; + extern int optind, optopt; + int errflg=0, c; + + if (argc < 3) + { + printUsage (); + return 1; + } + + client_name = (char *) malloc (sizeof (char) * 10); + peer_ip = (char *) malloc (sizeof (char) * 10); + sprintf(client_name, "netjack"); + sprintf(peer_ip, "localhost"); + + while ((c = getopt (argc, argv, ":h:H:o:i:O:I:n:p:r:B:b:c:m:R:e:N:s:")) != -1) + { + switch (c) + { + case 'h': + printUsage(); + exit (0); + break; + case 'H': + free(peer_ip); + peer_ip = (char *) malloc (sizeof (char) * strlen (optarg)+1); + strcpy (peer_ip, optarg); + break; + case 'o': + playback_channels_audio = atoi (optarg); + break; + case 'i': + capture_channels_audio = atoi (optarg); + break; + case 'O': + playback_channels_midi = atoi (optarg); + break; + case 'I': + capture_channels_midi = atoi (optarg); + break; + case 'n': + latency = atoi (optarg); + break; + case 'p': + peer_port = atoi (optarg); + break; + case 'r': + reply_port = atoi (optarg); + break; + case 'B': + bind_port = atoi (optarg); + break; + case 'f': + factor = atoi (optarg); + printf("This feature is deprecated and will be removed in future netjack versions. CELT offers a superiour way to conserve bandwidth"); + break; + case 'b': + bitdepth = atoi (optarg); + break; + case 'c': +#if HAVE_CELT + bitdepth = 1000; + factor = atoi (optarg); +#else + printf( "not built with celt supprt\n" ); + exit(10); +#endif + break; + case 'm': + mtu = atoi (optarg); + break; + case 'R': + redundancy = atoi (optarg); + break; + case 'e': + dont_htonl_floats = 1; + break; + case 'N': + free(client_name); + client_name = (char *) malloc (sizeof (char) * strlen (optarg)+1); + strcpy (client_name, optarg); + break; + case 's': + server_name = (char *) malloc (sizeof (char) * strlen (optarg)+1); + strcpy (server_name, optarg); + options |= JackServerName; + break; + case ':': + fprintf (stderr, "Option -%c requires an operand\n", optopt); + errflg++; + break; + case '?': + fprintf (stderr, "Unrecognized option: -%c\n", optopt); + errflg++; + } + } + if (errflg) + { + printUsage (); + exit (2); + } + + capture_channels = capture_channels_audio + capture_channels_midi; + playback_channels = playback_channels_audio + playback_channels_midi; + + outsockfd = socket (AF_INET, SOCK_DGRAM, 0); + insockfd = socket (AF_INET, SOCK_DGRAM, 0); + + if( (outsockfd == -1) || (insockfd == -1) ) { + fprintf (stderr, "cant open sockets\n" ); + return 1; + } + + init_sockaddr_in ((struct sockaddr_in *) &destaddr, peer_ip, peer_port); + if(bind_port) { + init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, bind_port); + if( bind (outsockfd, &bindaddr, sizeof (bindaddr)) ) { + fprintf (stderr, "bind failure\n" ); + } + } + if(reply_port) + { + init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port); + if( bind (insockfd, &bindaddr, sizeof (bindaddr)) ) { + fprintf (stderr, "bind failure\n" ); + } + } + + /* try to become a client of the JACK server */ + client = jack_client_open (client_name, options, &status, server_name); + if (client == NULL) + { + fprintf (stderr, "jack_client_open() failed, status = 0x%2.0x\n" + "Is the JACK server running ?\n", status); + return 1; + } + + /* Set up jack callbacks */ + jack_set_process_callback (client, process, 0); + jack_set_sync_callback (client, sync_cb, 0); + jack_set_freewheel_callback (client, freewheel_cb, 0); + jack_on_shutdown (client, jack_shutdown, 0); + + alloc_ports (capture_channels_audio, playback_channels_audio, capture_channels_midi, playback_channels_midi); + + if( bitdepth == 1000 ) + net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8)&(~1) ; + else + net_period = ceilf((float) jack_get_buffer_size (client) / (float) factor); + + int rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header); + global_packcache = packet_cache_new (latency + 50, rx_bufsize, mtu); + + /* tell the JACK server that we are ready to roll */ + if (jack_activate (client)) + { + fprintf (stderr, "Cannot activate client"); + return 1; + } + + /* Now sleep forever... and evaluate the state_ vars */ + + signal( SIGTERM, sigterm_handler ); + signal( SIGINT, sigterm_handler ); + + statecopy_connected = 2; // make it report unconnected on start. + statecopy_latency = state_latency; + statecopy_netxruns = state_netxruns; + + while ( !quit ) + { +#ifdef WIN32 + Sleep (1000); +#else + sleep(1); +#endif + if (statecopy_connected != state_connected) + { + statecopy_connected = state_connected; + if (statecopy_connected) + { + state_netxruns = 1; // We want to reset the netxrun count on each new connection + printf ("Connected :-)\n"); + } + else + printf ("Not Connected\n"); + + fflush(stdout); + } + + if (statecopy_connected) + { + if (statecopy_netxruns != state_netxruns) { + statecopy_netxruns = state_netxruns; + printf ("%s: at frame %06d -> total netxruns %d (%d%%) queue time= %d\n", + client_name, + state_currentframe, + statecopy_netxruns, + 100*statecopy_netxruns/state_currentframe, + state_recv_packet_queue_time); + + fflush(stdout); + } + } + else + { + if (statecopy_latency != state_latency) + { + statecopy_latency = state_latency; + if (statecopy_latency > 1) + printf ("current latency %d\n", statecopy_latency); + fflush(stdout); + } + } + } + + jack_client_close (client); + packet_cache_free (global_packcache); + exit (0); +} diff --git a/example-clients/samplerate.c b/example-clients/samplerate.c new file mode 100644 index 00000000..e8b77ecd --- /dev/null +++ b/example-clients/samplerate.c @@ -0,0 +1,85 @@ +/* + * smaplerate.c -- get current samplerate + * + * Copyright (C) 2003 Jack O'Quin. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +char *package; /* program name */ +jack_client_t *client; + +void jack_shutdown(void *arg) +{ + fprintf(stderr, "JACK shut down, exiting ...\n"); + exit(1); +} + +void signal_handler(int sig) +{ + jack_client_close(client); + fprintf(stderr, "signal received, exiting ...\n"); + exit(0); +} + +void parse_arguments(int argc, char *argv[]) +{ + + /* basename $0 */ + package = strrchr(argv[0], '/'); + if (package == 0) + package = argv[0]; + else + package++; + + if (argc==1) { + return; + } + fprintf(stderr, "usage: %s [bufsize]\n", package); + exit(9); +} + +int main(int argc, char *argv[]) +{ + parse_arguments(argc, argv); + + /* become a JACK client */ + if ((client = jack_client_open(package, JackNullOption, NULL)) == 0) { + fprintf(stderr, "JACK server not running?\n"); + exit(1); + } + + signal(SIGQUIT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGHUP, signal_handler); + signal(SIGINT, signal_handler); + + jack_on_shutdown(client, jack_shutdown, 0); + + fprintf(stdout, "%d\n", jack_get_sample_rate( client ) ); + + jack_client_close(client); + + return 0; +} diff --git a/example-clients/wait.c b/example-clients/wait.c new file mode 100644 index 00000000..81870321 --- /dev/null +++ b/example-clients/wait.c @@ -0,0 +1,136 @@ +#include +#include +#include +#include +#include + +#include + +#include + +char * my_name; + +void +show_usage (void) +{ + fprintf (stderr, "\nUsage: %s [options]\n", my_name); + fprintf (stderr, "Check for jack existence, or wait, until it either quits, or gets started\n"); + fprintf (stderr, "options:\n"); + fprintf (stderr, " -s, --server Connect to the jack server named \n"); + fprintf (stderr, " -w, --wait Wait for server to become available\n"); + fprintf (stderr, " -q, --quit Wait until server is quit\n"); + fprintf (stderr, " -c, --check Check wether server is running\n"); + fprintf (stderr, " -t, --timeout Wait timeout in seconds\n"); + fprintf (stderr, " -h, --help Display this help message\n"); + fprintf (stderr, "For more information see http://jackaudio.org/\n"); +} + +int +main (int argc, char *argv[]) +{ + jack_client_t *client; + jack_status_t status; + jack_options_t options = JackNoStartServer; + int c; + int option_index; + char *server_name = NULL; + int wait_for_start = 0; + int wait_for_quit = 0; + int just_check = 0; + int wait_timeout = 0; + time_t start_timestamp; + + + struct option long_options[] = { + { "server", 1, 0, 's' }, + { "wait", 0, 0, 'w' }, + { "quit", 0, 0, 'q' }, + { "check", 0, 0, 'c' }, + { "timeout", 1, 0, 't' }, + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } + }; + + my_name = strrchr(argv[0], '/'); + if (my_name == 0) { + my_name = argv[0]; + } else { + my_name ++; + } + + while ((c = getopt_long (argc, argv, "s:wqct:hv", long_options, &option_index)) >= 0) { + switch (c) { + case 's': + server_name = (char *) malloc (sizeof (char) * strlen(optarg)); + strcpy (server_name, optarg); + options |= JackServerName; + break; + case 'w': + wait_for_start = 1; + break; + case 'q': + wait_for_quit = 1; + break; + case 'c': + just_check = 1; + break; + case 't': + wait_timeout = atoi(optarg); + break; + case 'h': + show_usage (); + return 1; + break; + default: + show_usage (); + return 1; + break; + } + } + + /* try to open server in a loop. breaking under certein conditions */ + + start_timestamp = time( NULL ); + + while(1) { + client = jack_client_open ("wait", options, &status, server_name); + /* check for some real error and bail out */ + if( (client == NULL) && !(status & JackServerFailed) ) { + fprintf (stderr, "jack_client_open() failed, " + "status = 0x%2.0x\n", status); + return 1; + } + + if( client == NULL ) { + if( wait_for_quit ) { + fprintf( stdout, "server is gone\n" ); + break; + } + if( just_check ) { + fprintf( stdout, "not running\n" ); + break; + } + } else { + jack_client_close( client ); + if( wait_for_start ) { + fprintf( stdout, "server is available\n" ); + break; + } + if( just_check ) { + fprintf( stdout, "running\n" ); + break; + } + } + if( wait_timeout ) { + if( (time( NULL ) - start_timestamp) > wait_timeout ) { + fprintf( stdout, "timeout\n" ); + break; + } + } + + // Wait a second, and repeat + sleep(1); + } + + exit (0); +} diff --git a/example-clients/wscript b/example-clients/wscript index c8310d41..152c737d 100644 --- a/example-clients/wscript +++ b/example-clients/wscript @@ -16,6 +16,8 @@ example_programs = { 'jack_showtime' : 'showtime.c', 'jack_alias' : 'alias.c', 'jack_bufsize' : 'bufsize.c', + 'jack_wait' : 'wait.c', + 'jack_samplerate' : 'samplerate.c', 'jack_evmon' : 'evmon.c', 'jack_monitor_client' : 'monitor_client.c', 'jack_thru' : 'thru_client.c', @@ -32,9 +34,16 @@ example_libs = { def configure(conf): e = conf.check_cc(header_name='sndfile.h', define_name="HAVE_SNDFILE") + conf.check_cc(header_name='samplerate.h', define_name="HAVE_SAMPLERATE") + + if conf.is_defined('HAVE_SAMPLERATE'): + conf.env['LIB_SAMPLERATE'] = ['samplerate'] + if conf.is_defined('HAVE_SNDFILE'): conf.env['LIB_SNDFILE'] = ['sndfile'] + conf.check_cfg(package='celt', atleast_version='0.5.0', args='--cflags --libs') + e = conf.check_cc(header_name='ncurses.h', define_name="HAVE_NCURSES") if conf.is_defined('HAVE_NCURSES'): @@ -49,6 +58,8 @@ def configure(conf): conf.env['BUILD_EXAMPLE_CLIENT_REC'] = conf.is_defined('HAVE_SNDFILE') + conf.env['BUILD_EXAMPLE_ALSA_IO'] = conf.is_defined('HAVE_SAMPLERATE') + def build(bld): if bld.env['IS_LINUX']: os_incdir = ['../linux', '../posix'] @@ -80,8 +91,7 @@ def build(bld): prog.target = example_program - #if bld.env['BUILD_EXAMPLE_CLIENT_TRANSPORT'] - if bld.env['BUILD_EXAMPLE_CLIENT_TRANSPORT'] == True: + if bld.env['BUILD_EXAMPLE_CLIENT_TRANSPORT']: prog = bld.new_task_gen('cc', 'program') prog.includes = os_incdir + ['../common/jack', '../common'] prog.source = 'transport.c' @@ -96,7 +106,7 @@ def build(bld): prog.uselib_local = 'clientlib' prog.target = 'jack_transport' - if bld.env['BUILD_EXAMPLE_CLIENT_REC'] == True: + if bld.env['BUILD_EXAMPLE_CLIENT_REC']: prog = bld.new_task_gen('cc', 'program') prog.includes = os_incdir + ['../common/jack', '../common'] prog.source = 'capture_client.c' @@ -112,6 +122,38 @@ def build(bld): prog.uselib_local = 'clientlib' prog.target = 'jack_rec' + if bld.env['IS_LINUX'] or bld.env['IS_MACOSX']: + prog = bld.new_task_gen('cc', 'program') + prog.includes = os_incdir + ['../common/jack', '../common'] + prog.source = ['netsource.c', '../common/netjack_packet.c'] + prog.env.append_value("CCFLAGS", "-DNO_JACK_ERROR") + # Seems uneeded here... + #if bld.env['HAVE_CELT']: + #if bld.env['HAVE_CELT_API_0_5']: + # prog.defines = ['HAVE_CELT', 'HAVE_CELT_API_0_5'] + #elif bld.env['HAVE_CELT_API_0_7']: + # prog.defines = ['HAVE_CELT', 'HAVE_CELT_API_0_7'] + prog.uselib = 'CELT SAMPLERATE' + prog.uselib_local = 'clientlib' + prog.target = 'jack_netsource' + + if bld.env['IS_LINUX'] and bld.env['BUILD_EXAMPLE_ALSA_IO']: + prog = bld.new_task_gen('cc', 'program') + prog.includes = os_incdir + ['../common/jack', '../common'] + prog.source = ['alsa_in.c', '../common/memops.c'] + prog.env.append_value("CCFLAGS", "-DNO_JACK_ERROR") + prog.uselib = 'ALSA SAMPLERATE' + prog.uselib_local = 'clientlib' + prog.target = 'alsa_in' + + prog = bld.new_task_gen('cc', 'program') + prog.includes = os_incdir + ['../common/jack', '../common'] + prog.source = ['alsa_out.c', '../common/memops.c'] + prog.env.append_value("CCFLAGS", "-DNO_JACK_ERROR") + prog.uselib = 'ALSA SAMPLERATE' + prog.uselib_local = 'clientlib' + prog.target = 'alsa_out' + for example_lib, example_lib_source in example_libs.items(): lib = bld.new_task_gen('cc', 'shlib') lib.env['shlib_PATTERN'] = '%s.so' diff --git a/example-clients/zombie.c b/example-clients/zombie.c index 0d3943c4..a3a2dadd 100644 --- a/example-clients/zombie.c +++ b/example-clients/zombie.c @@ -52,9 +52,8 @@ int main (int argc, char *argv[]) { jack_client_t* client = NULL; - /* try to become a client of the JACK server */ - if ((client = jack_client_new ("zombie")) == 0) { + if ((client = jack_client_open ("zombie", JackNullOption, NULL)) == 0) { fprintf (stderr, "jack server not running?\n"); goto error; } diff --git a/linux/wscript b/linux/wscript index 8e12b8ad..56a77330 100644 --- a/linux/wscript +++ b/linux/wscript @@ -11,11 +11,14 @@ def configure(conf): conf. check_cfg(package='libffado', atleast_version='1.999.17', args='--cflags --libs') conf.env['BUILD_DRIVER_FFADO'] = conf.is_defined('HAVE_LIBFFADO') + conf.define('HAVE_PPOLL', 1 ) + + def create_jack_driver_obj(bld, target, sources, uselib = None): driver = bld.new_task_gen('cxx', 'shlib') driver.features.append('cc') driver.env['shlib_PATTERN'] = 'jack_%s.so' - driver.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] + driver.defines = ['HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL'] driver.includes = ['.', '../linux', '../posix', '../common', '../common/jack', '../dbus'] driver.target = target driver.source = sources @@ -64,3 +67,8 @@ def build(bld): create_jack_driver_obj(bld, 'net', '../common/JackNetDriver.cpp') create_jack_driver_obj(bld, 'loopback', '../common/JackLoopbackDriver.cpp') + + create_jack_driver_obj(bld, 'netone', [ '../common/JackNetOneDriver.cpp', + '../common/netjack.c', + '../common/netjack_packet.c' ], "SAMPLERATE CELT" ) + diff --git a/macosx/JackMachServerChannel.cpp b/macosx/JackMachServerChannel.cpp index 5b646c56..19295f79 100644 --- a/macosx/JackMachServerChannel.cpp +++ b/macosx/JackMachServerChannel.cpp @@ -143,10 +143,6 @@ boolean_t JackMachServerChannel::MessageHandler(mach_msg_header_t* Request, mach channel->ClientKill(Request->msgh_local_port); } else { JackRPCEngine_server(Request, Reply); - // Issued by JackEngine::ReleaseRefnum when temporary mode is used - if (JackServerGlobals::fKilled) { - kill(JackTools::GetPID(), SIGINT); - } } return true; } diff --git a/macosx/JackMachServerNotifyChannel.cpp b/macosx/JackMachServerNotifyChannel.cpp index ab686c57..2e1c9abe 100644 --- a/macosx/JackMachServerNotifyChannel.cpp +++ b/macosx/JackMachServerNotifyChannel.cpp @@ -50,7 +50,7 @@ void JackMachServerNotifyChannel::Notify(int refnum, int notify, int value) { kern_return_t res = rpc_jack_client_rt_notify(fClientPort.GetPort(), refnum, notify, value, 0); if (res != KERN_SUCCESS) { - jack_error("Could not write request ref = %ld notify = %ld err = %s", refnum, notify, mach_error_string(res)); + jack_error("Could not write request ref = %d notify = %d err = %s", refnum, notify, mach_error_string(res)); } } diff --git a/macosx/JackMachThread.cpp b/macosx/JackMachThread.cpp index fa836fb4..9692bdb9 100644 --- a/macosx/JackMachThread.cpp +++ b/macosx/JackMachThread.cpp @@ -160,9 +160,11 @@ int JackMachThread::Kill() // pthread_cancel still not yet implemented in Darwin (TO CHECK ON TIGER) jack_log("JackMachThread::Kill"); - if (fThread) { // If thread has been started + if (fThread != (pthread_t)NULL) { // If thread has been started mach_port_t machThread = pthread_mach_thread_np(fThread); - return (thread_terminate(machThread) == KERN_SUCCESS) ? 0 : -1; + int res = (thread_terminate(machThread) == KERN_SUCCESS) ? 0 : -1; + fThread = (pthread_t)NULL; + return res; } else { return -1; } @@ -172,7 +174,14 @@ int JackMachThread::AcquireRealTime() { jack_log("JackMachThread::AcquireRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld", long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000)); - return (fThread) ? AcquireRealTimeImp(fThread, fPeriod, fComputation, fConstraint) : -1; + return (fThread != (pthread_t)NULL) ? AcquireRealTimeImp(fThread, fPeriod, fComputation, fConstraint) : -1; +} + +int JackMachThread::AcquireSelfRealTime() +{ + jack_log("JackMachThread::AcquireRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld", + long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000)); + return AcquireRealTimeImp(pthread_self(), fPeriod, fComputation, fConstraint); } int JackMachThread::AcquireRealTime(int priority) @@ -181,19 +190,26 @@ int JackMachThread::AcquireRealTime(int priority) return AcquireRealTime(); } +int JackMachThread::AcquireSelfRealTime(int priority) +{ + fPriority = priority; + return AcquireSelfRealTime(); +} + int JackMachThread::AcquireRealTimeImp(pthread_t thread, UInt64 period, UInt64 computation, UInt64 constraint) { SetThreadToPriority(thread, 96, true, period, computation, constraint); - UInt64 int_period; - UInt64 int_computation; - UInt64 int_constraint; - GetParams(thread, &int_period, &int_computation, &int_constraint); return 0; } int JackMachThread::DropRealTime() { - return (fThread) ? DropRealTimeImp(fThread) : -1; + return (fThread != (pthread_t)NULL) ? DropRealTimeImp(fThread) : -1; +} + +int JackMachThread::DropSelfRealTime() +{ + return DropRealTimeImp(pthread_self()); } int JackMachThread::DropRealTimeImp(pthread_t thread) diff --git a/macosx/JackMachThread.h b/macosx/JackMachThread.h index e8105803..f7c038c0 100644 --- a/macosx/JackMachThread.h +++ b/macosx/JackMachThread.h @@ -105,9 +105,15 @@ class SERVER_EXPORT JackMachThread : public JackPosixThread int Kill(); - int AcquireRealTime(); - int AcquireRealTime(int priority); - int DropRealTime(); + int AcquireRealTime(); // Used when called from another thread + int AcquireSelfRealTime(); // Used when called from thread itself + + int AcquireRealTime(int priority); // Used when called from another thread + int AcquireSelfRealTime(int priority); // Used when called from thread itself + + int DropRealTime(); // Used when called from another thread + int DropSelfRealTime(); // Used when called from thread itself + void SetParams(UInt64 period, UInt64 computation, UInt64 constraint); static int GetParams(pthread_t thread, UInt64* period, UInt64* computation, UInt64* constraint); static int SetThreadToPriority(pthread_t thread, UInt32 inPriority, Boolean inIsFixed, UInt64 period, UInt64 computation, UInt64 constraint); diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index 4d5d42c8..c8aae4f5 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -21,6 +21,8 @@ 4B35C6B20D4733B9000DE7AE /* PBXTargetDependency */, 4BDCDC2C1002036100B15929 /* PBXTargetDependency */, 4BDCDC2E1002036100B15929 /* PBXTargetDependency */, + 4B32259110A31ABA00838A8E /* PBXTargetDependency */, + 4B43A8E91014618D00E52943 /* PBXTargetDependency */, 4BDCDC301002036100B15929 /* PBXTargetDependency */, 4BDCDC39100203D500B15929 /* PBXTargetDependency */, 4BDCDC3B100203D500B15929 /* PBXTargetDependency */, @@ -44,7 +46,7 @@ 4BFA83380DF6AB540087B4E1 /* PBXTargetDependency */, 4BFA833A0DF6AB540087B4E1 /* PBXTargetDependency */, 4BFA833C0DF6AB540087B4E1 /* PBXTargetDependency */, - 4B43A8E91014618D00E52943 /* PBXTargetDependency */, + 4B32258F10A31AB400838A8E /* PBXTargetDependency */, ); name = "All Universal 32/64 bits"; productName = All; @@ -62,6 +64,7 @@ 4BF339280F8B87800080FB5B /* PBXTargetDependency */, 4B699DBC097D421700A18468 /* PBXTargetDependency */, BA222AF20DC883F3001A17F4 /* PBXTargetDependency */, + 4B32258D10A31A9D00838A8E /* PBXTargetDependency */, 4B43A8CD1014607100E52943 /* PBXTargetDependency */, 4BD624D30CBCF55700DE782F /* PBXTargetDependency */, BA222AF00DC883EF001A17F4 /* PBXTargetDependency */, @@ -89,6 +92,7 @@ 4B363F250DEB0ABE001F72D9 /* PBXTargetDependency */, 4B363F530DEB0CFE001F72D9 /* PBXTargetDependency */, 4B363F780DEB0D85001F72D9 /* PBXTargetDependency */, + 4B32258B10A31A9000838A8E /* PBXTargetDependency */, ); name = "All Universal 32 bits"; productName = All; @@ -106,6 +110,28 @@ 4B19B31B0E2362E800DD4A82 /* JackLibSampleRateResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B30E0E2362E700DD4A82 /* JackLibSampleRateResampler.cpp */; }; 4B19B31C0E2362E800DD4A82 /* JackLibSampleRateResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */; }; 4B19B31F0E2362E800DD4A82 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */; }; + 4B3224EA10A315B100838A8E /* JackNetOneDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224E810A315B100838A8E /* JackNetOneDriver.cpp */; }; + 4B3224EB10A315B100838A8E /* JackNetOneDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224E910A315B100838A8E /* JackNetOneDriver.h */; }; + 4B3224F010A315C400838A8E /* netjack_packet.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EC10A315C400838A8E /* netjack_packet.c */; }; + 4B3224F110A315C400838A8E /* netjack_packet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224ED10A315C400838A8E /* netjack_packet.h */; }; + 4B3224F210A315C400838A8E /* netjack.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EE10A315C400838A8E /* netjack.c */; }; + 4B3224F310A315C400838A8E /* netjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224EF10A315C400838A8E /* netjack.h */; }; + 4B32253110A3173900838A8E /* JackNetOneDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224E810A315B100838A8E /* JackNetOneDriver.cpp */; }; + 4B32253210A3173A00838A8E /* JackNetOneDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224E910A315B100838A8E /* JackNetOneDriver.h */; }; + 4B32253310A3173B00838A8E /* netjack.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EE10A315C400838A8E /* netjack.c */; }; + 4B32253410A3173C00838A8E /* netjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224EF10A315C400838A8E /* netjack.h */; }; + 4B32253510A3173D00838A8E /* netjack_packet.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EC10A315C400838A8E /* netjack_packet.c */; }; + 4B32253610A3173E00838A8E /* netjack_packet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224ED10A315C400838A8E /* netjack_packet.h */; }; + 4B32256410A318E300838A8E /* netsource.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B32256310A318E300838A8E /* netsource.c */; }; + 4B32256B10A318FA00838A8E /* netjack.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EE10A315C400838A8E /* netjack.c */; }; + 4B32256C10A318FB00838A8E /* netjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224EF10A315C400838A8E /* netjack.h */; }; + 4B32256D10A318FC00838A8E /* netjack_packet.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EC10A315C400838A8E /* netjack_packet.c */; }; + 4B32256E10A318FD00838A8E /* netjack_packet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224ED10A315C400838A8E /* netjack_packet.h */; }; + 4B32257D10A3195700838A8E /* netjack.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EE10A315C400838A8E /* netjack.c */; }; + 4B32257E10A3195800838A8E /* netjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224EF10A315C400838A8E /* netjack.h */; }; + 4B32257F10A3195900838A8E /* netjack_packet.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EC10A315C400838A8E /* netjack_packet.c */; }; + 4B32258010A3195A00838A8E /* netjack_packet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224ED10A315C400838A8E /* netjack_packet.h */; }; + 4B32258110A3195B00838A8E /* netsource.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B32256310A318E300838A8E /* netsource.c */; }; 4B35C41E0D4731D1000DE7AE /* Jackdmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2250834F06A00C94B91 /* Jackdmp.cpp */; }; 4B35C4290D4731D1000DE7AE /* JackMachPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B799AD707899652003F3F15 /* JackMachPort.h */; }; 4B35C42A0D4731D1000DE7AE /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; }; @@ -484,6 +510,8 @@ 4B93F19E0E87998400E4ECCD /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; 4B93F1C00E87A35400E4ECCD /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; 4B93F22B0E87A72500E4ECCD /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; + 4B94334A10A5E666002A187F /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B94334B10A5E666002A187F /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B95BCAE0D913073000F7695 /* control.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B95BCAD0D913073000F7695 /* control.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B9A25B50DBF8330006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; 4B9A25B60DBF8330006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; @@ -495,15 +523,126 @@ 4B9A26610DBF8ADD006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; 4B9A26640DBF8B14006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; 4B9A26790DBF8B88006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; + 4BA3393510B2E36800190E3B /* JackMachPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B799AD707899652003F3F15 /* JackMachPort.h */; }; + 4BA3393610B2E36800190E3B /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; }; + 4BA3393710B2E36800190E3B /* JackTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1830834EE5800C94B91 /* JackTime.h */; }; + 4BA3393810B2E36800190E3B /* JackShmMem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1870834EE7900C94B91 /* JackShmMem.h */; }; + 4BA3393910B2E36800190E3B /* shm.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D18F0834EE8400C94B91 /* shm.h */; }; + 4BA3393A10B2E36800190E3B /* JackThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D19F0834EE9E00C94B91 /* JackThread.h */; }; + 4BA3393B10B2E36800190E3B /* JackActivationCount.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1A70834EEB400C94B91 /* JackActivationCount.h */; }; + 4BA3393C10B2E36800190E3B /* JackChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1AF0834EEC400C94B91 /* JackChannel.h */; }; + 4BA3393D10B2E36800190E3B /* JackGraphManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C70834EF2200C94B91 /* JackGraphManager.h */; }; + 4BA3393E10B2E36800190E3B /* JackPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1CF0834EF2F00C94B91 /* JackPort.h */; }; + 4BA3393F10B2E36800190E3B /* JackClientInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1D90834EF4500C94B91 /* JackClientInterface.h */; }; + 4BA3394010B2E36800190E3B /* JackClientControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1DD0834EF4D00C94B91 /* JackClientControl.h */; }; + 4BA3394110B2E36800190E3B /* JackClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1E10834EF5500C94B91 /* JackClient.h */; }; + 4BA3394210B2E36800190E3B /* JackInternalClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1EE0834EF9200C94B91 /* JackInternalClient.h */; }; + 4BA3394310B2E36800190E3B /* JackConnectionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C30834EF1400C94B91 /* JackConnectionManager.h */; }; + 4BA3394410B2E36800190E3B /* JackFrameTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */; }; + 4BA3394510B2E36800190E3B /* JackMachSemaphore.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF6C1D608ACE64C001E2013 /* JackMachSemaphore.h */; }; + 4BA3394610B2E36800190E3B /* JackGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB73F608AD291A00DB99B8 /* JackGlobals.h */; }; + 4BA3394710B2E36800190E3B /* JackMachThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB741F08AD2B9900DB99B8 /* JackMachThread.h */; }; + 4BA3394810B2E36800190E3B /* JackSynchro.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD561C708EEB910006BBC2A /* JackSynchro.h */; }; + 4BA3394910B2E36800190E3B /* JackAudioDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2290834F07D00C94B91 /* JackAudioDriver.h */; }; + 4BA3394A10B2E36800190E3B /* JackFreewheelDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1B90834EEF100C94B91 /* JackFreewheelDriver.h */; }; + 4BA3394B10B2E36800190E3B /* JackThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1BD0834EEFC00C94B91 /* JackThreadedDriver.h */; }; + 4BA3394C10B2E36800190E3B /* JackDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1B50834EEE400C94B91 /* JackDriver.h */; }; + 4BA3394D10B2E36800190E3B /* driver_interface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B869B3D08C8D21C001CF041 /* driver_interface.h */; }; + 4BA3394E10B2E36800190E3B /* JackDriverLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B869B4208C8D22F001CF041 /* JackDriverLoader.h */; }; + 4BA3394F10B2E36800190E3B /* JackEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2130834F02800C94B91 /* JackEngine.h */; }; + 4BA3395010B2E36800190E3B /* JackExternalClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1F70834EFBD00C94B91 /* JackExternalClient.h */; }; + 4BA3395110B2E36800190E3B /* JackServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2220834F05C00C94B91 /* JackServer.h */; }; + 4BA3395210B2E36800190E3B /* JackMachNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB298908AF450200D450D4 /* JackMachNotifyChannel.h */; }; + 4BA3395310B2E36800190E3B /* JackMachServerChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB297808AF44ED00D450D4 /* JackMachServerChannel.h */; }; + 4BA3395410B2E36800190E3B /* JackMachServerNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB297A08AF44ED00D450D4 /* JackMachServerNotifyChannel.h */; }; + 4BA3395510B2E36800190E3B /* JackConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66A8580934964500A89560 /* JackConstants.h */; }; + 4BA3395610B2E36800190E3B /* JackTransportEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */; }; + 4BA3395710B2E36800190E3B /* JackServerGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC2168D0A444BED00BDA09F /* JackServerGlobals.h */; }; + 4BA3395810B2E36800190E3B /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3395910B2E36800190E3B /* jack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737A0CC60A6D001AFFD4 /* jack.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3395A10B2E36800190E3B /* intclient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C73790CC60A6D001AFFD4 /* intclient.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3395B10B2E36800190E3B /* ringbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737B0CC60A6D001AFFD4 /* ringbuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3395C10B2E36800190E3B /* statistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737C0CC60A6D001AFFD4 /* statistics.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3395D10B2E36800190E3B /* thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737D0CC60A6D001AFFD4 /* thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3395E10B2E36800190E3B /* transport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737E0CC60A6D001AFFD4 /* transport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3395F10B2E36800190E3B /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737F0CC60A6D001AFFD4 /* types.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3396010B2E36800190E3B /* JackPortType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAB95B70B9E20B800A0C723 /* JackPortType.h */; }; + 4BA3396110B2E36800190E3B /* JackMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */; }; + 4BA3396210B2E36800190E3B /* midiport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6B9EF50CD0958B0051EE5A /* midiport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3396310B2E36800190E3B /* JackDebugClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B98AE010931D30C0091932A /* JackDebugClient.h */; }; + 4BA3396410B2E36800190E3B /* JackTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE4CC000CDA153400CCF5BB /* JackTools.h */; }; + 4BA3396510B2E36800190E3B /* JackNetTool.h in Headers */ = {isa = PBXBuildFile; fileRef = BA222AD70DC88268001A17F4 /* JackNetTool.h */; }; + 4BA3396610B2E36800190E3B /* jslist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B9A26000DBF8584006E9FBC /* jslist.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3396710B2E36800190E3B /* JackMessageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4F9C8B0DC20C0400706CB0 /* JackMessageBuffer.h */; }; + 4BA3396810B2E36800190E3B /* JackRestartThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4CA9730E02CF9600F4BFDA /* JackRestartThreadedDriver.h */; }; + 4BA3396910B2E36800190E3B /* JackControlAPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4E9AF90E5F1090000A3278 /* JackControlAPI.h */; }; + 4BA3396A10B2E36800190E3B /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; + 4BA3396B10B2E36800190E3B /* JackEngineProfiling.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BBAE40E0F42FA6100B8BD3F /* JackEngineProfiling.h */; }; + 4BA3396C10B2E36800190E3B /* JackProcessSync.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BECB2F40F4451C10091B70A /* JackProcessSync.h */; }; + 4BA3396D10B2E36800190E3B /* JackMidiDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF339200F8B873E0080FB5B /* JackMidiDriver.h */; }; + 4BA3396E10B2E36800190E3B /* JackWaitThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BBC93B90DF9736C002DF220 /* JackWaitThreadedDriver.h */; }; + 4BA3396F10B2E36800190E3B /* JackArgParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF284170F31B4BC00B05BE3 /* JackArgParser.h */; }; + 4BA3397210B2E36800190E3B /* JackMachPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B799AD607899652003F3F15 /* JackMachPort.cpp */; }; + 4BA3397310B2E36800190E3B /* JackShmMem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1880834EE7900C94B91 /* JackShmMem.cpp */; }; + 4BA3397410B2E36800190E3B /* shm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1900834EE8400C94B91 /* shm.c */; }; + 4BA3397510B2E36800190E3B /* JackActivationCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1A80834EEB400C94B91 /* JackActivationCount.cpp */; }; + 4BA3397610B2E36800190E3B /* JackGraphManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C80834EF2200C94B91 /* JackGraphManager.cpp */; }; + 4BA3397710B2E36800190E3B /* JackPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1D00834EF2F00C94B91 /* JackPort.cpp */; }; + 4BA3397810B2E36800190E3B /* JackClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E50834EF6700C94B91 /* JackClient.cpp */; }; + 4BA3397910B2E36800190E3B /* JackAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E90834EF7500C94B91 /* JackAPI.cpp */; }; + 4BA3397A10B2E36800190E3B /* JackConnectionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C40834EF1400C94B91 /* JackConnectionManager.cpp */; }; + 4BA3397B10B2E36800190E3B /* JackFrameTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */; }; + 4BA3397C10B2E36800190E3B /* JackMachSemaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF6C1D508ACE64C001E2013 /* JackMachSemaphore.cpp */; }; + 4BA3397D10B2E36800190E3B /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB741E08AD2B9900DB99B8 /* JackMachThread.cpp */; }; + 4BA3397E10B2E36800190E3B /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */; }; + 4BA3397F10B2E36800190E3B /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B003AB008E2B2BA0060EFDC /* ringbuffer.c */; }; + 4BA3398010B2E36800190E3B /* JackAudioDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D22A0834F07D00C94B91 /* JackAudioDriver.cpp */; }; + 4BA3398110B2E36800190E3B /* JackFreewheelDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1BA0834EEF100C94B91 /* JackFreewheelDriver.cpp */; }; + 4BA3398210B2E36800190E3B /* JackThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1BE0834EEFC00C94B91 /* JackThreadedDriver.cpp */; }; + 4BA3398310B2E36800190E3B /* JackDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1B60834EEE400C94B91 /* JackDriver.cpp */; }; + 4BA3398410B2E36800190E3B /* JackDriverLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B869D7F08C9CB00001CF041 /* JackDriverLoader.cpp */; }; + 4BA3398510B2E36800190E3B /* JackEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2140834F02800C94B91 /* JackEngine.cpp */; }; + 4BA3398610B2E36800190E3B /* JackExternalClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1F80834EFBD00C94B91 /* JackExternalClient.cpp */; }; + 4BA3398710B2E36800190E3B /* JackInternalClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1ED0834EF9200C94B91 /* JackInternalClient.cpp */; }; + 4BA3398810B2E36800190E3B /* JackRPCClientUser.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B89B759076B731100D170DE /* JackRPCClientUser.c */; }; + 4BA3398910B2E36800190E3B /* JackServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2210834F05C00C94B91 /* JackServer.cpp */; }; + 4BA3398A10B2E36800190E3B /* JackMacEngineRPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4259E5076B635E00C1ECE1 /* JackMacEngineRPC.cpp */; }; + 4BA3398B10B2E36800190E3B /* JackMachNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB298808AF450200D450D4 /* JackMachNotifyChannel.cpp */; }; + 4BA3398C10B2E36800190E3B /* JackMachServerChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB297908AF44ED00D450D4 /* JackMachServerChannel.cpp */; }; + 4BA3398D10B2E36800190E3B /* JackMachServerNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB297708AF44ED00D450D4 /* JackMachServerNotifyChannel.cpp */; }; + 4BA3398E10B2E36800190E3B /* JackTransportEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */; }; + 4BA3398F10B2E36800190E3B /* JackServerAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1F50834EFB000C94B91 /* JackServerAPI.cpp */; }; + 4BA3399010B2E36800190E3B /* JackServerGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC216880A444BDE00BDA09F /* JackServerGlobals.cpp */; }; + 4BA3399110B2E36800190E3B /* timestamps.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF520520CB8D0E80037470E /* timestamps.c */; }; + 4BA3399210B2E36800190E3B /* JackPortType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */; }; + 4BA3399310B2E36800190E3B /* JackAudioPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95EC0B9E21A500A0C723 /* JackAudioPort.cpp */; }; + 4BA3399410B2E36800190E3B /* JackMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */; }; + 4BA3399510B2E36800190E3B /* JackMidiAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */; }; + 4BA3399610B2E36800190E3B /* JackEngineControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6F7AEC0CD0CDBD00F48A9D /* JackEngineControl.cpp */; }; + 4BA3399710B2E36800190E3B /* JackDebugClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B98AE000931D30C0091932A /* JackDebugClient.cpp */; }; + 4BA3399810B2E36800190E3B /* JackTools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4CBFF0CDA153400CCF5BB /* JackTools.cpp */; }; + 4BA3399910B2E36800190E3B /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA222AD60DC88268001A17F4 /* JackNetTool.cpp */; }; + 4BA3399A10B2E36800190E3B /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; + 4BA3399B10B2E36800190E3B /* JackMessageBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4F9C8A0DC20C0400706CB0 /* JackMessageBuffer.cpp */; }; + 4BA3399C10B2E36800190E3B /* JackRestartThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4CA9740E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp */; }; + 4BA3399D10B2E36800190E3B /* JackControlAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4E9AF80E5F1090000A3278 /* JackControlAPI.cpp */; }; + 4BA3399E10B2E36800190E3B /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; + 4BA3399F10B2E36800190E3B /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; + 4BA339A010B2E36800190E3B /* JackEngineProfiling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBAE40F0F42FA6100B8BD3F /* JackEngineProfiling.cpp */; }; + 4BA339A110B2E36800190E3B /* JackProcessSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BECB2F30F4451C10091B70A /* JackProcessSync.cpp */; }; + 4BA339A210B2E36800190E3B /* JackMidiDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF3391F0F8B873E0080FB5B /* JackMidiDriver.cpp */; }; + 4BA339A310B2E36800190E3B /* JackWaitThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBC93B80DF9736C002DF220 /* JackWaitThreadedDriver.cpp */; }; + 4BA339A410B2E36800190E3B /* JackArgParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF284160F31B4BC00B05BE3 /* JackArgParser.cpp */; }; + 4BA339A710B2E36800190E3B /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; 4BA4ADB40E87AB2500F26C85 /* JackCoreAudioDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE5FECB0E725C090020B576 /* JackCoreAudioDriver.cpp */; }; 4BA4ADB50E87AB2600F26C85 /* JackCoreAudioDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE5FECC0E725C090020B576 /* JackCoreAudioDriver.h */; }; 4BA692B30CBE4C2D00EAD520 /* ipload.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA692B20CBE4C2D00EAD520 /* ipload.c */; }; 4BA692D70CBE4CC600EAD520 /* ipunload.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA692D60CBE4CC600EAD520 /* ipunload.c */; }; - 4BA7BE0F0DC232A400AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; }; - 4BA7BE1A0DC2347500AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; }; - 4BA7BE200DC234FB00AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; }; - 4BA7BE240DC2350D00AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; }; - 4BA7BE270DC2352A00AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; }; + 4BA7BE0F0DC232A400AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; + 4BA7BE1A0DC2347500AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; + 4BA7BE200DC234FB00AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; + 4BA7BE240DC2350D00AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; + 4BA7BE270DC2352A00AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; 4BA7FECA0D8E76650017FF73 /* control.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA7FEC80D8E76650017FF73 /* control.c */; }; 4BAB95B80B9E20B800A0C723 /* JackPortType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */; }; 4BAB95B90B9E20B800A0C723 /* JackPortType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAB95B70B9E20B800A0C723 /* JackPortType.h */; }; @@ -622,8 +761,8 @@ 4BF4BAB10E3480AB00403CDF /* JackAudioAdapterFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF4BAB00E3480AB00403CDF /* JackAudioAdapterFactory.cpp */; }; 4BF520530CB8D0E80037470E /* timestamps.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF520520CB8D0E80037470E /* timestamps.c */; }; 4BF520540CB8D0E80037470E /* timestamps.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF520520CB8D0E80037470E /* timestamps.c */; }; - 4BF520590CB8D1010037470E /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4BF5205A0CB8D1010037470E /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BF520590CB8D1010037470E /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (); }; }; + 4BF5205A0CB8D1010037470E /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (); }; }; 4BF5FBBC0E878B9C003D2374 /* JackPosixServerLaunch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBBA0E878B9C003D2374 /* JackPosixServerLaunch.cpp */; }; 4BF5FBC90E878D24003D2374 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; 4BF5FBCA0E878D24003D2374 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; @@ -676,6 +815,41 @@ remoteGlobalIDString = 4B5E08BF0E5B66EE00BEE4E0; remoteInfo = netadapter; }; + 4B3224E610A3157900838A8E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B3224D710A3156800838A8E; + remoteInfo = "jack_netone Universal"; + }; + 4B32258A10A31A9000838A8E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B32255710A3187800838A8E; + remoteInfo = "jack_netsource Universal"; + }; + 4B32258C10A31A9D00838A8E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B3224D710A3156800838A8E; + remoteInfo = "jack_netone Universal"; + }; + 4B32258E10A31AB400838A8E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B32257110A3190C00838A8E; + remoteInfo = "jack_netsource 64 bits"; + }; + 4B32259010A31ABA00838A8E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B32251D10A316B200838A8E; + remoteInfo = "jack_netone 64 bits"; + }; 4B35C5540D4731D2000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; @@ -1179,7 +1353,7 @@ 4B0A28E60D52073D002EFF74 /* jack_thread_wait */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_thread_wait; sourceTree = BUILT_PRODUCTS_DIR; }; 4B0A28EC0D520852002EFF74 /* tw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tw.c; path = "../example-clients/tw.c"; sourceTree = SOURCE_ROOT; }; 4B0A292D0D52108E002EFF74 /* jack_thread_wait */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_thread_wait; sourceTree = BUILT_PRODUCTS_DIR; }; - 4B19B3000E23620F00DD4A82 /* netmanager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netmanager.so; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B19B3000E23620F00DD4A82 /* audioadapter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = audioadapter.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B19B3060E2362E700DD4A82 /* JackAudioAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapter.cpp; path = ../common/JackAudioAdapter.cpp; sourceTree = SOURCE_ROOT; }; 4B19B3070E2362E700DD4A82 /* JackAudioAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioAdapter.h; path = ../common/JackAudioAdapter.h; sourceTree = SOURCE_ROOT; }; 4B19B3080E2362E700DD4A82 /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; }; @@ -1189,9 +1363,20 @@ 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackLibSampleRateResampler.h; path = ../common/JackLibSampleRateResampler.h; sourceTree = SOURCE_ROOT; }; 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackResampler.cpp; path = ../common/JackResampler.cpp; sourceTree = SOURCE_ROOT; }; 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackGlobals.cpp; path = ../common/JackGlobals.cpp; sourceTree = SOURCE_ROOT; }; + 4B3224E510A3156800838A8E /* jack_netone.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_netone.so; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B3224E810A315B100838A8E /* JackNetOneDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetOneDriver.cpp; path = ../common/JackNetOneDriver.cpp; sourceTree = SOURCE_ROOT; }; + 4B3224E910A315B100838A8E /* JackNetOneDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackNetOneDriver.h; path = ../common/JackNetOneDriver.h; sourceTree = SOURCE_ROOT; }; + 4B3224EC10A315C400838A8E /* netjack_packet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = netjack_packet.c; path = ../common/netjack_packet.c; sourceTree = SOURCE_ROOT; }; + 4B3224ED10A315C400838A8E /* netjack_packet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = netjack_packet.h; path = ../common/netjack_packet.h; sourceTree = SOURCE_ROOT; }; + 4B3224EE10A315C400838A8E /* netjack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = netjack.c; path = ../common/netjack.c; sourceTree = SOURCE_ROOT; }; + 4B3224EF10A315C400838A8E /* netjack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = netjack.h; path = ../common/netjack.h; sourceTree = SOURCE_ROOT; }; + 4B32252B10A316B200838A8E /* jack_netone.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_netone.so; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B32256110A3187800838A8E /* jack_netsource */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_netsource; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B32256310A318E300838A8E /* netsource.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = netsource.c; path = "../example-clients/netsource.c"; sourceTree = SOURCE_ROOT; }; + 4B32257B10A3190C00838A8E /* jack_netsource */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_netsource; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C4250D4731D1000DE7AE /* jackdmp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jackdmp; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C4830D4731D1000DE7AE /* Jackmp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackmp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackdmp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackservermp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5140D4731D1000DE7AE /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5200D4731D1000DE7AE /* jack_midisine */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midisine; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C52C0D4731D1000DE7AE /* jack_metro */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_metro; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1215,29 +1400,29 @@ 4B35C6290D4731D2000DE7AE /* jack_portaudio.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_portaudio.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C6340D4731D2000DE7AE /* jack_dummy.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_dummy.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C63E0D4731D3000DE7AE /* inprocess.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = inprocess.so; sourceTree = BUILT_PRODUCTS_DIR; }; - 4B363DD80DEB02F6001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B363DD80DEB02F6001F72D9 /* jack_alias */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_alias; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363DDE0DEB034E001F72D9 /* alias.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = alias.c; path = "../example-clients/alias.c"; sourceTree = SOURCE_ROOT; }; - 4B363E1A0DEB03C5001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B363E1A0DEB03C5001F72D9 /* jack_evmon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_evmon; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363E200DEB0401001F72D9 /* evmon.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = evmon.c; path = "../example-clients/evmon.c"; sourceTree = SOURCE_ROOT; }; - 4B363E4E0DEB0775001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B363E4E0DEB0775001F72D9 /* jack_bufsize */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_bufsize; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363E710DEB0808001F72D9 /* bufsize.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bufsize.c; path = "../example-clients/bufsize.c"; sourceTree = SOURCE_ROOT; }; - 4B363EE90DEB091C001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B363EE90DEB091C001F72D9 /* jack_rec */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_rec; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363EED0DEB094B001F72D9 /* capture_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = capture_client.c; path = "../example-clients/capture_client.c"; sourceTree = SOURCE_ROOT; }; - 4B363F1E0DEB0A6A001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B363F1E0DEB0A6A001F72D9 /* jack_monitor_client */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_monitor_client; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363F220DEB0AB0001F72D9 /* monitor_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = monitor_client.c; path = "../example-clients/monitor_client.c"; sourceTree = SOURCE_ROOT; }; 4B363F350DEB0BD1001F72D9 /* jack_showtime */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_showtime; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363F3D0DEB0C31001F72D9 /* showtime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = showtime.c; path = "../example-clients/showtime.c"; sourceTree = SOURCE_ROOT; }; - 4B363F720DEB0D4E001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_impulse_grabber; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363F750DEB0D7D001F72D9 /* impulse_grabber.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = impulse_grabber.c; path = "../example-clients/impulse_grabber.c"; sourceTree = SOURCE_ROOT; }; 4B37C20306DF1FBE0016E567 /* CALatencyLog.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CALatencyLog.cpp; path = /Developer/Examples/CoreAudio/PublicUtility/CALatencyLog.cpp; sourceTree = ""; }; 4B37C20406DF1FBE0016E567 /* CALatencyLog.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CALatencyLog.h; path = /Developer/Examples/CoreAudio/PublicUtility/CALatencyLog.h; sourceTree = ""; }; 4B37C20906DF1FE20016E567 /* latency.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = latency.c; path = /Developer/Examples/CoreAudio/PublicUtility/latency.c; sourceTree = ""; }; 4B3F49070AD8503300491C6E /* cpu.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpu.c; path = ../tests/cpu.c; sourceTree = SOURCE_ROOT; }; 4B4259E5076B635E00C1ECE1 /* JackMacEngineRPC.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMacEngineRPC.cpp; sourceTree = SOURCE_ROOT; }; - 4B43A8BA10145F6F00E52943 /* jack_dummy.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_dummy.so; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B43A8BA10145F6F00E52943 /* jack_loopback.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_loopback.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B43A8C81014605000E52943 /* JackLoopbackDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackLoopbackDriver.cpp; path = ../common/JackLoopbackDriver.cpp; sourceTree = SOURCE_ROOT; }; 4B43A8C91014605000E52943 /* JackLoopbackDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackLoopbackDriver.h; path = ../common/JackLoopbackDriver.h; sourceTree = SOURCE_ROOT; }; - 4B43A8E71014615800E52943 /* jack_dummy.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_dummy.so; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B43A8E71014615800E52943 /* jack_loopback.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_loopback.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B464301076CAC7700E5077C /* Jack-Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = "Jack-Info.plist"; sourceTree = SOURCE_ROOT; }; 4B4CA9730E02CF9600F4BFDA /* JackRestartThreadedDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackRestartThreadedDriver.h; path = ../common/JackRestartThreadedDriver.h; sourceTree = SOURCE_ROOT; }; 4B4CA9740E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackRestartThreadedDriver.cpp; path = ../common/JackRestartThreadedDriver.cpp; sourceTree = SOURCE_ROOT; }; @@ -1250,7 +1435,7 @@ 4B5A1BBD0CD1CC110005BF74 /* midiseq.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = midiseq.c; path = "../example-clients/midiseq.c"; sourceTree = SOURCE_ROOT; }; 4B5A1BDA0CD1CCE10005BF74 /* jack_midisine */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midisine; sourceTree = BUILT_PRODUCTS_DIR; }; 4B5A1BDC0CD1CD420005BF74 /* midisine.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = midisine.c; path = "../example-clients/midisine.c"; sourceTree = SOURCE_ROOT; }; - 4B5E08D50E5B66EE00BEE4E0 /* netmanager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netmanager.so; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B5E08D50E5B66EE00BEE4E0 /* netadapter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netadapter.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B5E08DF0E5B676C00BEE4E0 /* JackNetAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetAdapter.cpp; path = ../common/JackNetAdapter.cpp; sourceTree = SOURCE_ROOT; }; 4B5E08E00E5B676C00BEE4E0 /* JackNetAdapter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackNetAdapter.h; path = ../common/JackNetAdapter.h; sourceTree = SOURCE_ROOT; }; 4B5F253D0DEE9B8F0041E486 /* JackLockedEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackLockedEngine.h; path = ../common/JackLockedEngine.h; sourceTree = SOURCE_ROOT; }; @@ -1295,19 +1480,22 @@ 4B89B759076B731100D170DE /* JackRPCClientUser.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = JackRPCClientUser.c; path = RPC/JackRPCClientUser.c; sourceTree = SOURCE_ROOT; }; 4B89B769076B74D200D170DE /* JackRPCEngineUser.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = JackRPCEngineUser.c; path = RPC/JackRPCEngineUser.c; sourceTree = SOURCE_ROOT; }; 4B940B9B06DDDE5B00D77F60 /* AudioHardware.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AudioHardware.h; path = /System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/AudioHardware.h; sourceTree = ""; }; + 4B94334910A5E666002A187F /* systemdeps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = systemdeps.h; path = ../common/jack/systemdeps.h; sourceTree = SOURCE_ROOT; }; 4B95BCAD0D913073000F7695 /* control.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = control.h; path = ../common/jack/control.h; sourceTree = SOURCE_ROOT; }; 4B978DBB0A31CF4A009E2DD1 /* jack_portaudio.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_portaudio.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B98AE000931D30C0091932A /* JackDebugClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackDebugClient.cpp; path = ../common/JackDebugClient.cpp; sourceTree = SOURCE_ROOT; }; 4B98AE010931D30C0091932A /* JackDebugClient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackDebugClient.h; path = ../common/JackDebugClient.h; sourceTree = SOURCE_ROOT; }; 4B9A25B30DBF8330006E9FBC /* JackError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackError.cpp; path = ../common/JackError.cpp; sourceTree = SOURCE_ROOT; }; 4B9A26000DBF8584006E9FBC /* jslist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jslist.h; path = ../common/jack/jslist.h; sourceTree = SOURCE_ROOT; }; + 4BA339AC10B2E36800190E3B /* Jackservermp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackservermp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BA339AD10B2E36800190E3B /* Jack-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Jack-Info.plist"; sourceTree = ""; }; 4BA577BC08BF8BE200F82DE1 /* testSynchroClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSynchroClient.cpp; path = ../tests/testSynchroClient.cpp; sourceTree = SOURCE_ROOT; }; 4BA577FB08BF8E4600F82DE1 /* testSynchroServer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSynchroServer.cpp; path = ../tests/testSynchroServer.cpp; sourceTree = SOURCE_ROOT; }; 4BA692B00CBE4BC700EAD520 /* jack_load */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_load; sourceTree = BUILT_PRODUCTS_DIR; }; 4BA692B20CBE4C2D00EAD520 /* ipload.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ipload.c; path = "../example-clients/ipload.c"; sourceTree = SOURCE_ROOT; }; 4BA692D40CBE4C9000EAD520 /* jack_unload */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_unload; sourceTree = BUILT_PRODUCTS_DIR; }; 4BA692D60CBE4CC600EAD520 /* ipunload.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ipunload.c; path = "../example-clients/ipunload.c"; sourceTree = SOURCE_ROOT; }; - 4BA7FEC30D8E76270017FF73 /* jack_lsp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_lsp; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BA7FEC30D8E76270017FF73 /* jack_server_control */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_server_control; sourceTree = BUILT_PRODUCTS_DIR; }; 4BA7FEC80D8E76650017FF73 /* control.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = control.c; path = "../example-clients/control.c"; sourceTree = SOURCE_ROOT; }; 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackPortType.cpp; path = ../common/JackPortType.cpp; sourceTree = SOURCE_ROOT; }; 4BAB95B70B9E20B800A0C723 /* JackPortType.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackPortType.h; path = ../common/JackPortType.h; sourceTree = SOURCE_ROOT; }; @@ -1352,8 +1540,8 @@ 4BDCDB9D1001FB9C00B15929 /* jack_coremidi.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_coremidi.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4BDCDBC51001FCC000B15929 /* jack_net.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_net.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4BDCDBE81001FD2D00B15929 /* netmanager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netmanager.so; sourceTree = BUILT_PRODUCTS_DIR; }; - 4BDCDBFF1001FD7300B15929 /* netmanager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netmanager.so; sourceTree = BUILT_PRODUCTS_DIR; }; - 4BDCDC251001FDE300B15929 /* netmanager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netmanager.so; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BDCDBFF1001FD7300B15929 /* audioadapter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = audioadapter.so; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BDCDC251001FDE300B15929 /* netadapter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netadapter.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4BE4CBFF0CDA153400CCF5BB /* JackTools.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackTools.cpp; path = ../common/JackTools.cpp; sourceTree = SOURCE_ROOT; }; 4BE4CC000CDA153400CCF5BB /* JackTools.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackTools.h; path = ../common/JackTools.h; sourceTree = SOURCE_ROOT; }; 4BE5FECB0E725C090020B576 /* JackCoreAudioDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreAudioDriver.cpp; path = coreaudio/JackCoreAudioDriver.cpp; sourceTree = SOURCE_ROOT; }; @@ -1435,14 +1623,14 @@ 4BF8D2470834F20600C94B91 /* testSem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSem.cpp; path = ../tests/testSem.cpp; sourceTree = SOURCE_ROOT; }; 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackFrameTimer.cpp; path = ../common/JackFrameTimer.cpp; sourceTree = SOURCE_ROOT; }; 4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackFrameTimer.h; path = ../common/JackFrameTimer.h; sourceTree = SOURCE_ROOT; }; - 4BFA5E980DEC4D9C00FA4CDB /* testSem */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testSem; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BFA5E980DEC4D9C00FA4CDB /* testMutex */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testMutex; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA5E9E0DEC4DD900FA4CDB /* testMutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = testMutex.cpp; path = ../tests/testMutex.cpp; sourceTree = SOURCE_ROOT; }; - 4BFA828C0DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; - 4BFA829F0DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; - 4BFA82AB0DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; - 4BFA82B70DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; - 4BFA82C30DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; - 4BFA82CF0DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BFA828C0DF6A9E40087B4E1 /* jack_evmon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_evmon; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BFA829F0DF6A9E40087B4E1 /* jack_bufsize */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_bufsize; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BFA82AB0DF6A9E40087B4E1 /* jack_rec */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_rec; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BFA82B70DF6A9E40087B4E1 /* jack_monitor_client */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_monitor_client; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BFA82C30DF6A9E40087B4E1 /* jack_showtime */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_showtime; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BFA82CF0DF6A9E40087B4E1 /* jack_impulse_grabber */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_impulse_grabber; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA99A20AAAF3B0009E916C /* jdelay */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jdelay; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA99A90AAAF40C009E916C /* jdelay.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = jdelay.cpp; path = ../tests/jdelay.cpp; sourceTree = SOURCE_ROOT; }; 4BFB297708AF44ED00D450D4 /* JackMachServerNotifyChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMachServerNotifyChannel.cpp; sourceTree = ""; }; @@ -1490,6 +1678,34 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B3224E010A3156800838A8E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32252610A316B200838A8E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32255B10A3187800838A8E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32257510A3190C00838A8E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B35C41F0D4731D1000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1580,7 +1796,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4BA7BE0F0DC232A400AA3457 /* Jackdmp.framework in Frameworks */, + 4BA7BE0F0DC232A400AA3457 /* Jackservermp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1588,7 +1804,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4BA7BE1A0DC2347500AA3457 /* Jackdmp.framework in Frameworks */, + 4BA7BE1A0DC2347500AA3457 /* Jackservermp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1631,7 +1847,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4BA7BE200DC234FB00AA3457 /* Jackdmp.framework in Frameworks */, + 4BA7BE200DC234FB00AA3457 /* Jackservermp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1639,7 +1855,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4BA7BE240DC2350D00AA3457 /* Jackdmp.framework in Frameworks */, + 4BA7BE240DC2350D00AA3457 /* Jackservermp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1647,7 +1863,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4BA7BE270DC2352A00AA3457 /* Jackdmp.framework in Frameworks */, + 4BA7BE270DC2352A00AA3457 /* Jackservermp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1891,6 +2107,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BA339A610B2E36800190E3B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BA339A710B2E36800190E3B /* Accelerate.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BA692AA0CBE4BC700EAD520 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -2064,6 +2288,7 @@ 0249A662FF388D9811CA2CEA /* External Frameworks and Libraries */, 1AB674ADFE9D54B511CA2CBB /* Products */, 4B464301076CAC7700E5077C /* Jack-Info.plist */, + 4BA339AD10B2E36800190E3B /* Jack-Info.plist */, ); name = JackServer; sourceTree = ""; @@ -2121,7 +2346,7 @@ 4B5A1BDA0CD1CCE10005BF74 /* jack_midisine */, 4B35C4250D4731D1000DE7AE /* jackdmp */, 4B35C4830D4731D1000DE7AE /* Jackmp.framework */, - 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */, + 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */, 4B35C5140D4731D1000DE7AE /* jack_midiseq */, 4B35C5200D4731D1000DE7AE /* jack_midisine */, 4B35C52C0D4731D1000DE7AE /* jack_metro */, @@ -2148,34 +2373,39 @@ 4B0A28E60D52073D002EFF74 /* jack_thread_wait */, 4B0A292D0D52108E002EFF74 /* jack_thread_wait */, 4B57F5950D72C27900B4E719 /* jack_thread_wait */, - 4BA7FEC30D8E76270017FF73 /* jack_lsp */, + 4BA7FEC30D8E76270017FF73 /* jack_server_control */, BA222ACF0DC88132001A17F4 /* jack_net.so */, BA222AE90DC882DB001A17F4 /* netmanager.so */, - 4BA7FEC30D8E76270017FF73 /* jack_lsp */, - 4B363DD80DEB02F6001F72D9 /* jack_midiseq */, - 4B363E1A0DEB03C5001F72D9 /* jack_midiseq */, - 4B363E4E0DEB0775001F72D9 /* jack_midiseq */, - 4B363EE90DEB091C001F72D9 /* jack_midiseq */, - 4B363F1E0DEB0A6A001F72D9 /* jack_midiseq */, + 4BA7FEC30D8E76270017FF73 /* jack_server_control */, + 4B363DD80DEB02F6001F72D9 /* jack_alias */, + 4B363E1A0DEB03C5001F72D9 /* jack_evmon */, + 4B363E4E0DEB0775001F72D9 /* jack_bufsize */, + 4B363EE90DEB091C001F72D9 /* jack_rec */, + 4B363F1E0DEB0A6A001F72D9 /* jack_monitor_client */, 4B363F350DEB0BD1001F72D9 /* jack_showtime */, - 4B363F720DEB0D4E001F72D9 /* jack_midiseq */, - 4BFA5E980DEC4D9C00FA4CDB /* testSem */, - 4BFA828C0DF6A9E40087B4E1 /* jack_midiseq */, - 4BFA829F0DF6A9E40087B4E1 /* jack_midiseq */, - 4BFA82AB0DF6A9E40087B4E1 /* jack_midiseq */, - 4BFA82B70DF6A9E40087B4E1 /* jack_midiseq */, - 4BFA82C30DF6A9E40087B4E1 /* jack_midiseq */, - 4BFA82CF0DF6A9E40087B4E1 /* jack_midiseq */, - 4B19B3000E23620F00DD4A82 /* netmanager.so */, - 4B5E08D50E5B66EE00BEE4E0 /* netmanager.so */, + 4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */, + 4BFA5E980DEC4D9C00FA4CDB /* testMutex */, + 4BFA828C0DF6A9E40087B4E1 /* jack_evmon */, + 4BFA829F0DF6A9E40087B4E1 /* jack_bufsize */, + 4BFA82AB0DF6A9E40087B4E1 /* jack_rec */, + 4BFA82B70DF6A9E40087B4E1 /* jack_monitor_client */, + 4BFA82C30DF6A9E40087B4E1 /* jack_showtime */, + 4BFA82CF0DF6A9E40087B4E1 /* jack_impulse_grabber */, + 4B19B3000E23620F00DD4A82 /* audioadapter.so */, + 4B5E08D50E5B66EE00BEE4E0 /* netadapter.so */, 4BF3390C0F8B864B0080FB5B /* jack_coremidi.so */, 4BDCDB9D1001FB9C00B15929 /* jack_coremidi.so */, 4BDCDBC51001FCC000B15929 /* jack_net.so */, 4BDCDBE81001FD2D00B15929 /* netmanager.so */, - 4BDCDBFF1001FD7300B15929 /* netmanager.so */, - 4BDCDC251001FDE300B15929 /* netmanager.so */, - 4B43A8BA10145F6F00E52943 /* jack_dummy.so */, - 4B43A8E71014615800E52943 /* jack_dummy.so */, + 4BDCDBFF1001FD7300B15929 /* audioadapter.so */, + 4BDCDC251001FDE300B15929 /* netadapter.so */, + 4B43A8BA10145F6F00E52943 /* jack_loopback.so */, + 4B43A8E71014615800E52943 /* jack_loopback.so */, + 4B3224E510A3156800838A8E /* jack_netone.so */, + 4B32252B10A316B200838A8E /* jack_netone.so */, + 4B32256110A3187800838A8E /* jack_netsource */, + 4B32257B10A3190C00838A8E /* jack_netsource */, + 4BA339AC10B2E36800190E3B /* Jackservermp.framework */, ); name = Products; sourceTree = ""; @@ -2369,6 +2599,7 @@ 4B6C73780CC60A6D001AFFD4 /* jack */ = { isa = PBXGroup; children = ( + 4B94334910A5E666002A187F /* systemdeps.h */, 4B9A26000DBF8584006E9FBC /* jslist.h */, 4B95BCAD0D913073000F7695 /* control.h */, 4B6B9EF50CD0958B0051EE5A /* midiport.h */, @@ -2670,6 +2901,13 @@ BA222AEA0DC88379001A17F4 /* Net */ = { isa = PBXGroup; children = ( + 4B32256310A318E300838A8E /* netsource.c */, + 4B3224EC10A315C400838A8E /* netjack_packet.c */, + 4B3224ED10A315C400838A8E /* netjack_packet.h */, + 4B3224EE10A315C400838A8E /* netjack.c */, + 4B3224EF10A315C400838A8E /* netjack.h */, + 4B3224E810A315B100838A8E /* JackNetOneDriver.cpp */, + 4B3224E910A315B100838A8E /* JackNetOneDriver.h */, 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */, 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */, 4B5E08DF0E5B676C00BEE4E0 /* JackNetAdapter.cpp */, @@ -2724,6 +2962,44 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B3224D810A3156800838A8E /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B3224EB10A315B100838A8E /* JackNetOneDriver.h in Headers */, + 4B3224F110A315C400838A8E /* netjack_packet.h in Headers */, + 4B3224F310A315C400838A8E /* netjack.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32251E10A316B200838A8E /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B32253210A3173A00838A8E /* JackNetOneDriver.h in Headers */, + 4B32253410A3173C00838A8E /* netjack.h in Headers */, + 4B32253610A3173E00838A8E /* netjack_packet.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32255810A3187800838A8E /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B32256C10A318FB00838A8E /* netjack.h in Headers */, + 4B32256E10A318FD00838A8E /* netjack_packet.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32257210A3190C00838A8E /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B32257E10A3195800838A8E /* netjack.h in Headers */, + 4B32258010A3195A00838A8E /* netjack_packet.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B35C41C0D4731D1000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -3159,6 +3435,7 @@ 4BB9D4B30E2610B300351653 /* JackTransportEngine.h in Headers */, 4BC3B6A50E703B2E0066E42F /* JackPosixThread.h in Headers */, 4BECB2F80F4451C10091B70A /* JackProcessSync.h in Headers */, + 4B94334A10A5E666002A187F /* systemdeps.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3228,6 +3505,7 @@ 4BBAE4100F42FA6100B8BD3F /* JackEngineProfiling.h in Headers */, 4BECB2F60F4451C10091B70A /* JackProcessSync.h in Headers */, 4BF339240F8B873E0080FB5B /* JackMidiDriver.h in Headers */, + 4B94334B10A5E666002A187F /* systemdeps.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3340,6 +3618,72 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BA3393410B2E36800190E3B /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BA3393510B2E36800190E3B /* JackMachPort.h in Headers */, + 4BA3393610B2E36800190E3B /* JackError.h in Headers */, + 4BA3393710B2E36800190E3B /* JackTime.h in Headers */, + 4BA3393810B2E36800190E3B /* JackShmMem.h in Headers */, + 4BA3393910B2E36800190E3B /* shm.h in Headers */, + 4BA3393A10B2E36800190E3B /* JackThread.h in Headers */, + 4BA3393B10B2E36800190E3B /* JackActivationCount.h in Headers */, + 4BA3393C10B2E36800190E3B /* JackChannel.h in Headers */, + 4BA3393D10B2E36800190E3B /* JackGraphManager.h in Headers */, + 4BA3393E10B2E36800190E3B /* JackPort.h in Headers */, + 4BA3393F10B2E36800190E3B /* JackClientInterface.h in Headers */, + 4BA3394010B2E36800190E3B /* JackClientControl.h in Headers */, + 4BA3394110B2E36800190E3B /* JackClient.h in Headers */, + 4BA3394210B2E36800190E3B /* JackInternalClient.h in Headers */, + 4BA3394310B2E36800190E3B /* JackConnectionManager.h in Headers */, + 4BA3394410B2E36800190E3B /* JackFrameTimer.h in Headers */, + 4BA3394510B2E36800190E3B /* JackMachSemaphore.h in Headers */, + 4BA3394610B2E36800190E3B /* JackGlobals.h in Headers */, + 4BA3394710B2E36800190E3B /* JackMachThread.h in Headers */, + 4BA3394810B2E36800190E3B /* JackSynchro.h in Headers */, + 4BA3394910B2E36800190E3B /* JackAudioDriver.h in Headers */, + 4BA3394A10B2E36800190E3B /* JackFreewheelDriver.h in Headers */, + 4BA3394B10B2E36800190E3B /* JackThreadedDriver.h in Headers */, + 4BA3394C10B2E36800190E3B /* JackDriver.h in Headers */, + 4BA3394D10B2E36800190E3B /* driver_interface.h in Headers */, + 4BA3394E10B2E36800190E3B /* JackDriverLoader.h in Headers */, + 4BA3394F10B2E36800190E3B /* JackEngine.h in Headers */, + 4BA3395010B2E36800190E3B /* JackExternalClient.h in Headers */, + 4BA3395110B2E36800190E3B /* JackServer.h in Headers */, + 4BA3395210B2E36800190E3B /* JackMachNotifyChannel.h in Headers */, + 4BA3395310B2E36800190E3B /* JackMachServerChannel.h in Headers */, + 4BA3395410B2E36800190E3B /* JackMachServerNotifyChannel.h in Headers */, + 4BA3395510B2E36800190E3B /* JackConstants.h in Headers */, + 4BA3395610B2E36800190E3B /* JackTransportEngine.h in Headers */, + 4BA3395710B2E36800190E3B /* JackServerGlobals.h in Headers */, + 4BA3395810B2E36800190E3B /* timestamps.h in Headers */, + 4BA3395910B2E36800190E3B /* jack.h in Headers */, + 4BA3395A10B2E36800190E3B /* intclient.h in Headers */, + 4BA3395B10B2E36800190E3B /* ringbuffer.h in Headers */, + 4BA3395C10B2E36800190E3B /* statistics.h in Headers */, + 4BA3395D10B2E36800190E3B /* thread.h in Headers */, + 4BA3395E10B2E36800190E3B /* transport.h in Headers */, + 4BA3395F10B2E36800190E3B /* types.h in Headers */, + 4BA3396010B2E36800190E3B /* JackPortType.h in Headers */, + 4BA3396110B2E36800190E3B /* JackMidiPort.h in Headers */, + 4BA3396210B2E36800190E3B /* midiport.h in Headers */, + 4BA3396310B2E36800190E3B /* JackDebugClient.h in Headers */, + 4BA3396410B2E36800190E3B /* JackTools.h in Headers */, + 4BA3396510B2E36800190E3B /* JackNetTool.h in Headers */, + 4BA3396610B2E36800190E3B /* jslist.h in Headers */, + 4BA3396710B2E36800190E3B /* JackMessageBuffer.h in Headers */, + 4BA3396810B2E36800190E3B /* JackRestartThreadedDriver.h in Headers */, + 4BA3396910B2E36800190E3B /* JackControlAPI.h in Headers */, + 4BA3396A10B2E36800190E3B /* JackPosixThread.h in Headers */, + 4BA3396B10B2E36800190E3B /* JackEngineProfiling.h in Headers */, + 4BA3396C10B2E36800190E3B /* JackProcessSync.h in Headers */, + 4BA3396D10B2E36800190E3B /* JackMidiDriver.h in Headers */, + 4BA3396E10B2E36800190E3B /* JackWaitThreadedDriver.h in Headers */, + 4BA3396F10B2E36800190E3B /* JackArgParser.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BA692A70CBE4BC700EAD520 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -3577,9 +3921,81 @@ ); name = "audioadapter Universal"; productName = jack_coreaudio; - productReference = 4B19B3000E23620F00DD4A82 /* netmanager.so */; + productReference = 4B19B3000E23620F00DD4A82 /* audioadapter.so */; + productType = "com.apple.product-type.library.dynamic"; + }; + 4B3224D710A3156800838A8E /* jack_netone Universal */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B3224E110A3156800838A8E /* Build configuration list for PBXNativeTarget "jack_netone Universal" */; + buildPhases = ( + 4B3224D810A3156800838A8E /* Headers */, + 4B3224DC10A3156800838A8E /* Sources */, + 4B3224E010A3156800838A8E /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "jack_netone Universal"; + productName = jack_coreaudio; + productReference = 4B3224E510A3156800838A8E /* jack_netone.so */; + productType = "com.apple.product-type.library.dynamic"; + }; + 4B32251D10A316B200838A8E /* jack_netone 64 bits */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B32252710A316B200838A8E /* Build configuration list for PBXNativeTarget "jack_netone 64 bits" */; + buildPhases = ( + 4B32251E10A316B200838A8E /* Headers */, + 4B32252210A316B200838A8E /* Sources */, + 4B32252610A316B200838A8E /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "jack_netone 64 bits"; + productName = jack_coreaudio; + productReference = 4B32252B10A316B200838A8E /* jack_netone.so */; productType = "com.apple.product-type.library.dynamic"; }; + 4B32255710A3187800838A8E /* jack_netsource Universal */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B32255D10A3187800838A8E /* Build configuration list for PBXNativeTarget "jack_netsource Universal" */; + buildPhases = ( + 4B32255810A3187800838A8E /* Headers */, + 4B32255910A3187800838A8E /* Sources */, + 4B32255B10A3187800838A8E /* Frameworks */, + 4B32255C10A3187800838A8E /* Rez */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "jack_netsource Universal"; + productInstallPath = /usr/local/bin; + productName = jack_metro; + productReference = 4B32256110A3187800838A8E /* jack_netsource */; + productType = "com.apple.product-type.tool"; + }; + 4B32257110A3190C00838A8E /* jack_netsource 64 bits */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B32257710A3190C00838A8E /* Build configuration list for PBXNativeTarget "jack_netsource 64 bits" */; + buildPhases = ( + 4B32257210A3190C00838A8E /* Headers */, + 4B32257310A3190C00838A8E /* Sources */, + 4B32257510A3190C00838A8E /* Frameworks */, + 4B32257610A3190C00838A8E /* Rez */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "jack_netsource 64 bits"; + productInstallPath = /usr/local/bin; + productName = jack_metro; + productReference = 4B32257B10A3190C00838A8E /* jack_netsource */; + productType = "com.apple.product-type.tool"; + }; 4B35C41B0D4731D1000DE7AE /* jackdmp framework 64bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C4210D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jackdmp framework 64bits" */; @@ -3634,7 +4050,7 @@ ); name = "Jackservermp.framework 64 bits"; productName = Jack; - productReference = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; + productReference = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; productType = "com.apple.product-type.framework"; }; 4B35C50A0D4731D1000DE7AE /* jack_midiseq 64 bits */ = { @@ -4083,7 +4499,7 @@ name = "jack_alias Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4B363DD80DEB02F6001F72D9 /* jack_midiseq */; + productReference = 4B363DD80DEB02F6001F72D9 /* jack_alias */; productType = "com.apple.product-type.tool"; }; 4B363E100DEB03C5001F72D9 /* jack_evmon Universal */ = { @@ -4102,7 +4518,7 @@ name = "jack_evmon Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4B363E1A0DEB03C5001F72D9 /* jack_midiseq */; + productReference = 4B363E1A0DEB03C5001F72D9 /* jack_evmon */; productType = "com.apple.product-type.tool"; }; 4B363E440DEB0775001F72D9 /* jack_bufsize Universal */ = { @@ -4121,7 +4537,7 @@ name = "jack_bufsize Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4B363E4E0DEB0775001F72D9 /* jack_midiseq */; + productReference = 4B363E4E0DEB0775001F72D9 /* jack_bufsize */; productType = "com.apple.product-type.tool"; }; 4B363EDF0DEB091C001F72D9 /* jack_rec Universal */ = { @@ -4140,7 +4556,7 @@ name = "jack_rec Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4B363EE90DEB091C001F72D9 /* jack_midiseq */; + productReference = 4B363EE90DEB091C001F72D9 /* jack_rec */; productType = "com.apple.product-type.tool"; }; 4B363F140DEB0A6A001F72D9 /* jack_monitor_client Universal */ = { @@ -4159,7 +4575,7 @@ name = "jack_monitor_client Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4B363F1E0DEB0A6A001F72D9 /* jack_midiseq */; + productReference = 4B363F1E0DEB0A6A001F72D9 /* jack_monitor_client */; productType = "com.apple.product-type.tool"; }; 4B363F2B0DEB0BD1001F72D9 /* jack_showtime Universal */ = { @@ -4197,7 +4613,7 @@ name = "jack_impulse_grabber Universal"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4B363F720DEB0D4E001F72D9 /* jack_midiseq */; + productReference = 4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */; productType = "com.apple.product-type.tool"; }; 4B43A8B010145F6F00E52943 /* jack_loopback Universal */ = { @@ -4214,7 +4630,7 @@ ); name = "jack_loopback Universal"; productName = jack_coreaudio; - productReference = 4B43A8BA10145F6F00E52943 /* jack_dummy.so */; + productReference = 4B43A8BA10145F6F00E52943 /* jack_loopback.so */; productType = "com.apple.product-type.library.dynamic"; }; 4B43A8DD1014615800E52943 /* jack_loopback 64 bits */ = { @@ -4231,7 +4647,7 @@ ); name = "jack_loopback 64 bits"; productName = jack_coreaudio; - productReference = 4B43A8E71014615800E52943 /* jack_dummy.so */; + productReference = 4B43A8E71014615800E52943 /* jack_loopback.so */; productType = "com.apple.product-type.library.dynamic"; }; 4B5A1BB10CD1CB9E0005BF74 /* jack_midiseq Universal */ = { @@ -4286,7 +4702,7 @@ ); name = "netadapter Universal"; productName = jack_coreaudio; - productReference = 4B5E08D50E5B66EE00BEE4E0 /* netmanager.so */; + productReference = 4B5E08D50E5B66EE00BEE4E0 /* netadapter.so */; productType = "com.apple.product-type.library.dynamic"; }; 4B699BA7097D421600A18468 /* jackdmp framework Universal */ = { @@ -4626,6 +5042,25 @@ productReference = 4B978DBB0A31CF4A009E2DD1 /* jack_portaudio.so */; productType = "com.apple.product-type.library.dynamic"; }; + 4BA3393310B2E36800190E3B /* Jackservermp.framework 64 bits profiling */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4BA339A810B2E36800190E3B /* Build configuration list for PBXNativeTarget "Jackservermp.framework 64 bits profiling" */; + buildPhases = ( + 4BA3393410B2E36800190E3B /* Headers */, + 4BA3397010B2E36800190E3B /* Resources */, + 4BA3397110B2E36800190E3B /* Sources */, + 4BA339A510B2E36800190E3B /* Rez */, + 4BA339A610B2E36800190E3B /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Jackservermp.framework 64 bits profiling"; + productName = Jack; + productReference = 4BA339AC10B2E36800190E3B /* Jackservermp.framework */; + productType = "com.apple.product-type.framework"; + }; 4BA692A60CBE4BC700EAD520 /* jack_load Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4BA692AC0CBE4BC700EAD520 /* Build configuration list for PBXNativeTarget "jack_load Universal" */; @@ -4680,7 +5115,7 @@ name = "jack_server_control Universal"; productInstallPath = /usr/local/bin; productName = jack_lsp; - productReference = 4BA7FEC30D8E76270017FF73 /* jack_lsp */; + productReference = 4BA7FEC30D8E76270017FF73 /* jack_server_control */; productType = "com.apple.product-type.tool"; }; 4BD623ED0CBCF0F000DE782F /* inprocess Universal */ = { @@ -4765,7 +5200,7 @@ ); name = "audioadapter 64 bits"; productName = jack_coreaudio; - productReference = 4BDCDBFF1001FD7300B15929 /* netmanager.so */; + productReference = 4BDCDBFF1001FD7300B15929 /* audioadapter.so */; productType = "com.apple.product-type.library.dynamic"; }; 4BDCDC0F1001FDE300B15929 /* netadapter 64 bits */ = { @@ -4782,7 +5217,7 @@ ); name = "netadapter 64 bits"; productName = jack_coreaudio; - productReference = 4BDCDC251001FDE300B15929 /* netmanager.so */; + productReference = 4BDCDC251001FDE300B15929 /* netadapter.so */; productType = "com.apple.product-type.library.dynamic"; }; 4BE6C6910A3E096F005A203A /* jack_test Universal */ = { @@ -4856,7 +5291,7 @@ name = "testMutex Universal"; productInstallPath = /usr/local/bin; productName = testSem; - productReference = 4BFA5E980DEC4D9C00FA4CDB /* testSem */; + productReference = 4BFA5E980DEC4D9C00FA4CDB /* testMutex */; productType = "com.apple.product-type.tool"; }; 4BFA82820DF6A9E40087B4E1 /* jack_evmon 64 bits */ = { @@ -4875,7 +5310,7 @@ name = "jack_evmon 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4BFA828C0DF6A9E40087B4E1 /* jack_midiseq */; + productReference = 4BFA828C0DF6A9E40087B4E1 /* jack_evmon */; productType = "com.apple.product-type.tool"; }; 4BFA82950DF6A9E40087B4E1 /* jack_bufsize 64 bits */ = { @@ -4894,7 +5329,7 @@ name = "jack_bufsize 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4BFA829F0DF6A9E40087B4E1 /* jack_midiseq */; + productReference = 4BFA829F0DF6A9E40087B4E1 /* jack_bufsize */; productType = "com.apple.product-type.tool"; }; 4BFA82A10DF6A9E40087B4E1 /* jack_rec 64 bits */ = { @@ -4913,7 +5348,7 @@ name = "jack_rec 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4BFA82AB0DF6A9E40087B4E1 /* jack_midiseq */; + productReference = 4BFA82AB0DF6A9E40087B4E1 /* jack_rec */; productType = "com.apple.product-type.tool"; }; 4BFA82AD0DF6A9E40087B4E1 /* jack_monitor_client 64 bits */ = { @@ -4932,7 +5367,7 @@ name = "jack_monitor_client 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4BFA82B70DF6A9E40087B4E1 /* jack_midiseq */; + productReference = 4BFA82B70DF6A9E40087B4E1 /* jack_monitor_client */; productType = "com.apple.product-type.tool"; }; 4BFA82B90DF6A9E40087B4E1 /* jack_showtime 64 bits */ = { @@ -4951,7 +5386,7 @@ name = "jack_showtime 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4BFA82C30DF6A9E40087B4E1 /* jack_midiseq */; + productReference = 4BFA82C30DF6A9E40087B4E1 /* jack_showtime */; productType = "com.apple.product-type.tool"; }; 4BFA82C50DF6A9E40087B4E1 /* jack_impulse_grabber 64 bits */ = { @@ -4970,7 +5405,7 @@ name = "jack_impulse_grabber 64 bits"; productInstallPath = /usr/local/bin; productName = jack_metro; - productReference = 4BFA82CF0DF6A9E40087B4E1 /* jack_midiseq */; + productReference = 4BFA82CF0DF6A9E40087B4E1 /* jack_impulse_grabber */; productType = "com.apple.product-type.tool"; }; 4BFA99980AAAF3B0009E916C /* jdelay Universal */ = { @@ -5003,6 +5438,7 @@ buildRules = ( ); dependencies = ( + 4B3224E710A3157900838A8E /* PBXTargetDependency */, ); name = "jack_net Universal"; productName = jack_coreaudio; @@ -5069,6 +5505,7 @@ 4B363F140DEB0A6A001F72D9 /* jack_monitor_client Universal */, 4B363F2B0DEB0BD1001F72D9 /* jack_showtime Universal */, 4B363F680DEB0D4E001F72D9 /* jack_impulse_grabber Universal */, + 4B32255710A3187800838A8E /* jack_netsource Universal */, 4B699D4F097D421600A18468 /* synchroServer Universal */, 4B699D67097D421600A18468 /* synchroClient Universal */, 4B699D7F097D421700A18468 /* synchroServerClient Universal */, @@ -5078,6 +5515,7 @@ 4B43A8B010145F6F00E52943 /* jack_loopback Universal */, 4B699DA6097D421700A18468 /* jack_dummy Universal */, BA222AC50DC88132001A17F4 /* jack_net Universal */, + 4B3224D710A3156800838A8E /* jack_netone Universal */, 4BD623ED0CBCF0F000DE782F /* inprocess Universal */, BA222AE00DC882DB001A17F4 /* netmanager Universal */, 4B19B2F60E23620F00DD4A82 /* audioadapter Universal */, @@ -5085,6 +5523,7 @@ 4B35C41B0D4731D1000DE7AE /* jackdmp framework 64bits */, 4B35C4270D4731D1000DE7AE /* Jackmp.framework 64 bits */, 4B35C4850D4731D1000DE7AE /* Jackservermp.framework 64 bits */, + 4BA3393310B2E36800190E3B /* Jackservermp.framework 64 bits profiling */, 4B35C50A0D4731D1000DE7AE /* jack_midiseq 64 bits */, 4B35C5160D4731D1000DE7AE /* jack_midisine 64 bits */, 4B35C5220D4731D1000DE7AE /* jack_metro 64 bits */, @@ -5108,6 +5547,7 @@ 4BFA82AD0DF6A9E40087B4E1 /* jack_monitor_client 64 bits */, 4BFA82B90DF6A9E40087B4E1 /* jack_showtime 64 bits */, 4BFA82C50DF6A9E40087B4E1 /* jack_impulse_grabber 64 bits */, + 4B32257110A3190C00838A8E /* jack_netsource 64 bits */, 4B35C5D80D4731D2000DE7AE /* synchroServer 64 bits */, 4B35C5EC0D4731D2000DE7AE /* synchroClient 64 bits */, 4B35C6000D4731D2000DE7AE /* synchroServerClient 64 bits */, @@ -5117,6 +5557,7 @@ 4B43A8DD1014615800E52943 /* jack_loopback 64 bits */, 4BDCDB931001FB9C00B15929 /* jack_coremidi 64 bits */, 4BDCDBB71001FCC000B15929 /* jack_net 64 bits */, + 4B32251D10A316B200838A8E /* jack_netone 64 bits */, 4BDCDBD71001FD2D00B15929 /* netmanager 64 bits */, 4BDCDBEC1001FD7300B15929 /* audioadapter 64 bits */, 4BDCDC0F1001FDE300B15929 /* netadapter 64 bits */, @@ -5154,6 +5595,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BA3397010B2E36800190E3B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXRezBuildPhase section */ @@ -5171,6 +5619,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B32255C10A3187800838A8E /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32257610A3190C00838A8E /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B35C4200D4731D1000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; @@ -5493,6 +5955,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BA339A510B2E36800190E3B /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BA692AB0CBE4BC700EAD520 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; @@ -5616,6 +6085,46 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B3224DC10A3156800838A8E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B3224EA10A315B100838A8E /* JackNetOneDriver.cpp in Sources */, + 4B3224F010A315C400838A8E /* netjack_packet.c in Sources */, + 4B3224F210A315C400838A8E /* netjack.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32252210A316B200838A8E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B32253110A3173900838A8E /* JackNetOneDriver.cpp in Sources */, + 4B32253310A3173B00838A8E /* netjack.c in Sources */, + 4B32253510A3173D00838A8E /* netjack_packet.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32255910A3187800838A8E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B32256410A318E300838A8E /* netsource.c in Sources */, + 4B32256B10A318FA00838A8E /* netjack.c in Sources */, + 4B32256D10A318FC00838A8E /* netjack_packet.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32257310A3190C00838A8E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B32257D10A3195700838A8E /* netjack.c in Sources */, + 4B32257F10A3195900838A8E /* netjack_packet.c in Sources */, + 4B32258110A3195B00838A8E /* netsource.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B35C41D0D4731D1000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -6238,6 +6747,64 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BA3397110B2E36800190E3B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BA3397210B2E36800190E3B /* JackMachPort.cpp in Sources */, + 4BA3397310B2E36800190E3B /* JackShmMem.cpp in Sources */, + 4BA3397410B2E36800190E3B /* shm.c in Sources */, + 4BA3397510B2E36800190E3B /* JackActivationCount.cpp in Sources */, + 4BA3397610B2E36800190E3B /* JackGraphManager.cpp in Sources */, + 4BA3397710B2E36800190E3B /* JackPort.cpp in Sources */, + 4BA3397810B2E36800190E3B /* JackClient.cpp in Sources */, + 4BA3397910B2E36800190E3B /* JackAPI.cpp in Sources */, + 4BA3397A10B2E36800190E3B /* JackConnectionManager.cpp in Sources */, + 4BA3397B10B2E36800190E3B /* JackFrameTimer.cpp in Sources */, + 4BA3397C10B2E36800190E3B /* JackMachSemaphore.cpp in Sources */, + 4BA3397D10B2E36800190E3B /* JackMachThread.cpp in Sources */, + 4BA3397E10B2E36800190E3B /* JackGlobals.cpp in Sources */, + 4BA3397F10B2E36800190E3B /* ringbuffer.c in Sources */, + 4BA3398010B2E36800190E3B /* JackAudioDriver.cpp in Sources */, + 4BA3398110B2E36800190E3B /* JackFreewheelDriver.cpp in Sources */, + 4BA3398210B2E36800190E3B /* JackThreadedDriver.cpp in Sources */, + 4BA3398310B2E36800190E3B /* JackDriver.cpp in Sources */, + 4BA3398410B2E36800190E3B /* JackDriverLoader.cpp in Sources */, + 4BA3398510B2E36800190E3B /* JackEngine.cpp in Sources */, + 4BA3398610B2E36800190E3B /* JackExternalClient.cpp in Sources */, + 4BA3398710B2E36800190E3B /* JackInternalClient.cpp in Sources */, + 4BA3398810B2E36800190E3B /* JackRPCClientUser.c in Sources */, + 4BA3398910B2E36800190E3B /* JackServer.cpp in Sources */, + 4BA3398A10B2E36800190E3B /* JackMacEngineRPC.cpp in Sources */, + 4BA3398B10B2E36800190E3B /* JackMachNotifyChannel.cpp in Sources */, + 4BA3398C10B2E36800190E3B /* JackMachServerChannel.cpp in Sources */, + 4BA3398D10B2E36800190E3B /* JackMachServerNotifyChannel.cpp in Sources */, + 4BA3398E10B2E36800190E3B /* JackTransportEngine.cpp in Sources */, + 4BA3398F10B2E36800190E3B /* JackServerAPI.cpp in Sources */, + 4BA3399010B2E36800190E3B /* JackServerGlobals.cpp in Sources */, + 4BA3399110B2E36800190E3B /* timestamps.c in Sources */, + 4BA3399210B2E36800190E3B /* JackPortType.cpp in Sources */, + 4BA3399310B2E36800190E3B /* JackAudioPort.cpp in Sources */, + 4BA3399410B2E36800190E3B /* JackMidiPort.cpp in Sources */, + 4BA3399510B2E36800190E3B /* JackMidiAPI.cpp in Sources */, + 4BA3399610B2E36800190E3B /* JackEngineControl.cpp in Sources */, + 4BA3399710B2E36800190E3B /* JackDebugClient.cpp in Sources */, + 4BA3399810B2E36800190E3B /* JackTools.cpp in Sources */, + 4BA3399910B2E36800190E3B /* JackNetTool.cpp in Sources */, + 4BA3399A10B2E36800190E3B /* JackError.cpp in Sources */, + 4BA3399B10B2E36800190E3B /* JackMessageBuffer.cpp in Sources */, + 4BA3399C10B2E36800190E3B /* JackRestartThreadedDriver.cpp in Sources */, + 4BA3399D10B2E36800190E3B /* JackControlAPI.cpp in Sources */, + 4BA3399E10B2E36800190E3B /* JackPosixThread.cpp in Sources */, + 4BA3399F10B2E36800190E3B /* JackMachTime.c in Sources */, + 4BA339A010B2E36800190E3B /* JackEngineProfiling.cpp in Sources */, + 4BA339A110B2E36800190E3B /* JackProcessSync.cpp in Sources */, + 4BA339A210B2E36800190E3B /* JackMidiDriver.cpp in Sources */, + 4BA339A310B2E36800190E3B /* JackWaitThreadedDriver.cpp in Sources */, + 4BA339A410B2E36800190E3B /* JackArgParser.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BA692A80CBE4BC700EAD520 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -6460,6 +7027,31 @@ target = 4B5E08BF0E5B66EE00BEE4E0 /* netadapter Universal */; targetProxy = 4B224B330E65BA330066BE5B /* PBXContainerItemProxy */; }; + 4B3224E710A3157900838A8E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4B3224D710A3156800838A8E /* jack_netone Universal */; + targetProxy = 4B3224E610A3157900838A8E /* PBXContainerItemProxy */; + }; + 4B32258B10A31A9000838A8E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4B32255710A3187800838A8E /* jack_netsource Universal */; + targetProxy = 4B32258A10A31A9000838A8E /* PBXContainerItemProxy */; + }; + 4B32258D10A31A9D00838A8E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4B3224D710A3156800838A8E /* jack_netone Universal */; + targetProxy = 4B32258C10A31A9D00838A8E /* PBXContainerItemProxy */; + }; + 4B32258F10A31AB400838A8E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4B32257110A3190C00838A8E /* jack_netsource 64 bits */; + targetProxy = 4B32258E10A31AB400838A8E /* PBXContainerItemProxy */; + }; + 4B32259110A31ABA00838A8E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4B32251D10A316B200838A8E /* jack_netone 64 bits */; + targetProxy = 4B32259010A31ABA00838A8E /* PBXContainerItemProxy */; + }; 4B35C5530D4731D2000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B699D03097D421600A18468 /* jack_external_metro Universal */; @@ -6876,12 +7468,8 @@ 4B0A292A0D52108E002EFF74 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - i386, - ppc, - ppc64, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -7110,42 +7698,37 @@ }; name = Default; }; - 4B35C4220D4731D1000DE7AE /* Development */ = { + 4B3224E210A3156800838A8E /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + ARCHS = ( + i386, + ppc, + ); COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - FRAMEWORK_SEARCH_PATHS = ""; + DEBUGGING_SYMBOLS = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; - GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( + ../common, ., ../common/jack, ../posix, - ../common, - RPC, - ); - MACOSX_DEPLOYMENT_TARGET = 10.4; - OTHER_CFLAGS = ( - "-DUSE_POSIX_SHM", - "-D__SMP__", - "-DJACK_32_64", - ); - OTHER_CPLUSPLUSFLAGS = ( - "-DMACH_RPC_MACH_SEMA", - "-D__SMP__", - "-DJACK_32_64", ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", - Jackdmp, + Jackservermp, "-framework", CoreAudio, "-framework", @@ -7154,8 +7737,8 @@ AudioUnit, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jackdmp; - REZ_EXECUTABLE = YES; + PREBINDING = NO; + PRODUCT_NAME = jack_netone; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( @@ -7167,14 +7750,488 @@ }; name = Development; }; - 4B35C4230D4731D1000DE7AE /* Deployment */ = { + 4B3224E310A3156800838A8E /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + ARCHS = ( + i386, + ppc, + ); COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - FRAMEWORK_SEARCH_PATHS = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + HEADER_SEARCH_PATHS = ( + ../common, + ., + ../common/jack, + ../posix, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + "-framework", + Jackservermp, + "-framework", + CoreServices, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_netone; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B3224E410A3156800838A8E /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + "-framework", + Jackdmp, + "-framework", + AudioToolBox, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_dummy; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4B32252810A316B200838A8E /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = NO; + DEBUGGING_SYMBOLS = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G4; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ( + ../common, + ., + ../common/jack, + ../posix, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + "-framework", + Jackservermp, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_netone; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4B32252910A316B200838A8E /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + HEADER_SEARCH_PATHS = ( + ../common, + ., + ../common/jack, + ../posix, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = "-DJACK_32_64"; + OTHER_CPLUSPLUSFLAGS = ( + "-DMACH_RPC_MACH_SEMA", + "-DJACK_32_64", + ); + OTHER_LDFLAGS = ( + "-framework", + Jackservermp, + "-framework", + CoreServices, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_netone; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B32252A10A316B200838A8E /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + "-framework", + Jackdmp, + "-framework", + AudioToolBox, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_dummy; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4B32255E10A3187800838A8E /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_netsource; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4B32255F10A3187800838A8E /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + HEADER_SEARCH_PATHS = ../common; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_netsource; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B32256010A3187800838A8E /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + FRAMEWORK_SEARCH_PATHS = ""; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midiseq; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4B32257810A3190C00838A8E /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_netsource; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4B32257910A3190C00838A8E /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + HEADER_SEARCH_PATHS = ../common; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_netsource; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B32257A10A3190C00838A8E /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + FRAMEWORK_SEARCH_PATHS = ""; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midiseq; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4B35C4220D4731D1000DE7AE /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ( + ., + ../common/jack, + ../posix, + ../common, + RPC, + ); + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ( + "-DUSE_POSIX_SHM", + "-D__SMP__", + "-DJACK_32_64", + ); + OTHER_CPLUSPLUSFLAGS = ( + "-DMACH_RPC_MACH_SEMA", + "-D__SMP__", + "-DJACK_32_64", + ); + OTHER_LDFLAGS = ( + "-framework", + Jackdmp, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jackdmp; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4B35C4230D4731D1000DE7AE /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_OPTIMIZATION_LEVEL = 3; @@ -7666,12 +8723,8 @@ 4B35C5110D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -7765,12 +8818,8 @@ 4B35C51D0D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -7864,12 +8913,8 @@ 4B35C5290D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -7963,12 +9008,8 @@ 4B35C5350D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -8056,12 +9097,8 @@ 4B35C5410D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -8149,12 +9186,8 @@ 4B35C54D0D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -8239,12 +9272,8 @@ 4B35C55B0D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -8333,14 +9362,10 @@ name = Default; }; 4B35C5670D4731D2000DE7AE /* Development */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -8428,12 +9453,8 @@ 4B35C5730D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -8745,12 +9766,8 @@ 4B35C5A30D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -8838,12 +9855,8 @@ 4B35C5AF0D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -8930,12 +9943,8 @@ 4B35C5BB0D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -9022,12 +10031,8 @@ 4B35C5C70D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -9114,12 +10119,8 @@ 4B35C5D30D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -9552,12 +10553,8 @@ 4B35C61B0D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -9855,12 +10852,8 @@ 4B35C6310D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -10000,12 +10993,8 @@ 4B35C63B0D4731D3000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -11027,10 +12016,8 @@ 4B43A8E41014615800E52943 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - i386, - ppc, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -11904,10 +12891,8 @@ 4B699CA9097D421600A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - i386, - ppc, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DEBUG_INFORMATION_FORMAT = dwarf; @@ -11963,10 +12948,8 @@ 4B699CAA097D421600A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - i386, - ppc, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; @@ -13710,111 +14693,308 @@ CoreServices, ); OTHER_REZFLAGS = ""; - PREBINDING = NO; - PRODUCT_NAME = jack_portaudio; + PREBINDING = NO; + PRODUCT_NAME = jack_portaudio; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4B978DB90A31CF4A009E2DD1 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + COPY_PHASE_STRIP = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ../common/; + INSTALL_PATH = /usr/local/lib; + LD_OPENMP_FLAGS = "-fopenmp"; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + libportaudio.a, + "-framework", + Jackservermp, + "-framework", + CoreAudio, + "-framework", + AudioUnit, + "-framework", + CoreServices, + "-framework", + AudioToolbox, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_portaudio; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B978DBA0A31CF4A009E2DD1 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ../common/; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + libportaudio.a, + "-framework", + Jackdmp, + "-framework", + AudioToolBox, + "-framework", + CoreAudio, + "-framework", + AudioUnit, + "-framework", + CoreServices, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_portaudio; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4BA339A910B2E36800190E3B /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = NO; + DEBUGGING_SYMBOLS = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; + FRAMEWORK_VERSION = A; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + GENERATE_PKGINFO_FILE = NO; + HEADER_SEARCH_PATHS = ( + ../common, + ../posix, + RPC, + ../common/jack, + ); + INFOPLIST_FILE = "Jack-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; + OTHER_CFLAGS = ( + "-DJACK_MONITOR", + "-DSERVER_SIDE", + "-DJACK_32_64", + "-D__SMP__", + "-DUSE_POSIX_SHM", + ); + OTHER_CPLUSPLUSFLAGS = ( + "-DJACK_MONITOR", + "-DSERVER_SIDE", + "-DJACK_32_64", + "-D__SMP__", + "-DMACH_RPC_MACH_SEMA", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + ); + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_LDFLAGS = ( + "-framework", + Carbon, + "-framework", + CoreAudio, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = Jackdmp; + REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; - WARNING_CFLAGS = ( - "-Wmost", - "-Wno-four-char-constants", - "-Wno-unknown-pragmas", - ); + WARNING_CFLAGS = "-Wmost"; ZERO_LINK = YES; }; name = Development; }; - 4B978DB90A31CF4A009E2DD1 /* Deployment */ = { + 4BA339AA10B2E36800190E3B /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - i386, - ppc, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; - EXECUTABLE_EXTENSION = so; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; + FRAMEWORK_VERSION = A; + GCC_AUTO_VECTORIZATION = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; - GCC_MODEL_TUNING = G4; - GCC_PREPROCESSOR_DEFINITIONS = ""; - HEADER_SEARCH_PATHS = ../common/; - INSTALL_PATH = /usr/local/lib; - LD_OPENMP_FLAGS = "-fopenmp"; - LIBRARY_STYLE = DYNAMIC; - MACH_O_TYPE = mh_dylib; + GCC_ENABLE_SSE3_EXTENSIONS = YES; + GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + GENERATE_PKGINFO_FILE = NO; + HEADER_SEARCH_PATHS = ( + ../common, + ../posix, + RPC, + ../common/jack, + ); + INFOPLIST_FILE = "Jack-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; MACOSX_DEPLOYMENT_TARGET = 10.4; - OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_CFLAGS = ( + "-DJACK_MONITOR", + "-DSERVER_SIDE", + "-DJACK_32_64", + "-D__SMP__", + "-DUSE_POSIX_SHM", + ); + OTHER_CPLUSPLUSFLAGS = ( + "-DJACK_MONITOR", + "-DSERVER_SIDE", + "-DJACK_32_64", + "-D__SMP__", + "-DMACH_RPC_MACH_SEMA", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", + ); + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DLIB_DIR=\\\"lib\\\""; OTHER_LDFLAGS = ( - libportaudio.a, "-framework", - Jackservermp, + Carbon, "-framework", CoreAudio, - "-framework", - AudioUnit, - "-framework", - CoreServices, - "-framework", - AudioToolbox, ); OTHER_REZFLAGS = ""; - PREBINDING = NO; - PRODUCT_NAME = jack_portaudio; + PRODUCT_NAME = Jackservermp; + REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; - WARNING_CFLAGS = ( - "-Wmost", - "-Wno-four-char-constants", - "-Wno-unknown-pragmas", - ); + WARNING_CFLAGS = "-Wmost"; ZERO_LINK = NO; }; name = Deployment; }; - 4B978DBA0A31CF4A009E2DD1 /* Default */ = { + 4BA339AB10B2E36800190E3B /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( - i386, + ppc64, ppc, + i386, + x86_64, ); + DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; - EXECUTABLE_EXTENSION = so; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; - GCC_MODEL_TUNING = G4; - GCC_PREPROCESSOR_DEFINITIONS = ""; - HEADER_SEARCH_PATHS = ../common/; - INSTALL_PATH = /usr/local/lib; - LIBRARY_STYLE = DYNAMIC; - MACH_O_TYPE = mh_dylib; - OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; + FRAMEWORK_VERSION = A; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + GENERATE_PKGINFO_FILE = NO; + HEADER_SEARCH_PATHS = ( + RPC, + ../common/jack, + ); + INFOPLIST_FILE = "Jack-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; + OTHER_CFLAGS = ( + "-D__SMP__", + "-DJACK_32_64", + "-DUSE_POSIX_SHM", + ); + OTHER_CPLUSPLUSFLAGS = ( + "-D__SMP__", + "-DJACK_32_64", + "-DMACH_RPC_MACH_SEMA", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", + ); + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DLIB_DIR=\\\"lib\\\""; OTHER_LDFLAGS = ( - libportaudio.a, "-framework", - Jackdmp, + Carbon, "-framework", AudioToolBox, "-framework", CoreAudio, - "-framework", - AudioUnit, - "-framework", - CoreServices, ); OTHER_REZFLAGS = ""; - PREBINDING = NO; - PRODUCT_NAME = jack_portaudio; + PRODUCT_NAME = Jackdmp; + REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; - WARNING_CFLAGS = ( - "-Wmost", - "-Wno-four-char-constants", - "-Wno-unknown-pragmas", - ); + WARNING_CFLAGS = "-Wmost"; }; name = Default; }; @@ -14230,10 +15410,8 @@ 4BDCDB9A1001FB9C00B15929 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - i386, - ppc, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -14378,10 +15556,8 @@ 4BDCDBC21001FCC000B15929 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - i386, - ppc, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -14519,10 +15695,8 @@ 4BDCDBE51001FD2D00B15929 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - i386, - ppc, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -14665,7 +15839,7 @@ 4BDCDBFC1001FD7300B15929 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = i386; + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -14809,7 +15983,7 @@ 4BDCDC221001FDE300B15929 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = i386; + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -15399,12 +16573,8 @@ 4BFA82890DF6A9E40087B4E1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -15498,12 +16668,8 @@ 4BFA829C0DF6A9E40087B4E1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -15595,12 +16761,8 @@ 4BFA82A80DF6A9E40087B4E1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -15702,12 +16864,8 @@ 4BFA82B40DF6A9E40087B4E1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -15799,12 +16957,8 @@ 4BFA82C00DF6A9E40087B4E1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -15820,7 +16974,7 @@ CoreFoundation, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midiseq; + PRODUCT_NAME = jack_showtime; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -15896,12 +17050,8 @@ 4BFA82CC0DF6A9E40087B4E1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -16402,6 +17552,46 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; + 4B3224E110A3156800838A8E /* Build configuration list for PBXNativeTarget "jack_netone Universal" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B3224E210A3156800838A8E /* Development */, + 4B3224E310A3156800838A8E /* Deployment */, + 4B3224E410A3156800838A8E /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 4B32252710A316B200838A8E /* Build configuration list for PBXNativeTarget "jack_netone 64 bits" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B32252810A316B200838A8E /* Development */, + 4B32252910A316B200838A8E /* Deployment */, + 4B32252A10A316B200838A8E /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 4B32255D10A3187800838A8E /* Build configuration list for PBXNativeTarget "jack_netsource Universal" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B32255E10A3187800838A8E /* Development */, + 4B32255F10A3187800838A8E /* Deployment */, + 4B32256010A3187800838A8E /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 4B32257710A3190C00838A8E /* Build configuration list for PBXNativeTarget "jack_netsource 64 bits" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B32257810A3190C00838A8E /* Development */, + 4B32257910A3190C00838A8E /* Deployment */, + 4B32257A10A3190C00838A8E /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; 4B35C4210D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jackdmp framework 64bits" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -16992,6 +18182,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; + 4BA339A810B2E36800190E3B /* Build configuration list for PBXNativeTarget "Jackservermp.framework 64 bits profiling" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4BA339A910B2E36800190E3B /* Development */, + 4BA339AA10B2E36800190E3B /* Deployment */, + 4BA339AB10B2E36800190E3B /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; 4BA692AC0CBE4BC700EAD520 /* Build configuration list for PBXNativeTarget "jack_load Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/macosx/coreaudio/JackCoreAudioAdapter.cpp b/macosx/coreaudio/JackCoreAudioAdapter.cpp index 630366ec..cb05d622 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.cpp +++ b/macosx/coreaudio/JackCoreAudioAdapter.cpp @@ -301,6 +301,7 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra char playbackName[256]; fCaptureUID[0] = 0; fPlaybackUID[0] = 0; + fClockDriftCompensate = false; // Default values fCaptureChannels = -1; @@ -377,6 +378,10 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra fRingbufferCurSize = param->value.ui; fAdaptative = false; break; + + case 's': + fClockDriftCompensate = true; + break; } } @@ -721,10 +726,6 @@ int JackCoreAudioAdapter::SetupBuffers(int inchannels) // Prepare buffers fInputData = (AudioBufferList*)malloc(sizeof(UInt32) + inchannels * sizeof(AudioBuffer)); - if (fInputData == 0) { - jack_error("Cannot allocate memory for input buffers"); - return -1; - } fInputData->mNumberBuffers = inchannels; for (int i = 0; i < fCaptureChannels; i++) { fInputData->mBuffers[i].mNumberChannels = 1; @@ -1013,66 +1014,160 @@ static CFStringRef GetDeviceName(AudioDeviceID id) } 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); + } else { + int num_devices = outSize / sizeof(AudioObjectID); + jack_log("Input device has %d subdevices", num_devices); + for (int i = 0; i < num_devices; i++) { + captureDeviceIDArray.push_back(sub_device[i]); + } + } + + 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); + } else { + int num_devices = outSize / sizeof(AudioObjectID); + jack_log("Output device has %d subdevices", num_devices); + for (int i = 0; i < num_devices; i++) { + 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 osErr = noErr; UInt32 outSize; Boolean outWritable; - // Check devices... - if (IsAggregateDevice(captureDeviceID) || IsAggregateDevice(playbackDeviceID)) { - jack_error("JackCoreAudioAdapter::CreateAggregateDevice : cannot agregate devices that are already aggregate devices..."); - return -1; - } + // Prepare sub-devices for clock drift compensation + // Workaround for bug in the HAL : until 10.6.2 + AudioObjectPropertyAddress theAddressOwned = { kAudioObjectPropertyOwnedObjects, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; + AudioObjectPropertyAddress theAddressDrift = { kAudioSubDevicePropertyDriftCompensation, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; + UInt32 theQualifierDataSize = sizeof(AudioObjectID); + AudioClassID inClass = kAudioSubDeviceClassID; + void* theQualifierData = &inClass; + UInt32 subDevicesNum = 0; //--------------------------------------------------------------------------- // Setup SR of both devices otherwise creating AD may fail... //--------------------------------------------------------------------------- - if (SetupSampleRateAux(captureDeviceID, samplerate) < 0) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of input device"); + UInt32 keptclockdomain = 0; + 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); + if (osErr != 0) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); + printError(osErr); + } else { + 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..."); + need_clock_drift_compensation = true; + } + } + } } - if (SetupSampleRateAux(playbackDeviceID, samplerate) < 0) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of output device"); + + 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); + if (osErr != 0) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); + printError(osErr); + } else { + 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..."); + need_clock_drift_compensation = true; + } + } + } } - + + // 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 capture_name[256]; - char playback_name[256]; - GetDeviceNameFromID(captureDeviceID, capture_name); - GetDeviceNameFromID(playbackDeviceID, playback_name); - jack_info("Separated input = '%s' and output = '%s' devices, create a private aggregate device to handle them...", capture_name, playback_name); - + 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) + 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) + 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); @@ -1082,7 +1177,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDevice(AudioDeviceID captureDevice 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) @@ -1092,96 +1187,214 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDevice(AudioDeviceID captureDevice 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) { + CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID); + CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef); + //CFRelease(UID); + CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); + } + } + + for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { + CFStringRef UID = GetDeviceName(playbackDeviceID[i]); + if (UID) { + CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID); + CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef); + //CFRelease(UID); + CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); + } + } + + // add sub-device clock array for the aggregate device to the dictionary + CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceSubDeviceListKey), subDevicesArrayClock); + } else { + jack_info("Clock drift compensation was asked but is not needed (devices use the same clock domain)"); + } + } + */ + //------------------------------------------------- // Create a CFMutableArray for our sub-device list //------------------------------------------------- - CFStringRef captureDeviceUID = GetDeviceName(captureDeviceID); - CFStringRef playbackDeviceUID = GetDeviceName(playbackDeviceID); - - if (captureDeviceUID == NULL || playbackDeviceUID == NULL) - return -1; - // we need to append the UID for each device to a CFMutableArray, so create one here CFMutableArrayRef subDevicesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - - // two sub-devices in this example, so append the sub-device's UID to the CFArray - CFArrayAppendValue(subDevicesArray, captureDeviceUID); - CFArrayAppendValue(subDevicesArray, playbackDeviceUID); - + + vector captureDeviceUID; + for (UInt32 i = 0; i < captureDeviceID.size(); i++) { + CFStringRef ref = GetDeviceName(captureDeviceID[i]); + if (ref == NULL) + return -1; + captureDeviceUID.push_back(ref); + // 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]); + if (ref == NULL) + return -1; + playbackDeviceUID.push_back(ref); + // 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) - return osErr; - + 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) - return osErr; - + 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; outDataSize = sizeof(CFMutableArrayRef); osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &subDevicesArray); - if (osErr != noErr) - return osErr; - + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectSetPropertyData for sub-device list error"); + 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; pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; pluginAOPA.mElement = kAudioObjectPropertyElementMaster; outDataSize = sizeof(CFStringRef); - osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID); // capture is master... - if (osErr != noErr) - return osErr; - + osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID[0]); // First apture is master... + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectSetPropertyData for master device error"); + 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; + osErr = AudioObjectSetPropertyData(subDevices[index], &theAddressDrift, 0, NULL, sizeof(UInt32), &theDriftCompensationValue); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioSubDevicePropertyDriftCompensation error"); + printError(osErr); + } + } + } 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 - CFRelease(captureDeviceUID); - CFRelease(playbackDeviceUID); + 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; @@ -1252,7 +1465,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 = 12; + desc->nparams = 13; desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); i = 0; @@ -1283,16 +1496,14 @@ extern "C" strcpy(desc->params[i].name, "capture"); desc->params[i].character = 'C'; desc->params[i].type = JackDriverParamString; - strcpy(desc->params[i].value.str, "will take default CoreAudio input device"); - strcpy(desc->params[i].short_desc, "Provide capture ports. Optionally set CoreAudio device name"); + strcpy(desc->params[i].short_desc, "Input CoreAudio device name"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); i++; strcpy(desc->params[i].name, "playback"); desc->params[i].character = 'P'; desc->params[i].type = JackDriverParamString; - strcpy(desc->params[i].value.str, "will take default CoreAudio output device"); - strcpy(desc->params[i].short_desc, "Provide playback ports. Optionally set CoreAudio device name"); + strcpy(desc->params[i].short_desc, "Output CoreAudio device name"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); i++; @@ -1304,11 +1515,11 @@ extern "C" strcpy(desc->params[i].long_desc, desc->params[i].short_desc); i++; - strcpy(desc->params[i].name, "periodsize"); + strcpy(desc->params[i].name, "period"); desc->params[i].character = 'p'; desc->params[i].type = JackDriverParamUInt; desc->params[i].value.ui = 512U; - strcpy(desc->params[i].short_desc, "Period size"); + strcpy(desc->params[i].short_desc, "Frames per period"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); i++; @@ -1323,7 +1534,6 @@ extern "C" strcpy(desc->params[i].name, "device"); desc->params[i].character = 'd'; desc->params[i].type = JackDriverParamString; - strcpy(desc->params[i].value.str, "will take default CoreAudio device name"); strcpy(desc->params[i].short_desc, "CoreAudio device name"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); @@ -1350,7 +1560,15 @@ 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'; + desc->params[i].type = JackDriverParamBool; + 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/JackCoreAudioAdapter.h b/macosx/coreaudio/JackCoreAudioAdapter.h index d2f61006..8ef6e4d2 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.h +++ b/macosx/coreaudio/JackCoreAudioAdapter.h @@ -27,6 +27,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include +#include + +using namespace std; + namespace Jack { @@ -63,6 +67,7 @@ class JackCoreAudioAdapter : public JackAudioAdapterInterface AudioUnitRenderActionFlags* fActionFags; AudioTimeStamp* fCurrentTime; + bool fClockDriftCompensate; static OSStatus Render(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, @@ -91,6 +96,7 @@ class JackCoreAudioAdapter : public JackAudioAdapterInterface // Setup OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); + OSStatus CreateAggregateDeviceAux(vector captureDeviceID, vector playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); OSStatus DestroyAggregateDevice(); bool IsAggregateDevice(AudioDeviceID device); diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 3b2620cb..e540a164 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -297,7 +297,7 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, case kAudioDevicePropertyNominalSampleRate: { jack_error("Cannot handle kAudioDevicePropertyNominalSampleRate : server will quit..."); - driver->NotifyFailure(JackBackendError, "Another application has changed the sample rate."); // Message length limited to JACK_MESSAGE_SIZE + driver->NotifyFailure(JackBackendError, "Another application has changed the sample rate."); // Message length limited to JACK_MESSAGE_SIZE driver->CloseAUHAL(); kill(JackTools::GetPID(), SIGINT); return kAudioHardwareUnsupportedOperationError; @@ -387,22 +387,17 @@ OSStatus JackCoreAudioDriver::GetTotalChannels(AudioDeviceID device, int& channe OSStatus err = noErr; UInt32 outSize; Boolean outWritable; - AudioBufferList* bufferList = 0; - + channelCount = 0; err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, &outWritable); if (err == noErr) { - bufferList = (AudioBufferList*)malloc(outSize); + AudioBufferList bufferList[outSize]; err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, bufferList); if (err == noErr) { for (unsigned int i = 0; i < bufferList->mNumberBuffers; i++) channelCount += bufferList->mBuffers[i].mNumberChannels; } - - if (bufferList) - free(bufferList); } - return err; } @@ -414,7 +409,8 @@ JackCoreAudioDriver::JackCoreAudioDriver(const char* name, const char* alias, Ja fState(false), fHogged(false), fIOUsage(1.f), - fComputationGrain(-1.f) + fComputationGrain(-1.f), + fClockDriftCompensate(false) {} JackCoreAudioDriver::~JackCoreAudioDriver() @@ -449,39 +445,127 @@ OSStatus JackCoreAudioDriver::DestroyAggregateDevice() return noErr; } - + 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); + } else { + int num_devices = outSize / sizeof(AudioObjectID); + jack_log("Input device has %d subdevices", num_devices); + for (int i = 0; i < num_devices; i++) { + captureDeviceIDArray.push_back(sub_device[i]); + } + } + + 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); + } else { + int num_devices = outSize / sizeof(AudioObjectID); + jack_log("Output device has %d subdevices", num_devices); + for (int i = 0; i < num_devices; i++) { + 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 osErr = noErr; UInt32 outSize; Boolean outWritable; - // Check devices... (TO IMPROVE) - if (IsAggregateDevice(captureDeviceID) || IsAggregateDevice(playbackDeviceID)) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot agregate devices that are already aggregate devices..."); - return -1; - } - + // Prepare sub-devices for clock drift compensation + // Workaround for bug in the HAL : until 10.6.2 + AudioObjectPropertyAddress theAddressOwned = { kAudioObjectPropertyOwnedObjects, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; + AudioObjectPropertyAddress theAddressDrift = { kAudioSubDevicePropertyDriftCompensation, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; + UInt32 theQualifierDataSize = sizeof(AudioObjectID); + AudioClassID inClass = kAudioSubDeviceClassID; + void* theQualifierData = &inClass; + UInt32 subDevicesNum = 0; + //--------------------------------------------------------------------------- // Setup SR of both devices otherwise creating AD may fail... //--------------------------------------------------------------------------- - if (SetupSampleRateAux(captureDeviceID, samplerate) < 0) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of input device"); + UInt32 keptclockdomain = 0; + 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); + if (osErr != 0) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); + printError(osErr); + } else { + 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..."); + need_clock_drift_compensation = true; + } + } + } + } + + 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); + if (osErr != 0) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); + printError(osErr); + } else { + 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..."); + need_clock_drift_compensation = true; + } + } + } } - if (SetupSampleRateAux(playbackDeviceID, samplerate) < 0) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of output device"); + + // 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 capture_name[256]; - char playback_name[256]; - GetDeviceNameFromID(captureDeviceID, capture_name); - GetDeviceNameFromID(playbackDeviceID, playback_name); - jack_info("Separated input = '%s' and output = '%s' devices, create a private aggregate device to handle them...", capture_name, playback_name); - + 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"); @@ -536,24 +620,73 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI 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) { + CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID); + CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef); + //CFRelease(UID); + CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); + } + } + + for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { + CFStringRef UID = GetDeviceName(playbackDeviceID[i]); + if (UID) { + CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID); + CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef); + //CFRelease(UID); + CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); + } + } + + // add sub-device clock array for the aggregate device to the dictionary + CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceSubDeviceListKey), subDevicesArrayClock); + } else { + jack_info("Clock drift compensation was asked but is not needed (devices use the same clock domain)"); + } + } + */ + //------------------------------------------------- // Create a CFMutableArray for our sub-device list //------------------------------------------------- - CFStringRef captureDeviceUID = GetDeviceName(captureDeviceID); - CFStringRef playbackDeviceUID = GetDeviceName(playbackDeviceID); - - if (captureDeviceUID == NULL || playbackDeviceUID == NULL) - return -1; - // we need to append the UID for each device to a CFMutableArray, so create one here CFMutableArrayRef subDevicesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - - // two sub-devices in this example, so append the sub-device's UID to the CFArray - CFArrayAppendValue(subDevicesArray, captureDeviceUID); - CFArrayAppendValue(subDevicesArray, playbackDeviceUID); - + + vector captureDeviceUID; + for (UInt32 i = 0; i < captureDeviceID.size(); i++) { + CFStringRef ref = GetDeviceName(captureDeviceID[i]); + if (ref == NULL) + return -1; + captureDeviceUID.push_back(ref); + // 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]); + if (ref == NULL) + return -1; + playbackDeviceUID.push_back(ref); + // 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 //----------------------------------------------------------------------- @@ -599,7 +732,7 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI // pause again to give the changes time to take effect CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); - + //----------------------- // Set the master device //----------------------- @@ -610,7 +743,7 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; pluginAOPA.mElement = kAudioObjectPropertyElementMaster; outDataSize = sizeof(CFStringRef); - osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID); // capture is master... + osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID[0]); // First apture is master... if (osErr != noErr) { jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectSetPropertyData for master device error"); printError(osErr); @@ -619,7 +752,50 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI // 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; + osErr = AudioObjectSetPropertyData(subDevices[index], &theAddressDrift, 0, NULL, sizeof(UInt32), &theDriftCompensationValue); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioSubDevicePropertyDriftCompensation error"); + printError(osErr); + } + } + } 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 //---------- @@ -630,10 +806,18 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI // 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 - CFRelease(captureDeviceUID); - CFRelease(playbackDeviceUID); + 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; @@ -651,7 +835,7 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, { 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"); @@ -675,10 +859,23 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, // Creates aggregate device AudioDeviceID captureID, playbackID; - if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) - return -1; - if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) - return -1; + + if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { + jack_log("Will take default input"); + if (GetDefaultInputDevice(&captureID) != noErr) { + jack_error("Cannot open default device"); + return -1; + } + } + + if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) { + jack_log("Will take default output"); + if (GetDefaultOutputDevice(&playbackID) != noErr) { + jack_error("Cannot open default device"); + return -1; + } + } + if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) return -1; } @@ -1095,10 +1292,6 @@ int JackCoreAudioDriver::SetupBuffers(int inchannels) { // Prepare buffers fJackInputData = (AudioBufferList*)malloc(sizeof(UInt32) + inchannels * sizeof(AudioBuffer)); - if (fJackInputData == 0) { - jack_error("Cannot allocate memory for input buffers"); - return -1; - } fJackInputData->mNumberBuffers = inchannels; for (int i = 0; i < fCaptureChannels; i++) { fJackInputData->mBuffers[i].mNumberChannels = 1; @@ -1203,7 +1396,8 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, jack_nframes_t playback_latency, int async_output_latency, int computation_grain, - bool hogged) + bool hogged, + bool clock_drift) { int in_nChannels = 0; int out_nChannels = 0; @@ -1223,6 +1417,7 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, fIOUsage = float(async_output_latency) / 100.f; fComputationGrain = float(computation_grain) / 100.f; fHogged = hogged; + fClockDriftCompensate = clock_drift; SInt32 major; SInt32 minor; @@ -1233,9 +1428,10 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, if (major == 10 && minor >= 6) { CFRunLoopRef theRunLoop = NULL; AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; - OSStatus theError = AudioObjectSetPropertyData (kAudioObjectSystemObject, &theAddress, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop); - if (theError != noErr) { + OSStatus osErr = AudioObjectSetPropertyData (kAudioObjectSystemObject, &theAddress, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop); + if (osErr != noErr) { jack_error("JackCoreAudioDriver::Open kAudioHardwarePropertyRunLoop error"); + printError(osErr); } } @@ -1560,7 +1756,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 = 16; + desc->nparams = 17; desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); i = 0; @@ -1591,16 +1787,14 @@ extern "C" strcpy(desc->params[i].name, "capture"); desc->params[i].character = 'C'; desc->params[i].type = JackDriverParamString; - strcpy(desc->params[i].value.str, "will take default CoreAudio input device"); - strcpy(desc->params[i].short_desc, "Provide capture ports. Optionally set CoreAudio device name"); + strcpy(desc->params[i].short_desc, "Input CoreAudio device name"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); i++; strcpy(desc->params[i].name, "playback"); desc->params[i].character = 'P'; desc->params[i].type = JackDriverParamString; - strcpy(desc->params[i].value.str, "will take default CoreAudio output device"); - strcpy(desc->params[i].short_desc, "Provide playback ports. Optionally set CoreAudio device name"); + strcpy(desc->params[i].short_desc, "Output CoreAudio device name"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); i++; @@ -1639,7 +1833,6 @@ extern "C" strcpy(desc->params[i].name, "device"); desc->params[i].character = 'd'; desc->params[i].type = JackDriverParamString; - strcpy(desc->params[i].value.str, "will take default CoreAudio device name"); strcpy(desc->params[i].short_desc, "CoreAudio device name"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); @@ -1690,6 +1883,14 @@ 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'; + desc->params[i].type = JackDriverParamBool; + 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; } @@ -1712,6 +1913,7 @@ extern "C" int async_output_latency = 100; 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; @@ -1789,6 +1991,10 @@ extern "C" case 'G': computation_grain = param->value.ui; break; + + case 's': + clock_drift = true; + break; } } @@ -1800,7 +2006,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, - playback_driver_uid, systemic_input_latency, systemic_output_latency, async_output_latency, computation_grain, hogged) == 0) { + playback_driver_uid, systemic_input_latency, systemic_output_latency, async_output_latency, computation_grain, hogged, clock_drift) == 0) { return driver; } else { delete driver; diff --git a/macosx/coreaudio/JackCoreAudioDriver.h b/macosx/coreaudio/JackCoreAudioDriver.h index f3d909d2..f17bbf19 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.h +++ b/macosx/coreaudio/JackCoreAudioDriver.h @@ -26,6 +26,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackAudioDriver.h" #include "JackTime.h" +#include + +using namespace std; + namespace Jack { @@ -77,6 +81,7 @@ class JackCoreAudioDriver : public JackAudioDriver bool fMonitor; float fIOUsage; float fComputationGrain; + bool fClockDriftCompensate; /* #ifdef MAC_OS_X_VERSION_10_5 @@ -117,9 +122,10 @@ class JackCoreAudioDriver : public JackAudioDriver OSStatus GetDefaultOutputDevice(AudioDeviceID* id); OSStatus GetDeviceNameFromID(AudioDeviceID id, char* name); OSStatus GetTotalChannels(AudioDeviceID device, int& channelCount, bool isInput); - + // Setup OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); + OSStatus CreateAggregateDeviceAux(vector captureDeviceID, vector playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); OSStatus DestroyAggregateDevice(); bool IsAggregateDevice(AudioDeviceID device); @@ -178,7 +184,8 @@ class JackCoreAudioDriver : public JackAudioDriver jack_nframes_t playback_latency, int async_output_latency, int computation_grain, - bool hogged); + bool hogged, + bool clock_drift); int Close(); int Attach(); diff --git a/macosx/install_jackdmp b/macosx/install_jackdmp index 7e171b76..e1c50075 100755 --- a/macosx/install_jackdmp +++ b/macosx/install_jackdmp @@ -11,6 +11,7 @@ sudo install -d /usr/local/bin sudo cp jackdmp /usr/local/bin [ -f jack_load ] && sudo cp jack_load /usr/local/bin [ -f jack_unload ] && sudo cp jack_unload /usr/local/bin +[ -f jack_netsource ] && sudo cp jack_netsource /usr/local/bin # Copy drivers sudo install -d /usr/local/lib/jackmp @@ -19,6 +20,7 @@ sudo cp jack_coremidi.so /usr/local/lib/jackmp sudo cp jack_dummy.so /usr/local/lib/jackmp sudo cp jack_loopback.so /usr/local/lib/jackmp [ -f jack_net.so ] && sudo cp jack_net.so /usr/local/lib/jackmp +[ -f jack_netone.so ] && sudo cp jack_netone.so /usr/local/lib/jackmp # Copy tools [ -f netmanager.so ] && sudo cp netmanager.so /usr/local/lib/jackmp diff --git a/macosx/wscript b/macosx/wscript index 843874bc..8fa9bd37 100644 --- a/macosx/wscript +++ b/macosx/wscript @@ -6,6 +6,12 @@ def create_jack_driver_obj(bld, target, sources, uselib = None): driver.features.append('cc') driver.env['shlib_PATTERN'] = 'jack_%s.so' driver.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] + # Seems uneeded here... + #if bld.env['HAVE_CELT']: + #if bld.env['HAVE_CELT_API_0_5']: + # driver.defines += ['HAVE_CELT', 'HAVE_CELT_API_0_5'] + #elif bld.env['HAVE_CELT_API_0_7']: + # driver.defines += ['HAVE_CELT', 'HAVE_CELT_API_0_7'] driver.includes = ['.', '../macosx', '../posix', '../common', '../common/jack'] driver.target = target driver.source = sources @@ -73,3 +79,6 @@ def build(bld): create_jack_driver_obj(bld, 'net', '../common/JackNetDriver.cpp') + create_jack_driver_obj(bld, 'netone', [ '../common/JackNetOneDriver.cpp', + '../common/netjack.c', + '../common/netjack_packet.c' ], "SAMPLERATE CELT" ) diff --git a/posix/JackPosixThread.cpp b/posix/JackPosixThread.cpp index d61eb932..67d2d0c8 100644 --- a/posix/JackPosixThread.cpp +++ b/posix/JackPosixThread.cpp @@ -101,12 +101,12 @@ int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, voi int res; if ((res = pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_JOINABLE))) { - jack_error("Cannot request joinable thread creation for RT thread res = %d err = %s", res, strerror(errno)); + jack_error("Cannot request joinable thread creation for thread res = %d", res); return -1; } if ((res = pthread_attr_setscope(&attributes, PTHREAD_SCOPE_SYSTEM))) { - jack_error("Cannot set scheduling scope for RT thread res = %d err = %s", res, strerror(errno)); + jack_error("Cannot set scheduling scope for thread res = %d", res); return -1; } @@ -115,33 +115,34 @@ int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, voi jack_log("Create RT thread"); if ((res = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED))) { - jack_error("Cannot request explicit scheduling for RT thread res = %d err = %s", res, strerror(errno)); + jack_error("Cannot request explicit scheduling for RT thread res = %d", res); return -1; } if ((res = pthread_attr_setschedpolicy(&attributes, JACK_SCHED_POLICY))) { - jack_error("Cannot set RR scheduling class for RT thread res = %d err = %s", res, strerror(errno)); + jack_error("Cannot set RR scheduling class for RT thread res = %d", res); return -1; } - } else { - jack_log("Create non RT thread"); - } + + memset(&rt_param, 0, sizeof(rt_param)); + rt_param.sched_priority = priority; - memset(&rt_param, 0, sizeof(rt_param)); - rt_param.sched_priority = priority; + if ((res = pthread_attr_setschedparam(&attributes, &rt_param))) { + jack_error("Cannot set scheduling priority for RT thread res = %d", res); + return -1; + } - if ((res = pthread_attr_setschedparam(&attributes, &rt_param))) { - jack_error("Cannot set scheduling priority for RT thread res = %d err = %s", res, strerror(errno)); - return -1; + } else { + jack_log("Create non RT thread"); } if ((res = pthread_attr_setstacksize(&attributes, THREAD_STACK))) { - jack_error("Cannot set thread stack size res = %d err = %s", res, strerror(errno)); + jack_error("Cannot set thread stack size res = %d", res); return -1; } if ((res = JackGlobals::fJackThreadCreator(thread, &attributes, start_routine, arg))) { - jack_error("Cannot create thread res = %d err = %s", res, strerror(errno)); + jack_error("Cannot create thread res = %d", res); return -1; } @@ -208,12 +209,22 @@ int JackPosixThread::AcquireRealTime() return (fThread != (pthread_t)NULL) ? AcquireRealTimeImp(fThread, fPriority) : -1; } +int JackPosixThread::AcquireSelfRealTime() +{ + return AcquireRealTimeImp(pthread_self(), fPriority); +} + int JackPosixThread::AcquireRealTime(int priority) { fPriority = priority; return AcquireRealTime(); } +int JackPosixThread::AcquireSelfRealTime(int priority) +{ + fPriority = priority; + return AcquireSelfRealTime(); +} int JackPosixThread::AcquireRealTimeImp(pthread_t thread, int priority) { struct sched_param rtparam; @@ -235,6 +246,11 @@ int JackPosixThread::DropRealTime() return (fThread != (pthread_t)NULL) ? DropRealTimeImp(fThread) : -1; } +int JackPosixThread::DropSelfRealTime() +{ + return DropRealTimeImp(pthread_self()); +} + int JackPosixThread::DropRealTimeImp(pthread_t thread) { struct sched_param rtparam; @@ -303,7 +319,7 @@ bool jack_tls_allocate_key(jack_tls_key *key_ptr) ret = pthread_key_create(key_ptr, NULL); if (ret != 0) { - jack_error("pthread_key_create() failed with error %d errno %s", ret, strerror(errno)); + jack_error("pthread_key_create() failed with error %d", ret); return false; } @@ -317,7 +333,7 @@ bool jack_tls_free_key(jack_tls_key key) ret = pthread_key_delete(key); if (ret != 0) { - jack_error("pthread_key_delete() failed with error %d errno %s", ret, strerror(errno)); + jack_error("pthread_key_delete() failed with error %d", ret); return false; } @@ -331,7 +347,7 @@ bool jack_tls_set(jack_tls_key key, void *data_ptr) ret = pthread_setspecific(key, (const void *)data_ptr); if (ret != 0) { - jack_error("pthread_setspecific() failed with error %d errno %s", ret, strerror(errno)); + jack_error("pthread_setspecific() failed with error %d", ret); return false; } diff --git a/posix/JackPosixThread.h b/posix/JackPosixThread.h index a0cec26a..73345e17 100644 --- a/posix/JackPosixThread.h +++ b/posix/JackPosixThread.h @@ -58,9 +58,14 @@ class SERVER_EXPORT JackPosixThread : public detail::JackThreadInterface int Stop(); void Terminate(); - int AcquireRealTime(); - int AcquireRealTime(int priority); - int DropRealTime(); + int AcquireRealTime(); // Used when called from another thread + int AcquireSelfRealTime(); // Used when called from thread itself + + int AcquireRealTime(int priority); // Used when called from another thread + int AcquireSelfRealTime(int priority); // Used when called from thread itself + + int DropRealTime(); // Used when called from another thread + int DropSelfRealTime(); // Used when called from thread itself pthread_t GetThreadID(); diff --git a/posix/JackSocketServerChannel.cpp b/posix/JackSocketServerChannel.cpp index eb988aef..a5625219 100644 --- a/posix/JackSocketServerChannel.cpp +++ b/posix/JackSocketServerChannel.cpp @@ -396,12 +396,7 @@ bool JackSocketServerChannel::HandleRequest(int fd) jack_error("Unknown request %ld", header.fType); break; } - - // Issued by JackEngine::ReleaseRefnum when temporary mode is used - if (JackServerGlobals::fKilled) { - kill(JackTools::GetPID(), SIGINT); - } - + return true; } diff --git a/posix/JackSocketServerNotifyChannel.cpp b/posix/JackSocketServerNotifyChannel.cpp index b147fe06..c4e4888a 100644 --- a/posix/JackSocketServerNotifyChannel.cpp +++ b/posix/JackSocketServerNotifyChannel.cpp @@ -51,7 +51,7 @@ void JackSocketServerNotifyChannel::Notify(int refnum, int notify, int value) { JackClientNotificationRequest req(refnum, notify, value); if (req.Write(&fRequestSocket) < 0) { - jack_error("Could not write request ref = %ld notify = %ld", refnum, notify); + jack_error("Could not write request ref = %d notify = %d", refnum, notify); } } diff --git a/tests/test.cpp b/tests/test.cpp index 26d4eedf..e77edf49 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -220,7 +220,7 @@ void jack_shutdown(void *arg) exit(1); } -void jack_info_shutdown(int code, const char* reason, void *arg) +void jack_info_shutdown(jack_status_t code, const char* reason, void *arg) { printf("JACK server failure : %s\n", reason); exit(1); diff --git a/windows/JackShmMem_os.h b/windows/JackShmMem_os.h index 24fffb6a..37a419f2 100644 --- a/windows/JackShmMem_os.h +++ b/windows/JackShmMem_os.h @@ -21,7 +21,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifndef __JackShmMem_WIN32__ #define __JackShmMem_WIN32__ -#include +#include + +// See GetProcessWorkingSetSize and SetProcessWorkingSetSize #define CHECK_MLOCK(ptr, size) (VirtualLock((ptr), (size)) != 0) #define CHECK_MUNLOCK(ptr, size) (VirtualUnlock((ptr), (size)) != 0) diff --git a/windows/JackWinNamedPipeServerChannel.cpp b/windows/JackWinNamedPipeServerChannel.cpp index 03d9effc..da0da443 100644 --- a/windows/JackWinNamedPipeServerChannel.cpp +++ b/windows/JackWinNamedPipeServerChannel.cpp @@ -317,14 +317,7 @@ bool JackClientPipeThread::HandleRequest() break; } } - - /* TODO - // Issued by JackEngine::ReleaseRefnum when temporary mode is used - if (JackServerGlobals::fKilled) { - kill(JackTools::GetPID(), SIGINT); - } - */ - + // Unlock the global mutex ReleaseMutex(fMutex); return ret; diff --git a/windows/JackWinNamedPipeServerNotifyChannel.cpp b/windows/JackWinNamedPipeServerNotifyChannel.cpp index 7f2f14cf..1e3c4e21 100644 --- a/windows/JackWinNamedPipeServerNotifyChannel.cpp +++ b/windows/JackWinNamedPipeServerNotifyChannel.cpp @@ -50,7 +50,7 @@ void JackWinNamedPipeServerNotifyChannel::Notify(int refnum, int notify, int val { JackClientNotificationRequest req(refnum, notify, value); if (req.Write(&fRequestPipe) < 0) { - jack_error("Could not write request ref = %ld notify = %ld", refnum, notify); + jack_error("Could not write request ref = %d notify = %d", refnum, notify); } } diff --git a/windows/JackWinThread.cpp b/windows/JackWinThread.cpp index 4042f573..3893d220 100644 --- a/windows/JackWinThread.cpp +++ b/windows/JackWinThread.cpp @@ -58,7 +58,7 @@ JackWinThread::JackWinThread(JackRunnableInterface* runnable) : JackThreadInterface(runnable, 0, false, 0) { fEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - fThread = NULL; + fThread = (HANDLE)NULL; assert(fEvent); } @@ -126,12 +126,12 @@ int JackWinThread::StartImp(pthread_t* thread, int priority, int realtime, Threa int JackWinThread::Kill() { - if (fThread) { // If thread has been started + if (fThread != (HANDLE)NULL) { // If thread has been started TerminateThread(fThread, 0); WaitForSingleObject(fThread, INFINITE); CloseHandle(fThread); jack_log("JackWinThread::Kill"); - fThread = NULL; + fThread = (HANDLE)NULL; fStatus = kIdle; return 0; } else { @@ -141,12 +141,12 @@ int JackWinThread::Kill() int JackWinThread::Stop() { - if (fThread) { // If thread has been started + if (fThread != (HANDLE)NULL) { // If thread has been started jack_log("JackWinThread::Stop"); fStatus = kIdle; // Request for the thread to stop WaitForSingleObject(fEvent, INFINITE); CloseHandle(fThread); - fThread = NULL; + fThread = (HANDLE)NULL; return 0; } else { return -1; @@ -155,7 +155,7 @@ int JackWinThread::Stop() int JackWinThread::KillImp(pthread_t thread) { - if (thread) { // If thread has been started + if (thread != (HANDLE)NULL) { // If thread has been started TerminateThread(thread, 0); WaitForSingleObject(thread, INFINITE); CloseHandle(thread); @@ -178,7 +178,12 @@ int JackWinThread::StopImp(pthread_t thread) int JackWinThread::AcquireRealTime() { - return (fThread) ? AcquireRealTimeImp(fThread, fPriority) : -1; + return (fThread != (HANDLE)NULL) ? AcquireRealTimeImp(fThread, fPriority) : -1; +} + +int JackWinThread::AcquireSelfRealTime() +{ + return AcquireRealTimeImp(GetCurrentThread(), fPriority); } int JackWinThread::AcquireRealTime(int priority) @@ -187,6 +192,12 @@ int JackWinThread::AcquireRealTime(int priority) return AcquireRealTime(); } +int JackWinThread::AcquireSelfRealTime(int priority) +{ + fPriority = priority; + return AcquireSelfRealTime(); +} + int JackWinThread::AcquireRealTimeImp(pthread_t thread, int priority) { jack_log("JackWinThread::AcquireRealTime"); @@ -198,9 +209,15 @@ int JackWinThread::AcquireRealTimeImp(pthread_t thread, int priority) return -1; } } + int JackWinThread::DropRealTime() { - return DropRealTimeImp(fThread); + return (fThread != (HANDLE)NULL) ? DropRealTimeImp(fThread) : -1; +} + +int JackWinThread::DropSelfRealTime() +{ + return DropRealTimeImp(GetCurrentThread()); } int JackWinThread::DropRealTimeImp(pthread_t thread) diff --git a/windows/JackWinThread.h b/windows/JackWinThread.h index 11ab8af5..a3a5a25c 100644 --- a/windows/JackWinThread.h +++ b/windows/JackWinThread.h @@ -57,10 +57,15 @@ class SERVER_EXPORT JackWinThread : public detail::JackThreadInterface int Stop(); void Terminate(); - int AcquireRealTime(); - int AcquireRealTime(int priority) ; - int DropRealTime(); - + int AcquireRealTime(); // Used when called from another thread + int AcquireSelfRealTime(); // Used when called from thread itself + + int AcquireRealTime(int priority); // Used when called from another thread + int AcquireSelfRealTime(int priority); // Used when called from thread itself + + int DropRealTime(); // Used when called from another thread + int DropSelfRealTime(); // Used when called from thread itself + pthread_t GetThreadID(); static int AcquireRealTimeImp(pthread_t thread, int priority); diff --git a/windows/Setup/JackRouter.dll b/windows/Setup/JackRouter.dll index df435bed0c3e6d756bf89dea9b8fbf3f2c66ead3..226ea66792539d9053c87ba8a9c2674ea0583940 100644 GIT binary patch delta 161 zcmZo@U}|V!n(%?8T7cDicCZ2D4CT#7@`WY+&bX-r?h63; . - Jack_v1.9.3_setup.exe + Jack_v1.9.4_setup.exe - Jack v1.9.3 + Jack v1.9.4 Default - 2 diff --git a/wscript b/wscript index 6fb5c88c..a9128cca 100644 --- a/wscript +++ b/wscript @@ -114,6 +114,19 @@ def configure(conf): conf.sub_config('dbus') conf.sub_config('example-clients') + if conf.check_cfg(package='celt', atleast_version='0.7.0', args='--cflags --libs'): + conf.define('HAVE_CELT', 1) + conf.define('HAVE_CELT_API_0_7', 1) + conf.define('HAVE_CELT_API_0_5', 0) + elif conf.check_cfg(package='celt', atleast_version='0.5.0', args='--cflags --libs', required=True): + conf.define('HAVE_CELT', 1) + conf.define('HAVE_CELT_API_0_5', 1) + conf.define('HAVE_CELT_API_0_7', 0) + else: + conf.define('HAVE_CELT', 0) + conf.define('HAVE_CELT_API_0_5', 0) + conf.define('HAVE_CELT_API_0_7', 0) + conf.env['LIB_PTHREAD'] = ['pthread'] conf.env['LIB_DL'] = ['dl'] conf.env['LIB_RT'] = ['rt'] @@ -218,11 +231,11 @@ def configure(conf): conf.env.append_unique('CXXFLAGS', '-m32') conf.env.append_unique('CCFLAGS', '-m32') conf.env.append_unique('LINKFLAGS', '-m32') - conf.write_config_header('config.h') if Options.options.libdir32: conf.env['LIBDIR'] = conf.env['PREFIX'] + Options.options.libdir32 else: conf.env['LIBDIR'] = conf.env['PREFIX'] + '/lib32' + conf.write_config_header('config.h') def build(bld): print ("make[1]: Entering directory `" + os.getcwd() + "/" + blddir + "'" ) From 5f68a6557ada8830b88fb1b7374c251ad8b81000 Mon Sep 17 00:00:00 2001 From: sletz Date: Fri, 5 Feb 2010 11:37:24 +0000 Subject: [PATCH 025/472] rebase from trunk 3813:3899 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3900 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 67 +- common/JackAPI.cpp | 196 ++-- common/JackAudioAdapterInterface.cpp | 27 +- common/JackClient.cpp | 4 +- common/JackConnectionManager.cpp | 2 +- common/JackConnectionManager.h | 16 +- common/JackConstants.h | 4 +- common/JackControlAPI.cpp | 28 +- common/JackDebugClient.cpp | 133 +-- common/JackDebugClient.h | 4 +- common/JackDriver.cpp | 2 +- common/JackEngine.cpp | 13 +- common/JackEngine.h | 5 +- common/JackEngineProfiling.cpp | 340 +++---- common/JackException.h | 18 + common/JackFilters.h | 9 + common/JackGlobals.cpp | 23 + common/JackGlobals.h | 14 +- common/JackGraphManager.cpp | 58 +- common/JackGraphManager.h | 10 +- common/JackLibAPI.cpp | 6 + common/JackLibClient.cpp | 3 + common/JackLibGlobals.h | 8 +- common/JackLockedEngine.h | 39 +- common/JackMessageBuffer.cpp | 26 +- common/JackMessageBuffer.h | 3 + common/JackNetAPI.cpp | 37 +- common/JackNetInterface.cpp | 19 + common/JackNetOneDriver.cpp | 2 - common/JackNotification.h | 1 + common/JackPhysicalMidiInput.cpp | 287 ++++++ common/JackPhysicalMidiInput.h | 146 +++ common/JackPhysicalMidiOutput.cpp | 320 +++++++ common/JackPhysicalMidiOutput.h | 118 +++ common/JackPort.cpp | 13 +- common/JackServer.cpp | 9 +- common/JackServer.h | 2 +- common/JackServerAPI.cpp | 6 + common/JackServerGlobals.cpp | 5 +- common/JackServerGlobals.h | 1 + common/Jackdmp.cpp | 20 +- common/jack/jack.h | 214 +++-- common/jack/midiport.h | 22 +- common/jack/thread.h | 17 +- common/jack/transport.h | 25 +- common/jack/types.h | 2 +- common/jack/weakjack.h | 52 ++ common/jack/weakmacros.h | 61 ++ common/netjack.c | 35 +- common/netjack_packet.c | 8 +- common/ringbuffer.c | 7 +- common/shm.c | 123 ++- common/shm.h | 22 +- common/wscript | 3 +- dbus/controller_iface_control.c | 7 +- dbus/controller_iface_patchbay.c | 105 +++ dbus/jackdbus.c | 28 + dbus/jackdbus.h | 7 + dbus/wscript | 16 +- doxyfile | 2 +- example-clients/alsa_in.c | 4 +- example-clients/alsa_out.c | 4 +- example-clients/jack_control | 4 +- example-clients/netmaster.c | 10 +- example-clients/netsource.c | 7 +- example-clients/wscript | 7 +- linux/alsa/JackAlsaDriver.cpp | 160 ++-- linux/firewire/JackFFADODriver.cpp | 123 +-- linux/firewire/JackFFADOMidiInput.cpp | 59 ++ linux/firewire/JackFFADOMidiInput.h | 54 ++ linux/firewire/JackFFADOMidiOutput.cpp | 60 ++ linux/firewire/JackFFADOMidiOutput.h | 57 ++ linux/firewire/ffado_driver.h | 14 +- linux/wscript | 11 +- macosx/Jack-Info.plist | 4 +- macosx/JackMacEngineRPC.cpp | 11 +- macosx/JackMachClientChannel.cpp | 1 - macosx/JackMachServerChannel.cpp | 22 +- macosx/JackMachServerNotifyChannel.cpp | 17 +- macosx/JackMachServerNotifyChannel.h | 3 +- macosx/JackMachThread.h | 9 + macosx/JackPlatformPlug_os.h | 6 + macosx/Jackdmp.xcodeproj/project.pbxproj | 448 +++++++++- macosx/coreaudio/JackAudioQueueAdapter.cpp | 218 ++++- macosx/coreaudio/JackAudioQueueAdapter.h | 34 +- macosx/coreaudio/JackCoreAudioDriver.cpp | 119 ++- macosx/coremidi/JackCoreMidiDriver.cpp | 20 +- macosx/iphone/Info.plist | 2 +- macosx/iphone/freeverb.mm | 28 +- .../iPhoneNet.xcodeproj/project.pbxproj | 279 ++++++ posix/JackSocketServerChannel.cpp | 71 +- posix/JackSocketServerNotifyChannel.cpp | 10 + posix/JackSocketServerNotifyChannel.h | 1 + tests/test.cpp | 24 +- windows/JackRouter/JackRouter.cpp | 840 ++++++++++++++++++ windows/JackRouter/JackRouter.def | 9 + windows/JackRouter/JackRouter.dsp | 163 ++++ windows/JackRouter/JackRouter.dsw | 29 + windows/JackRouter/JackRouter.h | 174 ++++ windows/JackRouter/Psapi.Lib | Bin 0 -> 7230 bytes windows/JackRouter/README | 3 + windows/JackRouter/profport.cpp | 315 +++++++ windows/JackRouter/profport.h | 37 + windows/JackRouter/psapi.dll | Bin 0 -> 23040 bytes windows/JackRouter/psapi.h | 95 ++ windows/JackRouter/resource.h | 15 + windows/JackRouter/resource.rc | 109 +++ windows/JackWinNamedPipeServerChannel.cpp | 43 +- .../JackWinNamedPipeServerNotifyChannel.cpp | 9 + windows/JackWinNamedPipeServerNotifyChannel.h | 1 + windows/Setup/JackRouter.dll | Bin 32768 -> 32768 bytes windows/Setup/jack.ci | 6 +- windows/jack_disconnect.cbp | 2 +- windows/jack_netonedriver.cbp | 107 +++ windows/jack_netsource.cbp | 110 +++ windows/jackaudioadapter.rc | 8 +- windows/jackd.rc | 8 +- windows/jackd.workspace | 7 + windows/jacknetadapter.rc | 8 +- windows/jacknetdriver.rc | 8 +- windows/jacknetmanager.rc | 8 +- windows/jacknetonedriver.rc | 41 + windows/jackportaudio.rc | 8 +- windows/jackwinmme.rc | 8 +- windows/libjack.rc | 8 +- windows/libjackserver.cbp | 2 + windows/libjackserver.rc | 8 +- windows/resource.rc | 8 +- wscript | 21 +- 129 files changed, 5911 insertions(+), 1008 deletions(-) create mode 100644 common/JackPhysicalMidiInput.cpp create mode 100644 common/JackPhysicalMidiInput.h create mode 100644 common/JackPhysicalMidiOutput.cpp create mode 100644 common/JackPhysicalMidiOutput.h create mode 100644 common/jack/weakjack.h create mode 100644 common/jack/weakmacros.h create mode 100644 linux/firewire/JackFFADOMidiInput.cpp create mode 100644 linux/firewire/JackFFADOMidiInput.h create mode 100644 linux/firewire/JackFFADOMidiOutput.cpp create mode 100644 linux/firewire/JackFFADOMidiOutput.h create mode 100644 windows/JackRouter/JackRouter.cpp create mode 100644 windows/JackRouter/JackRouter.def create mode 100644 windows/JackRouter/JackRouter.dsp create mode 100644 windows/JackRouter/JackRouter.dsw create mode 100644 windows/JackRouter/JackRouter.h create mode 100644 windows/JackRouter/Psapi.Lib create mode 100644 windows/JackRouter/README create mode 100644 windows/JackRouter/profport.cpp create mode 100644 windows/JackRouter/profport.h create mode 100644 windows/JackRouter/psapi.dll create mode 100644 windows/JackRouter/psapi.h create mode 100644 windows/JackRouter/resource.h create mode 100644 windows/JackRouter/resource.rc create mode 100644 windows/jack_netonedriver.cbp create mode 100644 windows/jack_netsource.cbp create mode 100644 windows/jacknetonedriver.rc diff --git a/ChangeLog b/ChangeLog index 00471db2..4c2d8e8e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,10 +3,10 @@ --------------------------- Dmitry Baikov +Gabriel M. Beddingfield Steven Chamberlain Thom Johansen Thibault LeMeur -Pieter Palmers Tom Szilagyi Andrzej Szombierski Kjetil S.Matheussen @@ -19,12 +19,75 @@ Romain Moret Florian Faber Michael Voigt Torben Hohn -Paul Davis +Paul Davis +Peter L Jones +Devin Anderson +Josh Green +Mario Lang --------------------------- Jackdmp changes log --------------------------- +2010-01-29 Gabriel M. Beddingfield + + * Change JackEngineProfiling and JackAudioAdapterInterface gnuplot scripts to output SVG instead of PDF. + +2009-12-15 Stephane Letz + + * Shared memory manager was calling abort in case of fatal error, now return an error in caller. + +2009-12-13 Stephane Letz + + * Mario Lang alsa_io time calculation overflow patch. + +2009-12-10 Stephane Letz + + * Use a QUIT notification to properly quit the server channel, the server channel thread can then be 'stopped' instead of 'canceled'. + +2009-12-09 Stephane Letz + + * When threads are cancelled, the exception has to be rethrown. + +2009-12-08 Stephane Letz + + * Josh Green ALSA driver capture only patch. + +2009-12-03 Stephane Letz + + * Fix JackCoreMidiDriver::ReadProcAux when ring buffer is full (thanks Devin Anderson). + +2009-12-02 Stephane Letz + + * Special code in JackCoreAudio driver to handle completely buggy Digidesign CoreAudio user-land driver. + * Ensure that client-side message buffer thread calls thread_init callback if/when it is set by the client (backport of JACK1 rev 3838). + * Check dynamic port-max value. + +2009-12-01 Stephane Letz + + * Fix port_rename callback : now both old name and new name are given as parameters. + +2009-11-30 Stephane Letz + + * Devin Anderson patch for Jack FFADO driver issues with lost MIDI bytes between periods (and more). + +2009-11-29 Stephane Letz + + * More robust sample rate change handling code in JackCoreAudioDriver. + +2009-11-24 Stephane Letz + + * Dynamic choice of maximum port number. + +2009-11-23 Stephane Letz + + * Peter L Jones patch for NetJack1 compilation on Windows. + +2009-11-20 Stephane Letz + + * Version 1.9.5 started. + * Client debugging code improved. + 2009-11-18 Stephane Letz * Sync JackCoreAudioAdapter code with JackCoreAudioDriver. diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index 97e58833..06408833 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -251,7 +251,7 @@ extern "C" static inline bool CheckPort(jack_port_id_t port_index) { - return (port_index > 0 && port_index < PORT_NUM); + return (port_index > 0 && port_index < PORT_NUM_MAX); } static inline bool CheckBufferSize(jack_nframes_t buffer_size) @@ -290,6 +290,9 @@ EXPORT void jack_set_info_function (print_function func) EXPORT jack_client_t* jack_client_new(const char* client_name) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_client_new"); +#endif try { assert(JackGlobals::fOpenMutex); JackGlobals::fOpenMutex->Lock(); @@ -312,7 +315,7 @@ EXPORT jack_client_t* jack_client_new(const char* client_name) EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_get_buffer"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -332,7 +335,7 @@ EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames) EXPORT const char* jack_port_name(const jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_name"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -352,7 +355,7 @@ EXPORT const char* jack_port_name(const jack_port_t* port) EXPORT const char* jack_port_short_name(const jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_short_name"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -372,7 +375,7 @@ EXPORT const char* jack_port_short_name(const jack_port_t* port) EXPORT int jack_port_flags(const jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_flags"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -392,7 +395,7 @@ EXPORT int jack_port_flags(const jack_port_t* port) EXPORT const char* jack_port_type(const jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_type"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -412,7 +415,7 @@ EXPORT const char* jack_port_type(const jack_port_t* port) EXPORT jack_port_type_id_t jack_port_type_id(const jack_port_t *port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_type_id"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -432,7 +435,7 @@ EXPORT jack_port_type_id_t jack_port_type_id(const jack_port_t *port) EXPORT int jack_port_connected(const jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_connected"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -453,7 +456,7 @@ EXPORT int jack_port_connected(const jack_port_t* port) EXPORT int jack_port_connected_to(const jack_port_t* port, const char* port_name) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_connected_to"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -483,7 +486,7 @@ EXPORT int jack_port_connected_to(const jack_port_t* port, const char* port_name EXPORT int jack_port_tie(jack_port_t* src, jack_port_t* dst) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_tie"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t src_aux = (uint64_t)src; @@ -517,7 +520,7 @@ EXPORT int jack_port_tie(jack_port_t* src, jack_port_t* dst) EXPORT int jack_port_untie(jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_untie"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -537,7 +540,7 @@ EXPORT int jack_port_untie(jack_port_t* port) EXPORT jack_nframes_t jack_port_get_latency(jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_get_latency"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -558,7 +561,7 @@ EXPORT jack_nframes_t jack_port_get_latency(jack_port_t* port) EXPORT void jack_port_set_latency(jack_port_t* port, jack_nframes_t frames) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_set_latency"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -578,7 +581,7 @@ EXPORT void jack_port_set_latency(jack_port_t* port, jack_nframes_t frames) EXPORT int jack_recompute_total_latency(jack_client_t* ext_client, jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_recompute_total_latency"); #endif JackClient* client = (JackClient*)ext_client; @@ -604,7 +607,7 @@ EXPORT int jack_recompute_total_latency(jack_client_t* ext_client, jack_port_t* EXPORT int jack_recompute_total_latencies(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_recompute_total_latencies"); #endif JackClient* client = (JackClient*)ext_client; @@ -625,7 +628,7 @@ This is unsafe if case of concurrent access, and should be "serialized" doing a EXPORT int jack_port_set_name(jack_port_t* port, const char* name) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_set_name"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -655,7 +658,7 @@ EXPORT int jack_port_set_name(jack_port_t* port, const char* name) EXPORT int jack_port_set_alias(jack_port_t* port, const char* name) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_set_alias"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -678,7 +681,7 @@ EXPORT int jack_port_set_alias(jack_port_t* port, const char* name) EXPORT int jack_port_unset_alias(jack_port_t* port, const char* name) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_unset_alias"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -701,7 +704,7 @@ EXPORT int jack_port_unset_alias(jack_port_t* port, const char* name) EXPORT int jack_port_get_aliases(const jack_port_t* port, char* const aliases[2]) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_get_aliases"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -721,7 +724,7 @@ EXPORT int jack_port_get_aliases(const jack_port_t* port, char* const aliases[2] EXPORT int jack_port_request_monitor(jack_port_t* port, int onoff) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_request_monitor"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -741,7 +744,7 @@ EXPORT int jack_port_request_monitor(jack_port_t* port, int onoff) EXPORT int jack_port_request_monitor_by_name(jack_client_t* ext_client, const char* port_name, int onoff) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_request_monitor_by_name"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -764,7 +767,7 @@ EXPORT int jack_port_request_monitor_by_name(jack_client_t* ext_client, const ch EXPORT int jack_port_ensure_monitor(jack_port_t* port, int onoff) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_ensure_monitor"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -784,7 +787,7 @@ EXPORT int jack_port_ensure_monitor(jack_port_t* port, int onoff) EXPORT int jack_port_monitoring_input(jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_monitoring_input"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -804,7 +807,7 @@ EXPORT int jack_port_monitoring_input(jack_port_t* port) EXPORT int jack_is_realtime(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_is_realtime"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -819,7 +822,7 @@ EXPORT int jack_is_realtime(jack_client_t* ext_client) EXPORT void jack_on_shutdown(jack_client_t* ext_client, JackShutdownCallback callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_on_shutdown"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -832,7 +835,7 @@ EXPORT void jack_on_shutdown(jack_client_t* ext_client, JackShutdownCallback cal EXPORT void jack_on_info_shutdown(jack_client_t* ext_client, JackInfoShutdownCallback callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_on_info_shutdown"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -845,7 +848,7 @@ EXPORT void jack_on_info_shutdown(jack_client_t* ext_client, JackInfoShutdownCal EXPORT int jack_set_process_callback(jack_client_t* ext_client, JackProcessCallback callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_process_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -859,7 +862,7 @@ EXPORT int jack_set_process_callback(jack_client_t* ext_client, JackProcessCallb EXPORT jack_nframes_t jack_thread_wait(jack_client_t* ext_client, int status) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_thread_wait"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -874,7 +877,7 @@ EXPORT jack_nframes_t jack_thread_wait(jack_client_t* ext_client, int status) EXPORT jack_nframes_t jack_cycle_wait(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_cycle_wait"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -888,7 +891,7 @@ EXPORT jack_nframes_t jack_cycle_wait(jack_client_t* ext_client) EXPORT void jack_cycle_signal(jack_client_t* ext_client, int status) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_cycle_signal"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -901,7 +904,7 @@ EXPORT void jack_cycle_signal(jack_client_t* ext_client, int status) EXPORT int jack_set_process_thread(jack_client_t* ext_client, JackThreadCallback fun, void *arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_process_thread"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -915,7 +918,7 @@ EXPORT int jack_set_process_thread(jack_client_t* ext_client, JackThreadCallback EXPORT int jack_set_freewheel_callback(jack_client_t* ext_client, JackFreewheelCallback freewheel_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_freewheel_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -929,7 +932,7 @@ EXPORT int jack_set_freewheel_callback(jack_client_t* ext_client, JackFreewheelC EXPORT int jack_set_freewheel(jack_client_t* ext_client, int onoff) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_freewheel"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -943,7 +946,7 @@ EXPORT int jack_set_freewheel(jack_client_t* ext_client, int onoff) EXPORT int jack_set_buffer_size(jack_client_t* ext_client, jack_nframes_t buffer_size) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_buffer_size"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -959,7 +962,7 @@ EXPORT int jack_set_buffer_size(jack_client_t* ext_client, jack_nframes_t buffer EXPORT int jack_set_buffer_size_callback(jack_client_t* ext_client, JackBufferSizeCallback bufsize_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_buffer_size_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -973,7 +976,7 @@ EXPORT int jack_set_buffer_size_callback(jack_client_t* ext_client, JackBufferSi EXPORT int jack_set_sample_rate_callback(jack_client_t* ext_client, JackSampleRateCallback srate_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_sample_rate_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -987,7 +990,7 @@ EXPORT int jack_set_sample_rate_callback(jack_client_t* ext_client, JackSampleRa EXPORT int jack_set_client_registration_callback(jack_client_t* ext_client, JackClientRegistrationCallback registration_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_client_registration_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1001,7 +1004,7 @@ EXPORT int jack_set_client_registration_callback(jack_client_t* ext_client, Jack EXPORT int jack_set_port_registration_callback(jack_client_t* ext_client, JackPortRegistrationCallback registration_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_port_registration_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1015,7 +1018,7 @@ EXPORT int jack_set_port_registration_callback(jack_client_t* ext_client, JackPo EXPORT int jack_set_port_connect_callback(jack_client_t* ext_client, JackPortConnectCallback portconnect_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_port_connect_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1029,7 +1032,7 @@ EXPORT int jack_set_port_connect_callback(jack_client_t* ext_client, JackPortCon EXPORT int jack_set_port_rename_callback(jack_client_t* ext_client, JackPortRenameCallback rename_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_port_rename_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1043,7 +1046,7 @@ EXPORT int jack_set_port_rename_callback(jack_client_t* ext_client, JackPortRena EXPORT int jack_set_graph_order_callback(jack_client_t* ext_client, JackGraphOrderCallback graph_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_graph_order_callback"); #endif JackClient* client = (JackClient*)ext_client; jack_log("jack_set_graph_order_callback ext_client %x client %x ", ext_client, client); @@ -1058,7 +1061,7 @@ EXPORT int jack_set_graph_order_callback(jack_client_t* ext_client, JackGraphOrd EXPORT int jack_set_xrun_callback(jack_client_t* ext_client, JackXRunCallback xrun_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_xrun_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1072,7 +1075,7 @@ EXPORT int jack_set_xrun_callback(jack_client_t* ext_client, JackXRunCallback xr EXPORT int jack_set_thread_init_callback(jack_client_t* ext_client, JackThreadInitCallback init_callback, void *arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_thread_init_callback"); #endif JackClient* client = (JackClient*)ext_client; jack_log("jack_set_thread_init_callback ext_client %x client %x ", ext_client, client); @@ -1087,7 +1090,7 @@ EXPORT int jack_set_thread_init_callback(jack_client_t* ext_client, JackThreadIn EXPORT int jack_activate(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_activate"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1101,7 +1104,7 @@ EXPORT int jack_activate(jack_client_t* ext_client) EXPORT int jack_deactivate(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_deactivate"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1115,7 +1118,7 @@ EXPORT int jack_deactivate(jack_client_t* ext_client) EXPORT jack_port_t* jack_port_register(jack_client_t* ext_client, const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_register"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1136,7 +1139,7 @@ EXPORT jack_port_t* jack_port_register(jack_client_t* ext_client, const char* po EXPORT int jack_port_unregister(jack_client_t* ext_client, jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_unregister"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1159,7 +1162,7 @@ EXPORT int jack_port_unregister(jack_client_t* ext_client, jack_port_t* port) EXPORT int jack_port_is_mine(const jack_client_t* ext_client, const jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_is_mine"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1182,7 +1185,7 @@ EXPORT int jack_port_is_mine(const jack_client_t* ext_client, const jack_port_t* EXPORT const char** jack_port_get_connections(const jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_get_connections"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -1204,7 +1207,7 @@ EXPORT const char** jack_port_get_connections(const jack_port_t* port) EXPORT const char** jack_port_get_all_connections(const jack_client_t* ext_client, const jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_get_all_connections"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1231,7 +1234,7 @@ EXPORT const char** jack_port_get_all_connections(const jack_client_t* ext_clien EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t* ext_client, jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_get_total_latency"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1263,7 +1266,7 @@ EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t* ext_client, jac EXPORT int jack_connect(jack_client_t* ext_client, const char* src, const char* dst) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_connect"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1280,7 +1283,7 @@ EXPORT int jack_connect(jack_client_t* ext_client, const char* src, const char* EXPORT int jack_disconnect(jack_client_t* ext_client, const char* src, const char* dst) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_disconnect"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1297,7 +1300,7 @@ EXPORT int jack_disconnect(jack_client_t* ext_client, const char* src, const cha EXPORT int jack_port_disconnect(jack_client_t* ext_client, jack_port_t* src) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_disconnect"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1320,7 +1323,7 @@ EXPORT int jack_port_disconnect(jack_client_t* ext_client, jack_port_t* src) EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_get_sample_rate"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1335,7 +1338,7 @@ EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t* ext_client) EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_get_buffer_size"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1350,7 +1353,7 @@ EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t* ext_client) EXPORT const char** jack_get_ports(jack_client_t* ext_client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_get_ports"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1364,7 +1367,7 @@ EXPORT const char** jack_get_ports(jack_client_t* ext_client, const char* port_n EXPORT jack_port_t* jack_port_by_name(jack_client_t* ext_client, const char* portname) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_by_name"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1391,7 +1394,7 @@ EXPORT jack_port_t* jack_port_by_name(jack_client_t* ext_client, const char* por EXPORT jack_port_t* jack_port_by_id(jack_client_t* ext_client, jack_port_id_t id) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_by_id"); #endif /* jack_port_t* type is actually the port index */ #if defined(__x86_64__) || defined(__ppc64__) @@ -1404,7 +1407,7 @@ EXPORT jack_port_t* jack_port_by_id(jack_client_t* ext_client, jack_port_id_t id EXPORT int jack_engine_takeover_timebase(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_engine_takeover_timebase"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1419,7 +1422,7 @@ EXPORT int jack_engine_takeover_timebase(jack_client_t* ext_client) EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_frames_since_cycle_start"); #endif JackTimer timer; JackEngineControl* control = GetEngineControl(); @@ -1433,13 +1436,16 @@ EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t* ext_cli EXPORT jack_time_t jack_get_time() { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_get_time"); +#endif return GetMicroSeconds(); } EXPORT jack_time_t jack_frames_to_time(const jack_client_t* ext_client, jack_nframes_t frames) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_frames_to_time"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1460,7 +1466,7 @@ EXPORT jack_time_t jack_frames_to_time(const jack_client_t* ext_client, jack_nfr EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t* ext_client, jack_time_t time) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_time_to_frames"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1480,13 +1486,16 @@ EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t* ext_client, jack_ EXPORT jack_nframes_t jack_frame_time(const jack_client_t* ext_client) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_frame_time"); +#endif return jack_time_to_frames(ext_client, GetMicroSeconds()); } EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_last_frame_time"); #endif JackEngineControl* control = GetEngineControl(); return (control) ? control->fFrameTimer.ReadCurrentState()->CurFrame() : 0; @@ -1495,7 +1504,7 @@ EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t* ext_client) EXPORT float jack_cpu_load(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_cpu_load"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1510,7 +1519,7 @@ EXPORT float jack_cpu_load(jack_client_t* ext_client) EXPORT pthread_t jack_client_thread_id(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_client_thread_id"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1524,7 +1533,7 @@ EXPORT pthread_t jack_client_thread_id(jack_client_t* ext_client) EXPORT char* jack_get_client_name(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_get_client_name"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1554,7 +1563,7 @@ EXPORT int jack_port_type_size(void) EXPORT int jack_release_timebase(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_release_timebase"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1568,7 +1577,7 @@ EXPORT int jack_release_timebase(jack_client_t* ext_client) EXPORT int jack_set_sync_callback(jack_client_t* ext_client, JackSyncCallback sync_callback, void *arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_sync_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1582,7 +1591,7 @@ EXPORT int jack_set_sync_callback(jack_client_t* ext_client, JackSyncCallback sy EXPORT int jack_set_sync_timeout(jack_client_t* ext_client, jack_time_t timeout) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_sync_timeout"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1596,7 +1605,7 @@ EXPORT int jack_set_sync_timeout(jack_client_t* ext_client, jack_time_t timeout) EXPORT int jack_set_timebase_callback(jack_client_t* ext_client, int conditional, JackTimebaseCallback timebase_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_timebase_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1610,7 +1619,7 @@ EXPORT int jack_set_timebase_callback(jack_client_t* ext_client, int conditional EXPORT int jack_transport_locate(jack_client_t* ext_client, jack_nframes_t frame) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_transport_locate"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1625,7 +1634,7 @@ EXPORT int jack_transport_locate(jack_client_t* ext_client, jack_nframes_t frame EXPORT jack_transport_state_t jack_transport_query(const jack_client_t* ext_client, jack_position_t* pos) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_transport_query"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1639,7 +1648,7 @@ EXPORT jack_transport_state_t jack_transport_query(const jack_client_t* ext_clie EXPORT jack_nframes_t jack_get_current_transport_frame(const jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_get_current_transport_frame"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1653,7 +1662,7 @@ EXPORT jack_nframes_t jack_get_current_transport_frame(const jack_client_t* ext_ EXPORT int jack_transport_reposition(jack_client_t* ext_client, jack_position_t* pos) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_transport_reposition"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1668,7 +1677,7 @@ EXPORT int jack_transport_reposition(jack_client_t* ext_client, jack_position_t* EXPORT void jack_transport_start(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_transport_start"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1681,7 +1690,7 @@ EXPORT void jack_transport_start(jack_client_t* ext_client) EXPORT void jack_transport_stop(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_transport_stop"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1694,6 +1703,9 @@ EXPORT void jack_transport_stop(jack_client_t* ext_client) // deprecated EXPORT void jack_get_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_get_transport_info"); +#endif jack_error("jack_get_transport_info: deprecated"); if (tinfo) memset(tinfo, 0, sizeof(jack_transport_info_t)); @@ -1701,6 +1713,9 @@ EXPORT void jack_get_transport_info(jack_client_t* ext_client, jack_transport_in EXPORT void jack_set_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_set_transport_info"); +#endif jack_error("jack_set_transport_info: deprecated"); if (tinfo) memset(tinfo, 0, sizeof(jack_transport_info_t)); @@ -1710,7 +1725,7 @@ EXPORT void jack_set_transport_info(jack_client_t* ext_client, jack_transport_in EXPORT float jack_get_max_delayed_usecs(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_get_max_delayed_usecs"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1725,7 +1740,7 @@ EXPORT float jack_get_max_delayed_usecs(jack_client_t* ext_client) EXPORT float jack_get_xrun_delayed_usecs(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_get_xrun_delayed_usecs"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1740,7 +1755,7 @@ EXPORT float jack_get_xrun_delayed_usecs(jack_client_t* ext_client) EXPORT void jack_reset_max_delayed_usecs(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_reset_max_delayed_usecs"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1755,7 +1770,7 @@ EXPORT void jack_reset_max_delayed_usecs(jack_client_t* ext_client) EXPORT int jack_client_real_time_priority(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_client_real_time_priority"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1770,7 +1785,7 @@ EXPORT int jack_client_real_time_priority(jack_client_t* ext_client) EXPORT int jack_client_max_real_time_priority(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_client_max_real_time_priority"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1795,6 +1810,9 @@ EXPORT int jack_client_create_thread(jack_client_t* client, thread_routine routine, void *arg) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_client_create_thread"); +#endif return JackThread::StartImp(thread, priority, realtime, routine, arg); } @@ -1805,11 +1823,17 @@ EXPORT int jack_drop_real_time_scheduling(pthread_t thread) EXPORT int jack_client_stop_thread(jack_client_t* client, pthread_t thread) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_client_stop_thread"); +#endif return JackThread::StopImp(thread); } EXPORT int jack_client_kill_thread(jack_client_t* client, pthread_t thread) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_client_kill_thread"); +#endif return JackThread::KillImp(thread); } @@ -1837,7 +1861,7 @@ EXPORT void jack_internal_client_close (const char *client_name) EXPORT char* jack_get_internal_client_name(jack_client_t* ext_client, jack_intclient_t intclient) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_get_internal_client_name"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1854,7 +1878,7 @@ EXPORT char* jack_get_internal_client_name(jack_client_t* ext_client, jack_intcl EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t* ext_client, const char* client_name, jack_status_t* status) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_internal_client_handle"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1872,7 +1896,7 @@ EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t* ext_client, c EXPORT jack_intclient_t jack_internal_client_load_aux(jack_client_t* ext_client, const char* client_name, jack_options_t options, jack_status_t* status, va_list ap) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_internal_client_load_aux"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1911,7 +1935,7 @@ EXPORT jack_intclient_t jack_internal_client_load(jack_client_t *client, const c EXPORT jack_status_t jack_internal_client_unload(jack_client_t* ext_client, jack_intclient_t intclient) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_internal_client_load"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { diff --git a/common/JackAudioAdapterInterface.cpp b/common/JackAudioAdapterInterface.cpp index a347ca12..f765d032 100644 --- a/common/JackAudioAdapterInterface.cpp +++ b/common/JackAudioAdapterInterface.cpp @@ -17,10 +17,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "JackAudioAdapter.h" #ifdef __APPLE__ #include #endif + +#include "JackAudioAdapter.h" #ifndef TARGET_OS_IPHONE #include "JackLibSampleRateResampler.h" #endif @@ -73,8 +74,8 @@ namespace Jack fprintf(file, buffer); fprintf(file, "\n unset multiplot\n"); - fprintf(file, "set output 'AdapterTiming1.pdf\n"); - fprintf(file, "set terminal pdf\n"); + fprintf(file, "set output 'AdapterTiming1.svg\n"); + fprintf(file, "set terminal svg\n"); fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); @@ -85,8 +86,10 @@ namespace Jack fprintf(file, "plot "); sprintf(buffer, "\"JackAudioAdapter.log\" using 2 title \"Consumer interrupt period\" with lines,"); fprintf(file, buffer); - sprintf(buffer, "\"JackAudioAdapter.log\" using 3 title \"Producer interrupt period\" with lines"); + sprintf(buffer, "\"JackAudioAdapter.log\" using 3 title \"Producer interrupt period\" with lines\n"); fprintf(file, buffer); + fprintf(file, "unset multiplot\n"); + fprintf(file, "unset output\n"); fclose(file); @@ -105,8 +108,8 @@ namespace Jack fprintf(file, buffer); fprintf(file, "\n unset multiplot\n"); - fprintf(file, "set output 'AdapterTiming2.pdf\n"); - fprintf(file, "set terminal pdf\n"); + fprintf(file, "set output 'AdapterTiming2.svg\n"); + fprintf(file, "set terminal svg\n"); fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); @@ -117,8 +120,10 @@ namespace Jack fprintf(file, "plot "); sprintf(buffer, "\"JackAudioAdapter.log\" using 4 title \"Ratio 1\" with lines,"); fprintf(file, buffer); - sprintf(buffer, "\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with lines"); + sprintf(buffer, "\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with lines\n"); fprintf(file, buffer); + fprintf(file, "unset multiplot\n"); + fprintf(file, "unset output\n"); fclose(file); @@ -137,8 +142,8 @@ namespace Jack fprintf(file, buffer); fprintf(file, "\n unset multiplot\n"); - fprintf(file, "set output 'AdapterTiming3.pdf\n"); - fprintf(file, "set terminal pdf\n"); + fprintf(file, "set output 'AdapterTiming3.svg\n"); + fprintf(file, "set terminal svg\n"); fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); @@ -149,8 +154,10 @@ namespace Jack fprintf(file, "plot "); sprintf(buffer, "\"JackAudioAdapter.log\" using 6 title \"Frames position in consumer ringbuffer\" with lines,"); fprintf(file, buffer); - sprintf(buffer, "\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with lines"); + sprintf(buffer, "\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with lines\n"); fprintf(file, buffer); + fprintf(file, "unset multiplot\n"); + fprintf(file, "unset output\n"); fclose(file); } diff --git a/common/JackClient.cpp b/common/JackClient.cpp index e6469267..d4359f83 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -254,7 +254,7 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, case kPortRenameCallback: jack_log("JackClient::kPortRenameCallback port = %ld"); if (fPortRename) { - fPortRename(value1, GetGraphManager()->GetPort(value1)->GetName(), fPortRenameArg); + fPortRename(value1, message, GetGraphManager()->GetPort(value1)->GetName(), fPortRenameArg); } break; @@ -848,6 +848,8 @@ int JackClient::SetInitCallback(JackThreadInitCallback callback, void *arg) } else { fInitArg = arg; fInit = callback; + /* make sure that the message buffer thread is initialized too */ + JackMessageBuffer::fInstance->SetInitCallback(callback, arg); return 0; } } diff --git a/common/JackConnectionManager.cpp b/common/JackConnectionManager.cpp index 043b0c81..f6a74dca 100644 --- a/common/JackConnectionManager.cpp +++ b/common/JackConnectionManager.cpp @@ -33,7 +33,7 @@ JackConnectionManager::JackConnectionManager() int i; jack_log("JackConnectionManager::InitConnections size = %ld ", sizeof(JackConnectionManager)); - for (i = 0; i < PORT_NUM; i++) { + for (i = 0; i < PORT_NUM_MAX; i++) { fConnection[i].Init(); } diff --git a/common/JackConnectionManager.h b/common/JackConnectionManager.h index 47543038..5d5b8c62 100644 --- a/common/JackConnectionManager.h +++ b/common/JackConnectionManager.h @@ -353,11 +353,21 @@ struct JackClientTiming jack_time_t fFinishedAt; jack_client_state_t fStatus; - JackClientTiming(): fSignaledAt(0), fAwakeAt(0), fFinishedAt(0), fStatus(NotTriggered) - {} + JackClientTiming() + { + Init(); + } ~JackClientTiming() {} + void Init() + { + fSignaledAt = 0; + fAwakeAt = 0; + fFinishedAt = 0; + fStatus = NotTriggered; + } + } POST_PACKED_STRUCTURE; /*! @@ -379,7 +389,7 @@ class SERVER_EXPORT JackConnectionManager private: - JackFixedArray fConnection[PORT_NUM]; /*! Connection matrix: list of connected ports for a given port: needed to compute Mix buffer */ + JackFixedArray fConnection[PORT_NUM_MAX]; /*! Connection matrix: list of connected ports for a given port: needed to compute Mix buffer */ JackFixedArray1 fInputPort[CLIENT_NUM]; /*! Table of input port per refnum : to find a refnum for a given port */ JackFixedArray fOutputPort[CLIENT_NUM]; /*! Table of output port per refnum : to find a refnum for a given port */ JackFixedMatrix fConnectionRef; /*! Table of port connections by (refnum , refnum) */ diff --git a/common/JackConstants.h b/common/JackConstants.h index aa6e0ce5..60a631c3 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -24,7 +24,7 @@ #include "config.h" #endif -#define VERSION "1.9.4" +#define VERSION "1.9.5" #define BUFFER_SIZE_MAX 8192 @@ -38,6 +38,8 @@ #define PORT_NUM 2048 #endif +#define PORT_NUM_MAX 4096 // The "max" value for ports used in connection manager, although port number in graph manager is dynamic + #define DRIVER_PORT_NUM 256 #ifndef PORT_NUM_FOR_CLIENT diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index 37eeb88a..f4850207 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -82,7 +82,11 @@ struct jackctl_server /* uint32_t, clock source type */ union jackctl_parameter_value clock_source; union jackctl_parameter_value default_clock_source; - + + /* uint32_t, max port number */ + union jackctl_parameter_value port_max; + union jackctl_parameter_value default_port_max; + /* bool */ union jackctl_parameter_value replace_registry; union jackctl_parameter_value default_replace_registry; @@ -741,6 +745,20 @@ EXPORT jackctl_server_t * jackctl_server_create( { goto fail_free_parameters; } + + value.ui = PORT_NUM; + if (jackctl_add_parameter( + &server_ptr->parameters, + "port-max", + "Maximum number of ports.", + "", + JackParamUInt, + &server_ptr->port_max, + &server_ptr->default_port_max, + value) == NULL) + { + goto fail_free_parameters; + } value.b = false; if (jackctl_add_parameter( @@ -864,15 +882,21 @@ jackctl_server_start( if (!server_ptr->realtime.b && server_ptr->client_timeout.i == 0) server_ptr->client_timeout.i = 500; /* 0.5 sec; usable when non realtime. */ + + /* check port max value before allocating server */ + if (server_ptr->port_max.ui > PORT_NUM_MAX) { + jack_error("JACK server started with too much ports %d (when port max can be %d)", server_ptr->port_max.ui, PORT_NUM_MAX); + goto fail; + } /* get the engine/driver started */ - server_ptr->engine = new JackServer( server_ptr->sync.b, server_ptr->temporary.b, server_ptr->client_timeout.i, server_ptr->realtime.b, server_ptr->realtime_priority.i, + server_ptr->port_max.ui, server_ptr->verbose.b, (jack_timer_type_t)server_ptr->clock_source.ui, server_ptr->name.str); diff --git a/common/JackDebugClient.cpp b/common/JackDebugClient.cpp index a2a61d8d..6a90fcdc 100644 --- a/common/JackDebugClient.cpp +++ b/common/JackDebugClient.cpp @@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackDebugClient.h" #include "JackEngineControl.h" +#include "JackException.h" #include "JackError.h" #include "JackTime.h" #include @@ -55,9 +56,9 @@ JackDebugClient::~JackDebugClient() *fStream << setw(5) << "- Total number of instantiated port : " << fTotalPortNumber << endl; *fStream << setw(5) << "- Number of port remaining open when exiting client : " << fOpenPortNumber << endl; if (fOpenPortNumber != 0) - *fStream << "!!! WARNING !!! Some ports have not been unregistrated ! Incorrect exiting !" << endl; + *fStream << "!!! WARNING !!! Some ports have not been unregistered ! Incorrect exiting !" << endl; if (fIsDeactivated != fIsActivated) - *fStream << "!!! ERROR !!! Client seem do not perform symetric activation-deactivation ! (not the same number of activate and deactivate)" << endl; + *fStream << "!!! ERROR !!! Client seem to not perform symetric activation-deactivation ! (not the same number of activate and deactivate)" << endl; if (fIsClosed == 0) *fStream << "!!! ERROR !!! Client have not been closed with jack_client_close() !" << endl; @@ -68,9 +69,9 @@ JackDebugClient::~JackDebugClient() *fStream << setw(5) << "- Name : " << fPortList[i].name << endl; *fStream << setw(5) << "- idport : " << fPortList[i].idport << endl; *fStream << setw(5) << "- IsConnected : " << fPortList[i].IsConnected << endl; - *fStream << setw(5) << "- IsUnregistrated : " << fPortList[i].IsUnregistrated << endl; - if (fPortList[i].IsUnregistrated == 0) - *fStream << "!!! WARNING !!! Port have not been unregistrated ! Incorrect exiting !" << endl; + *fStream << setw(5) << "- IsUnregistered : " << fPortList[i].IsUnregistered << endl; + if (fPortList[i].IsUnregistered == 0) + *fStream << "!!! WARNING !!! Port have not been unregistered ! Incorrect exiting !" << endl; } *fStream << "delete object JackDebugClient : end of tracing" << endl; delete fStream; @@ -106,33 +107,39 @@ int JackDebugClient::Open(const char* server_name, const char* name, jack_option int JackDebugClient::Close() { - fIsClosed++; *fStream << "Client '" << fClientName << "' was closed" << endl; - return fClient->Close(); + int res = fClient->Close(); + fIsClosed++; + return res; } -void JackDebugClient::CheckClient() const +void JackDebugClient::CheckClient(const char* function_name) const { + *fStream << "CheckClient : " << function_name << ", calling thread : " << pthread_self() << endl; + if (fIsClosed > 0) { - *fStream << "!!! ERROR !!! : Accessing a client '" << fClientName << "' already closed !" << endl; + *fStream << "!!! ERROR !!! : Accessing a client '" << fClientName << "' already closed " << "from " << function_name << endl; *fStream << "This is likely to cause crash !'" << endl; + #ifdef __APPLE__ + // Debugger(); + #endif } } pthread_t JackDebugClient::GetThreadID() { - CheckClient(); + CheckClient("GetThreadID"); return fClient->GetThreadID(); } JackGraphManager* JackDebugClient::GetGraphManager() const { - CheckClient(); + CheckClient("GetGraphManager"); return fClient->GetGraphManager(); } JackEngineControl* JackDebugClient::GetEngineControl() const { - CheckClient(); + CheckClient("GetEngineControl"); return fClient->GetEngineControl(); } /*! @@ -141,13 +148,13 @@ JackEngineControl* JackDebugClient::GetEngineControl() const int JackDebugClient::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { - CheckClient(); + CheckClient("ClientNotify"); return fClient->ClientNotify( refnum, name, notify, sync, message, value1, value2); } int JackDebugClient::Activate() { - CheckClient(); + CheckClient("Activate"); int res = fClient->Activate(); fIsActivated++; if (fIsDeactivated) @@ -160,7 +167,7 @@ int JackDebugClient::Activate() int JackDebugClient::Deactivate() { - CheckClient(); + CheckClient("Deactivate"); int res = fClient->Deactivate(); fIsDeactivated++; if (fIsActivated == 0) @@ -177,7 +184,7 @@ int JackDebugClient::Deactivate() int JackDebugClient::PortRegister(const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size) { - CheckClient(); + CheckClient("PortRegister"); int res = fClient->PortRegister(port_name, port_type, flags, buffer_size); if (res <= 0) { *fStream << "Client '" << fClientName << "' try port register ('" << port_name << "') and server return error " << res << " ." << endl; @@ -186,7 +193,7 @@ int JackDebugClient::PortRegister(const char* port_name, const char* port_type, fPortList[fTotalPortNumber].idport = res; strcpy(fPortList[fTotalPortNumber].name, port_name); fPortList[fTotalPortNumber].IsConnected = 0; - fPortList[fTotalPortNumber].IsUnregistrated = 0; + fPortList[fTotalPortNumber].IsUnregistered = 0; } else { *fStream << "!!! WARNING !!! History is full : no more port history will be recorded." << endl; } @@ -199,42 +206,42 @@ int JackDebugClient::PortRegister(const char* port_name, const char* port_type, int JackDebugClient::PortUnRegister(jack_port_id_t port_index) { - CheckClient(); + CheckClient("PortUnRegister"); int res = fClient->PortUnRegister(port_index); fOpenPortNumber--; int i; for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history if (fPortList[i].idport == port_index) { // We found the last record - if (fPortList[i].IsUnregistrated != 0) + if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! : '" << fClientName << "' id deregistering port '" << fPortList[i].name << "' that have already been unregistered !" << endl; - fPortList[i].IsUnregistrated++; + fPortList[i].IsUnregistered++; break; } } if (i == 0) // Port is not found *fStream << "JackClientDebug : PortUnregister : port " << port_index << " was not previously registered !" << endl; if (res != 0) - *fStream << "Client '" << fClientName << "' try to do PortUnregister and server return " << res << " )." << endl; + *fStream << "Client '" << fClientName << "' try to do PortUnregister and server return " << res << endl; *fStream << "Client '" << fClientName << "' unregister port '" << port_index << "'." << endl; return res; } int JackDebugClient::PortConnect(const char* src, const char* dst) { - CheckClient(); + CheckClient("PortConnect"); if (!fIsActivated) *fStream << "!!! ERROR !!! Trying to connect a port ( " << src << " to " << dst << ") while the client has not been activated !" << endl; int i; int res = fClient->PortConnect( src, dst); for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history if (strcmp(fPortList[i].name, src) == 0) { // We found the last record in sources - if (fPortList[i].IsUnregistrated != 0) + if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! Connecting port " << src << " previoulsy unregistered !" << endl; fPortList[i].IsConnected++; *fStream << "Connecting port " << src << " to " << dst << ". "; break; } else if (strcmp(fPortList[i].name, dst) == 0 ) { // We found the record in dest - if (fPortList[i].IsUnregistrated != 0) + if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! Connecting port " << dst << " previoulsy unregistered !" << endl; fPortList[i].IsConnected++; *fStream << "Connecting port " << src << " to " << dst << ". "; @@ -251,20 +258,20 @@ int JackDebugClient::PortConnect(const char* src, const char* dst) int JackDebugClient::PortDisconnect(const char* src, const char* dst) { - CheckClient(); + CheckClient("PortDisconnect"); if (!fIsActivated) *fStream << "!!! ERROR !!! Trying to disconnect a port ( " << src << " to " << dst << ") while the client has not been activated !" << endl; int res = fClient->PortDisconnect( src, dst); int i; for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history if (strcmp(fPortList[i].name, src) == 0) { // We found the record in sources - if (fPortList[i].IsUnregistrated != 0) + if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! : Disconnecting port " << src << " previoulsy unregistered !" << endl; fPortList[i].IsConnected--; *fStream << "disconnecting port " << src << ". "; break; } else if (strcmp(fPortList[i].name, dst) == 0 ) { // We found the record in dest - if (fPortList[i].IsUnregistrated != 0) + if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! : Disonnecting port " << dst << " previoulsy unregistered !" << endl; fPortList[i].IsConnected--; *fStream << "disconnecting port " << dst << ". "; @@ -281,14 +288,14 @@ int JackDebugClient::PortDisconnect(const char* src, const char* dst) int JackDebugClient::PortDisconnect(jack_port_id_t src) { - CheckClient(); + CheckClient("PortDisconnect"); if (!fIsActivated) *fStream << "!!! ERROR !!! : Trying to disconnect port " << src << " while that client has not been activated !" << endl; int res = fClient->PortDisconnect(src); int i; for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history if (fPortList[i].idport == src) { // We found the record in sources - if (fPortList[i].IsUnregistrated != 0) + if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! : Disconnecting port " << src << " previoulsy unregistered !" << endl; fPortList[i].IsConnected--; *fStream << "Disconnecting port " << src << ". " << endl; @@ -305,7 +312,7 @@ int JackDebugClient::PortDisconnect(jack_port_id_t src) int JackDebugClient::PortIsMine(jack_port_id_t port_index) { - CheckClient(); + CheckClient("PortIsMine"); return fClient->PortIsMine(port_index); } @@ -315,13 +322,13 @@ int JackDebugClient::PortIsMine(jack_port_id_t port_index) int JackDebugClient::SetBufferSize(jack_nframes_t buffer_size) { - CheckClient(); + CheckClient("SetBufferSize"); return fClient->SetBufferSize(buffer_size); } int JackDebugClient::SetFreeWheel(int onoff) { - CheckClient(); + CheckClient("SetFreeWheel"); if (onoff && fFreewheel) *fStream << "!!! ERROR !!! : Freewheel setup seems incorrect : set = ON while FW is already ON " << endl; if (!onoff && !fFreewheel) @@ -348,61 +355,61 @@ void JackDebugClient::ShutDown() int JackDebugClient::ReleaseTimebase() { - CheckClient(); + CheckClient("ReleaseTimebase"); return fClient->ReleaseTimebase(); } int JackDebugClient::SetSyncCallback(JackSyncCallback sync_callback, void* arg) { - CheckClient(); + CheckClient("SetSyncCallback"); return fClient->SetSyncCallback(sync_callback, arg); } int JackDebugClient::SetSyncTimeout(jack_time_t timeout) { - CheckClient(); + CheckClient("SetSyncTimeout"); return fClient->SetSyncTimeout(timeout); } int JackDebugClient::SetTimebaseCallback(int conditional, JackTimebaseCallback timebase_callback, void* arg) { - CheckClient(); + CheckClient("SetTimebaseCallback"); return fClient->SetTimebaseCallback( conditional, timebase_callback, arg); } void JackDebugClient::TransportLocate(jack_nframes_t frame) { - CheckClient(); + CheckClient("TransportLocate"); fClient->TransportLocate(frame); } jack_transport_state_t JackDebugClient::TransportQuery(jack_position_t* pos) { - CheckClient(); + CheckClient("TransportQuery"); return fClient->TransportQuery(pos); } jack_nframes_t JackDebugClient::GetCurrentTransportFrame() { - CheckClient(); + CheckClient("GetCurrentTransportFrame"); return fClient->GetCurrentTransportFrame(); } int JackDebugClient::TransportReposition(jack_position_t* pos) { - CheckClient(); + CheckClient("TransportReposition"); return fClient->TransportReposition(pos); } void JackDebugClient::TransportStart() { - CheckClient(); + CheckClient("TransportStart"); fClient->TransportStart(); } void JackDebugClient::TransportStop() { - CheckClient(); + CheckClient("TransportStop"); fClient->TransportStop(); } @@ -412,13 +419,13 @@ void JackDebugClient::TransportStop() void JackDebugClient::OnShutdown(JackShutdownCallback callback, void *arg) { - CheckClient(); + CheckClient("OnShutdown"); fClient->OnShutdown(callback, arg); } void JackDebugClient::OnInfoShutdown(JackInfoShutdownCallback callback, void *arg) { - CheckClient(); + CheckClient("OnInfoShutdown"); fClient->OnInfoShutdown(callback, arg); } @@ -427,16 +434,18 @@ int JackDebugClient::TimeCallback(jack_nframes_t nframes, void *arg) JackDebugClient* client = (JackDebugClient*)arg; jack_time_t t1 = GetMicroSeconds(); int res = client->fProcessTimeCallback(nframes, client->fProcessTimeCallbackArg); + if (res == 0) { jack_time_t t2 = GetMicroSeconds(); - long delta = long((t2 - t1) - client->GetEngineControl()->fPeriodUsecs); - if (delta > 0 && !client->fFreewheel) - *client->fStream << "!!! ERROR !!! : Process overload of " << delta << " us" << endl; + long delta = long((t2 - t1) - client->GetEngineControl()->fPeriodUsecs); + if (delta > 0 && !client->fFreewheel) + *client->fStream << "!!! ERROR !!! : Process overload of " << delta << " us" << endl; + } return res; } int JackDebugClient::SetProcessCallback(JackProcessCallback callback, void *arg) { - CheckClient(); + CheckClient("SetProcessCallback"); fProcessTimeCallback = callback; fProcessTimeCallbackArg = arg; return fClient->SetProcessCallback(TimeCallback, this); @@ -444,86 +453,86 @@ int JackDebugClient::SetProcessCallback(JackProcessCallback callback, void *arg) int JackDebugClient::SetXRunCallback(JackXRunCallback callback, void *arg) { - CheckClient(); + CheckClient("SetXRunCallback"); return fClient->SetXRunCallback(callback, arg); } int JackDebugClient::SetInitCallback(JackThreadInitCallback callback, void *arg) { - CheckClient(); + CheckClient("SetInitCallback"); return fClient->SetInitCallback(callback, arg); } int JackDebugClient::SetGraphOrderCallback(JackGraphOrderCallback callback, void *arg) { - CheckClient(); + CheckClient("SetGraphOrderCallback"); return fClient->SetGraphOrderCallback(callback, arg); } int JackDebugClient::SetBufferSizeCallback(JackBufferSizeCallback callback, void *arg) { - CheckClient(); + CheckClient("SetBufferSizeCallback"); return fClient->SetBufferSizeCallback(callback, arg); } int JackDebugClient::SetClientRegistrationCallback(JackClientRegistrationCallback callback, void* arg) { - CheckClient(); + CheckClient("SetClientRegistrationCallback"); return fClient->SetClientRegistrationCallback(callback, arg); } int JackDebugClient::SetFreewheelCallback(JackFreewheelCallback callback, void *arg) { - CheckClient(); + CheckClient("SetFreewheelCallback"); return fClient->SetFreewheelCallback(callback, arg); } int JackDebugClient::SetPortRegistrationCallback(JackPortRegistrationCallback callback, void *arg) { - CheckClient(); + CheckClient("SetPortRegistrationCallback"); return fClient->SetPortRegistrationCallback(callback, arg); } int JackDebugClient::SetPortConnectCallback(JackPortConnectCallback callback, void *arg) { - CheckClient(); + CheckClient("SetPortConnectCallback"); return fClient->SetPortConnectCallback(callback, arg); } int JackDebugClient::SetPortRenameCallback(JackPortRenameCallback callback, void *arg) { - CheckClient(); + CheckClient("SetPortRenameCallback"); return fClient->SetPortRenameCallback(callback, arg); } JackClientControl* JackDebugClient::GetClientControl() const { - CheckClient(); + CheckClient("GetClientControl"); return fClient->GetClientControl(); } // Internal clients char* JackDebugClient::GetInternalClientName(int ref) { - CheckClient(); + CheckClient("GetInternalClientName"); return fClient->GetInternalClientName(ref); } int JackDebugClient::InternalClientHandle(const char* client_name, jack_status_t* status) { - CheckClient(); + CheckClient("InternalClientHandle"); return fClient->InternalClientHandle(client_name, status); } int JackDebugClient::InternalClientLoad(const char* client_name, jack_options_t options, jack_status_t* status, jack_varargs_t* va) { - CheckClient(); + CheckClient("InternalClientLoad"); return fClient->InternalClientLoad(client_name, options, status, va); } void JackDebugClient::InternalClientUnload(int ref, jack_status_t* status) { - CheckClient(); + CheckClient("InternalClientUnload"); fClient->InternalClientUnload(ref, status); } diff --git a/common/JackDebugClient.h b/common/JackDebugClient.h index 0bb21b20..6a31f432 100644 --- a/common/JackDebugClient.h +++ b/common/JackDebugClient.h @@ -38,7 +38,7 @@ typedef struct jack_port_id_t idport; char name[JACK_PORT_NAME_SIZE]; //portname int IsConnected; - int IsUnregistrated; + int IsUnregistered; } PortFollower; @@ -129,7 +129,7 @@ class JackDebugClient : public JackClient void InternalClientUnload(int ref, jack_status_t* status); JackClientControl* GetClientControl() const; - void CheckClient() const; + void CheckClient(const char* function_name) const; static int TimeCallback(jack_nframes_t nframes, void *arg); }; diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index bab5db0f..a485d810 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -167,7 +167,7 @@ int JackDriver::Open(jack_nframes_t buffer_size, int JackDriver::Close() { - if (fClientControl.fRefNum > 0) { + if (fClientControl.fRefNum >= 0) { jack_log("JackDriver::Close"); fGraphManager->DirectDisconnect(fClientControl.fRefNum, fClientControl.fRefNum); // Disconnect driver from itself for sync fClientControl.fActive = false; diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index 537c4160..fabebb01 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -89,6 +89,11 @@ int JackEngine::Close() return 0; } + +void JackEngine::NotifyQuit() +{ + fChannel.NotifyQuit(); +} //----------------------------- // Client ressource management @@ -322,9 +327,9 @@ void JackEngine::NotifyPortRegistation(jack_port_id_t port_index, bool onoff) NotifyClients((onoff ? kPortRegistrationOnCallback : kPortRegistrationOffCallback), false, "", port_index, 0); } -void JackEngine::NotifyPortRename(jack_port_id_t port) +void JackEngine::NotifyPortRename(jack_port_id_t port, const char* old_name) { - NotifyClients(kPortRenameCallback, false, "", port, 0); + NotifyClients(kPortRenameCallback, false, old_name, port, 0); } void JackEngine::NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst, bool onoff) @@ -846,8 +851,10 @@ int JackEngine::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t ds int JackEngine::PortRename(int refnum, jack_port_id_t port, const char* name) { AssertRefnum(refnum); + char old_name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + strcpy(old_name, fGraphManager->GetPort(port)->GetName()); fGraphManager->GetPort(port)->SetName(name); - NotifyPortRename(port); + NotifyPortRename(port, old_name); return 0; } diff --git a/common/JackEngine.h b/common/JackEngine.h index 8212daf9..3a4a24a9 100644 --- a/common/JackEngine.h +++ b/common/JackEngine.h @@ -69,7 +69,7 @@ class SERVER_EXPORT JackEngine void NotifyPortRegistation(jack_port_id_t port_index, bool onoff); void NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst, bool onoff); - void NotifyPortRename(jack_port_id_t src); + void NotifyPortRename(jack_port_id_t src, const char* old_name); void NotifyActivate(int refnum); public: @@ -79,7 +79,7 @@ class SERVER_EXPORT JackEngine int Open(); int Close(); - + // Client management int ClientCheck(const char* name, char* name_res, int protocol, int options, int* status); int ClientExternalOpen(const char* name, int pid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager); @@ -122,6 +122,7 @@ class SERVER_EXPORT JackEngine void NotifyBufferSize(jack_nframes_t buffer_size); void NotifySampleRate(jack_nframes_t sample_rate); void NotifyFreewheel(bool onoff); + void NotifyQuit(); }; diff --git a/common/JackEngineProfiling.cpp b/common/JackEngineProfiling.cpp index b0a1b441..4557fec9 100644 --- a/common/JackEngineProfiling.cpp +++ b/common/JackEngineProfiling.cpp @@ -25,6 +25,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackGlobals.h" #include "JackTime.h" +#include +#include + namespace Jack { @@ -38,12 +41,10 @@ JackEngineProfiling::JackEngineProfiling():fAudioCycle(0),fMeasuredClient(0) JackEngineProfiling::~JackEngineProfiling() { - FILE* file = fopen("JackEngineProfiling.log", "w"); - char buffer[1024]; - + std::ofstream fStream("JackEngineProfiling.log", std::ios_base::ate); jack_info("Write server and clients timing data..."); - if (file == NULL) { + if (!fStream.is_open()) { jack_error("JackEngineProfiling::Save cannot open JackEngineProfiling.log file"); } else { @@ -58,7 +59,7 @@ JackEngineProfiling::~JackEngineProfiling() continue; // Skip non valid cycles // Print driver delta and end cycle - fprintf(file, "%ld \t %ld \t", d1, d2); + fStream << d1 << "\t" << d2 << "\t"; // For each measured client for (unsigned int j = 0; j < fMeasuredClient; j++) { @@ -71,222 +72,261 @@ JackEngineProfiling::~JackEngineProfiling() long d5 = long(fProfileTable[i].fClientTable[ref].fSignaledAt - fProfileTable[i - 1].fCurCycleBegin); long d6 = long(fProfileTable[i].fClientTable[ref].fAwakeAt - fProfileTable[i - 1].fCurCycleBegin); long d7 = long(fProfileTable[i].fClientTable[ref].fFinishedAt - fProfileTable[i - 1].fCurCycleBegin); - - // Print ref, signal, start, end, scheduling, duration, status - fprintf(file, "%d \t %ld \t %ld \t %ld \t %ld \t %ld \t %d \t", - ref, - ((d5 > 0) ? d5 : 0), - ((d6 > 0) ? d6 : 0), - ((d7 > 0) ? d7 : 0), - ((d6 > 0 && d5 > 0) ? (d6 - d5) : 0), - ((d7 > 0 && d6 > 0) ? (d7 - d6) : 0), - fProfileTable[i].fClientTable[ref].fStatus); - } else { // Print tabs - fprintf(file, "\t \t \t \t \t \t \t"); + + fStream << ref << "\t" ; + fStream << ((d5 > 0) ? d5 : 0) << "\t"; + fStream << ((d6 > 0) ? d6 : 0) << "\t" ; + fStream << ((d7 > 0) ? d7 : 0) << "\t"; + fStream << ((d6 > 0 && d5 > 0) ? (d6 - d5) : 0) << "\t" ; + fStream << ((d7 > 0 && d6 > 0) ? (d7 - d6) : 0) << "\t" ; + fStream << fProfileTable[i].fClientTable[ref].fStatus << "\t" ;; + + } else { // Print tabs + fStream << "\t \t \t \t \t \t \t"; } } // Terminate line - fprintf(file, "\n"); + fStream << std::endl; } } // Driver period - file = fopen("Timing1.plot", "w"); - - if (file == NULL) { - jack_error("JackEngineProfiling::Save cannot open Timing1.log file"); + std::ofstream fStream1("Timing1.plot", std::ios_base::ate); + + if (!fStream1.is_open()) { + jack_error("JackEngineProfiling::Save cannot open Timing1.plot file"); } else { - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Audio driver timing\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot \"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines \n"); - - fprintf(file, "set output 'Timing1.pdf\n"); - fprintf(file, "set terminal pdf\n"); - - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Audio driver timing\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot \"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines \n"); - - fclose(file); + fStream1 << "set grid\n"; + fStream1 << "set title \"Audio driver timing\"\n"; + fStream1 << "set xlabel \"audio cycles\"\n"; + fStream1 << "set ylabel \"usec\"\n"; + fStream1 << "plot \"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines \n"; + + fStream1 << "set output 'Timing1.svg\n"; + fStream1 << "set terminal svg\n"; + + fStream1 << "set grid\n"; + fStream1 << "set title \"Audio driver timing\"\n"; + fStream1 << "set xlabel \"audio cycles\"\n"; + fStream1 << "set ylabel \"usec\"\n"; + fStream1 << "plot \"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines \n"; + fStream1 << "unset output\n"; } // Driver end date - file = fopen("Timing2.plot", "w"); - - if (file == NULL) { - jack_error("JackEngineProfiling::Save cannot open Timing2.log file"); + std::ofstream fStream2("Timing2.plot", std::ios_base::ate); + + if (!fStream2.is_open()) { + jack_error("JackEngineProfiling::Save cannot open Timing2.plot file"); } else { - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Driver end date\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot \"JackEngineProfiling.log\" using 2 title \"Driver end date\" with lines \n"); + fStream2 << "set grid\n"; + fStream2 << "set title \"Driver end date\"\n"; + fStream2 << "set xlabel \"audio cycles\"\n"; + fStream2 << "set ylabel \"usec\"\n"; + fStream2 << "plot \"JackEngineProfiling.log\" using 2 title \"Driver end date\" with lines \n"; - fprintf(file, "set output 'Timing2.pdf\n"); - fprintf(file, "set terminal pdf\n"); + fStream2 << "set output 'Timing2.svg\n"; + fStream2 << "set terminal svg\n"; - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Driver end date\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot \"JackEngineProfiling.log\" using 2 title \"Driver end date\" with lines \n"); - - fclose(file); + fStream2 << "set grid\n"; + fStream2 << "set title \"Driver end date\"\n"; + fStream2 << "set xlabel \"audio cycles\"\n"; + fStream2 << "set ylabel \"usec\"\n"; + fStream2 << "plot \"JackEngineProfiling.log\" using 2 title \"Driver end date\" with lines \n"; + fStream2 << "unset output\n"; } // Clients end date if (fMeasuredClient > 0) { - file = fopen("Timing3.plot", "w"); - if (file == NULL) { - jack_error("JackEngineProfiling::Save cannot open Timing3.log file"); + std::ofstream fStream3("Timing3.plot", std::ios_base::ate); + + if (!fStream3.is_open()) { + jack_error("JackEngineProfiling::Save cannot open Timing3.plot file"); } else { - fprintf(file, "set multiplot\n"); - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Clients end date\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot "); + fStream3 << "set multiplot\n"; + fStream3 << "set grid\n"; + fStream3 << "set title \"Clients end date\"\n"; + fStream3 << "set xlabel \"audio cycles\"\n"; + fStream3 << "set ylabel \"usec\"\n"; + fStream3 << "plot "; for (unsigned int i = 0; i < fMeasuredClient; i++) { if (i == 0) { if (i + 1 == fMeasuredClient) { // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines", - ((i + 1) * 7) - 1 , fIntervalTable[i].fName); - } else { - sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", - ((i + 1) * 7) - 1 , fIntervalTable[i].fName); + fStream3 << "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using "; + fStream3 << ((i + 1) * 7) - 1; + fStream3 << " title \"" << fIntervalTable[i].fName << "\"with lines"; + } else { + fStream3 << "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using "; + fStream3 << ((i + 1) * 7) - 1; + fStream3 << " title \"" << fIntervalTable[i].fName << "\"with lines,"; } } else if (i + 1 == fMeasuredClient) { // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) - 1 , fIntervalTable[i].fName); + fStream3 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) - 1 << " title \"" << fIntervalTable[i].fName << "\" with lines"; } else { - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) - 1, fIntervalTable[i].fName); + fStream3 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) - 1 << " title \"" << fIntervalTable[i].fName << "\" with lines,"; } - fprintf(file, buffer); } - fprintf(file, "\n unset multiplot\n"); - fprintf(file, "set output 'Timing3.pdf\n"); - fprintf(file, "set terminal pdf\n"); + fStream3 << "\n unset multiplot\n"; + fStream3 << "set output 'Timing3.svg\n"; + fStream3 << "set terminal svg\n"; - fprintf(file, "set multiplot\n"); - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Clients end date\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot "); + fStream3 << "set multiplot\n"; + fStream3 << "set grid\n"; + fStream3 << "set title \"Clients end date\"\n"; + fStream3 << "set xlabel \"audio cycles\"\n"; + fStream3 << "set ylabel \"usec\"\n"; + fStream3 << "plot "; for (unsigned int i = 0; i < fMeasuredClient; i++) { if (i == 0) { if ((i + 1) == fMeasuredClient) { // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines", - ((i + 1) * 7) - 1 , fIntervalTable[i].fName); + fStream3 << "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using "; + fStream3 << ((i + 1) * 7) - 1; + fStream3 << " title \"" << fIntervalTable[i].fName << "\"with lines"; } else { - sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", - ((i + 1) * 7) - 1 , fIntervalTable[i].fName); + fStream3 << "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using "; + fStream3 << ((i + 1) * 7) - 1; + fStream3 << " title \"" << fIntervalTable[i].fName << "\"with lines,"; } } else if ((i + 1) == fMeasuredClient) { // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) - 1 , fIntervalTable[i].fName); + fStream3 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) - 1 << " title \"" << fIntervalTable[i].fName << "\" with lines"; } else { - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) - 1, fIntervalTable[i].fName); + fStream3 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) - 1 << " title \"" << fIntervalTable[i].fName << "\" with lines,"; } - fprintf(file, buffer); } - - fclose(file); + fStream3 << "\nunset multiplot\n"; + fStream3 << "unset output\n"; } } // Clients scheduling if (fMeasuredClient > 0) { - file = fopen("Timing4.plot", "w"); - - if (file == NULL) { - jack_error("JackEngineProfiling::Save cannot open Timing4.log file"); + std::ofstream fStream4("Timing4.plot", std::ios_base::ate); + + if (!fStream4.is_open()) { + jack_error("JackEngineProfiling::Save cannot open Timing4.plot file"); } else { - fprintf(file, "set multiplot\n"); - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Clients scheduling latency\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot "); + fStream4 << "set multiplot\n"; + fStream4 << "set grid\n"; + fStream4 << "set title \"Clients scheduling latency\"\n"; + fStream4 << "set xlabel \"audio cycles\"\n"; + fStream4 << "set ylabel \"usec\"\n"; + fStream4 << "plot "; for (unsigned int i = 0; i < fMeasuredClient; i++) { - if ((i + 1) == fMeasuredClient) // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7), fIntervalTable[i].fName); - else - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7), fIntervalTable[i].fName); - fprintf(file, buffer); + if ((i + 1) == fMeasuredClient) { // Last client + fStream4 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) << " title \"" << fIntervalTable[i].fName << "\" with lines"; + } else { + fStream4 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) << " title \"" << fIntervalTable[i].fName << "\" with lines,"; + } } - fprintf(file, "\n unset multiplot\n"); - fprintf(file, "set output 'Timing4.pdf\n"); - fprintf(file, "set terminal pdf\n"); + fStream4 << "\n unset multiplot\n"; + fStream4 << "set output 'Timing4.svg\n"; + fStream4 << "set terminal svg\n"; - fprintf(file, "set multiplot\n"); - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Clients scheduling latency\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot "); + fStream4 << "set multiplot\n"; + fStream4 << "set grid\n"; + fStream4 << "set title \"Clients scheduling latency\"\n"; + fStream4 << "set xlabel \"audio cycles\"\n"; + fStream4 << "set ylabel \"usec\"\n"; + fStream4 << "plot "; for (unsigned int i = 0; i < fMeasuredClient; i++) { - if ((i + 1) == fMeasuredClient) // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7), fIntervalTable[i].fName); - else - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7), fIntervalTable[i].fName); - fprintf(file, buffer); + if ((i + 1) == fMeasuredClient) { // Last client + fStream4 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) << " title \"" << fIntervalTable[i].fName << "\" with lines"; + } else { + fStream4 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) << " title \"" << fIntervalTable[i].fName << "\" with lines,"; + } } - fclose(file); + fStream4 << "\nunset multiplot\n"; + fStream4 << "unset output\n"; } } // Clients duration if (fMeasuredClient > 0) { - file = fopen("Timing5.plot", "w"); + std::ofstream fStream5("Timing5.plot", std::ios_base::ate); - if (file == NULL) { - jack_error("JackEngineProfiling::Save cannot open Timing5.log file"); + if (!fStream5.is_open()) { + jack_error("JackEngineProfiling::Save cannot open Timing5.plot file"); } else { - fprintf(file, "set multiplot\n"); - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Clients duration\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot "); + fStream5 << "set multiplot\n"; + fStream5 << "set grid\n"; + fStream5 << "set title \"Clients duration\"\n"; + fStream5 << "set xlabel \"audio cycles\"\n"; + fStream5 << "set ylabel \"usec\"\n"; + fStream5 << "plot "; for (unsigned int i = 0; i < fMeasuredClient; i++) { - if ((i + 1) == fMeasuredClient) // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) + 1, fIntervalTable[i].fName); - else - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) + 1, fIntervalTable[i].fName); - fprintf(file, buffer); + if ((i + 1) == fMeasuredClient) { // Last client + fStream5 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) + 1 << " title \"" << fIntervalTable[i].fName << "\" with lines"; + } else { + fStream5 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) + 1 << " title \"" << fIntervalTable[i].fName << "\" with lines,"; + } } - fprintf(file, "\n unset multiplot\n"); - fprintf(file, "set output 'Timing5.pdf\n"); - fprintf(file, "set terminal pdf\n"); + fStream5 << "\n unset multiplot\n"; + fStream5 << "set output 'Timing5.svg\n"; + fStream5 << "set terminal svg\n"; - fprintf(file, "set multiplot\n"); - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Clients duration\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot "); + fStream5 << "set multiplot\n"; + fStream5 << "set grid\n"; + fStream5 << "set title \"Clients duration\"\n"; + fStream5 << "set xlabel \"audio cycles\"\n"; + fStream5 << "set ylabel \"usec\"\n"; + fStream5 << "plot "; for (unsigned int i = 0; i < fMeasuredClient; i++) { - if ((i + 1) == fMeasuredClient) // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) + 1, fIntervalTable[i].fName); - else - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) + 1, fIntervalTable[i].fName); - fprintf(file, buffer); + if ((i + 1) == fMeasuredClient) {// Last client + fStream5 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) + 1 << " title \"" << fIntervalTable[i].fName << "\" with lines"; + } else { + fStream5 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) + 1 << " title \"" << fIntervalTable[i].fName << "\" with lines,"; + } } - fclose(file); + fStream5 << "\nunset multiplot\n"; + fStream5 << "unset output\n"; } } + + std::ofstream fStream6("Timings.html", std::ios_base::ate); + if (!fStream6.is_open()) { + jack_error("JackEngineProfiling::Save cannot open Timings.html file"); + } else { + fStream6 << "\n"; + fStream6 << "\n"; + fStream6 << "\n"; + fStream6 << " \n"; + fStream6 << " JACK engine profiling\n"; + fStream6 << " \n"; + fStream6 << " \n"; + fStream6 << " \n"; + fStream6 << " \n"; + fStream6 << "

JACK engine profiling

\n"; + fStream6 << "
Timing1
"; + fStream6 << "
Timing2
"; + fStream6 << "
Timing3
"; + fStream6 << "
Timing4
"; + fStream6 << "
Timing5
"; + fStream6 << " \n"; + fStream6 << "\n"; + } + + std::ofstream fStream7("generate_timings", std::ios_base::ate); + if (!fStream7.is_open()) { + jack_error("JackEngineProfiling::Save cannot open generate_timings file"); + } else { + fStream7 << "gnuplot -persist Timing1.plot \n"; + fStream7 << "gnuplot -persist Timing2.plot\n"; + fStream7 << "gnuplot -persist Timing3.plot\n"; + fStream7 << "gnuplot -persist Timing4.plot\n"; + fStream7 << "gnuplot -persist Timing5.plot\n"; + } } bool JackEngineProfiling::CheckClient(const char* name, int cur_point) diff --git a/common/JackException.h b/common/JackException.h index 3270f20a..58a9a23b 100644 --- a/common/JackException.h +++ b/common/JackException.h @@ -75,6 +75,24 @@ class SERVER_EXPORT JackTemporaryException : public JackException { {} }; +/*! + \brief + */ + +class SERVER_EXPORT JackQuitException : public JackException { + + public: + + JackQuitException(const std::string& msg) : JackException(msg) + {} + JackQuitException(char* msg) : JackException(msg) + {} + JackQuitException(const char* msg) : JackException(msg) + {} + JackQuitException() : JackException("") + {} +}; + /*! \brief Exception possibly thrown by Net slaves. */ diff --git a/common/JackFilters.h b/common/JackFilters.h index 76bf7ecd..ad2afecc 100644 --- a/common/JackFilters.h +++ b/common/JackFilters.h @@ -20,13 +20,21 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifndef __JackFilters__ #define __JackFilters__ +#ifdef __APPLE__ +#include +#endif + #include "jack.h" +#ifndef TARGET_OS_IPHONE #include "JackAtomicState.h" +#endif #include #include namespace Jack { + +#ifndef TARGET_OS_IPHONE #define MAX_SIZE 64 @@ -204,6 +212,7 @@ namespace Jack } } POST_PACKED_STRUCTURE; +#endif /* Torben Hohn PI controler from JACK1 */ diff --git a/common/JackGlobals.cpp b/common/JackGlobals.cpp index c8c40545..2314c84d 100644 --- a/common/JackGlobals.cpp +++ b/common/JackGlobals.cpp @@ -37,5 +37,28 @@ JackClient* JackGlobals::fClientTable[CLIENT_NUM] = {}; #ifndef WIN32 jack_thread_creator_t JackGlobals::fJackThreadCreator = pthread_create; #endif + +#ifdef __CLIENTDEBUG__ +std::ofstream* JackGlobals::fStream = NULL; + +void JackGlobals::CheckContext(const char* name) +{ + if (JackGlobals::fStream == NULL) { + char provstr[256]; + char buffer[256]; + time_t curtime; + struct tm *loctime; + /* Get the current time. */ + curtime = time (NULL); + /* Convert it to local time representation. */ + loctime = localtime (&curtime); + strftime (buffer, 256, "%I-%M", loctime); + sprintf(provstr, "JackAPICall-%s.log", buffer); + JackGlobals::fStream = new std::ofstream(provstr, std::ios_base::ate); + JackGlobals::fStream->is_open(); + } + (*fStream) << "JACK API call : " << name << ", calling thread : " << pthread_self() << std::endl; +} +#endif } // end of namespace diff --git a/common/JackGlobals.h b/common/JackGlobals.h index 7586708e..3c581097 100644 --- a/common/JackGlobals.h +++ b/common/JackGlobals.h @@ -23,9 +23,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackPlatformPlug.h" #include "JackConstants.h" +#ifdef __CLIENTDEBUG__ +#include +#include +#include +#include +#endif + namespace Jack { - + // Globals used for client management on server or library side. struct JackGlobals { @@ -38,6 +45,11 @@ struct JackGlobals { #ifndef WIN32 static jack_thread_creator_t fJackThreadCreator; #endif + +#ifdef __CLIENTDEBUG__ + static std::ofstream* fStream; + static void CheckContext(const char* name); +#endif }; // Each "side" server and client will implement this to get the shared graph manager, engine control and inter-process synchro table. diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index d16becd6..ce77f875 100644 --- a/common/JackGraphManager.cpp +++ b/common/JackGraphManager.cpp @@ -29,13 +29,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -static void AssertPort(jack_port_id_t port_index) -{ - if (port_index >= PORT_NUM) { - jack_log("JackGraphManager::AssertPort port_index = %ld", port_index); - assert(port_index < PORT_NUM); - } -} static void AssertBufferSize(jack_nframes_t buffer_size) { @@ -44,7 +37,40 @@ 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) { + jack_log("JackGraphManager::AssertPort port_index = %ld", port_index); + assert(port_index < fPortMax); + } +} + +JackGraphManager* JackGraphManager::Allocate(int port_max) +{ + // Using "Placement" new + void* shared_ptr = JackShmMem::operator new(sizeof(JackGraphManager) + port_max * sizeof(JackPort)); + return new(shared_ptr) JackGraphManager(port_max); +} +void JackGraphManager::Destroy(JackGraphManager* manager) +{ + // "Placement" new was used + manager->~JackGraphManager(); + JackShmMem::operator delete(manager); +} + +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); @@ -262,7 +288,7 @@ int JackGraphManager::ComputeTotalLatency(jack_port_id_t port_index) int JackGraphManager::ComputeTotalLatencies() { jack_port_id_t port_index; - for (port_index = FIRST_AVAILABLE_PORT; port_index < PORT_NUM; port_index++) { + for (port_index = FIRST_AVAILABLE_PORT; port_index < fPortMax; port_index++) { JackPort* port = GetPort(port_index); if (port->IsUsed()) ComputeTotalLatency(port_index); @@ -276,7 +302,7 @@ void JackGraphManager::SetBufferSize(jack_nframes_t buffer_size) jack_log("JackGraphManager::SetBufferSize size = %ld", buffer_size); jack_port_id_t port_index; - for (port_index = FIRST_AVAILABLE_PORT; port_index < PORT_NUM; port_index++) { + for (port_index = FIRST_AVAILABLE_PORT; port_index < fPortMax; port_index++) { JackPort* port = GetPort(port_index); if (port->IsUsed()) port->ClearBuffer(buffer_size); @@ -289,7 +315,7 @@ jack_port_id_t JackGraphManager::AllocatePortAux(int refnum, const char* port_na jack_port_id_t port_index; // Available ports start at FIRST_AVAILABLE_PORT (= 1), otherwise a port_index of 0 is "seen" as a NULL port by the external API... - for (port_index = FIRST_AVAILABLE_PORT; port_index < PORT_NUM; port_index++) { + for (port_index = FIRST_AVAILABLE_PORT; port_index < fPortMax; port_index++) { JackPort* port = GetPort(port_index); if (!port->IsUsed()) { jack_log("JackGraphManager::AllocatePortAux port_index = %ld name = %s type = %s", port_index, port_name, port_type); @@ -299,7 +325,7 @@ jack_port_id_t JackGraphManager::AllocatePortAux(int refnum, const char* port_na } } - return (port_index < PORT_NUM) ? port_index : NO_PORT; + return (port_index < fPortMax) ? port_index : NO_PORT; } // Server @@ -424,7 +450,7 @@ void JackGraphManager::DisconnectAllInput(jack_port_id_t port_index) jack_log("JackGraphManager::DisconnectAllInput port_index = %ld", port_index); JackConnectionManager* manager = WriteNextStateStart(); - for (int i = 0; i < PORT_NUM; i++) { + for (unsigned int i = 0; i < fPortMax; i++) { if (manager->IsConnected(i, port_index)) { jack_log("JackGraphManager::Disconnect i = %ld port_index = %ld", i, port_index); Disconnect(i, port_index); @@ -661,7 +687,7 @@ int JackGraphManager::GetTwoPorts(const char* src_name, const char* dst_name, ja // Client : port array jack_port_id_t JackGraphManager::GetPort(const char* name) { - for (int i = 0; i < PORT_NUM; i++) { + for (unsigned int i = 0; i < fPortMax; i++) { JackPort* port = GetPort(i); if (port->IsUsed() && port->NameEquals(name)) return i; @@ -734,9 +760,9 @@ void JackGraphManager::GetPortsAux(const char** matching_ports, const char* port } // Cleanup port array - memset(matching_ports, 0, sizeof(char*) * PORT_NUM); + memset(matching_ports, 0, sizeof(char*) * fPortMax); - for (int i = 0; i < PORT_NUM; i++) { + for (unsigned int i = 0; i < fPortMax; i++) { bool matching = true; JackPort* port = GetPort(i); @@ -783,7 +809,7 @@ void JackGraphManager::GetPortsAux(const char** matching_ports, const char* port */ const char** JackGraphManager::GetPorts(const char* port_name_pattern, const char* type_name_pattern, unsigned long flags) { - const char** res = (const char**)malloc(sizeof(char*) * PORT_NUM); + const char** res = (const char**)malloc(sizeof(char*) * fPortMax); UInt16 cur_index, next_index; if (!res) diff --git a/common/JackGraphManager.h b/common/JackGraphManager.h index 0fdd3c82..c2d7e105 100644 --- a/common/JackGraphManager.h +++ b/common/JackGraphManager.h @@ -42,9 +42,11 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState private: - JackPort fPortArray[PORT_NUM]; + unsigned int fPortMax; JackClientTiming fClientTiming[CLIENT_NUM]; + JackPort fPortArray[0]; // The actual size depends of port_max, it will be dynamically computed and allocated using "placement" new + void AssertPort(jack_port_id_t port_index); jack_port_id_t AllocatePortAux(int refnum, const char* port_name, const char* port_type, JackPortFlags flags); void GetConnectionsAux(JackConnectionManager* manager, const char** res, jack_port_id_t port_index); void GetPortsAux(const char** matching_ports, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags); @@ -54,8 +56,7 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState public: - JackGraphManager() - {} + JackGraphManager(int port_max); ~JackGraphManager() {} @@ -127,6 +128,9 @@ 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); } POST_PACKED_STRUCTURE; diff --git a/common/JackLibAPI.cpp b/common/JackLibAPI.cpp index b2cce06f..45649c2d 100644 --- a/common/JackLibAPI.cpp +++ b/common/JackLibAPI.cpp @@ -112,6 +112,9 @@ EXPORT jack_client_t* jack_client_open_aux(const char* client_name, jack_options EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...) { try { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_client_open"); +#endif assert(JackGlobals::fOpenMutex); JackGlobals::fOpenMutex->Lock(); va_list ap; @@ -131,6 +134,9 @@ EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options EXPORT int jack_client_close(jack_client_t* ext_client) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_client_close"); +#endif assert(JackGlobals::fOpenMutex); JackGlobals::fOpenMutex->Lock(); int res = -1; diff --git a/common/JackLibClient.cpp b/common/JackLibClient.cpp index 4c92e9e3..effdfc6f 100644 --- a/common/JackLibClient.cpp +++ b/common/JackLibClient.cpp @@ -103,6 +103,9 @@ int JackLibClient::Open(const char* server_name, const char* name, jack_options_ } catch (int n) { jack_error("Map shared memory segments exception %d", n); goto error; + } catch (...) { + jack_error("Unknown error..."); + goto error; } SetupDriverSync(false); diff --git a/common/JackLibGlobals.h b/common/JackLibGlobals.h index f109b665..5ef8b9e9 100644 --- a/common/JackLibGlobals.h +++ b/common/JackLibGlobals.h @@ -31,6 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackError.h" #include #include + namespace Jack { @@ -123,13 +124,6 @@ struct JackLibGlobals } } - static void CheckContext() - { - if (!(fClientCount > 0 && fGlobals)) { - jack_error("Error !!! : client accessing an already desallocated library context"); - } - } - }; } // end of namespace diff --git a/common/JackLockedEngine.h b/common/JackLockedEngine.h index c2de8512..a9f044a8 100644 --- a/common/JackLockedEngine.h +++ b/common/JackLockedEngine.h @@ -31,6 +31,16 @@ namespace Jack #define TRY_CALL \ try { \ +/* +See : http://groups.google.com/group/comp.programming.threads/browse_thread/thread/652bcf186fbbf697/f63757846514e5e5 + +catch (...) { + // Assuming thread cancellation, must rethrow + throw; + +} +*/ + #define CATCH_EXCEPTION_RETURN \ } catch(std::bad_alloc& e) { \ jack_error("Memory allocation error..."); \ @@ -41,14 +51,15 @@ namespace Jack return -1; \ } catch (...) { \ jack_error("Unknown error..."); \ - return -1; \ + throw; \ } \ -#define CATCH_ENGINE_EXCEPTION \ +#define CATCH_EXCEPTION \ } catch(std::bad_alloc& e) { \ jack_error("Memory allocation error..."); \ } catch (...) { \ jack_error("Unknown error..."); \ + throw; \ } \ /*! @@ -83,7 +94,7 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble return fEngine.Close(); CATCH_EXCEPTION_RETURN } - + // Client management int ClientCheck(const char* name, char* name_res, int protocol, int options, int* status) { @@ -233,35 +244,35 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble TRY_CALL JackLock lock(this); fEngine.NotifyXRun(refnum); - CATCH_ENGINE_EXCEPTION + CATCH_EXCEPTION } void NotifyGraphReorder() { TRY_CALL JackLock lock(this); fEngine.NotifyGraphReorder(); - CATCH_ENGINE_EXCEPTION + CATCH_EXCEPTION } void NotifyBufferSize(jack_nframes_t buffer_size) { TRY_CALL JackLock lock(this); fEngine.NotifyBufferSize(buffer_size); - CATCH_ENGINE_EXCEPTION + CATCH_EXCEPTION } void NotifySampleRate(jack_nframes_t sample_rate) { TRY_CALL JackLock lock(this); fEngine.NotifySampleRate(sample_rate); - CATCH_ENGINE_EXCEPTION + CATCH_EXCEPTION } void NotifyFreewheel(bool onoff) { TRY_CALL JackLock lock(this); fEngine.NotifyFreewheel(onoff); - CATCH_ENGINE_EXCEPTION + CATCH_EXCEPTION } void NotifyFailure(int code, const char* reason) @@ -269,7 +280,7 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble TRY_CALL JackLock lock(this); fEngine.NotifyFailure(code, reason); - CATCH_ENGINE_EXCEPTION + CATCH_EXCEPTION } int GetClientPID(const char* name) @@ -287,7 +298,15 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble return fEngine.GetClientRefNum(name); CATCH_EXCEPTION_RETURN } - + + void NotifyQuit() + { + TRY_CALL + JackLock lock(this); + return fEngine.NotifyQuit(); + CATCH_EXCEPTION + } + }; } // end of namespace diff --git a/common/JackMessageBuffer.cpp b/common/JackMessageBuffer.cpp index 8dacfe67..b9f28463 100644 --- a/common/JackMessageBuffer.cpp +++ b/common/JackMessageBuffer.cpp @@ -29,7 +29,7 @@ namespace Jack JackMessageBuffer* JackMessageBuffer::fInstance = NULL; JackMessageBuffer::JackMessageBuffer() - :fThread(this),fInBuffer(0),fOutBuffer(0),fOverruns(0),fRunning(false) + :fInit(NULL),fInitArg(NULL),fThread(this),fInBuffer(0),fOutBuffer(0),fOverruns(0),fRunning(false) {} JackMessageBuffer::~JackMessageBuffer() @@ -82,6 +82,15 @@ bool JackMessageBuffer::Execute() while (fRunning) { fGuard.Lock(); fGuard.Wait(); + /* the client asked for all threads to run a thread + initialization callback, which includes us. + */ + if (fInit) { + fInit(fInitArg); + fInit = NULL; + /* and we're done */ + fGuard.Signal(); + } Flush(); fGuard.Unlock(); } @@ -115,5 +124,20 @@ void JackMessageBufferAdd(int level, const char *message) } } +void JackMessageBuffer::SetInitCallback(JackThreadInitCallback callback, void *arg) +{ + fGuard.Lock(); + /* set up the callback */ + fInitArg = arg; + fInit = callback; + /* wake msg buffer thread */ + fGuard.Signal(); + /* wait for it to be done */ + fGuard.Wait(); + /* and we're done */ + fGuard.Unlock(); +} + + }; diff --git a/common/JackMessageBuffer.h b/common/JackMessageBuffer.h index 5e3472a5..ec13a5dc 100644 --- a/common/JackMessageBuffer.h +++ b/common/JackMessageBuffer.h @@ -57,6 +57,8 @@ class JackMessageBuffer : public JackRunnableInterface private: + JackThreadInitCallback fInit; + void* fInitArg; JackMessage fBuffers[MB_BUFFERS]; JackThread fThread; JackProcessSync fGuard; @@ -82,6 +84,7 @@ class JackMessageBuffer : public JackRunnableInterface void static Destroy(); void AddMessage(int level, const char *message); + void SetInitCallback(JackThreadInitCallback callback, void *arg); static JackMessageBuffer* fInstance; }; diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index dd19f904..46825d8d 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -878,21 +878,46 @@ SERVER_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** in // Empty code for now.. -//#ifdef TARGET_OS_IPHONE +#ifdef TARGET_OS_IPHONE -SERVER_EXPORT void jack_error(const char *fmt, ...) +static void jack_format_and_log(int level, const char *prefix, const char *fmt, va_list ap) { - // TODO + char buffer[300]; + size_t len; + + if (prefix != NULL) { + len = strlen(prefix); + memcpy(buffer, prefix, len); + } else { + len = 0; + } + + vsnprintf(buffer + len, sizeof(buffer) - len, fmt, ap); + printf(buffer); + printf("\n"); } +SERVER_EXPORT void jack_error(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); + va_end(ap);} + SERVER_EXPORT void jack_info(const char *fmt, ...) { - // TODO + va_list ap; + va_start(ap, fmt); + jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); + va_end(ap); } SERVER_EXPORT void jack_log(const char *fmt, ...) { - // TODO + va_list ap; + va_start(ap, fmt); + jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); + va_end(ap); } -//#endif +#endif diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 5131c98c..1ecc04ca 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -227,6 +227,7 @@ namespace Jack do { session_params_t net_params; + memset(&net_params, 0, sizeof ( session_params_t )); SetPacketType ( &fParams, SLAVE_SETUP ); SessionParamsHToN(&fParams, &net_params); @@ -316,6 +317,7 @@ namespace Jack JackNetSocket mcast_socket ( fMulticastIP, fSocket.GetPort() ); session_params_t net_params; + memset(&net_params, 0, sizeof ( session_params_t )); SessionParamsHToN(&fParams, &net_params); if ( mcast_socket.NewSocket() == SOCKET_ERROR ) @@ -679,6 +681,8 @@ namespace Jack //utility session_params_t host_params; int rx_bytes = 0; + + jack_log ( "sizeof (session_params_t) %d", sizeof (session_params_t) ); //socket if ( fSocket.NewSocket() == SOCKET_ERROR ) { @@ -706,6 +710,7 @@ namespace Jack { //send 'available' session_params_t net_params; + memset(&net_params, 0, sizeof ( session_params_t )); SessionParamsHToN(&fParams, &net_params); if ( fSocket.SendTo ( &net_params, sizeof ( session_params_t ), 0, fMulticastIP ) == SOCKET_ERROR ) jack_error ( "Error in data send : %s", StrError ( NET_ERROR_CODE ) ); @@ -713,15 +718,28 @@ namespace Jack //filter incoming packets : don't exit while no error is detected memset(&net_params, 0, sizeof ( session_params_t )); rx_bytes = fSocket.CatchHost ( &net_params, sizeof ( session_params_t ), 0 ); + + SessionParamsDisplay(&net_params); + jack_error ( "rx_bytes %d %d", rx_bytes, errno ); + + SessionParamsNToH(&net_params, &host_params); if ( ( rx_bytes == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) ) { jack_error ( "Can't receive : %s", StrError ( NET_ERROR_CODE ) ); return NET_RECV_ERROR; } + for (int i = 0; i < 7; i++) { + jack_info ( " fPacketType %d", host_params.fPacketType[i]); + } + jack_info ( " received... host_params param %s %s %d %d", net_params.fPacketType, fParams.fPacketType, net_params.fPacketID, GetPacketType ( &host_params )); + + SessionParamsDisplay(&host_params); } while ( strcmp ( host_params.fPacketType, fParams.fPacketType ) && ( GetPacketType ( &host_params ) != SLAVE_SETUP ) ); + jack_info ( "SLAVE_SETUP received..." ); + //everything is OK, copy parameters fParams = host_params; @@ -746,6 +764,7 @@ namespace Jack //tell the master to start session_params_t net_params; + memset(&net_params, 0, sizeof ( session_params_t )); SetPacketType ( &fParams, START_MASTER ); SessionParamsHToN(&fParams, &net_params); if ( fSocket.Send ( &net_params, sizeof ( session_params_t ), 0 ) == SOCKET_ERROR ) diff --git a/common/JackNetOneDriver.cpp b/common/JackNetOneDriver.cpp index bc0160bc..4a75cc23 100644 --- a/common/JackNetOneDriver.cpp +++ b/common/JackNetOneDriver.cpp @@ -17,8 +17,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -//#define HAVE_CELT 1 - #ifdef WIN32 #include #endif diff --git a/common/JackNotification.h b/common/JackNotification.h index 43611a4f..be0c89fd 100644 --- a/common/JackNotification.h +++ b/common/JackNotification.h @@ -44,6 +44,7 @@ enum NotificationType { kPortRenameCallback = 13, kRealTimeCallback = 14, kShutDownCallback = 15, + kQUIT = 16, kMaxNotification }; diff --git a/common/JackPhysicalMidiInput.cpp b/common/JackPhysicalMidiInput.cpp new file mode 100644 index 00000000..311dad0b --- /dev/null +++ b/common/JackPhysicalMidiInput.cpp @@ -0,0 +1,287 @@ +/* +Copyright (C) 2009 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include +#include +#include + +#include "JackError.h" +#include "JackPhysicalMidiInput.h" + +namespace Jack { + +JackPhysicalMidiInput::JackPhysicalMidiInput(size_t buffer_size) +{ + size_t datum_size = sizeof(jack_midi_data_t); + assert(buffer_size > 0); + input_ring = jack_ringbuffer_create((buffer_size + 1) * datum_size); + if (! input_ring) { + throw std::bad_alloc(); + } + jack_ringbuffer_mlock(input_ring); + Clear(); + expected_data_bytes = 0; + status_byte = 0; +} + +JackPhysicalMidiInput::~JackPhysicalMidiInput() +{ + jack_ringbuffer_free(input_ring); +} + +void +JackPhysicalMidiInput::Clear() +{ + jack_ringbuffer_reset(input_ring); + buffered_bytes = 0; + unbuffered_bytes = 0; +} + +void +JackPhysicalMidiInput::HandleBufferFailure(size_t unbuffered_bytes, + size_t total_bytes) +{ + jack_error("%d MIDI byte(s) of a %d byte message could not be buffered - " + "message dropped", unbuffered_bytes, total_bytes); +} + +void +JackPhysicalMidiInput::HandleIncompleteMessage(size_t bytes) +{ + jack_error("Discarding %d MIDI byte(s) - incomplete message (cable " + "unplugged?)", bytes); +} + +void +JackPhysicalMidiInput::HandleInvalidStatusByte(jack_midi_data_t status) +{ + jack_error("Dropping invalid MIDI status byte '%x'", + (unsigned int) status); +} + +void +JackPhysicalMidiInput::HandleUnexpectedSysexEnd(size_t bytes) +{ + jack_error("Discarding %d MIDI byte(s) - received sysex end without sysex " + "start (cable unplugged?)", bytes); +} + +void +JackPhysicalMidiInput::HandleWriteFailure(size_t bytes) +{ + jack_error("Failed to write a %d byte MIDI message to the port buffer", + bytes); +} + +void +JackPhysicalMidiInput::Process(jack_nframes_t frames) +{ + assert(port_buffer); + port_buffer->Reset(frames); + jack_nframes_t current_frame = 0; + size_t datum_size = sizeof(jack_midi_data_t); + for (;;) { + jack_midi_data_t datum; + current_frame = Receive(&datum, current_frame, frames); + if (current_frame >= frames) { + break; + } + + jack_log("JackPhysicalMidiInput::Process (%d) - Received '%x' byte", + current_frame, (unsigned int) datum); + + if (datum >= 0xf8) { + // Realtime + if (datum == 0xfd) { + HandleInvalidStatusByte(datum); + } else { + + jack_log("JackPhysicalMidiInput::Process - Writing realtime " + "event."); + + WriteByteEvent(current_frame, datum); + } + continue; + } + if (datum == 0xf7) { + // Sysex end + if (status_byte != 0xf0) { + HandleUnexpectedSysexEnd(buffered_bytes + unbuffered_bytes); + Clear(); + expected_data_bytes = 0; + status_byte = 0; + } else { + + jack_log("JackPhysicalMidiInput::Process - Writing sysex " + "event."); + + WriteBufferedSysexEvent(current_frame); + } + continue; + } + if (datum >= 0x80) { + + // We're handling a non-realtime status byte + + jack_log("JackPhysicalMidiInput::Process - Handling non-realtime " + "status byte."); + + if (buffered_bytes || unbuffered_bytes) { + HandleIncompleteMessage(buffered_bytes + unbuffered_bytes + 1); + Clear(); + } + status_byte = datum; + switch (datum & 0xf0) { + case 0x80: + case 0x90: + case 0xa0: + case 0xb0: + case 0xe0: + // Note On, Note Off, Aftertouch, Control Change, Pitch Wheel + expected_data_bytes = 2; + break; + case 0xc0: + case 0xd0: + // Program Change, Channel Pressure + expected_data_bytes = 1; + break; + case 0xf0: + switch (datum) { + case 0xf0: + // Sysex message + expected_data_bytes = 0; + break; + case 0xf1: + case 0xf3: + // MTC Quarter frame, Song Select + expected_data_bytes = 1; + break; + case 0xf2: + // Song Position + expected_data_bytes = 2; + break; + case 0xf4: + case 0xf5: + // Undefined + HandleInvalidStatusByte(datum); + expected_data_bytes = 0; + status_byte = 0; + break; + case 0xf6: + // Tune Request + WriteByteEvent(current_frame, datum); + expected_data_bytes = 0; + status_byte = 0; + } + break; + } + continue; + } + + // We're handling a data byte + + jack_log("JackPhysicalMidiInput::Process - Buffering data byte."); + + if (jack_ringbuffer_write(input_ring, (const char *) &datum, + datum_size) == datum_size) { + buffered_bytes++; + } else { + unbuffered_bytes++; + } + unsigned long total_bytes = buffered_bytes + unbuffered_bytes; + assert((! expected_data_bytes) || + (total_bytes <= expected_data_bytes)); + if (total_bytes == expected_data_bytes) { + if (! unbuffered_bytes) { + + jack_log("JackPhysicalMidiInput::Process - Writing buffered " + "event."); + + WriteBufferedEvent(current_frame); + } else { + HandleBufferFailure(unbuffered_bytes, total_bytes); + Clear(); + } + if (status_byte >= 0xf0) { + expected_data_bytes = 0; + status_byte = 0; + } + } + } +} + +void +JackPhysicalMidiInput::WriteBufferedEvent(jack_nframes_t frame) +{ + assert(port_buffer && port_buffer->IsValid()); + size_t space = jack_ringbuffer_read_space(input_ring); + jack_midi_data_t *event = port_buffer->ReserveEvent(frame, space + 1); + if (event) { + jack_ringbuffer_data_t vector[2]; + jack_ringbuffer_get_read_vector(input_ring, vector); + event[0] = status_byte; + size_t data_length_1 = vector[0].len; + memcpy(event + 1, vector[0].buf, data_length_1); + size_t data_length_2 = vector[1].len; + if (data_length_2) { + memcpy(event + data_length_1 + 1, vector[1].buf, data_length_2); + } + } else { + HandleWriteFailure(space + 1); + } + Clear(); +} + +void +JackPhysicalMidiInput::WriteBufferedSysexEvent(jack_nframes_t frame) +{ + assert(port_buffer && port_buffer->IsValid()); + size_t space = jack_ringbuffer_read_space(input_ring); + jack_midi_data_t *event = port_buffer->ReserveEvent(frame, space + 2); + if (event) { + jack_ringbuffer_data_t vector[2]; + jack_ringbuffer_get_read_vector(input_ring, vector); + event[0] = status_byte; + size_t data_length_1 = vector[0].len; + memcpy(event + 1, vector[0].buf, data_length_1); + size_t data_length_2 = vector[1].len; + if (data_length_2) { + memcpy(event + data_length_1 + 1, vector[1].buf, data_length_2); + } + event[data_length_1 + data_length_2 + 1] = 0xf7; + } else { + HandleWriteFailure(space + 2); + } + Clear(); +} + +void +JackPhysicalMidiInput::WriteByteEvent(jack_nframes_t frame, + jack_midi_data_t datum) +{ + assert(port_buffer && port_buffer->IsValid()); + jack_midi_data_t *event = port_buffer->ReserveEvent(frame, 1); + if (event) { + event[0] = datum; + } else { + HandleWriteFailure(1); + } +} + +} diff --git a/common/JackPhysicalMidiInput.h b/common/JackPhysicalMidiInput.h new file mode 100644 index 00000000..6ba3b471 --- /dev/null +++ b/common/JackPhysicalMidiInput.h @@ -0,0 +1,146 @@ +/* +Copyright (C) 2009 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackPhysicalMidiInput__ +#define __JackPhysicalMidiInput__ + +#include "JackMidiPort.h" +#include "ringbuffer.h" + +namespace Jack { + + class JackPhysicalMidiInput { + + private: + + size_t buffered_bytes; + size_t expected_data_bytes; + jack_ringbuffer_t *input_ring; + JackMidiBuffer *port_buffer; + jack_midi_data_t status_byte; + size_t unbuffered_bytes; + + void + Clear(); + + void + WriteBufferedEvent(jack_nframes_t); + + void + WriteBufferedSysexEvent(jack_nframes_t); + + void + WriteByteEvent(jack_nframes_t, jack_midi_data_t); + + protected: + + /** + * Override to specify how to react when 1 or more bytes of a MIDI + * message are lost because there wasn't enough room in the input + * buffer. The first argument is the amount of bytes that couldn't be + * buffered, and the second argument is the total amount of bytes in + * the MIDI message. The default implementation calls 'jack_error' + * with a basic error message. + */ + + virtual void + HandleBufferFailure(size_t, size_t); + + /** + * Override to specify how to react when a new status byte is received + * before all of the data bytes in a message are received. The + * argument is the number of bytes being discarded. The default + * implementation calls 'jack_error' with a basic error message. + */ + + virtual void + HandleIncompleteMessage(size_t); + + /** + * Override to specify how to react when an invalid status byte (0xf4, + * 0xf5, 0xfd) is received. The argument contains the invalid status + * byte. The default implementation calls 'jack_error' with a basic + * error message. + */ + + virtual void + HandleInvalidStatusByte(jack_midi_data_t); + + /** + * Override to specify how to react when a sysex end byte (0xf7) is + * received without first receiving a sysex start byte (0xf0). The + * argument contains the amount of bytes that will be discarded. The + * default implementation calls 'jack_error' with a basic error + * message. + */ + + virtual void + HandleUnexpectedSysexEnd(size_t); + + /** + * Override to specify how to react when a MIDI message can not be + * written to the port buffer. The argument specifies the length of + * the MIDI message. The default implementation calls 'jack_error' + * with a basic error message. + */ + + virtual void + HandleWriteFailure(size_t); + + /** + * This method *must* be overridden to handle receiving MIDI bytes. + * The first argument is a pointer to the memory location at which the + * MIDI byte should be stored. The second argument is the last frame + * at which a MIDI byte was received, except at the beginning of the + * period when the value is 0. The third argument is the total number + * of frames in the period. The return value is the frame at which the + * MIDI byte is received at, or the value of the third argument is no + * more MIDI bytes can be received in this period. + */ + + virtual jack_nframes_t + Receive(jack_midi_data_t *, jack_nframes_t, jack_nframes_t) = 0; + + public: + + JackPhysicalMidiInput(size_t buffer_size=1024); + ~JackPhysicalMidiInput(); + + /** + * Called to process MIDI data during a period. + */ + + void + Process(jack_nframes_t); + + /** + * Set the MIDI buffer that will receive incoming messages. + */ + + inline void + SetPortBuffer(JackMidiBuffer *port_buffer) + { + this->port_buffer = port_buffer; + } + + }; + +} + +#endif diff --git a/common/JackPhysicalMidiOutput.cpp b/common/JackPhysicalMidiOutput.cpp new file mode 100644 index 00000000..8f41d443 --- /dev/null +++ b/common/JackPhysicalMidiOutput.cpp @@ -0,0 +1,320 @@ +/* +Copyright (C) 2009 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include + +#include "JackError.h" +#include "JackPhysicalMidiOutput.h" + +namespace Jack { + +JackPhysicalMidiOutput::JackPhysicalMidiOutput(size_t non_rt_buffer_size, + size_t rt_buffer_size) +{ + size_t datum_size = sizeof(jack_midi_data_t); + assert(non_rt_buffer_size > 0); + assert(rt_buffer_size > 0); + output_ring = jack_ringbuffer_create((non_rt_buffer_size + 1) * + datum_size); + if (! output_ring) { + throw std::bad_alloc(); + } + rt_output_ring = jack_ringbuffer_create((rt_buffer_size + 1) * + datum_size); + if (! rt_output_ring) { + jack_ringbuffer_free(output_ring); + throw std::bad_alloc(); + } + jack_ringbuffer_mlock(output_ring); + jack_ringbuffer_mlock(rt_output_ring); + running_status = 0; +} + +JackPhysicalMidiOutput::~JackPhysicalMidiOutput() +{ + jack_ringbuffer_free(output_ring); + jack_ringbuffer_free(rt_output_ring); +} + +jack_nframes_t +JackPhysicalMidiOutput::Advance(jack_nframes_t frame) +{ + return frame; +} + +inline jack_midi_data_t +JackPhysicalMidiOutput::ApplyRunningStatus(jack_midi_data_t **buffer, + size_t *size) +{ + + // Stolen and modified from alsa/midi_pack.h + + jack_midi_data_t status = (*buffer)[0]; + if ((status >= 0x80) && (status < 0xf0)) { + if (status == running_status) { + (*buffer)++; + (*size)--; + } else { + running_status = status; + } + } else if (status < 0xf8) { + running_status = 0; + } + return status; +} + +void +JackPhysicalMidiOutput::HandleEventLoss(JackMidiEvent *event) +{ + jack_error("%d byte MIDI event lost", event->size); +} + +void +JackPhysicalMidiOutput::Process(jack_nframes_t frames) +{ + assert(port_buffer); + jack_nframes_t current_frame = Advance(0); + jack_nframes_t current_midi_event = 0; + jack_midi_data_t datum; + size_t datum_size = sizeof(jack_midi_data_t); + JackMidiEvent *midi_event; + jack_midi_data_t *midi_event_buffer; + size_t midi_event_size; + jack_nframes_t midi_events = port_buffer->event_count; + + // First, send any realtime MIDI data that's left from last cycle. + + if ((current_frame < frames) && + jack_ringbuffer_read_space(rt_output_ring)) { + + jack_log("JackPhysicalMidiOutput::Process (%d) - Sending buffered " + "realtime data from last period.", current_frame); + + current_frame = SendBufferedData(rt_output_ring, current_frame, + frames); + + jack_log("JackPhysicalMidiOutput::Process (%d) - Sent", current_frame); + + } + + // Iterate through the events in this cycle. + + for (; (current_midi_event < midi_events) && (current_frame < frames); + current_midi_event++) { + + // Once we're inside this loop, we know that the realtime buffer + // is empty. As long as we don't find a realtime message, we can + // concentrate on sending non-realtime data. + + midi_event = &(port_buffer->events[current_midi_event]); + jack_nframes_t midi_event_time = midi_event->time; + midi_event_buffer = midi_event->GetData(port_buffer); + midi_event_size = midi_event->size; + datum = ApplyRunningStatus(&midi_event_buffer, &midi_event_size); + if (current_frame < midi_event_time) { + + // We have time before this event is scheduled to be sent. + // Send data in the non-realtime buffer. + + if (jack_ringbuffer_read_space(output_ring)) { + + jack_log("JackPhysicalMidiOutput::Process (%d) - Sending " + "buffered non-realtime data from last period.", + current_frame); + + current_frame = SendBufferedData(output_ring, current_frame, + midi_event_time); + + jack_log("JackPhysicalMidiOutput::Process (%d) - Sent", + current_frame); + + } + if (current_frame < midi_event_time) { + + // We _still_ have time before this event is scheduled to + // be sent. Let's send as much of this event as we can + // (save for one byte, which will need to be sent at or + // after its scheduled time). First though, we need to + // make sure that we can buffer this data if we need to. + // Otherwise, we might start sending a message that we + // can't finish. + + if (midi_event_size > 1) { + if (jack_ringbuffer_write_space(output_ring) < + ((midi_event_size - 1) * datum_size)) { + HandleEventLoss(midi_event); + continue; + } + + // Send as much of the event as possible (save for one + // byte). + + do { + + jack_log("JackPhysicalMidiOutput::Process (%d) - " + "Sending unbuffered event byte early.", + current_frame); + + current_frame = Send(current_frame, + *midi_event_buffer); + + jack_log("JackPhysicalMidiOutput::Process (%d) - " + "Sent.", current_frame); + + midi_event_buffer++; + midi_event_size--; + if (current_frame >= midi_event_time) { + + // The event we're processing must be a + // non-realtime event. It has more than one + // byte. + + goto buffer_non_realtime_data; + } + } while (midi_event_size > 1); + } + + jack_log("JackPhysicalMidiOutput::Process (%d) - Advancing to " + ">= %d", current_frame, midi_event_time); + + current_frame = Advance(midi_event_time); + + jack_log("JackPhysicalMidiOutput::Process (%d) - Advanced.", + current_frame); + + } + } + + // If the event is realtime, then we'll send the event now. + // Otherwise, we attempt to put the rest of the event bytes in the + // non-realtime buffer. + + if (datum >= 0xf8) { + + jack_log("JackPhysicalMidiOutput::Process (%d) - Sending " + "unbuffered realtime event.", current_frame); + + current_frame = Send(current_frame, datum); + + jack_log("JackPhysicalMidiOutput::Process (%d) - Sent.", + current_frame); + + } else if (jack_ringbuffer_write_space(output_ring) >= + (midi_event_size * datum_size)) { + buffer_non_realtime_data: + + jack_log("JackPhysicalMidiOutput::Process (%d) - Buffering %d " + "byte(s) of non-realtime data.", current_frame, + midi_event_size); + + jack_ringbuffer_write(output_ring, + (const char *) midi_event_buffer, + midi_event_size); + } else { + HandleEventLoss(midi_event); + } + } + + if (current_frame < frames) { + + // If we have time left to send data, then we know that all of the + // data in the realtime buffer has been sent, and that all of the + // non-realtime messages have either been sent, or buffered. We + // use whatever time is left to send data in the non-realtime + // buffer. + + if (jack_ringbuffer_read_space(output_ring)) { + + jack_log("JackPhysicalMidiOutput::Process (%d) - All events " + "processed. Sending buffered non-realtime data.", + current_frame); + + current_frame = SendBufferedData(output_ring, current_frame, + frames); + + jack_log("JackPhysicalMidiOutput::Process (%d) - Sent.", + current_frame); + + } + } else { + + // Since we have no time left, we need to put all remaining midi + // events in their appropriate buffers, and send them next period. + + for (; current_midi_event < midi_events; current_midi_event++) { + midi_event = &(port_buffer->events[current_midi_event]); + midi_event_buffer = midi_event->GetData(port_buffer); + midi_event_size = midi_event->size; + datum = ApplyRunningStatus(&midi_event_buffer, &midi_event_size); + if (datum >= 0xf8) { + + // Realtime. + + if (jack_ringbuffer_write_space(rt_output_ring) >= + datum_size) { + + jack_log("JackPhysicalMidiOutput::Process - Buffering " + "realtime event for next period."); + + jack_ringbuffer_write(rt_output_ring, + (const char *) &datum, datum_size); + continue; + } + } else { + + // Non-realtime. + + if (jack_ringbuffer_write_space(output_ring) >= + (midi_event_size * datum_size)) { + + jack_log("JackPhysicalMidiOutput::Process - Buffering " + "non-realtime event for next period."); + + jack_ringbuffer_write(output_ring, + (const char *) midi_event_buffer, + midi_event_size * datum_size); + continue; + } + } + HandleEventLoss(midi_event); + } + } +} + +jack_nframes_t +JackPhysicalMidiOutput::SendBufferedData(jack_ringbuffer_t *buffer, + jack_nframes_t current_frame, + jack_nframes_t boundary) +{ + assert(buffer); + assert(current_frame < boundary); + size_t datum_size = sizeof(jack_midi_data_t); + size_t data_length = jack_ringbuffer_read_space(buffer) / datum_size; + for (size_t i = 0; i < data_length; i++) { + jack_midi_data_t datum; + jack_ringbuffer_read(buffer, (char *) &datum, datum_size); + current_frame = Send(current_frame, datum); + if (current_frame >= boundary) { + break; + } + } + return current_frame; +} + +} diff --git a/common/JackPhysicalMidiOutput.h b/common/JackPhysicalMidiOutput.h new file mode 100644 index 00000000..f76a233a --- /dev/null +++ b/common/JackPhysicalMidiOutput.h @@ -0,0 +1,118 @@ +/* +Copyright (C) 2009 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackPhysicalMidiOutput__ +#define __JackPhysicalMidiOutput__ + +#include "JackMidiPort.h" +#include "ringbuffer.h" + +namespace Jack { + + class JackPhysicalMidiOutput { + + private: + + jack_midi_data_t + ApplyRunningStatus(jack_midi_data_t **, size_t *); + + jack_ringbuffer_t *output_ring; + JackMidiBuffer *port_buffer; + jack_ringbuffer_t *rt_output_ring; + jack_midi_data_t running_status; + + protected: + + /** + * Override to specify the next frame at which a midi byte can be sent. + * The returned frame must be greater than or equal to the frame + * argument. The default returns the frame passed to it. + */ + + virtual jack_nframes_t + Advance(jack_nframes_t); + + /** + * Override to customize how to react when a MIDI event can't be + * buffered and can't be sent immediately. The default calls + * 'jack_error' and specifies the number of bytes lost. + */ + + virtual void + HandleEventLoss(JackMidiEvent *); + + /** + * This method *must* be overridden to specify what happens when a MIDI + * byte is sent at the specfied frame. The frame argument specifies + * the frame at which the MIDI byte should be sent, and the second + * argument specifies the byte itself. The return value is the next + * frame at which a MIDI byte can be sent, and must be greater than or + * equal to the frame argument. + */ + + virtual jack_nframes_t + Send(jack_nframes_t, jack_midi_data_t) = 0; + + /** + * Override to optimize behavior when sending MIDI data that's in the + * ringbuffer. The first frame argument is the current frame, and the + * second frame argument is the boundary frame. The function returns + * the next frame at which MIDI data can be sent, regardless of whether + * or not the boundary is reached. The default implementation calls + * 'Send' with each byte in the ringbuffer until either the ringbuffer + * is empty, or a frame beyond the boundary frame is returned by + * 'Send'. + */ + + virtual jack_nframes_t + SendBufferedData(jack_ringbuffer_t *, jack_nframes_t, jack_nframes_t); + + public: + + /** + * The non-realtime buffer size and the realtime buffer size are both + * optional arguments. + */ + + JackPhysicalMidiOutput(size_t non_rt_buffer_size=1024, + size_t rt_buffer_size=64); + ~JackPhysicalMidiOutput(); + + /** + * Called to process MIDI data during a period. + */ + + void + Process(jack_nframes_t); + + /** + * Set the MIDI buffer that will contain the outgoing MIDI messages. + */ + + inline void + SetPortBuffer(JackMidiBuffer *port_buffer) + { + this->port_buffer = port_buffer; + } + + }; + +} + +#endif diff --git a/common/JackPort.cpp b/common/JackPort.cpp index 42b5fb2e..f8c62d67 100644 --- a/common/JackPort.cpp +++ b/common/JackPort.cpp @@ -28,15 +28,9 @@ namespace Jack { JackPort::JackPort() - : fTypeId(0), - fFlags(JackPortIsInput), - fRefNum( -1), - fLatency(0), - fTotalLatency(0), - fMonitorRequests(0), - fInUse(false), - fTied(NO_PORT) -{} +{ + Release(); +} bool JackPort::Allocate(int refnum, const char* port_name, const char* port_type, JackPortFlags flags) { @@ -68,6 +62,7 @@ void JackPort::Release() fInUse = false; fLatency = 0; fTotalLatency = 0; + fMonitorRequests = 0; fTied = NO_PORT; fAlias1[0] = '\0'; fAlias2[0] = '\0'; diff --git a/common/JackServer.cpp b/common/JackServer.cpp index a260b47a..e2676500 100644 --- a/common/JackServer.cpp +++ b/common/JackServer.cpp @@ -38,15 +38,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { -JackServer::JackServer(bool sync, bool temporary, long timeout, bool rt, long priority, bool verbose, jack_timer_type_t clock, const char* server_name) +JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int priority, int port_max, bool verbose, jack_timer_type_t clock, const char* server_name) { if (rt) { jack_info("JACK server starting in realtime mode with priority %ld", priority); } else { jack_info("JACK server starting in non-realtime mode"); } - - fGraphManager = new JackGraphManager(); + + fGraphManager = JackGraphManager::Allocate(port_max); fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, clock, server_name); fEngine = new JackLockedEngine(fGraphManager, GetSynchroTable(), fEngineControl); fFreewheelDriver = new JackThreadedDriver(new JackFreewheelDriver(fEngine, GetSynchroTable())); @@ -60,7 +60,7 @@ JackServer::JackServer(bool sync, bool temporary, long timeout, bool rt, long pr JackServer::~JackServer() { - delete fGraphManager; + JackGraphManager::Destroy(fGraphManager); delete fAudioDriver; delete fDriverInfo; delete fFreewheelDriver; @@ -125,6 +125,7 @@ fail_close1: int JackServer::Close() { jack_log("JackServer::Close"); + fEngine->NotifyQuit(); fChannel.Close(); fAudioDriver->Detach(); fAudioDriver->Close(); diff --git a/common/JackServer.h b/common/JackServer.h index 325237de..f99d7c20 100644 --- a/common/JackServer.h +++ b/common/JackServer.h @@ -62,7 +62,7 @@ class SERVER_EXPORT JackServer public: - JackServer(bool sync, bool temporary, long timeout, bool rt, long priority, bool verbose, jack_timer_type_t clock, const char* server_name); + JackServer(bool sync, bool temporary, int timeout, bool rt, int priority, int port_max, bool verbose, jack_timer_type_t clock, const char* server_name); ~JackServer(); int Open(jack_driver_desc_t* driver_desc, JSList* driver_params); diff --git a/common/JackServerAPI.cpp b/common/JackServerAPI.cpp index e8e6c021..a9755fe8 100644 --- a/common/JackServerAPI.cpp +++ b/common/JackServerAPI.cpp @@ -105,6 +105,9 @@ EXPORT jack_client_t* jack_client_open_aux(const char* client_name, jack_options EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_client_open"); +#endif try { assert(JackGlobals::fOpenMutex); JackGlobals::fOpenMutex->Lock(); @@ -125,6 +128,9 @@ EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options EXPORT int jack_client_close(jack_client_t* ext_client) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_client_close"); +#endif assert(JackGlobals::fOpenMutex); JackGlobals::fOpenMutex->Lock(); int res = -1; diff --git a/common/JackServerGlobals.cpp b/common/JackServerGlobals.cpp index 7698c640..fcad0a71 100644 --- a/common/JackServerGlobals.cpp +++ b/common/JackServerGlobals.cpp @@ -41,11 +41,12 @@ int JackServerGlobals::Start(const char* server_name, int time_out_ms, int rt, int priority, + int port_max, int verbose, jack_timer_type_t clock) { jack_log("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld ", sync, time_out_ms, rt, priority, verbose); - new JackServer(sync, temporary, time_out_ms, rt, priority, verbose, clock, server_name); // Will setup fInstance and fUserCount globals + new JackServer(sync, temporary, time_out_ms, rt, priority, port_max, verbose, clock, server_name); // Will setup fInstance and fUserCount globals int res = fInstance->Open(driver_desc, driver_params); return (res < 0) ? res : fInstance->Start(); } @@ -291,7 +292,7 @@ bool JackServerGlobals::Init() free(argv[i]); } - int res = Start(server_name, driver_desc, driver_params, sync, temporary, client_timeout, realtime, realtime_priority, verbose_aux, clock_source); + int res = Start(server_name, driver_desc, driver_params, sync, temporary, client_timeout, realtime, realtime_priority, port_max, verbose_aux, clock_source); if (res < 0) { jack_error("Cannot start server... exit"); Delete(); diff --git a/common/JackServerGlobals.h b/common/JackServerGlobals.h index 00d8b0ff..b4b688c1 100644 --- a/common/JackServerGlobals.h +++ b/common/JackServerGlobals.h @@ -54,6 +54,7 @@ struct SERVER_EXPORT JackServerGlobals int time_out_ms, int rt, int priority, + int port_max, int verbose, jack_timer_type_t clock); static void Stop(); diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index 9045827c..89ed0845 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -100,6 +100,7 @@ static void usage(FILE* file) " [ --name OR -n server-name ]\n" " [ --timeout OR -t client-timeout-in-msecs ]\n" " [ --loopback OR -L loopback-port-number ]\n" + " [ --port-max OR -p maximum-number-of-ports]\n" " [ --midi OR -X midi-driver ]\n" " [ --verbose OR -v ]\n" #ifdef __linux__ @@ -118,7 +119,7 @@ static void usage(FILE* file) " Available backends may include: portaudio, dummy or net.\n\n" #endif #ifdef __linux__ - " Available backends may include: alsa, dummy, freebob, firewire, net, oss or sun.\n\n" + " Available backends may include: alsa, dummy, freebob, firewire or net\n\n" #endif #if defined(__sun__) || defined(sun) " Available backends may include: boomer, oss, dummy or net.\n\n" @@ -178,11 +179,11 @@ int main(int argc, char* argv[]) jackctl_driver_t * loopback_driver_ctl; int replace_registry = 0; + const char *options = "-d:X:P:uvshVrRL:STFl:t:mn:p:" #ifdef __linux__ - const char *options = "-ad:X:P:uvshVrRL:STFl:t:mn:p:c:L:"; -#else - const char *options = "-ad:X:P:uvshVrRL:STFl:t:mn:p:L:"; + "c:" #endif + ; struct option long_options[] = { #ifdef __linux__ @@ -220,7 +221,6 @@ int main(int argc, char* argv[]) char *midi_driver_name = NULL; char **midi_driver_args = NULL; int midi_driver_nargs = 1; - int port_max = 512; int do_mlock = 1; int do_unlock = 0; int loopback = 0; @@ -291,7 +291,11 @@ int main(int argc, char* argv[]) break; case 'p': - port_max = (unsigned int)atol(optarg); + param = jackctl_get_parameter(server_parameters, "port-max"); + if (param != NULL) { + value.ui = atoi(optarg); + jackctl_parameter_set_value(param, &value); + } break; case 'm': @@ -408,7 +412,7 @@ int main(int argc, char* argv[]) // Audio driver audio_driver_ctl = jackctl_server_get_driver(server_ctl, audio_driver_name); if (audio_driver_ctl == NULL) { - fprintf(stderr, "Unkown driver \"%s\"\n", audio_driver_name); + fprintf(stderr, "Unknown driver \"%s\"\n", audio_driver_name); goto fail_free1; } @@ -446,7 +450,7 @@ int main(int argc, char* argv[]) midi_driver_ctl = jackctl_server_get_driver(server_ctl, midi_driver_name); if (midi_driver_ctl == NULL) { - fprintf(stderr, "Unkown driver \"%s\"\n", midi_driver_name); + fprintf(stderr, "Unknown driver \"%s\"\n", midi_driver_name); goto fail_free2; } diff --git a/common/jack/jack.h b/common/jack/jack.h index a5dc3aec..96800dcd 100644 --- a/common/jack/jack.h +++ b/common/jack/jack.h @@ -34,30 +34,20 @@ extern "C" * Note: More documentation can be found in jack/types.h. */ -/************************************************************* - * NOTE: JACK_WEAK_EXPORT ***MUST*** be used on every function - * added to the JACK API after the 0.116.2 release. - *************************************************************/ - -#ifndef JACK_WEAK_EXPORT -#ifdef __GNUC__ -/* JACK_WEAK_EXPORT needs to be a macro which - expands into a compiler directive. If non-null, the directive - must tell the compiler to arrange for weak linkage of - the symbol it used with. For this to work full may - require linker arguments in the client as well. -*/ -#define JACK_WEAK_EXPORT __attribute__((weak)) -#else -/* Add other things here for non-gcc platforms */ -#endif -#endif - -/** -* @defgroup ClientFunctions Creating & manipulating clients -* @{ -*/ - + /************************************************************* + * NOTE: JACK_WEAK_EXPORT ***MUST*** be used on every function + * added to the JACK API after the 0.116.2 release. + * + * Functions that predate this release are marked with + * JACK_WEAK_OPTIONAL_EXPORT which can be defined at compile + * time in a variety of ways. The default definition is empty, + * so that these symbols get normal linkage. If you wish to + * use all JACK symbols with weak linkage, include + * before jack.h. + *************************************************************/ + +#include + /** * Call this function to get version of the JACK, in form of several numbers * @@ -75,7 +65,7 @@ jack_get_version( int *major_ptr, int *minor_ptr, int *micro_ptr, - int *proto_ptr); + int *proto_ptr) JACK_OPTIONAL_WEAK_EXPORT; /** * Call this function to get version of the JACK, in form of a string @@ -84,7 +74,7 @@ jack_get_version( * */ const char * -jack_get_version_string(); +jack_get_version_string() JACK_OPTIONAL_WEAK_EXPORT; /** * Open an external client session with a JACK server. This interface @@ -121,7 +111,7 @@ jack_get_version_string(); */ jack_client_t * jack_client_open (const char *client_name, jack_options_t options, - jack_status_t *status, ...); + jack_status_t *status, ...) JACK_OPTIONAL_WEAK_EXPORT; /** * \bold THIS FUNCTION IS DEPRECATED AND SHOULD NOT BE USED IN @@ -129,20 +119,20 @@ jack_client_t * jack_client_open (const char *client_name, * * @deprecated Please use jack_client_open(). */ -jack_client_t * jack_client_new (const char *client_name); +jack_client_t * jack_client_new (const char *client_name) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * Disconnects an external client from a JACK server. * * @return 0 on success, otherwise a non-zero error code */ -int jack_client_close (jack_client_t *client); +int jack_client_close (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the maximum number of characters in a JACK client name * including the final NULL character. This value is a constant. */ -int jack_client_name_size (void); +int jack_client_name_size (void) JACK_OPTIONAL_WEAK_EXPORT; /** * @return pointer to actual client name. This is useful when @ref @@ -150,7 +140,7 @@ int jack_client_name_size (void); * JackNameNotUnique status was returned. In that case, the actual * name will differ from the @a client_name requested. */ -char * jack_get_client_name (jack_client_t *client); +char * jack_get_client_name (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * Load an internal client into the Jack server. @@ -175,14 +165,14 @@ char * jack_get_client_name (jack_client_t *client); */ int jack_internal_client_new (const char *client_name, const char *load_name, - const char *load_init); + const char *load_init) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * Remove an internal client from a JACK server. * * @deprecated Please use jack_internal_client_load(). */ -void jack_internal_client_close (const char *client_name); +void jack_internal_client_close (const char *client_name) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * Tell the Jack server that the program is ready to start processing @@ -190,7 +180,7 @@ void jack_internal_client_close (const char *client_name); * * @return 0 on success, otherwise a non-zero error code */ -int jack_activate (jack_client_t *client); +int jack_activate (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the Jack server to remove this @a client from the process @@ -199,18 +189,18 @@ int jack_activate (jack_client_t *client); * * @return 0 on success, otherwise a non-zero error code */ -int jack_deactivate (jack_client_t *client); +int jack_deactivate (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * @return pid of client. If not available, 0 will be returned. */ -int jack_get_client_pid (const char *name); +int jack_get_client_pid (const char *name) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the pthread ID of the thread running the JACK client side * code. */ -pthread_t jack_client_thread_id (jack_client_t *); +pthread_t jack_client_thread_id (jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ @@ -221,7 +211,7 @@ pthread_t jack_client_thread_id (jack_client_t *); * * @return 1 if JACK is running realtime, 0 otherwise */ -int jack_is_realtime (jack_client_t *client); +int jack_is_realtime (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * @defgroup NonCallbackAPI The non-callback API @@ -234,7 +224,7 @@ int jack_is_realtime (jack_client_t *client); * * @deprecated Please use jack_cycle_wait() and jack_cycle_signal() functions. */ -jack_nframes_t jack_thread_wait (jack_client_t*, int status); +jack_nframes_t jack_thread_wait (jack_client_t*, int status) JACK_OPTIONAL_WEAK_EXPORT; /** * Wait until this JACK client should process data. @@ -243,7 +233,7 @@ jack_nframes_t jack_thread_wait (jack_client_t*, int status); * * @return the number of frames of data to process */ -jack_nframes_t jack_cycle_wait (jack_client_t* client); + jack_nframes_t jack_cycle_wait (jack_client_t* client) JACK_OPTIONAL_WEAK_EXPORT; /** * Signal next clients in the graph. @@ -251,7 +241,7 @@ jack_nframes_t jack_cycle_wait (jack_client_t* client); * @param client - pointer to a JACK client structure * @param status - if non-zero, calling thread should exit */ -void jack_cycle_signal (jack_client_t* client, int status); +void jack_cycle_signal (jack_client_t* client, int status) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the Jack server to call @a thread_callback in the RT thread. @@ -269,7 +259,7 @@ void jack_cycle_signal (jack_client_t* client, int status); * * @return 0 on success, otherwise a non-zero error code. */ -int jack_set_process_thread(jack_client_t* client, JackThreadCallback thread_callback, void *arg); +int jack_set_process_thread(jack_client_t* client, JackThreadCallback thread_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ @@ -294,7 +284,7 @@ int jack_set_process_thread(jack_client_t* client, JackThreadCallback thread_cal */ int jack_set_thread_init_callback (jack_client_t *client, JackThreadInitCallback thread_init_callback, - void *arg); + void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * @param client pointer to JACK client structure. @@ -346,7 +336,7 @@ void jack_on_shutdown (jack_client_t *client, * jack_on_info_shutdown() will. */ void jack_on_info_shutdown (jack_client_t *client, - JackInfoShutdownCallback shutdown_callback, void *arg); + JackInfoShutdownCallback shutdown_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the Jack server to call @a process_callback whenever there is @@ -367,7 +357,7 @@ void jack_on_info_shutdown (jack_client_t *client, */ int jack_set_process_callback (jack_client_t *client, JackProcessCallback process_callback, - void *arg); + void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the Jack server to call @a freewheel_callback @@ -387,7 +377,7 @@ int jack_set_process_callback (jack_client_t *client, */ int jack_set_freewheel_callback (jack_client_t *client, JackFreewheelCallback freewheel_callback, - void *arg); + void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell JACK to call @a bufsize_callback whenever the size of the the @@ -410,7 +400,7 @@ int jack_set_freewheel_callback (jack_client_t *client, */ int jack_set_buffer_size_callback (jack_client_t *client, JackBufferSizeCallback bufsize_callback, - void *arg); + void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the Jack server to call @a srate_callback whenever the system @@ -427,11 +417,11 @@ int jack_set_buffer_size_callback (jack_client_t *client, */ int jack_set_sample_rate_callback (jack_client_t *client, JackSampleRateCallback srate_callback, - void *arg); + void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** - * Tell the JACK server to call @a registration_callback whenever a - * port is registered or unregistered, passing @a arg as a parameter. + * Tell the JACK server to call @a client_registration_callback whenever a + * client is registered or unregistered, passing @a arg as a parameter. * * All "notification events" are received in a seperated non RT thread, * the code in the supplied function does not need to be @@ -444,7 +434,7 @@ int jack_set_sample_rate_callback (jack_client_t *client, */ int jack_set_client_registration_callback (jack_client_t *, JackClientRegistrationCallback - registration_callback, void *arg); + registration_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the JACK server to call @a registration_callback whenever a @@ -460,8 +450,8 @@ int jack_set_client_registration_callback (jack_client_t *, * @return 0 on success, otherwise a non-zero error code */ int jack_set_port_registration_callback (jack_client_t *, - JackPortRegistrationCallback - registration_callback, void *arg); + JackPortRegistrationCallback + registration_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the JACK server to call @a connect_callback whenever a @@ -477,8 +467,8 @@ int jack_set_client_registration_callback (jack_client_t *, * @return 0 on success, otherwise a non-zero error code */ int jack_set_port_connect_callback (jack_client_t *, - JackPortConnectCallback - connect_callback, void *arg); + JackPortConnectCallback + connect_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the JACK server to call @a rename_callback whenever a @@ -494,8 +484,8 @@ int jack_set_port_connect_callback (jack_client_t *, * @return 0 on success, otherwise a non-zero error code */ int jack_set_port_rename_callback (jack_client_t *, - JackPortRenameCallback - rename_callback, void *arg); + JackPortRenameCallback + rename_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the JACK server to call @a graph_callback whenever the @@ -512,7 +502,7 @@ int jack_set_port_rename_callback (jack_client_t *, */ int jack_set_graph_order_callback (jack_client_t *, JackGraphOrderCallback graph_callback, - void *); + void *) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the JACK server to call @a xrun_callback whenever there is a @@ -528,7 +518,7 @@ int jack_set_graph_order_callback (jack_client_t *, * @return 0 on success, otherwise a non-zero error code */ int jack_set_xrun_callback (jack_client_t *, - JackXRunCallback xrun_callback, void *arg); + JackXRunCallback xrun_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ @@ -561,7 +551,7 @@ int jack_set_xrun_callback (jack_client_t *, * * @return 0 on success, otherwise a non-zero error code. */ -int jack_set_freewheel(jack_client_t* client, int onoff); +int jack_set_freewheel(jack_client_t* client, int onoff) JACK_OPTIONAL_WEAK_EXPORT; /** * Change the buffer size passed to the @a process_callback. @@ -578,13 +568,13 @@ int jack_set_freewheel(jack_client_t* client, int onoff); * * @return 0 on success, otherwise a non-zero error code */ -int jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes); +int jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the sample rate of the jack system, as set by the user when * jackd was started. */ -jack_nframes_t jack_get_sample_rate (jack_client_t *); +jack_nframes_t jack_get_sample_rate (jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the current maximum size that will ever be passed to the @a @@ -595,7 +585,7 @@ jack_nframes_t jack_get_sample_rate (jack_client_t *); * * @see jack_set_buffer_size_callback() */ -jack_nframes_t jack_get_buffer_size (jack_client_t *); +jack_nframes_t jack_get_buffer_size (jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT; /** * Old-style interface to become the timebase for the entire JACK @@ -607,7 +597,7 @@ jack_nframes_t jack_get_buffer_size (jack_client_t *); * * @return ENOSYS, function not implemented. */ -int jack_engine_takeover_timebase (jack_client_t *); +int jack_engine_takeover_timebase (jack_client_t *) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * @return the current CPU load estimated by JACK. This is a running @@ -615,7 +605,7 @@ int jack_engine_takeover_timebase (jack_client_t *); * all clients as a percentage of the real time available per cycle * determined by the buffer size and sample rate. */ -float jack_cpu_load (jack_client_t *client); +float jack_cpu_load (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ @@ -654,7 +644,7 @@ jack_port_t * jack_port_register (jack_client_t *client, const char *port_name, const char *port_type, unsigned long flags, - unsigned long buffer_size); + unsigned long buffer_size) JACK_OPTIONAL_WEAK_EXPORT; /** * Remove the port from the client, disconnecting any existing @@ -662,7 +652,7 @@ jack_port_t * jack_port_register (jack_client_t *client, * * @return 0 on success, otherwise a non-zero error code */ -int jack_port_unregister (jack_client_t *, jack_port_t *); +int jack_port_unregister (jack_client_t *, jack_port_t *) JACK_OPTIONAL_WEAK_EXPORT; /** * This returns a pointer to the memory area associated with the @@ -683,7 +673,7 @@ int jack_port_unregister (jack_client_t *, jack_port_t *); * Caching output ports is DEPRECATED in Jack 2.0, due to some new optimization (like "pipelining"). * Port buffers have to be retrieved in each callback for proper functionning. */ -void * jack_port_get_buffer (jack_port_t *, jack_nframes_t); +void * jack_port_get_buffer (jack_port_t *, jack_nframes_t) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the full name of the jack_port_t (including the @a @@ -691,7 +681,7 @@ void * jack_port_get_buffer (jack_port_t *, jack_nframes_t); * * @see jack_port_name_size(). */ -const char * jack_port_name (const jack_port_t *port); +const char * jack_port_name (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the short name of the jack_port_t (not including the @a @@ -699,35 +689,35 @@ const char * jack_port_name (const jack_port_t *port); * * @see jack_port_name_size(). */ -const char * jack_port_short_name (const jack_port_t *port); +const char * jack_port_short_name (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the @ref JackPortFlags of the jack_port_t. */ -int jack_port_flags (const jack_port_t *port); +int jack_port_flags (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the @a port type, at most jack_port_type_size() characters * including a final NULL. */ -const char * jack_port_type (const jack_port_t *port); +const char * jack_port_type (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the @a port type id. */ -jack_port_type_id_t jack_port_type_id (const jack_port_t *port); +jack_port_type_id_t jack_port_type_id (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return TRUE if the jack_port_t belongs to the jack_client_t. */ -int jack_port_is_mine (const jack_client_t *, const jack_port_t *port); +int jack_port_is_mine (const jack_client_t *, const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return number of connections to or from @a port. * * @pre The calling client must own @a port. */ -int jack_port_connected (const jack_port_t *port); +int jack_port_connected (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return TRUE if the locally-owned @a port is @b directly connected @@ -736,7 +726,7 @@ int jack_port_connected (const jack_port_t *port); * @see jack_port_name_size() */ int jack_port_connected_to (const jack_port_t *port, - const char *port_name); + const char *port_name) JACK_OPTIONAL_WEAK_EXPORT; /** * @return a null-terminated array of full port names to which the @a @@ -749,7 +739,7 @@ int jack_port_connected_to (const jack_port_t *port, * * @see jack_port_name_size(), jack_port_get_all_connections() */ -const char ** jack_port_get_connections (const jack_port_t *port); +const char ** jack_port_get_connections (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return a null-terminated array of full port names to which the @a @@ -771,7 +761,7 @@ const char ** jack_port_get_connections (const jack_port_t *port); * @see jack_port_name_size() */ const char ** jack_port_get_all_connections (const jack_client_t *client, - const jack_port_t *port); + const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @@ -780,7 +770,7 @@ const char ** jack_port_get_all_connections (const jack_client_t *client, * turned out to serve essentially no purpose in real-life * JACK clients. */ -int jack_port_tie (jack_port_t *src, jack_port_t *dst); +int jack_port_tie (jack_port_t *src, jack_port_t *dst) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * @@ -789,7 +779,7 @@ int jack_port_tie (jack_port_t *src, jack_port_t *dst); * turned out to serve essentially no purpose in real-life * JACK clients. */ -int jack_port_untie (jack_port_t *port); +int jack_port_untie (jack_port_t *port) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * @return the time (in frames) between data being available or @@ -801,7 +791,7 @@ int jack_port_untie (jack_port_t *port); * connector and the corresponding frames being readable from the * port. */ -jack_nframes_t jack_port_get_latency (jack_port_t *port); +jack_nframes_t jack_port_get_latency (jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * The maximum of the sum of the latencies in every @@ -809,7 +799,7 @@ jack_nframes_t jack_port_get_latency (jack_port_t *port); * ports with the @ref JackPortIsTerminal flag set. */ jack_nframes_t jack_port_get_total_latency (jack_client_t *, - jack_port_t *port); + jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * The port latency is zero by default. Clients that control @@ -821,7 +811,7 @@ jack_nframes_t jack_port_get_total_latency (jack_client_t *, * to an external digital converter, the latency setting should * include both buffering by the audio interface *and* the converter. */ -void jack_port_set_latency (jack_port_t *, jack_nframes_t); +void jack_port_set_latency (jack_port_t *, jack_nframes_t) JACK_OPTIONAL_WEAK_EXPORT; /** * Request a complete recomputation of a port's total latency. This @@ -834,7 +824,7 @@ void jack_port_set_latency (jack_port_t *, jack_nframes_t); * @return zero for successful execution of the request. non-zero * otherwise. */ -int jack_recompute_total_latency (jack_client_t*, jack_port_t* port); +int jack_recompute_total_latency (jack_client_t*, jack_port_t* port) JACK_OPTIONAL_WEAK_EXPORT; /** * Request a complete recomputation of all port latencies. This @@ -849,7 +839,7 @@ int jack_recompute_total_latency (jack_client_t*, jack_port_t* port); * @return zero for successful execution of the request. non-zero * otherwise. */ -int jack_recompute_total_latencies (jack_client_t*); + int jack_recompute_total_latencies (jack_client_t*) JACK_OPTIONAL_WEAK_EXPORT; /** * Modify a port's short name. May be called at any time. If the @@ -858,7 +848,7 @@ int jack_recompute_total_latencies (jack_client_t*); * * @return 0 on success, otherwise a non-zero error code. */ -int jack_port_set_name (jack_port_t *port, const char *port_name); +int jack_port_set_name (jack_port_t *port, const char *port_name) JACK_OPTIONAL_WEAK_EXPORT; /** * Set @a alias as an alias for @a port. May be called at any time. @@ -873,7 +863,7 @@ int jack_port_set_name (jack_port_t *port, const char *port_name); * * @return 0 on success, otherwise a non-zero error code. */ -int jack_port_set_alias (jack_port_t *port, const char *alias); +int jack_port_set_alias (jack_port_t *port, const char *alias) JACK_OPTIONAL_WEAK_EXPORT; /** * Remove @a alias as an alias for @a port. May be called at any time. @@ -883,20 +873,20 @@ int jack_port_set_alias (jack_port_t *port, const char *alias); * * @return 0 on success, otherwise a non-zero error code. */ -int jack_port_unset_alias (jack_port_t *port, const char *alias); +int jack_port_unset_alias (jack_port_t *port, const char *alias) JACK_OPTIONAL_WEAK_EXPORT; /** * Get any aliases known for @port. * * @return the number of aliases discovered for the port */ -int jack_port_get_aliases (const jack_port_t *port, char* const aliases[2]); +int jack_port_get_aliases (const jack_port_t *port, char* const aliases[2]) JACK_OPTIONAL_WEAK_EXPORT; /** * If @ref JackPortCanMonitor is set for this @a port, turn input * monitoring on or off. Otherwise, do nothing. */ -int jack_port_request_monitor (jack_port_t *port, int onoff); +int jack_port_request_monitor (jack_port_t *port, int onoff) JACK_OPTIONAL_WEAK_EXPORT; /** * If @ref JackPortCanMonitor is set for this @a port_name, turn input @@ -907,7 +897,7 @@ int jack_port_request_monitor (jack_port_t *port, int onoff); * @see jack_port_name_size() */ int jack_port_request_monitor_by_name (jack_client_t *client, - const char *port_name, int onoff); + const char *port_name, int onoff) JACK_OPTIONAL_WEAK_EXPORT; /** * If @ref JackPortCanMonitor is set for a port, this function turns @@ -916,12 +906,12 @@ int jack_port_request_monitor_by_name (jack_client_t *client, * * @return 0 on success, otherwise a non-zero error code */ -int jack_port_ensure_monitor (jack_port_t *port, int onoff); +int jack_port_ensure_monitor (jack_port_t *port, int onoff) JACK_OPTIONAL_WEAK_EXPORT; /** * @return TRUE if input monitoring has been requested for @a port. */ -int jack_port_monitoring_input (jack_port_t *port); +int jack_port_monitoring_input (jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * Establish a connection between two ports. @@ -942,7 +932,7 @@ int jack_port_monitoring_input (jack_port_t *port); */ int jack_connect (jack_client_t *, const char *source_port, - const char *destination_port); + const char *destination_port) JACK_OPTIONAL_WEAK_EXPORT; /** * Remove a connection between two ports. @@ -959,7 +949,7 @@ int jack_connect (jack_client_t *, */ int jack_disconnect (jack_client_t *, const char *source_port, - const char *destination_port); + const char *destination_port) JACK_OPTIONAL_WEAK_EXPORT; /** * Perform the same function as jack_disconnect() using port handles @@ -970,7 +960,7 @@ int jack_disconnect (jack_client_t *, * while generic connection clients (e.g. patchbays) would use * jack_disconnect(). */ -int jack_port_disconnect (jack_client_t *, jack_port_t *); +int jack_port_disconnect (jack_client_t *, jack_port_t *) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the maximum number of characters in a full JACK port name @@ -980,13 +970,13 @@ int jack_port_disconnect (jack_client_t *, jack_port_t *); * with a colon (:) followed by its short name and a NULL * character. */ -int jack_port_name_size(void); +int jack_port_name_size(void) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the maximum number of characters in a JACK port type name * including the final NULL character. This value is a constant. */ -int jack_port_type_size(void); +int jack_port_type_size(void) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ @@ -1014,20 +1004,20 @@ int jack_port_type_size(void); const char ** jack_get_ports (jack_client_t *, const char *port_name_pattern, const char *type_name_pattern, - unsigned long flags); + unsigned long flags) JACK_OPTIONAL_WEAK_EXPORT; /** * @return address of the jack_port_t named @a port_name. * * @see jack_port_name_size() */ -jack_port_t * jack_port_by_name (jack_client_t *, const char *port_name); +jack_port_t * jack_port_by_name (jack_client_t *, const char *port_name) JACK_OPTIONAL_WEAK_EXPORT; /** * @return address of the jack_port_t of a @a port_id. */ jack_port_t * jack_port_by_id (jack_client_t *client, - jack_port_id_t port_id); + jack_port_id_t port_id) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ @@ -1044,7 +1034,7 @@ jack_port_t * jack_port_by_id (jack_client_t *client, * @return the estimated time in frames that has passed since the JACK * server began the current process cycle. */ -jack_nframes_t jack_frames_since_cycle_start (const jack_client_t *); +jack_nframes_t jack_frames_since_cycle_start (const jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the estimated current time in frames. @@ -1052,7 +1042,7 @@ jack_nframes_t jack_frames_since_cycle_start (const jack_client_t *); * callback). The return value can be compared with the value of * jack_last_frame_time to relate time in other threads to JACK time. */ -jack_nframes_t jack_frame_time (const jack_client_t *); +jack_nframes_t jack_frame_time (const jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the precise time at the start of the current process cycle. @@ -1068,17 +1058,17 @@ jack_nframes_t jack_frame_time (const jack_client_t *); * If an xrun occurs, clients must check this value again, as time * may have advanced in a non-linear way (e.g. cycles may have been skipped). */ -jack_nframes_t jack_last_frame_time (const jack_client_t *client); +jack_nframes_t jack_last_frame_time (const jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the estimated time in microseconds of the specified frame time */ -jack_time_t jack_frames_to_time(const jack_client_t *client, jack_nframes_t); +jack_time_t jack_frames_to_time(const jack_client_t *client, jack_nframes_t) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the estimated time in frames for the specified system time. */ -jack_nframes_t jack_time_to_frames(const jack_client_t *client, jack_time_t); +jack_nframes_t jack_time_to_frames(const jack_client_t *client, jack_time_t) JACK_OPTIONAL_WEAK_EXPORT; /** * @return return JACK's current system time in microseconds, @@ -1086,7 +1076,7 @@ jack_nframes_t jack_time_to_frames(const jack_client_t *client, jack_time_t); * * The value returned is guaranteed to be monotonic, but not linear. */ -jack_time_t jack_get_time(); +jack_time_t jack_get_time() JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ @@ -1103,7 +1093,7 @@ jack_time_t jack_get_time(); * * @param msg error message text (no newline at end). */ -extern void (*jack_error_callback)(const char *msg); +extern void (*jack_error_callback)(const char *msg) JACK_OPTIONAL_WEAK_EXPORT; /** * Set the @ref jack_error_callback for error message display. @@ -1112,7 +1102,7 @@ extern void (*jack_error_callback)(const char *msg); * The JACK library provides two built-in callbacks for this purpose: * default_jack_error_callback() and silent_jack_error_callback(). */ -void jack_set_error_function (void (*func)(const char *)); +void jack_set_error_function (void (*func)(const char *)) JACK_OPTIONAL_WEAK_EXPORT; /** * Display JACK info message. @@ -1122,7 +1112,7 @@ void jack_set_error_function (void (*func)(const char *)); * * @param msg info message text (no newline at end). */ -extern void (*jack_info_callback)(const char *msg); +extern void (*jack_info_callback)(const char *msg) JACK_OPTIONAL_WEAK_EXPORT; /** * Set the @ref jack_info_callback for info message display. @@ -1131,7 +1121,7 @@ extern void (*jack_info_callback)(const char *msg); * The JACK library provides two built-in callbacks for this purpose: * default_jack_info_callback() and silent_jack_info_callback(). */ -void jack_set_info_function (void (*func)(const char *)); +void jack_set_info_function (void (*func)(const char *)) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ @@ -1142,7 +1132,7 @@ void jack_set_info_function (void (*func)(const char *)); * Developers are strongly encouraged to use this function instead of the standard "free" function in new code. * */ -void jack_free(void* ptr); +void jack_free(void* ptr) JACK_OPTIONAL_WEAK_EXPORT; #ifdef __cplusplus diff --git a/common/jack/midiport.h b/common/jack/midiport.h index da0b940d..fd620b8d 100644 --- a/common/jack/midiport.h +++ b/common/jack/midiport.h @@ -27,7 +27,7 @@ extern "C" { #include #include - +#include /** Type for raw event data contained in @ref jack_midi_event_t. */ typedef unsigned char jack_midi_data_t; @@ -53,7 +53,7 @@ typedef struct _jack_midi_event * @return number of events inside @a port_buffer */ jack_nframes_t -jack_midi_get_event_count(void* port_buffer); +jack_midi_get_event_count(void* port_buffer) JACK_OPTIONAL_WEAK_EXPORT; /** Get a MIDI event from an event port buffer. @@ -70,7 +70,7 @@ jack_midi_get_event_count(void* port_buffer); int jack_midi_event_get(jack_midi_event_t *event, void *port_buffer, - jack_nframes_t event_index); + jack_nframes_t event_index) JACK_OPTIONAL_WEAK_EXPORT; /** Clear an event buffer. @@ -82,7 +82,7 @@ jack_midi_event_get(jack_midi_event_t *event, * @param port_buffer Port buffer to clear (must be an output port buffer). */ void -jack_midi_clear_buffer(void *port_buffer); +jack_midi_clear_buffer(void *port_buffer) JACK_OPTIONAL_WEAK_EXPORT; /** Get the size of the largest event that can be stored by the port. @@ -93,7 +93,7 @@ jack_midi_clear_buffer(void *port_buffer); * @param port_buffer Port buffer to check size of. */ size_t -jack_midi_max_event_size(void* port_buffer); +jack_midi_max_event_size(void* port_buffer) JACK_OPTIONAL_WEAK_EXPORT; /** Allocate space for an event to be written to an event port buffer. @@ -112,9 +112,9 @@ jack_midi_max_event_size(void* port_buffer); * NULL on error (ie not enough space). */ jack_midi_data_t* -jack_midi_event_reserve(void *port_buffer, +jack_midi_event_reserve(void *port_buffer, jack_nframes_t time, - size_t data_size); + size_t data_size) JACK_OPTIONAL_WEAK_EXPORT; /** Write an event into an event port buffer. @@ -130,10 +130,10 @@ jack_midi_event_reserve(void *port_buffer, * @return 0 on success, ENOBUFS if there's not enough space in buffer for event. */ int -jack_midi_event_write(void *port_buffer, - jack_nframes_t time, +jack_midi_event_write(void *port_buffer, + jack_nframes_t time, const jack_midi_data_t *data, - size_t data_size); + size_t data_size) JACK_OPTIONAL_WEAK_EXPORT; /** Get the number of events that could not be written to @a port_buffer. @@ -145,7 +145,7 @@ jack_midi_event_write(void *port_buffer, * @returns Number of events that could not be written to @a port_buffer. */ jack_nframes_t -jack_midi_get_lost_event_count(void *port_buffer); +jack_midi_get_lost_event_count(void *port_buffer) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ diff --git a/common/jack/thread.h b/common/jack/thread.h index 48adf084..5d002afa 100644 --- a/common/jack/thread.h +++ b/common/jack/thread.h @@ -26,6 +26,7 @@ extern "C" #endif #include +#include /** @file thread.h * @@ -45,7 +46,7 @@ extern "C" * Otherwise returns -1. */ -int jack_client_real_time_priority (jack_client_t*); +int jack_client_real_time_priority (jack_client_t*) JACK_OPTIONAL_WEAK_EXPORT; /** * @returns if JACK is running with realtime scheduling, this returns @@ -53,7 +54,7 @@ int jack_client_real_time_priority (jack_client_t*); * is subject to realtime scheduling. Otherwise returns -1. */ -int jack_client_max_real_time_priority (jack_client_t*); +int jack_client_max_real_time_priority (jack_client_t*) JACK_OPTIONAL_WEAK_EXPORT; /** * Attempt to enable realtime scheduling for a thread. On some @@ -65,7 +66,7 @@ int jack_client_max_real_time_priority (jack_client_t*); * @returns 0, if successful; EPERM, if the calling process lacks * required realtime privileges; otherwise some other error number. */ -int jack_acquire_real_time_scheduling (pthread_t thread, int priority); +int jack_acquire_real_time_scheduling (pthread_t thread, int priority) JACK_OPTIONAL_WEAK_EXPORT; /** * Create a thread for JACK or one of its clients. The thread is @@ -88,7 +89,7 @@ int jack_client_create_thread (jack_client_t* client, int priority, int realtime, /* boolean */ void *(*start_routine)(void*), - void *arg); + void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Drop realtime scheduling for a thread. @@ -97,7 +98,7 @@ int jack_client_create_thread (jack_client_t* client, * * @returns 0, if successful; otherwise an error number. */ -int jack_drop_real_time_scheduling (pthread_t thread); +int jack_drop_real_time_scheduling (pthread_t thread) JACK_OPTIONAL_WEAK_EXPORT; /** * Stop the thread, waiting for the thread handler to terminate. @@ -106,7 +107,7 @@ int jack_drop_real_time_scheduling (pthread_t thread); * * @returns 0, if successful; otherwise an error number. */ -int jack_client_stop_thread(jack_client_t* client, pthread_t thread); +int jack_client_stop_thread(jack_client_t* client, pthread_t thread) JACK_OPTIONAL_WEAK_EXPORT; /** * Cancel the thread then waits for the thread handler to terminate. @@ -115,7 +116,7 @@ int jack_client_stop_thread(jack_client_t* client, pthread_t thread); * * @returns 0, if successful; otherwise an error number. */ - int jack_client_kill_thread(jack_client_t* client, pthread_t thread); + int jack_client_kill_thread(jack_client_t* client, pthread_t thread) JACK_OPTIONAL_WEAK_EXPORT; #ifndef WIN32 @@ -142,7 +143,7 @@ int jack_client_stop_thread(jack_client_t* client, pthread_t thread); * @param creator a function that creates a new thread * */ -void jack_set_thread_creator (jack_thread_creator_t creator); +void jack_set_thread_creator (jack_thread_creator_t creator) JACK_OPTIONAL_WEAK_EXPORT; #endif diff --git a/common/jack/transport.h b/common/jack/transport.h index 67bcaa2a..e8ba8cbb 100644 --- a/common/jack/transport.h +++ b/common/jack/transport.h @@ -26,6 +26,7 @@ extern "C" { #endif #include +#include /** * @defgroup TransportControl Transport and Timebase control @@ -48,7 +49,7 @@ extern "C" { * * @return 0 on success, otherwise a non-zero error code. */ -int jack_release_timebase (jack_client_t *client); +int jack_release_timebase (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * Register (or unregister) as a slow-sync client, one that cannot @@ -72,7 +73,7 @@ int jack_release_timebase (jack_client_t *client); */ int jack_set_sync_callback (jack_client_t *client, JackSyncCallback sync_callback, - void *arg); + void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Set the timeout value for slow-sync clients. @@ -92,7 +93,7 @@ int jack_set_sync_callback (jack_client_t *client, * @return 0 on success, otherwise a non-zero error code. */ int jack_set_sync_timeout (jack_client_t *client, - jack_time_t timeout); + jack_time_t timeout) JACK_OPTIONAL_WEAK_EXPORT; /** * Register as timebase master for the JACK subsystem. @@ -122,7 +123,7 @@ int jack_set_sync_timeout (jack_client_t *client, int jack_set_timebase_callback (jack_client_t *client, int conditional, JackTimebaseCallback timebase_callback, - void *arg); + void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Reposition the transport to a new frame number. @@ -141,7 +142,7 @@ int jack_set_timebase_callback (jack_client_t *client, * @return 0 if valid request, non-zero otherwise. */ int jack_transport_locate (jack_client_t *client, - jack_nframes_t frame); + jack_nframes_t frame) JACK_OPTIONAL_WEAK_EXPORT; /** * Query the current transport state and position. @@ -159,7 +160,7 @@ int jack_transport_locate (jack_client_t *client, * @return Current transport state. */ jack_transport_state_t jack_transport_query (const jack_client_t *client, - jack_position_t *pos); + jack_position_t *pos) JACK_OPTIONAL_WEAK_EXPORT; /** * Return an estimate of the current transport frame, @@ -168,7 +169,7 @@ jack_transport_state_t jack_transport_query (const jack_client_t *client, * * @param client the JACK client structure */ -jack_nframes_t jack_get_current_transport_frame (const jack_client_t *client); +jack_nframes_t jack_get_current_transport_frame (const jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * Request a new transport position. @@ -187,7 +188,7 @@ jack_nframes_t jack_get_current_transport_frame (const jack_client_t *client); * @return 0 if valid request, EINVAL if position structure rejected. */ int jack_transport_reposition (jack_client_t *client, - jack_position_t *pos); + jack_position_t *pos) JACK_OPTIONAL_WEAK_EXPORT; /** * Start the JACK transport rolling. @@ -200,7 +201,7 @@ int jack_transport_reposition (jack_client_t *client, * * @param client the JACK client structure. */ -void jack_transport_start (jack_client_t *client); +void jack_transport_start (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * Stop the JACK transport. @@ -210,7 +211,7 @@ void jack_transport_start (jack_client_t *client); * * @param client the JACK client structure. */ -void jack_transport_stop (jack_client_t *client); +void jack_transport_stop (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * Gets the current transport info structure (deprecated). @@ -225,7 +226,7 @@ void jack_transport_stop (jack_client_t *client); * @pre Must be called from the process thread. */ void jack_get_transport_info (jack_client_t *client, - jack_transport_info_t *tinfo); + jack_transport_info_t *tinfo) JACK_OPTIONAL_WEAK_EXPORT; /** * Set the transport info structure (deprecated). @@ -235,7 +236,7 @@ void jack_get_transport_info (jack_client_t *client, * a ::JackTimebaseCallback. */ void jack_set_transport_info (jack_client_t *client, - jack_transport_info_t *tinfo); + jack_transport_info_t *tinfo) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ diff --git a/common/jack/types.h b/common/jack/types.h index fd71ceac..6c1b0f95 100644 --- a/common/jack/types.h +++ b/common/jack/types.h @@ -202,7 +202,7 @@ typedef void (*JackPortConnectCallback)(jack_port_id_t a, jack_port_id_t b, int * * @return zero on success, non-zero on error */ -typedef int (*JackPortRenameCallback)(jack_port_id_t port, const char* new_name, void *arg); +typedef int (*JackPortRenameCallback)(jack_port_id_t port, const char* old_name, const char* new_name, void *arg); /** * Prototype for the client supplied function that is called diff --git a/common/jack/weakjack.h b/common/jack/weakjack.h new file mode 100644 index 00000000..11d2acaa --- /dev/null +++ b/common/jack/weakjack.h @@ -0,0 +1,52 @@ +/* + Copyright (C) 2010 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __weakjack_h__ +#define __weakjack_h__ + +#ifndef JACK_OPTIONAL_WEAK_EXPORT +/* JACK_OPTIONAL_WEAK_EXPORT needs to be a macro which + expands into a compiler directive. If non-null, the directive + must tell the compiler to arrange for weak linkage of + the symbol it used with. For this to work fully may + require linker arguments for the client as well. +*/ +#ifdef __GNUC__ +#define JACK_OPTIONAL_WEAK_EXPORT __attribute__((__weak__)) +#else +/* Add other things here for non-gcc platforms */ +#endif +#endif + +#ifndef JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT +/* JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT needs to be a macro + which expands into a compiler directive. If non-null, the directive + must tell the compiler to arrange for weak linkage of the + symbol it is used with AND optionally to mark the symbol + as deprecated. For this to work fully may require + linker arguments for the client as well. +*/ +#ifdef __GNUC__ +#define JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT __attribute__((__weak__,__deprecated__)) +#else +/* Add other things here for non-gcc platforms */ +#endif +#endif + +#endif /* weakjack */ diff --git a/common/jack/weakmacros.h b/common/jack/weakmacros.h new file mode 100644 index 00000000..3db19d3f --- /dev/null +++ b/common/jack/weakmacros.h @@ -0,0 +1,61 @@ +/* + Copyright (C) 2010 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __weakmacros_h__ +#define __weakmacros_h__ + +/************************************************************* + * NOTE: JACK_WEAK_EXPORT ***MUST*** be used on every function + * added to the JACK API after the 0.116.2 release. + * + * Functions that predate this release are marked with + * JACK_WEAK_OPTIONAL_EXPORT which can be defined at compile + * time in a variety of ways. The default definition is empty, + * so that these symbols get normal linkage. If you wish to + * use all JACK symbols with weak linkage, include + * before jack.h. + *************************************************************/ + +#ifndef JACK_WEAK_EXPORT +#ifdef __GNUC__ +/* JACK_WEAK_EXPORT needs to be a macro which + expands into a compiler directive. If non-null, the directive + must tell the compiler to arrange for weak linkage of + the symbol it used with. For this to work full may + require linker arguments in the client as well. +*/ +#define JACK_WEAK_EXPORT __attribute__((weak)) +#else +/* Add other things here for non-gcc platforms */ +#endif +#endif + +#ifndef JACK_OPTIONAL_WEAK_EXPORT +#define JACK_OPTIONAL_WEAK_EXPORT +#endif + +#ifndef JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT +#ifdef __GNUC__ +#define JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT __attribute__((__deprecated__)) +#else +/* Add other things here for non-gcc platforms */ +#endif /* __GNUC__ */ +#endif + +#endif /* __weakmacros_h__ */ diff --git a/common/netjack.c b/common/netjack.c index eb5f36b7..a073c2cf 100644 --- a/common/netjack.c +++ b/common/netjack.c @@ -42,6 +42,7 @@ $Id: net_driver.c,v 1.17 2006/04/16 20:16:10 torbenh Exp $ #ifdef WIN32 #include #include +#define socklen_t int #else #include #include @@ -49,7 +50,9 @@ $Id: net_driver.c,v 1.17 2006/04/16 20:16:10 torbenh Exp $ #include "netjack.h" -//#include "config.h" +#ifdef __linux__ +#include "config.h" +#endif #if HAVE_SAMPLERATE #include @@ -92,7 +95,7 @@ int netjack_wait( netjack_driver_state_t *netj ) jacknet_packet_header *pkthdr; if( !netj->next_deadline_valid ) { - netj->next_deadline = jack_get_time() + netj->deadline_offset; + netj->next_deadline = jack_get_time() + netj->period_usecs; netj->next_deadline_valid = 1; } @@ -165,7 +168,7 @@ int netjack_wait( netjack_driver_state_t *netj ) netj->packet_data_valid = 1; int want_deadline; - if( netj->jitter_val != 0 ) + if( netj->jitter_val != 0 ) want_deadline = netj->jitter_val; else if( netj->latency < 4 ) want_deadline = -netj->period_usecs/2; @@ -174,23 +177,23 @@ int netjack_wait( netjack_driver_state_t *netj ) if( netj->deadline_goodness != MASTER_FREEWHEELS ) { if( netj->deadline_goodness < want_deadline ) { - netj->deadline_offset -= netj->period_usecs/100; + netj->next_deadline -= netj->period_usecs/100; //jack_log( "goodness: %d, Adjust deadline: --- %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 ); } if( netj->deadline_goodness > want_deadline ) { - netj->deadline_offset += netj->period_usecs/100; + netj->next_deadline += netj->period_usecs/100; //jack_log( "goodness: %d, Adjust deadline: +++ %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 ); } } - if( netj->deadline_offset < (netj->period_usecs*70/100) ) { - jack_error( "master is forcing deadline_offset to below 70%% of period_usecs... increase latency setting on master" ); - netj->deadline_offset = (netj->period_usecs*90/100); - } +// if( netj->next_deadline < (netj->period_usecs*70/100) ) { +// jack_error( "master is forcing deadline_offset to below 70%% of period_usecs... increase latency setting on master" ); +// netj->deadline_offset = (netj->period_usecs*90/100); +// } - netj->next_deadline = jack_get_time() + netj->deadline_offset; + netj->next_deadline += netj->period_usecs; } else { netj->time_to_deadline = 0; - netj->next_deadline = jack_get_time() + netj->deadline_offset; + netj->next_deadline += netj->period_usecs; // bah... the packet is not there. // either // - it got lost. @@ -581,7 +584,13 @@ netjack_startup( netjack_driver_state_t *netj ) struct sockaddr_in address; // Now open the socket, and wait for the first packet to arrive... netj->sockfd = socket (AF_INET, SOCK_DGRAM, 0); + #ifdef WIN32 + u_long parm = 1; + DWORD bufsize = 262144; + //ioctlsocket( netj->sockfd, FIONBIO, &parm ); + setsockopt( netj->sockfd, SOL_SOCKET, SO_RCVBUF, (char *)&bufsize, sizeof(bufsize) ); + setsockopt( netj->sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&bufsize, sizeof(bufsize) ); if (netj->sockfd == INVALID_SOCKET) #else if (netj->sockfd == -1) @@ -705,7 +714,7 @@ netjack_startup( netjack_driver_state_t *netj ) netj->period_usecs = (jack_time_t) floor ((((float) netj->period_size) / (float)netj->sample_rate) * 1000000.0f); - + if( netj->latency == 0 ) netj->deadline_offset = 50*netj->period_usecs; else @@ -716,7 +725,7 @@ netjack_startup( netjack_driver_state_t *netj ) // TODO: this is a hack. But i dont want to change the packet header. netj->resample_factor = (netj->resample_factor * netj->period_size * 1024 / netj->sample_rate / 8)&(~1); netj->resample_factor_up = (netj->resample_factor_up * netj->period_size * 1024 / netj->sample_rate / 8)&(~1); - + netj->net_period_down = netj->resample_factor; netj->net_period_up = netj->resample_factor_up; } else { diff --git a/common/netjack_packet.c b/common/netjack_packet.c index 4edbb2a3..dfe3b9e2 100644 --- a/common/netjack_packet.c +++ b/common/netjack_packet.c @@ -26,7 +26,9 @@ * */ -//#include "config.h" +#ifdef __linux__ +#include "config.h" +#endif #ifdef __APPLE__ #define _DARWIN_C_SOURCE @@ -50,7 +52,9 @@ #ifdef WIN32 #include +#define socklen_t int #include +#define socklen_t int #else #include #include @@ -126,7 +130,7 @@ int get_sample_size (int bitdepth) if (bitdepth == 16) return sizeof (int16_t); //JN: why? is this for buffer sizes before or after encoding? - //JN: if the former, why not int16_t, if the latter, shouldn't it depend on -c N? + //JN: if the former, why not int16_t, if the latter, shouldn't it depend on -c N? if( bitdepth == CELT_MODE ) return sizeof( unsigned char ); return sizeof (int32_t); diff --git a/common/ringbuffer.c b/common/ringbuffer.c index f2096630..45ee27b3 100644 --- a/common/ringbuffer.c +++ b/common/ringbuffer.c @@ -70,7 +70,7 @@ jack_ringbuffer_create (size_t sz) int power_of_two; jack_ringbuffer_t *rb; - if ((rb = malloc (sizeof (jack_ringbuffer_t))) == NULL) { + if ((rb = (jack_ringbuffer_t *) malloc (sizeof (jack_ringbuffer_t))) == NULL) { return NULL; } @@ -81,7 +81,7 @@ jack_ringbuffer_create (size_t sz) rb->size_mask -= 1; rb->write_ptr = 0; rb->read_ptr = 0; - if ((rb->buf = malloc (rb->size)) == NULL) { + if ((rb->buf = (char *) malloc (rb->size)) == NULL) { free (rb); return NULL; } @@ -400,4 +400,5 @@ jack_ringbuffer_get_write_vector (const jack_ringbuffer_t * rb, vec[0].len = free_cnt; vec[1].len = 0; } -} \ No newline at end of file +} + diff --git a/common/shm.c b/common/shm.c index fdd3b151..e74a2134 100644 --- a/common/shm.c +++ b/common/shm.c @@ -18,23 +18,23 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ - -/* This module provides a set of abstract shared memory interfaces - * with support using both System V and POSIX shared memory - * implementations. The code is divided into three sections: - * - * - common (interface-independent) code - * - POSIX implementation - * - System V implementation - * - * The implementation used is determined by whether USE_POSIX_SHM was - * set in the ./configure step. - */ + +/* This module provides a set of abstract shared memory interfaces + * with support using both System V and POSIX shared memory + * implementations. The code is divided into three sections: + * + * - common (interface-independent) code + * - POSIX implementation + * - System V implementation + * + * The implementation used is determined by whether USE_POSIX_SHM was + * set in the ./configure step. + */ #include "JackConstants.h" #ifdef WIN32 -#include +#include #include #else @@ -145,23 +145,22 @@ static int semid = -1; #ifdef WIN32 -static void -semaphore_init () {} +static int +semaphore_init () {return 0;} -static void -semaphore_add (int value) {} +static int +semaphore_add (int value) {return 0;} #else /* all semaphore errors are fatal -- issue message, but do not return */ static void semaphore_error (char *msg) { - jack_error ("Fatal JACK semaphore error: %s (%s)", + jack_error ("JACK semaphore error: %s (%s)", msg, strerror (errno)); - abort (); } -static void +static int semaphore_init () { key_t semkey = JACK_SEMAPHORE_KEY; @@ -180,21 +179,26 @@ semaphore_init () sbuf.sem_op = 1; sbuf.sem_flg = 0; if (semop(semid, &sbuf, 1) == -1) { - semaphore_error ("semop"); + semaphore_error ("semop"); + return -1; } } else if (errno == EEXIST) { if ((semid = semget(semkey, 0, 0)) == -1) { - semaphore_error ("semget"); + semaphore_error ("semget"); + return -1; } } else { - semaphore_error ("semget creation"); + semaphore_error ("semget creation"); + return -1; } } + + return 0; } -static inline void +static inline int semaphore_add (int value) { struct sembuf sbuf; @@ -202,20 +206,26 @@ semaphore_add (int value) sbuf.sem_num = 0; sbuf.sem_op = value; sbuf.sem_flg = SEM_UNDO; + if (semop(semid, &sbuf, 1) == -1) { semaphore_error ("semop"); + return -1; } + + return 0; } #endif -static void +static int jack_shm_lock_registry (void) { - if (semid == -1) - semaphore_init (); + if (semid == -1) { + if (semaphore_init () < 0) + return -1; + } - semaphore_add (-1); + return semaphore_add (-1); } static void @@ -297,7 +307,10 @@ jack_server_initialize_shm (int new_registry) if (jack_shm_header) return 0; /* already initialized */ - jack_shm_lock_registry (); + if (jack_shm_lock_registry () < 0) { + jack_error ("jack_shm_lock_registry fails..."); + return -1; + } rc = jack_access_registry (®istry_info); @@ -353,7 +366,11 @@ jack_initialize_shm (const char *server_name) jack_set_server_prefix (server_name); - jack_shm_lock_registry (); + if (jack_shm_lock_registry () < 0) { + jack_error ("jack_shm_lock_registry fails..."); + return -1; + } + if ((rc = jack_access_registry (®istry_info)) == 0) { if ((rc = jack_shm_validate_registry ()) != 0) { jack_error ("Incompatible shm registry, " @@ -412,15 +429,20 @@ jack_release_shm_entry (jack_shm_registry_index_t index) sizeof (jack_shm_registry[index].id)); } -void +int jack_release_shm_info (jack_shm_registry_index_t index) { /* must NOT have the registry locked */ if (jack_shm_registry[index].allocator == GetPID()) { - jack_shm_lock_registry (); + if (jack_shm_lock_registry () < 0) { + jack_error ("jack_shm_lock_registry fails..."); + return -1; + } jack_release_shm_entry (index); jack_shm_unlock_registry (); } + + return 0; } /* Claim server_name for this process. @@ -440,7 +462,10 @@ jack_register_server (const char *server_name, int new_registry) if (jack_server_initialize_shm (new_registry)) return ENOMEM; - jack_shm_lock_registry (); + if (jack_shm_lock_registry () < 0) { + jack_error ("jack_shm_lock_registry fails..."); + return -1; + } /* See if server_name already registered. Since server names * are per-user, we register the unique server prefix string. @@ -493,11 +518,14 @@ jack_register_server (const char *server_name, int new_registry) } /* release server_name registration */ -void +int jack_unregister_server (const char *server_name /* unused */) { int i; - jack_shm_lock_registry (); + if (jack_shm_lock_registry () < 0) { + jack_error ("jack_shm_lock_registry fails..."); + return -1; + } for (i = 0; i < MAX_SERVERS; i++) { if (jack_shm_header->server[i].pid == GetPID()) { @@ -506,7 +534,8 @@ jack_unregister_server (const char *server_name /* unused */) } } - jack_shm_unlock_registry (); + jack_shm_unlock_registry (); + return 0; } /* called for server startup and termination */ @@ -517,7 +546,10 @@ jack_cleanup_shm () int destroy; jack_shm_info_t copy; - jack_shm_lock_registry (); + if (jack_shm_lock_registry () < 0) { + jack_error ("jack_shm_lock_registry fails..."); + return -1; + } for (i = 0; i < MAX_SHM_ID; i++) { jack_shm_registry_t* r; @@ -741,7 +773,10 @@ jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* si) int rc = -1; char name[SHM_NAME_MAX+1]; - jack_shm_lock_registry (); + if (jack_shm_lock_registry () < 0) { + jack_error ("jack_shm_lock_registry fails..."); + return -1; + } if ((registry = jack_get_free_shm_info ()) == NULL) { jack_error ("shm registry full"); @@ -780,7 +815,7 @@ jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* si) close (shm_fd); registry->size = size; strncpy (registry->id, name, sizeof (registry->id)); - registry->allocator = getpid(); + registry->allocator = GetPID(); si->index = registry->index; si->ptr.attached_at = MAP_FAILED; /* not attached */ rc = 0; /* success */ @@ -936,7 +971,10 @@ jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* si) int rc = -1; char name[SHM_NAME_MAX+1]; - jack_shm_lock_registry (); + if (jack_shm_lock_registry () < 0) { + jack_error ("jack_shm_lock_registry fails..."); + return -1; + } if ((registry = jack_get_free_shm_info ()) == NULL) { jack_error ("shm registry full"); @@ -1133,7 +1171,10 @@ jack_shmalloc (const char* name_not_used, jack_shmsize_t size, int rc = -1; jack_shm_registry_t* registry; - jack_shm_lock_registry (); + if (jack_shm_lock_registry () < 0) { + jack_error ("jack_shm_lock_registry fails..."); + return -1; + } if ((registry = jack_get_free_shm_info ())) { diff --git a/common/shm.h b/common/shm.h index 4a7d15c6..ed5a953f 100644 --- a/common/shm.h +++ b/common/shm.h @@ -115,33 +115,33 @@ extern "C" * indicating where the shared memory has been * attached to the address space. */ - + typedef struct _jack_shm_info { jack_shm_registry_index_t index; /* offset into the registry */ uint32_t size; union { void *attached_at; /* address where attached */ - char ptr_size[8]; - } ptr; /* a "pointer" that has the same 8 bytes size when compling in 32 or 64 bits */ + char ptr_size[8]; + } ptr; /* a "pointer" that has the same 8 bytes size when compling in 32 or 64 bits */ } POST_PACKED_STRUCTURE jack_shm_info_t; /* utility functions used only within JACK */ - + void jack_shm_copy_from_registry (jack_shm_info_t*, jack_shm_registry_index_t); void jack_shm_copy_to_registry (jack_shm_info_t*, jack_shm_registry_index_t*); - void jack_release_shm_info (jack_shm_registry_index_t); - char* jack_shm_addr (jack_shm_info_t* si); + int jack_release_shm_info (jack_shm_registry_index_t); + char* jack_shm_addr (jack_shm_info_t* si); - // here begin the API + // here begin the API int jack_register_server (const char *server_name, int new_registry); - void jack_unregister_server (const char *server_name); + int jack_unregister_server (const char *server_name); int jack_initialize_shm (const char *server_name); - int jack_initialize_shm_server (void); - int jack_initialize_shm_client (void); + int jack_initialize_shm_server (void); + int jack_initialize_shm_client (void); int jack_cleanup_shm (void); int jack_shmalloc (const char *shm_name, jack_shmsize_t size, @@ -149,7 +149,7 @@ extern "C" void jack_release_shm (jack_shm_info_t*); void jack_destroy_shm (jack_shm_info_t*); int jack_attach_shm (jack_shm_info_t*); - int jack_attach_shm_read (jack_shm_info_t*); + int jack_attach_shm_read (jack_shm_info_t*); int jack_resize_shm (jack_shm_info_t*, jack_shmsize_t size); #ifdef __cplusplus diff --git a/common/wscript b/common/wscript index 951ab68b..4af4f268 100644 --- a/common/wscript +++ b/common/wscript @@ -130,7 +130,8 @@ def build(bld): 'JackNetTool.cpp', 'JackNetInterface.cpp', 'JackArgParser.cpp', - 'JackDummyDriver.cpp', + 'JackPhysicalMidiInput.cpp', + 'JackPhysicalMidiOutput.cpp', ] if bld.env['IS_LINUX']: diff --git a/dbus/controller_iface_control.c b/dbus/controller_iface_control.c index 768c192f..ca3ab038 100644 --- a/dbus/controller_iface_control.c +++ b/dbus/controller_iface_control.c @@ -283,8 +283,11 @@ jack_control_run_method( return true; not_started: - jack_dbus_error (call, JACK_DBUS_ERROR_SERVER_NOT_RUNNING, - "Can't execute method '%s' with stopped JACK server", call->method_name); + jack_dbus_only_error( + call, + JACK_DBUS_ERROR_SERVER_NOT_RUNNING, + "Can't execute method '%s' with stopped JACK server", + call->method_name); exit: return true; diff --git a/dbus/controller_iface_patchbay.c b/dbus/controller_iface_patchbay.c index 9adb7cfa..ed477d7d 100644 --- a/dbus/controller_iface_patchbay.c +++ b/dbus/controller_iface_patchbay.c @@ -281,6 +281,35 @@ jack_controller_patchbay_send_signal_ports_disconnected( DBUS_TYPE_INVALID); } +void +jack_controller_patchbay_send_signal_port_renamed( + dbus_uint64_t new_graph_version, + dbus_uint64_t client_id, + const char * client_name, + dbus_uint64_t port_id, + const char * port_old_name, + const char * port_new_name) +{ + + jack_dbus_send_signal( + JACK_CONTROLLER_OBJECT_PATH, + JACK_DBUS_IFACE_NAME, + "PortRenamed", + DBUS_TYPE_UINT64, + &new_graph_version, + DBUS_TYPE_UINT64, + &client_id, + DBUS_TYPE_STRING, + &client_name, + DBUS_TYPE_UINT64, + &port_id, + DBUS_TYPE_STRING, + &port_old_name, + DBUS_TYPE_STRING, + &port_new_name, + DBUS_TYPE_INVALID); +} + static struct jack_graph_client * jack_controller_patchbay_find_client( @@ -1618,6 +1647,65 @@ jack_controller_port_connect_callback( } } +int jack_controller_port_rename_callback(jack_port_id_t port, const char * old_name, const char * new_name, void * context) +{ + struct jack_graph_port * port_ptr; + const char * port_new_short_name; + const char * port_old_short_name; + char * name_buffer; + + jack_info("port renamed: '%s' -> '%s'", old_name, new_name); + + port_new_short_name = strchr(new_name, ':'); + if (port_new_short_name == NULL) + { + jack_error("renamed port new name '%s' does not contain ':' separator char", new_name); + return -1; + } + + port_new_short_name++; /* skip ':' separator char */ + + port_old_short_name = strchr(old_name, ':'); + if (port_old_short_name == NULL) + { + jack_error("renamed port old name '%s' does not contain ':' separator char", old_name); + return -1; + } + + port_old_short_name++; /* skip ':' separator char */ + + port_ptr = jack_controller_patchbay_find_port_by_full_name(patchbay_ptr, old_name); + if (port_ptr == NULL) + { + jack_error("renamed port '%s' not found", old_name); + return -1; + } + + name_buffer = strdup(port_new_short_name); + if (name_buffer == NULL) + { + jack_error("strdup() call for port name '%s' failed.", port_new_short_name); + return 1; + } + + free(port_ptr->name); + port_ptr->name = name_buffer; + + pthread_mutex_lock(&patchbay_ptr->lock); + patchbay_ptr->graph.version++; + jack_controller_patchbay_send_signal_port_renamed( + patchbay_ptr->graph.version, + port_ptr->client->id, + port_ptr->client->name, + port_ptr->id, + port_old_short_name, + port_ptr->name); + jack_controller_patchbay_send_signal_graph_changed(patchbay_ptr->graph.version); + pthread_mutex_unlock(&patchbay_ptr->lock); + + return 0; +} + #undef controller_ptr void @@ -1714,6 +1802,13 @@ jack_controller_patchbay_init( goto fail_uninit_mutex; } + ret = jack_set_port_rename_callback(controller_ptr->client, jack_controller_port_rename_callback, controller_ptr); + if (ret != 0) + { + jack_error("jack_set_port_rename_callback() failed with error %d", ret); + goto fail_uninit_mutex; + } + return true; fail_uninit_mutex: @@ -1838,6 +1933,15 @@ JACK_DBUS_SIGNAL_ARGUMENTS_BEGIN(PortsDisconnected) JACK_DBUS_SIGNAL_ARGUMENT("connection_id", DBUS_TYPE_UINT64_AS_STRING) JACK_DBUS_SIGNAL_ARGUMENTS_END +JACK_DBUS_SIGNAL_ARGUMENTS_BEGIN(PortRenamed) + JACK_DBUS_SIGNAL_ARGUMENT("new_graph_version", DBUS_TYPE_UINT64_AS_STRING) + JACK_DBUS_SIGNAL_ARGUMENT("port_id", DBUS_TYPE_UINT64_AS_STRING) + JACK_DBUS_SIGNAL_ARGUMENT("client_id", DBUS_TYPE_UINT64_AS_STRING) + JACK_DBUS_SIGNAL_ARGUMENT("client_name", DBUS_TYPE_STRING_AS_STRING) + JACK_DBUS_SIGNAL_ARGUMENT("port_old_name", DBUS_TYPE_STRING_AS_STRING) + JACK_DBUS_SIGNAL_ARGUMENT("port_new_name", DBUS_TYPE_STRING_AS_STRING) +JACK_DBUS_SIGNAL_ARGUMENTS_END + JACK_DBUS_SIGNALS_BEGIN JACK_DBUS_SIGNAL_DESCRIBE(GraphChanged) JACK_DBUS_SIGNAL_DESCRIBE(ClientAppeared) @@ -1846,6 +1950,7 @@ JACK_DBUS_SIGNALS_BEGIN JACK_DBUS_SIGNAL_DESCRIBE(PortDisappeared) JACK_DBUS_SIGNAL_DESCRIBE(PortsConnected) JACK_DBUS_SIGNAL_DESCRIBE(PortsDisconnected) + JACK_DBUS_SIGNAL_DESCRIBE(PortRenamed) JACK_DBUS_SIGNALS_END JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_patchbay, JACK_DBUS_IFACE_NAME) diff --git a/dbus/jackdbus.c b/dbus/jackdbus.c index ef03680f..eb86308b 100644 --- a/dbus/jackdbus.c +++ b/dbus/jackdbus.c @@ -765,6 +765,34 @@ jack_dbus_error( va_end(ap); } +void +jack_dbus_only_error( + void *dbus_call_context_ptr, + const char *error_name, + const char *format, + ...) +{ + va_list ap; + char buffer[300]; + + va_start(ap, format); + + vsnprintf(buffer, sizeof(buffer), format, ap); + + if (((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply != NULL) + { + dbus_message_unref(((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply); + ((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply = NULL; + } + + ((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply = dbus_message_new_error( + ((struct jack_dbus_method_call *)dbus_call_context_ptr)->message, + error_name, + buffer); + + va_end(ap); +} + int main (int argc, char **argv) { diff --git a/dbus/jackdbus.h b/dbus/jackdbus.h index d94bc334..d920cf06 100644 --- a/dbus/jackdbus.h +++ b/dbus/jackdbus.h @@ -257,6 +257,13 @@ jack_dbus_error( const char *format, ...); +void +jack_dbus_only_error( + void *dbus_call_context_ptr, + const char *error_name, + const char *format, + ...); + bool jack_dbus_get_method_args( struct jack_dbus_method_call *call, diff --git a/dbus/wscript b/dbus/wscript index e23e67b0..a4066b57 100644 --- a/dbus/wscript +++ b/dbus/wscript @@ -10,11 +10,15 @@ def set_options(opt): opt.add_option('--enable-pkg-config-dbus-service-dir', action='store_true', default=False, help='force D-Bus service install dir to be one returned by pkg-config') def configure(conf): - if not conf.check_cfg(package='dbus-1', atleast_version='1.0.0', args='--cflags --libs'): + conf.env['BUILD_JACKDBUS'] = False + + if not conf.check_cfg(package='dbus-1', atleast_version='1.0.0', args='--cflags --libs') or not conf.is_defined('HAVE_DBUS_1'): + print Logs.colors.RED + 'WARNING !! jackdbus will not be built because libdbus-dev is missing' + Logs.colors.NORMAL return dbus_dir = conf.check_cfg(package='dbus-1', args='--variable=session_bus_services_dir') if not dbus_dir: + print Logs.colors.RED + 'WARNING !! jackdbus will not be built because service dir is unknown' + Logs.colors.NORMAL return dbus_dir = dbus_dir.strip() @@ -31,15 +35,13 @@ def configure(conf): if conf.is_defined('HAVE_EXPAT'): conf.env['LIB_EXPAT'] = ['expat'] + else: + print Logs.colors.RED + 'WARNING !! jackdbus will not be built because of expat is missing' + Logs.colors.NORMAL + return - conf.env['BUILD_JACKDBUS1'] = conf.is_defined('HAVE_EXPAT') and conf.is_defined('HAVE_DBUS_1') - + conf.env['BUILD_JACKDBUS'] = True def build(bld): - - if bld.env['BUILD_JACKDBUS1'] != True: - return - obj = bld.new_task_gen('cc', 'program') if bld.env['IS_LINUX']: sysdeps_dbus_include = ['../linux', '../posix'] diff --git a/doxyfile b/doxyfile index 0ba53fc0..bc5116a0 100644 --- a/doxyfile +++ b/doxyfile @@ -23,7 +23,7 @@ PROJECT_NAME = "Jack2" # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 1.9.4 +PROJECT_NUMBER = 1.9.5 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/example-clients/alsa_in.c b/example-clients/alsa_in.c index 2a8b78c3..a04271eb 100644 --- a/example-clients/alsa_in.c +++ b/example-clients/alsa_in.c @@ -184,7 +184,7 @@ static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_ } /* set the buffer time */ - buffer_time = 1000000*period*nperiods/rate; + buffer_time = 1000000*(uint64_t)period*nperiods/rate; err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, &dir); if (err < 0) { printf("Unable to set buffer time %i for playback: %s\n", 1000000*period*nperiods/rate, snd_strerror(err)); @@ -199,7 +199,7 @@ static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_ printf( "WARNING: buffer size does not match: (requested %d, got %d)\n", nperiods * period, (int) real_buffer_size ); } /* set the period time */ - period_time = 1000000*period/rate; + period_time = 1000000*(uint64_t)period/rate; err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, &dir); if (err < 0) { printf("Unable to set period time %i for playback: %s\n", 1000000*period/rate, snd_strerror(err)); diff --git a/example-clients/alsa_out.c b/example-clients/alsa_out.c index 2d34cd13..852e978c 100644 --- a/example-clients/alsa_out.c +++ b/example-clients/alsa_out.c @@ -183,7 +183,7 @@ static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_ } /* set the buffer time */ - buffer_time = 1000000*period*nperiods/rate; + buffer_time = 1000000*(uint64_t)period*nperiods/rate; err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, &dir); if (err < 0) { printf("Unable to set buffer time %i for playback: %s\n", 1000000*period*nperiods/rate, snd_strerror(err)); @@ -198,7 +198,7 @@ static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_ printf( "WARNING: buffer size does not match: (requested %d, got %d)\n", nperiods * period, (int) real_buffer_size ); } /* set the period time */ - period_time = 1000000*period/rate; + period_time = 1000000*(uint64_t)period/rate; err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, &dir); if (err < 0) { printf("Unable to set period time %i for playback: %s\n", 1000000*period/rate, snd_strerror(err)); diff --git a/example-clients/jack_control b/example-clients/jack_control index c7b2dab5..1d06436b 100755 --- a/example-clients/jack_control +++ b/example-clients/jack_control @@ -106,9 +106,9 @@ def main(): print "Usage: %s [command] [command] ..." % os.path.basename(sys.argv[0]) print "Commands:" print " exit - exit jack dbus service (stops jack server if currently running)" - print " status - check whether jack server is started, return value is 0 if runing and 1 otherwise" + print " status - check whether jack server is started, return value is 0 if running and 1 otherwise" print " start - start jack server if not currently started" - print " stop - stop jack server if currenly started" + print " stop - stop jack server if currently started" print " sm - switch master to currently selected driver" print " dl - get list of available drivers" print " dg - get currently selected driver" diff --git a/example-clients/netmaster.c b/example-clients/netmaster.c index c9d5be48..3ca00900 100644 --- a/example-clients/netmaster.c +++ b/example-clients/netmaster.c @@ -136,8 +136,14 @@ main (int argc, char *argv[]) for (i = 0; i < result.audio_output; i++) { audio_output_buffer[i] = calloc(buffer_size, sizeof(float)); } - - // Run until interrupted + + /* + Run until interrupted. + + WARNING !! : this code is given for demonstration purpose. For proper timing bevahiour + it has to be called in a real-time context (which is *not* the case here...) + */ + while (1) { // Copy input to output diff --git a/example-clients/netsource.c b/example-clients/netsource.c index ed4c1af0..d6d252c2 100644 --- a/example-clients/netsource.c +++ b/example-clients/netsource.c @@ -34,8 +34,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include +#ifdef __linux__ +#include "config.h" +#endif + #ifdef WIN32 #include +#define socklen_t int #include #else #include @@ -753,7 +758,7 @@ main (int argc, char *argv[]) if (statecopy_netxruns != state_netxruns) { statecopy_netxruns = state_netxruns; printf ("%s: at frame %06d -> total netxruns %d (%d%%) queue time= %d\n", - client_name, + client_name, state_currentframe, statecopy_netxruns, 100*statecopy_netxruns/state_currentframe, diff --git a/example-clients/wscript b/example-clients/wscript index 152c737d..215be593 100644 --- a/example-clients/wscript +++ b/example-clients/wscript @@ -51,10 +51,11 @@ def configure(conf): e = conf.check_cc(lib='readline', define_name="HAVE_READLINE") - if conf.is_defined('HAVE_READLINE'): - conf.env['LIB_READLINE'] = ['readline'] + # define_name="HAVE_READLINE" has no effect, LIB_READLINE is defined if readline is available + #if conf.is_defined('HAVE_READLINE'): + # conf.env['LIB_READLINE'] = ['readline'] - conf.env['BUILD_EXAMPLE_CLIENT_TRANSPORT'] = conf.is_defined('HAVE_READLINE') and conf.is_defined('HAVE_NCURSES') + conf.env['BUILD_EXAMPLE_CLIENT_TRANSPORT'] = bool(conf.env['LIB_READLINE']) and bool(conf.env['LIB_NCURSES']) conf.env['BUILD_EXAMPLE_CLIENT_REC'] = conf.is_defined('HAVE_SNDFILE') diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index 45486f53..8c0168e5 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -263,102 +263,106 @@ JackAlsaDriver::alsa_driver_hw_specific (alsa_driver_t *driver, int hw_monitorin void JackAlsaDriver::alsa_driver_setup_io_function_pointers (alsa_driver_t *driver) { - if (SND_PCM_FORMAT_FLOAT_LE == driver->playback_sample_format) { - if (driver->playback_interleaved) { - driver->channel_copy = memcpy_interleave_d32_s32; - } else { - driver->channel_copy = memcpy_fake; - } - driver->read_via_copy = sample_move_floatLE_sSs; - driver->write_via_copy = sample_move_dS_floatLE; - } else { - - switch (driver->playback_sample_bytes) { - case 2: + if (driver->playback_handle) { + if (SND_PCM_FORMAT_FLOAT_LE == driver->playback_sample_format) { if (driver->playback_interleaved) { - driver->channel_copy = memcpy_interleave_d16_s16; + driver->channel_copy = memcpy_interleave_d32_s32; } else { driver->channel_copy = memcpy_fake; } + driver->read_via_copy = sample_move_floatLE_sSs; + driver->write_via_copy = sample_move_dS_floatLE; + } else { + + switch (driver->playback_sample_bytes) { + case 2: + if (driver->playback_interleaved) { + driver->channel_copy = memcpy_interleave_d16_s16; + } else { + driver->channel_copy = memcpy_fake; + } - switch (driver->dither) { - case Rectangular: - jack_info("Rectangular dithering at 16 bits"); - driver->write_via_copy = driver->quirk_bswap? - sample_move_dither_rect_d16_sSs: - sample_move_dither_rect_d16_sS; - break; + switch (driver->dither) { + case Rectangular: + jack_info("Rectangular dithering at 16 bits"); + driver->write_via_copy = driver->quirk_bswap? + sample_move_dither_rect_d16_sSs: + sample_move_dither_rect_d16_sS; + break; - case Triangular: - jack_info("Triangular dithering at 16 bits"); - driver->write_via_copy = driver->quirk_bswap? - sample_move_dither_tri_d16_sSs: - sample_move_dither_tri_d16_sS; - break; + case Triangular: + jack_info("Triangular dithering at 16 bits"); + driver->write_via_copy = driver->quirk_bswap? + sample_move_dither_tri_d16_sSs: + sample_move_dither_tri_d16_sS; + break; - case Shaped: - jack_info("Noise-shaped dithering at 16 bits"); - driver->write_via_copy = driver->quirk_bswap? - sample_move_dither_shaped_d16_sSs: - sample_move_dither_shaped_d16_sS; - break; + case Shaped: + jack_info("Noise-shaped dithering at 16 bits"); + driver->write_via_copy = driver->quirk_bswap? + sample_move_dither_shaped_d16_sSs: + sample_move_dither_shaped_d16_sS; + break; - default: - driver->write_via_copy = driver->quirk_bswap? - sample_move_d16_sSs : - sample_move_d16_sS; + default: + driver->write_via_copy = driver->quirk_bswap? + sample_move_d16_sSs : + sample_move_d16_sS; + break; + } break; - } - break; - case 3: /* NO DITHER */ - if (driver->playback_interleaved) { - driver->channel_copy = memcpy_interleave_d24_s24; - } else { - driver->channel_copy = memcpy_fake; - } + case 3: /* NO DITHER */ + if (driver->playback_interleaved) { + driver->channel_copy = memcpy_interleave_d24_s24; + } else { + driver->channel_copy = memcpy_fake; + } - driver->write_via_copy = driver->quirk_bswap? - sample_move_d24_sSs: - sample_move_d24_sS; + driver->write_via_copy = driver->quirk_bswap? + sample_move_d24_sSs: + sample_move_d24_sS; - break; + break; - case 4: /* NO DITHER */ - if (driver->playback_interleaved) { - driver->channel_copy = memcpy_interleave_d32_s32; - } else { - driver->channel_copy = memcpy_fake; - } + case 4: /* NO DITHER */ + if (driver->playback_interleaved) { + driver->channel_copy = memcpy_interleave_d32_s32; + } else { + driver->channel_copy = memcpy_fake; + } - driver->write_via_copy = driver->quirk_bswap? - sample_move_d32u24_sSs: - sample_move_d32u24_sS; - break; + driver->write_via_copy = driver->quirk_bswap? + sample_move_d32u24_sSs: + sample_move_d32u24_sS; + break; - default: - jack_error ("impossible sample width (%d) discovered!", - driver->playback_sample_bytes); - exit (1); + default: + jack_error ("impossible sample width (%d) discovered!", + driver->playback_sample_bytes); + exit (1); + } } } - switch (driver->capture_sample_bytes) { - case 2: - driver->read_via_copy = driver->quirk_bswap? - sample_move_dS_s16s: - sample_move_dS_s16; - break; - case 3: - driver->read_via_copy = driver->quirk_bswap? - sample_move_dS_s24s: - sample_move_dS_s24; - break; - case 4: - driver->read_via_copy = driver->quirk_bswap? - sample_move_dS_s32u24s: - sample_move_dS_s32u24; - break; + if (driver->capture_handle) { + switch (driver->capture_sample_bytes) { + case 2: + driver->read_via_copy = driver->quirk_bswap? + sample_move_dS_s16s: + sample_move_dS_s16; + break; + case 3: + driver->read_via_copy = driver->quirk_bswap? + sample_move_dS_s24s: + sample_move_dS_s24; + break; + case 4: + driver->read_via_copy = driver->quirk_bswap? + sample_move_dS_s32u24s: + sample_move_dS_s32u24; + break; + } } } diff --git a/linux/firewire/JackFFADODriver.cpp b/linux/firewire/JackFFADODriver.cpp index b6080d69..be2f3359 100644 --- a/linux/firewire/JackFFADODriver.cpp +++ b/linux/firewire/JackFFADODriver.cpp @@ -2,6 +2,7 @@ Copyright (C) 2001 Paul Davis Copyright (C) 2004 Grame Copyright (C) 2007 Pieter Palmers +Copyright (C) 2009 Devin Anderson 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 @@ -35,6 +36,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include "JackFFADODriver.h" +#include "JackFFADOMidiInput.h" +#include "JackFFADOMidiOutput.h" #include "JackEngineControl.h" #include "JackClientControl.h" #include "JackPort.h" @@ -91,29 +94,14 @@ JackFFADODriver::ffado_driver_read (ffado_driver_t * driver, jack_nframes_t nfra /* process the midi data */ for (chn = 0; chn < driver->capture_nchannels; chn++) { if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) { - jack_nframes_t i; - int done; - uint32_t *midi_buffer = driver->capture_channels[chn].midi_buffer; - midi_unpack_t *midi_unpack = &driver->capture_channels[chn].midi_unpack; - buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[chn], nframes); - jack_midi_clear_buffer(buf); - - /* if the returned buffer is invalid, discard the midi data */ - if (!buf) continue; - /* else unpack - note that libffado guarantees that midi bytes are on 8-byte aligned indexes - */ - for (i = 0; i < nframes; i += 8) { - if (midi_buffer[i] & 0xFF000000) { - done = midi_unpack_buf(midi_unpack, (unsigned char *)(midi_buffer + i), 1, buf, i); - if (done != 1) { - printError("buffer overflow in channel %d\n", chn); - break; - } - - printMessage("MIDI IN: %08X (i=%d)", midi_buffer[i], i); - } + JackFFADOMidiInput *midi_input = (JackFFADOMidiInput *) driver->capture_channels[chn].midi_input; + JackMidiBuffer *buffer = (JackMidiBuffer *) fGraphManager->GetBuffer(fCapturePortList[chn], nframes); + if (! buffer) { + continue; } + midi_input->SetInputBuffer(driver->capture_channels[chn].midi_buffer); + midi_input->SetPortBuffer(buffer); + midi_input->Process(nframes); } } @@ -146,80 +134,20 @@ JackFFADODriver::ffado_driver_write (ffado_driver_t * driver, jack_nframes_t nfr ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(buf)); ffado_streaming_playback_stream_onoff(driver->dev, chn, 1); } else if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) { - jack_nframes_t nevents; - jack_nframes_t i; - midi_pack_t *midi_pack = &driver->playback_channels[chn].midi_pack; uint32_t *midi_buffer = driver->playback_channels[chn].midi_buffer; - buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[chn], nframes); - jack_nframes_t min_next_pos = 0; - memset(midi_buffer, 0, nframes * sizeof(uint32_t)); + buf = (jack_default_audio_sample_t *) fGraphManager->GetBuffer(fPlaybackPortList[chn], nframes); ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(midi_buffer)); - /* if the returned buffer is invalid, continue */ if (!buf) { ffado_streaming_playback_stream_onoff(driver->dev, chn, 0); continue; } ffado_streaming_playback_stream_onoff(driver->dev, chn, 1); - - // check if we still have to process bytes from the previous period - if (driver->playback_channels[chn].nb_overflow_bytes) { - printMessage("have to process %d bytes from previous period", driver->playback_channels[chn].nb_overflow_bytes); - } - for (i = 0; i < driver->playback_channels[chn].nb_overflow_bytes; ++i) { - midi_buffer[min_next_pos] = 0x01000000 | (driver->playback_channels[chn].overflow_buffer[i] & 0xFF); - min_next_pos += 8; - } - driver->playback_channels[chn].nb_overflow_bytes = 0; - - // process the events in this period - nevents = jack_midi_get_event_count(buf); - //if (nevents) - // printMessage("MIDI: %d events in ch %d", nevents, chn); - - for (i = 0; i < nevents; ++i) { - size_t j; - jack_midi_event_t event; - jack_midi_event_get(&event, buf, i); - - midi_pack_event(midi_pack, &event); - - // floor the initial position to be a multiple of 8 - jack_nframes_t pos = event.time & 0xFFFFFFF8; - for (j = 0; j < event.size; j++) { - // make sure we don't overwrite a previous byte - while (pos < min_next_pos && pos < nframes) { - pos += 8; - printMessage("have to correct pos to %d", pos); - } - - if (pos >= nframes) { - unsigned int f; - printMessage("midi message crosses period boundary"); - driver->playback_channels[chn].nb_overflow_bytes = event.size - j; - if (driver->playback_channels[chn].nb_overflow_bytes > MIDI_OVERFLOW_BUFFER_SIZE) { - printError("too much midi bytes cross period boundary"); - driver->playback_channels[chn].nb_overflow_bytes = MIDI_OVERFLOW_BUFFER_SIZE; - } - // save the bytes that still have to be transmitted in the next period - for (f = 0; f < driver->playback_channels[chn].nb_overflow_bytes; f++) { - driver->playback_channels[chn].overflow_buffer[f] = event.buffer[j+f]; - } - // exit since we can't transmit anything anymore. - // the rate should be controlled - if (i < nevents - 1) { - printError("%d midi events lost due to period crossing", nevents - i - 1); - } - break; - } else { - midi_buffer[pos] = 0x01000000 | (event.buffer[j] & 0xFF); - pos += 8; - min_next_pos = pos; - } - } - //printMessage("MIDI: sent %d-byte event at %ld", (int)event.size, (long)event.time); - } + JackFFADOMidiOutput *midi_output = (JackFFADOMidiOutput *) driver->playback_channels[chn].midi_output; + midi_output->SetPortBuffer((JackMidiBuffer *) buf); + midi_output->SetOutputBuffer(midi_buffer); + midi_output->Process(nframes); } else { // always have a valid buffer ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(driver->nullbuffer)); @@ -279,16 +207,21 @@ JackFFADODriver::ffado_driver_wait (ffado_driver_t *driver, int extra_fd, int *s } else if (response == ffado_wait_error) { // an error happened (unhandled xrun) // this should be fatal + jack_error("JackFFADODriver::ffado_driver_wait - unhandled xrun"); *status = -1; return 0; } else if (response == ffado_wait_shutdown) { // ffado requested shutdown (e.g. device unplugged) // this should be fatal + jack_error("JackFFADODriver::ffado_driver_wait - shutdown requested " + "(device unplugged?)"); *status = -1; return 0; } else { // unknown response code. should be fatal // this should be fatal + jack_error("JackFFADODriver::ffado_driver_wait - unexpected error " + "code '%d' returned from 'ffado_streaming_wait'", response); *status = -1; return 0; } @@ -541,9 +474,7 @@ int JackFFADODriver::Attach() printError(" cannot enable port %s", buf); } - // setup midi unpacker - midi_unpack_init(&driver->capture_channels[chn].midi_unpack); - midi_unpack_reset(&driver->capture_channels[chn].midi_unpack); + driver->capture_channels[chn].midi_input = new JackFFADOMidiInput(); // setup the midi buffer driver->capture_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t)); @@ -616,9 +547,13 @@ int JackFFADODriver::Attach() if (ffado_streaming_playback_stream_onoff(driver->dev, chn, 0)) { printError(" cannot enable port %s", buf); } - // setup midi packer - midi_pack_reset(&driver->playback_channels[chn].midi_pack); // setup the midi buffer + + // This constructor optionally accepts arguments for the + // non-realtime buffer size and the realtime buffer size. Ideally, + // these would become command-line options for the FFADO driver. + driver->playback_channels[chn].midi_output = new JackFFADOMidiOutput(); + driver->playback_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t)); port = fGraphManager->GetPort(port_index); @@ -658,12 +593,16 @@ int JackFFADODriver::Detach() for (chn = 0; chn < driver->capture_nchannels; chn++) { if (driver->capture_channels[chn].midi_buffer) free(driver->capture_channels[chn].midi_buffer); + if (driver->capture_channels[chn].midi_input) + delete ((JackFFADOMidiInput *) (driver->capture_channels[chn].midi_input)); } free(driver->capture_channels); for (chn = 0; chn < driver->playback_nchannels; chn++) { if (driver->playback_channels[chn].midi_buffer) free(driver->playback_channels[chn].midi_buffer); + if (driver->playback_channels[chn].midi_output) + delete ((JackFFADOMidiOutput *) (driver->playback_channels[chn].midi_output)); } free(driver->playback_channels); diff --git a/linux/firewire/JackFFADOMidiInput.cpp b/linux/firewire/JackFFADOMidiInput.cpp new file mode 100644 index 00000000..38ed539b --- /dev/null +++ b/linux/firewire/JackFFADOMidiInput.cpp @@ -0,0 +1,59 @@ +/* +Copyright (C) 2009 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include + +#include "JackFFADOMidiInput.h" + +namespace Jack { + +JackFFADOMidiInput::JackFFADOMidiInput(size_t buffer_size): + JackPhysicalMidiInput(buffer_size) +{ + new_period = true; +} + +JackFFADOMidiInput::~JackFFADOMidiInput() +{ + // Empty +} + +jack_nframes_t +JackFFADOMidiInput::Receive(jack_midi_data_t *datum, + jack_nframes_t current_frame, + jack_nframes_t total_frames) +{ + assert(input_buffer); + if (! new_period) { + current_frame += 8; + } else { + new_period = false; + } + for (; current_frame < total_frames; current_frame += 8) { + uint32_t data = input_buffer[current_frame]; + if (data & 0xff000000) { + *datum = (jack_midi_data_t) (data & 0xff); + return current_frame; + } + } + new_period = true; + return total_frames; +} + +} diff --git a/linux/firewire/JackFFADOMidiInput.h b/linux/firewire/JackFFADOMidiInput.h new file mode 100644 index 00000000..12dc043c --- /dev/null +++ b/linux/firewire/JackFFADOMidiInput.h @@ -0,0 +1,54 @@ +/* +Copyright (C) 2009 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackFFADOMidiInput__ +#define __JackFFADOMidiInput__ + +#include "JackPhysicalMidiInput.h" + +namespace Jack { + + class JackFFADOMidiInput: public JackPhysicalMidiInput { + + private: + + uint32_t *input_buffer; + bool new_period; + + protected: + + jack_nframes_t + Receive(jack_midi_data_t *, jack_nframes_t, jack_nframes_t); + + public: + + JackFFADOMidiInput(size_t buffer_size=1024); + ~JackFFADOMidiInput(); + + inline void + SetInputBuffer(uint32_t *input_buffer) + { + this->input_buffer = input_buffer; + } + + }; + +} + +#endif diff --git a/linux/firewire/JackFFADOMidiOutput.cpp b/linux/firewire/JackFFADOMidiOutput.cpp new file mode 100644 index 00000000..995f2d28 --- /dev/null +++ b/linux/firewire/JackFFADOMidiOutput.cpp @@ -0,0 +1,60 @@ +/* +Copyright (C) 2009 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include + +#include "JackError.h" +#include "JackFFADOMidiOutput.h" + +namespace Jack { + +JackFFADOMidiOutput::JackFFADOMidiOutput(size_t non_rt_buffer_size, + size_t rt_buffer_size): + JackPhysicalMidiOutput(non_rt_buffer_size, rt_buffer_size) +{ + // Empty +} + +JackFFADOMidiOutput::~JackFFADOMidiOutput() +{ + // Empty +} + +jack_nframes_t +JackFFADOMidiOutput::Advance(jack_nframes_t current_frame) +{ + if (current_frame % 8) { + current_frame = (current_frame & (~ ((jack_nframes_t) 7))) + 8; + } + return current_frame; +} + +jack_nframes_t +JackFFADOMidiOutput::Send(jack_nframes_t current_frame, jack_midi_data_t datum) +{ + assert(output_buffer); + + jack_log("JackFFADOMidiOutput::Send (%d) - Sending '%x' byte.", + current_frame, (unsigned int) datum); + + output_buffer[current_frame] = 0x01000000 | ((uint32_t) datum); + return current_frame + 8; +} + +} diff --git a/linux/firewire/JackFFADOMidiOutput.h b/linux/firewire/JackFFADOMidiOutput.h new file mode 100644 index 00000000..309e7f61 --- /dev/null +++ b/linux/firewire/JackFFADOMidiOutput.h @@ -0,0 +1,57 @@ +/* +Copyright (C) 2009 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackFFADOMidiOutput__ +#define __JackFFADOMidiOutput__ + +#include "JackPhysicalMidiOutput.h" + +namespace Jack { + + class JackFFADOMidiOutput: public JackPhysicalMidiOutput { + + private: + + uint32_t *output_buffer; + + protected: + + jack_nframes_t + Advance(jack_nframes_t); + + jack_nframes_t + Send(jack_nframes_t, jack_midi_data_t); + + public: + + JackFFADOMidiOutput(size_t non_rt_buffer_size=1024, + size_t rt_buffer_size=64); + ~JackFFADOMidiOutput(); + + inline void + SetOutputBuffer(uint32_t *output_buffer) + { + this->output_buffer = output_buffer; + } + + }; + +} + +#endif diff --git a/linux/firewire/ffado_driver.h b/linux/firewire/ffado_driver.h index a851d845..a06c1361 100644 --- a/linux/firewire/ffado_driver.h +++ b/linux/firewire/ffado_driver.h @@ -7,6 +7,7 @@ * http://www.jackaudio.org * * Copyright (C) 2005-2007 Pieter Palmers + * Copyright (C) 2009 Devin Anderson * * adapted for JackMP by Pieter Palmers * @@ -51,9 +52,7 @@ #include #include -#include -#include "../alsa/midi_pack.h" -#include "../alsa/midi_unpack.h" +//#include // debug print control flags #define DEBUG_LEVEL_BUFFERS (1<<0) @@ -143,21 +142,16 @@ struct _ffado_jack_settings typedef struct _ffado_capture_channel { ffado_streaming_stream_type stream_type; - midi_unpack_t midi_unpack; uint32_t *midi_buffer; + void *midi_input; } ffado_capture_channel_t; -#define MIDI_OVERFLOW_BUFFER_SIZE 4 typedef struct _ffado_playback_channel { ffado_streaming_stream_type stream_type; - midi_pack_t midi_pack; uint32_t *midi_buffer; - // to hold the midi bytes that couldn't be transferred - // during the previous period - char overflow_buffer[MIDI_OVERFLOW_BUFFER_SIZE]; - unsigned int nb_overflow_bytes; + void *midi_output; } ffado_playback_channel_t; diff --git a/linux/wscript b/linux/wscript index 56a77330..869985d4 100644 --- a/linux/wscript +++ b/linux/wscript @@ -2,7 +2,7 @@ # encoding: utf-8 def configure(conf): - conf.check_cfg(package='alsa', atleast_version='1.0.0', args='--cflags --libs') + conf.check_cfg(package='alsa', atleast_version='1.0.18', args='--cflags --libs') conf.env['BUILD_DRIVER_ALSA'] = conf.is_defined('HAVE_ALSA') conf. check_cfg(package='libfreebob', atleast_version='1.0.0', args='--cflags --libs') @@ -55,6 +55,13 @@ def build(bld): 'alsa/ice1712.c' ] + ffado_driver_src = ['firewire/JackFFADODriver.cpp', + 'firewire/JackFFADOMidiInput.cpp', + 'firewire/JackFFADOMidiOutput.cpp', + '../common/JackPhysicalMidiInput.cpp', + '../common/JackPhysicalMidiOutput.cpp' + ] + if bld.env['BUILD_DRIVER_ALSA'] == True: create_jack_driver_obj(bld, 'alsa', alsa_driver_src, "ALSA") @@ -62,7 +69,7 @@ def build(bld): create_jack_driver_obj(bld, 'freebob', 'freebob/JackFreebobDriver.cpp', "LIBFREEBOB") if bld.env['BUILD_DRIVER_FFADO'] == True: - create_jack_driver_obj(bld, 'firewire', 'firewire/JackFFADODriver.cpp', "LIBFFADO") + create_jack_driver_obj(bld, 'firewire', ffado_driver_src, "LIBFFADO") create_jack_driver_obj(bld, 'net', '../common/JackNetDriver.cpp') diff --git a/macosx/Jack-Info.plist b/macosx/Jack-Info.plist index 1e5eb07e..8b6a61de 100644 --- a/macosx/Jack-Info.plist +++ b/macosx/Jack-Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable Jackservermp CFBundleGetInfoString - Jackdmp 1.9.4, @03-09 Paul Davis, Grame + Jackdmp 1.9.5, @03-09 Paul Davis, Grame CFBundleIdentifier com.grame.Jackmp CFBundleInfoDictionaryVersion @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.9.4 + 1.9.5 diff --git a/macosx/JackMacEngineRPC.cpp b/macosx/JackMacEngineRPC.cpp index 4ddb0b1c..fb95621d 100644 --- a/macosx/JackMacEngineRPC.cpp +++ b/macosx/JackMacEngineRPC.cpp @@ -18,9 +18,11 @@ This program is free software; you can redistribute it and/or modify */ #include "JackServer.h" +#include "JackNotification.h" #include "JackLockedEngine.h" #include "JackRPCEngine.h" #include "JackMachServerChannel.h" +#include "JackException.h" #include using namespace Jack; @@ -238,6 +240,11 @@ rpc_type server_rpc_jack_client_rt_notify(mach_port_t server_port, int refnum, i JackMachServerChannel* channel = JackMachServerChannel::fPortTable[server_port]; assert(channel); assert(channel->GetServer()); - channel->GetServer()->Notify(refnum, notify, value); - return KERN_SUCCESS; + + if (notify == kQUIT) { + throw JackQuitException(); + } else { + channel->GetServer()->Notify(refnum, notify, value); + return KERN_SUCCESS; + } } diff --git a/macosx/JackMachClientChannel.cpp b/macosx/JackMachClientChannel.cpp index c666bbb3..f5f88504 100644 --- a/macosx/JackMachClientChannel.cpp +++ b/macosx/JackMachClientChannel.cpp @@ -23,7 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackRPCClientServer.c" #include "JackError.h" #include "JackLibClient.h" -#include "JackLibGlobals.h" #include "JackMachThread.h" #include "JackConstants.h" diff --git a/macosx/JackMachServerChannel.cpp b/macosx/JackMachServerChannel.cpp index 19295f79..fcf4fe8c 100644 --- a/macosx/JackMachServerChannel.cpp +++ b/macosx/JackMachServerChannel.cpp @@ -58,7 +58,12 @@ int JackMachServerChannel::Open(const char* server_name, JackServer* server) void JackMachServerChannel::Close() { jack_log("JackMachServerChannel::Close"); + #ifdef MAC_OS_X_VERSION_10_5 + // Exception does not work in this case on pre Snow Loopard systems, see JackMachServerNotifyChannel::NotifyQuit() fThread.Kill(); + #else + fThread.Stop(); + #endif fServerPort.DestroyPort(); } @@ -149,12 +154,19 @@ boolean_t JackMachServerChannel::MessageHandler(mach_msg_header_t* Request, mach bool JackMachServerChannel::Execute() { - kern_return_t res; - if ((res = mach_msg_server(MessageHandler, 1024, fServerPort.GetPortSet(), 0)) != KERN_SUCCESS) { - jack_log("JackMachServerChannel::Execute: err = %s", mach_error_string(res)); + try { + + kern_return_t res; + if ((res = mach_msg_server(MessageHandler, 1024, fServerPort.GetPortSet(), 0)) != KERN_SUCCESS) { + jack_log("JackMachServerChannel::Execute: err = %s", mach_error_string(res)); + return false; + } + return true; + + } catch (JackQuitException& e) { + jack_log("JackMachServerChannel::Execute JackQuitException"); + return false; } - //return (res == KERN_SUCCESS); mach_msg_server can fail if the client reply port is not valid anymore (crashed client) - return true; } } // end of namespace diff --git a/macosx/JackMachServerNotifyChannel.cpp b/macosx/JackMachServerNotifyChannel.cpp index 2e1c9abe..f55ce09e 100644 --- a/macosx/JackMachServerNotifyChannel.cpp +++ b/macosx/JackMachServerNotifyChannel.cpp @@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackMachServerNotifyChannel.h" #include "JackRPCEngineUser.c" +#include "JackNotification.h" #include "JackTools.h" #include "JackConstants.h" #include "JackError.h" @@ -42,9 +43,7 @@ int JackMachServerNotifyChannel::Open(const char* server_name) } void JackMachServerNotifyChannel::Close() -{ - //fClientPort.DisconnectPort(); pas nŽcessaire car le JackMachServerChannel a dŽja disparu? -} +{} void JackMachServerNotifyChannel::Notify(int refnum, int notify, int value) { @@ -53,6 +52,18 @@ void JackMachServerNotifyChannel::Notify(int refnum, int notify, int value) jack_error("Could not write request ref = %d notify = %d err = %s", refnum, notify, mach_error_string(res)); } } + +void JackMachServerNotifyChannel::NotifyQuit() +{ + #ifdef MAC_OS_X_VERSION_10_5 + // Nothing : since exception does not work in this case on pre Snow Loopard systems, see JackMachServerChannel::Close() + #else + kern_return_t res = rpc_jack_client_rt_notify(fClientPort.GetPort(), -1, kQUIT, 0, 0); + if (res != KERN_SUCCESS) { + jack_error("Could not write request ref = %d notify = %d err = %s", -1, kQUIT, mach_error_string(res)); + } +#endif +} } // end of namespace diff --git a/macosx/JackMachServerNotifyChannel.h b/macosx/JackMachServerNotifyChannel.h index 98523a84..8eb7b72f 100644 --- a/macosx/JackMachServerNotifyChannel.h +++ b/macosx/JackMachServerNotifyChannel.h @@ -46,7 +46,8 @@ class JackMachServerNotifyChannel void Close(); // Close the Server/Client connection void Notify(int refnum, int notify, int value); -}; + void NotifyQuit(); +}; } // end of namespace diff --git a/macosx/JackMachThread.h b/macosx/JackMachThread.h index f7c038c0..ac96f4a0 100644 --- a/macosx/JackMachThread.h +++ b/macosx/JackMachThread.h @@ -61,8 +61,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __JackMachThread__ #define __JackMachThread__ +#include + +#ifdef TARGET_OS_IPHONE +typedef unsigned char Boolean; +#endif + + #include "JackPosixThread.h" +#ifndef TARGET_OS_IPHONE #import +#endif #include #include diff --git a/macosx/JackPlatformPlug_os.h b/macosx/JackPlatformPlug_os.h index c52a259f..df7f0175 100644 --- a/macosx/JackPlatformPlug_os.h +++ b/macosx/JackPlatformPlug_os.h @@ -20,6 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __JackPlatformPlug_APPLE__ #define __JackPlatformPlug_APPLE__ +#include + namespace Jack { class JackPosixMutex; @@ -42,13 +44,16 @@ namespace Jack { typedef JackPosixMutex JackMutex; } namespace Jack { typedef JackMachThread JackThread; } /* __JackPlatformSynchro__ client activation */ +#ifndef TARGET_OS_IPHONE #include "JackMachSemaphore.h" namespace Jack { typedef JackMachSemaphore JackSynchro; } +#endif /* __JackPlatformProcessSync__ */ #include "JackProcessSync.h" /* Only on windows a special JackProcessSync is used. It is directly defined by including JackProcessSync.h here */ +#ifndef TARGET_OS_IPHONE /* __JackPlatformServerChannel__ */ #include "JackMachServerChannel.h" namespace Jack { typedef JackMachServerChannel JackServerChannel; } @@ -64,6 +69,7 @@ namespace Jack { typedef JackMachServerNotifyChannel JackServerNotifyChannel; } /* __JackPlatformNotifyChannel__ */ #include "JackMachNotifyChannel.h" namespace Jack { typedef JackMachNotifyChannel JackNotifyChannel; } +#endif /* __JackPlatformNetSocket__ */ #include "JackNetUnixSocket.h" diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index c8aae4f5..461f827b 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -323,6 +323,83 @@ 4B43A8CB1014605000E52943 /* JackLoopbackDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B43A8C91014605000E52943 /* JackLoopbackDriver.h */; }; 4B43A8DF1014615800E52943 /* JackLoopbackDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B43A8C91014605000E52943 /* JackLoopbackDriver.h */; }; 4B43A8E11014615800E52943 /* JackLoopbackDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B43A8C81014605000E52943 /* JackLoopbackDriver.cpp */; }; + 4B47AC8210B5890100469C67 /* JackMachPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B799AD707899652003F3F15 /* JackMachPort.h */; }; + 4B47AC8310B5890100469C67 /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; }; + 4B47AC8410B5890100469C67 /* JackTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1830834EE5800C94B91 /* JackTime.h */; }; + 4B47AC8510B5890100469C67 /* JackShmMem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1870834EE7900C94B91 /* JackShmMem.h */; }; + 4B47AC8610B5890100469C67 /* shm.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D18F0834EE8400C94B91 /* shm.h */; }; + 4B47AC8710B5890100469C67 /* JackThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D19F0834EE9E00C94B91 /* JackThread.h */; }; + 4B47AC8810B5890100469C67 /* JackActivationCount.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1A70834EEB400C94B91 /* JackActivationCount.h */; }; + 4B47AC8910B5890100469C67 /* JackChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1AF0834EEC400C94B91 /* JackChannel.h */; }; + 4B47AC8A10B5890100469C67 /* JackGraphManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C70834EF2200C94B91 /* JackGraphManager.h */; }; + 4B47AC8B10B5890100469C67 /* JackPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1CF0834EF2F00C94B91 /* JackPort.h */; }; + 4B47AC8C10B5890100469C67 /* JackClientInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1D90834EF4500C94B91 /* JackClientInterface.h */; }; + 4B47AC8D10B5890100469C67 /* JackClientControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1DD0834EF4D00C94B91 /* JackClientControl.h */; }; + 4B47AC8E10B5890100469C67 /* JackClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1E10834EF5500C94B91 /* JackClient.h */; }; + 4B47AC8F10B5890100469C67 /* JackInternalClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1EE0834EF9200C94B91 /* JackInternalClient.h */; }; + 4B47AC9010B5890100469C67 /* JackLibGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1FB0834EFD100C94B91 /* JackLibGlobals.h */; }; + 4B47AC9110B5890100469C67 /* JackLibClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1FC0834EFD100C94B91 /* JackLibClient.h */; }; + 4B47AC9210B5890100469C67 /* JackConnectionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C30834EF1400C94B91 /* JackConnectionManager.h */; }; + 4B47AC9310B5890100469C67 /* JackFrameTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */; }; + 4B47AC9410B5890100469C67 /* JackMachSemaphore.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF6C1D608ACE64C001E2013 /* JackMachSemaphore.h */; }; + 4B47AC9510B5890100469C67 /* JackGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB73F608AD291A00DB99B8 /* JackGlobals.h */; }; + 4B47AC9610B5890100469C67 /* JackMachThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB741F08AD2B9900DB99B8 /* JackMachThread.h */; }; + 4B47AC9710B5890100469C67 /* JackMachClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB298708AF450200D450D4 /* JackMachClientChannel.h */; }; + 4B47AC9810B5890100469C67 /* JackSynchro.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD561C708EEB910006BBC2A /* JackSynchro.h */; }; + 4B47AC9910B5890100469C67 /* JackDebugClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B98AE010931D30C0091932A /* JackDebugClient.h */; }; + 4B47AC9A10B5890100469C67 /* JackConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66A8580934964500A89560 /* JackConstants.h */; }; + 4B47AC9B10B5890100469C67 /* JackTransportEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */; }; + 4B47AC9C10B5890100469C67 /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47AC9D10B5890100469C67 /* intclient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C73790CC60A6D001AFFD4 /* intclient.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47AC9E10B5890100469C67 /* jack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737A0CC60A6D001AFFD4 /* jack.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47AC9F10B5890100469C67 /* ringbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737B0CC60A6D001AFFD4 /* ringbuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47ACA010B5890100469C67 /* statistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737C0CC60A6D001AFFD4 /* statistics.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47ACA110B5890100469C67 /* thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737D0CC60A6D001AFFD4 /* thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47ACA210B5890100469C67 /* transport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737E0CC60A6D001AFFD4 /* transport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47ACA310B5890100469C67 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737F0CC60A6D001AFFD4 /* types.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47ACA410B5890100469C67 /* JackPortType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAB95B70B9E20B800A0C723 /* JackPortType.h */; }; + 4B47ACA510B5890100469C67 /* JackMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */; }; + 4B47ACA610B5890100469C67 /* midiport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6B9EF50CD0958B0051EE5A /* midiport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47ACA710B5890100469C67 /* JackTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE4CC000CDA153400CCF5BB /* JackTools.h */; }; + 4B47ACA810B5890100469C67 /* jslist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B9A26000DBF8584006E9FBC /* jslist.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47ACA910B5890100469C67 /* JackMessageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4F9C8B0DC20C0400706CB0 /* JackMessageBuffer.h */; }; + 4B47ACAA10B5890100469C67 /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; + 4B47ACAB10B5890100469C67 /* JackProcessSync.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BECB2F40F4451C10091B70A /* JackProcessSync.h */; }; + 4B47ACAE10B5890100469C67 /* JackMacLibClientRPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF3937C0626BF3600CC67FA /* JackMacLibClientRPC.cpp */; }; + 4B47ACAF10B5890100469C67 /* JackRPCEngineUser.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B89B769076B74D200D170DE /* JackRPCEngineUser.c */; }; + 4B47ACB010B5890100469C67 /* JackMachPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B799AD607899652003F3F15 /* JackMachPort.cpp */; }; + 4B47ACB110B5890100469C67 /* JackShmMem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1880834EE7900C94B91 /* JackShmMem.cpp */; }; + 4B47ACB210B5890100469C67 /* shm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1900834EE8400C94B91 /* shm.c */; }; + 4B47ACB310B5890100469C67 /* JackActivationCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1A80834EEB400C94B91 /* JackActivationCount.cpp */; }; + 4B47ACB410B5890100469C67 /* JackGraphManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C80834EF2200C94B91 /* JackGraphManager.cpp */; }; + 4B47ACB510B5890100469C67 /* JackPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1D00834EF2F00C94B91 /* JackPort.cpp */; }; + 4B47ACB610B5890100469C67 /* JackClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E50834EF6700C94B91 /* JackClient.cpp */; }; + 4B47ACB710B5890100469C67 /* JackAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E90834EF7500C94B91 /* JackAPI.cpp */; }; + 4B47ACB810B5890100469C67 /* JackLibClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1FD0834EFD100C94B91 /* JackLibClient.cpp */; }; + 4B47ACB910B5890100469C67 /* JackLibAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1FE0834EFD100C94B91 /* JackLibAPI.cpp */; }; + 4B47ACBA10B5890100469C67 /* JackConnectionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C40834EF1400C94B91 /* JackConnectionManager.cpp */; }; + 4B47ACBB10B5890100469C67 /* JackFrameTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */; }; + 4B47ACBC10B5890100469C67 /* JackMachSemaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF6C1D508ACE64C001E2013 /* JackMachSemaphore.cpp */; }; + 4B47ACBD10B5890100469C67 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB741E08AD2B9900DB99B8 /* JackMachThread.cpp */; }; + 4B47ACBE10B5890100469C67 /* JackMachClientChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB29AE08AF45FD00D450D4 /* JackMachClientChannel.cpp */; }; + 4B47ACBF10B5890100469C67 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */; }; + 4B47ACC010B5890100469C67 /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B003AB008E2B2BA0060EFDC /* ringbuffer.c */; }; + 4B47ACC110B5890100469C67 /* JackDebugClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B98AE000931D30C0091932A /* JackDebugClient.cpp */; }; + 4B47ACC210B5890100469C67 /* JackTransportEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */; }; + 4B47ACC310B5890100469C67 /* timestamps.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF520520CB8D0E80037470E /* timestamps.c */; }; + 4B47ACC410B5890100469C67 /* JackPortType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */; }; + 4B47ACC510B5890100469C67 /* JackAudioPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95EC0B9E21A500A0C723 /* JackAudioPort.cpp */; }; + 4B47ACC610B5890100469C67 /* JackMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */; }; + 4B47ACC710B5890100469C67 /* JackMidiAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */; }; + 4B47ACC810B5890100469C67 /* JackEngineControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6F7AEC0CD0CDBD00F48A9D /* JackEngineControl.cpp */; }; + 4B47ACC910B5890100469C67 /* JackTools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4CBFF0CDA153400CCF5BB /* JackTools.cpp */; }; + 4B47ACCA10B5890100469C67 /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; + 4B47ACCB10B5890100469C67 /* JackMessageBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4F9C8A0DC20C0400706CB0 /* JackMessageBuffer.cpp */; }; + 4B47ACCC10B5890100469C67 /* JackPosixServerLaunch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBBA0E878B9C003D2374 /* JackPosixServerLaunch.cpp */; }; + 4B47ACCD10B5890100469C67 /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; + 4B47ACCE10B5890100469C67 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; + 4B47ACCF10B5890100469C67 /* JackProcessSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BECB2F30F4451C10091B70A /* JackProcessSync.cpp */; }; + 4B47ACD210B5890100469C67 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; 4B4CA9750E02CF9600F4BFDA /* JackRestartThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4CA9730E02CF9600F4BFDA /* JackRestartThreadedDriver.h */; }; 4B4CA9760E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4CA9740E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp */; }; 4B4CA9770E02CF9600F4BFDA /* JackRestartThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4CA9730E02CF9600F4BFDA /* JackRestartThreadedDriver.h */; }; @@ -676,6 +753,18 @@ 4BC3B6BE0E703BCC0066E42F /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */; }; 4BC3B6BF0E703BCC0066E42F /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */; }; 4BC3B6C00E703BCC0066E42F /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */; }; + 4BCBCE5D10C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5910C4FE3F00450FFE /* JackPhysicalMidiInput.cpp */; }; + 4BCBCE5E10C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCBCE5A10C4FE3F00450FFE /* JackPhysicalMidiInput.h */; }; + 4BCBCE5F10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5B10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp */; }; + 4BCBCE6010C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCBCE5C10C4FE3F00450FFE /* JackPhysicalMidiOutput.h */; }; + 4BCBCE6110C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5910C4FE3F00450FFE /* JackPhysicalMidiInput.cpp */; }; + 4BCBCE6210C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCBCE5A10C4FE3F00450FFE /* JackPhysicalMidiInput.h */; }; + 4BCBCE6310C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5B10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp */; }; + 4BCBCE6410C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCBCE5C10C4FE3F00450FFE /* JackPhysicalMidiOutput.h */; }; + 4BCBCE6510C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5910C4FE3F00450FFE /* JackPhysicalMidiInput.cpp */; }; + 4BCBCE6610C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCBCE5A10C4FE3F00450FFE /* JackPhysicalMidiInput.h */; }; + 4BCBCE6710C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5B10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp */; }; + 4BCBCE6810C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCBCE5C10C4FE3F00450FFE /* JackPhysicalMidiOutput.h */; }; 4BCC87960D57168300A7FEB1 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; 4BCC87970D57168300A7FEB1 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; 4BCC87980D57168300A7FEB1 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; @@ -1424,6 +1513,7 @@ 4B43A8C91014605000E52943 /* JackLoopbackDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackLoopbackDriver.h; path = ../common/JackLoopbackDriver.h; sourceTree = SOURCE_ROOT; }; 4B43A8E71014615800E52943 /* jack_loopback.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_loopback.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B464301076CAC7700E5077C /* Jack-Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = "Jack-Info.plist"; sourceTree = SOURCE_ROOT; }; + 4B47ACD710B5890100469C67 /* Jackmp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackmp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4B4CA9730E02CF9600F4BFDA /* JackRestartThreadedDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackRestartThreadedDriver.h; path = ../common/JackRestartThreadedDriver.h; sourceTree = SOURCE_ROOT; }; 4B4CA9740E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackRestartThreadedDriver.cpp; path = ../common/JackRestartThreadedDriver.cpp; sourceTree = SOURCE_ROOT; }; 4B4E9AF80E5F1090000A3278 /* JackControlAPI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackControlAPI.cpp; path = ../common/JackControlAPI.cpp; sourceTree = SOURCE_ROOT; }; @@ -1488,7 +1578,6 @@ 4B9A25B30DBF8330006E9FBC /* JackError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackError.cpp; path = ../common/JackError.cpp; sourceTree = SOURCE_ROOT; }; 4B9A26000DBF8584006E9FBC /* jslist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jslist.h; path = ../common/jack/jslist.h; sourceTree = SOURCE_ROOT; }; 4BA339AC10B2E36800190E3B /* Jackservermp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackservermp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 4BA339AD10B2E36800190E3B /* Jack-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Jack-Info.plist"; sourceTree = ""; }; 4BA577BC08BF8BE200F82DE1 /* testSynchroClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSynchroClient.cpp; path = ../tests/testSynchroClient.cpp; sourceTree = SOURCE_ROOT; }; 4BA577FB08BF8E4600F82DE1 /* testSynchroServer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSynchroServer.cpp; path = ../tests/testSynchroServer.cpp; sourceTree = SOURCE_ROOT; }; 4BA692B00CBE4BC700EAD520 /* jack_load */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_load; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1531,6 +1620,10 @@ 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetUnixSocket.cpp; path = ../posix/JackNetUnixSocket.cpp; sourceTree = SOURCE_ROOT; }; 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackNetUnixSocket.h; path = ../posix/JackNetUnixSocket.h; sourceTree = SOURCE_ROOT; }; 4BC8326D0DF42C7D00DD1C93 /* JackMutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMutex.h; path = ../common/JackMutex.h; sourceTree = SOURCE_ROOT; }; + 4BCBCE5910C4FE3F00450FFE /* JackPhysicalMidiInput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackPhysicalMidiInput.cpp; path = ../common/JackPhysicalMidiInput.cpp; sourceTree = SOURCE_ROOT; }; + 4BCBCE5A10C4FE3F00450FFE /* JackPhysicalMidiInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackPhysicalMidiInput.h; path = ../common/JackPhysicalMidiInput.h; sourceTree = SOURCE_ROOT; }; + 4BCBCE5B10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackPhysicalMidiOutput.cpp; path = ../common/JackPhysicalMidiOutput.cpp; sourceTree = SOURCE_ROOT; }; + 4BCBCE5C10C4FE3F00450FFE /* JackPhysicalMidiOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackPhysicalMidiOutput.h; path = ../common/JackPhysicalMidiOutput.h; sourceTree = SOURCE_ROOT; }; 4BCC87950D57168300A7FEB1 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = /System/Library/Frameworks/Accelerate.framework; sourceTree = ""; }; 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackTransportEngine.h; path = ../common/JackTransportEngine.h; sourceTree = SOURCE_ROOT; }; 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackTransportEngine.cpp; path = ../common/JackTransportEngine.cpp; sourceTree = SOURCE_ROOT; }; @@ -1958,6 +2051,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B47ACD110B5890100469C67 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B47ACD210B5890100469C67 /* Accelerate.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B5A1BB50CD1CB9E0005BF74 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -2288,7 +2389,6 @@ 0249A662FF388D9811CA2CEA /* External Frameworks and Libraries */, 1AB674ADFE9D54B511CA2CBB /* Products */, 4B464301076CAC7700E5077C /* Jack-Info.plist */, - 4BA339AD10B2E36800190E3B /* Jack-Info.plist */, ); name = JackServer; sourceTree = ""; @@ -2406,6 +2506,7 @@ 4B32256110A3187800838A8E /* jack_netsource */, 4B32257B10A3190C00838A8E /* jack_netsource */, 4BA339AC10B2E36800190E3B /* Jackservermp.framework */, + 4B47ACD710B5890100469C67 /* Jackmp.framework */, ); name = Products; sourceTree = ""; @@ -2856,6 +2957,10 @@ 4BF3390D0F8B86AF0080FB5B /* MIDI */ = { isa = PBXGroup; children = ( + 4BCBCE5910C4FE3F00450FFE /* JackPhysicalMidiInput.cpp */, + 4BCBCE5A10C4FE3F00450FFE /* JackPhysicalMidiInput.h */, + 4BCBCE5B10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp */, + 4BCBCE5C10C4FE3F00450FFE /* JackPhysicalMidiOutput.h */, 4BF3391F0F8B873E0080FB5B /* JackMidiDriver.cpp */, 4BF339200F8B873E0080FB5B /* JackMidiDriver.h */, 4BF339140F8B86DC0080FB5B /* JackCoreMidiDriver.h */, @@ -3120,6 +3225,8 @@ 4BF339220F8B873E0080FB5B /* JackMidiDriver.h in Headers */, 4BDCDBD21001FD0200B15929 /* JackWaitThreadedDriver.h in Headers */, 4BDCDC0A1001FDA800B15929 /* JackArgParser.h in Headers */, + 4BCBCE6210C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */, + 4BCBCE6410C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3354,6 +3461,55 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B47AC8110B5890100469C67 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B47AC8210B5890100469C67 /* JackMachPort.h in Headers */, + 4B47AC8310B5890100469C67 /* JackError.h in Headers */, + 4B47AC8410B5890100469C67 /* JackTime.h in Headers */, + 4B47AC8510B5890100469C67 /* JackShmMem.h in Headers */, + 4B47AC8610B5890100469C67 /* shm.h in Headers */, + 4B47AC8710B5890100469C67 /* JackThread.h in Headers */, + 4B47AC8810B5890100469C67 /* JackActivationCount.h in Headers */, + 4B47AC8910B5890100469C67 /* JackChannel.h in Headers */, + 4B47AC8A10B5890100469C67 /* JackGraphManager.h in Headers */, + 4B47AC8B10B5890100469C67 /* JackPort.h in Headers */, + 4B47AC8C10B5890100469C67 /* JackClientInterface.h in Headers */, + 4B47AC8D10B5890100469C67 /* JackClientControl.h in Headers */, + 4B47AC8E10B5890100469C67 /* JackClient.h in Headers */, + 4B47AC8F10B5890100469C67 /* JackInternalClient.h in Headers */, + 4B47AC9010B5890100469C67 /* JackLibGlobals.h in Headers */, + 4B47AC9110B5890100469C67 /* JackLibClient.h in Headers */, + 4B47AC9210B5890100469C67 /* JackConnectionManager.h in Headers */, + 4B47AC9310B5890100469C67 /* JackFrameTimer.h in Headers */, + 4B47AC9410B5890100469C67 /* JackMachSemaphore.h in Headers */, + 4B47AC9510B5890100469C67 /* JackGlobals.h in Headers */, + 4B47AC9610B5890100469C67 /* JackMachThread.h in Headers */, + 4B47AC9710B5890100469C67 /* JackMachClientChannel.h in Headers */, + 4B47AC9810B5890100469C67 /* JackSynchro.h in Headers */, + 4B47AC9910B5890100469C67 /* JackDebugClient.h in Headers */, + 4B47AC9A10B5890100469C67 /* JackConstants.h in Headers */, + 4B47AC9B10B5890100469C67 /* JackTransportEngine.h in Headers */, + 4B47AC9C10B5890100469C67 /* timestamps.h in Headers */, + 4B47AC9D10B5890100469C67 /* intclient.h in Headers */, + 4B47AC9E10B5890100469C67 /* jack.h in Headers */, + 4B47AC9F10B5890100469C67 /* ringbuffer.h in Headers */, + 4B47ACA010B5890100469C67 /* statistics.h in Headers */, + 4B47ACA110B5890100469C67 /* thread.h in Headers */, + 4B47ACA210B5890100469C67 /* transport.h in Headers */, + 4B47ACA310B5890100469C67 /* types.h in Headers */, + 4B47ACA410B5890100469C67 /* JackPortType.h in Headers */, + 4B47ACA510B5890100469C67 /* JackMidiPort.h in Headers */, + 4B47ACA610B5890100469C67 /* midiport.h in Headers */, + 4B47ACA710B5890100469C67 /* JackTools.h in Headers */, + 4B47ACA810B5890100469C67 /* jslist.h in Headers */, + 4B47ACA910B5890100469C67 /* JackMessageBuffer.h in Headers */, + 4B47ACAA10B5890100469C67 /* JackPosixThread.h in Headers */, + 4B47ACAB10B5890100469C67 /* JackProcessSync.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B5A1BB20CD1CB9E0005BF74 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -3506,6 +3662,8 @@ 4BECB2F60F4451C10091B70A /* JackProcessSync.h in Headers */, 4BF339240F8B873E0080FB5B /* JackMidiDriver.h in Headers */, 4B94334B10A5E666002A187F /* systemdeps.h in Headers */, + 4BCBCE5E10C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */, + 4BCBCE6010C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3681,6 +3839,8 @@ 4BA3396D10B2E36800190E3B /* JackMidiDriver.h in Headers */, 4BA3396E10B2E36800190E3B /* JackWaitThreadedDriver.h in Headers */, 4BA3396F10B2E36800190E3B /* JackArgParser.h in Headers */, + 4BCBCE6610C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */, + 4BCBCE6810C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4650,6 +4810,25 @@ productReference = 4B43A8E71014615800E52943 /* jack_loopback.so */; productType = "com.apple.product-type.library.dynamic"; }; + 4B47AC8010B5890100469C67 /* Jackmp.framework 64 bits debugging */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B47ACD310B5890100469C67 /* Build configuration list for PBXNativeTarget "Jackmp.framework 64 bits debugging" */; + buildPhases = ( + 4B47AC8110B5890100469C67 /* Headers */, + 4B47ACAC10B5890100469C67 /* Resources */, + 4B47ACAD10B5890100469C67 /* Sources */, + 4B47ACD010B5890100469C67 /* Rez */, + 4B47ACD110B5890100469C67 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Jackmp.framework 64 bits debugging"; + productName = Jack; + productReference = 4B47ACD710B5890100469C67 /* Jackmp.framework */; + productType = "com.apple.product-type.framework"; + }; 4B5A1BB10CD1CB9E0005BF74 /* jack_midiseq Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B5A1BB70CD1CB9E0005BF74 /* Build configuration list for PBXNativeTarget "jack_midiseq Universal" */; @@ -5522,6 +5701,7 @@ 4B5E08BF0E5B66EE00BEE4E0 /* netadapter Universal */, 4B35C41B0D4731D1000DE7AE /* jackdmp framework 64bits */, 4B35C4270D4731D1000DE7AE /* Jackmp.framework 64 bits */, + 4B47AC8010B5890100469C67 /* Jackmp.framework 64 bits debugging */, 4B35C4850D4731D1000DE7AE /* Jackservermp.framework 64 bits */, 4BA3393310B2E36800190E3B /* Jackservermp.framework 64 bits profiling */, 4B35C50A0D4731D1000DE7AE /* jack_midiseq 64 bits */, @@ -5581,6 +5761,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B47ACAC10B5890100469C67 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B699C23097D421600A18468 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -5836,6 +6023,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B47ACD010B5890100469C67 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B5A1BB60CD1CB9E0005BF74 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; @@ -6229,6 +6423,8 @@ 4BF339210F8B873E0080FB5B /* JackMidiDriver.cpp in Sources */, 4BDCDBD11001FD0100B15929 /* JackWaitThreadedDriver.cpp in Sources */, 4BDCDC091001FDA800B15929 /* JackArgParser.cpp in Sources */, + 4BCBCE6110C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */, + 4BCBCE6310C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6490,6 +6686,47 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B47ACAD10B5890100469C67 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B47ACAE10B5890100469C67 /* JackMacLibClientRPC.cpp in Sources */, + 4B47ACAF10B5890100469C67 /* JackRPCEngineUser.c in Sources */, + 4B47ACB010B5890100469C67 /* JackMachPort.cpp in Sources */, + 4B47ACB110B5890100469C67 /* JackShmMem.cpp in Sources */, + 4B47ACB210B5890100469C67 /* shm.c in Sources */, + 4B47ACB310B5890100469C67 /* JackActivationCount.cpp in Sources */, + 4B47ACB410B5890100469C67 /* JackGraphManager.cpp in Sources */, + 4B47ACB510B5890100469C67 /* JackPort.cpp in Sources */, + 4B47ACB610B5890100469C67 /* JackClient.cpp in Sources */, + 4B47ACB710B5890100469C67 /* JackAPI.cpp in Sources */, + 4B47ACB810B5890100469C67 /* JackLibClient.cpp in Sources */, + 4B47ACB910B5890100469C67 /* JackLibAPI.cpp in Sources */, + 4B47ACBA10B5890100469C67 /* JackConnectionManager.cpp in Sources */, + 4B47ACBB10B5890100469C67 /* JackFrameTimer.cpp in Sources */, + 4B47ACBC10B5890100469C67 /* JackMachSemaphore.cpp in Sources */, + 4B47ACBD10B5890100469C67 /* JackMachThread.cpp in Sources */, + 4B47ACBE10B5890100469C67 /* JackMachClientChannel.cpp in Sources */, + 4B47ACBF10B5890100469C67 /* JackGlobals.cpp in Sources */, + 4B47ACC010B5890100469C67 /* ringbuffer.c in Sources */, + 4B47ACC110B5890100469C67 /* JackDebugClient.cpp in Sources */, + 4B47ACC210B5890100469C67 /* JackTransportEngine.cpp in Sources */, + 4B47ACC310B5890100469C67 /* timestamps.c in Sources */, + 4B47ACC410B5890100469C67 /* JackPortType.cpp in Sources */, + 4B47ACC510B5890100469C67 /* JackAudioPort.cpp in Sources */, + 4B47ACC610B5890100469C67 /* JackMidiPort.cpp in Sources */, + 4B47ACC710B5890100469C67 /* JackMidiAPI.cpp in Sources */, + 4B47ACC810B5890100469C67 /* JackEngineControl.cpp in Sources */, + 4B47ACC910B5890100469C67 /* JackTools.cpp in Sources */, + 4B47ACCA10B5890100469C67 /* JackError.cpp in Sources */, + 4B47ACCB10B5890100469C67 /* JackMessageBuffer.cpp in Sources */, + 4B47ACCC10B5890100469C67 /* JackPosixServerLaunch.cpp in Sources */, + 4B47ACCD10B5890100469C67 /* JackPosixThread.cpp in Sources */, + 4B47ACCE10B5890100469C67 /* JackMachTime.c in Sources */, + 4B47ACCF10B5890100469C67 /* JackProcessSync.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B5A1BB30CD1CB9E0005BF74 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -6624,6 +6861,8 @@ 4BBAE4110F42FA6100B8BD3F /* JackEngineProfiling.cpp in Sources */, 4BECB2F50F4451C10091B70A /* JackProcessSync.cpp in Sources */, 4BF339230F8B873E0080FB5B /* JackMidiDriver.cpp in Sources */, + 4BCBCE5D10C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */, + 4BCBCE5F10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6802,6 +7041,8 @@ 4BA339A210B2E36800190E3B /* JackMidiDriver.cpp in Sources */, 4BA339A310B2E36800190E3B /* JackWaitThreadedDriver.cpp in Sources */, 4BA339A410B2E36800190E3B /* JackArgParser.cpp in Sources */, + 4BCBCE6510C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */, + 4BCBCE6710C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -12152,6 +12393,199 @@ }; name = Default; }; + 4B47ACD410B5890100469C67 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = NO; + DEBUGGING_SYMBOLS = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; + FRAMEWORK_VERSION = A; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + GENERATE_PKGINFO_FILE = NO; + HEADER_SEARCH_PATHS = ( + ../common, + ../posix, + RPC, + ../common/jack, + ); + INFOPLIST_FILE = "Jack-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; + OTHER_CFLAGS = ( + "-DUSE_POSIX_SHM", + "-DJACK_32_64", + "-D__SMP__", + ); + OTHER_CPLUSPLUSFLAGS = ( + "-D__CLIENTDEBUG__", + "-DMACH_RPC_MACH_SEMA", + "-D__SMP__", + "-DJACK_32_64", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", + ); + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_LDFLAGS = ( + "-framework", + Carbon, + "-framework", + CoreAudio, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = Jackmp; + REZ_EXECUTABLE = NO; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost"; + ZERO_LINK = YES; + }; + name = Development; + }; + 4B47ACD510B5890100469C67 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; + FRAMEWORK_VERSION = A; + GCC_AUTO_VECTORIZATION = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_ENABLE_SSE3_EXTENSIONS = YES; + GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + GENERATE_PKGINFO_FILE = NO; + HEADER_SEARCH_PATHS = ( + ../common, + ../posix, + RPC, + ../common/jack, + ); + INFOPLIST_FILE = "Jack-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ( + "-DUSE_POSIX_SHM", + "-DJACK_32_64", + "-D__SMP__", + ); + OTHER_CPLUSPLUSFLAGS = ( + "-D__CLIENTDEBUG__", + "-DMACH_RPC_MACH_SEMA", + "-DJACK_32_64", + "-D__SMP__", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", + ); + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; + OTHER_LDFLAGS = ( + "-framework", + Carbon, + "-framework", + CoreAudio, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = Jackmp; + REZ_EXECUTABLE = NO; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost"; + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B47ACD610B5890100469C67 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc64, + ppc, + i386, + x86_64, + ); + DEBUG_INFORMATION_FORMAT = dwarf; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; + FRAMEWORK_VERSION = A; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + GENERATE_PKGINFO_FILE = NO; + HEADER_SEARCH_PATHS = ( + RPC, + ../common/jack, + ); + INFOPLIST_FILE = "Jack-Info copy 2.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; + OTHER_CFLAGS = ( + "-DUSE_POSIX_SHM", + "-DJACK_32_64", + "-D__SMP__", + ); + OTHER_CPLUSPLUSFLAGS = ( + "-DMACH_RPC_MACH_SEMA", + "-DJACK_32_64", + "-D__SMP__", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", + ); + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_LDFLAGS = ( + "-framework", + Carbon, + "-framework", + AudioToolBox, + "-framework", + CoreAudio, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = Jackmp; + REZ_EXECUTABLE = NO; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost"; + }; + name = Default; + }; 4B5A1BB80CD1CB9E0005BF74 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { @@ -17952,6 +18386,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; + 4B47ACD310B5890100469C67 /* Build configuration list for PBXNativeTarget "Jackmp.framework 64 bits debugging" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B47ACD410B5890100469C67 /* Development */, + 4B47ACD510B5890100469C67 /* Deployment */, + 4B47ACD610B5890100469C67 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; 4B5A1BB70CD1CB9E0005BF74 /* Build configuration list for PBXNativeTarget "jack_midiseq Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/macosx/coreaudio/JackAudioQueueAdapter.cpp b/macosx/coreaudio/JackAudioQueueAdapter.cpp index 3cb9e9af..e6a1db35 100644 --- a/macosx/coreaudio/JackAudioQueueAdapter.cpp +++ b/macosx/coreaudio/JackAudioQueueAdapter.cpp @@ -18,59 +18,105 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackAudioQueueAdapter.h" -#include +//#include namespace Jack { // NOT YET WORKING.... -static void Print4CharCode(char* msg, long c) +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; //printf("%s'%s'\n", (msg), __4CC_string); snprintf(__4CC_string, 5, "%s'%s'\n", (msg), __4CC_string); } + +static int ComputeRecordBufferSize(AudioQueueRef mQueue, const AudioStreamBasicDescription *format, float seconds) +{ + OSStatus err; + int packets, frames, bytes = 0; + frames = (int)ceil(seconds * format->mSampleRate); + + if (format->mBytesPerFrame > 0) + bytes = frames * format->mBytesPerFrame; + else { + UInt32 maxPacketSize; + if (format->mBytesPerPacket > 0) { + maxPacketSize = format->mBytesPerPacket; // constant packet size + } else { + UInt32 propertySize = sizeof(maxPacketSize); + if ((err = AudioQueueGetProperty(mQueue, kAudioQueueProperty_MaximumOutputPacketSize, &maxPacketSize, &propertySize)) != noErr) { + printf("Couldn't get queue's maximum output packet size\n"); + return 0; + } + } + if (format->mFramesPerPacket > 0) + packets = frames / format->mFramesPerPacket; + else + packets = frames; // worst-case scenario: 1 frame in a packet + if (packets == 0) // sanity check + packets = 1; + bytes = packets * maxPacketSize; + } + return bytes; +} void JackAudioQueueAdapter::CaptureCallback(void * inUserData, - AudioQueueRef inAQ, - AudioQueueBufferRef inBuffer, - const AudioTimeStamp * inStartTime, - UInt32 inNumPackets, - const AudioStreamPacketDescription *inPacketDesc) + AudioQueueRef inAQ, + AudioQueueBufferRef inBuffer, + const AudioTimeStamp * inStartTime, + UInt32 inNumPackets, + const AudioStreamPacketDescription *inPacketDesc) { JackAudioQueueAdapter* adapter = (JackAudioQueueAdapter*)inUserData; - + OSStatus err; printf("JackAudioQueueAdapter::CaptureCallback\n"); - if (AudioQueueEnqueueBuffer(adapter->fCaptureQueue, inBuffer, 0, NULL) != noErr) { - printf("JackAudioQueueAdapter::CaptureCallback error\n"); - } - // Use the adapter to communicate with audio callback // jack_adapter_push_input(adapter, audio_output, audio_output_buffer); + + if ((err = AudioQueueEnqueueBuffer(adapter->fCaptureQueue, inBuffer, 0, NULL)) != noErr) { + printf("JackAudioQueueAdapter::CaptureCallback error %d\n", err); + } else { + printf("JackAudioQueueAdapter::CaptureCallback enqueue buffer\n"); + } } void JackAudioQueueAdapter::PlaybackCallback(void * inUserData, - AudioQueueRef inAQ, - AudioQueueBufferRef inCompleteAQBuffer) + AudioQueueRef inAQ, + AudioQueueBufferRef inCompleteAQBuffer) { JackAudioQueueAdapter* adapter = (JackAudioQueueAdapter*)inUserData; - + OSStatus err; printf("JackAudioQueueAdapter::PlaybackCallback\n"); - if (AudioQueueEnqueueBuffer(adapter->fPlaybackQueue, inCompleteAQBuffer, 0, &adapter->fPlaybackPacketDescs) != noErr) { - printf("JackAudioQueueAdapter::PlaybackCallback error\n"); - } - // Use the adapter to communicate with audio callback // jack_adapter_pull_output(adapter, audio_input, audio_input_buffer); + + //if (AudioQueueEnqueueBuffer(adapter->fPlaybackQueue, inCompleteAQBuffer, 0, &adapter->fPlaybackPacketDescs) != noErr) { + if ((err = AudioQueueEnqueueBuffer(inAQ, inCompleteAQBuffer, 0, NULL)) != noErr) { + printf("JackAudioQueueAdapter::PlaybackCallback error %d\n", err); + } else { + printf("JackAudioQueueAdapter::PlaybackCallback enqueue buffer\n"); + } } +void JackAudioQueueAdapter::InterruptionListener(void* inClientData, UInt32 inInterruptionState) +{ + JackAudioQueueAdapter* obj = (JackAudioQueueAdapter*)inClientData; +} + +void JackAudioQueueAdapter::PropListener(void* inClientData, + AudioSessionPropertyID inID, + UInt32 inDataSize, + const void* inData) +{} + JackAudioQueueAdapter::JackAudioQueueAdapter(int inchan, int outchan, jack_nframes_t buffer_size, jack_nframes_t sample_rate, jack_adapter_t* adapter) :fCaptureChannels(inchan), fPlaybackChannels(outchan), fBufferSize(buffer_size), fSampleRate(sample_rate), fAdapter(adapter) @@ -79,9 +125,46 @@ JackAudioQueueAdapter::JackAudioQueueAdapter(int inchan, int outchan, jack_nfram JackAudioQueueAdapter::~JackAudioQueueAdapter() {} -int JackAudioQueueAdapter::Open() +int JackAudioQueueAdapter::Open() { - OSStatus err; + OSStatus err; + int bufferByteSize; + UInt32 size; + + /* + err = AudioSessionInitialize(NULL, NULL, InterruptionListener, this); + if (err != noErr) { + fprintf(stderr, "AudioSessionInitialize error %d\n", err); + return -1; + } + + err = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, PropListener, this); + if (err) { + fprintf(stderr, "kAudioSessionProperty_AudioRouteChange error %d\n", err); + } + + UInt32 inputAvailable = 0; + UInt32 size = sizeof(inputAvailable); + + // we do not want to allow recording if input is not available + err = AudioSessionGetProperty(kAudioSessionProperty_AudioInputAvailable, &size, &inputAvailable); + if (err != noErr) { + fprintf(stderr, "kAudioSessionProperty_AudioInputAvailable error %d\n", err); + } + + // we also need to listen to see if input availability changes + err = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioInputAvailable, PropListener, this); + if (err != noErr) { + fprintf(stderr, "kAudioSessionProperty_AudioInputAvailable error %d\n", err); + } + + err = AudioSessionSetActive(true); + if (err != noErr) { + fprintf(stderr, "AudioSessionSetActive (true) failed %d", err); + return -1; + } + */ + AudioStreamBasicDescription captureDataFormat; /* @@ -95,26 +178,55 @@ int JackAudioQueueAdapter::Open() captureDataFormat.mChannelsPerFrame = fCaptureChannels; captureDataFormat.mBitsPerChannel = 32; */ - + + captureDataFormat.mSampleRate = fSampleRate; captureDataFormat.mFormatID = kAudioFormatLinearPCM; - captureDataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; - captureDataFormat.mBytesPerPacket = 4; + captureDataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; + captureDataFormat.mBytesPerPacket = 4; captureDataFormat.mFramesPerPacket = 1; // this means each packet in the AQ has two samples, one for each channel -> 4 bytes/frame/packet captureDataFormat.mBytesPerFrame = 4; captureDataFormat.mChannelsPerFrame = 2; captureDataFormat.mBitsPerChannel = 16; + if ((err = AudioQueueNewInput(&captureDataFormat, CaptureCallback, this, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &fCaptureQueue)) != noErr) { Print4CharCode("error code : unknown", err); return -1; } + size = sizeof(captureDataFormat.mSampleRate); + if ((err = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &size, &captureDataFormat.mSampleRate)) != noErr) { + printf("couldn't get hardware sample rate\n"); + } + + size = sizeof(captureDataFormat.mChannelsPerFrame); + if ((err = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputNumberChannels, &size, &captureDataFormat.mChannelsPerFrame)) != noErr) { + printf("couldn't get input channel count\n"); + } + + size = sizeof(captureDataFormat); + if ((err = AudioQueueGetProperty(fCaptureQueue, kAudioQueueProperty_StreamDescription, &captureDataFormat, &size)) != noErr) { + printf("couldn't get queue's format\n"); + } + + bufferByteSize = ComputeRecordBufferSize(fCaptureQueue, &captureDataFormat, kBufferDurationSeconds); // enough bytes for half a second + for (int i = 0; i < kNumberBuffers; ++i) { + if ((err = AudioQueueAllocateBuffer(fCaptureQueue, bufferByteSize, &fCaptureQueueBuffers[i])) != noErr) { + printf("Capture AudioQueueAllocateBuffer failed\n"); + } + if ((err = AudioQueueEnqueueBuffer(fCaptureQueue, fCaptureQueueBuffers[i], 0, NULL)) != noErr) { + printf("Capture AudioQueueEnqueueBuffer failed\n"); + } + } + + //AudioQueueSetProperty(fCaptureQueue, kAudioQueueProperty_MagicCookie, cookie, size) //AudioQueueSetProperty(fCaptureQueue, kAudioQueueProperty_ChannelLayout, acl, size AudioStreamBasicDescription playbackDataFormat; + /* playbackDataFormat.mSampleRate = fSampleRate; playbackDataFormat.mFormatID = kAudioFormatLinearPCM; playbackDataFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; @@ -123,38 +235,78 @@ int JackAudioQueueAdapter::Open() playbackDataFormat.mBytesPerFrame = sizeof(float); playbackDataFormat.mChannelsPerFrame = fPlaybackChannels; playbackDataFormat.mBitsPerChannel = 32; + */ + + playbackDataFormat.mSampleRate = fSampleRate; + playbackDataFormat.mFormatID = kAudioFormatLinearPCM; + playbackDataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; + playbackDataFormat.mBytesPerPacket = 4; + playbackDataFormat.mFramesPerPacket = 1; + playbackDataFormat.mBytesPerFrame = 4; + playbackDataFormat.mChannelsPerFrame = fPlaybackChannels; + playbackDataFormat.mBitsPerChannel = 16; + if ((err = AudioQueueNewOutput(&playbackDataFormat, PlaybackCallback, this, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &fPlaybackQueue)) != noErr) { Print4CharCode("error code : unknown", err); return -1; } + for (int i = 0; i < kNumberBuffers; ++i) { + if ((err = AudioQueueAllocateBuffer(fPlaybackQueue, bufferByteSize, &fPlaybackQueueBuffers[i])) != noErr) { + printf("Playback AudioQueueAllocateBuffer failed %d\n", err); + } + //if ((err = AudioQueueEnqueueBuffer(fPlaybackQueue, fPlaybackQueueBuffers[i], 0, NULL)) != noErr) { + // printf("Playback AudioQueueEnqueueBuffer failed %d\n", err); + //} + } + + AudioQueueSetParameter(fPlaybackQueue, kAudioQueueParam_Volume, 1.0); + //AudioQueueSetProperty(fPlaybackQueue, kAudioQueueProperty_MagicCookie, cookie, size); //AudioQueueSetProperty(fPlaybackQueue, kAudioQueueProperty_ChannelLayout, acl, size); //AudioQueueSetParameter(fPlaybackQueue, kAudioQueueParam_Volume, volume - //AudioQueueStart(fCaptureQueue, NULL); - AudioQueueStart(fPlaybackQueue, NULL); - return 0; } -int JackAudioQueueAdapter::Close() +int JackAudioQueueAdapter::Close() { - AudioQueueStop(fCaptureQueue, true); - AudioQueueStop(fPlaybackQueue, true); + //AudioSessionSetActive(false); AudioQueueDispose(fCaptureQueue, true); AudioQueueDispose(fPlaybackQueue, true); return 0; } + +int JackAudioQueueAdapter::Start() +{ + for (int i = 0; i < kNumberBuffers; ++i) { + PlaybackCallback(this, fPlaybackQueue, fPlaybackQueueBuffers[i]); + } + + AudioQueueStart(fCaptureQueue, NULL); + AudioQueueStart(fPlaybackQueue, NULL); + + return 0; +} + +int JackAudioQueueAdapter::Stop() +{ + + AudioQueueStop(fCaptureQueue, NULL); + AudioQueueStop(fPlaybackQueue, NULL); + + return 0; +} + -int JackAudioQueueAdapter::SetSampleRate(jack_nframes_t sample_rate) +int JackAudioQueueAdapter::SetSampleRate(jack_nframes_t sample_rate) { return 0; } -int JackAudioQueueAdapter::SetBufferSize(jack_nframes_t buffer_size) +int JackAudioQueueAdapter::SetBufferSize(jack_nframes_t buffer_size) { return 0; } diff --git a/macosx/coreaudio/JackAudioQueueAdapter.h b/macosx/coreaudio/JackAudioQueueAdapter.h index 1de09959..da8f8430 100644 --- a/macosx/coreaudio/JackAudioQueueAdapter.h +++ b/macosx/coreaudio/JackAudioQueueAdapter.h @@ -20,8 +20,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifndef __JackAudioQueueAdapter__ #define __JackAudioQueueAdapter__ -#include -#include +//#include +//#include + +#include #include @@ -32,7 +34,8 @@ namespace Jack \brief Audio adapter using AudioQueue API. */ -static const int kNumberBuffers = 3; +#define kNumberBuffers 3 +#define kBufferDurationSeconds .5 class JackAudioQueueAdapter { @@ -44,7 +47,7 @@ class JackAudioQueueAdapter AudioQueueRef fPlaybackQueue; AudioQueueBufferRef fPlaybackQueueBuffers[kNumberBuffers]; - AudioStreamPacketDescription fPlaybackPacketDescs; + //AudioStreamPacketDescription fPlaybackPacketDescs; jack_nframes_t fBufferSize; @@ -55,17 +58,24 @@ class JackAudioQueueAdapter jack_adapter_t* fAdapter; - static void CaptureCallback(void * inUserData, + static void CaptureCallback(void* inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, - const AudioTimeStamp * inStartTime, + const AudioTimeStamp* inStartTime, UInt32 inNumPackets, - const AudioStreamPacketDescription *inPacketDesc); + const AudioStreamPacketDescription* inPacketDesc); - static void PlaybackCallback(void * inUserData, - AudioQueueRef inAQ, - AudioQueueBufferRef inCompleteAQBuffer); + static void PlaybackCallback(void* inUserData, + AudioQueueRef inAQ, + AudioQueueBufferRef inCompleteAQBuffer); + + static void InterruptionListener(void* inClientData, UInt32 inInterruptionState); + + static void PropListener(void* inClientData, + AudioSessionPropertyID inID, + UInt32 inDataSize, + const void* inData); public: @@ -74,6 +84,10 @@ class JackAudioQueueAdapter virtual int Open(); virtual int Close(); + + virtual int Start(); + virtual int Stop(); + virtual int SetSampleRate(jack_nframes_t sample_rate); virtual int SetBufferSize(jack_nframes_t buffer_size); diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index e540a164..2143170f 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -250,10 +250,10 @@ OSStatus JackCoreAudioDriver::MeasureCallback(AudioDeviceID inDevice, } OSStatus JackCoreAudioDriver::SRNotificationCallback(AudioDeviceID inDevice, - UInt32 inChannel, - Boolean isInput, - AudioDevicePropertyID inPropertyID, - void* inClientData) + UInt32 inChannel, + Boolean isInput, + AudioDevicePropertyID inPropertyID, + void* inClientData) { JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData; @@ -262,6 +262,16 @@ OSStatus JackCoreAudioDriver::SRNotificationCallback(AudioDeviceID inDevice, case kAudioDevicePropertyNominalSampleRate: { jack_log("JackCoreAudioDriver::SRNotificationCallback kAudioDevicePropertyNominalSampleRate"); driver->fState = true; + // Check new sample rate + Float64 sampleRate; + UInt32 outSize = sizeof(Float64); + OSStatus err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); + if (err != noErr) { + jack_error("Cannot get current sample rate"); + printError(err); + } else { + jack_log("SRNotificationCallback : checked sample rate = %f", sampleRate); + } break; } } @@ -271,14 +281,23 @@ OSStatus JackCoreAudioDriver::SRNotificationCallback(AudioDeviceID inDevice, // A better implementation would possibly try to recover in case of hardware device change (see HALLAB HLFilePlayerWindowControllerAudioDevicePropertyListenerProc code) OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, - UInt32 inChannel, - Boolean isInput, - AudioDevicePropertyID inPropertyID, - void* inClientData) + UInt32 inChannel, + Boolean isInput, + AudioDevicePropertyID inPropertyID, + void* inClientData) { JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData; switch (inPropertyID) { + + case kAudioDevicePropertyDeviceIsRunning: { + UInt32 isrunning = 0; + UInt32 outsize = sizeof(UInt32); + if (AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyDeviceIsRunning, &outsize, &isrunning) == noErr) { + jack_log("JackCoreAudioDriver::DeviceNotificationCallback kAudioDevicePropertyDeviceIsRunning = %d", isrunning); + } + break; + } case kAudioDeviceProcessorOverload: { jack_error("JackCoreAudioDriver::DeviceNotificationCallback kAudioDeviceProcessorOverload"); @@ -296,12 +315,52 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, } case kAudioDevicePropertyNominalSampleRate: { - jack_error("Cannot handle kAudioDevicePropertyNominalSampleRate : server will quit..."); - driver->NotifyFailure(JackBackendError, "Another application has changed the sample rate."); // Message length limited to JACK_MESSAGE_SIZE - driver->CloseAUHAL(); - kill(JackTools::GetPID(), SIGINT); - return kAudioHardwareUnsupportedOperationError; - } + 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); + if (err != noErr) { + jack_error("Cannot set sample rate = %f", sampleRate); + printError(err); + } else { + jack_log("Set sample rate = %f", sampleRate); + } + + // Check new sample rate again... + outsize = sizeof(Float64); + err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sampleRate); + if (err != noErr) { + jack_error("Cannot get current sample rate"); + printError(err); + } else { + 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(); + kill(JackTools::GetPID(), SIGINT); + return kAudioHardwareUnsupportedOperationError; + } + } + } } return noErr; @@ -926,8 +985,6 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, if (fHogged) { if (TakeHog()) { jack_info("Device = %ld has been hogged", fDeviceID); - } else { - jack_error("Cannot hog device = %ld", fDeviceID); } } @@ -1020,6 +1077,8 @@ int JackCoreAudioDriver::SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes 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 @@ -1046,6 +1105,16 @@ 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); + if (err != noErr) { + jack_error("Cannot get current sample rate"); + printError(err); + } else { + jack_log("Checked sample rate = %f", sampleRate); + } // Remove SR change notification AudioDeviceRemovePropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback); @@ -1199,9 +1268,9 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (capturing && inchannels > 0) { size = sizeof(AudioStreamBasicDescription); - err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &srcFormat, &size); + err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, &size); if (err1 != noErr) { - jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); + jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); printError(err1); goto error; } @@ -1219,9 +1288,8 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, 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"); + jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); printError(err1); goto error; } @@ -1230,9 +1298,9 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (playing && outchannels > 0) { size = sizeof(AudioStreamBasicDescription); - err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 1, &dstFormat, &size); + err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, &size); if (err1 != noErr) { - jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); + jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); printError(err1); goto error; } @@ -1250,9 +1318,8 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, 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"); + jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); printError(err1); goto error; } @@ -1623,7 +1690,7 @@ int JackCoreAudioDriver::Start() return -1; } - // Waiting for Measure callback to be called ( = driver has started) + // Waiting for Measure callback to be called (= driver has started) fState = false; int count = 0; while (!fState && count++ < WAIT_COUNTER) { @@ -1695,7 +1762,7 @@ bool JackCoreAudioDriver::TakeHogAux(AudioDeviceID deviceID, bool isInput) hog_pid = getpid(); err = AudioDeviceSetProperty(deviceID, 0, 0, isInput, kAudioDevicePropertyHogMode, propSize, &hog_pid); if (err != noErr) { - jack_error("Can't hog device = %d because it's being hogged by another program", deviceID); + jack_error("Can't hog device = %d because it's being hogged by another program or cannot be hogged", deviceID); return false; } } diff --git a/macosx/coremidi/JackCoreMidiDriver.cpp b/macosx/coremidi/JackCoreMidiDriver.cpp index 891af946..08bd8c80 100644 --- a/macosx/coremidi/JackCoreMidiDriver.cpp +++ b/macosx/coremidi/JackCoreMidiDriver.cpp @@ -52,19 +52,17 @@ void JackCoreMidiDriver::ReadProcAux(const MIDIPacketList *pktlist, jack_ringbuf // TODO : use timestamp + // Check available size first.. + size = jack_ringbuffer_write_space(ringbuffer); + if (size < (sizeof(UInt16) + packet->length)) { + jack_error("ReadProc : ring buffer is full, skip events..."); + return; + } // Write length of each packet first - size = jack_ringbuffer_write(ringbuffer, (char*)&packet->length, sizeof(UInt16)); - if (size != sizeof(UInt16)) { - jack_error("ReadProc : ring buffer is full, skip events..."); - return; - } + jack_ringbuffer_write(ringbuffer, (char*)&packet->length, sizeof(UInt16)); // Write event actual data - size = jack_ringbuffer_write(ringbuffer, (char*)packet->data, packet->length); - if (size != packet->length) { - jack_error("ReadProc : ring buffer is full, skip events..."); - return; - } - + jack_ringbuffer_write(ringbuffer, (char*)packet->data, packet->length); + packet = MIDIPacketNext(packet); } } diff --git a/macosx/iphone/Info.plist b/macosx/iphone/Info.plist index fdf83406..38cb25cf 100644 --- a/macosx/iphone/Info.plist +++ b/macosx/iphone/Info.plist @@ -11,7 +11,7 @@ CFBundleIconFile CFBundleIdentifier - com.yourcompany.${PRODUCT_NAME:identifier} + fr.grame.iGrame.iPhoneFaustNet CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/macosx/iphone/freeverb.mm b/macosx/iphone/freeverb.mm index 9b7832f7..3daabc9a 100644 --- a/macosx/iphone/freeverb.mm +++ b/macosx/iphone/freeverb.mm @@ -38,6 +38,8 @@ #include #include +#include "JackAudioQueueAdapter.h" + using namespace std; // On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero) @@ -690,19 +692,36 @@ static int net_process(jack_nframes_t buffer_size, // MAIN //------------------------------------------------------------------------- + +#define TEST_MASTER "194.5.49.5" + int main(int argc, char *argv[]) { UI* interface = new CMDUI(argc, argv); jack_net_slave_t* net; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + //Jack::JackAudioQueueAdapter audio(2, 2, 1024, 44100, NULL); + gNumInChans = DSP.getNumInputs(); gNumOutChans = DSP.getNumOutputs(); jack_slave_t request = { gNumInChans, gNumOutChans, 0, 0, DEFAULT_MTU, -1, JackSlowMode }; jack_master_t result; - - if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { + + printf("Network\n"); + + //if (audio.Open() < 0) { + // fprintf(stderr, "Cannot open audio\n"); + // return 1; + //} + + //audio.Start(); + + // Hang around forever... + //while(1) CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.25, false); + + if ((net = jack_net_slave_open(TEST_MASTER, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { fprintf(stderr, "jack remote server not running ?\n"); return 1; } @@ -726,5 +745,10 @@ int main(int argc, char *argv[]) { // Wait for application end jack_net_slave_deactivate(net); jack_net_slave_close(net); + + //if (audio.Close() < 0) { + // fprintf(stderr, "Cannot close audio\n"); + //} + return retVal; } diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj index 8ce87173..a1211fef 100755 --- a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -56,7 +56,45 @@ 4B2791890F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; 4B27918A0F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; 4B27918B0F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; + 4B41469810BD3C4300C12F0C /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; + 4B41469A10BD3C4300C12F0C /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; }; + 4B41469B10BD3C4300C12F0C /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93870F49B0E300D3626B /* JackMachTime.c */; }; + 4B41469C10BD3C4300C12F0C /* JackNetAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */; }; + 4B41469D10BD3C4300C12F0C /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */; }; + 4B41469E10BD3C4300C12F0C /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; + 4B41469F10BD3C4300C12F0C /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; + 4B4146A010BD3C4300C12F0C /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; + 4B4146A110BD3C4300C12F0C /* JackAudioQueueAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */; }; + 4B4146A210BD3C4300C12F0C /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; + 4B4146A310BD3C4300C12F0C /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; }; + 4B4146A410BD3C4300C12F0C /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; + 4B4146A510BD3C4300C12F0C /* iPhoneNetAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */; }; + 4B4146A610BD3C4300C12F0C /* freeverb.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BBDC8F90F5420C000465F9C /* freeverb.mm */; }; + 4B4146A710BD3C4300C12F0C /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; + 4B4146A910BD3C4300C12F0C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 4B4146AA10BD3C4300C12F0C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 4B4146AB10BD3C4300C12F0C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 4B4146AC10BD3C4300C12F0C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; 4BBDC8FA0F5420C000465F9C /* freeverb.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BBDC8F90F5420C000465F9C /* freeverb.mm */; }; + 4BCF75DA10BC2FD90082C526 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; + 4BCF75DC10BC2FD90082C526 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; }; + 4BCF75DD10BC2FD90082C526 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93870F49B0E300D3626B /* JackMachTime.c */; }; + 4BCF75DE10BC2FD90082C526 /* JackNetAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */; }; + 4BCF75DF10BC2FD90082C526 /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */; }; + 4BCF75E010BC2FD90082C526 /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; + 4BCF75E110BC2FD90082C526 /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; + 4BCF75E210BC2FD90082C526 /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; + 4BCF75E310BC2FD90082C526 /* JackAudioQueueAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */; }; + 4BCF75E410BC2FD90082C526 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; + 4BCF75E510BC2FD90082C526 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; }; + 4BCF75E610BC2FD90082C526 /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; + 4BCF75E710BC2FD90082C526 /* iPhoneNetAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */; }; + 4BCF75E910BC2FD90082C526 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; + 4BCF75EB10BC2FD90082C526 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 4BCF75EC10BC2FD90082C526 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 4BCF75ED10BC2FD90082C526 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 4BCF75EE10BC2FD90082C526 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; + 4BCF75F710BC30140082C526 /* audio_thru.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BCF75F610BC30140082C526 /* audio_thru.mm */; }; 4BF1360F0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; 4BF136100F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; 4BF136130F4B0B5E00218A3F /* JackAudioAdapterInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */; }; @@ -109,7 +147,10 @@ 4B1A947E0F49C42300D3626B /* JackAudioQueueAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioQueueAdapter.h; path = ../coreaudio/JackAudioQueueAdapter.h; sourceTree = SOURCE_ROOT; }; 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.1.sdk/System/Library/Frameworks/AudioToolbox.framework; sourceTree = ""; }; 4B2791870F72570C000536B7 /* JackGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackGlobals.cpp; path = ../../common/JackGlobals.cpp; sourceTree = SOURCE_ROOT; }; + 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BBDC8F90F5420C000465F9C /* freeverb.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = freeverb.mm; sourceTree = SOURCE_ROOT; }; + 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BCF75F610BC30140082C526 /* audio_thru.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = audio_thru.mm; sourceTree = SOURCE_ROOT; }; 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; }; 4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioAdapterInterface.h; path = ../../common/JackAudioAdapterInterface.h; sourceTree = SOURCE_ROOT; }; 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackResampler.cpp; path = ../../common/JackResampler.cpp; sourceTree = SOURCE_ROOT; }; @@ -150,6 +191,28 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B4146A810BD3C4300C12F0C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B4146A910BD3C4300C12F0C /* Foundation.framework in Frameworks */, + 4B4146AA10BD3C4300C12F0C /* UIKit.framework in Frameworks */, + 4B4146AB10BD3C4300C12F0C /* CoreGraphics.framework in Frameworks */, + 4B4146AC10BD3C4300C12F0C /* AudioToolbox.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BCF75EA10BC2FD90082C526 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BCF75EB10BC2FD90082C526 /* Foundation.framework in Frameworks */, + 4BCF75EC10BC2FD90082C526 /* UIKit.framework in Frameworks */, + 4BCF75ED10BC2FD90082C526 /* CoreGraphics.framework in Frameworks */, + 4BCF75EE10BC2FD90082C526 /* AudioToolbox.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BFF456F0F4D5D9700106083 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -171,6 +234,8 @@ 4BFF45120F4D59DB00106083 /* libjacknet.a */, 4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */, 4B0772380F54018C000DC657 /* iPhoneNetMaster.app */, + 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */, + 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */, ); name = Products; sourceTree = ""; @@ -189,6 +254,7 @@ 29B97315FDCFA39411CA2CEA /* Other Sources */ = { isa = PBXGroup; children = ( + 4BCF75F610BC30140082C526 /* audio_thru.mm */, 4BBDC8F90F5420C000465F9C /* freeverb.mm */, 4B0773840F541EE2000DC657 /* iPhoneNetAppDelegate.h */, 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */, @@ -307,6 +373,40 @@ productReference = 4BFF45120F4D59DB00106083 /* libjacknet.a */; productType = "com.apple.product-type.library.static"; }; + 4B41469610BD3C4300C12F0C /* iPhoneFaustNet Distribution */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B4146AD10BD3C4300C12F0C /* Build configuration list for PBXNativeTarget "iPhoneFaustNet Distribution" */; + buildPhases = ( + 4B41469710BD3C4300C12F0C /* Resources */, + 4B41469910BD3C4300C12F0C /* Sources */, + 4B4146A810BD3C4300C12F0C /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "iPhoneFaustNet Distribution"; + productName = iPhoneNet; + productReference = 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */; + productType = "com.apple.product-type.application"; + }; + 4BCF75D810BC2FD90082C526 /* iPhoneThruNet */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4BCF75EF10BC2FD90082C526 /* Build configuration list for PBXNativeTarget "iPhoneThruNet" */; + buildPhases = ( + 4BCF75D910BC2FD90082C526 /* Resources */, + 4BCF75DB10BC2FD90082C526 /* Sources */, + 4BCF75EA10BC2FD90082C526 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = iPhoneThruNet; + productName = iPhoneNet; + productReference = 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */; + productType = "com.apple.product-type.application"; + }; 4BFF455E0F4D5D9700106083 /* iPhoneFaustNet */ = { isa = PBXNativeTarget; buildConfigurationList = 4BFF45740F4D5D9700106083 /* Build configuration list for PBXNativeTarget "iPhoneFaustNet" */; @@ -339,6 +439,8 @@ 4B07721F0F54018C000DC657 /* iPhoneNetMaster */, 1D6058900D05DD3D006BFB54 /* iPhoneNetSlave */, 4BFF455E0F4D5D9700106083 /* iPhoneFaustNet */, + 4BCF75D810BC2FD90082C526 /* iPhoneThruNet */, + 4B41469610BD3C4300C12F0C /* iPhoneFaustNet Distribution */, 4B1A940F0F49BDE000D3626B /* jacknet */, ); }; @@ -361,6 +463,22 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B41469710BD3C4300C12F0C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B41469810BD3C4300C12F0C /* MainWindow.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BCF75D910BC2FD90082C526 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BCF75DA10BC2FD90082C526 /* MainWindow.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BFF455F0F4D5D9700106083 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -432,6 +550,48 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B41469910BD3C4300C12F0C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B41469A10BD3C4300C12F0C /* JackMachThread.cpp in Sources */, + 4B41469B10BD3C4300C12F0C /* JackMachTime.c in Sources */, + 4B41469C10BD3C4300C12F0C /* JackNetAPI.cpp in Sources */, + 4B41469D10BD3C4300C12F0C /* JackNetInterface.cpp in Sources */, + 4B41469E10BD3C4300C12F0C /* JackNetTool.cpp in Sources */, + 4B41469F10BD3C4300C12F0C /* JackNetUnixSocket.cpp in Sources */, + 4B4146A010BD3C4300C12F0C /* JackPosixThread.cpp in Sources */, + 4B4146A110BD3C4300C12F0C /* JackAudioQueueAdapter.cpp in Sources */, + 4B4146A210BD3C4300C12F0C /* JackAudioAdapterInterface.cpp in Sources */, + 4B4146A310BD3C4300C12F0C /* JackResampler.cpp in Sources */, + 4B4146A410BD3C4300C12F0C /* ringbuffer.c in Sources */, + 4B4146A510BD3C4300C12F0C /* iPhoneNetAppDelegate.m in Sources */, + 4B4146A610BD3C4300C12F0C /* freeverb.mm in Sources */, + 4B4146A710BD3C4300C12F0C /* JackGlobals.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BCF75DB10BC2FD90082C526 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BCF75DC10BC2FD90082C526 /* JackMachThread.cpp in Sources */, + 4BCF75DD10BC2FD90082C526 /* JackMachTime.c in Sources */, + 4BCF75DE10BC2FD90082C526 /* JackNetAPI.cpp in Sources */, + 4BCF75DF10BC2FD90082C526 /* JackNetInterface.cpp in Sources */, + 4BCF75E010BC2FD90082C526 /* JackNetTool.cpp in Sources */, + 4BCF75E110BC2FD90082C526 /* JackNetUnixSocket.cpp in Sources */, + 4BCF75E210BC2FD90082C526 /* JackPosixThread.cpp in Sources */, + 4BCF75E310BC2FD90082C526 /* JackAudioQueueAdapter.cpp in Sources */, + 4BCF75E410BC2FD90082C526 /* JackAudioAdapterInterface.cpp in Sources */, + 4BCF75E510BC2FD90082C526 /* JackResampler.cpp in Sources */, + 4BCF75E610BC2FD90082C526 /* ringbuffer.c in Sources */, + 4BCF75E710BC2FD90082C526 /* iPhoneNetAppDelegate.m in Sources */, + 4BCF75E910BC2FD90082C526 /* JackGlobals.cpp in Sources */, + 4BCF75F710BC30140082C526 /* audio_thru.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BFF45610F4D5D9700106083 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -585,6 +745,107 @@ }; name = Release; }; + 4B4146AE10BD3C4300C12F0C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Stéphane Letz (8LJEY2RN3N)"; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + HEADER_SEARCH_PATHS = ( + ../../macosx, + ../../posix, + ../../common/jack, + ../../common, + ); + INFOPLIST_FILE = "Info copy 2.plist"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\\\\\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\\\\\"", + ); + OTHER_LDFLAGS = ""; + PRODUCT_NAME = iPhoneFaustNet; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = "CEF78041-8E2A-499D-BF7C-8A1B22B6C2AC"; + SDKROOT = iphoneos2.2.1; + }; + name = Debug; + }; + 4B4146AF10BD3C4300C12F0C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + HEADER_SEARCH_PATHS = ( + ../../macosx, + ../../common/jack, + ../../common, + ../../posix, + ); + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\\\\\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\\\\\"", + ); + ONLY_ACTIVE_ARCH = NO; + PRODUCT_NAME = iPhoneFaustNet; + SDKROOT = iphoneos3.1.2; + }; + name = Release; + }; + 4BCF75F010BC2FD90082C526 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + HEADER_SEARCH_PATHS = ( + ../../macosx, + ../../posix, + ../../common/jack, + ../../common, + ); + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\\\\\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\\\\\"", + ); + OTHER_LDFLAGS = ""; + PRODUCT_NAME = iPhoneThruNet; + SDKROOT = iphoneos2.2.1; + }; + name = Debug; + }; + 4BCF75F110BC2FD90082C526 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + HEADER_SEARCH_PATHS = ( + ../../macosx, + ../../common/jack, + ../../common, + ../../posix, + ); + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\\\\\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\\\\\"", + ); + ONLY_ACTIVE_ARCH = NO; + PRODUCT_NAME = iPhoneFaustNet; + }; + name = Release; + }; 4BFF45750F4D5D9700106083 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -691,6 +952,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 4B4146AD10BD3C4300C12F0C /* Build configuration list for PBXNativeTarget "iPhoneFaustNet Distribution" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B4146AE10BD3C4300C12F0C /* Debug */, + 4B4146AF10BD3C4300C12F0C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4BCF75EF10BC2FD90082C526 /* Build configuration list for PBXNativeTarget "iPhoneThruNet" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4BCF75F010BC2FD90082C526 /* Debug */, + 4BCF75F110BC2FD90082C526 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 4BFF45740F4D5D9700106083 /* Build configuration list for PBXNativeTarget "iPhoneFaustNet" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/posix/JackSocketServerChannel.cpp b/posix/JackSocketServerChannel.cpp index a5625219..d2a59b33 100644 --- a/posix/JackSocketServerChannel.cpp +++ b/posix/JackSocketServerChannel.cpp @@ -26,6 +26,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackClient.h" #include "JackTools.h" #include "JackNotification.h" +#include "JackException.h" + #include #include @@ -64,7 +66,7 @@ int JackSocketServerChannel::Open(const char* server_name, JackServer* server) void JackSocketServerChannel::Close() { - fThread.Kill(); + fThread.Stop(); fRequestListenSocket.Close(); // Close remaining client sockets @@ -387,8 +389,14 @@ bool JackSocketServerChannel::HandleRequest(int fd) case JackRequest::kNotification: { jack_log("JackRequest::Notification"); JackClientNotificationRequest req; - if (req.Read(socket) == 0) - fServer->Notify(req.fRefNum, req.fNotify, req.fValue); + if (req.Read(socket) == 0) { + if (req.fNotify == kQUIT) { + jack_log("JackRequest::Notification kQUIT"); + throw JackQuitException(); + } else { + fServer->Notify(req.fRefNum, req.fNotify, req.fValue); + } + } break; } @@ -436,35 +444,42 @@ bool JackSocketServerChannel::Init() bool JackSocketServerChannel::Execute() { - // Global poll - if ((poll(fPollTable, fSocketTable.size() + 1, 10000) < 0) && (errno != EINTR)) { - jack_error("Engine poll failed err = %s request thread quits...", strerror(errno)); - return false; - } else { - - // Poll all clients - for (unsigned int i = 1; i < fSocketTable.size() + 1; i++) { - int fd = fPollTable[i].fd; - jack_log("fPollTable i = %ld fd = %ld", i, fd); - if (fPollTable[i].revents & ~POLLIN) { - jack_log("Poll client error err = %s", strerror(errno)); - ClientKill(fd); - } else if (fPollTable[i].revents & POLLIN) { - if (!HandleRequest(fd)) - jack_log("Could not handle external client request"); + try { + + // Global poll + if ((poll(fPollTable, fSocketTable.size() + 1, 10000) < 0) && (errno != EINTR)) { + jack_error("Engine poll failed err = %s request thread quits...", strerror(errno)); + return false; + } else { + + // Poll all clients + for (unsigned int i = 1; i < fSocketTable.size() + 1; i++) { + int fd = fPollTable[i].fd; + jack_log("fPollTable i = %ld fd = %ld", i, fd); + if (fPollTable[i].revents & ~POLLIN) { + jack_log("Poll client error err = %s", strerror(errno)); + ClientKill(fd); + } else if (fPollTable[i].revents & POLLIN) { + if (!HandleRequest(fd)) + jack_log("Could not handle external client request"); + } } + + // Check the server request socket */ + if (fPollTable[0].revents & POLLERR) + jack_error("Error on server request socket err = %s", strerror(errno)); + + if (fPollTable[0].revents & POLLIN) + ClientCreate(); } - // Check the server request socket */ - if (fPollTable[0].revents & POLLERR) - jack_error("Error on server request socket err = %s", strerror(errno)); - - if (fPollTable[0].revents & POLLIN) - ClientCreate(); + BuildPoolTable(); + return true; + + } catch (JackQuitException& e) { + jack_log("JackMachServerChannel::Execute JackQuitException"); + return false; } - - BuildPoolTable(); - return true; } } // end of namespace diff --git a/posix/JackSocketServerNotifyChannel.cpp b/posix/JackSocketServerNotifyChannel.cpp index c4e4888a..df7381f1 100644 --- a/posix/JackSocketServerNotifyChannel.cpp +++ b/posix/JackSocketServerNotifyChannel.cpp @@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackError.h" #include "JackRequest.h" #include "JackConstants.h" +#include "JackNotification.h" namespace Jack { @@ -55,6 +56,15 @@ void JackSocketServerNotifyChannel::Notify(int refnum, int notify, int value) } } +void JackSocketServerNotifyChannel::NotifyQuit() +{ + JackClientNotificationRequest req(-1, kQUIT, 0); + if (req.Write(&fRequestSocket) < 0) { + jack_error("Could not write request ref = %d notify = %d", -1, kQUIT); + } +} + + } // end of namespace diff --git a/posix/JackSocketServerNotifyChannel.h b/posix/JackSocketServerNotifyChannel.h index d8687dfa..261ddbd4 100644 --- a/posix/JackSocketServerNotifyChannel.h +++ b/posix/JackSocketServerNotifyChannel.h @@ -44,6 +44,7 @@ class JackSocketServerNotifyChannel void Close(); void Notify(int refnum, int notify, int value); + void NotifyQuit(); }; } // end of namespace diff --git a/tests/test.cpp b/tests/test.cpp index e77edf49..018b7499 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -85,6 +85,7 @@ int reorder = 0; // graph reorder callback int RT = 0; // is real time or not... int FW = 0; // freewheel mode int init_clbk = 0; // init callback +int port_rename_clbk = 0; // portrename callback int i, j, k = 0; int port_callback_reg = 0; jack_nframes_t cur_buffer_size, old_buffer_size, cur_pos; @@ -180,6 +181,13 @@ void Jack_Client_Registration_Callback(const char* name, int val, void *arg) client_register--; } +int Jack_Port_Rename_Callback(jack_port_id_t port, const char* old_name, const char* new_name, void *arg) +{ + Log("Rename callback has been successfully called with old_name '%s' and new_name '%s'. (msg from callback)\n"); + port_rename_clbk = 1; + return 0; +} + int Jack_Update_Buffer_Size(jack_nframes_t nframes, void *arg) { cur_buffer_size = jack_get_buffer_size(client1); @@ -679,6 +687,7 @@ int main (int argc, char *argv[]) printf("!!! ERROR !!! while calling jack_set_thread_init_callback()...\n"); if (jack_set_freewheel_callback(client1, Jack_Freewheel_Callback, 0) != 0 ) printf("\n!!! ERROR !!! while calling jack_set_freewheel_callback()...\n"); + if (jack_set_process_callback(client1, process1, 0) != 0) { printf("Error when calling jack_set_process_callback() !\n"); @@ -694,6 +703,9 @@ int main (int argc, char *argv[]) if (jack_set_graph_order_callback(client1, Jack_Graph_Order_Callback, 0) != 0) { printf("Error when calling Jack_Graph_Order_Callback() !\n"); } + + if (jack_set_port_rename_callback(client1, Jack_Port_Rename_Callback, 0) != 0 ) + printf("\n!!! ERROR !!! while calling jack_set_rename_callback()...\n"); if (jack_set_xrun_callback(client1, Jack_XRun_Callback, 0 ) != 0) { printf("Error when calling jack_set_xrun_callback() !\n"); @@ -818,13 +830,23 @@ int main (int argc, char *argv[]) printf ("Fatal error : cannot activate client1\n"); exit(1); } + + /** + * Test if portrename callback have been called. + * + */ + jack_port_set_name (output_port1, "renamed-port#"); + jack_sleep(1 * 1000); + if (port_rename_clbk == 0) + printf("!!! ERROR !!! Jack_Port_Rename_Callback was not called !!.\n"); + /** * Test if init callback initThread have been called. * */ if (init_clbk == 0) - printf("!!! ERROR !!! JackThreadInitCallback was not called !!.\n"); + printf("!!! ERROR !!! Jack_Thread_Init_Callback was not called !!.\n"); jack_sleep(10 * 1000); // test see the clock in the graph at the begining... diff --git a/windows/JackRouter/JackRouter.cpp b/windows/JackRouter/JackRouter.cpp new file mode 100644 index 00000000..47727af7 --- /dev/null +++ b/windows/JackRouter/JackRouter.cpp @@ -0,0 +1,840 @@ +/* +Copyright (C) 2006 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. + +*/ + +#ifdef WIN32 +#pragma warning (disable : 4786) +#endif + +#include +#include +#include +#include +#include "JackRouter.h" +#include "profport.h" + +/* + + 08/07/2007 SL : USe jack_client_open instead of jack_client_new (automatic client renaming). + 09/08/2007 SL : Add JackRouter.ini parameter file. + 09/20/2007 SL : Better error report in DllRegisterServer (for Vista). + 09/27/2007 SL : Add AUDO_CONNECT property in JackRouter.ini file. + 10/10/2007 SL : Use ASIOSTInt32LSB instead of ASIOSTInt16LSB. + + */ + +//------------------------------------------------------------------------------------------ +// extern +void getNanoSeconds(ASIOTimeStamp *time); + +// local +double AsioSamples2double (ASIOSamples* samples); + +static const double twoRaisedTo32 = 4294967296.; +static const double twoRaisedTo32Reciprocal = 1. / twoRaisedTo32; + +//------------------------------------------------------------------------------------------ +// on windows, we do the COM stuff. + +#if WINDOWS +#include "windows.h" +#include "mmsystem.h" +#include "psapi.h" + +using namespace std; + +// class id. +// {838FE50A-C1AB-4b77-B9B6-0A40788B53F3} +CLSID IID_ASIO_DRIVER = { 0x838fe50a, 0xc1ab, 0x4b77, { 0xb9, 0xb6, 0xa, 0x40, 0x78, 0x8b, 0x53, 0xf3 } }; + + +CFactoryTemplate g_Templates[1] = { + {L"ASIOJACK", &IID_ASIO_DRIVER, JackRouter::CreateInstance} +}; +int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]); + +CUnknown* JackRouter::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr) +{ + return (CUnknown*)new JackRouter(pUnk,phr); +}; + +STDMETHODIMP JackRouter::NonDelegatingQueryInterface(REFIID riid, void ** ppv) +{ + if (riid == IID_ASIO_DRIVER) { + return GetInterface(this, ppv); + } + return CUnknown::NonDelegatingQueryInterface(riid, ppv); +} + +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Register ASIO Driver +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +extern LONG RegisterAsioDriver(CLSID,char *,char *,char *,char *); +extern LONG UnregisterAsioDriver(CLSID,char *,char *); + +// +// Server registration, called on REGSVR32.EXE "the dllname.dll" +// +HRESULT _stdcall DllRegisterServer() +{ + LONG rc; + char errstr[128]; + + rc = RegisterAsioDriver (IID_ASIO_DRIVER,"JackRouter.dll","JackRouter","JackRouter","Apartment"); + + if (rc) { + memset(errstr,0,128); + sprintf(errstr,"Register Server failed ! (%d)",rc); + MessageBox(0,(LPCTSTR)errstr,(LPCTSTR)"JackRouter",MB_OK); + return -1; + } + + return S_OK; +} + +// +// Server unregistration +// +HRESULT _stdcall DllUnregisterServer() +{ + LONG rc; + char errstr[128]; + + rc = UnregisterAsioDriver (IID_ASIO_DRIVER,"JackRouter.dll","JackRouter"); + + if (rc) { + memset(errstr,0,128); + sprintf(errstr,"Unregister Server failed ! (%d)",rc); + MessageBox(0,(LPCTSTR)errstr,(LPCTSTR)"JackRouter",MB_OK); + return -1; + } + + return S_OK; +} + +// Globals + +list > JackRouter::fConnections; +bool JackRouter::fFirstActivate = true; + +//------------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------------------ +JackRouter::JackRouter (LPUNKNOWN pUnk, HRESULT *phr) + : CUnknown("ASIOJACK", pUnk, phr) + +//------------------------------------------------------------------------------------------ + +#else + +// when not on windows, we derive from AsioDriver +JackRouter::JackRouter() : AsioDriver() + +#endif +{ + long i; + + fSamplePosition = 0; + fActive = false; + fStarted = false; + fTimeInfoMode = false; + fTcRead = false; + fClient = NULL; + fAutoConnectIn = true; + fAutoConnectOut = true; + + for (i = 0; i < kNumInputs; i++) { + fInputBuffers[i] = 0; + fInputPorts[i] = 0; + fInMap[i] = 0; + } + for (i = 0; i < kNumOutputs; i++) { + fOutputBuffers[i] = 0; + fOutputPorts[i] = 0; + fOutMap[i] = 0; + } + fCallbacks = 0; + fActiveInputs = fActiveOutputs = 0; + fToggle = 0; + fBufferSize = 512; + fSampleRate = 44100; + printf("Constructor\n"); + + // Use "jackrouter.ini" parameters if available + HMODULE handle = LoadLibrary("JackRouter.dll"); + + if (handle) { + + // Get JackRouter.dll path + char dllName[512]; + string confPath; + DWORD res = GetModuleFileName(handle, dllName, 512); + + // Compute .ini file path + string fullPath = dllName; + int lastPos = fullPath.find_last_of(PATH_SEP); + string dllFolder = fullPath.substr(0, lastPos); + confPath = dllFolder + PATH_SEP + "JackRouter.ini"; + + // Get parameters + kNumInputs = get_private_profile_int("IO", "input", 2, confPath.c_str()); + kNumOutputs = get_private_profile_int("IO", "output", 2, confPath.c_str()); + + fAutoConnectIn = get_private_profile_int("AUTO_CONNECT", "input", 1, confPath.c_str()); + fAutoConnectOut = get_private_profile_int("AUTO_CONNECT", "output", 1, confPath.c_str()); + + FreeLibrary(handle); + + } else { + printf("LoadLibrary error\n"); + } +} + +//------------------------------------------------------------------------------------------ +JackRouter::~JackRouter() +{ + stop (); + disposeBuffers (); + printf("Destructor\n"); + jack_client_close(fClient); +} + +//------------------------------------------------------------------------------------------ +#include +#include +#include +#include "psapi.h" + +static bool GetEXEName(DWORD dwProcessID, char* name) +{ + DWORD aProcesses [1024], cbNeeded, cProcesses; + unsigned int i; + + // Enumerate all processes + if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) + return false; + + // Calculate how many process identifiers were returned. + cProcesses = cbNeeded / sizeof(DWORD); + + TCHAR szEXEName[MAX_PATH]; + // Loop through all process to find the one that matches + // the one we are looking for + + for (i = 0; i < cProcesses; i++) { + if (aProcesses [i] == dwProcessID) { + // Get a handle to the process + HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | + PROCESS_VM_READ, FALSE, dwProcessID); + + // Get the process name + if (NULL != hProcess) { + HMODULE hMod; + DWORD cbNeeded; + + if(EnumProcessModules(hProcess, &hMod, + sizeof(hMod), &cbNeeded)) { + //Get the name of the exe file + GetModuleBaseName(hProcess, hMod, szEXEName, + sizeof(szEXEName)/sizeof(TCHAR)); + int len = strlen((char*)szEXEName) - 4; // remove ".exe" + strncpy(name, (char*)szEXEName, len); + name[len] = '\0'; + return true; + } + } + } + } + + return false; +} + + //------------------------------------------------------------------------------------------ +static inline float ClipFloat(float sample) +{ + return (sample < -1.0f) ? -1.0f : (sample > 1.0f) ? 1.0f : sample; +} + +//------------------------------------------------------------------------------------------ +void JackRouter::shutdown(void* arg) +{ + JackRouter* driver = (JackRouter*)arg; + /* + //exit(1); + char errstr[128]; + + memset(errstr,0,128); + sprintf(errstr,"JACK server has quitted"); + MessageBox(0,(LPCTSTR)errstr,(LPCTSTR)"JackRouter",MB_OK); + */ +} + +//------------------------------------------------------------------------------------------ +int JackRouter::process(jack_nframes_t nframes, void* arg) +{ + JackRouter* driver = (JackRouter*)arg; + int i,j; + int pos = (driver->fToggle) ? 0 : driver->fBufferSize ; + + for (i = 0; i < driver->fActiveInputs; i++) { + +#ifdef LONG_SAMPLE + float* buffer = (float*)jack_port_get_buffer(driver->fInputPorts[i], nframes); + long* in = driver->fInputBuffers[i] + pos; + for (j = 0; j < nframes; j++) { + in[j] = buffer[j] * float(0x7fffffff); + } +#else + memcpy(driver->fInputBuffers[i] + pos, + jack_port_get_buffer(driver->fInputPorts[i], nframes), + nframes * sizeof(float)); +#endif + + } + + driver->bufferSwitch(); + + for (i = 0; i < driver->fActiveOutputs; i++) { + +#ifdef LONG_SAMPLE + float* buffer = (float*)jack_port_get_buffer(driver->fOutputPorts[i], nframes); + long* out = driver->fOutputBuffers[i] + pos; + float gain = 1.f/float(0x7fffffff); + for (j = 0; j < nframes; j++) { + buffer[j] = out[j] * gain; + } +#else + memcpy(jack_port_get_buffer(driver->fOutputPorts[i], nframes), + driver->fOutputBuffers[i] + pos, + nframes * sizeof(float)); +#endif + } + + return 0; +} + +//------------------------------------------------------------------------------------------ +void JackRouter::getDriverName(char *name) +{ + strcpy (name, "JackRouter"); +} + +//------------------------------------------------------------------------------------------ +long JackRouter::getDriverVersion() +{ + return 0x00000001L; +} + +//------------------------------------------------------------------------------------------ +void JackRouter::getErrorMessage(char *string) +{ + strcpy (string, fErrorMessage); +} + +//------------------------------------------------------------------------------------------ +ASIOBool JackRouter::init(void* sysRef) +{ + char name[MAX_PATH]; + sysRef = sysRef; + + if (fActive) + return true; + + HANDLE win = (HANDLE)sysRef; + int my_pid = _getpid(); + + if (!GetEXEName(my_pid, name)) { // If getting the .exe name fails, takes a generic one. + _snprintf(name, sizeof(name) - 1, "JackRouter_%d", my_pid); + } + + if (fClient) { + printf("Error: jack client still present...\n"); + return true; + } + + fClient = jack_client_open(name, JackNullOption, NULL); + if (fClient == NULL) { + strcpy (fErrorMessage, "Open error: is jack server running?"); + printf("Open error: is jack server running?\n"); + return false; + } + + fBufferSize = jack_get_buffer_size(fClient); + fSampleRate = jack_get_sample_rate(fClient); + jack_set_process_callback(fClient, process, this); + jack_on_shutdown(fClient, shutdown, this); + + fInputLatency = fBufferSize; // typically + fOutputLatency = fBufferSize * 2; + fMilliSeconds = (long)((double)(fBufferSize * 1000) / fSampleRate); + + // Typically fBufferSize * 2; try to get 1 by offering direct buffer + // access, and using asioPostOutput for lower latency + + printf("Init ASIO Jack\n"); + fActive = true; + return true; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::start() +{ + if (fCallbacks) { + fSamplePosition = 0; + fTheSystemTime.lo = fTheSystemTime.hi = 0; + fToggle = 0; + fStarted = true; + printf("Start ASIO Jack\n"); + + if (jack_activate(fClient) == 0) { + + if (fFirstActivate) { + AutoConnect(); + fFirstActivate = false; + } else { + RestoreConnections(); + } + + return ASE_OK; + + } else { + return ASE_NotPresent; + } + } + + return ASE_NotPresent; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::stop() +{ + fStarted = false; + printf("Stop ASIO Jack\n"); + SaveConnections(); + jack_deactivate(fClient); + return ASE_OK; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::getChannels(long *numInputChannels, long *numOutputChannels) +{ + *numInputChannels = kNumInputs; + *numOutputChannels = kNumOutputs; + return ASE_OK; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::getLatencies(long *_inputLatency, long *_outputLatency) +{ + *_inputLatency = fInputLatency; + *_outputLatency = fOutputLatency; + return ASE_OK; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::getBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity) +{ + *minSize = *maxSize = *preferredSize = fBufferSize; // allow this size only + *granularity = 0; + return ASE_OK; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::canSampleRate(ASIOSampleRate sampleRate) +{ + return (sampleRate == fSampleRate) ? ASE_OK : ASE_NoClock; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::getSampleRate(ASIOSampleRate *sampleRate) +{ + *sampleRate = fSampleRate; + return ASE_OK; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::setSampleRate(ASIOSampleRate sampleRate) +{ + return (sampleRate == fSampleRate) ? ASE_OK : ASE_NoClock; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::getClockSources(ASIOClockSource *clocks, long *numSources) +{ + // Internal + if (clocks && numSources) { + clocks->index = 0; + clocks->associatedChannel = -1; + clocks->associatedGroup = -1; + clocks->isCurrentSource = ASIOTrue; + strcpy(clocks->name, "Internal"); + *numSources = 1; + return ASE_OK; + } else { + return ASE_InvalidParameter; + } +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::setClockSource(long index) +{ + if (!index) { + fAsioTime.timeInfo.flags |= kClockSourceChanged; + return ASE_OK; + } else { + return ASE_NotPresent; + } +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) +{ + tStamp->lo = fTheSystemTime.lo; + tStamp->hi = fTheSystemTime.hi; + + if (fSamplePosition >= twoRaisedTo32) { + sPos->hi = (unsigned long)(fSamplePosition * twoRaisedTo32Reciprocal); + sPos->lo = (unsigned long)(fSamplePosition - (sPos->hi * twoRaisedTo32)); + } else { + sPos->hi = 0; + sPos->lo = (unsigned long)fSamplePosition; + } + return ASE_OK; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::getChannelInfo(ASIOChannelInfo *info) +{ + if (info->channel < 0 || (info->isInput ? info->channel >= kNumInputs : info->channel >= kNumOutputs)) + return ASE_InvalidParameter; +#ifdef LONG_SAMPLE + info->type = ASIOSTInt32LSB; +#else + info->type = ASIOSTFloat32LSB; +#endif + + info->channelGroup = 0; + info->isActive = ASIOFalse; + long i; + char buf[32]; + + if (info->isInput) { + for (i = 0; i < fActiveInputs; i++) { + if (fInMap[i] == info->channel) { + info->isActive = ASIOTrue; + //_snprintf(buf, sizeof(buf) - 1, "Jack::In%d ", info->channel); + //strcpy(info->name, buf); + //strcpy(info->name, jack_port_name(fInputPorts[i])); + break; + } + } + _snprintf(buf, sizeof(buf) - 1, "In%d ", info->channel); + strcpy(info->name, buf); + } else { + for (i = 0; i < fActiveOutputs; i++) { + if (fOutMap[i] == info->channel) { //NOT USED !! + info->isActive = ASIOTrue; + //_snprintf(buf, sizeof(buf) - 1, "Jack::Out%d ", info->channel); + //strcpy(info->name, buf); + //strcpy(info->name, jack_port_name(fOutputPorts[i])); + break; + } + } + _snprintf(buf, sizeof(buf) - 1, "Out%d ", info->channel); + strcpy(info->name, buf); + } + return ASE_OK; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, + long bufferSize, ASIOCallbacks *callbacks) +{ + ASIOBufferInfo *info = bufferInfos; + long i; + bool notEnoughMem = false; + char buf[256]; + fActiveInputs = 0; + fActiveOutputs = 0; + + for (i = 0; i < numChannels; i++, info++) { + if (info->isInput) { + if (info->channelNum < 0 || info->channelNum >= kNumInputs) + goto error; + fInMap[fActiveInputs] = info->channelNum; + #ifdef LONG_SAMPLE + fInputBuffers[fActiveInputs] = new long[fBufferSize * 2]; // double buffer + #else + fInputBuffers[fActiveInputs] = new float[fBufferSize * 2]; // double buffer + #endif + if (fInputBuffers[fActiveInputs]) { + info->buffers[0] = fInputBuffers[fActiveInputs]; + info->buffers[1] = fInputBuffers[fActiveInputs] + fBufferSize; + } else { + info->buffers[0] = info->buffers[1] = 0; + notEnoughMem = true; + } + + _snprintf(buf, sizeof(buf) - 1, "in%d", fActiveInputs + 1); + fInputPorts[fActiveInputs] + = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput,0); + if (fInputPorts[fActiveInputs] == NULL) + goto error; + + fActiveInputs++; + if (fActiveInputs > kNumInputs) { +error: + disposeBuffers(); + return ASE_InvalidParameter; + } + } else { // output + if (info->channelNum < 0 || info->channelNum >= kNumOutputs) + goto error; + fOutMap[fActiveOutputs] = info->channelNum; + + #ifdef LONG_SAMPLE + fOutputBuffers[fActiveOutputs] = new long[fBufferSize * 2]; // double buffer + #else + fOutputBuffers[fActiveOutputs] = new float[fBufferSize * 2]; // double buffer + #endif + + if (fOutputBuffers[fActiveOutputs]) { + info->buffers[0] = fOutputBuffers[fActiveOutputs]; + info->buffers[1] = fOutputBuffers[fActiveOutputs] + fBufferSize; + } else { + info->buffers[0] = info->buffers[1] = 0; + notEnoughMem = true; + } + + _snprintf(buf, sizeof(buf) - 1, "out%d", fActiveOutputs + 1); + fOutputPorts[fActiveOutputs] + = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput,0); + if (fOutputPorts[fActiveOutputs] == NULL) + goto error; + + fActiveOutputs++; + if (fActiveOutputs > kNumOutputs) { + fActiveOutputs--; + disposeBuffers(); + return ASE_InvalidParameter; + } + } + } + + if (notEnoughMem) { + disposeBuffers(); + return ASE_NoMemory; + } + + this->fCallbacks = callbacks; + if (callbacks->asioMessage (kAsioSupportsTimeInfo, 0, 0, 0)) { + fTimeInfoMode = true; + fAsioTime.timeInfo.speed = 1.; + fAsioTime.timeInfo.systemTime.hi = fAsioTime.timeInfo.systemTime.lo = 0; + fAsioTime.timeInfo.samplePosition.hi = fAsioTime.timeInfo.samplePosition.lo = 0; + fAsioTime.timeInfo.sampleRate = fSampleRate; + fAsioTime.timeInfo.flags = kSystemTimeValid | kSamplePositionValid | kSampleRateValid; + + fAsioTime.timeCode.speed = 1.; + fAsioTime.timeCode.timeCodeSamples.lo = fAsioTime.timeCode.timeCodeSamples.hi = 0; + fAsioTime.timeCode.flags = kTcValid | kTcRunning ; + } else { + fTimeInfoMode = false; + } + + return ASE_OK; +} + +//--------------------------------------------------------------------------------------------- +ASIOError JackRouter::disposeBuffers() +{ + long i; + + fCallbacks = 0; + stop(); + + for (i = 0; i < fActiveInputs; i++) { + delete[] fInputBuffers[i]; + jack_port_unregister(fClient, fInputPorts[i]); + } + fActiveInputs = 0; + + for (i = 0; i < fActiveOutputs; i++) { + delete[] fOutputBuffers[i]; + jack_port_unregister(fClient, fOutputPorts[i]); + } + fActiveOutputs = 0; + + return ASE_OK; +} + +//--------------------------------------------------------------------------------------------- +ASIOError JackRouter::controlPanel() +{ + return ASE_NotPresent; +} + +//--------------------------------------------------------------------------------------------- +ASIOError JackRouter::future(long selector, void* opt) // !!! check properties +{ + ASIOTransportParameters* tp = (ASIOTransportParameters*)opt; + switch (selector) + { + case kAsioEnableTimeCodeRead: fTcRead = true; return ASE_SUCCESS; + case kAsioDisableTimeCodeRead: fTcRead = false; return ASE_SUCCESS; + case kAsioSetInputMonitor: return ASE_SUCCESS; // for testing!!! + case kAsioCanInputMonitor: return ASE_SUCCESS; // for testing!!! + case kAsioCanTimeInfo: return ASE_SUCCESS; + case kAsioCanTimeCode: return ASE_SUCCESS; + } + return ASE_NotPresent; +} + +//-------------------------------------------------------------------------------------------------------- +// private methods +//-------------------------------------------------------------------------------------------------------- + +//--------------------------------------------------------------------------------------------- +void JackRouter::bufferSwitch() +{ + if (fStarted && fCallbacks) { + getNanoSeconds(&fTheSystemTime); // latch system time + fSamplePosition += fBufferSize; + if (fTimeInfoMode) { + bufferSwitchX (); + } else { + fCallbacks->bufferSwitch (fToggle, ASIOFalse); + } + fToggle = fToggle ? 0 : 1; + } +} + +//--------------------------------------------------------------------------------------------- +// asio2 buffer switch +void JackRouter::bufferSwitchX () +{ + getSamplePosition (&fAsioTime.timeInfo.samplePosition, &fAsioTime.timeInfo.systemTime); + long offset = fToggle ? fBufferSize : 0; + if (fTcRead) { + // Create a fake time code, which is 10 minutes ahead of the card's sample position + // Please note that for simplicity here time code will wrap after 32 bit are reached + fAsioTime.timeCode.timeCodeSamples.lo = fAsioTime.timeInfo.samplePosition.lo + 600.0 * fSampleRate; + fAsioTime.timeCode.timeCodeSamples.hi = 0; + } + fCallbacks->bufferSwitchTimeInfo (&fAsioTime, fToggle, ASIOFalse); + fAsioTime.timeInfo.flags &= ~(kSampleRateChanged | kClockSourceChanged); +} + +//--------------------------------------------------------------------------------------------- +ASIOError JackRouter::outputReady() +{ + return ASE_NotPresent; +} + +//--------------------------------------------------------------------------------------------- +double AsioSamples2double(ASIOSamples* samples) +{ + double a = (double)(samples->lo); + if (samples->hi) + a += (double)(samples->hi) * twoRaisedTo32; + return a; +} + +//--------------------------------------------------------------------------------------------- +void getNanoSeconds(ASIOTimeStamp* ts) +{ + double nanoSeconds = (double)((unsigned long)timeGetTime ()) * 1000000.; + ts->hi = (unsigned long)(nanoSeconds / twoRaisedTo32); + ts->lo = (unsigned long)(nanoSeconds - (ts->hi * twoRaisedTo32)); +} + +//------------------------------------------------------------------------ +void JackRouter::SaveConnections() +{ + const char** connections; + int i; + + for (i = 0; i < fActiveInputs; ++i) { + if (fInputPorts[i] && (connections = jack_port_get_connections(fInputPorts[i])) != 0) { + for (int j = 0; connections[j]; j++) { + fConnections.push_back(make_pair(connections[j], jack_port_name(fInputPorts[i]))); + } + jack_free(connections); + } + } + + for (i = 0; i < fActiveOutputs; ++i) { + if (fOutputPorts[i] && (connections = jack_port_get_connections(fOutputPorts[i])) != 0) { + for (int j = 0; connections[j]; j++) { + fConnections.push_back(make_pair(jack_port_name(fOutputPorts[i]), connections[j])); + } + jack_free(connections); + } + } +} + +//------------------------------------------------------------------------ +void JackRouter::RestoreConnections() +{ + list >::const_iterator it; + + for (it = fConnections.begin(); it != fConnections.end(); it++) { + pair connection = *it; + jack_connect(fClient, connection.first.c_str(), connection.second.c_str()); + } + + fConnections.clear(); +} + +//------------------------------------------------------------------------------------------ +void JackRouter::AutoConnect() +{ + const char** ports; + + if ((ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput)) == NULL) { + printf("Cannot find any physical capture ports\n"); + } else { + if (fAutoConnectIn) { + for (int i = 0; i < fActiveInputs; i++) { + if (!ports[i]) { + printf("source port is null i = %ld\n", i); + break; + } else if (jack_connect(fClient, ports[i], jack_port_name(fInputPorts[i])) != 0) { + printf("Cannot connect input ports\n"); + } + } + } + jack_free(ports); + } + + if ((ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput)) == NULL) { + printf("Cannot find any physical playback ports"); + } else { + if (fAutoConnectOut) { + for (int i = 0; i < fActiveOutputs; i++) { + if (!ports[i]){ + printf("destination port is null i = %ld\n", i); + break; + } else if (jack_connect(fClient, jack_port_name(fOutputPorts[i]), ports[i]) != 0) { + printf("Cannot connect output ports\n"); + } + } + } + jack_free(ports); + } +} + diff --git a/windows/JackRouter/JackRouter.def b/windows/JackRouter/JackRouter.def new file mode 100644 index 00000000..1316d71f --- /dev/null +++ b/windows/JackRouter/JackRouter.def @@ -0,0 +1,9 @@ +LIBRARY JackRouter +DESCRIPTION 'ASIO Jack Driver' +PROTMODE +EXPORTS + DllMain + DllGetClassObject + DllCanUnloadNow + DllRegisterServer + DllUnregisterServer diff --git a/windows/JackRouter/JackRouter.dsp b/windows/JackRouter/JackRouter.dsp new file mode 100644 index 00000000..c92ddf99 --- /dev/null +++ b/windows/JackRouter/JackRouter.dsp @@ -0,0 +1,163 @@ +# Microsoft Developer Studio Project File - Name="JackRouter" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=JackRouter - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "JackRouter.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "JackRouter.mak" CFG="JackRouter - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "JackRouter - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "JackRouter - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "JackRouter - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\..\..\ASIOSDK2\common" /I "..\..\common" /I "..\..\common\jack" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /dll /machine:I386 + +!ELSEIF "$(CFG)" == "JackRouter - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /G5 /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\..\ASIOSDK2\common" /I "..\..\common" /I "..\..\common\jack" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"Debug/JackRouter_debug.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "JackRouter - Win32 Release" +# Name "JackRouter - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\..\..\ASIOSDK2\common\combase.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\ASIOSDK2\common\dllentry.cpp +# End Source File +# Begin Source File + +SOURCE=.\JackRouter.cpp +# End Source File +# Begin Source File + +SOURCE=.\JackRouter.def +# End Source File +# Begin Source File + +SOURCE=.\profport.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\ASIOSDK2\common\register.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\common\asio.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\Asiodrvr.h +# End Source File +# Begin Source File + +SOURCE=..\asiosmpl.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\common\asiosys.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\common\combase.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\common\iasiodrv.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\Psapi.Lib +# End Source File +# Begin Source File + +SOURCE=..\Release\bin\libjack.lib +# End Source File +# End Target +# End Project diff --git a/windows/JackRouter/JackRouter.dsw b/windows/JackRouter/JackRouter.dsw new file mode 100644 index 00000000..e26ab1ee --- /dev/null +++ b/windows/JackRouter/JackRouter.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "JackRouter"=".\JackRouter.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/windows/JackRouter/JackRouter.h b/windows/JackRouter/JackRouter.h new file mode 100644 index 00000000..bf5d44c8 --- /dev/null +++ b/windows/JackRouter/JackRouter.h @@ -0,0 +1,174 @@ +/* +Copyright (C) 2006 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 _asiosmpl_ +#define _asiosmpl_ + +#include "asiosys.h" + + +// Globals +static int kBlockFrames = 256; +static int kNumInputs = 4; +static int kNumOutputs = 4; + + +#if WINDOWS + +#include "jack.h" +#include "rpc.h" +#include "rpcndr.h" +#ifndef COM_NO_WINDOWS_H +#include +#include "ole2.h" + +#endif + +#include "combase.h" +#include "iasiodrv.h" + +#define MAX_PORTS 32 + +#define LONG_SAMPLE 1 + +#define PATH_SEP "\\" + +#include +#include + +class JackRouter : public IASIO, public CUnknown +{ +public: + JackRouter(LPUNKNOWN pUnk, HRESULT *phr); + ~JackRouter(); + + DECLARE_IUNKNOWN + //STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { \ + // return GetOwner()->QueryInterface(riid,ppv); \ + //}; \ + //STDMETHODIMP_(ULONG) AddRef() { \ + // return GetOwner()->AddRef(); \ + //}; \ + //STDMETHODIMP_(ULONG) Release() { \ + // return GetOwner()->Release(); \ + //}; + + // Factory method + static CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr); + // IUnknown + virtual HRESULT STDMETHODCALLTYPE NonDelegatingQueryInterface(REFIID riid,void **ppvObject); +#else + +#include "asiodrvr.h" + + +//--------------------------------------------------------------------------------------------- +class JackRouter : public AsioDriver +{ +public: + JackRouter(); + ~JackRouter(); +#endif + + static int process(jack_nframes_t nframes, void* arg); + static void shutdown(void* arg); + + ASIOBool init(void* sysRef); + void getDriverName(char *name); // max 32 bytes incl. terminating zero + long getDriverVersion(); + void getErrorMessage(char *string); // max 128 bytes incl. + + ASIOError start(); + ASIOError stop(); + + ASIOError getChannels(long *numInputChannels, long *numOutputChannels); + ASIOError getLatencies(long *inputLatency, long *outputLatency); + ASIOError getBufferSize(long *minSize, long *maxSize, + long *preferredSize, long *granularity); + + ASIOError canSampleRate(ASIOSampleRate sampleRate); + ASIOError getSampleRate(ASIOSampleRate *sampleRate); + ASIOError setSampleRate(ASIOSampleRate sampleRate); + ASIOError getClockSources(ASIOClockSource *clocks, long *numSources); + ASIOError setClockSource(long index); + + ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp); + ASIOError getChannelInfo(ASIOChannelInfo *info); + + ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, + long bufferSize, ASIOCallbacks *callbacks); + ASIOError disposeBuffers(); + + ASIOError controlPanel(); + ASIOError future(long selector, void *opt); + ASIOError outputReady(); + + void bufferSwitch(); + long getMilliSeconds() {return fMilliSeconds;} + + static bool fFirstActivate; + static std::list > fConnections; // Connections list + +private: + + void bufferSwitchX(); + + double fSamplePosition; + ASIOCallbacks* fCallbacks; + ASIOTime fAsioTime; + ASIOTimeStamp fTheSystemTime; + +#ifdef LONG_SAMPLE + long* fInputBuffers[MAX_PORTS * 2]; + long* fOutputBuffers[MAX_PORTS * 2]; +#else + float* fInputBuffers[MAX_PORTS * 2]; + float* fOutputBuffers[MAX_PORTS * 2]; +#endif + long fInMap[MAX_PORTS]; + long fOutMap[MAX_PORTS]; + + long fInputLatency; + long fOutputLatency; + long fActiveInputs; + long fActiveOutputs; + long fToggle; + long fMilliSeconds; + bool fActive, fStarted; + bool fTimeInfoMode, fTcRead; + char fErrorMessage[128]; + + bool fAutoConnectIn; + bool fAutoConnectOut; + + // Jack part + jack_client_t* fClient; + jack_port_t* fInputPorts[MAX_PORTS]; + jack_port_t* fOutputPorts[MAX_PORTS]; + long fBufferSize; + ASIOSampleRate fSampleRate; + + void AutoConnect(); + void SaveConnections(); + void RestoreConnections(); + +}; + +#endif + diff --git a/windows/JackRouter/Psapi.Lib b/windows/JackRouter/Psapi.Lib new file mode 100644 index 0000000000000000000000000000000000000000..ae896911ef3f262e1df96418d91b910c8be19f6f GIT binary patch literal 7230 zcmcIp%}*Og6n{2J0Ed7vV7}VQQ6n|ExIot6N^NBlNU>rZ7f5_bWn6m$Re?yg1jyd#@L&Z7gD5soqB7O6@yR)-vjPXj3*?k}Ln~yi|y)jq6FE&cM zKZd@IIiLBth2&z=NX{pm{5k$PpI9>3>vjkLZUPJ)0}Oux2*&}&3{EexMT(+~(BvAY zSJ)y=p)REt*domwG8%mXKxpGj;bjjh7U>gMf@bZ+b3Mj^MkoJ&KYkiDPDxW(`% zl{4wq+WqX^!pid2G89&82i07oUNW1_^?LbW&upgV7qOd4b-&;xwAm2#1&uoA|75mU zueXX#Gh3{h%eLMJ*c3L#cPQgpp9@QJwVyjZG=|-uF z5l<|(S*bhx!E*o{t95zfyd}hTwtdz`^M&;0KsD9&?A&Q-8^C0PPzA7F<98NoXrlQ!}*2l}< zsp4VpgD>ovO1f5QRf>C+Ba^$#oq8kR%okgwU2Ff_DB&3L&D*=h+K%I(y4c9bnGNd7 zwUSA_GAUe4FQYM_xMPwrH}ff}?dCf;%O0APPmowBN>_Q;JZ9Ke+*`%NURiOSJyq#E z!z5*fnZ*=yJOuD*7$6=7Fvb90A{}EqUz-GYg%qCxc!6{{1Mp-N;4K<`oB$}J&IkOC zi~~GJ3L@_a=>f{$qi%E>;0@-Hhe*%x{R9cq84N)freO*$z(p8^2#mov48sUqf_@l) zK?uPl%)l&MhA2$H6$n7EW1BwA5bhA8Kg{lpc5tYZP>ws@*w|L)@IL*x(K;d9XhkRv z6~;C6A`hXo)Wt%yak5bxQzT*2jA@HZI<}%M#v?M6?8Xu(7P=(jKCIY}&a>sTbwW99 zE?jpeCG64}J=#PYU4C(wBJC;_QG2-E&MHdmyRT-FoQO(Zu||znZg;eR_`;~s(~fW3 zetVeGsj&5Cz2oBARmASI{qj{&dU5)uZ~A7AB|F!-uZK`;DaI^ZS+TXmT5HvU!>A;NS6|02EPj6Q5rF!!44Epj&I z63jbD?*s$e6vSTRbq2H0Amt9qNnMAra6j@$Z{+Dm`=g49F)q2nT> z1FeVPW!3T6JcJY&^dTPdH-8rm@sM8Z{AqUdOB{sfEjQHhsx67153F3*6-uv>0LqD4OopX#vW&Q=Ty+smJ>Q@knjWelW4u9}>ZeTjzk)=fWa2 z&DpUMH}&(niu1Z4v0QbM1=#V<`K{zd1(6kB7MOfH*Kv4j;kq>yP2sE;$m2>(vp3`9mqVQOL@#tojKA0mOn7y25*nz2Bk-C|uPo^B@nC^R* z1t{OnA?8K|p4VMYf}L;79rMBMItKap(YO=W`6Ejgb2XOqS)0^z6CBfVmF)s+abAyg e1F@n6%m04d1#&|CLr;kc section - the name of the section to search for +* entry - the name of the entry to find the value of +* def - the default value in the event of a failed read +* file_name - the name of the .ini file to read from +* Returns: the value located at entry +***************************************************************************/ +int get_private_profile_int(char *section, + char *entry, int def, char *file_name) +{ + FILE *fp = fopen(file_name,"r"); + char buff[MAX_LINE_LENGTH]; + + if( !fp ) return def; /* Return default value if file does not exist */ + if (!read_section (fp, section)) goto err; + if (!read_entry (fp, entry, buff, MAX_LINE_LENGTH)) goto err; + def = read_int_value (buff, def); +err: + fclose (fp); + return def; +} + +/************************************************************************** +* Function: get_private_profile_string() +* Arguments: section - the name of the section to search for +* entry - the name of the entry to find the value of +* def - default string in the event of a failed read +* buffer - a pointer to the buffer to copy into +* buffer_len - the max number of characters to copy +* file_name - the name of the .ini file to read from +* Returns: the number of characters copied into the supplied buffer +***************************************************************************/ + +int get_private_profile_string(char *section, char *entry, char *def, + char *buffer, int buffer_len, char *file_name) +{ + FILE *fp = fopen (file_name,"r"); + char buff[MAX_LINE_LENGTH]; + char *val; + + if( !fp ) goto err; /* Return default value if file does not exist */ + if (!read_section (fp, section)) goto err; + if (!read_entry (fp, entry, buff, MAX_LINE_LENGTH)) goto err; + val = read_value (buff); + if(val) def = val; + +err: + if (fp) fclose (fp); + if (def) { + strncpy (buffer, def, buffer_len - 1); + buffer[buffer_len] = '\0'; + } + else buffer[buffer_len] = '\0'; + return strlen (buffer); +} + + +/*************************************************************************** + * Function: write_private_profile_string() + * Arguments: section - the name of the section to search for + * entry - the name of the entry to find the value of + * buffer - pointer to the buffer that holds the string + * file_name - the name of the .ini file to read from + * Returns: TRUE if successful, otherwise FALSE + ***************************************************************************/ +int write_private_profile_string(char *section, + char *entry, char *buffer, char *file_name) + +{ + char * content = read_file(file_name); + FILE * fd = fopen(file_name,"w"); + char t_section[MAX_LINE_LENGTH], *ptr; + int ret = 0; + + if (!fd) goto end; + if (!content) { + fprintf (fd, "[%s]\n%s = %s\n", section, entry, buffer); + ret = 1; + goto end; + } + sprintf(t_section,"[%s]",section); /* Format the section name */ + ptr = str_search (content, t_section, 0); /* look for the section start */ + if (!ptr) { + /* no such section: add the new section at end of file */ + fprintf (fd, "%s\n[%s]\n%s = %s\n", content, section, entry, buffer); + } + else { + char * eptr; + eptr = str_search (ptr, entry, '['); + if (!eptr) { + /* no such entry: looks for next section */ + eptr = str_search (++ptr, "[", 0); + if (!eptr) { + /* section is the last one */ + fprintf (fd, "%s\n%s = %s\n", content, entry, buffer); + } + else { + while (*ptr && (*ptr != '\n')) ptr++; + *ptr = 0; + fprintf (fd, "%s\n%s = %s", content, entry, buffer); + *ptr = '\n'; + fprintf (fd, "%s", ptr); + } + } + else { + *eptr++ = 0; + fprintf (fd, "%s%s = %s", content, entry, buffer); + while (*eptr && (*eptr != '\n')) eptr++; + if (eptr) fprintf (fd, "%s", eptr); + } + } + ret = 1; + +end: + if (content) free(content); + if (fd) fclose(fd); + return 0; +} + +/*************************************************************************** + * Function: write_private_profile_int() + * Arguments: section - the name of the section to search for + * entry - the name of the entry to find the value of + * buffer - the value to be written + * file_name - the name of the .ini file to read from + * Returns: TRUE if successful, otherwise FALSE + ***************************************************************************/ +int write_private_profile_int(char *section, + char *entry, int val, char *file_name) +{ + char buffer [64]; + sprintf(buffer, "%d", val); + return write_private_profile_string (section,entry, buffer, file_name); +} + +#endif // #ifndef WIN32 + + +/************************************************************************** +* Function: get_private_profile_float() +* Arguments: section - the name of the section to search for +* entry - the name of the entry to find the value of +* def - the default value in the event of a failed read +* file_name - the name of the .ini file to read from +* Returns: the value located at entry +* Warning: The float value to be read must not contain more than 100 digits. +* Author: CD, 15/11/2006. +***************************************************************************/ +#define maxFloatLen 100 +float get_private_profile_float (char * section, char * entry, float def, char * file_name) +{ + float result = def; + char buffer[ maxFloatLen ], *endptr; + + if ( get_private_profile_string(section, entry, "", buffer, maxFloatLen, file_name) > 0 ) + { + result = (float)strtod(buffer, &endptr); + if ((result==0) && (endptr==buffer)) + result = def; + } + return result; +} diff --git a/windows/JackRouter/profport.h b/windows/JackRouter/profport.h new file mode 100644 index 00000000..2f717177 --- /dev/null +++ b/windows/JackRouter/profport.h @@ -0,0 +1,37 @@ + +/****************************************************************************** + PORTABLE ROUTINES FOR WRITING PRIVATE PROFILE STRINGS -- by Joseph J. Graf + Header file containing prototypes and compile-time configuration. + + [09/05/02] D. Fober - Windows definitions added +******************************************************************************/ + +#ifndef __profport__ +#define __profport__ + +#define MAX_LINE_LENGTH 1024 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef WIN32 +#include "Windows.h" +#define get_private_profile_int GetPrivateProfileInt +#define get_private_profile_string GetPrivateProfileString +#define write_private_profile_string WritePrivateProfileString +#define write_private_profile_int WritePrivateProfileInt +#else +int get_private_profile_int (char * section, char * entry, int def, char * file_name); +int get_private_profile_string (char * section, char * entry, char * def, char * buffer, int buffer_len, char * file_name); +int write_private_profile_string (char * section, char * entry, char * buffer, char * file_name); +int write_private_profile_int (char * section, char * entry, int val, char * file_name); +#endif + +float get_private_profile_float (char * section, char * entry, float def, char * file_name); + +#ifdef __cplusplus +} +#endif + +#endif //__profport__ diff --git a/windows/JackRouter/psapi.dll b/windows/JackRouter/psapi.dll new file mode 100644 index 0000000000000000000000000000000000000000..ff4c964c7b2b195b22d99328130f5b97b0c1b05c GIT binary patch literal 23040 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 UC+cVDm!+;xe+vK0^S|@^cV|9)-2eap literal 0 HcmV?d00001 diff --git a/windows/JackRouter/psapi.h b/windows/JackRouter/psapi.h new file mode 100644 index 00000000..af72931e --- /dev/null +++ b/windows/JackRouter/psapi.h @@ -0,0 +1,95 @@ +/* + psapi.h - Include file for PSAPI.DLL APIs + + Written by Mumit Khan + + This file is part of a free library for the Win32 API. + + NOTE: This strictly does not belong in the Win32 API since it's + really part of Platform SDK. However,GDB needs it and we might + as well provide it here. + + This library 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. + +*/ +#ifndef _PSAPI_H +#define _PSAPI_H +#if __GNUC__ >=3 +#pragma GCC system_header +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef RC_INVOKED + +typedef struct _MODULEINFO { + LPVOID lpBaseOfDll; + DWORD SizeOfImage; + LPVOID EntryPoint; +} MODULEINFO,*LPMODULEINFO; + +typedef struct _PSAPI_WS_WATCH_INFORMATION { + LPVOID FaultingPc; + LPVOID FaultingVa; +} PSAPI_WS_WATCH_INFORMATION,*PPSAPI_WS_WATCH_INFORMATION; + +typedef struct _PROCESS_MEMORY_COUNTERS { + DWORD cb; + DWORD PageFaultCount; + DWORD PeakWorkingSetSize; + DWORD WorkingSetSize; + DWORD QuotaPeakPagedPoolUsage; + DWORD QuotaPagedPoolUsage; + DWORD QuotaPeakNonPagedPoolUsage; + DWORD QuotaNonPagedPoolUsage; + DWORD PagefileUsage; + DWORD PeakPagefileUsage; +} PROCESS_MEMORY_COUNTERS,*PPROCESS_MEMORY_COUNTERS; + +/* Grouped by application,not in alphabetical order. */ +BOOL WINAPI EnumProcesses(DWORD *,DWORD,DWORD *); +BOOL WINAPI EnumProcessModules(HANDLE,HMODULE *,DWORD,LPDWORD); +DWORD WINAPI GetModuleBaseNameA(HANDLE,HMODULE,LPSTR,DWORD); +DWORD WINAPI GetModuleBaseNameW(HANDLE,HMODULE,LPWSTR,DWORD); +DWORD WINAPI GetModuleFileNameExA(HANDLE,HMODULE,LPSTR,DWORD); +DWORD WINAPI GetModuleFileNameExW(HANDLE,HMODULE,LPWSTR,DWORD); +BOOL WINAPI GetModuleInformation(HANDLE,HMODULE,LPMODULEINFO,DWORD); +BOOL WINAPI EmptyWorkingSet(HANDLE); +BOOL WINAPI QueryWorkingSet(HANDLE,PVOID,DWORD); +BOOL WINAPI InitializeProcessForWsWatch(HANDLE); +BOOL WINAPI GetWsChanges(HANDLE,PPSAPI_WS_WATCH_INFORMATION,DWORD); +DWORD WINAPI GetMappedFileNameW(HANDLE,LPVOID,LPWSTR,DWORD); +DWORD WINAPI GetMappedFileNameA(HANDLE,LPVOID,LPSTR,DWORD); +BOOL WINAPI EnumDeviceDrivers(LPVOID *,DWORD,LPDWORD); +DWORD WINAPI GetDeviceDriverBaseNameA(LPVOID,LPSTR,DWORD); +DWORD WINAPI GetDeviceDriverBaseNameW(LPVOID,LPWSTR,DWORD); +DWORD WINAPI GetDeviceDriverFileNameA(LPVOID,LPSTR,DWORD); +DWORD WINAPI GetDeviceDriverFileNameW(LPVOID,LPWSTR,DWORD); +BOOL WINAPI GetProcessMemoryInfo(HANDLE,PPROCESS_MEMORY_COUNTERS,DWORD); + +#endif /* not RC_INVOKED */ + +#ifdef UNICODE +#define GetModuleBaseName GetModuleBaseNameW +#define GetModuleFileNameEx GetModuleFileNameExW +#define GetMappedFilenameEx GetMappedFilenameExW +#define GetDeviceDriverBaseName GetDeviceDriverBaseNameW +#define GetDeviceDriverFileName GetDeviceDriverFileNameW +#else +#define GetModuleBaseName GetModuleBaseNameA +#define GetModuleFileNameEx GetModuleFileNameExA +#define GetMappedFilenameEx GetMappedFilenameExA +#define GetDeviceDriverBaseName GetDeviceDriverBaseNameA +#define GetDeviceDriverFileName GetDeviceDriverFileNameA +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _PSAPI_H */ + diff --git a/windows/JackRouter/resource.h b/windows/JackRouter/resource.h new file mode 100644 index 00000000..673206e6 --- /dev/null +++ b/windows/JackRouter/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resource.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/windows/JackRouter/resource.rc b/windows/JackRouter/resource.rc new file mode 100644 index 00000000..4289ddc2 --- /dev/null +++ b/windows/JackRouter/resource.rc @@ -0,0 +1,109 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// French (France) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA) +#ifdef _WIN32 +LANGUAGE LANG_FRENCH, SUBLANG_FRENCH +#pragma code_page(1252) +#endif //_WIN32 + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,2,0,0 + PRODUCTVERSION 0,2,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040c04b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "Grame\0" + VALUE "FileDescription", "JackRouter ASIO driver\0" + VALUE "FileVersion", "0, 2, 0, 0\0" + VALUE "InternalName", "JackRouter\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "JackRouter.dll\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "JackRouter\0" + VALUE "ProductVersion", "0, 2, 0, 0\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x40c, 1200 + END +END + +#endif // !_MAC + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // French (France) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/windows/JackWinNamedPipeServerChannel.cpp b/windows/JackWinNamedPipeServerChannel.cpp index da0da443..3e6daa9c 100644 --- a/windows/JackWinNamedPipeServerChannel.cpp +++ b/windows/JackWinNamedPipeServerChannel.cpp @@ -24,6 +24,8 @@ Copyright (C) 2004-2006 Grame #include "JackLockedEngine.h" #include "JackGlobals.h" #include "JackClient.h" +#include "JackNotification.h" +#include "JackException.h" #include using namespace std; @@ -57,7 +59,7 @@ int JackClientPipeThread::Open(JackServer* server) // Open the Server/Client con jack_error("Cannot start Jack server listener\n"); return -1; } - + fServer = server; return 0; } @@ -71,15 +73,20 @@ void JackClientPipeThread::Close() // Close the Server/Client connection all ressources will be desallocated at the end. */ - fThread.Kill(); + fThread.Stop(); fPipe->Close(); fRefNum = -1; } - + bool JackClientPipeThread::Execute() { - jack_log("JackClientPipeThread::Execute"); - return(HandleRequest()); + try{ + jack_log("JackClientPipeThread::Execute"); + return (HandleRequest()); + } catch (JackQuitException& e) { + jack_log("JackMachServerChannel::Execute JackQuitException"); + return false; + } } bool JackClientPipeThread::HandleRequest() @@ -307,8 +314,14 @@ bool JackClientPipeThread::HandleRequest() case JackRequest::kNotification: { jack_log("JackRequest::Notification"); JackClientNotificationRequest req; - if (req.Read(fPipe) == 0) - fServer->Notify(req.fRefNum, req.fNotify, req.fValue); + if (req.Read(fPipe) == 0) { + if (req.fNotify == kQUIT) { + jack_log("JackRequest::Notification kQUIT"); + throw JackQuitException(); + } else { + fServer->Notify(req.fRefNum, req.fNotify, req.fValue); + } + } break; } @@ -317,7 +330,7 @@ bool JackClientPipeThread::HandleRequest() break; } } - + // Unlock the global mutex ReleaseMutex(fMutex); return ret; @@ -373,17 +386,17 @@ int JackWinNamedPipeServerChannel::Open(const char* server_name, JackServer* ser { jack_log("JackWinNamedPipeServerChannel::Open "); snprintf(fServerName, sizeof(fServerName), server_name); - + // Needed for internal connection from JackWinNamedPipeServerNotifyChannel object if (fRequestListenPipe.Bind(jack_server_dir, server_name, 0) < 0) { jack_error("JackWinNamedPipeServerChannel::Open : cannot create result listen pipe"); return -1; } - + fServer = server; return 0; } - + void JackWinNamedPipeServerChannel::Close() { /* TODO : solve WIN32 thread Kill issue @@ -403,11 +416,11 @@ int JackWinNamedPipeServerChannel::Start() if (fThread.Start() != 0) { jack_error("Cannot start Jack server listener"); return -1; - } - + } + return 0; -} - +} + bool JackWinNamedPipeServerChannel::Init() { jack_log("JackWinNamedPipeServerChannel::Init "); diff --git a/windows/JackWinNamedPipeServerNotifyChannel.cpp b/windows/JackWinNamedPipeServerNotifyChannel.cpp index 1e3c4e21..8036d81f 100644 --- a/windows/JackWinNamedPipeServerNotifyChannel.cpp +++ b/windows/JackWinNamedPipeServerNotifyChannel.cpp @@ -21,6 +21,7 @@ This program is free software; you can redistribute it and/or modify #include "JackError.h" #include "JackRequest.h" #include "JackConstants.h" +#include "JackNotification.h" namespace Jack { @@ -54,6 +55,14 @@ void JackWinNamedPipeServerNotifyChannel::Notify(int refnum, int notify, int val } } +void JackWinNamedPipeServerNotifyChannel::NotifyQuit() +{ + JackClientNotificationRequest req(-1, kQUIT, 0); + if (req.Write(&fRequestPipe) < 0) { + jack_error("Could not write request ref = %d notify = %d", -1, kQUIT); + } +} + } // end of namespace diff --git a/windows/JackWinNamedPipeServerNotifyChannel.h b/windows/JackWinNamedPipeServerNotifyChannel.h index aa1a6c91..be4d7ff2 100644 --- a/windows/JackWinNamedPipeServerNotifyChannel.h +++ b/windows/JackWinNamedPipeServerNotifyChannel.h @@ -45,6 +45,7 @@ class JackWinNamedPipeServerNotifyChannel void Close(); void Notify(int refnum, int notify, int value); + void NotifyQuit(); }; } // end of namespace diff --git a/windows/Setup/JackRouter.dll b/windows/Setup/JackRouter.dll index 226ea66792539d9053c87ba8a9c2674ea0583940..f06fe1b66bbb999b6c6f7bacaef4a3ac95d26767 100644 GIT binary patch delta 159 zcmZo@U}|V!n(%>H>ww0_&p+*LZ!$16@G>$qTmaIKfcO;8JSStvAOr|WMvkZU$?_wh6a0NE-o?EnA( delta 159 zcmZo@U}|V!n(%?ST7Y%q=b!erR~Q%?I2aikP6O$?K>QSl1%UjcK>8mL^8wkMKzsqn k)&P&Az6ZodHfuTtvruTnPS@XTAlGc(?&E0;0QxI0M*si- diff --git a/windows/Setup/jack.ci b/windows/Setup/jack.ci index 2c3eb9a0..25233392 100644 --- a/windows/Setup/jack.ci +++ b/windows/Setup/jack.ci @@ -1,9 +1,9 @@ <*project version = 4 civer = "Free v4.14.5" winver = "2.6/5.1.2600" > . - Jack_v1.9.4_setup.exe + Jack_v1.9.5_setup.exe - Jack v1.9.4 + Jack v1.9.5 Default - 2 @@ -72,6 +72,8 @@ <_>..\Release\bin\libsamplerate-0.dllinstovernewer0 <_>..\Release\bin\portaudio_x86.dllinstovernewer0 <_>..\Release\bin\jack\jack_net.dllinstjackovernewer0 +<_>..\Release\bin\jack\jack_netone.dllinstjackovernewer0 +<_>..\Release\bin\jack_netsource.exeinstovernewer0 <_>..\Release\bin\jack\jack_dummy.dllinstjackovernewer0 <_>..\Release\bin\jack\jack_loopback.dllinstjackovernewer0 <_>..\Release\bin\jack\jack_winmme.dllinstjackovernewer0 diff --git a/windows/jack_disconnect.cbp b/windows/jack_disconnect.cbp index cbb02515..994f2127 100644 --- a/windows/jack_disconnect.cbp +++ b/windows/jack_disconnect.cbp @@ -37,7 +37,7 @@ - + diff --git a/windows/jack_netonedriver.cbp b/windows/jack_netonedriver.cbp new file mode 100644 index 00000000..0aa97036 --- /dev/null +++ b/windows/jack_netonedriver.cbp @@ -0,0 +1,107 @@ + + + + + + diff --git a/windows/jack_netsource.cbp b/windows/jack_netsource.cbp new file mode 100644 index 00000000..ddfe02e8 --- /dev/null +++ b/windows/jack_netsource.cbp @@ -0,0 +1,110 @@ + + + + + + diff --git a/windows/jackaudioadapter.rc b/windows/jackaudioadapter.rc index 02d66940..25d4b155 100644 --- a/windows/jackaudioadapter.rc +++ b/windows/jackaudioadapter.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Audio Adapter for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "audioadapter\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "audioadapter.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "audioadapter\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackd.rc b/windows/jackd.rc index 5f909413..db62e72c 100644 --- a/windows/jackd.rc +++ b/windows/jackd.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEOS VOS_UNKNOWN FILETYPE VFT_APP BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack server for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "jackd\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jackd.exe\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jackd\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackd.workspace b/windows/jackd.workspace index 7e09eb88..9be9ce63 100644 --- a/windows/jackd.workspace +++ b/windows/jackd.workspace @@ -11,6 +11,9 @@ + + + @@ -33,6 +36,10 @@ + + + + diff --git a/windows/jacknetadapter.rc b/windows/jacknetadapter.rc index 62a7a3c0..7488ea91 100644 --- a/windows/jacknetadapter.rc +++ b/windows/jacknetadapter.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Adapter for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "netadapter\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "netadapter.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "netadapter\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetdriver.rc b/windows/jacknetdriver.rc index 8a7a1806..a98f2fc4 100644 --- a/windows/jacknetdriver.rc +++ b/windows/jacknetdriver.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Driver for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "jack_netdriver\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_netdriver.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_netdriver\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetmanager.rc b/windows/jacknetmanager.rc index ffc1dde8..c440861f 100644 --- a/windows/jacknetmanager.rc +++ b/windows/jacknetmanager.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Manager for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "netmanager\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "netmanager.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "netmanager\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetonedriver.rc b/windows/jacknetonedriver.rc new file mode 100644 index 00000000..9c184d36 --- /dev/null +++ b/windows/jacknetonedriver.rc @@ -0,0 +1,41 @@ +// Generated by ResEdit 1.4.3 +// Copyright (C) 2006-2008 +// http://www.resedit.net + +#include "resource.h" +#include "afxres.h" + + +// +// Version Information resources +// +LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT +1 VERSIONINFO + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 + FILEOS VOS_UNKNOWN + FILETYPE VFT_DLL +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040c04b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "Grame\0" + VALUE "FileDescription", "Jackmp NetOne Driver for Windows\0" + VALUE "FileVersion", "1, 9, 5, 0\0" + VALUE "InternalName", "jack_netonedriver\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "jack_netonedriver.dll\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "jack_netonedriver\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 1036, 1200 + END +END diff --git a/windows/jackportaudio.rc b/windows/jackportaudio.rc index 7e8429a0..2c4e66da 100644 --- a/windows/jackportaudio.rc +++ b/windows/jackportaudio.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp PortAudio Driver for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "jack_portaudio\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_portaudio.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_portaudio\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackwinmme.rc b/windows/jackwinmme.rc index 5a38e821..6d8e19f3 100644 --- a/windows/jackwinmme.rc +++ b/windows/jackwinmme.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp WinMMEo Driver for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "jack_portaudio\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_winmme.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_winmme\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/libjack.rc b/windows/libjack.rc index b4e79369..7beda3d8 100644 --- a/windows/libjack.rc +++ b/windows/libjack.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack client library for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "libjack\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjack.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjack\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/libjackserver.cbp b/windows/libjackserver.cbp index 8a82c34b..b0b76f1f 100644 --- a/windows/libjackserver.cbp +++ b/windows/libjackserver.cbp @@ -156,6 +156,8 @@ + + diff --git a/windows/libjackserver.rc b/windows/libjackserver.rc index dc0bbb6b..b62a275e 100644 --- a/windows/libjackserver.rc +++ b/windows/libjackserver.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack server library for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "libjackserver\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjackserver.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjackserver\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/resource.rc b/windows/resource.rc index 51ba4994..e5d5f15c 100644 --- a/windows/resource.rc +++ b/windows/resource.rc @@ -14,8 +14,8 @@ LANGUAGE LANG_FRENCH, SUBLANG_FRENCH #ifndef _MAC VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -33,14 +33,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "libjackmp\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjackmp.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjackmp\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/wscript b/wscript index a9128cca..33469397 100644 --- a/wscript +++ b/wscript @@ -68,8 +68,8 @@ def set_options(opt): opt.add_option('--profile', action='store_true', default=False, help='Build with engine profiling') opt.add_option('--mixed', action='store_true', default=False, help='Build with 32/64 bits mixed mode') opt.add_option('--clients', default=64, type="int", dest="clients", help='Maximum number of JACK clients') - opt.add_option('--ports', default=2048, type="int", dest="ports", help='Maximum number of ports') - opt.add_option('--ports-per-application', default=512, type="int", dest="application_ports", help='Maximum number of ports per application') + opt.add_option('--ports-per-application', default=768, type="int", dest="application_ports", help='Maximum number of ports per application') + opt.add_option('--debug', action='store_true', default=False, dest='debug', help="Build debuggable binaries") opt.sub_options('dbus') def configure(conf): @@ -112,6 +112,8 @@ def configure(conf): conf.sub_config('linux') if Options.options.dbus: conf.sub_config('dbus') + if conf.env['BUILD_JACKDBUS'] != True: + conf.fatal('jackdbus was explicitly requested but cannot be built') conf.sub_config('example-clients') if conf.check_cfg(package='celt', atleast_version='0.7.0', args='--cflags --libs'): @@ -136,8 +138,8 @@ def configure(conf): conf.env['BUILD_DOXYGEN_DOCS'] = Options.options.doxygen conf.env['BUILD_WITH_PROFILE'] = Options.options.profile conf.env['BUILD_WITH_32_64'] = Options.options.mixed - conf.env['BUILD_JACKDBUS'] = Options.options.dbus conf.env['BUILD_CLASSIC'] = Options.options.classic + conf.env['BUILD_DEBUG'] = Options.options.debug if conf.env['BUILD_JACKDBUS']: conf.env['BUILD_JACKD'] = conf.env['BUILD_CLASSIC'] @@ -149,8 +151,12 @@ def configure(conf): else: conf.env['LIBDIR'] = conf.env['PREFIX'] + '/lib' + if conf.env['BUILD_DEBUG']: + conf.env.append_unique('CXXFLAGS', '-g') + conf.env.append_unique('CCFLAGS', '-g') + conf.env.append_unique('LINKFLAGS', '-g') + conf.define('CLIENT_NUM', Options.options.clients) - conf.define('PORT_NUM', Options.options.ports) conf.define('PORT_NUM_FOR_CLIENT', Options.options.application_ports) conf.define('ADDON_DIR', os.path.normpath(os.path.join(conf.env['LIBDIR'], 'jack'))) @@ -184,12 +190,12 @@ def configure(conf): print version_msg print "Build with a maximum of %d JACK clients" % conf.env['CLIENT_NUM'] - print "Build with a maximum of %d ports" % conf.env['PORT_NUM'] print "Build with a maximum of %d ports per application" % conf.env['PORT_NUM_FOR_CLIENT'] display_msg("Install prefix", conf.env['PREFIX'], 'CYAN') display_msg("Library directory", conf.env['LIBDIR'], 'CYAN') display_msg("Drivers directory", conf.env['ADDON_DIR'], 'CYAN') + display_feature('Build debuggable binaries', conf.env['BUILD_DEBUG']) display_feature('Build doxygen documentation', conf.env['BUILD_DOXYGEN_DOCS']) display_feature('Build with engine profiling', conf.env['BUILD_WITH_PROFILE']) display_feature('Build with 32/64 bits mixed mode', conf.env['BUILD_WITH_32_64']) @@ -198,8 +204,9 @@ def configure(conf): display_feature('Build D-Bus JACK (jackdbus)', conf.env['BUILD_JACKDBUS']) if conf.env['BUILD_JACKDBUS'] and conf.env['BUILD_JACKD']: - print Logs.colors.RED + 'WARNING !! mixing both jackd and jackdbus may cause issues!' + Logs.colors.NORMAL - + print Logs.colors.RED + 'WARNING !! mixing both jackd and jackdbus may cause issues:' + Logs.colors.NORMAL + print Logs.colors.RED + 'WARNING !! jackdbus does not use .jackdrc nor qjackctl settings' + Logs.colors.NORMAL + if conf.env['IS_LINUX']: display_feature('Build with ALSA support', conf.env['BUILD_DRIVER_ALSA'] == True) display_feature('Build with FireWire (FreeBob) support', conf.env['BUILD_DRIVER_FREEBOB'] == True) From 6ae91579c43ad2c4756b001ca967189195072434 Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 16 Feb 2010 15:43:59 +0000 Subject: [PATCH 026/472] Add missing error functions. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3914 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetAPI.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 46825d8d..185e0da6 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -877,7 +877,6 @@ SERVER_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** in } -// Empty code for now.. #ifdef TARGET_OS_IPHONE static void jack_format_and_log(int level, const char *prefix, const char *fmt, va_list ap) @@ -920,4 +919,17 @@ SERVER_EXPORT void jack_log(const char *fmt, ...) va_end(ap); } +#else + +// Empty code for now.. + +SERVER_EXPORT void jack_error(const char *fmt, ...) +{} + +SERVER_EXPORT void jack_info(const char *fmt, ...) +{} + +SERVER_EXPORT void jack_log(const char *fmt, ...) +{} + #endif From ec2e42c933e891c00bbad46a61c85d950e4116d8 Mon Sep 17 00:00:00 2001 From: sletz Date: Thu, 18 Feb 2010 09:08:09 +0000 Subject: [PATCH 027/472] rebase from trunk 3899:3916 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3917 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 4 + README | 1 + common/JackAudioDriver.cpp | 7 +- common/JackClient.cpp | 2 +- common/JackConstants.h | 2 +- common/JackDriver.h | 4 + common/JackEngine.cpp | 147 ++++++++++++----------- common/JackEngine.h | 10 +- common/JackEngineControl.cpp | 3 +- common/JackEngineControl.h | 2 +- common/JackGraphManager.cpp | 12 ++ common/JackGraphManager.h | 4 +- common/JackLockedEngine.h | 82 ++++++------- common/JackMidiDriver.cpp | 7 +- common/JackMutex.h | 6 +- common/JackNetOneDriver.cpp | 14 +-- common/jack/types.h | 10 +- common/jack/weakmacros.h | 8 +- doxyfile | 2 +- example-clients/lsp.c | 6 + linux/alsa/JackAlsaDriver.cpp | 6 +- linux/alsa/alsa_rawmidi.c | 2 +- linux/alsa/alsa_seqmidi.c | 2 +- linux/firewire/JackFFADODriver.cpp | 28 ++--- linux/freebob/JackFreebobDriver.cpp | 11 +- macosx/Jack-Info.plist | 4 +- macosx/Jackdmp.xcodeproj/project.pbxproj | 28 +++++ macosx/coreaudio/JackCoreAudioDriver.cpp | 11 +- macosx/coremidi/JackCoreMidiDriver.cpp | 7 +- posix/JackNetUnixSocket.cpp | 7 ++ posix/JackPosixMutex.h | 6 +- tests/test.cpp | 31 ++++- windows/JackRouter/resource.rc | 10 +- windows/JackWinMutex.h | 10 +- windows/Setup/JackRouter.dll | Bin 32768 -> 32768 bytes windows/Setup/jack.ci | 6 +- windows/jackaudioadapter.rc | 10 +- windows/jackd.rc | 10 +- windows/jacknetadapter.rc | 10 +- windows/jacknetdriver.rc | 10 +- windows/jacknetmanager.rc | 10 +- windows/jackportaudio.rc | 10 +- windows/jackwinmme.rc | 10 +- windows/libjack.rc | 10 +- windows/libjackserver.rc | 10 +- windows/resource.rc | 10 +- windows/winmme/JackWinMMEDriver.cpp | 7 +- wscript | 2 +- 48 files changed, 351 insertions(+), 260 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4c2d8e8e..41d80af3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -29,6 +29,10 @@ Mario Lang Jackdmp changes log --------------------------- +2010-02-15 Gabriel M. Beddingfield + + * Version 1.9.6 started. + 2010-01-29 Gabriel M. Beddingfield * Change JackEngineProfiling and JackAudioAdapterInterface gnuplot scripts to output SVG instead of PDF. diff --git a/README b/README index d9f58484..2c689250 100644 --- a/README +++ b/README @@ -214,6 +214,7 @@ Note : To experiment with the -S option, jackdmp must be launched in a console. 1.9.2 : Solaris version. New "profiling" tools. Rework the mutex/signal classes. Support for BIG_ENDIAN machines in NetJack2. D-BUS based device reservation to better coexist with PulseAudio on Linux. Add auto_connect parameter in netmanager and netadapter. Use Torben Hohn PI controler code for adapters. Client incorrect re-naming fixed : now done at socket and fifo level. Virtualize and allow overriding of thread creation function, to allow Wine support (from JACK1). 1.9.3 : New JackBoomerDriver class for Boomer driver on Solaris. Add mixed 32/64 bits mode (off by default). Native MIDI backend (JackCoreMidiDriver, JackWinMMEDriver). In ALSA audio card reservation code, tries to open the card even if reservation fails. Clock source setting on Linux. Add jackctl_server_switch_master API. Fix transport callback (timebase master, sync) issue when used after jack_activate (RT thread was not running). D-Bus access for jackctl_server_add_slave/jackctl_server_remove_slave API. Cleanup "loopback" stuff in server. Torben Hohn fix for InitTime and GetMicroSeconds in JackWinTime.c. New jack_free function added in jack.h. Reworked Torben Hohn fix for server restart issue on Windows. Correct jack_set_error_function, jack_set_info_function and jack_set_thread_creator functions. Correct JackFifo::TimedWait for EINTR handling. Move DBus based audio device reservation code in ALSA backend compilation. Correct JackTransportEngine::MakeAllLocating, sync callback has to be called in this case also. NetJack2 code : better error checkout, method renaming. Tim Bechmann patch : hammerfall, only release monitor thread, if it has been created. Tim Bechmann memops.c optimization patches. In combined --dbus and --classic compilation code, use PulseAudio acquire/release code. Big rewrite of Solaris boomer driver, seems to work in duplex mode at least. Loopback backend reborn as a dynamically loadable separated backend. 1.9.4 : Solaris boomer backend now working in capture or playback only mode. Add a -G parameter in CoreAudio backend (the computation value in RT thread expressed as percent of period). Use SNDCTL_DSP_SYNCGROUP/SNDCTL_DSP_SYNCSTART API to synchronize input and output in Solaris boomer backend. Big endian bug fix in memops.c. Fix issues in JackNetDriver::DecodeTransportData and JackNetDriver::Initialize. Correct CPU timing in JackNetDriver, now take cycle begin time after Read. Simplify transport in NetJack2: master only can control transport. Change CoreAudio notification thread setup for OSX Snow Leopard. Correct server temporary mode : now set a global and quit after server/client message handling is finished. Add a string parameter to server ==> client notification, add a new JackInfoShutdownCallback type. CoreAudio backend now issue a JackInfoShutdownCallback when an unrecoverable error is detected (sampling rate change, stream configuration changeÉ). Correct jackdmp.cpp (failures case were not correct..). Improve JackCoreAudioDriver code. Raise default port number to 2048. Correct JackProcessSync::LockedTimedWait. Correct JACK_MESSAGE_SIZE value, particularly in OSX RPC code. Now start server channel thread only when backend has been started (so in JackServer::Start). Should solve race conditions at start time. jack_verbose moved to JackGlobals class. Improve aggregate device management in JackCoreAudioDriver : now a "private" device only and cleanup properly. Aggregate device code added to JackCoreAudioAdapter. Implement "hog mode" (exclusive access of the audio device) in JackCoreAudioDriver. Fix jack_set_sample_rate_callback to have he same behavior as in JACK1. Dynamic system version detection in JackCoreAudioDriver to either create public or private aggregate device. In JackCoreAudioDriver, force the SR value to the wanted one *before* creating aggregate device (otherwise creation will fail). In JackCoreAudioDriver, better cleanup of AD when intermediate open failure. In JackCoreAudioDriver::Start, wait for the audio driver to effectively start (use the MeasureCallback). In JackCoreAudioDriver, improve management of input/output channels: -1 is now used internally to indicate a wanted max value. In JackCoreAudioDriver::OpenAUHAL, correct stream format setup and cleanup. Correct crash bug in JackAudioAdapterInterface when not input is used in adapter (temporary fixÉ). Sync JackCoreAudioAdapter code on JackCoreAudioDriver one. JACK_SCHED_POLICY switched to SCHED_FIFO. Now can aggregate device that are themselves AD. No reason to make jack_on_shutdown deprecated, so revert the incorrect change. Thread AcquireRealTime and DropRealTime were (incorrectly) using fThread field. Use pthread_self()) (or GetCurrentThread() on Windows) to get the calling thread. Correctly save and restore RT mode state in freewheel mode. Correct freewheel code on client side. Fix AcquireRealTime and DropRealTime: now distinguish when called from another thread (AcquireRealTime/DropRealTime) and from the thread itself (AcquireSelfRealTime/DropSelfRealTime). Correct JackPosixThread::StartImp : thread priority setting now done in the RT case only. Correct JackGraphManager::GetBuffer for the "client loop with one connection" case : buffer must be copied. Correct JackInfoShutdownCallback prototype, two new JackClientProcessFailure and JackClientZombie JackStatus code. Correct JackCoreAudio driver when empty strings are given as -C, -P or -d parameter. Better memory allocation error checking on client (library) side. Better memory allocation error checking in ringbuffer.c, weak import improvements. Memory allocation error checking for jack_client_new and jack_client_open (server and client side). Memory allocation error checking in server for RPC. Simplify server temporary mode : now use a JackTemporaryException. Lock/Unlock shared memory segments (to test...). Sync with JACK1 : -r parameter now used for no-realtime, realtime (-R) is now default, usable backend given vie platform. In JackCoreAudio driver, (possibly) clock drift compensation when needed in aggregated devices. In JackCoreAudio driver, clock drift compensation in aggregated devices working. In JackCoreAudio driver, clock drift compensation semantic changed a bit : when on, does not activate if not needed (same clock domain). Sync JackCoreAudioAdapter code with JackCoreAudioDriver. +1.9.5 : Dynamic choice of maximum port number. More robust sample rate change handling code in JackCoreAudioDriver. Devin Anderson patch for Jack FFADO driver issues with lost MIDI bytes between periods (and more). Fix port_rename callback : now both old name and new name are given as parameters. Special code in JackCoreAudio driver to handle completely buggy Digidesign CoreAudio user-land driver. Ensure that client-side message buffer thread calls thread_init callback if/when it is set by the client (backport of JACK1 rev 3838). Check dynamic port-max value. Fix JackCoreMidiDriver::ReadProcAux when ring buffer is full (thanks Devin Anderson). Josh Green ALSA driver capture only patch. When threads are cancelled, the exception has to be rethrown. Use a QUIT notification to properly quit the server channel, the server channel thread can then be 'stopped' instead of 'canceled'. Mario Lang alsa_io time calculation overflow patch. Shared memory manager was calling abort in case of fatal error, now return an error in caller. Change JackEngineProfiling and JackAudioAdapterInterface gnuplot scripts to output SVG instead of PDF. This is a work in progress but the implementation is now stable enough to be tested. jackdmp has been used successfully with the following applications : Ardour, Hydrogen, Jamin, Qjackctl, Jack-Rack, SooperLooper, AlsaPlayer... diff --git a/common/JackAudioDriver.cpp b/common/JackAudioDriver.cpp index 3bcae9e9..dc53077c 100644 --- a/common/JackAudioDriver.cpp +++ b/common/JackAudioDriver.cpp @@ -101,7 +101,6 @@ int JackAudioDriver::Attach() jack_port_id_t port_index; char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - unsigned long port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; int i; jack_log("JackAudioDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); @@ -109,7 +108,7 @@ int JackAudioDriver::Attach() for (i = 0; i < fCaptureChannels; i++) { snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", name); return -1; } @@ -120,12 +119,10 @@ int JackAudioDriver::Attach() jack_log("JackAudioDriver::Attach fCapturePortList[i] port_index = %ld", port_index); } - port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; - for (i = 0; i < fPlaybackChannels; i++) { snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", name); return -1; } diff --git a/common/JackClient.cpp b/common/JackClient.cpp index d4359f83..889a24a8 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -252,7 +252,7 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, break; case kPortRenameCallback: - jack_log("JackClient::kPortRenameCallback port = %ld"); + jack_log("JackClient::kPortRenameCallback port = %ld", value1); if (fPortRename) { fPortRename(value1, message, GetGraphManager()->GetPort(value1)->GetName(), fPortRenameArg); } diff --git a/common/JackConstants.h b/common/JackConstants.h index 60a631c3..695fcd0f 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -24,7 +24,7 @@ #include "config.h" #endif -#define VERSION "1.9.5" +#define VERSION "1.9.6" #define BUFFER_SIZE_MAX 8192 diff --git a/common/JackDriver.h b/common/JackDriver.h index 83f7e250..901e6bf3 100644 --- a/common/JackDriver.h +++ b/common/JackDriver.h @@ -109,6 +109,10 @@ 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) class SERVER_EXPORT JackDriver : public JackDriverClientInterface { diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index fabebb01..8c205975 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -35,8 +35,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { -#define AssertRefnum(ref) assert(ref >= 0 && ref < CLIENT_NUM); - JackEngine::JackEngine(JackGraphManager* manager, JackSynchro* table, JackEngineControl* control) @@ -213,28 +211,28 @@ void JackEngine::NotifyClient(int refnum, int event, int sync, const char* messa JackClientInterface* client = fClientTable[refnum]; // The client may be notified by the RT thread while closing - if (!client) { - jack_log("JackEngine::NotifyClient: client not available anymore"); - } else if (client->GetClientControl()->fCallback[event]) { - if (client->ClientNotify(refnum, client->GetClientControl()->fName, event, sync, message, value1, value2) < 0) - jack_error("NotifyClient fails name = %s event = %ld val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2); - } else { - jack_log("JackEngine::NotifyClient: no callback for event = %ld", event); + if (client) { + + if (client && client->GetClientControl()->fCallback[event]) { + /* + Important for internal clients : unlock before calling the notification callbacks. + */ + bool res = fMutex.Unlock(); + if (client->ClientNotify(refnum, client->GetClientControl()->fName, event, sync, message, value1, value2) < 0) + jack_error("NotifyClient fails name = %s event = %ld val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2); + if (res) + fMutex.Lock(); + + } else { + jack_log("JackEngine::NotifyClient: no callback for event = %ld", event); + } } } -void JackEngine::NotifyClients(int event, int sync, const char* message, int value1, int value2) +void JackEngine::NotifyClients(int event, int sync, const char* message, int value1, int value2) { for (int i = 0; i < CLIENT_NUM; i++) { - JackClientInterface* client = fClientTable[i]; - if (client) { - if (client->GetClientControl()->fCallback[event]) { - if (client->ClientNotify(i, client->GetClientControl()->fName, event, sync, message, value1, value2) < 0) - jack_error("NotifyClient fails name = %s event = %ld val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2); - } else { - jack_log("JackEngine::NotifyClients: no callback for event = %ld", event); - } - } + NotifyClient(i, event, sync, message, value1, value2); } } @@ -274,8 +272,7 @@ void JackEngine::NotifyRemoveClient(const char* name, int refnum) void JackEngine::NotifyXRun(jack_time_t callback_usecs, float delayed_usecs) { // Use the audio thread => request thread communication channel - fEngineControl->ResetFrameTime(callback_usecs); - fEngineControl->NotifyXRun(delayed_usecs); + fEngineControl->NotifyXRun(callback_usecs, delayed_usecs); fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); } @@ -348,14 +345,9 @@ void JackEngine::NotifyActivate(int refnum) int JackEngine::GetInternalClientName(int refnum, char* name_res) { - AssertRefnum(refnum); JackClientInterface* client = fClientTable[refnum]; - if (client) { - strncpy(name_res, client->GetClientControl()->fName, JACK_CLIENT_NAME_SIZE); - return 0; - } else { - return -1; - } + strncpy(name_res, client->GetClientControl()->fName, JACK_CLIENT_NAME_SIZE); + return 0; } int JackEngine::InternalClientHandle(const char* client_name, int* status, int* int_ref) @@ -378,7 +370,6 @@ int JackEngine::InternalClientHandle(const char* client_name, int* status, int* int JackEngine::InternalClientUnload(int refnum, int* status) { - AssertRefnum(refnum); JackClientInterface* client = fClientTable[refnum]; if (client) { int res = client->Close(); @@ -592,26 +583,19 @@ error: // Used for external clients int JackEngine::ClientExternalClose(int refnum) { - AssertRefnum(refnum); JackClientInterface* client = fClientTable[refnum]; - - if (client) { - fEngineControl->fTransport.ResetTimebase(refnum); - int res = ClientCloseAux(refnum, client, true); - client->Close(); - delete client; - return res; - } else { - return -1; - } + fEngineControl->fTransport.ResetTimebase(refnum); + int res = ClientCloseAux(refnum, client, true); + client->Close(); + delete client; + return res; } // Used for server internal clients or drivers when the RT thread is stopped int JackEngine::ClientInternalClose(int refnum, bool wait) { - AssertRefnum(refnum); JackClientInterface* client = fClientTable[refnum]; - return (client) ? ClientCloseAux(refnum, client, wait) : -1; + return ClientCloseAux(refnum, client, wait); } int JackEngine::ClientCloseAux(int refnum, JackClientInterface* client, bool wait) @@ -656,11 +640,9 @@ int JackEngine::ClientCloseAux(int refnum, JackClientInterface* client, bool wai int JackEngine::ClientActivate(int refnum, bool is_real_time) { - AssertRefnum(refnum); JackClientInterface* client = fClientTable[refnum]; - assert(fClientTable[refnum]); - jack_log("JackEngine::ClientActivate ref = %ld name = %s", refnum, client->GetClientControl()->fName); + if (is_real_time) fGraphManager->Activate(refnum); @@ -669,7 +651,30 @@ int JackEngine::ClientActivate(int refnum, bool is_real_time) jack_error("JackEngine::ClientActivate wait error ref = %ld name = %s", refnum, client->GetClientControl()->fName); return -1; } else { + jack_int_t input_ports[PORT_NUM_FOR_CLIENT]; + jack_int_t output_ports[PORT_NUM_FOR_CLIENT]; + 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); + + // Then issue port registration notification + for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { + NotifyPortRegistation(input_ports[i], true); + } + for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (output_ports[i] != EMPTY); i++) { + NotifyPortRegistation(output_ports[i], true); + } + return 0; } } @@ -677,25 +682,30 @@ int JackEngine::ClientActivate(int refnum, bool is_real_time) // May be called without client int JackEngine::ClientDeactivate(int refnum) { - AssertRefnum(refnum); JackClientInterface* client = fClientTable[refnum]; - if (client == NULL) - return -1; - jack_log("JackEngine::ClientDeactivate ref = %ld name = %s", refnum, client->GetClientControl()->fName); - // Disconnect all ports ==> notifications are sent - jack_int_t ports[PORT_NUM_FOR_CLIENT]; - int i; + jack_int_t input_ports[PORT_NUM_FOR_CLIENT]; + jack_int_t output_ports[PORT_NUM_FOR_CLIENT]; + fGraphManager->GetInputPorts(refnum, input_ports); + fGraphManager->GetOutputPorts(refnum, output_ports); - fGraphManager->GetInputPorts(refnum, ports); - for (i = 0; (i < PORT_NUM_FOR_CLIENT) && (ports[i] != EMPTY) ; i++) { - PortDisconnect(refnum, ports[i], ALL_PORTS); + // 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]); } - - fGraphManager->GetOutputPorts(refnum, ports); - for (i = 0; (i < PORT_NUM_FOR_CLIENT) && (ports[i] != EMPTY) ; i++) { - PortDisconnect(refnum, ports[i], ALL_PORTS); + 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 + for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { + NotifyPortRegistation(input_ports[i], false); + } + for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (output_ports[i] != EMPTY); i++) { + NotifyPortRegistation(output_ports[i], false); } fGraphManager->Deactivate(refnum); @@ -717,8 +727,7 @@ int JackEngine::ClientDeactivate(int refnum) int JackEngine::PortRegister(int refnum, const char* name, const char *type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index) { jack_log("JackEngine::PortRegister ref = %ld name = %s type = %s flags = %d buffer_size = %d", refnum, name, type, flags, buffer_size); - AssertRefnum(refnum); - assert(fClientTable[refnum]); + JackClientInterface* client = fClientTable[refnum]; // Check if port name already exists if (fGraphManager->GetPort(name) != NO_PORT) { @@ -728,7 +737,8 @@ int JackEngine::PortRegister(int refnum, const char* name, const char *type, uns *port_index = fGraphManager->AllocatePort(refnum, name, type, (JackPortFlags)flags, fEngineControl->fBufferSize); if (*port_index != NO_PORT) { - NotifyPortRegistation(*port_index, true); + if (client->GetClientControl()->fActive) + NotifyPortRegistation(*port_index, true); return 0; } else { return -1; @@ -738,14 +748,14 @@ int JackEngine::PortRegister(int refnum, const char* name, const char *type, uns int JackEngine::PortUnRegister(int refnum, jack_port_id_t port_index) { jack_log("JackEngine::PortUnRegister ref = %ld port_index = %ld", refnum, port_index); - AssertRefnum(refnum); - assert(fClientTable[refnum]); + JackClientInterface* client = fClientTable[refnum]; // Disconnect port ==> notification is sent PortDisconnect(refnum, port_index, ALL_PORTS); if (fGraphManager->ReleasePort(refnum, port_index) == 0) { - NotifyPortRegistation(port_index, false); + if (client->GetClientControl()->fActive) + NotifyPortRegistation(port_index, false); return 0; } else { return -1; @@ -755,7 +765,6 @@ int JackEngine::PortUnRegister(int refnum, jack_port_id_t port_index) int JackEngine::PortConnect(int refnum, const char* src, const char* dst) { jack_log("JackEngine::PortConnect src = %s dst = %s", src, dst); - AssertRefnum(refnum); jack_port_id_t port_src, port_dst; return (fGraphManager->GetTwoPorts(src, dst, &port_src, &port_dst) < 0) @@ -766,7 +775,6 @@ int JackEngine::PortConnect(int refnum, const char* src, const char* dst) int JackEngine::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst) { jack_log("JackEngine::PortConnect src = %d dst = %d", src, dst); - AssertRefnum(refnum); JackClientInterface* client; int ref; @@ -802,7 +810,6 @@ int JackEngine::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst) int JackEngine::PortDisconnect(int refnum, const char* src, const char* dst) { jack_log("JackEngine::PortDisconnect src = %s dst = %s", src, dst); - AssertRefnum(refnum); jack_port_id_t port_src, port_dst; return (fGraphManager->GetTwoPorts(src, dst, &port_src, &port_dst) < 0) @@ -813,8 +820,7 @@ int JackEngine::PortDisconnect(int refnum, const char* src, const char* dst) int JackEngine::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst) { jack_log("JackEngine::PortDisconnect src = %d dst = %d", src, dst); - AssertRefnum(refnum); - + if (dst == ALL_PORTS) { jack_int_t connections[CONNECTION_NUM_FOR_PORT]; @@ -850,7 +856,6 @@ int JackEngine::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t ds int JackEngine::PortRename(int refnum, jack_port_id_t port, const char* name) { - AssertRefnum(refnum); char old_name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; strcpy(old_name, fGraphManager->GetPort(port)->GetName()); fGraphManager->GetPort(port)->SetName(name); diff --git a/common/JackEngine.h b/common/JackEngine.h index 3a4a24a9..945d7e9c 100644 --- a/common/JackEngine.h +++ b/common/JackEngine.h @@ -23,6 +23,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackConstants.h" #include "JackGraphManager.h" #include "JackSynchro.h" +#include "JackMutex.h" #include "JackTransportEngine.h" #include "JackPlatformPlug.h" @@ -37,8 +38,10 @@ class JackExternalClient; \brief Engine description. */ -class SERVER_EXPORT JackEngine +class SERVER_EXPORT JackEngine : public JackLockAble { + friend class JackLockedEngine; + private: JackGraphManager* fGraphManager; @@ -71,6 +74,11 @@ class SERVER_EXPORT JackEngine void NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst, bool onoff); void NotifyPortRename(jack_port_id_t src, const char* old_name); void NotifyActivate(int refnum); + + bool CheckClient(int refnum) + { + return (refnum >= 0 && refnum < CLIENT_NUM && fClientTable[refnum] != NULL); + } public: diff --git a/common/JackEngineControl.cpp b/common/JackEngineControl.cpp index 872dcd32..db13ae78 100644 --- a/common/JackEngineControl.cpp +++ b/common/JackEngineControl.cpp @@ -81,8 +81,9 @@ void JackEngineControl::ResetRollingUsecs() fRollingInterval = int(floor((JACK_ENGINE_ROLLING_INTERVAL * 1000.f) / fPeriodUsecs)); } -void JackEngineControl::NotifyXRun(float delayed_usecs) +void JackEngineControl::NotifyXRun(jack_time_t callback_usecs, float delayed_usecs) { + ResetFrameTime(callback_usecs); fXrunDelayedUsecs = delayed_usecs; if (delayed_usecs > fMaxDelayedUsecs) fMaxDelayedUsecs = delayed_usecs; diff --git a/common/JackEngineControl.h b/common/JackEngineControl.h index 326e3b7f..3ba54b87 100644 --- a/common/JackEngineControl.h +++ b/common/JackEngineControl.h @@ -162,7 +162,7 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem } // XRun - void NotifyXRun(float delayed_usecs); + void NotifyXRun(jack_time_t callback_usecs, float delayed_usecs); void ResetXRun() { fMaxDelayedUsecs = 0.f; diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index ce77f875..36e29430 100644 --- a/common/JackGraphManager.cpp +++ b/common/JackGraphManager.cpp @@ -376,6 +376,18 @@ 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(); diff --git a/common/JackGraphManager.h b/common/JackGraphManager.h index c2d7e105..93b09ff9 100644 --- a/common/JackGraphManager.h +++ b/common/JackGraphManager.h @@ -65,6 +65,8 @@ 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); @@ -75,7 +77,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); diff --git a/common/JackLockedEngine.h b/common/JackLockedEngine.h index a9f044a8..827ab527 100644 --- a/common/JackLockedEngine.h +++ b/common/JackLockedEngine.h @@ -37,7 +37,6 @@ See : http://groups.google.com/group/comp.programming.threads/browse_thread/thre catch (...) { // Assuming thread cancellation, must rethrow throw; - } */ @@ -62,11 +61,12 @@ catch (...) { throw; \ } \ + /*! \brief Locked Engine, access to methods is serialized using a mutex. */ -class SERVER_EXPORT JackLockedEngine : public JackLockAble +class SERVER_EXPORT JackLockedEngine { private: @@ -99,21 +99,21 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble int ClientCheck(const char* name, char* name_res, int protocol, int options, int* status) { TRY_CALL - JackLock lock(this); + JackLock lock(&fEngine); return fEngine.ClientCheck(name, name_res, protocol, options, status); CATCH_EXCEPTION_RETURN } int ClientExternalOpen(const char* name, int pid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager) { TRY_CALL - JackLock lock(this); + JackLock lock(&fEngine); return fEngine.ClientExternalOpen(name, pid, ref, shared_engine, shared_client, shared_graph_manager); CATCH_EXCEPTION_RETURN } int ClientInternalOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, bool wait) { TRY_CALL - JackLock lock(this); + JackLock lock(&fEngine); return fEngine.ClientInternalOpen(name, ref, shared_engine, shared_manager, client, wait); CATCH_EXCEPTION_RETURN } @@ -121,30 +121,30 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble int ClientExternalClose(int refnum) { TRY_CALL - JackLock lock(this); - return fEngine.ClientExternalClose(refnum); + JackLock lock(&fEngine); + return (fEngine.CheckClient(refnum)) ? fEngine.ClientExternalClose(refnum) : - 1; CATCH_EXCEPTION_RETURN } int ClientInternalClose(int refnum, bool wait) { TRY_CALL - JackLock lock(this); - return fEngine.ClientInternalClose(refnum, wait); + JackLock lock(&fEngine); + return (fEngine.CheckClient(refnum)) ? fEngine.ClientInternalClose(refnum, wait) : -1; CATCH_EXCEPTION_RETURN } int ClientActivate(int refnum, bool is_real_time) { TRY_CALL - JackLock lock(this); - return fEngine.ClientActivate(refnum, is_real_time); + JackLock lock(&fEngine); + return (fEngine.CheckClient(refnum)) ? fEngine.ClientActivate(refnum, is_real_time) : -1; CATCH_EXCEPTION_RETURN } int ClientDeactivate(int refnum) { TRY_CALL - JackLock lock(this); - return fEngine.ClientDeactivate(refnum); + JackLock lock(&fEngine); + return (fEngine.CheckClient(refnum)) ? fEngine.ClientDeactivate(refnum) : -1; CATCH_EXCEPTION_RETURN } @@ -152,21 +152,22 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble int GetInternalClientName(int int_ref, char* name_res) { TRY_CALL - JackLock lock(this); + JackLock lock(&fEngine); return fEngine.GetInternalClientName(int_ref, name_res); CATCH_EXCEPTION_RETURN } int InternalClientHandle(const char* client_name, int* status, int* int_ref) { TRY_CALL - JackLock lock(this); + JackLock lock(&fEngine); return fEngine.InternalClientHandle(client_name, status, int_ref); CATCH_EXCEPTION_RETURN } int InternalClientUnload(int refnum, int* status) { TRY_CALL - JackLock lock(this); + JackLock lock(&fEngine); + // Client is tested in fEngine.InternalClientUnload return fEngine.InternalClientUnload(refnum, status); CATCH_EXCEPTION_RETURN } @@ -175,53 +176,53 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble int PortRegister(int refnum, const char* name, const char *type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port) { TRY_CALL - JackLock lock(this); - return fEngine.PortRegister(refnum, name, type, flags, buffer_size, port); + JackLock lock(&fEngine); + return (fEngine.CheckClient(refnum)) ? fEngine.PortRegister(refnum, name, type, flags, buffer_size, port) : -1; CATCH_EXCEPTION_RETURN } int PortUnRegister(int refnum, jack_port_id_t port) { TRY_CALL - JackLock lock(this); - return fEngine.PortUnRegister(refnum, port); + JackLock lock(&fEngine); + return (fEngine.CheckClient(refnum)) ? fEngine.PortUnRegister(refnum, port) : -1; CATCH_EXCEPTION_RETURN } int PortConnect(int refnum, const char* src, const char* dst) { TRY_CALL - JackLock lock(this); - return fEngine.PortConnect(refnum, src, dst); + JackLock lock(&fEngine); + return (fEngine.CheckClient(refnum)) ? fEngine.PortConnect(refnum, src, dst) : -1; CATCH_EXCEPTION_RETURN } int PortDisconnect(int refnum, const char* src, const char* dst) { TRY_CALL - JackLock lock(this); - return fEngine.PortDisconnect(refnum, src, dst); + JackLock lock(&fEngine); + return (fEngine.CheckClient(refnum)) ? fEngine.PortDisconnect(refnum, src, dst) : -1; CATCH_EXCEPTION_RETURN } int PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst) { TRY_CALL - JackLock lock(this); - return fEngine.PortConnect(refnum, src, dst); + JackLock lock(&fEngine); + return (fEngine.CheckClient(refnum)) ? fEngine.PortConnect(refnum, src, dst) : -1; CATCH_EXCEPTION_RETURN } int PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst) { TRY_CALL - JackLock lock(this); - return fEngine.PortDisconnect(refnum, src, dst); + JackLock lock(&fEngine); + return (fEngine.CheckClient(refnum)) ? fEngine.PortDisconnect(refnum, src, dst) : -1; CATCH_EXCEPTION_RETURN } int PortRename(int refnum, jack_port_id_t port, const char* name) { TRY_CALL - JackLock lock(this); - return fEngine.PortRename(refnum, port, name); + JackLock lock(&fEngine); + return (fEngine.CheckClient(refnum)) ? fEngine.PortRename(refnum, port, name) : -1; CATCH_EXCEPTION_RETURN } @@ -241,36 +242,35 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble void NotifyXRun(int refnum) { - TRY_CALL - JackLock lock(this); + // RT : no lock fEngine.NotifyXRun(refnum); - CATCH_EXCEPTION } + void NotifyGraphReorder() { TRY_CALL - JackLock lock(this); + JackLock lock(&fEngine); fEngine.NotifyGraphReorder(); CATCH_EXCEPTION } void NotifyBufferSize(jack_nframes_t buffer_size) { TRY_CALL - JackLock lock(this); + JackLock lock(&fEngine); fEngine.NotifyBufferSize(buffer_size); CATCH_EXCEPTION } void NotifySampleRate(jack_nframes_t sample_rate) { TRY_CALL - JackLock lock(this); + JackLock lock(&fEngine); fEngine.NotifySampleRate(sample_rate); CATCH_EXCEPTION } void NotifyFreewheel(bool onoff) { TRY_CALL - JackLock lock(this); + JackLock lock(&fEngine); fEngine.NotifyFreewheel(onoff); CATCH_EXCEPTION } @@ -278,7 +278,7 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble void NotifyFailure(int code, const char* reason) { TRY_CALL - JackLock lock(this); + JackLock lock(&fEngine); fEngine.NotifyFailure(code, reason); CATCH_EXCEPTION } @@ -286,7 +286,7 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble int GetClientPID(const char* name) { TRY_CALL - JackLock lock(this); + JackLock lock(&fEngine); return fEngine.GetClientPID(name); CATCH_EXCEPTION_RETURN } @@ -294,7 +294,7 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble int GetClientRefNum(const char* name) { TRY_CALL - JackLock lock(this); + JackLock lock(&fEngine); return fEngine.GetClientRefNum(name); CATCH_EXCEPTION_RETURN } @@ -302,7 +302,7 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble void NotifyQuit() { TRY_CALL - JackLock lock(this); + JackLock lock(&fEngine); return fEngine.NotifyQuit(); CATCH_EXCEPTION } diff --git a/common/JackMidiDriver.cpp b/common/JackMidiDriver.cpp index b5bfd4c4..4ddf417c 100644 --- a/common/JackMidiDriver.cpp +++ b/common/JackMidiDriver.cpp @@ -74,7 +74,6 @@ int JackMidiDriver::Attach() jack_port_id_t port_index; char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - unsigned long port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; int i; jack_log("JackMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); @@ -82,7 +81,7 @@ int JackMidiDriver::Attach() for (i = 0; i < fCaptureChannels; i++) { snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", name); return -1; } @@ -92,12 +91,10 @@ int JackMidiDriver::Attach() jack_log("JackMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index); } - port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; - for (i = 0; i < fPlaybackChannels; i++) { snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", name); return -1; } diff --git a/common/JackMutex.h b/common/JackMutex.h index e2472add..0a2600d7 100644 --- a/common/JackMutex.h +++ b/common/JackMutex.h @@ -36,11 +36,9 @@ namespace Jack class JackLockAble { - private: - - JackMutex fMutex; - protected: + + JackMutex fMutex; JackLockAble() {} diff --git a/common/JackNetOneDriver.cpp b/common/JackNetOneDriver.cpp index 4a75cc23..3259b563 100644 --- a/common/JackNetOneDriver.cpp +++ b/common/JackNetOneDriver.cpp @@ -138,19 +138,15 @@ namespace Jack jack_port_id_t port_id; char buf[64]; unsigned int chn; - int port_flags; - //if (netj.handle_transport_sync) // jack_set_sync_callback(netj.client, (JackSyncCallback) net_driver_sync_cb, NULL); - port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; - for (chn = 0; chn < netj.capture_channels_audio; chn++) { snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, - static_cast ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT ) + CaptureDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) { jack_error ( "driver: cannot register port for %s", buf ); return -1; @@ -184,7 +180,7 @@ namespace Jack snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, - static_cast ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT ) + CaptureDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) { jack_error ( "driver: cannot register port for %s", buf ); return -1; @@ -195,13 +191,11 @@ namespace Jack jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); } - port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; - for (chn = 0; chn < netj.playback_channels_audio; chn++) { snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, - static_cast ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT ) + PlaybackDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) { jack_error ( "driver: cannot register port for %s", buf ); return -1; @@ -231,7 +225,7 @@ namespace Jack snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, - static_cast ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT ) + PlaybackDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) { jack_error ( "driver: cannot register port for %s", buf ); return -1; diff --git a/common/jack/types.h b/common/jack/types.h index 6c1b0f95..3722d7f4 100644 --- a/common/jack/types.h +++ b/common/jack/types.h @@ -295,7 +295,15 @@ enum JackPortFlags { * systems are examples of clients that would set this flag for * their ports. */ - JackPortIsTerminal = 0x10 + JackPortIsTerminal = 0x10, + + /** + * JackPortIsActive means the port has been registered and the + * client is "active", that is jack_activate has been called + * + * JackPortIsActive is on between jack_activate and jack_deactivate. + */ + JackPortIsActive = 0x20 }; /** diff --git a/common/jack/weakmacros.h b/common/jack/weakmacros.h index 3db19d3f..b3207f6a 100644 --- a/common/jack/weakmacros.h +++ b/common/jack/weakmacros.h @@ -42,7 +42,8 @@ */ #define JACK_WEAK_EXPORT __attribute__((weak)) #else -/* Add other things here for non-gcc platforms */ +/* Add other things here for non-gcc platforms */ +#define JACK_WEAK_EXPORT #endif #endif @@ -53,8 +54,9 @@ #ifndef JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT #ifdef __GNUC__ #define JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT __attribute__((__deprecated__)) -#else -/* Add other things here for non-gcc platforms */ +#else +/* Add other things here for non-gcc platforms */ +#define JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT #endif /* __GNUC__ */ #endif diff --git a/doxyfile b/doxyfile index bc5116a0..a0d35e99 100644 --- a/doxyfile +++ b/doxyfile @@ -23,7 +23,7 @@ PROJECT_NAME = "Jack2" # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 1.9.5 +PROJECT_NUMBER = 1.9.6 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/example-clients/lsp.c b/example-clients/lsp.c index db8b4543..5a3362f2 100644 --- a/example-clients/lsp.c +++ b/example-clients/lsp.c @@ -208,6 +208,12 @@ 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); } } diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index 8c0168e5..fff7aea9 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -2087,7 +2087,7 @@ int JackAlsaDriver::Attach() assert(fCaptureChannels < DRIVER_PORT_NUM); assert(fPlaybackChannels < DRIVER_PORT_NUM); - port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; + port_flags = (unsigned long)CaptureDriverFlags; alsa_driver_t* alsa_driver = (alsa_driver_t*)fDriver; @@ -2114,7 +2114,7 @@ int JackAlsaDriver::Attach() jack_log("JackAudioDriver::Attach fCapturePortList[i] %ld ", port_index); } - port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; + port_flags = (unsigned long)PlaybackDriverFlags; for (int i = 0; i < fPlaybackChannels; i++) { snprintf(alias, sizeof(alias) - 1, "%s:playback_%u", fAliasName, i + 1); @@ -2135,7 +2135,7 @@ int JackAlsaDriver::Attach() if (fWithMonitorPorts) { jack_log("Create monitor port "); snprintf(name, sizeof(name) - 1, "%s:monitor_%d", fClientControl.fName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, MonitorDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error ("ALSA: cannot register monitor port for %s", name); } else { port = fGraphManager->GetPort(port_index); diff --git a/linux/alsa/alsa_rawmidi.c b/linux/alsa/alsa_rawmidi.c index 13d7f310..62e18cd7 100644 --- a/linux/alsa/alsa_rawmidi.c +++ b/linux/alsa/alsa_rawmidi.c @@ -432,7 +432,7 @@ inline int midi_port_open_jack(alsa_rawmidi_t *midi, midi_port_t *port, int type 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, 0); + type | JackPortIsPhysical | JackPortIsTerminal | JackPortIsActive, 0); if (port->jack) jack_port_set_alias(port->jack, alias); diff --git a/linux/alsa/alsa_seqmidi.c b/linux/alsa/alsa_seqmidi.c index f079703c..0abc52a9 100644 --- a/linux/alsa/alsa_seqmidi.c +++ b/linux/alsa/alsa_seqmidi.c @@ -488,7 +488,7 @@ 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); + jack_caps |= (JackPortIsPhysical | JackPortIsTerminal | JackPortIsActive); } if (jack_caps & JackPortIsOutput) diff --git a/linux/firewire/JackFFADODriver.cpp b/linux/firewire/JackFFADODriver.cpp index be2f3359..735aace6 100644 --- a/linux/firewire/JackFFADODriver.cpp +++ b/linux/firewire/JackFFADODriver.cpp @@ -359,8 +359,6 @@ int JackFFADODriver::Attach() { JackPort* port; int port_index; - unsigned long port_flags; - char buf[JACK_PORT_NAME_SIZE]; char portname[JACK_PORT_NAME_SIZE]; @@ -418,8 +416,6 @@ int JackFFADODriver::Attach() /* ports */ // capture - port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; - driver->capture_nchannels = ffado_streaming_get_nb_capture_streams(driver->dev); driver->capture_channels = (ffado_capture_channel_t *)calloc(driver->capture_nchannels, sizeof(ffado_capture_channel_t)); if (driver->capture_channels == NULL) { @@ -433,11 +429,11 @@ int JackFFADODriver::Attach() driver->capture_channels[chn].stream_type = ffado_streaming_get_capture_stream_type(driver->dev, chn); if (driver->capture_channels[chn].stream_type == ffado_stream_type_audio) { - snprintf(buf, sizeof(buf) - 1, "%s:AC%d_%s", fClientControl.fName, (int)chn, portname); + snprintf(buf, sizeof(buf) - 1, "%s:%s", fClientControl.fName, portname); printMessage ("Registering audio capture port %s", buf); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, - (JackPortFlags)port_flags, + CaptureDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", buf); return -1; @@ -451,16 +447,19 @@ int JackFFADODriver::Attach() port = fGraphManager->GetPort(port_index); port->SetLatency(driver->period_size + driver->capture_frame_latency); + // capture port aliases (jackd1 style port names) + snprintf(buf, sizeof(buf) - 1, "%s:capture_%i", fClientControl.fName, (int) chn + 1); + port->SetAlias(buf); fCapturePortList[chn] = port_index; jack_log("JackFFADODriver::Attach fCapturePortList[i] %ld ", port_index); fCaptureChannels++; } else if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) { - snprintf(buf, sizeof(buf) - 1, "%s:MC%d_%s", fClientControl.fName, (int)chn, portname); + snprintf(buf, sizeof(buf) - 1, "%s:%s", fClientControl.fName, portname); printMessage ("Registering midi capture port %s", buf); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, - (JackPortFlags)port_flags, + CaptureDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", buf); return -1; @@ -489,8 +488,6 @@ int JackFFADODriver::Attach() } // playback - port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; - driver->playback_nchannels = ffado_streaming_get_nb_playback_streams(driver->dev); driver->playback_channels = (ffado_playback_channel_t *)calloc(driver->playback_nchannels, sizeof(ffado_playback_channel_t)); if (driver->playback_channels == NULL) { @@ -505,11 +502,11 @@ int JackFFADODriver::Attach() driver->playback_channels[chn].stream_type = ffado_streaming_get_playback_stream_type(driver->dev, chn); if (driver->playback_channels[chn].stream_type == ffado_stream_type_audio) { - snprintf(buf, sizeof(buf) - 1, "%s:AP%d_%s", fClientControl.fName, (int)chn, portname); + snprintf(buf, sizeof(buf) - 1, "%s:%s", fClientControl.fName, portname); printMessage ("Registering audio playback port %s", buf); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, - (JackPortFlags)port_flags, + PlaybackDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", buf); return -1; @@ -526,15 +523,18 @@ int JackFFADODriver::Attach() port = fGraphManager->GetPort(port_index); // Add one buffer more latency if "async" mode is used... port->SetLatency((driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency); + // playback port aliases (jackd1 style port names) + snprintf(buf, sizeof(buf) - 1, "%s:playback_%i", fClientControl.fName, (int) chn + 1); + port->SetAlias(buf); fPlaybackPortList[chn] = port_index; jack_log("JackFFADODriver::Attach fPlaybackPortList[i] %ld ", port_index); fPlaybackChannels++; } else if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) { - snprintf(buf, sizeof(buf) - 1, "%s:MP%d_%s", fClientControl.fName, (int)chn, portname); + snprintf(buf, sizeof(buf) - 1, "%s:%s", fClientControl.fName, portname); printMessage ("Registering midi playback port %s", buf); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, - (JackPortFlags)port_flags, + PlaybackDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", buf); return -1; diff --git a/linux/freebob/JackFreebobDriver.cpp b/linux/freebob/JackFreebobDriver.cpp index c5d5770a..348e4635 100644 --- a/linux/freebob/JackFreebobDriver.cpp +++ b/linux/freebob/JackFreebobDriver.cpp @@ -667,8 +667,7 @@ int JackFreebobDriver::Attach() { JackPort* port; int port_index; - unsigned long port_flags; - + char buf[JACK_PORT_NAME_SIZE]; char portname[JACK_PORT_NAME_SIZE]; @@ -717,8 +716,6 @@ int JackFreebobDriver::Attach() /* ports */ // capture - port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; - driver->capture_nchannels = freebob_streaming_get_nb_capture_streams(driver->dev); driver->capture_nchannels_audio = 0; @@ -734,7 +731,7 @@ int JackFreebobDriver::Attach() if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, - (JackPortFlags)port_flags, + CaptureDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", buf); return -1; @@ -748,8 +745,6 @@ int JackFreebobDriver::Attach() } // playback - port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; - driver->playback_nchannels = freebob_streaming_get_nb_playback_streams(driver->dev); driver->playback_nchannels_audio = 0; @@ -764,7 +759,7 @@ int JackFreebobDriver::Attach() printMessage ("Registering playback port %s", buf); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, - (JackPortFlags)port_flags, + PlaybackDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", buf); return -1; diff --git a/macosx/Jack-Info.plist b/macosx/Jack-Info.plist index 8b6a61de..ce9bac00 100644 --- a/macosx/Jack-Info.plist +++ b/macosx/Jack-Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable Jackservermp CFBundleGetInfoString - Jackdmp 1.9.5, @03-09 Paul Davis, Grame + Jackdmp 1.9.6, @03-10 Paul Davis, Grame CFBundleIdentifier com.grame.Jackmp CFBundleInfoDictionaryVersion @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.9.5 + 1.9.6 diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index 461f827b..d4e6c7f0 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -580,6 +580,18 @@ 4B80D7EB0BA0D17400F035BB /* JackMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */; }; 4B80D7EC0BA0D17400F035BB /* JackMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */; }; 4B80D7ED0BA0D17400F035BB /* JackMidiAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */; }; + 4B88D03B11298BEE007A87C1 /* weakjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03911298BEE007A87C1 /* weakjack.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B88D03C11298BEE007A87C1 /* weakmacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03A11298BEE007A87C1 /* weakmacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B88D03D11298BEE007A87C1 /* weakjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03911298BEE007A87C1 /* weakjack.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B88D03E11298BEE007A87C1 /* weakmacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03A11298BEE007A87C1 /* weakmacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B88D03F11298BEE007A87C1 /* weakjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03911298BEE007A87C1 /* weakjack.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B88D04011298BEE007A87C1 /* weakmacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03A11298BEE007A87C1 /* weakmacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B88D04111298BEE007A87C1 /* weakjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03911298BEE007A87C1 /* weakjack.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B88D04211298BEE007A87C1 /* weakmacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03A11298BEE007A87C1 /* weakmacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B88D04311298BEE007A87C1 /* weakjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03911298BEE007A87C1 /* weakjack.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B88D04411298BEE007A87C1 /* weakmacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03A11298BEE007A87C1 /* weakmacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B88D04511298BEE007A87C1 /* weakjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03911298BEE007A87C1 /* weakjack.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B88D04611298BEE007A87C1 /* weakmacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03A11298BEE007A87C1 /* weakmacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B93F1990E87992100E4ECCD /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; 4B93F19A0E87992200E4ECCD /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; 4B93F19C0E87998200E4ECCD /* JackPosixServerLaunch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBBA0E878B9C003D2374 /* JackPosixServerLaunch.cpp */; }; @@ -1567,6 +1579,8 @@ 4B869B3D08C8D21C001CF041 /* driver_interface.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = driver_interface.h; path = ../common/driver_interface.h; sourceTree = SOURCE_ROOT; }; 4B869B4208C8D22F001CF041 /* JackDriverLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackDriverLoader.h; path = ../common/JackDriverLoader.h; sourceTree = SOURCE_ROOT; }; 4B869D7F08C9CB00001CF041 /* JackDriverLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackDriverLoader.cpp; path = ../common/JackDriverLoader.cpp; sourceTree = SOURCE_ROOT; }; + 4B88D03911298BEE007A87C1 /* weakjack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = weakjack.h; path = ../common/jack/weakjack.h; sourceTree = SOURCE_ROOT; }; + 4B88D03A11298BEE007A87C1 /* weakmacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = weakmacros.h; path = ../common/jack/weakmacros.h; sourceTree = SOURCE_ROOT; }; 4B89B759076B731100D170DE /* JackRPCClientUser.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = JackRPCClientUser.c; path = RPC/JackRPCClientUser.c; sourceTree = SOURCE_ROOT; }; 4B89B769076B74D200D170DE /* JackRPCEngineUser.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = JackRPCEngineUser.c; path = RPC/JackRPCEngineUser.c; sourceTree = SOURCE_ROOT; }; 4B940B9B06DDDE5B00D77F60 /* AudioHardware.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AudioHardware.h; path = /System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/AudioHardware.h; sourceTree = ""; }; @@ -2711,6 +2725,8 @@ 4B6C737D0CC60A6D001AFFD4 /* thread.h */, 4B6C737E0CC60A6D001AFFD4 /* transport.h */, 4B6C737F0CC60A6D001AFFD4 /* types.h */, + 4B88D03911298BEE007A87C1 /* weakjack.h */, + 4B88D03A11298BEE007A87C1 /* weakmacros.h */, ); name = jack; path = ../common/jack; @@ -3159,6 +3175,8 @@ 4B4F9C910DC20C0400706CB0 /* JackMessageBuffer.h in Headers */, 4B93F19E0E87998400E4ECCD /* JackPosixThread.h in Headers */, 4BECB2FA0F4451C10091B70A /* JackProcessSync.h in Headers */, + 4B88D03F11298BEE007A87C1 /* weakjack.h in Headers */, + 4B88D04011298BEE007A87C1 /* weakmacros.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3227,6 +3245,8 @@ 4BDCDC0A1001FDA800B15929 /* JackArgParser.h in Headers */, 4BCBCE6210C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */, 4BCBCE6410C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */, + 4B88D04311298BEE007A87C1 /* weakjack.h in Headers */, + 4B88D04411298BEE007A87C1 /* weakmacros.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3507,6 +3527,8 @@ 4B47ACA910B5890100469C67 /* JackMessageBuffer.h in Headers */, 4B47ACAA10B5890100469C67 /* JackPosixThread.h in Headers */, 4B47ACAB10B5890100469C67 /* JackProcessSync.h in Headers */, + 4B88D04111298BEE007A87C1 /* weakjack.h in Headers */, + 4B88D04211298BEE007A87C1 /* weakmacros.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3592,6 +3614,8 @@ 4BC3B6A50E703B2E0066E42F /* JackPosixThread.h in Headers */, 4BECB2F80F4451C10091B70A /* JackProcessSync.h in Headers */, 4B94334A10A5E666002A187F /* systemdeps.h in Headers */, + 4B88D03B11298BEE007A87C1 /* weakjack.h in Headers */, + 4B88D03C11298BEE007A87C1 /* weakmacros.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3664,6 +3688,8 @@ 4B94334B10A5E666002A187F /* systemdeps.h in Headers */, 4BCBCE5E10C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */, 4BCBCE6010C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */, + 4B88D03D11298BEE007A87C1 /* weakjack.h in Headers */, + 4B88D03E11298BEE007A87C1 /* weakmacros.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3841,6 +3867,8 @@ 4BA3396F10B2E36800190E3B /* JackArgParser.h in Headers */, 4BCBCE6610C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */, 4BCBCE6810C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */, + 4B88D04511298BEE007A87C1 /* weakjack.h in Headers */, + 4B88D04611298BEE007A87C1 /* weakmacros.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 2143170f..2441375c 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -1560,8 +1560,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]; - unsigned long port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; - + jack_log("JackCoreAudioDriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); for (int i = 0; i < fCaptureChannels; i++) { @@ -1580,7 +1579,7 @@ int JackCoreAudioDriver::Attach() snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("Cannot register port for %s", name); return -1; } @@ -1601,8 +1600,6 @@ int JackCoreAudioDriver::Attach() fCapturePortList[i] = port_index; } - port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; - for (int i = 0; i < fPlaybackChannels; i++) { err = AudioDeviceGetPropertyInfo(fDeviceID, i + 1, false, kAudioDevicePropertyChannelName, &size, &isWritable); @@ -1619,7 +1616,7 @@ int JackCoreAudioDriver::Attach() snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("Cannot register port for %s", name); return -1; } @@ -1644,7 +1641,7 @@ int JackCoreAudioDriver::Attach() if (fWithMonitorPorts) { jack_log("Create monitor port "); snprintf(name, sizeof(name) - 1, "%s:monitor_%u", fClientControl.fName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, MonitorDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("Cannot register monitor port for %s", name); return -1; } else { diff --git a/macosx/coremidi/JackCoreMidiDriver.cpp b/macosx/coremidi/JackCoreMidiDriver.cpp index 08bd8c80..0f52e900 100644 --- a/macosx/coremidi/JackCoreMidiDriver.cpp +++ b/macosx/coremidi/JackCoreMidiDriver.cpp @@ -222,7 +222,6 @@ int JackCoreMidiDriver::Attach() char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char endpoint_name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - unsigned long port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; int i; jack_log("JackCoreMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); @@ -239,7 +238,7 @@ int JackCoreMidiDriver::Attach() } snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", name); return -1; } @@ -249,8 +248,6 @@ int JackCoreMidiDriver::Attach() jack_log("JackCoreMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index); } - port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; - for (i = 0; i < fPlaybackChannels; i++) { err = MIDIObjectGetStringProperty(fMidiSource[i], kMIDIPropertyName, &pname); @@ -263,7 +260,7 @@ int JackCoreMidiDriver::Attach() } snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", name); return -1; } diff --git a/posix/JackNetUnixSocket.cpp b/posix/JackNetUnixSocket.cpp index 7649ca8c..d110c5c9 100644 --- a/posix/JackNetUnixSocket.cpp +++ b/posix/JackNetUnixSocket.cpp @@ -99,6 +99,13 @@ namespace Jack Reset(); } fSockfd = socket ( AF_INET, SOCK_DGRAM, 0 ); + + /* Enable address reuse */ + int res, on = 1; + if ((res = setsockopt( fSockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) < 0) { + StrError(NET_ERROR_CODE); + } + return fSockfd; } diff --git a/posix/JackPosixMutex.h b/posix/JackPosixMutex.h index 91d21132..ddf89553 100644 --- a/posix/JackPosixMutex.h +++ b/posix/JackPosixMutex.h @@ -103,11 +103,12 @@ class JackPosixMutex pthread_mutex_destroy(&fMutex); } - void Lock() + bool Lock() { int res = pthread_mutex_lock(&fMutex); if (res != 0) jack_error("JackPosixMutex::Lock res = %d", res); + return (res == 0); } bool Trylock() @@ -115,11 +116,12 @@ class JackPosixMutex return (pthread_mutex_trylock(&fMutex) == 0); } - void Unlock() + bool Unlock() { int res = pthread_mutex_unlock(&fMutex); if (res != 0) jack_error("JackPosixMutex::Unlock res = %d", res); + return (res == 0); } }; diff --git a/tests/test.cpp b/tests/test.cpp index 018b7499..4e025c01 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -183,7 +183,7 @@ void Jack_Client_Registration_Callback(const char* name, int val, void *arg) int Jack_Port_Rename_Callback(jack_port_id_t port, const char* old_name, const char* new_name, void *arg) { - Log("Rename callback has been successfully called with old_name '%s' and new_name '%s'. (msg from callback)\n"); + Log("Rename callback has been successfully called with old_name '%s' and new_name '%s'. (msg from callback)\n", old_name, new_name); port_rename_clbk = 1; return 0; } @@ -822,6 +822,8 @@ int main (int argc, char *argv[]) printf("error : port_set_name function can't be tested...\n"); } + port_callback_reg = 0; // number of port registration received by the callback + /** * Activate the client * @@ -840,6 +842,20 @@ int main (int argc, char *argv[]) if (port_rename_clbk == 0) printf("!!! ERROR !!! Jack_Port_Rename_Callback was not called !!.\n"); + + + /** + * Test if portregistration callback have been called. + * + */ + + jack_sleep(1 * 1000); + + if (1 == port_callback_reg) { + Log("%i ports have been successfully created, and %i callback reg ports have been received... ok\n", 1, port_callback_reg); + } else { + printf("!!! ERROR !!! %i ports have been created, and %i callback reg ports have been received !\n", 1, port_callback_reg); + } /** * Test if init callback initThread have been called. @@ -1095,11 +1111,14 @@ int main (int argc, char *argv[]) } jack_sleep(1 * 1000); // To hope all port registration and reorder callback have been received... + + // Check port registration callback if (j == port_callback_reg) { Log("%i ports have been successfully created, and %i callback reg ports have been received... ok\n", j, port_callback_reg); } else { - printf("!!! ERROR !!! %i ports have been created, and %i callback reg ports have been received !\n", j, k); + printf("!!! ERROR !!! %i ports have been created, and %i callback reg ports have been received !\n", j, port_callback_reg); } + if (reorder == (2 * j)) { Log("%i graph reorder callback have been received... ok\n", reorder); } else { @@ -1147,6 +1166,7 @@ int main (int argc, char *argv[]) * Deregister all ports previously created. * */ + port_callback_reg = 0; // to check registration callback Log("Deregistering all ports of the client...\n"); inports = jack_get_ports(client1, NULL, NULL, 0); a = 0; @@ -1160,6 +1180,13 @@ int main (int argc, char *argv[]) } a++; } + + // Check port registration callback again + if (j == port_callback_reg) { + Log("%i ports have been successfully created, and %i callback reg ports have been received... ok\n", j, port_callback_reg); + } else { + printf("!!! ERROR !!! %i ports have been created, and %i callback reg ports have been received !\n", j, port_callback_reg); + } free(inports); // free array of ports (as mentionned in the doc of jack_get_ports) diff --git a/windows/JackRouter/resource.rc b/windows/JackRouter/resource.rc index 4289ddc2..e1580227 100644 --- a/windows/JackRouter/resource.rc +++ b/windows/JackRouter/resource.rc @@ -28,8 +28,8 @@ LANGUAGE LANG_FRENCH, SUBLANG_FRENCH // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,2,0,0 - PRODUCTVERSION 0,2,0,0 + FILEVERSION 0,2,1,0 + PRODUCTVERSION 0,2,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -47,14 +47,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "JackRouter ASIO driver\0" - VALUE "FileVersion", "0, 2, 0, 0\0" + VALUE "FileVersion", "0, 2, 1, 0\0" VALUE "InternalName", "JackRouter\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "JackRouter.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "JackRouter\0" - VALUE "ProductVersion", "0, 2, 0, 0\0" + VALUE "ProductVersion", "0, 2, 1, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/JackWinMutex.h b/windows/JackWinMutex.h index 422752b6..55434ace 100644 --- a/windows/JackWinMutex.h +++ b/windows/JackWinMutex.h @@ -43,15 +43,15 @@ class JackWinMutex // In recursive mode by default fMutex = (HANDLE)CreateMutex(0, FALSE, 0); } - + virtual ~JackWinMutex() { CloseHandle(fMutex); } - void Lock() + bool Lock() { - WaitForSingleObject(fMutex, INFINITE); + return (WAIT_OBJECT_0 == WaitForSingleObject(fMutex, INFINITE)); } bool Trylock() @@ -59,9 +59,9 @@ class JackWinMutex return (WAIT_OBJECT_0 == WaitForSingleObject(fMutex, 0)); } - void Unlock() + bool Unlock() { - ReleaseMutex(fMutex); + return(ReleaseMutex(fMutex) != 0); } }; diff --git a/windows/Setup/JackRouter.dll b/windows/Setup/JackRouter.dll index f06fe1b66bbb999b6c6f7bacaef4a3ac95d26767..d74a292500d9b170a2a8cb73bce7dec9755fd54b 100644 GIT binary patch delta 195 zcmZo@U}|V!n(%>nx^BtF&p+*LZ!<77@G~+rTmsThfcOm%iv#&*fHW(R76oDfAifUd zn*eDgAbt&GKLz5`n>8JSStvAOr|WMvkZU$?_qi|3$;iOO00NAg=O-vKG8#@km^hQ! SkilSbY|?K=!_AS&%VhvUIyq$k delta 195 zcmZo@U}|V!n(%>H>ww0_&p+*LZ!$16@G>$qTmaIKfcO;8JSStvAOr|WMvkZU$?_qi|3$-uzG00x`qCnz#98caTzIFs3c R!E$nJ(r-qC&5_B=WdH+)INbmM diff --git a/windows/Setup/jack.ci b/windows/Setup/jack.ci index 25233392..df6e3871 100644 --- a/windows/Setup/jack.ci +++ b/windows/Setup/jack.ci @@ -1,9 +1,9 @@ <*project version = 4 civer = "Free v4.14.5" winver = "2.6/5.1.2600" > . - Jack_v1.9.5_setup.exe + Jack_v1.9.6_setup.exe - Jack v1.9.5 + Jack v1.9.6 Default - 2 @@ -92,6 +92,8 @@ <_>..\..\common\jack\transport.hinstincludes\jackovernewer0 <_>..\..\common\jack\types.hinstincludes\jackovernewer0 <_>..\..\common\jack\systemdeps.hinstincludes\jackovernewer1 +<_>..\..\common\jack\weakjack.hinstincludes\jackovernewer1 +<_>..\..\common\jack\weakmacros.hinstincludes\jackovernewer1 <_>.\JackRouter.dllinstovernewer0 <_>.\JackRouter.iniinstovernewer0 <_>.\qjackctl\mingwm10.dllinstovernewer0 diff --git a/windows/jackaudioadapter.rc b/windows/jackaudioadapter.rc index 25d4b155..aa57cf89 100644 --- a/windows/jackaudioadapter.rc +++ b/windows/jackaudioadapter.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,5,0 - PRODUCTVERSION 1,9,5,0 + FILEVERSION 1,9,6,0 + PRODUCTVERSION 1,9,6,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Audio Adapter for Windows\0" - VALUE "FileVersion", "1, 9, 5, 0\0" + VALUE "FileVersion", "1, 9, 6, 0\0" VALUE "InternalName", "audioadapter\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "audioadapter.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "audioadapter\0" - VALUE "ProductVersion", "1, 9, 5, 0\0" + VALUE "ProductVersion", "1, 9, 6, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackd.rc b/windows/jackd.rc index db62e72c..acdd0501 100644 --- a/windows/jackd.rc +++ b/windows/jackd.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,5,0 - PRODUCTVERSION 1,9,5,0 + FILEVERSION 1,9,6,0 + PRODUCTVERSION 1,9,6,0 FILEOS VOS_UNKNOWN FILETYPE VFT_APP BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack server for Windows\0" - VALUE "FileVersion", "1, 9, 5, 0\0" + VALUE "FileVersion", "1, 9, 6, 0\0" VALUE "InternalName", "jackd\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jackd.exe\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jackd\0" - VALUE "ProductVersion", "1, 9, 5, 0\0" + VALUE "ProductVersion", "1, 9, 6, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetadapter.rc b/windows/jacknetadapter.rc index 7488ea91..415b9fbd 100644 --- a/windows/jacknetadapter.rc +++ b/windows/jacknetadapter.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,5,0 - PRODUCTVERSION 1,9,5,0 + FILEVERSION 1,9,6,0 + PRODUCTVERSION 1,9,6,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Adapter for Windows\0" - VALUE "FileVersion", "1, 9, 5, 0\0" + VALUE "FileVersion", "1, 9, 6, 0\0" VALUE "InternalName", "netadapter\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "netadapter.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "netadapter\0" - VALUE "ProductVersion", "1, 9, 5, 0\0" + VALUE "ProductVersion", "1, 9, 6, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetdriver.rc b/windows/jacknetdriver.rc index a98f2fc4..a1157d17 100644 --- a/windows/jacknetdriver.rc +++ b/windows/jacknetdriver.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,5,0 - PRODUCTVERSION 1,9,5,0 + FILEVERSION 1,9,6,0 + PRODUCTVERSION 1,9,6,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Driver for Windows\0" - VALUE "FileVersion", "1, 9, 5, 0\0" + VALUE "FileVersion", "1, 9, 6, 0\0" VALUE "InternalName", "jack_netdriver\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_netdriver.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_netdriver\0" - VALUE "ProductVersion", "1, 9, 5, 0\0" + VALUE "ProductVersion", "1, 9, 6, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetmanager.rc b/windows/jacknetmanager.rc index c440861f..f417048d 100644 --- a/windows/jacknetmanager.rc +++ b/windows/jacknetmanager.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,5,0 - PRODUCTVERSION 1,9,5,0 + FILEVERSION 1,9,6,0 + PRODUCTVERSION 1,9,6,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Manager for Windows\0" - VALUE "FileVersion", "1, 9, 5, 0\0" + VALUE "FileVersion", "1, 9, 6, 0\0" VALUE "InternalName", "netmanager\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "netmanager.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "netmanager\0" - VALUE "ProductVersion", "1, 9, 5, 0\0" + VALUE "ProductVersion", "1, 9, 6, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackportaudio.rc b/windows/jackportaudio.rc index 2c4e66da..df292330 100644 --- a/windows/jackportaudio.rc +++ b/windows/jackportaudio.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,5,0 - PRODUCTVERSION 1,9,5,0 + FILEVERSION 1,9,6,0 + PRODUCTVERSION 1,9,6,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp PortAudio Driver for Windows\0" - VALUE "FileVersion", "1, 9, 5, 0\0" + VALUE "FileVersion", "1, 9, 6, 0\0" VALUE "InternalName", "jack_portaudio\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_portaudio.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_portaudio\0" - VALUE "ProductVersion", "1, 9, 5, 0\0" + VALUE "ProductVersion", "1, 9, 6, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackwinmme.rc b/windows/jackwinmme.rc index 6d8e19f3..a11da0d1 100644 --- a/windows/jackwinmme.rc +++ b/windows/jackwinmme.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,5,0 - PRODUCTVERSION 1,9,5,0 + FILEVERSION 1,9,6,0 + PRODUCTVERSION 1,9,6,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp WinMMEo Driver for Windows\0" - VALUE "FileVersion", "1, 9, 5, 0\0" + VALUE "FileVersion", "1, 9, 6, 0\0" VALUE "InternalName", "jack_portaudio\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_winmme.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_winmme\0" - VALUE "ProductVersion", "1, 9, 5, 0\0" + VALUE "ProductVersion", "1, 9, 6, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/libjack.rc b/windows/libjack.rc index 7beda3d8..b24e3f07 100644 --- a/windows/libjack.rc +++ b/windows/libjack.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,5,0 - PRODUCTVERSION 1,9,5,0 + FILEVERSION 1,9,6,0 + PRODUCTVERSION 1,9,6,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack client library for Windows\0" - VALUE "FileVersion", "1, 9, 5, 0\0" + VALUE "FileVersion", "1, 9, 6, 0\0" VALUE "InternalName", "libjack\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjack.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjack\0" - VALUE "ProductVersion", "1, 9, 5, 0\0" + VALUE "ProductVersion", "1, 9, 6, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/libjackserver.rc b/windows/libjackserver.rc index b62a275e..6fe89a1c 100644 --- a/windows/libjackserver.rc +++ b/windows/libjackserver.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,5,0 - PRODUCTVERSION 1,9,5,0 + FILEVERSION 1,9,6,0 + PRODUCTVERSION 1,9,6,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack server library for Windows\0" - VALUE "FileVersion", "1, 9, 5, 0\0" + VALUE "FileVersion", "1, 9, 56, 0\0" VALUE "InternalName", "libjackserver\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjackserver.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjackserver\0" - VALUE "ProductVersion", "1, 9, 5, 0\0" + VALUE "ProductVersion", "1, 9, 6, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/resource.rc b/windows/resource.rc index e5d5f15c..6b41c2a7 100644 --- a/windows/resource.rc +++ b/windows/resource.rc @@ -14,8 +14,8 @@ LANGUAGE LANG_FRENCH, SUBLANG_FRENCH #ifndef _MAC VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,9,5,0 - PRODUCTVERSION 1,9,5,0 + FILEVERSION 1,9,6,0 + PRODUCTVERSION 1,9,6,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -33,14 +33,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp for Windows\0" - VALUE "FileVersion", "1, 9, 5, 0\0" + VALUE "FileVersion", "1, 9, 6, 0\0" VALUE "InternalName", "libjackmp\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjackmp.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjackmp\0" - VALUE "ProductVersion", "1, 9, 5, 0\0" + VALUE "ProductVersion", "1, 9, 6, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/winmme/JackWinMMEDriver.cpp b/windows/winmme/JackWinMMEDriver.cpp index 65a7de65..b76a8299 100644 --- a/windows/winmme/JackWinMMEDriver.cpp +++ b/windows/winmme/JackWinMMEDriver.cpp @@ -289,7 +289,6 @@ int JackWinMMEDriver::Attach() jack_port_id_t port_index; char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - unsigned long port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; MMRESULT res; int i; @@ -305,7 +304,7 @@ int JackWinMMEDriver::Attach() } snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", name); return -1; } @@ -315,8 +314,6 @@ int JackWinMMEDriver::Attach() jack_log("JackMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index); } - port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; - for (i = 0; i < fPlaybackChannels; i++) { MIDIOUTCAPS caps; res = midiOutGetDevCaps(fMidiSource[i].fIndex, &caps, sizeof(caps)); @@ -327,7 +324,7 @@ int JackWinMMEDriver::Attach() } snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", name); return -1; } diff --git a/wscript b/wscript index 33469397..5ced3c2c 100644 --- a/wscript +++ b/wscript @@ -11,7 +11,7 @@ import Task import re import Logs -VERSION='1.9.4' +VERSION='1.9.6' APPNAME='jack' JACK_API_VERSION = '0.1.0' From 32a7808346bfe3c896cec2ac564634e09b6940f0 Mon Sep 17 00:00:00 2001 From: sletz Date: Thu, 18 Feb 2010 11:12:29 +0000 Subject: [PATCH 028/472] Compile again on Snow Leopard. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3918 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackAudioAdapterInterface.cpp | 4 ++-- common/JackFilters.h | 2 +- common/JackNetAPI.cpp | 2 +- macosx/JackMachThread.cpp | 4 ++-- macosx/JackMachThread.h | 6 +++--- macosx/JackPlatformPlug_os.h | 11 +++++++++-- macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj | 8 ++++++++ macosx/iphone/iPhoneNet_Prefix.pch | 2 ++ 8 files changed, 28 insertions(+), 11 deletions(-) diff --git a/common/JackAudioAdapterInterface.cpp b/common/JackAudioAdapterInterface.cpp index f765d032..fed62e03 100644 --- a/common/JackAudioAdapterInterface.cpp +++ b/common/JackAudioAdapterInterface.cpp @@ -22,7 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #endif #include "JackAudioAdapter.h" -#ifndef TARGET_OS_IPHONE +#ifndef MY_TARGET_OS_IPHONE #include "JackLibSampleRateResampler.h" #endif #include "JackTime.h" @@ -194,7 +194,7 @@ namespace Jack fRunning = false; } -#ifdef TARGET_OS_IPHONE +#ifdef MY_TARGET_OS_IPHONE void JackAudioAdapterInterface::Create() {} #else diff --git a/common/JackFilters.h b/common/JackFilters.h index ad2afecc..ac9de9f9 100644 --- a/common/JackFilters.h +++ b/common/JackFilters.h @@ -25,7 +25,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #endif #include "jack.h" -#ifndef TARGET_OS_IPHONE +#ifndef MY_TARGET_OS_IPHONE #include "JackAtomicState.h" #endif #include diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 185e0da6..d8833e09 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -877,7 +877,7 @@ SERVER_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** in } -#ifdef TARGET_OS_IPHONE +#ifdef MY_TARGET_OS_IPHONE static void jack_format_and_log(int level, const char *prefix, const char *fmt, va_list ap) { diff --git a/macosx/JackMachThread.cpp b/macosx/JackMachThread.cpp index 9692bdb9..61b67b43 100644 --- a/macosx/JackMachThread.cpp +++ b/macosx/JackMachThread.cpp @@ -31,7 +31,7 @@ int JackMachThread::SetThreadToPriority(pthread_t thread, UInt32 inPriority, Boo // REAL-TIME / TIME-CONSTRAINT THREAD thread_time_constraint_policy_data_t theTCPolicy; -#ifdef TARGET_OS_IPHONE +#ifdef MY_TARGET_OS_IPHONE theTCPolicy.period = 0; theTCPolicy.computation = 0; theTCPolicy.constraint = 0; @@ -138,7 +138,7 @@ int JackMachThread::GetParams(pthread_t thread, UInt64* period, UInt64* computat &count, &get_default); if (res == KERN_SUCCESS) { - #ifdef TARGET_OS_IPHONE + #ifdef MY_TARGET_OS_IPHONE *period = 0; *computation = 0; *constraint = 0; diff --git a/macosx/JackMachThread.h b/macosx/JackMachThread.h index ac96f4a0..d25331d2 100644 --- a/macosx/JackMachThread.h +++ b/macosx/JackMachThread.h @@ -63,19 +63,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include -#ifdef TARGET_OS_IPHONE +#ifdef MY_TARGET_OS_IPHONE typedef unsigned char Boolean; #endif #include "JackPosixThread.h" -#ifndef TARGET_OS_IPHONE +#ifndef MY_TARGET_OS_IPHONE #import #endif #include #include -#ifndef TARGET_OS_IPHONE +#ifndef MY_TARGET_OS_IPHONE #include #endif diff --git a/macosx/JackPlatformPlug_os.h b/macosx/JackPlatformPlug_os.h index df7f0175..d8cc1ca3 100644 --- a/macosx/JackPlatformPlug_os.h +++ b/macosx/JackPlatformPlug_os.h @@ -33,6 +33,13 @@ namespace Jack class JackMachServerNotifyChannel; class JackMachNotifyChannel; class JackNetUnixSocket; + +#ifdef MY_TARGET_OS_IPHONE + class JackClient; + class JackGraphManager; + class JackEngineControl; + class JackSynchro; +#endif } /* __JackPlatformMutex__ */ @@ -44,7 +51,7 @@ namespace Jack { typedef JackPosixMutex JackMutex; } namespace Jack { typedef JackMachThread JackThread; } /* __JackPlatformSynchro__ client activation */ -#ifndef TARGET_OS_IPHONE +#ifndef MY_TARGET_OS_IPHONE #include "JackMachSemaphore.h" namespace Jack { typedef JackMachSemaphore JackSynchro; } #endif @@ -53,7 +60,7 @@ namespace Jack { typedef JackMachSemaphore JackSynchro; } #include "JackProcessSync.h" /* Only on windows a special JackProcessSync is used. It is directly defined by including JackProcessSync.h here */ -#ifndef TARGET_OS_IPHONE +#ifndef MY_TARGET_OS_IPHONE /* __JackPlatformServerChannel__ */ #include "JackMachServerChannel.h" namespace Jack { typedef JackMachServerChannel JackServerChannel; } diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj index a1211fef..71611610 100755 --- a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -719,6 +719,7 @@ COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( ../../common/jack, ../../common, @@ -739,6 +740,13 @@ COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + HEADER_SEARCH_PATHS = ( + ../../macosx, + ../../posix, + ../../common, + ../../common/jack, + ); PREBINDING = NO; PRODUCT_NAME = jacknet; ZERO_LINK = NO; diff --git a/macosx/iphone/iPhoneNet_Prefix.pch b/macosx/iphone/iPhoneNet_Prefix.pch index 8de611d5..55c63732 100644 --- a/macosx/iphone/iPhoneNet_Prefix.pch +++ b/macosx/iphone/iPhoneNet_Prefix.pch @@ -6,3 +6,5 @@ #import #import #endif + +#define MY_TARGET_OS_IPHONE 1 From a449e6e1fa1adc1262d69096fda904204addf387 Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 24 Feb 2010 14:46:29 +0000 Subject: [PATCH 029/472] Cleanup. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3920 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackEngineProfiling.cpp | 2 +- common/JackNetAPI.cpp | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/common/JackEngineProfiling.cpp b/common/JackEngineProfiling.cpp index 4557fec9..de9d451d 100644 --- a/common/JackEngineProfiling.cpp +++ b/common/JackEngineProfiling.cpp @@ -67,7 +67,7 @@ JackEngineProfiling::~JackEngineProfiling() int ref = fIntervalTable[j].fRefNum; // Is valid client cycle - if (fProfileTable[i].fClientTable[ref].fStatus != NotTriggered) { + if (fProfileTable[i].fClientTable[ref].fStatus != NotTriggered) { long d5 = long(fProfileTable[i].fClientTable[ref].fSignaledAt - fProfileTable[i - 1].fCurCycleBegin); long d6 = long(fProfileTable[i].fClientTable[ref].fAwakeAt - fProfileTable[i - 1].fCurCycleBegin); diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index d8833e09..708c26e5 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -23,7 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackError.h" #include "JackTime.h" #include "JackException.h" - #include "JackAudioAdapterInterface.h" #ifdef __cplusplus @@ -242,7 +241,7 @@ struct JackNetExtMaster : public JackNetMasterInterface { int MasterInit() { - // Check MASTER <<==> SLAVE network protocol coherency + // Check MASTER <==> SLAVE network protocol coherency if (fParams.fProtocolVersion != MASTER_PROTOCOL) { fprintf(stderr, "Error : slave is running with a different protocol %s\n", fParams.fName); return -1; @@ -355,7 +354,6 @@ struct JackNetExtMaster : public JackNetMasterInterface { return 0; DecodeSyncPacket(); - return DataRecv(); } @@ -615,7 +613,6 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf return 0; DecodeSyncPacket(); - return DataRecv(); } From 5dd1940b9d2e1f7e39abe8592256c5255611c562 Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 24 Feb 2010 14:51:34 +0000 Subject: [PATCH 030/472] Better error handling. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3921 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetAPI.cpp | 77 +++++----- common/JackResampler.cpp | 28 ++++ common/JackResampler.h | 3 + macosx/JackMachThread.cpp | 21 +-- macosx/coreaudio/JackCoreAudioAdapter.h | 2 +- .../iPhoneNet.xcodeproj/project.pbxproj | 135 ++++++++++++++++++ macosx/iphone/main_master.mm | 6 +- 7 files changed, 227 insertions(+), 45 deletions(-) diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 708c26e5..655c8deb 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -194,7 +194,7 @@ struct JackNetExtMaster : public JackNetMasterInterface { SessionParamsNToH(&net_params, &fParams); if ((rx_bytes == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) { - fprintf(stderr, "Error in receive : %s\n", StrError(NET_ERROR_CODE)); + fprintf(stderr, "Error in receive : %s\n", StrError(NET_ERROR_CODE)); if (++attempt == 10) { fprintf(stderr, "Can't receive on the socket, exiting net manager.\n" ); goto error; @@ -339,43 +339,55 @@ struct JackNetExtMaster : public JackNetMasterInterface { int Read(int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer) { - assert((unsigned int)audio_input == fParams.fSendAudioChannels); - int port_index; - - for (port_index = 0; port_index < audio_input; port_index++) { - fNetAudioPlaybackBuffer->SetBuffer(port_index, audio_input_buffer[port_index]); - } - - for (port_index = 0; port_index < midi_input; port_index++) { - fNetMidiPlaybackBuffer->SetBuffer(port_index, ((JackMidiBuffer**)midi_input_buffer)[port_index]); - } - - if (SyncRecv() == SOCKET_ERROR) - return 0; + try { + assert((unsigned int)audio_input == fParams.fSendAudioChannels); + int port_index; + + for (port_index = 0; port_index < audio_input; port_index++) { + fNetAudioPlaybackBuffer->SetBuffer(port_index, audio_input_buffer[port_index]); + } + + for (port_index = 0; port_index < midi_input; port_index++) { + fNetMidiPlaybackBuffer->SetBuffer(port_index, ((JackMidiBuffer**)midi_input_buffer)[port_index]); + } + + if (SyncRecv() == SOCKET_ERROR) + return 0; - DecodeSyncPacket(); - return DataRecv(); + DecodeSyncPacket(); + return DataRecv(); + + } catch (JackNetException& e) { + jack_error("Connection lost."); + return -1; + } } int Write(int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer) { - assert((unsigned int)audio_output == fParams.fReturnAudioChannels); - int port_index; - - for (port_index = 0; port_index < audio_output; port_index++) { - fNetAudioCaptureBuffer->SetBuffer(port_index, audio_output_buffer[port_index]); - } + try { + assert((unsigned int)audio_output == fParams.fReturnAudioChannels); + int port_index; + + for (port_index = 0; port_index < audio_output; port_index++) { + fNetAudioCaptureBuffer->SetBuffer(port_index, audio_output_buffer[port_index]); + } + + for (port_index = 0; port_index < midi_output; port_index++) { + fNetMidiCaptureBuffer->SetBuffer(port_index, ((JackMidiBuffer**)midi_output_buffer)[port_index]); + } + + EncodeSyncPacket(); - for (port_index = 0; port_index < midi_output; port_index++) { - fNetMidiCaptureBuffer->SetBuffer(port_index, ((JackMidiBuffer**)midi_output_buffer)[port_index]); - } - - EncodeSyncPacket(); - - if (SyncSend() == SOCKET_ERROR) - return SOCKET_ERROR; + if (SyncSend() == SOCKET_ERROR) + return SOCKET_ERROR; - return DataSend(); + return DataSend(); + + } catch (JackNetException& e) { + jack_error("Connection lost."); + return -1; + } } // Transport @@ -898,7 +910,8 @@ SERVER_EXPORT void jack_error(const char *fmt, ...) va_list ap; va_start(ap, fmt); jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); - va_end(ap);} + va_end(ap); +} SERVER_EXPORT void jack_info(const char *fmt, ...) { diff --git a/common/JackResampler.cpp b/common/JackResampler.cpp index fb1793d4..b6c1917c 100644 --- a/common/JackResampler.cpp +++ b/common/JackResampler.cpp @@ -81,6 +81,34 @@ unsigned int JackResampler::Write(float* buffer, unsigned int frames) } } +unsigned int JackResampler::Read(void* buffer, unsigned int bytes) +{ + size_t len = jack_ringbuffer_read_space(fRingBuffer); + jack_log("JackResampler::Read input available = %ld", len); + + if (len < bytes) { + jack_error("JackResampler::Read : producer too slow, missing bytes = %d", bytes); + return 0; + } else { + jack_ringbuffer_read(fRingBuffer, (char*)buffer, bytes); + return bytes; + } +} + +unsigned int JackResampler::Write(void* buffer, unsigned int bytes) +{ + size_t len = jack_ringbuffer_write_space(fRingBuffer); + jack_log("JackResampler::Write output available = %ld", len); + + if (len < bytes) { + jack_error("JackResampler::Write : consumer too slow, skip bytes = %d", bytes); + return 0; + } else { + jack_ringbuffer_write(fRingBuffer, (char*)buffer, bytes); + return bytes; + } +} + unsigned int JackResampler::ReadResample(float* buffer, unsigned int frames) { return Read(buffer, frames); diff --git a/common/JackResampler.h b/common/JackResampler.h index 521f5139..bfb93f04 100644 --- a/common/JackResampler.h +++ b/common/JackResampler.h @@ -60,6 +60,9 @@ class JackResampler virtual unsigned int Read(float* buffer, unsigned int frames); virtual unsigned int Write(float* buffer, unsigned int frames); + virtual unsigned int Read(void* buffer, unsigned int bytes); + virtual unsigned int Write(void* buffer, unsigned int bytes); + virtual unsigned int ReadSpace(); virtual unsigned int WriteSpace(); diff --git a/macosx/JackMachThread.cpp b/macosx/JackMachThread.cpp index 61b67b43..0faaf941 100644 --- a/macosx/JackMachThread.cpp +++ b/macosx/JackMachThread.cpp @@ -22,6 +22,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackMachThread.h" #include "JackError.h" +#include "/Developer/Extras/CoreAudio/PublicUtility/CAHostTimeBase.h" + namespace Jack { @@ -32,17 +34,16 @@ int JackMachThread::SetThreadToPriority(pthread_t thread, UInt32 inPriority, Boo thread_time_constraint_policy_data_t theTCPolicy; #ifdef MY_TARGET_OS_IPHONE - theTCPolicy.period = 0; - theTCPolicy.computation = 0; - theTCPolicy.constraint = 0; + theTCPolicy.period = CAHostTimeBase::ConvertFromNanos(period); + theTCPolicy.computation = CAHostTimeBase::ConvertFromNanos(computation); + theTCPolicy.constraint = CAHostTimeBase::ConvertFromNanos(constraint); #else theTCPolicy.period = AudioConvertNanosToHostTime(period); theTCPolicy.computation = AudioConvertNanosToHostTime(computation); theTCPolicy.constraint = AudioConvertNanosToHostTime(constraint); - #endif theTCPolicy.preemptible = true; - kern_return_t res = thread_policy_set(pthread_mach_thread_np(thread), THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t) & theTCPolicy, THREAD_TIME_CONSTRAINT_POLICY_COUNT); + kern_return_t res = thread_policy_set(pthread_mach_thread_np(thread), THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t) &theTCPolicy, THREAD_TIME_CONSTRAINT_POLICY_COUNT); jack_log("JackMachThread::thread_policy_set res = %ld", res); return (res == KERN_SUCCESS) ? 0 : -1; } else { @@ -65,7 +66,7 @@ int JackMachThread::SetThreadToPriority(pthread_t thread, UInt32 inPriority, Boo relativePriority = inPriority - GetThreadSetPriority(pthread_self()); thePrecedencePolicy.importance = relativePriority; - kern_return_t res = thread_policy_set(pthread_mach_thread_np(thread), THREAD_PRECEDENCE_POLICY, (thread_policy_t) & thePrecedencePolicy, THREAD_PRECEDENCE_POLICY_COUNT); + kern_return_t res = thread_policy_set(pthread_mach_thread_np(thread), THREAD_PRECEDENCE_POLICY, (thread_policy_t) &thePrecedencePolicy, THREAD_PRECEDENCE_POLICY_COUNT); jack_log("JackMachThread::thread_policy_set res = %ld", res); return (res == KERN_SUCCESS) ? 0 : -1; } @@ -139,9 +140,9 @@ int JackMachThread::GetParams(pthread_t thread, UInt64* period, UInt64* computat &get_default); if (res == KERN_SUCCESS) { #ifdef MY_TARGET_OS_IPHONE - *period = 0; - *computation = 0; - *constraint = 0; + *period = CAHostTimeBase::ConvertToNanos(theTCPolicy.period); + *computation = CAHostTimeBase::ConvertToNanos(theTCPolicy.computation); + *constraint = CAHostTimeBase::ConvertToNanos(theTCPolicy.constraint); #else *period = AudioConvertHostTimeToNanos(theTCPolicy.period); *computation = AudioConvertHostTimeToNanos(theTCPolicy.computation); @@ -179,7 +180,7 @@ int JackMachThread::AcquireRealTime() int JackMachThread::AcquireSelfRealTime() { - jack_log("JackMachThread::AcquireRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld", + jack_log("JackMachThread::AcquireSelfRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld", long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000)); return AcquireRealTimeImp(pthread_self(), fPeriod, fComputation, fConstraint); } diff --git a/macosx/coreaudio/JackCoreAudioAdapter.h b/macosx/coreaudio/JackCoreAudioAdapter.h index 8ef6e4d2..f002933f 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.h +++ b/macosx/coreaudio/JackCoreAudioAdapter.h @@ -136,7 +136,7 @@ class JackCoreAudioAdapter : public JackAudioAdapterInterface public: - JackCoreAudioAdapter( jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params); + JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params); ~JackCoreAudioAdapter() {} diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj index 71611610..0eeabc23 100755 --- a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -76,6 +76,13 @@ 4B4146AB10BD3C4300C12F0C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 4B4146AC10BD3C4300C12F0C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; 4BBDC8FA0F5420C000465F9C /* freeverb.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BBDC8F90F5420C000465F9C /* freeverb.mm */; }; + 4BCB37B6112D647C008C7BC1 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; + 4BCB37C7112D647C008C7BC1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 4BCB37C8112D647C008C7BC1 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 4BCB37C9112D647C008C7BC1 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 4BCB37CA112D647C008C7BC1 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; + 4BCB37D6112D64B4008C7BC1 /* HardwareClock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCB37D5112D64B4008C7BC1 /* HardwareClock.cpp */; }; + 4BCB37D9112D64D8008C7BC1 /* iphone-faust.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */; }; 4BCF75DA10BC2FD90082C526 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 4BCF75DC10BC2FD90082C526 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; }; 4BCF75DD10BC2FD90082C526 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93870F49B0E300D3626B /* JackMachTime.c */; }; @@ -103,6 +110,12 @@ 4BF1364F0F4B0F7700218A3F /* JackResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF1364C0F4B0F7700218A3F /* JackResampler.h */; }; 4BF136550F4B0F9F00218A3F /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; 4BF136560F4B0F9F00218A3F /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; + 4BF15E2511356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; + 4BF15E2611356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; + 4BF15E2711356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; + 4BF15E2811356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; + 4BF15E2911356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; + 4BF15E2A11356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; 4BFF45600F4D5D9700106083 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 4BFF45630F4D5D9700106083 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; }; 4BFF45640F4D5D9700106083 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93870F49B0E300D3626B /* JackMachTime.c */; }; @@ -149,6 +162,9 @@ 4B2791870F72570C000536B7 /* JackGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackGlobals.cpp; path = ../../common/JackGlobals.cpp; sourceTree = SOURCE_ROOT; }; 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BBDC8F90F5420C000465F9C /* freeverb.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = freeverb.mm; sourceTree = SOURCE_ROOT; }; + 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaust.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BCB37D5112D64B4008C7BC1 /* HardwareClock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HardwareClock.cpp; sourceTree = SOURCE_ROOT; }; + 4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "iphone-faust.mm"; sourceTree = SOURCE_ROOT; }; 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BCF75F610BC30140082C526 /* audio_thru.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = audio_thru.mm; sourceTree = SOURCE_ROOT; }; 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; }; @@ -156,6 +172,7 @@ 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackResampler.cpp; path = ../../common/JackResampler.cpp; sourceTree = SOURCE_ROOT; }; 4BF1364C0F4B0F7700218A3F /* JackResampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackResampler.h; path = ../../common/JackResampler.h; sourceTree = SOURCE_ROOT; }; 4BF136540F4B0F9F00218A3F /* ringbuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ringbuffer.c; path = ../../common/ringbuffer.c; sourceTree = SOURCE_ROOT; }; + 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CAHostTimeBase.cpp; path = /Developer/Extras/CoreAudio/PublicUtility/CAHostTimeBase.cpp; sourceTree = ""; }; 4BFF45120F4D59DB00106083 /* libjacknet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjacknet.a; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -202,6 +219,17 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BCB37C6112D647C008C7BC1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BCB37C7112D647C008C7BC1 /* Foundation.framework in Frameworks */, + 4BCB37C8112D647C008C7BC1 /* UIKit.framework in Frameworks */, + 4BCB37C9112D647C008C7BC1 /* CoreGraphics.framework in Frameworks */, + 4BCB37CA112D647C008C7BC1 /* AudioToolbox.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BCF75EA10BC2FD90082C526 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -236,6 +264,7 @@ 4B0772380F54018C000DC657 /* iPhoneNetMaster.app */, 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */, 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */, + 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */, ); name = Products; sourceTree = ""; @@ -243,6 +272,9 @@ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { isa = PBXGroup; children = ( + 4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */, + 4BCB37D5112D64B4008C7BC1 /* HardwareClock.cpp */, + 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */, 29B97315FDCFA39411CA2CEA /* Other Sources */, 29B97317FDCFA39411CA2CEA /* Resources */, 29B97323FDCFA39411CA2CEA /* Frameworks */, @@ -390,6 +422,23 @@ productReference = 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */; productType = "com.apple.product-type.application"; }; + 4BCB37B4112D647C008C7BC1 /* iPhoneFaust */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4BCB37CB112D647C008C7BC1 /* Build configuration list for PBXNativeTarget "iPhoneFaust" */; + buildPhases = ( + 4BCB37B5112D647C008C7BC1 /* Resources */, + 4BCB37B7112D647C008C7BC1 /* Sources */, + 4BCB37C6112D647C008C7BC1 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = iPhoneFaust; + productName = iPhoneNet; + productReference = 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */; + productType = "com.apple.product-type.application"; + }; 4BCF75D810BC2FD90082C526 /* iPhoneThruNet */ = { isa = PBXNativeTarget; buildConfigurationList = 4BCF75EF10BC2FD90082C526 /* Build configuration list for PBXNativeTarget "iPhoneThruNet" */; @@ -441,6 +490,7 @@ 4BFF455E0F4D5D9700106083 /* iPhoneFaustNet */, 4BCF75D810BC2FD90082C526 /* iPhoneThruNet */, 4B41469610BD3C4300C12F0C /* iPhoneFaustNet Distribution */, + 4BCB37B4112D647C008C7BC1 /* iPhoneFaust */, 4B1A940F0F49BDE000D3626B /* jacknet */, ); }; @@ -471,6 +521,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BCB37B5112D647C008C7BC1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BCB37B6112D647C008C7BC1 /* MainWindow.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BCF75D910BC2FD90082C526 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -508,6 +566,7 @@ 4B07724A0F54021B000DC657 /* main_slave.mm in Sources */, 4B0773870F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, 4B27918A0F72570C000536B7 /* JackGlobals.cpp in Sources */, + 4BF15E2611356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -529,6 +588,7 @@ 4B0772510F54022D000DC657 /* main_master.mm in Sources */, 4B0773860F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, 4B27918B0F72570C000536B7 /* JackGlobals.cpp in Sources */, + 4BF15E2511356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -568,6 +628,17 @@ 4B4146A510BD3C4300C12F0C /* iPhoneNetAppDelegate.m in Sources */, 4B4146A610BD3C4300C12F0C /* freeverb.mm in Sources */, 4B4146A710BD3C4300C12F0C /* JackGlobals.cpp in Sources */, + 4BF15E2911356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BCB37B7112D647C008C7BC1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BCB37D6112D64B4008C7BC1 /* HardwareClock.cpp in Sources */, + 4BCB37D9112D64D8008C7BC1 /* iphone-faust.mm in Sources */, + 4BF15E2A11356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -589,6 +660,7 @@ 4BCF75E710BC2FD90082C526 /* iPhoneNetAppDelegate.m in Sources */, 4BCF75E910BC2FD90082C526 /* JackGlobals.cpp in Sources */, 4BCF75F710BC30140082C526 /* audio_thru.mm in Sources */, + 4BF15E2811356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -610,6 +682,7 @@ 4B0773880F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, 4BBDC8FA0F5420C000465F9C /* freeverb.mm in Sources */, 4B2791880F72570C000536B7 /* JackGlobals.cpp in Sources */, + 4BF15E2711356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -805,6 +878,59 @@ }; name = Release; }; + 4BCB37CC112D647C008C7BC1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + GCC_THUMB_SUPPORT = NO; + HEADER_SEARCH_PATHS = ( + ../../macosx, + ../../posix, + ../../common/jack, + ../../common, + ); + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 3.1.3; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\\\\\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\\\\\"", + ); + OTHER_LDFLAGS = ""; + PRODUCT_NAME = iPhoneFaust; + SDKROOT = iphoneos3.1.3; + }; + name = Debug; + }; + 4BCB37CD112D647C008C7BC1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + GCC_THUMB_SUPPORT = NO; + HEADER_SEARCH_PATHS = ( + ../../macosx, + ../../common/jack, + ../../common, + ../../posix, + ); + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\\\\\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\\\\\"", + ); + ONLY_ACTIVE_ARCH = NO; + PRODUCT_NAME = iPhoneFaust; + SDKROOT = iphoneos3.1.3; + }; + name = Release; + }; 4BCF75F010BC2FD90082C526 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -969,6 +1095,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 4BCB37CB112D647C008C7BC1 /* Build configuration list for PBXNativeTarget "iPhoneFaust" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4BCB37CC112D647C008C7BC1 /* Debug */, + 4BCB37CD112D647C008C7BC1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 4BCF75EF10BC2FD90082C526 /* Build configuration list for PBXNativeTarget "iPhoneThruNet" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/macosx/iphone/main_master.mm b/macosx/iphone/main_master.mm index 00c3bff7..55d4eb87 100644 --- a/macosx/iphone/main_master.mm +++ b/macosx/iphone/main_master.mm @@ -45,7 +45,7 @@ int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int i; - int buffer_size = 512; + int buffer_size = 2048; int sample_rate = 44100; jack_master_t request = { buffer_size, sample_rate, "master" }; jack_slave_t result; @@ -72,17 +72,19 @@ int main(int argc, char *argv[]) { // Run until interrupted while (1) { - + // Copy input to output for (i = 0; i < result.audio_input; i++) { memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); } if (jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) { + printf("jack_net_master_send error..\n"); break; } if (jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { + printf("jack_net_master_recv error..\n"); break; } usleep(wait_usec); From bae05a4f073df6671d13ffc6cdbdd39b9e3057c5 Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 24 Feb 2010 15:59:47 +0000 Subject: [PATCH 031/472] Add audio code for iPod, streaming from Mac to iPod (in master mode) now somewhat works. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3922 0c269be4-1314-0410-8aa9-9f06e86f4224 --- macosx/coreaudio/JackAudioQueueAdapter.cpp | 314 -------------- macosx/coreaudio/JackAudioQueueAdapter.h | 99 ----- macosx/coreaudio/TiPhoneCoreAudioRenderer.cpp | 390 ++++++++++++++++++ macosx/coreaudio/TiPhoneCoreAudioRenderer.h | 103 +++++ .../iPhoneNet.xcodeproj/project.pbxproj | 18 +- macosx/iphone/main_master.mm | 75 ++-- macosx/iphone/main_slave.mm | 4 - 7 files changed, 556 insertions(+), 447 deletions(-) delete mode 100644 macosx/coreaudio/JackAudioQueueAdapter.cpp delete mode 100644 macosx/coreaudio/JackAudioQueueAdapter.h create mode 100644 macosx/coreaudio/TiPhoneCoreAudioRenderer.cpp create mode 100644 macosx/coreaudio/TiPhoneCoreAudioRenderer.h diff --git a/macosx/coreaudio/JackAudioQueueAdapter.cpp b/macosx/coreaudio/JackAudioQueueAdapter.cpp deleted file mode 100644 index e6a1db35..00000000 --- a/macosx/coreaudio/JackAudioQueueAdapter.cpp +++ /dev/null @@ -1,314 +0,0 @@ -/* -Copyright (C) 2009 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. - -*/ - -#include "JackAudioQueueAdapter.h" -//#include - -namespace Jack -{ - -// NOT YET WORKING.... - -static void Print4CharCode(const char* msg, long c) -{ - UInt32 __4CC_number = (c); - char __4CC_string[5]; - //*((SInt32*)__4CC_string) = EndianU32_NtoB(__4CC_number); - __4CC_string[4] = 0; - //printf("%s'%s'\n", (msg), __4CC_string); - snprintf(__4CC_string, 5, "%s'%s'\n", (msg), __4CC_string); -} - -static int ComputeRecordBufferSize(AudioQueueRef mQueue, const AudioStreamBasicDescription *format, float seconds) -{ - OSStatus err; - int packets, frames, bytes = 0; - frames = (int)ceil(seconds * format->mSampleRate); - - if (format->mBytesPerFrame > 0) - bytes = frames * format->mBytesPerFrame; - else { - UInt32 maxPacketSize; - if (format->mBytesPerPacket > 0) { - maxPacketSize = format->mBytesPerPacket; // constant packet size - } else { - UInt32 propertySize = sizeof(maxPacketSize); - if ((err = AudioQueueGetProperty(mQueue, kAudioQueueProperty_MaximumOutputPacketSize, &maxPacketSize, &propertySize)) != noErr) { - printf("Couldn't get queue's maximum output packet size\n"); - return 0; - } - } - if (format->mFramesPerPacket > 0) - packets = frames / format->mFramesPerPacket; - else - packets = frames; // worst-case scenario: 1 frame in a packet - if (packets == 0) // sanity check - packets = 1; - bytes = packets * maxPacketSize; - } - return bytes; -} - -void JackAudioQueueAdapter::CaptureCallback(void * inUserData, - AudioQueueRef inAQ, - AudioQueueBufferRef inBuffer, - const AudioTimeStamp * inStartTime, - UInt32 inNumPackets, - const AudioStreamPacketDescription *inPacketDesc) -{ - JackAudioQueueAdapter* adapter = (JackAudioQueueAdapter*)inUserData; - OSStatus err; - printf("JackAudioQueueAdapter::CaptureCallback\n"); - - // Use the adapter to communicate with audio callback - // jack_adapter_push_input(adapter, audio_output, audio_output_buffer); - - if ((err = AudioQueueEnqueueBuffer(adapter->fCaptureQueue, inBuffer, 0, NULL)) != noErr) { - printf("JackAudioQueueAdapter::CaptureCallback error %d\n", err); - } else { - printf("JackAudioQueueAdapter::CaptureCallback enqueue buffer\n"); - } -} - -void JackAudioQueueAdapter::PlaybackCallback(void * inUserData, - AudioQueueRef inAQ, - AudioQueueBufferRef inCompleteAQBuffer) -{ - JackAudioQueueAdapter* adapter = (JackAudioQueueAdapter*)inUserData; - OSStatus err; - printf("JackAudioQueueAdapter::PlaybackCallback\n"); - - - // Use the adapter to communicate with audio callback - // jack_adapter_pull_output(adapter, audio_input, audio_input_buffer); - - //if (AudioQueueEnqueueBuffer(adapter->fPlaybackQueue, inCompleteAQBuffer, 0, &adapter->fPlaybackPacketDescs) != noErr) { - if ((err = AudioQueueEnqueueBuffer(inAQ, inCompleteAQBuffer, 0, NULL)) != noErr) { - printf("JackAudioQueueAdapter::PlaybackCallback error %d\n", err); - } else { - printf("JackAudioQueueAdapter::PlaybackCallback enqueue buffer\n"); - } -} - -void JackAudioQueueAdapter::InterruptionListener(void* inClientData, UInt32 inInterruptionState) -{ - JackAudioQueueAdapter* obj = (JackAudioQueueAdapter*)inClientData; -} - -void JackAudioQueueAdapter::PropListener(void* inClientData, - AudioSessionPropertyID inID, - UInt32 inDataSize, - const void* inData) -{} - - -JackAudioQueueAdapter::JackAudioQueueAdapter(int inchan, int outchan, jack_nframes_t buffer_size, jack_nframes_t sample_rate, jack_adapter_t* adapter) - :fCaptureChannels(inchan), fPlaybackChannels(outchan), fBufferSize(buffer_size), fSampleRate(sample_rate), fAdapter(adapter) -{} - -JackAudioQueueAdapter::~JackAudioQueueAdapter() -{} - -int JackAudioQueueAdapter::Open() -{ - OSStatus err; - int bufferByteSize; - UInt32 size; - - /* - err = AudioSessionInitialize(NULL, NULL, InterruptionListener, this); - if (err != noErr) { - fprintf(stderr, "AudioSessionInitialize error %d\n", err); - return -1; - } - - err = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, PropListener, this); - if (err) { - fprintf(stderr, "kAudioSessionProperty_AudioRouteChange error %d\n", err); - } - - UInt32 inputAvailable = 0; - UInt32 size = sizeof(inputAvailable); - - // we do not want to allow recording if input is not available - err = AudioSessionGetProperty(kAudioSessionProperty_AudioInputAvailable, &size, &inputAvailable); - if (err != noErr) { - fprintf(stderr, "kAudioSessionProperty_AudioInputAvailable error %d\n", err); - } - - // we also need to listen to see if input availability changes - err = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioInputAvailable, PropListener, this); - if (err != noErr) { - fprintf(stderr, "kAudioSessionProperty_AudioInputAvailable error %d\n", err); - } - - err = AudioSessionSetActive(true); - if (err != noErr) { - fprintf(stderr, "AudioSessionSetActive (true) failed %d", err); - return -1; - } - */ - - AudioStreamBasicDescription captureDataFormat; - - /* - captureDataFormat.mSampleRate = fSampleRate; - captureDataFormat.mFormatID = kAudioFormatLinearPCM; - //captureDataFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; - captureDataFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked; - captureDataFormat.mBytesPerPacket = sizeof(float); - captureDataFormat.mFramesPerPacket = 1; - captureDataFormat.mBytesPerFrame = sizeof(float); - captureDataFormat.mChannelsPerFrame = fCaptureChannels; - captureDataFormat.mBitsPerChannel = 32; - */ - - - captureDataFormat.mSampleRate = fSampleRate; - captureDataFormat.mFormatID = kAudioFormatLinearPCM; - captureDataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; - captureDataFormat.mBytesPerPacket = 4; - captureDataFormat.mFramesPerPacket = 1; // this means each packet in the AQ has two samples, one for each channel -> 4 bytes/frame/packet - captureDataFormat.mBytesPerFrame = 4; - captureDataFormat.mChannelsPerFrame = 2; - captureDataFormat.mBitsPerChannel = 16; - - - if ((err = AudioQueueNewInput(&captureDataFormat, CaptureCallback, this, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &fCaptureQueue)) != noErr) { - Print4CharCode("error code : unknown", err); - return -1; - } - - size = sizeof(captureDataFormat.mSampleRate); - if ((err = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &size, &captureDataFormat.mSampleRate)) != noErr) { - printf("couldn't get hardware sample rate\n"); - } - - size = sizeof(captureDataFormat.mChannelsPerFrame); - if ((err = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputNumberChannels, &size, &captureDataFormat.mChannelsPerFrame)) != noErr) { - printf("couldn't get input channel count\n"); - } - - size = sizeof(captureDataFormat); - if ((err = AudioQueueGetProperty(fCaptureQueue, kAudioQueueProperty_StreamDescription, &captureDataFormat, &size)) != noErr) { - printf("couldn't get queue's format\n"); - } - - bufferByteSize = ComputeRecordBufferSize(fCaptureQueue, &captureDataFormat, kBufferDurationSeconds); // enough bytes for half a second - for (int i = 0; i < kNumberBuffers; ++i) { - if ((err = AudioQueueAllocateBuffer(fCaptureQueue, bufferByteSize, &fCaptureQueueBuffers[i])) != noErr) { - printf("Capture AudioQueueAllocateBuffer failed\n"); - } - if ((err = AudioQueueEnqueueBuffer(fCaptureQueue, fCaptureQueueBuffers[i], 0, NULL)) != noErr) { - printf("Capture AudioQueueEnqueueBuffer failed\n"); - } - } - - - //AudioQueueSetProperty(fCaptureQueue, kAudioQueueProperty_MagicCookie, cookie, size) - //AudioQueueSetProperty(fCaptureQueue, kAudioQueueProperty_ChannelLayout, acl, size - - AudioStreamBasicDescription playbackDataFormat; - - /* - playbackDataFormat.mSampleRate = fSampleRate; - playbackDataFormat.mFormatID = kAudioFormatLinearPCM; - playbackDataFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; - playbackDataFormat.mBytesPerPacket = sizeof(float); - playbackDataFormat.mFramesPerPacket = 1; - playbackDataFormat.mBytesPerFrame = sizeof(float); - playbackDataFormat.mChannelsPerFrame = fPlaybackChannels; - playbackDataFormat.mBitsPerChannel = 32; - */ - - playbackDataFormat.mSampleRate = fSampleRate; - playbackDataFormat.mFormatID = kAudioFormatLinearPCM; - playbackDataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; - playbackDataFormat.mBytesPerPacket = 4; - playbackDataFormat.mFramesPerPacket = 1; - playbackDataFormat.mBytesPerFrame = 4; - playbackDataFormat.mChannelsPerFrame = fPlaybackChannels; - playbackDataFormat.mBitsPerChannel = 16; - - - if ((err = AudioQueueNewOutput(&playbackDataFormat, PlaybackCallback, this, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &fPlaybackQueue)) != noErr) { - Print4CharCode("error code : unknown", err); - return -1; - } - - for (int i = 0; i < kNumberBuffers; ++i) { - if ((err = AudioQueueAllocateBuffer(fPlaybackQueue, bufferByteSize, &fPlaybackQueueBuffers[i])) != noErr) { - printf("Playback AudioQueueAllocateBuffer failed %d\n", err); - } - //if ((err = AudioQueueEnqueueBuffer(fPlaybackQueue, fPlaybackQueueBuffers[i], 0, NULL)) != noErr) { - // printf("Playback AudioQueueEnqueueBuffer failed %d\n", err); - //} - } - - AudioQueueSetParameter(fPlaybackQueue, kAudioQueueParam_Volume, 1.0); - - - //AudioQueueSetProperty(fPlaybackQueue, kAudioQueueProperty_MagicCookie, cookie, size); - //AudioQueueSetProperty(fPlaybackQueue, kAudioQueueProperty_ChannelLayout, acl, size); - //AudioQueueSetParameter(fPlaybackQueue, kAudioQueueParam_Volume, volume - - return 0; -} -int JackAudioQueueAdapter::Close() -{ - //AudioSessionSetActive(false); - - AudioQueueDispose(fCaptureQueue, true); - AudioQueueDispose(fPlaybackQueue, true); - return 0; -} - -int JackAudioQueueAdapter::Start() -{ - for (int i = 0; i < kNumberBuffers; ++i) { - PlaybackCallback(this, fPlaybackQueue, fPlaybackQueueBuffers[i]); - } - - AudioQueueStart(fCaptureQueue, NULL); - AudioQueueStart(fPlaybackQueue, NULL); - - return 0; -} - -int JackAudioQueueAdapter::Stop() -{ - - AudioQueueStop(fCaptureQueue, NULL); - AudioQueueStop(fPlaybackQueue, NULL); - - return 0; -} - - -int JackAudioQueueAdapter::SetSampleRate(jack_nframes_t sample_rate) -{ - return 0; -} - -int JackAudioQueueAdapter::SetBufferSize(jack_nframes_t buffer_size) -{ - return 0; -} - -}; diff --git a/macosx/coreaudio/JackAudioQueueAdapter.h b/macosx/coreaudio/JackAudioQueueAdapter.h deleted file mode 100644 index da8f8430..00000000 --- a/macosx/coreaudio/JackAudioQueueAdapter.h +++ /dev/null @@ -1,99 +0,0 @@ -/* -Copyright (C) 2009 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 __JackAudioQueueAdapter__ -#define __JackAudioQueueAdapter__ - -//#include -//#include - -#include - -#include - -namespace Jack -{ - -/*! -\brief Audio adapter using AudioQueue API. -*/ - -#define kNumberBuffers 3 -#define kBufferDurationSeconds .5 - -class JackAudioQueueAdapter -{ - - private: - - AudioQueueRef fCaptureQueue; - AudioQueueBufferRef fCaptureQueueBuffers[kNumberBuffers]; - - AudioQueueRef fPlaybackQueue; - AudioQueueBufferRef fPlaybackQueueBuffers[kNumberBuffers]; - //AudioStreamPacketDescription fPlaybackPacketDescs; - - - jack_nframes_t fBufferSize; - jack_nframes_t fSampleRate; - - int fCaptureChannels; - int fPlaybackChannels; - - jack_adapter_t* fAdapter; - - static void CaptureCallback(void* inUserData, - AudioQueueRef inAQ, - AudioQueueBufferRef inBuffer, - const AudioTimeStamp* inStartTime, - UInt32 inNumPackets, - const AudioStreamPacketDescription* inPacketDesc); - - - static void PlaybackCallback(void* inUserData, - AudioQueueRef inAQ, - AudioQueueBufferRef inCompleteAQBuffer); - - static void InterruptionListener(void* inClientData, UInt32 inInterruptionState); - - static void PropListener(void* inClientData, - AudioSessionPropertyID inID, - UInt32 inDataSize, - const void* inData); - - public: - - JackAudioQueueAdapter(int inchan, int outchan, jack_nframes_t buffer_size, jack_nframes_t sample_rate, jack_adapter_t* adapter); - ~JackAudioQueueAdapter(); - - virtual int Open(); - virtual int Close(); - - virtual int Start(); - virtual int Stop(); - - - virtual int SetSampleRate(jack_nframes_t sample_rate); - virtual int SetBufferSize(jack_nframes_t buffer_size); - -}; - -} - -#endif diff --git a/macosx/coreaudio/TiPhoneCoreAudioRenderer.cpp b/macosx/coreaudio/TiPhoneCoreAudioRenderer.cpp new file mode 100644 index 00000000..e798c973 --- /dev/null +++ b/macosx/coreaudio/TiPhoneCoreAudioRenderer.cpp @@ -0,0 +1,390 @@ +/* +Copyright (C) 2010 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. + +*/ + +#include "TiPhoneCoreAudioRenderer.h" + +static void PrintStreamDesc(AudioStreamBasicDescription *inDesc) +{ + printf("- - - - - - - - - - - - - - - - - - - -\n"); + printf(" Sample Rate:%f\n", inDesc->mSampleRate); + printf(" Format ID:%.*s\n", (int) sizeof(inDesc->mFormatID), (char*)&inDesc->mFormatID); + printf(" Format Flags:%lX\n", inDesc->mFormatFlags); + printf(" Bytes per Packet:%ld\n", inDesc->mBytesPerPacket); + printf(" Frames per Packet:%ld\n", inDesc->mFramesPerPacket); + printf(" Bytes per Frame:%ld\n", inDesc->mBytesPerFrame); + printf(" Channels per Frame:%ld\n", inDesc->mChannelsPerFrame); + printf(" Bits per Channel:%ld\n", inDesc->mBitsPerChannel); + printf("- - - - - - - - - - - - - - - - - - - -\n"); +} + +static void printError(OSStatus err) +{ + switch (err) { + case kAudioConverterErr_FormatNotSupported: + printf("error code : kAudioConverterErr_FormatNotSupported\n"); + break; + case kAudioConverterErr_OperationNotSupported: + printf("error code : kAudioConverterErr_OperationNotSupported\n"); + break; + case kAudioConverterErr_PropertyNotSupported: + printf("error code : kAudioConverterErr_PropertyNotSupported\n"); + break; + case kAudioConverterErr_InvalidInputSize: + printf("error code : kAudioConverterErr_InvalidInputSize\n"); + break; + case kAudioConverterErr_InvalidOutputSize: + printf("error code : kAudioConverterErr_InvalidOutputSize\n"); + break; + case kAudioConverterErr_UnspecifiedError: + printf("error code : kAudioConverterErr_UnspecifiedError\n"); + break; + case kAudioConverterErr_BadPropertySizeError: + printf("error code : kAudioConverterErr_BadPropertySizeError\n"); + break; + case kAudioConverterErr_RequiresPacketDescriptionsError: + printf("error code : kAudioConverterErr_RequiresPacketDescriptionsError\n"); + break; + case kAudioConverterErr_InputSampleRateOutOfRange: + printf("error code : kAudioConverterErr_InputSampleRateOutOfRange\n"); + break; + case kAudioConverterErr_OutputSampleRateOutOfRange: + printf("error code : kAudioConverterErr_OutputSampleRateOutOfRange\n"); + break; + default: + printf("error code : unknown\n"); + break; + } +} + +OSStatus TiPhoneCoreAudioRenderer::Render(void *inRefCon, + AudioUnitRenderActionFlags *ioActionFlags, + const AudioTimeStamp *inTimeStamp, + UInt32, + UInt32 inNumberFrames, + AudioBufferList *ioData) +{ + TiPhoneCoreAudioRendererPtr renderer = (TiPhoneCoreAudioRendererPtr)inRefCon; + AudioUnitRender(renderer->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, ioData); + + float coef = float(LONG_MAX); + float inv_coef = 1.f/float(LONG_MAX); + + for (int chan = 0; chan < renderer->fDevNumInChans; chan++) { + for (int frame = 0; frame < inNumberFrames; frame++) { + renderer->fInChannel[chan][frame] = float(((long*)ioData->mBuffers[chan].mData)[frame]) * inv_coef; + } + } + + renderer->PerformAudioCallback((int)inNumberFrames); + + for (int chan = 0; chan < renderer->fDevNumOutChans; chan++) { + for (int frame = 0; frame < inNumberFrames; frame++) { + ((long*)ioData->mBuffers[chan].mData)[frame] = long(renderer->fOutChannel[chan][frame] * coef); + } + } + + return 0; +} + +void TiPhoneCoreAudioRenderer::InterruptionListener(void *inClientData, UInt32 inInterruption) +{ + TiPhoneCoreAudioRenderer *obj = (TiPhoneCoreAudioRenderer*)inClientData; + printf("Session interrupted! --- %s ---", inInterruption == kAudioSessionBeginInterruption ? "Begin Interruption" : "End Interruption"); + + if (inInterruption == kAudioSessionEndInterruption) { + // make sure we are again the active session + AudioSessionSetActive(true); + AudioOutputUnitStart(obj->fAUHAL); + } + + if (inInterruption == kAudioSessionBeginInterruption) { + AudioOutputUnitStop(obj->fAUHAL); + } +} + +int TiPhoneCoreAudioRenderer::OpenDefault(int bufferSize, int samplerate) +{ + OSStatus err1; + UInt32 outSize; + UInt32 enableIO; + AudioStreamBasicDescription srcFormat, dstFormat; + + printf("OpenDefault fDevNumInChans = %ld fDevNumOutChans = %ld bufferSize = %ld samplerate = %ld\n", fDevNumInChans, fDevNumOutChans, bufferSize, samplerate); + + // Initialize and configure the audio session + err1 = AudioSessionInitialize(NULL, NULL, InterruptionListener, this); + if (err1 != noErr) { + printf("Couldn't initialize audio session\n"); + printError(err1); + return OPEN_ERR; + } + + err1 = AudioSessionSetActive(true); + if (err1 != noErr) { + printf("Couldn't set audio session active\n"); + printError(err1); + return OPEN_ERR; + } + + UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord; + err1 = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory); + if (err1 != noErr) { + printf("Couldn't set audio category\n"); + printError(err1); + return OPEN_ERR; + } + + //err1 = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, propListener, self), "couldn't set property listener"); + + Float64 hwSampleRate; + outSize = sizeof(hwSampleRate); + err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &outSize, &hwSampleRate); + if (err1 != noErr) { + printf("Couldn't get hw sample rate\n"); + printError(err1); + return OPEN_ERR; + } else { + printf("Get hw sample rate %f\n", hwSampleRate); + } + + Float32 hwBufferSize; + outSize = sizeof(hwBufferSize); + err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareIOBufferDuration, &outSize, &hwBufferSize); + if (err1 != noErr) { + printf("Couldn't get hw buffer duration\n"); + printError(err1); + return OPEN_ERR; + } else { + printf("Get hw buffer duration %f\n", hwBufferSize); + } + + UInt32 hwInput; + outSize = sizeof(hwInput); + err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputNumberChannels, &outSize, &hwInput); + if (err1 != noErr) { + printf("Couldn't get hw input channels\n"); + printError(err1); + return OPEN_ERR; + } else { + printf("Get hw input channels %d\n", hwInput); + } + + UInt32 hwOutput; + outSize = sizeof(hwOutput); + err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputNumberChannels, &outSize, &hwOutput); + if (err1 != noErr) { + printf("Couldn't get hw output channels\n"); + printError(err1); + return OPEN_ERR; + } else { + printf("Get hw output channels %d\n", hwOutput); + } + + Float32 preferredBufferSize = float(bufferSize) / float(samplerate); + printf("preferredBufferSize %f \n", preferredBufferSize); + + err1 = AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(preferredBufferSize), &preferredBufferSize); + if (err1 != noErr) { + printf("Couldn't set i/o buffer duration\n"); + printError(err1); + return OPEN_ERR; + } + + Float64 preferredSamplerate = float(samplerate); + err1 = AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareSampleRate, sizeof(preferredSamplerate), &preferredSamplerate); + if (err1 != noErr) { + printf("Couldn't set i/o sample rate\n"); + printError(err1); + return OPEN_ERR; + } + + // AUHAL + AudioComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_RemoteIO, kAudioUnitManufacturer_Apple, 0, 0}; + AudioComponent HALOutput = AudioComponentFindNext(NULL, &cd); + + err1 = AudioComponentInstanceNew(HALOutput, &fAUHAL); + if (err1 != noErr) { + printf("Error calling OpenAComponent\n"); + printError(err1); + goto error; + } + + enableIO = 1; + err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO)); + if (err1 != noErr) { + printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output\n"); + printError(err1); + goto error; + } + + enableIO = 1; + err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO)); + if (err1 != noErr) { + printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input\n"); + printError(err1); + goto error; + } + + UInt32 maxFPS; + outSize = sizeof(maxFPS); + err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, &maxFPS, &outSize); + if (err1 != noErr) { + printf("Couldn't get kAudioUnitProperty_MaximumFramesPerSlice\n"); + printError(err1); + goto error; + } else { + printf("Get kAudioUnitProperty_MaximumFramesPerSlice %d\n", maxFPS); + } + + err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&bufferSize, sizeof(UInt32)); + if (err1 != noErr) { + printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n"); + printError(err1); + goto error; + } + + err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, (UInt32*)&bufferSize, sizeof(UInt32)); + if (err1 != noErr) { + printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n"); + printError(err1); + goto error; + } + + err1 = AudioUnitInitialize(fAUHAL); + if (err1 != noErr) { + printf("Cannot initialize AUHAL unit\n"); + printError(err1); + goto error; + } + + // Setting format + + if (fDevNumInChans > 0) { + outSize = sizeof(AudioStreamBasicDescription); + err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, &outSize); + if (err1 != noErr) { + printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n"); + printError(err1); + } + PrintStreamDesc(&srcFormat); + + srcFormat.mFormatID = kAudioFormatLinearPCM; + srcFormat.mFormatFlags = kAudioFormatFlagsCanonical | kLinearPCMFormatFlagIsNonInterleaved; + srcFormat.mBytesPerPacket = sizeof(AudioUnitSampleType); + srcFormat.mFramesPerPacket = 1; + srcFormat.mBytesPerFrame = sizeof(AudioUnitSampleType); + srcFormat.mChannelsPerFrame = fDevNumInChans; + srcFormat.mBitsPerChannel = 32; + + PrintStreamDesc(&srcFormat); + + err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription)); + if (err1 != noErr) { + printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n"); + printError(err1); + } + } + + if (fDevNumOutChans > 0) { + outSize = sizeof(AudioStreamBasicDescription); + err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, &outSize); + if (err1 != noErr) { + printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input\n"); + printError(err1); + } + PrintStreamDesc(&dstFormat); + + dstFormat.mFormatID = kAudioFormatLinearPCM; + dstFormat.mFormatFlags = kAudioFormatFlagsCanonical | kLinearPCMFormatFlagIsNonInterleaved; + dstFormat.mBytesPerPacket = sizeof(AudioUnitSampleType); + dstFormat.mFramesPerPacket = 1; + dstFormat.mBytesPerFrame = sizeof(AudioUnitSampleType); + dstFormat.mChannelsPerFrame = fDevNumOutChans; + dstFormat.mBitsPerChannel = 32; + + PrintStreamDesc(&dstFormat); + + err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription)); + if (err1 != noErr) { + printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input\n"); + printError(err1); + } + } + + if (fDevNumInChans > 0 && fDevNumOutChans == 0) { + AURenderCallbackStruct output; + output.inputProc = Render; + output.inputProcRefCon = this; + err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &output, sizeof(output)); + if (err1 != noErr) { + printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1\n"); + printError(err1); + goto error; + } + } else { + AURenderCallbackStruct output; + output.inputProc = Render; + output.inputProcRefCon = this; + err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &output, sizeof(output)); + if (err1 != noErr) { + printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0\n"); + printError(err1); + goto error; + } + } + + return NO_ERR; + +error: + AudioUnitUninitialize(fAUHAL); + AudioComponentInstanceDispose(fAUHAL); + return OPEN_ERR; +} + +int TiPhoneCoreAudioRenderer::Close() +{ + AudioUnitUninitialize(fAUHAL); + AudioComponentInstanceDispose(fAUHAL); + return NO_ERR; +} + +int TiPhoneCoreAudioRenderer::Start() +{ + AudioSessionSetActive(true); + OSStatus err = AudioOutputUnitStart(fAUHAL); + + if (err != noErr) { + printf("Error while opening device : device open error \n"); + return OPEN_ERR; + } else { + return NO_ERR; + } +} + +int TiPhoneCoreAudioRenderer::Stop() +{ + OSStatus err = AudioOutputUnitStop(fAUHAL); + + if (err != noErr) { + printf("Error while closing device : device close error \n"); + return OPEN_ERR; + } else { + return NO_ERR; + } +} diff --git a/macosx/coreaudio/TiPhoneCoreAudioRenderer.h b/macosx/coreaudio/TiPhoneCoreAudioRenderer.h new file mode 100644 index 00000000..2aab9be1 --- /dev/null +++ b/macosx/coreaudio/TiPhoneCoreAudioRenderer.h @@ -0,0 +1,103 @@ +/* +Copyright (C) 2010 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 __TiPhoneCoreAudioRenderer__ +#define __TiPhoneCoreAudioRenderer__ + +#include +#include +#include + +#define MAX_CHANNELS 256 +#define OPEN_ERR -1 +#define NO_ERR 0 + +typedef void (*AudioCallback) (int frames, float** inputs, float** outputs, void* arg); + +class TiPhoneCoreAudioRenderer +{ + + private: + + AudioUnit fAUHAL; + AudioCallback fAudioCallback; + void* fCallbackArg; + + int fDevNumInChans; + int fDevNumOutChans; + + float* fInChannel[MAX_CHANNELS]; + float* fOutChannel[MAX_CHANNELS]; + + static OSStatus Render(void *inRefCon, + AudioUnitRenderActionFlags *ioActionFlags, + const AudioTimeStamp *inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList *ioData); + + static void InterruptionListener(void *inClientData, UInt32 inInterruption); + + public: + + TiPhoneCoreAudioRenderer(int input, int output) + :fDevNumInChans(input), fDevNumOutChans(output), fAudioCallback(NULL), fCallbackArg(NULL) + { + for (int i = 0; i < fDevNumInChans; i++) { + fInChannel[i] = new float[8192]; + } + + for (int i = 0; i < fDevNumOutChans; i++) { + fOutChannel[i] = new float[8192]; + } + } + virtual ~TiPhoneCoreAudioRenderer() + { + for (int i = 0; i < fDevNumInChans; i++) { + delete[] fInChannel[i]; + } + + for (int i = 0; i < fDevNumOutChans; i++) { + delete[] fOutChannel[i]; + } + } + + int OpenDefault(int bufferSize, int sampleRate); + int Close(); + + int Start(); + int Stop(); + + void SetAudioCallback(AudioCallback callback, void* arg) + { + fAudioCallback = callback; + fCallbackArg = arg; + } + + void PerformAudioCallback(int frames) + { + if (fAudioCallback) + fAudioCallback(frames, fInChannel, fOutChannel, fCallbackArg); + } + +}; + +typedef TiPhoneCoreAudioRenderer * TiPhoneCoreAudioRendererPtr; + +#endif diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj index 0eeabc23..3ef8728e 100755 --- a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -19,7 +19,6 @@ 4B0772280F54018C000DC657 /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; 4B0772290F54018C000DC657 /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; 4B07722A0F54018C000DC657 /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; - 4B07722B0F54018C000DC657 /* JackAudioQueueAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */; }; 4B07722C0F54018C000DC657 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; 4B07722D0F54018C000DC657 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; }; 4B07722E0F54018C000DC657 /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; @@ -116,6 +115,12 @@ 4BF15E2811356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; 4BF15E2911356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; 4BF15E2A11356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; + 4BF15F7811357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; }; + 4BF15F7911357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; }; + 4BF15F7A11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; }; + 4BF15F7B11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; }; + 4BF15F7C11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; }; + 4BF15F7D11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; }; 4BFF45600F4D5D9700106083 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 4BFF45630F4D5D9700106083 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; }; 4BFF45640F4D5D9700106083 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93870F49B0E300D3626B /* JackMachTime.c */; }; @@ -173,6 +178,7 @@ 4BF1364C0F4B0F7700218A3F /* JackResampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackResampler.h; path = ../../common/JackResampler.h; sourceTree = SOURCE_ROOT; }; 4BF136540F4B0F9F00218A3F /* ringbuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ringbuffer.c; path = ../../common/ringbuffer.c; sourceTree = SOURCE_ROOT; }; 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CAHostTimeBase.cpp; path = /Developer/Extras/CoreAudio/PublicUtility/CAHostTimeBase.cpp; sourceTree = ""; }; + 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TiPhoneCoreAudioRenderer.cpp; path = ../coreaudio/TiPhoneCoreAudioRenderer.cpp; sourceTree = SOURCE_ROOT; }; 4BFF45120F4D59DB00106083 /* libjacknet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjacknet.a; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -275,6 +281,7 @@ 4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */, 4BCB37D5112D64B4008C7BC1 /* HardwareClock.cpp */, 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */, + 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */, 29B97315FDCFA39411CA2CEA /* Other Sources */, 29B97317FDCFA39411CA2CEA /* Resources */, 29B97323FDCFA39411CA2CEA /* Frameworks */, @@ -567,6 +574,7 @@ 4B0773870F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, 4B27918A0F72570C000536B7 /* JackGlobals.cpp in Sources */, 4BF15E2611356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, + 4BF15F7911357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -581,7 +589,6 @@ 4B0772280F54018C000DC657 /* JackNetTool.cpp in Sources */, 4B0772290F54018C000DC657 /* JackNetUnixSocket.cpp in Sources */, 4B07722A0F54018C000DC657 /* JackPosixThread.cpp in Sources */, - 4B07722B0F54018C000DC657 /* JackAudioQueueAdapter.cpp in Sources */, 4B07722C0F54018C000DC657 /* JackAudioAdapterInterface.cpp in Sources */, 4B07722D0F54018C000DC657 /* JackResampler.cpp in Sources */, 4B07722E0F54018C000DC657 /* ringbuffer.c in Sources */, @@ -589,6 +596,7 @@ 4B0773860F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, 4B27918B0F72570C000536B7 /* JackGlobals.cpp in Sources */, 4BF15E2511356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, + 4BF15F7811357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -629,6 +637,7 @@ 4B4146A610BD3C4300C12F0C /* freeverb.mm in Sources */, 4B4146A710BD3C4300C12F0C /* JackGlobals.cpp in Sources */, 4BF15E2911356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, + 4BF15F7C11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -639,6 +648,7 @@ 4BCB37D6112D64B4008C7BC1 /* HardwareClock.cpp in Sources */, 4BCB37D9112D64D8008C7BC1 /* iphone-faust.mm in Sources */, 4BF15E2A11356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, + 4BF15F7D11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -661,6 +671,7 @@ 4BCF75E910BC2FD90082C526 /* JackGlobals.cpp in Sources */, 4BCF75F710BC30140082C526 /* audio_thru.mm in Sources */, 4BF15E2811356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, + 4BF15F7B11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -683,6 +694,7 @@ 4BBDC8FA0F5420C000465F9C /* freeverb.mm in Sources */, 4B2791880F72570C000536B7 /* JackGlobals.cpp in Sources */, 4BF15E2711356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, + 4BF15F7A11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -747,6 +759,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( + ../../macosx/coreaudio, ../../macosx, ../../posix, ../../common/jack, @@ -771,6 +784,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( + ../../macosx/coreaudio, ../../common/jack, ../../common, ../../posix, diff --git a/macosx/iphone/main_master.mm b/macosx/iphone/main_master.mm index 55d4eb87..b7cd0d28 100644 --- a/macosx/iphone/main_master.mm +++ b/macosx/iphone/main_master.mm @@ -9,7 +9,7 @@ #import #include -#include "JackAudioQueueAdapter.h" +#include "TiPhoneCoreAudioRenderer.h" #define NUM_INPUT 2 #define NUM_OUTPUT 2 @@ -17,27 +17,34 @@ jack_net_master_t* net; jack_adapter_t* adapter; -Jack::JackAudioQueueAdapter* audio; +float** audio_input_buffer; +float** audio_output_buffer; -static int net_process(jack_nframes_t buffer_size, - int audio_input, - float** audio_input_buffer, - int midi_input, - void** midi_input_buffer, - int audio_output, - float** audio_output_buffer, - int midi_output, - void** midi_output_buffer, - void* data) +int buffer_size = 2048; +int sample_rate = 44100; + +jack_master_t request = { buffer_size, sample_rate, "master" }; +jack_slave_t result; + +void MasterAudioCallback(int frames, float** inputs, float** outputs, void* arg) { - // Process input, produce output - if (audio_input == audio_output) { - // Copy input to output - for (int i = 0; i < audio_input; i++) { - memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); - } + int i; + + for (i = 0; i < result.audio_input; i++) { + memcpy(audio_output_buffer[i], inputs[i], buffer_size * sizeof(float)); + } + + if (jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) { + printf("jack_net_master_send error..\n"); + } + + if (jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { + printf("jack_net_master_recv error..\n"); + } + + for (i = 0; i < result.audio_output; i++) { + memcpy(outputs[i], audio_input_buffer[i], buffer_size * sizeof(float)); } - return 0; } int main(int argc, char *argv[]) { @@ -45,14 +52,9 @@ int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int i; - int buffer_size = 2048; - int sample_rate = 44100; - jack_master_t request = { buffer_size, sample_rate, "master" }; - jack_slave_t result; - float** audio_input_buffer; - float** audio_output_buffer; - int wait_usec = (int) ((((float)buffer_size) * 1000000) / ((float)sample_rate)); - + + TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT); + if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { return -1; } @@ -68,8 +70,24 @@ int main(int argc, char *argv[]) { audio_output_buffer[i] = (float*)(calloc(buffer_size, sizeof(float))); } - // Quite brutal way, the application actually does not start completely, the netjack audio processing loop is used instead... + if (audio_device.OpenDefault(buffer_size, sample_rate) < 0) { + return -1; + } + + audio_device.SetAudioCallback(MasterAudioCallback, NULL); + + if (audio_device.Start() < 0) { + return -1; + } + + // Run until interrupted + while (1) {} + + audio_device.Stop(); + audio_device.Close(); + /* + // Quite brutal way, the application actually does not start completely, the netjack audio processing loop is used instead... // Run until interrupted while (1) { @@ -89,6 +107,7 @@ int main(int argc, char *argv[]) { } usleep(wait_usec); }; + */ // Wait for application end jack_net_master_close(net); diff --git a/macosx/iphone/main_slave.mm b/macosx/iphone/main_slave.mm index f899d823..af9b54c0 100644 --- a/macosx/iphone/main_slave.mm +++ b/macosx/iphone/main_slave.mm @@ -9,16 +9,12 @@ #import #include -#include "JackAudioQueueAdapter.h" - #define NUM_INPUT 2 #define NUM_OUTPUT 2 jack_net_slave_t* net; jack_adapter_t* adapter; -Jack::JackAudioQueueAdapter* audio; - static int net_process(jack_nframes_t buffer_size, int audio_input, float** audio_input_buffer, From eb681fa591486a0cc443d372961de00d36f8f689 Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 24 Feb 2010 17:47:31 +0000 Subject: [PATCH 032/472] Cleanup. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3923 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetAPI.cpp | 2 +- .../iPhoneNet.xcodeproj/project.pbxproj | 22 ++++------------ macosx/iphone/main_master.mm | 26 +++++++++---------- 3 files changed, 18 insertions(+), 32 deletions(-) diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 655c8deb..e780fd46 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -384,7 +384,7 @@ struct JackNetExtMaster : public JackNetMasterInterface { return DataSend(); - } catch (JackNetException& e) { + } catch (JackNetException& e) { jack_error("Connection lost."); return -1; } diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj index 3ef8728e..740dfe19 100755 --- a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -49,7 +49,6 @@ 4B1A94580F49C03600D3626B /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; 4B1A94590F49C03600D3626B /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; 4B1A945A0F49C03600D3626B /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; - 4B1A947F0F49C42300D3626B /* JackAudioQueueAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */; }; 4B1A95760F49CEAB00D3626B /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; 4B2791880F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; 4B2791890F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; @@ -63,7 +62,6 @@ 4B41469E10BD3C4300C12F0C /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; 4B41469F10BD3C4300C12F0C /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; 4B4146A010BD3C4300C12F0C /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; - 4B4146A110BD3C4300C12F0C /* JackAudioQueueAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */; }; 4B4146A210BD3C4300C12F0C /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; 4B4146A310BD3C4300C12F0C /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; }; 4B4146A410BD3C4300C12F0C /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; @@ -90,7 +88,6 @@ 4BCF75E010BC2FD90082C526 /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; 4BCF75E110BC2FD90082C526 /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; 4BCF75E210BC2FD90082C526 /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; - 4BCF75E310BC2FD90082C526 /* JackAudioQueueAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */; }; 4BCF75E410BC2FD90082C526 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; 4BCF75E510BC2FD90082C526 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; }; 4BCF75E610BC2FD90082C526 /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; @@ -129,7 +126,6 @@ 4BFF45670F4D5D9700106083 /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; 4BFF45680F4D5D9700106083 /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; 4BFF45690F4D5D9700106083 /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; - 4BFF456A0F4D5D9700106083 /* JackAudioQueueAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */; }; 4BFF456B0F4D5D9700106083 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; 4BFF456C0F4D5D9700106083 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; }; 4BFF456D0F4D5D9700106083 /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; @@ -161,8 +157,6 @@ 4B1A93540F49ACFC00D3626B /* JackMachThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMachThread.h; path = ../JackMachThread.h; sourceTree = SOURCE_ROOT; }; 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMachThread.cpp; path = ../JackMachThread.cpp; sourceTree = SOURCE_ROOT; }; 4B1A93870F49B0E300D3626B /* JackMachTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = JackMachTime.c; path = ../JackMachTime.c; sourceTree = SOURCE_ROOT; }; - 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioQueueAdapter.cpp; path = ../coreaudio/JackAudioQueueAdapter.cpp; sourceTree = SOURCE_ROOT; }; - 4B1A947E0F49C42300D3626B /* JackAudioQueueAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioQueueAdapter.h; path = ../coreaudio/JackAudioQueueAdapter.h; sourceTree = SOURCE_ROOT; }; 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.1.sdk/System/Library/Frameworks/AudioToolbox.framework; sourceTree = ""; }; 4B2791870F72570C000536B7 /* JackGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackGlobals.cpp; path = ../../common/JackGlobals.cpp; sourceTree = SOURCE_ROOT; }; 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -170,7 +164,7 @@ 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaust.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BCB37D5112D64B4008C7BC1 /* HardwareClock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HardwareClock.cpp; sourceTree = SOURCE_ROOT; }; 4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "iphone-faust.mm"; sourceTree = SOURCE_ROOT; }; - 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneThruNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BCF75F610BC30140082C526 /* audio_thru.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = audio_thru.mm; sourceTree = SOURCE_ROOT; }; 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; }; 4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioAdapterInterface.h; path = ../../common/JackAudioAdapterInterface.h; sourceTree = SOURCE_ROOT; }; @@ -268,7 +262,7 @@ 4BFF45120F4D59DB00106083 /* libjacknet.a */, 4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */, 4B0772380F54018C000DC657 /* iPhoneNetMaster.app */, - 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */, + 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */, 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */, 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */, ); @@ -283,7 +277,6 @@ 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */, 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */, 29B97315FDCFA39411CA2CEA /* Other Sources */, - 29B97317FDCFA39411CA2CEA /* Resources */, 29B97323FDCFA39411CA2CEA /* Frameworks */, 19C28FACFE9D520D11CA2CBB /* Products */, ); @@ -293,6 +286,7 @@ 29B97315FDCFA39411CA2CEA /* Other Sources */ = { isa = PBXGroup; children = ( + 29B97317FDCFA39411CA2CEA /* Resources */, 4BCF75F610BC30140082C526 /* audio_thru.mm */, 4BBDC8F90F5420C000465F9C /* freeverb.mm */, 4B0773840F541EE2000DC657 /* iPhoneNetAppDelegate.h */, @@ -302,8 +296,6 @@ 4BF1364C0F4B0F7700218A3F /* JackResampler.h */, 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */, 4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */, - 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */, - 4B1A947E0F49C42300D3626B /* JackAudioQueueAdapter.h */, 4B1A93870F49B0E300D3626B /* JackMachTime.c */, 4B1A93540F49ACFC00D3626B /* JackMachThread.h */, 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */, @@ -460,7 +452,7 @@ ); name = iPhoneThruNet; productName = iPhoneNet; - productReference = 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */; + productReference = 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */; productType = "com.apple.product-type.application"; }; 4BFF455E0F4D5D9700106083 /* iPhoneFaustNet */ = { @@ -566,7 +558,6 @@ 4B1A94580F49C03600D3626B /* JackNetTool.cpp in Sources */, 4B1A94590F49C03600D3626B /* JackNetUnixSocket.cpp in Sources */, 4B1A945A0F49C03600D3626B /* JackPosixThread.cpp in Sources */, - 4B1A947F0F49C42300D3626B /* JackAudioQueueAdapter.cpp in Sources */, 4BF1360F0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */, 4BF1364D0F4B0F7700218A3F /* JackResampler.cpp in Sources */, 4BF136550F4B0F9F00218A3F /* ringbuffer.c in Sources */, @@ -629,7 +620,6 @@ 4B41469E10BD3C4300C12F0C /* JackNetTool.cpp in Sources */, 4B41469F10BD3C4300C12F0C /* JackNetUnixSocket.cpp in Sources */, 4B4146A010BD3C4300C12F0C /* JackPosixThread.cpp in Sources */, - 4B4146A110BD3C4300C12F0C /* JackAudioQueueAdapter.cpp in Sources */, 4B4146A210BD3C4300C12F0C /* JackAudioAdapterInterface.cpp in Sources */, 4B4146A310BD3C4300C12F0C /* JackResampler.cpp in Sources */, 4B4146A410BD3C4300C12F0C /* ringbuffer.c in Sources */, @@ -663,7 +653,6 @@ 4BCF75E010BC2FD90082C526 /* JackNetTool.cpp in Sources */, 4BCF75E110BC2FD90082C526 /* JackNetUnixSocket.cpp in Sources */, 4BCF75E210BC2FD90082C526 /* JackPosixThread.cpp in Sources */, - 4BCF75E310BC2FD90082C526 /* JackAudioQueueAdapter.cpp in Sources */, 4BCF75E410BC2FD90082C526 /* JackAudioAdapterInterface.cpp in Sources */, 4BCF75E510BC2FD90082C526 /* JackResampler.cpp in Sources */, 4BCF75E610BC2FD90082C526 /* ringbuffer.c in Sources */, @@ -686,7 +675,6 @@ 4BFF45670F4D5D9700106083 /* JackNetTool.cpp in Sources */, 4BFF45680F4D5D9700106083 /* JackNetUnixSocket.cpp in Sources */, 4BFF45690F4D5D9700106083 /* JackPosixThread.cpp in Sources */, - 4BFF456A0F4D5D9700106083 /* JackAudioQueueAdapter.cpp in Sources */, 4BFF456B0F4D5D9700106083 /* JackAudioAdapterInterface.cpp in Sources */, 4BFF456C0F4D5D9700106083 /* JackResampler.cpp in Sources */, 4BFF456D0F4D5D9700106083 /* ringbuffer.c in Sources */, @@ -772,7 +760,7 @@ ); OTHER_LDFLAGS = ""; PRODUCT_NAME = iPhoneNetMaster; - SDKROOT = iphoneos2.2.1; + SDKROOT = iphoneos3.1.3; }; name = Debug; }; diff --git a/macosx/iphone/main_master.mm b/macosx/iphone/main_master.mm index b7cd0d28..b552de0b 100644 --- a/macosx/iphone/main_master.mm +++ b/macosx/iphone/main_master.mm @@ -20,7 +20,7 @@ jack_adapter_t* adapter; float** audio_input_buffer; float** audio_output_buffer; -int buffer_size = 2048; +int buffer_size = 4096; int sample_rate = 44100; jack_master_t request = { buffer_size, sample_rate, "master" }; @@ -30,18 +30,18 @@ void MasterAudioCallback(int frames, float** inputs, float** outputs, void* arg) { int i; + // Copy from iPod input to network for (i = 0; i < result.audio_input; i++) { memcpy(audio_output_buffer[i], inputs[i], buffer_size * sizeof(float)); } - if (jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) { printf("jack_net_master_send error..\n"); } + // Copy from network to iPod output if (jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { printf("jack_net_master_recv error..\n"); } - for (i = 0; i < result.audio_output; i++) { memcpy(outputs[i], audio_input_buffer[i], buffer_size * sizeof(float)); } @@ -52,6 +52,7 @@ int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int i; + int wait_usec = (unsigned long)((((float)buffer_size) / ((float)sample_rate)) * 1000000.0f); TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT); @@ -80,12 +81,9 @@ int main(int argc, char *argv[]) { return -1; } - // Run until interrupted + // Run until interrupted while (1) {} - audio_device.Stop(); - audio_device.Close(); - /* // Quite brutal way, the application actually does not start completely, the netjack audio processing loop is used instead... // Run until interrupted @@ -98,17 +96,20 @@ int main(int argc, char *argv[]) { if (jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) { printf("jack_net_master_send error..\n"); - break; } if (jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { printf("jack_net_master_recv error..\n"); - break; } usleep(wait_usec); }; */ + audio_device.Stop(); + audio_device.Close(); + + int retVal = UIApplicationMain(argc, argv, nil, nil); + // Wait for application end jack_net_master_close(net); @@ -118,13 +119,10 @@ int main(int argc, char *argv[]) { free(audio_input_buffer); for (i = 0; i < result.audio_output; i++) { - free(audio_output_buffer[i]); + free(audio_output_buffer[i]); } free(audio_output_buffer); - //int retVal = UIApplicationMain(argc, argv, nil, nil); [pool release]; - - //return retVal; - return 0; + return retVal; } From bc5ecb8e570e65fb45b6cfdc85783bb53db34682 Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 24 Feb 2010 20:20:41 +0000 Subject: [PATCH 033/472] Streaming from Mac to iPod (in slave mode) now somewhat works. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3924 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackAudioAdapterInterface.cpp | 2 + common/JackAudioAdapterInterface.h | 4 +- common/JackNetAPI.cpp | 20 +++++- .../iPhoneNet.xcodeproj/project.pbxproj | 16 +++-- macosx/iphone/main_master.mm | 2 +- macosx/iphone/main_slave.mm | 63 ++++++++++++++----- 6 files changed, 80 insertions(+), 27 deletions(-) diff --git a/common/JackAudioAdapterInterface.cpp b/common/JackAudioAdapterInterface.cpp index fed62e03..b8df9dd3 100644 --- a/common/JackAudioAdapterInterface.cpp +++ b/common/JackAudioAdapterInterface.cpp @@ -181,6 +181,8 @@ namespace Jack { if (fRingbufferCurSize > DEFAULT_RB_SIZE) fRingbufferCurSize = DEFAULT_RB_SIZE; + + jack_log("JackAudioAdapterInterface::ResetRingBuffers new_size = %ld", fRingbufferCurSize); for (int i = 0; i < fCaptureChannels; i++) fCaptureRingBuffer[i]->Reset(fRingbufferCurSize); diff --git a/common/JackAudioAdapterInterface.h b/common/JackAudioAdapterInterface.h index acf2b400..0412ae6f 100644 --- a/common/JackAudioAdapterInterface.h +++ b/common/JackAudioAdapterInterface.h @@ -129,8 +129,10 @@ namespace Jack fAdaptedSampleRate ( adapted_sample_rate ), fPIControler(host_sample_rate / host_sample_rate, 256), fQuality(0), + fRingbufferCurSize(DEFAULT_ADAPTATIVE_SIZE), fPullAndPushTime(0), - fRunning ( false ) + fRunning(false), + fAdaptative(true) {} virtual ~JackAudioAdapterInterface() diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index e780fd46..3ad6e771 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -746,10 +746,24 @@ struct JackNetAdapter : public JackAudioAdapterInterface { //ringbuffers fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; - for (int i = 0; i < fCaptureChannels; i++ ) + + if (fAdaptative) { + AdaptRingBufferSize(); + jack_info("Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize); + } else { + if (fRingbufferCurSize > DEFAULT_RB_SIZE) + fRingbufferCurSize = DEFAULT_RB_SIZE; + jack_info("Fixed ringbuffer size = %d frames", fRingbufferCurSize); + } + + for (int i = 0; i < fCaptureChannels; i++ ) { fCaptureRingBuffer[i] = new JackResampler(); - for (int i = 0; i < fPlaybackChannels; i++ ) + fCaptureRingBuffer[i]->Reset(fRingbufferCurSize); + } + for (int i = 0; i < fPlaybackChannels; i++ ) { fPlaybackRingBuffer[i] = new JackResampler(); + fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize); + } if (fCaptureChannels > 0) jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace()); @@ -925,7 +939,7 @@ SERVER_EXPORT void jack_log(const char *fmt, ...) { va_list ap; va_start(ap, fmt); - jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); + //jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); va_end(ap); } diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj index 740dfe19..7463ae57 100755 --- a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -27,7 +27,6 @@ 4B0772330F54018C000DC657 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 4B0772340F54018C000DC657 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; 4B07724A0F54021B000DC657 /* main_slave.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B0772490F54021B000DC657 /* main_slave.mm */; }; - 4B0772510F54022D000DC657 /* main_master.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B0772500F54022D000DC657 /* main_master.mm */; }; 4B0773860F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */; }; 4B0773870F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */; }; 4B0773880F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */; }; @@ -73,6 +72,7 @@ 4B4146AB10BD3C4300C12F0C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 4B4146AC10BD3C4300C12F0C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; 4BBDC8FA0F5420C000465F9C /* freeverb.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BBDC8F90F5420C000465F9C /* freeverb.mm */; }; + 4BC9C1F71135AB2800D22670 /* main_master.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B0772500F54022D000DC657 /* main_master.mm */; }; 4BCB37B6112D647C008C7BC1 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 4BCB37C7112D647C008C7BC1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 4BCB37C8112D647C008C7BC1 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; @@ -161,10 +161,11 @@ 4B2791870F72570C000536B7 /* JackGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackGlobals.cpp; path = ../../common/JackGlobals.cpp; sourceTree = SOURCE_ROOT; }; 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BBDC8F90F5420C000465F9C /* freeverb.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = freeverb.mm; sourceTree = SOURCE_ROOT; }; + 4BC9C1D31135AA1800D22670 /* iPhoneNetMasterAppl-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "iPhoneNetMasterAppl-Info.plist"; sourceTree = ""; }; 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaust.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BCB37D5112D64B4008C7BC1 /* HardwareClock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HardwareClock.cpp; sourceTree = SOURCE_ROOT; }; 4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "iphone-faust.mm"; sourceTree = SOURCE_ROOT; }; - 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneThruNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BCF75F610BC30140082C526 /* audio_thru.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = audio_thru.mm; sourceTree = SOURCE_ROOT; }; 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; }; 4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioAdapterInterface.h; path = ../../common/JackAudioAdapterInterface.h; sourceTree = SOURCE_ROOT; }; @@ -262,7 +263,7 @@ 4BFF45120F4D59DB00106083 /* libjacknet.a */, 4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */, 4B0772380F54018C000DC657 /* iPhoneNetMaster.app */, - 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */, + 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */, 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */, 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */, ); @@ -319,6 +320,7 @@ children = ( 28AD733E0D9D9553002E5188 /* MainWindow.xib */, 8D1107310486CEB800E47090 /* Info.plist */, + 4BC9C1D31135AA1800D22670 /* iPhoneNetMasterAppl-Info.plist */, ); name = Resources; sourceTree = ""; @@ -452,7 +454,7 @@ ); name = iPhoneThruNet; productName = iPhoneNet; - productReference = 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */; + productReference = 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */; productType = "com.apple.product-type.application"; }; 4BFF455E0F4D5D9700106083 /* iPhoneFaustNet */ = { @@ -583,11 +585,11 @@ 4B07722C0F54018C000DC657 /* JackAudioAdapterInterface.cpp in Sources */, 4B07722D0F54018C000DC657 /* JackResampler.cpp in Sources */, 4B07722E0F54018C000DC657 /* ringbuffer.c in Sources */, - 4B0772510F54022D000DC657 /* main_master.mm in Sources */, 4B0773860F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, 4B27918B0F72570C000536B7 /* JackGlobals.cpp in Sources */, 4BF15E2511356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, 4BF15F7811357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */, + 4BC9C1F71135AB2800D22670 /* main_master.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -699,6 +701,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( + ../../macosx/coreaudio, ../../macosx, ../../posix, ../../common/jack, @@ -711,7 +714,7 @@ ); OTHER_LDFLAGS = ""; PRODUCT_NAME = iPhoneNetSlave; - SDKROOT = iphoneos2.2.1; + SDKROOT = iphoneos3.1.3; }; name = Debug; }; @@ -723,6 +726,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( + ../../macosx/coreaudio, ../../common/jack, ../../common, ../../posix, diff --git a/macosx/iphone/main_master.mm b/macosx/iphone/main_master.mm index b552de0b..00123edf 100644 --- a/macosx/iphone/main_master.mm +++ b/macosx/iphone/main_master.mm @@ -26,7 +26,7 @@ int sample_rate = 44100; jack_master_t request = { buffer_size, sample_rate, "master" }; jack_slave_t result; -void MasterAudioCallback(int frames, float** inputs, float** outputs, void* arg) +static void MasterAudioCallback(int frames, float** inputs, float** outputs, void* arg) { int i; diff --git a/macosx/iphone/main_slave.mm b/macosx/iphone/main_slave.mm index af9b54c0..f657f045 100644 --- a/macosx/iphone/main_slave.mm +++ b/macosx/iphone/main_slave.mm @@ -9,33 +9,39 @@ #import #include +#include "TiPhoneCoreAudioRenderer.h" + #define NUM_INPUT 2 #define NUM_OUTPUT 2 jack_net_slave_t* net; jack_adapter_t* adapter; +int buffer_size; +int sample_rate ; + + static int net_process(jack_nframes_t buffer_size, - int audio_input, - float** audio_input_buffer, - int midi_input, - void** midi_input_buffer, - int audio_output, - float** audio_output_buffer, - int midi_output, - void** midi_output_buffer, - void* data) + int audio_input, + float** audio_input_buffer, + int midi_input, + void** midi_input_buffer, + int audio_output, + float** audio_output_buffer, + int midi_output, + void** midi_output_buffer, + void* data) { - // Process input, produce output - if (audio_input == audio_output) { - // Copy input to output - for (int i = 0; i < audio_input; i++) { - memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); - } - } + + jack_adapter_pull_and_push(adapter, audio_output_buffer, audio_input_buffer, buffer_size); return 0; } +static void SlaveAudioCallback(int frames, float** inputs, float** outputs, void* arg) +{ + jack_adapter_push_and_pull(adapter, inputs, outputs, frames); +} + int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; @@ -46,17 +52,42 @@ int main(int argc, char *argv[]) { if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { return -1; } + + if ((adapter = jack_create_adapter(NUM_INPUT, + NUM_OUTPUT, + result.buffer_size, + result.sample_rate, + result.buffer_size, + result.sample_rate)) == 0) { + return -1; + } + + TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT); jack_set_net_slave_process_callback(net, net_process, NULL); if (jack_net_slave_activate(net) != 0) { return -1; } + if (audio_device.OpenDefault(result.buffer_size, result.sample_rate) < 0) { + return -1; + } + + audio_device.SetAudioCallback(SlaveAudioCallback, NULL); + + if (audio_device.Start() < 0) { + return -1; + } + int retVal = UIApplicationMain(argc, argv, nil, nil); [pool release]; + audio_device.Stop(); + audio_device.Close(); + // Wait for application end jack_net_slave_deactivate(net); jack_net_slave_close(net); + jack_destroy_adapter(adapter); return retVal; } From 21164db0b1ac556241beb0f59a4b57a94e78d7da Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 1 Mar 2010 11:39:21 +0000 Subject: [PATCH 034/472] Cleanup. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3926 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackAudioAdapterInterface.cpp | 2 - common/JackNetInterface.cpp | 71 +++++++++--------- .../iPhoneNet.xcodeproj/project.pbxproj | 34 ++++++--- macosx/iphone/icon.png | Bin 0 -> 5297 bytes 4 files changed, 60 insertions(+), 47 deletions(-) create mode 100644 macosx/iphone/icon.png diff --git a/common/JackAudioAdapterInterface.cpp b/common/JackAudioAdapterInterface.cpp index b8df9dd3..fed62e03 100644 --- a/common/JackAudioAdapterInterface.cpp +++ b/common/JackAudioAdapterInterface.cpp @@ -181,8 +181,6 @@ namespace Jack { if (fRingbufferCurSize > DEFAULT_RB_SIZE) fRingbufferCurSize = DEFAULT_RB_SIZE; - - jack_log("JackAudioAdapterInterface::ResetRingBuffers new_size = %ld", fRingbufferCurSize); for (int i = 0; i < fCaptureChannels; i++) fCaptureRingBuffer[i]->Reset(fRingbufferCurSize); diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 1ecc04ca..6d287258 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -24,6 +24,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. using namespace std; +#define PACKET_AVAILABLE_SIZE (fParams.fMtu - sizeof(packet_header_t)) + /* TODO : since midi buffers now uses up to BUFFER_SIZE_MAX frames, probably also use BUFFER_SIZE_MAX in everything related to MIDI events @@ -61,6 +63,7 @@ namespace Jack JackNetInterface::JackNetInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip ) : fSocket ( socket ) { + jack_log("JackNetInterface ( session_params_t& params...)"); fParams = params; strcpy(fMulticastIP, multicast_ip); fTxBuffer = NULL; @@ -93,7 +96,7 @@ namespace Jack if (fParams.fSendAudioChannels == 0 && fParams.fReturnAudioChannels == 0) { fParams.fFramesPerPacket = fParams.fPeriodSize; } else { - jack_nframes_t period = ( int ) powf ( 2.f, ( int ) ( log (float ( fParams.fMtu - sizeof ( packet_header_t ) ) + jack_nframes_t period = ( int ) powf ( 2.f, ( int ) ( log (float (PACKET_AVAILABLE_SIZE) / ( max ( fParams.fReturnAudioChannels, fParams.fSendAudioChannels ) * sizeof ( sample_t ) ) ) / log ( 2. ) ) ); fParams.fFramesPerPacket = ( period > fParams.fPeriodSize ) ? fParams.fPeriodSize : period; } @@ -109,7 +112,7 @@ namespace Jack audio_size = fParams.fMtu * ( fParams.fPeriodSize / fParams.fFramesPerPacket ); //midi midi_size = fParams.fMtu * ( max ( fParams.fSendMidiChannels, fParams.fReturnMidiChannels ) * - fParams.fPeriodSize * sizeof ( sample_t ) / ( fParams.fMtu - sizeof ( packet_header_t ) ) ); + fParams.fPeriodSize * sizeof(sample_t) / PACKET_AVAILABLE_SIZE); //bufsize = sync + audio + midi bufsize = MAX_LATENCY * (fParams.fMtu + ( int ) audio_size + ( int ) midi_size); @@ -128,13 +131,14 @@ namespace Jack { //even if there is no midi data, jack need an empty buffer to know there is no event to read //99% of the cases : all data in one packet - if ( fTxHeader.fMidiDataSize <= ( fParams.fMtu - sizeof ( packet_header_t ) ) ) + + if (fTxHeader.fMidiDataSize <= PACKET_AVAILABLE_SIZE) { return 1; - //else, get the number of needed packets (simply slice the biiig buffer) - int npckt = fTxHeader.fMidiDataSize / ( fParams.fMtu - sizeof ( packet_header_t ) ); - if ( fTxHeader.fMidiDataSize % ( fParams.fMtu - sizeof ( packet_header_t ) ) ) - return ++npckt; - return npckt; + } else { //get the number of needed packets (simply slice the biiig buffer) + return (fTxHeader.fMidiDataSize % PACKET_AVAILABLE_SIZE) + ? (fTxHeader.fMidiDataSize / PACKET_AVAILABLE_SIZE + 1) + : fTxHeader.fMidiDataSize / PACKET_AVAILABLE_SIZE; + } } bool JackNetInterface::IsNextPacket() @@ -162,7 +166,7 @@ namespace Jack fNSubProcess = fParams.fPeriodSize / fParams.fFramesPerPacket; //payload size - fPayloadSize = fParams.fMtu - sizeof ( packet_header_t ); + fPayloadSize = PACKET_AVAILABLE_SIZE; //TX header init strcpy ( fTxHeader.fPacketType, "header" ); @@ -460,10 +464,11 @@ namespace Jack // - if the network is two fast, just wait the next cycle, this mode allows a shorter cycle duration for the master // - this mode will skip the two first cycles, thus it lets time for data to be processed and queued on the socket rx buffer //the slow mode is the safest mode because it wait twice the bandwidth relative time (send/return + process) - if (fCycleOffset < 2) - return 0; - else + if (fCycleOffset < 2) { + return 0; + } else { rx_bytes = Recv ( rx_head->fPacketSize, 0 ); + } if (fCycleOffset > 2) { jack_info("Warning : '%s' runs in slow network mode, but data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); @@ -475,13 +480,15 @@ namespace Jack // - extra latency is set to one cycle, what is the time needed to receive streams using full network bandwidth // - if the network is too fast, just wait the next cycle, the benefit here is the master's cycle is shorter // - indeed, data is supposed to be on the network rx buffer, so we don't have to wait for it - if (fCycleOffset < 1) + if (fCycleOffset < 1) { return 0; - else + } else { rx_bytes = Recv ( rx_head->fPacketSize, 0 ); + } - if (fCycleOffset != 1) + if (fCycleOffset != 1) { jack_info("'%s' can't run in normal network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); + } break; case 'f' : @@ -491,8 +498,9 @@ namespace Jack // - but if there is a cycle offset, tell the user, that means we're not in fast mode anymore, network is too slow rx_bytes = Recv ( rx_head->fPacketSize, 0 ); - if (fCycleOffset != 0) + if (fCycleOffset != 0) { jack_info("'%s' can't run in fast network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); + } break; } @@ -539,9 +547,6 @@ namespace Jack case 'a': //audio rx_bytes = Recv ( rx_head->fPacketSize, 0 ); - // SL: 25/01/09 - // if ( !IsNextPacket() ) - // jack_error ( "Packet(s) missing from '%s'...", fParams.fName ); if (recvd_audio_pckt++ != rx_head->fSubCycle) { jack_error("Packet(s) missing from '%s'...", fParams.fSlaveNetName); } @@ -553,10 +558,6 @@ namespace Jack break; case 's': //sync - /* SL: 25/01/09 - if ( rx_head->fCycle == fTxHeader.fCycle ) - return 0; - */ jack_info("NetMaster : overloaded, skipping receive from '%s'", fParams.fName); return 0; } @@ -805,16 +806,15 @@ namespace Jack { net_error_t error = fSocket.GetError(); //no data isn't really an error in realtime processing, so just return 0 - if ( error == NET_NO_DATA ) + if ( error == NET_NO_DATA ) { jack_error ( "No data, is the master still running ?" ); //if a network error occurs, this exception will restart the driver - else if ( error == NET_CONN_ERROR ) - { + } else if ( error == NET_CONN_ERROR ) { jack_error ( "Connection lost." ); throw JackNetException(); - } - else + } else { jack_error ( "Fatal error in slave receive : %s", StrError ( NET_ERROR_CODE ) ); + } } packet_header_t* header = reinterpret_cast(fRxBuffer); @@ -833,13 +833,12 @@ namespace Jack { net_error_t error = fSocket.GetError(); //if a network error occurs, this exception will restart the driver - if ( error == NET_CONN_ERROR ) - { + if ( error == NET_CONN_ERROR ) { jack_error ( "Connection lost." ); throw JackNetException(); - } - else + } else { jack_error ( "Fatal error in slave send : %s", StrError ( NET_ERROR_CODE ) ); + } } return tx_bytes; } @@ -848,6 +847,7 @@ namespace Jack { int rx_bytes = 0; packet_header_t* rx_head = reinterpret_cast ( fRxBuffer ); + //receive sync (launch the cycle) do { @@ -885,17 +885,16 @@ namespace Jack fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; fNetMidiCaptureBuffer->RenderFromNetwork ( rx_head->fSubCycle, rx_bytes - sizeof ( packet_header_t ) ); + // Last midi packet is received, so finish rendering... if ( ++recvd_midi_pckt == rx_head->fNMidiPckt ) fNetMidiCaptureBuffer->RenderToJackPorts(); break; case 'a': //audio rx_bytes = Recv ( rx_head->fPacketSize, 0 ); - //SL: 25/01/09 - // if ( !IsNextPacket() ) - // jack_error ( "Packet(s) missing..." ); if (recvd_audio_pckt++ != rx_head->fSubCycle) { - jack_error("Packet(s) missing from '%s'...", fParams.fMasterNetName); + //jack_error("Packet(s) missing from '%s'...", fParams.fMasterNetName); + jack_error("Packet(s) missing from '%s'... %d %d %d", fParams.fMasterNetName, rx_head->fCycle, recvd_audio_pckt, rx_head->fSubCycle); } fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fSubCycle = rx_head->fSubCycle; diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj index 7463ae57..5ea267ea 100755 --- a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -71,6 +71,12 @@ 4B4146AA10BD3C4300C12F0C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 4B4146AB10BD3C4300C12F0C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 4B4146AC10BD3C4300C12F0C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; + 4B9CB1371136CA99007DE01A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B9CB1361136CA99007DE01A /* icon.png */; }; + 4B9CB1381136CA99007DE01A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B9CB1361136CA99007DE01A /* icon.png */; }; + 4B9CB1391136CA99007DE01A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B9CB1361136CA99007DE01A /* icon.png */; }; + 4B9CB13A1136CA99007DE01A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B9CB1361136CA99007DE01A /* icon.png */; }; + 4B9CB13B1136CA99007DE01A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B9CB1361136CA99007DE01A /* icon.png */; }; + 4B9CB13C1136CA99007DE01A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B9CB1361136CA99007DE01A /* icon.png */; }; 4BBDC8FA0F5420C000465F9C /* freeverb.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BBDC8F90F5420C000465F9C /* freeverb.mm */; }; 4BC9C1F71135AB2800D22670 /* main_master.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B0772500F54022D000DC657 /* main_master.mm */; }; 4BCB37B6112D647C008C7BC1 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; @@ -160,12 +166,13 @@ 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.1.sdk/System/Library/Frameworks/AudioToolbox.framework; sourceTree = ""; }; 4B2791870F72570C000536B7 /* JackGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackGlobals.cpp; path = ../../common/JackGlobals.cpp; sourceTree = SOURCE_ROOT; }; 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B9CB1361136CA99007DE01A /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = SOURCE_ROOT; }; 4BBDC8F90F5420C000465F9C /* freeverb.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = freeverb.mm; sourceTree = SOURCE_ROOT; }; 4BC9C1D31135AA1800D22670 /* iPhoneNetMasterAppl-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "iPhoneNetMasterAppl-Info.plist"; sourceTree = ""; }; 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaust.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BCB37D5112D64B4008C7BC1 /* HardwareClock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HardwareClock.cpp; sourceTree = SOURCE_ROOT; }; 4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "iphone-faust.mm"; sourceTree = SOURCE_ROOT; }; - 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneThruNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BCF75F610BC30140082C526 /* audio_thru.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = audio_thru.mm; sourceTree = SOURCE_ROOT; }; 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; }; 4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioAdapterInterface.h; path = ../../common/JackAudioAdapterInterface.h; sourceTree = SOURCE_ROOT; }; @@ -263,7 +270,7 @@ 4BFF45120F4D59DB00106083 /* libjacknet.a */, 4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */, 4B0772380F54018C000DC657 /* iPhoneNetMaster.app */, - 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */, + 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */, 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */, 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */, ); @@ -318,6 +325,7 @@ 29B97317FDCFA39411CA2CEA /* Resources */ = { isa = PBXGroup; children = ( + 4B9CB1361136CA99007DE01A /* icon.png */, 28AD733E0D9D9553002E5188 /* MainWindow.xib */, 8D1107310486CEB800E47090 /* Info.plist */, 4BC9C1D31135AA1800D22670 /* iPhoneNetMasterAppl-Info.plist */, @@ -389,9 +397,9 @@ productReference = 4B0772380F54018C000DC657 /* iPhoneNetMaster.app */; productType = "com.apple.product-type.application"; }; - 4B1A940F0F49BDE000D3626B /* jacknet */ = { + 4B1A940F0F49BDE000D3626B /* libjacknet */ = { isa = PBXNativeTarget; - buildConfigurationList = 4B1A94130F49BDFF00D3626B /* Build configuration list for PBXNativeTarget "jacknet" */; + buildConfigurationList = 4B1A94130F49BDFF00D3626B /* Build configuration list for PBXNativeTarget "libjacknet" */; buildPhases = ( 4B1A940C0F49BDE000D3626B /* Headers */, 4B1A940D0F49BDE000D3626B /* Sources */, @@ -401,7 +409,7 @@ ); dependencies = ( ); - name = jacknet; + name = libjacknet; productName = jacknet; productReference = 4BFF45120F4D59DB00106083 /* libjacknet.a */; productType = "com.apple.product-type.library.static"; @@ -454,7 +462,7 @@ ); name = iPhoneThruNet; productName = iPhoneNet; - productReference = 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */; + productReference = 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */; productType = "com.apple.product-type.application"; }; 4BFF455E0F4D5D9700106083 /* iPhoneFaustNet */ = { @@ -492,7 +500,7 @@ 4BCF75D810BC2FD90082C526 /* iPhoneThruNet */, 4B41469610BD3C4300C12F0C /* iPhoneFaustNet Distribution */, 4BCB37B4112D647C008C7BC1 /* iPhoneFaust */, - 4B1A940F0F49BDE000D3626B /* jacknet */, + 4B1A940F0F49BDE000D3626B /* libjacknet */, ); }; /* End PBXProject section */ @@ -503,6 +511,7 @@ buildActionMask = 2147483647; files = ( 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */, + 4B9CB1381136CA99007DE01A /* icon.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -511,6 +520,7 @@ buildActionMask = 2147483647; files = ( 4B0772210F54018C000DC657 /* MainWindow.xib in Resources */, + 4B9CB1371136CA99007DE01A /* icon.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -519,6 +529,7 @@ buildActionMask = 2147483647; files = ( 4B41469810BD3C4300C12F0C /* MainWindow.xib in Resources */, + 4B9CB13B1136CA99007DE01A /* icon.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -527,6 +538,7 @@ buildActionMask = 2147483647; files = ( 4BCB37B6112D647C008C7BC1 /* MainWindow.xib in Resources */, + 4B9CB13C1136CA99007DE01A /* icon.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -535,6 +547,7 @@ buildActionMask = 2147483647; files = ( 4BCF75DA10BC2FD90082C526 /* MainWindow.xib in Resources */, + 4B9CB13A1136CA99007DE01A /* icon.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -543,6 +556,7 @@ buildActionMask = 2147483647; files = ( 4BFF45600F4D5D9700106083 /* MainWindow.xib in Resources */, + 4B9CB1391136CA99007DE01A /* icon.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -737,7 +751,7 @@ "$(inherited)", "\"$(SRCROOT)/build/Debug-iphonesimulator\"", ); - PRODUCT_NAME = iPhoneNetSlave; + PRODUCT_NAME = NetJackSlave; }; name = Release; }; @@ -808,6 +822,7 @@ MACH_O_TYPE = staticlib; PREBINDING = NO; PRODUCT_NAME = jacknet; + SDKROOT = iphoneos3.1.3; STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = static; }; name = Debug; @@ -828,6 +843,7 @@ ); PREBINDING = NO; PRODUCT_NAME = jacknet; + SDKROOT = iphoneos3.1.3; ZERO_LINK = NO; }; name = Release; @@ -1083,7 +1099,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4B1A94130F49BDFF00D3626B /* Build configuration list for PBXNativeTarget "jacknet" */ = { + 4B1A94130F49BDFF00D3626B /* Build configuration list for PBXNativeTarget "libjacknet" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B1A94110F49BDE100D3626B /* Debug */, diff --git a/macosx/iphone/icon.png b/macosx/iphone/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9e312ea68368e826171b0212a15a548c4e34a78a GIT binary patch literal 5297 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 DmEt5- literal 0 HcmV?d00001 From 1305523784a200c0535a1f54b498826453673c69 Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 2 Mar 2010 09:37:22 +0000 Subject: [PATCH 035/472] rebase from trunk 3916:3930 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3931 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 6 +- common/JackNetTool.cpp | 2 +- macosx/Jackdmp.xcodeproj/project.pbxproj | 92 +++++-------------- macosx/coreaudio/JackCoreAudioAdapter.cpp | 56 ++++++++--- macosx/coreaudio/JackCoreAudioDriver.cpp | 37 ++++++-- .../iPhoneNet.xcodeproj/project.pbxproj | 1 + wscript | 14 ++- 7 files changed, 114 insertions(+), 94 deletions(-) diff --git a/ChangeLog b/ChangeLog index 41d80af3..99565bf9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -29,7 +29,11 @@ Mario Lang Jackdmp changes log --------------------------- -2010-02-15 Gabriel M. Beddingfield +2010-03-02 Stephane Letz + + * Improve JackCoreAudioDriver and JackCoreAudioAdapter : when no devices are described, takes default input and output and aggregate them. + +2010-02-15 Stephane Letz * Version 1.9.6 started. diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index 81e2404f..82f03523 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -283,7 +283,7 @@ namespace Jack jack_info ( "Sample rate : %u frames per second", params->fSampleRate ); jack_info ( "Period size : %u frames per period", params->fPeriodSize ); jack_info ( "Frames per packet : %u", params->fFramesPerPacket ); - jack_info ( "Packet per period : %u", params->fPeriodSize / params->fFramesPerPacket ); + jack_info ( "Packet per period : %u", (params->fFramesPerPacket != 0) ? params->fPeriodSize / params->fFramesPerPacket : 0); jack_info ( "Bitdepth : %s", bitdepth ); jack_info ( "Slave mode : %s", ( params->fSlaveSyncMode ) ? "sync" : "async" ); jack_info ( "Network mode : %s", mode ); diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index d4e6c7f0..17395706 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -106,7 +106,6 @@ 4B19B3140E2362E800DD4A82 /* JackAudioAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3070E2362E700DD4A82 /* JackAudioAdapter.h */; }; 4B19B3150E2362E800DD4A82 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3080E2362E700DD4A82 /* JackAudioAdapterInterface.cpp */; }; 4B19B3160E2362E800DD4A82 /* JackAudioAdapterInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3090E2362E700DD4A82 /* JackAudioAdapterInterface.h */; }; - 4B19B3190E2362E800DD4A82 /* JackException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30C0E2362E700DD4A82 /* JackException.h */; }; 4B19B31B0E2362E800DD4A82 /* JackLibSampleRateResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B30E0E2362E700DD4A82 /* JackLibSampleRateResampler.cpp */; }; 4B19B31C0E2362E800DD4A82 /* JackLibSampleRateResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */; }; 4B19B31F0E2362E800DD4A82 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */; }; @@ -423,15 +422,12 @@ 4B5DB9830CD2429A00EBA5EE /* JackDebugClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B98AE000931D30C0091932A /* JackDebugClient.cpp */; }; 4B5DB9840CD2429B00EBA5EE /* JackDebugClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B98AE010931D30C0091932A /* JackDebugClient.h */; }; 4B5E08C30E5B66EE00BEE4E0 /* JackAudioAdapterInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3090E2362E700DD4A82 /* JackAudioAdapterInterface.h */; }; - 4B5E08C40E5B66EE00BEE4E0 /* JackException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30C0E2362E700DD4A82 /* JackException.h */; }; 4B5E08C60E5B66EE00BEE4E0 /* JackLibSampleRateResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */; }; 4B5E08CC0E5B66EE00BEE4E0 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3080E2362E700DD4A82 /* JackAudioAdapterInterface.cpp */; }; 4B5E08CD0E5B66EE00BEE4E0 /* JackLibSampleRateResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B30E0E2362E700DD4A82 /* JackLibSampleRateResampler.cpp */; }; 4B5E08CE0E5B66EE00BEE4E0 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */; }; 4B5E08E10E5B676C00BEE4E0 /* JackNetAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5E08DF0E5B676C00BEE4E0 /* JackNetAdapter.cpp */; }; 4B5E08E20E5B676D00BEE4E0 /* JackNetAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B5E08E00E5B676C00BEE4E0 /* JackNetAdapter.h */; }; - 4B5E08EB0E5B67EA00BEE4E0 /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B76C7680E5AB2DB00E2AC21 /* JackNetInterface.cpp */; }; - 4B5E08EC0E5B67EB00BEE4E0 /* JackNetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B76C7690E5AB2DB00E2AC21 /* JackNetInterface.h */; }; 4B5E08EE0E5B680200BEE4E0 /* JackAudioAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3060E2362E700DD4A82 /* JackAudioAdapter.cpp */; }; 4B5E08EF0E5B680200BEE4E0 /* JackAudioAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3070E2362E700DD4A82 /* JackAudioAdapter.h */; }; 4B5F253E0DEE9B8F0041E486 /* JackLockedEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B5F253D0DEE9B8F0041E486 /* JackLockedEngine.h */; }; @@ -570,10 +566,6 @@ 4B6C738A0CC60A85001AFFD4 /* thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737D0CC60A6D001AFFD4 /* thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C738B0CC60A86001AFFD4 /* transport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737E0CC60A6D001AFFD4 /* transport.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6F7AEE0CD0CDBD00F48A9D /* JackEngineControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6F7AEC0CD0CDBD00F48A9D /* JackEngineControl.cpp */; }; - 4B76C76A0E5AB2DB00E2AC21 /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B76C7680E5AB2DB00E2AC21 /* JackNetInterface.cpp */; }; - 4B76C76B0E5AB2DB00E2AC21 /* JackNetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B76C7690E5AB2DB00E2AC21 /* JackNetInterface.h */; }; - 4B76C76C0E5AB2DB00E2AC21 /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B76C7680E5AB2DB00E2AC21 /* JackNetInterface.cpp */; }; - 4B76C76D0E5AB2DB00E2AC21 /* JackNetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B76C7690E5AB2DB00E2AC21 /* JackNetInterface.h */; }; 4B80D7E80BA0D17400F035BB /* JackMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */; }; 4B80D7E90BA0D17400F035BB /* JackMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */; }; 4B80D7EA0BA0D17400F035BB /* JackMidiAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */; }; @@ -755,16 +747,22 @@ 4BC216850A444BAD00BDA09F /* JackServerAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1F50834EFB000C94B91 /* JackServerAPI.cpp */; }; 4BC216890A444BDE00BDA09F /* JackServerGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC216880A444BDE00BDA09F /* JackServerGlobals.cpp */; }; 4BC2168E0A444BED00BDA09F /* JackServerGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC2168D0A444BED00BDA09F /* JackServerGlobals.h */; }; + 4BC2CA55113C6C930076717C /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B76C7680E5AB2DB00E2AC21 /* JackNetInterface.cpp */; }; + 4BC2CA56113C6C940076717C /* JackNetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B76C7690E5AB2DB00E2AC21 /* JackNetInterface.h */; }; + 4BC2CA57113C6C9B0076717C /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */; }; + 4BC2CA58113C6C9C0076717C /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */; }; + 4BC2CA59113C6CB60076717C /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B76C7680E5AB2DB00E2AC21 /* JackNetInterface.cpp */; }; + 4BC2CA5A113C6CB80076717C /* JackNetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B76C7690E5AB2DB00E2AC21 /* JackNetInterface.h */; }; + 4BC2CA5B113C6CBE0076717C /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */; }; + 4BC2CA5C113C6CC00076717C /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */; }; + 4BC2CA5D113C6CC90076717C /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B76C7680E5AB2DB00E2AC21 /* JackNetInterface.cpp */; }; + 4BC2CA5E113C6CCA0076717C /* JackNetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B76C7690E5AB2DB00E2AC21 /* JackNetInterface.h */; }; + 4BC2CA5F113C6CD10076717C /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */; }; + 4BC2CA60113C6CD20076717C /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */; }; 4BC3B6A40E703B2E0066E42F /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; 4BC3B6A50E703B2E0066E42F /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; 4BC3B6A60E703B2E0066E42F /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; 4BC3B6A70E703B2E0066E42F /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; - 4BC3B6BB0E703BCC0066E42F /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */; }; - 4BC3B6BC0E703BCC0066E42F /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */; }; - 4BC3B6BD0E703BCC0066E42F /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */; }; - 4BC3B6BE0E703BCC0066E42F /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */; }; - 4BC3B6BF0E703BCC0066E42F /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */; }; - 4BC3B6C00E703BCC0066E42F /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */; }; 4BCBCE5D10C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5910C4FE3F00450FFE /* JackPhysicalMidiInput.cpp */; }; 4BCBCE5E10C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCBCE5A10C4FE3F00450FFE /* JackPhysicalMidiInput.h */; }; 4BCBCE5F10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5B10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp */; }; @@ -787,25 +785,13 @@ 4BDCDB951001FB9C00B15929 /* JackCoreMidiDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF339140F8B86DC0080FB5B /* JackCoreMidiDriver.h */; }; 4BDCDB971001FB9C00B15929 /* JackCoreMidiDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF339150F8B86DC0080FB5B /* JackCoreMidiDriver.cpp */; }; 4BDCDBB91001FCC000B15929 /* JackNetDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = BA222ADD0DC882A5001A17F4 /* JackNetDriver.h */; }; - 4BDCDBBA1001FCC000B15929 /* JackNetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B76C7690E5AB2DB00E2AC21 /* JackNetInterface.h */; }; - 4BDCDBBB1001FCC000B15929 /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */; }; 4BDCDBBD1001FCC000B15929 /* JackNetDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA222ADC0DC882A5001A17F4 /* JackNetDriver.cpp */; }; - 4BDCDBBE1001FCC000B15929 /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B76C7680E5AB2DB00E2AC21 /* JackNetInterface.cpp */; }; - 4BDCDBBF1001FCC000B15929 /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */; }; 4BDCDBD11001FD0100B15929 /* JackWaitThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBC93B80DF9736C002DF220 /* JackWaitThreadedDriver.cpp */; }; 4BDCDBD21001FD0200B15929 /* JackWaitThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BBC93B90DF9736C002DF220 /* JackWaitThreadedDriver.h */; }; 4BDCDBD91001FD2D00B15929 /* JackNetManager.h in Headers */ = {isa = PBXBuildFile; fileRef = BA222AEC0DC883B3001A17F4 /* JackNetManager.h */; }; - 4BDCDBDA1001FD2D00B15929 /* JackNetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B76C7690E5AB2DB00E2AC21 /* JackNetInterface.h */; }; - 4BDCDBDB1001FD2D00B15929 /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */; }; - 4BDCDBDC1001FD2D00B15929 /* JackArgParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF284170F31B4BC00B05BE3 /* JackArgParser.h */; }; 4BDCDBDE1001FD2D00B15929 /* JackNetManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA222AEB0DC883B3001A17F4 /* JackNetManager.cpp */; }; - 4BDCDBDF1001FD2D00B15929 /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B76C7680E5AB2DB00E2AC21 /* JackNetInterface.cpp */; }; - 4BDCDBE01001FD2D00B15929 /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */; }; - 4BDCDBE11001FD2D00B15929 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; - 4BDCDBE21001FD2D00B15929 /* JackArgParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF284160F31B4BC00B05BE3 /* JackArgParser.cpp */; }; 4BDCDBEE1001FD7300B15929 /* JackAudioAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3070E2362E700DD4A82 /* JackAudioAdapter.h */; }; 4BDCDBEF1001FD7300B15929 /* JackAudioAdapterInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3090E2362E700DD4A82 /* JackAudioAdapterInterface.h */; }; - 4BDCDBF01001FD7300B15929 /* JackException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30C0E2362E700DD4A82 /* JackException.h */; }; 4BDCDBF11001FD7300B15929 /* JackLibSampleRateResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */; }; 4BDCDBF21001FD7300B15929 /* JackCoreAudioAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE5FED00E725C320020B576 /* JackCoreAudioAdapter.h */; }; 4BDCDBF41001FD7300B15929 /* JackAudioAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3060E2362E700DD4A82 /* JackAudioAdapter.cpp */; }; @@ -817,19 +803,14 @@ 4BDCDC091001FDA800B15929 /* JackArgParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF284160F31B4BC00B05BE3 /* JackArgParser.cpp */; }; 4BDCDC0A1001FDA800B15929 /* JackArgParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF284170F31B4BC00B05BE3 /* JackArgParser.h */; }; 4BDCDC111001FDE300B15929 /* JackAudioAdapterInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3090E2362E700DD4A82 /* JackAudioAdapterInterface.h */; }; - 4BDCDC121001FDE300B15929 /* JackException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30C0E2362E700DD4A82 /* JackException.h */; }; 4BDCDC131001FDE300B15929 /* JackLibSampleRateResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */; }; 4BDCDC141001FDE300B15929 /* JackNetAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B5E08E00E5B676C00BEE4E0 /* JackNetAdapter.h */; }; - 4BDCDC151001FDE300B15929 /* JackNetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B76C7690E5AB2DB00E2AC21 /* JackNetInterface.h */; }; 4BDCDC161001FDE300B15929 /* JackAudioAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3070E2362E700DD4A82 /* JackAudioAdapter.h */; }; - 4BDCDC171001FDE300B15929 /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */; }; 4BDCDC191001FDE300B15929 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3080E2362E700DD4A82 /* JackAudioAdapterInterface.cpp */; }; 4BDCDC1A1001FDE300B15929 /* JackLibSampleRateResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B30E0E2362E700DD4A82 /* JackLibSampleRateResampler.cpp */; }; 4BDCDC1B1001FDE300B15929 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */; }; 4BDCDC1C1001FDE300B15929 /* JackNetAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5E08DF0E5B676C00BEE4E0 /* JackNetAdapter.cpp */; }; - 4BDCDC1D1001FDE300B15929 /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B76C7680E5AB2DB00E2AC21 /* JackNetInterface.cpp */; }; 4BDCDC1E1001FDE300B15929 /* JackAudioAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3060E2362E700DD4A82 /* JackAudioAdapter.cpp */; }; - 4BDCDC1F1001FDE300B15929 /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */; }; 4BE3225A0CC611EF00AFA640 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737F0CC60A6D001AFFD4 /* types.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BE3225B0CC611F500AFA640 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737F0CC60A6D001AFFD4 /* types.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BE4CC010CDA153400CCF5BB /* JackTools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4CBFF0CDA153400CCF5BB /* JackTools.cpp */; }; @@ -849,8 +830,6 @@ 4BECB2FA0F4451C10091B70A /* JackProcessSync.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BECB2F40F4451C10091B70A /* JackProcessSync.h */; }; 4BECB2FB0F4451C10091B70A /* JackProcessSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BECB2F30F4451C10091B70A /* JackProcessSync.cpp */; }; 4BECB2FC0F4451C10091B70A /* JackProcessSync.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BECB2F40F4451C10091B70A /* JackProcessSync.h */; }; - 4BF284180F31B4BC00B05BE3 /* JackArgParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF284160F31B4BC00B05BE3 /* JackArgParser.cpp */; }; - 4BF284190F31B4BC00B05BE3 /* JackArgParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF284170F31B4BC00B05BE3 /* JackArgParser.h */; }; 4BF2841A0F31B4BC00B05BE3 /* JackArgParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF284160F31B4BC00B05BE3 /* JackArgParser.cpp */; }; 4BF2841B0F31B4BC00B05BE3 /* JackArgParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF284170F31B4BC00B05BE3 /* JackArgParser.h */; }; 4BF3391A0F8B86DC0080FB5B /* JackCoreMidiDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF339140F8B86DC0080FB5B /* JackCoreMidiDriver.h */; }; @@ -865,7 +844,6 @@ 4BF520590CB8D1010037470E /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (); }; }; 4BF5205A0CB8D1010037470E /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (); }; }; 4BF5FBBC0E878B9C003D2374 /* JackPosixServerLaunch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBBA0E878B9C003D2374 /* JackPosixServerLaunch.cpp */; }; - 4BF5FBC90E878D24003D2374 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; 4BF5FBCA0E878D24003D2374 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; 4BF5FBCB0E878D24003D2374 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; 4BFA5E9F0DEC4DD900FA4CDB /* testMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFA5E9E0DEC4DD900FA4CDB /* testMutex.cpp */; }; @@ -3077,7 +3055,6 @@ files = ( 4B19B3140E2362E800DD4A82 /* JackAudioAdapter.h in Headers */, 4B19B3160E2362E800DD4A82 /* JackAudioAdapterInterface.h in Headers */, - 4B19B3190E2362E800DD4A82 /* JackException.h in Headers */, 4B19B31C0E2362E800DD4A82 /* JackLibSampleRateResampler.h in Headers */, 4BE5FED20E725C320020B576 /* JackCoreAudioAdapter.h in Headers */, ); @@ -3247,6 +3224,8 @@ 4BCBCE6410C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */, 4B88D04311298BEE007A87C1 /* weakjack.h in Headers */, 4B88D04411298BEE007A87C1 /* weakmacros.h in Headers */, + 4BC2CA5A113C6CB80076717C /* JackNetInterface.h in Headers */, + 4BC2CA5C113C6CC00076717C /* JackNetUnixSocket.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3551,12 +3530,9 @@ buildActionMask = 2147483647; files = ( 4B5E08C30E5B66EE00BEE4E0 /* JackAudioAdapterInterface.h in Headers */, - 4B5E08C40E5B66EE00BEE4E0 /* JackException.h in Headers */, 4B5E08C60E5B66EE00BEE4E0 /* JackLibSampleRateResampler.h in Headers */, 4B5E08E20E5B676D00BEE4E0 /* JackNetAdapter.h in Headers */, - 4B5E08EC0E5B67EB00BEE4E0 /* JackNetInterface.h in Headers */, 4B5E08EF0E5B680200BEE4E0 /* JackAudioAdapter.h in Headers */, - 4BC3B6C00E703BCC0066E42F /* JackNetUnixSocket.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3690,6 +3666,8 @@ 4BCBCE6010C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */, 4B88D03D11298BEE007A87C1 /* weakjack.h in Headers */, 4B88D03E11298BEE007A87C1 /* weakmacros.h in Headers */, + 4BC2CA56113C6C940076717C /* JackNetInterface.h in Headers */, + 4BC2CA58113C6C9C0076717C /* JackNetUnixSocket.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3869,6 +3847,8 @@ 4BCBCE6810C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */, 4B88D04511298BEE007A87C1 /* weakjack.h in Headers */, 4B88D04611298BEE007A87C1 /* weakmacros.h in Headers */, + 4BC2CA5E113C6CCA0076717C /* JackNetInterface.h in Headers */, + 4BC2CA60113C6CD20076717C /* JackNetUnixSocket.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3913,8 +3893,6 @@ buildActionMask = 2147483647; files = ( 4BDCDBB91001FCC000B15929 /* JackNetDriver.h in Headers */, - 4BDCDBBA1001FCC000B15929 /* JackNetInterface.h in Headers */, - 4BDCDBBB1001FCC000B15929 /* JackNetUnixSocket.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3923,9 +3901,6 @@ buildActionMask = 2147483647; files = ( 4BDCDBD91001FD2D00B15929 /* JackNetManager.h in Headers */, - 4BDCDBDA1001FD2D00B15929 /* JackNetInterface.h in Headers */, - 4BDCDBDB1001FD2D00B15929 /* JackNetUnixSocket.h in Headers */, - 4BDCDBDC1001FD2D00B15929 /* JackArgParser.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3935,7 +3910,6 @@ files = ( 4BDCDBEE1001FD7300B15929 /* JackAudioAdapter.h in Headers */, 4BDCDBEF1001FD7300B15929 /* JackAudioAdapterInterface.h in Headers */, - 4BDCDBF01001FD7300B15929 /* JackException.h in Headers */, 4BDCDBF11001FD7300B15929 /* JackLibSampleRateResampler.h in Headers */, 4BDCDBF21001FD7300B15929 /* JackCoreAudioAdapter.h in Headers */, ); @@ -3946,12 +3920,9 @@ buildActionMask = 2147483647; files = ( 4BDCDC111001FDE300B15929 /* JackAudioAdapterInterface.h in Headers */, - 4BDCDC121001FDE300B15929 /* JackException.h in Headers */, 4BDCDC131001FDE300B15929 /* JackLibSampleRateResampler.h in Headers */, 4BDCDC141001FDE300B15929 /* JackNetAdapter.h in Headers */, - 4BDCDC151001FDE300B15929 /* JackNetInterface.h in Headers */, 4BDCDC161001FDE300B15929 /* JackAudioAdapter.h in Headers */, - 4BDCDC171001FDE300B15929 /* JackNetUnixSocket.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4038,8 +4009,6 @@ buildActionMask = 2147483647; files = ( BA222ADF0DC882A5001A17F4 /* JackNetDriver.h in Headers */, - 4B76C76B0E5AB2DB00E2AC21 /* JackNetInterface.h in Headers */, - 4BC3B6BC0E703BCC0066E42F /* JackNetUnixSocket.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4048,9 +4017,6 @@ buildActionMask = 2147483647; files = ( BA222AEE0DC883B3001A17F4 /* JackNetManager.h in Headers */, - 4B76C76D0E5AB2DB00E2AC21 /* JackNetInterface.h in Headers */, - 4BC3B6BE0E703BCC0066E42F /* JackNetUnixSocket.h in Headers */, - 4BF284190F31B4BC00B05BE3 /* JackArgParser.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6453,6 +6419,8 @@ 4BDCDC091001FDA800B15929 /* JackArgParser.cpp in Sources */, 4BCBCE6110C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */, 4BCBCE6310C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */, + 4BC2CA59113C6CB60076717C /* JackNetInterface.cpp in Sources */, + 4BC2CA5B113C6CBE0076717C /* JackNetUnixSocket.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6779,9 +6747,7 @@ 4B5E08CD0E5B66EE00BEE4E0 /* JackLibSampleRateResampler.cpp in Sources */, 4B5E08CE0E5B66EE00BEE4E0 /* JackResampler.cpp in Sources */, 4B5E08E10E5B676C00BEE4E0 /* JackNetAdapter.cpp in Sources */, - 4B5E08EB0E5B67EA00BEE4E0 /* JackNetInterface.cpp in Sources */, 4B5E08EE0E5B680200BEE4E0 /* JackAudioAdapter.cpp in Sources */, - 4BC3B6BF0E703BCC0066E42F /* JackNetUnixSocket.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6891,6 +6857,8 @@ 4BF339230F8B873E0080FB5B /* JackMidiDriver.cpp in Sources */, 4BCBCE5D10C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */, 4BCBCE5F10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */, + 4BC2CA55113C6C930076717C /* JackNetInterface.cpp in Sources */, + 4BC2CA57113C6C9B0076717C /* JackNetUnixSocket.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7071,6 +7039,8 @@ 4BA339A410B2E36800190E3B /* JackArgParser.cpp in Sources */, 4BCBCE6510C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */, 4BCBCE6710C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */, + 4BC2CA5D113C6CC90076717C /* JackNetInterface.cpp in Sources */, + 4BC2CA5F113C6CD10076717C /* JackNetUnixSocket.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7119,8 +7089,6 @@ buildActionMask = 2147483647; files = ( 4BDCDBBD1001FCC000B15929 /* JackNetDriver.cpp in Sources */, - 4BDCDBBE1001FCC000B15929 /* JackNetInterface.cpp in Sources */, - 4BDCDBBF1001FCC000B15929 /* JackNetUnixSocket.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7129,10 +7097,6 @@ buildActionMask = 2147483647; files = ( 4BDCDBDE1001FD2D00B15929 /* JackNetManager.cpp in Sources */, - 4BDCDBDF1001FD2D00B15929 /* JackNetInterface.cpp in Sources */, - 4BDCDBE01001FD2D00B15929 /* JackNetUnixSocket.cpp in Sources */, - 4BDCDBE11001FD2D00B15929 /* JackMachTime.c in Sources */, - 4BDCDBE21001FD2D00B15929 /* JackArgParser.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7157,9 +7121,7 @@ 4BDCDC1A1001FDE300B15929 /* JackLibSampleRateResampler.cpp in Sources */, 4BDCDC1B1001FDE300B15929 /* JackResampler.cpp in Sources */, 4BDCDC1C1001FDE300B15929 /* JackNetAdapter.cpp in Sources */, - 4BDCDC1D1001FDE300B15929 /* JackNetInterface.cpp in Sources */, 4BDCDC1E1001FDE300B15929 /* JackAudioAdapter.cpp in Sources */, - 4BDCDC1F1001FDE300B15929 /* JackNetUnixSocket.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7256,8 +7218,6 @@ buildActionMask = 2147483647; files = ( BA222ADE0DC882A5001A17F4 /* JackNetDriver.cpp in Sources */, - 4B76C76A0E5AB2DB00E2AC21 /* JackNetInterface.cpp in Sources */, - 4BC3B6BB0E703BCC0066E42F /* JackNetUnixSocket.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7266,10 +7226,6 @@ buildActionMask = 2147483647; files = ( BA222AED0DC883B3001A17F4 /* JackNetManager.cpp in Sources */, - 4B76C76C0E5AB2DB00E2AC21 /* JackNetInterface.cpp in Sources */, - 4BC3B6BD0E703BCC0066E42F /* JackNetUnixSocket.cpp in Sources */, - 4BF5FBC90E878D24003D2374 /* JackMachTime.c in Sources */, - 4BF284180F31B4BC00B05BE3 /* JackArgParser.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/macosx/coreaudio/JackCoreAudioAdapter.cpp b/macosx/coreaudio/JackCoreAudioAdapter.cpp index cb05d622..8e25b58d 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.cpp +++ b/macosx/coreaudio/JackCoreAudioAdapter.cpp @@ -545,10 +545,23 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, // Creates aggregate device AudioDeviceID captureID, playbackID; - if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) - return -1; - if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) - return -1; + + if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { + jack_log("Will take default input"); + if (GetDefaultInputDevice(&captureID) != noErr) { + jack_error("Cannot open default input device"); + return -1; + } + } + + if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) { + jack_log("Will take default output"); + if (GetDefaultOutputDevice(&playbackID) != noErr) { + jack_error("Cannot open default output device"); + return -1; + } + } + if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) return -1; } @@ -558,7 +571,7 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, jack_log("JackCoreAudioAdapter::Open capture only"); if (GetDeviceIDFromUID(capture_driver_uid, &fDeviceID) != noErr) { if (GetDefaultInputDevice(&fDeviceID) != noErr) { - jack_error("Cannot open default device"); + jack_error("Cannot open default input device"); return -1; } } @@ -572,7 +585,7 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, jack_log("JackCoreAudioAdapter::Open playback only"); if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) { if (GetDefaultOutputDevice(&fDeviceID) != noErr) { - jack_error("Cannot open default device"); + jack_error("Cannot open default output device"); return -1; } } @@ -583,14 +596,31 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, // Use default driver in duplex mode } else { - jack_log("JackCoreAudioAdapter::Open default driver"); + jack_log("JackCoreAudioDriver::Open default driver"); if (GetDefaultDevice(&fDeviceID) != noErr) { - jack_error("Cannot open default device"); - return -1; - } - if (GetDeviceNameFromID(fDeviceID, capture_driver_name) != noErr || GetDeviceNameFromID(fDeviceID, playback_driver_name) != noErr) { - jack_error("Cannot get device name from device ID"); - return -1; + 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) { + jack_error("Cannot open default input device"); + return -1; + } + } + + if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) { + jack_log("Will take default output"); + if (GetDefaultOutputDevice(&playbackID) != noErr) { + jack_error("Cannot open default output device"); + return -1; + } + } + + if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) + return -1; } } diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 2441375c..6f053008 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -922,7 +922,7 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { jack_log("Will take default input"); if (GetDefaultInputDevice(&captureID) != noErr) { - jack_error("Cannot open default device"); + jack_error("Cannot open default input device"); return -1; } } @@ -930,7 +930,7 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) { jack_log("Will take default output"); if (GetDefaultOutputDevice(&playbackID) != noErr) { - jack_error("Cannot open default device"); + jack_error("Cannot open default output device"); return -1; } } @@ -945,7 +945,7 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, if (GetDeviceIDFromUID(capture_driver_uid, &fDeviceID) != noErr) { jack_log("Will take default input"); if (GetDefaultInputDevice(&fDeviceID) != noErr) { - jack_error("Cannot open default device"); + jack_error("Cannot open default input device"); return -1; } } @@ -960,7 +960,7 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) { jack_log("Will take default output"); if (GetDefaultOutputDevice(&fDeviceID) != noErr) { - jack_error("Cannot open default device"); + jack_error("Cannot open default output device"); return -1; } } @@ -973,12 +973,29 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, } else { jack_log("JackCoreAudioDriver::Open default driver"); if (GetDefaultDevice(&fDeviceID) != noErr) { - jack_error("Cannot open default device"); - return -1; - } - if (GetDeviceNameFromID(fDeviceID, capture_driver_name) != noErr || GetDeviceNameFromID(fDeviceID, playback_driver_name) != noErr) { - jack_error("Cannot get device name from device ID"); - return -1; + 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) { + jack_error("Cannot open default input device"); + return -1; + } + } + + if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) { + jack_log("Will take default output"); + if (GetDefaultOutputDevice(&playbackID) != noErr) { + jack_error("Cannot open default output device"); + return -1; + } + } + + if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) + return -1; } } diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj index 5ea267ea..31df802d 100755 --- a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -986,6 +986,7 @@ COPY_PHASE_STRIP = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + GCC_VERSION = ""; HEADER_SEARCH_PATHS = ( ../../macosx, ../../common/jack, diff --git a/wscript b/wscript index 5ced3c2c..bc88c490 100644 --- a/wscript +++ b/wscript @@ -69,7 +69,10 @@ def set_options(opt): opt.add_option('--mixed', action='store_true', default=False, help='Build with 32/64 bits mixed mode') opt.add_option('--clients', default=64, type="int", dest="clients", help='Maximum number of JACK clients') opt.add_option('--ports-per-application', default=768, type="int", dest="application_ports", help='Maximum number of ports per application') - opt.add_option('--debug', action='store_true', default=False, dest='debug', help="Build debuggable binaries") + opt.add_option('--debug', action='store_true', default=False, dest='debug', help='Build debuggable binaries') + opt.add_option('--firewire', action='store_true', default=False, help='Enable FireWire driver (FFADO)') + opt.add_option('--freebob', action='store_true', default=False, help='Enable FreeBob driver') + opt.add_option('--alsa', action='store_true', default=False, help='Enable ALSA driver') opt.sub_options('dbus') def configure(conf): @@ -110,6 +113,15 @@ def configure(conf): conf.sub_config('common') if conf.env['IS_LINUX']: conf.sub_config('linux') + if Options.options.alsa and not conf.env['BUILD_DRIVER_ALSA']: + conf.fatal('ALSA driver was explicitly requested but cannot be built') + if Options.options.freebob and not conf.env['BUILD_DRIVER_FREEBOB']: + conf.fatal('FreeBob driver was explicitly requested but cannot be built') + if Options.options.firewire and not conf.env['BUILD_DRIVER_FFADO']: + conf.fatal('FFADO driver was explicitly requested but cannot be built') + conf.env['BUILD_DRIVER_ALSA'] = Options.options.alsa + conf.env['BUILD_DRIVER_FFADO'] = Options.options.firewire + conf.env['BUILD_DRIVER_FREEBOB'] = Options.options.freebob if Options.options.dbus: conf.sub_config('dbus') if conf.env['BUILD_JACKDBUS'] != True: From b6bf30679ddb6697cd816ca5592e170c65bdcee2 Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 2 Mar 2010 14:27:53 +0000 Subject: [PATCH 036/472] More flexible handling of network audio buffers. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3932 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetInterface.cpp | 47 +++- common/JackNetInterface.h | 3 +- common/JackNetTool.cpp | 110 +++++----- common/JackNetTool.h | 206 +++++++++++++++++- common/JackTools.h | 2 +- macosx/coreaudio/TiPhoneCoreAudioRenderer.cpp | 4 +- macosx/coreaudio/TiPhoneCoreAudioRenderer.h | 2 +- macosx/iphone/main_master.mm | 2 +- macosx/iphone/main_slave.mm | 29 ++- 9 files changed, 314 insertions(+), 91 deletions(-) diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 6d287258..7892e7d0 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -115,6 +115,7 @@ namespace Jack fParams.fPeriodSize * sizeof(sample_t) / PACKET_AVAILABLE_SIZE); //bufsize = sync + audio + midi bufsize = MAX_LATENCY * (fParams.fMtu + ( int ) audio_size + ( int ) midi_size); + jack_info("SetNetBufferSize bufsize = %d", bufsize); //tx buffer if ( fSocket.SetOption ( SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof ( bufsize ) ) == SOCKET_ERROR ) @@ -298,8 +299,12 @@ namespace Jack assert ( fNetMidiPlaybackBuffer ); //audio net buffers - fNetAudioCaptureBuffer = new NetAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); - fNetAudioPlaybackBuffer = new NetAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); + fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); + fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); + + //fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); + //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); + assert ( fNetAudioCaptureBuffer ); assert ( fNetAudioPlaybackBuffer ); @@ -387,7 +392,7 @@ namespace Jack bool JackNetMasterInterface::IsSynched() { if (fParams.fNetworkMode == 's') { - return (fCycleOffset < 3); + return (fCycleOffset < (CYCLE_OFFSET_SLOW + 1)); } else { return true; } @@ -464,13 +469,13 @@ namespace Jack // - if the network is two fast, just wait the next cycle, this mode allows a shorter cycle duration for the master // - this mode will skip the two first cycles, thus it lets time for data to be processed and queued on the socket rx buffer //the slow mode is the safest mode because it wait twice the bandwidth relative time (send/return + process) - if (fCycleOffset < 2) { + if (fCycleOffset < CYCLE_OFFSET_SLOW) { return 0; } else { rx_bytes = Recv ( rx_head->fPacketSize, 0 ); } - - if (fCycleOffset > 2) { + + if (fCycleOffset > CYCLE_OFFSET_SLOW) { jack_info("Warning : '%s' runs in slow network mode, but data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); } break; @@ -514,6 +519,8 @@ namespace Jack uint jumpcnt = 0; uint recvd_midi_pckt = 0; uint recvd_audio_pckt = 0; + int last_cycle = 0; + packet_header_t* rx_head = reinterpret_cast ( fRxBuffer ); while ( !fRxHeader.fIsLastPckt ) @@ -553,16 +560,22 @@ namespace Jack fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fSubCycle = rx_head->fSubCycle; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; - fNetAudioPlaybackBuffer->RenderToJackPorts ( rx_head->fSubCycle ); + fNetAudioPlaybackBuffer->RenderToJackPorts ( rx_head->fCycle, rx_head->fSubCycle); jumpcnt = 0; + last_cycle = rx_head->fCycle; break; case 's': //sync jack_info("NetMaster : overloaded, skipping receive from '%s'", fParams.fName); + // Finish rendering (copy to JACK ports) + fNetAudioPlaybackBuffer->FinishRenderToJackPorts(last_cycle); return 0; } } } + + // Finish rendering (copy to JACK ports) + fNetAudioPlaybackBuffer->FinishRenderToJackPorts(last_cycle); return rx_bytes; } @@ -790,8 +803,11 @@ namespace Jack fNetMidiPlaybackBuffer = new NetMidiBuffer ( &fParams, fParams.fReturnMidiChannels, fTxData ); //audio net buffers - fNetAudioCaptureBuffer = new NetAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); - fNetAudioPlaybackBuffer = new NetAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); + fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); + fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); + + //fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); + //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); //audio netbuffer length fAudioTxLen = sizeof ( packet_header_t ) + fNetAudioPlaybackBuffer->GetSize(); @@ -867,6 +883,8 @@ namespace Jack uint recvd_midi_pckt = 0; uint recvd_audio_pckt = 0; int rx_bytes = 0; + int last_cycle = 0; + packet_header_t* rx_head = reinterpret_cast ( fRxBuffer ); while ( !fRxHeader.fIsLastPckt ) @@ -893,21 +911,26 @@ namespace Jack case 'a': //audio rx_bytes = Recv ( rx_head->fPacketSize, 0 ); if (recvd_audio_pckt++ != rx_head->fSubCycle) { - //jack_error("Packet(s) missing from '%s'...", fParams.fMasterNetName); - jack_error("Packet(s) missing from '%s'... %d %d %d", fParams.fMasterNetName, rx_head->fCycle, recvd_audio_pckt, rx_head->fSubCycle); + jack_error("Packet(s) missing from '%s'...", fParams.fMasterNetName); } fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fSubCycle = rx_head->fSubCycle; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; - fNetAudioCaptureBuffer->RenderToJackPorts ( rx_head->fSubCycle ); + fNetAudioCaptureBuffer->RenderToJackPorts ( rx_head->fCycle, rx_head->fSubCycle); + last_cycle = rx_head->fCycle; break; case 's': //sync jack_info ( "NetSlave : overloaded, skipping receive." ); + // Finish rendering (copy to JACK ports) + fNetAudioCaptureBuffer->FinishRenderToJackPorts(last_cycle); return 0; } } } + + // Finish rendering (copy to JACK ports) + fNetAudioCaptureBuffer->FinishRenderToJackPorts(last_cycle); fRxHeader.fCycle = rx_head->fCycle; return 0; } diff --git a/common/JackNetInterface.h b/common/JackNetInterface.h index ca90875f..b573e2cc 100644 --- a/common/JackNetInterface.h +++ b/common/JackNetInterface.h @@ -212,6 +212,7 @@ namespace Jack #define MASTER_INIT_TIMEOUT 1000000 // in usec #define SLAVE_INIT_TIMEOUT 2000000 // in usec -#define MAX_LATENCY 6 +#define CYCLE_OFFSET_SLOW 2 +#define MAX_LATENCY CYCLE_OFFSET_SLOW * 4 #endif diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index 82f03523..0eee2474 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -127,93 +127,93 @@ namespace Jack // net audio buffer ********************************************************************************* - NetAudioBuffer::NetAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) + + NetSingleAudioBuffer::NetSingleAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) + : fPortBuffer(params, nports), fNetBuffer(net_buffer) + {} + + NetSingleAudioBuffer::~NetSingleAudioBuffer() + {} + + size_t NetSingleAudioBuffer::GetSize() { - fNPorts = nports; - fPeriodSize = params->fPeriodSize; - fSubPeriodSize = params->fFramesPerPacket; - fSubPeriodBytesSize = fSubPeriodSize * sizeof ( sample_t ); - fPortBuffer = new sample_t* [fNPorts]; - for ( int port_index = 0; port_index < fNPorts; port_index++ ) - fPortBuffer[port_index] = NULL; - fNetBuffer = net_buffer; + return fPortBuffer.GetSize(); } - NetAudioBuffer::~NetAudioBuffer() + void NetSingleAudioBuffer::SetBuffer ( int index, sample_t* buffer ) { - delete[] fPortBuffer; + fPortBuffer.SetBuffer(index, buffer); } - size_t NetAudioBuffer::GetSize() + sample_t* NetSingleAudioBuffer::GetBuffer ( int index ) { - return fNPorts * fSubPeriodBytesSize; + return fPortBuffer.GetBuffer(index); } - void NetAudioBuffer::SetBuffer ( int index, sample_t* buffer ) + void NetSingleAudioBuffer::RenderFromJackPorts (int subcycle) { - fPortBuffer[index] = buffer; + fPortBuffer.RenderFromJackPorts(fNetBuffer, subcycle); } - sample_t* NetAudioBuffer::GetBuffer ( int index ) + void NetSingleAudioBuffer::RenderToJackPorts (int cycle, int subcycle) { - return fPortBuffer[index]; + fPortBuffer.RenderToJackPorts(fNetBuffer, subcycle); } -#ifdef __BIG_ENDIAN__ +// Buffered - static inline float SwapFloat(float f) + NetBufferedAudioBuffer::NetBufferedAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) { - union - { - float f; - unsigned char b[4]; - } dat1, dat2; + fMaxCycle = 0; + fNetBuffer = net_buffer; + + for (int i = 0; i < AUDIO_BUFFER_SIZE; i++) { + fPortBuffer[i].Init(params, nports); + } + + fJackPortBuffer = new sample_t* [nports]; + for ( int port_index = 0; port_index < nports; port_index++ ) + fJackPortBuffer[port_index] = NULL; + } - dat1.f = f; - dat2.b[0] = dat1.b[3]; - dat2.b[1] = dat1.b[2]; - dat2.b[2] = dat1.b[1]; - dat2.b[3] = dat1.b[0]; - return dat2.f; + NetBufferedAudioBuffer::~NetBufferedAudioBuffer() + { + delete [] fJackPortBuffer; } - void NetAudioBuffer::RenderFromJackPorts ( int subcycle ) + size_t NetBufferedAudioBuffer::GetSize() { - for ( int port_index = 0; port_index < fNPorts; port_index++ ) { - float* src = (float*)(fPortBuffer[port_index] + subcycle * fSubPeriodSize); - float* dst = (float*)(fNetBuffer + port_index * fSubPeriodBytesSize); - for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(float); sample++) { - dst[sample] = SwapFloat(src[sample]); - } - } + return fPortBuffer[0].GetSize(); } - void NetAudioBuffer::RenderToJackPorts ( int subcycle ) + void NetBufferedAudioBuffer::SetBuffer ( int index, sample_t* buffer ) { - for ( int port_index = 0; port_index < fNPorts; port_index++ ) { - float* src = (float*)(fNetBuffer + port_index * fSubPeriodBytesSize); - float* dst = (float*)(fPortBuffer[port_index] + subcycle * fSubPeriodSize); - for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(float); sample++) { - dst[sample] = SwapFloat(src[sample]); - } - } + fJackPortBuffer[index] = buffer; } - -#else - void NetAudioBuffer::RenderFromJackPorts ( int subcycle ) + sample_t* NetBufferedAudioBuffer::GetBuffer ( int index ) { - for ( int port_index = 0; port_index < fNPorts; port_index++ ) - memcpy ( fNetBuffer + port_index * fSubPeriodBytesSize, fPortBuffer[port_index] + subcycle * fSubPeriodSize, fSubPeriodBytesSize ); + return fJackPortBuffer[index]; + } + + void NetBufferedAudioBuffer::RenderFromJackPorts (int subcycle ) + { + fPortBuffer[0].RenderFromJackPorts(fNetBuffer, subcycle); // Always use first buffer... } - void NetAudioBuffer::RenderToJackPorts ( int subcycle ) + void NetBufferedAudioBuffer::RenderToJackPorts (int cycle, int subcycle) { - for ( int port_index = 0; port_index < fNPorts; port_index++ ) - memcpy ( fPortBuffer[port_index] + subcycle * fSubPeriodSize, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize ); + if (cycle < fMaxCycle) { + jack_info("Wrong order fCycle %d subcycle %d fMaxCycle %d", cycle, subcycle, fMaxCycle); + } + fPortBuffer[cycle % AUDIO_BUFFER_SIZE].RenderToJackPorts(fNetBuffer, subcycle); } -#endif + void NetBufferedAudioBuffer::FinishRenderToJackPorts (int cycle) + { + fMaxCycle = std::max(fMaxCycle, cycle); + fPortBuffer[(cycle + 1) % AUDIO_BUFFER_SIZE].Copy(fJackPortBuffer); // Copy internal buffer in JACK ports + } // SessionParams ************************************************************************************ diff --git a/common/JackNetTool.h b/common/JackNetTool.h index cb6f494f..a3ebe1f9 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -248,6 +248,25 @@ namespace Jack // audio data ********************************************************************************* + class SERVER_EXPORT NetAudioBuffer + { + + public: + NetAudioBuffer () + {} + ~NetAudioBuffer() + {} + + virtual size_t GetSize() = 0; + //jack<->buffer + virtual void RenderFromJackPorts (int subcycle ) = 0; + virtual void RenderToJackPorts ( int cycle, int subcycle) = 0; + virtual void FinishRenderToJackPorts (int cycle) = 0; + + virtual void SetBuffer ( int index, sample_t* buffer ) = 0; + virtual sample_t* GetBuffer ( int index ) = 0; + }; + /** \Brief Audio buffer and operations class @@ -257,24 +276,191 @@ namespace Jack So there is no need of an intermediate buffer as in NetMidiBuffer. */ + + struct JackPortList { + + jack_nframes_t fPeriodSize; + jack_nframes_t fSubPeriodSize; + size_t fSubPeriodBytesSize; + sample_t** fPortBuffer; + int fNPorts; + + JackPortList(session_params_t* params, uint32_t nports) + { + fNPorts = nports; + fPeriodSize = params->fPeriodSize; + fSubPeriodSize = params->fFramesPerPacket; + fSubPeriodBytesSize = fSubPeriodSize * sizeof ( sample_t ); + fPortBuffer = new sample_t* [fNPorts]; + for ( int port_index = 0; port_index < fNPorts; port_index++ ) + fPortBuffer[port_index] = NULL; + } + + JackPortList() + { + fNPorts = 0; + fPeriodSize = 0; + fSubPeriodSize = 0; + fSubPeriodBytesSize = 0; + fPortBuffer = 0; + } + + ~JackPortList() + { + delete [] fPortBuffer; + } + + void SetBuffer( int index, sample_t* buffer ) + { + fPortBuffer[index] = buffer; + } + + sample_t* GetBuffer ( int index ) + { + return fPortBuffer[index]; + } + + void Copy(sample_t** buffers) + { + for ( int port_index = 0; port_index < fNPorts; port_index++ ) + memcpy(buffers[port_index], fPortBuffer[port_index], fPeriodSize * sizeof(float)); + } + + size_t GetSize() + { + return fNPorts * fSubPeriodBytesSize; + } + + #ifdef __BIG_ENDIAN__ + + static inline float SwapFloat(float f) + { + union + { + float f; + unsigned char b[4]; + } dat1, dat2; + + dat1.f = f; + dat2.b[0] = dat1.b[3]; + dat2.b[1] = dat1.b[2]; + dat2.b[2] = dat1.b[1]; + dat2.b[3] = dat1.b[0]; + return dat2.f; + } + + void RenderFromJackPorts (char* net_buffer, int subcycle ) + { + for ( int port_index = 0; port_index < fNPorts; port_index++ ) { + float* src = (float*)(fPortBuffer[port_index] + subcycle * fSubPeriodSize); + float* dst = (float*)(net_buffer + port_index * fSubPeriodBytesSize); + for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(float); sample++) { + dst[sample] = SwapFloat(src[sample]); + } + } + } + + void RenderToJackPorts (char* net_buffer, int subcycle) + { + for ( int port_index = 0; port_index < fNPorts; port_index++ ) { + float* src = (float*)(net_buffer + port_index * fSubPeriodBytesSize); + float* dst = (float*)(fPortBuffer[port_index] + subcycle * fSubPeriodSize); + for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(float); sample++) { + dst[sample] = SwapFloat(src[sample]); + } + } + } + + #else + + void RenderFromJackPorts (char* net_buffer, int subcycle ) + { + for ( int port_index = 0; port_index < fNPorts; port_index++ ) + memcpy ( net_buffer + port_index * fSubPeriodBytesSize, fPortBuffer[port_index] + subcycle * fSubPeriodSize, fSubPeriodBytesSize ); + } + + void RenderToJackPorts (char* net_buffer, int subcycle) + { + for ( int port_index = 0; port_index < fNPorts; port_index++ ) + memcpy ( fPortBuffer[port_index] + subcycle * fSubPeriodSize, net_buffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize ); + } + + #endif + + }; + + struct JackPortListAllocate : public JackPortList { + + JackPortListAllocate() + { + fNPorts = 0; + fPeriodSize = 0; + fSubPeriodSize = 0; + fSubPeriodBytesSize = 0; + fPortBuffer = 0; + } + + ~JackPortListAllocate() + { + for ( int port_index = 0; port_index < fNPorts; port_index++ ) + delete [] fPortBuffer[port_index]; + delete [] fPortBuffer; + } + + void Init(session_params_t* params, uint32_t nports) + { + fNPorts = nports; + fPeriodSize = params->fPeriodSize; + fSubPeriodSize = params->fFramesPerPacket; + fSubPeriodBytesSize = fSubPeriodSize * sizeof ( sample_t ); + fPortBuffer = new sample_t* [fNPorts]; + for ( int port_index = 0; port_index < fNPorts; port_index++ ) + fPortBuffer[port_index] = new sample_t[fPeriodSize]; + } + + }; - class SERVER_EXPORT NetAudioBuffer + class SERVER_EXPORT NetSingleAudioBuffer : public NetAudioBuffer { private: - int fNPorts; - jack_nframes_t fPeriodSize; - jack_nframes_t fSubPeriodSize; - size_t fSubPeriodBytesSize; + JackPortList fPortBuffer; + char* fNetBuffer; + + public: + NetSingleAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ); + ~NetSingleAudioBuffer(); + + size_t GetSize(); + //jack<->buffer + void RenderFromJackPorts (int subcycle ); + void RenderToJackPorts (int cycle, int subcycle); + + void SetBuffer ( int index, sample_t* buffer ); + sample_t* GetBuffer ( int index ); + + void FinishRenderToJackPorts (int cycle) {} + }; + + #define AUDIO_BUFFER_SIZE 8 + + class SERVER_EXPORT NetBufferedAudioBuffer : public NetAudioBuffer + { + + private: char* fNetBuffer; - sample_t** fPortBuffer; + JackPortListAllocate fPortBuffer[AUDIO_BUFFER_SIZE]; + sample_t** fJackPortBuffer; + int fMaxCycle; + public: - NetAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ); - ~NetAudioBuffer(); + NetBufferedAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ); + ~NetBufferedAudioBuffer(); size_t GetSize(); //jack<->buffer - void RenderFromJackPorts ( int subcycle ); - void RenderToJackPorts ( int subcycle ); + void RenderFromJackPorts (int subcycle ); + void RenderToJackPorts ( int cycle, int subcycle); + void FinishRenderToJackPorts (int cycle); void SetBuffer ( int index, sample_t* buffer ); sample_t* GetBuffer ( int index ); diff --git a/common/JackTools.h b/common/JackTools.h index 5960fed8..2d058e81 100644 --- a/common/JackTools.h +++ b/common/JackTools.h @@ -137,7 +137,7 @@ namespace Jack T Add ( T measure_point ) { - return fCurrentMeasure[fMeasureId++] = measure_point; + return fCurrentMeasure[fMeasureId++] = measure_point; } uint32_t AddLast ( T measure_point ) diff --git a/macosx/coreaudio/TiPhoneCoreAudioRenderer.cpp b/macosx/coreaudio/TiPhoneCoreAudioRenderer.cpp index e798c973..07c67969 100644 --- a/macosx/coreaudio/TiPhoneCoreAudioRenderer.cpp +++ b/macosx/coreaudio/TiPhoneCoreAudioRenderer.cpp @@ -118,14 +118,14 @@ void TiPhoneCoreAudioRenderer::InterruptionListener(void *inClientData, UInt32 i } } -int TiPhoneCoreAudioRenderer::OpenDefault(int bufferSize, int samplerate) +int TiPhoneCoreAudioRenderer::Open(int bufferSize, int samplerate) { OSStatus err1; UInt32 outSize; UInt32 enableIO; AudioStreamBasicDescription srcFormat, dstFormat; - printf("OpenDefault fDevNumInChans = %ld fDevNumOutChans = %ld bufferSize = %ld samplerate = %ld\n", fDevNumInChans, fDevNumOutChans, bufferSize, samplerate); + printf("Open fDevNumInChans = %ld fDevNumOutChans = %ld bufferSize = %ld samplerate = %ld\n", fDevNumInChans, fDevNumOutChans, bufferSize, samplerate); // Initialize and configure the audio session err1 = AudioSessionInitialize(NULL, NULL, InterruptionListener, this); diff --git a/macosx/coreaudio/TiPhoneCoreAudioRenderer.h b/macosx/coreaudio/TiPhoneCoreAudioRenderer.h index 2aab9be1..3c22eba4 100644 --- a/macosx/coreaudio/TiPhoneCoreAudioRenderer.h +++ b/macosx/coreaudio/TiPhoneCoreAudioRenderer.h @@ -78,7 +78,7 @@ class TiPhoneCoreAudioRenderer } } - int OpenDefault(int bufferSize, int sampleRate); + int Open(int bufferSize, int sampleRate); int Close(); int Start(); diff --git a/macosx/iphone/main_master.mm b/macosx/iphone/main_master.mm index 00123edf..189ee2c7 100644 --- a/macosx/iphone/main_master.mm +++ b/macosx/iphone/main_master.mm @@ -71,7 +71,7 @@ int main(int argc, char *argv[]) { audio_output_buffer[i] = (float*)(calloc(buffer_size, sizeof(float))); } - if (audio_device.OpenDefault(buffer_size, sample_rate) < 0) { + if (audio_device.Open(buffer_size, sample_rate) < 0) { return -1; } diff --git a/macosx/iphone/main_slave.mm b/macosx/iphone/main_slave.mm index f657f045..e25b7ff2 100644 --- a/macosx/iphone/main_slave.mm +++ b/macosx/iphone/main_slave.mm @@ -11,8 +11,8 @@ #include "TiPhoneCoreAudioRenderer.h" -#define NUM_INPUT 2 -#define NUM_OUTPUT 2 +#define NUM_INPUT 1 +#define NUM_OUTPUT 1 jack_net_slave_t* net; jack_adapter_t* adapter; @@ -33,23 +33,36 @@ static int net_process(jack_nframes_t buffer_size, void* data) { - jack_adapter_pull_and_push(adapter, audio_output_buffer, audio_input_buffer, buffer_size); + //jack_adapter_pull_and_push(adapter, audio_output_buffer, audio_input_buffer, buffer_size); + + // Process input, produce output + if (audio_input == audio_output) { + // Copy input to output + for (int i = 0; i < audio_input; i++) { + memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); + } + } return 0; } static void SlaveAudioCallback(int frames, float** inputs, float** outputs, void* arg) { - jack_adapter_push_and_pull(adapter, inputs, outputs, frames); + //jack_adapter_push_and_pull(adapter, inputs, outputs, frames); } +//http://www.securityfocus.com/infocus/1884 + +#define WIFI_MTU 1500 + + int main(int argc, char *argv[]) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - jack_slave_t request = { NUM_INPUT, NUM_OUTPUT, 0, 0, DEFAULT_MTU, -1, JackSlowMode }; + jack_slave_t request = { NUM_INPUT, NUM_OUTPUT, 0, 0, WIFI_MTU, -1, JackSlowMode }; jack_master_t result; - if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { + if ((net = jack_net_slave_open("169.254.136.64", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { return -1; } @@ -69,7 +82,7 @@ int main(int argc, char *argv[]) { return -1; } - if (audio_device.OpenDefault(result.buffer_size, result.sample_rate) < 0) { + if (audio_device.Open(result.buffer_size, result.sample_rate) < 0) { return -1; } From f5ea7a7b9213ac25468c8f08fb7e1b137a8f90ba Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 2 Mar 2010 20:27:58 +0000 Subject: [PATCH 037/472] Cleanup, limit size for sync packet. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3934 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetInterface.cpp | 122 ++++++++++++++++-------------------- common/JackNetInterface.h | 4 +- macosx/iphone/main_slave.mm | 4 +- 3 files changed, 61 insertions(+), 69 deletions(-) diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 7892e7d0..cd2b7e3e 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -25,6 +25,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. using namespace std; #define PACKET_AVAILABLE_SIZE (fParams.fMtu - sizeof(packet_header_t)) +#define HEADER_SIZE (sizeof(packet_header_t)) /* TODO : since midi buffers now uses up to BUFFER_SIZE_MAX frames, @@ -309,8 +310,8 @@ namespace Jack assert ( fNetAudioPlaybackBuffer ); //audio netbuffer length - fAudioTxLen = sizeof ( packet_header_t ) + fNetAudioCaptureBuffer->GetSize(); - fAudioRxLen = sizeof ( packet_header_t ) + fNetAudioPlaybackBuffer->GetSize(); + fAudioTxLen = HEADER_SIZE + fNetAudioCaptureBuffer->GetSize(); + fAudioRxLen = HEADER_SIZE + fNetAudioPlaybackBuffer->GetSize(); } void JackNetMasterInterface::Exit() @@ -340,24 +341,23 @@ namespace Jack int JackNetMasterInterface::Recv ( size_t size, int flags ) { int rx_bytes; - if ( ( ( rx_bytes = fSocket.Recv ( fRxBuffer, size, flags ) ) == SOCKET_ERROR ) && fRunning ) - { + + if ((( rx_bytes = fSocket.Recv(fRxBuffer, size, flags)) == SOCKET_ERROR) && fRunning) { net_error_t error = fSocket.GetError(); //no data isn't really a network error, so just return 0 avalaible read bytes - if ( error == NET_NO_DATA ) + if (error == NET_NO_DATA) { return 0; - else if ( error == NET_CONN_ERROR ) - { + } else if (error == NET_CONN_ERROR) { //fatal connection issue, exit - jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) ); + jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError(NET_ERROR_CODE)); //ask to the manager to properly remove the master Exit(); // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine. ThreadExit(); + } else { + jack_error ( "Error in master receive : %s", StrError(NET_ERROR_CODE)); } - else - jack_error ( "Error in master receive : %s", StrError ( NET_ERROR_CODE ) ); } packet_header_t* header = reinterpret_cast(fRxBuffer); @@ -371,20 +371,18 @@ namespace Jack packet_header_t* header = reinterpret_cast(fTxBuffer); PacketHeaderHToN(header, header); - if ( ( ( tx_bytes = fSocket.Send ( fTxBuffer, size, flags ) ) == SOCKET_ERROR ) && fRunning ) - { + if (((tx_bytes = fSocket.Send(fTxBuffer, size, flags)) == SOCKET_ERROR) && fRunning) { net_error_t error = fSocket.GetError(); - if ( error == NET_CONN_ERROR ) - { + if (error == NET_CONN_ERROR) { //fatal connection issue, exit - jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) ); + jack_error ("'%s' : %s, exiting.", fParams.fName, StrError (NET_ERROR_CODE)); Exit(); // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine. ThreadExit(); + } else { + jack_error("Error in master send : %s", StrError(NET_ERROR_CODE)); } - else - jack_error ( "Error in master send : %s", StrError ( NET_ERROR_CODE ) ); } return tx_bytes; } @@ -404,9 +402,9 @@ namespace Jack fTxHeader.fSubCycle = 0; fTxHeader.fDataType = 's'; fTxHeader.fIsLastPckt = ( fParams.fSendMidiChannels == 0 && fParams.fSendAudioChannels == 0) ? 1 : 0; - fTxHeader.fPacketSize = fParams.fMtu; - memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) ); - return Send ( fTxHeader.fPacketSize, 0 ); + fTxHeader.fPacketSize = HEADER_SIZE; + memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); + return Send(fTxHeader.fPacketSize, 0); } int JackNetMasterInterface::DataSend() @@ -422,10 +420,10 @@ namespace Jack for ( subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ ) { fTxHeader.fSubCycle = subproc; - fTxHeader.fIsLastPckt = ( ( subproc == ( fTxHeader.fNMidiPckt - 1 ) ) && (fParams.fSendAudioChannels == 0)) ? 1 : 0; - fTxHeader.fPacketSize = sizeof ( packet_header_t ) + fNetMidiCaptureBuffer->RenderToNetwork ( subproc, fTxHeader.fMidiDataSize ); - memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) ); - if ( Send ( fTxHeader.fPacketSize, 0 ) == SOCKET_ERROR ) + fTxHeader.fIsLastPckt = (( subproc == (fTxHeader.fNMidiPckt - 1)) && (fParams.fSendAudioChannels == 0)) ? 1 : 0; + fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiCaptureBuffer->RenderToNetwork(subproc, fTxHeader.fMidiDataSize); + memcpy ( fTxBuffer, &fTxHeader, HEADER_SIZE); + if (Send (fTxHeader.fPacketSize, 0) == SOCKET_ERROR) return SOCKET_ERROR; } } @@ -436,14 +434,14 @@ namespace Jack fTxHeader.fDataType = 'a'; fTxHeader.fMidiDataSize = 0; fTxHeader.fNMidiPckt = 0; - for ( subproc = 0; subproc < fNSubProcess; subproc++ ) + for (subproc = 0; subproc < fNSubProcess; subproc++) { fTxHeader.fSubCycle = subproc; - fTxHeader.fIsLastPckt = ( subproc == ( fNSubProcess - 1 ) ) ? 1 : 0; + fTxHeader.fIsLastPckt = (subproc == (fNSubProcess - 1)) ? 1 : 0; fTxHeader.fPacketSize = fAudioTxLen; - memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) ); - fNetAudioCaptureBuffer->RenderFromJackPorts ( subproc ); - if ( Send ( fTxHeader.fPacketSize, 0 ) == SOCKET_ERROR ) + memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); + fNetAudioCaptureBuffer->RenderFromJackPorts(subproc); + if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) return SOCKET_ERROR; } } @@ -454,7 +452,7 @@ namespace Jack int JackNetMasterInterface::SyncRecv() { packet_header_t* rx_head = reinterpret_cast ( fRxBuffer ); - int rx_bytes = Recv ( fParams.fMtu, MSG_PEEK ); + int rx_bytes = Recv(HEADER_SIZE, MSG_PEEK); if ( ( rx_bytes == 0 ) || ( rx_bytes == SOCKET_ERROR ) ) return rx_bytes; @@ -485,13 +483,13 @@ namespace Jack // - extra latency is set to one cycle, what is the time needed to receive streams using full network bandwidth // - if the network is too fast, just wait the next cycle, the benefit here is the master's cycle is shorter // - indeed, data is supposed to be on the network rx buffer, so we don't have to wait for it - if (fCycleOffset < 1) { + if (fCycleOffset < CYCLE_OFFSET_NORMAL) { return 0; } else { rx_bytes = Recv ( rx_head->fPacketSize, 0 ); } - if (fCycleOffset != 1) { + if (fCycleOffset > CYCLE_OFFSET_NORMAL) { jack_info("'%s' can't run in normal network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); } break; @@ -503,7 +501,7 @@ namespace Jack // - but if there is a cycle offset, tell the user, that means we're not in fast mode anymore, network is too slow rx_bytes = Recv ( rx_head->fPacketSize, 0 ); - if (fCycleOffset != 0) { + if (fCycleOffset > CYCLE_OFFSET_FAST) { jack_info("'%s' can't run in fast network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); } break; @@ -526,7 +524,7 @@ namespace Jack while ( !fRxHeader.fIsLastPckt ) { //how much data is queued on the rx buffer ? - rx_bytes = Recv ( fParams.fMtu, MSG_PEEK ); + rx_bytes = Recv(HEADER_SIZE, MSG_PEEK); if ( rx_bytes == SOCKET_ERROR ) return rx_bytes; @@ -546,7 +544,7 @@ namespace Jack rx_bytes = Recv ( rx_head->fPacketSize, 0 ); fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; - fNetMidiPlaybackBuffer->RenderFromNetwork ( rx_head->fSubCycle, rx_bytes - sizeof ( packet_header_t ) ); + fNetMidiPlaybackBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE); if ( ++recvd_midi_pckt == rx_head->fNMidiPckt ) fNetMidiPlaybackBuffer->RenderToJackPorts(); jumpcnt = 0; @@ -732,29 +730,17 @@ namespace Jack //filter incoming packets : don't exit while no error is detected memset(&net_params, 0, sizeof ( session_params_t )); rx_bytes = fSocket.CatchHost ( &net_params, sizeof ( session_params_t ), 0 ); - - SessionParamsDisplay(&net_params); - jack_error ( "rx_bytes %d %d", rx_bytes, errno ); - - SessionParamsNToH(&net_params, &host_params); if ( ( rx_bytes == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) ) { jack_error ( "Can't receive : %s", StrError ( NET_ERROR_CODE ) ); return NET_RECV_ERROR; } - for (int i = 0; i < 7; i++) { - jack_info ( " fPacketType %d", host_params.fPacketType[i]); - } - jack_info ( " received... host_params param %s %s %d %d", net_params.fPacketType, fParams.fPacketType, net_params.fPacketID, GetPacketType ( &host_params )); - - SessionParamsDisplay(&host_params); } while ( strcmp ( host_params.fPacketType, fParams.fPacketType ) && ( GetPacketType ( &host_params ) != SLAVE_SETUP ) ); - - jack_info ( "SLAVE_SETUP received..." ); - + //everything is OK, copy parameters + SessionParamsDisplay(&host_params); fParams = host_params; //set the new buffer sizes @@ -810,8 +796,8 @@ namespace Jack //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); //audio netbuffer length - fAudioTxLen = sizeof ( packet_header_t ) + fNetAudioPlaybackBuffer->GetSize(); - fAudioRxLen = sizeof ( packet_header_t ) + fNetAudioCaptureBuffer->GetSize(); + fAudioTxLen = HEADER_SIZE + fNetAudioPlaybackBuffer->GetSize(); + fAudioRxLen = HEADER_SIZE + fNetAudioCaptureBuffer->GetSize(); } int JackNetSlaveInterface::Recv ( size_t size, int flags ) @@ -867,7 +853,7 @@ namespace Jack //receive sync (launch the cycle) do { - rx_bytes = Recv ( fParams.fMtu, 0 ); + rx_bytes = Recv(HEADER_SIZE, 0); //connection issue, send will detect it, so don't skip the cycle (return 0) if ( rx_bytes == SOCKET_ERROR ) return rx_bytes; @@ -889,7 +875,7 @@ namespace Jack while ( !fRxHeader.fIsLastPckt ) { - rx_bytes = Recv ( fParams.fMtu, MSG_PEEK ); + rx_bytes = Recv(HEADER_SIZE, MSG_PEEK); //error here, problem with recv, just skip the cycle (return -1) if ( rx_bytes == SOCKET_ERROR ) @@ -902,7 +888,7 @@ namespace Jack rx_bytes = Recv ( rx_head->fPacketSize, 0 ); fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; - fNetMidiCaptureBuffer->RenderFromNetwork ( rx_head->fSubCycle, rx_bytes - sizeof ( packet_header_t ) ); + fNetMidiCaptureBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE); // Last midi packet is received, so finish rendering... if ( ++recvd_midi_pckt == rx_head->fNMidiPckt ) fNetMidiCaptureBuffer->RenderToJackPorts(); @@ -938,16 +924,18 @@ namespace Jack int JackNetSlaveInterface::SyncSend() { //tx header - if ( fParams.fSlaveSyncMode ) + if ( fParams.fSlaveSyncMode ) { fTxHeader.fCycle = fRxHeader.fCycle; - else + } else { fTxHeader.fCycle++; + } fTxHeader.fSubCycle = 0; fTxHeader.fDataType = 's'; fTxHeader.fIsLastPckt = ( fParams.fReturnMidiChannels == 0 && fParams.fReturnAudioChannels == 0) ? 1 : 0; - fTxHeader.fPacketSize = fParams.fMtu; - memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) ); - return Send ( fTxHeader.fPacketSize, 0 ); + fTxHeader.fPacketSize = HEADER_SIZE; + + memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); + return Send (fTxHeader.fPacketSize, 0); } int JackNetSlaveInterface::DataSend() @@ -963,10 +951,10 @@ namespace Jack for ( subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ ) { fTxHeader.fSubCycle = subproc; - fTxHeader.fIsLastPckt = ( ( subproc == ( fTxHeader.fNMidiPckt - 1 ) ) && !fParams.fReturnAudioChannels ) ? 1 : 0; - fTxHeader.fPacketSize = sizeof ( packet_header_t ) + fNetMidiPlaybackBuffer->RenderToNetwork ( subproc, fTxHeader.fMidiDataSize ); - memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) ); - if ( Send ( fTxHeader.fPacketSize, 0 ) == SOCKET_ERROR ) + fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNMidiPckt - 1)) && !fParams.fReturnAudioChannels) ? 1 : 0; + fTxHeader.fPacketSize = HEADER_SIZE+ fNetMidiPlaybackBuffer->RenderToNetwork(subproc, fTxHeader.fMidiDataSize); + memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); + if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) return SOCKET_ERROR; } } @@ -980,11 +968,11 @@ namespace Jack for ( subproc = 0; subproc < fNSubProcess; subproc++ ) { fTxHeader.fSubCycle = subproc; - fTxHeader.fIsLastPckt = ( subproc == ( fNSubProcess - 1 ) ) ? 1 : 0; + fTxHeader.fIsLastPckt = (subproc == (fNSubProcess - 1)) ? 1 : 0; fTxHeader.fPacketSize = fAudioTxLen; - memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) ); - fNetAudioPlaybackBuffer->RenderFromJackPorts ( subproc ); - if ( Send ( fTxHeader.fPacketSize, 0 ) == SOCKET_ERROR ) + memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); + fNetAudioPlaybackBuffer->RenderFromJackPorts (subproc); + if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) return SOCKET_ERROR; } } diff --git a/common/JackNetInterface.h b/common/JackNetInterface.h index b573e2cc..62264d4e 100644 --- a/common/JackNetInterface.h +++ b/common/JackNetInterface.h @@ -212,7 +212,9 @@ namespace Jack #define MASTER_INIT_TIMEOUT 1000000 // in usec #define SLAVE_INIT_TIMEOUT 2000000 // in usec -#define CYCLE_OFFSET_SLOW 2 +#define CYCLE_OFFSET_FAST 0 +#define CYCLE_OFFSET_NORMAL 1 +#define CYCLE_OFFSET_SLOW 3 #define MAX_LATENCY CYCLE_OFFSET_SLOW * 4 #endif diff --git a/macosx/iphone/main_slave.mm b/macosx/iphone/main_slave.mm index e25b7ff2..b3435fec 100644 --- a/macosx/iphone/main_slave.mm +++ b/macosx/iphone/main_slave.mm @@ -62,10 +62,12 @@ int main(int argc, char *argv[]) { jack_slave_t request = { NUM_INPUT, NUM_OUTPUT, 0, 0, WIFI_MTU, -1, JackSlowMode }; jack_master_t result; - if ((net = jack_net_slave_open("169.254.136.64", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { + //if ((net = jack_net_slave_open("169.254.121.189", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { + if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { return -1; } + if ((adapter = jack_create_adapter(NUM_INPUT, NUM_OUTPUT, result.buffer_size, From 2dcaaa51f2e8c79f71f5be50dd38a01342ee17ff Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 3 Mar 2010 15:57:50 +0000 Subject: [PATCH 038/472] More cleanup. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3936 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetInterface.cpp | 77 ++++------ common/JackNetInterface.h | 5 - common/JackNetTool.h | 8 + .../iPhoneNet.xcodeproj/project.pbxproj | 137 +++++++++++++++++- 4 files changed, 171 insertions(+), 56 deletions(-) diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index cd2b7e3e..19fe53fe 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -64,7 +64,6 @@ namespace Jack JackNetInterface::JackNetInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip ) : fSocket ( socket ) { - jack_log("JackNetInterface ( session_params_t& params...)"); fParams = params; strcpy(fMulticastIP, multicast_ip); fTxBuffer = NULL; @@ -105,8 +104,6 @@ namespace Jack int JackNetInterface::SetNetBufferSize() { - jack_log ( "JackNetInterface::SetNetBufferSize" ); - float audio_size, midi_size; int bufsize; //audio @@ -116,7 +113,8 @@ namespace Jack fParams.fPeriodSize * sizeof(sample_t) / PACKET_AVAILABLE_SIZE); //bufsize = sync + audio + midi bufsize = MAX_LATENCY * (fParams.fMtu + ( int ) audio_size + ( int ) midi_size); - jack_info("SetNetBufferSize bufsize = %d", bufsize); + + jack_log("SetNetBufferSize bufsize = %d", bufsize); //tx buffer if ( fSocket.SetOption ( SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof ( bufsize ) ) == SOCKET_ERROR ) @@ -167,9 +165,6 @@ namespace Jack //number of audio subcycles (packets) fNSubProcess = fParams.fPeriodSize / fParams.fFramesPerPacket; - //payload size - fPayloadSize = PACKET_AVAILABLE_SIZE; - //TX header init strcpy ( fTxHeader.fPacketType, "header" ); fTxHeader.fID = fParams.fID; @@ -195,8 +190,8 @@ namespace Jack assert ( fRxBuffer ); //net audio/midi buffers'addresses - fTxData = fTxBuffer + sizeof ( packet_header_t ); - fRxData = fRxBuffer + sizeof ( packet_header_t ); + fTxData = fTxBuffer + HEADER_SIZE; + fRxData = fRxBuffer + HEADER_SIZE; } // JackNetMasterInterface ************************************************************************************ @@ -308,10 +303,6 @@ namespace Jack assert ( fNetAudioCaptureBuffer ); assert ( fNetAudioPlaybackBuffer ); - - //audio netbuffer length - fAudioTxLen = HEADER_SIZE + fNetAudioCaptureBuffer->GetSize(); - fAudioRxLen = HEADER_SIZE + fNetAudioPlaybackBuffer->GetSize(); } void JackNetMasterInterface::Exit() @@ -344,7 +335,7 @@ namespace Jack if ((( rx_bytes = fSocket.Recv(fRxBuffer, size, flags)) == SOCKET_ERROR) && fRunning) { net_error_t error = fSocket.GetError(); - //no data isn't really a network error, so just return 0 avalaible read bytes + //no data isn't really a network error, so just return 0 available read bytes if (error == NET_NO_DATA) { return 0; } else if (error == NET_CONN_ERROR) { @@ -403,6 +394,7 @@ namespace Jack fTxHeader.fDataType = 's'; fTxHeader.fIsLastPckt = ( fParams.fSendMidiChannels == 0 && fParams.fSendAudioChannels == 0) ? 1 : 0; fTxHeader.fPacketSize = HEADER_SIZE; + memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); return Send(fTxHeader.fPacketSize, 0); } @@ -438,7 +430,7 @@ namespace Jack { fTxHeader.fSubCycle = subproc; fTxHeader.fIsLastPckt = (subproc == (fNSubProcess - 1)) ? 1 : 0; - fTxHeader.fPacketSize = fAudioTxLen; + fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioPlaybackBuffer->GetSize(); memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); fNetAudioCaptureBuffer->RenderFromJackPorts(subproc); if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) @@ -514,11 +506,9 @@ namespace Jack int JackNetMasterInterface::DataRecv() { int rx_bytes = 0; - uint jumpcnt = 0; - uint recvd_midi_pckt = 0; - uint recvd_audio_pckt = 0; int last_cycle = 0; - + uint recvd_midi_pckt = 0; + packet_header_t* rx_head = reinterpret_cast ( fRxBuffer ); while ( !fRxHeader.fIsLastPckt ) @@ -526,15 +516,10 @@ namespace Jack //how much data is queued on the rx buffer ? rx_bytes = Recv(HEADER_SIZE, MSG_PEEK); + //error here, problem with recv, just skip the cycle (return -1) if ( rx_bytes == SOCKET_ERROR ) return rx_bytes; - //if no data - if ( ( rx_bytes == 0 ) && ( ++jumpcnt == fNSubProcess ) ) - { - jack_error ( "No data from %s...", fParams.fName ); - jumpcnt = 0; - } - //else if data is valid, + if ( rx_bytes && ( rx_head->fDataStream == 'r' ) && ( rx_head->fID == fParams.fID ) ) { //read data @@ -545,21 +530,20 @@ namespace Jack fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; fNetMidiPlaybackBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE); + // Last midi packet is received, so finish rendering... if ( ++recvd_midi_pckt == rx_head->fNMidiPckt ) fNetMidiPlaybackBuffer->RenderToJackPorts(); - jumpcnt = 0; break; case 'a': //audio rx_bytes = Recv ( rx_head->fPacketSize, 0 ); - if (recvd_audio_pckt++ != rx_head->fSubCycle) { - jack_error("Packet(s) missing from '%s'...", fParams.fSlaveNetName); + if (!IsNextPacket()) { + jack_error("Packet(s) missing from '%s'...", fParams.fMasterNetName); } fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fSubCycle = rx_head->fSubCycle; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; fNetAudioPlaybackBuffer->RenderToJackPorts ( rx_head->fCycle, rx_head->fSubCycle); - jumpcnt = 0; last_cycle = rx_head->fCycle; break; @@ -581,7 +565,7 @@ namespace Jack { //this method contains every step of sync packet informations coding //first of all, reset sync packet - memset ( fTxData, 0, fPayloadSize ); + memset ( fTxData, 0, PACKET_AVAILABLE_SIZE ); //then, first step : transport if (fParams.fTransportSync) { @@ -787,6 +771,8 @@ namespace Jack //midi net buffers fNetMidiCaptureBuffer = new NetMidiBuffer ( &fParams, fParams.fSendMidiChannels, fRxData ); fNetMidiPlaybackBuffer = new NetMidiBuffer ( &fParams, fParams.fReturnMidiChannels, fTxData ); + assert ( fNetMidiCaptureBuffer ); + assert ( fNetMidiPlaybackBuffer ); //audio net buffers fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); @@ -794,10 +780,9 @@ namespace Jack //fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); - - //audio netbuffer length - fAudioTxLen = HEADER_SIZE + fNetAudioPlaybackBuffer->GetSize(); - fAudioRxLen = HEADER_SIZE + fNetAudioCaptureBuffer->GetSize(); + + assert ( fNetAudioCaptureBuffer ); + assert ( fNetAudioPlaybackBuffer ); } int JackNetSlaveInterface::Recv ( size_t size, int flags ) @@ -866,20 +851,21 @@ namespace Jack int JackNetSlaveInterface::DataRecv() { - uint recvd_midi_pckt = 0; - uint recvd_audio_pckt = 0; int rx_bytes = 0; int last_cycle = 0; - + uint recvd_midi_pckt = 0; + packet_header_t* rx_head = reinterpret_cast ( fRxBuffer ); while ( !fRxHeader.fIsLastPckt ) { + //how much data is queued on the rx buffer ? rx_bytes = Recv(HEADER_SIZE, MSG_PEEK); + //error here, problem with recv, just skip the cycle (return -1) - if ( rx_bytes == SOCKET_ERROR ) return rx_bytes; + if ( rx_bytes && ( rx_head->fDataStream == 's' ) && ( rx_head->fID == fParams.fID ) ) { switch ( rx_head->fDataType ) @@ -896,7 +882,7 @@ namespace Jack case 'a': //audio rx_bytes = Recv ( rx_head->fPacketSize, 0 ); - if (recvd_audio_pckt++ != rx_head->fSubCycle) { + if (!IsNextPacket()) { jack_error("Packet(s) missing from '%s'...", fParams.fMasterNetName); } fRxHeader.fCycle = rx_head->fCycle; @@ -931,7 +917,7 @@ namespace Jack } fTxHeader.fSubCycle = 0; fTxHeader.fDataType = 's'; - fTxHeader.fIsLastPckt = ( fParams.fReturnMidiChannels == 0 && fParams.fReturnAudioChannels == 0) ? 1 : 0; + fTxHeader.fIsLastPckt = (fParams.fReturnMidiChannels == 0 && fParams.fReturnAudioChannels == 0) ? 1 : 0; fTxHeader.fPacketSize = HEADER_SIZE; memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); @@ -943,8 +929,9 @@ namespace Jack uint subproc; //midi - if ( fParams.fReturnMidiChannels > 0) + if (fParams.fReturnMidiChannels > 0) { + //set global header fields and get the number of midi packets fTxHeader.fDataType = 'm'; fTxHeader.fMidiDataSize = fNetMidiPlaybackBuffer->RenderFromJackPorts(); fTxHeader.fNMidiPckt = GetNMidiPckt(); @@ -952,7 +939,7 @@ namespace Jack { fTxHeader.fSubCycle = subproc; fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNMidiPckt - 1)) && !fParams.fReturnAudioChannels) ? 1 : 0; - fTxHeader.fPacketSize = HEADER_SIZE+ fNetMidiPlaybackBuffer->RenderToNetwork(subproc, fTxHeader.fMidiDataSize); + fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiPlaybackBuffer->RenderToNetwork(subproc, fTxHeader.fMidiDataSize); memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) return SOCKET_ERROR; @@ -969,7 +956,7 @@ namespace Jack { fTxHeader.fSubCycle = subproc; fTxHeader.fIsLastPckt = (subproc == (fNSubProcess - 1)) ? 1 : 0; - fTxHeader.fPacketSize = fAudioTxLen; + fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioCaptureBuffer->GetSize(); memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); fNetAudioPlaybackBuffer->RenderFromJackPorts (subproc); if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) @@ -984,7 +971,7 @@ namespace Jack { //this method contains every step of sync packet informations coding //first of all, reset sync packet - memset ( fTxData, 0, fPayloadSize ); + memset ( fTxData, 0, PACKET_AVAILABLE_SIZE ); //then first step : transport if (fParams.fTransportSync) { EncodeTransportData(); diff --git a/common/JackNetInterface.h b/common/JackNetInterface.h index 62264d4e..55706cf7 100644 --- a/common/JackNetInterface.h +++ b/common/JackNetInterface.h @@ -57,11 +57,6 @@ namespace Jack NetAudioBuffer* fNetAudioCaptureBuffer; NetAudioBuffer* fNetAudioPlaybackBuffer; - //sizes - int fAudioRxLen; - int fAudioTxLen; - int fPayloadSize; - //utility methods void SetFramesPerPacket(); int SetNetBufferSize(); diff --git a/common/JackNetTool.h b/common/JackNetTool.h index a3ebe1f9..4dae55a7 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -233,11 +233,14 @@ namespace Jack void Reset(); size_t GetSize(); + //utility void DisplayEvents(); + //jack<->buffer int RenderFromJackPorts(); int RenderToJackPorts(); + //network<->buffer int RenderFromNetwork ( int subcycle, size_t copy_size ); int RenderToNetwork ( int subcycle, size_t total_size ); @@ -258,10 +261,15 @@ namespace Jack {} virtual size_t GetSize() = 0; + //jack<->buffer virtual void RenderFromJackPorts (int subcycle ) = 0; virtual void RenderToJackPorts ( int cycle, int subcycle) = 0; virtual void FinishRenderToJackPorts (int cycle) = 0; + + //network<->buffer + //int RenderFromNetwork ( int subcycle, size_t copy_size ) = 0; + //int RenderToNetwork ( int subcycle, size_t total_size ) = 0; virtual void SetBuffer ( int index, sample_t* buffer ) = 0; virtual sample_t* GetBuffer ( int index ) = 0; diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj index 31df802d..24592449 100755 --- a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -104,6 +104,16 @@ 4BCF75ED10BC2FD90082C526 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 4BCF75EE10BC2FD90082C526 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; 4BCF75F710BC30140082C526 /* audio_thru.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BCF75F610BC30140082C526 /* audio_thru.mm */; }; + 4BDFCD3D113DB6B700D77992 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; + 4BDFCD3E113DB6B700D77992 /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B9CB1361136CA99007DE01A /* icon.png */; }; + 4BDFCD4A113DB6B700D77992 /* main_slave.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B0772490F54021B000DC657 /* main_slave.mm */; }; + 4BDFCD4B113DB6B700D77992 /* iPhoneNetAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */; }; + 4BDFCD4D113DB6B700D77992 /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; + 4BDFCD4E113DB6B700D77992 /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; }; + 4BDFCD50113DB6B700D77992 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 4BDFCD51113DB6B700D77992 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 4BDFCD52113DB6B700D77992 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 4BDFCD53113DB6B700D77992 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; 4BF1360F0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; 4BF136100F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; 4BF136130F4B0B5E00218A3F /* JackAudioAdapterInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */; }; @@ -143,7 +153,7 @@ /* Begin PBXFileReference section */ 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - 1D6058910D05DD3D006BFB54 /* iPhoneNetSlave.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneNetSlave.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1D6058910D05DD3D006BFB54 /* NetJackSlave.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetJackSlave.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; @@ -172,8 +182,11 @@ 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaust.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BCB37D5112D64B4008C7BC1 /* HardwareClock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HardwareClock.cpp; sourceTree = SOURCE_ROOT; }; 4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "iphone-faust.mm"; sourceTree = SOURCE_ROOT; }; - 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneThruNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BCF75F610BC30140082C526 /* audio_thru.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = audio_thru.mm; sourceTree = SOURCE_ROOT; }; + 4BDFCCD7113DB30500D77992 /* Info copy.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info copy.plist"; sourceTree = ""; }; + 4BDFCD57113DB6B700D77992 /* NetJackSlave.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetJackSlave.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BDFCD59113DB6B700D77992 /* Info copy 2.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info copy 2.plist"; sourceTree = ""; }; 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; }; 4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioAdapterInterface.h; path = ../../common/JackAudioAdapterInterface.h; sourceTree = SOURCE_ROOT; }; 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackResampler.cpp; path = ../../common/JackResampler.cpp; sourceTree = SOURCE_ROOT; }; @@ -249,6 +262,17 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BDFCD4F113DB6B700D77992 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BDFCD50113DB6B700D77992 /* Foundation.framework in Frameworks */, + 4BDFCD51113DB6B700D77992 /* UIKit.framework in Frameworks */, + 4BDFCD52113DB6B700D77992 /* CoreGraphics.framework in Frameworks */, + 4BDFCD53113DB6B700D77992 /* AudioToolbox.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BFF456F0F4D5D9700106083 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -266,13 +290,14 @@ 19C28FACFE9D520D11CA2CBB /* Products */ = { isa = PBXGroup; children = ( - 1D6058910D05DD3D006BFB54 /* iPhoneNetSlave.app */, + 1D6058910D05DD3D006BFB54 /* NetJackSlave.app */, 4BFF45120F4D59DB00106083 /* libjacknet.a */, 4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */, 4B0772380F54018C000DC657 /* iPhoneNetMaster.app */, - 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */, + 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */, 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */, 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */, + 4BDFCD57113DB6B700D77992 /* NetJackSlave.app */, ); name = Products; sourceTree = ""; @@ -329,6 +354,8 @@ 28AD733E0D9D9553002E5188 /* MainWindow.xib */, 8D1107310486CEB800E47090 /* Info.plist */, 4BC9C1D31135AA1800D22670 /* iPhoneNetMasterAppl-Info.plist */, + 4BDFCCD7113DB30500D77992 /* Info copy.plist */, + 4BDFCD59113DB6B700D77992 /* Info copy 2.plist */, ); name = Resources; sourceTree = ""; @@ -377,7 +404,7 @@ ); name = iPhoneNetSlave; productName = iPhoneNet; - productReference = 1D6058910D05DD3D006BFB54 /* iPhoneNetSlave.app */; + productReference = 1D6058910D05DD3D006BFB54 /* NetJackSlave.app */; productType = "com.apple.product-type.application"; }; 4B07721F0F54018C000DC657 /* iPhoneNetMaster */ = { @@ -462,7 +489,24 @@ ); name = iPhoneThruNet; productName = iPhoneNet; - productReference = 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */; + productReference = 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */; + productType = "com.apple.product-type.application"; + }; + 4BDFCD3B113DB6B700D77992 /* iPhoneNetSlaveLib */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4BDFCD54113DB6B700D77992 /* Build configuration list for PBXNativeTarget "iPhoneNetSlaveLib" */; + buildPhases = ( + 4BDFCD3C113DB6B700D77992 /* Resources */, + 4BDFCD3F113DB6B700D77992 /* Sources */, + 4BDFCD4F113DB6B700D77992 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = iPhoneNetSlaveLib; + productName = iPhoneNet; + productReference = 4BDFCD57113DB6B700D77992 /* NetJackSlave.app */; productType = "com.apple.product-type.application"; }; 4BFF455E0F4D5D9700106083 /* iPhoneFaustNet */ = { @@ -496,6 +540,7 @@ targets = ( 4B07721F0F54018C000DC657 /* iPhoneNetMaster */, 1D6058900D05DD3D006BFB54 /* iPhoneNetSlave */, + 4BDFCD3B113DB6B700D77992 /* iPhoneNetSlaveLib */, 4BFF455E0F4D5D9700106083 /* iPhoneFaustNet */, 4BCF75D810BC2FD90082C526 /* iPhoneThruNet */, 4B41469610BD3C4300C12F0C /* iPhoneFaustNet Distribution */, @@ -551,6 +596,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BDFCD3C113DB6B700D77992 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BDFCD3D113DB6B700D77992 /* MainWindow.xib in Resources */, + 4BDFCD3E113DB6B700D77992 /* icon.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BFF455F0F4D5D9700106083 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -680,6 +734,17 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BDFCD3F113DB6B700D77992 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BDFCD4A113DB6B700D77992 /* main_slave.mm in Sources */, + 4BDFCD4B113DB6B700D77992 /* iPhoneNetAppDelegate.m in Sources */, + 4BDFCD4D113DB6B700D77992 /* CAHostTimeBase.cpp in Sources */, + 4BDFCD4E113DB6B700D77992 /* TiPhoneCoreAudioRenderer.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BFF45610F4D5D9700106083 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1003,6 +1068,57 @@ }; name = Release; }; + 4BDFCD55113DB6B700D77992 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + HEADER_SEARCH_PATHS = ( + ../../macosx/coreaudio, + ../../macosx, + ../../posix, + ../../common/jack, + ../../common, + ); + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\"", + ); + OTHER_LDFLAGS = "-ljacknet"; + PRODUCT_NAME = iPhoneNetSlave; + SDKROOT = iphoneos3.1.3; + }; + name = Debug; + }; + 4BDFCD56113DB6B700D77992 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + HEADER_SEARCH_PATHS = ( + ../../macosx/coreaudio, + ../../common/jack, + ../../common, + ../../posix, + ../../macosx, + ); + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\"", + ); + OTHER_LDFLAGS = "-ljacknet"; + PRODUCT_NAME = NetJackSlave; + }; + name = Release; + }; 4BFF45750F4D5D9700106083 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1136,6 +1252,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 4BDFCD54113DB6B700D77992 /* Build configuration list for PBXNativeTarget "iPhoneNetSlaveLib" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4BDFCD55113DB6B700D77992 /* Debug */, + 4BDFCD56113DB6B700D77992 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 4BFF45740F4D5D9700106083 /* Build configuration list for PBXNativeTarget "iPhoneFaustNet" */ = { isa = XCConfigurationList; buildConfigurations = ( From 3b009644a7dd6fc51c645fb6eb9873121b9e98f5 Mon Sep 17 00:00:00 2001 From: sletz Date: Fri, 5 Mar 2010 10:50:03 +0000 Subject: [PATCH 039/472] Raise network protocol, major cleanup. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3939 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetAPI.cpp | 16 ++- common/JackNetDriver.cpp | 5 +- common/JackNetInterface.cpp | 247 ++++++++++++++++-------------------- common/JackNetInterface.h | 14 +- common/JackNetManager.cpp | 9 +- common/JackNetTool.cpp | 68 +++++++--- common/JackNetTool.h | 206 ++++++++++++++++++++++++------ macosx/iphone/main_slave.mm | 9 +- 8 files changed, 357 insertions(+), 217 deletions(-) diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 3ad6e771..90ce515c 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -262,7 +262,9 @@ struct JackNetExtMaster : public JackNetMasterInterface { return -1; // Set global parameters - SetParams(); + if (!SetParams()) + return -1; + AllocPorts(); return 0; } @@ -465,12 +467,12 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf int Open(jack_master_t* result) { // Init network connection - if (!JackNetSlaveInterface::InitConnection()){ + if (!JackNetSlaveInterface::InitConnection()) return -1; - } // Then set global parameters - SetParams(); + if (!SetParams()) + return -1; // Set result if (result != NULL) { @@ -494,7 +496,8 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf return -1; // Then set global parameters - SetParams(); + if (!SetParams()) + return -1; // We need to notify possibly new buffer size and sample rate (see Execute) if (fBufferSizeCallback) @@ -514,6 +517,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf return 0; } + void AllocPorts() { unsigned int port_index; @@ -939,7 +943,7 @@ SERVER_EXPORT void jack_log(const char *fmt, ...) { va_list ap; va_start(ap, fmt); - //jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); + jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); va_end(ap); } diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index 5f5af5db..477acb28 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -142,11 +142,12 @@ namespace Jack ( fParams.fSlaveSyncMode ) ? "sync" : "async", ( fParams.fTransportSync ) ? "with" : "without" ); //init network - if ( !JackNetSlaveInterface::Init() ) + if (!JackNetSlaveInterface::Init()) return false; //set global parameters - SetParams(); + if (!SetParams()) + return false; //allocate midi ports lists fMidiCapturePortList = new jack_port_id_t [fParams.fSendMidiChannels]; diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 19fe53fe..38584b04 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -89,88 +89,45 @@ namespace Jack delete fNetMidiPlaybackBuffer; } - void JackNetInterface::SetFramesPerPacket() - { - jack_log ( "JackNetInterface::SetFramesPerPacket" ); - - if (fParams.fSendAudioChannels == 0 && fParams.fReturnAudioChannels == 0) { - fParams.fFramesPerPacket = fParams.fPeriodSize; - } else { - jack_nframes_t period = ( int ) powf ( 2.f, ( int ) ( log (float (PACKET_AVAILABLE_SIZE) - / ( max ( fParams.fReturnAudioChannels, fParams.fSendAudioChannels ) * sizeof ( sample_t ) ) ) / log ( 2. ) ) ); - fParams.fFramesPerPacket = ( period > fParams.fPeriodSize ) ? fParams.fPeriodSize : period; - } - } - int JackNetInterface::SetNetBufferSize() { - float audio_size, midi_size; - int bufsize; //audio - audio_size = fParams.fMtu * ( fParams.fPeriodSize / fParams.fFramesPerPacket ); + float audio_size = (fNetAudioCaptureBuffer) + ? fNetAudioCaptureBuffer->GetCycleSize() + : (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleSize() : 0; + + jack_log ("audio_size %f", audio_size); + //midi - midi_size = fParams.fMtu * ( max ( fParams.fSendMidiChannels, fParams.fReturnMidiChannels ) * - fParams.fPeriodSize * sizeof(sample_t) / PACKET_AVAILABLE_SIZE); + float midi_size = (fNetMidiCaptureBuffer) + ? fNetMidiCaptureBuffer->GetCycleSize() + : (fNetMidiPlaybackBuffer) ? fNetMidiPlaybackBuffer->GetCycleSize() : 0; + + jack_log ("midi_size %f", midi_size); + //bufsize = sync + audio + midi - bufsize = MAX_LATENCY * (fParams.fMtu + ( int ) audio_size + ( int ) midi_size); + int bufsize = MAX_LATENCY * (fParams.fMtu + (int)audio_size + (int) midi_size); jack_log("SetNetBufferSize bufsize = %d", bufsize); //tx buffer - if ( fSocket.SetOption ( SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof ( bufsize ) ) == SOCKET_ERROR ) + if (fSocket.SetOption(SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR) return SOCKET_ERROR; //rx buffer - if ( fSocket.SetOption ( SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof ( bufsize ) ) == SOCKET_ERROR ) + if (fSocket.SetOption(SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR) return SOCKET_ERROR; return 0; } - int JackNetInterface::GetNMidiPckt() - { - //even if there is no midi data, jack need an empty buffer to know there is no event to read - //99% of the cases : all data in one packet - - if (fTxHeader.fMidiDataSize <= PACKET_AVAILABLE_SIZE) { - return 1; - } else { //get the number of needed packets (simply slice the biiig buffer) - return (fTxHeader.fMidiDataSize % PACKET_AVAILABLE_SIZE) - ? (fTxHeader.fMidiDataSize / PACKET_AVAILABLE_SIZE + 1) - : fTxHeader.fMidiDataSize / PACKET_AVAILABLE_SIZE; - } - } - - bool JackNetInterface::IsNextPacket() - { - packet_header_t* rx_head = reinterpret_cast ( fRxBuffer ); - //ignore first cycle - if ( fRxHeader.fCycle <= 1 ) { - return true; - } - //same PcktID (cycle), next SubPcktID (subcycle) - if ( ( fRxHeader.fSubCycle < ( fNSubProcess - 1 ) ) && ( rx_head->fCycle == fRxHeader.fCycle ) && ( rx_head->fSubCycle == ( fRxHeader.fSubCycle + 1 ) ) ) { - return true; - } - //next PcktID (cycle), SubPcktID reset to 0 (first subcyle) - if ( ( rx_head->fCycle == ( fRxHeader.fCycle + 1 ) ) && ( fRxHeader.fSubCycle == ( fNSubProcess - 1 ) ) && ( rx_head->fSubCycle == 0 ) ) { - return true; - } - //else, packet(s) missing, return false - return false; - } - - void JackNetInterface::SetParams() + bool JackNetInterface::SetParams() { - //number of audio subcycles (packets) - fNSubProcess = fParams.fPeriodSize / fParams.fFramesPerPacket; - //TX header init strcpy ( fTxHeader.fPacketType, "header" ); fTxHeader.fID = fParams.fID; fTxHeader.fCycle = 0; fTxHeader.fSubCycle = 0; - fTxHeader.fMidiDataSize = 0; fTxHeader.fBitdepth = fParams.fBitdepth; fTxHeader.fIsLastPckt = 0; @@ -179,7 +136,6 @@ namespace Jack fRxHeader.fID = fParams.fID; fRxHeader.fCycle = 0; fRxHeader.fSubCycle = 0; - fRxHeader.fMidiDataSize = 0; fRxHeader.fBitdepth = fParams.fBitdepth; fRxHeader.fIsLastPckt = 0; @@ -192,6 +148,8 @@ namespace Jack //net audio/midi buffers'addresses fTxData = fTxBuffer + HEADER_SIZE; fRxData = fRxBuffer + HEADER_SIZE; + + return true; } // JackNetMasterInterface ************************************************************************************ @@ -220,11 +178,8 @@ namespace Jack return false; } - //set the number of complete audio frames we can put in a packet - SetFramesPerPacket(); - //send 'SLAVE_SETUP' until 'START_MASTER' received - jack_info ( "Sending parameters to %s ...", fParams.fSlaveNetName ); + jack_info ( "Sending parameters to %s...", fParams.fSlaveNetName ); do { session_params_t net_params; @@ -250,18 +205,6 @@ namespace Jack return false; } - //set the new timeout for the socket - if ( SetRxTimeout() == SOCKET_ERROR ) { - jack_error ( "Can't set rx timeout : %s", StrError ( NET_ERROR_CODE ) ); - return false; - } - - //set the new rx buffer size - if ( SetNetBufferSize() == SOCKET_ERROR ) { - jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) ); - return false; - } - return true; } @@ -270,16 +213,22 @@ namespace Jack jack_log ( "JackNetMasterInterface::SetRxTimeout" ); float time = 0; + //slow or normal mode, short timeout on recv (2 audio subcycles) - if ( ( fParams.fNetworkMode == 's' ) || ( fParams.fNetworkMode == 'n' ) ) - time = 2000000.f * ( static_cast ( fParams.fFramesPerPacket ) / static_cast ( fParams.fSampleRate ) ); + if ((fParams.fNetworkMode == 's') || (fParams.fNetworkMode == 'n')) { + time = 2000000.f * ((fNetAudioCaptureBuffer) + ? fNetAudioCaptureBuffer->GetCycleDuration() + : (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleDuration() : 0); + } //fast mode, wait for 75% of the entire cycle duration - else if ( fParams.fNetworkMode == 'f' ) - time = 750000.f * ( static_cast ( fParams.fPeriodSize ) / static_cast ( fParams.fSampleRate ) ); - return fSocket.SetTimeOut ( static_cast ( time ) ); + else if (fParams.fNetworkMode == 'f') { + time = 750000.f * (static_cast(fParams.fPeriodSize) / static_cast(fParams.fSampleRate)); + } + + return fSocket.SetTimeOut (static_cast(time)); } - void JackNetMasterInterface::SetParams() + bool JackNetMasterInterface::SetParams() { jack_log ( "JackNetMasterInterface::SetParams" ); @@ -303,6 +252,28 @@ namespace Jack assert ( fNetAudioCaptureBuffer ); assert ( fNetAudioPlaybackBuffer ); + + //set the new timeout for the socket + if ( SetRxTimeout() == SOCKET_ERROR ) { + jack_error ( "Can't set rx timeout : %s", StrError ( NET_ERROR_CODE ) ); + goto error; + } + + //set the new rx buffer size + if ( SetNetBufferSize() == SOCKET_ERROR ) { + jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) ); + goto error; + } + + return true; + + error: + + delete fNetMidiCaptureBuffer; + delete fNetMidiPlaybackBuffer; + delete fNetAudioCaptureBuffer; + delete fNetAudioPlaybackBuffer; + return false; } void JackNetMasterInterface::Exit() @@ -402,18 +373,21 @@ namespace Jack int JackNetMasterInterface::DataSend() { uint subproc; + uint data_size; + //midi if ( fParams.fSendMidiChannels > 0) { //set global header fields and get the number of midi packets fTxHeader.fDataType = 'm'; - fTxHeader.fMidiDataSize = fNetMidiCaptureBuffer->RenderFromJackPorts(); - fTxHeader.fNMidiPckt = GetNMidiPckt(); - for ( subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ ) + data_size = fNetMidiCaptureBuffer->RenderFromJackPorts(); + fTxHeader.fNumPacket = fNetMidiCaptureBuffer->GetNumPackets(); + + for ( subproc = 0; subproc < fTxHeader.fNumPacket; subproc++ ) { fTxHeader.fSubCycle = subproc; - fTxHeader.fIsLastPckt = (( subproc == (fTxHeader.fNMidiPckt - 1)) && (fParams.fSendAudioChannels == 0)) ? 1 : 0; - fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiCaptureBuffer->RenderToNetwork(subproc, fTxHeader.fMidiDataSize); + fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && (fParams.fSendAudioChannels == 0)) ? 1 : 0; + fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiCaptureBuffer->RenderToNetwork(subproc, data_size); memcpy ( fTxBuffer, &fTxHeader, HEADER_SIZE); if (Send (fTxHeader.fPacketSize, 0) == SOCKET_ERROR) return SOCKET_ERROR; @@ -424,15 +398,15 @@ namespace Jack if ( fParams.fSendAudioChannels > 0) { fTxHeader.fDataType = 'a'; - fTxHeader.fMidiDataSize = 0; - fTxHeader.fNMidiPckt = 0; - for (subproc = 0; subproc < fNSubProcess; subproc++) + data_size = fNetAudioCaptureBuffer->RenderFromJackPorts(); + fTxHeader.fNumPacket = fNetAudioCaptureBuffer->GetNumPackets(); + + for (subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) { fTxHeader.fSubCycle = subproc; - fTxHeader.fIsLastPckt = (subproc == (fNSubProcess - 1)) ? 1 : 0; - fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioPlaybackBuffer->GetSize(); + fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0; + fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioCaptureBuffer->RenderToNetwork(subproc, data_size); memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); - fNetAudioCaptureBuffer->RenderFromJackPorts(subproc); if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) return SOCKET_ERROR; } @@ -506,8 +480,8 @@ namespace Jack int JackNetMasterInterface::DataRecv() { int rx_bytes = 0; - int last_cycle = 0; uint recvd_midi_pckt = 0; + uint recvd_audio_pckt = 0; packet_header_t* rx_head = reinterpret_cast ( fRxBuffer ); @@ -530,34 +504,30 @@ namespace Jack fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; fNetMidiPlaybackBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE); - // Last midi packet is received, so finish rendering... - if ( ++recvd_midi_pckt == rx_head->fNMidiPckt ) + // Last midi packet is received, so finish rendering... + if (++recvd_midi_pckt == rx_head->fNumPacket) fNetMidiPlaybackBuffer->RenderToJackPorts(); break; case 'a': //audio rx_bytes = Recv ( rx_head->fPacketSize, 0 ); - if (!IsNextPacket()) { - jack_error("Packet(s) missing from '%s'...", fParams.fMasterNetName); - } fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fSubCycle = rx_head->fSubCycle; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; - fNetAudioPlaybackBuffer->RenderToJackPorts ( rx_head->fCycle, rx_head->fSubCycle); - last_cycle = rx_head->fCycle; + fNetAudioPlaybackBuffer->RenderFromNetwork (rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE); + // Last audio packet is received, so finish rendering... + if (fRxHeader.fIsLastPckt) + fNetAudioPlaybackBuffer->RenderToJackPorts(); break; case 's': //sync jack_info("NetMaster : overloaded, skipping receive from '%s'", fParams.fName); - // Finish rendering (copy to JACK ports) - fNetAudioPlaybackBuffer->FinishRenderToJackPorts(last_cycle); + // TODO : finish midi and audio rendering ? return 0; } } } - - // Finish rendering (copy to JACK ports) - fNetAudioPlaybackBuffer->FinishRenderToJackPorts(last_cycle); + return rx_bytes; } @@ -727,18 +697,11 @@ namespace Jack SessionParamsDisplay(&host_params); fParams = host_params; - //set the new buffer sizes - if ( SetNetBufferSize() == SOCKET_ERROR ) { - jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) ); - return NET_SOCKET_ERROR; - } - //connect the socket if ( fSocket.Connect() == SOCKET_ERROR ) { jack_error ( "Error in connect : %s", StrError ( NET_ERROR_CODE ) ); return NET_CONNECT_ERROR; } - return NET_CONNECTED; } @@ -759,7 +722,7 @@ namespace Jack return NET_ROLLING; } - void JackNetSlaveInterface::SetParams() + bool JackNetSlaveInterface::SetParams() { jack_log ( "JackNetSlaveInterface::SetParams" ); @@ -783,6 +746,21 @@ namespace Jack assert ( fNetAudioCaptureBuffer ); assert ( fNetAudioPlaybackBuffer ); + + //set the new buffer sizes + if ( SetNetBufferSize() == SOCKET_ERROR ) { + jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) ); + goto error; + } + + return true; + + error: + delete fNetMidiCaptureBuffer; + delete fNetMidiPlaybackBuffer; + delete fNetAudioCaptureBuffer; + delete fNetAudioPlaybackBuffer; + return false; } int JackNetSlaveInterface::Recv ( size_t size, int flags ) @@ -852,8 +830,9 @@ namespace Jack int JackNetSlaveInterface::DataRecv() { int rx_bytes = 0; - int last_cycle = 0; + //int last_cycle = 0; uint recvd_midi_pckt = 0; + uint recvd_audio_pckt = 0; packet_header_t* rx_head = reinterpret_cast ( fRxBuffer ); @@ -876,33 +855,29 @@ namespace Jack fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; fNetMidiCaptureBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE); // Last midi packet is received, so finish rendering... - if ( ++recvd_midi_pckt == rx_head->fNMidiPckt ) + if ( ++recvd_midi_pckt == rx_head->fNumPacket ) fNetMidiCaptureBuffer->RenderToJackPorts(); break; case 'a': //audio rx_bytes = Recv ( rx_head->fPacketSize, 0 ); - if (!IsNextPacket()) { - jack_error("Packet(s) missing from '%s'...", fParams.fMasterNetName); - } fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fSubCycle = rx_head->fSubCycle; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; - fNetAudioCaptureBuffer->RenderToJackPorts ( rx_head->fCycle, rx_head->fSubCycle); - last_cycle = rx_head->fCycle; + fNetAudioCaptureBuffer->RenderFromNetwork (rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE); + if (fRxHeader.fIsLastPckt) { + fNetAudioCaptureBuffer->RenderToJackPorts(); + } break; case 's': //sync jack_info ( "NetSlave : overloaded, skipping receive." ); - // Finish rendering (copy to JACK ports) - fNetAudioCaptureBuffer->FinishRenderToJackPorts(last_cycle); + // TODO : finish midi and audio rendering ? return 0; } } } - // Finish rendering (copy to JACK ports) - fNetAudioCaptureBuffer->FinishRenderToJackPorts(last_cycle); fRxHeader.fCycle = rx_head->fCycle; return 0; } @@ -927,19 +902,20 @@ namespace Jack int JackNetSlaveInterface::DataSend() { uint subproc; + uint data_size; //midi if (fParams.fReturnMidiChannels > 0) { //set global header fields and get the number of midi packets fTxHeader.fDataType = 'm'; - fTxHeader.fMidiDataSize = fNetMidiPlaybackBuffer->RenderFromJackPorts(); - fTxHeader.fNMidiPckt = GetNMidiPckt(); - for ( subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ ) + data_size = fNetMidiPlaybackBuffer->RenderFromJackPorts(); + fTxHeader.fNumPacket = fNetMidiPlaybackBuffer->GetNumPackets(); + for ( subproc = 0; subproc < fTxHeader.fNumPacket; subproc++ ) { fTxHeader.fSubCycle = subproc; - fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNMidiPckt - 1)) && !fParams.fReturnAudioChannels) ? 1 : 0; - fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiPlaybackBuffer->RenderToNetwork(subproc, fTxHeader.fMidiDataSize); + fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && !fParams.fReturnAudioChannels) ? 1 : 0; + fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiPlaybackBuffer->RenderToNetwork(subproc, data_size); memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) return SOCKET_ERROR; @@ -950,15 +926,14 @@ namespace Jack if ( fParams.fReturnAudioChannels > 0) { fTxHeader.fDataType = 'a'; - fTxHeader.fMidiDataSize = 0; - fTxHeader.fNMidiPckt = 0; - for ( subproc = 0; subproc < fNSubProcess; subproc++ ) + data_size = fNetAudioPlaybackBuffer->RenderFromJackPorts(); + fTxHeader.fNumPacket = fNetAudioPlaybackBuffer->GetNumPackets(); + for ( subproc = 0; subproc < fTxHeader.fNumPacket; subproc++ ) { fTxHeader.fSubCycle = subproc; - fTxHeader.fIsLastPckt = (subproc == (fNSubProcess - 1)) ? 1 : 0; - fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioCaptureBuffer->GetSize(); + fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0; + fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioPlaybackBuffer->RenderToNetwork(subproc, data_size); memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); - fNetAudioPlaybackBuffer->RenderFromJackPorts (subproc); if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) return SOCKET_ERROR; } diff --git a/common/JackNetInterface.h b/common/JackNetInterface.h index 55706cf7..d4214904 100644 --- a/common/JackNetInterface.h +++ b/common/JackNetInterface.h @@ -35,8 +35,7 @@ namespace Jack session_params_t fParams; JackNetSocket fSocket; char fMulticastIP[32]; - uint fNSubProcess; - + //headers packet_header_t fTxHeader; packet_header_t fRxHeader; @@ -58,13 +57,10 @@ namespace Jack NetAudioBuffer* fNetAudioPlaybackBuffer; //utility methods - void SetFramesPerPacket(); int SetNetBufferSize(); - int GetNMidiPckt(); - bool IsNextPacket(); - + //virtual methods : depends on the sub class master/slave - virtual void SetParams(); + virtual bool SetParams(); virtual bool Init() = 0; //transport @@ -103,7 +99,7 @@ namespace Jack bool Init(); int SetRxTimeout(); - void SetParams(); + bool SetParams(); void Exit(); @@ -149,7 +145,7 @@ namespace Jack net_status_t SendAvailableToMaster(); net_status_t SendStartToMaster(); - void SetParams(); + bool SetParams(); int SyncRecv(); int SyncSend(); diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index b42d970e..fb6d855b 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -113,11 +113,12 @@ namespace Jack bool JackNetMaster::Init(bool auto_connect) { //network init - if ( !JackNetMasterInterface::Init() ) + if (!JackNetMasterInterface::Init()) return false; //set global parameters - SetParams(); + if (!SetParams()) + return false; //jack client and process jack_status_t status; @@ -415,7 +416,7 @@ namespace Jack for ( port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++ ) fNetMidiPlaybackBuffer->SetBuffer ( port_index, static_cast ( jack_port_get_buffer ( fMidiPlaybackPorts[port_index], fParams.fPeriodSize ) ) ); - for ( port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++ ) + for ( port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++ ) fNetAudioPlaybackBuffer->SetBuffer ( port_index, static_cast ( jack_port_get_buffer ( fAudioPlaybackPorts[port_index], fParams.fPeriodSize ) ) ); @@ -601,7 +602,7 @@ namespace Jack if ( fSocket.SetTimeOut ( 2000000 ) == SOCKET_ERROR ) jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) ); - jack_info ( "Waiting for a slave..." ); + jack_log ( "sizeof (session_params_t) %d", sizeof (session_params_t) ); //main loop, wait for data, deal with it and wait again do diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index 0eee2474..862216a3 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -35,6 +35,9 @@ namespace Jack for ( int port_index = 0; port_index < fNPorts; port_index++ ) fPortBuffer[port_index] = NULL; fNetBuffer = net_buffer; + + fCycleSize = params->fMtu * (max(params->fSendMidiChannels, params->fReturnMidiChannels) * + params->fPeriodSize * sizeof(sample_t) / (params->fMtu - sizeof(packet_header_t))); } NetMidiBuffer::~NetMidiBuffer() @@ -47,6 +50,23 @@ namespace Jack { return fMaxBufsize; } + + size_t NetMidiBuffer::GetCycleSize() + { + return fCycleSize; + } + + int NetMidiBuffer::GetNumPackets() + { + /* + return (data_size % PACKET_AVAILABLE_SIZE) + ? (data_size / PACKET_AVAILABLE_SIZE + 1) + : data_size / PACKET_AVAILABLE_SIZE; + */ + + //TODO + return 0; + } void NetMidiBuffer::SetBuffer ( int index, JackMidiBuffer* buffer ) { @@ -124,10 +144,8 @@ namespace Jack return copy_size; } - // net audio buffer ********************************************************************************* - NetSingleAudioBuffer::NetSingleAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) : fPortBuffer(params, nports), fNetBuffer(net_buffer) {} @@ -139,6 +157,11 @@ namespace Jack { return fPortBuffer.GetSize(); } + + size_t NetSingleAudioBuffer::GetCycleSize() + { + return fPortBuffer.GetCycleSize(); + } void NetSingleAudioBuffer::SetBuffer ( int index, sample_t* buffer ) { @@ -150,18 +173,30 @@ namespace Jack return fPortBuffer.GetBuffer(index); } - void NetSingleAudioBuffer::RenderFromJackPorts (int subcycle) + int NetSingleAudioBuffer::RenderFromJackPorts () { - fPortBuffer.RenderFromJackPorts(fNetBuffer, subcycle); + return fPortBuffer.RenderFromJackPorts(); } - void NetSingleAudioBuffer::RenderToJackPorts (int cycle, int subcycle) + int NetSingleAudioBuffer::RenderToJackPorts () + { + return fPortBuffer.RenderToJackPorts(); + } + + //network<->buffer + int NetSingleAudioBuffer::RenderFromNetwork ( int cycle, int subcycle, size_t copy_size ) + { + return fPortBuffer.RenderFromNetwork(fNetBuffer, cycle, subcycle, copy_size); + } + + int NetSingleAudioBuffer::RenderToNetwork (int subcycle, size_t total_size ) { - fPortBuffer.RenderToJackPorts(fNetBuffer, subcycle); + return fPortBuffer.RenderToNetwork(fNetBuffer, subcycle, total_size); } // Buffered +/* NetBufferedAudioBuffer::NetBufferedAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) { fMaxCycle = 0; @@ -172,7 +207,7 @@ namespace Jack } fJackPortBuffer = new sample_t* [nports]; - for ( int port_index = 0; port_index < nports; port_index++ ) + for ( uint32_t port_index = 0; port_index < nports; port_index++ ) fJackPortBuffer[port_index] = NULL; } @@ -185,6 +220,11 @@ namespace Jack { return fPortBuffer[0].GetSize(); } + + size_t NetBufferedAudioBuffer::GetCycleSize() + { + return fPortBuffer[0].GetCycleSize(); + } void NetBufferedAudioBuffer::SetBuffer ( int index, sample_t* buffer ) { @@ -214,6 +254,7 @@ namespace Jack fMaxCycle = std::max(fMaxCycle, cycle); fPortBuffer[(cycle + 1) % AUDIO_BUFFER_SIZE].Copy(fJackPortBuffer); // Copy internal buffer in JACK ports } + */ // SessionParams ************************************************************************************ @@ -230,7 +271,6 @@ namespace Jack dst_params->fReturnMidiChannels = htonl ( src_params->fReturnMidiChannels ); dst_params->fSampleRate = htonl ( src_params->fSampleRate ); dst_params->fPeriodSize = htonl ( src_params->fPeriodSize ); - dst_params->fFramesPerPacket = htonl ( src_params->fFramesPerPacket ); dst_params->fBitdepth = htonl ( src_params->fBitdepth ); dst_params->fSlaveSyncMode = htonl ( src_params->fSlaveSyncMode ); } @@ -248,7 +288,6 @@ namespace Jack dst_params->fReturnMidiChannels = ntohl ( src_params->fReturnMidiChannels ); dst_params->fSampleRate = ntohl ( src_params->fSampleRate ); dst_params->fPeriodSize = ntohl ( src_params->fPeriodSize ); - dst_params->fFramesPerPacket = ntohl ( src_params->fFramesPerPacket ); dst_params->fBitdepth = ntohl ( src_params->fBitdepth ); dst_params->fSlaveSyncMode = ntohl ( src_params->fSlaveSyncMode ); } @@ -282,8 +321,6 @@ namespace Jack jack_info ( "Return channels (audio - midi) : %d - %d", params->fReturnAudioChannels, params->fReturnMidiChannels ); jack_info ( "Sample rate : %u frames per second", params->fSampleRate ); jack_info ( "Period size : %u frames per period", params->fPeriodSize ); - jack_info ( "Frames per packet : %u", params->fFramesPerPacket ); - jack_info ( "Packet per period : %u", (params->fFramesPerPacket != 0) ? params->fPeriodSize / params->fFramesPerPacket : 0); jack_info ( "Bitdepth : %s", bitdepth ); jack_info ( "Slave mode : %s", ( params->fSlaveSyncMode ) ? "sync" : "async" ); jack_info ( "Network mode : %s", mode ); @@ -338,9 +375,8 @@ namespace Jack { memcpy(dst_header, src_header, sizeof(packet_header_t)); dst_header->fID = htonl ( src_header->fID ); - dst_header->fMidiDataSize = htonl ( src_header->fMidiDataSize ); dst_header->fBitdepth = htonl ( src_header->fBitdepth ); - dst_header->fNMidiPckt = htonl ( src_header->fNMidiPckt ); + dst_header->fNumPacket = htonl ( src_header->fNumPacket ); dst_header->fPacketSize = htonl ( src_header->fPacketSize ); dst_header->fCycle = htonl ( src_header->fCycle ); dst_header->fSubCycle = htonl ( src_header->fSubCycle ); @@ -351,9 +387,8 @@ namespace Jack { memcpy(dst_header, src_header, sizeof(packet_header_t)); dst_header->fID = ntohl ( src_header->fID ); - dst_header->fMidiDataSize = ntohl ( src_header->fMidiDataSize ); dst_header->fBitdepth = ntohl ( src_header->fBitdepth ); - dst_header->fNMidiPckt = ntohl ( src_header->fNMidiPckt ); + dst_header->fNumPacket = ntohl ( src_header->fNumPacket ); dst_header->fPacketSize = ntohl ( src_header->fPacketSize ); dst_header->fCycle = ntohl ( src_header->fCycle ); dst_header->fSubCycle = ntohl ( src_header->fSubCycle ); @@ -370,8 +405,7 @@ namespace Jack jack_info ( "ID : %u", header->fID ); jack_info ( "Cycle : %u", header->fCycle ); jack_info ( "SubCycle : %u", header->fSubCycle ); - jack_info ( "Midi packets : %u", header->fNMidiPckt ); - jack_info ( "Midi data size : %u", header->fMidiDataSize ); + jack_info ( "Midi packets : %u", header->fNumPacket ); jack_info ( "Last packet : '%s'", ( header->fIsLastPckt ) ? "yes" : "no" ); jack_info ( "Bitdepth : %s", bitdepth ); jack_info ( "**********************************************" ); diff --git a/common/JackNetTool.h b/common/JackNetTool.h index 4dae55a7..7c79f9ec 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -67,8 +67,8 @@ namespace Jack are kept in LITTLE_ENDIAN format (to avoid 2 conversions in the more common LITTLE_ENDIAN <==> LITTLE_ENDIAN connection case). */ - #define MASTER_PROTOCOL 1 - #define SLAVE_PROTOCOL 1 + #define MASTER_PROTOCOL 2 + #define SLAVE_PROTOCOL 2 struct _session_params { @@ -87,7 +87,6 @@ namespace Jack uint32_t fReturnMidiChannels; //number of slave->master midi channels uint32_t fSampleRate; //session sample rate uint32_t fPeriodSize; //period size - uint32_t fFramesPerPacket; //complete frames per packet uint32_t fBitdepth; //samples bitdepth (unused) uint32_t fSlaveSyncMode; //is the slave in sync mode ? char fNetworkMode; //fast, normal or slow mode @@ -159,14 +158,11 @@ namespace Jack char fDataStream; //s for send, r for return uint32_t fID; //unique ID of the slave uint32_t fBitdepth; //bitdepth of the data samples - uint32_t fMidiDataSize; //size of midi data in bytes - uint32_t fNMidiPckt; //number of midi packets of the cycle + uint32_t fNumPacket; //number of data packets of the cycle uint32_t fPacketSize; //packet size in bytes uint32_t fCycle; //process cycle counter uint32_t fSubCycle; //midi/audio subcycle counter uint32_t fIsLastPckt; //is it the last packet of a given cycle ('y' or 'n') - char fASyncWrongCycle; //is the current async cycle wrong (slave's side; 'y' or 'n') - char fFree[26]; //unused }; //net timebase master @@ -199,8 +195,8 @@ namespace Jack int32_t fState; //current cycle state jack_position_t fPosition; //current cycle position }; - -//midi data *********************************************************************************** + + //midi data *********************************************************************************** /** \Brief Midi buffer and operations class @@ -226,6 +222,8 @@ namespace Jack char* fBuffer; char* fNetBuffer; JackMidiBuffer** fPortBuffer; + + size_t fCycleSize; // needed size in bytes ofr an entire cycle public: NetMidiBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ); @@ -234,6 +232,11 @@ namespace Jack void Reset(); size_t GetSize(); + // needed size in bytes for an entire cycle + size_t GetCycleSize(); + + int GetNumPackets(); + //utility void DisplayEvents(); @@ -262,14 +265,21 @@ namespace Jack virtual size_t GetSize() = 0; + // needed syze in bytes ofr an entire cycle + virtual size_t GetCycleSize() = 0; + + // cycle duration in sec + virtual float GetCycleDuration() = 0; + + virtual int GetNumPackets() = 0; + //jack<->buffer - virtual void RenderFromJackPorts (int subcycle ) = 0; - virtual void RenderToJackPorts ( int cycle, int subcycle) = 0; - virtual void FinishRenderToJackPorts (int cycle) = 0; + virtual int RenderFromJackPorts () = 0; + virtual int RenderToJackPorts () = 0; //network<->buffer - //int RenderFromNetwork ( int subcycle, size_t copy_size ) = 0; - //int RenderToNetwork ( int subcycle, size_t total_size ) = 0; + virtual int RenderFromNetwork ( int cycle, int subcycle, size_t copy_size ) = 0; + virtual int RenderToNetwork (int subcycle, size_t total_size ) = 0; virtual void SetBuffer ( int index, sample_t* buffer ) = 0; virtual sample_t* GetBuffer ( int index ) = 0; @@ -292,16 +302,39 @@ namespace Jack size_t fSubPeriodBytesSize; sample_t** fPortBuffer; int fNPorts; + size_t fCycleSize; // needed size in bytes for an entire cycle + float fCycleDuration; // in dec + + int fLastSubCycle; JackPortList(session_params_t* params, uint32_t nports) { fNPorts = nports; fPeriodSize = params->fPeriodSize; - fSubPeriodSize = params->fFramesPerPacket; + + if (params->fSendAudioChannels == 0 && params->fReturnAudioChannels == 0) { + fSubPeriodSize = params->fPeriodSize; + } else { + jack_nframes_t period = ( int ) powf ( 2.f, ( int ) ( log (float ((params->fMtu - sizeof(packet_header_t))) + / ( max ( params->fReturnAudioChannels, params->fSendAudioChannels ) * sizeof ( sample_t ) ) ) / log ( 2. ) ) ); + fSubPeriodSize = ( period > params->fPeriodSize ) ? params->fPeriodSize : period; + } + fSubPeriodBytesSize = fSubPeriodSize * sizeof ( sample_t ); + fPortBuffer = new sample_t* [fNPorts]; for ( int port_index = 0; port_index < fNPorts; port_index++ ) fPortBuffer[port_index] = NULL; + + fCycleDuration = float(fSubPeriodSize) / float(params->fSampleRate); + fCycleSize = params->fMtu * ( fPeriodSize / fSubPeriodBytesSize ); + + fLastSubCycle = -1; + } + + int GetNumPackets() + { + return fPeriodSize / fSubPeriodSize; } JackPortList() @@ -338,7 +371,19 @@ namespace Jack { return fNPorts * fSubPeriodBytesSize; } - + + // needed syze in bytes ofr an entire cycle + size_t GetCycleSize() + { + return fCycleSize; + } + + // cycle duration in sec + float GetCycleDuration() + { + return fCycleDuration; + } + #ifdef __BIG_ENDIAN__ static inline float SwapFloat(float f) @@ -357,40 +402,75 @@ namespace Jack return dat2.f; } - void RenderFromJackPorts (char* net_buffer, int subcycle ) + int RenderFromJackPorts () { - for ( int port_index = 0; port_index < fNPorts; port_index++ ) { - float* src = (float*)(fPortBuffer[port_index] + subcycle * fSubPeriodSize); - float* dst = (float*)(net_buffer + port_index * fSubPeriodBytesSize); - for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(float); sample++) { - dst[sample] = SwapFloat(src[sample]); - } - } + return fNPorts * fSubPeriodBytesSize; // in bytes } - void RenderToJackPorts (char* net_buffer, int subcycle) + int RenderToJackPorts () { - for ( int port_index = 0; port_index < fNPorts; port_index++ ) { + return fPeriodSize * sizeof(sample_t); // in bytes TODO + } + + //network<->buffer + int RenderFromNetwork (char* net_buffer, int cycle, int subcycle, size_t copy_size ) + { + for ( int port_index = 0; port_index < fNPorts; port_index++ ) { float* src = (float*)(net_buffer + port_index * fSubPeriodBytesSize); float* dst = (float*)(fPortBuffer[port_index] + subcycle * fSubPeriodSize); for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(float); sample++) { dst[sample] = SwapFloat(src[sample]); } - } + } + + return copy_size; + } + + int RenderToNetwork (char* net_buffer, int subcycle, size_t total_size ) + { + + for ( int port_index = 0; port_index < fNPorts; port_index++ ) { + float* src = (float*)(fPortBuffer[port_index] + subcycle * fSubPeriodSize); + float* dst = (float*)(net_buffer + port_index * fSubPeriodBytesSize); + for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(float); sample++) { + dst[sample] = SwapFloat(src[sample]); + } + } + + return fNPorts * fSubPeriodBytesSize; } #else - void RenderFromJackPorts (char* net_buffer, int subcycle ) + int RenderFromJackPorts () { - for ( int port_index = 0; port_index < fNPorts; port_index++ ) - memcpy ( net_buffer + port_index * fSubPeriodBytesSize, fPortBuffer[port_index] + subcycle * fSubPeriodSize, fSubPeriodBytesSize ); + return fNPorts * fSubPeriodBytesSize; // in bytes } - void RenderToJackPorts (char* net_buffer, int subcycle) + int RenderToJackPorts () + { + fLastSubCycle = -1; + return fPeriodSize * sizeof(sample_t); // in bytes; TODO + } + + //network<->buffer + int RenderFromNetwork (char* net_buffer, int cycle, int subcycle, size_t copy_size ) { for ( int port_index = 0; port_index < fNPorts; port_index++ ) memcpy ( fPortBuffer[port_index] + subcycle * fSubPeriodSize, net_buffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize ); + if (subcycle != fLastSubCycle + 1) { + jack_error("Packet(s) missing from... %d %d", fLastSubCycle, subcycle); + } + fLastSubCycle = subcycle; + return copy_size; + } + + int RenderToNetwork (char* net_buffer,int subcycle, size_t total_size ) + { + for ( int port_index = 0; port_index < fNPorts; port_index++ ) + memcpy ( net_buffer + port_index * fSubPeriodBytesSize, fPortBuffer[port_index] + subcycle * fSubPeriodSize, fSubPeriodBytesSize ); + + return fNPorts * fSubPeriodBytesSize; } #endif @@ -419,7 +499,15 @@ namespace Jack { fNPorts = nports; fPeriodSize = params->fPeriodSize; - fSubPeriodSize = params->fFramesPerPacket; + + if (params->fSendAudioChannels == 0 && params->fReturnAudioChannels == 0) { + fSubPeriodSize = params->fPeriodSize; + } else { + jack_nframes_t period = ( int ) powf ( 2.f, ( int ) ( log (float ((params->fMtu - sizeof(packet_header_t))) + / ( max ( params->fReturnAudioChannels, params->fSendAudioChannels ) * sizeof ( sample_t ) ) ) / log ( 2. ) ) ); + fSubPeriodSize = ( period > params->fPeriodSize ) ? params->fPeriodSize : period; + } + fSubPeriodBytesSize = fSubPeriodSize * sizeof ( sample_t ); fPortBuffer = new sample_t* [fNPorts]; for ( int port_index = 0; port_index < fNPorts; port_index++ ) @@ -439,18 +527,36 @@ namespace Jack ~NetSingleAudioBuffer(); size_t GetSize(); + + // needed size in bytes for an entire cycle + size_t GetCycleSize(); + + // cycle duration in sec + float GetCycleDuration() + { + return fPortBuffer.GetCycleDuration(); + } + + int GetNumPackets() + { + return fPortBuffer.GetNumPackets(); + } + //jack<->buffer - void RenderFromJackPorts (int subcycle ); - void RenderToJackPorts (int cycle, int subcycle); + int RenderFromJackPorts (); + int RenderToJackPorts (); void SetBuffer ( int index, sample_t* buffer ); sample_t* GetBuffer ( int index ); - - void FinishRenderToJackPorts (int cycle) {} + + //network<->buffer + int RenderFromNetwork ( int cycle, int subcycle, size_t copy_size ); + int RenderToNetwork (int subcycle, size_t total_size ); }; #define AUDIO_BUFFER_SIZE 8 + /* class SERVER_EXPORT NetBufferedAudioBuffer : public NetAudioBuffer { @@ -465,14 +571,36 @@ namespace Jack ~NetBufferedAudioBuffer(); size_t GetSize(); + // needed syze in bytes ofr an entire cycle + size_t GetCycleSize(); + + // cycle duration in sec + float GetCycleDuration() + { + return fPortBuffer[0].GetCycleDuration(); + } + //jack<->buffer - void RenderFromJackPorts (int subcycle ); - void RenderToJackPorts ( int cycle, int subcycle); - void FinishRenderToJackPorts (int cycle); + int RenderFromJackPorts (int subcycle ); + int RenderToJackPorts ( int cycle, int subcycle); + //void FinishRenderToJackPorts (int cycle); + + //network<->buffer + int RenderFromNetwork ( int subcycle, size_t copy_size ) + { + // TODO + return 0; + } + int RenderToNetwork ( int subcycle, size_t total_size ) + { + // TODO + return 0; + } void SetBuffer ( int index, sample_t* buffer ); sample_t* GetBuffer ( int index ); }; + */ //utility ************************************************************************************* diff --git a/macosx/iphone/main_slave.mm b/macosx/iphone/main_slave.mm index b3435fec..8e400563 100644 --- a/macosx/iphone/main_slave.mm +++ b/macosx/iphone/main_slave.mm @@ -33,7 +33,7 @@ static int net_process(jack_nframes_t buffer_size, void* data) { - //jack_adapter_pull_and_push(adapter, audio_output_buffer, audio_input_buffer, buffer_size); + jack_adapter_pull_and_push(adapter, audio_output_buffer, audio_input_buffer, buffer_size); // Process input, produce output if (audio_input == audio_output) { @@ -47,7 +47,7 @@ static int net_process(jack_nframes_t buffer_size, static void SlaveAudioCallback(int frames, float** inputs, float** outputs, void* arg) { - //jack_adapter_push_and_pull(adapter, inputs, outputs, frames); + jack_adapter_push_and_pull(adapter, inputs, outputs, frames); } //http://www.securityfocus.com/infocus/1884 @@ -62,8 +62,8 @@ int main(int argc, char *argv[]) { jack_slave_t request = { NUM_INPUT, NUM_OUTPUT, 0, 0, WIFI_MTU, -1, JackSlowMode }; jack_master_t result; - //if ((net = jack_net_slave_open("169.254.121.189", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { - if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { + if ((net = jack_net_slave_open("169.254.46.132", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { + //if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { return -1; } @@ -77,6 +77,7 @@ int main(int argc, char *argv[]) { return -1; } + TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT); jack_set_net_slave_process_callback(net, net_process, NULL); From 5b8e976b0ab5347c2b6a2ecb56bba5e98a661e78 Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 9 Mar 2010 19:10:15 +0000 Subject: [PATCH 040/472] Use of CELT codec. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3949 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetInterface.cpp | 63 ++-- common/JackNetManager.cpp | 3 - common/JackNetTool.cpp | 287 +++++++++++++++++- common/JackNetTool.h | 116 +++++-- macosx/Jackdmp.xcodeproj/project.pbxproj | 2 + .../iPhoneNet.xcodeproj/project.pbxproj | 9 +- macosx/iphone/main_slave.mm | 8 +- 7 files changed, 413 insertions(+), 75 deletions(-) diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 38584b04..554700c6 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -243,9 +243,19 @@ namespace Jack assert ( fNetMidiCaptureBuffer ); assert ( fNetMidiPlaybackBuffer ); + try { //audio net buffers - fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); - fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); + #ifdef CELT + fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); + fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); + #else + fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); + fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); + #endif + } catch (exception&) { + jack_error("NetAudioBuffer allocation error..."); + return false; + } //fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); @@ -500,7 +510,7 @@ namespace Jack switch ( rx_head->fDataType ) { case 'm': //midi - rx_bytes = Recv ( rx_head->fPacketSize, 0 ); + rx_bytes = Recv(rx_head->fPacketSize, 0); fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; fNetMidiPlaybackBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE); @@ -510,13 +520,13 @@ namespace Jack break; case 'a': //audio - rx_bytes = Recv ( rx_head->fPacketSize, 0 ); + rx_bytes = Recv(rx_head->fPacketSize, 0); fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fSubCycle = rx_head->fSubCycle; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; - fNetAudioPlaybackBuffer->RenderFromNetwork (rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE); - // Last audio packet is received, so finish rendering... - if (fRxHeader.fIsLastPckt) + fNetAudioPlaybackBuffer->RenderFromNetwork (rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE); + // Last audio packet is received, so finish rendering... + if (fRxHeader.fIsLastPckt) fNetAudioPlaybackBuffer->RenderToJackPorts(); break; @@ -647,9 +657,7 @@ namespace Jack //utility session_params_t host_params; int rx_bytes = 0; - - jack_log ( "sizeof (session_params_t) %d", sizeof (session_params_t) ); - + //socket if ( fSocket.NewSocket() == SOCKET_ERROR ) { jack_error ( "Fatal error : network unreachable - %s", StrError ( NET_ERROR_CODE ) ); @@ -738,12 +746,24 @@ namespace Jack assert ( fNetMidiPlaybackBuffer ); //audio net buffers - fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); - fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); - - //fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); - //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); - + //fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); + //fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); + + try { + #ifdef CELT + fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); + fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); + #else + fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); + fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); + //fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); + //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); + #endif + } catch (exception&) { + jack_error("NetAudioBuffer allocation error..."); + return false; + } + assert ( fNetAudioCaptureBuffer ); assert ( fNetAudioPlaybackBuffer ); @@ -830,7 +850,6 @@ namespace Jack int JackNetSlaveInterface::DataRecv() { int rx_bytes = 0; - //int last_cycle = 0; uint recvd_midi_pckt = 0; uint recvd_audio_pckt = 0; @@ -850,24 +869,24 @@ namespace Jack switch ( rx_head->fDataType ) { case 'm': //midi - rx_bytes = Recv ( rx_head->fPacketSize, 0 ); + rx_bytes = Recv(rx_head->fPacketSize, 0); fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; fNetMidiCaptureBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE); // Last midi packet is received, so finish rendering... - if ( ++recvd_midi_pckt == rx_head->fNumPacket ) + if (++recvd_midi_pckt == rx_head->fNumPacket) fNetMidiCaptureBuffer->RenderToJackPorts(); break; case 'a': //audio - rx_bytes = Recv ( rx_head->fPacketSize, 0 ); + rx_bytes = Recv(rx_head->fPacketSize, 0); fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fSubCycle = rx_head->fSubCycle; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; fNetAudioCaptureBuffer->RenderFromNetwork (rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE); - if (fRxHeader.fIsLastPckt) { + // Last audio packet is received, so finish rendering... + if (fRxHeader.fIsLastPckt) fNetAudioCaptureBuffer->RenderToJackPorts(); - } break; case 's': //sync diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index fb6d855b..b41559c4 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -201,7 +201,6 @@ namespace Jack } } - //midi for ( i = 0; i < fParams.fSendMidiChannels; i++ ) { @@ -602,8 +601,6 @@ namespace Jack if ( fSocket.SetTimeOut ( 2000000 ) == SOCKET_ERROR ) jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) ); - jack_log ( "sizeof (session_params_t) %d", sizeof (session_params_t) ); - //main loop, wait for data, deal with it and wait again do { diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index 862216a3..a84a5e9b 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -19,6 +19,72 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackNetTool.h" +#ifdef __APPLE__ + +#include + +class HardwareClock +{ +public: + HardwareClock(); + + void Reset(); + void Update(); + + float GetDeltaTime() const; + double GetTime() const; + +private: + double m_clockToSeconds; + + uint64_t m_startAbsTime; + uint64_t m_lastAbsTime; + + double m_time; + float m_deltaTime; +}; + +HardwareClock::HardwareClock() +{ + mach_timebase_info_data_t info; + mach_timebase_info(&info); + m_clockToSeconds = (double)info.numer/info.denom/1000000000.0; + + Reset(); +} + +void HardwareClock::Reset() +{ + m_startAbsTime = mach_absolute_time(); + m_lastAbsTime = m_startAbsTime; + + m_time = m_startAbsTime*m_clockToSeconds; + m_deltaTime = 1.0f/60.0f; +} + +void HardwareClock::Update() +{ + const uint64_t currentTime = mach_absolute_time(); + const uint64_t dt = currentTime - m_lastAbsTime; + + m_time = currentTime*m_clockToSeconds; + m_deltaTime = (double)dt*m_clockToSeconds; + + m_lastAbsTime = currentTime; +} + +float HardwareClock::GetDeltaTime() const +{ + return m_deltaTime; +} + +double HardwareClock::GetTime() const +{ + return m_time; +} + +#endif + using namespace std; namespace Jack @@ -46,11 +112,6 @@ namespace Jack delete[] fPortBuffer; } - size_t NetMidiBuffer::GetSize() - { - return fMaxBufsize; - } - size_t NetMidiBuffer::GetCycleSize() { return fCycleSize; @@ -153,11 +214,6 @@ namespace Jack NetSingleAudioBuffer::~NetSingleAudioBuffer() {} - size_t NetSingleAudioBuffer::GetSize() - { - return fPortBuffer.GetSize(); - } - size_t NetSingleAudioBuffer::GetCycleSize() { return fPortBuffer.GetCycleSize(); @@ -193,6 +249,212 @@ namespace Jack { return fPortBuffer.RenderToNetwork(fNetBuffer, subcycle, total_size); } + + // Celt audio buffer ********************************************************************************* + +#ifdef CELT + + #define KPS 32 + #define KPS_DIV 8 + + NetCeltAudioBuffer::NetCeltAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) + : fNetBuffer(net_buffer) + { + int res1, res2; + jack_nframes_t period; + + fNPorts = nports; + fPeriodSize = params->fPeriodSize; + + fCeltMode = new CELTMode *[fNPorts]; + fCeltEncoder = new CELTEncoder *[fNPorts]; + fCeltDecoder = new CELTDecoder *[fNPorts]; + + memset(fCeltMode, 0, fNPorts * sizeof(CELTMode*)); + memset(fCeltEncoder, 0, fNPorts * sizeof(CELTEncoder*)); + memset(fCeltDecoder, 0, fNPorts * sizeof(CELTDecoder*)); + + int error = CELT_OK; + + for (int i = 0; i < fNPorts; i++) { + fCeltMode[i] = celt_mode_create(params->fSampleRate, params->fPeriodSize, &error); + if (error != CELT_OK) + goto error; + + fCeltEncoder[i] = celt_encoder_create(fCeltMode[i], 1, &error); + if (error != CELT_OK) + goto error; + celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(0)); + + fCeltDecoder[i] = celt_decoder_create(fCeltMode[i], 1, &error); + if (error != CELT_OK) + goto error; + celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(0)); + } + + fPortBuffer = new sample_t* [fNPorts]; + for (int port_index = 0; port_index < fNPorts; port_index++) + fPortBuffer[port_index] = NULL; + + /* + celt_int32 lookahead; + celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); + */ + + //fCompressedSizeByte = (KPS * params->fPeriodSize * 1024 / params->fSampleRate / 8)&(~1); + fCompressedSizeByte = (params->fPeriodSize * sizeof(sample_t)) / KPS_DIV; // TODO + + fCompressedBuffer = new unsigned char* [fNPorts]; + for (int port_index = 0; port_index < fNPorts; port_index++) + fCompressedBuffer[port_index] = new unsigned char[fCompressedSizeByte]; + + jack_log("fCompressedSizeByte %d", fCompressedSizeByte); + + res1 = (fNPorts * fCompressedSizeByte) % (params->fMtu - sizeof(packet_header_t)); + res2 = (fNPorts * fCompressedSizeByte) / (params->fMtu - sizeof(packet_header_t)); + + jack_log("res1 = %d res2 = %d", res1, res2); + + fNumPackets = (res1) ? (res2 + 1) : res2; + + fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets; + fLastSubPeriodBytesSize = fSubPeriodBytesSize + (fCompressedSizeByte - (fSubPeriodBytesSize * fNumPackets)); + + jack_log("fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize); + + fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate); + fCycleSize = params->fMtu * fNumPackets; + + fLastSubCycle = -1; + return; + + error: + + FreeCelt(); + throw std::bad_alloc(); + } + + NetCeltAudioBuffer::~NetCeltAudioBuffer() + { + FreeCelt(); + + for (int port_index = 0; port_index < fNPorts; port_index++) + delete [] fCompressedBuffer[port_index]; + + delete [] fCompressedBuffer; + delete [] fPortBuffer; + } + + void NetCeltAudioBuffer::FreeCelt() + { + for (int i = 0; i < fNPorts; i++) { + if (fCeltEncoder[i]) + celt_encoder_destroy(fCeltEncoder[i]); + if (fCeltDecoder[i]) + celt_decoder_destroy(fCeltDecoder[i]); + if (fCeltMode[i]) + celt_mode_destroy(fCeltMode[i]); + } + + delete [] fCeltMode; + delete [] fCeltEncoder; + delete [] fCeltDecoder; + } + + size_t NetCeltAudioBuffer::GetCycleSize() + { + return fCycleSize; + } + + float NetCeltAudioBuffer::GetCycleDuration() + { + return fCycleDuration; + } + + int NetCeltAudioBuffer::GetNumPackets() + { + return fNumPackets; + } + + void NetCeltAudioBuffer::SetBuffer(int index, sample_t* buffer) + { + fPortBuffer[index] = buffer; + } + + sample_t* NetCeltAudioBuffer::GetBuffer(int index) + { + return fPortBuffer[index]; + } + + int NetCeltAudioBuffer::RenderFromJackPorts() + { + float floatbuf[fPeriodSize]; + + for (int port_index = 0; port_index < fNPorts; port_index++) { + memcpy(floatbuf, fPortBuffer[port_index], fPeriodSize * sizeof(float)); + int res = celt_encode_float(fCeltEncoder[port_index], floatbuf, NULL, fCompressedBuffer[port_index], fCompressedSizeByte); + if (res != fCompressedSizeByte) { + jack_error("celt_encode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res); + } + } + + return fNPorts * fCompressedSizeByte; // in bytes + } + + int NetCeltAudioBuffer::RenderToJackPorts() + { + for (int port_index = 0; port_index < fNPorts; port_index++) { + int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index]); + if (res != CELT_OK) { + jack_error("celt_decode_float error res = %d", fCompressedSizeByte, res); + } + } + + fLastSubCycle = -1; + //return fPeriodSize * sizeof(sample_t); // in bytes; TODO + return 0; + } + + HardwareClock clock; + //network<->buffer + int NetCeltAudioBuffer::RenderFromNetwork(int cycle, int subcycle, size_t copy_size) + { + //clock.Update(); + + if (subcycle == fNumPackets - 1) { + for (int port_index = 0; port_index < fNPorts; port_index++) + memcpy(fCompressedBuffer[port_index] + subcycle * fSubPeriodBytesSize, fNetBuffer + port_index * fSubPeriodBytesSize, fLastSubPeriodBytesSize); + } else { + for (int port_index = 0; port_index < fNPorts; port_index++) + memcpy(fCompressedBuffer[port_index] + subcycle * fSubPeriodBytesSize, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize); + } + + if (subcycle != fLastSubCycle + 1) + jack_error("Packet(s) missing from... %d %d", fLastSubCycle, subcycle); + + fLastSubCycle = subcycle; + + //clock.Update(); + //const float dt = clock.GetDeltaTime(); + //printf("Delta: %f s\n", dt); + + return copy_size; + } + + int NetCeltAudioBuffer::RenderToNetwork(int subcycle, size_t total_size) + { + if (subcycle == fNumPackets - 1) { + for (int port_index = 0; port_index < fNPorts; port_index++) + memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fCompressedBuffer[port_index] + subcycle * fSubPeriodBytesSize, fLastSubPeriodBytesSize); + } else { + for (int port_index = 0; port_index < fNPorts; port_index++) + memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fCompressedBuffer[port_index] + subcycle * fSubPeriodBytesSize, fSubPeriodBytesSize); + } + + return fNPorts * fSubPeriodBytesSize; + } + +#endif // Buffered @@ -216,11 +478,6 @@ namespace Jack delete [] fJackPortBuffer; } - size_t NetBufferedAudioBuffer::GetSize() - { - return fPortBuffer[0].GetSize(); - } - size_t NetBufferedAudioBuffer::GetCycleSize() { return fPortBuffer[0].GetCycleSize(); diff --git a/common/JackNetTool.h b/common/JackNetTool.h index 7c79f9ec..dee280a8 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -216,6 +216,7 @@ namespace Jack class SERVER_EXPORT NetMidiBuffer { private: + int fNPorts; size_t fMaxBufsize; int fMaxPcktSize; @@ -226,11 +227,11 @@ namespace Jack size_t fCycleSize; // needed size in bytes ofr an entire cycle public: + NetMidiBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ); ~NetMidiBuffer(); void Reset(); - size_t GetSize(); // needed size in bytes for an entire cycle size_t GetCycleSize(); @@ -258,13 +259,12 @@ namespace Jack { public: + NetAudioBuffer () {} - ~NetAudioBuffer() + virtual ~NetAudioBuffer() {} - virtual size_t GetSize() = 0; - // needed syze in bytes ofr an entire cycle virtual size_t GetCycleSize() = 0; @@ -303,7 +303,7 @@ namespace Jack sample_t** fPortBuffer; int fNPorts; size_t fCycleSize; // needed size in bytes for an entire cycle - float fCycleDuration; // in dec + float fCycleDuration; // in sec int fLastSubCycle; @@ -312,22 +312,22 @@ namespace Jack fNPorts = nports; fPeriodSize = params->fPeriodSize; - if (params->fSendAudioChannels == 0 && params->fReturnAudioChannels == 0) { + if (params->fSendAudioChannels == 0 && params->fReturnAudioChannels == 0) { fSubPeriodSize = params->fPeriodSize; } else { - jack_nframes_t period = ( int ) powf ( 2.f, ( int ) ( log (float ((params->fMtu - sizeof(packet_header_t))) - / ( max ( params->fReturnAudioChannels, params->fSendAudioChannels ) * sizeof ( sample_t ) ) ) / log ( 2. ) ) ); - fSubPeriodSize = ( period > params->fPeriodSize ) ? params->fPeriodSize : period; + jack_nframes_t period = (int) powf(2.f, (int) (log (float ((params->fMtu - sizeof(packet_header_t))) + / (max(params->fReturnAudioChannels, params->fSendAudioChannels) * sizeof(sample_t))) / log(2.))); + fSubPeriodSize = (period > params->fPeriodSize) ? params->fPeriodSize : period; } - fSubPeriodBytesSize = fSubPeriodSize * sizeof ( sample_t ); + fSubPeriodBytesSize = fSubPeriodSize * sizeof(sample_t); fPortBuffer = new sample_t* [fNPorts]; - for ( int port_index = 0; port_index < fNPorts; port_index++ ) + for (int port_index = 0; port_index < fNPorts; port_index++) fPortBuffer[port_index] = NULL; fCycleDuration = float(fSubPeriodSize) / float(params->fSampleRate); - fCycleSize = params->fMtu * ( fPeriodSize / fSubPeriodBytesSize ); + fCycleSize = params->fMtu * (fPeriodSize / fSubPeriodSize); fLastSubCycle = -1; } @@ -363,15 +363,10 @@ namespace Jack void Copy(sample_t** buffers) { - for ( int port_index = 0; port_index < fNPorts; port_index++ ) + for (int port_index = 0; port_index < fNPorts; port_index++) memcpy(buffers[port_index], fPortBuffer[port_index], fPeriodSize * sizeof(float)); } - size_t GetSize() - { - return fNPorts * fSubPeriodBytesSize; - } - // needed syze in bytes ofr an entire cycle size_t GetCycleSize() { @@ -413,7 +408,7 @@ namespace Jack } //network<->buffer - int RenderFromNetwork (char* net_buffer, int cycle, int subcycle, size_t copy_size ) + int RenderFromNetwork(char* net_buffer, int cycle, int subcycle, size_t copy_size) { for ( int port_index = 0; port_index < fNPorts; port_index++ ) { float* src = (float*)(net_buffer + port_index * fSubPeriodBytesSize); @@ -426,7 +421,7 @@ namespace Jack return copy_size; } - int RenderToNetwork (char* net_buffer, int subcycle, size_t total_size ) + int RenderToNetwork(char* net_buffer, int subcycle, size_t total_size) { for ( int port_index = 0; port_index < fNPorts; port_index++ ) { @@ -454,10 +449,10 @@ namespace Jack } //network<->buffer - int RenderFromNetwork (char* net_buffer, int cycle, int subcycle, size_t copy_size ) + int RenderFromNetwork(char* net_buffer, int cycle, int subcycle, size_t copy_size) { - for ( int port_index = 0; port_index < fNPorts; port_index++ ) - memcpy ( fPortBuffer[port_index] + subcycle * fSubPeriodSize, net_buffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize ); + for (int port_index = 0; port_index < fNPorts; port_index++) + memcpy(fPortBuffer[port_index] + subcycle * fSubPeriodSize, net_buffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize); if (subcycle != fLastSubCycle + 1) { jack_error("Packet(s) missing from... %d %d", fLastSubCycle, subcycle); } @@ -465,10 +460,10 @@ namespace Jack return copy_size; } - int RenderToNetwork (char* net_buffer,int subcycle, size_t total_size ) + int RenderToNetwork(char* net_buffer,int subcycle, size_t total_size) { - for ( int port_index = 0; port_index < fNPorts; port_index++ ) - memcpy ( net_buffer + port_index * fSubPeriodBytesSize, fPortBuffer[port_index] + subcycle * fSubPeriodSize, fSubPeriodBytesSize ); + for (int port_index = 0; port_index < fNPorts; port_index++) + memcpy(net_buffer + port_index * fSubPeriodBytesSize, fPortBuffer[port_index] + subcycle * fSubPeriodSize, fSubPeriodBytesSize); return fNPorts * fSubPeriodBytesSize; } @@ -490,7 +485,7 @@ namespace Jack ~JackPortListAllocate() { - for ( int port_index = 0; port_index < fNPorts; port_index++ ) + for (int port_index = 0; port_index < fNPorts; port_index++) delete [] fPortBuffer[port_index]; delete [] fPortBuffer; } @@ -519,15 +514,15 @@ namespace Jack class SERVER_EXPORT NetSingleAudioBuffer : public NetAudioBuffer { private: + JackPortList fPortBuffer; char* fNetBuffer; public: + NetSingleAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ); ~NetSingleAudioBuffer(); - - size_t GetSize(); - + // needed size in bytes for an entire cycle size_t GetCycleSize(); @@ -554,6 +549,66 @@ namespace Jack int RenderToNetwork (int subcycle, size_t total_size ); }; +#define CELT 1 + +#ifdef CELT + +#include + + class SERVER_EXPORT NetCeltAudioBuffer : public NetAudioBuffer + { + private: + + CELTMode ** fCeltMode; + CELTEncoder ** fCeltEncoder; + CELTDecoder ** fCeltDecoder; + + int fCompressedSizeByte; + jack_nframes_t fPeriodSize; + int fNumPackets; + float fCycleDuration; // in sec + size_t fCycleSize; // needed size in bytes for an entire cycle + + size_t fSubPeriodBytesSize; + size_t fLastSubPeriodBytesSize; + + sample_t** fPortBuffer; + char* fNetBuffer; + unsigned char ** fCompressedBuffer; + + int fNPorts; + + int fLastSubCycle; + + void FreeCelt(); + + public: + + NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer); + ~NetCeltAudioBuffer(); + + // needed size in bytes for an entire cycle + size_t GetCycleSize(); + + // cycle duration in sec + float GetCycleDuration(); + + int GetNumPackets(); + + void SetBuffer(int index, sample_t* buffer); + sample_t* GetBuffer(int index); + + //jack<->buffer + int RenderFromJackPorts(); + int RenderToJackPorts(); + + //network<->buffer + int RenderFromNetwork(int cycle, int subcycle, size_t copy_size); + int RenderToNetwork(int subcycle, size_t total_size); + }; + +#endif + #define AUDIO_BUFFER_SIZE 8 /* @@ -570,7 +625,6 @@ namespace Jack NetBufferedAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ); ~NetBufferedAudioBuffer(); - size_t GetSize(); // needed syze in bytes ofr an entire cycle size_t GetCycleSize(); diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index 17395706..d2f997d6 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -8801,6 +8801,7 @@ ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_LDFLAGS = ( + libcelt.a, "-framework", Carbon, "-framework", @@ -8869,6 +8870,7 @@ OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DLIB_DIR=\\\"lib\\\""; OTHER_LDFLAGS = ( + libcelt.a, "-framework", Carbon, "-framework", diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj index 24592449..e919d7e8 100755 --- a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -780,6 +780,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( + /usr/local/include, ../../macosx/coreaudio, ../../macosx, ../../posix, @@ -791,7 +792,7 @@ "$(inherited)", "\"$(SRCROOT)/build/Debug-iphonesimulator\"", ); - OTHER_LDFLAGS = ""; + OTHER_LDFLAGS = libcelt.a; PRODUCT_NAME = iPhoneNetSlave; SDKROOT = iphoneos3.1.3; }; @@ -802,9 +803,13 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; + GCC_OPTIMIZATION_LEVEL = 3; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + GCC_THUMB_SUPPORT = NO; HEADER_SEARCH_PATHS = ( + ., + /usr/local/include, ../../macosx/coreaudio, ../../common/jack, ../../common, @@ -816,7 +821,9 @@ "$(inherited)", "\"$(SRCROOT)/build/Debug-iphonesimulator\"", ); + OTHER_LDFLAGS = libcelt.a; PRODUCT_NAME = NetJackSlave; + SDKROOT = iphoneos3.1.3; }; name = Release; }; diff --git a/macosx/iphone/main_slave.mm b/macosx/iphone/main_slave.mm index 8e400563..225cacb7 100644 --- a/macosx/iphone/main_slave.mm +++ b/macosx/iphone/main_slave.mm @@ -11,8 +11,8 @@ #include "TiPhoneCoreAudioRenderer.h" -#define NUM_INPUT 1 -#define NUM_OUTPUT 1 +#define NUM_INPUT 2 +#define NUM_OUTPUT 2 jack_net_slave_t* net; jack_adapter_t* adapter; @@ -62,7 +62,7 @@ int main(int argc, char *argv[]) { jack_slave_t request = { NUM_INPUT, NUM_OUTPUT, 0, 0, WIFI_MTU, -1, JackSlowMode }; jack_master_t result; - if ((net = jack_net_slave_open("169.254.46.132", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { + if ((net = jack_net_slave_open("169.254.126.231", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { //if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { return -1; } @@ -85,6 +85,7 @@ int main(int argc, char *argv[]) { return -1; } + if (audio_device.Open(result.buffer_size, result.sample_rate) < 0) { return -1; } @@ -95,6 +96,7 @@ int main(int argc, char *argv[]) { return -1; } + int retVal = UIApplicationMain(argc, argv, nil, nil); [pool release]; From f4fa01f3ab8d9ca11c4f684ba61f308247ba7403 Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 10 Mar 2010 13:08:14 +0000 Subject: [PATCH 041/472] More cleanup. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3950 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetAPI.cpp | 2 +- common/JackNetInterface.cpp | 71 +++++++++---------- common/JackNetInterface.h | 10 ++- common/JackNetTool.cpp | 7 +- .../iPhoneNet.xcodeproj/project.pbxproj | 8 +-- macosx/iphone/main_slave.mm | 12 +--- 6 files changed, 52 insertions(+), 58 deletions(-) diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 90ce515c..699a48bb 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -751,7 +751,7 @@ struct JackNetAdapter : public JackAudioAdapterInterface { fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; - if (fAdaptative) { + if (fAdaptative) { AdaptRingBufferSize(); jack_info("Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize); } else { diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 554700c6..0a947203 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -39,33 +39,24 @@ namespace Jack JackNetInterface::JackNetInterface() : fSocket() { - fTxBuffer = NULL; - fRxBuffer = NULL; - fNetAudioCaptureBuffer = NULL; - fNetAudioPlaybackBuffer = NULL; - fNetMidiCaptureBuffer = NULL; - fNetMidiPlaybackBuffer = NULL; - memset(&fSendTransportData, 0, sizeof(net_transport_data_t)); - memset(&fReturnTransportData, 0, sizeof(net_transport_data_t)); + Initialize(); } JackNetInterface::JackNetInterface ( const char* multicast_ip, int port ) : fSocket ( multicast_ip, port ) { strcpy(fMulticastIP, multicast_ip); - fTxBuffer = NULL; - fRxBuffer = NULL; - fNetAudioCaptureBuffer = NULL; - fNetAudioPlaybackBuffer = NULL; - fNetMidiCaptureBuffer = NULL; - fNetMidiPlaybackBuffer = NULL; - memset(&fSendTransportData, 0, sizeof(net_transport_data_t)); - memset(&fReturnTransportData, 0, sizeof(net_transport_data_t)); + Initialize(); } JackNetInterface::JackNetInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip ) : fSocket ( socket ) { fParams = params; strcpy(fMulticastIP, multicast_ip); + Initialize(); + } + + void JackNetInterface::Initialize() + { fTxBuffer = NULL; fRxBuffer = NULL; fNetAudioCaptureBuffer = NULL; @@ -75,7 +66,7 @@ namespace Jack memset(&fSendTransportData, 0, sizeof(net_transport_data_t)); memset(&fReturnTransportData, 0, sizeof(net_transport_data_t)); } - + JackNetInterface::~JackNetInterface() { jack_log ( "JackNetInterface::~JackNetInterface" ); @@ -95,19 +86,16 @@ namespace Jack float audio_size = (fNetAudioCaptureBuffer) ? fNetAudioCaptureBuffer->GetCycleSize() : (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleSize() : 0; - jack_log ("audio_size %f", audio_size); //midi float midi_size = (fNetMidiCaptureBuffer) ? fNetMidiCaptureBuffer->GetCycleSize() : (fNetMidiPlaybackBuffer) ? fNetMidiPlaybackBuffer->GetCycleSize() : 0; - jack_log ("midi_size %f", midi_size); //bufsize = sync + audio + midi int bufsize = MAX_LATENCY * (fParams.fMtu + (int)audio_size + (int) midi_size); - jack_log("SetNetBufferSize bufsize = %d", bufsize); //tx buffer @@ -190,8 +178,8 @@ namespace Jack if ( fSocket.Send ( &net_params, sizeof ( session_params_t ), 0 ) == SOCKET_ERROR ) jack_error ( "Error in send : ", StrError ( NET_ERROR_CODE ) ); - memset(&net_params, 0, sizeof ( session_params_t )); - if ( ( ( rx_bytes = fSocket.Recv ( &net_params, sizeof ( session_params_t ), 0 ) ) == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) ) + memset(&net_params, 0, sizeof (session_params_t)); + if (((rx_bytes = fSocket.Recv(&net_params, sizeof(session_params_t), 0)) == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) { jack_error ( "Problem with network." ); return false; @@ -260,18 +248,18 @@ namespace Jack //fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); - assert ( fNetAudioCaptureBuffer ); - assert ( fNetAudioPlaybackBuffer ); + assert(fNetAudioCaptureBuffer); + assert(fNetAudioPlaybackBuffer); //set the new timeout for the socket - if ( SetRxTimeout() == SOCKET_ERROR ) { - jack_error ( "Can't set rx timeout : %s", StrError ( NET_ERROR_CODE ) ); + if (SetRxTimeout() == SOCKET_ERROR) { + jack_error("Can't set rx timeout : %s", StrError(NET_ERROR_CODE)); goto error; } //set the new rx buffer size - if ( SetNetBufferSize() == SOCKET_ERROR ) { - jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) ); + if (SetNetBufferSize() == SOCKET_ERROR) { + jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE)); goto error; } @@ -310,7 +298,7 @@ namespace Jack mcast_socket.Close(); } - int JackNetMasterInterface::Recv ( size_t size, int flags ) + int JackNetMasterInterface::Recv(size_t size, int flags) { int rx_bytes; @@ -337,7 +325,7 @@ namespace Jack return rx_bytes; } - int JackNetMasterInterface::Send ( size_t size, int flags ) + int JackNetMasterInterface::Send(size_t size, int flags) { int tx_bytes; packet_header_t* header = reinterpret_cast(fTxBuffer); @@ -373,7 +361,7 @@ namespace Jack fTxHeader.fCycle++; fTxHeader.fSubCycle = 0; fTxHeader.fDataType = 's'; - fTxHeader.fIsLastPckt = ( fParams.fSendMidiChannels == 0 && fParams.fSendAudioChannels == 0) ? 1 : 0; + fTxHeader.fIsLastPckt = (fParams.fSendMidiChannels == 0 && fParams.fSendAudioChannels == 0) ? 1 : 0; fTxHeader.fPacketSize = HEADER_SIZE; memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); @@ -386,7 +374,7 @@ namespace Jack uint data_size; //midi - if ( fParams.fSendMidiChannels > 0) + if (fParams.fSendMidiChannels > 0) { //set global header fields and get the number of midi packets fTxHeader.fDataType = 'm'; @@ -405,7 +393,7 @@ namespace Jack } //audio - if ( fParams.fSendAudioChannels > 0) + if (fParams.fSendAudioChannels > 0) { fTxHeader.fDataType = 'a'; data_size = fNetAudioCaptureBuffer->RenderFromJackPorts(); @@ -424,7 +412,7 @@ namespace Jack return 0; } - + int JackNetMasterInterface::SyncRecv() { packet_header_t* rx_head = reinterpret_cast ( fRxBuffer ); @@ -443,15 +431,18 @@ namespace Jack // - if the network is two fast, just wait the next cycle, this mode allows a shorter cycle duration for the master // - this mode will skip the two first cycles, thus it lets time for data to be processed and queued on the socket rx buffer //the slow mode is the safest mode because it wait twice the bandwidth relative time (send/return + process) + if (fCycleOffset < CYCLE_OFFSET_SLOW) { return 0; } else { rx_bytes = Recv ( rx_head->fPacketSize, 0 ); } - if (fCycleOffset > CYCLE_OFFSET_SLOW) { + //rx_bytes = Recv ( rx_head->fPacketSize, 0 ); + + if (fCycleOffset != fLastfCycleOffset) jack_info("Warning : '%s' runs in slow network mode, but data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); - } + fLastfCycleOffset = fCycleOffset; break; case 'n' : @@ -533,6 +524,7 @@ namespace Jack case 's': //sync jack_info("NetMaster : overloaded, skipping receive from '%s'", fParams.fName); // TODO : finish midi and audio rendering ? + fNetAudioPlaybackBuffer->RenderToJackPorts(); return 0; } } @@ -783,9 +775,9 @@ namespace Jack return false; } - int JackNetSlaveInterface::Recv ( size_t size, int flags ) + int JackNetSlaveInterface::Recv(size_t size, int flags) { - int rx_bytes = fSocket.Recv ( fRxBuffer, size, flags ); + int rx_bytes = fSocket.Recv(fRxBuffer, size, flags); //handle errors if ( rx_bytes == SOCKET_ERROR ) { @@ -807,7 +799,7 @@ namespace Jack return rx_bytes; } - int JackNetSlaveInterface::Send ( size_t size, int flags ) + int JackNetSlaveInterface::Send(size_t size, int flags) { packet_header_t* header = reinterpret_cast(fTxBuffer); PacketHeaderHToN(header, header); @@ -892,6 +884,7 @@ namespace Jack case 's': //sync jack_info ( "NetSlave : overloaded, skipping receive." ); // TODO : finish midi and audio rendering ? + fNetAudioCaptureBuffer->RenderToJackPorts(); return 0; } } diff --git a/common/JackNetInterface.h b/common/JackNetInterface.h index d4214904..d7405a56 100644 --- a/common/JackNetInterface.h +++ b/common/JackNetInterface.h @@ -31,7 +31,12 @@ namespace Jack class SERVER_EXPORT JackNetInterface { + private: + + void Initialize(); + protected: + session_params_t fParams; JackNetSocket fSocket; char fMulticastIP[32]; @@ -96,6 +101,7 @@ namespace Jack protected: bool fRunning; int fCycleOffset; + int fLastfCycleOffset; bool Init(); int SetRxTimeout(); @@ -119,7 +125,7 @@ namespace Jack bool IsSynched(); public: - JackNetMasterInterface() : JackNetInterface(), fRunning(false), fCycleOffset(0) + JackNetMasterInterface() : JackNetInterface(), fRunning(false), fCycleOffset(0), fLastfCycleOffset(0) {} JackNetMasterInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip ) : JackNetInterface ( params, socket, multicast_ip ) @@ -205,7 +211,7 @@ namespace Jack #define CYCLE_OFFSET_FAST 0 #define CYCLE_OFFSET_NORMAL 1 -#define CYCLE_OFFSET_SLOW 3 +#define CYCLE_OFFSET_SLOW 30 #define MAX_LATENCY CYCLE_OFFSET_SLOW * 4 #endif diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index a84a5e9b..b691e2c1 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -284,12 +284,12 @@ namespace Jack fCeltEncoder[i] = celt_encoder_create(fCeltMode[i], 1, &error); if (error != CELT_OK) goto error; - celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(0)); + celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1)); fCeltDecoder[i] = celt_decoder_create(fCeltMode[i], 1, &error); if (error != CELT_OK) goto error; - celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(0)); + celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1)); } fPortBuffer = new sample_t* [fNPorts]; @@ -318,7 +318,8 @@ namespace Jack fNumPackets = (res1) ? (res2 + 1) : res2; fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets; - fLastSubPeriodBytesSize = fSubPeriodBytesSize + (fCompressedSizeByte - (fSubPeriodBytesSize * fNumPackets)); + //fLastSubPeriodBytesSize = fSubPeriodBytesSize + (fCompressedSizeByte - (fSubPeriodBytesSize * fNumPackets)); + fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets; jack_log("fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize); diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj index e919d7e8..07a76deb 100755 --- a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -153,7 +153,7 @@ /* Begin PBXFileReference section */ 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - 1D6058910D05DD3D006BFB54 /* NetJackSlave.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetJackSlave.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1D6058910D05DD3D006BFB54 /* NetJack.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetJack.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; @@ -290,7 +290,7 @@ 19C28FACFE9D520D11CA2CBB /* Products */ = { isa = PBXGroup; children = ( - 1D6058910D05DD3D006BFB54 /* NetJackSlave.app */, + 1D6058910D05DD3D006BFB54 /* NetJack.app */, 4BFF45120F4D59DB00106083 /* libjacknet.a */, 4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */, 4B0772380F54018C000DC657 /* iPhoneNetMaster.app */, @@ -404,7 +404,7 @@ ); name = iPhoneNetSlave; productName = iPhoneNet; - productReference = 1D6058910D05DD3D006BFB54 /* NetJackSlave.app */; + productReference = 1D6058910D05DD3D006BFB54 /* NetJack.app */; productType = "com.apple.product-type.application"; }; 4B07721F0F54018C000DC657 /* iPhoneNetMaster */ = { @@ -822,7 +822,7 @@ "\"$(SRCROOT)/build/Debug-iphonesimulator\"", ); OTHER_LDFLAGS = libcelt.a; - PRODUCT_NAME = NetJackSlave; + PRODUCT_NAME = NetJack; SDKROOT = iphoneos3.1.3; }; name = Release; diff --git a/macosx/iphone/main_slave.mm b/macosx/iphone/main_slave.mm index 225cacb7..054d9d4e 100644 --- a/macosx/iphone/main_slave.mm +++ b/macosx/iphone/main_slave.mm @@ -18,8 +18,7 @@ jack_net_slave_t* net; jack_adapter_t* adapter; int buffer_size; -int sample_rate ; - +int sample_rate; static int net_process(jack_nframes_t buffer_size, int audio_input, @@ -54,7 +53,6 @@ static void SlaveAudioCallback(int frames, float** inputs, float** outputs, void #define WIFI_MTU 1500 - int main(int argc, char *argv[]) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -62,12 +60,11 @@ int main(int argc, char *argv[]) { jack_slave_t request = { NUM_INPUT, NUM_OUTPUT, 0, 0, WIFI_MTU, -1, JackSlowMode }; jack_master_t result; - if ((net = jack_net_slave_open("169.254.126.231", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { - //if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { + //if ((net = jack_net_slave_open("169.254.112.119", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { + if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPod", &request, &result)) == 0) { return -1; } - if ((adapter = jack_create_adapter(NUM_INPUT, NUM_OUTPUT, result.buffer_size, @@ -77,7 +74,6 @@ int main(int argc, char *argv[]) { return -1; } - TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT); jack_set_net_slave_process_callback(net, net_process, NULL); @@ -85,7 +81,6 @@ int main(int argc, char *argv[]) { return -1; } - if (audio_device.Open(result.buffer_size, result.sample_rate) < 0) { return -1; } @@ -96,7 +91,6 @@ int main(int argc, char *argv[]) { return -1; } - int retVal = UIApplicationMain(argc, argv, nil, nil); [pool release]; From eade0c1c85b1578c1e145eb5a0b308c876956f33 Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 10 Mar 2010 16:34:22 +0000 Subject: [PATCH 042/472] Add NetIntAudioBuffer class. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3951 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetInterface.cpp | 6 ++ common/JackNetTool.cpp | 140 ++++++++++++++++++++++++++++++++++-- common/JackNetTool.h | 50 +++++++++++++ macosx/iphone/main_slave.mm | 1 + 4 files changed, 193 insertions(+), 4 deletions(-) diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 0a947203..3b2f1eec 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -236,6 +236,9 @@ namespace Jack #ifdef CELT fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); + + //fNetAudioCaptureBuffer = new NetIntAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); + //fNetAudioPlaybackBuffer = new NetIntAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); #else fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); @@ -745,6 +748,9 @@ namespace Jack #ifdef CELT fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); + + // fNetAudioCaptureBuffer = new NetIntAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); + // fNetAudioPlaybackBuffer = new NetIntAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); #else fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index b691e2c1..099eeca2 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -261,7 +261,6 @@ namespace Jack : fNetBuffer(net_buffer) { int res1, res2; - jack_nframes_t period; fNPorts = nports; fPeriodSize = params->fPeriodSize; @@ -318,7 +317,6 @@ namespace Jack fNumPackets = (res1) ? (res2 + 1) : res2; fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets; - //fLastSubPeriodBytesSize = fSubPeriodBytesSize + (fCompressedSizeByte - (fSubPeriodBytesSize * fNumPackets)); fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets; jack_log("fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize); @@ -424,7 +422,7 @@ namespace Jack if (subcycle == fNumPackets - 1) { for (int port_index = 0; port_index < fNPorts; port_index++) - memcpy(fCompressedBuffer[port_index] + subcycle * fSubPeriodBytesSize, fNetBuffer + port_index * fSubPeriodBytesSize, fLastSubPeriodBytesSize); + memcpy(fCompressedBuffer[port_index] + subcycle * fSubPeriodBytesSize, fNetBuffer + port_index * fLastSubPeriodBytesSize, fLastSubPeriodBytesSize); } else { for (int port_index = 0; port_index < fNPorts; port_index++) memcpy(fCompressedBuffer[port_index] + subcycle * fSubPeriodBytesSize, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize); @@ -446,10 +444,12 @@ namespace Jack { if (subcycle == fNumPackets - 1) { for (int port_index = 0; port_index < fNPorts; port_index++) - memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fCompressedBuffer[port_index] + subcycle * fSubPeriodBytesSize, fLastSubPeriodBytesSize); + memcpy(fNetBuffer + port_index * fLastSubPeriodBytesSize, fCompressedBuffer[port_index] + subcycle * fSubPeriodBytesSize, fLastSubPeriodBytesSize); + return fNPorts * fLastSubPeriodBytesSize; } else { for (int port_index = 0; port_index < fNPorts; port_index++) memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fCompressedBuffer[port_index] + subcycle * fSubPeriodBytesSize, fSubPeriodBytesSize); + return fNPorts * fSubPeriodBytesSize; } return fNPorts * fSubPeriodBytesSize; @@ -457,6 +457,138 @@ namespace Jack #endif + + NetIntAudioBuffer::NetIntAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) + : fNetBuffer(net_buffer) + { + int res1, res2; + + fNPorts = nports; + fPeriodSize = params->fPeriodSize; + + fPortBuffer = new sample_t* [fNPorts]; + for (int port_index = 0; port_index < fNPorts; port_index++) + fPortBuffer[port_index] = NULL; + + fIntBuffer = new short* [fNPorts]; + for (int port_index = 0; port_index < fNPorts; port_index++) + fIntBuffer[port_index] = new short[fPeriodSize]; + + fCompressedSizeByte = (params->fPeriodSize * sizeof(short)); + + jack_log("fCompressedSizeByte %d", fCompressedSizeByte); + + res1 = (fNPorts * fCompressedSizeByte) % (params->fMtu - sizeof(packet_header_t)); + res2 = (fNPorts * fCompressedSizeByte) / (params->fMtu - sizeof(packet_header_t)); + + jack_log("res1 = %d res2 = %d", res1, res2); + + fNumPackets = (res1) ? (res2 + 1) : res2; + + fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets; + fSubPeriodSize = fSubPeriodBytesSize / sizeof(short); + + //fLastSubPeriodBytesSize = fSubPeriodBytesSize + (fCompressedSizeByte - (fSubPeriodBytesSize * fNumPackets)); + fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets; + fLastSubPeriodSize = fLastSubPeriodBytesSize / sizeof(short); + + jack_log("fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize); + + fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate); + fCycleSize = params->fMtu * fNumPackets; + + fLastSubCycle = -1; + return; + } + + NetIntAudioBuffer::~NetIntAudioBuffer() + { + for (int port_index = 0; port_index < fNPorts; port_index++) + delete [] fIntBuffer[port_index]; + + delete [] fIntBuffer; + delete [] fPortBuffer; + } + + size_t NetIntAudioBuffer::GetCycleSize() + { + return fCycleSize; + } + + float NetIntAudioBuffer::GetCycleDuration() + { + return fCycleDuration; + } + + int NetIntAudioBuffer::GetNumPackets() + { + return fNumPackets; + } + + void NetIntAudioBuffer::SetBuffer(int index, sample_t* buffer) + { + fPortBuffer[index] = buffer; + } + + sample_t* NetIntAudioBuffer::GetBuffer(int index) + { + return fPortBuffer[index]; + } + + int NetIntAudioBuffer::RenderFromJackPorts() + { + for (int port_index = 0; port_index < fNPorts; port_index++) { + for (unsigned int frame = 0; frame < fPeriodSize; frame++) + fIntBuffer[port_index][frame] = short(fPortBuffer[port_index][frame] * 32768.f); + } + + return fNPorts * fCompressedSizeByte; // in bytes + } + + int NetIntAudioBuffer::RenderToJackPorts() + { + for (int port_index = 0; port_index < fNPorts; port_index++) { + float coef = 1.f / 32768.f; + for (unsigned int frame = 0; frame < fPeriodSize; frame++) + fPortBuffer[port_index][frame] = float(fIntBuffer[port_index][frame] * coef); + } + + fLastSubCycle = -1; + //return fPeriodSize * sizeof(sample_t); // in bytes; TODO + return 0; + } + + //network<->buffer + int NetIntAudioBuffer::RenderFromNetwork(int cycle, int subcycle, size_t copy_size) + { + if (subcycle == fNumPackets - 1) { + for (int port_index = 0; port_index < fNPorts; port_index++) + memcpy(fIntBuffer[port_index] + subcycle * fSubPeriodSize, fNetBuffer + port_index * fLastSubPeriodBytesSize, fLastSubPeriodBytesSize); + } else { + for (int port_index = 0; port_index < fNPorts; port_index++) + memcpy(fIntBuffer[port_index] + subcycle * fSubPeriodSize, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize); + } + + if (subcycle != fLastSubCycle + 1) + jack_error("Packet(s) missing from... %d %d", fLastSubCycle, subcycle); + + fLastSubCycle = subcycle; + return copy_size; + } + + int NetIntAudioBuffer::RenderToNetwork(int subcycle, size_t total_size) + { + if (subcycle == fNumPackets - 1) { + for (int port_index = 0; port_index < fNPorts; port_index++) + memcpy(fNetBuffer + port_index * fLastSubPeriodBytesSize, fIntBuffer[port_index] + subcycle * fSubPeriodSize, fLastSubPeriodBytesSize); + return fNPorts * fLastSubPeriodBytesSize; + } else { + for (int port_index = 0; port_index < fNPorts; port_index++) + memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fIntBuffer[port_index] + subcycle * fSubPeriodSize, fSubPeriodBytesSize); + return fNPorts * fSubPeriodBytesSize; + } + } + // Buffered /* diff --git a/common/JackNetTool.h b/common/JackNetTool.h index dee280a8..6291fcdd 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -608,6 +608,56 @@ namespace Jack }; #endif + + class SERVER_EXPORT NetIntAudioBuffer : public NetAudioBuffer + { + private: + + int fCompressedSizeByte; + jack_nframes_t fPeriodSize; + + int fNumPackets; + float fCycleDuration; // in sec + size_t fCycleSize; // needed size in bytes for an entire cycle + + size_t fSubPeriodSize; + size_t fSubPeriodBytesSize; + size_t fLastSubPeriodSize;; + size_t fLastSubPeriodBytesSize; + + sample_t** fPortBuffer; + char* fNetBuffer; + short ** fIntBuffer; + + int fNPorts; + + int fLastSubCycle; + + public: + + NetIntAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer); + ~NetIntAudioBuffer(); + + // needed size in bytes for an entire cycle + size_t GetCycleSize(); + + // cycle duration in sec + float GetCycleDuration(); + + int GetNumPackets(); + + void SetBuffer(int index, sample_t* buffer); + sample_t* GetBuffer(int index); + + //jack<->buffer + int RenderFromJackPorts(); + int RenderToJackPorts(); + + //network<->buffer + int RenderFromNetwork(int cycle, int subcycle, size_t copy_size); + int RenderToNetwork(int subcycle, size_t total_size); + }; + #define AUDIO_BUFFER_SIZE 8 diff --git a/macosx/iphone/main_slave.mm b/macosx/iphone/main_slave.mm index 054d9d4e..6235bbad 100644 --- a/macosx/iphone/main_slave.mm +++ b/macosx/iphone/main_slave.mm @@ -97,6 +97,7 @@ int main(int argc, char *argv[]) { audio_device.Stop(); audio_device.Close(); + // Wait for application end jack_net_slave_deactivate(net); jack_net_slave_close(net); From aeb3596194be501624d5bbde6ebf636895da716b Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 10 Mar 2010 18:05:09 +0000 Subject: [PATCH 043/472] Correct input or output only. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3952 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackAudioAdapterInterface.cpp | 30 +++++++++----- common/JackNetAPI.cpp | 7 +++- common/JackNetInterface.cpp | 44 +++++++++++---------- common/JackNetTool.cpp | 19 +++++---- common/JackNetTool.h | 6 +-- common/jack/net.h | 8 ++-- macosx/coreaudio/TiPhoneCoreAudioRenderer.h | 3 ++ macosx/iphone/main_slave.mm | 11 ++++-- 8 files changed, 75 insertions(+), 53 deletions(-) diff --git a/common/JackAudioAdapterInterface.cpp b/common/JackAudioAdapterInterface.cpp index fed62e03..8d626df8 100644 --- a/common/JackAudioAdapterInterface.cpp +++ b/common/JackAudioAdapterInterface.cpp @@ -257,21 +257,27 @@ namespace Jack ratio = fPIControler.GetRatio(fPlaybackRingBuffer[0]->GetError() - delta_frames); #ifdef JACK_MONITOR - if (fCaptureRingBuffer[0] != NULL) + if (fCaptureRingBuffer && fCaptureRingBuffer[0] != NULL) fTable.Write(fCaptureRingBuffer[0]->GetError(), fCaptureRingBuffer[0]->GetError() - delta_frames, ratio, 1/ratio, fCaptureRingBuffer[0]->ReadSpace(), fCaptureRingBuffer[0]->ReadSpace()); #endif // Push/pull from ringbuffer for (int i = 0; i < fCaptureChannels; i++) { fCaptureRingBuffer[i]->SetRatio(ratio); - if (fCaptureRingBuffer[i]->WriteResample(inputBuffer[i], frames) < frames) - failure = true; + if (inputBuffer[i]) { + if (fCaptureRingBuffer[i]->WriteResample(inputBuffer[i], frames) < frames) { + failure = true; + } + } } for (int i = 0; i < fPlaybackChannels; i++) { fPlaybackRingBuffer[i]->SetRatio(1/ratio); - if (fPlaybackRingBuffer[i]->ReadResample(outputBuffer[i], frames) < frames) - failure = true; + if (outputBuffer[i]) { + if (fPlaybackRingBuffer[i]->ReadResample(outputBuffer[i], frames) < frames) { + failure = true; + } + } } // Reset all ringbuffers in case of failure if (failure) { @@ -297,13 +303,19 @@ namespace Jack // Push/pull from ringbuffer for (int i = 0; i < fCaptureChannels; i++) { - if (fCaptureRingBuffer[i]->Read(inputBuffer[i], frames) < frames) - res = -1; + if (inputBuffer[i]) { + if (fCaptureRingBuffer[i]->Read(inputBuffer[i], frames) < frames) { + res = -1; + } + } } for (int i = 0; i < fPlaybackChannels; i++) { - if (fPlaybackRingBuffer[i]->Write(outputBuffer[i], frames) < frames) - res = -1; + if (outputBuffer[i]) { + if (fPlaybackRingBuffer[i]->Write(outputBuffer[i], frames) < frames) { + res = -1; + } + } } return res; diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 699a48bb..745e1a62 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -748,8 +748,11 @@ struct JackNetAdapter : public JackAudioAdapterInterface { void Create() { //ringbuffers - fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; - fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; + + if (fCaptureChannels > 0) + fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; + if (fPlaybackChannels > 0) + fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; if (fAdaptative) { AdaptRingBufferSize(); diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 3b2f1eec..7446a08d 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -234,26 +234,27 @@ namespace Jack try { //audio net buffers #ifdef CELT - fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); - fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); + if (fParams.fSendAudioChannels) + fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); + + if (fParams.fReturnAudioChannels) + fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); //fNetAudioCaptureBuffer = new NetIntAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); //fNetAudioPlaybackBuffer = new NetIntAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); #else - fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); - fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); + fNetAudioCaptureBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); + fNetAudioPlaybackBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); #endif + + //fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); + //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); + } catch (exception&) { jack_error("NetAudioBuffer allocation error..."); return false; } - - //fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); - //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); - - assert(fNetAudioCaptureBuffer); - assert(fNetAudioPlaybackBuffer); - + //set the new timeout for the socket if (SetRxTimeout() == SOCKET_ERROR) { jack_error("Can't set rx timeout : %s", StrError(NET_ERROR_CODE)); @@ -741,19 +742,23 @@ namespace Jack assert ( fNetMidiPlaybackBuffer ); //audio net buffers - //fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); - //fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); + //fNetAudioCaptureBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); + //fNetAudioPlaybackBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); try { #ifdef CELT - fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); - fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); + if (fParams.fSendAudioChannels) + fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); + + if (fParams.fReturnAudioChannels) + fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); // fNetAudioCaptureBuffer = new NetIntAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); // fNetAudioPlaybackBuffer = new NetIntAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); #else - fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); - fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); + fNetAudioCaptureBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); + fNetAudioPlaybackBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); + //fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); #endif @@ -762,10 +767,7 @@ namespace Jack return false; } - assert ( fNetAudioCaptureBuffer ); - assert ( fNetAudioPlaybackBuffer ); - - //set the new buffer sizes + //set the new buffer sizes if ( SetNetBufferSize() == SOCKET_ERROR ) { jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) ); goto error; diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index 099eeca2..def43d6e 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -207,45 +207,45 @@ namespace Jack // net audio buffer ********************************************************************************* - NetSingleAudioBuffer::NetSingleAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) + NetFloatAudioBuffer::NetFloatAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) : fPortBuffer(params, nports), fNetBuffer(net_buffer) {} - NetSingleAudioBuffer::~NetSingleAudioBuffer() + NetFloatAudioBuffer::~NetFloatAudioBuffer() {} - size_t NetSingleAudioBuffer::GetCycleSize() + size_t NetFloatAudioBuffer::GetCycleSize() { return fPortBuffer.GetCycleSize(); } - void NetSingleAudioBuffer::SetBuffer ( int index, sample_t* buffer ) + void NetFloatAudioBuffer::SetBuffer ( int index, sample_t* buffer ) { fPortBuffer.SetBuffer(index, buffer); } - sample_t* NetSingleAudioBuffer::GetBuffer ( int index ) + sample_t* NetFloatAudioBuffer::GetBuffer ( int index ) { return fPortBuffer.GetBuffer(index); } - int NetSingleAudioBuffer::RenderFromJackPorts () + int NetFloatAudioBuffer::RenderFromJackPorts () { return fPortBuffer.RenderFromJackPorts(); } - int NetSingleAudioBuffer::RenderToJackPorts () + int NetFloatAudioBuffer::RenderToJackPorts () { return fPortBuffer.RenderToJackPorts(); } //network<->buffer - int NetSingleAudioBuffer::RenderFromNetwork ( int cycle, int subcycle, size_t copy_size ) + int NetFloatAudioBuffer::RenderFromNetwork ( int cycle, int subcycle, size_t copy_size ) { return fPortBuffer.RenderFromNetwork(fNetBuffer, cycle, subcycle, copy_size); } - int NetSingleAudioBuffer::RenderToNetwork (int subcycle, size_t total_size ) + int NetFloatAudioBuffer::RenderToNetwork (int subcycle, size_t total_size ) { return fPortBuffer.RenderToNetwork(fNetBuffer, subcycle, total_size); } @@ -457,7 +457,6 @@ namespace Jack #endif - NetIntAudioBuffer::NetIntAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) : fNetBuffer(net_buffer) { diff --git a/common/JackNetTool.h b/common/JackNetTool.h index 6291fcdd..dcda14ec 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -511,7 +511,7 @@ namespace Jack }; - class SERVER_EXPORT NetSingleAudioBuffer : public NetAudioBuffer + class SERVER_EXPORT NetFloatAudioBuffer : public NetAudioBuffer { private: @@ -520,8 +520,8 @@ namespace Jack public: - NetSingleAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ); - ~NetSingleAudioBuffer(); + NetFloatAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ); + ~NetFloatAudioBuffer(); // needed size in bytes for an entire cycle size_t GetCycleSize(); diff --git a/common/jack/net.h b/common/jack/net.h index ba1dd0dc..1bce751d 100644 --- a/common/jack/net.h +++ b/common/jack/net.h @@ -44,10 +44,10 @@ extern "C" typedef struct { - int audio_input; - int audio_output; - int midi_input; - int midi_ouput; + int audio_input; // from master or to slave + int audio_output; // to master or from slave + int midi_input; // from master or to slave + int midi_output; // to master or from slave int mtu; int time_out; // in millisecond, -1 means in infinite char mode; diff --git a/macosx/coreaudio/TiPhoneCoreAudioRenderer.h b/macosx/coreaudio/TiPhoneCoreAudioRenderer.h index 3c22eba4..1bd50e15 100644 --- a/macosx/coreaudio/TiPhoneCoreAudioRenderer.h +++ b/macosx/coreaudio/TiPhoneCoreAudioRenderer.h @@ -59,6 +59,9 @@ class TiPhoneCoreAudioRenderer TiPhoneCoreAudioRenderer(int input, int output) :fDevNumInChans(input), fDevNumOutChans(output), fAudioCallback(NULL), fCallbackArg(NULL) { + memset(fInChannel, 0, sizeof(float*) * MAX_CHANNELS); + memset(fOutChannel, 0, sizeof(float*) * MAX_CHANNELS); + for (int i = 0; i < fDevNumInChans; i++) { fInChannel[i] = new float[8192]; } diff --git a/macosx/iphone/main_slave.mm b/macosx/iphone/main_slave.mm index 6235bbad..aec9beb1 100644 --- a/macosx/iphone/main_slave.mm +++ b/macosx/iphone/main_slave.mm @@ -11,7 +11,7 @@ #include "TiPhoneCoreAudioRenderer.h" -#define NUM_INPUT 2 +#define NUM_INPUT 0 #define NUM_OUTPUT 2 jack_net_slave_t* net; @@ -20,6 +20,7 @@ jack_adapter_t* adapter; int buffer_size; int sample_rate; + static int net_process(jack_nframes_t buffer_size, int audio_input, float** audio_input_buffer, @@ -32,6 +33,7 @@ static int net_process(jack_nframes_t buffer_size, void* data) { + //printf("audio_input %d audio_output %d \n", audio_input, audio_output); jack_adapter_pull_and_push(adapter, audio_output_buffer, audio_input_buffer, buffer_size); // Process input, produce output @@ -57,7 +59,7 @@ int main(int argc, char *argv[]) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - jack_slave_t request = { NUM_INPUT, NUM_OUTPUT, 0, 0, WIFI_MTU, -1, JackSlowMode }; + jack_slave_t request = { NUM_OUTPUT, NUM_INPUT, 0, 0, WIFI_MTU, -1, JackSlowMode }; jack_master_t result; //if ((net = jack_net_slave_open("169.254.112.119", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { @@ -73,9 +75,10 @@ int main(int argc, char *argv[]) { result.sample_rate)) == 0) { return -1; } - + TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT); - + + jack_set_net_slave_process_callback(net, net_process, NULL); if (jack_net_slave_activate(net) != 0) { return -1; From 52993cd8599441b895f3425c775995882bc42ffb Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 10 Mar 2010 20:04:47 +0000 Subject: [PATCH 044/472] Add jack_flush_adapter API. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3953 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackAudioAdapterInterface.h | 9 +++++---- common/JackNetAPI.cpp | 19 ++++++++++++++++++- common/JackNetInterface.cpp | 4 +++- common/JackResampler.cpp | 1 + common/jack/net.h | 3 +++ common/ringbuffer.c | 1 + macosx/iphone/main_slave.mm | 14 +++++++++++--- 7 files changed, 42 insertions(+), 9 deletions(-) diff --git a/common/JackAudioAdapterInterface.h b/common/JackAudioAdapterInterface.h index 0412ae6f..080d4596 100644 --- a/common/JackAudioAdapterInterface.h +++ b/common/JackAudioAdapterInterface.h @@ -102,7 +102,7 @@ namespace Jack public: - JackAudioAdapterInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ): + JackAudioAdapterInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate, jack_nframes_t ring_buffer_size = DEFAULT_ADAPTATIVE_SIZE): fCaptureChannels ( 0 ), fPlaybackChannels ( 0 ), fHostBufferSize ( buffer_size ), @@ -112,7 +112,7 @@ namespace Jack fPIControler(sample_rate / sample_rate, 256), fCaptureRingBuffer(NULL), fPlaybackRingBuffer(NULL), fQuality(0), - fRingbufferCurSize(DEFAULT_ADAPTATIVE_SIZE), + fRingbufferCurSize(ring_buffer_size), fPullAndPushTime(0), fRunning(false), fAdaptative(true) @@ -120,7 +120,8 @@ namespace Jack JackAudioAdapterInterface ( jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, jack_nframes_t adapted_buffer_size, - jack_nframes_t adapted_sample_rate ) : + jack_nframes_t adapted_sample_rate, + jack_nframes_t ring_buffer_size = DEFAULT_ADAPTATIVE_SIZE ) : fCaptureChannels ( 0 ), fPlaybackChannels ( 0 ), fHostBufferSize ( host_buffer_size ), @@ -129,7 +130,7 @@ namespace Jack fAdaptedSampleRate ( adapted_sample_rate ), fPIControler(host_sample_rate / host_sample_rate, 256), fQuality(0), - fRingbufferCurSize(DEFAULT_ADAPTATIVE_SIZE), + fRingbufferCurSize(ring_buffer_size), fPullAndPushTime(0), fRunning(false), fAdaptative(true) diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 745e1a62..ec811555 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -111,6 +111,7 @@ extern "C" jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_sample_rate); SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter); + SERVER_EXPORT void jack_flush_adapter(jack_adapter_t* adapter); SERVER_EXPORT int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); SERVER_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); @@ -485,7 +486,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf return 0; } - int Restart() + int Restart() { // If shutdown cb is set, then call it if (fShutdownCallback) @@ -782,6 +783,16 @@ struct JackNetAdapter : public JackAudioAdapterInterface { { Destroy(); } + + int Flush() + { + for (int i = 0; i < fCaptureChannels; i++ ) { + fCaptureRingBuffer[i]->Reset(fRingbufferCurSize); + } + for (int i = 0; i < fPlaybackChannels; i++ ) { + fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize); + } + } }; @@ -894,6 +905,12 @@ SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter) return 0; } +SERVER_EXPORT void jack_flush_adapter(jack_adapter_t* adapter) +{ + JackNetAdapter* slave = (JackNetAdapter*)adapter; + slave->Flush(); +} + SERVER_EXPORT int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames) { JackNetAdapter* slave = (JackNetAdapter*)adapter; diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 7446a08d..6b4fec0e 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -436,13 +436,15 @@ namespace Jack // - this mode will skip the two first cycles, thus it lets time for data to be processed and queued on the socket rx buffer //the slow mode is the safest mode because it wait twice the bandwidth relative time (send/return + process) + /* if (fCycleOffset < CYCLE_OFFSET_SLOW) { return 0; } else { rx_bytes = Recv ( rx_head->fPacketSize, 0 ); } + */ - //rx_bytes = Recv ( rx_head->fPacketSize, 0 ); + rx_bytes = Recv ( rx_head->fPacketSize, 0 ); if (fCycleOffset != fLastfCycleOffset) jack_info("Warning : '%s' runs in slow network mode, but data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); diff --git a/common/JackResampler.cpp b/common/JackResampler.cpp index b6c1917c..b9a26f44 100644 --- a/common/JackResampler.cpp +++ b/common/JackResampler.cpp @@ -39,6 +39,7 @@ JackResampler::~JackResampler() void JackResampler::Reset(unsigned int new_size) { fRingBufferSize = new_size; + jack_ringbuffer_reset(fRingBuffer); jack_ringbuffer_reset_size(fRingBuffer, sizeof(float) * fRingBufferSize); jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize / 2)); } diff --git a/common/jack/net.h b/common/jack/net.h index 1bce751d..91688a83 100644 --- a/common/jack/net.h +++ b/common/jack/net.h @@ -268,6 +268,9 @@ jack_adapter_t* jack_create_adapter(int input, int output, */ int jack_destroy_adapter(jack_adapter_t* adapter); + +void jack_flush_adapter(jack_adapter_t* adapter); + /** * Push input to and pull output from ringbuffer * diff --git a/common/ringbuffer.c b/common/ringbuffer.c index 45ee27b3..c6237f5e 100644 --- a/common/ringbuffer.c +++ b/common/ringbuffer.c @@ -126,6 +126,7 @@ jack_ringbuffer_reset (jack_ringbuffer_t * rb) { rb->read_ptr = 0; rb->write_ptr = 0; + memset(rb->buf, 0, rb->size); } /* Reset the read and write pointers to zero. This is not thread diff --git a/macosx/iphone/main_slave.mm b/macosx/iphone/main_slave.mm index aec9beb1..289d643c 100644 --- a/macosx/iphone/main_slave.mm +++ b/macosx/iphone/main_slave.mm @@ -14,13 +14,12 @@ #define NUM_INPUT 0 #define NUM_OUTPUT 2 -jack_net_slave_t* net; -jack_adapter_t* adapter; +jack_net_slave_t* net = NULL; +jack_adapter_t* adapter = NULL; int buffer_size; int sample_rate; - static int net_process(jack_nframes_t buffer_size, int audio_input, float** audio_input_buffer, @@ -46,6 +45,13 @@ static int net_process(jack_nframes_t buffer_size, return 0; } +static void net_shutdown(void *arg) +{ + if (adapter) + jack_flush_adapter(adapter); +} + + static void SlaveAudioCallback(int frames, float** inputs, float** outputs, void* arg) { jack_adapter_push_and_pull(adapter, inputs, outputs, frames); @@ -80,6 +86,8 @@ int main(int argc, char *argv[]) { jack_set_net_slave_process_callback(net, net_process, NULL); + jack_set_net_slave_shutdown_callback(net, net_shutdown, NULL); + if (jack_net_slave_activate(net) != 0) { return -1; } From 347ff4c348fdb77a8d260c21d12d52adeb45447d Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 10 Mar 2010 20:33:09 +0000 Subject: [PATCH 045/472] Implement connection time-out git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3954 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetAPI.cpp | 13 ++++++++----- common/JackNetInterface.cpp | 22 ++++++++++++++-------- common/JackNetInterface.h | 6 +++--- common/jack/net.h | 2 +- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index ec811555..d895f3ca 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -46,7 +46,7 @@ extern "C" int audio_input; int audio_output; int midi_input; - int midi_ouput; + int midi_output; int mtu; int time_out; // in millisecond, -1 means in infinite char mode; @@ -230,8 +230,8 @@ struct JackNetExtMaster : public JackNetMasterInterface { result->audio_input = fParams.fSendAudioChannels; result->audio_output = fParams.fReturnAudioChannels; result->midi_input = fParams.fSendMidiChannels; - result->midi_ouput = fParams.fReturnMidiChannels; - result->midi_ouput = fParams.fMtu; + result->midi_output = fParams.fReturnMidiChannels; + result->mtu = fParams.fMtu; result->mode = fParams.fNetworkMode; return 0; @@ -425,6 +425,8 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf JackMidiBuffer** fMidiCaptureBuffer; JackMidiBuffer** fMidiPlaybackBuffer; + int fConnectTimeOut; + JackNetExtSlave(const char* ip, int port, const char* name, @@ -448,9 +450,10 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf fParams.fSendAudioChannels = request->audio_input; fParams.fReturnAudioChannels = request->audio_output; fParams.fSendMidiChannels = request->midi_input; - fParams.fReturnMidiChannels = request->midi_ouput; + fParams.fReturnMidiChannels = request->midi_output; fParams.fNetworkMode = request->mode; fParams.fSlaveSyncMode = 1; + fConnectTimeOut = request->time_out; // Create name with hostname and client name GetHostName(host_name, JACK_CLIENT_NAME_SIZE); @@ -468,7 +471,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf int Open(jack_master_t* result) { // Init network connection - if (!JackNetSlaveInterface::InitConnection()) + if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) return -1; // Then set global parameters diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 6b4fec0e..0e7a9f45 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -609,10 +609,11 @@ namespace Jack // Separate the connection protocol into two separated step - bool JackNetSlaveInterface::InitConnection() + bool JackNetSlaveInterface::InitConnection(int time_out) { - jack_log ( "JackNetSlaveInterface::InitConnection()" ); - + jack_log("JackNetSlaveInterface::InitConnection()"); + int try_count = (time_out > 0) ? ((1000000 * time_out) / SLAVE_INIT_TIMEOUT) : LONG_MAX; + //set the parameters to send strcpy (fParams.fPacketType, "params"); fParams.fProtocolVersion = SLAVE_PROTOCOL; @@ -622,13 +623,13 @@ namespace Jack do { //get a master - status = SendAvailableToMaster(); + status = SendAvailableToMaster(try_count); if (status == NET_SOCKET_ERROR) return false; } - while (status != NET_CONNECTED); + while (status != NET_CONNECTED && --try_count > 0); - return true; + return (try_count != 0); } bool JackNetSlaveInterface::InitRendering() @@ -649,7 +650,7 @@ namespace Jack return true; } - net_status_t JackNetSlaveInterface::SendAvailableToMaster() + net_status_t JackNetSlaveInterface::SendAvailableToMaster(int count) { jack_log ( "JackNetSlaveInterface::SendAvailableToMaster()" ); //utility @@ -697,7 +698,12 @@ namespace Jack return NET_RECV_ERROR; } } - while ( strcmp ( host_params.fPacketType, fParams.fPacketType ) && ( GetPacketType ( &host_params ) != SLAVE_SETUP ) ); + while (strcmp(host_params.fPacketType, fParams.fPacketType) && (GetPacketType(&host_params) != SLAVE_SETUP) && (--count > 0)); + + // Time out failure.. + if (count == 0) { + return NET_CONNECT_ERROR; + } //everything is OK, copy parameters SessionParamsDisplay(&host_params); diff --git a/common/JackNetInterface.h b/common/JackNetInterface.h index d7405a56..3a562d49 100644 --- a/common/JackNetInterface.h +++ b/common/JackNetInterface.h @@ -145,10 +145,10 @@ namespace Jack static uint fSlaveCounter; bool Init(); - bool InitConnection(); + bool InitConnection(int time_out); bool InitRendering(); - net_status_t SendAvailableToMaster(); + net_status_t SendAvailableToMaster(int count = LONG_MAX); net_status_t SendStartToMaster(); bool SetParams(); @@ -207,7 +207,7 @@ namespace Jack #define SLAVE_SETUP_RETRY 5 #define MASTER_INIT_TIMEOUT 1000000 // in usec -#define SLAVE_INIT_TIMEOUT 2000000 // in usec +#define SLAVE_INIT_TIMEOUT 1000000 // in usec #define CYCLE_OFFSET_FAST 0 #define CYCLE_OFFSET_NORMAL 1 diff --git a/common/jack/net.h b/common/jack/net.h index 91688a83..44e71c44 100644 --- a/common/jack/net.h +++ b/common/jack/net.h @@ -49,7 +49,7 @@ typedef struct { int midi_input; // from master or to slave int midi_output; // to master or from slave int mtu; - int time_out; // in millisecond, -1 means in infinite + int time_out; // in second, -1 means in infinite char mode; } jack_slave_t; From cbd652cf85b583e77d5f737c45b42fe2e356f91e Mon Sep 17 00:00:00 2001 From: sletz Date: Thu, 11 Mar 2010 10:18:41 +0000 Subject: [PATCH 046/472] Improve master mode. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3955 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackAudioAdapterInterface.h | 4 +- common/JackNetAPI.cpp | 11 ++--- common/JackNetAdapter.cpp | 21 ++++++--- common/JackNetDriver.cpp | 10 +++-- common/JackNetInterface.cpp | 44 +++++++++++-------- common/JackNetInterface.h | 3 +- common/JackNetManager.cpp | 8 +++- common/JackNetTool.cpp | 17 ++----- common/JackNetTool.h | 2 +- common/JackWaitThreadedDriver.h | 4 +- .../iPhoneNet.xcodeproj/project.pbxproj | 33 +++++++------- macosx/iphone/main_master.mm | 18 +++++--- macosx/iphone/main_slave.mm | 1 + 13 files changed, 99 insertions(+), 77 deletions(-) diff --git a/common/JackAudioAdapterInterface.h b/common/JackAudioAdapterInterface.h index 080d4596..a661598f 100644 --- a/common/JackAudioAdapterInterface.h +++ b/common/JackAudioAdapterInterface.h @@ -212,13 +212,13 @@ namespace Jack int GetInputs() { - jack_log ( "JackAudioAdapterInterface::GetInputs %d", fCaptureChannels ); + //jack_log("JackAudioAdapterInterface::GetInputs %d", fCaptureChannels); return fCaptureChannels; } int GetOutputs() { - jack_log ( "JackAudioAdapterInterface::GetOutputs %d", fPlaybackChannels ); + //jack_log ("JackAudioAdapterInterface::GetOutputs %d", fPlaybackChannels); return fPlaybackChannels; } diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index d895f3ca..bc25d421 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -214,6 +214,7 @@ struct JackNetExtMaster : public JackNetMasterInterface { fprintf(stderr, "Can't init new net master...\n"); goto error; } + jack_info ( "Waiting for a slave..." ); break; case KILL_MASTER: @@ -787,7 +788,7 @@ struct JackNetAdapter : public JackAudioAdapterInterface { Destroy(); } - int Flush() + void Flush() { for (int i = 0; i < fCaptureChannels; i++ ) { fCaptureRingBuffer[i]->Reset(fRingbufferCurSize); @@ -881,14 +882,14 @@ SERVER_EXPORT int jack_net_master_close(jack_net_master_t* net) } SERVER_EXPORT int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer) { - JackNetExtMaster* slave = (JackNetExtMaster*)net; - return slave->Read(audio_input, audio_input_buffer, midi_input, midi_input_buffer); + JackNetExtMaster* master = (JackNetExtMaster*)net; + return master->Read(audio_input, audio_input_buffer, midi_input, midi_input_buffer); } SERVER_EXPORT int jack_net_master_send(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer) { - JackNetExtMaster* slave = (JackNetExtMaster*)net; - return slave->Write(audio_output, audio_output_buffer, midi_output, midi_output_buffer); + JackNetExtMaster* master = (JackNetExtMaster*)net; + return master->Write(audio_output, audio_output_buffer, midi_output, midi_output_buffer); } // Adapter API diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index 8eff6900..b44ba331 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -117,18 +117,18 @@ namespace Jack JackNetAdapter::~JackNetAdapter() { - jack_log ( "JackNetAdapter::~JackNetAdapter" ); + jack_log ("JackNetAdapter::~JackNetAdapter"); int port_index; - if ( fSoftCaptureBuffer ) + if (fSoftCaptureBuffer) { - for ( port_index = 0; port_index < fCaptureChannels; port_index++ ) + for (port_index = 0; port_index < fCaptureChannels; port_index++) delete[] fSoftCaptureBuffer[port_index]; delete[] fSoftCaptureBuffer; } - if ( fSoftPlaybackBuffer ) + if (fSoftPlaybackBuffer) { - for ( port_index = 0; port_index < fPlaybackChannels; port_index++ ) + for ( port_index = 0; port_index < fPlaybackChannels; port_index++) delete[] fSoftPlaybackBuffer[port_index]; delete[] fSoftPlaybackBuffer; } @@ -194,6 +194,8 @@ namespace Jack } //thread------------------------------------------------------------------------------ + // TODO : if failure, thread exist... need to restart ? + bool JackNetAdapter::Init() { jack_log ( "JackNetAdapter::Init" ); @@ -201,11 +203,16 @@ namespace Jack int port_index; //init network connection - if ( !JackNetSlaveInterface::Init() ) + if (!JackNetSlaveInterface::Init()) { + jack_error("JackNetSlaveInterface::Init() error..." ); return false; + } //then set global parameters - SetParams(); + if (!SetParams()) { + jack_error("SetParams error..." ); + return false; + } //set buffers fSoftCaptureBuffer = new sample_t*[fCaptureChannels]; diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index 477acb28..5f36c3f9 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -142,13 +142,17 @@ namespace Jack ( fParams.fSlaveSyncMode ) ? "sync" : "async", ( fParams.fTransportSync ) ? "with" : "without" ); //init network - if (!JackNetSlaveInterface::Init()) + if (!JackNetSlaveInterface::Init()) { + jack_error("JackNetSlaveInterface::Init() error..." ); return false; + } //set global parameters - if (!SetParams()) + if (!SetParams()) { + jack_error("SetParams error..." ); return false; - + } + //allocate midi ports lists fMidiCapturePortList = new jack_port_id_t [fParams.fSendMidiChannels]; fMidiPlaybackPortList = new jack_port_id_t [fParams.fReturnMidiChannels]; diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 0e7a9f45..9dc6b583 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -67,9 +67,21 @@ namespace Jack memset(&fReturnTransportData, 0, sizeof(net_transport_data_t)); } + void JackNetInterface::FreeNetworkBuffers() + { + delete fNetMidiCaptureBuffer; + delete fNetMidiPlaybackBuffer; + delete fNetAudioCaptureBuffer; + delete fNetAudioPlaybackBuffer; + fNetMidiCaptureBuffer = NULL; + fNetMidiPlaybackBuffer = NULL; + fNetAudioCaptureBuffer = NULL; + fNetAudioPlaybackBuffer = NULL; + } + JackNetInterface::~JackNetInterface() { - jack_log ( "JackNetInterface::~JackNetInterface" ); + jack_log ("JackNetInterface::~JackNetInterface"); fSocket.Close(); delete[] fTxBuffer; @@ -270,11 +282,7 @@ namespace Jack return true; error: - - delete fNetMidiCaptureBuffer; - delete fNetMidiPlaybackBuffer; - delete fNetAudioCaptureBuffer; - delete fNetAudioPlaybackBuffer; + FreeNetworkBuffers(); return false; } @@ -650,7 +658,7 @@ namespace Jack return true; } - net_status_t JackNetSlaveInterface::SendAvailableToMaster(int count) + net_status_t JackNetSlaveInterface::SendAvailableToMaster(long try_count) { jack_log ( "JackNetSlaveInterface::SendAvailableToMaster()" ); //utility @@ -698,10 +706,11 @@ namespace Jack return NET_RECV_ERROR; } } - while (strcmp(host_params.fPacketType, fParams.fPacketType) && (GetPacketType(&host_params) != SLAVE_SETUP) && (--count > 0)); + while (strcmp(host_params.fPacketType, fParams.fPacketType) && (GetPacketType(&host_params) != SLAVE_SETUP) && (--try_count > 0)); // Time out failure.. - if (count == 0) { + if (try_count == 0) { + jack_error("Time out error in connect"); return NET_CONNECT_ERROR; } @@ -710,8 +719,8 @@ namespace Jack fParams = host_params; //connect the socket - if ( fSocket.Connect() == SOCKET_ERROR ) { - jack_error ( "Error in connect : %s", StrError ( NET_ERROR_CODE ) ); + if (fSocket.Connect() == SOCKET_ERROR) { + jack_error("Error in connect : %s", StrError(NET_ERROR_CODE)); return NET_CONNECT_ERROR; } return NET_CONNECTED; @@ -719,17 +728,17 @@ namespace Jack net_status_t JackNetSlaveInterface::SendStartToMaster() { - jack_log ( "JackNetSlaveInterface::SendStartToMaster" ); + jack_log("JackNetSlaveInterface::SendStartToMaster"); //tell the master to start session_params_t net_params; memset(&net_params, 0, sizeof ( session_params_t )); SetPacketType ( &fParams, START_MASTER ); SessionParamsHToN(&fParams, &net_params); - if ( fSocket.Send ( &net_params, sizeof ( session_params_t ), 0 ) == SOCKET_ERROR ) + if (fSocket.Send(&net_params, sizeof(session_params_t), 0) == SOCKET_ERROR) { - jack_error ( "Error in send : %s", StrError ( NET_ERROR_CODE ) ); - return ( fSocket.GetError() == NET_CONN_ERROR ) ? NET_ERROR : NET_SEND_ERROR; + jack_error("Error in send : %s", StrError(NET_ERROR_CODE)); + return (fSocket.GetError() == NET_CONN_ERROR) ? NET_ERROR : NET_SEND_ERROR; } return NET_ROLLING; } @@ -784,10 +793,7 @@ namespace Jack return true; error: - delete fNetMidiCaptureBuffer; - delete fNetMidiPlaybackBuffer; - delete fNetAudioCaptureBuffer; - delete fNetAudioPlaybackBuffer; + FreeNetworkBuffers(); return false; } diff --git a/common/JackNetInterface.h b/common/JackNetInterface.h index 3a562d49..8e3aab93 100644 --- a/common/JackNetInterface.h +++ b/common/JackNetInterface.h @@ -63,6 +63,7 @@ namespace Jack //utility methods int SetNetBufferSize(); + void FreeNetworkBuffers(); //virtual methods : depends on the sub class master/slave virtual bool SetParams(); @@ -148,7 +149,7 @@ namespace Jack bool InitConnection(int time_out); bool InitRendering(); - net_status_t SendAvailableToMaster(int count = LONG_MAX); + net_status_t SendAvailableToMaster(long count = LONG_MAX); // long here (and not int...) net_status_t SendStartToMaster(); bool SetParams(); diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index b41559c4..d0961935 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -113,12 +113,16 @@ namespace Jack bool JackNetMaster::Init(bool auto_connect) { //network init - if (!JackNetMasterInterface::Init()) + if (!JackNetMasterInterface::Init()){ + jack_error("JackNetMasterInterface::Init() error..." ); return false; + } //set global parameters - if (!SetParams()) + if (!SetParams()) { + jack_error("SetParams error..." ); return false; + } //jack client and process jack_status_t status; diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index def43d6e..d4e3fba3 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -49,7 +49,6 @@ HardwareClock::HardwareClock() mach_timebase_info_data_t info; mach_timebase_info(&info); m_clockToSeconds = (double)info.numer/info.denom/1000000000.0; - Reset(); } @@ -57,7 +56,6 @@ void HardwareClock::Reset() { m_startAbsTime = mach_absolute_time(); m_lastAbsTime = m_startAbsTime; - m_time = m_startAbsTime*m_clockToSeconds; m_deltaTime = 1.0f/60.0f; } @@ -69,7 +67,6 @@ void HardwareClock::Update() m_time = currentTime*m_clockToSeconds; m_deltaTime = (double)dt*m_clockToSeconds; - m_lastAbsTime = currentTime; } @@ -200,8 +197,8 @@ namespace Jack int NetMidiBuffer::RenderToNetwork ( int subcycle, size_t total_size ) { int size = total_size - subcycle * fMaxPcktSize; - int copy_size = ( size <= fMaxPcktSize ) ? size : fMaxPcktSize; - memcpy ( fNetBuffer, fBuffer + subcycle * fMaxPcktSize, copy_size ); + int copy_size = (size <= fMaxPcktSize) ? size : fMaxPcktSize; + memcpy(fNetBuffer, fBuffer + subcycle * fMaxPcktSize, copy_size); return copy_size; } @@ -414,12 +411,9 @@ namespace Jack return 0; } - HardwareClock clock; - //network<->buffer + //network<->buffer int NetCeltAudioBuffer::RenderFromNetwork(int cycle, int subcycle, size_t copy_size) { - //clock.Update(); - if (subcycle == fNumPackets - 1) { for (int port_index = 0; port_index < fNPorts; port_index++) memcpy(fCompressedBuffer[port_index] + subcycle * fSubPeriodBytesSize, fNetBuffer + port_index * fLastSubPeriodBytesSize, fLastSubPeriodBytesSize); @@ -432,11 +426,6 @@ namespace Jack jack_error("Packet(s) missing from... %d %d", fLastSubCycle, subcycle); fLastSubCycle = subcycle; - - //clock.Update(); - //const float dt = clock.GetDeltaTime(); - //printf("Delta: %f s\n", dt); - return copy_size; } diff --git a/common/JackNetTool.h b/common/JackNetTool.h index dcda14ec..6ecabe4c 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -278,7 +278,7 @@ namespace Jack virtual int RenderToJackPorts () = 0; //network<->buffer - virtual int RenderFromNetwork ( int cycle, int subcycle, size_t copy_size ) = 0; + virtual int RenderFromNetwork ( int cycle, int subcycle, size_t copy_size ) = 0; virtual int RenderToNetwork (int subcycle, size_t total_size ) = 0; virtual void SetBuffer ( int index, sample_t* buffer ) = 0; diff --git a/common/JackWaitThreadedDriver.h b/common/JackWaitThreadedDriver.h index f81db20c..1448572b 100644 --- a/common/JackWaitThreadedDriver.h +++ b/common/JackWaitThreadedDriver.h @@ -64,8 +64,8 @@ class SERVER_EXPORT JackWaitThreadedDriver : public JackThreadedDriver // JackRunnableInterface interface bool Execute() { - // Blocks until decorated driver is started (that is when it's Init method returns). - fDriver->Initialize(); + // Blocks until decorated driver is started (that is when it's Initialize method returns true). + while (!fDriver->Initialize()) {} fRunning = true; return false; } diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj index 07a76deb..1b84bcbb 100755 --- a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -153,12 +153,12 @@ /* Begin PBXFileReference section */ 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - 1D6058910D05DD3D006BFB54 /* NetJack.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetJack.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1D6058910D05DD3D006BFB54 /* NetJackSlave.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetJackSlave.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; 32CA4F630368D1EE00C91783 /* iPhoneNet_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iPhoneNet_Prefix.pch; sourceTree = ""; }; - 4B0772380F54018C000DC657 /* iPhoneNetMaster.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneNetMaster.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B0772380F54018C000DC657 /* NetJackMaster.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetJackMaster.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4B0772490F54021B000DC657 /* main_slave.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main_slave.mm; sourceTree = SOURCE_ROOT; }; 4B0772500F54022D000DC657 /* main_master.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main_master.mm; sourceTree = SOURCE_ROOT; }; 4B0773840F541EE2000DC657 /* iPhoneNetAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iPhoneNetAppDelegate.h; sourceTree = ""; }; @@ -182,7 +182,7 @@ 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaust.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BCB37D5112D64B4008C7BC1 /* HardwareClock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HardwareClock.cpp; sourceTree = SOURCE_ROOT; }; 4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "iphone-faust.mm"; sourceTree = SOURCE_ROOT; }; - 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneThruNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BCF75F610BC30140082C526 /* audio_thru.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = audio_thru.mm; sourceTree = SOURCE_ROOT; }; 4BDFCCD7113DB30500D77992 /* Info copy.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info copy.plist"; sourceTree = ""; }; 4BDFCD57113DB6B700D77992 /* NetJackSlave.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetJackSlave.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -290,11 +290,11 @@ 19C28FACFE9D520D11CA2CBB /* Products */ = { isa = PBXGroup; children = ( - 1D6058910D05DD3D006BFB54 /* NetJack.app */, + 1D6058910D05DD3D006BFB54 /* NetJackSlave.app */, 4BFF45120F4D59DB00106083 /* libjacknet.a */, 4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */, - 4B0772380F54018C000DC657 /* iPhoneNetMaster.app */, - 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */, + 4B0772380F54018C000DC657 /* NetJackMaster.app */, + 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */, 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */, 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */, 4BDFCD57113DB6B700D77992 /* NetJackSlave.app */, @@ -404,7 +404,7 @@ ); name = iPhoneNetSlave; productName = iPhoneNet; - productReference = 1D6058910D05DD3D006BFB54 /* NetJack.app */; + productReference = 1D6058910D05DD3D006BFB54 /* NetJackSlave.app */; productType = "com.apple.product-type.application"; }; 4B07721F0F54018C000DC657 /* iPhoneNetMaster */ = { @@ -421,7 +421,7 @@ ); name = iPhoneNetMaster; productName = iPhoneNet; - productReference = 4B0772380F54018C000DC657 /* iPhoneNetMaster.app */; + productReference = 4B0772380F54018C000DC657 /* NetJackMaster.app */; productType = "com.apple.product-type.application"; }; 4B1A940F0F49BDE000D3626B /* libjacknet */ = { @@ -489,7 +489,7 @@ ); name = iPhoneThruNet; productName = iPhoneNet; - productReference = 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */; + productReference = 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */; productType = "com.apple.product-type.application"; }; 4BDFCD3B113DB6B700D77992 /* iPhoneNetSlaveLib */ = { @@ -793,7 +793,7 @@ "\"$(SRCROOT)/build/Debug-iphonesimulator\"", ); OTHER_LDFLAGS = libcelt.a; - PRODUCT_NAME = iPhoneNetSlave; + PRODUCT_NAME = NetJackSlave; SDKROOT = iphoneos3.1.3; }; name = Debug; @@ -822,7 +822,7 @@ "\"$(SRCROOT)/build/Debug-iphonesimulator\"", ); OTHER_LDFLAGS = libcelt.a; - PRODUCT_NAME = NetJack; + PRODUCT_NAME = NetJackSlave; SDKROOT = iphoneos3.1.3; }; name = Release; @@ -837,6 +837,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( + /usr/local/include, ../../macosx/coreaudio, ../../macosx, ../../posix, @@ -848,8 +849,8 @@ "$(inherited)", "\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\"", ); - OTHER_LDFLAGS = ""; - PRODUCT_NAME = iPhoneNetMaster; + OTHER_LDFLAGS = libcelt.a; + PRODUCT_NAME = NetJackMaster; SDKROOT = iphoneos3.1.3; }; name = Debug; @@ -862,6 +863,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( + /usr/local/include, ../../macosx/coreaudio, ../../common/jack, ../../common, @@ -873,7 +875,8 @@ "$(inherited)", "\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\"", ); - PRODUCT_NAME = iPhoneNetMaster; + OTHER_LDFLAGS = libcelt.a; + PRODUCT_NAME = NetJackMaster; }; name = Release; }; @@ -1097,7 +1100,7 @@ "\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\"", ); OTHER_LDFLAGS = "-ljacknet"; - PRODUCT_NAME = iPhoneNetSlave; + PRODUCT_NAME = NetJackSlave; SDKROOT = iphoneos3.1.3; }; name = Debug; diff --git a/macosx/iphone/main_master.mm b/macosx/iphone/main_master.mm index 189ee2c7..308662f2 100644 --- a/macosx/iphone/main_master.mm +++ b/macosx/iphone/main_master.mm @@ -20,7 +20,7 @@ jack_adapter_t* adapter; float** audio_input_buffer; float** audio_output_buffer; -int buffer_size = 4096; +int buffer_size = 1024; int sample_rate = 44100; jack_master_t request = { buffer_size, sample_rate, "master" }; @@ -30,18 +30,22 @@ static void MasterAudioCallback(int frames, float** inputs, float** outputs, voi { int i; - // Copy from iPod input to network + // Copy from iPod input to network buffers for (i = 0; i < result.audio_input; i++) { memcpy(audio_output_buffer[i], inputs[i], buffer_size * sizeof(float)); } + + // Send network buffers if (jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) { printf("jack_net_master_send error..\n"); } - // Copy from network to iPod output + // Recv network buffers if (jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { printf("jack_net_master_recv error..\n"); } + + // Copy from network buffers to iPod output for (i = 0; i < result.audio_output; i++) { memcpy(outputs[i], audio_input_buffer[i], buffer_size * sizeof(float)); } @@ -57,6 +61,7 @@ int main(int argc, char *argv[]) { TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT); if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { + printf("jack_net_master_open error..\n"); return -1; } @@ -82,7 +87,7 @@ int main(int argc, char *argv[]) { } // Run until interrupted - while (1) {} + //while (1) {} /* // Quite brutal way, the application actually does not start completely, the netjack audio processing loop is used instead... @@ -105,10 +110,11 @@ int main(int argc, char *argv[]) { }; */ + int retVal = UIApplicationMain(argc, argv, nil, nil); + audio_device.Stop(); audio_device.Close(); - - int retVal = UIApplicationMain(argc, argv, nil, nil); + // Wait for application end jack_net_master_close(net); diff --git a/macosx/iphone/main_slave.mm b/macosx/iphone/main_slave.mm index 289d643c..9de14866 100644 --- a/macosx/iphone/main_slave.mm +++ b/macosx/iphone/main_slave.mm @@ -70,6 +70,7 @@ int main(int argc, char *argv[]) { //if ((net = jack_net_slave_open("169.254.112.119", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPod", &request, &result)) == 0) { + printf("jack_net_slave_open error..\n"); return -1; } From b393026e6853c8e833902ec6a38f39b9de0425b7 Mon Sep 17 00:00:00 2001 From: sletz Date: Fri, 12 Mar 2010 11:08:33 +0000 Subject: [PATCH 047/472] Capture or playback only mode now working in master mode. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3956 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetAPI.cpp | 60 +++++++++++-------- common/JackNetAdapter.cpp | 41 ++++++++----- macosx/coreaudio/JackCoreAudioDriver.cpp | 2 +- macosx/coreaudio/TiPhoneCoreAudioRenderer.cpp | 27 +++++++-- macosx/coreaudio/TiPhoneCoreAudioRenderer.h | 12 +++- .../iPhoneNet.xcodeproj/project.pbxproj | 4 -- macosx/iphone/main_master.mm | 58 +++++++++++++----- macosx/iphone/main_slave.mm | 2 +- 8 files changed, 139 insertions(+), 67 deletions(-) diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index bc25d421..c58c19cf 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -145,6 +145,10 @@ struct JackNetExtMaster : public JackNetMasterInterface { fSocket.SetPort(port); fRequest.buffer_size = request->buffer_size; fRequest.sample_rate = request->sample_rate; + fAudioCaptureBuffer = NULL; + fAudioPlaybackBuffer = NULL; + fMidiCaptureBuffer = NULL; + fMidiPlaybackBuffer = NULL; } virtual ~JackNetExtMaster() @@ -283,28 +287,36 @@ struct JackNetExtMaster : public JackNetMasterInterface { unsigned int port_index; // Set buffers - fAudioPlaybackBuffer = new float*[fParams.fSendAudioChannels]; - for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) { - fAudioPlaybackBuffer[port_index] = new float[fParams.fPeriodSize]; - fNetAudioPlaybackBuffer->SetBuffer(port_index, fAudioPlaybackBuffer[port_index]); + if (fParams.fSendAudioChannels > 0) { + fAudioCaptureBuffer = new float*[fParams.fSendAudioChannels]; + for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) { + fAudioCaptureBuffer[port_index] = new float[fParams.fPeriodSize]; + fNetAudioCaptureBuffer->SetBuffer(port_index, fAudioCaptureBuffer[port_index]); + } } - fMidiPlaybackBuffer = new JackMidiBuffer*[fParams.fSendMidiChannels]; - for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) { - fMidiPlaybackBuffer[port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize]; - fNetMidiPlaybackBuffer->SetBuffer(port_index, fMidiPlaybackBuffer[port_index]); + if (fParams.fSendMidiChannels > 0) { + fMidiCaptureBuffer = new JackMidiBuffer*[fParams.fSendMidiChannels]; + for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) { + fMidiCaptureBuffer[port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize]; + fNetMidiCaptureBuffer->SetBuffer(port_index, fMidiCaptureBuffer[port_index]); + } } - fAudioCaptureBuffer = new float*[fParams.fReturnAudioChannels]; - for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) { - fAudioCaptureBuffer[port_index] = new float[fParams.fPeriodSize]; - fNetAudioCaptureBuffer->SetBuffer(port_index, fAudioCaptureBuffer[port_index]); - } + if (fParams.fReturnAudioChannels > 0) { + fAudioPlaybackBuffer = new float*[fParams.fReturnAudioChannels]; + for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) { + fAudioPlaybackBuffer[port_index] = new float[fParams.fPeriodSize]; + fNetAudioPlaybackBuffer->SetBuffer(port_index, fAudioPlaybackBuffer[port_index]); + } + } - fMidiCaptureBuffer = new JackMidiBuffer*[fParams.fReturnMidiChannels]; - for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) { - fMidiCaptureBuffer[port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize]; - fNetMidiCaptureBuffer->SetBuffer(port_index, fMidiCaptureBuffer[port_index]); + if (fParams.fReturnMidiChannels > 0) { + fMidiPlaybackBuffer = new JackMidiBuffer*[fParams.fReturnMidiChannels]; + for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) { + fMidiPlaybackBuffer[port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize]; + fNetMidiPlaybackBuffer->SetBuffer(port_index, fMidiPlaybackBuffer[port_index]); + } } } @@ -344,14 +356,13 @@ struct JackNetExtMaster : public JackNetMasterInterface { int Read(int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer) { try { - assert((unsigned int)audio_input == fParams.fSendAudioChannels); - int port_index; + assert((unsigned int)audio_input == fParams.fReturnAudioChannels); - for (port_index = 0; port_index < audio_input; port_index++) { + for (int port_index = 0; port_index < audio_input; port_index++) { fNetAudioPlaybackBuffer->SetBuffer(port_index, audio_input_buffer[port_index]); } - for (port_index = 0; port_index < midi_input; port_index++) { + for (int port_index = 0; port_index < midi_input; port_index++) { fNetMidiPlaybackBuffer->SetBuffer(port_index, ((JackMidiBuffer**)midi_input_buffer)[port_index]); } @@ -370,14 +381,13 @@ struct JackNetExtMaster : public JackNetMasterInterface { int Write(int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer) { try { - assert((unsigned int)audio_output == fParams.fReturnAudioChannels); - int port_index; + assert((unsigned int)audio_output == fParams.fSendAudioChannels); - for (port_index = 0; port_index < audio_output; port_index++) { + for (int port_index = 0; port_index < audio_output; port_index++) { fNetAudioCaptureBuffer->SetBuffer(port_index, audio_output_buffer[port_index]); } - for (port_index = 0; port_index < midi_output; port_index++) { + for (int port_index = 0; port_index < midi_output; port_index++) { fNetMidiCaptureBuffer->SetBuffer(port_index, ((JackMidiBuffer**)midi_output_buffer)[port_index]); } diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index b44ba331..d33572cd 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -40,8 +40,8 @@ namespace Jack fSocket.GetName ( fParams.fSlaveNetName ); fParams.fMtu = DEFAULT_MTU; fParams.fTransportSync = 0; - fParams.fSendAudioChannels = 2; - fParams.fReturnAudioChannels = 2; + int send_audio = -1; + int return_audio = -1; fParams.fSendMidiChannels = 0; fParams.fReturnMidiChannels = 0; fParams.fSampleRate = sample_rate; @@ -71,10 +71,10 @@ namespace Jack fParams.fMtu = param->value.i; break; case 'C' : - fParams.fSendAudioChannels = param->value.i; + send_audio = param->value.i; break; case 'P' : - fParams.fReturnAudioChannels = param->value.i; + return_audio = param->value.i; break; case 'n' : strncpy ( fParams.fName, param->value.str, JACK_CLIENT_NAME_SIZE ); @@ -105,7 +105,13 @@ namespace Jack //set the socket parameters fSocket.SetPort ( port ); fSocket.SetAddress ( fMulticastIP, port ); - + + // If not set, takes deafault + fParams.fSendAudioChannels = (send_audio == -1) ? 2 : send_audio; + + // If not set, takes deafault + fParams.fReturnAudioChannels = (return_audio == -1) ? 2 : return_audio; + //set the audio adapter interface channel values SetInputs ( fParams.fSendAudioChannels ); SetOutputs ( fParams.fReturnAudioChannels ); @@ -215,17 +221,22 @@ namespace Jack } //set buffers - fSoftCaptureBuffer = new sample_t*[fCaptureChannels]; - for ( port_index = 0; port_index < fCaptureChannels; port_index++ ) - { - fSoftCaptureBuffer[port_index] = new sample_t[fParams.fPeriodSize]; - fNetAudioCaptureBuffer->SetBuffer ( port_index, fSoftCaptureBuffer[port_index] ); + if (fCaptureChannels > 0) { + fSoftCaptureBuffer = new sample_t*[fCaptureChannels]; + for ( port_index = 0; port_index < fCaptureChannels; port_index++ ) + { + fSoftCaptureBuffer[port_index] = new sample_t[fParams.fPeriodSize]; + fNetAudioCaptureBuffer->SetBuffer ( port_index, fSoftCaptureBuffer[port_index] ); + } } - fSoftPlaybackBuffer = new sample_t*[fPlaybackChannels]; - for ( port_index = 0; port_index < fCaptureChannels; port_index++ ) - { - fSoftPlaybackBuffer[port_index] = new sample_t[fParams.fPeriodSize]; - fNetAudioPlaybackBuffer->SetBuffer ( port_index, fSoftPlaybackBuffer[port_index] ); + + if (fPlaybackChannels > 0) { + fSoftPlaybackBuffer = new sample_t*[fPlaybackChannels]; + for ( port_index = 0; port_index < fPlaybackChannels; port_index++ ) + { + fSoftPlaybackBuffer[port_index] = new sample_t[fParams.fPeriodSize]; + fNetAudioPlaybackBuffer->SetBuffer ( port_index, fSoftPlaybackBuffer[port_index] ); + } } //set audio adapter parameters diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 6f053008..8b829d27 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -1983,7 +1983,7 @@ extern "C" bool capture = false; bool playback = false; int chan_in = -1; // Default: if not explicitely set, then max possible will be used... - int chan_out = -1; // Default: ifà not explicitely set, then max possible will be used... + int chan_out = -1; // Default: if not explicitely set, then max possible will be used... bool monitor = false; const char* capture_driver_uid = ""; const char* playback_driver_uid = ""; diff --git a/macosx/coreaudio/TiPhoneCoreAudioRenderer.cpp b/macosx/coreaudio/TiPhoneCoreAudioRenderer.cpp index 07c67969..d44a9899 100644 --- a/macosx/coreaudio/TiPhoneCoreAudioRenderer.cpp +++ b/macosx/coreaudio/TiPhoneCoreAudioRenderer.cpp @@ -80,14 +80,14 @@ OSStatus TiPhoneCoreAudioRenderer::Render(void *inRefCon, AudioBufferList *ioData) { TiPhoneCoreAudioRendererPtr renderer = (TiPhoneCoreAudioRendererPtr)inRefCon; - AudioUnitRender(renderer->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, ioData); + AudioUnitRender(renderer->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, renderer->fCAInputData); float coef = float(LONG_MAX); float inv_coef = 1.f/float(LONG_MAX); for (int chan = 0; chan < renderer->fDevNumInChans; chan++) { for (int frame = 0; frame < inNumberFrames; frame++) { - renderer->fInChannel[chan][frame] = float(((long*)ioData->mBuffers[chan].mData)[frame]) * inv_coef; + renderer->fInChannel[chan][frame] = float(((int*)renderer->fCAInputData->mBuffers[chan].mData)[frame]) * inv_coef; } } @@ -95,7 +95,7 @@ OSStatus TiPhoneCoreAudioRenderer::Render(void *inRefCon, for (int chan = 0; chan < renderer->fDevNumOutChans; chan++) { for (int frame = 0; frame < inNumberFrames; frame++) { - ((long*)ioData->mBuffers[chan].mData)[frame] = long(renderer->fOutChannel[chan][frame] * coef); + ((int*)ioData->mBuffers[chan].mData)[frame] = int(renderer->fOutChannel[chan][frame] * coef); } } @@ -326,7 +326,7 @@ int TiPhoneCoreAudioRenderer::Open(int bufferSize, int samplerate) printError(err1); } } - + if (fDevNumInChans > 0 && fDevNumOutChans == 0) { AURenderCallbackStruct output; output.inputProc = Render; @@ -348,6 +348,25 @@ int TiPhoneCoreAudioRenderer::Open(int bufferSize, int samplerate) goto error; } } + + // Prepare buffers + fCAInputData = (AudioBufferList*)malloc(sizeof(UInt32) + fDevNumInChans * sizeof(AudioBuffer)); + fCAInputData->mNumberBuffers = fDevNumInChans; + for (int i = 0; i < fDevNumInChans; i++) { + fCAInputData->mBuffers[i].mNumberChannels = 1; + fCAInputData->mBuffers[i].mDataByteSize = bufferSize * sizeof(int); + fCAInputData->mBuffers[i].mData = malloc(bufferSize * sizeof(int)); + } + + /* + // Add listeners + err1 = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDeviceProcessorOverload, DeviceNotificationCallback, this); + if (err != noErr) { + jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDeviceProcessorOverload"); + printError(err); + return -1; + } + */ return NO_ERR; diff --git a/macosx/coreaudio/TiPhoneCoreAudioRenderer.h b/macosx/coreaudio/TiPhoneCoreAudioRenderer.h index 1bd50e15..a5c47ab7 100644 --- a/macosx/coreaudio/TiPhoneCoreAudioRenderer.h +++ b/macosx/coreaudio/TiPhoneCoreAudioRenderer.h @@ -41,6 +41,8 @@ class TiPhoneCoreAudioRenderer int fDevNumInChans; int fDevNumOutChans; + + AudioBufferList* fCAInputData; float* fInChannel[MAX_CHANNELS]; float* fOutChannel[MAX_CHANNELS]; @@ -57,7 +59,7 @@ class TiPhoneCoreAudioRenderer public: TiPhoneCoreAudioRenderer(int input, int output) - :fDevNumInChans(input), fDevNumOutChans(output), fAudioCallback(NULL), fCallbackArg(NULL) + :fAudioCallback(NULL), fCallbackArg(NULL), fDevNumInChans(input), fDevNumOutChans(output), fCAInputData(NULL) { memset(fInChannel, 0, sizeof(float*) * MAX_CHANNELS); memset(fOutChannel, 0, sizeof(float*) * MAX_CHANNELS); @@ -70,6 +72,7 @@ class TiPhoneCoreAudioRenderer fOutChannel[i] = new float[8192]; } } + virtual ~TiPhoneCoreAudioRenderer() { for (int i = 0; i < fDevNumInChans; i++) { @@ -79,6 +82,13 @@ class TiPhoneCoreAudioRenderer for (int i = 0; i < fDevNumOutChans; i++) { delete[] fOutChannel[i]; } + + if (fCAInputData) { + for (int i = 0; i < fDevNumInChans; i++) { + free(fCAInputData->mBuffers[i].mData); + } + free(fCAInputData); + } } int Open(int bufferSize, int sampleRate); diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj index 1b84bcbb..95548e7e 100755 --- a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -184,9 +184,7 @@ 4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "iphone-faust.mm"; sourceTree = SOURCE_ROOT; }; 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneThruNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BCF75F610BC30140082C526 /* audio_thru.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = audio_thru.mm; sourceTree = SOURCE_ROOT; }; - 4BDFCCD7113DB30500D77992 /* Info copy.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info copy.plist"; sourceTree = ""; }; 4BDFCD57113DB6B700D77992 /* NetJackSlave.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetJackSlave.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 4BDFCD59113DB6B700D77992 /* Info copy 2.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info copy 2.plist"; sourceTree = ""; }; 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; }; 4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioAdapterInterface.h; path = ../../common/JackAudioAdapterInterface.h; sourceTree = SOURCE_ROOT; }; 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackResampler.cpp; path = ../../common/JackResampler.cpp; sourceTree = SOURCE_ROOT; }; @@ -354,8 +352,6 @@ 28AD733E0D9D9553002E5188 /* MainWindow.xib */, 8D1107310486CEB800E47090 /* Info.plist */, 4BC9C1D31135AA1800D22670 /* iPhoneNetMasterAppl-Info.plist */, - 4BDFCCD7113DB30500D77992 /* Info copy.plist */, - 4BDFCD59113DB6B700D77992 /* Info copy 2.plist */, ); name = Resources; sourceTree = ""; diff --git a/macosx/iphone/main_master.mm b/macosx/iphone/main_master.mm index 308662f2..3f58a076 100644 --- a/macosx/iphone/main_master.mm +++ b/macosx/iphone/main_master.mm @@ -17,37 +17,59 @@ jack_net_master_t* net; jack_adapter_t* adapter; -float** audio_input_buffer; -float** audio_output_buffer; +float** audio_input_buffer = NULL; +float** audio_output_buffer = NULL; -int buffer_size = 1024; -int sample_rate = 44100; +int buffer_size = 512; +int sample_rate = 32000; +//int sample_rate = 32000; jack_master_t request = { buffer_size, sample_rate, "master" }; jack_slave_t result; +static void MixAudio(float** dst, float** src1, float** src2, int channels, int buffer_size) +{ + for (int chan = 0; chan < channels; chan++) { + for (int frame = 0; frame < buffer_size; frame++) { + dst[chan][frame] = src1[chan][frame] + src2[chan][frame]; + } + } +} + static void MasterAudioCallback(int frames, float** inputs, float** outputs, void* arg) { int i; + /* // Copy from iPod input to network buffers for (i = 0; i < result.audio_input; i++) { - memcpy(audio_output_buffer[i], inputs[i], buffer_size * sizeof(float)); + memcpy(audio_input_buffer[i], inputs[i], buffer_size * sizeof(float)); + } + */ + + /* + // Copy from network out buffers to network in buffers (audio thru) + for (i = 0; i < result.audio_input; i++) { + memcpy(audio_input_buffer[i], audio_output_buffer[i], buffer_size * sizeof(float)); } + */ + + // Mix iPod input and network in buffers to network out buffers + MixAudio(audio_input_buffer, inputs, audio_output_buffer, result.audio_input, buffer_size); // Send network buffers - if (jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) { + if (jack_net_master_send(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { printf("jack_net_master_send error..\n"); } // Recv network buffers - if (jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { + if (jack_net_master_recv(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) { printf("jack_net_master_recv error..\n"); } // Copy from network buffers to iPod output for (i = 0; i < result.audio_output; i++) { - memcpy(outputs[i], audio_input_buffer[i], buffer_size * sizeof(float)); + memcpy(outputs[i], audio_output_buffer[i], buffer_size * sizeof(float)); } } @@ -58,22 +80,26 @@ int main(int argc, char *argv[]) { int i; int wait_usec = (unsigned long)((((float)buffer_size) / ((float)sample_rate)) * 1000000.0f); - TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT); - if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { printf("jack_net_master_open error..\n"); return -1; } + TiPhoneCoreAudioRenderer audio_device(result.audio_input, result.audio_output); + // Allocate buffers - audio_input_buffer = (float**)calloc(result.audio_input, sizeof(float*)); - for (i = 0; i < result.audio_input; i++) { - audio_input_buffer[i] = (float*)(calloc(buffer_size, sizeof(float))); + if (result.audio_input > 0) { + audio_input_buffer = (float**)calloc(result.audio_input, sizeof(float*)); + for (i = 0; i < result.audio_input; i++) { + audio_input_buffer[i] = (float*)(calloc(buffer_size, sizeof(float))); + } } - audio_output_buffer = (float**)calloc(result.audio_output, sizeof(float*)); - for (i = 0; i < result.audio_output; i++) { - audio_output_buffer[i] = (float*)(calloc(buffer_size, sizeof(float))); + if (result.audio_output > 0) { + audio_output_buffer = (float**)calloc(result.audio_output, sizeof(float*)); + for (i = 0; i < result.audio_output; i++) { + audio_output_buffer[i] = (float*)(calloc(buffer_size, sizeof(float))); + } } if (audio_device.Open(buffer_size, sample_rate) < 0) { diff --git a/macosx/iphone/main_slave.mm b/macosx/iphone/main_slave.mm index 9de14866..74d1b91d 100644 --- a/macosx/iphone/main_slave.mm +++ b/macosx/iphone/main_slave.mm @@ -70,7 +70,7 @@ int main(int argc, char *argv[]) { //if ((net = jack_net_slave_open("169.254.112.119", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPod", &request, &result)) == 0) { - printf("jack_net_slave_open error..\n"); + printf("jack_net_master_open error..\n"); return -1; } From d43ba8b98ee358b6efc73c5191af502b909688e6 Mon Sep 17 00:00:00 2001 From: sletz Date: Fri, 12 Mar 2010 21:15:05 +0000 Subject: [PATCH 048/472] Add parameter to chose sample encoder type and quality. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3957 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetAPI.cpp | 16 ++- common/JackNetInterface.cpp | 113 ++++++++++++++---- common/JackNetManager.cpp | 1 - common/JackNetTool.cpp | 31 +++-- common/JackNetTool.h | 13 +- common/jack/net.h | 11 +- .../iPhoneNet.xcodeproj/project.pbxproj | 6 +- macosx/iphone/main_master.mm | 10 +- macosx/iphone/main_slave.mm | 2 +- 9 files changed, 153 insertions(+), 50 deletions(-) diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index c58c19cf..137f3da9 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -40,8 +40,15 @@ extern "C" JackNormalMode = 'n', JackSlowMode = 's', }; + + enum JackNetEncoder { + + JackFloatEncoder = 0, + JackIntEncoder = 1, + JackCeltEncoder = 2, + }; - typedef struct { + typedef struct { int audio_input; int audio_output; @@ -49,6 +56,8 @@ extern "C" int midi_output; int mtu; int time_out; // in millisecond, -1 means in infinite + int encoder; + int kbps; // KB per second for CELT encoder char mode; } jack_slave_t; @@ -256,7 +265,7 @@ struct JackNetExtMaster : public JackNetMasterInterface { // Settings fSocket.GetName(fParams.fMasterNetName); fParams.fID = 1; - fParams.fBitdepth = 0; + fParams.fSampleEncoder = JackFloatEncoder; fParams.fPeriodSize = fRequest.buffer_size; fParams.fSampleRate = fRequest.sample_rate; @@ -463,7 +472,8 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf fParams.fSendMidiChannels = request->midi_input; fParams.fReturnMidiChannels = request->midi_output; fParams.fNetworkMode = request->mode; - fParams.fSlaveSyncMode = 1; + fParams.fSampleEncoder = request->encoder; + fParams.fKBps = request->kbps; fConnectTimeOut = request->time_out; // Create name with hostname and client name diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 9dc6b583..4247056d 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -128,7 +128,6 @@ namespace Jack fTxHeader.fID = fParams.fID; fTxHeader.fCycle = 0; fTxHeader.fSubCycle = 0; - fTxHeader.fBitdepth = fParams.fBitdepth; fTxHeader.fIsLastPckt = 0; //RX header init @@ -136,7 +135,6 @@ namespace Jack fRxHeader.fID = fParams.fID; fRxHeader.fCycle = 0; fRxHeader.fSubCycle = 0; - fRxHeader.fBitdepth = fParams.fBitdepth; fRxHeader.fIsLastPckt = 0; //network buffers @@ -244,24 +242,48 @@ namespace Jack assert ( fNetMidiPlaybackBuffer ); try { - //audio net buffers - #ifdef CELT - if (fParams.fSendAudioChannels) - fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); + + //audio net buffers + if (fParams.fSendAudioChannels) { + + switch (fParams.fSampleEncoder) { + + case JackFloatEncoder: + fNetAudioCaptureBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); + break; + + case JackIntEncoder: + fNetAudioCaptureBuffer = new NetIntAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); + break; + + case JackCeltEncoder: + #ifdef CELT + fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData, fParams.fKBps ); + #endif + break; + } + } - if (fParams.fReturnAudioChannels) - fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); + if (fParams.fReturnAudioChannels) { + + switch (fParams.fSampleEncoder) { + + case JackFloatEncoder: + fNetAudioPlaybackBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); + break; + + case JackIntEncoder: + fNetAudioPlaybackBuffer = new NetIntAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); + break; + + case JackCeltEncoder: + #ifdef CELT + fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData, fParams.fKBps ); + #endif + break; + } + } - //fNetAudioCaptureBuffer = new NetIntAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); - //fNetAudioPlaybackBuffer = new NetIntAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); - #else - fNetAudioCaptureBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); - fNetAudioPlaybackBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); - #endif - - //fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); - //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); - } catch (exception&) { jack_error("NetAudioBuffer allocation error..."); return false; @@ -764,11 +786,15 @@ namespace Jack try { #ifdef CELT - if (fParams.fSendAudioChannels) - fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); + if (fParams.fSendAudioChannels) { + // fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); + fNetAudioCaptureBuffer = new NetIntAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); + } - if (fParams.fReturnAudioChannels) - fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); + if (fParams.fReturnAudioChannels) { + //fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); + fNetAudioPlaybackBuffer = new NetIntAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); + } // fNetAudioCaptureBuffer = new NetIntAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); // fNetAudioPlaybackBuffer = new NetIntAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); @@ -779,6 +805,49 @@ namespace Jack //fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); #endif + + + //audio net buffers + if (fParams.fSendAudioChannels) { + + switch (fParams.fSampleEncoder) { + + case JackFloatEncoder: + fNetAudioCaptureBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); + break; + + case JackIntEncoder: + fNetAudioCaptureBuffer = new NetIntAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); + break; + + case JackCeltEncoder: + #ifdef CELT + fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData, fParams.fKBps ); + #endif + break; + } + } + + if (fParams.fReturnAudioChannels) { + + switch (fParams.fSampleEncoder) { + + case JackFloatEncoder: + fNetAudioPlaybackBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); + break; + + case JackIntEncoder: + fNetAudioPlaybackBuffer = new NetIntAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData); + break; + + case JackCeltEncoder: + #ifdef CELT + fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData, fParams.fKBps ); + #endif + break; + } + } + } catch (exception&) { jack_error("NetAudioBuffer allocation error..."); return false; diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index d0961935..123c513a 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -658,7 +658,6 @@ namespace Jack params.fID = ++fGlobalID; params.fSampleRate = jack_get_sample_rate ( fManagerClient ); params.fPeriodSize = jack_get_buffer_size ( fManagerClient ); - params.fBitdepth = 0; SetSlaveName ( params ); //create a new master and add it to the list diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index d4e3fba3..210f1f94 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -254,7 +254,7 @@ namespace Jack #define KPS 32 #define KPS_DIV 8 - NetCeltAudioBuffer::NetCeltAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) + NetCeltAudioBuffer::NetCeltAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer, int kbps ) : fNetBuffer(net_buffer) { int res1, res2; @@ -297,8 +297,8 @@ namespace Jack celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); */ - //fCompressedSizeByte = (KPS * params->fPeriodSize * 1024 / params->fSampleRate / 8)&(~1); - fCompressedSizeByte = (params->fPeriodSize * sizeof(sample_t)) / KPS_DIV; // TODO + fCompressedSizeByte = (kbps * params->fPeriodSize * 1024) / (params->fSampleRate * 8); + //fCompressedSizeByte = (params->fPeriodSize * sizeof(sample_t)) / KPS_DIV; // TODO fCompressedBuffer = new unsigned char* [fNPorts]; for (int port_index = 0; port_index < fNPorts; port_index++) @@ -649,7 +649,7 @@ namespace Jack dst_params->fReturnMidiChannels = htonl ( src_params->fReturnMidiChannels ); dst_params->fSampleRate = htonl ( src_params->fSampleRate ); dst_params->fPeriodSize = htonl ( src_params->fPeriodSize ); - dst_params->fBitdepth = htonl ( src_params->fBitdepth ); + dst_params->fSampleEncoder = htonl ( src_params->fSampleEncoder ); dst_params->fSlaveSyncMode = htonl ( src_params->fSlaveSyncMode ); } @@ -666,14 +666,26 @@ namespace Jack dst_params->fReturnMidiChannels = ntohl ( src_params->fReturnMidiChannels ); dst_params->fSampleRate = ntohl ( src_params->fSampleRate ); dst_params->fPeriodSize = ntohl ( src_params->fPeriodSize ); - dst_params->fBitdepth = ntohl ( src_params->fBitdepth ); + dst_params->fSampleEncoder = ntohl ( src_params->fSampleEncoder ); dst_params->fSlaveSyncMode = ntohl ( src_params->fSlaveSyncMode ); } SERVER_EXPORT void SessionParamsDisplay ( session_params_t* params ) { - char bitdepth[16]; - ( params->fBitdepth ) ? sprintf ( bitdepth, "%u", params->fBitdepth ) : sprintf ( bitdepth, "%s", "float" ); + char encoder[16]; + switch ( params->fSampleEncoder ) + { + case JackFloatEncoder: + strcpy ( encoder, "float" ); + break; + case JackIntEncoder: + strcpy ( encoder, "integer" ); + break; + case JackCeltEncoder: + strcpy ( encoder, "CELT" ); + break; + } + char mode[8]; switch ( params->fNetworkMode ) { @@ -699,7 +711,7 @@ namespace Jack jack_info ( "Return channels (audio - midi) : %d - %d", params->fReturnAudioChannels, params->fReturnMidiChannels ); jack_info ( "Sample rate : %u frames per second", params->fSampleRate ); jack_info ( "Period size : %u frames per period", params->fPeriodSize ); - jack_info ( "Bitdepth : %s", bitdepth ); + jack_info ( "SampleEncoder : %u", params->fSampleEncoder ); jack_info ( "Slave mode : %s", ( params->fSlaveSyncMode ) ? "sync" : "async" ); jack_info ( "Network mode : %s", mode ); jack_info ( "****************************************************" ); @@ -753,7 +765,6 @@ namespace Jack { memcpy(dst_header, src_header, sizeof(packet_header_t)); dst_header->fID = htonl ( src_header->fID ); - dst_header->fBitdepth = htonl ( src_header->fBitdepth ); dst_header->fNumPacket = htonl ( src_header->fNumPacket ); dst_header->fPacketSize = htonl ( src_header->fPacketSize ); dst_header->fCycle = htonl ( src_header->fCycle ); @@ -765,7 +776,6 @@ namespace Jack { memcpy(dst_header, src_header, sizeof(packet_header_t)); dst_header->fID = ntohl ( src_header->fID ); - dst_header->fBitdepth = ntohl ( src_header->fBitdepth ); dst_header->fNumPacket = ntohl ( src_header->fNumPacket ); dst_header->fPacketSize = ntohl ( src_header->fPacketSize ); dst_header->fCycle = ntohl ( src_header->fCycle ); @@ -776,7 +786,6 @@ namespace Jack SERVER_EXPORT void PacketHeaderDisplay ( packet_header_t* header ) { char bitdepth[16]; - ( header->fBitdepth ) ? sprintf ( bitdepth, "%u", header->fBitdepth ) : sprintf ( bitdepth, "%s", "float" ); jack_info ( "********************Header********************" ); jack_info ( "Data type : %c", header->fDataType ); jack_info ( "Data stream : %c", header->fDataStream ); diff --git a/common/JackNetTool.h b/common/JackNetTool.h index 6ecabe4c..63138f51 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -47,6 +47,13 @@ namespace Jack typedef struct sockaddr socket_address_t; typedef struct in_addr address_t; typedef jack_default_audio_sample_t sample_t; + + enum JackNetEncoder { + + JackFloatEncoder = 0, + JackIntEncoder = 1, + JackCeltEncoder = 2, + }; //session params ****************************************************************************** @@ -87,7 +94,8 @@ namespace Jack uint32_t fReturnMidiChannels; //number of slave->master midi channels uint32_t fSampleRate; //session sample rate uint32_t fPeriodSize; //period size - uint32_t fBitdepth; //samples bitdepth (unused) + uint32_t fSampleEncoder; //samples encoder + uint32_t fKBps; // KB per second for CELT encoder uint32_t fSlaveSyncMode; //is the slave in sync mode ? char fNetworkMode; //fast, normal or slow mode }; @@ -157,7 +165,6 @@ namespace Jack char fDataType; //a for audio, m for midi and s for sync char fDataStream; //s for send, r for return uint32_t fID; //unique ID of the slave - uint32_t fBitdepth; //bitdepth of the data samples uint32_t fNumPacket; //number of data packets of the cycle uint32_t fPacketSize; //packet size in bytes uint32_t fCycle; //process cycle counter @@ -584,7 +591,7 @@ namespace Jack public: - NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer); + NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps); ~NetCeltAudioBuffer(); // needed size in bytes for an entire cycle diff --git a/common/jack/net.h b/common/jack/net.h index 44e71c44..09ab5338 100644 --- a/common/jack/net.h +++ b/common/jack/net.h @@ -35,12 +35,19 @@ extern "C" #define SOCKET_ERROR -1 - enum JackNetMode { +enum JackNetMode { JackFastMode = 'f', JackNormalMode = 'n', JackSlowMode = 's', }; + +enum JackNetEncoder { + + JackFloatEncoder = 0, + JackIntEncoder = 1, + JackCeltEncoder = 2, +}; typedef struct { @@ -50,6 +57,8 @@ typedef struct { int midi_output; // to master or from slave int mtu; int time_out; // in second, -1 means in infinite + int encoder; + int kbps; // KB per second for CELT encoder char mode; } jack_slave_t; diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj index 95548e7e..a5db89b8 100755 --- a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -182,7 +182,7 @@ 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaust.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BCB37D5112D64B4008C7BC1 /* HardwareClock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HardwareClock.cpp; sourceTree = SOURCE_ROOT; }; 4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "iphone-faust.mm"; sourceTree = SOURCE_ROOT; }; - 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneThruNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BCF75F610BC30140082C526 /* audio_thru.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = audio_thru.mm; sourceTree = SOURCE_ROOT; }; 4BDFCD57113DB6B700D77992 /* NetJackSlave.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetJackSlave.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; }; @@ -292,7 +292,7 @@ 4BFF45120F4D59DB00106083 /* libjacknet.a */, 4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */, 4B0772380F54018C000DC657 /* NetJackMaster.app */, - 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */, + 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */, 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */, 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */, 4BDFCD57113DB6B700D77992 /* NetJackSlave.app */, @@ -485,7 +485,7 @@ ); name = iPhoneThruNet; productName = iPhoneNet; - productReference = 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */; + productReference = 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */; productType = "com.apple.product-type.application"; }; 4BDFCD3B113DB6B700D77992 /* iPhoneNetSlaveLib */ = { diff --git a/macosx/iphone/main_master.mm b/macosx/iphone/main_master.mm index 3f58a076..86fec8b3 100644 --- a/macosx/iphone/main_master.mm +++ b/macosx/iphone/main_master.mm @@ -20,8 +20,8 @@ jack_adapter_t* adapter; float** audio_input_buffer = NULL; float** audio_output_buffer = NULL; -int buffer_size = 512; -int sample_rate = 32000; +int buffer_size = 1024; +int sample_rate = 22050; //int sample_rate = 32000; jack_master_t request = { buffer_size, sample_rate, "master" }; @@ -40,12 +40,12 @@ static void MasterAudioCallback(int frames, float** inputs, float** outputs, voi { int i; - /* + // Copy from iPod input to network buffers for (i = 0; i < result.audio_input; i++) { memcpy(audio_input_buffer[i], inputs[i], buffer_size * sizeof(float)); } - */ + /* // Copy from network out buffers to network in buffers (audio thru) @@ -55,7 +55,7 @@ static void MasterAudioCallback(int frames, float** inputs, float** outputs, voi */ // Mix iPod input and network in buffers to network out buffers - MixAudio(audio_input_buffer, inputs, audio_output_buffer, result.audio_input, buffer_size); + //MixAudio(audio_input_buffer, inputs, audio_output_buffer, result.audio_input, buffer_size); // Send network buffers if (jack_net_master_send(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { diff --git a/macosx/iphone/main_slave.mm b/macosx/iphone/main_slave.mm index 74d1b91d..b3eea568 100644 --- a/macosx/iphone/main_slave.mm +++ b/macosx/iphone/main_slave.mm @@ -65,7 +65,7 @@ int main(int argc, char *argv[]) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - jack_slave_t request = { NUM_OUTPUT, NUM_INPUT, 0, 0, WIFI_MTU, -1, JackSlowMode }; + jack_slave_t request = { NUM_OUTPUT, NUM_INPUT, 0, 0, WIFI_MTU, -1, JackCeltEncoder, 128, JackSlowMode }; jack_master_t result; //if ((net = jack_net_slave_open("169.254.112.119", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { From 07a0c94b93093971d65b4f862e4fcc3e436a3393 Mon Sep 17 00:00:00 2001 From: sletz Date: Sat, 13 Mar 2010 21:46:50 +0000 Subject: [PATCH 049/472] More doc in net.h header. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3959 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetAPI.cpp | 7 +- common/JackNetTool.cpp | 1 - common/jack/net.h | 55 ++- macosx/iphone/MainWindow.xib | 316 ++++++++++++++++-- .../iPhoneNet.xcodeproj/project.pbxproj | 10 +- macosx/iphone/main_master.mm | 11 +- macosx/iphone/main_slave.mm | 9 +- 7 files changed, 340 insertions(+), 69 deletions(-) diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 137f3da9..f83cab53 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -448,9 +448,9 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf int fConnectTimeOut; JackNetExtSlave(const char* ip, - int port, - const char* name, - jack_slave_t* request) + int port, + const char* name, + jack_slave_t* request) :fThread(this), fProcessCallback(NULL),fProcessArg(NULL), fShutdownCallback(NULL), fShutdownArg(NULL), @@ -542,7 +542,6 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf return 0; } - void AllocPorts() { unsigned int port_index; diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index 210f1f94..5a9cf42d 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -476,7 +476,6 @@ namespace Jack fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets; fSubPeriodSize = fSubPeriodBytesSize / sizeof(short); - //fLastSubPeriodBytesSize = fSubPeriodBytesSize + (fCompressedSizeByte - (fSubPeriodBytesSize * fNumPackets)); fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets; fLastSubPeriodSize = fLastSubPeriodBytesSize / sizeof(short); diff --git a/common/jack/net.h b/common/jack/net.h index 09ab5338..8a5894c7 100644 --- a/common/jack/net.h +++ b/common/jack/net.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2009 Grame + Copyright (C) 2009-2010 Grame This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -44,9 +44,9 @@ enum JackNetMode { enum JackNetEncoder { - JackFloatEncoder = 0, - JackIntEncoder = 1, - JackCeltEncoder = 2, + JackFloatEncoder = 0, // Samples are transmitted as float + JackIntEncoder = 1, // Samples are transmitted as 16 bits integer + JackCeltEncoder = 2, // Samples are transmitted using CELT codec (http://www.celt-codec.org/) }; typedef struct { @@ -55,11 +55,11 @@ typedef struct { int audio_output; // to master or from slave int midi_input; // from master or to slave int midi_output; // to master or from slave - int mtu; + int mtu; // Network Maximum Transmission Unit int time_out; // in second, -1 means in infinite - int encoder; + int encoder; // Encoder type (one of JackNetEncoder) int kbps; // KB per second for CELT encoder - char mode; + char mode; } jack_slave_t; @@ -99,14 +99,14 @@ int jack_net_slave_close(jack_net_slave_t* net); /** * Prototype for Process callback. * @param nframes buffer size - * @param audio_input number of audio inputs - * @param audio_input_buffer an array of audio input buffers + * @param audio_input number of audio inputs + * @param audio_input_buffer an array of audio input buffers (from master) * @param midi_input number of MIDI inputs - * @param midi_input_buffer an array of MIDI input buffers + * @param midi_input_buffer an array of MIDI input buffers (from master) * @param audio_output number of audio outputs - * @param audio_output_buffer an array of audio output buffers + * @param audio_output_buffer an array of audio output buffers (to master) * @param midi_output number of MIDI outputs - * @param midi_output_buffer an array of MIDI output buffers + * @param midi_output_buffer an array of MIDI output buffers (to master) * @param arg pointer to a client supplied structure supplied by jack_set_net_process_callback(). * * @return zero on success, non-zero on error @@ -242,7 +242,7 @@ int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_ /** * Send sync and data to the network * @param net the network connection - * @param audio_output number of audio ouputs + * @param audio_output number of audio outputs * @param audio_output_buffer an array of audio output buffers * @param midi_output number of MIDI ouputs * @param midi_output_buffer an array of MIDI output buffers @@ -261,6 +261,12 @@ typedef struct _jack_adapter jack_adapter_t; /** * Create an adapter. + * @param input number of audio inputs + * @param output of audio outputs + * @param host_buffer_size the host buffer size in frames + * @param host_sample_rate the host buffer sample rate + * @param adapted_buffer_size the adapted buffer size in frames + * @param adapted_sample_rate the adapted buffer sample rate * * @return 0 on success, otherwise a non-zero error code */ @@ -272,29 +278,42 @@ jack_adapter_t* jack_create_adapter(int input, int output, /** * Destroy an adapter. + * @param adapter the adapter to be destroyed * * @return 0 on success, otherwise a non-zero error code */ int jack_destroy_adapter(jack_adapter_t* adapter); - +/** + * Flush internal state of an adapter. + * @param adapter the adapter to be flushed + * + * @return 0 on success, otherwise a non-zero error code + */ void jack_flush_adapter(jack_adapter_t* adapter); /** - * Push input to and pull output from ringbuffer + * Push input to and pull output from adapter ringbuffer + * @param adapter the adapter + * @param input an array of audio input buffers + * @param output an array of audio ouput buffers + * @param frames number of frames * * @return 0 on success, otherwise a non-zero error code */ int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); /** - * Pull input to and push output from ringbuffer - * + * Pull input to and push output from adapter ringbuffer + * @param adapter the adapter + * @param input an array of audio input buffers + * @param output an array of audio ouput buffers + * @param frames number of frames + * * @return 0 on success, otherwise a non-zero error code */ int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); - #ifdef __cplusplus } #endif diff --git a/macosx/iphone/MainWindow.xib b/macosx/iphone/MainWindow.xib index 175cb7bd..a36742fe 100644 --- a/macosx/iphone/MainWindow.xib +++ b/macosx/iphone/MainWindow.xib @@ -1,11 +1,15 @@ - + 528 - 9E17 - 672 - 949.33 - 352.00 + 10C540 + 740 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + YES @@ -14,6 +18,15 @@ YES com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + YES + + + YES + + YES @@ -26,6 +39,31 @@ 1316 + + YES + + + 1316 + {{25, 40}, {267, 21}} + + NO + YES + NO + NetJack : client on JACK server + + Helvetica-Bold + 17 + 16 + + + 1 + MCAwIDAAA + + + 1 + 10 + + {320, 480} @@ -63,9 +101,7 @@ YES 0 - - YES - + @@ -74,36 +110,44 @@ YES + - + -1 - - RmlsZSdzIE93bmVyA + + File's Owner 3 - + -2 - + + + + 10 + + YES - + YES -1.CustomClassName -2.CustomClassName + 10.IBPluginDependency 2.IBAttributePlaceholdersKey 2.IBEditorWindowLastContentRect 2.IBPluginDependency + 2.IBUserGuides 3.CustomClassName 3.IBPluginDependency @@ -111,26 +155,31 @@ YES UIApplication UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin YES - - YES - + YES - {{438, 320}, {320, 480}} + {{366, 320}, {320, 480}} com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + + 153.5 + 0 + + iPhoneNetAppDelegate com.apple.InterfaceBuilder.IBCocoaTouchPlugin YES - - YES - + YES @@ -138,15 +187,13 @@ YES - - YES - + YES - 9 + 11 @@ -155,12 +202,21 @@ iPhoneNetAppDelegate NSObject - window - UIWindow + YES + + YES + navigationController + window + + + YES + UINavigationController + UIWindow + IBProjectSource - Classes/iPhoneNetAppDelegate.h + iPhoneNetAppDelegate.h @@ -172,9 +228,213 @@ + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UINavigationController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIResponder + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + +
0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES iPhoneNet.xcodeproj 3 + 3.1 diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj index a5db89b8..4b976838 100755 --- a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -71,6 +71,7 @@ 4B4146AA10BD3C4300C12F0C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 4B4146AB10BD3C4300C12F0C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 4B4146AC10BD3C4300C12F0C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; + 4B6B712C114BAE9A00ED9788 /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; 4B9CB1371136CA99007DE01A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B9CB1361136CA99007DE01A /* icon.png */; }; 4B9CB1381136CA99007DE01A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B9CB1361136CA99007DE01A /* icon.png */; }; 4B9CB1391136CA99007DE01A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B9CB1361136CA99007DE01A /* icon.png */; }; @@ -182,7 +183,7 @@ 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaust.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BCB37D5112D64B4008C7BC1 /* HardwareClock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HardwareClock.cpp; sourceTree = SOURCE_ROOT; }; 4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "iphone-faust.mm"; sourceTree = SOURCE_ROOT; }; - 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneThruNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BCF75F610BC30140082C526 /* audio_thru.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = audio_thru.mm; sourceTree = SOURCE_ROOT; }; 4BDFCD57113DB6B700D77992 /* NetJackSlave.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetJackSlave.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; }; @@ -292,7 +293,7 @@ 4BFF45120F4D59DB00106083 /* libjacknet.a */, 4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */, 4B0772380F54018C000DC657 /* NetJackMaster.app */, - 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */, + 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */, 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */, 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */, 4BDFCD57113DB6B700D77992 /* NetJackSlave.app */, @@ -485,7 +486,7 @@ ); name = iPhoneThruNet; productName = iPhoneNet; - productReference = 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */; + productReference = 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */; productType = "com.apple.product-type.application"; }; 4BDFCD3B113DB6B700D77992 /* iPhoneNetSlaveLib */ = { @@ -672,6 +673,7 @@ 4BF1364E0F4B0F7700218A3F /* JackResampler.cpp in Sources */, 4BF136560F4B0F9F00218A3F /* ringbuffer.c in Sources */, 4B2791890F72570C000536B7 /* JackGlobals.cpp in Sources */, + 4B6B712C114BAE9A00ED9788 /* CAHostTimeBase.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -885,6 +887,7 @@ GCC_OPTIMIZATION_LEVEL = 0; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( + /usr/local/include, ../../common/jack, ../../common, ../../posix, @@ -907,6 +910,7 @@ GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; HEADER_SEARCH_PATHS = ( + /usr/local/include, ../../macosx, ../../posix, ../../common, diff --git a/macosx/iphone/main_master.mm b/macosx/iphone/main_master.mm index 86fec8b3..7ec618b3 100644 --- a/macosx/iphone/main_master.mm +++ b/macosx/iphone/main_master.mm @@ -40,13 +40,11 @@ static void MasterAudioCallback(int frames, float** inputs, float** outputs, voi { int i; - // Copy from iPod input to network buffers for (i = 0; i < result.audio_input; i++) { memcpy(audio_input_buffer[i], inputs[i], buffer_size * sizeof(float)); } - /* // Copy from network out buffers to network in buffers (audio thru) for (i = 0; i < result.audio_input; i++) { @@ -76,9 +74,7 @@ static void MasterAudioCallback(int frames, float** inputs, float** outputs, voi int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - int i; - int wait_usec = (unsigned long)((((float)buffer_size) / ((float)sample_rate)) * 1000000.0f); if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { printf("jack_net_master_open error..\n"); @@ -112,12 +108,12 @@ int main(int argc, char *argv[]) { return -1; } - // Run until interrupted - //while (1) {} - /* // Quite brutal way, the application actually does not start completely, the netjack audio processing loop is used instead... // Run until interrupted + + int wait_usec = (unsigned long)((((float)buffer_size) / ((float)sample_rate)) * 1000000.0f); + while (1) { // Copy input to output @@ -141,7 +137,6 @@ int main(int argc, char *argv[]) { audio_device.Stop(); audio_device.Close(); - // Wait for application end jack_net_master_close(net); diff --git a/macosx/iphone/main_slave.mm b/macosx/iphone/main_slave.mm index b3eea568..b4ef278b 100644 --- a/macosx/iphone/main_slave.mm +++ b/macosx/iphone/main_slave.mm @@ -31,13 +31,11 @@ static int net_process(jack_nframes_t buffer_size, void** midi_output_buffer, void* data) { - - //printf("audio_input %d audio_output %d \n", audio_input, audio_output); jack_adapter_pull_and_push(adapter, audio_output_buffer, audio_input_buffer, buffer_size); // Process input, produce output if (audio_input == audio_output) { - // Copy input to output + // Copy net input to net output for (int i = 0; i < audio_input; i++) { memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); } @@ -51,7 +49,6 @@ static void net_shutdown(void *arg) jack_flush_adapter(adapter); } - static void SlaveAudioCallback(int frames, float** inputs, float** outputs, void* arg) { jack_adapter_push_and_pull(adapter, inputs, outputs, frames); @@ -70,7 +67,7 @@ int main(int argc, char *argv[]) { //if ((net = jack_net_slave_open("169.254.112.119", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPod", &request, &result)) == 0) { - printf("jack_net_master_open error..\n"); + printf("jack_net_slave_open error..\n"); return -1; } @@ -85,7 +82,6 @@ int main(int argc, char *argv[]) { TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT); - jack_set_net_slave_process_callback(net, net_process, NULL); jack_set_net_slave_shutdown_callback(net, net_shutdown, NULL); @@ -109,7 +105,6 @@ int main(int argc, char *argv[]) { audio_device.Stop(); audio_device.Close(); - // Wait for application end jack_net_slave_deactivate(net); jack_net_slave_close(net); From 54ebab2cf2de6b2c3b37e3112d0d275f711bd04f Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 24 Mar 2010 11:07:52 +0000 Subject: [PATCH 050/472] rebase from trunk 3930:3966 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3967 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 242 +- common/JackAtomicArrayState.h | 34 +- common/JackConstants.h | 2 +- common/JackControlAPI.h | 2 +- common/JackError.cpp | 38 +- common/JackError.h | 35 +- common/JackGraphManager.cpp | 2 +- common/JackShmMem.cpp | 35 +- common/JackShmMem.h | 35 +- common/JackTools.cpp | 6 +- common/JackWeakAPI.cpp | 107 +- common/driver_interface.h | 2 +- common/jack/control.h | 4 +- common/shm.c | 44 +- dbus/controller_iface_control.c | 27 +- example-clients/alsa_in.c | 8 +- example-clients/alsa_out.c | 8 +- example-clients/internal_metro.cpp | 10 +- example-clients/internal_metro.h | 1 + example-clients/metro.c | 6 +- linux/firewire/JackFFADODriver.cpp | 12 +- macosx/JackMachServerChannel.cpp | 2 +- macosx/coreaudio/JackCoreAudioDriver.cpp | 8 +- solaris/oss/JackBoomerDriver.cpp | 8 +- solaris/oss/JackOSSDriver.cpp | 8 +- tests/external_metro.cpp | 3 +- tests/external_metro.h | 1 + windows/JackCompilerDeps_os.h | 33 +- windows/JackNetWinSocket.cpp | 33 +- windows/JackNetWinSocket.h | 34 +- windows/JackPlatformPlug_os.h | 33 +- windows/JackShmMem_os.h | 38 +- windows/JackSystemDeps_os.h | 33 +- windows/JackTypes_os.h | 33 +- windows/JackWinEvent.cpp | 33 +- windows/JackWinEvent.h | 34 +- windows/JackWinMutex.h | 33 +- windows/JackWinNamedPipe.cpp | 33 +- windows/JackWinNamedPipe.h | 33 +- windows/JackWinNamedPipeClientChannel.cpp | 33 +- windows/JackWinNamedPipeClientChannel.h | 33 +- windows/JackWinNamedPipeNotifyChannel.cpp | 33 +- windows/JackWinNamedPipeNotifyChannel.h | 33 +- windows/JackWinNamedPipeServerChannel.cpp | 29 +- windows/JackWinNamedPipeServerChannel.h | 33 +- windows/JackWinNamedPipeServerNotifyChannel.h | 33 +- windows/JackWinProcessSync.cpp | 33 +- windows/JackWinProcessSync.h | 33 +- windows/JackWinSemaphore.cpp | 34 +- windows/JackWinSemaphore.h | 33 +- windows/JackWinThread.cpp | 34 +- windows/JackWinThread.h | 34 +- windows/JackWinTime.c | 34 +- windows/README | 32 +- windows/jackd.workspace | 4 +- windows/libjack.cbp | 54 +- windows/libjackserver.cbp | 58 +- windows/portaudio/JackPortAudioDriver.cpp | 8 +- windows/regex.c | 4949 ----------------- windows/regex.h | 506 -- 60 files changed, 952 insertions(+), 6214 deletions(-) delete mode 100644 windows/regex.c delete mode 100644 windows/regex.h diff --git a/ChangeLog b/ChangeLog index 99565bf9..efaf99f8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19,202 +19,226 @@ Romain Moret Florian Faber Michael Voigt Torben Hohn -Paul Davis -Peter L Jones -Devin Anderson -Josh Green +Paul Davis +Peter L Jones +Devin Anderson +Josh Green Mario Lang +Arnold Krille --------------------------- Jackdmp changes log ---------------------------- - +--------------------------- + +2010-03-24 Stephane Letz + + * On Windows, now use TRE library for regexp (BSD license instead of GPL license). + +2010-03-19 Stephane Letz + + * Fix some file header to have library side code use LGPL. + * Apply srcfactor.diff patch for ticket #162. + +2010-03-06 Stephane Letz + + * Arnold Krille firewire patch. + * Raise JACK_DRIVER_PARAM_STRING_MAX and JACK_PARAM_STRING_MAX to 127 otherwise some audio drivers cannot be loaded on OSX. + +2010-03-04 Stephane Letz + + * Correct JackMachServerChannel::Execute : keep running even in error cases. + * Raise JACK_PROTOCOL_VERSION number. + +2010-03-03 Stephane Letz + + * Correct JackGraphManager::DeactivatePort. + 2010-03-02 Stephane Letz - * Improve JackCoreAudioDriver and JackCoreAudioAdapter : when no devices are described, takes default input and output and aggregate them. - + * Improve JackCoreAudioDriver and JackCoreAudioAdapter : when no devices are described, takes default input and output and aggregate them. + 2010-02-15 Stephane Letz - * Version 1.9.6 started. - + * Version 1.9.6 started. + 2010-01-29 Gabriel M. Beddingfield - * Change JackEngineProfiling and JackAudioAdapterInterface gnuplot scripts to output SVG instead of PDF. - + * Change JackEngineProfiling and JackAudioAdapterInterface gnuplot scripts to output SVG instead of PDF. + 2009-12-15 Stephane Letz - * Shared memory manager was calling abort in case of fatal error, now return an error in caller. - + * Shared memory manager was calling abort in case of fatal error, now return an error in caller. + 2009-12-13 Stephane Letz - * Mario Lang alsa_io time calculation overflow patch. - + * Mario Lang alsa_io time calculation overflow patch. + 2009-12-10 Stephane Letz - * Use a QUIT notification to properly quit the server channel, the server channel thread can then be 'stopped' instead of 'canceled'. - + * Use a QUIT notification to properly quit the server channel, the server channel thread can then be 'stopped' instead of 'canceled'. + 2009-12-09 Stephane Letz - * When threads are cancelled, the exception has to be rethrown. - + * When threads are cancelled, the exception has to be rethrown. + 2009-12-08 Stephane Letz - * Josh Green ALSA driver capture only patch. - + * Josh Green ALSA driver capture only patch. + 2009-12-03 Stephane Letz - * Fix JackCoreMidiDriver::ReadProcAux when ring buffer is full (thanks Devin Anderson). - + * Fix JackCoreMidiDriver::ReadProcAux when ring buffer is full (thanks Devin Anderson). + 2009-12-02 Stephane Letz - * Special code in JackCoreAudio driver to handle completely buggy Digidesign CoreAudio user-land driver. - * Ensure that client-side message buffer thread calls thread_init callback if/when it is set by the client (backport of JACK1 rev 3838). - * Check dynamic port-max value. - + * Special code in JackCoreAudio driver to handle completely buggy Digidesign CoreAudio user-land driver. + * Ensure that client-side message buffer thread calls thread_init callback if/when it is set by the client (backport of JACK1 rev 3838). + * Check dynamic port-max value. + 2009-12-01 Stephane Letz - * Fix port_rename callback : now both old name and new name are given as parameters. - + * Fix port_rename callback : now both old name and new name are given as parameters. + 2009-11-30 Stephane Letz - * Devin Anderson patch for Jack FFADO driver issues with lost MIDI bytes between periods (and more). - + * Devin Anderson patch for Jack FFADO driver issues with lost MIDI bytes between periods (and more). + 2009-11-29 Stephane Letz - * More robust sample rate change handling code in JackCoreAudioDriver. - + * More robust sample rate change handling code in JackCoreAudioDriver. + 2009-11-24 Stephane Letz - * Dynamic choice of maximum port number. - + * Dynamic choice of maximum port number. + 2009-11-23 Stephane Letz - * Peter L Jones patch for NetJack1 compilation on Windows. - + * Peter L Jones patch for NetJack1 compilation on Windows. + 2009-11-20 Stephane Letz - * Version 1.9.5 started. - * Client debugging code improved. - + * Version 1.9.5 started. + * Client debugging code improved. + 2009-11-18 Stephane Letz - * Sync JackCoreAudioAdapter code with JackCoreAudioDriver. - + * Sync JackCoreAudioAdapter code with JackCoreAudioDriver. + 2009-11-17 Stephane Letz - * In JackCoreAudio driver, clock drift compensation in aggregated devices working. - * In JackCoreAudio driver, clock drift compensation semantic changed a bit : when on, does not activate if not needed (same clock domain). - + * In JackCoreAudio driver, clock drift compensation in aggregated devices working. + * In JackCoreAudio driver, clock drift compensation semantic changed a bit : when on, does not activate if not needed (same clock domain). + 2009-11-16 Stephane Letz - * In JackCoreAudio driver, (possibly) clock drift compensation when needed in aggregated devices. - + * In JackCoreAudio driver, (possibly) clock drift compensation when needed in aggregated devices. + 2009-11-14 Stephane Letz - * Sync with JACK1 : -r parameter now used for no-realtime, realtime (-R) is now default, usable backend given vie platform. - + * Sync with JACK1 : -r parameter now used for no-realtime, realtime (-R) is now default, usable backend given vie platform. + 2009-11-13 Stephane Letz - * Better memory allocation error checking in ringbuffer.c, weak import improvements. - * Memory allocation error checking for jack_client_new and jack_client_open (server and client side). - * Memory allocation error checking in server for RPC. - * Simplify server temporary mode : now use a JackTemporaryException. - * Lock/Unlock shared memory segments (to test...). - + * Better memory allocation error checking in ringbuffer.c, weak import improvements. + * Memory allocation error checking for jack_client_new and jack_client_open (server and client side). + * Memory allocation error checking in server for RPC. + * Simplify server temporary mode : now use a JackTemporaryException. + * Lock/Unlock shared memory segments (to test...). + 2009-11-12 Stephane Letz - * Better memory allocation error checking on client (library) side. - + * Better memory allocation error checking on client (library) side. + 2009-11-11 Stephane Letz - * Correct JackCoreAudio driver when empty strings are given as -C, -P or -d parameter. - + * Correct JackCoreAudio driver when empty strings are given as -C, -P or -d parameter. + 2009-11-10 Stephane Letz - * Correct JackInfoShutdownCallback prototype, two new JackClientProcessFailure and JackClientZombie JackStatus code. - + * Correct JackInfoShutdownCallback prototype, two new JackClientProcessFailure and JackClientZombie JackStatus code. + 2009-11-09 Stephane Letz - * Correct JackGraphManager::GetBuffer for the "client loop with one connection" case : buffer must be copied. - + * Correct JackGraphManager::GetBuffer for the "client loop with one connection" case : buffer must be copied. + 2009-11-07 Stephane Letz - * Fix AcquireRealTime and DropRealTime: now distinguish when called from another thread (AcquireRealTime/DropRealTime) and from the thread itself (AcquireSelfRealTime/DropSelfRealTime). - * Correct JackPosixThread::StartImp : thread priority setting now done in the RT case only. - + * Fix AcquireRealTime and DropRealTime: now distinguish when called from another thread (AcquireRealTime/DropRealTime) and from the thread itself (AcquireSelfRealTime/DropSelfRealTime). + * Correct JackPosixThread::StartImp : thread priority setting now done in the RT case only. + 2009-11-06 Stephane Letz - * Correctly save and restore RT mode state in freewheel mode. - * Correct freewheel code on client side. - + * Correctly save and restore RT mode state in freewheel mode. + * Correct freewheel code on client side. + 2009-11-05 Stephane Letz - * No reason to make jack_on_shutdown deprecated, so revert the incorrect change. - * Thread AcquireRealTime and DropRealTime were (incorrectly) using fThread field. Use pthread_self()) (or GetCurrentThread() on Windows) to get the calling thread. - + * No reason to make jack_on_shutdown deprecated, so revert the incorrect change. + * Thread AcquireRealTime and DropRealTime were (incorrectly) using fThread field. Use pthread_self()) (or GetCurrentThread() on Windows) to get the calling thread. + 2009-10-30 Stephane Letz - * In JackCoreAudioDriver, improve management of input/output channels: -1 is now used internally to indicate a wanted max value. - * In JackCoreAudioDriver::OpenAUHAL, correct stream format setup and cleanup. - * Correct crash bug in JackAudioAdapterInterface when not input is used in adapter (temporary fix...) - * Sync JackCoreAudioAdapter code on JackCoreAudioDriver one. - * JACK_SCHED_POLICY switched to SCHED_FIFO. - * Now can aggregate device that are themselves AD. - + * In JackCoreAudioDriver, improve management of input/output channels: -1 is now used internally to indicate a wanted max value. + * In JackCoreAudioDriver::OpenAUHAL, correct stream format setup and cleanup. + * Correct crash bug in JackAudioAdapterInterface when not input is used in adapter (temporary fix...) + * Sync JackCoreAudioAdapter code on JackCoreAudioDriver one. + * JACK_SCHED_POLICY switched to SCHED_FIFO. + * Now can aggregate device that are themselves AD. + 2009-10-29 Stephane Letz - * In JackCoreAudioDriver::Start, wait for the audio driver to effectively start (use the MeasureCallback). - + * In JackCoreAudioDriver::Start, wait for the audio driver to effectively start (use the MeasureCallback). + 2009-10-28 Stephane Letz - * In JackCoreAudioDriver, force the SR value to the wanted one *before* creating aggregate device (otherwise creation will fail). - * In JackCoreAudioDriver, better cleanup of AD when intermediate open failure. - + * In JackCoreAudioDriver, force the SR value to the wanted one *before* creating aggregate device (otherwise creation will fail). + * In JackCoreAudioDriver, better cleanup of AD when intermediate open failure. + 2009-10-27 Stephane Letz - * Dynamic system version detection in JackCoreAudioDriver to either create public or private aggregate device. - + * Dynamic system version detection in JackCoreAudioDriver to either create public or private aggregate device. + 2009-10-26 Stephane Letz - * Implement "hog mode" (exclusive access of the audio device) in JackCoreAudioDriver. - * Fix jack_set_sample_rate_callback to have he same behavior as in JACK1. - + * Implement "hog mode" (exclusive access of the audio device) in JackCoreAudioDriver. + * Fix jack_set_sample_rate_callback to have he same behavior as in JACK1. + 2009-10-25 Stephane Letz - * Improve aggregate device management in JackCoreAudioDriver : now a "private" device only and cleanup properly. - * Aggregate device code added to JackCoreAudioAdapter. - + * Improve aggregate device management in JackCoreAudioDriver : now a "private" device only and cleanup properly. + * Aggregate device code added to JackCoreAudioAdapter. + 2009-10-23 Stephane Letz - * Correct JackProcessSync::LockedTimedWait. - * Correct JACK_MESSAGE_SIZE value, particularly in OSX RPC code. - * Now start server channel thread only when backend has been started (so in JackServer::Start). Should solve race conditions at start time. - * jack_verbose moved to JackGlobals class. - + * Correct JackProcessSync::LockedTimedWait. + * Correct JACK_MESSAGE_SIZE value, particularly in OSX RPC code. + * Now start server channel thread only when backend has been started (so in JackServer::Start). Should solve race conditions at start time. + * jack_verbose moved to JackGlobals class. + 2009-10-22 Stephane Letz - * Correct jackdmp.cpp (failures case were not correct..). Improve JackCoreAudioDriver code. Raise default port number to 2048. - + * Correct jackdmp.cpp (failures case were not correct..). Improve JackCoreAudioDriver code. Raise default port number to 2048. + 2009-10-20 Stephane Letz - * Add a string parameter to server ==> client notification, add a new JackInfoShutdownCallback type. - * CoreAudio backend now issue a JackInfoShutdownCallback when an unrecoverable error is detected (sampling rate change, stream configuration changeÉ) + * Add a string parameter to server ==> client notification, add a new JackInfoShutdownCallback type. + * CoreAudio backend now issue a JackInfoShutdownCallback when an unrecoverable error is detected (sampling rate change, stream configuration changeÉ) 2009-10-17 Stephane Letz - * Correct server temporary mode : now set a global and quit after server/client message handling is finished. - + * Correct server temporary mode : now set a global and quit after server/client message handling is finished. + 2009-10-15 Stephane Letz - * Change CoreAudio notification thread setup for OSX Snow Leopard. - + * Change CoreAudio notification thread setup for OSX Snow Leopard. + 2009-09-18 Stephane Letz - * Simplify transport in NetJack2: master only can control transport. + * Simplify transport in NetJack2: master only can control transport. 2009-09-15 Stephane Letz - * Correct CPU timing in JackNetDriver, now take cycle begin time after Read. + * Correct CPU timing in JackNetDriver, now take cycle begin time after Read. * Fix issues in JackNetDriver::DecodeTransportData and JackNetDriver::Initialize. 2009-08-28 Stephane Letz @@ -570,7 +594,7 @@ Mario Lang 2008-11-21 Stephane Letz * Report ringbuffer.c fixes from JACK1. - * Better isolation of server and clients system resources to allow starting the server in several user account at the same time. + * Better isolation of server and clients system resources to allow starting the server in several user account at the same time. * Correct ressource cleanup in case of driver open failure. 2008-11-19 Stephane Letz diff --git a/common/JackAtomicArrayState.h b/common/JackAtomicArrayState.h index 8a0daf08..177158da 100644 --- a/common/JackAtomicArrayState.h +++ b/common/JackAtomicArrayState.h @@ -1,21 +1,21 @@ /* -Copyright (C) 2004-2006 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. - -*/ + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ #ifndef __JackAtomicArrayState__ #define __JackAtomicArrayState__ diff --git a/common/JackConstants.h b/common/JackConstants.h index 695fcd0f..e04906dd 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -88,7 +88,7 @@ #define ALL_CLIENTS -1 // for notification -#define JACK_PROTOCOL_VERSION 7 +#define JACK_PROTOCOL_VERSION 8 #define SOCKET_TIME_OUT 5 // in sec #define DRIVER_OPEN_TIMEOUT 5 // in sec diff --git a/common/JackControlAPI.h b/common/JackControlAPI.h index cc07dcab..d0b0cbc1 100644 --- a/common/JackControlAPI.h +++ b/common/JackControlAPI.h @@ -47,7 +47,7 @@ typedef enum #define JACK_PARAM_MAX (JackParamBool + 1) /** @brief Max length of string parameter value, excluding terminating nul char */ -#define JACK_PARAM_STRING_MAX 63 +#define JACK_PARAM_STRING_MAX 127 /** @brief Type for parameter value */ /* intentionally similar to jack_driver_param_value_t */ diff --git a/common/JackError.cpp b/common/JackError.cpp index 3705c35c..905bbef8 100644 --- a/common/JackError.cpp +++ b/common/JackError.cpp @@ -1,23 +1,23 @@ /* - Copyright (C) 2001 Paul Davis - Copyright (C) 2004-2008 Grame - Copyright (C) 2008 Nedko Arnaudov - - 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. - -*/ + Copyright (C) 2001 Paul Davis + Copyright (C) 2004-2008 Grame + Copyright (C) 2008 Nedko Arnaudov + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ #include #include diff --git a/common/JackError.h b/common/JackError.h index 403c55ae..e16a65b2 100644 --- a/common/JackError.h +++ b/common/JackError.h @@ -1,22 +1,21 @@ /* -Copyright (C) 2001 Paul Davis -Copyright (C) 2004-2008 Grame -Copyright (C) 2008 Nedko Arnaudov - -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. - + Copyright (C) 2001 Paul Davis + Copyright (C) 2004-2008 Grame + Copyright (C) 2008 Nedko Arnaudov + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index 36e29430..1a92191c 100644 --- a/common/JackGraphManager.cpp +++ b/common/JackGraphManager.cpp @@ -385,7 +385,7 @@ void JackGraphManager::ActivatePort(jack_port_id_t port_index) void JackGraphManager::DeactivatePort(jack_port_id_t port_index) { JackPort* port = GetPort(port_index); - port->fFlags = (JackPortFlags)(port->fFlags | ~JackPortIsActive); + port->fFlags = (JackPortFlags)(port->fFlags & ~JackPortIsActive); } void JackGraphManager::GetInputPorts(int refnum, jack_int_t* res) diff --git a/common/JackShmMem.cpp b/common/JackShmMem.cpp index 90d42e7b..11c4f988 100644 --- a/common/JackShmMem.cpp +++ b/common/JackShmMem.cpp @@ -1,22 +1,21 @@ /* -Copyright (C) 2001 Paul Davis -Copyright (C) 2004-2009 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. - -*/ + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ #include "JackError.h" #include "JackShmMem.h" diff --git a/common/JackShmMem.h b/common/JackShmMem.h index 0a00daa5..fdef507b 100644 --- a/common/JackShmMem.h +++ b/common/JackShmMem.h @@ -1,22 +1,21 @@ /* -Copyright (C) 2001 Paul Davis -Copyright (C) 2004-2009 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. - -*/ + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ #ifndef __JackShmMem__ #define __JackShmMem__ diff --git a/common/JackTools.cpp b/common/JackTools.cpp index a7a7020e..d74f34c0 100644 --- a/common/JackTools.cpp +++ b/common/JackTools.cpp @@ -194,7 +194,7 @@ namespace Jack { } if (fgets(buf, sizeof(buf), in) == NULL) { - fclose(in); + pclose(in); return -1; } @@ -202,7 +202,7 @@ namespace Jack { if (buf[len - 1] != '\n') { /* didn't get a whole line */ - fclose(in); + pclose(in); return -1; } @@ -210,7 +210,7 @@ namespace Jack { memcpy(jack_tmpdir, buf, len - 1); jack_tmpdir[len - 1] = '\0'; - fclose(in); + pclose(in); return 0; } #endif diff --git a/common/JackWeakAPI.cpp b/common/JackWeakAPI.cpp index 81e21d35..d516be76 100644 --- a/common/JackWeakAPI.cpp +++ b/common/JackWeakAPI.cpp @@ -1,33 +1,36 @@ -/* -Copyright (C) 2009 Grame - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 of the License, or -(at your option) any later version. +//============================================================================= +// MuseScore +// Linux Music Score Editor +// $Id: +// +// jackWeakAPI based on code from Stéphane Letz (Grame) +// partly based on Julien Pommier (PianoTeq : http://www.pianoteq.com/) code. +// +// Copyright (C) 2002-2007 Werner Schweer and others +// Copyright (C) 2009 Grame -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 Lesser General Public License for more details. +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. -You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// 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 Lesser General Public License for more details. -*/ - -/* - Completed from Julien Pommier (PianoTeq : http://www.pianoteq.com/) code. -*/ +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include #include +#ifndef WIN32 #include +#endif #include -#include #include /* dynamically load libjack and forward all registered calls to libjack @@ -40,13 +43,21 @@ typedef void *(*thread_routine)(void*); using std::cerr; int libjack_is_present = 0; // public symbol, similar to what relaytool does. + +#ifdef WIN32 +HMODULE libjack_handle = 0; +#else static void *libjack_handle = 0; +#endif + static void __attribute__((constructor)) tryload_libjack() { if (getenv("SKIP_LIBJACK") == 0) { // just in case libjack is causing troubles.. #ifdef __APPLE__ libjack_handle = dlopen("libjack.0.dylib", RTLD_LAZY); + #elif defined(WIN32) + libjack_handle = LoadLibrary("libjack.dll"); #else libjack_handle = dlopen("libjack.so.0", RTLD_LAZY); #endif @@ -59,12 +70,22 @@ void *load_jack_function(const char *fn_name) { void *fn = 0; if (!libjack_handle) { - std::cerr << "libjack not found, so do not try to load " << fn_name << " ffs !\n"; + fprintf (stderr, "libjack not found, so do not try to load %s ffs !\n", fn_name); return 0; } +#ifdef WIN32 + fn = (void*)GetProcAddress(libjack_handle, fn_name); +#else fn = dlsym(libjack_handle, fn_name); +#endif if (!fn) { - std::cerr << "could not dlsym(" << libjack_handle << "), " << dlerror() << "\n"; +#ifdef WIN32 + char* lpMsgBuf; + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR) &lpMsgBuf,0,NULL ); + fprintf (stderr, "could not GetProcAddress( %s ), %s \n", fn_name, lpMsgBuf) ; +#else + fprintf (stderr, "could not dlsym( %s ), %s \n", fn_name, dlerror()) ; +#endif } return fn; } @@ -78,6 +99,15 @@ void *load_jack_function(const char *fn_name) else return (return_type)-1; \ } +#define DECL_FUNCTION_NULL(return_type, fn_name, arguments_types, arguments) \ + typedef return_type (*fn_name##_ptr_t)arguments_types; \ + return_type fn_name arguments_types { \ + static fn_name##_ptr_t fn = 0; \ + if (fn == 0) { fn = (fn_name##_ptr_t)load_jack_function(#fn_name); } \ + if (fn) return (*fn)arguments; \ + else return (return_type)0; \ + } + #define DECL_VOID_FUNCTION(fn_name, arguments_types, arguments) \ typedef void (*fn_name##_ptr_t)arguments_types; \ void fn_name arguments_types { \ @@ -86,14 +116,15 @@ void *load_jack_function(const char *fn_name) if (fn) (*fn)arguments; \ } + DECL_VOID_FUNCTION(jack_get_version, (int *major_ptr, int *minor_ptr, int *micro_ptr, int *proto_ptr), (major_ptr, minor_ptr, micro_ptr, proto_ptr)); -DECL_FUNCTION(const char *, jack_get_version_string, (), ()); -DECL_FUNCTION(jack_client_t *, jack_client_open, (const char *client_name, jack_options_t options, jack_status_t *status, ...), +DECL_FUNCTION_NULL(const char *, jack_get_version_string, (), ()); +DECL_FUNCTION_NULL(jack_client_t *, jack_client_open, (const char *client_name, jack_options_t options, jack_status_t *status, ...), (client_name, options, status)); DECL_FUNCTION(int, jack_client_close, (jack_client_t *client), (client)); -DECL_FUNCTION(jack_client_t *, jack_client_new, (const char *client_name), (client_name)); +DECL_FUNCTION_NULL(jack_client_t *, jack_client_new, (const char *client_name), (client_name)); DECL_FUNCTION(int, jack_client_name_size, (), ()); -DECL_FUNCTION(char*, jack_get_client_name, (jack_client_t *client), (client)); +DECL_FUNCTION_NULL(char*, jack_get_client_name, (jack_client_t *client), (client)); DECL_FUNCTION(int, jack_internal_client_new, (const char *client_name, const char *load_name, const char *load_init), (client_name, load_name, load_init)); @@ -146,21 +177,21 @@ DECL_FUNCTION(int, jack_set_xrun_callback, (jack_client_t *client, void *arg), (client, xrun_callback, arg)); DECL_FUNCTION(int, jack_activate, (jack_client_t *client), (client)); DECL_FUNCTION(int, jack_deactivate, (jack_client_t *client), (client)); -DECL_FUNCTION(jack_port_t *, jack_port_register, (jack_client_t *client, const char *port_name, const char *port_type, +DECL_FUNCTION_NULL(jack_port_t *, jack_port_register, (jack_client_t *client, const char *port_name, const char *port_type, unsigned long flags, unsigned long buffer_size), (client, port_name, port_type, flags, buffer_size)); DECL_FUNCTION(int, jack_port_unregister, (jack_client_t *client, jack_port_t* port), (client, port)); -DECL_FUNCTION(void *, jack_port_get_buffer, (jack_port_t *port, jack_nframes_t nframes), (port, nframes)); -DECL_FUNCTION(const char*, jack_port_name, (const jack_port_t *port), (port)); -DECL_FUNCTION(const char*, jack_port_short_name, (const jack_port_t *port), (port)); +DECL_FUNCTION_NULL(void *, jack_port_get_buffer, (jack_port_t *port, jack_nframes_t nframes), (port, nframes)); +DECL_FUNCTION_NULL(const char*, jack_port_name, (const jack_port_t *port), (port)); +DECL_FUNCTION_NULL(const char*, jack_port_short_name, (const jack_port_t *port), (port)); DECL_FUNCTION(int, jack_port_flags, (const jack_port_t *port), (port)); -DECL_FUNCTION(const char*, jack_port_type, (const jack_port_t *port), (port)); +DECL_FUNCTION_NULL(const char*, jack_port_type, (const jack_port_t *port), (port)); DECL_FUNCTION(jack_port_type_id_t, jack_port_type_id, (const jack_port_t *port), (port)); DECL_FUNCTION(int, jack_port_is_mine, (const jack_client_t *client, const jack_port_t* port), (client, port)); DECL_FUNCTION(int, jack_port_connected, (const jack_port_t *port), (port)); DECL_FUNCTION(int, jack_port_connected_to, (const jack_port_t *port, const char *port_name), (port, port_name)); -DECL_FUNCTION(const char**, jack_port_get_connections, (const jack_port_t *port), (port)); -DECL_FUNCTION(const char**, jack_port_get_all_connections, (const jack_client_t *client,const jack_port_t *port), (client, port)); +DECL_FUNCTION_NULL(const char**, jack_port_get_connections, (const jack_port_t *port), (port)); +DECL_FUNCTION_NULL(const char**, jack_port_get_all_connections, (const jack_client_t *client,const jack_port_t *port), (client, port)); DECL_FUNCTION(int, jack_port_tie, (jack_port_t *src, jack_port_t *dst), (src, dst)); DECL_FUNCTION(int, jack_port_untie, (jack_port_t *port), (port)); DECL_FUNCTION(jack_nframes_t, jack_port_get_latency, (jack_port_t *port), (port)); @@ -185,10 +216,10 @@ DECL_FUNCTION(int, jack_port_type_size,(),()); DECL_FUNCTION(jack_nframes_t, jack_get_sample_rate, (jack_client_t *client), (client)); DECL_FUNCTION(jack_nframes_t, jack_get_buffer_size, (jack_client_t *client), (client)); -DECL_FUNCTION(const char**, jack_get_ports, (jack_client_t *client, const char *port_name_pattern, const char * type_name_pattern, +DECL_FUNCTION_NULL(const char**, jack_get_ports, (jack_client_t *client, const char *port_name_pattern, const char * type_name_pattern, unsigned long flags), (client, port_name_pattern, type_name_pattern, flags)); -DECL_FUNCTION(jack_port_t *, jack_port_by_name, (jack_client_t * client, const char *port_name), (client, port_name)); -DECL_FUNCTION(jack_port_t *, jack_port_by_id, (jack_client_t *client, jack_port_id_t port_id), (client, port_id)); +DECL_FUNCTION_NULL(jack_port_t *, jack_port_by_name, (jack_client_t * client, const char *port_name), (client, port_name)); +DECL_FUNCTION_NULL(jack_port_t *, jack_port_by_id, (jack_client_t *client, jack_port_id_t port_id), (client, port_id)); DECL_FUNCTION(int, jack_engine_takeover_timebase, (jack_client_t * client), (client)); DECL_FUNCTION(jack_nframes_t, jack_frames_since_cycle_start, (const jack_client_t * client), (client)); @@ -198,7 +229,7 @@ DECL_FUNCTION(jack_time_t, jack_frames_to_time, (const jack_client_t *client, ja DECL_FUNCTION(jack_nframes_t, jack_frame_time, (const jack_client_t *client), (client)); DECL_FUNCTION(jack_nframes_t, jack_last_frame_time, (const jack_client_t *client), (client)); DECL_FUNCTION(float, jack_cpu_load, (jack_client_t *client), (client)); -DECL_FUNCTION(pthread_t, jack_client_thread_id, (jack_client_t *client), (client)); +DECL_FUNCTION_NULL(pthread_t, jack_client_thread_id, (jack_client_t *client), (client)); DECL_VOID_FUNCTION(jack_set_error_function, (print_function fun), (fun)); DECL_VOID_FUNCTION(jack_set_info_function, (print_function fun), (fun)); @@ -256,6 +287,6 @@ DECL_FUNCTION(jack_nframes_t, jack_midi_get_event_count, (void* port_buffer), (p DECL_FUNCTION(int, jack_midi_event_get, (jack_midi_event_t* event, void* port_buffer, jack_nframes_t event_index), (event, port_buffer, event_index)) ; DECL_VOID_FUNCTION(jack_midi_clear_buffer, (void* port_buffer), (port_buffer)); DECL_FUNCTION(size_t, jack_midi_max_event_size, (void* port_buffer), (port_buffer)); -DECL_FUNCTION(jack_midi_data_t*, jack_midi_event_reserve, (void* port_buffer, jack_nframes_t time, size_t data_size), (port_buffer, time, data_size)); +DECL_FUNCTION_NULL(jack_midi_data_t*, jack_midi_event_reserve, (void* port_buffer, jack_nframes_t time, size_t data_size), (port_buffer, time, data_size)); DECL_FUNCTION(int, jack_midi_event_write, (void* port_buffer, jack_nframes_t time, const jack_midi_data_t* data, size_t data_size), (port_buffer, time, data, data_size)); DECL_FUNCTION(jack_nframes_t, jack_midi_get_lost_event_count, (void* port_buffer), (port_buffer)); diff --git a/common/driver_interface.h b/common/driver_interface.h index d336f413..6c97099c 100644 --- a/common/driver_interface.h +++ b/common/driver_interface.h @@ -33,7 +33,7 @@ extern "C" #define JACK_DRIVER_NAME_MAX 15 #define JACK_DRIVER_PARAM_NAME_MAX 15 -#define JACK_DRIVER_PARAM_STRING_MAX 63 +#define JACK_DRIVER_PARAM_STRING_MAX 127 #define JACK_DRIVER_PARAM_DESC 255 #define JACK_PATH_MAX 511 diff --git a/common/jack/control.h b/common/jack/control.h index 6360d30a..caeb931d 100644 --- a/common/jack/control.h +++ b/common/jack/control.h @@ -48,8 +48,8 @@ typedef enum /** @brief Max value that jackctl_param_type_t type can have */ #define JACK_PARAM_MAX (JackParamBool + 1) -/** @brief Max length of string parameter value, excluding terminating nul char */ -#define JACK_PARAM_STRING_MAX 63 +/** @brief Max length of string parameter value, excluding terminating null char */ +#define JACK_PARAM_STRING_MAX 127 /** @brief Type for parameter value */ /* intentionally similar to jack_driver_param_value_t */ diff --git a/common/shm.c b/common/shm.c index e74a2134..d0e62de9 100644 --- a/common/shm.c +++ b/common/shm.c @@ -1,24 +1,3 @@ -/* - * Copyright (C) 2003 Paul Davis - * Copyright (C) 2004 Jack O'Quin - * Copyright (C) 2006-2007 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. - * - */ - /* This module provides a set of abstract shared memory interfaces * with support using both System V and POSIX shared memory * implementations. The code is divided into three sections: @@ -31,6 +10,25 @@ * set in the ./configure step. */ +/* + Copyright (C) 2001-2003 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + #include "JackConstants.h" #ifdef WIN32 @@ -148,7 +146,7 @@ static int semid = -1; static int semaphore_init () {return 0;} -static int +static int semaphore_add (int value) {return 0;} #else @@ -534,7 +532,7 @@ jack_unregister_server (const char *server_name /* unused */) } } - jack_shm_unlock_registry (); + jack_shm_unlock_registry (); return 0; } diff --git a/dbus/controller_iface_control.c b/dbus/controller_iface_control.c index ca3ab038..967cde19 100644 --- a/dbus/controller_iface_control.c +++ b/dbus/controller_iface_control.c @@ -87,34 +87,31 @@ jack_control_run_method( { if (!jack_controller_start_server(controller_ptr, call)) { - jack_error ("Failed to start server"); - } - else - { - jack_controller_control_send_signal_server_started(); + jack_dbus_error(call, JACK_DBUS_ERROR_GENERIC, "Failed to start server"); + return true; } + + jack_controller_control_send_signal_server_started(); } else if (strcmp (call->method_name, "StopServer") == 0) { if (!jack_controller_stop_server(controller_ptr, call)) { - jack_error ("Failed to stop server"); - } - else - { - jack_controller_control_send_signal_server_stopped(); + jack_dbus_error(call, JACK_DBUS_ERROR_GENERIC, "Failed to stop server"); + return true; } + + jack_controller_control_send_signal_server_stopped(); } else if (strcmp (call->method_name, "SwitchMaster") == 0) { if (!jack_controller_switch_master(controller_ptr, call)) { - jack_error ("Failed to switch master"); - } - else - { - jack_controller_control_send_signal_server_stopped(); + jack_dbus_error(call, JACK_DBUS_ERROR_GENERIC, "Failed to switch master"); + return true; } + + jack_controller_control_send_signal_server_stopped(); } else if (strcmp (call->method_name, "GetLoad") == 0) { diff --git a/example-clients/alsa_in.c b/example-clients/alsa_in.c index a04271eb..85259cde 100644 --- a/example-clients/alsa_in.c +++ b/example-clients/alsa_in.c @@ -38,6 +38,8 @@ int jack_buffer_size; int quit = 0; double resample_mean = 1.0; double static_resample_factor = 1.0; +double resample_lower_limit = 0.25; +double resample_upper_limit = 4.0; double *offset_array; double *window_array; @@ -388,8 +390,8 @@ int process (jack_nframes_t nframes, void *arg) { output_offset = (float) offset; // Clamp a bit. - if( current_resample_factor < 0.25 ) current_resample_factor = 0.25; - if( current_resample_factor > 4 ) current_resample_factor = 4; + if( current_resample_factor < resample_lower_limit ) current_resample_factor = resample_lower_limit; + if( current_resample_factor > resample_upper_limit ) current_resample_factor = resample_upper_limit; // Now Calculate how many samples we need. rlen = ceil( ((double)nframes) / current_resample_factor )+2; @@ -675,6 +677,8 @@ int main (int argc, char *argv[]) { printf( "selected sample format: %s\n", formats[format].name ); static_resample_factor = (double) jack_sample_rate / (double) sample_rate; + resample_lower_limit = static_resample_factor * 0.25; + resample_upper_limit = static_resample_factor * 4.0; resample_mean = static_resample_factor; offset_array = malloc( sizeof(double) * smooth_size ); diff --git a/example-clients/alsa_out.c b/example-clients/alsa_out.c index 852e978c..85b00e12 100644 --- a/example-clients/alsa_out.c +++ b/example-clients/alsa_out.c @@ -37,6 +37,8 @@ int jack_buffer_size; double resample_mean = 1.0; double static_resample_factor = 1.0; +double resample_lower_limit = 0.25; +double resample_upper_limit = 4.0; double *offset_array; double *window_array; @@ -395,8 +397,8 @@ int process (jack_nframes_t nframes, void *arg) { output_offset = (float) offset; // Clamp a bit. - if( current_resample_factor < 0.25 ) current_resample_factor = 0.25; - if( current_resample_factor > 4 ) current_resample_factor = 4; + if( current_resample_factor < resample_lower_limit ) current_resample_factor = resample_lower_limit; + if( current_resample_factor > resample_upper_limit ) current_resample_factor = resample_upper_limit; // Now Calculate how many samples we need. rlen = ceil( ((double)nframes) * current_resample_factor )+2; @@ -666,6 +668,8 @@ int main (int argc, char *argv[]) { sample_rate = jack_sample_rate; static_resample_factor = (double) sample_rate / (double) jack_sample_rate; + resample_lower_limit = static_resample_factor * 0.25; + resample_upper_limit = static_resample_factor * 4.0; resample_mean = static_resample_factor; offset_array = malloc( sizeof(double) * smooth_size ); diff --git a/example-clients/internal_metro.cpp b/example-clients/internal_metro.cpp index 59806c74..14747d64 100644 --- a/example-clients/internal_metro.cpp +++ b/example-clients/internal_metro.cpp @@ -46,7 +46,6 @@ InternalMetro::InternalMetro(int freq, double max_amp, int dur_arg, int bpm, cha { sample_t scale; int i, attack_length, decay_length; - double *amp; int attack_percent = 1, decay_percent = 10; const char *bpm_string = "bpm"; @@ -59,7 +58,7 @@ InternalMetro::InternalMetro(int freq, double max_amp, int dur_arg, int bpm, cha } if ((client = jack_client_open (client_name, JackNullOption, NULL)) == 0) { fprintf (stderr, "jack server not running?\n"); - return ; + return; } jack_set_process_callback (client, process_audio, this); @@ -81,11 +80,11 @@ InternalMetro::InternalMetro(int freq, double max_amp, int dur_arg, int bpm, cha ", wave length = %" PRIu32 "\n", tone_length, wave_length); */ - return ; + return; } if (attack_length + decay_length > (int)tone_length) { fprintf (stderr, "invalid attack/decay\n"); - return ; + return; } /* Build the wave table */ @@ -110,7 +109,6 @@ InternalMetro::InternalMetro(int freq, double max_amp, int dur_arg, int bpm, cha if (jack_activate (client)) { fprintf(stderr, "cannot activate client"); - return; } } @@ -120,4 +118,6 @@ InternalMetro::~InternalMetro() jack_port_unregister(client, input_port); jack_port_unregister(client, output_port); jack_client_close(client); + free(amp); + free(wave); } diff --git a/example-clients/internal_metro.h b/example-clients/internal_metro.h index bbe156a8..7febb6dc 100644 --- a/example-clients/internal_metro.h +++ b/example-clients/internal_metro.h @@ -53,6 +53,7 @@ extern "C" int bpm; jack_nframes_t tone_length, wave_length; sample_t *wave; + double *amp; long offset ; InternalMetro(int freq, double max_amp, int dur_arg, int bpm, char* client_name); diff --git a/example-clients/metro.c b/example-clients/metro.c index 9afc58b2..d2daaa7f 100644 --- a/example-clients/metro.c +++ b/example-clients/metro.c @@ -257,7 +257,7 @@ main (int argc, char *argv[]) if (jack_activate (client)) { fprintf (stderr, "cannot activate client\n"); - return 1; + goto error; } /* install a signal handler to properly quits jack client */ @@ -282,5 +282,9 @@ main (int argc, char *argv[]) }; jack_client_close(client); + +error: + free(amp); + free(wave); exit (0); } diff --git a/linux/firewire/JackFFADODriver.cpp b/linux/firewire/JackFFADODriver.cpp index 735aace6..7e679c55 100644 --- a/linux/firewire/JackFFADODriver.cpp +++ b/linux/firewire/JackFFADODriver.cpp @@ -753,12 +753,20 @@ extern "C" strcpy (desc->name, "firewire"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->desc, "Linux FFADO API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - desc->nparams = 11; + desc->nparams = 12; params = (jack_driver_param_desc_t *)calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); desc->params = params; i = 0; + strcpy (params[i].name, "device"); + params[i].character = 'd'; + params[i].type = JackDriverParamString; + strcpy (params[i].value.str, "hw:0"); + strcpy (params[i].short_desc, "The FireWire device to use."); + strcpy (params[i].long_desc, "The FireWire device to use. Please consult the FFADO documentation for more info."); + + i++; strcpy (params[i].name, "period"); params[i].character = 'p'; params[i].type = JackDriverParamUInt; @@ -881,7 +889,7 @@ extern "C" switch (param->character) { case 'd': - device_name = strdup (param->value.str); + device_name = const_cast(param->value.str); break; case 'p': cmlparams.period_size = param->value.ui; diff --git a/macosx/JackMachServerChannel.cpp b/macosx/JackMachServerChannel.cpp index fcf4fe8c..411886a7 100644 --- a/macosx/JackMachServerChannel.cpp +++ b/macosx/JackMachServerChannel.cpp @@ -159,7 +159,7 @@ bool JackMachServerChannel::Execute() kern_return_t res; if ((res = mach_msg_server(MessageHandler, 1024, fServerPort.GetPortSet(), 0)) != KERN_SUCCESS) { jack_log("JackMachServerChannel::Execute: err = %s", mach_error_string(res)); - return false; + // A recoverable error, so keep running... } return true; diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 8b829d27..406fddbe 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -2002,8 +2002,8 @@ extern "C" switch (param->character) { case 'd': - capture_driver_uid = strdup(param->value.str); - playback_driver_uid = strdup(param->value.str); + capture_driver_uid = param->value.str; + playback_driver_uid = param->value.str; break; case 'D': @@ -2026,14 +2026,14 @@ extern "C" case 'C': capture = true; if (strcmp(param->value.str, "none") != 0) { - capture_driver_uid = strdup(param->value.str); + capture_driver_uid = param->value.str; } break; case 'P': playback = true; if (strcmp(param->value.str, "none") != 0) { - playback_driver_uid = strdup(param->value.str); + playback_driver_uid = param->value.str; } break; diff --git a/solaris/oss/JackBoomerDriver.cpp b/solaris/oss/JackBoomerDriver.cpp index 25056326..f10b2e89 100644 --- a/solaris/oss/JackBoomerDriver.cpp +++ b/solaris/oss/JackBoomerDriver.cpp @@ -985,20 +985,20 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine case 'C': capture = true; if (strcmp(param->value.str, "none") != 0) { - capture_pcm_name = strdup(param->value.str); + capture_pcm_name = param->value.str; } break; case 'P': playback = true; if (strcmp(param->value.str, "none") != 0) { - playback_pcm_name = strdup(param->value.str); + playback_pcm_name = param->value.str; } break; case 'd': - playback_pcm_name = strdup (param->value.str); - capture_pcm_name = strdup (param->value.str); + playback_pcm_name = param->value.str; + capture_pcm_name = param->value.str; break; case 'e': diff --git a/solaris/oss/JackOSSDriver.cpp b/solaris/oss/JackOSSDriver.cpp index af0ed43b..7890f6ae 100644 --- a/solaris/oss/JackOSSDriver.cpp +++ b/solaris/oss/JackOSSDriver.cpp @@ -904,20 +904,20 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine case 'C': capture = true; if (strcmp(param->value.str, "none") != 0) { - capture_pcm_name = strdup(param->value.str); + capture_pcm_name = param->value.str; } break; case 'P': playback = true; if (strcmp(param->value.str, "none") != 0) { - playback_pcm_name = strdup(param->value.str); + playback_pcm_name = param->value.str; } break; case 'd': - playback_pcm_name = strdup (param->value.str); - capture_pcm_name = strdup (param->value.str); + playback_pcm_name = param->value.str; + capture_pcm_name = param->value.str; break; case 'b': diff --git a/tests/external_metro.cpp b/tests/external_metro.cpp index 25600eba..6ca8bc90 100644 --- a/tests/external_metro.cpp +++ b/tests/external_metro.cpp @@ -60,7 +60,6 @@ ExternalMetro::ExternalMetro(int freq, double max_amp, int dur_arg, int bpm, con { sample_t scale; int i, attack_length, decay_length; - double *amp; int attack_percent = 1, decay_percent = 10; const char *bpm_string = "bpm"; jack_options_t options = JackNullOption; @@ -131,6 +130,8 @@ ExternalMetro::~ExternalMetro() jack_port_unregister(client, input_port); jack_port_unregister(client, output_port); jack_client_close(client); + free(amp); + free(wave); } int main (int argc, char *argv[]) diff --git a/tests/external_metro.h b/tests/external_metro.h index e0bcc186..8c618410 100644 --- a/tests/external_metro.h +++ b/tests/external_metro.h @@ -53,6 +53,7 @@ extern "C" int bpm; jack_nframes_t tone_length, wave_length; sample_t *wave; + double *amp; long offset ; ExternalMetro(int freq, double max_amp, int dur_arg, int bpm, const char* client_name = "metro"); diff --git a/windows/JackCompilerDeps_os.h b/windows/JackCompilerDeps_os.h index 858cbd8f..75cbc50a 100644 --- a/windows/JackCompilerDeps_os.h +++ b/windows/JackCompilerDeps_os.h @@ -1,21 +1,22 @@ /* -Copyright (C) 2004-2005 Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ -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 __JackCompilerDeps_WIN32__ #define __JackCompilerDeps_WIN32__ diff --git a/windows/JackNetWinSocket.cpp b/windows/JackNetWinSocket.cpp index 94390b4d..adf8a434 100644 --- a/windows/JackNetWinSocket.cpp +++ b/windows/JackNetWinSocket.cpp @@ -1,21 +1,22 @@ /* -Copyright (C) 2008 Romain Moret at Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ -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. - -*/ #include "JackNetWinSocket.h" diff --git a/windows/JackNetWinSocket.h b/windows/JackNetWinSocket.h index 21ad275d..bd303eff 100644 --- a/windows/JackNetWinSocket.h +++ b/windows/JackNetWinSocket.h @@ -1,21 +1,21 @@ /* -Copyright (C) 2008 Romain Moret at 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. - -*/ + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ #ifndef __JackNetWinSocket__ #define __JackNetWinSocket__ diff --git a/windows/JackPlatformPlug_os.h b/windows/JackPlatformPlug_os.h index 536a6018..87c2e40f 100644 --- a/windows/JackPlatformPlug_os.h +++ b/windows/JackPlatformPlug_os.h @@ -1,21 +1,22 @@ /* -Copyright (C) 2004-2008 Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 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 -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ #ifndef __JackPlatformPlug_WIN32__ #define __JackPlatformPlug_WIN32__ diff --git a/windows/JackShmMem_os.h b/windows/JackShmMem_os.h index 37a419f2..31c9a052 100644 --- a/windows/JackShmMem_os.h +++ b/windows/JackShmMem_os.h @@ -1,28 +1,28 @@ /* -Copyright (C) 2001 Paul Davis -Copyright (C) 2004-2008 Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ -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 __JackShmMem_WIN32__ #define __JackShmMem_WIN32__ -#include - +#include + // See GetProcessWorkingSetSize and SetProcessWorkingSetSize #define CHECK_MLOCK(ptr, size) (VirtualLock((ptr), (size)) != 0) diff --git a/windows/JackSystemDeps_os.h b/windows/JackSystemDeps_os.h index 69b842b3..cf64509e 100644 --- a/windows/JackSystemDeps_os.h +++ b/windows/JackSystemDeps_os.h @@ -1,21 +1,22 @@ /* -Copyright (C) 2004-2006 Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ -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 __JackSystemDeps_WIN32__ #define __JackSystemDeps_WIN32__ diff --git a/windows/JackTypes_os.h b/windows/JackTypes_os.h index 13e67349..6551378f 100644 --- a/windows/JackTypes_os.h +++ b/windows/JackTypes_os.h @@ -1,21 +1,22 @@ /* - 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 Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 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 - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ #ifndef __JackTypes_WIN32__ #define __JackTypes_WIN32__ diff --git a/windows/JackWinEvent.cpp b/windows/JackWinEvent.cpp index c64fcf97..be5ff65d 100644 --- a/windows/JackWinEvent.cpp +++ b/windows/JackWinEvent.cpp @@ -1,21 +1,22 @@ /* -Copyright (C) 2004-2005 Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ -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. - -*/ #include "JackWinEvent.h" #include "JackTools.h" diff --git a/windows/JackWinEvent.h b/windows/JackWinEvent.h index 35fcb2f7..379c4c63 100644 --- a/windows/JackWinEvent.h +++ b/windows/JackWinEvent.h @@ -1,21 +1,21 @@ /* -Copyright (C) 2004-2005 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. - -*/ + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ #ifndef __JackWinEvent__ #define __JackWinEvent__ diff --git a/windows/JackWinMutex.h b/windows/JackWinMutex.h index 55434ace..480f8987 100644 --- a/windows/JackWinMutex.h +++ b/windows/JackWinMutex.h @@ -1,23 +1,22 @@ /* - Copyright (C) 2006 Grame - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 - Lesser General Public License for more details. + 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France - grame@grame.fr -*/ #ifndef __JackWinMutex__ #define __JackWinMutex__ diff --git a/windows/JackWinNamedPipe.cpp b/windows/JackWinNamedPipe.cpp index d3329055..9d067cd2 100644 --- a/windows/JackWinNamedPipe.cpp +++ b/windows/JackWinNamedPipe.cpp @@ -1,21 +1,22 @@ /* -Copyright (C) 2004-2006 Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ -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. - -*/ #include "JackWinNamedPipe.h" #include "JackError.h" diff --git a/windows/JackWinNamedPipe.h b/windows/JackWinNamedPipe.h index 864b6c94..6487d4b3 100644 --- a/windows/JackWinNamedPipe.h +++ b/windows/JackWinNamedPipe.h @@ -1,21 +1,22 @@ /* -Copyright (C) 2004-2006 Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ -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 __JackWinNamedPipe__ #define __JackWinNamedPipe__ diff --git a/windows/JackWinNamedPipeClientChannel.cpp b/windows/JackWinNamedPipeClientChannel.cpp index fedc1095..9b3e2473 100644 --- a/windows/JackWinNamedPipeClientChannel.cpp +++ b/windows/JackWinNamedPipeClientChannel.cpp @@ -1,21 +1,22 @@ /* -Copyright (C) 2004-2006 Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 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 - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ #include "JackWinNamedPipeClientChannel.h" #include "JackRequest.h" diff --git a/windows/JackWinNamedPipeClientChannel.h b/windows/JackWinNamedPipeClientChannel.h index 32bf6a5d..fc5617e7 100644 --- a/windows/JackWinNamedPipeClientChannel.h +++ b/windows/JackWinNamedPipeClientChannel.h @@ -1,21 +1,22 @@ /* -Copyright (C) 2004-2006 Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 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 - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ #ifndef __JackWinNamedPipeClientChannel__ #define __JackWinNamedPipeClientChannel__ diff --git a/windows/JackWinNamedPipeNotifyChannel.cpp b/windows/JackWinNamedPipeNotifyChannel.cpp index a7375085..1c559d87 100644 --- a/windows/JackWinNamedPipeNotifyChannel.cpp +++ b/windows/JackWinNamedPipeNotifyChannel.cpp @@ -1,21 +1,22 @@ /* -Copyright (C) 2004-2006 Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 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 - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ #include "JackRequest.h" #include "JackWinNamedPipeNotifyChannel.h" diff --git a/windows/JackWinNamedPipeNotifyChannel.h b/windows/JackWinNamedPipeNotifyChannel.h index 9d90e26b..d11b17ad 100644 --- a/windows/JackWinNamedPipeNotifyChannel.h +++ b/windows/JackWinNamedPipeNotifyChannel.h @@ -1,21 +1,22 @@ /* -Copyright (C) 2004-2006 Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 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 - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ #ifndef __JackWinNamedPipeNotifyChannel__ #define __JackWinNamedPipeNotifyChannel__ diff --git a/windows/JackWinNamedPipeServerChannel.cpp b/windows/JackWinNamedPipeServerChannel.cpp index 3e6daa9c..a8ce3a22 100644 --- a/windows/JackWinNamedPipeServerChannel.cpp +++ b/windows/JackWinNamedPipeServerChannel.cpp @@ -1,21 +1,22 @@ /* -Copyright (C) 2004-2006 Grame + Copyright (C) 2004-2008 Grame - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + 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 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 - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ -*/ #include "JackWinNamedPipeServerChannel.h" #include "JackNotification.h" @@ -73,7 +74,7 @@ void JackClientPipeThread::Close() // Close the Server/Client connection all ressources will be desallocated at the end. */ - fThread.Stop(); + fThread.Kill(); fPipe->Close(); fRefNum = -1; } diff --git a/windows/JackWinNamedPipeServerChannel.h b/windows/JackWinNamedPipeServerChannel.h index 7404f04d..21fad162 100644 --- a/windows/JackWinNamedPipeServerChannel.h +++ b/windows/JackWinNamedPipeServerChannel.h @@ -1,21 +1,22 @@ /* -Copyright (C) 2004-2006 Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 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 - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ #ifndef __JackWinNamedPipeServerChannel__ #define __JackWinNamedPipeServerChannel__ diff --git a/windows/JackWinNamedPipeServerNotifyChannel.h b/windows/JackWinNamedPipeServerNotifyChannel.h index be4d7ff2..ae706fc5 100644 --- a/windows/JackWinNamedPipeServerNotifyChannel.h +++ b/windows/JackWinNamedPipeServerNotifyChannel.h @@ -1,21 +1,22 @@ /* -Copyright (C) 2004-2006 Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 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 - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ #ifndef __JackWinNamedPipeServerNotifyChannel__ #define __JackWinNamedPipeServerNotifyChannel__ diff --git a/windows/JackWinProcessSync.cpp b/windows/JackWinProcessSync.cpp index 56171fba..12dbcdcf 100644 --- a/windows/JackWinProcessSync.cpp +++ b/windows/JackWinProcessSync.cpp @@ -1,21 +1,22 @@ /* -Copyright (C) 2004-2006 Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ -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. - -*/ #include "JackWinProcessSync.h" #include "JackError.h" diff --git a/windows/JackWinProcessSync.h b/windows/JackWinProcessSync.h index 33a340c9..fd6d3d7c 100644 --- a/windows/JackWinProcessSync.h +++ b/windows/JackWinProcessSync.h @@ -1,21 +1,22 @@ /* -Copyright (C) 2004-2006 Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ -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 __JackWinProcessSync__ #define __JackWinProcessSync__ diff --git a/windows/JackWinSemaphore.cpp b/windows/JackWinSemaphore.cpp index 8ce52d62..4500b10b 100644 --- a/windows/JackWinSemaphore.cpp +++ b/windows/JackWinSemaphore.cpp @@ -1,21 +1,21 @@ /* -Copyright (C) 2004-2005 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. - -*/ + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ #include "JackWinSemaphore.h" #include "JackConstants.h" diff --git a/windows/JackWinSemaphore.h b/windows/JackWinSemaphore.h index d4330e5f..04779699 100644 --- a/windows/JackWinSemaphore.h +++ b/windows/JackWinSemaphore.h @@ -1,21 +1,22 @@ /* -Copyright (C) 2004-2005 Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ -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 __JackWinSemaphore__ #define __JackWinSemaphore__ diff --git a/windows/JackWinThread.cpp b/windows/JackWinThread.cpp index 3893d220..99aed2ff 100644 --- a/windows/JackWinThread.cpp +++ b/windows/JackWinThread.cpp @@ -1,22 +1,22 @@ /* -Copyright (C) 2001 Paul Davis -Copyright (C) 2004-2006 Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ -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. - -*/ #include "JackWinThread.h" #include "JackError.h" diff --git a/windows/JackWinThread.h b/windows/JackWinThread.h index a3a5a25c..7bb745b2 100644 --- a/windows/JackWinThread.h +++ b/windows/JackWinThread.h @@ -1,22 +1,22 @@ /* -Copyright (C) 2001 Paul Davis -Copyright (C) 2004-2006 Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ -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 __JackWinThread__ diff --git a/windows/JackWinTime.c b/windows/JackWinTime.c index bd950806..065ea9f9 100644 --- a/windows/JackWinTime.c +++ b/windows/JackWinTime.c @@ -1,22 +1,22 @@ /* -Copyright (C) 2001-2003 Paul Davis -Copyright (C) 2004-2008 Grame + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 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 -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ #include "JackTime.h" diff --git a/windows/README b/windows/README index f7cbebb7..9653665c 100644 --- a/windows/README +++ b/windows/README @@ -1,32 +1,35 @@ ------------------------------- -Jackmp on Windows +JACK2 on Windows ------------------------------- This folder contains all the windows specific sources. You will also find two sets of files : -- VisualC++6 workspace and project files, in order to compile Jack with MSVC -- Code::Blocks (8.02) workspace and project files, in order to compile Jack with MingW +- VisualC++6 workspace and project files, in order to compile JACK with MSVC +- Code::Blocks (8.02) workspace and project files, in order to compile JACK with MingW The built binaries will be located in '/Release/bin' (or '/Debug/bin' if you build the Debug target). Once compiled, you'll find there everything you need : - the two 'libjackmp.dll' and 'libjackservermp.dll', client and server jack libraries -- the 'jackdmp.exe', main application : the jack server +- the 'jackdmp.exe', main application : the JACK server - the 'jack_xxx.exe' utilities and examples -- in the jackmp directory, you'll find the driver's DLL's ('jack_portaudio.dll' and 'jack_netdriver.dll') and some tools ( 'netmanager.dll', 'audioadapter.dll', 'netadapter.dll' for example ) +- in the jackmp directory, you'll find the driver's DLL's ('jack_portaudio.dll' and 'jack_netdriver.dll') and some tools ('netmanager.dll', 'audioadapter.dll', 'netadapter.dll' for example) In Code::Blocks all the projects are automatically built in a correct order (dll's then apps) by doing 'build->build workspace'. In VC6, you'll have to build the projects one by one. +The needed regexp library TRE can be found here http://laurikari.net/tre/. Unzip and place the "tre-0.8.0" folder into the "windows" folder. +Then edit and comment "#define snprintf sprintf_s" at the end off the "tre-0.8.0/win32/config.h" file before building the JACK project. + ------------------------------- Notes about VC and GCC versions ------------------------------- -The Visual Studio workspace is limited to VC6. Jack will not compile on most recent MSVC's. The fact is recent compilers (MSVC7, 8 or 9) don't agree with some of the Jack sources. -But now you can compile Jack using GCC, with MingW. +The Visual Studio workspace is limited to VC6. JACK will not compile on most recent MSVC's. The fact is recent compilers (MSVC7, 8 or 9) don't agree with some of the JACK sources. +But now you can compile JACK using GCC, with MingW. The project is actually organized in a Code::Blocks workspace. This is a simple and efficient way to compile the whole project. -But for some reasons, you need to compile Jack using a SJLJ version of G++ (available on MingW website). +But for some reasons, you need to compile JACK using a SJLJ version of G++ (available on MingW website). Current GCC/G++ version (3.4.5) doesn't includes SJLJ so you'll have to use another one. -Jack needs the use of SJLJ exceptions instead of DW2 because exceptions are exchanged between DLL's, and DW2 does not allow to throw an exception out of a DLL, so it wouldn't be cought. +JACK needs the use of SJLJ exceptions instead of DW2 because exceptions are exchanged between DLL's, and DW2 does not allow to throw an exception out of a DLL, so it wouldn't be cought. The ressources files has been created with ResEdit (ANSI build). VisualStudio uses 'ressource.rc' and 'ressource_vc.h'. The other files are used by MingW. @@ -34,20 +37,19 @@ You can make a small installer ('setup.exe') with CreateInstallFree, a little fr A binary version of qjackctl is also included. ------------------------------- -Running Jack on Windows +Running JACK on Windows ------------------------------- You can use two drivers : PortAudio and NetDriver. The PortAudio backend allow the use of many soundcards, using ASIO, DirectSound or WMME drivers (any ASIO driver can be seen by PortAudio). The NetDriver allow you to use NetJack2 on windows. Thus you can easily exchange midi and audio streams bitween computers (Linux, MacOSX or Windows). In both cases, you have to use the minimalist : - 'jackd -R -d ...' - command. With PortAudio, you can have a list of supported drivers with : + 'jackd -R -d ...' command. With PortAudio, you can have a list of supported drivers with : 'jackd -R -S -d portaudio -l' Other options still stay the same. -You can also pick a binary of Qjackctl, but this is still in development. - +You can also pick a binary of Qjackctl, but this is still in development. + ------------------------------- Running Jack on windows ------------------------------- @@ -55,4 +57,4 @@ Running Jack on windows More information at : 'http://www.grame.fr/~letz/jackdmp.html'. For any question or suggestion, you can refer to the mailing list 'jack-devel@jackaudio.org' -Enjoy Jack on windows... ;-) +Enjoy JACK on windows... ;-) diff --git a/windows/jackd.workspace b/windows/jackd.workspace index 9be9ce63..d26dfe36 100644 --- a/windows/jackd.workspace +++ b/windows/jackd.workspace @@ -20,7 +20,7 @@ - + @@ -36,7 +36,7 @@ - + diff --git a/windows/libjack.cbp b/windows/libjack.cbp index 6c1e5ba7..41a71885 100644 --- a/windows/libjack.cbp +++ b/windows/libjack.cbp @@ -25,10 +25,13 @@ + + + @@ -64,10 +67,13 @@ + + + @@ -104,10 +110,13 @@ + + + @@ -180,9 +189,52 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/windows/libjackserver.cbp b/windows/libjackserver.cbp index b0b76f1f..e4db2136 100644 --- a/windows/libjackserver.cbp +++ b/windows/libjackserver.cbp @@ -26,10 +26,13 @@ + + + @@ -55,10 +58,13 @@ + + + @@ -85,10 +91,13 @@ + + + @@ -145,6 +154,8 @@ + + @@ -156,8 +167,6 @@ - - @@ -185,9 +194,52 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/windows/portaudio/JackPortAudioDriver.cpp b/windows/portaudio/JackPortAudioDriver.cpp index 01e3d943..d910bb9d 100644 --- a/windows/portaudio/JackPortAudioDriver.cpp +++ b/windows/portaudio/JackPortAudioDriver.cpp @@ -404,8 +404,8 @@ extern "C" { case 'd': - capture_pcm_name = strdup(param->value.str); - playback_pcm_name = strdup(param->value.str); + capture_pcm_name = param->value.str; + playback_pcm_name = param->value.str; break; case 'D': @@ -428,14 +428,14 @@ extern "C" case 'C': capture = true; if (strcmp(param->value.str, "none") != 0) { - capture_pcm_name = strdup(param->value.str); + capture_pcm_name = param->value.str; } break; case 'P': playback = TRUE; if (strcmp(param->value.str, "none") != 0) { - playback_pcm_name = strdup(param->value.str); + playback_pcm_name = param->value.str; } break; diff --git a/windows/regex.c b/windows/regex.c deleted file mode 100644 index db611160..00000000 --- a/windows/regex.c +++ /dev/null @@ -1,4949 +0,0 @@ -/* Extended regular expression matching and search library, - version 0.12. - (Implements POSIX draft P10003.2/D11.2, except for - internationalization features.) - - Copyright (C) 1993 Free Software Foundation, Inc. - - 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, 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. */ - -/* AIX requires this to be the first thing in the file. */ -#if defined (_AIX) && !defined (REGEX_MALLOC) - #pragma alloca -#endif - -#define _GNU_SOURCE - -/* We need this for `regex.h', and perhaps for the Emacs include files. */ -#include - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* The `emacs' switch turns on certain matching commands - that make sense only in Emacs. */ -#ifdef emacs - -#include "lisp.h" -#include "buffer.h" -#include "syntax.h" - -/* Emacs uses `NULL' as a predicate. */ -#undef NULL - -#else /* not emacs */ - -/* We used to test for `BSTRING' here, but only GCC and Emacs define - `BSTRING', as far as I know, and neither of them use this code. */ -#if HAVE_STRING_H || STDC_HEADERS -#include -#ifndef bcmp -#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n)) -#endif -#ifndef bcopy -#define bcopy(s, d, n) memcpy ((d), (s), (n)) -#endif -#ifndef bzero -#define bzero(s, n) memset ((s), 0, (n)) -#endif -#else -#include -#endif - -#ifdef STDC_HEADERS -#include -#else -char *malloc (); -char *realloc (); -#endif - - -/* Define the syntax stuff for \<, \>, etc. */ - -/* This must be nonzero for the wordchar and notwordchar pattern - commands in re_match_2. */ -#ifndef Sword -#define Sword 1 -#endif - -#ifdef SYNTAX_TABLE - -extern char *re_syntax_table; - -#else /* not SYNTAX_TABLE */ - -/* How many characters in the character set. */ -#define CHAR_SET_SIZE 256 - -static char re_syntax_table[CHAR_SET_SIZE]; - -static void -init_syntax_once () -{ - register int c; - static int done = 0; - - if (done) - return; - - bzero (re_syntax_table, sizeof re_syntax_table); - - for (c = 'a'; c <= 'z'; c++) - re_syntax_table[c] = Sword; - - for (c = 'A'; c <= 'Z'; c++) - re_syntax_table[c] = Sword; - - for (c = '0'; c <= '9'; c++) - re_syntax_table[c] = Sword; - - re_syntax_table['_'] = Sword; - - done = 1; -} - -#endif /* not SYNTAX_TABLE */ - -#define SYNTAX(c) re_syntax_table[c] - -#endif /* not emacs */ - -/* Get the interface, including the syntax bits. */ -#include "regex.h" - -/* isalpha etc. are used for the character classes. */ -#include - -#ifndef isascii -#define isascii(c) 1 -#endif - -#ifdef isblank -#define ISBLANK(c) (isascii (c) && isblank (c)) -#else -#define ISBLANK(c) ((c) == ' ' || (c) == '\t') -#endif -#ifdef isgraph -#define ISGRAPH(c) (isascii (c) && isgraph (c)) -#else -#define ISGRAPH(c) (isascii (c) && isprint (c) && !isspace (c)) -#endif - -#define ISPRINT(c) (isascii (c) && isprint (c)) -#define ISDIGIT(c) (isascii (c) && isdigit (c)) -#define ISALNUM(c) (isascii (c) && isalnum (c)) -#define ISALPHA(c) (isascii (c) && isalpha (c)) -#define ISCNTRL(c) (isascii (c) && iscntrl (c)) -#define ISLOWER(c) (isascii (c) && islower (c)) -#define ISPUNCT(c) (isascii (c) && ispunct (c)) -#define ISSPACE(c) (isascii (c) && isspace (c)) -#define ISUPPER(c) (isascii (c) && isupper (c)) -#define ISXDIGIT(c) (isascii (c) && isxdigit (c)) - -#ifndef NULL -#define NULL 0 -#endif - -/* We remove any previous definition of `SIGN_EXTEND_CHAR', - since ours (we hope) works properly with all combinations of - machines, compilers, `char' and `unsigned char' argument types. - (Per Bothner suggested the basic approach.) */ -#undef SIGN_EXTEND_CHAR -#if __STDC__ -#define SIGN_EXTEND_CHAR(c) ((signed char) (c)) -#else /* not __STDC__ */ -/* As in Harbison and Steele. */ -#define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128) -#endif - -/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we - use `alloca' instead of `malloc'. This is because using malloc in - re_search* or re_match* could cause memory leaks when C-g is used in - Emacs; also, malloc is slower and causes storage fragmentation. On - the other hand, malloc is more portable, and easier to debug. - - Because we sometimes use alloca, some routines have to be macros, - not functions -- `alloca'-allocated space disappears at the end of the - function it is called in. */ - -#ifdef REGEX_MALLOC - -#define REGEX_ALLOCATE malloc -#define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize) - -#else /* not REGEX_MALLOC */ - -/* Emacs already defines alloca, sometimes. */ -#ifndef alloca - -/* Make alloca work the best possible way. */ -#ifdef __GNUC__ -#define alloca __builtin_alloca -#else /* not __GNUC__ */ -#if HAVE_ALLOCA_H -#include -#else /* not __GNUC__ or HAVE_ALLOCA_H */ -#ifndef _AIX /* Already did AIX, up at the top. */ -char *alloca (); -#endif /* not _AIX */ -#endif /* not HAVE_ALLOCA_H */ -#endif /* not __GNUC__ */ - -#endif /* not alloca */ - -#define REGEX_ALLOCATE alloca - -/* Assumes a `char *destination' variable. */ -#define REGEX_REALLOCATE(source, osize, nsize) \ - (destination = (char *) alloca (nsize), \ - bcopy (source, destination, osize), \ - destination) - -#endif /* not REGEX_MALLOC */ - - -/* True if `size1' is non-NULL and PTR is pointing anywhere inside - `string1' or just past its end. This works if PTR is NULL, which is - a good thing. */ -#define FIRST_STRING_P(ptr) \ - (size1 && string1 <= (ptr) && (ptr) <= string1 + size1) - -/* (Re)Allocate N items of type T using malloc, or fail. */ -#define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t))) -#define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t))) -#define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t))) - -#define BYTEWIDTH 8 /* In bits. */ - -#define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) - -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) - -typedef char boolean; -#define false 0 -#define true 1 - -/* These are the command codes that appear in compiled regular - expressions. Some opcodes are followed by argument bytes. A - command code can specify any interpretation whatsoever for its - arguments. Zero bytes may appear in the compiled regular expression. - - The value of `exactn' is needed in search.c (search_buffer) in Emacs. - So regex.h defines a symbol `RE_EXACTN_VALUE' to be 1; the value of - `exactn' we use here must also be 1. */ - -typedef enum -{ - no_op = 0, - - /* Followed by one byte giving n, then by n literal bytes. */ - exactn = 1, - - /* Matches any (more or less) character. */ - anychar, - - /* Matches any one char belonging to specified set. First - following byte is number of bitmap bytes. Then come bytes - for a bitmap saying which chars are in. Bits in each byte - are ordered low-bit-first. A character is in the set if its - bit is 1. A character too large to have a bit in the map is - automatically not in the set. */ - charset, - - /* Same parameters as charset, but match any character that is - not one of those specified. */ - charset_not, - - /* Start remembering the text that is matched, for storing in a - register. Followed by one byte with the register number, in - the range 0 to one less than the pattern buffer's re_nsub - field. Then followed by one byte with the number of groups - inner to this one. (This last has to be part of the - start_memory only because we need it in the on_failure_jump - of re_match_2.) */ - start_memory, - - /* Stop remembering the text that is matched and store it in a - memory register. Followed by one byte with the register - number, in the range 0 to one less than `re_nsub' in the - pattern buffer, and one byte with the number of inner groups, - just like `start_memory'. (We need the number of inner - groups here because we don't have any easy way of finding the - corresponding start_memory when we're at a stop_memory.) */ - stop_memory, - - /* Match a duplicate of something remembered. Followed by one - byte containing the register number. */ - duplicate, - - /* Fail unless at beginning of line. */ - begline, - - /* Fail unless at end of line. */ - endline, - - /* Succeeds if at beginning of buffer (if emacs) or at beginning - of string to be matched (if not). */ - begbuf, - - /* Analogously, for end of buffer/string. */ - endbuf, - - /* Followed by two byte relative address to which to jump. */ - jump, - - /* Same as jump, but marks the end of an alternative. */ - jump_past_alt, - - /* Followed by two-byte relative address of place to resume at - in case of failure. */ - on_failure_jump, - - /* Like on_failure_jump, but pushes a placeholder instead of the - current string position when executed. */ - on_failure_keep_string_jump, - - /* Throw away latest failure point and then jump to following - two-byte relative address. */ - pop_failure_jump, - - /* Change to pop_failure_jump if know won't have to backtrack to - match; otherwise change to jump. This is used to jump - back to the beginning of a repeat. If what follows this jump - clearly won't match what the repeat does, such that we can be - sure that there is no use backtracking out of repetitions - already matched, then we change it to a pop_failure_jump. - Followed by two-byte address. */ - maybe_pop_jump, - - /* Jump to following two-byte address, and push a dummy failure - point. This failure point will be thrown away if an attempt - is made to use it for a failure. A `+' construct makes this - before the first repeat. Also used as an intermediary kind - of jump when compiling an alternative. */ - dummy_failure_jump, - - /* Push a dummy failure point and continue. Used at the end of - alternatives. */ - push_dummy_failure, - - /* Followed by two-byte relative address and two-byte number n. - After matching N times, jump to the address upon failure. */ - succeed_n, - - /* Followed by two-byte relative address, and two-byte number n. - Jump to the address N times, then fail. */ - jump_n, - - /* Set the following two-byte relative address to the - subsequent two-byte number. The address *includes* the two - bytes of number. */ - set_number_at, - - wordchar, /* Matches any word-constituent character. */ - notwordchar, /* Matches any char that is not a word-constituent. */ - - wordbeg, /* Succeeds if at word beginning. */ - wordend, /* Succeeds if at word end. */ - - wordbound, /* Succeeds if at a word boundary. */ - notwordbound /* Succeeds if not at a word boundary. */ - -#ifdef emacs - ,before_dot, /* Succeeds if before point. */ - at_dot, /* Succeeds if at point. */ - after_dot, /* Succeeds if after point. */ - - /* Matches any character whose syntax is specified. Followed by - a byte which contains a syntax code, e.g., Sword. */ - syntaxspec, - - /* Matches any character whose syntax is not that specified. */ - notsyntaxspec -#endif /* emacs */ -} re_opcode_t; - -/* Common operations on the compiled pattern. */ - -/* Store NUMBER in two contiguous bytes starting at DESTINATION. */ - -#define STORE_NUMBER(destination, number) \ - do { \ - (destination)[0] = (number) & 0377; \ - (destination)[1] = (number) >> 8; \ - } while (0) - -/* Same as STORE_NUMBER, except increment DESTINATION to - the byte after where the number is stored. Therefore, DESTINATION - must be an lvalue. */ - -#define STORE_NUMBER_AND_INCR(destination, number) \ - do { \ - STORE_NUMBER (destination, number); \ - (destination) += 2; \ - } while (0) - -/* Put into DESTINATION a number stored in two contiguous bytes starting - at SOURCE. */ - -#define EXTRACT_NUMBER(destination, source) \ - do { \ - (destination) = *(source) & 0377; \ - (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \ - } while (0) - -#ifdef DEBUG -static void -extract_number (dest, source) - int *dest; - unsigned char *source; -{ - int temp = SIGN_EXTEND_CHAR (*(source + 1)); - *dest = *source & 0377; - *dest += temp << 8; -} - -#ifndef EXTRACT_MACROS /* To debug the macros. */ -#undef EXTRACT_NUMBER -#define EXTRACT_NUMBER(dest, src) extract_number (&dest, src) -#endif /* not EXTRACT_MACROS */ - -#endif /* DEBUG */ - -/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number. - SOURCE must be an lvalue. */ - -#define EXTRACT_NUMBER_AND_INCR(destination, source) \ - do { \ - EXTRACT_NUMBER (destination, source); \ - (source) += 2; \ - } while (0) - -#ifdef DEBUG -static void -extract_number_and_incr (destination, source) - int *destination; - unsigned char **source; -{ - extract_number (destination, *source); - *source += 2; -} - -#ifndef EXTRACT_MACROS -#undef EXTRACT_NUMBER_AND_INCR -#define EXTRACT_NUMBER_AND_INCR(dest, src) \ - extract_number_and_incr (&dest, &src) -#endif /* not EXTRACT_MACROS */ - -#endif /* DEBUG */ - -/* If DEBUG is defined, Regex prints many voluminous messages about what - it is doing (if the variable `debug' is nonzero). If linked with the - main program in `iregex.c', you can enter patterns and strings - interactively. And if linked with the main program in `main.c' and - the other test files, you can run the already-written tests. */ - -#ifdef DEBUG - -/* We use standard I/O for debugging. */ -#include - -/* It is useful to test things that ``must'' be true when debugging. */ -#include - -static int debug = 0; - -#define DEBUG_STATEMENT(e) e -#define DEBUG_PRINT1(x) if (debug) printf (x) -#define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2) -#define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3) -#define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4) -#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \ - if (debug) print_partial_compiled_pattern (s, e) -#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \ - if (debug) print_double_string (w, s1, sz1, s2, sz2) - - -//extern void printchar (); -void printchar( int i ) {} - -/* Print the fastmap in human-readable form. */ - -void -print_fastmap (fastmap) - char *fastmap; -{ - unsigned was_a_range = 0; - unsigned i = 0; - - while (i < (1 << BYTEWIDTH)) - { - if (fastmap[i++]) - { - was_a_range = 0; - printchar (i - 1); - while (i < (1 << BYTEWIDTH) && fastmap[i]) - { - was_a_range = 1; - i++; - } - if (was_a_range) - { - printf ("-"); - printchar (i - 1); - } - } - } - putchar ('\n'); -} - - -/* Print a compiled pattern string in human-readable form, starting at - the START pointer into it and ending just before the pointer END. */ - -void -print_partial_compiled_pattern (start, end) - unsigned char *start; - unsigned char *end; -{ - int mcnt, mcnt2; - unsigned char *p = start; - unsigned char *pend = end; - - if (start == NULL) - { - printf ("(null)\n"); - return; - } - - /* Loop over pattern commands. */ - while (p < pend) - { - switch ((re_opcode_t) *p++) - { - case no_op: - printf ("/no_op"); - break; - - case exactn: - mcnt = *p++; - printf ("/exactn/%d", mcnt); - do - { - putchar ('/'); - printchar (*p++); - } - while (--mcnt); - break; - - case start_memory: - mcnt = *p++; - printf ("/start_memory/%d/%d", mcnt, *p++); - break; - - case stop_memory: - mcnt = *p++; - printf ("/stop_memory/%d/%d", mcnt, *p++); - break; - - case duplicate: - printf ("/duplicate/%d", *p++); - break; - - case anychar: - printf ("/anychar"); - break; - - case charset: - case charset_not: - { - register int c; - - printf ("/charset%s", - (re_opcode_t) *(p - 1) == charset_not ? "_not" : ""); - - assert (p + *p < pend); - - for (c = 0; c < *p; c++) - { - unsigned bit; - unsigned char map_byte = p[1 + c]; - - putchar ('/'); - - for (bit = 0; bit < BYTEWIDTH; bit++) - if (map_byte & (1 << bit)) - printchar (c * BYTEWIDTH + bit); - } - p += 1 + *p; - break; - } - - case begline: - printf ("/begline"); - break; - - case endline: - printf ("/endline"); - break; - - case on_failure_jump: - extract_number_and_incr (&mcnt, &p); - printf ("/on_failure_jump/0/%d", mcnt); - break; - - case on_failure_keep_string_jump: - extract_number_and_incr (&mcnt, &p); - printf ("/on_failure_keep_string_jump/0/%d", mcnt); - break; - - case dummy_failure_jump: - extract_number_and_incr (&mcnt, &p); - printf ("/dummy_failure_jump/0/%d", mcnt); - break; - - case push_dummy_failure: - printf ("/push_dummy_failure"); - break; - - case maybe_pop_jump: - extract_number_and_incr (&mcnt, &p); - printf ("/maybe_pop_jump/0/%d", mcnt); - break; - - case pop_failure_jump: - extract_number_and_incr (&mcnt, &p); - printf ("/pop_failure_jump/0/%d", mcnt); - break; - - case jump_past_alt: - extract_number_and_incr (&mcnt, &p); - printf ("/jump_past_alt/0/%d", mcnt); - break; - - case jump: - extract_number_and_incr (&mcnt, &p); - printf ("/jump/0/%d", mcnt); - break; - - case succeed_n: - extract_number_and_incr (&mcnt, &p); - extract_number_and_incr (&mcnt2, &p); - printf ("/succeed_n/0/%d/0/%d", mcnt, mcnt2); - break; - - case jump_n: - extract_number_and_incr (&mcnt, &p); - extract_number_and_incr (&mcnt2, &p); - printf ("/jump_n/0/%d/0/%d", mcnt, mcnt2); - break; - - case set_number_at: - extract_number_and_incr (&mcnt, &p); - extract_number_and_incr (&mcnt2, &p); - printf ("/set_number_at/0/%d/0/%d", mcnt, mcnt2); - break; - - case wordbound: - printf ("/wordbound"); - break; - - case notwordbound: - printf ("/notwordbound"); - break; - - case wordbeg: - printf ("/wordbeg"); - break; - - case wordend: - printf ("/wordend"); - -#ifdef emacs - case before_dot: - printf ("/before_dot"); - break; - - case at_dot: - printf ("/at_dot"); - break; - - case after_dot: - printf ("/after_dot"); - break; - - case syntaxspec: - printf ("/syntaxspec"); - mcnt = *p++; - printf ("/%d", mcnt); - break; - - case notsyntaxspec: - printf ("/notsyntaxspec"); - mcnt = *p++; - printf ("/%d", mcnt); - break; -#endif /* emacs */ - - case wordchar: - printf ("/wordchar"); - break; - - case notwordchar: - printf ("/notwordchar"); - break; - - case begbuf: - printf ("/begbuf"); - break; - - case endbuf: - printf ("/endbuf"); - break; - - default: - printf ("?%d", *(p-1)); - } - } - printf ("/\n"); -} - - -void -print_compiled_pattern (bufp) - struct re_pattern_buffer *bufp; -{ - unsigned char *buffer = bufp->buffer; - - print_partial_compiled_pattern (buffer, buffer + bufp->used); - printf ("%d bytes used/%d bytes allocated.\n", bufp->used, bufp->allocated); - - if (bufp->fastmap_accurate && bufp->fastmap) - { - printf ("fastmap: "); - print_fastmap (bufp->fastmap); - } - - printf ("re_nsub: %d\t", bufp->re_nsub); - printf ("regs_alloc: %d\t", bufp->regs_allocated); - printf ("can_be_null: %d\t", bufp->can_be_null); - printf ("newline_anchor: %d\n", bufp->newline_anchor); - printf ("no_sub: %d\t", bufp->no_sub); - printf ("not_bol: %d\t", bufp->not_bol); - printf ("not_eol: %d\t", bufp->not_eol); - printf ("syntax: %d\n", bufp->syntax); - /* Perhaps we should print the translate table? */ -} - - -void -print_double_string (where, string1, size1, string2, size2) - const char *where; - const char *string1; - const char *string2; - int size1; - int size2; -{ - unsigned this_char; - - if (where == NULL) - printf ("(null)"); - else - { - if (FIRST_STRING_P (where)) - { - for (this_char = where - string1; this_char < size1; this_char++) - printchar (string1[this_char]); - - where = string2; - } - - for (this_char = where - string2; this_char < size2; this_char++) - printchar (string2[this_char]); - } -} - -#else /* not DEBUG */ - -#undef assert -#define assert(e) - -#define DEBUG_STATEMENT(e) -#define DEBUG_PRINT1(x) -#define DEBUG_PRINT2(x1, x2) -#define DEBUG_PRINT3(x1, x2, x3) -#define DEBUG_PRINT4(x1, x2, x3, x4) -#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) -#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) - -#endif /* not DEBUG */ - -/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can - also be assigned to arbitrarily: each pattern buffer stores its own - syntax, so it can be changed between regex compilations. */ -reg_syntax_t re_syntax_options = RE_SYNTAX_EMACS; - - -/* Specify the precise syntax of regexps for compilation. This provides - for compatibility for various utilities which historically have - different, incompatible syntaxes. - - The argument SYNTAX is a bit mask comprised of the various bits - defined in regex.h. We return the old syntax. */ - -reg_syntax_t -re_set_syntax (syntax) - reg_syntax_t syntax; -{ - reg_syntax_t ret = re_syntax_options; - - re_syntax_options = syntax; - return ret; -} - -/* This table gives an error message for each of the error codes listed - in regex.h. Obviously the order here has to be same as there. */ - -static const char *re_error_msg[] = - { NULL, /* REG_NOERROR */ - "No match", /* REG_NOMATCH */ - "Invalid regular expression", /* REG_BADPAT */ - "Invalid collation character", /* REG_ECOLLATE */ - "Invalid character class name", /* REG_ECTYPE */ - "Trailing backslash", /* REG_EESCAPE */ - "Invalid back reference", /* REG_ESUBREG */ - "Unmatched [ or [^", /* REG_EBRACK */ - "Unmatched ( or \\(", /* REG_EPAREN */ - "Unmatched \\{", /* REG_EBRACE */ - "Invalid content of \\{\\}", /* REG_BADBR */ - "Invalid range end", /* REG_ERANGE */ - "Memory exhausted", /* REG_ESPACE */ - "Invalid preceding regular expression", /* REG_BADRPT */ - "Premature end of regular expression", /* REG_EEND */ - "Regular expression too big", /* REG_ESIZE */ - "Unmatched ) or \\)", /* REG_ERPAREN */ - }; - -/* Subroutine declarations and macros for regex_compile. */ - -static void store_op1 (), store_op2 (); -static void insert_op1 (), insert_op2 (); -static boolean at_begline_loc_p (), at_endline_loc_p (); -static boolean group_in_compile_stack (); -static reg_errcode_t compile_range (); - -/* Fetch the next character in the uncompiled pattern---translating it - if necessary. Also cast from a signed character in the constant - string passed to us by the user to an unsigned char that we can use - as an array index (in, e.g., `translate'). */ -#define PATFETCH(c) \ - do {if (p == pend) return REG_EEND; \ - c = (unsigned char) *p++; \ - if (translate) c = translate[c]; \ - } while (0) - -/* Fetch the next character in the uncompiled pattern, with no - translation. */ -#define PATFETCH_RAW(c) \ - do {if (p == pend) return REG_EEND; \ - c = (unsigned char) *p++; \ - } while (0) - -/* Go backwards one character in the pattern. */ -#define PATUNFETCH p-- - - -/* If `translate' is non-null, return translate[D], else just D. We - cast the subscript to translate because some data is declared as - `char *', to avoid warnings when a string constant is passed. But - when we use a character as a subscript we must make it unsigned. */ -#define TRANSLATE(d) (translate ? translate[(unsigned char) (d)] : (d)) - - -/* Macros for outputting the compiled pattern into `buffer'. */ - -/* If the buffer isn't allocated when it comes in, use this. */ -#define INIT_BUF_SIZE 32 - -/* Make sure we have at least N more bytes of space in buffer. */ -#define GET_BUFFER_SPACE(n) \ - while (b - bufp->buffer + (n) > bufp->allocated) \ - EXTEND_BUFFER () - -/* Make sure we have one more byte of buffer space and then add C to it. */ -#define BUF_PUSH(c) \ - do { \ - GET_BUFFER_SPACE (1); \ - *b++ = (unsigned char) (c); \ - } while (0) - - -/* Ensure we have two more bytes of buffer space and then append C1 and C2. */ -#define BUF_PUSH_2(c1, c2) \ - do { \ - GET_BUFFER_SPACE (2); \ - *b++ = (unsigned char) (c1); \ - *b++ = (unsigned char) (c2); \ - } while (0) - - -/* As with BUF_PUSH_2, except for three bytes. */ -#define BUF_PUSH_3(c1, c2, c3) \ - do { \ - GET_BUFFER_SPACE (3); \ - *b++ = (unsigned char) (c1); \ - *b++ = (unsigned char) (c2); \ - *b++ = (unsigned char) (c3); \ - } while (0) - - -/* Store a jump with opcode OP at LOC to location TO. We store a - relative address offset by the three bytes the jump itself occupies. */ -#define STORE_JUMP(op, loc, to) \ - store_op1 (op, loc, (to) - (loc) - 3) - -/* Likewise, for a two-argument jump. */ -#define STORE_JUMP2(op, loc, to, arg) \ - store_op2 (op, loc, (to) - (loc) - 3, arg) - -/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */ -#define INSERT_JUMP(op, loc, to) \ - insert_op1 (op, loc, (to) - (loc) - 3, b) - -/* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */ -#define INSERT_JUMP2(op, loc, to, arg) \ - insert_op2 (op, loc, (to) - (loc) - 3, arg, b) - - -/* This is not an arbitrary limit: the arguments which represent offsets - into the pattern are two bytes long. So if 2^16 bytes turns out to - be too small, many things would have to change. */ -#define MAX_BUF_SIZE (1L << 16) - - -/* Extend the buffer by twice its current size via realloc and - reset the pointers that pointed into the old block to point to the - correct places in the new one. If extending the buffer results in it - being larger than MAX_BUF_SIZE, then flag memory exhausted. */ -#define EXTEND_BUFFER() \ - do { \ - unsigned char *old_buffer = bufp->buffer; \ - if (bufp->allocated == MAX_BUF_SIZE) \ - return REG_ESIZE; \ - bufp->allocated <<= 1; \ - if (bufp->allocated > MAX_BUF_SIZE) \ - bufp->allocated = MAX_BUF_SIZE; \ - bufp->buffer = (unsigned char *) realloc (bufp->buffer, bufp->allocated);\ - if (bufp->buffer == NULL) \ - return REG_ESPACE; \ - /* If the buffer moved, move all the pointers into it. */ \ - if (old_buffer != bufp->buffer) \ - { \ - b = (b - old_buffer) + bufp->buffer; \ - begalt = (begalt - old_buffer) + bufp->buffer; \ - if (fixup_alt_jump) \ - fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\ - if (laststart) \ - laststart = (laststart - old_buffer) + bufp->buffer; \ - if (pending_exact) \ - pending_exact = (pending_exact - old_buffer) + bufp->buffer; \ - } \ - } while (0) - - -/* Since we have one byte reserved for the register number argument to - {start,stop}_memory, the maximum number of groups we can report - things about is what fits in that byte. */ -#define MAX_REGNUM 255 - -/* But patterns can have more than `MAX_REGNUM' registers. We just - ignore the excess. */ -typedef unsigned regnum_t; - - -/* Macros for the compile stack. */ - -/* Since offsets can go either forwards or backwards, this type needs to - be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */ -typedef int pattern_offset_t; - -typedef struct -{ - pattern_offset_t begalt_offset; - pattern_offset_t fixup_alt_jump; - pattern_offset_t inner_group_offset; - pattern_offset_t laststart_offset; - regnum_t regnum; -} compile_stack_elt_t; - - -typedef struct -{ - compile_stack_elt_t *stack; - unsigned size; - unsigned avail; /* Offset of next open position. */ -} compile_stack_type; - - -#define INIT_COMPILE_STACK_SIZE 32 - -#define COMPILE_STACK_EMPTY (compile_stack.avail == 0) -#define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size) - -/* The next available element. */ -#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail]) - - -/* Set the bit for character C in a list. */ -#define SET_LIST_BIT(c) \ - (b[((unsigned char) (c)) / BYTEWIDTH] \ - |= 1 << (((unsigned char) c) % BYTEWIDTH)) - - -/* Get the next unsigned number in the uncompiled pattern. */ -#define GET_UNSIGNED_NUMBER(num) \ - { if (p != pend) \ - { \ - PATFETCH (c); \ - while (ISDIGIT (c)) \ - { \ - if (num < 0) \ - num = 0; \ - num = num * 10 + c - '0'; \ - if (p == pend) \ - break; \ - PATFETCH (c); \ - } \ - } \ - } - -#define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ - -#define IS_CHAR_CLASS(string) \ - (STREQ (string, "alpha") || STREQ (string, "upper") \ - || STREQ (string, "lower") || STREQ (string, "digit") \ - || STREQ (string, "alnum") || STREQ (string, "xdigit") \ - || STREQ (string, "space") || STREQ (string, "print") \ - || STREQ (string, "punct") || STREQ (string, "graph") \ - || STREQ (string, "cntrl") || STREQ (string, "blank")) - -/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX. - Returns one of error codes defined in `regex.h', or zero for success. - - Assumes the `allocated' (and perhaps `buffer') and `translate' - fields are set in BUFP on entry. - - If it succeeds, results are put in BUFP (if it returns an error, the - contents of BUFP are undefined): - `buffer' is the compiled pattern; - `syntax' is set to SYNTAX; - `used' is set to the length of the compiled pattern; - `fastmap_accurate' is zero; - `re_nsub' is the number of subexpressions in PATTERN; - `not_bol' and `not_eol' are zero; - - The `fastmap' and `newline_anchor' fields are neither - examined nor set. */ - -static reg_errcode_t -regex_compile (pattern, size, syntax, bufp) - const char *pattern; - int size; - reg_syntax_t syntax; - struct re_pattern_buffer *bufp; -{ - /* We fetch characters from PATTERN here. Even though PATTERN is - `char *' (i.e., signed), we declare these variables as unsigned, so - they can be reliably used as array indices. */ - register unsigned char c, c1; - - /* A random tempory spot in PATTERN. */ - const char *p1; - - /* Points to the end of the buffer, where we should append. */ - register unsigned char *b; - - /* Keeps track of unclosed groups. */ - compile_stack_type compile_stack; - - /* Points to the current (ending) position in the pattern. */ - const char *p = pattern; - const char *pend = pattern + size; - - /* How to translate the characters in the pattern. */ - char *translate = bufp->translate; - - /* Address of the count-byte of the most recently inserted `exactn' - command. This makes it possible to tell if a new exact-match - character can be added to that command or if the character requires - a new `exactn' command. */ - unsigned char *pending_exact = 0; - - /* Address of start of the most recently finished expression. - This tells, e.g., postfix * where to find the start of its - operand. Reset at the beginning of groups and alternatives. */ - unsigned char *laststart = 0; - - /* Address of beginning of regexp, or inside of last group. */ - unsigned char *begalt; - - /* Place in the uncompiled pattern (i.e., the {) to - which to go back if the interval is invalid. */ - const char *beg_interval; - - /* Address of the place where a forward jump should go to the end of - the containing expression. Each alternative of an `or' -- except the - last -- ends with a forward jump of this sort. */ - unsigned char *fixup_alt_jump = 0; - - /* Counts open-groups as they are encountered. Remembered for the - matching close-group on the compile stack, so the same register - number is put in the stop_memory as the start_memory. */ - regnum_t regnum = 0; - -#ifdef DEBUG - DEBUG_PRINT1 ("\nCompiling pattern: "); - if (debug) - { - unsigned debug_count; - - for (debug_count = 0; debug_count < size; debug_count++) - printchar (pattern[debug_count]); - putchar ('\n'); - } -#endif /* DEBUG */ - - /* Initialize the compile stack. */ - compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t); - if (compile_stack.stack == NULL) - return REG_ESPACE; - - compile_stack.size = INIT_COMPILE_STACK_SIZE; - compile_stack.avail = 0; - - /* Initialize the pattern buffer. */ - bufp->syntax = syntax; - bufp->fastmap_accurate = 0; - bufp->not_bol = bufp->not_eol = 0; - - /* Set `used' to zero, so that if we return an error, the pattern - printer (for debugging) will think there's no pattern. We reset it - at the end. */ - bufp->used = 0; - - /* Always count groups, whether or not bufp->no_sub is set. */ - bufp->re_nsub = 0; - -#if !defined (emacs) && !defined (SYNTAX_TABLE) - /* Initialize the syntax table. */ - init_syntax_once (); -#endif - - if (bufp->allocated == 0) - { - if (bufp->buffer) - { /* If zero allocated, but buffer is non-null, try to realloc - enough space. This loses if buffer's address is bogus, but - that is the user's responsibility. */ - RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char); - } - else - { /* Caller did not allocate a buffer. Do it for them. */ - bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char); - } - if (!bufp->buffer) return REG_ESPACE; - - bufp->allocated = INIT_BUF_SIZE; - } - - begalt = b = bufp->buffer; - - /* Loop through the uncompiled pattern until we're at the end. */ - while (p != pend) - { - PATFETCH (c); - - switch (c) - { - case '^': - { - if ( /* If at start of pattern, it's an operator. */ - p == pattern + 1 - /* If context independent, it's an operator. */ - || syntax & RE_CONTEXT_INDEP_ANCHORS - /* Otherwise, depends on what's come before. */ - || at_begline_loc_p (pattern, p, syntax)) - BUF_PUSH (begline); - else - goto normal_char; - } - break; - - - case '$': - { - if ( /* If at end of pattern, it's an operator. */ - p == pend - /* If context independent, it's an operator. */ - || syntax & RE_CONTEXT_INDEP_ANCHORS - /* Otherwise, depends on what's next. */ - || at_endline_loc_p (p, pend, syntax)) - BUF_PUSH (endline); - else - goto normal_char; - } - break; - - - case '+': - case '?': - if ((syntax & RE_BK_PLUS_QM) - || (syntax & RE_LIMITED_OPS)) - goto normal_char; - handle_plus: - case '*': - /* If there is no previous pattern... */ - if (!laststart) - { - if (syntax & RE_CONTEXT_INVALID_OPS) - return REG_BADRPT; - else if (!(syntax & RE_CONTEXT_INDEP_OPS)) - goto normal_char; - } - - { - /* Are we optimizing this jump? */ - boolean keep_string_p = false; - - /* 1 means zero (many) matches is allowed. */ - char zero_times_ok = 0, many_times_ok = 0; - - /* If there is a sequence of repetition chars, collapse it - down to just one (the right one). We can't combine - interval operators with these because of, e.g., `a{2}*', - which should only match an even number of `a's. */ - - for (;;) - { - zero_times_ok |= c != '+'; - many_times_ok |= c != '?'; - - if (p == pend) - break; - - PATFETCH (c); - - if (c == '*' - || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?'))) - ; - - else if (syntax & RE_BK_PLUS_QM && c == '\\') - { - if (p == pend) return REG_EESCAPE; - - PATFETCH (c1); - if (!(c1 == '+' || c1 == '?')) - { - PATUNFETCH; - PATUNFETCH; - break; - } - - c = c1; - } - else - { - PATUNFETCH; - break; - } - - /* If we get here, we found another repeat character. */ - } - - /* Star, etc. applied to an empty pattern is equivalent - to an empty pattern. */ - if (!laststart) - break; - - /* Now we know whether or not zero matches is allowed - and also whether or not two or more matches is allowed. */ - if (many_times_ok) - { /* More than one repetition is allowed, so put in at the - end a backward relative jump from `b' to before the next - jump we're going to put in below (which jumps from - laststart to after this jump). - - But if we are at the `*' in the exact sequence `.*\n', - insert an unconditional jump backwards to the ., - instead of the beginning of the loop. This way we only - push a failure point once, instead of every time - through the loop. */ - assert (p - 1 > pattern); - - /* Allocate the space for the jump. */ - GET_BUFFER_SPACE (3); - - /* We know we are not at the first character of the pattern, - because laststart was nonzero. And we've already - incremented `p', by the way, to be the character after - the `*'. Do we have to do something analogous here - for null bytes, because of RE_DOT_NOT_NULL? */ - if (TRANSLATE (*(p - 2)) == TRANSLATE ('.') - && zero_times_ok - && p < pend && TRANSLATE (*p) == TRANSLATE ('\n') - && !(syntax & RE_DOT_NEWLINE)) - { /* We have .*\n. */ - STORE_JUMP (jump, b, laststart); - keep_string_p = true; - } - else - /* Anything else. */ - STORE_JUMP (maybe_pop_jump, b, laststart - 3); - - /* We've added more stuff to the buffer. */ - b += 3; - } - - /* On failure, jump from laststart to b + 3, which will be the - end of the buffer after this jump is inserted. */ - GET_BUFFER_SPACE (3); - INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump - : on_failure_jump, - laststart, b + 3); - pending_exact = 0; - b += 3; - - if (!zero_times_ok) - { - /* At least one repetition is required, so insert a - `dummy_failure_jump' before the initial - `on_failure_jump' instruction of the loop. This - effects a skip over that instruction the first time - we hit that loop. */ - GET_BUFFER_SPACE (3); - INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6); - b += 3; - } - } - break; - - - case '.': - laststart = b; - BUF_PUSH (anychar); - break; - - - case '[': - { - boolean had_char_class = false; - - if (p == pend) return REG_EBRACK; - - /* Ensure that we have enough space to push a charset: the - opcode, the length count, and the bitset; 34 bytes in all. */ - GET_BUFFER_SPACE (34); - - laststart = b; - - /* We test `*p == '^' twice, instead of using an if - statement, so we only need one BUF_PUSH. */ - BUF_PUSH (*p == '^' ? charset_not : charset); - if (*p == '^') - p++; - - /* Remember the first position in the bracket expression. */ - p1 = p; - - /* Push the number of bytes in the bitmap. */ - BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH); - - /* Clear the whole map. */ - bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH); - - /* charset_not matches newline according to a syntax bit. */ - if ((re_opcode_t) b[-2] == charset_not - && (syntax & RE_HAT_LISTS_NOT_NEWLINE)) - SET_LIST_BIT ('\n'); - - /* Read in characters and ranges, setting map bits. */ - for (;;) - { - if (p == pend) return REG_EBRACK; - - PATFETCH (c); - - /* \ might escape characters inside [...] and [^...]. */ - if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\') - { - if (p == pend) return REG_EESCAPE; - - PATFETCH (c1); - SET_LIST_BIT (c1); - continue; - } - - /* Could be the end of the bracket expression. If it's - not (i.e., when the bracket expression is `[]' so - far), the ']' character bit gets set way below. */ - if (c == ']' && p != p1 + 1) - break; - - /* Look ahead to see if it's a range when the last thing - was a character class. */ - if (had_char_class && c == '-' && *p != ']') - return REG_ERANGE; - - /* Look ahead to see if it's a range when the last thing - was a character: if this is a hyphen not at the - beginning or the end of a list, then it's the range - operator. */ - if (c == '-' - && !(p - 2 >= pattern && p[-2] == '[') - && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^') - && *p != ']') - { - reg_errcode_t ret - = compile_range (&p, pend, translate, syntax, b); - if (ret != REG_NOERROR) return ret; - } - - else if (p[0] == '-' && p[1] != ']') - { /* This handles ranges made up of characters only. */ - reg_errcode_t ret; - - /* Move past the `-'. */ - PATFETCH (c1); - - ret = compile_range (&p, pend, translate, syntax, b); - if (ret != REG_NOERROR) return ret; - } - - /* See if we're at the beginning of a possible character - class. */ - - else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':') - { /* Leave room for the null. */ - char str[CHAR_CLASS_MAX_LENGTH + 1]; - - PATFETCH (c); - c1 = 0; - - /* If pattern is `[[:'. */ - if (p == pend) return REG_EBRACK; - - for (;;) - { - PATFETCH (c); - if (c == ':' || c == ']' || p == pend - || c1 == CHAR_CLASS_MAX_LENGTH) - break; - str[c1++] = c; - } - str[c1] = '\0'; - - /* If isn't a word bracketed by `[:' and:`]': - undo the ending character, the letters, and leave - the leading `:' and `[' (but set bits for them). */ - if (c == ':' && *p == ']') - { - int ch; - boolean is_alnum = STREQ (str, "alnum"); - boolean is_alpha = STREQ (str, "alpha"); - boolean is_blank = STREQ (str, "blank"); - boolean is_cntrl = STREQ (str, "cntrl"); - boolean is_digit = STREQ (str, "digit"); - boolean is_graph = STREQ (str, "graph"); - boolean is_lower = STREQ (str, "lower"); - boolean is_print = STREQ (str, "print"); - boolean is_punct = STREQ (str, "punct"); - boolean is_space = STREQ (str, "space"); - boolean is_upper = STREQ (str, "upper"); - boolean is_xdigit = STREQ (str, "xdigit"); - - if (!IS_CHAR_CLASS (str)) return REG_ECTYPE; - - /* Throw away the ] at the end of the character - class. */ - PATFETCH (c); - - if (p == pend) return REG_EBRACK; - - for (ch = 0; ch < 1 << BYTEWIDTH; ch++) - { - if ( (is_alnum && ISALNUM (ch)) - || (is_alpha && ISALPHA (ch)) - || (is_blank && ISBLANK (ch)) - || (is_cntrl && ISCNTRL (ch)) - || (is_digit && ISDIGIT (ch)) - || (is_graph && ISGRAPH (ch)) - || (is_lower && ISLOWER (ch)) - || (is_print && ISPRINT (ch)) - || (is_punct && ISPUNCT (ch)) - || (is_space && ISSPACE (ch)) - || (is_upper && ISUPPER (ch)) - || (is_xdigit && ISXDIGIT (ch))) - SET_LIST_BIT (ch); - } - had_char_class = true; - } - else - { - c1++; - while (c1--) - PATUNFETCH; - SET_LIST_BIT ('['); - SET_LIST_BIT (':'); - had_char_class = false; - } - } - else - { - had_char_class = false; - SET_LIST_BIT (c); - } - } - - /* Discard any (non)matching list bytes that are all 0 at the - end of the map. Decrease the map-length byte too. */ - while ((int) b[-1] > 0 && b[b[-1] - 1] == 0) - b[-1]--; - b += b[-1]; - } - break; - - - case '(': - if (syntax & RE_NO_BK_PARENS) - goto handle_open; - else - goto normal_char; - - - case ')': - if (syntax & RE_NO_BK_PARENS) - goto handle_close; - else - goto normal_char; - - - case '\n': - if (syntax & RE_NEWLINE_ALT) - goto handle_alt; - else - goto normal_char; - - - case '|': - if (syntax & RE_NO_BK_VBAR) - goto handle_alt; - else - goto normal_char; - - - case '{': - if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES) - goto handle_interval; - else - goto normal_char; - - - case '\\': - if (p == pend) return REG_EESCAPE; - - /* Do not translate the character after the \, so that we can - distinguish, e.g., \B from \b, even if we normally would - translate, e.g., B to b. */ - PATFETCH_RAW (c); - - switch (c) - { - case '(': - if (syntax & RE_NO_BK_PARENS) - goto normal_backslash; - - handle_open: - bufp->re_nsub++; - regnum++; - - if (COMPILE_STACK_FULL) - { - RETALLOC (compile_stack.stack, compile_stack.size << 1, - compile_stack_elt_t); - if (compile_stack.stack == NULL) return REG_ESPACE; - - compile_stack.size <<= 1; - } - - /* These are the values to restore when we hit end of this - group. They are all relative offsets, so that if the - whole pattern moves because of realloc, they will still - be valid. */ - COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer; - COMPILE_STACK_TOP.fixup_alt_jump - = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0; - COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer; - COMPILE_STACK_TOP.regnum = regnum; - - /* We will eventually replace the 0 with the number of - groups inner to this one. But do not push a - start_memory for groups beyond the last one we can - represent in the compiled pattern. */ - if (regnum <= MAX_REGNUM) - { - COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2; - BUF_PUSH_3 (start_memory, regnum, 0); - } - - compile_stack.avail++; - - fixup_alt_jump = 0; - laststart = 0; - begalt = b; - /* If we've reached MAX_REGNUM groups, then this open - won't actually generate any code, so we'll have to - clear pending_exact explicitly. */ - pending_exact = 0; - break; - - - case ')': - if (syntax & RE_NO_BK_PARENS) goto normal_backslash; - - if (COMPILE_STACK_EMPTY) - if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) - goto normal_backslash; - else - return REG_ERPAREN; - - handle_close: - if (fixup_alt_jump) - { /* Push a dummy failure point at the end of the - alternative for a possible future - `pop_failure_jump' to pop. See comments at - `push_dummy_failure' in `re_match_2'. */ - BUF_PUSH (push_dummy_failure); - - /* We allocated space for this jump when we assigned - to `fixup_alt_jump', in the `handle_alt' case below. */ - STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1); - } - - /* See similar code for backslashed left paren above. */ - if (COMPILE_STACK_EMPTY) - if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) - goto normal_char; - else - return REG_ERPAREN; - - /* Since we just checked for an empty stack above, this - ``can't happen''. */ - assert (compile_stack.avail != 0); - { - /* We don't just want to restore into `regnum', because - later groups should continue to be numbered higher, - as in `(ab)c(de)' -- the second group is #2. */ - regnum_t this_group_regnum; - - compile_stack.avail--; - begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset; - fixup_alt_jump - = COMPILE_STACK_TOP.fixup_alt_jump - ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1 - : 0; - laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset; - this_group_regnum = COMPILE_STACK_TOP.regnum; - /* If we've reached MAX_REGNUM groups, then this open - won't actually generate any code, so we'll have to - clear pending_exact explicitly. */ - pending_exact = 0; - - /* We're at the end of the group, so now we know how many - groups were inside this one. */ - if (this_group_regnum <= MAX_REGNUM) - { - unsigned char *inner_group_loc - = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset; - - *inner_group_loc = regnum - this_group_regnum; - BUF_PUSH_3 (stop_memory, this_group_regnum, - regnum - this_group_regnum); - } - } - break; - - - case '|': /* `\|'. */ - if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR) - goto normal_backslash; - handle_alt: - if (syntax & RE_LIMITED_OPS) - goto normal_char; - - /* Insert before the previous alternative a jump which - jumps to this alternative if the former fails. */ - GET_BUFFER_SPACE (3); - INSERT_JUMP (on_failure_jump, begalt, b + 6); - pending_exact = 0; - b += 3; - - /* The alternative before this one has a jump after it - which gets executed if it gets matched. Adjust that - jump so it will jump to this alternative's analogous - jump (put in below, which in turn will jump to the next - (if any) alternative's such jump, etc.). The last such - jump jumps to the correct final destination. A picture: - _____ _____ - | | | | - | v | v - a | b | c - - If we are at `b', then fixup_alt_jump right now points to a - three-byte space after `a'. We'll put in the jump, set - fixup_alt_jump to right after `b', and leave behind three - bytes which we'll fill in when we get to after `c'. */ - - if (fixup_alt_jump) - STORE_JUMP (jump_past_alt, fixup_alt_jump, b); - - /* Mark and leave space for a jump after this alternative, - to be filled in later either by next alternative or - when know we're at the end of a series of alternatives. */ - fixup_alt_jump = b; - GET_BUFFER_SPACE (3); - b += 3; - - laststart = 0; - begalt = b; - break; - - - case '{': - /* If \{ is a literal. */ - if (!(syntax & RE_INTERVALS) - /* If we're at `\{' and it's not the open-interval - operator. */ - || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) - || (p - 2 == pattern && p == pend)) - goto normal_backslash; - - handle_interval: - { - /* If got here, then the syntax allows intervals. */ - - /* At least (most) this many matches must be made. */ - int lower_bound = -1, upper_bound = -1; - - beg_interval = p - 1; - - if (p == pend) - { - if (syntax & RE_NO_BK_BRACES) - goto unfetch_interval; - else - return REG_EBRACE; - } - - GET_UNSIGNED_NUMBER (lower_bound); - - if (c == ',') - { - GET_UNSIGNED_NUMBER (upper_bound); - if (upper_bound < 0) upper_bound = RE_DUP_MAX; - } - else - /* Interval such as `{1}' => match exactly once. */ - upper_bound = lower_bound; - - if (lower_bound < 0 || upper_bound > RE_DUP_MAX - || lower_bound > upper_bound) - { - if (syntax & RE_NO_BK_BRACES) - goto unfetch_interval; - else - return REG_BADBR; - } - - if (!(syntax & RE_NO_BK_BRACES)) - { - if (c != '\\') return REG_EBRACE; - - PATFETCH (c); - } - - if (c != '}') - { - if (syntax & RE_NO_BK_BRACES) - goto unfetch_interval; - else - return REG_BADBR; - } - - /* We just parsed a valid interval. */ - - /* If it's invalid to have no preceding re. */ - if (!laststart) - { - if (syntax & RE_CONTEXT_INVALID_OPS) - return REG_BADRPT; - else if (syntax & RE_CONTEXT_INDEP_OPS) - laststart = b; - else - goto unfetch_interval; - } - - /* If the upper bound is zero, don't want to succeed at - all; jump from `laststart' to `b + 3', which will be - the end of the buffer after we insert the jump. */ - if (upper_bound == 0) - { - GET_BUFFER_SPACE (3); - INSERT_JUMP (jump, laststart, b + 3); - b += 3; - } - - /* Otherwise, we have a nontrivial interval. When - we're all done, the pattern will look like: - set_number_at - set_number_at - succeed_n - - jump_n - (The upper bound and `jump_n' are omitted if - `upper_bound' is 1, though.) */ - else - { /* If the upper bound is > 1, we need to insert - more at the end of the loop. */ - unsigned nbytes = 10 + (upper_bound > 1) * 10; - - GET_BUFFER_SPACE (nbytes); - - /* Initialize lower bound of the `succeed_n', even - though it will be set during matching by its - attendant `set_number_at' (inserted next), - because `re_compile_fastmap' needs to know. - Jump to the `jump_n' we might insert below. */ - INSERT_JUMP2 (succeed_n, laststart, - b + 5 + (upper_bound > 1) * 5, - lower_bound); - b += 5; - - /* Code to initialize the lower bound. Insert - before the `succeed_n'. The `5' is the last two - bytes of this `set_number_at', plus 3 bytes of - the following `succeed_n'. */ - insert_op2 (set_number_at, laststart, 5, lower_bound, b); - b += 5; - - if (upper_bound > 1) - { /* More than one repetition is allowed, so - append a backward jump to the `succeed_n' - that starts this interval. - - When we've reached this during matching, - we'll have matched the interval once, so - jump back only `upper_bound - 1' times. */ - STORE_JUMP2 (jump_n, b, laststart + 5, - upper_bound - 1); - b += 5; - - /* The location we want to set is the second - parameter of the `jump_n'; that is `b-2' as - an absolute address. `laststart' will be - the `set_number_at' we're about to insert; - `laststart+3' the number to set, the source - for the relative address. But we are - inserting into the middle of the pattern -- - so everything is getting moved up by 5. - Conclusion: (b - 2) - (laststart + 3) + 5, - i.e., b - laststart. - - We insert this at the beginning of the loop - so that if we fail during matching, we'll - reinitialize the bounds. */ - insert_op2 (set_number_at, laststart, b - laststart, - upper_bound - 1, b); - b += 5; - } - } - pending_exact = 0; - beg_interval = NULL; - } - break; - - unfetch_interval: - /* If an invalid interval, match the characters as literals. */ - assert (beg_interval); - p = beg_interval; - beg_interval = NULL; - - /* normal_char and normal_backslash need `c'. */ - PATFETCH (c); - - if (!(syntax & RE_NO_BK_BRACES)) - { - if (p > pattern && p[-1] == '\\') - goto normal_backslash; - } - goto normal_char; - -#ifdef emacs - /* There is no way to specify the before_dot and after_dot - operators. rms says this is ok. --karl */ - case '=': - BUF_PUSH (at_dot); - break; - - case 's': - laststart = b; - PATFETCH (c); - BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]); - break; - - case 'S': - laststart = b; - PATFETCH (c); - BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]); - break; -#endif /* emacs */ - - - case 'w': - laststart = b; - BUF_PUSH (wordchar); - break; - - - case 'W': - laststart = b; - BUF_PUSH (notwordchar); - break; - - - case '<': - BUF_PUSH (wordbeg); - break; - - case '>': - BUF_PUSH (wordend); - break; - - case 'b': - BUF_PUSH (wordbound); - break; - - case 'B': - BUF_PUSH (notwordbound); - break; - - case '`': - BUF_PUSH (begbuf); - break; - - case '\'': - BUF_PUSH (endbuf); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - if (syntax & RE_NO_BK_REFS) - goto normal_char; - - c1 = c - '0'; - - if (c1 > regnum) - return REG_ESUBREG; - - /* Can't back reference to a subexpression if inside of it. */ - if (group_in_compile_stack (compile_stack, c1)) - goto normal_char; - - laststart = b; - BUF_PUSH_2 (duplicate, c1); - break; - - - case '+': - case '?': - if (syntax & RE_BK_PLUS_QM) - goto handle_plus; - else - goto normal_backslash; - - default: - normal_backslash: - /* You might think it would be useful for \ to mean - not to translate; but if we don't translate it - it will never match anything. */ - c = TRANSLATE (c); - goto normal_char; - } - break; - - - default: - /* Expects the character in `c'. */ - normal_char: - /* If no exactn currently being built. */ - if (!pending_exact - - /* If last exactn not at current position. */ - || pending_exact + *pending_exact + 1 != b - - /* We have only one byte following the exactn for the count. */ - || *pending_exact == (1 << BYTEWIDTH) - 1 - - /* If followed by a repetition operator. */ - || *p == '*' || *p == '^' - || ((syntax & RE_BK_PLUS_QM) - ? *p == '\\' && (p[1] == '+' || p[1] == '?') - : (*p == '+' || *p == '?')) - || ((syntax & RE_INTERVALS) - && ((syntax & RE_NO_BK_BRACES) - ? *p == '{' - : (p[0] == '\\' && p[1] == '{')))) - { - /* Start building a new exactn. */ - - laststart = b; - - BUF_PUSH_2 (exactn, 0); - pending_exact = b - 1; - } - - BUF_PUSH (c); - (*pending_exact)++; - break; - } /* switch (c) */ - } /* while p != pend */ - - - /* Through the pattern now. */ - - if (fixup_alt_jump) - STORE_JUMP (jump_past_alt, fixup_alt_jump, b); - - if (!COMPILE_STACK_EMPTY) - return REG_EPAREN; - - free (compile_stack.stack); - - /* We have succeeded; set the length of the buffer. */ - bufp->used = b - bufp->buffer; - -#ifdef DEBUG - if (debug) - { - DEBUG_PRINT1 ("\nCompiled pattern: "); - print_compiled_pattern (bufp); - } -#endif /* DEBUG */ - - return REG_NOERROR; -} /* regex_compile */ - -/* Subroutines for `regex_compile'. */ - -/* Store OP at LOC followed by two-byte integer parameter ARG. */ - -static void -store_op1 (op, loc, arg) - re_opcode_t op; - unsigned char *loc; - int arg; -{ - *loc = (unsigned char) op; - STORE_NUMBER (loc + 1, arg); -} - - -/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */ - -static void -store_op2 (op, loc, arg1, arg2) - re_opcode_t op; - unsigned char *loc; - int arg1, arg2; -{ - *loc = (unsigned char) op; - STORE_NUMBER (loc + 1, arg1); - STORE_NUMBER (loc + 3, arg2); -} - - -/* Copy the bytes from LOC to END to open up three bytes of space at LOC - for OP followed by two-byte integer parameter ARG. */ - -static void -insert_op1 (op, loc, arg, end) - re_opcode_t op; - unsigned char *loc; - int arg; - unsigned char *end; -{ - register unsigned char *pfrom = end; - register unsigned char *pto = end + 3; - - while (pfrom != loc) - *--pto = *--pfrom; - - store_op1 (op, loc, arg); -} - - -/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */ - -static void -insert_op2 (op, loc, arg1, arg2, end) - re_opcode_t op; - unsigned char *loc; - int arg1, arg2; - unsigned char *end; -{ - register unsigned char *pfrom = end; - register unsigned char *pto = end + 5; - - while (pfrom != loc) - *--pto = *--pfrom; - - store_op2 (op, loc, arg1, arg2); -} - - -/* P points to just after a ^ in PATTERN. Return true if that ^ comes - after an alternative or a begin-subexpression. We assume there is at - least one character before the ^. */ - -static boolean -at_begline_loc_p (pattern, p, syntax) - const char *pattern, *p; - reg_syntax_t syntax; -{ - const char *prev = p - 2; - boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\'; - - return - /* After a subexpression? */ - (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash)) - /* After an alternative? */ - || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash)); -} - - -/* The dual of at_begline_loc_p. This one is for $. We assume there is - at least one character after the $, i.e., `P < PEND'. */ - -static boolean -at_endline_loc_p (p, pend, syntax) - const char *p, *pend; - int syntax; -{ - const char *next = p; - boolean next_backslash = *next == '\\'; - const char *next_next = p + 1 < pend ? p + 1 : NULL; - - return - /* Before a subexpression? */ - (syntax & RE_NO_BK_PARENS ? *next == ')' - : next_backslash && next_next && *next_next == ')') - /* Before an alternative? */ - || (syntax & RE_NO_BK_VBAR ? *next == '|' - : next_backslash && next_next && *next_next == '|'); -} - - -/* Returns true if REGNUM is in one of COMPILE_STACK's elements and - false if it's not. */ - -static boolean -group_in_compile_stack (compile_stack, regnum) - compile_stack_type compile_stack; - regnum_t regnum; -{ - int this_element; - - for (this_element = compile_stack.avail - 1; - this_element >= 0; - this_element--) - if (compile_stack.stack[this_element].regnum == regnum) - return true; - - return false; -} - - -/* Read the ending character of a range (in a bracket expression) from the - uncompiled pattern *P_PTR (which ends at PEND). We assume the - starting character is in `P[-2]'. (`P[-1]' is the character `-'.) - Then we set the translation of all bits between the starting and - ending characters (inclusive) in the compiled pattern B. - - Return an error code. - - We use these short variable names so we can use the same macros as - `regex_compile' itself. */ - -static reg_errcode_t -compile_range (p_ptr, pend, translate, syntax, b) - const char **p_ptr, *pend; - char *translate; - reg_syntax_t syntax; - unsigned char *b; -{ - unsigned this_char; - - const char *p = *p_ptr; - int range_start, range_end; - - if (p == pend) - return REG_ERANGE; - - /* Even though the pattern is a signed `char *', we need to fetch - with unsigned char *'s; if the high bit of the pattern character - is set, the range endpoints will be negative if we fetch using a - signed char *. - - We also want to fetch the endpoints without translating them; the - appropriate translation is done in the bit-setting loop below. */ - range_start = ((unsigned char *) p)[-2]; - range_end = ((unsigned char *) p)[0]; - - /* Have to increment the pointer into the pattern string, so the - caller isn't still at the ending character. */ - (*p_ptr)++; - - /* If the start is after the end, the range is empty. */ - if (range_start > range_end) - return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR; - - /* Here we see why `this_char' has to be larger than an `unsigned - char' -- the range is inclusive, so if `range_end' == 0xff - (assuming 8-bit characters), we would otherwise go into an infinite - loop, since all characters <= 0xff. */ - for (this_char = range_start; this_char <= range_end; this_char++) - { - SET_LIST_BIT (TRANSLATE (this_char)); - } - - return REG_NOERROR; -} - -/* Failure stack declarations and macros; both re_compile_fastmap and - re_match_2 use a failure stack. These have to be macros because of - REGEX_ALLOCATE. */ - - -/* Number of failure points for which to initially allocate space - when matching. If this number is exceeded, we allocate more - space, so it is not a hard limit. */ -#ifndef INIT_FAILURE_ALLOC -#define INIT_FAILURE_ALLOC 5 -#endif - -/* Roughly the maximum number of failure points on the stack. Would be - exactly that if always used MAX_FAILURE_SPACE each time we failed. - This is a variable only so users of regex can assign to it; we never - change it ourselves. */ -int re_max_failures = 2000; - -typedef const unsigned char *fail_stack_elt_t; - -typedef struct -{ - fail_stack_elt_t *stack; - unsigned size; - unsigned avail; /* Offset of next open position. */ -} fail_stack_type; - -#define FAIL_STACK_EMPTY() (fail_stack.avail == 0) -#define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0) -#define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size) -#define FAIL_STACK_TOP() (fail_stack.stack[fail_stack.avail]) - - -/* Initialize `fail_stack'. Do `return -2' if the alloc fails. */ - -#define INIT_FAIL_STACK() \ - do { \ - fail_stack.stack = (fail_stack_elt_t *) \ - REGEX_ALLOCATE (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \ - \ - if (fail_stack.stack == NULL) \ - return -2; \ - \ - fail_stack.size = INIT_FAILURE_ALLOC; \ - fail_stack.avail = 0; \ - } while (0) - - -/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items. - - Return 1 if succeeds, and 0 if either ran out of memory - allocating space for it or it was already too large. - - REGEX_REALLOCATE requires `destination' be declared. */ - -#define DOUBLE_FAIL_STACK(fail_stack) \ - ((fail_stack).size > re_max_failures * MAX_FAILURE_ITEMS \ - ? 0 \ - : ((fail_stack).stack = (fail_stack_elt_t *) \ - REGEX_REALLOCATE ((fail_stack).stack, \ - (fail_stack).size * sizeof (fail_stack_elt_t), \ - ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \ - \ - (fail_stack).stack == NULL \ - ? 0 \ - : ((fail_stack).size <<= 1, \ - 1))) - - -/* Push PATTERN_OP on FAIL_STACK. - - Return 1 if was able to do so and 0 if ran out of memory allocating - space to do so. */ -#define PUSH_PATTERN_OP(pattern_op, fail_stack) \ - ((FAIL_STACK_FULL () \ - && !DOUBLE_FAIL_STACK (fail_stack)) \ - ? 0 \ - : ((fail_stack).stack[(fail_stack).avail++] = pattern_op, \ - 1)) - -/* This pushes an item onto the failure stack. Must be a four-byte - value. Assumes the variable `fail_stack'. Probably should only - be called from within `PUSH_FAILURE_POINT'. */ -#define PUSH_FAILURE_ITEM(item) \ - fail_stack.stack[fail_stack.avail++] = (fail_stack_elt_t) item - -/* The complement operation. Assumes `fail_stack' is nonempty. */ -#define POP_FAILURE_ITEM() fail_stack.stack[--fail_stack.avail] - -/* Used to omit pushing failure point id's when we're not debugging. */ -#ifdef DEBUG -#define DEBUG_PUSH PUSH_FAILURE_ITEM -#define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_ITEM () -#else -#define DEBUG_PUSH(item) -#define DEBUG_POP(item_addr) -#endif - - -/* Push the information about the state we will need - if we ever fail back to it. - - Requires variables fail_stack, regstart, regend, reg_info, and - num_regs be declared. DOUBLE_FAIL_STACK requires `destination' be - declared. - - Does `return FAILURE_CODE' if runs out of memory. */ - -#define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \ - do { \ - char *destination; \ - /* Must be int, so when we don't save any registers, the arithmetic \ - of 0 + -1 isn't done as unsigned. */ \ - int this_reg; \ - \ - DEBUG_STATEMENT (failure_id++); \ - DEBUG_STATEMENT (nfailure_points_pushed++); \ - DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \ - DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\ - DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\ - \ - DEBUG_PRINT2 (" slots needed: %d\n", NUM_FAILURE_ITEMS); \ - DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \ - \ - /* Ensure we have enough space allocated for what we will push. */ \ - while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \ - { \ - if (!DOUBLE_FAIL_STACK (fail_stack)) \ - return failure_code; \ - \ - DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \ - (fail_stack).size); \ - DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\ - } \ - \ - /* Push the info, starting with the registers. */ \ - DEBUG_PRINT1 ("\n"); \ - \ - for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \ - this_reg++) \ - { \ - DEBUG_PRINT2 (" Pushing reg: %d\n", this_reg); \ - DEBUG_STATEMENT (num_regs_pushed++); \ - \ - DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \ - PUSH_FAILURE_ITEM (regstart[this_reg]); \ - \ - DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \ - PUSH_FAILURE_ITEM (regend[this_reg]); \ - \ - DEBUG_PRINT2 (" info: 0x%x\n ", reg_info[this_reg]); \ - DEBUG_PRINT2 (" match_null=%d", \ - REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \ - DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \ - DEBUG_PRINT2 (" matched_something=%d", \ - MATCHED_SOMETHING (reg_info[this_reg])); \ - DEBUG_PRINT2 (" ever_matched=%d", \ - EVER_MATCHED_SOMETHING (reg_info[this_reg])); \ - DEBUG_PRINT1 ("\n"); \ - PUSH_FAILURE_ITEM (reg_info[this_reg].word); \ - } \ - \ - DEBUG_PRINT2 (" Pushing low active reg: %d\n", lowest_active_reg);\ - PUSH_FAILURE_ITEM (lowest_active_reg); \ - \ - DEBUG_PRINT2 (" Pushing high active reg: %d\n", highest_active_reg);\ - PUSH_FAILURE_ITEM (highest_active_reg); \ - \ - DEBUG_PRINT2 (" Pushing pattern 0x%x: ", pattern_place); \ - DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \ - PUSH_FAILURE_ITEM (pattern_place); \ - \ - DEBUG_PRINT2 (" Pushing string 0x%x: `", string_place); \ - DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \ - size2); \ - DEBUG_PRINT1 ("'\n"); \ - PUSH_FAILURE_ITEM (string_place); \ - \ - DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \ - DEBUG_PUSH (failure_id); \ - } while (0) - -/* This is the number of items that are pushed and popped on the stack - for each register. */ -#define NUM_REG_ITEMS 3 - -/* Individual items aside from the registers. */ -#ifdef DEBUG -#define NUM_NONREG_ITEMS 5 /* Includes failure point id. */ -#else -#define NUM_NONREG_ITEMS 4 -#endif - -/* We push at most this many items on the stack. */ -#define MAX_FAILURE_ITEMS ((num_regs - 1) * NUM_REG_ITEMS + NUM_NONREG_ITEMS) - -/* We actually push this many items. */ -#define NUM_FAILURE_ITEMS \ - ((highest_active_reg - lowest_active_reg + 1) * NUM_REG_ITEMS \ - + NUM_NONREG_ITEMS) - -/* How many items can still be added to the stack without overflowing it. */ -#define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail) - - -/* Pops what PUSH_FAIL_STACK pushes. - - We restore into the parameters, all of which should be lvalues: - STR -- the saved data position. - PAT -- the saved pattern position. - LOW_REG, HIGH_REG -- the highest and lowest active registers. - REGSTART, REGEND -- arrays of string positions. - REG_INFO -- array of information about each subexpression. - - Also assumes the variables `fail_stack' and (if debugging), `bufp', - `pend', `string1', `size1', `string2', and `size2'. */ - -#define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\ -{ \ - DEBUG_STATEMENT (fail_stack_elt_t failure_id;) \ - int this_reg; \ - const unsigned char *string_temp; \ - \ - assert (!FAIL_STACK_EMPTY ()); \ - \ - /* Remove failure points and point to how many regs pushed. */ \ - DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \ - DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \ - DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \ - \ - assert (fail_stack.avail >= NUM_NONREG_ITEMS); \ - \ - DEBUG_POP (&failure_id); \ - DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \ - \ - /* If the saved string location is NULL, it came from an \ - on_failure_keep_string_jump opcode, and we want to throw away the \ - saved NULL, thus retaining our current position in the string. */ \ - string_temp = POP_FAILURE_ITEM (); \ - if (string_temp != NULL) \ - str = (const char *) string_temp; \ - \ - DEBUG_PRINT2 (" Popping string 0x%x: `", str); \ - DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \ - DEBUG_PRINT1 ("'\n"); \ - \ - pat = (unsigned char *) POP_FAILURE_ITEM (); \ - DEBUG_PRINT2 (" Popping pattern 0x%x: ", pat); \ - DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \ - \ - /* Restore register info. */ \ - high_reg = (unsigned) POP_FAILURE_ITEM (); \ - DEBUG_PRINT2 (" Popping high active reg: %d\n", high_reg); \ - \ - low_reg = (unsigned) POP_FAILURE_ITEM (); \ - DEBUG_PRINT2 (" Popping low active reg: %d\n", low_reg); \ - \ - for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \ - { \ - DEBUG_PRINT2 (" Popping reg: %d\n", this_reg); \ - \ - reg_info[this_reg].word = POP_FAILURE_ITEM (); \ - DEBUG_PRINT2 (" info: 0x%x\n", reg_info[this_reg]); \ - \ - regend[this_reg] = (const char *) POP_FAILURE_ITEM (); \ - DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \ - \ - regstart[this_reg] = (const char *) POP_FAILURE_ITEM (); \ - DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \ - } \ - \ - DEBUG_STATEMENT (nfailure_points_popped++); \ -} /* POP_FAILURE_POINT */ - -/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in - BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible - characters can start a string that matches the pattern. This fastmap - is used by re_search to skip quickly over impossible starting points. - - The caller must supply the address of a (1 << BYTEWIDTH)-byte data - area as BUFP->fastmap. - - We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in - the pattern buffer. - - Returns 0 if we succeed, -2 if an internal error. */ - -int -re_compile_fastmap (bufp) - struct re_pattern_buffer *bufp; -{ - int j, k; - fail_stack_type fail_stack; -#ifndef REGEX_MALLOC - char *destination; -#endif - /* We don't push any register information onto the failure stack. */ - unsigned num_regs = 0; - - register char *fastmap = bufp->fastmap; - unsigned char *pattern = bufp->buffer; - unsigned long size = bufp->used; - const unsigned char *p = pattern; - register unsigned char *pend = pattern + size; - - /* Assume that each path through the pattern can be null until - proven otherwise. We set this false at the bottom of switch - statement, to which we get only if a particular path doesn't - match the empty string. */ - boolean path_can_be_null = true; - - /* We aren't doing a `succeed_n' to begin with. */ - boolean succeed_n_p = false; - - assert (fastmap != NULL && p != NULL); - - INIT_FAIL_STACK (); - bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */ - bufp->fastmap_accurate = 1; /* It will be when we're done. */ - bufp->can_be_null = 0; - - while (p != pend || !FAIL_STACK_EMPTY ()) - { - if (p == pend) - { - bufp->can_be_null |= path_can_be_null; - - /* Reset for next path. */ - path_can_be_null = true; - - p = fail_stack.stack[--fail_stack.avail]; - } - - /* We should never be about to go beyond the end of the pattern. */ - assert (p < pend); - -#ifdef SWITCH_ENUM_BUG - switch ((int) ((re_opcode_t) *p++)) -#else - switch ((re_opcode_t) *p++) -#endif - { - - /* I guess the idea here is to simply not bother with a fastmap - if a backreference is used, since it's too hard to figure out - the fastmap for the corresponding group. Setting - `can_be_null' stops `re_search_2' from using the fastmap, so - that is all we do. */ - case duplicate: - bufp->can_be_null = 1; - return 0; - - - /* Following are the cases which match a character. These end - with `break'. */ - - case exactn: - fastmap[p[1]] = 1; - break; - - - case charset: - for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) - if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))) - fastmap[j] = 1; - break; - - - case charset_not: - /* Chars beyond end of map must be allowed. */ - for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++) - fastmap[j] = 1; - - for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) - if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))) - fastmap[j] = 1; - break; - - - case wordchar: - for (j = 0; j < (1 << BYTEWIDTH); j++) - if (SYNTAX (j) == Sword) - fastmap[j] = 1; - break; - - - case notwordchar: - for (j = 0; j < (1 << BYTEWIDTH); j++) - if (SYNTAX (j) != Sword) - fastmap[j] = 1; - break; - - - case anychar: - /* `.' matches anything ... */ - for (j = 0; j < (1 << BYTEWIDTH); j++) - fastmap[j] = 1; - - /* ... except perhaps newline. */ - if (!(bufp->syntax & RE_DOT_NEWLINE)) - fastmap['\n'] = 0; - - /* Return if we have already set `can_be_null'; if we have, - then the fastmap is irrelevant. Something's wrong here. */ - else if (bufp->can_be_null) - return 0; - - /* Otherwise, have to check alternative paths. */ - break; - - -#ifdef emacs - case syntaxspec: - k = *p++; - for (j = 0; j < (1 << BYTEWIDTH); j++) - if (SYNTAX (j) == (enum syntaxcode) k) - fastmap[j] = 1; - break; - - - case notsyntaxspec: - k = *p++; - for (j = 0; j < (1 << BYTEWIDTH); j++) - if (SYNTAX (j) != (enum syntaxcode) k) - fastmap[j] = 1; - break; - - - /* All cases after this match the empty string. These end with - `continue'. */ - - - case before_dot: - case at_dot: - case after_dot: - continue; -#endif /* not emacs */ - - - case no_op: - case begline: - case endline: - case begbuf: - case endbuf: - case wordbound: - case notwordbound: - case wordbeg: - case wordend: - case push_dummy_failure: - continue; - - - case jump_n: - case pop_failure_jump: - case maybe_pop_jump: - case jump: - case jump_past_alt: - case dummy_failure_jump: - EXTRACT_NUMBER_AND_INCR (j, p); - p += j; - if (j > 0) - continue; - - /* Jump backward implies we just went through the body of a - loop and matched nothing. Opcode jumped to should be - `on_failure_jump' or `succeed_n'. Just treat it like an - ordinary jump. For a * loop, it has pushed its failure - point already; if so, discard that as redundant. */ - if ((re_opcode_t) *p != on_failure_jump - && (re_opcode_t) *p != succeed_n) - continue; - - p++; - EXTRACT_NUMBER_AND_INCR (j, p); - p += j; - - /* If what's on the stack is where we are now, pop it. */ - if (!FAIL_STACK_EMPTY () - && fail_stack.stack[fail_stack.avail - 1] == p) - fail_stack.avail--; - - continue; - - - case on_failure_jump: - case on_failure_keep_string_jump: - handle_on_failure_jump: - EXTRACT_NUMBER_AND_INCR (j, p); - - /* For some patterns, e.g., `(a?)?', `p+j' here points to the - end of the pattern. We don't want to push such a point, - since when we restore it above, entering the switch will - increment `p' past the end of the pattern. We don't need - to push such a point since we obviously won't find any more - fastmap entries beyond `pend'. Such a pattern can match - the null string, though. */ - if (p + j < pend) - { - if (!PUSH_PATTERN_OP (p + j, fail_stack)) - return -2; - } - else - bufp->can_be_null = 1; - - if (succeed_n_p) - { - EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */ - succeed_n_p = false; - } - - continue; - - - case succeed_n: - /* Get to the number of times to succeed. */ - p += 2; - - /* Increment p past the n for when k != 0. */ - EXTRACT_NUMBER_AND_INCR (k, p); - if (k == 0) - { - p -= 4; - succeed_n_p = true; /* Spaghetti code alert. */ - goto handle_on_failure_jump; - } - continue; - - - case set_number_at: - p += 4; - continue; - - - case start_memory: - case stop_memory: - p += 2; - continue; - - - default: - abort (); /* We have listed all the cases. */ - } /* switch *p++ */ - - /* Getting here means we have found the possible starting - characters for one path of the pattern -- and that the empty - string does not match. We need not follow this path further. - Instead, look at the next alternative (remembered on the - stack), or quit if no more. The test at the top of the loop - does these things. */ - path_can_be_null = false; - p = pend; - } /* while p */ - - /* Set `can_be_null' for the last path (also the first path, if the - pattern is empty). */ - bufp->can_be_null |= path_can_be_null; - return 0; -} /* re_compile_fastmap */ - -/* Set REGS to hold NUM_REGS registers, storing them in STARTS and - ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use - this memory for recording register information. STARTS and ENDS - must be allocated using the malloc library routine, and must each - be at least NUM_REGS * sizeof (regoff_t) bytes long. - - If NUM_REGS == 0, then subsequent matches should allocate their own - register data. - - Unless this function is called, the first search or match using - PATTERN_BUFFER will allocate its own register data, without - freeing the old data. */ - -void -re_set_registers (bufp, regs, num_regs, starts, ends) - struct re_pattern_buffer *bufp; - struct re_registers *regs; - unsigned num_regs; - regoff_t *starts, *ends; -{ - if (num_regs) - { - bufp->regs_allocated = REGS_REALLOCATE; - regs->num_regs = num_regs; - regs->start = starts; - regs->end = ends; - } - else - { - bufp->regs_allocated = REGS_UNALLOCATED; - regs->num_regs = 0; - regs->start = regs->end = (regoff_t) 0; - } -} - -/* Searching routines. */ - -/* Like re_search_2, below, but only one string is specified, and - doesn't let you say where to stop matching. */ - -int -re_search (bufp, string, size, startpos, range, regs) - struct re_pattern_buffer *bufp; - const char *string; - int size, startpos, range; - struct re_registers *regs; -{ - return re_search_2 (bufp, NULL, 0, string, size, startpos, range, - regs, size); -} - - -/* Using the compiled pattern in BUFP->buffer, first tries to match the - virtual concatenation of STRING1 and STRING2, starting first at index - STARTPOS, then at STARTPOS + 1, and so on. - - STRING1 and STRING2 have length SIZE1 and SIZE2, respectively. - - RANGE is how far to scan while trying to match. RANGE = 0 means try - only at STARTPOS; in general, the last start tried is STARTPOS + - RANGE. - - In REGS, return the indices of the virtual concatenation of STRING1 - and STRING2 that matched the entire BUFP->buffer and its contained - subexpressions. - - Do not consider matching one past the index STOP in the virtual - concatenation of STRING1 and STRING2. - - We return either the position in the strings at which the match was - found, -1 if no match, or -2 if error (such as failure - stack overflow). */ - -int -re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop) - struct re_pattern_buffer *bufp; - const char *string1, *string2; - int size1, size2; - int startpos; - int range; - struct re_registers *regs; - int stop; -{ - int val; - register char *fastmap = bufp->fastmap; - register char *translate = bufp->translate; - int total_size = size1 + size2; - int endpos = startpos + range; - - /* Check for out-of-range STARTPOS. */ - if (startpos < 0 || startpos > total_size) - return -1; - - /* Fix up RANGE if it might eventually take us outside - the virtual concatenation of STRING1 and STRING2. */ - if (endpos < -1) - range = -1 - startpos; - else if (endpos > total_size) - range = total_size - startpos; - - /* If the search isn't to be a backwards one, don't waste time in a - search for a pattern that must be anchored. */ - if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == begbuf && range > 0) - { - if (startpos > 0) - return -1; - else - range = 1; - } - - /* Update the fastmap now if not correct already. */ - if (fastmap && !bufp->fastmap_accurate) - if (re_compile_fastmap (bufp) == -2) - return -2; - - /* Loop through the string, looking for a place to start matching. */ - for (;;) - { - /* If a fastmap is supplied, skip quickly over characters that - cannot be the start of a match. If the pattern can match the - null string, however, we don't need to skip characters; we want - the first null string. */ - if (fastmap && startpos < total_size && !bufp->can_be_null) - { - if (range > 0) /* Searching forwards. */ - { - register const char *d; - register int lim = 0; - int irange = range; - - if (startpos < size1 && startpos + range >= size1) - lim = range - (size1 - startpos); - - d = (startpos >= size1 ? string2 - size1 : string1) + startpos; - - /* Written out as an if-else to avoid testing `translate' - inside the loop. */ - if (translate) - while (range > lim - && !fastmap[(unsigned char) - translate[(unsigned char) *d++]]) - range--; - else - while (range > lim && !fastmap[(unsigned char) *d++]) - range--; - - startpos += irange - range; - } - else /* Searching backwards. */ - { - register char c = (size1 == 0 || startpos >= size1 - ? string2[startpos - size1] - : string1[startpos]); - - if (!fastmap[(unsigned char) TRANSLATE (c)]) - goto advance; - } - } - - /* If can't match the null string, and that's all we have left, fail. */ - if (range >= 0 && startpos == total_size && fastmap - && !bufp->can_be_null) - return -1; - - val = re_match_2 (bufp, string1, size1, string2, size2, - startpos, regs, stop); - if (val >= 0) - return startpos; - - if (val == -2) - return -2; - - advance: - if (!range) - break; - else if (range > 0) - { - range--; - startpos++; - } - else - { - range++; - startpos--; - } - } - return -1; -} /* re_search_2 */ - -/* Declarations and macros for re_match_2. */ - -static int bcmp_translate (); -static boolean alt_match_null_string_p (), - common_op_match_null_string_p (), - group_match_null_string_p (); - -/* Structure for per-register (a.k.a. per-group) information. - This must not be longer than one word, because we push this value - onto the failure stack. Other register information, such as the - starting and ending positions (which are addresses), and the list of - inner groups (which is a bits list) are maintained in separate - variables. - - We are making a (strictly speaking) nonportable assumption here: that - the compiler will pack our bit fields into something that fits into - the type of `word', i.e., is something that fits into one item on the - failure stack. */ -typedef union -{ - fail_stack_elt_t word; - struct - { - /* This field is one if this group can match the empty string, - zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */ -#define MATCH_NULL_UNSET_VALUE 3 - unsigned match_null_string_p : 2; - unsigned is_active : 1; - unsigned matched_something : 1; - unsigned ever_matched_something : 1; - } bits; -} register_info_type; - -#define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p) -#define IS_ACTIVE(R) ((R).bits.is_active) -#define MATCHED_SOMETHING(R) ((R).bits.matched_something) -#define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something) - - -/* Call this when have matched a real character; it sets `matched' flags - for the subexpressions which we are currently inside. Also records - that those subexprs have matched. */ -#define SET_REGS_MATCHED() \ - do \ - { \ - unsigned r; \ - for (r = lowest_active_reg; r <= highest_active_reg; r++) \ - { \ - MATCHED_SOMETHING (reg_info[r]) \ - = EVER_MATCHED_SOMETHING (reg_info[r]) \ - = 1; \ - } \ - } \ - while (0) - - -/* This converts PTR, a pointer into one of the search strings `string1' - and `string2' into an offset from the beginning of that string. */ -#define POINTER_TO_OFFSET(ptr) \ - (FIRST_STRING_P (ptr) ? (ptr) - string1 : (ptr) - string2 + size1) - -/* Registers are set to a sentinel when they haven't yet matched. */ -#define REG_UNSET_VALUE ((char *) -1) -#define REG_UNSET(e) ((e) == REG_UNSET_VALUE) - - -/* Macros for dealing with the split strings in re_match_2. */ - -#define MATCHING_IN_FIRST_STRING (dend == end_match_1) - -/* Call before fetching a character with *d. This switches over to - string2 if necessary. */ -#define PREFETCH() \ - while (d == dend) \ - { \ - /* End of string2 => fail. */ \ - if (dend == end_match_2) \ - goto fail; \ - /* End of string1 => advance to string2. */ \ - d = string2; \ - dend = end_match_2; \ - } - - -/* Test if at very beginning or at very end of the virtual concatenation - of `string1' and `string2'. If only one string, it's `string2'. */ -#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2) -#define AT_STRINGS_END(d) ((d) == end2) - - -/* Test if D points to a character which is word-constituent. We have - two special cases to check for: if past the end of string1, look at - the first character in string2; and if before the beginning of - string2, look at the last character in string1. */ -#define WORDCHAR_P(d) \ - (SYNTAX ((d) == end1 ? *string2 \ - : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \ - == Sword) - -/* Test if the character before D and the one at D differ with respect - to being word-constituent. */ -#define AT_WORD_BOUNDARY(d) \ - (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \ - || WORDCHAR_P (d - 1) != WORDCHAR_P (d)) - - -/* Free everything we malloc. */ -#ifdef REGEX_MALLOC -#define FREE_VAR(var) if (var) free (var); var = NULL -#define FREE_VARIABLES() \ - do { \ - FREE_VAR (fail_stack.stack); \ - FREE_VAR (regstart); \ - FREE_VAR (regend); \ - FREE_VAR (old_regstart); \ - FREE_VAR (old_regend); \ - FREE_VAR (best_regstart); \ - FREE_VAR (best_regend); \ - FREE_VAR (reg_info); \ - FREE_VAR (reg_dummy); \ - FREE_VAR (reg_info_dummy); \ - } while (0) -#else /* not REGEX_MALLOC */ -/* Some MIPS systems (at least) want this to free alloca'd storage. */ -#define FREE_VARIABLES() alloca (0) -#endif /* not REGEX_MALLOC */ - - -/* These values must meet several constraints. They must not be valid - register values; since we have a limit of 255 registers (because - we use only one byte in the pattern for the register number), we can - use numbers larger than 255. They must differ by 1, because of - NUM_FAILURE_ITEMS above. And the value for the lowest register must - be larger than the value for the highest register, so we do not try - to actually save any registers when none are active. */ -#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH) -#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1) - -/* Matching routines. */ - -#ifndef emacs /* Emacs never uses this. */ -/* re_match is like re_match_2 except it takes only a single string. */ - -int -re_match (bufp, string, size, pos, regs) - struct re_pattern_buffer *bufp; - const char *string; - int size, pos; - struct re_registers *regs; - { - return re_match_2 (bufp, NULL, 0, string, size, pos, regs, size); -} -#endif /* not emacs */ - - -/* re_match_2 matches the compiled pattern in BUFP against the - the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1 - and SIZE2, respectively). We start matching at POS, and stop - matching at STOP. - - If REGS is non-null and the `no_sub' field of BUFP is nonzero, we - store offsets for the substring each group matched in REGS. See the - documentation for exactly how many groups we fill. - - We return -1 if no match, -2 if an internal error (such as the - failure stack overflowing). Otherwise, we return the length of the - matched substring. */ - -int -re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) - struct re_pattern_buffer *bufp; - const char *string1, *string2; - int size1, size2; - int pos; - struct re_registers *regs; - int stop; -{ - /* General temporaries. */ - int mcnt; - unsigned char *p1; - - /* Just past the end of the corresponding string. */ - const char *end1, *end2; - - /* Pointers into string1 and string2, just past the last characters in - each to consider matching. */ - const char *end_match_1, *end_match_2; - - /* Where we are in the data, and the end of the current string. */ - const char *d, *dend; - - /* Where we are in the pattern, and the end of the pattern. */ - unsigned char *p = bufp->buffer; - register unsigned char *pend = p + bufp->used; - - /* We use this to map every character in the string. */ - char *translate = bufp->translate; - - /* Failure point stack. Each place that can handle a failure further - down the line pushes a failure point on this stack. It consists of - restart, regend, and reg_info for all registers corresponding to - the subexpressions we're currently inside, plus the number of such - registers, and, finally, two char *'s. The first char * is where - to resume scanning the pattern; the second one is where to resume - scanning the strings. If the latter is zero, the failure point is - a ``dummy''; if a failure happens and the failure point is a dummy, - it gets discarded and the next next one is tried. */ - fail_stack_type fail_stack; -#ifdef DEBUG - static unsigned failure_id = 0; - unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0; -#endif - - /* We fill all the registers internally, independent of what we - return, for use in backreferences. The number here includes - an element for register zero. */ - unsigned num_regs = bufp->re_nsub + 1; - - /* The currently active registers. */ - unsigned lowest_active_reg = NO_LOWEST_ACTIVE_REG; - unsigned highest_active_reg = NO_HIGHEST_ACTIVE_REG; - - /* Information on the contents of registers. These are pointers into - the input strings; they record just what was matched (on this - attempt) by a subexpression part of the pattern, that is, the - regnum-th regstart pointer points to where in the pattern we began - matching and the regnum-th regend points to right after where we - stopped matching the regnum-th subexpression. (The zeroth register - keeps track of what the whole pattern matches.) */ - const char **regstart, **regend; - - /* If a group that's operated upon by a repetition operator fails to - match anything, then the register for its start will need to be - restored because it will have been set to wherever in the string we - are when we last see its open-group operator. Similarly for a - register's end. */ - const char **old_regstart, **old_regend; - - /* The is_active field of reg_info helps us keep track of which (possibly - nested) subexpressions we are currently in. The matched_something - field of reg_info[reg_num] helps us tell whether or not we have - matched any of the pattern so far this time through the reg_num-th - subexpression. These two fields get reset each time through any - loop their register is in. */ - register_info_type *reg_info; - - /* The following record the register info as found in the above - variables when we find a match better than any we've seen before. - This happens as we backtrack through the failure points, which in - turn happens only if we have not yet matched the entire string. */ - unsigned best_regs_set = false; - const char **best_regstart, **best_regend; - - /* Logically, this is `best_regend[0]'. But we don't want to have to - allocate space for that if we're not allocating space for anything - else (see below). Also, we never need info about register 0 for - any of the other register vectors, and it seems rather a kludge to - treat `best_regend' differently than the rest. So we keep track of - the end of the best match so far in a separate variable. We - initialize this to NULL so that when we backtrack the first time - and need to test it, it's not garbage. */ - const char *match_end = NULL; - - /* Used when we pop values we don't care about. */ - const char **reg_dummy; - register_info_type *reg_info_dummy; - -#ifdef DEBUG - /* Counts the total number of registers pushed. */ - unsigned num_regs_pushed = 0; -#endif - - DEBUG_PRINT1 ("\n\nEntering re_match_2.\n"); - - INIT_FAIL_STACK (); - - /* Do not bother to initialize all the register variables if there are - no groups in the pattern, as it takes a fair amount of time. If - there are groups, we include space for register 0 (the whole - pattern), even though we never use it, since it simplifies the - array indexing. We should fix this. */ - if (bufp->re_nsub) - { - regstart = REGEX_TALLOC (num_regs, const char *); - regend = REGEX_TALLOC (num_regs, const char *); - old_regstart = REGEX_TALLOC (num_regs, const char *); - old_regend = REGEX_TALLOC (num_regs, const char *); - best_regstart = REGEX_TALLOC (num_regs, const char *); - best_regend = REGEX_TALLOC (num_regs, const char *); - reg_info = REGEX_TALLOC (num_regs, register_info_type); - reg_dummy = REGEX_TALLOC (num_regs, const char *); - reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type); - - if (!(regstart && regend && old_regstart && old_regend && reg_info - && best_regstart && best_regend && reg_dummy && reg_info_dummy)) - { - FREE_VARIABLES (); - return -2; - } - } -#ifdef REGEX_MALLOC - else - { - /* We must initialize all our variables to NULL, so that - `FREE_VARIABLES' doesn't try to free them. */ - regstart = regend = old_regstart = old_regend = best_regstart - = best_regend = reg_dummy = NULL; - reg_info = reg_info_dummy = (register_info_type *) NULL; - } -#endif /* REGEX_MALLOC */ - - /* The starting position is bogus. */ - if (pos < 0 || pos > size1 + size2) - { - FREE_VARIABLES (); - return -1; - } - - /* Initialize subexpression text positions to -1 to mark ones that no - start_memory/stop_memory has been seen for. Also initialize the - register information struct. */ - for (mcnt = 1; mcnt < num_regs; mcnt++) - { - regstart[mcnt] = regend[mcnt] - = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE; - - REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE; - IS_ACTIVE (reg_info[mcnt]) = 0; - MATCHED_SOMETHING (reg_info[mcnt]) = 0; - EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0; - } - - /* We move `string1' into `string2' if the latter's empty -- but not if - `string1' is null. */ - if (size2 == 0 && string1 != NULL) - { - string2 = string1; - size2 = size1; - string1 = 0; - size1 = 0; - } - end1 = string1 + size1; - end2 = string2 + size2; - - /* Compute where to stop matching, within the two strings. */ - if (stop <= size1) - { - end_match_1 = string1 + stop; - end_match_2 = string2; - } - else - { - end_match_1 = end1; - end_match_2 = string2 + stop - size1; - } - - /* `p' scans through the pattern as `d' scans through the data. - `dend' is the end of the input string that `d' points within. `d' - is advanced into the following input string whenever necessary, but - this happens before fetching; therefore, at the beginning of the - loop, `d' can be pointing at the end of a string, but it cannot - equal `string2'. */ - if (size1 > 0 && pos <= size1) - { - d = string1 + pos; - dend = end_match_1; - } - else - { - d = string2 + pos - size1; - dend = end_match_2; - } - - DEBUG_PRINT1 ("The compiled pattern is: "); - DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend); - DEBUG_PRINT1 ("The string to match is: `"); - DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2); - DEBUG_PRINT1 ("'\n"); - - /* This loops over pattern commands. It exits by returning from the - function if the match is complete, or it drops through if the match - fails at this starting point in the input data. */ - for (;;) - { - DEBUG_PRINT2 ("\n0x%x: ", p); - - if (p == pend) - { /* End of pattern means we might have succeeded. */ - DEBUG_PRINT1 ("end of pattern ... "); - - /* If we haven't matched the entire string, and we want the - longest match, try backtracking. */ - if (d != end_match_2) - { - DEBUG_PRINT1 ("backtracking.\n"); - - if (!FAIL_STACK_EMPTY ()) - { /* More failure points to try. */ - boolean same_str_p = (FIRST_STRING_P (match_end) - == MATCHING_IN_FIRST_STRING); - - /* If exceeds best match so far, save it. */ - if (!best_regs_set - || (same_str_p && d > match_end) - || (!same_str_p && !MATCHING_IN_FIRST_STRING)) - { - best_regs_set = true; - match_end = d; - - DEBUG_PRINT1 ("\nSAVING match as best so far.\n"); - - for (mcnt = 1; mcnt < num_regs; mcnt++) - { - best_regstart[mcnt] = regstart[mcnt]; - best_regend[mcnt] = regend[mcnt]; - } - } - goto fail; - } - - /* If no failure points, don't restore garbage. */ - else if (best_regs_set) - { - restore_best_regs: - /* Restore best match. It may happen that `dend == - end_match_1' while the restored d is in string2. - For example, the pattern `x.*y.*z' against the - strings `x-' and `y-z-', if the two strings are - not consecutive in memory. */ - DEBUG_PRINT1 ("Restoring best registers.\n"); - - d = match_end; - dend = ((d >= string1 && d <= end1) - ? end_match_1 : end_match_2); - - for (mcnt = 1; mcnt < num_regs; mcnt++) - { - regstart[mcnt] = best_regstart[mcnt]; - regend[mcnt] = best_regend[mcnt]; - } - } - } /* d != end_match_2 */ - - DEBUG_PRINT1 ("Accepting match.\n"); - - /* If caller wants register contents data back, do it. */ - if (regs && !bufp->no_sub) - { - /* Have the register data arrays been allocated? */ - if (bufp->regs_allocated == REGS_UNALLOCATED) - { /* No. So allocate them with malloc. We need one - extra element beyond `num_regs' for the `-1' marker - GNU code uses. */ - regs->num_regs = MAX (RE_NREGS, num_regs + 1); - regs->start = TALLOC (regs->num_regs, regoff_t); - regs->end = TALLOC (regs->num_regs, regoff_t); - if (regs->start == NULL || regs->end == NULL) - return -2; - bufp->regs_allocated = REGS_REALLOCATE; - } - else if (bufp->regs_allocated == REGS_REALLOCATE) - { /* Yes. If we need more elements than were already - allocated, reallocate them. If we need fewer, just - leave it alone. */ - if (regs->num_regs < num_regs + 1) - { - regs->num_regs = num_regs + 1; - RETALLOC (regs->start, regs->num_regs, regoff_t); - RETALLOC (regs->end, regs->num_regs, regoff_t); - if (regs->start == NULL || regs->end == NULL) - return -2; - } - } - else - assert (bufp->regs_allocated == REGS_FIXED); - - /* Convert the pointer data in `regstart' and `regend' to - indices. Register zero has to be set differently, - since we haven't kept track of any info for it. */ - if (regs->num_regs > 0) - { - regs->start[0] = pos; - regs->end[0] = (MATCHING_IN_FIRST_STRING ? d - string1 - : d - string2 + size1); - } - - /* Go through the first `min (num_regs, regs->num_regs)' - registers, since that is all we initialized. */ - for (mcnt = 1; mcnt < MIN (num_regs, regs->num_regs); mcnt++) - { - if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt])) - regs->start[mcnt] = regs->end[mcnt] = -1; - else - { - regs->start[mcnt] = POINTER_TO_OFFSET (regstart[mcnt]); - regs->end[mcnt] = POINTER_TO_OFFSET (regend[mcnt]); - } - } - - /* If the regs structure we return has more elements than - were in the pattern, set the extra elements to -1. If - we (re)allocated the registers, this is the case, - because we always allocate enough to have at least one - -1 at the end. */ - for (mcnt = num_regs; mcnt < regs->num_regs; mcnt++) - regs->start[mcnt] = regs->end[mcnt] = -1; - } /* regs && !bufp->no_sub */ - - FREE_VARIABLES (); - DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n", - nfailure_points_pushed, nfailure_points_popped, - nfailure_points_pushed - nfailure_points_popped); - DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed); - - mcnt = d - pos - (MATCHING_IN_FIRST_STRING - ? string1 - : string2 - size1); - - DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt); - - return mcnt; - } - - /* Otherwise match next pattern command. */ -#ifdef SWITCH_ENUM_BUG - switch ((int) ((re_opcode_t) *p++)) -#else - switch ((re_opcode_t) *p++) -#endif - { - /* Ignore these. Used to ignore the n of succeed_n's which - currently have n == 0. */ - case no_op: - DEBUG_PRINT1 ("EXECUTING no_op.\n"); - break; - - - /* Match the next n pattern characters exactly. The following - byte in the pattern defines n, and the n bytes after that - are the characters to match. */ - case exactn: - mcnt = *p++; - DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt); - - /* This is written out as an if-else so we don't waste time - testing `translate' inside the loop. */ - if (translate) - { - do - { - PREFETCH (); - if (translate[(unsigned char) *d++] != (char) *p++) - goto fail; - } - while (--mcnt); - } - else - { - do - { - PREFETCH (); - if (*d++ != (char) *p++) goto fail; - } - while (--mcnt); - } - SET_REGS_MATCHED (); - break; - - - /* Match any character except possibly a newline or a null. */ - case anychar: - DEBUG_PRINT1 ("EXECUTING anychar.\n"); - - PREFETCH (); - - if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n') - || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000')) - goto fail; - - SET_REGS_MATCHED (); - DEBUG_PRINT2 (" Matched `%d'.\n", *d); - d++; - break; - - - case charset: - case charset_not: - { - register unsigned char c; - boolean not = (re_opcode_t) *(p - 1) == charset_not; - - DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : ""); - - PREFETCH (); - c = TRANSLATE (*d); /* The character to match. */ - - /* Cast to `unsigned' instead of `unsigned char' in case the - bit list is a full 32 bytes long. */ - if (c < (unsigned) (*p * BYTEWIDTH) - && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) - not = !not; - - p += 1 + *p; - - if (!not) goto fail; - - SET_REGS_MATCHED (); - d++; - break; - } - - - /* The beginning of a group is represented by start_memory. - The arguments are the register number in the next byte, and the - number of groups inner to this one in the next. The text - matched within the group is recorded (in the internal - registers data structure) under the register number. */ - case start_memory: - DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]); - - /* Find out if this group can match the empty string. */ - p1 = p; /* To send to group_match_null_string_p. */ - - if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE) - REG_MATCH_NULL_STRING_P (reg_info[*p]) - = group_match_null_string_p (&p1, pend, reg_info); - - /* Save the position in the string where we were the last time - we were at this open-group operator in case the group is - operated upon by a repetition operator, e.g., with `(a*)*b' - against `ab'; then we want to ignore where we are now in - the string in case this attempt to match fails. */ - old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) - ? REG_UNSET (regstart[*p]) ? d : regstart[*p] - : regstart[*p]; - DEBUG_PRINT2 (" old_regstart: %d\n", - POINTER_TO_OFFSET (old_regstart[*p])); - - regstart[*p] = d; - DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p])); - - IS_ACTIVE (reg_info[*p]) = 1; - MATCHED_SOMETHING (reg_info[*p]) = 0; - - /* This is the new highest active register. */ - highest_active_reg = *p; - - /* If nothing was active before, this is the new lowest active - register. */ - if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) - lowest_active_reg = *p; - - /* Move past the register number and inner group count. */ - p += 2; - break; - - - /* The stop_memory opcode represents the end of a group. Its - arguments are the same as start_memory's: the register - number, and the number of inner groups. */ - case stop_memory: - DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]); - - /* We need to save the string position the last time we were at - this close-group operator in case the group is operated - upon by a repetition operator, e.g., with `((a*)*(b*)*)*' - against `aba'; then we want to ignore where we are now in - the string in case this attempt to match fails. */ - old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) - ? REG_UNSET (regend[*p]) ? d : regend[*p] - : regend[*p]; - DEBUG_PRINT2 (" old_regend: %d\n", - POINTER_TO_OFFSET (old_regend[*p])); - - regend[*p] = d; - DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p])); - - /* This register isn't active anymore. */ - IS_ACTIVE (reg_info[*p]) = 0; - - /* If this was the only register active, nothing is active - anymore. */ - if (lowest_active_reg == highest_active_reg) - { - lowest_active_reg = NO_LOWEST_ACTIVE_REG; - highest_active_reg = NO_HIGHEST_ACTIVE_REG; - } - else - { /* We must scan for the new highest active register, since - it isn't necessarily one less than now: consider - (a(b)c(d(e)f)g). When group 3 ends, after the f), the - new highest active register is 1. */ - unsigned char r = *p - 1; - while (r > 0 && !IS_ACTIVE (reg_info[r])) - r--; - - /* If we end up at register zero, that means that we saved - the registers as the result of an `on_failure_jump', not - a `start_memory', and we jumped to past the innermost - `stop_memory'. For example, in ((.)*) we save - registers 1 and 2 as a result of the *, but when we pop - back to the second ), we are at the stop_memory 1. - Thus, nothing is active. */ - if (r == 0) - { - lowest_active_reg = NO_LOWEST_ACTIVE_REG; - highest_active_reg = NO_HIGHEST_ACTIVE_REG; - } - else - highest_active_reg = r; - } - - /* If just failed to match something this time around with a - group that's operated on by a repetition operator, try to - force exit from the ``loop'', and restore the register - information for this group that we had before trying this - last match. */ - if ((!MATCHED_SOMETHING (reg_info[*p]) - || (re_opcode_t) p[-3] == start_memory) - && (p + 2) < pend) - { - boolean is_a_jump_n = false; - - p1 = p + 2; - mcnt = 0; - switch ((re_opcode_t) *p1++) - { - case jump_n: - is_a_jump_n = true; - case pop_failure_jump: - case maybe_pop_jump: - case jump: - case dummy_failure_jump: - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - if (is_a_jump_n) - p1 += 2; - break; - - default: - /* do nothing */ ; - } - p1 += mcnt; - - /* If the next operation is a jump backwards in the pattern - to an on_failure_jump right before the start_memory - corresponding to this stop_memory, exit from the loop - by forcing a failure after pushing on the stack the - on_failure_jump's jump in the pattern, and d. */ - if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump - && (re_opcode_t) p1[3] == start_memory && p1[4] == *p) - { - /* If this group ever matched anything, then restore - what its registers were before trying this last - failed match, e.g., with `(a*)*b' against `ab' for - regstart[1], and, e.g., with `((a*)*(b*)*)*' - against `aba' for regend[3]. - - Also restore the registers for inner groups for, - e.g., `((a*)(b*))*' against `aba' (register 3 would - otherwise get trashed). */ - - if (EVER_MATCHED_SOMETHING (reg_info[*p])) - { - unsigned r; - - EVER_MATCHED_SOMETHING (reg_info[*p]) = 0; - - /* Restore this and inner groups' (if any) registers. */ - for (r = *p; r < *p + *(p + 1); r++) - { - regstart[r] = old_regstart[r]; - - /* xx why this test? */ - if ((int) old_regend[r] >= (int) regstart[r]) - regend[r] = old_regend[r]; - } - } - p1++; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - PUSH_FAILURE_POINT (p1 + mcnt, d, -2); - - goto fail; - } - } - - /* Move past the register number and the inner group count. */ - p += 2; - break; - - - /* \ has been turned into a `duplicate' command which is - followed by the numeric value of as the register number. */ - case duplicate: - { - register const char *d2, *dend2; - int regno = *p++; /* Get which register to match against. */ - DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno); - - /* Can't back reference a group which we've never matched. */ - if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno])) - goto fail; - - /* Where in input to try to start matching. */ - d2 = regstart[regno]; - - /* Where to stop matching; if both the place to start and - the place to stop matching are in the same string, then - set to the place to stop, otherwise, for now have to use - the end of the first string. */ - - dend2 = ((FIRST_STRING_P (regstart[regno]) - == FIRST_STRING_P (regend[regno])) - ? regend[regno] : end_match_1); - for (;;) - { - /* If necessary, advance to next segment in register - contents. */ - while (d2 == dend2) - { - if (dend2 == end_match_2) break; - if (dend2 == regend[regno]) break; - - /* End of string1 => advance to string2. */ - d2 = string2; - dend2 = regend[regno]; - } - /* At end of register contents => success */ - if (d2 == dend2) break; - - /* If necessary, advance to next segment in data. */ - PREFETCH (); - - /* How many characters left in this segment to match. */ - mcnt = dend - d; - - /* Want how many consecutive characters we can match in - one shot, so, if necessary, adjust the count. */ - if (mcnt > dend2 - d2) - mcnt = dend2 - d2; - - /* Compare that many; failure if mismatch, else move - past them. */ - if (translate - ? bcmp_translate (d, d2, mcnt, translate) - : bcmp (d, d2, mcnt)) - goto fail; - d += mcnt, d2 += mcnt; - } - } - break; - - - /* begline matches the empty string at the beginning of the string - (unless `not_bol' is set in `bufp'), and, if - `newline_anchor' is set, after newlines. */ - case begline: - DEBUG_PRINT1 ("EXECUTING begline.\n"); - - if (AT_STRINGS_BEG (d)) - { - if (!bufp->not_bol) break; - } - else if (d[-1] == '\n' && bufp->newline_anchor) - { - break; - } - /* In all other cases, we fail. */ - goto fail; - - - /* endline is the dual of begline. */ - case endline: - DEBUG_PRINT1 ("EXECUTING endline.\n"); - - if (AT_STRINGS_END (d)) - { - if (!bufp->not_eol) break; - } - - /* We have to ``prefetch'' the next character. */ - else if ((d == end1 ? *string2 : *d) == '\n' - && bufp->newline_anchor) - { - break; - } - goto fail; - - - /* Match at the very beginning of the data. */ - case begbuf: - DEBUG_PRINT1 ("EXECUTING begbuf.\n"); - if (AT_STRINGS_BEG (d)) - break; - goto fail; - - - /* Match at the very end of the data. */ - case endbuf: - DEBUG_PRINT1 ("EXECUTING endbuf.\n"); - if (AT_STRINGS_END (d)) - break; - goto fail; - - - /* on_failure_keep_string_jump is used to optimize `.*\n'. It - pushes NULL as the value for the string on the stack. Then - `pop_failure_point' will keep the current value for the - string, instead of restoring it. To see why, consider - matching `foo\nbar' against `.*\n'. The .* matches the foo; - then the . fails against the \n. But the next thing we want - to do is match the \n against the \n; if we restored the - string value, we would be back at the foo. - - Because this is used only in specific cases, we don't need to - check all the things that `on_failure_jump' does, to make - sure the right things get saved on the stack. Hence we don't - share its code. The only reason to push anything on the - stack at all is that otherwise we would have to change - `anychar's code to do something besides goto fail in this - case; that seems worse than this. */ - case on_failure_keep_string_jump: - DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump"); - - EXTRACT_NUMBER_AND_INCR (mcnt, p); - DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt); - - PUSH_FAILURE_POINT (p + mcnt, NULL, -2); - break; - - - /* Uses of on_failure_jump: - - Each alternative starts with an on_failure_jump that points - to the beginning of the next alternative. Each alternative - except the last ends with a jump that in effect jumps past - the rest of the alternatives. (They really jump to the - ending jump of the following alternative, because tensioning - these jumps is a hassle.) - - Repeats start with an on_failure_jump that points past both - the repetition text and either the following jump or - pop_failure_jump back to this on_failure_jump. */ - case on_failure_jump: - on_failure: - DEBUG_PRINT1 ("EXECUTING on_failure_jump"); - - EXTRACT_NUMBER_AND_INCR (mcnt, p); - DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt); - - /* If this on_failure_jump comes right before a group (i.e., - the original * applied to a group), save the information - for that group and all inner ones, so that if we fail back - to this point, the group's information will be correct. - For example, in \(a*\)*\1, we need the preceding group, - and in \(\(a*\)b*\)\2, we need the inner group. */ - - /* We can't use `p' to check ahead because we push - a failure point to `p + mcnt' after we do this. */ - p1 = p; - - /* We need to skip no_op's before we look for the - start_memory in case this on_failure_jump is happening as - the result of a completed succeed_n, as in \(a\)\{1,3\}b\1 - against aba. */ - while (p1 < pend && (re_opcode_t) *p1 == no_op) - p1++; - - if (p1 < pend && (re_opcode_t) *p1 == start_memory) - { - /* We have a new highest active register now. This will - get reset at the start_memory we are about to get to, - but we will have saved all the registers relevant to - this repetition op, as described above. */ - highest_active_reg = *(p1 + 1) + *(p1 + 2); - if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) - lowest_active_reg = *(p1 + 1); - } - - DEBUG_PRINT1 (":\n"); - PUSH_FAILURE_POINT (p + mcnt, d, -2); - break; - - - /* A smart repeat ends with `maybe_pop_jump'. - We change it to either `pop_failure_jump' or `jump'. */ - case maybe_pop_jump: - EXTRACT_NUMBER_AND_INCR (mcnt, p); - DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt); - { - register unsigned char *p2 = p; - - /* Compare the beginning of the repeat with what in the - pattern follows its end. If we can establish that there - is nothing that they would both match, i.e., that we - would have to backtrack because of (as in, e.g., `a*a') - then we can change to pop_failure_jump, because we'll - never have to backtrack. - - This is not true in the case of alternatives: in - `(a|ab)*' we do need to backtrack to the `ab' alternative - (e.g., if the string was `ab'). But instead of trying to - detect that here, the alternative has put on a dummy - failure point which is what we will end up popping. */ - - /* Skip over open/close-group commands. */ - while (p2 + 2 < pend - && ((re_opcode_t) *p2 == stop_memory - || (re_opcode_t) *p2 == start_memory)) - p2 += 3; /* Skip over args, too. */ - - /* If we're at the end of the pattern, we can change. */ - if (p2 == pend) - { - /* Consider what happens when matching ":\(.*\)" - against ":/". I don't really understand this code - yet. */ - p[-3] = (unsigned char) pop_failure_jump; - DEBUG_PRINT1 - (" End of pattern: change to `pop_failure_jump'.\n"); - } - - else if ((re_opcode_t) *p2 == exactn - || (bufp->newline_anchor && (re_opcode_t) *p2 == endline)) - { - register unsigned char c - = *p2 == (unsigned char) endline ? '\n' : p2[2]; - p1 = p + mcnt; - - /* p1[0] ... p1[2] are the `on_failure_jump' corresponding - to the `maybe_finalize_jump' of this case. Examine what - follows. */ - if ((re_opcode_t) p1[3] == exactn && p1[5] != c) - { - p[-3] = (unsigned char) pop_failure_jump; - DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n", - c, p1[5]); - } - - else if ((re_opcode_t) p1[3] == charset - || (re_opcode_t) p1[3] == charset_not) - { - int not = (re_opcode_t) p1[3] == charset_not; - - if (c < (unsigned char) (p1[4] * BYTEWIDTH) - && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) - not = !not; - - /* `not' is equal to 1 if c would match, which means - that we can't change to pop_failure_jump. */ - if (!not) - { - p[-3] = (unsigned char) pop_failure_jump; - DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); - } - } - } - } - p -= 2; /* Point at relative address again. */ - if ((re_opcode_t) p[-1] != pop_failure_jump) - { - p[-1] = (unsigned char) jump; - DEBUG_PRINT1 (" Match => jump.\n"); - goto unconditional_jump; - } - /* Note fall through. */ - - - /* The end of a simple repeat has a pop_failure_jump back to - its matching on_failure_jump, where the latter will push a - failure point. The pop_failure_jump takes off failure - points put on by this pop_failure_jump's matching - on_failure_jump; we got through the pattern to here from the - matching on_failure_jump, so didn't fail. */ - case pop_failure_jump: - { - /* We need to pass separate storage for the lowest and - highest registers, even though we don't care about the - actual values. Otherwise, we will restore only one - register from the stack, since lowest will == highest in - `pop_failure_point'. */ - unsigned dummy_low_reg, dummy_high_reg; - unsigned char *pdummy; - const char *sdummy; - - DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n"); - POP_FAILURE_POINT (sdummy, pdummy, - dummy_low_reg, dummy_high_reg, - reg_dummy, reg_dummy, reg_info_dummy); - } - /* Note fall through. */ - - - /* Unconditionally jump (without popping any failure points). */ - case jump: - unconditional_jump: - EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */ - DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt); - p += mcnt; /* Do the jump. */ - DEBUG_PRINT2 ("(to 0x%x).\n", p); - break; - - - /* We need this opcode so we can detect where alternatives end - in `group_match_null_string_p' et al. */ - case jump_past_alt: - DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n"); - goto unconditional_jump; - - - /* Normally, the on_failure_jump pushes a failure point, which - then gets popped at pop_failure_jump. We will end up at - pop_failure_jump, also, and with a pattern of, say, `a+', we - are skipping over the on_failure_jump, so we have to push - something meaningless for pop_failure_jump to pop. */ - case dummy_failure_jump: - DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n"); - /* It doesn't matter what we push for the string here. What - the code at `fail' tests is the value for the pattern. */ - PUSH_FAILURE_POINT (0, 0, -2); - goto unconditional_jump; - - - /* At the end of an alternative, we need to push a dummy failure - point in case we are followed by a `pop_failure_jump', because - we don't want the failure point for the alternative to be - popped. For example, matching `(a|ab)*' against `aab' - requires that we match the `ab' alternative. */ - case push_dummy_failure: - DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n"); - /* See comments just above at `dummy_failure_jump' about the - two zeroes. */ - PUSH_FAILURE_POINT (0, 0, -2); - break; - - /* Have to succeed matching what follows at least n times. - After that, handle like `on_failure_jump'. */ - case succeed_n: - EXTRACT_NUMBER (mcnt, p + 2); - DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt); - - assert (mcnt >= 0); - /* Originally, this is how many times we HAVE to succeed. */ - if (mcnt > 0) - { - mcnt--; - p += 2; - STORE_NUMBER_AND_INCR (p, mcnt); - DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p, mcnt); - } - else if (mcnt == 0) - { - DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n", p+2); - p[2] = (unsigned char) no_op; - p[3] = (unsigned char) no_op; - goto on_failure; - } - break; - - case jump_n: - EXTRACT_NUMBER (mcnt, p + 2); - DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt); - - /* Originally, this is how many times we CAN jump. */ - if (mcnt) - { - mcnt--; - STORE_NUMBER (p + 2, mcnt); - goto unconditional_jump; - } - /* If don't have to jump any more, skip over the rest of command. */ - else - p += 4; - break; - - case set_number_at: - { - DEBUG_PRINT1 ("EXECUTING set_number_at.\n"); - - EXTRACT_NUMBER_AND_INCR (mcnt, p); - p1 = p + mcnt; - EXTRACT_NUMBER_AND_INCR (mcnt, p); - DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt); - STORE_NUMBER (p1, mcnt); - break; - } - - case wordbound: - DEBUG_PRINT1 ("EXECUTING wordbound.\n"); - if (AT_WORD_BOUNDARY (d)) - break; - goto fail; - - case notwordbound: - DEBUG_PRINT1 ("EXECUTING notwordbound.\n"); - if (AT_WORD_BOUNDARY (d)) - goto fail; - break; - - case wordbeg: - DEBUG_PRINT1 ("EXECUTING wordbeg.\n"); - if (WORDCHAR_P (d) && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1))) - break; - goto fail; - - case wordend: - DEBUG_PRINT1 ("EXECUTING wordend.\n"); - if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1) - && (!WORDCHAR_P (d) || AT_STRINGS_END (d))) - break; - goto fail; - -#ifdef emacs -#ifdef emacs19 - case before_dot: - DEBUG_PRINT1 ("EXECUTING before_dot.\n"); - if (PTR_CHAR_POS ((unsigned char *) d) >= point) - goto fail; - break; - - case at_dot: - DEBUG_PRINT1 ("EXECUTING at_dot.\n"); - if (PTR_CHAR_POS ((unsigned char *) d) != point) - goto fail; - break; - - case after_dot: - DEBUG_PRINT1 ("EXECUTING after_dot.\n"); - if (PTR_CHAR_POS ((unsigned char *) d) <= point) - goto fail; - break; -#else /* not emacs19 */ - case at_dot: - DEBUG_PRINT1 ("EXECUTING at_dot.\n"); - if (PTR_CHAR_POS ((unsigned char *) d) + 1 != point) - goto fail; - break; -#endif /* not emacs19 */ - - case syntaxspec: - DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt); - mcnt = *p++; - goto matchsyntax; - - case wordchar: - DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n"); - mcnt = (int) Sword; - matchsyntax: - PREFETCH (); - if (SYNTAX (*d++) != (enum syntaxcode) mcnt) - goto fail; - SET_REGS_MATCHED (); - break; - - case notsyntaxspec: - DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt); - mcnt = *p++; - goto matchnotsyntax; - - case notwordchar: - DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n"); - mcnt = (int) Sword; - matchnotsyntax: - PREFETCH (); - if (SYNTAX (*d++) == (enum syntaxcode) mcnt) - goto fail; - SET_REGS_MATCHED (); - break; - -#else /* not emacs */ - case wordchar: - DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n"); - PREFETCH (); - if (!WORDCHAR_P (d)) - goto fail; - SET_REGS_MATCHED (); - d++; - break; - - case notwordchar: - DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n"); - PREFETCH (); - if (WORDCHAR_P (d)) - goto fail; - SET_REGS_MATCHED (); - d++; - break; -#endif /* not emacs */ - - default: - abort (); - } - continue; /* Successfully executed one pattern command; keep going. */ - - - /* We goto here if a matching operation fails. */ - fail: - if (!FAIL_STACK_EMPTY ()) - { /* A restart point is known. Restore to that state. */ - DEBUG_PRINT1 ("\nFAIL:\n"); - POP_FAILURE_POINT (d, p, - lowest_active_reg, highest_active_reg, - regstart, regend, reg_info); - - /* If this failure point is a dummy, try the next one. */ - if (!p) - goto fail; - - /* If we failed to the end of the pattern, don't examine *p. */ - assert (p <= pend); - if (p < pend) - { - boolean is_a_jump_n = false; - - /* If failed to a backwards jump that's part of a repetition - loop, need to pop this failure point and use the next one. */ - switch ((re_opcode_t) *p) - { - case jump_n: - is_a_jump_n = true; - case maybe_pop_jump: - case pop_failure_jump: - case jump: - p1 = p + 1; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - p1 += mcnt; - - if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n) - || (!is_a_jump_n - && (re_opcode_t) *p1 == on_failure_jump)) - goto fail; - break; - default: - /* do nothing */ ; - } - } - - if (d >= string1 && d <= end1) - dend = end_match_1; - } - else - break; /* Matching at this starting point really fails. */ - } /* for (;;) */ - - if (best_regs_set) - goto restore_best_regs; - - FREE_VARIABLES (); - - return -1; /* Failure to match. */ -} /* re_match_2 */ - -/* Subroutine definitions for re_match_2. */ - - -/* We are passed P pointing to a register number after a start_memory. - - Return true if the pattern up to the corresponding stop_memory can - match the empty string, and false otherwise. - - If we find the matching stop_memory, sets P to point to one past its number. - Otherwise, sets P to an undefined byte less than or equal to END. - - We don't handle duplicates properly (yet). */ - -static boolean -group_match_null_string_p (p, end, reg_info) - unsigned char **p, *end; - register_info_type *reg_info; -{ - int mcnt; - /* Point to after the args to the start_memory. */ - unsigned char *p1 = *p + 2; - - while (p1 < end) - { - /* Skip over opcodes that can match nothing, and return true or - false, as appropriate, when we get to one that can't, or to the - matching stop_memory. */ - - switch ((re_opcode_t) *p1) - { - /* Could be either a loop or a series of alternatives. */ - case on_failure_jump: - p1++; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - - /* If the next operation is not a jump backwards in the - pattern. */ - - if (mcnt >= 0) - { - /* Go through the on_failure_jumps of the alternatives, - seeing if any of the alternatives cannot match nothing. - The last alternative starts with only a jump, - whereas the rest start with on_failure_jump and end - with a jump, e.g., here is the pattern for `a|b|c': - - /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6 - /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3 - /exactn/1/c - - So, we have to first go through the first (n-1) - alternatives and then deal with the last one separately. */ - - - /* Deal with the first (n-1) alternatives, which start - with an on_failure_jump (see above) that jumps to right - past a jump_past_alt. */ - - while ((re_opcode_t) p1[mcnt-3] == jump_past_alt) - { - /* `mcnt' holds how many bytes long the alternative - is, including the ending `jump_past_alt' and - its number. */ - - if (!alt_match_null_string_p (p1, p1 + mcnt - 3, - reg_info)) - return false; - - /* Move to right after this alternative, including the - jump_past_alt. */ - p1 += mcnt; - - /* Break if it's the beginning of an n-th alternative - that doesn't begin with an on_failure_jump. */ - if ((re_opcode_t) *p1 != on_failure_jump) - break; - - /* Still have to check that it's not an n-th - alternative that starts with an on_failure_jump. */ - p1++; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - if ((re_opcode_t) p1[mcnt-3] != jump_past_alt) - { - /* Get to the beginning of the n-th alternative. */ - p1 -= 3; - break; - } - } - - /* Deal with the last alternative: go back and get number - of the `jump_past_alt' just before it. `mcnt' contains - the length of the alternative. */ - EXTRACT_NUMBER (mcnt, p1 - 2); - - if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info)) - return false; - - p1 += mcnt; /* Get past the n-th alternative. */ - } /* if mcnt > 0 */ - break; - - - case stop_memory: - assert (p1[1] == **p); - *p = p1 + 2; - return true; - - - default: - if (!common_op_match_null_string_p (&p1, end, reg_info)) - return false; - } - } /* while p1 < end */ - - return false; -} /* group_match_null_string_p */ - - -/* Similar to group_match_null_string_p, but doesn't deal with alternatives: - It expects P to be the first byte of a single alternative and END one - byte past the last. The alternative can contain groups. */ - -static boolean -alt_match_null_string_p (p, end, reg_info) - unsigned char *p, *end; - register_info_type *reg_info; -{ - int mcnt; - unsigned char *p1 = p; - - while (p1 < end) - { - /* Skip over opcodes that can match nothing, and break when we get - to one that can't. */ - - switch ((re_opcode_t) *p1) - { - /* It's a loop. */ - case on_failure_jump: - p1++; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - p1 += mcnt; - break; - - default: - if (!common_op_match_null_string_p (&p1, end, reg_info)) - return false; - } - } /* while p1 < end */ - - return true; -} /* alt_match_null_string_p */ - - -/* Deals with the ops common to group_match_null_string_p and - alt_match_null_string_p. - - Sets P to one after the op and its arguments, if any. */ - -static boolean -common_op_match_null_string_p (p, end, reg_info) - unsigned char **p, *end; - register_info_type *reg_info; -{ - int mcnt; - boolean ret; - int reg_no; - unsigned char *p1 = *p; - - switch ((re_opcode_t) *p1++) - { - case no_op: - case begline: - case endline: - case begbuf: - case endbuf: - case wordbeg: - case wordend: - case wordbound: - case notwordbound: -#ifdef emacs - case before_dot: - case at_dot: - case after_dot: -#endif - break; - - case start_memory: - reg_no = *p1; - assert (reg_no > 0 && reg_no <= MAX_REGNUM); - ret = group_match_null_string_p (&p1, end, reg_info); - - /* Have to set this here in case we're checking a group which - contains a group and a back reference to it. */ - - if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE) - REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret; - - if (!ret) - return false; - break; - - /* If this is an optimized succeed_n for zero times, make the jump. */ - case jump: - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - if (mcnt >= 0) - p1 += mcnt; - else - return false; - break; - - case succeed_n: - /* Get to the number of times to succeed. */ - p1 += 2; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - - if (mcnt == 0) - { - p1 -= 4; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - p1 += mcnt; - } - else - return false; - break; - - case duplicate: - if (!REG_MATCH_NULL_STRING_P (reg_info[*p1])) - return false; - break; - - case set_number_at: - p1 += 4; - - default: - /* All other opcodes mean we cannot match the empty string. */ - return false; - } - - *p = p1; - return true; -} /* common_op_match_null_string_p */ - - -/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN - bytes; nonzero otherwise. */ - -static int -bcmp_translate (s1, s2, len, translate) - unsigned char *s1, *s2; - register int len; - char *translate; -{ - register unsigned char *p1 = s1, *p2 = s2; - while (len) - { - if (translate[*p1++] != translate[*p2++]) return 1; - len--; - } - return 0; -} - -/* Entry points for GNU code. */ - -/* re_compile_pattern is the GNU regular expression compiler: it - compiles PATTERN (of length SIZE) and puts the result in BUFP. - Returns 0 if the pattern was valid, otherwise an error string. - - Assumes the `allocated' (and perhaps `buffer') and `translate' fields - are set in BUFP on entry. - - We call regex_compile to do the actual compilation. */ - -const char * -re_compile_pattern (pattern, length, bufp) - const char *pattern; - int length; - struct re_pattern_buffer *bufp; -{ - reg_errcode_t ret; - - /* GNU code is written to assume at least RE_NREGS registers will be set - (and at least one extra will be -1). */ - bufp->regs_allocated = REGS_UNALLOCATED; - - /* And GNU code determines whether or not to get register information - by passing null for the REGS argument to re_match, etc., not by - setting no_sub. */ - bufp->no_sub = 0; - - /* Match anchors at newline. */ - bufp->newline_anchor = 1; - - ret = regex_compile (pattern, length, re_syntax_options, bufp); - - return re_error_msg[(int) ret]; -} - -/* Entry points compatible with 4.2 BSD regex library. We don't define - them if this is an Emacs or POSIX compilation. */ - -#if !defined (emacs) && !defined (_POSIX_SOURCE) - -/* BSD has one and only one pattern buffer. */ -static struct re_pattern_buffer re_comp_buf; - -char * -re_comp (s) - const char *s; -{ - reg_errcode_t ret; - - if (!s) - { - if (!re_comp_buf.buffer) - return "No previous regular expression"; - return 0; - } - - if (!re_comp_buf.buffer) - { - re_comp_buf.buffer = (unsigned char *) malloc (200); - if (re_comp_buf.buffer == NULL) - return "Memory exhausted"; - re_comp_buf.allocated = 200; - - re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH); - if (re_comp_buf.fastmap == NULL) - return "Memory exhausted"; - } - - /* Since `re_exec' always passes NULL for the `regs' argument, we - don't need to initialize the pattern buffer fields which affect it. */ - - /* Match anchors at newlines. */ - re_comp_buf.newline_anchor = 1; - - ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf); - - /* Yes, we're discarding `const' here. */ - return (char *) re_error_msg[(int) ret]; -} - - -int -re_exec (s) - const char *s; -{ - const int len = strlen (s); - return - 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0); -} -#endif /* not emacs and not _POSIX_SOURCE */ - -/* POSIX.2 functions. Don't define these for Emacs. */ - -#ifndef emacs - -/* regcomp takes a regular expression as a string and compiles it. - - PREG is a regex_t *. We do not expect any fields to be initialized, - since POSIX says we shouldn't. Thus, we set - - `buffer' to the compiled pattern; - `used' to the length of the compiled pattern; - `syntax' to RE_SYNTAX_POSIX_EXTENDED if the - REG_EXTENDED bit in CFLAGS is set; otherwise, to - RE_SYNTAX_POSIX_BASIC; - `newline_anchor' to REG_NEWLINE being set in CFLAGS; - `fastmap' and `fastmap_accurate' to zero; - `re_nsub' to the number of subexpressions in PATTERN. - - PATTERN is the address of the pattern string. - - CFLAGS is a series of bits which affect compilation. - - If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we - use POSIX basic syntax. - - If REG_NEWLINE is set, then . and [^...] don't match newline. - Also, regexec will try a match beginning after every newline. - - If REG_ICASE is set, then we considers upper- and lowercase - versions of letters to be equivalent when matching. - - If REG_NOSUB is set, then when PREG is passed to regexec, that - routine will report only success or failure, and nothing about the - registers. - - It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for - the return codes and their meanings.) */ - -int -regcomp (preg, pattern, cflags) - regex_t *preg; - const char *pattern; - int cflags; -{ - reg_errcode_t ret; - unsigned syntax - = (cflags & REG_EXTENDED) ? - RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC; - - /* regex_compile will allocate the space for the compiled pattern. */ - preg->buffer = 0; - preg->allocated = 0; - - /* Don't bother to use a fastmap when searching. This simplifies the - REG_NEWLINE case: if we used a fastmap, we'd have to put all the - characters after newlines into the fastmap. This way, we just try - every character. */ - preg->fastmap = 0; - - if (cflags & REG_ICASE) - { - unsigned i; - - preg->translate = (char *) malloc (CHAR_SET_SIZE); - if (preg->translate == NULL) - return (int) REG_ESPACE; - - /* Map uppercase characters to corresponding lowercase ones. */ - for (i = 0; i < CHAR_SET_SIZE; i++) - preg->translate[i] = ISUPPER (i) ? tolower (i) : i; - } - else - preg->translate = NULL; - - /* If REG_NEWLINE is set, newlines are treated differently. */ - if (cflags & REG_NEWLINE) - { /* REG_NEWLINE implies neither . nor [^...] match newline. */ - syntax &= ~RE_DOT_NEWLINE; - syntax |= RE_HAT_LISTS_NOT_NEWLINE; - /* It also changes the matching behavior. */ - preg->newline_anchor = 1; - } - else - preg->newline_anchor = 0; - - preg->no_sub = !!(cflags & REG_NOSUB); - - /* POSIX says a null character in the pattern terminates it, so we - can use strlen here in compiling the pattern. */ - ret = regex_compile (pattern, strlen (pattern), syntax, preg); - - /* POSIX doesn't distinguish between an unmatched open-group and an - unmatched close-group: both are REG_EPAREN. */ - if (ret == REG_ERPAREN) ret = REG_EPAREN; - - return (int) ret; -} - - -/* regexec searches for a given pattern, specified by PREG, in the - string STRING. - - If NMATCH is zero or REG_NOSUB was set in the cflags argument to - `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at - least NMATCH elements, and we set them to the offsets of the - corresponding matched substrings. - - EFLAGS specifies `execution flags' which affect matching: if - REG_NOTBOL is set, then ^ does not match at the beginning of the - string; if REG_NOTEOL is set, then $ does not match at the end. - - We return 0 if we find a match and REG_NOMATCH if not. */ - -int -regexec (preg, string, nmatch, pmatch, eflags) - const regex_t *preg; - const char *string; - size_t nmatch; - regmatch_t pmatch[]; - int eflags; -{ - int ret; - struct re_registers regs; - regex_t private_preg; - int len = strlen (string); - boolean want_reg_info = !preg->no_sub && nmatch > 0; - - private_preg = *preg; - - private_preg.not_bol = !!(eflags & REG_NOTBOL); - private_preg.not_eol = !!(eflags & REG_NOTEOL); - - /* The user has told us exactly how many registers to return - information about, via `nmatch'. We have to pass that on to the - matching routines. */ - private_preg.regs_allocated = REGS_FIXED; - - if (want_reg_info) - { - regs.num_regs = nmatch; - regs.start = TALLOC (nmatch, regoff_t); - regs.end = TALLOC (nmatch, regoff_t); - if (regs.start == NULL || regs.end == NULL) - return (int) REG_NOMATCH; - } - - /* Perform the searching operation. */ - ret = re_search (&private_preg, string, len, - /* start: */ 0, /* range: */ len, - want_reg_info ? ®s : (struct re_registers *) 0); - - /* Copy the register information to the POSIX structure. */ - if (want_reg_info) - { - if (ret >= 0) - { - unsigned r; - - for (r = 0; r < nmatch; r++) - { - pmatch[r].rm_so = regs.start[r]; - pmatch[r].rm_eo = regs.end[r]; - } - } - - /* If we needed the temporary register info, free the space now. */ - free (regs.start); - free (regs.end); - } - - /* We want zero return to mean success, unlike `re_search'. */ - return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH; -} - - -/* Returns a message corresponding to an error code, ERRCODE, returned - from either regcomp or regexec. We don't use PREG here. */ - -size_t -regerror (errcode_vc, preg, errbuf, errbuf_size) - int errcode_vc; - const regex_t *preg; - char *errbuf; - size_t errbuf_size; -{ - const char *msg; - size_t msg_size; - - if (errcode_vc < 0 - || errcode_vc >= (sizeof (re_error_msg) / sizeof (re_error_msg[0]))) - /* Only error codes returned by the rest of the code should be passed - to this routine. If we are given anything else, or if other regex - code generates an invalid error code, then the program has a bug. - Dump core so we can fix it. */ - abort (); - - msg = re_error_msg[errcode_vc]; - - /* POSIX doesn't require that we do anything in this case, but why - not be nice. */ - if (! msg) - msg = "Success"; - - msg_size = strlen (msg) + 1; /* Includes the null. */ - - if (errbuf_size != 0) - { - if (msg_size > errbuf_size) - { - strncpy (errbuf, msg, errbuf_size - 1); - errbuf[errbuf_size - 1] = 0; - } - else - strcpy (errbuf, msg); - } - - return msg_size; -} - - -/* Free dynamically allocated space used by PREG. */ - -void -regfree (preg) - regex_t *preg; -{ - if (preg->buffer != NULL) - free (preg->buffer); - preg->buffer = NULL; - - preg->allocated = 0; - preg->used = 0; - - if (preg->fastmap != NULL) - free (preg->fastmap); - preg->fastmap = NULL; - preg->fastmap_accurate = 0; - - if (preg->translate != NULL) - free (preg->translate); - preg->translate = NULL; -} - -#endif /* not emacs */ - -/* -Local variables: -make-backup-files: t -version-control: t -trim-versions-without-asking: nil -End: -*/ diff --git a/windows/regex.h b/windows/regex.h deleted file mode 100644 index adcf40c5..00000000 --- a/windows/regex.h +++ /dev/null @@ -1,506 +0,0 @@ -/* Definitions for data structures and routines for the regular - expression library, version 0.12. - - Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - - 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, 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 __REGEXP_LIBRARY_H__ -#define __REGEXP_LIBRARY_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* POSIX says that must be included (by the caller) before - . */ - -#ifdef VMS - /* VMS doesn't have `size_t' in , even though POSIX says it - should be there. */ -#include -#endif - - - /* The following bits are used to determine the regexp syntax we - recognize. The set/not-set meanings are chosen so that Emacs syntax - remains the value 0. The bits are given in alphabetical order, and - the definitions shifted by one from the previous bit; thus, when we - add or remove a bit, only one other definition need change. */ - typedef unsigned reg_syntax_t; - - /* If this bit is not set, then \ inside a bracket expression is literal. - If set, then such a \ quotes the following character. */ -#define RE_BACKSLASH_ESCAPE_IN_LISTS (1) - - /* If this bit is not set, then + and ? are operators, and \+ and \? are - literals. - If set, then \+ and \? are operators and + and ? are literals. */ -#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1) - - /* If this bit is set, then character classes are supported. They are: - [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:], - [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:]. - If not set, then character classes are not supported. */ -#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1) - - /* If this bit is set, then ^ and $ are always anchors (outside bracket - expressions, of course). - If this bit is not set, then it depends: - ^ is an anchor if it is at the beginning of a regular - expression or after an open-group or an alternation operator; - $ is an anchor if it is at the end of a regular expression, or - before a close-group or an alternation operator. - - This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because - POSIX draft 11.2 says that * etc. in leading positions is undefined. - We already implemented a previous draft which made those constructs - invalid, though, so we haven't changed the code back. */ -#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1) - - /* If this bit is set, then special characters are always special - regardless of where they are in the pattern. - If this bit is not set, then special characters are special only in - some contexts; otherwise they are ordinary. Specifically, - * + ? and intervals are only special when not after the beginning, - open-group, or alternation operator. */ -#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1) - - /* If this bit is set, then *, +, ?, and { cannot be first in an re or - immediately after an alternation or begin-group operator. */ -#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1) - - /* If this bit is set, then . matches newline. - If not set, then it doesn't. */ -#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1) - - /* If this bit is set, then . doesn't match NUL. - If not set, then it does. */ -#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1) - - /* If this bit is set, nonmatching lists [^...] do not match newline. - If not set, they do. */ -#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1) - - /* If this bit is set, either \{...\} or {...} defines an - interval, depending on RE_NO_BK_BRACES. - If not set, \{, \}, {, and } are literals. */ -#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1) - - /* If this bit is set, +, ? and | aren't recognized as operators. - If not set, they are. */ -#define RE_LIMITED_OPS (RE_INTERVALS << 1) - - /* If this bit is set, newline is an alternation operator. - If not set, newline is literal. */ -#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1) - - /* If this bit is set, then `{...}' defines an interval, and \{ and \} - are literals. - If not set, then `\{...\}' defines an interval. */ -#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1) - - /* If this bit is set, (...) defines a group, and \( and \) are literals. - If not set, \(...\) defines a group, and ( and ) are literals. */ -#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1) - - /* If this bit is set, then \ matches . - If not set, then \ is a back-reference. */ -#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1) - - /* If this bit is set, then | is an alternation operator, and \| is literal. - If not set, then \| is an alternation operator, and | is literal. */ -#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1) - - /* If this bit is set, then an ending range point collating higher - than the starting range point, as in [z-a], is invalid. - If not set, then when ending range point collates higher than the - starting range point, the range is ignored. */ -#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1) - - /* If this bit is set, then an unmatched ) is ordinary. - If not set, then an unmatched ) is invalid. */ -#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1) - - /* This global variable defines the particular regexp syntax to use (for - some interfaces). When a regexp is compiled, the syntax used is - stored in the pattern buffer, so changing this does not affect - already-compiled regexps. */ - extern reg_syntax_t re_syntax_options; - - /* Define combinations of the above bits for the standard possibilities. - (The [[[ comments delimit what gets put into the Texinfo file, so - don't delete them!) */ - /* [[[begin syntaxes]]] */ -#define RE_SYNTAX_EMACS 0 - -#define RE_SYNTAX_AWK \ - (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ - | RE_NO_BK_PARENS | RE_NO_BK_REFS \ - | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ - | RE_UNMATCHED_RIGHT_PAREN_ORD) - -#define RE_SYNTAX_POSIX_AWK \ - (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS) - -#define RE_SYNTAX_GREP \ - (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ - | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ - | RE_NEWLINE_ALT) - -#define RE_SYNTAX_EGREP \ - (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ - | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ - | RE_NO_BK_VBAR) - -#define RE_SYNTAX_POSIX_EGREP \ - (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES) - - /* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */ -#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC - -#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC - - /* Syntax bits common to both basic and extended POSIX regex syntax. */ -#define _RE_SYNTAX_POSIX_COMMON \ - (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ - | RE_INTERVALS | RE_NO_EMPTY_RANGES) - -#define RE_SYNTAX_POSIX_BASIC \ - (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM) - - /* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes - RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this - isn't minimal, since other operators, such as \`, aren't disabled. */ -#define RE_SYNTAX_POSIX_MINIMAL_BASIC \ - (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS) - -#define RE_SYNTAX_POSIX_EXTENDED \ - (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \ - | RE_NO_BK_PARENS | RE_NO_BK_VBAR \ - | RE_UNMATCHED_RIGHT_PAREN_ORD) - - /* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS - replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */ -#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \ - (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \ - | RE_NO_BK_PARENS | RE_NO_BK_REFS \ - | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD) - /* [[[end syntaxes]]] */ - - /* Maximum number of duplicates an interval can allow. Some systems - (erroneously) define this in other header files, but we want our - value, so remove any previous define. */ -#ifdef RE_DUP_MAX -#undef RE_DUP_MAX -#endif -#define RE_DUP_MAX ((1 << 15) - 1) - - - /* POSIX `cflags' bits (i.e., information for `regcomp'). */ - - /* If this bit is set, then use extended regular expression syntax. - If not set, then use basic regular expression syntax. */ -#define REG_EXTENDED 1 - - /* If this bit is set, then ignore case when matching. - If not set, then case is significant. */ -#define REG_ICASE (REG_EXTENDED << 1) - - /* If this bit is set, then anchors do not match at newline - characters in the string. - If not set, then anchors do match at newlines. */ -#define REG_NEWLINE (REG_ICASE << 1) - - /* If this bit is set, then report only success or fail in regexec. - If not set, then returns differ between not matching and errors. */ -#define REG_NOSUB (REG_NEWLINE << 1) - - - /* POSIX `eflags' bits (i.e., information for regexec). */ - - /* If this bit is set, then the beginning-of-line operator doesn't match - the beginning of the string (presumably because it's not the - beginning of a line). - If not set, then the beginning-of-line operator does match the - beginning of the string. */ -#define REG_NOTBOL 1 - - /* Like REG_NOTBOL, except for the end-of-line. */ -#define REG_NOTEOL (1 << 1) - - - /* If any error codes are removed, changed, or added, update the - `re_error_msg' table in regex.c. */ - typedef enum { - REG_NOERROR = 0, /* Success. */ - REG_NOMATCH, /* Didn't find a match (for regexec). */ - - /* POSIX regcomp return error codes. (In the order listed in the - standard.) */ - REG_BADPAT, /* Invalid pattern. */ - REG_ECOLLATE, /* Not implemented. */ - REG_ECTYPE, /* Invalid character class name. */ - REG_EESCAPE, /* Trailing backslash. */ - REG_ESUBREG, /* Invalid back reference. */ - REG_EBRACK, /* Unmatched left bracket. */ - REG_EPAREN, /* Parenthesis imbalance. */ - REG_EBRACE, /* Unmatched \{. */ - REG_BADBR, /* Invalid contents of \{\}. */ - REG_ERANGE, /* Invalid range end. */ - REG_ESPACE, /* Ran out of memory. */ - REG_BADRPT, /* No preceding re for repetition op. */ - - /* Error codes we've added. */ - REG_EEND, /* Premature end. */ - REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */ - REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ - } - reg_errcode_t; - - /* This data structure represents a compiled pattern. Before calling - the pattern compiler, the fields `buffer', `allocated', `fastmap', - `translate', and `no_sub' can be set. After the pattern has been - compiled, the `re_nsub' field is available. All other fields are - private to the regex routines. */ - - struct re_pattern_buffer { - /* [[[begin pattern_buffer]]] */ - /* Space that holds the compiled pattern. It is declared as - `unsigned char *' because its elements are - sometimes used as array indexes. */ - unsigned char *buffer; - - /* Number of bytes to which `buffer' points. */ - unsigned long allocated; - - /* Number of bytes actually used in `buffer'. */ - unsigned long used; - - /* Syntax setting with which the pattern was compiled. */ - reg_syntax_t syntax; - - /* Pointer to a fastmap, if any, otherwise zero. re_search uses - the fastmap, if there is one, to skip over impossible - starting points for matches. */ - char *fastmap; - - /* Either a translate table to apply to all characters before - comparing them, or zero for no translation. The translation - is applied to a pattern when it is compiled and to a string - when it is matched. */ - char *translate; - - /* Number of subexpressions found by the compiler. */ - size_t re_nsub; - - /* Zero if this pattern cannot match the empty string, one else. - Well, in truth it's used only in `re_search_2', to see - whether or not we should use the fastmap, so we don't set - this absolutely perfectly; see `re_compile_fastmap' (the - `duplicate' case). */ -unsigned can_be_null : - 1; - - /* If REGS_UNALLOCATED, allocate space in the `regs' structure - for `max (RE_NREGS, re_nsub + 1)' groups. - If REGS_REALLOCATE, reallocate space if necessary. - If REGS_FIXED, use what's there. */ -#define REGS_UNALLOCATED 0 -#define REGS_REALLOCATE 1 -#define REGS_FIXED 2 - -unsigned regs_allocated : - 2; - - /* Set to zero when `regex_compile' compiles a pattern; set to one - by `re_compile_fastmap' if it updates the fastmap. */ -unsigned fastmap_accurate : - 1; - - /* If set, `re_match_2' does not return information about - subexpressions. */ -unsigned no_sub : - 1; - - /* If set, a beginning-of-line anchor doesn't match at the - beginning of the string. */ -unsigned not_bol : - 1; - - /* Similarly for an end-of-line anchor. */ -unsigned not_eol : - 1; - - /* If true, an anchor at a newline matches. */ -unsigned newline_anchor : - 1; - - /* [[[end pattern_buffer]]] */ - }; - - typedef struct re_pattern_buffer regex_t; - - - /* search.c (search_buffer) in Emacs needs this one opcode value. It is - defined both in `regex.c' and here. */ -#define RE_EXACTN_VALUE 1 - - /* Type for byte offsets within the string. POSIX mandates this. */ - typedef int regoff_t; - - - /* This is the structure we store register match data in. See - regex.texinfo for a full description of what registers match. */ - struct re_registers { - unsigned num_regs; - regoff_t *start; - regoff_t *end; - }; - - - /* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer, - `re_match_2' returns information about at least this many registers - the first time a `regs' structure is passed. */ -#ifndef RE_NREGS -#define RE_NREGS 30 -#endif - - - /* POSIX specification for registers. Aside from the different names than - `re_registers', POSIX uses an array of structures, instead of a - structure of arrays. */ - typedef struct { - regoff_t rm_so; /* Byte offset from string's start to substring's start. */ - regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ - } - regmatch_t; - - /* Declarations for routines. */ - - /* To avoid duplicating every routine declaration -- once with a - prototype (if we are ANSI), and once without (if we aren't) -- we - use the following macro to declare argument types. This - unfortunately clutters up the declarations a bit, but I think it's - worth it. */ - -#if __STDC__ - -#define _RE_ARGS(args) args - -#else /* not __STDC__ */ - -#define _RE_ARGS(args) () - -#endif /* not __STDC__ */ - - /* Sets the current default syntax to SYNTAX, and return the old syntax. - You can also simply assign to the `re_syntax_options' variable. */ - extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax)); - - /* Compile the regular expression PATTERN, with length LENGTH - and syntax given by the global `re_syntax_options', into the buffer - BUFFER. Return NULL if successful, and an error string if not. */ - extern const char *re_compile_pattern - _RE_ARGS ((const char *pattern, int length, - struct re_pattern_buffer *buffer)); - - - /* Compile a fastmap for the compiled pattern in BUFFER; used to - accelerate searches. Return 0 if successful and -2 if was an - internal error. */ - extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer)); - - - /* Search in the string STRING (with length LENGTH) for the pattern - compiled into BUFFER. Start searching at position START, for RANGE - characters. Return the starting position of the match, -1 for no - match, or -2 for an internal error. Also return register - information in REGS (if REGS and BUFFER->no_sub are nonzero). */ - extern int re_search - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, - int length, int start, int range, struct re_registers *regs)); - - - /* Like `re_search', but search in the concatenation of STRING1 and - STRING2. Also, stop searching at index START + STOP. */ - extern int re_search_2 - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, - int length1, const char *string2, int length2, - int start, int range, struct re_registers *regs, int stop)); - - - /* Like `re_search', but return how many characters in STRING the regexp - in BUFFER matched, starting at position START. */ - extern int re_match - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, - int length, int start, struct re_registers *regs)); - - - /* Relates to `re_match' as `re_search_2' relates to `re_search'. */ - extern int re_match_2 - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, - int length1, const char *string2, int length2, - int start, struct re_registers *regs, int stop)); - - - /* Set REGS to hold NUM_REGS registers, storing them in STARTS and - ENDS. Subsequent matches using BUFFER and REGS will use this memory - for recording register information. STARTS and ENDS must be - allocated with malloc, and must each be at least `NUM_REGS * sizeof - (regoff_t)' bytes long. - - If NUM_REGS == 0, then subsequent matches should allocate their own - register data. - - Unless this function is called, the first search or match using - PATTERN_BUFFER will allocate its own register data, without - freeing the old data. */ - extern void re_set_registers - _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs, - unsigned num_regs, regoff_t *starts, regoff_t *ends)); - - /* 4.2 bsd compatibility. */ - extern char *re_comp _RE_ARGS ((const char *)); - extern int re_exec _RE_ARGS ((const char *)); - - /* POSIX compatibility. */ - extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags)); - extern int regexec - _RE_ARGS ((const regex_t *preg, const char *string, size_t nmatch, - regmatch_t pmatch[], int eflags)); - extern size_t regerror - _RE_ARGS ((int errcode, const regex_t *preg, char *errbuf, - size_t errbuf_size)); - extern void regfree _RE_ARGS ((regex_t *preg)); - -#endif /* not __REGEXP_LIBRARY_H__ */ - -#ifdef __cplusplus -} -#endif - - -/* -Local variables: -make-backup-files: t -version-control: t -trim-versions-without-asking: nil -End: -*/ From 249c0c3b5d894aeca33c8cf2036ff1f6690a633e Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 5 May 2010 07:26:21 +0000 Subject: [PATCH 051/472] rebase from trunk 3966:4004 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@4005 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 14 +- common/JackAPI.cpp | 186 ++++------------------- common/JackConstants.h | 24 --- common/JackDriverLoader.cpp | 2 +- common/JackLibAPI.cpp | 68 ++++++++- common/JackServerAPI.cpp | 64 +++++++- common/jack/jack.h | 6 +- dbus/sigsegv.c | 8 +- example-clients/connect.c | 31 +++- example-clients/netsource.c | 30 ++-- example-clients/wscript | 2 +- linux/JackAtomic_os.h | 22 ++- linux/JackPlatformPlug_os.h | 4 + linux/alsa/JackAlsaDriver.cpp | 13 +- linux/alsa/JackAlsaDriver.h | 2 +- linux/cycles.h | 14 ++ linux/firewire/JackFFADODriver.cpp | 8 +- macosx/JackAtomic_os.h | 14 +- macosx/JackPlatformPlug_os.h | 4 + macosx/Jackdmp.xcodeproj/project.pbxproj | 92 ++++++++--- macosx/coremidi/JackCoreMidiDriver.cpp | 8 +- posix/JackFifo.cpp | 2 +- solaris/JackPlatformPlug_os.h | 4 + windows/JackPlatformPlug_os.h | 4 + 24 files changed, 361 insertions(+), 265 deletions(-) diff --git a/ChangeLog b/ChangeLog index efaf99f8..0b5b074e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -29,11 +29,23 @@ Arnold Krille --------------------------- Jackdmp changes log --------------------------- + +2010-04-016 Stephane Letz + + * Make jack_connect/jack_disconnect wait for effective port connection/disconnection. + +2010-04-07 Stephane Letz + + * Remove call to exit in library code. + +2010-03-26 Stephane Letz + + * ffado-portname-sync.patch from ticket #163 applied. 2010-03-24 Stephane Letz * On Windows, now use TRE library for regexp (BSD license instead of GPL license). - + 2010-03-19 Stephane Letz * Fix some file header to have library side code use LGPL. diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index 06408833..f6a67b99 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -56,9 +56,9 @@ extern "C" const char * jack_get_version_string(); - EXPORT jack_client_t * jack_client_open_aux (const char *client_name, + jack_client_t * jack_client_new_aux (const char *client_name, jack_options_t options, - jack_status_t *status, va_list ap); + jack_status_t *status); EXPORT jack_client_t * jack_client_open (const char *client_name, jack_options_t options, jack_status_t *status, ...); @@ -300,7 +300,7 @@ EXPORT jack_client_t* jack_client_new(const char* client_name) int options = JackUseExactName; if (getenv("JACK_START_SERVER") == NULL) options |= JackNoStartServer; - jack_client_t* res = jack_client_open_aux(client_name, (jack_options_t)options, NULL, NULL); + jack_client_t* res = jack_client_new_aux(client_name, (jack_options_t)options, NULL); JackGlobals::fOpenMutex->Unlock(); return res; } catch (std::bad_alloc& e) { @@ -317,11 +317,7 @@ EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames) #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_get_buffer"); #endif -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_get_buffer called with an incorrect port %ld", myport); @@ -337,11 +333,7 @@ EXPORT const char* jack_port_name(const jack_port_t* port) #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_name"); #endif -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_name called with an incorrect port %ld", myport); @@ -357,11 +349,7 @@ EXPORT const char* jack_port_short_name(const jack_port_t* port) #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_short_name"); #endif -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_short_name called with an incorrect port %ld", myport); @@ -377,11 +365,7 @@ EXPORT int jack_port_flags(const jack_port_t* port) #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_flags"); #endif -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_flags called with an incorrect port %ld", myport); @@ -397,11 +381,7 @@ EXPORT const char* jack_port_type(const jack_port_t* port) #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_type"); #endif - #if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_flags called an incorrect port %ld", myport); @@ -417,11 +397,7 @@ EXPORT jack_port_type_id_t jack_port_type_id(const jack_port_t *port) #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_type_id"); #endif -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_type_id called an incorrect port %ld", myport); @@ -437,11 +413,7 @@ EXPORT int jack_port_connected(const jack_port_t* port) #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_connected"); #endif -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_connected called with an incorrect port %ld", myport); @@ -458,11 +430,7 @@ EXPORT int jack_port_connected_to(const jack_port_t* port, const char* port_name #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_connected_to"); #endif -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t src = (jack_port_id_t)port_aux; if (!CheckPort(src)) { jack_error("jack_port_connected_to called with an incorrect port %ld", src); @@ -488,21 +456,13 @@ EXPORT int jack_port_tie(jack_port_t* src, jack_port_t* dst) #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_tie"); #endif -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t src_aux = (uint64_t)src; -#else - uint32_t src_aux = (uint32_t)src; -#endif + uintptr_t src_aux = (uintptr_t)src; jack_port_id_t mysrc = (jack_port_id_t)src_aux; if (!CheckPort(mysrc)) { jack_error("jack_port_tie called with a NULL src port"); return -1; } -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t dst_aux = (uint64_t)dst; -#else - uint32_t dst_aux = (uint32_t)dst; -#endif + uintptr_t dst_aux = (uintptr_t)dst; jack_port_id_t mydst = (jack_port_id_t)dst_aux; if (!CheckPort(mydst)) { jack_error("jack_port_tie called with a NULL dst port"); @@ -522,11 +482,7 @@ EXPORT int jack_port_untie(jack_port_t* port) #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_untie"); #endif -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_untie called with an incorrect port %ld", myport); @@ -542,11 +498,7 @@ EXPORT jack_nframes_t jack_port_get_latency(jack_port_t* port) #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_get_latency"); #endif -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_get_latency called with an incorrect port %ld", myport); @@ -563,11 +515,7 @@ EXPORT void jack_port_set_latency(jack_port_t* port, jack_nframes_t frames) #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_set_latency"); #endif -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_set_latency called with an incorrect port %ld", myport); @@ -585,11 +533,7 @@ EXPORT int jack_recompute_total_latency(jack_client_t* ext_client, jack_port_t* #endif JackClient* client = (JackClient*)ext_client; -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (client == NULL) { jack_error("jack_recompute_total_latencies called with a NULL client"); @@ -630,11 +574,7 @@ EXPORT int jack_port_set_name(jack_port_t* port, const char* name) #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_set_name"); #endif -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_set_name called with an incorrect port %ld", myport); @@ -660,11 +600,7 @@ EXPORT int jack_port_set_alias(jack_port_t* port, const char* name) #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_set_alias"); #endif -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_set_alias called with an incorrect port %ld", myport); @@ -683,11 +619,7 @@ EXPORT int jack_port_unset_alias(jack_port_t* port, const char* name) #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_unset_alias"); #endif -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_unset_alias called with an incorrect port %ld", myport); @@ -706,11 +638,7 @@ EXPORT int jack_port_get_aliases(const jack_port_t* port, char* const aliases[2] #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_get_aliases"); #endif -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_get_aliases called with an incorrect port %ld", myport); @@ -726,11 +654,7 @@ EXPORT int jack_port_request_monitor(jack_port_t* port, int onoff) #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_request_monitor"); #endif -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_request_monitor called with an incorrect port %ld", myport); @@ -769,11 +693,7 @@ EXPORT int jack_port_ensure_monitor(jack_port_t* port, int onoff) #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_ensure_monitor"); #endif - #if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_ensure_monitor called with an incorrect port %ld", myport); @@ -789,11 +709,7 @@ EXPORT int jack_port_monitoring_input(jack_port_t* port) #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_monitoring_input"); #endif -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_monitoring_input called with an incorrect port %ld", myport); @@ -1128,11 +1044,7 @@ EXPORT jack_port_t* jack_port_register(jack_client_t* ext_client, const char* po jack_error("jack_port_register called with a NULL port name or a NULL port_type"); return NULL; } else { -#if defined(__x86_64__) || defined(__ppc64__) - return (jack_port_t *)((uint64_t)client->PortRegister(port_name, port_type, flags, buffer_size)); -#else - return (jack_port_t *)client->PortRegister(port_name, port_type, flags, buffer_size); -#endif + return (jack_port_t *)((uintptr_t)client->PortRegister(port_name, port_type, flags, buffer_size)); } } @@ -1146,11 +1058,7 @@ EXPORT int jack_port_unregister(jack_client_t* ext_client, jack_port_t* port) jack_error("jack_port_unregister called with a NULL client"); return -1; } -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_unregister called with an incorrect port %ld", myport); @@ -1169,11 +1077,7 @@ EXPORT int jack_port_is_mine(const jack_client_t* ext_client, const jack_port_t* jack_error("jack_port_is_mine called with a NULL client"); return -1; } -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_is_mine called with an incorrect port %ld", myport); @@ -1187,11 +1091,7 @@ EXPORT const char** jack_port_get_connections(const jack_port_t* port) #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_port_get_connections"); #endif -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_get_connections called with an incorrect port %ld", myport); @@ -1215,11 +1115,7 @@ EXPORT const char** jack_port_get_all_connections(const jack_client_t* ext_clien return NULL; } -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_get_all_connections called with an incorrect port %ld", myport); @@ -1242,11 +1138,7 @@ EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t* ext_client, jac return 0; } -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)port; -#else - uint32_t port_aux = (uint32_t)port; -#endif + uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_get_total_latency called with an incorrect port %ld", myport); @@ -1307,11 +1199,7 @@ EXPORT int jack_port_disconnect(jack_client_t* ext_client, jack_port_t* src) jack_error("jack_port_disconnect called with a NULL client"); return -1; } -#if defined(__x86_64__) || defined(__ppc64__) - uint64_t port_aux = (uint64_t)src; -#else - uint32_t port_aux = (uint32_t)src; -#endif + uintptr_t port_aux = (uintptr_t)src; jack_port_id_t myport = (jack_port_id_t)port_aux; if (!CheckPort(myport)) { jack_error("jack_port_disconnect called with an incorrect port %ld", myport); @@ -1383,11 +1271,7 @@ EXPORT jack_port_t* jack_port_by_name(jack_client_t* ext_client, const char* por if (!manager) return NULL; int res = manager->GetPort(portname); // returns a port index at least > 1 -#if defined(__x86_64__) || defined(__ppc64__) - return (res == NO_PORT) ? NULL : (jack_port_t*)((uint64_t)res); -#else - return (res == NO_PORT) ? NULL : (jack_port_t*)res; -#endif + return (res == NO_PORT) ? NULL : (jack_port_t*)((uintptr_t)res); } } @@ -1397,11 +1281,7 @@ EXPORT jack_port_t* jack_port_by_id(jack_client_t* ext_client, jack_port_id_t id JackGlobals::CheckContext("jack_port_by_id"); #endif /* jack_port_t* type is actually the port index */ -#if defined(__x86_64__) || defined(__ppc64__) - return (jack_port_t*)((uint64_t)id); -#else - return (jack_port_t*)id; -#endif + return (jack_port_t*)((uintptr_t)id); } EXPORT int jack_engine_takeover_timebase(jack_client_t* ext_client) diff --git a/common/JackConstants.h b/common/JackConstants.h index e04906dd..94a7e422 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -59,30 +59,6 @@ #define JACK_DEFAULT_SERVER_NAME "default" -#ifdef WIN32 -#define jack_server_dir "server" -#define jack_client_dir "client" -#define ADDON_DIR "jack" -#endif - -#ifdef __APPLE__ -#define jack_server_dir "/tmp" -#define jack_client_dir "/tmp" -#define JACK_DEFAULT_DRIVER "coreaudio" -#endif - -#ifdef __linux__ -#define jack_server_dir "/dev/shm" -#define jack_client_dir "/dev/shm" -#define JACK_DEFAULT_DRIVER "alsa" -#endif - -#if defined(__sun__) || defined(sun) -#define jack_server_dir "/tmp" -#define jack_client_dir "/tmp" -#define JACK_DEFAULT_DRIVER "oss" -#endif - #define jack_server_entry "jackdmp_entry" #define jack_client_entry "jack_client" diff --git a/common/JackDriverLoader.cpp b/common/JackDriverLoader.cpp index 428d3ab0..704a4ef9 100644 --- a/common/JackDriverLoader.cpp +++ b/common/JackDriverLoader.cpp @@ -152,7 +152,7 @@ jack_parse_driver_params (jack_driver_desc_t * desc, int argc, char* argv[], JSL fprintf (stderr, "Options for driver '%s':\n", desc->name); jack_print_driver_options (desc, stderr); - exit (1); + return 1; } for (param_index = 0; param_index < desc->nparams; param_index++) { diff --git a/common/JackLibAPI.cpp b/common/JackLibAPI.cpp index 45649c2d..73f290db 100644 --- a/common/JackLibAPI.cpp +++ b/common/JackLibAPI.cpp @@ -36,7 +36,10 @@ extern "C" { #endif - EXPORT jack_client_t * jack_client_open_aux (const char *client_name, + jack_client_t * jack_client_new_aux (const char *client_name, + jack_options_t options, + jack_status_t *status); + jack_client_t * jack_client_open_aux (const char *client_name, jack_options_t options, jack_status_t *status, va_list ap); EXPORT jack_client_t * jack_client_open (const char *client_name, @@ -52,18 +55,18 @@ extern "C" JackLibGlobals* JackLibGlobals::fGlobals = NULL; int JackLibGlobals::fClientCount = 0; -EXPORT jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t options, jack_status_t* status, va_list ap) +jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t* status) { jack_varargs_t va; /* variable arguments */ jack_status_t my_status; JackClient* client; if (client_name == NULL) { - jack_error("jack_client_open called with a NULL client_name"); + jack_error("jack_client_new called with a NULL client_name"); return NULL; } - jack_log("jack_client_open %s", client_name); + jack_log("jack_client_new %s", client_name); if (status == NULL) /* no status from caller? */ status = &my_status; /* use local status word */ @@ -77,11 +80,60 @@ EXPORT jack_client_t* jack_client_open_aux(const char* client_name, jack_options } /* parse variable arguments */ - if (ap) { - jack_varargs_parse(options, ap, &va); + jack_varargs_init(&va); + + JackLibGlobals::Init(); // jack library initialisation + + if (try_start_server(&va, options, status)) { + jack_error("jack server is not running or cannot be started"); + JackLibGlobals::Destroy(); // jack library destruction + return 0; + } + + if (JACK_DEBUG) { + client = new JackDebugClient(new JackLibClient(GetSynchroTable())); // Debug mode } else { - jack_varargs_init(&va); + client = new JackLibClient(GetSynchroTable()); + } + + int res = client->Open(va.server_name, client_name, options, status); + if (res < 0) { + delete client; + JackLibGlobals::Destroy(); // jack library destruction + int my_status1 = (JackFailure | JackServerError); + *status = (jack_status_t)my_status1; + return NULL; + } else { + return (jack_client_t*)client; + } +} + +jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t options, jack_status_t* status, va_list ap) +{ + jack_varargs_t va; /* variable arguments */ + jack_status_t my_status; + JackClient* client; + + if (client_name == NULL) { + jack_error("jack_client_open called with a NULL client_name"); + return NULL; } + + jack_log("jack_client_open %s", client_name); + + if (status == NULL) /* no status from caller? */ + status = &my_status; /* use local status word */ + *status = (jack_status_t)0; + + /* validate parameters */ + if ((options & ~JackOpenOptions)) { + int my_status1 = *status | (JackFailure | JackInvalidOption); + *status = (jack_status_t)my_status1; + return NULL; + } + + /* parse variable arguments */ + jack_varargs_parse(options, ap, &va); JackLibGlobals::Init(); // jack library initialisation @@ -111,10 +163,10 @@ EXPORT jack_client_t* jack_client_open_aux(const char* client_name, jack_options EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...) { - try { #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_client_open"); #endif + try { assert(JackGlobals::fOpenMutex); JackGlobals::fOpenMutex->Lock(); va_list ap; diff --git a/common/JackServerAPI.cpp b/common/JackServerAPI.cpp index a9755fe8..50b4d291 100644 --- a/common/JackServerAPI.cpp +++ b/common/JackServerAPI.cpp @@ -33,7 +33,10 @@ extern "C" { #endif - EXPORT jack_client_t * jack_client_open_aux (const char *client_name, + jack_client_t * jack_client_new_aux (const char *client_name, + jack_options_t options, + jack_status_t *status); + jack_client_t * jack_client_open_aux (const char *client_name, jack_options_t options, jack_status_t *status, va_list ap); EXPORT jack_client_t * jack_client_open (const char *client_name, @@ -48,18 +51,18 @@ extern "C" using namespace Jack; -EXPORT jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t options, jack_status_t* status, va_list ap) +jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t* status) { jack_varargs_t va; /* variable arguments */ jack_status_t my_status; JackClient* client; if (client_name == NULL) { - jack_error("jack_client_open called with a NULL client_name"); + jack_error("jack_client_new called with a NULL client_name"); return NULL; } - jack_log("jack_client_open %s", client_name); + jack_log("jack_client_new %s", client_name); if (status == NULL) /* no status from caller? */ status = &my_status; /* use local status word */ @@ -73,12 +76,59 @@ EXPORT jack_client_t* jack_client_open_aux(const char* client_name, jack_options } /* parse variable arguments */ - if (ap) { - jack_varargs_parse(options, ap, &va); + jack_varargs_init(&va); + + if (!JackServerGlobals::Init()) { // jack server initialisation + int my_status1 = (JackFailure | JackServerError); + *status = (jack_status_t)my_status1; + return NULL; + } + + if (JACK_DEBUG) { + client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode } else { - jack_varargs_init(&va); + client = new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable()); + } + + int res = client->Open(va.server_name, client_name, options, status); + if (res < 0) { + delete client; + JackServerGlobals::Destroy(); // jack server destruction + int my_status1 = (JackFailure | JackServerError); + *status = (jack_status_t)my_status1; + return NULL; + } else { + return (jack_client_t*)client; + } +} + +jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t options, jack_status_t* status, va_list ap) +{ + jack_varargs_t va; /* variable arguments */ + jack_status_t my_status; + JackClient* client; + + if (client_name == NULL) { + jack_error("jack_client_open called with a NULL client_name"); + return NULL; } + jack_log("jack_client_open %s", client_name); + + if (status == NULL) /* no status from caller? */ + status = &my_status; /* use local status word */ + *status = (jack_status_t)0; + + /* validate parameters */ + if ((options & ~JackOpenOptions)) { + int my_status1 = *status | (JackFailure | JackInvalidOption); + *status = (jack_status_t)my_status1; + return NULL; + } + + /* parse variable arguments */ + jack_varargs_parse(options, ap, &va); + if (!JackServerGlobals::Init()) { // jack server initialisation int my_status1 = (JackFailure | JackServerError); *status = (jack_status_t)my_status1; diff --git a/common/jack/jack.h b/common/jack/jack.h index 96800dcd..85e11fea 100644 --- a/common/jack/jack.h +++ b/common/jack/jack.h @@ -732,7 +732,7 @@ int jack_port_connected_to (const jack_port_t *port, * @return a null-terminated array of full port names to which the @a * port is connected. If none, returns NULL. * - * The caller is responsible for calling free(3) on any non-NULL + * The caller is responsible for calling jack_free(3) on any non-NULL * returned value. * * @param port locally owned jack_port_t pointer. @@ -745,7 +745,7 @@ const char ** jack_port_get_connections (const jack_port_t *port) JACK_OPTIONAL_ * @return a null-terminated array of full port names to which the @a * port is connected. If none, returns NULL. * - * The caller is responsible for calling free(3) on any non-NULL + * The caller is responsible for calling jack_free(3) on any non-NULL * returned value. * * This differs from jack_port_get_connections() in two important @@ -996,7 +996,7 @@ int jack_port_type_size(void) JACK_OPTIONAL_WEAK_EXPORT; * If zero, no selection based on flags will be carried out. * * @return a NULL-terminated array of ports that match the specified - * arguments. The caller is responsible for calling free(3) any + * arguments. The caller is responsible for calling jack_free(3) any * non-NULL returned value. * * @see jack_port_name_size(), jack_port_type_size() diff --git a/dbus/sigsegv.c b/dbus/sigsegv.c index 26bc204f..ab535bc2 100644 --- a/dbus/sigsegv.c +++ b/dbus/sigsegv.c @@ -99,7 +99,13 @@ static void signal_segv(int signum, siginfo_t* info, void*ptr) { jack_error("info.si_code = %d (%s)", info->si_code, si_codes[info->si_code]); jack_error("info.si_addr = %p", info->si_addr); for(i = 0; i < NGREG; i++) - jack_error("reg[%02d] = 0x" REGFORMAT, i, ucontext->uc_mcontext.gregs[i]); + jack_error("reg[%02d] = 0x" REGFORMAT, i, +#if defined(__powerpc__) + ucontext->uc_mcontext.uc_regs[i] +#else + ucontext->uc_mcontext.gregs[i] +#endif + ); #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64) # if defined(SIGSEGV_STACK_IA64) diff --git a/example-clients/connect.c b/example-clients/connect.c index a89e538a..635b2361 100644 --- a/example-clients/connect.c +++ b/example-clients/connect.c @@ -1,6 +1,6 @@ /* Copyright (C) 2002 Jeremy Hall - + 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 @@ -29,9 +29,16 @@ jack_port_t *input_port; jack_port_t *output_port; int connecting, disconnecting; +int done = 0; #define TRUE 1 #define FALSE 0 + +void port_connect_callback(jack_port_id_t a, jack_port_id_t b, int connect, void* arg) +{ + done = 1; +} + int main (int argc, char *argv[]) { @@ -43,7 +50,7 @@ main (int argc, char *argv[]) } else { my_name ++; } - + printf("name %s\n", my_name); if (strstr(my_name, "jack_disconnect")) { @@ -70,7 +77,9 @@ main (int argc, char *argv[]) return 1; } - /* display the current sample rate. once the client is activated + jack_set_port_connect_callback(client, port_connect_callback, NULL); + + /* display the current sample rate. once the client is activated (see below), you should rely on your own sample rate callback (see above) for this value. */ @@ -85,7 +94,7 @@ main (int argc, char *argv[]) fprintf (stderr, "ERROR %s not a valid port\n", argv[2]); goto error; } - + /* tell the JACK server that we are ready to roll */ if (jack_activate (client)) { @@ -109,12 +118,22 @@ main (int argc, char *argv[]) goto error; } } + + // Wait for connection/disconnection to be effective + while(!done) { + #ifdef WIN32 + Sleep(10); + #else + usleep(10000); + #endif + } + jack_deactivate (client); jack_client_close (client); return 0; - + error: - if (client) + if (client) jack_client_close (client); return 1; } diff --git a/example-clients/netsource.c b/example-clients/netsource.c index d6d252c2..a78dc8cb 100644 --- a/example-clients/netsource.c +++ b/example-clients/netsource.c @@ -503,11 +503,12 @@ init_sockaddr_in (struct sockaddr_in *name , const char *hostname , uint16_t por if (hostinfo == NULL) { fprintf (stderr, "init_sockaddr_in: unknown host: %s.\n", hostname); fflush( stderr ); + return; } #ifdef WIN32 - name->sin_addr.s_addr = inet_addr( hostname ); + name->sin_addr.s_addr = inet_addr( hostname ); #else - name->sin_addr = *(struct in_addr *) hostinfo->h_addr ; + name->sin_addr = *(struct in_addr *) hostinfo->h_addr ; #endif } else @@ -622,15 +623,15 @@ main (int argc, char *argv[]) case 'b': bitdepth = atoi (optarg); break; - case 'c': -#if HAVE_CELT - bitdepth = 1000; + case 'c': + #if HAVE_CELT + bitdepth = 1000; factor = atoi (optarg); -#else + #else printf( "not built with celt supprt\n" ); exit(10); -#endif - break; + #endif + break; case 'm': mtu = atoi (optarg); break; @@ -677,18 +678,17 @@ main (int argc, char *argv[]) } init_sockaddr_in ((struct sockaddr_in *) &destaddr, peer_ip, peer_port); - if(bind_port) { + if (bind_port) { init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, bind_port); if( bind (outsockfd, &bindaddr, sizeof (bindaddr)) ) { - fprintf (stderr, "bind failure\n" ); - } + fprintf (stderr, "bind failure\n" ); + } } - if(reply_port) - { + if (reply_port) { init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port); if( bind (insockfd, &bindaddr, sizeof (bindaddr)) ) { - fprintf (stderr, "bind failure\n" ); - } + fprintf (stderr, "bind failure\n" ); + } } /* try to become a client of the JACK server */ diff --git a/example-clients/wscript b/example-clients/wscript index 215be593..3f629cca 100644 --- a/example-clients/wscript +++ b/example-clients/wscript @@ -59,7 +59,7 @@ def configure(conf): conf.env['BUILD_EXAMPLE_CLIENT_REC'] = conf.is_defined('HAVE_SNDFILE') - conf.env['BUILD_EXAMPLE_ALSA_IO'] = conf.is_defined('HAVE_SAMPLERATE') + conf.env['BUILD_EXAMPLE_ALSA_IO'] = conf.is_defined('HAVE_SAMPLERATE') and conf.is_defined('HAVE_ALSA') def build(bld): if bld.env['IS_LINUX']: diff --git a/linux/JackAtomic_os.h b/linux/JackAtomic_os.h index b69cb22a..37181e04 100644 --- a/linux/JackAtomic_os.h +++ b/linux/JackAtomic_os.h @@ -42,9 +42,9 @@ static inline int CAS(register UInt32 value, register UInt32 newvalue, register "1: \n" " li %0, 0 \n" "2: \n" - : "=r" (result) - : "r" (addr), "r" (value), "r" (newvalue), "r" (tmp) - ); + : "=r" (result) + : "r" (addr), "r" (value), "r" (newvalue), "r" (tmp) + ); return result; } @@ -61,13 +61,23 @@ static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* ad "# CAS \n\t" LOCK "cmpxchg %2, (%1) \n\t" "sete %0 \n\t" - : "=a" (ret) - : "c" (addr), "d" (newvalue), "a" (value) - ); + : "=a" (ret) + : "c" (addr), "d" (newvalue), "a" (value) + ); return ret; } #endif +#if !defined(__i386__) && !defined(__x86_64__) && !defined(__PPC__) +#warning using builtin gcc (version > 4.1) atomic + +static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr) +{ + return __sync_bool_compare_and_swap (&addr, value, newvalue); +} +#endif + + #endif diff --git a/linux/JackPlatformPlug_os.h b/linux/JackPlatformPlug_os.h index c0cd93ba..22750dcc 100644 --- a/linux/JackPlatformPlug_os.h +++ b/linux/JackPlatformPlug_os.h @@ -20,6 +20,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __JackPlatformPlug_linux__ #define __JackPlatformPlug_linux__ +#define jack_server_dir "/dev/shm" +#define jack_client_dir "/dev/shm" +#define JACK_DEFAULT_DRIVER "alsa" + namespace Jack { struct JackRequest; diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index fff7aea9..cc86f2ed 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -260,7 +260,7 @@ JackAlsaDriver::alsa_driver_hw_specific (alsa_driver_t *driver, int hw_monitorin return 0; } -void +int JackAlsaDriver::alsa_driver_setup_io_function_pointers (alsa_driver_t *driver) { if (driver->playback_handle) { @@ -340,7 +340,7 @@ JackAlsaDriver::alsa_driver_setup_io_function_pointers (alsa_driver_t *driver) default: jack_error ("impossible sample width (%d) discovered!", driver->playback_sample_bytes); - exit (1); + return -1; } } } @@ -364,6 +364,8 @@ JackAlsaDriver::alsa_driver_setup_io_function_pointers (alsa_driver_t *driver) break; } } + + return 0; } int @@ -779,7 +781,7 @@ JackAlsaDriver::alsa_driver_set_parameters (alsa_driver_t *driver, default: jack_error ("programming error: unhandled format " "type for playback"); - exit (1); + return -1; } } @@ -797,7 +799,7 @@ JackAlsaDriver::alsa_driver_set_parameters (alsa_driver_t *driver, default: jack_error ("programming error: unhandled format " "type for capture"); - exit (1); + return -1; } } @@ -836,7 +838,8 @@ JackAlsaDriver::alsa_driver_set_parameters (alsa_driver_t *driver, driver->user_nchannels = driver->playback_nchannels; } - alsa_driver_setup_io_function_pointers (driver); + if (alsa_driver_setup_io_function_pointers (driver) != 0) + return -1; /* Allocate and initialize structures that rely on the channels counts. diff --git a/linux/alsa/JackAlsaDriver.h b/linux/alsa/JackAlsaDriver.h index fc66195a..8bab0e69 100644 --- a/linux/alsa/JackAlsaDriver.h +++ b/linux/alsa/JackAlsaDriver.h @@ -53,7 +53,7 @@ class JackAlsaDriver : public JackAudioDriver int alsa_driver_generic_hardware(alsa_driver_t *driver); int alsa_driver_hw_specific(alsa_driver_t *driver, int hw_monitoring, int hw_metering); - void alsa_driver_setup_io_function_pointers (alsa_driver_t *driver); + int alsa_driver_setup_io_function_pointers (alsa_driver_t *driver); int alsa_driver_configure_stream(alsa_driver_t *driver, char *device_name, const char *stream_name, snd_pcm_t *handle, diff --git a/linux/cycles.h b/linux/cycles.h index 51be192f..eff99e02 100644 --- a/linux/cycles.h +++ b/linux/cycles.h @@ -103,6 +103,20 @@ static inline cycles_t get_cycles (void) #endif +/* everything else but x86, amd64 or ppc */ +#if !defined (__PPC__) && !defined (__x86_64__) && !defined (__i386__) + +#warning No suitable get_cycles() implementation. Returning 0 instead + +typedef unsigned long long cycles_t; + +static inline cycles_t get_cycles(void) +{ + return 0; +} + +#endif + #endif #endif /* __jack_cycles_h__ */ diff --git a/linux/firewire/JackFFADODriver.cpp b/linux/firewire/JackFFADODriver.cpp index 7e679c55..17df4663 100644 --- a/linux/firewire/JackFFADODriver.cpp +++ b/linux/firewire/JackFFADODriver.cpp @@ -429,7 +429,7 @@ int JackFFADODriver::Attach() driver->capture_channels[chn].stream_type = ffado_streaming_get_capture_stream_type(driver->dev, chn); if (driver->capture_channels[chn].stream_type == ffado_stream_type_audio) { - snprintf(buf, sizeof(buf) - 1, "%s:%s", fClientControl.fName, portname); + snprintf(buf, sizeof(buf) - 1, "firewire_pcm:%s_in", portname); printMessage ("Registering audio capture port %s", buf); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, @@ -455,7 +455,7 @@ int JackFFADODriver::Attach() fCaptureChannels++; } else if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) { - snprintf(buf, sizeof(buf) - 1, "%s:%s", fClientControl.fName, portname); + snprintf(buf, sizeof(buf) - 1, "firewire_pcm:%s_in", portname); printMessage ("Registering midi capture port %s", buf); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, @@ -502,7 +502,7 @@ int JackFFADODriver::Attach() driver->playback_channels[chn].stream_type = ffado_streaming_get_playback_stream_type(driver->dev, chn); if (driver->playback_channels[chn].stream_type == ffado_stream_type_audio) { - snprintf(buf, sizeof(buf) - 1, "%s:%s", fClientControl.fName, portname); + snprintf(buf, sizeof(buf) - 1, "firewire_pcm:%s_out", portname); printMessage ("Registering audio playback port %s", buf); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, @@ -530,7 +530,7 @@ int JackFFADODriver::Attach() jack_log("JackFFADODriver::Attach fPlaybackPortList[i] %ld ", port_index); fPlaybackChannels++; } else if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) { - snprintf(buf, sizeof(buf) - 1, "%s:%s", fClientControl.fName, portname); + snprintf(buf, sizeof(buf) - 1, "firewire_pcm:%s_out", portname); printMessage ("Registering midi playback port %s", buf); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, diff --git a/macosx/JackAtomic_os.h b/macosx/JackAtomic_os.h index bd88a223..540239d4 100644 --- a/macosx/JackAtomic_os.h +++ b/macosx/JackAtomic_os.h @@ -41,10 +41,10 @@ static inline int CAS(register UInt32 value, register UInt32 newvalue, register "1: \n" " li %0, 0 \n" "2: \n" - : "=r" (result) - : "r" (addr), "r" (value), "r" (newvalue) - : "r0" - ); + : "=r" (result) + : "r" (addr), "r" (value), "r" (newvalue) + : "r0" + ); return result; } @@ -61,9 +61,9 @@ static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* ad "# CAS \n\t" LOCK "cmpxchg %2, (%1) \n\t" "sete %0 \n\t" - : "=a" (ret) - : "c" (addr), "d" (newvalue), "a" (value) - ); + : "=a" (ret) + : "c" (addr), "d" (newvalue), "a" (value) + ); return ret; } diff --git a/macosx/JackPlatformPlug_os.h b/macosx/JackPlatformPlug_os.h index d8cc1ca3..44ab5c33 100644 --- a/macosx/JackPlatformPlug_os.h +++ b/macosx/JackPlatformPlug_os.h @@ -22,6 +22,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include +#define jack_server_dir "/tmp" +#define jack_client_dir "/tmp" +#define JACK_DEFAULT_DRIVER "coreaudio" + namespace Jack { class JackPosixMutex; diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index d2f997d6..486ae06c 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -7950,16 +7950,17 @@ LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_CPLUSPLUSFLAGS = ( + "-DHAVE_CELT_API_0_7", + "-DHAVE_CELT", + "-DMACH_RPC_MACH_SEMA", + ); OTHER_LDFLAGS = ( + libcelt.a, "-framework", Jackservermp, "-framework", - CoreAudio, - "-framework", CoreServices, - "-framework", - AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; @@ -8000,8 +8001,13 @@ MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_CPLUSPLUSFLAGS = ( + "-DHAVE_CELT_API_0_7", + "-DHAVE_CELT", + "-DMACH_RPC_MACH_SEMA", + ); OTHER_LDFLAGS = ( + libcelt.a, "-framework", Jackservermp, "-framework", @@ -8037,7 +8043,11 @@ LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_CPLUSPLUSFLAGS = ( + "-DHAVE_CELT_API_0_7", + "-DHAVE_CELT", + "-DMACH_RPC_MACH_SEMA", + ); OTHER_LDFLAGS = ( "-framework", Jackdmp, @@ -8087,17 +8097,19 @@ INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; - OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_CFLAGS = "-DJACK_32_64"; + OTHER_CPLUSPLUSFLAGS = ( + "-DJACK_32_64", + "-DHAVE_CELT", + "-DHAVE_CELT_API_0_7", + "-DMACH_RPC_MACH_SEMA", + ); OTHER_LDFLAGS = ( + libcelt.a, "-framework", Jackservermp, "-framework", - CoreAudio, - "-framework", CoreServices, - "-framework", - AudioUnit, ); OTHER_REZFLAGS = ""; PREBINDING = NO; @@ -8137,10 +8149,13 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = "-DJACK_32_64"; OTHER_CPLUSPLUSFLAGS = ( + "-DHAVE_CELT", + "-DHAVE_CELT_API_0_7", "-DMACH_RPC_MACH_SEMA", "-DJACK_32_64", ); OTHER_LDFLAGS = ( + libcelt.a, "-framework", Jackservermp, "-framework", @@ -8216,8 +8231,17 @@ GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; - OTHER_CFLAGS = ""; + OTHER_CFLAGS = ( + "-DHAVE_CELT", + "-DHAVE_CELT_API_0_7", + ); + OTHER_CPLUSPLUSFLAGS = ( + "-DHAVE_CELT", + "-DHAVE_CELT_API_0_7", + "$(OTHER_CFLAGS)", + ); OTHER_LDFLAGS = ( + libcelt.a, "-framework", Jackmp, "-framework", @@ -8249,8 +8273,17 @@ GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; - OTHER_CFLAGS = ""; + OTHER_CFLAGS = ( + "-DHAVE_CELT", + "-DHAVE_CELT_API_0_7", + ); + OTHER_CPLUSPLUSFLAGS = ( + "-DHAVE_CELT", + "-DHAVE_CELT_API_0_7", + "$(OTHER_CFLAGS)", + ); OTHER_LDFLAGS = ( + libcelt.a, "-framework", Jackmp, "-framework", @@ -8280,6 +8313,11 @@ FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = ( + "-DHAVE_CELT", + "-DHAVE_CELT_API_0_7", + "$(OTHER_CFLAGS)", + ); OTHER_LDFLAGS = ( "-framework", Jackmp, @@ -8311,8 +8349,13 @@ GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../common; - OTHER_CFLAGS = ""; + OTHER_CFLAGS = ( + "-DHAVE_CELT", + "-DHAVE_CELT_API_0_7", + ); + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( + libcelt.a, "-framework", Jackmp, "-framework", @@ -8342,8 +8385,13 @@ GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; MACOSX_DEPLOYMENT_TARGET = 10.4; - OTHER_CFLAGS = ""; + OTHER_CFLAGS = ( + "-DHAVE_CELT", + "-DHAVE_CELT_API_0_7", + ); + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( + libcelt.a, "-framework", Jackmp, "-framework", @@ -8372,7 +8420,15 @@ ); FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ../common; - OTHER_CFLAGS = ""; + OTHER_CFLAGS = ( + "-DHAVE_CELT", + "-DHAVE_CELT_API_0_7", + ); + OTHER_CPLUSPLUSFLAGS = ( + "-DHAVE_CELT", + "-DHAVE_CELT_API_0_7", + "$(OTHER_CFLAGS)", + ); OTHER_LDFLAGS = ( "-framework", Jackmp, diff --git a/macosx/coremidi/JackCoreMidiDriver.cpp b/macosx/coremidi/JackCoreMidiDriver.cpp index 0f52e900..55ffeae6 100644 --- a/macosx/coremidi/JackCoreMidiDriver.cpp +++ b/macosx/coremidi/JackCoreMidiDriver.cpp @@ -40,11 +40,13 @@ static MIDITimeStamp MIDIGetCurrentHostTime() void JackCoreMidiDriver::ReadProcAux(const MIDIPacketList *pktlist, jack_ringbuffer_t* ringbuffer) { // Write the number of packets - size_t size = jack_ringbuffer_write(ringbuffer, (char*)&pktlist->numPackets, sizeof(UInt32)); - if (size != sizeof(UInt32)) { + size_t size = jack_ringbuffer_write_space(ringbuffer); + if (size < sizeof(UInt32)) { jack_error("ReadProc : ring buffer is full, skip events..."); return; - } + } + + jack_ringbuffer_write(ringbuffer, (char*)&pktlist->numPackets, sizeof(UInt32)); for (unsigned int i = 0; i < pktlist->numPackets; ++i) { diff --git a/posix/JackFifo.cpp b/posix/JackFifo.cpp index 1cd3e5d3..be13a5d7 100644 --- a/posix/JackFifo.cpp +++ b/posix/JackFifo.cpp @@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackFifo.h" #include "JackTools.h" #include "JackError.h" -#include "JackConstants.h" +#include "JackPlatformPlug.h" #include #include #include diff --git a/solaris/JackPlatformPlug_os.h b/solaris/JackPlatformPlug_os.h index a244010a..e3a03d34 100644 --- a/solaris/JackPlatformPlug_os.h +++ b/solaris/JackPlatformPlug_os.h @@ -20,6 +20,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __JackPlatformPlug_sun__ #define __JackPlatformPlug_sun__ +#define jack_server_dir "/tmp" +#define jack_client_dir "/tmp" +#define JACK_DEFAULT_DRIVER "oss" + namespace Jack { struct JackRequest; diff --git a/windows/JackPlatformPlug_os.h b/windows/JackPlatformPlug_os.h index 87c2e40f..bbafd0c9 100644 --- a/windows/JackPlatformPlug_os.h +++ b/windows/JackPlatformPlug_os.h @@ -21,6 +21,10 @@ #ifndef __JackPlatformPlug_WIN32__ #define __JackPlatformPlug_WIN32__ +#define jack_server_dir "server" +#define jack_client_dir "client" +#define ADDON_DIR "jack" + namespace Jack { struct JackRequest; From 7e4abd92c569678d6b343d67f94b3192fda44067 Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 12 May 2010 08:37:24 +0000 Subject: [PATCH 052/472] Cleanup encoder allocation. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@4012 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetInterface.cpp | 61 ++++++++++++------------------------- common/JackNetTool.cpp | 18 ++++++++--- 2 files changed, 33 insertions(+), 46 deletions(-) diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 4247056d..1eb66ca1 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -228,7 +228,7 @@ namespace Jack bool JackNetMasterInterface::SetParams() { - jack_log ( "JackNetMasterInterface::SetParams" ); + jack_log("JackNetMasterInterface::SetParams"); JackNetInterface::SetParams(); @@ -236,11 +236,12 @@ namespace Jack fRxHeader.fDataStream = 'r'; //midi net buffers - fNetMidiCaptureBuffer = new NetMidiBuffer ( &fParams, fParams.fSendMidiChannels, fTxData ); - fNetMidiPlaybackBuffer = new NetMidiBuffer ( &fParams, fParams.fReturnMidiChannels, fRxData ); - assert ( fNetMidiCaptureBuffer ); - assert ( fNetMidiPlaybackBuffer ); - + if (fParams.fSendMidiChannels) + fNetMidiCaptureBuffer = new NetMidiBuffer(&fParams, fParams.fSendMidiChannels, fTxData); + + if (fParams.fReturnMidiChannels) + fNetMidiPlaybackBuffer = new NetMidiBuffer(&fParams, fParams.fReturnMidiChannels, fRxData); + try { //audio net buffers @@ -253,7 +254,7 @@ namespace Jack break; case JackIntEncoder: - fNetAudioCaptureBuffer = new NetIntAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); + fNetAudioCaptureBuffer = new NetIntAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); break; case JackCeltEncoder: @@ -269,7 +270,7 @@ namespace Jack switch (fParams.fSampleEncoder) { case JackFloatEncoder: - fNetAudioPlaybackBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); + fNetAudioPlaybackBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); break; case JackIntEncoder: @@ -774,39 +775,15 @@ namespace Jack fTxHeader.fDataStream = 'r'; fRxHeader.fDataStream = 's'; - //midi net buffers - fNetMidiCaptureBuffer = new NetMidiBuffer ( &fParams, fParams.fSendMidiChannels, fRxData ); - fNetMidiPlaybackBuffer = new NetMidiBuffer ( &fParams, fParams.fReturnMidiChannels, fTxData ); - assert ( fNetMidiCaptureBuffer ); - assert ( fNetMidiPlaybackBuffer ); - - //audio net buffers - //fNetAudioCaptureBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); - //fNetAudioPlaybackBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); - - try { - #ifdef CELT - if (fParams.fSendAudioChannels) { - // fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); - fNetAudioCaptureBuffer = new NetIntAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); - } - - if (fParams.fReturnAudioChannels) { - //fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); - fNetAudioPlaybackBuffer = new NetIntAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); - } - - // fNetAudioCaptureBuffer = new NetIntAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); - // fNetAudioPlaybackBuffer = new NetIntAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); - #else - fNetAudioCaptureBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); - fNetAudioPlaybackBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); - - //fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); - //fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); - #endif - + //midi net buffers + if (fParams.fSendMidiChannels) + fNetMidiCaptureBuffer = new NetMidiBuffer(&fParams, fParams.fSendMidiChannels, fTxData); + if (fParams.fReturnMidiChannels) + fNetMidiPlaybackBuffer = new NetMidiBuffer(&fParams, fParams.fReturnMidiChannels, fRxData); + + try { + //audio net buffers if (fParams.fSendAudioChannels) { @@ -817,7 +794,7 @@ namespace Jack break; case JackIntEncoder: - fNetAudioCaptureBuffer = new NetIntAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); + fNetAudioCaptureBuffer = new NetIntAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData ); break; case JackCeltEncoder: @@ -833,7 +810,7 @@ namespace Jack switch (fParams.fSampleEncoder) { case JackFloatEncoder: - fNetAudioPlaybackBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); + fNetAudioPlaybackBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData ); break; case JackIntEncoder: diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index 5a9cf42d..d44658df 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -304,19 +304,19 @@ namespace Jack for (int port_index = 0; port_index < fNPorts; port_index++) fCompressedBuffer[port_index] = new unsigned char[fCompressedSizeByte]; - jack_log("fCompressedSizeByte %d", fCompressedSizeByte); + jack_log("NetCeltAudioBuffer fCompressedSizeByte %d", fCompressedSizeByte); res1 = (fNPorts * fCompressedSizeByte) % (params->fMtu - sizeof(packet_header_t)); res2 = (fNPorts * fCompressedSizeByte) / (params->fMtu - sizeof(packet_header_t)); - jack_log("res1 = %d res2 = %d", res1, res2); + jack_log("NetCeltAudioBuffer res1 = %d res2 = %d", res1, res2); fNumPackets = (res1) ? (res2 + 1) : res2; fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets; fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets; - jack_log("fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize); + jack_log("NetCeltAudioBuffer fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize); fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate); fCycleSize = params->fMtu * fNumPackets; @@ -710,7 +710,17 @@ namespace Jack jack_info ( "Return channels (audio - midi) : %d - %d", params->fReturnAudioChannels, params->fReturnMidiChannels ); jack_info ( "Sample rate : %u frames per second", params->fSampleRate ); jack_info ( "Period size : %u frames per period", params->fPeriodSize ); - jack_info ( "SampleEncoder : %u", params->fSampleEncoder ); + switch (params->fSampleEncoder) { + case (JackFloatEncoder): + jack_info ( "SampleEncoder : %s", "Float" ); + break; + case (JackIntEncoder): + jack_info ( "SampleEncoder : %s", "16 bits integer"); + break; + case (JackCeltEncoder): + jack_info ( "SampleEncoder : %s", "CELT"); + break; + }; jack_info ( "Slave mode : %s", ( params->fSlaveSyncMode ) ? "sync" : "async" ); jack_info ( "Network mode : %s", mode ); jack_info ( "****************************************************" ); From 7a2863cf55e20fbf274df687ca295e40bc84b34c Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 23 Aug 2010 10:38:25 +0000 Subject: [PATCH 053/472] rebase from trunk 4004:4041 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@4042 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 52 ++- common/JackClient.cpp | 5 +- common/JackError.cpp | 12 +- common/JackError.h | 3 +- common/JackPhysicalMidiInput.h | 2 +- common/JackPhysicalMidiOutput.h | 2 +- common/Jackdmp.cpp | 2 +- common/jack/systemdeps.h | 2 +- common/netjack.c | 2 +- common/netjack.h | 1 - common/shm.c | 2 +- dbus/audio_reserve.c | 2 +- dbus/controller.c | 23 +- dbus/controller_iface_control.c | 41 +- dbus/sigsegv.c | 4 + example-clients/ipload.c | 42 +- linux/JackPlatformPlug_os.h | 5 + linux/cycles.h | 39 +- linux/firewire/JackFFADODriver.cpp | 15 +- macosx/coreaudio/JackCoreAudioDriver.cpp | 71 +-- macosx/coreaudio/JackCoreAudioDriver.h | 8 - macosx/libcelt.a | Bin 0 -> 1026340 bytes man/alsa_in.0 | 97 ++++ man/alsa_out.0 | 1 + man/fill_template | 5 + man/jack_bufsize.0 | 14 + man/jack_connect.0 | 11 + man/jack_disconnect.0 | 1 + man/jack_freewheel.0 | 16 + man/jack_impulse_grabber.0 | 11 + man/jack_load.0 | 28 ++ man/jack_lsp.0 | 47 ++ man/jack_metro.0 | 40 ++ man/jack_monitor_client.0 | 18 + man/jack_netsource.0 | 109 +++++ man/jack_samplerate.0 | 9 + man/jack_showtime.0 | 13 + man/jack_simple_client.0 | 20 + man/jack_transport.0 | 13 + man/jack_unload.0 | 19 + man/jack_wait.0 | 41 ++ man/jackd.0 | 547 +++++++++++++++++++++++ man/jackrec.0 | 23 + man/wscript | 13 + posix/JackPosixSemaphore.cpp | 7 +- tests/test.cpp | 53 ++- wscript | 11 +- 47 files changed, 1351 insertions(+), 151 deletions(-) create mode 100644 macosx/libcelt.a create mode 100644 man/alsa_in.0 create mode 100644 man/alsa_out.0 create mode 100644 man/fill_template create mode 100644 man/jack_bufsize.0 create mode 100644 man/jack_connect.0 create mode 100644 man/jack_disconnect.0 create mode 100644 man/jack_freewheel.0 create mode 100644 man/jack_impulse_grabber.0 create mode 100644 man/jack_load.0 create mode 100644 man/jack_lsp.0 create mode 100644 man/jack_metro.0 create mode 100644 man/jack_monitor_client.0 create mode 100644 man/jack_netsource.0 create mode 100644 man/jack_samplerate.0 create mode 100644 man/jack_showtime.0 create mode 100644 man/jack_simple_client.0 create mode 100644 man/jack_transport.0 create mode 100644 man/jack_unload.0 create mode 100644 man/jack_wait.0 create mode 100644 man/jackd.0 create mode 100644 man/jackrec.0 create mode 100644 man/wscript diff --git a/ChangeLog b/ChangeLog index 0b5b074e..f54ae963 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24,20 +24,60 @@ Peter L Jones Devin Anderson Josh Green Mario Lang -Arnold Krille +Arnold Krille +Jan Engelhardt +Adrian Knoth --------------------------- Jackdmp changes log --------------------------- -2010-04-016 Stephane Letz +2010-08-23 Stephane Letz - * Make jack_connect/jack_disconnect wait for effective port connection/disconnection. + * Adrian Knoth fix for linux cycle.h (ticket 188). + +2010-07-07 Stephane Letz + + * Jan Engelhardt patch for get_cycles on SPARC. + * Adrian Knoth hurd.patch, kfreebsd-fix.patch and alpha_ia64-sigsegv.patch from ticket 177. + +2010-06-29 Stephane Letz + + * Arnold Krille firewire snooping patch. + +2010-06-16 Stephane Letz + + * David Garcia Garzon unused_pkt_buf_field_jack2 netone patch. + +2010-06-13 Stephane Letz + + * Fix JackPosixSemaphore::TimedWait : same behavior as JackPosixSemaphore::Wait regarding EINTR. + +2010-05-31 Stephane Letz + + * Fix from Fernando Lopez-Lezcano for compilation on fc13. + +2010-05-30 Stephane Letz + + * David Garcia Garzon netone patch. +2010-05-27 Stephane Letz + + * In JackCoreAudioDriver, move code called in MeasureCallback to be called once in IO thread. + +2010-05-07 Stephane Letz + + * Add tests to validate intclient.h API. + * On Linux, inter-process synchronization primitive switched to POSIX semaphore. + +2010-04-16 Stephane Letz + + * Make jack_connect/jack_disconnect wait for effective port connection/disconnection. + 2010-04-07 Stephane Letz * Remove call to exit in library code. - + 2010-03-26 Stephane Letz * ffado-portname-sync.patch from ticket #163 applied. @@ -45,7 +85,7 @@ Arnold Krille 2010-03-24 Stephane Letz * On Windows, now use TRE library for regexp (BSD license instead of GPL license). - + 2010-03-19 Stephane Letz * Fix some file header to have library side code use LGPL. @@ -234,7 +274,7 @@ Arnold Krille 2009-10-20 Stephane Letz * Add a string parameter to server ==> client notification, add a new JackInfoShutdownCallback type. - * CoreAudio backend now issue a JackInfoShutdownCallback when an unrecoverable error is detected (sampling rate change, stream configuration changeÉ) + * CoreAudio backend now issue a JackInfoShutdownCallback when an unrecoverable error is detected (sampling rate change, stream configuration changed) 2009-10-17 Stephane Letz diff --git a/common/JackClient.cpp b/common/JackClient.cpp index 889a24a8..800c70f6 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -1012,7 +1012,7 @@ int JackClient::InternalClientLoad(const char* client_name, jack_options_t optio if (va->load_name && (strlen(va->load_name) >= JACK_PATH_MAX)) { jack_error("\"%s\" is too long for a shared object name.\n" "Please use %lu characters or less.", - va->load_name, PATH_MAX); + va->load_name, JACK_PATH_MAX); int my_status1 = *status | (JackFailure | JackInvalidOption); *status = (jack_status_t)my_status1; return 0; @@ -1027,7 +1027,8 @@ int JackClient::InternalClientLoad(const char* client_name, jack_options_t optio return 0; } - int int_ref, result = -1; + int int_ref = 0; + int result = -1; fChannel->InternalClientLoad(GetClientControl()->fRefNum, client_name, va->load_name, va->load_init, options, (int*)status, &int_ref, &result); return int_ref; } diff --git a/common/JackError.cpp b/common/JackError.cpp index 905bbef8..d78f95e5 100644 --- a/common/JackError.cpp +++ b/common/JackError.cpp @@ -27,17 +27,15 @@ using namespace Jack; -void change_thread_log_function(jack_log_function_t log_function) +static bool change_thread_log_function(jack_log_function_t log_function) { - if (!jack_tls_set(JackGlobals::fKeyLogFunction, (void*)log_function)) - { - jack_error("failed to set thread log function"); - } + return (jack_tls_get(JackGlobals::fKeyLogFunction) == NULL + && jack_tls_set(JackGlobals::fKeyLogFunction, (void*)log_function)); } -SERVER_EXPORT void set_threaded_log_function() +SERVER_EXPORT int set_threaded_log_function() { - change_thread_log_function(JackMessageBufferAdd); + return change_thread_log_function(JackMessageBufferAdd); } void jack_log_function(int level, const char *message) diff --git a/common/JackError.h b/common/JackError.h index e16a65b2..03b4eada 100644 --- a/common/JackError.h +++ b/common/JackError.h @@ -53,10 +53,9 @@ extern "C" typedef void (* jack_log_function_t)(int level, const char *message); - void change_thread_log_function(jack_log_function_t log_function); void jack_log_function(int level, const char *message); - SERVER_EXPORT void set_threaded_log_function(); + SERVER_EXPORT int set_threaded_log_function(); #ifdef __cplusplus } diff --git a/common/JackPhysicalMidiInput.h b/common/JackPhysicalMidiInput.h index 6ba3b471..a05de6d0 100644 --- a/common/JackPhysicalMidiInput.h +++ b/common/JackPhysicalMidiInput.h @@ -120,7 +120,7 @@ namespace Jack { public: JackPhysicalMidiInput(size_t buffer_size=1024); - ~JackPhysicalMidiInput(); + virtual ~JackPhysicalMidiInput(); /** * Called to process MIDI data during a period. diff --git a/common/JackPhysicalMidiOutput.h b/common/JackPhysicalMidiOutput.h index f76a233a..9b4804b7 100644 --- a/common/JackPhysicalMidiOutput.h +++ b/common/JackPhysicalMidiOutput.h @@ -92,7 +92,7 @@ namespace Jack { JackPhysicalMidiOutput(size_t non_rt_buffer_size=1024, size_t rt_buffer_size=64); - ~JackPhysicalMidiOutput(); + virtual ~JackPhysicalMidiOutput(); /** * Called to process MIDI data during a period. diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index 89ed0845..fcf83a16 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -85,7 +85,7 @@ static void copyright(FILE* file) { fprintf(file, "jackdmp " VERSION "\n" "Copyright 2001-2005 Paul Davis and others.\n" - "Copyright 2004-2009 Grame.\n" + "Copyright 2004-2010 Grame.\n" "jackdmp comes with ABSOLUTELY NO WARRANTY\n" "This is free software, and you are welcome to redistribute it\n" "under certain conditions; see the file COPYING for details\n"); diff --git a/common/jack/systemdeps.h b/common/jack/systemdeps.h index 939e3c35..eadecd40 100644 --- a/common/jack/systemdeps.h +++ b/common/jack/systemdeps.h @@ -53,7 +53,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #endif /* WIN32 */ -#if defined(__APPLE__) || defined(__linux__) || defined(__sun__) || defined(sun) +#if defined(__APPLE__) || defined(__linux__) || defined(__sun__) || defined(sun) || defined(__unix__) #include #include #include diff --git a/common/netjack.c b/common/netjack.c index a073c2cf..077fad8c 100644 --- a/common/netjack.c +++ b/common/netjack.c @@ -564,6 +564,7 @@ netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj, netj->resample_factor = resample_factor; netj->resample_factor_up = resample_factor_up; + netj->jitter_val = jitter_val; return netj; } @@ -734,7 +735,6 @@ netjack_startup( netjack_driver_state_t *netj ) } netj->rx_bufsize = sizeof (jacknet_packet_header) + netj->net_period_down * netj->capture_channels * get_sample_size (netj->bitdepth); - netj->pkt_buf = malloc (netj->rx_bufsize); global_packcache = packet_cache_new (netj->latency + 50, netj->rx_bufsize, netj->mtu); netj->expected_framecnt_valid = 0; diff --git a/common/netjack.h b/common/netjack.h index 91c81be5..edac28a0 100644 --- a/common/netjack.h +++ b/common/netjack.h @@ -85,7 +85,6 @@ struct _netjack_driver_state { unsigned int handle_transport_sync; unsigned int *rx_buf; - unsigned int *pkt_buf; unsigned int rx_bufsize; //unsigned int tx_bufsize; unsigned int mtu; diff --git a/common/shm.c b/common/shm.c index d0e62de9..2cb1d40e 100644 --- a/common/shm.c +++ b/common/shm.c @@ -512,7 +512,7 @@ jack_register_server (const char *server_name, int new_registry) unlock: jack_shm_unlock_registry (); - return 0; + return res; } /* release server_name registration */ diff --git a/dbus/audio_reserve.c b/dbus/audio_reserve.c index 049826a5..da811c83 100644 --- a/dbus/audio_reserve.c +++ b/dbus/audio_reserve.c @@ -60,7 +60,7 @@ SERVER_EXPORT int audio_reservation_finish() if (gConnection) { dbus_connection_unref(gConnection); gConnection = NULL; - jack_info("audio_reservation_finish"); + jack_info("audio_reservation_finish"); } return 0; } diff --git a/dbus/controller.c b/dbus/controller.c index 17b51fdf..9c2bf3a5 100644 --- a/dbus/controller.c +++ b/dbus/controller.c @@ -1,6 +1,6 @@ /* -*- Mode: C ; c-basic-offset: 4 -*- */ /* - Copyright (C) 2007,2008 Nedko Arnaudov + Copyright (C) 2007,2008,2010 Nedko Arnaudov Copyright (C) 2007-2008 Juuso Alasuutari This program is free software; you can redistribute it and/or modify @@ -25,6 +25,7 @@ #include #include #include +#include #include "controller.h" #include "controller_internal.h" @@ -142,11 +143,7 @@ jack_controller_start_server( jack_info("Starting jack server..."); - if (controller_ptr->started) - { - jack_info("Already started."); - return TRUE; - } + assert(!controller_ptr->started); /* should be ensured by caller */ if (controller_ptr->driver == NULL) { @@ -171,7 +168,6 @@ jack_controller_start_server( if (controller_ptr->client == NULL) { jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to create dbusapi jack client"); - goto fail_stop_server; } @@ -179,13 +175,12 @@ jack_controller_start_server( if (ret != 0) { jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to set xrun callback. error is %d", ret); - goto fail_close_client; } if (!jack_controller_patchbay_init(controller_ptr)) { - jack_error("Failed to initialize patchbay district"); + jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to initialize patchbay district"); goto fail_close_client; } @@ -193,7 +188,6 @@ jack_controller_start_server( if (ret != 0) { jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to activate dbusapi jack client. error is %d", ret); - goto fail_patchbay_uninit; } @@ -232,16 +226,12 @@ jack_controller_stop_server( jack_info("Stopping jack server..."); - if (!controller_ptr->started) - { - jack_info("Already stopped."); - return TRUE; - } + assert(controller_ptr->started); /* should be ensured by caller */ ret = jack_deactivate(controller_ptr->client); if (ret != 0) { - jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to deactivate dbusapi jack client. error is %d", ret); + jack_error("failed to deactivate dbusapi jack client. error is %d", ret); } jack_controller_patchbay_uninit(controller_ptr); @@ -256,6 +246,7 @@ jack_controller_stop_server( if (!jackctl_server_stop(controller_ptr->server)) { + jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to stop server"); return FALSE; } diff --git a/dbus/controller_iface_control.c b/dbus/controller_iface_control.c index 967cde19..cd0187da 100644 --- a/dbus/controller_iface_control.c +++ b/dbus/controller_iface_control.c @@ -1,6 +1,6 @@ /* -*- Mode: C ; c-basic-offset: 4 -*- */ /* - Copyright (C) 2007,2008 Nedko Arnaudov + Copyright (C) 2007,2008,2010 Nedko Arnaudov Copyright (C) 2007-2008 Juuso Alasuutari This program is free software; you can redistribute it and/or modify @@ -85,29 +85,46 @@ jack_control_run_method( } else if (strcmp (call->method_name, "StartServer") == 0) { - if (!jack_controller_start_server(controller_ptr, call)) + if (controller_ptr->started) { - jack_dbus_error(call, JACK_DBUS_ERROR_GENERIC, "Failed to start server"); - return true; + jack_info("Ignoring JACK server start request because server is already started."); + } + else + { + if (!jack_controller_start_server(controller_ptr, call)) + { + /* the reply is set by the failed function */ + assert(call->reply != NULL); + return true; + } + + jack_controller_control_send_signal_server_started(); } - - jack_controller_control_send_signal_server_started(); } else if (strcmp (call->method_name, "StopServer") == 0) { - if (!jack_controller_stop_server(controller_ptr, call)) + if (!controller_ptr->started) { - jack_dbus_error(call, JACK_DBUS_ERROR_GENERIC, "Failed to stop server"); - return true; + jack_info("Ignoring JACK server stop request because server is already stopped."); + } + else + { + if (!jack_controller_stop_server(controller_ptr, call)) + { + /* the reply is set by the failed function */ + assert(call->reply != NULL); + return true; + } + + jack_controller_control_send_signal_server_stopped(); } - - jack_controller_control_send_signal_server_stopped(); } else if (strcmp (call->method_name, "SwitchMaster") == 0) { if (!jack_controller_switch_master(controller_ptr, call)) { - jack_dbus_error(call, JACK_DBUS_ERROR_GENERIC, "Failed to switch master"); + /* the reply is set by the failed function */ + assert(call->reply != NULL); return true; } diff --git a/dbus/sigsegv.c b/dbus/sigsegv.c index ab535bc2..ea309547 100644 --- a/dbus/sigsegv.c +++ b/dbus/sigsegv.c @@ -98,14 +98,18 @@ static void signal_segv(int signum, siginfo_t* info, void*ptr) { jack_error("info.si_errno = %d", info->si_errno); jack_error("info.si_code = %d (%s)", info->si_code, si_codes[info->si_code]); jack_error("info.si_addr = %p", info->si_addr); +#if !defined(__alpha__) && !defined(__ia64__) && !defined(__FreeBSD_kernel__) && !defined(__arm__) && !defined(__hppa__) && !defined(__sh__) for(i = 0; i < NGREG; i++) jack_error("reg[%02d] = 0x" REGFORMAT, i, #if defined(__powerpc__) ucontext->uc_mcontext.uc_regs[i] +#elif defined(__sparc__) && defined(__arch64__) + ucontext->uc_mcontext.mc_gregs[i] #else ucontext->uc_mcontext.gregs[i] #endif ); +#endif /* alpha, ia64, kFreeBSD, arm, hppa */ #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64) # if defined(SIGSEGV_STACK_IA64) diff --git a/example-clients/ipload.c b/example-clients/ipload.c index 49810a46..4868de3b 100644 --- a/example-clients/ipload.c +++ b/example-clients/ipload.c @@ -17,9 +17,9 @@ #include #include #include -#include +#include #ifndef WIN32 -#include +#include #endif #include #include @@ -126,7 +126,7 @@ parse_args (int argc, char *argv[]) int main (int argc, char *argv[]) { - jack_status_t status; + jack_status_t status; char* name; /* parse and validate command arguments */ @@ -157,8 +157,8 @@ main (int argc, char *argv[]) (JackLoadName|JackLoadInit), &status, load_name, load_init); if (status & JackFailure) { - fprintf (stderr, "could not load %s, status = 0x%2.0x\n", - load_name, status); + fprintf (stderr, "could not load %s, intclient = %d status = 0x%2.0x\n", + load_name, (int)intclient, status); return 2; } if (status & JackNameNotUnique) { @@ -178,23 +178,23 @@ main (int argc, char *argv[]) if (wait_opt) { /* define a signal handler to unload the client, then - * wait for it to exit */ - #ifdef WIN32 - signal(SIGINT, signal_handler); - signal(SIGABRT, signal_handler); - signal(SIGTERM, signal_handler); - #else - signal(SIGQUIT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGHUP, signal_handler); - signal(SIGINT, signal_handler); - #endif - - while (1) { - #ifdef WIN32 - Sleep(1000); + * wait for it to exit */ + #ifdef WIN32 + signal(SIGINT, signal_handler); + signal(SIGABRT, signal_handler); + signal(SIGTERM, signal_handler); + #else + signal(SIGQUIT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGHUP, signal_handler); + signal(SIGINT, signal_handler); + #endif + + while (1) { + #ifdef WIN32 + Sleep(1000); #else - sleep (1); + sleep (1); #endif } } diff --git a/linux/JackPlatformPlug_os.h b/linux/JackPlatformPlug_os.h index 22750dcc..5cabe8b5 100644 --- a/linux/JackPlatformPlug_os.h +++ b/linux/JackPlatformPlug_os.h @@ -49,8 +49,13 @@ namespace Jack {typedef JackPosixMutex JackMutex; } namespace Jack { typedef JackPosixThread JackThread; } /* __JackPlatformSynchro__ client activation */ +/* #include "JackFifo.h" namespace Jack { typedef JackFifo JackSynchro; } +*/ + +#include "JackPosixSemaphore.h" +namespace Jack { typedef JackPosixSemaphore JackSynchro; } /* __JackPlatformChannelTransaction__ */ #include "JackSocket.h" diff --git a/linux/cycles.h b/linux/cycles.h index eff99e02..20477a2e 100644 --- a/linux/cycles.h +++ b/linux/cycles.h @@ -51,7 +51,17 @@ static inline unsigned long get_cycles(void) return (((unsigned long)hi)<<32) | ((unsigned long)lo); } -#endif +#endif /* __x86_64__ */ + +#ifdef __sparc_v9__ +/* rd is V9 only */ +static inline unsigned long long get_cycles(void) +{ + unsigned long long res; + __asm__ __volatile__("rd %%tick, %0" : "=r"(res)); + return res; +} +#endif /* __sparc_v9__ */ #ifdef __PPC__ @@ -82,7 +92,7 @@ static inline cycles_t get_cycles(void) return ret; } -#endif +#endif /* __PPC__ */ #ifdef __i386__ @@ -101,10 +111,26 @@ static inline cycles_t get_cycles (void) return ret; } -#endif +#endif /* __i386__ */ + +/* everything else but x86, amd64, sparcv9 or ppc */ +#if !defined (__PPC__) && !defined (__x86_64__) && !defined (__i386__) && !defined (__sparc_v9__) + +#warning No suitable get_cycles() implementation. Returning 0 instead + +typedef unsigned long long cycles_t; + +static inline cycles_t get_cycles(void) +{ + return 0; +} + +#endif /* everything else but x86, amd64, sparcv9 or ppc */ + +#endif /* __linux__ */ + -/* everything else but x86, amd64 or ppc */ -#if !defined (__PPC__) && !defined (__x86_64__) && !defined (__i386__) +#if defined(__FreeBSD_kernel__) #warning No suitable get_cycles() implementation. Returning 0 instead @@ -115,8 +141,7 @@ static inline cycles_t get_cycles(void) return 0; } -#endif +#endif /* __FreeBSD_kernel__ */ -#endif #endif /* __jack_cycles_h__ */ diff --git a/linux/firewire/JackFFADODriver.cpp b/linux/firewire/JackFFADODriver.cpp index 17df4663..9cb554e4 100644 --- a/linux/firewire/JackFFADODriver.cpp +++ b/linux/firewire/JackFFADODriver.cpp @@ -338,6 +338,7 @@ JackFFADODriver::ffado_driver_new (const char *name, driver->device_options.verbose = params->verbose_level; driver->capture_frame_latency = params->capture_frame_latency; driver->playback_frame_latency = params->playback_frame_latency; + driver->device_options.snoop_mode = params->snoop_mode; debugPrint(DEBUG_LEVEL_STARTUP, " Driver compiled on %s %s", __DATE__, __TIME__); debugPrint(DEBUG_LEVEL_STARTUP, " Created driver %s", name); @@ -753,7 +754,7 @@ extern "C" strcpy (desc->name, "firewire"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->desc, "Linux FFADO API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - desc->nparams = 12; + desc->nparams = 13; params = (jack_driver_param_desc_t *)calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); desc->params = params; @@ -854,6 +855,14 @@ extern "C" strcpy (params[i].short_desc, "libffado verbose level"); strcpy (params[i].long_desc, params[i].short_desc); + i++; + strcpy (params[i].name, "snoop"); + params[i].character = 'X'; + params[i].type = JackDriverParamBool; + params[i].value.i = 0; + strcpy (params[i].short_desc, "Snoop firewire traffic"); + strcpy (params[i].long_desc, params[i].short_desc); + return desc; } @@ -863,7 +872,7 @@ extern "C" ffado_jack_settings_t cmlparams; - char *device_name="hw:0"; + char *device_name=(char*)"hw:0"; cmlparams.period_size_set = 0; cmlparams.sample_rate_set = 0; @@ -919,7 +928,7 @@ extern "C" cmlparams.slave_mode = param->value.ui; break; case 'X': - cmlparams.snoop_mode = param->value.ui; + cmlparams.snoop_mode = param->value.i; break; case 'v': cmlparams.verbose_level = param->value.ui; diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 406fddbe..a1403df3 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -194,6 +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(); } @@ -221,33 +237,6 @@ int JackCoreAudioDriver::Write() return 0; } -// Will run only once -OSStatus JackCoreAudioDriver::MeasureCallback(AudioDeviceID inDevice, - const AudioTimeStamp* inNow, - const AudioBufferList* inInputData, - const AudioTimeStamp* inInputTime, - AudioBufferList* outOutputData, - const AudioTimeStamp* inOutputTime, - void* inClientData) -{ - JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData; - AudioDeviceStop(driver->fDeviceID, MeasureCallback); - - jack_log("JackCoreAudioDriver::MeasureCallback called"); - JackMachThread::GetParams(pthread_self(), &driver->fEngineControl->fPeriod, &driver->fEngineControl->fComputation, &driver->fEngineControl->fConstraint); - - if (driver->fComputationGrain > 0) { - jack_log("JackCoreAudioDriver::MeasureCallback : 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; - - // Setup threadded based log function - set_threaded_log_function(); - return noErr; -} OSStatus JackCoreAudioDriver::SRNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, @@ -1682,27 +1671,10 @@ int JackCoreAudioDriver::Start() { jack_log("JackCoreAudioDriver::Start"); JackAudioDriver::Start(); -/* -#ifdef MAC_OS_X_VERSION_10_5 - OSStatus err = AudioDeviceCreateIOProcID(fDeviceID, MeasureCallback, this, &fMesureCallbackID); -#else - OSStatus err = AudioDeviceAddIOProc(fDeviceID, MeasureCallback, this); -#endif -*/ - OSStatus err = AudioDeviceAddIOProc(fDeviceID, MeasureCallback, this); - - if (err != noErr) - return -1; - err = AudioOutputUnitStart(fAUHAL); + OSStatus err = AudioOutputUnitStart(fAUHAL); if (err != noErr) return -1; - - if ((err = AudioDeviceStart(fDeviceID, MeasureCallback)) != noErr) { - jack_error("Cannot start MeasureCallback"); - printError(err); - return -1; - } // Waiting for Measure callback to be called (= driver has started) fState = false; @@ -1724,15 +1696,6 @@ int JackCoreAudioDriver::Start() int JackCoreAudioDriver::Stop() { jack_log("JackCoreAudioDriver::Stop"); - AudioDeviceStop(fDeviceID, MeasureCallback); -/* -#ifdef MAC_OS_X_VERSION_10_5 - AudioDeviceDestroyIOProcID(fDeviceID, fMesureCallbackID); -#else - AudioDeviceRemoveIOProc(fDeviceID, MeasureCallback); -#endif -*/ - AudioDeviceRemoveIOProc(fDeviceID, MeasureCallback); return (AudioOutputUnitStop(fAUHAL) == noErr) ? 0 : -1; } diff --git a/macosx/coreaudio/JackCoreAudioDriver.h b/macosx/coreaudio/JackCoreAudioDriver.h index f17bbf19..9f827dfc 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.h +++ b/macosx/coreaudio/JackCoreAudioDriver.h @@ -96,14 +96,6 @@ class JackCoreAudioDriver : public JackAudioDriver UInt32 inNumberFrames, AudioBufferList *ioData); - static OSStatus MeasureCallback(AudioDeviceID inDevice, - const AudioTimeStamp* inNow, - const AudioBufferList* inInputData, - const AudioTimeStamp* inInputTime, - AudioBufferList* outOutputData, - const AudioTimeStamp* inOutputTime, - void* inClientData); - static OSStatus DeviceNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, diff --git a/macosx/libcelt.a b/macosx/libcelt.a new file mode 100644 index 0000000000000000000000000000000000000000..d64e6b88ea8f00cc323c8cd3c5a921ceda9ca70f GIT binary patch literal 1026340 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�md|0BM2`72D2=FIOE9yaEs5L5W+0eCf(vQHL_xKu<^h04R}XiEZV0)tOGum%Y=llem3Y=KTBm@ByiizJsoW*Hdz z_?p6#{3H=S`F_Mbgn-7m1>o-zwH;5v zU#Lu*M4%LHX`rYT6tQm*z9jHT^@P-nT&;Q{)XOQJP-(FOou0WUEgnK8;H+f&I_kEr zTn`mA6}q>sJmTov8nCJZ#FfN0x5T!9L@XrkLsC>Jt)nndTbZk(lboF2T=|p|Mb2-! z^}ZR<>nitlw}dkotWye6UCDNS#BGmL!`~3#@s9w05$NPt9QZ}qZ8 z2q-hK>J1>$7-!mKW?k`Ejs3nkZY=wya7g_LM;N`?v1}-^gs??;Qs9&736&YnAVAGZ zID}9MID-JQ9gl#zz6ap6MDN3W^4}q#H++Rcw1gQz+W;g9bP_jMOcUrdf|&xHOpq

fqzt)B1zf>2B(4)5mh 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 bykPEuZ&!RTq=Msh} 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 ${i%%0}1 +done diff --git a/man/jack_bufsize.0 b/man/jack_bufsize.0 new file mode 100644 index 00000000..f9d0dd61 --- /dev/null +++ b/man/jack_bufsize.0 @@ -0,0 +1,14 @@ +.TH JACK_BUFSIZE "1" "!DATE!" "!VERSION!" +.SH NAME +jack_bufsize \- JACK toolkit client to change the JACK buffer size +.SH SYNOPSIS +.B jack_bufsize bufsize +.SH DESCRIPTION +.B jack_bufsize +jack_bufsize sets the size of the buffer (frames per period) used in JACK. +This change happens on-line (the JACK server and its clients do not need to be +restarted). +.br +When invoked without arguments, it prints the current bufsize, and exits. + + diff --git a/man/jack_connect.0 b/man/jack_connect.0 new file mode 100644 index 00000000..602ac39b --- /dev/null +++ b/man/jack_connect.0 @@ -0,0 +1,11 @@ +.TH JACK_CONNECT "1" "!DATE!" "!VERSION!" +.SH NAME +\fBjack_connect\fR, \fBjack_disconnect\fR \- JACK toolkit clients for connecting & disconnecting ports +.SH SYNOPSIS +\fB jack_connect\fR [ \fI-s\fR | \fI--server servername\fR ] [\fI-h\fR | \fI--help\fR ] port1 port2 +\fB jack_disconnect\fR [ \fI-s\fR | \fI--server servername\fR ] [\fI-h\fR | \fI--help\fR ] port1 port2 +.SH DESCRIPTION +\fBjack_connect\fR connects the two named ports. \fBjack_connect\fR disconnects the two named ports. +.SH RETURNS +The exit status is zero if successful, 1 otherwise + diff --git a/man/jack_disconnect.0 b/man/jack_disconnect.0 new file mode 100644 index 00000000..90300cc1 --- /dev/null +++ b/man/jack_disconnect.0 @@ -0,0 +1 @@ +.so man1/jack_connect.1 diff --git a/man/jack_freewheel.0 b/man/jack_freewheel.0 new file mode 100644 index 00000000..0941ffd7 --- /dev/null +++ b/man/jack_freewheel.0 @@ -0,0 +1,16 @@ +.TH JACK_FREEWHEEL "1" "!DATE!" "!VERSION!" +.SH NAME +jack_freewheel \- JACK toolkit client to control freewheeling mode +.SH SYNOPSIS +.B jack_freewheel [y|n] +.SH DESCRIPTION +.B jack_freewheel +Turns freewheeling mode on (y) or off (n). While in freewheeling mode, +the JACK server does not wait in between process() calls, and does not +read or write data from/to any audio interface. That results in the JACK graph +processing data as fast as possible. Freewheeling makes fast exports to +files possible. +.PP +There is no useful reason to use this tool other than testing. JACK +clients that use freewheeling will turn it on and off themselves. + diff --git a/man/jack_impulse_grabber.0 b/man/jack_impulse_grabber.0 new file mode 100644 index 00000000..544716b4 --- /dev/null +++ b/man/jack_impulse_grabber.0 @@ -0,0 +1,11 @@ +.TH JACK_IMPULSE_GRABBER "1" "!DATE!" "!VERSION!" +.SH NAME +jack_impulse_grabber \- JACK toolkit client to grab an impulse (response) +.SH SYNOPSIS +\fBjack_impulse_grabber\fR \fB-d\fR \fIduration\fR [\fI-f\fR (C|gnuplot)] +.SH DESCRIPTION +\fBjack_impulse_grabber\fR is a JACK example client for collecting +impulses recordings from JACK ports. + + + diff --git a/man/jack_load.0 b/man/jack_load.0 new file mode 100644 index 00000000..599116e0 --- /dev/null +++ b/man/jack_load.0 @@ -0,0 +1,28 @@ +.TH JACK_LOAD "1" "!DATE!" "!VERSION!" +.SH NAME +jack_load \- JACK toolkit client for loading in-process clients +.SH SYNOPSIS +\fBjack_load\fR [ \fI-i\fR initstring ] [ \fI-s\fR servername ] [\fI-w\fR ] client-name so-name [ initstring ] +.SH DESCRIPTION +\fBjack_load\fR is a JACK toolkit client. It loads the specified plugin and creates an in-process client. +.SH ARGUMENTS +.PP +The client-name must be a currently unused client name. +.PP +The so-name is the name of file that client code is stored in (typically, \fIclientname.so\fR) +.SH OPTIONS +.TP +\fB-i\fR, \fB--init\fR init-string +.br +initialization string passed to the in-process client. Note that this can also be specified as the last argument on the command line. +.TP +\fB-s\fR, \fB--server\fR servername +.br +Name of JACK server to connect to +.TP +\fB-w\fR, \fB--wait\fR +Wait for a signal (eg. from Ctrl-c) and then unload the client. +.SH AUTHOR +Jeremy Hall + + diff --git a/man/jack_lsp.0 b/man/jack_lsp.0 new file mode 100644 index 00000000..a54ba5eb --- /dev/null +++ b/man/jack_lsp.0 @@ -0,0 +1,47 @@ +.TH JACK_LSP "1" "!DATE!" "!VERSION!" +.SH NAME +jack_lsp \- JACK toolkit client to list informtion on ports +.SH SYNOPSIS +\fBjack_lsp\fR [ \fI-s\fR | \fI--server\fR servername ] [ \fI-AclLptvh\fR ] +.SH DESCRIPTION +\fBjack_lsp\fR lists all known ports associated with a JACK +server. It can also optionally list various kinds of information about each port. +.SH OPTIONS +.TP +\fB-s\fR, \fB--server\fR \fIservername\fR +.br +Connect to the jack server named \fIservername\fR +.TP +\fB-A\fR, \fB--aliases\fR +.br +List aliases for each port +.TP +\fB-c\fR, \fB--connections\fR +.br +List connections to/from each port +.TP +\fB-l\fR, \fB--latency\fR +.br +Display per-port latency in frames at each port +.TP +\fB-L\fR, \fI--latency\fR +.br +Display total latency in frames at each port +.TP +\fB-p\fR, \fB--properties\fR +.br +Display port properties. Output may include input|output, can-monitor, physical, terminal +.TP +\fB-t\fR, \fB--type\fR +.br +Display port type +.TP +\fB-h\fR, \fB--help\fR +.br +Display help/usage message +.TP +\fB-v\fR, \fB--version\fR +.br +Output version information and exit + + diff --git a/man/jack_metro.0 b/man/jack_metro.0 new file mode 100644 index 00000000..e38a9542 --- /dev/null +++ b/man/jack_metro.0 @@ -0,0 +1,40 @@ +.TH JACK_METRO "1" "!DATE!" "!VERSION!" +.SH NAME +jack_metro \- JACK toolkit metronome +.SH SYNOPSIS +\fBjack_metro\fR [ \fI-n\fR name ] [ \fI-f\fR hz ] [ \fI-D\fR msecs ] [\fI-a\fR % ] [ \fI-d\fR % ] \fI-b\fR bpm +.SH DESCRIPTION +\fBjack_metro\fR is a simple metronome for JACK. It generates a +synthetic "tick" sound for every beat. Note that is does \fBnot\fR +connect its output port by default - to hear the sound it makes you must +connect them using some other tool. +.SH OPTIONS +.TP +\fB-n\fR, \fB--name\fR +.br +Specify a name for this instance of the metronome. +.TP +\fB-f\fR, \fB--frequency\fR Hz +.br +Define the frequency of the "tick" in Hz. +.TP +\fB-D\fR, \fB--duration\fR msecs +.br +Define the duration of the "tick" in milliseconds. +.TP +\fB-a\fR, \fB--attack\fR %-age +.br +Define the duration of the attack phase of the "tick" as a percentage +of the duration. +.TP +\fB-d\fR, \fB--decay\fR %-age +.br +Define the duration of the decay phase of the "tick" as a percentage +of the duration. +.TP +\fB--b\fR, \fB--bpm\fR bpm +.br +Define the number of beats per minute. +.SH AUTHOR +Anthony Van Groningen + diff --git a/man/jack_monitor_client.0 b/man/jack_monitor_client.0 new file mode 100644 index 00000000..09911070 --- /dev/null +++ b/man/jack_monitor_client.0 @@ -0,0 +1,18 @@ +.TH JACK_CONNECT "1" "!DATE!" "!VERSION!" +.SH NAME +jack_monitor_client \- The JACK Audio Connection Kit example client +.SH SYNOPSIS +.B jack_monitor_client +client-name +.PP +The client-name must be the name of a existing client that monitoring is +to be enabled for. +.SH DESCRIPTION +.B jack_monitor_client +is an example client for the JACK Audio Connection Kit. It enables +monitoring for the specified client. +.SH AUTHOR +Jeremy Hall +.PP +This manpage was written by Robert Jordens for Debian. + diff --git a/man/jack_netsource.0 b/man/jack_netsource.0 new file mode 100644 index 00000000..5de4af7f --- /dev/null +++ b/man/jack_netsource.0 @@ -0,0 +1,109 @@ +.TH JACK_NETSOURCE "1" "!DATE!" "!VERSION!" +.SH NAME +jack_netsource \- Netjack Master client for one slave +.SH SYNOPSIS +\fBjack_netsource\fR [ \fI-H\fR hostname ] [ \fIoptions\fR ] + +.SH DESCRIPTION +\fBjack_netsource\fR The Master side of a netjack connection. Represents the slave jackd -dnet in the master jack graph. +Most connection parameters are configured via the netsource, and the slave will set itself up according to the commandline +option given to jack_netsource. +.br +Netjack allows low latency audio connections over general IP networks. When using celt for compression, it is even possible +to establish transatlantic links, with latencies not much over the actual ping time. +.br +But the main usecase is of course a LAN, where it can achieve one jack period of latency. + +.SH OPTIONS +.TP +\fB-h\fR this help text +.TP +\fB-H\fR \fIslave host\fR +.br +Host name of the slave JACK +.TP +\fB-o\fR \fInum channels\fR +.br +Number of audio playback channels +.TP +\fB-i\fR \fInum channels\fR +.br +Number of audio capture channels +.TP +\fB-O\fR \fInum channels\fR +.br +Number of midi playback channels +.TP +\fB-I\fR \fInum channels\fR +.br +Number of midi capture channels +.TP +\fB-n\fR \fIperiods\fR +.br +Network latency in JACK periods +.TP +\fB-p\fR \fIport\fR +.br +UDP port that the slave is listening on +.TP +\fB-r\fR \fIreply port\fR +.br +UDP port that we are listening on +.TP +\fB-B\fR \fIbind port\fR +.br +reply port, for use in NAT environments +.TP +\fB-b\fR \fIbitdepth\fR +.br +Set transport to use 16bit or 8bit +.TP +\fB-c\fR \fIbytes\fR +.br +Use CELT encoding with per period and channel +.TP +\fB-m\fR \fImtu\fR +.br +Assume this mtu for the link +.TP +\fB-R\fR \fIN\fR +.br +Redundancy: send out packets N times. +.TP +\fB-e\fR +.br +skip host-to-network endianness conversion +.TP +\fB-N\fR \fIjack name\fR +.br +Reports a different client name to jack +.TP +.TP +\fB-s\fR, \fB--server\fR \fIservername\fR +.br +Connect to the jack server named \fIservername\fR +.TP +\fB-h\fR, \fB--help\fR +.br +Display help/usage message +.TP +\fB-v\fR, \fB--version\fR +.br +Output version information and exit + + +.SH EXAMPLES + +.PP +run a 4 audio channel bidirectional link with one period of latency and no midi channels. Audio data is flowing uncompressed over the wire: +.br +On \fIhostA\fR: +.IP +\fBjackd \-d alsa \fR +.br +\fBjack_netsource \-H hostB -n1 -i4 -o4 -I0 -O0 \fR +.PP +On \fIhostB\fR: +.IP +\fBjackd \-d net \fR + diff --git a/man/jack_samplerate.0 b/man/jack_samplerate.0 new file mode 100644 index 00000000..ef11ed06 --- /dev/null +++ b/man/jack_samplerate.0 @@ -0,0 +1,9 @@ +.TH JACK_SAMPLERATE "1" "!DATE!" "!VERSION!" +.SH NAME +jack_samplerate \- JACK toolkit client to print current samplerate +.SH SYNOPSIS +.B jack_samplerate +.SH DESCRIPTION +.B jack_samplerate prints the current samplerate, and exits. + + diff --git a/man/jack_showtime.0 b/man/jack_showtime.0 new file mode 100644 index 00000000..210caa7d --- /dev/null +++ b/man/jack_showtime.0 @@ -0,0 +1,13 @@ +.TH JACK_SHOWTIME "1" "!DATE!" "!VERSION!" +.SH NAME +jack_showtime \- The JACK Audio Connection Kit example client +.SH SYNOPSIS +.B jack_showtime +.SH DESCRIPTION +.B jack_showtime +prints the current timebase information to stdout +.SH AUTHOR +Paul Davis +.PP +This manpage was written by Stefan Schwandter + diff --git a/man/jack_simple_client.0 b/man/jack_simple_client.0 new file mode 100644 index 00000000..a3cf16e0 --- /dev/null +++ b/man/jack_simple_client.0 @@ -0,0 +1,20 @@ +.TH JACK_CONNECT "1" "!DATE!" "!VERSION!" +.SH NAME +jack_simple_client \- The JACK Audio Connection Kit example client +.SH SYNOPSYS +.B jack_simple_client +client-name +.PP +The client-name must be a yet unused client name. +.SH DESCRIPTION +.B jack_simple_client +is an example client for the JACK Audio Connection Kit. It creates two +ports (client-name:input and client-name:output) that pass the data +unmodified. +.SH EXAMPLE +jack_simple_client in_process_test +.SH AUTHOR +Jeremy Hall +.PP +This manpage was written by Robert Jordens for Debian. + diff --git a/man/jack_transport.0 b/man/jack_transport.0 new file mode 100644 index 00000000..6aa8ddd7 --- /dev/null +++ b/man/jack_transport.0 @@ -0,0 +1,13 @@ +.TH JACK_TRANSPORT "1" "!DATE!" "!VERSION!" +.SH NAME +jack_transport \- JACK toolkit client for transport control +.SH SYNOPSIS +.B jack_transport +.SH DESCRIPTION +.B jack_transport +is a toolkit client for the JACK Audio Connection Kit. It provides command-line +control over the JACK transport system. Type help at jack_transport's +command prompt to see the available commands. +.SH AUTHOR +Jeremy Hall + diff --git a/man/jack_unload.0 b/man/jack_unload.0 new file mode 100644 index 00000000..79b1e33d --- /dev/null +++ b/man/jack_unload.0 @@ -0,0 +1,19 @@ +.TH JACK_UNLOAD "1" "!DATE!" "!VERSION!" +.SH NAME +jack_unload \- The JACK Audio Connection Kit example client +.SH SYNOPSIS +.B jack_unload +client-name +.PP +The client-name must be the name of a loaded client that can be unloaded. +.SH DESCRIPTION +.B jack_unload +is the counterpart to +.B jack_load +and unloads the specified client. +.SH EXAMPLE +.B jack_unload in_process_test +.SH AUTHOR +Jeremy Hall +.PP +This manpage was written by Robert Jordens for Debian. diff --git a/man/jack_wait.0 b/man/jack_wait.0 new file mode 100644 index 00000000..239e8c22 --- /dev/null +++ b/man/jack_wait.0 @@ -0,0 +1,41 @@ +.TH JACK_WAIT "1" "!DATE!" "!VERSION!" +.SH NAME +jack_wait \- JACK toolkit client to check and wait for existence/exit of jackd. +.SH SYNOPSIS +\fBjack_wait\fR [ \fI-s\fR | \fI--server\fR servername ] [ \fI-t\fR | \fI--timeout\fR timeout_seconds [ \fI-cqwhv\fR ] +.SH DESCRIPTION +\fBjack_wait\fR When invoked with \fI-c\fR it only checks for the existence of a jack server. When invoked with \fI-w\fR the +program will wait for a jackd to be available. +The \fI-q\fR makes it wait for the jackd to exit. + +.SH OPTIONS +.TP +\fB-w\fR, \fB--wait\fR +.br +Wait for jackd to be available. +.TP +\fB-q\fR, \fB--quit\fR +.br +Wait for jackd quit. +.TP +\fB-c\fR, \fB--check\fR +.br +Only check for existence of jackd, and exit. +.TP +\fB-s\fR, \fB--server\fR \fIservername\fR +.br +Connect to the jack server named \fIservername\fR +.TP +\fB-t\fR, \fB--timeout\fR \fItimeout_seconds\fR +.br +Only wait \fItimeout_seconds\fR. +.TP +\fB-h\fR, \fB--help\fR +.br +Display help/usage message +.TP +\fB-v\fR, \fB--version\fR +.br +Output version information and exit + + diff --git a/man/jackd.0 b/man/jackd.0 new file mode 100644 index 00000000..5700aabe --- /dev/null +++ b/man/jackd.0 @@ -0,0 +1,547 @@ +.TH "JACKD" "1" "!VERSION!" "!DATE!" "" +.SH "NAME" +jackd \- JACK Audio Connection Kit sound server +.SH "SYNOPSIS" +\fBjackd\fR [\fIoptions\fR] \fB\-d\fI backend \fR +[\fIbackend\-parameters\fR] +.br +\fBjackd \-\-help\fR +.SH "DESCRIPTION" +\fBjackd\fR is the JACK audio server daemon, a low\-latency audio +server. Originally written for the +GNU/Linux operating system, it also supports Mac OS X and various Unix +platforms. JACK can connect a number of different client applications +to an audio device and also to each other. Most clients are external, +running in their own processes as normal applications. JACK also +supports internal clients, which run within the \fBjackd\fR process +using a loadable "plugin" interface. + +JACK differs from other audio servers in being designed from the +ground up for professional audio work. It focuses on two key areas: +synchronous execution of all clients, and low latency operation. + +For the latest JACK information, please consult the web site, +<\fBhttp://www.jackaudio.org\fR>. +.SH "OPTIONS" +.TP +\fB\-d, \-\-driver \fIbackend\fR [\fIbackend\-parameters\fR ] +.br +Select the audio interface backend. The current list of supported +backends is: \fBalsa\fR, \fBcoreaudio\fR, \fBdummy\fR, \fBfreebob\fR, +\fBoss\fR \fBsun\fR and \fBportaudio\fR. They are not all available +on all platforms. All \fIbackend\-parameters\fR are optional. + +.TP +\fB\-h, \-\-help\fR +.br +Print a brief usage message describing the main \fBjackd\fR options. +These do not include \fIbackend\-parameters\fR, which are listed using +the \fB\-\-help\fR option for each specific backend. Examples below +show how to list them. +.TP +\fB\-m, \-\-no\-mlock\fR +Do not attempt to lock memory, even if \fB\-\-realtime\fR. +.TP +\fB\-n, \-\-name\fR \fIserver\-name\fR +Name this \fBjackd\fR instance \fIserver\-name\fR. If unspecified, +this name comes from the \fB$JACK_DEFAULT_SERVER\fR environment +variable. It will be "default" if that is not defined. +.TP +\fB\-p, \-\-port\-max \fI n\fR +Set the maximum number of ports the JACK server can manage. +The default value is 256. +.TP +\fB\-\-replace-registry\fR +.br +Remove the shared memory registry used by all JACK server instances +before startup. This should rarely be used, and is intended only +for occasions when the structure of this registry changes in ways +that are incompatible across JACK versions (which is rare). +.TP +\fB\-R, \-\-realtime\fR +.br +Use realtime scheduling (default = true). This is needed for reliable low\-latency +performance. On many systems, it requires \fBjackd\fR to run with +special scheduler and memory allocation privileges, which may be +obtained in several ways. +.TP +\fB\-r, \-\-no-realtime\fR +.br +Do not use realtime scheduling. +.TP +\fB\-P, \-\-realtime\-priority \fIint\fR +When running \fB\-\-realtime\fR, set the scheduler priority to +\fIint\fR. +.TP +\fB\-\-silent\fR +Silence any output during operation. +.TP +\fB\-T, \-\-temporary\fR +Exit once all clients have closed their connections. +.TP +\fB\-t, \-\-timeout \fIint\fR +.br +Set client timeout limit in milliseconds. The default is 500 msec. +In realtime mode the client timeout must be smaller than the watchdog timeout (5000 msec). +.TP +\fB\-Z, \-\-nozombies\fR +.br +Prevent JACK from ever kicking out clients because they were too slow. +This cancels the effect any specified timeout value, but JACK and its clients are +still subject to the supervision of the watchdog thread or its equivalent. +.TP +\fB\-u, \-\-unlock\fR +.br +Unlock libraries GTK+, QT, FLTK, Wine. +.TP +\fB\-v, \-\-verbose\fR +Give verbose output. +.TP +\fB\-c, \-\-clocksource\fR (\fI c(ycle)\fR | \fI h(pet) \fR | \fI s(ystem) \fR) +Select a specific wall clock (Cycle Counter, HPET timer, System timer). +.TP +\fB\-V, \-\-version\fR +Print the current JACK version number and exit. +.SS ALSA BACKEND OPTIONS +.TP +\fB\-C, \-\-capture\fR [ \fIname\fR ] +Provide only capture ports, unless combined with \-D or \-P. Parameterally set +capture device name. +.TP +\fB\-d, \-\-device \fIname\fR +.br +The ALSA pcm device \fIname\fR to use. If none is specified, JACK will +use "hw:0", the first hardware card defined in \fB/etc/modules.conf\fR. +.TP +\fB\-z, \-\-dither [rectangular,triangular,shaped,none] +Set dithering mode. If \fBnone\fR or unspecified, dithering is off. +Only the first letter of the mode name is required. +.TP +\fB\-D, \-\-duplex\fR +Provide both capture and playback ports. Defaults to on unless only one +of \-P or \-C is specified. +.TP +\fB\-h, \-\-help\fR Print a brief usage message describing only the +\fBalsa\fR backend parameters. +.TP +\fB\-M, \-\-hwmeter\fR +.br +Enable hardware metering for devices that support it. Otherwise, use +software metering. +.TP +\fB\-H, \-\-hwmon\fR +.br +Enable hardware monitoring of capture ports. This is a method for +obtaining "zero latency" monitoring of audio input. It requires +support in hardware and from the underlying ALSA device driver. + +When enabled, requests to monitor capture ports will be satisfied by +creating a direct signal path between audio interface input and output +connectors, with no processing by the host computer at all. This +offers the lowest possible latency for the monitored signal. + +Presently (March 2003), only the RME Hammerfall series and cards based +on the ICE1712 chipset (M\-Audio Delta series, Terratec, and others) +support \fB\-\-hwmon\fR. In the future, some consumer cards may also +be supported by modifying their mixer settings. + +Without \fB\-\-hwmon\fR, port monitoring requires JACK to read audio +into system memory, then copy it back out to the hardware again, +imposing the basic JACK system latency determined by the +\fB\-\-period\fR and \fB\-\-nperiods\fR parameters. +.TP +\fB\-i, \-\-inchannels \fIint\fR +.br +Number of capture channels. Default is maximum supported by hardware. +.TP +\fB\-n, \-\-nperiods \fIint\fR +.br +Specify the number of periods of playback latency. In seconds, this +corresponds to \fB\-\-nperiods\fR times \fB\-\-period\fR divided by +\fB\-\-rate\fR. The default is 2, the minimum allowable. For most +devices, there is no need for any other value with the +\fB\-\-realtime\fR option. Without realtime privileges or with boards +providing unreliable interrupts (like ymfpci), a larger value may +yield fewer xruns. This can also help if the system is not tuned for +reliable realtime scheduling. + +For most ALSA devices, the hardware buffer has exactly +\fB\-\-period\fR times \fB\-\-nperiods\fR frames. Some devices demand +a larger buffer. If so, JACK will use the smallest possible buffer +containing at least \fB\-\-nperiods\fR, but the playback latency does +not increase. + +For USB audio devices it is recommended to use \fB\-n 3\fR. Firewire +devices supported by FFADO (formerly Freebob) are configured with +\fB\-n 3\fR by default. +.TP +\fB\-o, \-\-outchannels \fIint\fR +.br +Number of playback channels. Default is maximum supported by hardware. +.TP +\fB\-P, \-\-playback\fR [ \fIname\fR ] +Provide only playback ports, unless combined with \-D or \-C. Optionally set +playback device name. +.TP +\fB\-p, \-\-period \fIint\fR +.br +Specify the number of frames between JACK \fBprocess()\fR calls. This +value must be a power of 2, and the default is 1024. If you need low +latency, set \fB\-p\fR as low as you can go without seeing xruns. A larger +period size yields higher latency, but makes xruns less likely. The JACK +capture latency in seconds is \fB\-\-period\fR divided by \fB\-\-rate\fR. +.TP +\fB\-r, \-\-rate \fIint\fR +Specify the sample rate. The default is 48000. +.TP +\fB\-S, \-\-shorts +.br +Try to configure card for 16\-bit samples first, only trying 32\-bits if +unsuccessful. Default is to prefer 32\-bit samples. +.TP +\fB\-s, \-\-softmode\fR +.br +Ignore xruns reported by the ALSA driver. This makes JACK less likely +to disconnect unresponsive ports when running without \fB\-\-realtime\fR. +.TP +\fB\-X, \-\-midi \fR[\fIseq\fR|\fIraw\fR] +.br +Specify which ALSA MIDI system to provide access to. Using \fBraw\fR +will provide a set of JACK MIDI ports that correspond to each raw ALSA +device on the machine. Using \fBseq\fR will provide a set of JACK MIDI +ports that correspond to each ALSA "sequencer" client (which includes +each hardware MIDI port on the machine). \fBraw\fR provides slightly +better performance but does not permit JACK MIDI communication with +software written to use the ALSA "sequencer" API. +.SS COREAUDIO BACKEND PARAMETERS +.TP +\fB\-c \-\-channel\fR +Maximum number of channels (default: 2) +.TP +\fB\-i \-\-channelin\fR +Maximum number of input channels (default: 2) +.TP +\fB\-o \-\-channelout\fR +Maximum number of output channels (default: 2) +.TP +\fB\-C \-\-capture\fR +Whether or not to capture (default: true) +.TP +\fB\-P \-\-playback\fR +Whether or not to playback (default: true) +.TP +\fB\-D \-\-duplex\fR +Capture and playback (default: true) +.TP +\fB\-r \-\-rate\fR +Sample rate (default: 44100) +.TP +\fB\-p \-\-period\fR +Frames per period (default: 128). Must be a power of 2. +.TP +\fB\-n \-\-name\fR +Driver name (default: none) +.TP +\fB\-I \-\-id\fR +Audio Device ID (default: 0) +.SS DUMMY BACKEND PARAMETERS +.TP +\fB\-C, \-\-capture \fIint\fR +Specify number of capture ports. The default value is 2. +.TP +\fB\-P, \-\-playback \fIint\fR +Specify number of playback ports. The default value is 2. +.TP +\fB\-r, \-\-rate \fIint\fR +Specify sample rate. The default value is 48000. +.TP +\fB\-p, \-\-period \fIint\fR +Specify the number of frames between JACK \fBprocess()\fR calls. This +value must be a power of 2, and the default is 1024. If you need low +latency, set \fB\-p\fR as low as you can go without seeing xruns. A larger +period size yields higher latency, but makes xruns less likely. The JACK +capture latency in seconds is \fB\-\-period\fR divided by \fB\-\-rate\fR. +.TP +\fB\-w, \-\-wait \fIint\fR +Specify number of usecs to wait between engine processes. +The default value is 21333. + + +.SS NET BACKEND PARAMETERS + +.TP + \fB\-i, \-\-audio\-ins \fIint\fR +Number of capture channels (default: 2) +.TP + \fB\-o, \-\-audio\-outs \fIint\fR +Number of playback channels (default: 2) +.TP + \fB\-I, \-\-midi\-ins \fIint\fR +Number of midi capture channels (default: 1) +.TP +\fB\-O, \-\-midi\-outs \fIint\fR +Number of midi playback channels (default: 1) +.TP + \fB\-r, \-\-rate \fIint\fR +Sample rate (default: 48000) +.TP +\fB\-p, \-\-period \fIint\fR +Frames per period (default: 1024) +.TP +\fB\-n, \-\-num\-periods \fIint\fR +Network latency setting in no. of periods (default: 5) +.TP +\fB\-l, \-\-listen\-port \fIint\fR +The socket port we are listening on for sync packets (default: 3000) +.TP +\fB\-f, \-\-factor \fIint\fR +Factor for sample rate reduction (default: 1) +.TP +\fB\-u, \-\-upstream\-factor \fIint\fR +Factor for sample rate reduction on the upstream (default: 0) +.TP +\fB\-c, \-\-celt \fIint\fR +sets celt encoding and number of kbits per channel (default: 0) +.TP +\fB\-b, \-\-bit\-depth \fIint\fR +Sample bit\-depth (0 for float, 8 for 8bit and 16 for 16bit) (default: 0) +.TP +\fB\-t, \-\-transport\-sync \fIint\fR +Whether to slave the transport to the master transport (default: true) +.TP +\fB\-a, \-\-autoconf \fIint\fR +Whether to use Autoconfig, or just start. (default: true) +.TP +\fB\-R, \-\-redundancy \fIint\fR +Send packets N times (default: 1) +.TP +\fB\-e, \-\-native\-endian \fIint\fR +Dont convert samples to network byte order. (default: false) +.TP +\fB\-J, \-\-jitterval \fIint\fR +attempted jitterbuffer microseconds on master (default: 0) +.TP +\fB\-D, \-\-always\-deadline \fIint\fR +always use deadline (default: false) + + +.SS OSS BACKEND PARAMETERS +.TP +\fB\-r, \-\-rate \fIint\fR +Specify the sample rate. The default is 48000. +.TP +\fB\-p, \-\-period \fIint\fR +Specify the number of frames between JACK \fBprocess()\fR calls. This +value must be a power of 2, and the default is 1024. If you need low +latency, set \fB\-p\fR as low as you can go without seeing xruns. A larger +period size yields higher latency, but makes xruns less likely. The JACK +capture latency in seconds is \fB\-\-period\fR divided by \fB\-\-rate\fR. +.TP +\fB\-n, \-\-nperiods \fIint\fR +Specify the number of periods in the hardware buffer. The default is +2. The period size (\fB\-p\fR) times \fB\-\-nperiods\fR times four is +the JACK buffer size in bytes. The JACK output latency in seconds is +\fB\-\-nperiods\fR times \fB\-\-period\fR divided by \fB\-\-rate\fR. +.TP +\fB\-w, \-\-wordlength \fIint\fR +Specify the sample size in bits. The default is 16. +.TP +\fB\-i, \-\-inchannels \fIint\fR +Specify how many channels to capture (default: 2) +.TP +\fB\-o, \-\-outchannels \fIint\fR +Specify number of playback channels (default: 2) +.TP +\fB\-C, \-\-capture \fIdevice_file\fR +Specify input device for capture (default: /dev/dsp) +.TP +\fB\-P, \-\-playback \fIdevice_file\fR +Specify output device for playback (default: /dev/dsp) +.TP +\fB\-b, \-\-ignorehwbuf \fIboolean\fR +Specify, whether to ignore hardware period size (default: false) +.SS SUN BACKEND PARAMETERS +.TP +\fB\-r, \-\-rate \fIint\fR +Specify the sample rate. The default is 48000. +.TP +\fB\-p, \-\-period \fIint\fR +Specify the number of frames between JACK \fBprocess()\fR calls. This +value must be a power of 2, and the default is 1024. If you need low +latency, set \fB\-p\fR as low as you can go without seeing xruns. A larger +period size yields higher latency, but makes xruns less likely. The JACK +capture latency in seconds is \fB\-\-period\fR divided by \fB\-\-rate\fR. +.TP +\fB\-n, \-\-nperiods \fIint\fR +Specify the number of periods in the hardware buffer. The default is +2. The period size (\fB\-p\fR) times \fB\-\-nperiods\fR times four +(assuming 2 channels 16-bit samples) is the JACK buffer size in bytes. +The JACK output latency in seconds is \fB\-\-nperiods\fR times +\fB\-\-period\fR divided by \fB\-\-rate\fR. +.TP +\fB\-w, \-\-wordlength \fIint\fR +Specify the sample size in bits. The default is 16. +.TP +\fB\-i, \-\-inchannels \fIint\fR +Specify how many channels to capture (default: 2) +.TP +\fB\-o, \-\-outchannels \fIint\fR +Specify number of playback channels (default: 2) +.TP +\fB\-C, \-\-capture \fIdevice_file\fR +Specify input device for capture (default: /dev/audio) +.TP +\fB\-P, \-\-playback \fIdevice_file\fR +Specify output device for playback (default: /dev/audio) +.TP +\fB\-b, \-\-ignorehwbuf \fIboolean\fR +Specify, whether to ignore hardware period size (default: false) +.SS PORTAUDIO BACKEND PARAMETERS +.TP +\fB\-c \-\-channel\fR +Maximum number of channels (default: all available hardware channels) +.TP +\fB\-i \-\-channelin\fR +Maximum number of input channels (default: all available hardware channels) +.TP +\fB\-o \-\-channelout\fR +Maximum number of output channels (default: all available hardware channels) +.TP +\fB\-C \-\-capture\fR +Whether or not to capture (default: true) +.TP +\fB\-P \-\-playback\fR +Whether or not to playback (default: true) +.TP +\fB\-D \-\-duplex\fR +Capture and playback (default: true) +.TP +\fB\-r \-\-rate\fR +Sample rate (default: 48000) +.TP +\fB\-p \-\-period\fR +Frames per period (default: 1024). Must be a power of 2. +.TP +\fB\-n \-\-name\fR +Driver name (default: none) +.TP +\fB\-z \-\-dither\fR +Dithering mode (default: none) +.SH "EXAMPLES" +.PP +Print usage message for the parameters specific to each backend. +.IP +\fBjackd \-d alsa \-\-help\fR +.br +\fBjackd \-d coreaudio \-\-help\fR +.br +\fBjackd \-d net \-\-help\fR +.br +\fBjackd \-d dummy \-\-help\fR +.br +\fBjackd \-d firewire \-\-help\fR +.br +\fBjackd \-d freebob \-\-help\fR +.br +\fBjackd \-d oss \-\-help\fR +.br +\fBjackd \-d sun \-\-help\fR +.br +\fBjackd \-d portaudio \-\-help\fR +.PP +Run the JACK daemon with realtime priority using the first ALSA +hardware card defined in \fB/etc/modules.conf\fR. +.IP +\fBjackstart \-\-realtime \-\-driver=alsa\fR +.PP +Run the JACK daemon with low latency giving verbose output, which can +be helpful for trouble\-shooting system latency problems. A +reasonably well\-tuned system with a good sound card and a +low\-latency kernel can handle these values reliably. Some can do +better. If you get xrun messages, try a larger buffer. Tuning a +system for low latency can be challenging. The JACK FAQ, +.I http://jackit.sourceforge.net/docs/faq.php\fR +has some useful suggestions. +.IP +\fBjackstart \-Rv \-d alsa \-p 128 \-n 2 \-r 44100\fR +.PP +Run \fBjackd\fR with realtime priority using the "sblive" ALSA device +defined in ~/.asoundrc. Apply shaped dithering to playback audio. +.IP +\fBjackd \-R \-d alsa \-d sblive \-\-dither=shaped\fR +.PP +Run \fBjackd\fR with no special privileges using the second ALSA +hardware card defined in \fB/etc/modules.conf\fR. Any xruns reported +by the ALSA backend will be ignored. The larger buffer helps reduce +data loss. Rectangular dithering will be used for playback. +.IP +\fBjackd \-d alsa \-d hw:1 \-p2048 \-n3 \-\-softmode \-zr\fR +.PP +Run \fBjackd\fR in full\-duplex mode using the ALSA hw:0,0 device for +playback and the hw:0,2 device for capture. +.IP +\fBjackd \-d alsa \-P hw:0,0 \-C hw:0,2\fR +.PP +Run \fBjackd\fR in playback\-only mode using the ALSA hw:0,0 device. +.IP +\fBjackd \-d alsa \-P hw:0,0\fR +.SH "ENVIRONMENT" +.br +JACK is evolving a mechanism for automatically starting the server +when needed. Any client started without a running JACK server will +attempt to start one itself using the command line found in the first +line of \fB$HOME/.jackdrc\fR if it exists, or \fB/etc/jackdrc\fR if it +does not. If neither file exists, a built\-in default command will be +used, including the \fB\-T\fR flag, which causes the server to shut +down when all clients have exited. + +As a transition, this only happens when \fB$JACK_START_SERVER\fR is +defined in the environment of the calling process. In the future this +will become normal behavior. In either case, defining +\fB$JACK_NO_START_SERVER\fR disables this feature. + +To change where JACK looks for the backend drivers, set +\fB$JACK_DRIVER_DIR\fR. + +\fB$JACK_DEFAULT_SERVER\fR specifies the default server name. If not +defined, the string "default" is used. If set in their respective +environments, this affects \fBjackd\fR unless its \fB\-\-name\fR +parameter is set, and all JACK clients unless they pass an explicit +name to \fBjack_client_open()\fR. + +.SH "SEE ALSO:" +.PP +.I http://www.jackaudio.org +.br +The official JACK website with news, docs and a list of JACK clients. +.PP +.I http://jackaudio.org/email +.br +The JACK developers' mailing list. Subscribe, to take part in +development of JACK or JACK clients. User questions are also welcome, +there is no user-specific mailing list. +.PP +.I http://www.jackosx.com/ +.br +Tools specific to the Mac OS X version of JACK. +.PP +.I http://www.alsa\-project.org +.br +The Advanced Linux Sound Architecture. +.SH "BUGS" +Please report bugs to +.br +.I http://trac.jackaudio.org/ +.SH "AUTHORS" +Architect and original implementor: Paul Davis +.PP +Original design Group: Paul Davis, David Olofson, Kai Vehmanen, Benno Sennoner, +Richard Guenther, and other members of the Linux Audio Developers group. +.PP +Programming: Paul Davis, Jack O'Quin, Taybin Rutkin, Stephane Letz, Fernando +Pablo Lopez-Lezcano, Steve Harris, Jeremy Hall, Andy Wingo, Kai +Vehmanen, Melanie Thielker, Jussi Laako, Tilman Linneweh, Johnny +Petrantoni, Torben Hohn. +.PP +Manpage written by Stefan Schwandter, Jack O'Quin and Alexandre +Prokoudine. diff --git a/man/jackrec.0 b/man/jackrec.0 new file mode 100644 index 00000000..1ea2a6fb --- /dev/null +++ b/man/jackrec.0 @@ -0,0 +1,23 @@ +.TH JACKREC "1" "!DATE!" "!VERSION!" +.SH NAME +jackrec \- JACK toolkit client for recording audio +.SH SYNOPSIS +.B jackrec +\-f filename \-d seconds [ \-b bitdepth ] port1 [ port2 ... ] +.SH DESCRIPTION +.B jackrec is a basic, but useful, audio recorder that will record +audio from 1 or more JACK ports to a file on disk. The file format is +always RIFF/WAV, with samples stored as signed integers. The sample +bit depth can be selected using the \fI-b\fR option. The file will +have as many channels as there are ports specified on the command line +- each channel will contain the data recorded from one port. The user +should generally specify the duration (in seconds) using the \fI-d\fR +option. If not specified, jackrec will record until terminated by a +signal (eg. from Ctrl-c). +.PP +This application is not intended to be a heavy duty audio recorder, +and originated as an example client to show how to handle threading +and disk I/O in a JACK client. However, it is a useful, simple +recorder and is included in the JACK toolkit as a result. + + diff --git a/man/wscript b/man/wscript new file mode 100644 index 00000000..31bd60f3 --- /dev/null +++ b/man/wscript @@ -0,0 +1,13 @@ +#! /usr/bin/env python +# encoding: utf-8 + +import Build +import re +import os +import misc + + +def build(bld): + bld.exec_command("cd man ; sh fill_template %s" % bld.env['JACK_VERSION']) + bld.install_files(bld.env['MANDIR'], '*.1') + diff --git a/posix/JackPosixSemaphore.cpp b/posix/JackPosixSemaphore.cpp index 30530e1c..d151c5a4 100644 --- a/posix/JackPosixSemaphore.cpp +++ b/posix/JackPosixSemaphore.cpp @@ -118,10 +118,12 @@ bool JackPosixSemaphore::TimedWait(long usec) time.tv_sec += tv_usec / 1000000; time.tv_nsec = (tv_usec % 1000000) * 1000; - if ((res = sem_timedwait(fSemaphore, &time)) != 0) { + while ((res = sem_timedwait(fSemaphore, &time)) < 0) { jack_error("JackPosixSemaphore::TimedWait err = %s", strerror(errno)); jack_log("now %ld %ld ", now.tv_sec, now.tv_usec); jack_log("next %ld %ld ", time.tv_sec, time.tv_nsec/1000); + if (errno != EINTR) + break; } return (res == 0); } @@ -184,9 +186,8 @@ bool JackPosixSemaphore::ConnectOutput(const char* name, const char* server_name bool JackPosixSemaphore::Disconnect() { - jack_log("JackPosixSemaphore::Disconnect %s", fName); - if (fSemaphore) { + jack_log("JackPosixSemaphore::Disconnect %s", fName); if (sem_close(fSemaphore) != 0) { jack_error("Disconnect: can't disconnect named semaphore name = %s err = %s", fName, strerror(errno)); return false; diff --git a/tests/test.cpp b/tests/test.cpp index 4e025c01..4e181f65 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -632,7 +633,57 @@ int main (int argc, char *argv[]) if (status & JackServerStarted) { fprintf(stderr, "JACK server started\n"); } - + + /** + * Internal client tests... + * + */ + jack_intclient_t intclient; + + Log("trying to load the \"inprocess\" server internal client \n"); + + intclient = jack_internal_client_load (client1, "inprocess", + (jack_options_t)(JackLoadName|JackLoadInit), + &status, "inprocess", ""); + + if (intclient == 0 || status & JackFailure) { + printf("!!! ERROR !!! cannot load internal client \"inprocess\" intclient %d status 0x%2.0x !\n", intclient, status); + } else { + + Log("\"inprocess\" server internal client loaded\n"); + + char* internal_name = jack_get_internal_client_name(client1, intclient); + if (strcmp(internal_name, "inprocess") == 0) { + Log("jack_get_internal_client_name returns %s\n", internal_name); + } else { + printf("!!! ERROR !!! jack_get_internal_client_name returns incorrect name %s\n", internal_name); + } + + jack_intclient_t intclient1 = jack_internal_client_handle(client1, "inprocess", &status); + if (intclient1 == intclient) { + Log("jack_internal_client_handle returns correct handle\n"); + } else { + printf("!!! ERROR !!! jack_internal_client_handle returns incorrect handle %d\n", intclient1); + } + + // Unload internal client + status = jack_internal_client_unload (client1, intclient); + if (status == 0) { + Log("jack_internal_client_unload done first time returns correct value\n"); + } else { + printf("!!! ERROR !!! jack_internal_client_unload returns incorrect value 0x%2.0x\n", status); + } + + // Unload internal client second time + status = jack_internal_client_unload (client1, intclient); + if (status & JackFailure && status & JackNoSuchClient) { + Log("jack_internal_client_unload done second time returns correct value\n"); + } else { + printf("!!! ERROR !!! jack_internal_client_unload returns incorrect value 0x%2.0x\n", status); + } + } + + /** * try to register another one with the same name... * diff --git a/wscript b/wscript index bc88c490..52f01f63 100644 --- a/wscript +++ b/wscript @@ -62,6 +62,7 @@ def set_options(opt): opt.add_option('--libdir', type='string', help="Library directory [Default: /lib]") opt.add_option('--libdir32', type='string', help="32bit Library directory [Default: /lib32]") + opt.add_option('--mandir', type='string', help="Manpage directory [Default: /share/man/man1]") opt.add_option('--dbus', action='store_true', default=False, help='Enable D-Bus JACK (jackdbus)') opt.add_option('--classic', action='store_true', default=False, help='Force enable standard JACK (jackd) even if D-Bus JACK (jackdbus) is enabled too') opt.add_option('--doxygen', action='store_true', default=False, help='Enable build of doxygen documentation') @@ -78,7 +79,7 @@ def set_options(opt): def configure(conf): platform = Utils.detect_platform() conf.env['IS_MACOSX'] = platform == 'darwin' - conf.env['IS_LINUX'] = platform == 'linux' + conf.env['IS_LINUX'] = platform == 'linux' or platform == 'posix' conf.env['IS_SUN'] = platform == 'sunos' if conf.env['IS_LINUX']: @@ -163,6 +164,11 @@ def configure(conf): else: conf.env['LIBDIR'] = conf.env['PREFIX'] + '/lib' + if Options.options.libdir: + conf.env['MANDIR'] = conf.env['PREFIX'] + Options.options.mandir + else: + conf.env['MANDIR'] = conf.env['PREFIX'] + '/share/man/man1' + if conf.env['BUILD_DEBUG']: conf.env.append_unique('CXXFLAGS', '-g') conf.env.append_unique('CCFLAGS', '-g') @@ -242,6 +248,8 @@ def configure(conf): print Logs.colors.NORMAL, print + conf.env.append_unique('LINKFLAGS', '-lm -lstdc++') + if Options.options.mixed == True: env_variant2 = conf.env.copy() conf.set_env_name('lib32', env_variant2) @@ -267,6 +275,7 @@ def build(bld): bld.add_subdirs('linux') bld.add_subdirs('example-clients') bld.add_subdirs('tests') + bld.add_subdirs('man') if bld.env['BUILD_JACKDBUS'] == True: bld.add_subdirs('dbus') From 4828d0c835392d7b01b8d597eaa2bdde08d669d8 Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 8 Nov 2010 16:05:29 +0000 Subject: [PATCH 054/472] rebase from trunk 4041:4083 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@4084 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 35 +- README | 3 +- common/JackAPI.cpp | 142 +- common/JackAudioDriver.cpp | 34 +- common/JackChannel.h | 28 +- common/JackClient.cpp | 112 +- common/JackClient.h | 15 +- common/JackClientControl.h | 18 +- common/JackConstants.h | 5 +- common/JackControlAPI.cpp | 10 +- common/JackDebugClient.cpp | 20 +- common/JackDebugClient.h | 6 +- common/JackDriverLoader.cpp | 25 +- common/JackDriverLoader.h | 6 +- common/JackEngine.cpp | 201 +- common/JackEngine.h | 35 +- common/JackError.cpp | 20 +- common/JackError.h | 20 +- common/JackExternalClient.cpp | 4 +- common/JackExternalClient.h | 4 +- common/JackInternalClient.cpp | 12 +- common/JackInternalClient.h | 10 +- common/JackInternalClientChannel.h | 13 +- common/JackLibAPI.cpp | 10 +- common/JackLibClient.cpp | 6 +- common/JackLibClient.h | 4 +- common/JackLockedEngine.h | 45 +- common/JackNetOneDriver.cpp | 602 +- common/JackNotification.h | 1 + common/JackRequest.h | 449 +- common/JackServer.cpp | 32 +- common/JackServer.h | 6 +- common/JackServerAPI.cpp | 12 +- common/JackThread.h | 1 + common/JackTools.cpp | 10 + common/JackTools.h | 4 + common/Jackdmp.cpp | 7 +- common/jack/jack.h | 5 +- common/jack/midiport.h | 14 + common/jack/session.h | 229 + common/jack/types.h | 90 +- common/varargs.h | 19 +- common/wscript | 14 +- dbus/controller_iface_patchbay.c | 2 +- dbus/jackdbus.c | 98 +- doxyfile | 2 +- example-clients/lsp.c | 4 +- example-clients/netsource.c | 88 +- example-clients/session_notify.c | 184 + example-clients/simple_session_client.c | 202 + example-clients/wscript | 2 + linux/alsa/JackAlsaDriver.cpp | 669 +- linux/firewire/JackFFADODriver.cpp | 6 +- linux/freebob/JackFreebobDriver.cpp | 6 +- macosx/Jack-Info.plist | 4 +- macosx/JackCompilerDeps_os.h | 55 + macosx/JackMacEngineRPC.cpp | 250 - macosx/JackMacLibClientRPC.cpp | 47 - macosx/JackMachClientChannel.cpp | 334 - macosx/JackMachClientChannel.h | 99 - macosx/JackMachNotifyChannel.cpp | 67 - macosx/JackMachNotifyChannel.h | 53 - macosx/JackMachPort.cpp | 295 - macosx/JackMachPort.h | 88 - macosx/JackMachServerChannel.cpp | 174 - macosx/JackMachServerChannel.h | 76 - macosx/JackMachServerNotifyChannel.cpp | 70 - macosx/JackMachServerNotifyChannel.h | 55 - macosx/JackPlatformPlug_os.h | 33 +- macosx/Jackdmp.xcodeproj/project.pbxproj | 361 +- macosx/RPC/JackRPCClient.defs | 47 - macosx/RPC/JackRPCClient.h | 194 - macosx/RPC/JackRPCClientServer.c | 1373 ----- macosx/RPC/JackRPCClientUser.c | 466 -- macosx/RPC/JackRPCEngine.defs | 181 - macosx/RPC/JackRPCEngine.h | 1040 ---- macosx/RPC/JackRPCEngineServer.c | 6817 --------------------- macosx/RPC/JackRPCEngineUser.c | 6302 ------------------- macosx/RPC/Jackdefs.h | 25 - macosx/coreaudio/JackCoreAudioDriver.cpp | 11 +- macosx/coreaudio/JackCoreAudioDriver.h | 8 - posix/JackCompilerDeps_os.h | 2 +- posix/JackPosixThread.cpp | 7 +- posix/JackPosixThread.h | 3 +- posix/JackSocket.cpp | 4 +- posix/JackSocketClientChannel.cpp | 74 +- posix/JackSocketClientChannel.h | 28 +- posix/JackSocketServerChannel.cpp | 76 +- posix/JackSocketServerChannel.h | 8 +- solaris/oss/JackBoomerDriver.cpp | 2 + solaris/oss/JackBoomerDriver.h | 5 +- solaris/oss/JackOSSDriver.cpp | 4 +- tests/test.cpp | 52 +- windows/JackWinNamedPipeClientChannel.cpp | 26 +- windows/JackWinNamedPipeClientChannel.h | 20 +- windows/JackWinNamedPipeServerChannel.cpp | 85 +- windows/JackWinNamedPipeServerChannel.h | 14 +- windows/JackWinThread.cpp | 5 + windows/JackWinThread.h | 23 +- windows/Setup/JackRouter.dll | Bin 32768 -> 32768 bytes windows/Setup/jack.ci | 4 +- windows/jack_dummy.cbp | 193 +- windows/jack_loopback.cbp | 3 + windows/jackaudioadapter.rc | 8 +- windows/jackd.rc | 8 +- windows/jackdummydriver.rc | 41 + windows/jackloopbackdriver.rc | 41 + windows/jacknetadapter.rc | 8 +- windows/jacknetdriver.rc | 8 +- windows/jacknetmanager.rc | 8 +- windows/jacknetonedriver.rc | 82 +- windows/jackportaudio.rc | 8 +- windows/jackwinmme.rc | 10 +- windows/libjack.rc | 8 +- windows/libjackserver.rc | 8 +- windows/resource.rc | 8 +- wscript | 2 +- 117 files changed, 3450 insertions(+), 19562 deletions(-) create mode 100644 common/jack/session.h create mode 100644 example-clients/session_notify.c create mode 100644 example-clients/simple_session_client.c create mode 100644 macosx/JackCompilerDeps_os.h delete mode 100644 macosx/JackMacEngineRPC.cpp delete mode 100644 macosx/JackMacLibClientRPC.cpp delete mode 100644 macosx/JackMachClientChannel.cpp delete mode 100644 macosx/JackMachClientChannel.h delete mode 100644 macosx/JackMachNotifyChannel.cpp delete mode 100644 macosx/JackMachNotifyChannel.h delete mode 100644 macosx/JackMachPort.cpp delete mode 100644 macosx/JackMachPort.h delete mode 100644 macosx/JackMachServerChannel.cpp delete mode 100644 macosx/JackMachServerChannel.h delete mode 100644 macosx/JackMachServerNotifyChannel.cpp delete mode 100644 macosx/JackMachServerNotifyChannel.h delete mode 100644 macosx/RPC/JackRPCClient.defs delete mode 100644 macosx/RPC/JackRPCClient.h delete mode 100644 macosx/RPC/JackRPCClientServer.c delete mode 100644 macosx/RPC/JackRPCClientUser.c delete mode 100644 macosx/RPC/JackRPCEngine.defs delete mode 100644 macosx/RPC/JackRPCEngine.h delete mode 100644 macosx/RPC/JackRPCEngineServer.c delete mode 100644 macosx/RPC/JackRPCEngineUser.c delete mode 100644 macosx/RPC/Jackdefs.h create mode 100644 windows/jackdummydriver.rc create mode 100644 windows/jackloopbackdriver.rc diff --git a/ChangeLog b/ChangeLog index f54ae963..4b05b3e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -26,11 +26,42 @@ Josh Green Mario Lang Arnold Krille Jan Engelhardt -Adrian Knoth +Adrian Knoth +David Garcia Garzon --------------------------- Jackdmp changes log ---------------------------- +--------------------------- + +2010-11-05 Stephane Letz + + * In jackdmp.cpp, jackctl_setup_signals moved before jackctl_server_start. + * Correct symbols export in backends. + +2010-11-03 Stephane Letz + + * Improve backend error handling: fatal error returned by Read/Write now cause a Process failure (so a thread exit for blocking backends). Recoverable ones (XRuns..) are now treated internally in ALSA, FreeBob and FFADO backends. + +2010-10-30 Stephane Letz + + * Correct JackServer::Open to avoid a race when control API is used on OSX. + +2010-10-29 Stephane Letz + + * Correct lsp.c code. + * Add note about unique port-name requirement. + +2010-09-08 Stephane Letz + + * Sync JackAlsaDriver::alsa_driver_check_card_type with JACK1 backend. + +2010-08-30 Stephane Letz + + * Version 1.9.7 started. + +2010-08-25 Stephane Letz + + * In JackCoreAudioDriver, fix an issue when no value is given for input. 2010-08-23 Stephane Letz diff --git a/README b/README index 2c689250..92eb746d 100644 --- a/README +++ b/README @@ -214,7 +214,8 @@ Note : To experiment with the -S option, jackdmp must be launched in a console. 1.9.2 : Solaris version. New "profiling" tools. Rework the mutex/signal classes. Support for BIG_ENDIAN machines in NetJack2. D-BUS based device reservation to better coexist with PulseAudio on Linux. Add auto_connect parameter in netmanager and netadapter. Use Torben Hohn PI controler code for adapters. Client incorrect re-naming fixed : now done at socket and fifo level. Virtualize and allow overriding of thread creation function, to allow Wine support (from JACK1). 1.9.3 : New JackBoomerDriver class for Boomer driver on Solaris. Add mixed 32/64 bits mode (off by default). Native MIDI backend (JackCoreMidiDriver, JackWinMMEDriver). In ALSA audio card reservation code, tries to open the card even if reservation fails. Clock source setting on Linux. Add jackctl_server_switch_master API. Fix transport callback (timebase master, sync) issue when used after jack_activate (RT thread was not running). D-Bus access for jackctl_server_add_slave/jackctl_server_remove_slave API. Cleanup "loopback" stuff in server. Torben Hohn fix for InitTime and GetMicroSeconds in JackWinTime.c. New jack_free function added in jack.h. Reworked Torben Hohn fix for server restart issue on Windows. Correct jack_set_error_function, jack_set_info_function and jack_set_thread_creator functions. Correct JackFifo::TimedWait for EINTR handling. Move DBus based audio device reservation code in ALSA backend compilation. Correct JackTransportEngine::MakeAllLocating, sync callback has to be called in this case also. NetJack2 code : better error checkout, method renaming. Tim Bechmann patch : hammerfall, only release monitor thread, if it has been created. Tim Bechmann memops.c optimization patches. In combined --dbus and --classic compilation code, use PulseAudio acquire/release code. Big rewrite of Solaris boomer driver, seems to work in duplex mode at least. Loopback backend reborn as a dynamically loadable separated backend. 1.9.4 : Solaris boomer backend now working in capture or playback only mode. Add a -G parameter in CoreAudio backend (the computation value in RT thread expressed as percent of period). Use SNDCTL_DSP_SYNCGROUP/SNDCTL_DSP_SYNCSTART API to synchronize input and output in Solaris boomer backend. Big endian bug fix in memops.c. Fix issues in JackNetDriver::DecodeTransportData and JackNetDriver::Initialize. Correct CPU timing in JackNetDriver, now take cycle begin time after Read. Simplify transport in NetJack2: master only can control transport. Change CoreAudio notification thread setup for OSX Snow Leopard. Correct server temporary mode : now set a global and quit after server/client message handling is finished. Add a string parameter to server ==> client notification, add a new JackInfoShutdownCallback type. CoreAudio backend now issue a JackInfoShutdownCallback when an unrecoverable error is detected (sampling rate change, stream configuration changeÉ). Correct jackdmp.cpp (failures case were not correct..). Improve JackCoreAudioDriver code. Raise default port number to 2048. Correct JackProcessSync::LockedTimedWait. Correct JACK_MESSAGE_SIZE value, particularly in OSX RPC code. Now start server channel thread only when backend has been started (so in JackServer::Start). Should solve race conditions at start time. jack_verbose moved to JackGlobals class. Improve aggregate device management in JackCoreAudioDriver : now a "private" device only and cleanup properly. Aggregate device code added to JackCoreAudioAdapter. Implement "hog mode" (exclusive access of the audio device) in JackCoreAudioDriver. Fix jack_set_sample_rate_callback to have he same behavior as in JACK1. Dynamic system version detection in JackCoreAudioDriver to either create public or private aggregate device. In JackCoreAudioDriver, force the SR value to the wanted one *before* creating aggregate device (otherwise creation will fail). In JackCoreAudioDriver, better cleanup of AD when intermediate open failure. In JackCoreAudioDriver::Start, wait for the audio driver to effectively start (use the MeasureCallback). In JackCoreAudioDriver, improve management of input/output channels: -1 is now used internally to indicate a wanted max value. In JackCoreAudioDriver::OpenAUHAL, correct stream format setup and cleanup. Correct crash bug in JackAudioAdapterInterface when not input is used in adapter (temporary fixÉ). Sync JackCoreAudioAdapter code on JackCoreAudioDriver one. JACK_SCHED_POLICY switched to SCHED_FIFO. Now can aggregate device that are themselves AD. No reason to make jack_on_shutdown deprecated, so revert the incorrect change. Thread AcquireRealTime and DropRealTime were (incorrectly) using fThread field. Use pthread_self()) (or GetCurrentThread() on Windows) to get the calling thread. Correctly save and restore RT mode state in freewheel mode. Correct freewheel code on client side. Fix AcquireRealTime and DropRealTime: now distinguish when called from another thread (AcquireRealTime/DropRealTime) and from the thread itself (AcquireSelfRealTime/DropSelfRealTime). Correct JackPosixThread::StartImp : thread priority setting now done in the RT case only. Correct JackGraphManager::GetBuffer for the "client loop with one connection" case : buffer must be copied. Correct JackInfoShutdownCallback prototype, two new JackClientProcessFailure and JackClientZombie JackStatus code. Correct JackCoreAudio driver when empty strings are given as -C, -P or -d parameter. Better memory allocation error checking on client (library) side. Better memory allocation error checking in ringbuffer.c, weak import improvements. Memory allocation error checking for jack_client_new and jack_client_open (server and client side). Memory allocation error checking in server for RPC. Simplify server temporary mode : now use a JackTemporaryException. Lock/Unlock shared memory segments (to test...). Sync with JACK1 : -r parameter now used for no-realtime, realtime (-R) is now default, usable backend given vie platform. In JackCoreAudio driver, (possibly) clock drift compensation when needed in aggregated devices. In JackCoreAudio driver, clock drift compensation in aggregated devices working. In JackCoreAudio driver, clock drift compensation semantic changed a bit : when on, does not activate if not needed (same clock domain). Sync JackCoreAudioAdapter code with JackCoreAudioDriver. -1.9.5 : Dynamic choice of maximum port number. More robust sample rate change handling code in JackCoreAudioDriver. Devin Anderson patch for Jack FFADO driver issues with lost MIDI bytes between periods (and more). Fix port_rename callback : now both old name and new name are given as parameters. Special code in JackCoreAudio driver to handle completely buggy Digidesign CoreAudio user-land driver. Ensure that client-side message buffer thread calls thread_init callback if/when it is set by the client (backport of JACK1 rev 3838). Check dynamic port-max value. Fix JackCoreMidiDriver::ReadProcAux when ring buffer is full (thanks Devin Anderson). Josh Green ALSA driver capture only patch. When threads are cancelled, the exception has to be rethrown. Use a QUIT notification to properly quit the server channel, the server channel thread can then be 'stopped' instead of 'canceled'. Mario Lang alsa_io time calculation overflow patch. Shared memory manager was calling abort in case of fatal error, now return an error in caller. Change JackEngineProfiling and JackAudioAdapterInterface gnuplot scripts to output SVG instead of PDF. +1.9.5 : Dynamic choice of maximum port number. More robust sample rate change handling code in JackCoreAudioDriver. Devin Anderson patch for Jack FFADO driver issues with lost MIDI bytes between periods (and more). Fix port_rename callback : now both old name and new name are given as parameters. Special code in JackCoreAudio driver to handle completely buggy Digidesign CoreAudio user-land driver. Ensure that client-side message buffer thread calls thread_init callback if/when it is set by the client (backport of JACK1 rev 3838). Check dynamic port-max value. Fix JackCoreMidiDriver::ReadProcAux when ring buffer is full (thanks Devin Anderson). Josh Green ALSA driver capture only patch. When threads are cancelled, the exception has to be rethrown. Use a QUIT notification to properly quit the server channel, the server channel thread can then be 'stopped' instead of 'canceled'. Mario Lang alsa_io time calculation overflow patch. Shared memory manager was calling abort in case of fatal error, now return an error in caller. Change JackEngineProfiling and JackAudioAdapterInterface gnuplot scripts to output SVG instead of PDF. +1.9.6 : Improve JackCoreAudioDriver and JackCoreAudioAdapter : when no devices are described, takes default input and output and aggregate them.Correct JackGraphManager::DeactivatePort. Correct JackMachServerChannel::Execute : keep running even in error cases. Raise JACK_PROTOCOL_VERSION number. Arnold Krille firewire patch. Raise JACK_DRIVER_PARAM_STRING_MAX and JACK_PARAM_STRING_MAX to 127 otherwise some audio drivers cannot be loaded on OSX. Fix some file header to have library side code use LGPL. On Windows, now use TRE library for regexp (BSD license instead of GPL license). ffado-portname-sync.patch from ticket #163 applied. Remove call to exit in library code. Make jack_connect/jack_disconnect wait for effective port connection/disconnection. Add tests to validate intclient.h API. On Linux, inter-process synchronization primitive switched to POSIX semaphore. In JackCoreAudioDriver, move code called in MeasureCallback to be called once in IO thread. David Garcia Garzon netone patch. Fix from Fernando Lopez-Lezcano for compilation on fc13. Fix JackPosixSemaphore::TimedWait : same behavior as JackPosixSemaphore::Wait regarding EINTR. David Garcia Garzon unused_pkt_buf_field_jack2 netone patch. Arnold Krille firewire snooping patch. Jan Engelhardt patch for get_cycles on SPARC. Adrian Knoth hurd.patch, kfreebsd-fix.patch and alpha_ia64-sigsegv.patch from ticket 177. Adrian Knoth fix for linux cycle.h (ticket 188). In JackCoreAudioDriver, fix an issue when no value is given for input. This is a work in progress but the implementation is now stable enough to be tested. jackdmp has been used successfully with the following applications : Ardour, Hydrogen, Jamin, Qjackctl, Jack-Rack, SooperLooper, AlsaPlayer... diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index f6a67b99..fe60ebe2 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -108,8 +108,8 @@ extern "C" JackPortConnectCallback connect_callback, void *arg); EXPORT int jack_set_port_rename_callback (jack_client_t *, - JackPortRenameCallback - rename_callback, void *arg); + JackPortRenameCallback + rename_callback, void *arg); EXPORT int jack_set_graph_order_callback (jack_client_t *, JackGraphOrderCallback graph_callback, void *); @@ -217,7 +217,7 @@ extern "C" EXPORT int jack_client_create_thread (jack_client_t* client, pthread_t *thread, int priority, - int realtime, // boolean + int realtime, // boolean thread_routine routine, void *arg); EXPORT int jack_drop_real_time_scheduling (pthread_t thread); @@ -1686,7 +1686,7 @@ EXPORT int jack_acquire_real_time_scheduling(pthread_t thread, int priority) EXPORT int jack_client_create_thread(jack_client_t* client, pthread_t *thread, int priority, - int realtime, /* boolean */ + int realtime, /* boolean */ thread_routine routine, void *arg) { @@ -1766,8 +1766,8 @@ EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t* ext_client, c return 0; } else { jack_status_t my_status; - if (status == NULL) /* no status from caller? */ - status = &my_status; /* use local status word */ + if (status == NULL) /* no status from caller? */ + status = &my_status; /* use local status word */ *status = (jack_status_t)0; return client->InternalClientHandle(client_name, status); } @@ -1786,8 +1786,8 @@ EXPORT jack_intclient_t jack_internal_client_load_aux(jack_client_t* ext_client, jack_varargs_t va; jack_status_t my_status; - if (status == NULL) /* no status from caller? */ - status = &my_status; /* use local status word */ + if (status == NULL) /* no status from caller? */ + status = &my_status; /* use local status word */ *status = (jack_status_t)0; /* validate parameters */ @@ -1859,3 +1859,129 @@ EXPORT void jack_free(void* ptr) free(ptr); } } + +// session.h +EXPORT int jack_set_session_callback(jack_client_t* ext_client, JackSessionCallback session_callback, void* arg) +{ +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_set_session_callback"); +#endif + JackClient* client = (JackClient*)ext_client; + jack_log("jack_set_session_callback ext_client %x client %x ", ext_client, client); + if (client == NULL) { + jack_error("jack_set_session_callback called with a NULL client"); + return -1; + } else { + return client->SetSessionCallback(session_callback, arg); + } +} + +EXPORT jack_session_command_t *jack_session_notify(jack_client_t* ext_client, const char* target, jack_session_event_type_t ev_type, const char *path) +{ +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_session_notify"); +#endif + JackClient* client = (JackClient*)ext_client; + jack_log("jack_session_notify ext_client %x client %x ", ext_client, client); + if (client == NULL) { + jack_error("jack_session_notify called with a NULL client"); + return NULL; + } else { + return client->SessionNotify(target, ev_type, path); + } +} + +EXPORT int jack_session_reply(jack_client_t *ext_client, jack_session_event_t *event) +{ +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_session_reply"); +#endif + JackClient* client = (JackClient*)ext_client; + jack_log("jack_session_reply ext_client %x client %x ", ext_client, client); + if (client == NULL) { + jack_error("jack_session_reply called with a NULL client"); + return -1; + } else { + return client->SessionReply(event); + } +} + +EXPORT void jack_session_event_free(jack_session_event_t* ev) +{ + if (ev) { + if (ev->session_dir) + free((void *)ev->session_dir); + if (ev->client_uuid) + free((void *)ev->client_uuid); + if (ev->command_line) + free(ev->command_line); + free(ev); + } +} + +EXPORT char *jack_get_uuid_for_client_name( jack_client_t *ext_client, const char *client_name ) +{ +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_get_uuid_for_client_name"); +#endif + JackClient* client = (JackClient*)ext_client; + jack_log("jack_get_uuid_for_client_name ext_client %x client %x ", ext_client, client); + if (client == NULL) { + jack_error("jack_get_uuid_for_client_name called with a NULL client"); + return NULL; + } else { + return client->GetUUIDForClientName(client_name); + } +} + +EXPORT char *jack_get_client_name_by_uuid( jack_client_t *ext_client, const char *client_uuid ) +{ +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_get_client_name_by_uuid"); +#endif + JackClient* client = (JackClient*)ext_client; + jack_log("jack_get_uuid_for_client_name ext_client %x client %x ", ext_client, client); + if (client == NULL) { + jack_error("jack_get_client_name_by_uuid called with a NULL client"); + return NULL; + } else { + return client->GetClientNameForUUID(client_uuid); + } +} + +EXPORT int jack_reserve_client_name( jack_client_t *ext_client, const char *name, const char *uuid ) +{ +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_reserve_client_name"); +#endif + JackClient* client = (JackClient*)ext_client; + jack_log("jack_reserve_client_name ext_client %x client %x ", ext_client, client); + if (client == NULL) { + jack_error("jack_reserve_client_name called with a NULL client"); + return -1; + } else { + return client->ReserveClientName(name, uuid); + } +} + +EXPORT void jack_session_commands_free( jack_session_command_t *cmds ) +{ + if (!cmds) + return; + + int i=0; + while(1) { + if (cmds[i].client_name) + free ((char *)cmds[i].client_name); + if (cmds[i].command) + free ((char *)cmds[i].command); + if (cmds[i].uuid) + free ((char *)cmds[i].uuid); + else + break; + + i += 1; + } + + free(cmds); +} diff --git a/common/JackAudioDriver.cpp b/common/JackAudioDriver.cpp index dc53077c..9748b46a 100644 --- a/common/JackAudioDriver.cpp +++ b/common/JackAudioDriver.cpp @@ -195,7 +195,7 @@ int JackAudioDriver::ProcessNull() ProcessGraphAsync(); } - // Keep end cycle time + // Keep end cycle time JackDriver::CycleTakeEndTime(); WaitUntilNextCycle(); return 0; @@ -215,14 +215,14 @@ int JackAudioDriver::ProcessAsync() { // Read input buffers for the current cycle if (Read() < 0) { - jack_error("JackAudioDriver::ProcessAsync: read error, skip cycle"); - return 0; // Skip cycle, but continue processing... + jack_error("JackAudioDriver::ProcessAsync: read error, stopping..."); + return -1; } // Write output buffers from the previous cycle if (Write() < 0) { - jack_error("JackAudioDriver::ProcessAsync: write error, skip cycle"); - return 0; // Skip cycle, but continue processing... + jack_error("JackAudioDriver::ProcessAsync: write error, stopping..."); + return -1; } if (fIsMaster) { @@ -244,9 +244,9 @@ output buffers computed at the *current cycle* are used. int JackAudioDriver::ProcessSync() { // Read input buffers for the current cycle - if (Read() < 0) { - jack_error("JackAudioDriver::ProcessSync: read error, skip cycle"); - return 0; // Skip cycle, but continue processing... + if (Read() < 0) { + jack_error("JackAudioDriver::ProcessSync: read error, stopping..."); + return -1; } if (fIsMaster) { @@ -255,10 +255,10 @@ int JackAudioDriver::ProcessSync() fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); } - // Write output buffers for the current cycle - if (Write() < 0) { - jack_error("JackAudioDriver::ProcessSync: write error, skip cycle"); - return 0; // Skip cycle, but continue processing... + // Write output buffers from the current cycle + if (Write() < 0) { + jack_error("JackAudioDriver::ProcessSync: write error, stopping..."); + return -1; } // Keep end cycle time @@ -270,10 +270,10 @@ void JackAudioDriver::ProcessGraphAsync() { // fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle if (!fEngine->Process(fBeginDateUst, fEndDateUst)) - jack_error("JackAudioDriver::ProcessAsync Process error"); + jack_error("JackAudioDriver::ProcessGraphAsync: Process error"); fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); if (ProcessSlaves() < 0) - jack_error("JackAudioDriver::ProcessAsync ProcessSlaves error"); + jack_error("JackAudioDriver::ProcessGraphAsync: ProcessSlaves error"); } void JackAudioDriver::ProcessGraphSync() @@ -282,11 +282,11 @@ void JackAudioDriver::ProcessGraphSync() if (fEngine->Process(fBeginDateUst, fEndDateUst)) { fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); if (ProcessSlaves() < 0) - jack_error("JackAudioDriver::ProcessSync ProcessSlaves error, engine may now behave abnormally!!"); + jack_error("JackAudioDriver::ProcessGraphSync: ProcessSlaves error, engine may now behave abnormally!!"); if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) - jack_error("JackAudioDriver::ProcessSync SuspendRefNum error, engine may now behave abnormally!!"); + jack_error("JackAudioDriver::ProcessGraphSync: SuspendRefNum error, engine may now behave abnormally!!"); } else { // Graph not finished: do not activate it - jack_error("JackAudioDriver::ProcessSync: error"); + jack_error("JackAudioDriver::ProcessGraphSync: Process error"); } } diff --git a/common/JackChannel.h b/common/JackChannel.h index 655e2bcf..40cfd264 100644 --- a/common/JackChannel.h +++ b/common/JackChannel.h @@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define __JackChannel__ #include "types.h" +#include "session.h" namespace Jack { @@ -49,7 +50,7 @@ class JackClientChannelInterface {} // Open the Server/Client connection - virtual int Open(const char* server_name, const char* name, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status) + virtual int Open(const char* server_name, const char* name, int uuid, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status) { return 0; } @@ -73,9 +74,9 @@ class JackClientChannelInterface return -1; } - virtual void ClientCheck(const char* name, char* name_res, int protocol, int options, int* status, int* result) + virtual void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result) {} - virtual void ClientOpen(const char* name, int pid, int* shared_engine, int* shared_client, int* shared_graph, int* result) + virtual void ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result) {} virtual void ClientOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, int* result) {} @@ -120,12 +121,31 @@ class JackClientChannelInterface virtual void InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result) {} - virtual void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int* result) + virtual void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result) {} virtual void InternalClientUnload(int refnum, int int_ref, int* status, int* result) {} + virtual void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char *path, jack_session_command_t **result) + {} + + virtual void SessionReply(int refnum, int *result) + {} + + virtual void GetUUIDForClientName(int refnum, const char *client_name, char *uuid_res, int *result) + {} + + virtual void GetClientNameForUUID(int refnum, const char *uuid, char *name_res, int *result) + {} + + virtual void ReserveClientName(int refnum, const char *client_name, const char *uuid, int *result) + {} + + virtual bool IsChannelThread() + { + return false; + } }; } diff --git a/common/JackClient.cpp b/common/JackClient.cpp index 800c70f6..3a59140e 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -112,9 +112,9 @@ pthread_t JackClient::GetThreadID() } /*! - In "async" mode, the server does not synchronize itself on the output drivers, thus it would never "consume" the activations. - The synchronization primitives for drivers are setup in "flush" mode that to not keep unneeded activations. - Drivers synchro are setup in "flush" mode if server is "async" and NOT freewheel. + In "async" mode, the server does not synchronize itself on the output drivers, thus it would never "consume" the activations. + The synchronization primitives for drivers are setup in "flush" mode that to not keep unneeded activations. + Drivers synchro are setup in "flush" mode if server is "async" and NOT freewheel. */ void JackClient::SetupDriverSync(bool freewheel) { @@ -170,7 +170,7 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, case kAddClient: jack_log("JackClient::kAddClient fName = %s name = %s", GetClientControl()->fName, name); - if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) { // Don't call the callback for the registering client itself + if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) { // Don't call the callback for the registering client itself fClientRegistration(name, 1, fClientRegistrationArg); } break; @@ -272,6 +272,23 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, fInfoShutdown = NULL; } break; + + case kSessionCallback: + jack_log("JackClient::kSessionCallback"); + if (fSession) { + jack_session_event_t *event = (jack_session_event_t *) malloc( sizeof(jack_session_event_t) ); + char uuid_buf[JACK_UUID_SIZE]; + event->type = (jack_session_event_type_t) value1; + event->session_dir = strdup( message ); + event->command_line = NULL; + event->flags = (jack_session_flags_t) 0; + snprintf( uuid_buf, sizeof(uuid_buf), "%d", GetClientControl()->fSessionID ); + event->client_uuid = strdup( uuid_buf ); + fImmediateSessionReply = false; + fSession(event, fSessionArg); + res = (fImmediateSessionReply) ? 1 : 2; + } + break; } } @@ -280,7 +297,7 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, /*! \brief We need to start thread before activating in the server, otherwise the FW driver - connected to the client may not be activated. + connected to the client may not be activated. */ int JackClient::Activate() { @@ -410,7 +427,7 @@ inline void JackClient::ExecuteThread() while (true) { CycleWaitAux(); CycleSignalAux(CallProcessCallback()); - } + } } inline jack_nframes_t JackClient::CycleWaitAux() @@ -981,6 +998,19 @@ int JackClient::SetProcessThread(JackThreadCallback fun, void *arg) } } +int JackClient::SetSessionCallback(JackSessionCallback callback, void *arg) +{ + if (IsActive()) { + jack_error("You cannot set callbacks on an active client"); + return -1; + } else { + GetClientControl()->fCallback[kSessionCallback] = (callback != NULL); + fSessionArg = arg; + fSession = callback; + return 0; + } +} + //------------------ // Internal clients //------------------ @@ -1027,9 +1057,8 @@ int JackClient::InternalClientLoad(const char* client_name, jack_options_t optio return 0; } - int int_ref = 0; - int result = -1; - fChannel->InternalClientLoad(GetClientControl()->fRefNum, client_name, va->load_name, va->load_init, options, (int*)status, &int_ref, &result); + int int_ref, result = -1; + fChannel->InternalClientLoad(GetClientControl()->fRefNum, client_name, va->load_name, va->load_init, options, (int*)status, &int_ref, -1, &result); return int_ref; } @@ -1039,6 +1068,71 @@ void JackClient::InternalClientUnload(int ref, jack_status_t* status) fChannel->InternalClientUnload(GetClientControl()->fRefNum, ref, (int*)status, &result); } +//------------------ +// Session API +//------------------ + +jack_session_command_t *JackClient::SessionNotify( const char* target, jack_session_event_type_t type, const char* path ) +{ + jack_session_command_t *res; + fChannel->SessionNotify( GetClientControl()->fRefNum, target, type, path, &res ); + return res; +} + +int JackClient::SessionReply( jack_session_event_t *ev ) +{ + if (ev->command_line) { + strncpy( GetClientControl()->fSessionCommand, ev->command_line, sizeof(GetClientControl()->fSessionCommand) ); + } else { + GetClientControl()->fSessionCommand[0] = '\0'; + } + + GetClientControl()->fSessionFlags = ev->flags; + + jack_log( "JackClient::SessionReply... we are here" ); + if (fChannel->IsChannelThread()) { + jack_log( "JackClient::SessionReply... in callback reply" ); + fImmediateSessionReply = true; + return 0; + } + + jack_log( "JackClient::SessionReply... out of cb" ); + + int res; + fChannel->SessionReply( GetClientControl()->fRefNum, &res); + return res; +} + +char* JackClient::GetUUIDForClientName(const char* client_name) +{ + char uuid_res[JACK_UUID_SIZE]; + int result = -1; + fChannel->GetUUIDForClientName( GetClientControl()->fRefNum, client_name, uuid_res, &result); + + if (result) + return NULL; + + return strdup(uuid_res); +} + +char* JackClient::GetClientNameForUUID(const char* uuid) +{ + char name_res[JACK_CLIENT_NAME_SIZE + 1]; + int result = -1; + fChannel->GetClientNameForUUID(GetClientControl()->fRefNum, uuid, name_res, &result); + + if (result) + return NULL; + + return strdup(name_res); +} + +int JackClient::ReserveClientName(const char *name, const char* uuid) +{ + int result = -1; + fChannel->ReserveClientName( GetClientControl()->fRefNum, name, uuid, &result); + return result; +} } // end of namespace diff --git a/common/JackClient.h b/common/JackClient.h index 215098a0..cd5ab090 100644 --- a/common/JackClient.h +++ b/common/JackClient.h @@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackPlatformPlug.h" #include "JackChannel.h" #include "types.h" +#include "session.h" #include "varargs.h" #include @@ -66,6 +67,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface JackTimebaseCallback fTimebase; JackSyncCallback fSync; JackThreadCallback fThreadFun; + JackSessionCallback fSession; void* fProcessArg; void* fGraphOrderArg; @@ -83,12 +85,15 @@ class JackClient : public JackClientInterface, public JackRunnableInterface void* fTimebaseArg; void* fSyncArg; void* fThreadFunArg; + void* fSessionArg; char fServerName[64]; JackThread fThread; /*! Thread to execute the Process function */ detail::JackClientChannelInterface* fChannel; JackSynchro* fSynchroTable; std::list fPortList; + + bool fImmediateSessionReply; int StartThread(); void SetupDriverSync(bool freewheel); @@ -118,7 +123,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface JackClient(JackSynchro* table); virtual ~JackClient(); - virtual int Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status) = 0; + virtual int Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) = 0; virtual int Close(); virtual JackGraphManager* GetGraphManager() const = 0; @@ -173,6 +178,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface virtual int SetPortRegistrationCallback(JackPortRegistrationCallback callback, void* arg); virtual int SetPortConnectCallback(JackPortConnectCallback callback, void *arg); virtual int SetPortRenameCallback(JackPortRenameCallback callback, void *arg); + virtual int SetSessionCallback(JackSessionCallback callback, void *arg); // Internal clients virtual char* GetInternalClientName(int ref); @@ -184,6 +190,13 @@ class JackClient : public JackClientInterface, public JackRunnableInterface void CycleSignal(int status); int SetProcessThread(JackThreadCallback fun, void *arg); + // Session api + virtual jack_session_command_t *SessionNotify(const char *target, jack_session_event_type_t type, const char *path); + virtual int SessionReply(jack_session_event_t *ev); +char* GetUUIDForClientName(const char* client_name); +char* GetClientNameForUUID(const char* uuid); +int ReserveClientName(const char *name, const char* uuid); + // JackRunnableInterface interface bool Init(); bool Execute(); diff --git a/common/JackClientControl.h b/common/JackClientControl.h index a82313c7..98f2ad31 100644 --- a/common/JackClientControl.h +++ b/common/JackClientControl.h @@ -26,6 +26,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackSynchro.h" #include "JackNotification.h" +#include "jack/session.h" + namespace Jack { @@ -44,22 +46,26 @@ struct JackClientControl : public JackShmMemAble int fPID; bool fActive; - JackClientControl(const char* name, int pid, int refnum) + int fSessionID; + char fSessionCommand[JACK_SESSION_COMMAND_SIZE]; + jack_session_flags_t fSessionFlags; + + JackClientControl(const char* name, int pid, int refnum, int uuid) { - Init(name, pid, refnum); + Init(name, pid, refnum, uuid); } JackClientControl(const char* name) { - Init(name, 0, -1); + Init(name, 0, -1, -1); } JackClientControl() { - Init("", 0, -1); + Init("", 0, -1, -1); } - void Init(const char* name, int pid, int refnum) + void Init(const char* name, int pid, int refnum, int uuid) { strcpy(fName, name); for (int i = 0; i < kMaxNotification; i++) @@ -77,6 +83,8 @@ struct JackClientControl : public JackShmMemAble fTransportSync = false; fTransportTimebase = false; fActive = false; + + fSessionID = uuid; } } POST_PACKED_STRUCTURE; diff --git a/common/JackConstants.h b/common/JackConstants.h index 94a7e422..33d52cbd 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -24,7 +24,7 @@ #include "config.h" #endif -#define VERSION "1.9.6" +#define VERSION "1.9.7" #define BUFFER_SIZE_MAX 8192 @@ -33,6 +33,8 @@ #define JACK_CLIENT_NAME_SIZE 64 #define JACK_MESSAGE_SIZE 256 +#define JACK_UUID_SIZE 32 +#define JACK_SESSION_COMMAND_SIZE 256 #ifndef PORT_NUM #define PORT_NUM 2048 @@ -71,6 +73,7 @@ #define FREEWHEEL_DRIVER_TIMEOUT 10 // in sec #define DRIVER_TIMEOUT_FACTOR 10 + #define NO_PORT 0xFFFE #define EMPTY 0xFFFD diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index f4850207..cd0ec2bf 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -450,21 +450,21 @@ sigset_t jackctl_setup_signals( unsigned int flags) { - if ((waitEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) { + if ((waitEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) { jack_error("CreateEvent fails err = %ld", GetLastError()); return 0; } - (void) signal(SIGINT, do_nothing_handler); + (void) signal(SIGINT, do_nothing_handler); (void) signal(SIGABRT, do_nothing_handler); (void) signal(SIGTERM, do_nothing_handler); - return (sigset_t)waitEvent; + return (sigset_t)waitEvent; } void jackctl_wait_signals(sigset_t signals) { - if (WaitForSingleObject(waitEvent, INFINITE) != WAIT_OBJECT_0) { + if (WaitForSingleObject(waitEvent, INFINITE) != WAIT_OBJECT_0) { jack_error("WaitForSingleObject fails err = %ld", GetLastError()); } } @@ -1179,7 +1179,7 @@ EXPORT bool jackctl_server_load_internal( { int status; if (server_ptr->engine != NULL) { - server_ptr->engine->InternalClientLoad(internal->desc_ptr->name, internal->desc_ptr->name, internal->set_parameters, JackNullOption, &internal->refnum, &status); + server_ptr->engine->InternalClientLoad(internal->desc_ptr->name, internal->desc_ptr->name, internal->set_parameters, JackNullOption, &internal->refnum, -1, &status); return (internal->refnum > 0); } else { return false; diff --git a/common/JackDebugClient.cpp b/common/JackDebugClient.cpp index 6a90fcdc..77a6df28 100644 --- a/common/JackDebugClient.cpp +++ b/common/JackDebugClient.cpp @@ -36,8 +36,8 @@ namespace Jack JackDebugClient::JackDebugClient(JackClient * client) { - fTotalPortNumber = 1; // The total number of port opened and maybe closed. Historical view. - fOpenPortNumber = 0; // The current number of opened port. + fTotalPortNumber = 1; // The total number of port opened and maybe closed. Historical view. + fOpenPortNumber = 0; // The current number of opened port. fIsActivated = 0; fIsDeactivated = 0; fIsClosed = 0; @@ -78,9 +78,9 @@ JackDebugClient::~JackDebugClient() delete fClient; } -int JackDebugClient::Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status) +int JackDebugClient::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) { - int res = fClient->Open(server_name, name, options, status); + int res = fClient->Open(server_name, name, uuid, options, status); char provstr[256]; char buffer[256]; time_t curtime; @@ -210,8 +210,8 @@ int JackDebugClient::PortUnRegister(jack_port_id_t port_index) int res = fClient->PortUnRegister(port_index); fOpenPortNumber--; int i; - for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history - if (fPortList[i].idport == port_index) { // We found the last record + for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history + if (fPortList[i].idport == port_index) { // We found the last record if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! : '" << fClientName << "' id deregistering port '" << fPortList[i].name << "' that have already been unregistered !" << endl; fPortList[i].IsUnregistered++; @@ -233,8 +233,8 @@ int JackDebugClient::PortConnect(const char* src, const char* dst) *fStream << "!!! ERROR !!! Trying to connect a port ( " << src << " to " << dst << ") while the client has not been activated !" << endl; int i; int res = fClient->PortConnect( src, dst); - for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history - if (strcmp(fPortList[i].name, src) == 0) { // We found the last record in sources + for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history + if (strcmp(fPortList[i].name, src) == 0) { // We found the last record in sources if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! Connecting port " << src << " previoulsy unregistered !" << endl; fPortList[i].IsConnected++; @@ -293,8 +293,8 @@ int JackDebugClient::PortDisconnect(jack_port_id_t src) *fStream << "!!! ERROR !!! : Trying to disconnect port " << src << " while that client has not been activated !" << endl; int res = fClient->PortDisconnect(src); int i; - for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history - if (fPortList[i].idport == src) { // We found the record in sources + for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history + if (fPortList[i].idport == src) { // We found the record in sources if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! : Disconnecting port " << src << " previoulsy unregistered !" << endl; fPortList[i].IsConnected--; diff --git a/common/JackDebugClient.h b/common/JackDebugClient.h index 6a31f432..fc9ebf55 100644 --- a/common/JackDebugClient.h +++ b/common/JackDebugClient.h @@ -53,8 +53,8 @@ class JackDebugClient : public JackClient JackClient* fClient; std::ofstream* fStream; PortFollower fPortList[MAX_PORT_HISTORY]; // Arbitrary value... To be tuned... - int fTotalPortNumber; // The total number of port opened and maybe closed. Historical view. - int fOpenPortNumber; // The current number of opened port. + int fTotalPortNumber; // The total number of port opened and maybe closed. Historical view. + int fOpenPortNumber; // The current number of opened port. int fIsActivated; int fIsDeactivated; int fIsClosed; @@ -68,7 +68,7 @@ class JackDebugClient : public JackClient JackDebugClient(JackClient* fTheClient); virtual ~JackDebugClient(); - virtual int Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status); + virtual int Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status); int Close(); virtual JackGraphManager* GetGraphManager() const; diff --git a/common/JackDriverLoader.cpp b/common/JackDriverLoader.cpp index 704a4ef9..80ea3318 100644 --- a/common/JackDriverLoader.cpp +++ b/common/JackDriverLoader.cpp @@ -32,7 +32,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. jack_driver_desc_t * jackctl_driver_get_desc(jackctl_driver_t * driver); -SERVER_EXPORT void jack_print_driver_options (jack_driver_desc_t* desc, FILE* file) +EXPORT void jack_print_driver_options (jack_driver_desc_t* desc, FILE* file) { unsigned long i; char arg_default[JACK_DRIVER_PARAM_STRING_MAX + 1]; @@ -75,7 +75,7 @@ jack_print_driver_param_usage (jack_driver_desc_t * desc, unsigned long param, F fprintf (file, "%s\n", desc->params[param].long_desc); } -SERVER_EXPORT void jack_free_driver_params(JSList * driver_params) +EXPORT void jack_free_driver_params(JSList * driver_params) { JSList *node_ptr = driver_params; JSList *next_node_ptr; @@ -228,7 +228,7 @@ jack_parse_driver_params (jack_driver_desc_t * desc, int argc, char* argv[], JSL return 0; } -SERVER_EXPORT int +EXPORT int jackctl_parse_driver_params (jackctl_driver *driver_ptr, int argc, char* argv[]) { struct option * long_options; @@ -436,17 +436,17 @@ jack_get_descriptor (JSList * drivers, const char * sofile, const char * symbol) #ifdef WIN32 if ((so_get_descriptor == NULL) && (dlerr = GetLastError()) != 0) { - jack_log("jack_get_descriptor : dll is not a driver, err = %ld", dlerr); + jack_error("jack_get_descriptor : dll is not a driver, err = %ld", dlerr); #else if ((so_get_descriptor == NULL) && (dlerr = dlerror ()) != NULL) { - jack_log("jack_get_descriptor err = %s", dlerr); + jack_error("jack_get_descriptor err = %s", dlerr); #endif UnloadDriverModule(dlhandle); free(filename); return NULL; } - + if ((descriptor = so_get_descriptor ()) == NULL) { jack_error("driver from '%s' returned NULL descriptor", filename); UnloadDriverModule(dlhandle); @@ -467,7 +467,7 @@ jack_get_descriptor (JSList * drivers, const char * sofile, const char * symbol) /* check it doesn't exist already */ for (node = drivers; node; node = jack_slist_next (node)) { other_descriptor = (jack_driver_desc_t *) node->data; - + if (strcmp(descriptor->name, other_descriptor->name) == 0) { jack_error("the drivers in '%s' and '%s' both have the name '%s'; using the first", other_descriptor->file, filename, other_descriptor->name); @@ -563,6 +563,8 @@ jack_drivers_load (JSList * drivers) { desc = jack_get_descriptor (drivers, filedata.cFileName, "driver_get_descriptor"); if (desc) { driver_list = jack_slist_append (driver_list, desc); + } else { + jack_error ("jack_get_descriptor returns null for \'%s\'", filedata.cFileName); } } while (FindNextFile(file, &filedata)); @@ -601,7 +603,7 @@ jack_drivers_load (JSList * drivers) { } while ((dir_entry = readdir(dir_stream))) { - + /* check the filename is of the right format */ if (strncmp ("jack_", dir_entry->d_name, 5) != 0) { continue; @@ -617,8 +619,11 @@ jack_drivers_load (JSList * drivers) { } desc = jack_get_descriptor (drivers, dir_entry->d_name, "driver_get_descriptor"); + if (desc) { driver_list = jack_slist_append (driver_list, desc); + } else { + jack_error ("jack_get_descriptor returns null for \'%s\'", dir_entry->d_name); } } @@ -687,6 +692,8 @@ jack_internals_load (JSList * internals) { desc = jack_get_descriptor (internals, filedata.cFileName, "jack_get_descriptor"); if (desc) { driver_list = jack_slist_append (driver_list, desc); + } else { + jack_error ("jack_get_descriptor returns null for \'%s\'", filedata.cFileName); } } while (FindNextFile(file, &filedata)); @@ -743,6 +750,8 @@ jack_internals_load (JSList * internals) { desc = jack_get_descriptor (internals, dir_entry->d_name, "jack_get_descriptor"); if (desc) { driver_list = jack_slist_append (driver_list, desc); + } else { + jack_error ("jack_get_descriptor returns null for \'%s\'", dir_entry->d_name); } } diff --git a/common/JackDriverLoader.h b/common/JackDriverLoader.h index f68fb041..17777e54 100644 --- a/common/JackDriverLoader.h +++ b/common/JackDriverLoader.h @@ -68,9 +68,9 @@ jack_driver_desc_t * jack_find_driver_descriptor (JSList * drivers, const char * JSList * jack_drivers_load (JSList * drivers); JSList * jack_internals_load (JSList * internals); -SERVER_EXPORT int jackctl_parse_driver_params (jackctl_driver * driver_ptr, int argc, char* argv[]); -SERVER_EXPORT void jack_free_driver_params(JSList * param_ptr); -SERVER_EXPORT void jack_print_driver_options(jack_driver_desc_t* desc, FILE* file); +EXPORT int jackctl_parse_driver_params (jackctl_driver * driver_ptr, int argc, char* argv[]); +EXPORT void jack_free_driver_params(JSList * param_ptr); +EXPORT void jack_print_driver_options(jack_driver_desc_t* desc, FILE* file); #endif diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index 8c205975..28f54432 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -44,12 +44,15 @@ JackEngine::JackEngine(JackGraphManager* manager, fEngineControl = control; for (int i = 0; i < CLIENT_NUM; i++) fClientTable[i] = NULL; + fLastSwitchUsecs = 0; + fMaxUUID = 0; + fSessionPendingReplies = 0; + fSessionTransaction = NULL; + fSessionResult = NULL; } JackEngine::~JackEngine() -{ - jack_log("JackEngine::~JackEngine"); -} +{} int JackEngine::Open() { @@ -134,7 +137,7 @@ void JackEngine::ReleaseRefnum(int ref) void JackEngine::ProcessNext(jack_time_t cur_cycle_begin) { fLastSwitchUsecs = cur_cycle_begin; - if (fGraphManager->RunNextGraph()) // True if the graph actually switched to a new state + if (fGraphManager->RunNextGraph()) // True if the graph actually switched to a new state fChannel.Notify(ALL_CLIENTS, kGraphOrderCallback, 0); fSignal.Signal(); // Signal for threads waiting for next cycle } @@ -386,7 +389,7 @@ int JackEngine::InternalClientUnload(int refnum, int* status) // Client management //------------------- -int JackEngine::ClientCheck(const char* name, char* name_res, int protocol, int options, int* status) +int JackEngine::ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status) { // Clear status *status = 0; @@ -400,7 +403,11 @@ int JackEngine::ClientCheck(const char* name, char* name_res, int protocol, int return -1; } - if (ClientCheckName(name)) { + std::map::iterator res = fReservationMap.find(uuid); + + if (res != fReservationMap.end()) { + strncpy( name_res, res->second.c_str(), JACK_CLIENT_NAME_SIZE ); + } else if (ClientCheckName(name)) { *status |= JackNameNotUnique; @@ -426,7 +433,7 @@ bool JackEngine::GenerateUniqueName(char* name) if (length > JACK_CLIENT_NAME_SIZE - 4) { jack_error("%s exists and is too long to make unique", name); - return true; /* failure */ + return true; /* failure */ } /* generate a unique name by appending "-01".."-99" */ @@ -460,9 +467,32 @@ bool JackEngine::ClientCheckName(const char* name) return true; } + for (std::map::iterator i=fReservationMap.begin(); i!=fReservationMap.end(); i++) { + if (i->second == name) + return true; + } + return false; } +int JackEngine::GetNewUUID() +{ + return fMaxUUID++; +} + +void JackEngine::EnsureUUID(int uuid) +{ + if (uuid > fMaxUUID) + fMaxUUID = uuid+1; + + for (int i = 0; i < CLIENT_NUM; i++) { + JackClientInterface* client = fClientTable[i]; + if (client && (client->GetClientControl()->fSessionID==uuid)) { + client->GetClientControl()->fSessionID = GetNewUUID(); + } + } +} + int JackEngine::GetClientPID(const char* name) { for (int i = 0; i < CLIENT_NUM; i++) { @@ -486,9 +516,26 @@ int JackEngine::GetClientRefNum(const char* name) } // Used for external clients -int JackEngine::ClientExternalOpen(const char* name, int pid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager) +int JackEngine::ClientExternalOpen(const char* name, int pid, int uuid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager) { - jack_log("JackEngine::ClientExternalOpen: name = %s ", name); + char real_name[JACK_CLIENT_NAME_SIZE+1]; + + if (uuid < 0) { + uuid = GetNewUUID(); + strncpy( real_name, name, JACK_CLIENT_NAME_SIZE ); + } else { + std::map::iterator res = fReservationMap.find(uuid); + if (res != fReservationMap.end()) { + strncpy( real_name, res->second.c_str(), JACK_CLIENT_NAME_SIZE ); + fReservationMap.erase(uuid); + } else { + strncpy( real_name, name, JACK_CLIENT_NAME_SIZE ); + } + + EnsureUUID(uuid); + } + + jack_log("JackEngine::ClientExternalOpen: uuid=%d, name = %s ", uuid, real_name); int refnum = AllocateRefnum(); if (refnum < 0) { @@ -498,12 +545,12 @@ int JackEngine::ClientExternalOpen(const char* name, int pid, int* ref, int* sha JackExternalClient* client = new JackExternalClient(); - if (!fSynchroTable[refnum].Allocate(name, fEngineControl->fServerName, 0)) { + if (!fSynchroTable[refnum].Allocate(real_name, fEngineControl->fServerName, 0)) { jack_error("Cannot allocate synchro"); goto error; } - if (client->Open(name, pid, refnum, shared_client) < 0) { + if (client->Open(real_name, pid, refnum, uuid, shared_client) < 0) { jack_error("Cannot open client"); goto error; } @@ -516,7 +563,7 @@ int JackEngine::ClientExternalOpen(const char* name, int pid, int* ref, int* sha fClientTable[refnum] = client; - if (NotifyAddClient(client, name, refnum) < 0) { + if (NotifyAddClient(client, real_name, refnum) < 0) { jack_error("Cannot notify add client"); goto error; } @@ -863,5 +910,135 @@ int JackEngine::PortRename(int refnum, jack_port_id_t port, const char* name) return 0; } +void JackEngine::SessionNotify(int refnum, const char *target, jack_session_event_type_t type, const char *path, JackChannelTransaction *socket) +{ + if (fSessionPendingReplies != 0) { + JackSessionNotifyResult res(-1); + res.Write(socket); + jack_log("JackEngine::SessionNotify ... busy"); + return; + } + + for (int i = 0; i < CLIENT_NUM; i++) { + JackClientInterface* client = fClientTable[i]; + if (client && (client->GetClientControl()->fSessionID < 0)) { + client->GetClientControl()->fSessionID = GetNewUUID(); + } + } + fSessionResult = new JackSessionNotifyResult(); + + for (int i = 0; i < CLIENT_NUM; i++) { + JackClientInterface* client = fClientTable[i]; + if (client && client->GetClientControl()->fCallback[kSessionCallback]) { + + // check if this is a notification to a specific client. + if (target!=NULL && strlen(target)!=0) { + if (strcmp(target, client->GetClientControl()->fName)) { + continue; + } + } + + char path_buf[JACK_PORT_NAME_SIZE]; + snprintf( path_buf, sizeof(path_buf), "%s%s%c", path, client->GetClientControl()->fName, DIR_SEPARATOR ); + + int res = JackTools::MkDir(path_buf); + if (res) + jack_error( "JackEngine::SessionNotify: can not create session directory '%s'", path_buf ); + + int result = client->ClientNotify(i, client->GetClientControl()->fName, kSessionCallback, true, path_buf, (int) type, 0); + + if (result == 2) { + fSessionPendingReplies += 1; + } else if (result == 1) { + char uuid_buf[JACK_UUID_SIZE]; + snprintf( uuid_buf, sizeof(uuid_buf), "%d", client->GetClientControl()->fSessionID ); + fSessionResult->fCommandList.push_back( JackSessionCommand( uuid_buf, + client->GetClientControl()->fName, + client->GetClientControl()->fSessionCommand, + client->GetClientControl()->fSessionFlags )); + } + } + } + + if (fSessionPendingReplies == 0) { + fSessionResult->Write(socket); + delete fSessionResult; + fSessionResult = NULL; + } else { + fSessionTransaction = socket; + } +} + +void JackEngine::SessionReply(int refnum) +{ + JackClientInterface* client = fClientTable[refnum]; + char uuid_buf[JACK_UUID_SIZE]; + snprintf( uuid_buf, sizeof(uuid_buf), "%d", client->GetClientControl()->fSessionID ); + fSessionResult->fCommandList.push_back( JackSessionCommand( uuid_buf, + client->GetClientControl()->fName, + client->GetClientControl()->fSessionCommand, + client->GetClientControl()->fSessionFlags )); + fSessionPendingReplies -= 1; + + if (fSessionPendingReplies == 0) { + fSessionResult->Write(fSessionTransaction); + delete fSessionResult; + fSessionResult = NULL; + } +} + +void JackEngine::GetUUIDForClientName(const char *client_name, char *uuid_res, int *result) +{ + for (int i = 0; i < CLIENT_NUM; i++) { + JackClientInterface* client = fClientTable[i]; + + if (client && (strcmp(client_name, client->GetClientControl()->fName)==0)) { + snprintf(uuid_res, JACK_UUID_SIZE, "%d", client->GetClientControl()->fSessionID); + *result = 0; + return; + } + } + // did not find name. + *result = -1; + return; +} + +void JackEngine::GetClientNameForUUID(const char *uuid, char *name_res, int *result) +{ + for (int i = 0; i < CLIENT_NUM; i++) { + JackClientInterface* client = fClientTable[i]; + + if (!client) + continue; + + char uuid_buf[JACK_UUID_SIZE]; + snprintf(uuid_buf, JACK_UUID_SIZE, "%d", client->GetClientControl()->fSessionID); + + if (strcmp(uuid,uuid_buf) == 0) { + strncpy(name_res, client->GetClientControl()->fName, JACK_CLIENT_NAME_SIZE); + *result = 0; + return; + } + } + // did not find uuid. + *result = -1; + return; +} + +void JackEngine::ReserveClientName(const char *name, const char *uuid, int *result) +{ + jack_log( "JackEngine::ReserveClientName ( name = %s, uuid = %s )", name, uuid ); + + if (ClientCheckName(name)) { + *result = -1; + jack_log( "name already taken" ); + return; + } + + EnsureUUID(atoi(uuid)); + fReservationMap[atoi(uuid)] = name; + *result = 0; +} + } // end of namespace diff --git a/common/JackEngine.h b/common/JackEngine.h index 945d7e9c..ae969cb7 100644 --- a/common/JackEngine.h +++ b/common/JackEngine.h @@ -26,6 +26,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackMutex.h" #include "JackTransportEngine.h" #include "JackPlatformPlug.h" +#include namespace Jack { @@ -41,7 +42,7 @@ class JackExternalClient; class SERVER_EXPORT JackEngine : public JackLockAble { friend class JackLockedEngine; - + private: JackGraphManager* fGraphManager; @@ -52,6 +53,12 @@ class SERVER_EXPORT JackEngine : public JackLockAble JackProcessSync fSignal; jack_time_t fLastSwitchUsecs; + int fSessionPendingReplies; + JackChannelTransaction *fSessionTransaction; + JackSessionNotifyResult *fSessionResult; + std::map fReservationMap; + int fMaxUUID; + int ClientCloseAux(int refnum, JackClientInterface* client, bool wait); void CheckXRun(jack_time_t callback_usecs); @@ -69,12 +76,15 @@ class SERVER_EXPORT JackEngine : public JackLockAble void NotifyClient(int refnum, int event, int sync, const char* message, int value1, int value2); void NotifyClients(int event, int sync, const char* message, int value1, int value2); - + void NotifyPortRegistation(jack_port_id_t port_index, bool onoff); void NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst, bool onoff); void NotifyPortRename(jack_port_id_t src, const char* old_name); void NotifyActivate(int refnum); - + + int GetNewUUID(); + void EnsureUUID(int uuid); + bool CheckClient(int refnum) { return (refnum >= 0 && refnum < CLIENT_NUM && fClientTable[refnum] != NULL); @@ -87,10 +97,10 @@ class SERVER_EXPORT JackEngine : public JackLockAble int Open(); int Close(); - + // Client management - int ClientCheck(const char* name, char* name_res, int protocol, int options, int* status); - int ClientExternalOpen(const char* name, int pid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager); + int ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status); + int ClientExternalOpen(const char* name, int pid, int uuid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager); int ClientInternalOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, bool wait); int ClientExternalClose(int refnum); @@ -98,10 +108,10 @@ class SERVER_EXPORT JackEngine : public JackLockAble int ClientActivate(int refnum, bool is_real_time); int ClientDeactivate(int refnum); - + int GetClientPID(const char* name); int GetClientRefNum(const char* name); - + // Internal client management int GetInternalClientName(int int_ref, char* name_res); int InternalClientHandle(const char* client_name, int* status, int* int_ref); @@ -116,7 +126,7 @@ class SERVER_EXPORT JackEngine : public JackLockAble int PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst); int PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst); - + int PortRename(int refnum, jack_port_id_t port, const char* name); // Graph @@ -131,6 +141,13 @@ class SERVER_EXPORT JackEngine : public JackLockAble void NotifySampleRate(jack_nframes_t sample_rate); void NotifyFreewheel(bool onoff); void NotifyQuit(); + + void SessionNotify( int refnum, const char *target, jack_session_event_type_t type, const char *path, JackChannelTransaction *socket ); + void SessionReply( int refnum ); + + void GetUUIDForClientName(const char *client_name, char *uuid_res, int *result); + void GetClientNameForUUID(const char *uuid, char *name_res, int *result); + void ReserveClientName(const char *name, const char *uuid, int *result); }; diff --git a/common/JackError.cpp b/common/JackError.cpp index d78f95e5..7763d997 100644 --- a/common/JackError.cpp +++ b/common/JackError.cpp @@ -33,7 +33,7 @@ static bool change_thread_log_function(jack_log_function_t log_function) && jack_tls_set(JackGlobals::fKeyLogFunction, (void*)log_function)); } -SERVER_EXPORT int set_threaded_log_function() +EXPORT int set_threaded_log_function() { return change_thread_log_function(JackMessageBufferAdd); } @@ -88,7 +88,7 @@ static void jack_format_and_log(int level, const char *prefix, const char *fmt, log_function(level, buffer); } -SERVER_EXPORT void jack_error(const char *fmt, ...) +EXPORT void jack_error(const char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -96,7 +96,7 @@ SERVER_EXPORT void jack_error(const char *fmt, ...) va_end(ap); } -SERVER_EXPORT void jack_info(const char *fmt, ...) +EXPORT void jack_info(const char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -104,7 +104,7 @@ SERVER_EXPORT void jack_info(const char *fmt, ...) va_end(ap); } -SERVER_EXPORT void jack_log(const char *fmt,...) +EXPORT void jack_log(const char *fmt,...) { if (JackGlobals::fVerbose) { va_list ap; @@ -114,23 +114,23 @@ SERVER_EXPORT void jack_log(const char *fmt,...) } } -SERVER_EXPORT void default_jack_error_callback(const char *desc) +EXPORT void default_jack_error_callback(const char *desc) { fprintf(stderr, "%s\n", desc); fflush(stderr); } -SERVER_EXPORT void default_jack_info_callback(const char *desc) +EXPORT void default_jack_info_callback(const char *desc) { fprintf(stdout, "%s\n", desc); fflush(stdout); } -SERVER_EXPORT void silent_jack_error_callback(const char *desc) +EXPORT void silent_jack_error_callback(const char *desc) {} -SERVER_EXPORT void silent_jack_info_callback(const char *desc) +EXPORT void silent_jack_info_callback(const char *desc) {} -SERVER_EXPORT void (*jack_error_callback)(const char *desc) = &default_jack_error_callback; -SERVER_EXPORT void (*jack_info_callback)(const char *desc) = &default_jack_info_callback; +EXPORT void (*jack_error_callback)(const char *desc) = &default_jack_error_callback; +EXPORT void (*jack_info_callback)(const char *desc) = &default_jack_info_callback; diff --git a/common/JackError.h b/common/JackError.h index 03b4eada..425266f9 100644 --- a/common/JackError.h +++ b/common/JackError.h @@ -35,27 +35,27 @@ extern "C" #define LOG_LEVEL_INFO 1 #define LOG_LEVEL_ERROR 2 - SERVER_EXPORT void jack_error(const char *fmt, ...); + EXPORT void jack_error(const char *fmt, ...); - SERVER_EXPORT void jack_info(const char *fmt, ...); + EXPORT void jack_info(const char *fmt, ...); // like jack_info() but only if verbose mode is enabled - SERVER_EXPORT void jack_log(const char *fmt, ...); + EXPORT void jack_log(const char *fmt, ...); - SERVER_EXPORT extern void (*jack_error_callback)(const char *desc); - SERVER_EXPORT extern void (*jack_info_callback)(const char *desc); + EXPORT extern void (*jack_error_callback)(const char *desc); + EXPORT extern void (*jack_info_callback)(const char *desc); - SERVER_EXPORT extern void default_jack_error_callback(const char *desc); - SERVER_EXPORT extern void default_jack_info_callback(const char *desc); + EXPORT extern void default_jack_error_callback(const char *desc); + EXPORT extern void default_jack_info_callback(const char *desc); - SERVER_EXPORT extern void silent_jack_error_callback(const char *desc); - SERVER_EXPORT extern void silent_jack_info_callback(const char *desc); + EXPORT extern void silent_jack_error_callback(const char *desc); + EXPORT extern void silent_jack_info_callback(const char *desc); typedef void (* jack_log_function_t)(int level, const char *message); void jack_log_function(int level, const char *message); - SERVER_EXPORT int set_threaded_log_function(); + EXPORT int set_threaded_log_function(); #ifdef __cplusplus } diff --git a/common/JackExternalClient.cpp b/common/JackExternalClient.cpp index 4d56557b..1dca599a 100644 --- a/common/JackExternalClient.cpp +++ b/common/JackExternalClient.cpp @@ -41,7 +41,7 @@ int JackExternalClient::ClientNotify(int refnum, const char* name, int notify, i return result; } -int JackExternalClient::Open(const char* name, int pid, int refnum, int* shared_client) +int JackExternalClient::Open(const char* name, int pid, int refnum, int uuid, int* shared_client) { try { @@ -53,7 +53,7 @@ int JackExternalClient::Open(const char* name, int pid, int refnum, int* shared_ // Use "placement new" to allocate object in shared memory JackShmMemAble* shared_mem = static_cast(JackShmMem::operator new(sizeof(JackClientControl))); shared_mem->Init(); - fClientControl = new(shared_mem) JackClientControl(name, pid, refnum); + fClientControl = new(shared_mem) JackClientControl(name, pid, refnum, uuid); if (!fClientControl) { jack_error("Cannot allocate client shared memory segment"); diff --git a/common/JackExternalClient.h b/common/JackExternalClient.h index 29e0f7d6..c7c7fc42 100644 --- a/common/JackExternalClient.h +++ b/common/JackExternalClient.h @@ -39,14 +39,14 @@ class JackExternalClient : public JackClientInterface private: JackNotifyChannel fChannel; /*! Server/client communication channel */ - JackClientControl* fClientControl; /*! Client control in shared memory */ + JackClientControl* fClientControl; /*! Client control in shared memory */ public: JackExternalClient(); virtual ~JackExternalClient(); - int Open(const char* name, int pid, int refnum, int* shared_client); + int Open(const char* name, int pid, int refnum, int uuid, int* shared_client); int Close(); int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); diff --git a/common/JackInternalClient.cpp b/common/JackInternalClient.cpp index 1150a5e9..0f0e3e2a 100644 --- a/common/JackInternalClient.cpp +++ b/common/JackInternalClient.cpp @@ -63,7 +63,7 @@ JackInternalClient::~JackInternalClient() delete fChannel; } -int JackInternalClient::Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status) +int JackInternalClient::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) { int result; char name_res[JACK_CLIENT_NAME_SIZE + 1]; @@ -71,7 +71,7 @@ int JackInternalClient::Open(const char* server_name, const char* name, jack_opt strncpy(fServerName, server_name, sizeof(fServerName)); - fChannel->ClientCheck(name, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result); + fChannel->ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result); if (result < 0) { int status1 = *status; if (status1 & JackVersionError) @@ -198,11 +198,11 @@ JackLoadableInternalClient::~JackLoadableInternalClient() UnloadJackModule(fHandle); } -int JackLoadableInternalClient1::Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status) +int JackLoadableInternalClient1::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) { int res = -1; - if (JackInternalClient::Open(server_name, name, options, status) == 0) { + if (JackInternalClient::Open(server_name, name, uuid, options, status) == 0) { if (fInitialize((jack_client_t*)this, fObjectData) == 0) { res = 0; } else { @@ -214,11 +214,11 @@ int JackLoadableInternalClient1::Open(const char* server_name, const char* name, return res; } -int JackLoadableInternalClient2::Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status) +int JackLoadableInternalClient2::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) { int res = -1; - if (JackInternalClient::Open(server_name, name, options, status) == 0) { + if (JackInternalClient::Open(server_name, name, uuid, options, status) == 0) { if (fInitialize((jack_client_t*)this, fParameters) == 0) { res = 0; } else { diff --git a/common/JackInternalClient.h b/common/JackInternalClient.h index fe398139..19885c8b 100644 --- a/common/JackInternalClient.h +++ b/common/JackInternalClient.h @@ -46,14 +46,14 @@ class JackInternalClient : public JackClient JackInternalClient(JackServer* server, JackSynchro* table); virtual ~JackInternalClient(); - int Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status); + int Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status); JackGraphManager* GetGraphManager() const; JackEngineControl* GetEngineControl() const; JackClientControl* GetClientControl() const; - static JackGraphManager* fGraphManager; /*! Shared memory Port manager */ - static JackEngineControl* fEngineControl; /*! Shared engine cotrol */ + static JackGraphManager* fGraphManager; /*! Shared memory Port manager */ + static JackEngineControl* fEngineControl; /*! Shared engine cotrol */ }; /*! @@ -100,7 +100,7 @@ class JackLoadableInternalClient1 : public JackLoadableInternalClient {} int Init(const char* so_name); - int Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status); + int Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status); }; @@ -119,7 +119,7 @@ class JackLoadableInternalClient2 : public JackLoadableInternalClient {} int Init(const char* so_name); - int Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status); + int Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status); }; diff --git a/common/JackInternalClientChannel.h b/common/JackInternalClientChannel.h index 93130ca5..8deb6b7b 100644 --- a/common/JackInternalClientChannel.h +++ b/common/JackInternalClientChannel.h @@ -50,9 +50,9 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface return 0; } - void ClientCheck(const char* name, char* name_res, int protocol, int options, int* status, int* result) + void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result) { - *result = fEngine->ClientCheck(name, name_res, protocol, options, status); + *result = fEngine->ClientCheck(name, uuid, name_res, protocol, options, status); } void ClientOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, int* result) { @@ -112,6 +112,11 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface *result = fServer->SetFreewheel(onoff); } + void SessionNotify( int refnum, const char *target, jack_session_event_type_t type, const char *path, jack_session_command_t **result ) + { + *result = NULL; + } + void ReleaseTimebase(int refnum, int* result) { *result = fServer->ReleaseTimebase(refnum); @@ -132,9 +137,9 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface *result = fEngine->InternalClientHandle(client_name, status, int_ref); } - void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int* result) + void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result) { - *result = fServer->InternalClientLoad(client_name, so_name, objet_data, options, int_ref, status); + *result = fServer->InternalClientLoad(client_name, so_name, objet_data, options, int_ref, uuid, status); } void InternalClientUnload(int refnum, int int_ref, int* status, int* result) diff --git a/common/JackLibAPI.cpp b/common/JackLibAPI.cpp index 73f290db..f22b5e07 100644 --- a/common/JackLibAPI.cpp +++ b/common/JackLibAPI.cpp @@ -57,7 +57,7 @@ int JackLibGlobals::fClientCount = 0; jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t* status) { - jack_varargs_t va; /* variable arguments */ + jack_varargs_t va; /* variable arguments */ jack_status_t my_status; JackClient* client; @@ -68,8 +68,8 @@ jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t optio jack_log("jack_client_new %s", client_name); - if (status == NULL) /* no status from caller? */ - status = &my_status; /* use local status word */ + if (status == NULL) /* no status from caller? */ + status = &my_status; /* use local status word */ *status = (jack_status_t)0; /* validate parameters */ @@ -96,7 +96,7 @@ jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t optio client = new JackLibClient(GetSynchroTable()); } - int res = client->Open(va.server_name, client_name, options, status); + int res = client->Open(va.server_name, client_name, va.session_id, options, status); if (res < 0) { delete client; JackLibGlobals::Destroy(); // jack library destruction @@ -149,7 +149,7 @@ jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t opti client = new JackLibClient(GetSynchroTable()); } - int res = client->Open(va.server_name, client_name, options, status); + int res = client->Open(va.server_name, client_name, va.session_id, options, status); if (res < 0) { delete client; JackLibGlobals::Destroy(); // jack library destruction diff --git a/common/JackLibClient.cpp b/common/JackLibClient.cpp index effdfc6f..2b54aa16 100644 --- a/common/JackLibClient.cpp +++ b/common/JackLibClient.cpp @@ -67,7 +67,7 @@ JackLibClient::~JackLibClient() delete fChannel; } -int JackLibClient::Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status) +int JackLibClient::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) { int shared_engine, shared_client, shared_graph, result; jack_log("JackLibClient::Open name = %s", name); @@ -76,7 +76,7 @@ int JackLibClient::Open(const char* server_name, const char* name, jack_options_ // Open server/client channel char name_res[JACK_CLIENT_NAME_SIZE + 1]; - if (fChannel->Open(server_name, name, name_res, this, options, status) < 0) { + if (fChannel->Open(server_name, name, uuid, name_res, this, options, status) < 0) { jack_error("Cannot connect to the server"); goto error; } @@ -88,7 +88,7 @@ int JackLibClient::Open(const char* server_name, const char* name, jack_options_ } // Require new client - fChannel->ClientOpen(name_res, JackTools::GetPID(), &shared_engine, &shared_client, &shared_graph, &result); + fChannel->ClientOpen(name_res, JackTools::GetPID(), uuid, &shared_engine, &shared_client, &shared_graph, &result); if (result < 0) { jack_error("Cannot open %s client", name_res); goto error; diff --git a/common/JackLibClient.h b/common/JackLibClient.h index 0621ed15..f2820601 100644 --- a/common/JackLibClient.h +++ b/common/JackLibClient.h @@ -37,14 +37,14 @@ class JackLibClient : public JackClient private: - JackShmReadWritePtr1 fClientControl; /*! Shared client control */ + JackShmReadWritePtr1 fClientControl; /*! Shared client control */ public: JackLibClient(JackSynchro* table); virtual ~JackLibClient(); - int Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status); + int Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status); int ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); diff --git a/common/JackLockedEngine.h b/common/JackLockedEngine.h index 827ab527..b1620859 100644 --- a/common/JackLockedEngine.h +++ b/common/JackLockedEngine.h @@ -96,18 +96,18 @@ class SERVER_EXPORT JackLockedEngine } // Client management - int ClientCheck(const char* name, char* name_res, int protocol, int options, int* status) + int ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status) { TRY_CALL JackLock lock(&fEngine); - return fEngine.ClientCheck(name, name_res, protocol, options, status); + return fEngine.ClientCheck(name, uuid, name_res, protocol, options, status); CATCH_EXCEPTION_RETURN } - int ClientExternalOpen(const char* name, int pid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager) + int ClientExternalOpen(const char* name, int pid, int uuid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager) { TRY_CALL JackLock lock(&fEngine); - return fEngine.ClientExternalOpen(name, pid, ref, shared_engine, shared_client, shared_graph_manager); + return fEngine.ClientExternalOpen(name, pid, uuid, ref, shared_engine, shared_client, shared_graph_manager); CATCH_EXCEPTION_RETURN } int ClientInternalOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, bool wait) @@ -306,7 +306,44 @@ class SERVER_EXPORT JackLockedEngine return fEngine.NotifyQuit(); CATCH_EXCEPTION } + + void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char *path, JackChannelTransaction *socket) + { + TRY_CALL + JackLock lock(&fEngine); + fEngine.SessionNotify(refnum, target, type, path, socket); + CATCH_EXCEPTION + } + + void SessionReply(int refnum) + { + TRY_CALL + JackLock lock(&fEngine); + fEngine.SessionReply(refnum); + CATCH_EXCEPTION + } + void GetUUIDForClientName(const char *client_name, char *uuid_res, int *result) + { + TRY_CALL + JackLock lock(&fEngine); + fEngine.GetUUIDForClientName(client_name, uuid_res, result); + CATCH_EXCEPTION + } + void GetClientNameForUUID(const char *uuid, char *name_res, int *result) + { + TRY_CALL + JackLock lock(&fEngine); + fEngine.GetClientNameForUUID(uuid, name_res, result); + CATCH_EXCEPTION + } + void ReserveClientName(const char *name, const char *uuid, int *result) + { + TRY_CALL + JackLock lock(&fEngine); + fEngine.ReserveClientName(name, uuid, result); + CATCH_EXCEPTION + } }; } // end of namespace diff --git a/common/JackNetOneDriver.cpp b/common/JackNetOneDriver.cpp index 3259b563..4364606b 100644 --- a/common/JackNetOneDriver.cpp +++ b/common/JackNetOneDriver.cpp @@ -54,36 +54,36 @@ namespace Jack { jack_log ( "JackNetOneDriver::JackNetOneDriver port %d", port ); -#ifdef WIN32 - WSADATA wsa; - int rc = WSAStartup(MAKEWORD(2,0),&wsa); -#endif - - netjack_init( & (this->netj), - NULL, // client - name, - capture_ports, - playback_ports, - midi_input_ports, - midi_output_ports, - sample_rate, - period_size, - port, - transport_sync, - resample_factor, - 0, - bitdepth, - use_autoconfig, - latency, - redundancy, - dont_htonl_floats, - always_deadline, - jitter_val); + #ifdef WIN32 + WSADATA wsa; + int rc = WSAStartup(MAKEWORD(2,0),&wsa); + #endif + + netjack_init( & (this->netj), + NULL, // client + name, + capture_ports, + playback_ports, + midi_input_ports, + midi_output_ports, + sample_rate, + period_size, + port, + transport_sync, + resample_factor, + 0, + bitdepth, + use_autoconfig, + latency, + redundancy, + dont_htonl_floats, + always_deadline, + jitter_val); } JackNetOneDriver::~JackNetOneDriver() { - // No destructor yet. + // No destructor yet. } //open, close, attach and detach------------------------------------------------------ @@ -135,49 +135,49 @@ namespace Jack int JackNetOneDriver::AllocPorts() { - jack_port_id_t port_id; - char buf[64]; - unsigned int chn; + jack_port_id_t port_id; + char buf[64]; + unsigned int chn; - //if (netj.handle_transport_sync) - // jack_set_sync_callback(netj.client, (JackSyncCallback) net_driver_sync_cb, NULL); + //if (netj.handle_transport_sync) + // jack_set_sync_callback(netj.client, (JackSyncCallback) net_driver_sync_cb, NULL); - for (chn = 0; chn < netj.capture_channels_audio; chn++) { - snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); + for (chn = 0; chn < netj.capture_channels_audio; chn++) { + snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); - if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, - CaptureDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) - { - jack_error ( "driver: cannot register port for %s", buf ); - return -1; + if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, + CaptureDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) + { + jack_error ( "driver: cannot register port for %s", buf ); + return -1; + } + //port = fGraphManager->GetPort ( port_id ); + + netj.capture_ports = + jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); + + if( netj.bitdepth == CELT_MODE ) { + #if HAVE_CELT + #if HAVE_CELT_API_0_7 + celt_int32 lookahead; + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); + netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); + #else + celt_int32_t lookahead; + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); + netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode ) ); + #endif + celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); + netj.codec_latency = 2*lookahead; + #endif + } else { + #if HAVE_SAMPLERATE + netj.capture_srcs = jack_slist_append(netj.capture_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); + #endif } - //port = fGraphManager->GetPort ( port_id ); - - netj.capture_ports = - jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); - - if( netj.bitdepth == CELT_MODE ) { -#if HAVE_CELT -#if HAVE_CELT_API_0_7 - celt_int32 lookahead; - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); - netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); -#else - celt_int32_t lookahead; - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); - netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode ) ); -#endif - celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); - netj.codec_latency = 2*lookahead; -#endif - } else { -#if HAVE_SAMPLERATE - netj.capture_srcs = jack_slist_append(netj.capture_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); -#endif - } - } - for (chn = netj.capture_channels_audio; chn < netj.capture_channels; chn++) { - snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); + } + for (chn = netj.capture_channels_audio; chn < netj.capture_channels; chn++) { + snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) @@ -187,12 +187,12 @@ namespace Jack } //port = fGraphManager->GetPort ( port_id ); - netj.capture_ports = - jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); - } + netj.capture_ports = + jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); + } - for (chn = 0; chn < netj.playback_channels_audio; chn++) { - snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); + for (chn = 0; chn < netj.playback_channels_audio; chn++) { + snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) @@ -202,27 +202,27 @@ namespace Jack } //port = fGraphManager->GetPort ( port_id ); - netj.playback_ports = - jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); - - if( netj.bitdepth == CELT_MODE ) { -#if HAVE_CELT -#if HAVE_CELT_API_0_7 - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); - netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); -#else - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); - netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode ) ); -#endif -#endif - } else { -#if HAVE_SAMPLERATE - netj.playback_srcs = jack_slist_append(netj.playback_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); -#endif - } - } - for (chn = netj.playback_channels_audio; chn < netj.playback_channels; chn++) { - snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); + netj.playback_ports = + jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); + + if( netj.bitdepth == CELT_MODE ) { + #if HAVE_CELT + #if HAVE_CELT_API_0_7 + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); + netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); + #else + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); + netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode ) ); + #endif + #endif + } else { + #if HAVE_SAMPLERATE + netj.playback_srcs = jack_slist_append(netj.playback_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); + #endif + } + } + for (chn = netj.playback_channels_audio; chn < netj.playback_channels; chn++) { + snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) @@ -232,10 +232,10 @@ namespace Jack } //port = fGraphManager->GetPort ( port_id ); - netj.playback_ports = - jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); - } - return 0; + netj.playback_ports = + jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); + } + return 0; } //init and restart-------------------------------------------------------------------- @@ -243,16 +243,16 @@ namespace Jack { jack_log ( "JackNetOneDriver::Init()" ); - if( global_packcache != NULL ) { - FreePorts(); - netjack_release( &netj ); - } + if( global_packcache != NULL ) { + FreePorts(); + netjack_release( &netj ); + } //display some additional infos jack_info ( "NetOne driver started" ); - if( netjack_startup( &netj ) ) { - return false; - } + if( netjack_startup( &netj ) ) { + return false; + } //register jack ports if ( AllocPorts() != 0 ) @@ -261,7 +261,6 @@ namespace Jack return false; } - //monitor //driver parametering JackAudioDriver::SetBufferSize ( netj.period_size ); @@ -281,161 +280,160 @@ namespace Jack //driver processes-------------------------------------------------------------------- int JackNetOneDriver::Read() { - int delay; - delay = netjack_wait( &netj ); - if( delay ) { - NotifyXRun(fBeginDateUst, (float) delay); - jack_error( "netxruns... duration: %dms", delay/1000 ); - } + int delay; + delay = netjack_wait( &netj ); + if( delay ) { + NotifyXRun(fBeginDateUst, (float) delay); + jack_error( "netxruns... duration: %dms", delay/1000 ); + } - if( (netj.num_lost_packets * netj.period_size / netj.sample_rate) > 2 ) - JackTools::ThrowJackNetException(); + if( (netj.num_lost_packets * netj.period_size / netj.sample_rate) > 2 ) + JackTools::ThrowJackNetException(); - //netjack_read( &netj, netj.period_size ); + //netjack_read( &netj, netj.period_size ); JackDriver::CycleTakeBeginTime(); - jack_position_t local_trans_pos; - jack_transport_state_t local_trans_state; + jack_position_t local_trans_pos; + jack_transport_state_t local_trans_state; - unsigned int *packet_buf, *packet_bufX; + unsigned int *packet_buf, *packet_bufX; - if( ! netj.packet_data_valid ) { + if( ! netj.packet_data_valid ) { jack_log( "data not valid" ); - render_payload_to_jack_ports (netj.bitdepth, NULL, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats ); - return 0; - } - packet_buf = netj.rx_buf; + render_payload_to_jack_ports (netj.bitdepth, NULL, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats ); + return 0; + } + packet_buf = netj.rx_buf; - jacknet_packet_header *pkthdr = (jacknet_packet_header *)packet_buf; + jacknet_packet_header *pkthdr = (jacknet_packet_header *)packet_buf; - packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); + packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); - netj.reply_port = pkthdr->reply_port; - netj.latency = pkthdr->latency; + netj.reply_port = pkthdr->reply_port; + netj.latency = pkthdr->latency; - // Special handling for latency=0 - if( netj.latency == 0 ) - netj.resync_threshold = 0; - else - netj.resync_threshold = MIN( 15, pkthdr->latency-1 ); + // Special handling for latency=0 + if( netj.latency == 0 ) + netj.resync_threshold = 0; + else + netj.resync_threshold = MIN( 15, pkthdr->latency-1 ); - // check whether, we should handle the transport sync stuff, or leave trnasports untouched. - if (netj.handle_transport_sync) { -#if 1 - unsigned int compensated_tranport_pos = (pkthdr->transport_frame + (pkthdr->latency * netj.period_size) + netj.codec_latency); + // check whether, we should handle the transport sync stuff, or leave trnasports untouched. + if (netj.handle_transport_sync) { + #if 1 + unsigned int compensated_tranport_pos = (pkthdr->transport_frame + (pkthdr->latency * netj.period_size) + netj.codec_latency); - // read local transport info.... - //local_trans_state = jack_transport_query(netj.client, &local_trans_pos); + // read local transport info.... + //local_trans_state = jack_transport_query(netj.client, &local_trans_pos); local_trans_state = fEngineControl->fTransport.Query ( &local_trans_pos ); - // Now check if we have to start or stop local transport to sync to remote... - switch (pkthdr->transport_state) { - case JackTransportStarting: - // the master transport is starting... so we set our reply to the sync_callback; - if (local_trans_state == JackTransportStopped) { - fEngineControl->fTransport.SetCommand ( TransportCommandStart ); - //jack_transport_start(netj.client); - //last_transport_state = JackTransportStopped; - netj.sync_state = 0; - jack_info("locally stopped... starting..."); - } - - if (local_trans_pos.frame != compensated_tranport_pos) - { - jack_position_t new_pos = local_trans_pos; - new_pos.frame = compensated_tranport_pos + 2*netj.period_size; - new_pos.valid = (jack_position_bits_t) 0; - - - fEngineControl->fTransport.RequestNewPos ( &new_pos ); - //jack_transport_locate(netj.client, compensated_tranport_pos); - //last_transport_state = JackTransportRolling; - netj.sync_state = 0; - jack_info("starting locate to %d", compensated_tranport_pos ); - } - break; - case JackTransportStopped: - netj.sync_state = 1; - if (local_trans_pos.frame != (pkthdr->transport_frame)) { - jack_position_t new_pos = local_trans_pos; - new_pos.frame = pkthdr->transport_frame; - new_pos.valid = (jack_position_bits_t)0; - fEngineControl->fTransport.RequestNewPos ( &new_pos ); - //jack_transport_locate(netj.client, (pkthdr->transport_frame)); - jack_info("transport is stopped locate to %d", pkthdr->transport_frame); - } - if (local_trans_state != JackTransportStopped) - //jack_transport_stop(netj.client); - fEngineControl->fTransport.SetCommand ( TransportCommandStop ); - break; - case JackTransportRolling: - netj.sync_state = 1; -// if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * netj.period_size)) { -// jack_transport_locate(netj.client, (pkthdr->transport_frame + (pkthdr->latency + 2) * netj.period_size)); -// jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*netj.period_size); -// } - if (local_trans_state != JackTransportRolling) - fEngineControl->fTransport.SetState ( JackTransportRolling ); - - break; - - case JackTransportLooping: - break; - } + // Now check if we have to start or stop local transport to sync to remote... + switch (pkthdr->transport_state) { + case JackTransportStarting: + // the master transport is starting... so we set our reply to the sync_callback; + if (local_trans_state == JackTransportStopped) { + fEngineControl->fTransport.SetCommand ( TransportCommandStart ); + //jack_transport_start(netj.client); + //last_transport_state = JackTransportStopped; + netj.sync_state = 0; + jack_info("locally stopped... starting..."); + } + + if (local_trans_pos.frame != compensated_tranport_pos) + { + jack_position_t new_pos = local_trans_pos; + new_pos.frame = compensated_tranport_pos + 2*netj.period_size; + new_pos.valid = (jack_position_bits_t) 0; + + + fEngineControl->fTransport.RequestNewPos ( &new_pos ); + //jack_transport_locate(netj.client, compensated_tranport_pos); + //last_transport_state = JackTransportRolling; + netj.sync_state = 0; + jack_info("starting locate to %d", compensated_tranport_pos ); + } + break; + case JackTransportStopped: + netj.sync_state = 1; + if (local_trans_pos.frame != (pkthdr->transport_frame)) { + jack_position_t new_pos = local_trans_pos; + new_pos.frame = pkthdr->transport_frame; + new_pos.valid = (jack_position_bits_t)0; + fEngineControl->fTransport.RequestNewPos ( &new_pos ); + //jack_transport_locate(netj.client, (pkthdr->transport_frame)); + jack_info("transport is stopped locate to %d", pkthdr->transport_frame); + } + if (local_trans_state != JackTransportStopped) + //jack_transport_stop(netj.client); + fEngineControl->fTransport.SetCommand ( TransportCommandStop ); + break; + case JackTransportRolling: + netj.sync_state = 1; + // if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * netj.period_size)) { + // jack_transport_locate(netj.client, (pkthdr->transport_frame + (pkthdr->latency + 2) * netj.period_size)); + // jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*netj.period_size); + // } + if (local_trans_state != JackTransportRolling) + fEngineControl->fTransport.SetState ( JackTransportRolling ); + + break; + + case JackTransportLooping: + break; + } #endif - } + } - render_payload_to_jack_ports (netj.bitdepth, packet_bufX, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats ); - packet_cache_release_packet(global_packcache, netj.expected_framecnt ); - return 0; + render_payload_to_jack_ports (netj.bitdepth, packet_bufX, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats ); + packet_cache_release_packet(global_packcache, netj.expected_framecnt ); + return 0; } int JackNetOneDriver::Write() { - int syncstate = netj.sync_state | ((fEngineControl->fTransport.GetState() == JackTransportNetStarting) ? 1 : 0 ); - uint32_t *packet_buf, *packet_bufX; - - int packet_size = get_sample_size(netj.bitdepth) * netj.playback_channels * netj.net_period_up + sizeof(jacknet_packet_header); - jacknet_packet_header *pkthdr; + int syncstate = netj.sync_state | ((fEngineControl->fTransport.GetState() == JackTransportNetStarting) ? 1 : 0 ); + uint32_t *packet_buf, *packet_bufX; - packet_buf = (uint32_t *) alloca(packet_size); - pkthdr = (jacknet_packet_header *)packet_buf; + int packet_size = get_sample_size(netj.bitdepth) * netj.playback_channels * netj.net_period_up + sizeof(jacknet_packet_header); + jacknet_packet_header *pkthdr; - if( netj.running_free ) { - return 0; - } + packet_buf = (uint32_t *) alloca(packet_size); + pkthdr = (jacknet_packet_header *)packet_buf; - // offset packet_bufX by the packetheader. - packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); + if( netj.running_free ) { + return 0; + } - pkthdr->sync_state = syncstate;; - pkthdr->latency = netj.time_to_deadline; - //printf( "time to deadline = %d goodness=%d\n", (int)netj.time_to_deadline, netj.deadline_goodness ); - pkthdr->framecnt = netj.expected_framecnt; + // offset packet_bufX by the packetheader. + packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); + pkthdr->sync_state = syncstate;; + pkthdr->latency = netj.time_to_deadline; + //printf( "time to deadline = %d goodness=%d\n", (int)netj.time_to_deadline, netj.deadline_goodness ); + pkthdr->framecnt = netj.expected_framecnt; - render_jack_ports_to_payload(netj.bitdepth, netj.playback_ports, netj.playback_srcs, netj.period_size, packet_bufX, netj.net_period_up, netj.dont_htonl_floats ); + render_jack_ports_to_payload(netj.bitdepth, netj.playback_ports, netj.playback_srcs, netj.period_size, packet_bufX, netj.net_period_up, netj.dont_htonl_floats ); - packet_header_hton(pkthdr); - if (netj.srcaddress_valid) - { - unsigned int r; + packet_header_hton(pkthdr); + if (netj.srcaddress_valid) + { + unsigned int r; -#ifdef __APPLE__ - static const int flag = 0; -#else - static const int flag = 0; -#endif + #ifdef __APPLE__ + static const int flag = 0; + #else + static const int flag = 0; + #endif - if (netj.reply_port) - netj.syncsource_address.sin_port = htons(netj.reply_port); + if (netj.reply_port) + netj.syncsource_address.sin_port = htons(netj.reply_port); - for( r=0; rdata; - node = jack_slist_remove_link( node, this_node ); - jack_slist_free_1( this_node ); - fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); + JSList *this_node = node; + jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); } netj.capture_ports = NULL; node = netj.playback_ports; while( node != NULL ) { - JSList *this_node = node; - jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; - node = jack_slist_remove_link( node, this_node ); - jack_slist_free_1( this_node ); - fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); + JSList *this_node = node; + jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); } netj.playback_ports = NULL; @@ -523,7 +521,7 @@ JackNetOneDriver::render_payload_to_jack_ports_float ( void *packet_payload, jac uint32_t *packet_bufX = (uint32_t *)packet_payload; if( !packet_payload ) - return; + return; while (node != NULL) { @@ -532,9 +530,8 @@ JackNetOneDriver::render_payload_to_jack_ports_float ( void *packet_payload, jac #if HAVE_SAMPLERATE SRC_DATA src; #endif - - jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; - JackPort *port = fGraphManager->GetPort( port_id ); + jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; + JackPort *port = fGraphManager->GetPort( port_id ); jack_default_audio_sample_t* buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); @@ -569,19 +566,19 @@ JackNetOneDriver::render_payload_to_jack_ports_float ( void *packet_payload, jac else #endif { - if( dont_htonl_floats ) - { - memcpy( buf, packet_bufX, net_period_down*sizeof(jack_default_audio_sample_t)); - } - else - { - for (i = 0; i < net_period_down; i++) - { - val.i = packet_bufX[i]; - val.i = ntohl (val.i); - buf[i] = val.f; - } - } + if( dont_htonl_floats ) + { + memcpy( buf, packet_bufX, net_period_down*sizeof(jack_default_audio_sample_t)); + } + else + { + for (i = 0; i < net_period_down; i++) + { + val.i = packet_bufX[i]; + val.i = ntohl (val.i); + buf[i] = val.f; + } + } } } else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) @@ -616,8 +613,8 @@ JackNetOneDriver::render_jack_ports_to_payload_float (JSList *playback_ports, JS #endif unsigned int i; int_float_t val; - jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; - JackPort *port = fGraphManager->GetPort( port_id ); + jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; + JackPort *port = fGraphManager->GetPort( port_id ); jack_default_audio_sample_t* buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); @@ -652,19 +649,19 @@ JackNetOneDriver::render_jack_ports_to_payload_float (JSList *playback_ports, JS else #endif { - if( dont_htonl_floats ) - { - memcpy( packet_bufX, buf, net_period_up*sizeof(jack_default_audio_sample_t) ); - } - else - { - for (i = 0; i < net_period_up; i++) - { - val.f = buf[i]; - val.i = htonl (val.i); - packet_bufX[i] = val.i; - } - } + if( dont_htonl_floats ) + { + memcpy( packet_bufX, buf, net_period_up*sizeof(jack_default_audio_sample_t) ); + } + else + { + for (i = 0; i < net_period_up; i++) + { + val.f = buf[i]; + val.i = htonl (val.i); + packet_bufX[i] = val.i; + } + } } } else if (strncmp(porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) @@ -694,26 +691,24 @@ JackNetOneDriver::render_payload_to_jack_ports_celt (void *packet_payload, jack_ while (node != NULL) { - jack_port_id_t port_id = (jack_port_id_t) (intptr_t)node->data; - JackPort *port = fGraphManager->GetPort( port_id ); + jack_port_id_t port_id = (jack_port_id_t) (intptr_t)node->data; + JackPort *port = fGraphManager->GetPort( port_id ); jack_default_audio_sample_t* buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); const char *portname = port->GetType(); - if (strncmp(portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) { // audio port, decode celt data. + CELTDecoder *decoder = (CELTDecoder *)src_node->data; + if( !packet_payload ) + celt_decode_float( decoder, NULL, net_period_down, buf ); + else + celt_decode_float( decoder, packet_bufX, net_period_down, buf ); - CELTDecoder *decoder = (CELTDecoder *)src_node->data; - if( !packet_payload ) - celt_decode_float( decoder, NULL, net_period_down, buf ); - else - celt_decode_float( decoder, packet_bufX, net_period_down, buf ); - - src_node = jack_slist_next (src_node); + src_node = jack_slist_next (src_node); } else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) { @@ -722,7 +717,7 @@ JackNetOneDriver::render_payload_to_jack_ports_celt (void *packet_payload, jack_ unsigned int buffer_size_uint32 = net_period_down / 2; uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; if( packet_payload ) - decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } packet_bufX = (packet_bufX + net_period_down); node = jack_slist_next (node); @@ -741,8 +736,8 @@ JackNetOneDriver::render_jack_ports_to_payload_celt (JSList *playback_ports, JSL while (node != NULL) { - jack_port_id_t port_id = (jack_port_id_t) (intptr_t) node->data; - JackPort *port = fGraphManager->GetPort( port_id ); + jack_port_id_t port_id = (jack_port_id_t) (intptr_t) node->data; + JackPort *port = fGraphManager->GetPort( port_id ); jack_default_audio_sample_t* buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); @@ -800,8 +795,6 @@ JackNetOneDriver::render_jack_ports_to_payload (int bitdepth, JSList *playback_p render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats); } - - //driver loader----------------------------------------------------------------------- #ifdef __cplusplus @@ -982,28 +975,26 @@ JackNetOneDriver::render_jack_ports_to_payload (int bitdepth, JSList *playback_p SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize ( Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params ) { - jack_nframes_t sample_rate = 48000; - jack_nframes_t resample_factor = 1; - jack_nframes_t period_size = 1024; - unsigned int capture_ports = 2; - unsigned int playback_ports = 2; - unsigned int capture_ports_midi = 1; - unsigned int playback_ports_midi = 1; - unsigned int listen_port = 3000; - unsigned int resample_factor_up = 0; - unsigned int bitdepth = 0; - unsigned int handle_transport_sync = 1; - unsigned int use_autoconfig = 1; - unsigned int latency = 5; - unsigned int redundancy = 1; - unsigned int mtu = 1400; - int dont_htonl_floats = 0; - int always_deadline = 0; - int jitter_val = 0; - const JSList * node; - const jack_driver_param_t * param; - - + jack_nframes_t sample_rate = 48000; + jack_nframes_t resample_factor = 1; + jack_nframes_t period_size = 1024; + unsigned int capture_ports = 2; + unsigned int playback_ports = 2; + unsigned int capture_ports_midi = 1; + unsigned int playback_ports_midi = 1; + unsigned int listen_port = 3000; + unsigned int bitdepth = 0; + unsigned int handle_transport_sync = 1; + unsigned int use_autoconfig = 1; + unsigned int latency = 5; + unsigned int redundancy = 1; + unsigned int mtu = 1400; + unsigned int resample_factor_up = 1; + int dont_htonl_floats = 0; + int always_deadline = 0; + int jitter_val = 0; + const JSList * node; + const jack_driver_param_t * param; for ( node = params; node; node = jack_slist_next ( node ) ) { @@ -1102,7 +1093,6 @@ JackNetOneDriver::render_jack_ports_to_payload (int bitdepth, JSList *playback_p try { - Jack::JackDriverClientInterface* driver = new Jack::JackWaitThreadedDriver ( new Jack::JackNetOneDriver ( "system", "net_pcm", engine, table, listen_port, mtu, diff --git a/common/JackNotification.h b/common/JackNotification.h index be0c89fd..bca178af 100644 --- a/common/JackNotification.h +++ b/common/JackNotification.h @@ -45,6 +45,7 @@ enum NotificationType { kRealTimeCallback = 14, kShutDownCallback = 15, kQUIT = 16, + kSessionCallback = 17, kMaxNotification }; diff --git a/common/JackRequest.h b/common/JackRequest.h index d366f69e..c83753a3 100644 --- a/common/JackRequest.h +++ b/common/JackRequest.h @@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "types.h" #include #include +#include namespace Jack { @@ -65,7 +66,12 @@ struct JackRequest kInternalClientLoad = 29, kInternalClientUnload = 30, kPortRename = 31, - kNotification = 32 + kNotification = 32, + kSessionNotify = 33, + kSessionReply = 34, + kGetClientByUUID = 35, + kReserveClientName = 36, + kGetUUIDByClient = 37 }; RequestType fType; @@ -98,7 +104,7 @@ struct JackRequest struct JackResult { - int fResult; + int fResult; JackResult(): fResult( -1) {} @@ -129,31 +135,34 @@ struct JackClientCheckRequest : public JackRequest char fName[JACK_CLIENT_NAME_SIZE + 1]; int fProtocol; int fOptions; + int fUUID; JackClientCheckRequest() {} - JackClientCheckRequest(const char* name, int protocol, int options) - : JackRequest(JackRequest::kClientCheck), fProtocol(protocol), fOptions(options) + JackClientCheckRequest(const char* name, int protocol, int options, int uuid) + : JackRequest(JackRequest::kClientCheck), fProtocol(protocol), fOptions(options), fUUID(uuid) { snprintf(fName, sizeof(fName), "%s", name); } int Read(JackChannelTransaction* trans) { - CheckRes(trans->Read(&fName, JACK_CLIENT_NAME_SIZE + 1)); + CheckRes(trans->Read(&fName, sizeof(fName))); CheckRes(trans->Read(&fProtocol, sizeof(int))); - return trans->Read(&fOptions, sizeof(int)); + CheckRes(trans->Read(&fOptions, sizeof(int))); + return trans->Read(&fUUID, sizeof(int)); } int Write(JackChannelTransaction* trans) { CheckRes(JackRequest::Write(trans)); - CheckRes(trans->Write(&fName, JACK_CLIENT_NAME_SIZE + 1)); + CheckRes(trans->Write(&fName, sizeof(fName))); CheckRes(trans->Write(&fProtocol, sizeof(int))); - return trans->Write(&fOptions, sizeof(int)); + CheckRes(trans->Write(&fOptions, sizeof(int))); + return trans->Write(&fUUID, sizeof(int)); } -} POST_PACKED_STRUCTURE; +}; /*! \brief CheckClient result. @@ -176,7 +185,7 @@ struct JackClientCheckResult : public JackResult int Read(JackChannelTransaction* trans) { CheckRes(JackResult::Read(trans)); - CheckRes(trans->Read(&fName, JACK_CLIENT_NAME_SIZE + 1)); + CheckRes(trans->Read(&fName, sizeof(fName))); CheckRes(trans->Read(&fStatus, sizeof(int))); return 0; } @@ -184,12 +193,12 @@ struct JackClientCheckResult : public JackResult int Write(JackChannelTransaction* trans) { CheckRes(JackResult::Write(trans)); - CheckRes(trans->Write(&fName, JACK_CLIENT_NAME_SIZE + 1)); + CheckRes(trans->Write(&fName, sizeof(fName))); CheckRes(trans->Write(&fStatus, sizeof(int))); return 0; } -} POST_PACKED_STRUCTURE; +}; /*! \brief NewClient request. @@ -199,30 +208,34 @@ struct JackClientOpenRequest : public JackRequest { int fPID; + int fUUID; char fName[JACK_CLIENT_NAME_SIZE + 1]; - + JackClientOpenRequest() {} - JackClientOpenRequest(const char* name, int pid): JackRequest(JackRequest::kClientOpen) + JackClientOpenRequest(const char* name, int pid, int uuid): JackRequest(JackRequest::kClientOpen) { snprintf(fName, sizeof(fName), "%s", name); fPID = pid; + fUUID = uuid; } int Read(JackChannelTransaction* trans) { CheckRes(trans->Read(&fPID, sizeof(int))); - return trans->Read(&fName, JACK_CLIENT_NAME_SIZE + 1); + CheckRes(trans->Read(&fUUID, sizeof(int))); + return trans->Read(&fName, sizeof(fName)); } int Write(JackChannelTransaction* trans) { CheckRes(JackRequest::Write(trans)); CheckRes(trans->Write(&fPID, sizeof(int))); - return trans->Write(&fName, JACK_CLIENT_NAME_SIZE + 1); + CheckRes(trans->Write(&fUUID, sizeof(int))); + return trans->Write(&fName, sizeof(fName)); } -} POST_PACKED_STRUCTURE; +}; /*! \brief NewClient result. @@ -260,7 +273,7 @@ struct JackClientOpenResult : public JackResult return 0; } -} POST_PACKED_STRUCTURE; +}; /*! \brief CloseClient request. @@ -287,7 +300,7 @@ struct JackClientCloseRequest : public JackRequest return trans->Write(&fRefNum, sizeof(int)); } -} POST_PACKED_STRUCTURE; +}; /*! \brief Activate request. @@ -318,7 +331,7 @@ struct JackActivateRequest : public JackRequest return trans->Write(&fIsRealTime, sizeof(int)); } -} POST_PACKED_STRUCTURE; +}; /*! \brief Deactivate request. @@ -345,7 +358,7 @@ struct JackDeactivateRequest : public JackRequest return trans->Write(&fRefNum, sizeof(int)); } -} POST_PACKED_STRUCTURE; +}; /*! \brief PortRegister request. @@ -372,8 +385,8 @@ struct JackPortRegisterRequest : public JackRequest int Read(JackChannelTransaction* trans) { CheckRes(trans->Read(&fRefNum, sizeof(int))); - CheckRes(trans->Read(&fName, JACK_PORT_NAME_SIZE + 1)); - CheckRes(trans->Read(&fPortType, JACK_PORT_TYPE_SIZE + 1)); + CheckRes(trans->Read(&fName, sizeof(fName))); + CheckRes(trans->Read(&fPortType, sizeof(fPortType))); CheckRes(trans->Read(&fFlags, sizeof(unsigned int))); CheckRes(trans->Read(&fBufferSize, sizeof(unsigned int))); return 0; @@ -383,14 +396,14 @@ struct JackPortRegisterRequest : public JackRequest { CheckRes(JackRequest::Write(trans)); CheckRes(trans->Write(&fRefNum, sizeof(int))); - CheckRes(trans->Write(&fName, JACK_PORT_NAME_SIZE + 1)); - CheckRes(trans->Write(&fPortType, JACK_PORT_TYPE_SIZE + 1)); + CheckRes(trans->Write(&fName, sizeof(fName))); + CheckRes(trans->Write(&fPortType, sizeof(fPortType))); CheckRes(trans->Write(&fFlags, sizeof(unsigned int))); CheckRes(trans->Write(&fBufferSize, sizeof(unsigned int))); return 0; } -} POST_PACKED_STRUCTURE; +}; /*! \brief PortRegister result. @@ -416,7 +429,7 @@ struct JackPortRegisterResult : public JackResult return trans->Write(&fPortIndex, sizeof(jack_port_id_t)); } -} POST_PACKED_STRUCTURE; +}; /*! \brief PortUnregister request. @@ -449,7 +462,7 @@ struct JackPortUnRegisterRequest : public JackRequest return 0; } -} POST_PACKED_STRUCTURE; +}; /*! \brief PortConnectName request. @@ -474,8 +487,8 @@ struct JackPortConnectNameRequest : public JackRequest int Read(JackChannelTransaction* trans) { CheckRes(trans->Read(&fRefNum, sizeof(int))); - CheckRes(trans->Read(&fSrc, JACK_PORT_NAME_SIZE + 1)); - CheckRes(trans->Read(&fDst, JACK_PORT_NAME_SIZE + 1)); + CheckRes(trans->Read(&fSrc, sizeof(fSrc))); + CheckRes(trans->Read(&fDst, sizeof(fDst))); return 0; } @@ -484,12 +497,12 @@ struct JackPortConnectNameRequest : public JackRequest { CheckRes(JackRequest::Write(trans)); CheckRes(trans->Write(&fRefNum, sizeof(int))); - CheckRes(trans->Write(&fSrc, JACK_PORT_NAME_SIZE + 1)); - CheckRes(trans->Write(&fDst, JACK_PORT_NAME_SIZE + 1)); + CheckRes(trans->Write(&fSrc, sizeof(fSrc))); + CheckRes(trans->Write(&fDst, sizeof(fDst))); return 0; } -} POST_PACKED_STRUCTURE; +}; /*! \brief PortDisconnectName request. @@ -514,8 +527,8 @@ struct JackPortDisconnectNameRequest : public JackRequest int Read(JackChannelTransaction* trans) { CheckRes(trans->Read(&fRefNum, sizeof(int))); - CheckRes(trans->Read(&fSrc, JACK_PORT_NAME_SIZE + 1)); - CheckRes(trans->Read(&fDst, JACK_PORT_NAME_SIZE + 1)); + CheckRes(trans->Read(&fSrc, sizeof(fSrc))); + CheckRes(trans->Read(&fDst, sizeof(fDst))); return 0; } @@ -523,12 +536,12 @@ struct JackPortDisconnectNameRequest : public JackRequest { CheckRes(JackRequest::Write(trans)); CheckRes(trans->Write(&fRefNum, sizeof(int))); - CheckRes(trans->Write(&fSrc, JACK_PORT_NAME_SIZE + 1)); - CheckRes(trans->Write(&fDst, JACK_PORT_NAME_SIZE + 1)); + CheckRes(trans->Write(&fSrc, sizeof(fSrc))); + CheckRes(trans->Write(&fDst, sizeof(fDst))); return 0; } -} POST_PACKED_STRUCTURE; +}; /*! \brief PortConnect request. @@ -564,7 +577,7 @@ struct JackPortConnectRequest : public JackRequest return 0; } -} POST_PACKED_STRUCTURE; +}; /*! \brief PortDisconnect request. @@ -598,10 +611,9 @@ struct JackPortDisconnectRequest : public JackRequest CheckRes(trans->Write(&fSrc, sizeof(jack_port_id_t))); CheckRes(trans->Write(&fDst, sizeof(jack_port_id_t))); return 0; - } -} POST_PACKED_STRUCTURE; +}; /*! \brief PortRename request. @@ -626,7 +638,7 @@ struct JackPortRenameRequest : public JackRequest { CheckRes(trans->Read(&fRefNum, sizeof(int))); CheckRes(trans->Read(&fPort, sizeof(jack_port_id_t))); - CheckRes(trans->Read(&fName, JACK_PORT_NAME_SIZE + 1)); + CheckRes(trans->Read(&fName, sizeof(fName))); return 0; } @@ -635,12 +647,12 @@ struct JackPortRenameRequest : public JackRequest CheckRes(JackRequest::Write(trans)); CheckRes(trans->Write(&fRefNum, sizeof(int))); CheckRes(trans->Write(&fPort, sizeof(jack_port_id_t))); - CheckRes(trans->Write(&fName, JACK_PORT_NAME_SIZE + 1)); + CheckRes(trans->Write(&fName, sizeof(fName))); return 0; } -} POST_PACKED_STRUCTURE; +}; /*! \brief SetBufferSize request. @@ -668,7 +680,7 @@ struct JackSetBufferSizeRequest : public JackRequest return trans->Write(&fBufferSize, sizeof(jack_nframes_t)); } -} POST_PACKED_STRUCTURE; +}; /*! \brief SetFreeWheel request. @@ -696,7 +708,7 @@ struct JackSetFreeWheelRequest : public JackRequest return trans->Write(&fOnOff, sizeof(int)); } -} POST_PACKED_STRUCTURE; +}; /*! \brief ReleaseTimebase request. @@ -724,7 +736,7 @@ struct JackReleaseTimebaseRequest : public JackRequest return trans->Write(&fRefNum, sizeof(int)); } -} POST_PACKED_STRUCTURE; +}; /*! \brief SetTimebaseCallback request. @@ -755,7 +767,7 @@ struct JackSetTimebaseCallbackRequest : public JackRequest return trans->Write(&fConditionnal, sizeof(int)); } -} POST_PACKED_STRUCTURE; +}; /*! \brief GetInternalClientName request. @@ -786,7 +798,7 @@ struct JackGetInternalClientNameRequest : public JackRequest return trans->Write(&fIntRefNum, sizeof(int)); } -} POST_PACKED_STRUCTURE; +}; /*! \brief GetInternalClient result. @@ -808,18 +820,18 @@ struct JackGetInternalClientNameResult : public JackResult int Read(JackChannelTransaction* trans) { CheckRes(JackResult::Read(trans)); - CheckRes(trans->Read(&fName, JACK_CLIENT_NAME_SIZE + 1)); + CheckRes(trans->Read(&fName, sizeof(fName))); return 0; } int Write(JackChannelTransaction* trans) { CheckRes(JackResult::Write(trans)); - CheckRes(trans->Write(&fName, JACK_CLIENT_NAME_SIZE + 1)); + CheckRes(trans->Write(&fName, sizeof(fName))); return 0; } -} POST_PACKED_STRUCTURE; +}; /*! \brief InternalClientHandle request. @@ -842,17 +854,17 @@ struct JackInternalClientHandleRequest : public JackRequest int Read(JackChannelTransaction* trans) { CheckRes(trans->Read(&fRefNum, sizeof(int))); - return trans->Read(&fName, JACK_CLIENT_NAME_SIZE + 1); + return trans->Read(&fName, sizeof(fName)); } int Write(JackChannelTransaction* trans) { CheckRes(JackRequest::Write(trans)); CheckRes(trans->Write(&fRefNum, sizeof(int))); - return trans->Write(&fName, JACK_CLIENT_NAME_SIZE + 1); + return trans->Write(&fName, sizeof(fName)); } -} POST_PACKED_STRUCTURE; +}; /*! \brief InternalClientHandle result. @@ -886,7 +898,7 @@ struct JackInternalClientHandleResult : public JackResult return 0; } -} POST_PACKED_STRUCTURE; +}; /*! \brief InternalClientLoad request. @@ -904,23 +916,26 @@ struct JackInternalClientLoadRequest : public JackRequest char fDllName[MAX_PATH + 1]; char fLoadInitName[JACK_LOAD_INIT_LIMIT + 1]; int fOptions; + int fUUID; JackInternalClientLoadRequest() {} - JackInternalClientLoadRequest(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options) - : JackRequest(JackRequest::kInternalClientLoad), fRefNum(refnum), fOptions(options) + JackInternalClientLoadRequest(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int uuid ) + : JackRequest(JackRequest::kInternalClientLoad), fRefNum(refnum), fOptions(options), fUUID(uuid) { snprintf(fName, sizeof(fName), "%s", client_name); snprintf(fDllName, sizeof(fDllName), "%s", so_name); snprintf(fLoadInitName, sizeof(fLoadInitName), "%s", objet_data); + snprintf(fLoadInitName, sizeof(fLoadInitName), "%s", objet_data); } int Read(JackChannelTransaction* trans) { CheckRes(trans->Read(&fRefNum, sizeof(int))); - CheckRes(trans->Read(&fName, JACK_CLIENT_NAME_SIZE + 1)); - CheckRes(trans->Read(&fDllName, MAX_PATH + 1)); - CheckRes(trans->Read(&fLoadInitName, JACK_LOAD_INIT_LIMIT + 1)); + CheckRes(trans->Read(&fName, sizeof(fName))); + CheckRes(trans->Read(&fDllName, sizeof(fDllName))); + CheckRes(trans->Read(&fLoadInitName, sizeof(fLoadInitName))); + CheckRes(trans->Read(&fUUID, sizeof(int))); return trans->Read(&fOptions, sizeof(int)); } @@ -928,13 +943,14 @@ struct JackInternalClientLoadRequest : public JackRequest { CheckRes(JackRequest::Write(trans)); CheckRes(trans->Write(&fRefNum, sizeof(int))); - CheckRes(trans->Write(&fName, JACK_CLIENT_NAME_SIZE + 1)); - CheckRes(trans->Write(&fDllName, MAX_PATH + 1)); - CheckRes(trans->Write(&fLoadInitName, JACK_LOAD_INIT_LIMIT + 1)); + CheckRes(trans->Write(&fName, sizeof(fName))); + CheckRes(trans->Write(&fDllName, sizeof(fDllName))); + CheckRes(trans->Write(&fLoadInitName, sizeof(fLoadInitName))); + CheckRes(trans->Write(&fUUID, sizeof(int))); return trans->Write(&fOptions, sizeof(int)); } -} POST_PACKED_STRUCTURE; +}; /*! \brief InternalClientLoad result. @@ -968,7 +984,7 @@ struct JackInternalClientLoadResult : public JackResult return 0; } -} POST_PACKED_STRUCTURE; +}; /*! \brief InternalClientUnload request. @@ -998,7 +1014,7 @@ struct JackInternalClientUnloadRequest : public JackRequest CheckRes(trans->Write(&fRefNum, sizeof(int))); return trans->Write(&fIntRefNum, sizeof(int)); } -} POST_PACKED_STRUCTURE; +}; /*! \brief InternalClientLoad result. @@ -1029,7 +1045,7 @@ struct JackInternalClientUnloadResult : public JackResult return 0; } -} POST_PACKED_STRUCTURE; +}; /*! \brief ClientNotification request. @@ -1065,7 +1081,292 @@ struct JackClientNotificationRequest : public JackRequest return 0; } -} POST_PACKED_STRUCTURE; +}; + +struct JackSessionCommand +{ + char fUUID[JACK_UUID_SIZE]; + char fClientName[JACK_CLIENT_NAME_SIZE+1]; + char fCommand[JACK_SESSION_COMMAND_SIZE]; + jack_session_flags_t fFlags; + + JackSessionCommand() + {} + + JackSessionCommand( const char *uuid, const char *clientname, const char *command, jack_session_flags_t flags ) + { + strncpy( fUUID, uuid, sizeof(fUUID)); + strncpy( fClientName, clientname, sizeof(fClientName)); + strncpy( fCommand, command, sizeof(fCommand)); + fFlags = flags; + } +}; + +struct JackSessionNotifyResult : public JackResult +{ + + std::list fCommandList; + + JackSessionNotifyResult(): JackResult() + {} + JackSessionNotifyResult(int32_t result) + : JackResult(result) + {} + + int Read(JackChannelTransaction* trans) + { + CheckRes(JackResult::Read(trans)); + while(1) { + JackSessionCommand buffer; + + CheckRes(trans->Read(buffer.fUUID, sizeof(buffer.fUUID))); + if (buffer.fUUID[0] == '\0') + break; + + CheckRes(trans->Read(buffer.fClientName, sizeof(buffer.fClientName))); + CheckRes(trans->Read(buffer.fCommand, sizeof(buffer.fCommand))); + CheckRes(trans->Read(&(buffer.fFlags), sizeof(buffer.fFlags))); + + fCommandList.push_back(buffer); + } + return 0; + } + + int Write(JackChannelTransaction* trans) + { + char terminator[JACK_UUID_SIZE]; + terminator[0] = '\0'; + + CheckRes(JackResult::Write(trans)); + for (std::list::iterator i=fCommandList.begin(); i!=fCommandList.end(); i++) { + CheckRes(trans->Write(i->fUUID, sizeof(i->fUUID))); + CheckRes(trans->Write(i->fClientName, sizeof(i->fClientName))); + CheckRes(trans->Write(i->fCommand, sizeof(i->fCommand))); + CheckRes(trans->Write(&(i->fFlags), sizeof(i->fFlags))); + } + CheckRes(trans->Write(terminator, sizeof(terminator))); + return 0; + } + +}; + +/*! +\brief SessionNotify request. +*/ + +struct JackSessionNotifyRequest : public JackRequest +{ + char fPath[JACK_MESSAGE_SIZE + 1]; + char fDst[JACK_CLIENT_NAME_SIZE + 1]; + jack_session_event_type_t fEventType; + int fRefNum; + + JackSessionNotifyRequest() + {} + JackSessionNotifyRequest(int refnum, const char *path, jack_session_event_type_t type, const char *dst) + : JackRequest(JackRequest::kSessionNotify), fEventType(type), fRefNum(refnum) + { + snprintf(fPath, sizeof(fPath), "%s", path); + if (dst) + snprintf(fDst, sizeof(fDst), "%s", dst); + else + fDst[0] = '\0'; + } + + int Read(JackChannelTransaction* trans) + { + CheckRes(trans->Read(&fRefNum, sizeof(fRefNum))); + CheckRes(trans->Read(&fPath, sizeof(fPath))); + CheckRes(trans->Read(&fDst, sizeof(fDst))); + CheckRes(trans->Read(&fEventType, sizeof(fEventType))); + return 0; + } + + int Write(JackChannelTransaction* trans) + { + CheckRes(JackRequest::Write(trans)); + CheckRes(trans->Write(&fRefNum, sizeof(fRefNum))); + CheckRes(trans->Write(&fPath, sizeof(fPath))); + CheckRes(trans->Write(&fDst, sizeof(fDst))); + CheckRes(trans->Write(&fEventType, sizeof(fEventType))); + return 0; + } + +}; + +struct JackSessionReplyRequest : public JackRequest +{ + int fRefNum; + + JackSessionReplyRequest() + {} + + JackSessionReplyRequest(int refnum) + : JackRequest(JackRequest::kSessionReply), fRefNum(refnum) + {} + + int Read(JackChannelTransaction* trans) + { + CheckRes(trans->Read(&fRefNum, sizeof(fRefNum))); + return 0; + } + + int Write(JackChannelTransaction* trans) + { + CheckRes(JackRequest::Write(trans)); + CheckRes(trans->Write(&fRefNum, sizeof(fRefNum))); + return 0; + } + +}; + +struct JackClientNameResult : public JackResult +{ + char fName[JACK_CLIENT_NAME_SIZE + 1]; + + JackClientNameResult(): JackResult() + {} + JackClientNameResult(int32_t result, const char* name) + : JackResult(result) + { + snprintf(fName, sizeof(fName), "%s", name); + } + + int Read(JackChannelTransaction* trans) + { + CheckRes(JackResult::Read(trans)); + CheckRes(trans->Read(&fName, sizeof(fName))); + return 0; + } + + int Write(JackChannelTransaction* trans) + { + CheckRes(JackResult::Write(trans)); + CheckRes(trans->Write(&fName, sizeof(fName))); + return 0; + } + +}; + +struct JackUUIDResult : public JackResult +{ + + char fUUID[JACK_UUID_SIZE]; + + JackUUIDResult(): JackResult() + {} + JackUUIDResult(int32_t result, const char* uuid) + : JackResult(result) + { + snprintf(fUUID, sizeof(fUUID), "%s", uuid); + } + + int Read(JackChannelTransaction* trans) + { + CheckRes(JackResult::Read(trans)); + CheckRes(trans->Read(&fUUID, sizeof(fUUID))); + return 0; + } + + int Write(JackChannelTransaction* trans) + { + CheckRes(JackResult::Write(trans)); + CheckRes(trans->Write(&fUUID, sizeof(fUUID))); + return 0; + } + +}; + +struct JackGetUUIDRequest : public JackRequest +{ + char fName[JACK_CLIENT_NAME_SIZE + 1]; + + JackGetUUIDRequest() + {} + + JackGetUUIDRequest(const char* client_name) + : JackRequest(JackRequest::kGetUUIDByClient) + { + strncpy(fName, client_name, sizeof(fName)); + } + + int Read(JackChannelTransaction* trans) + { + CheckRes(trans->Read(&fName, sizeof(fName))); + return 0; + } + + int Write(JackChannelTransaction* trans) + { + CheckRes(JackRequest::Write(trans)); + CheckRes(trans->Write(&fName, sizeof(fName))); + return 0; + } + +}; + +struct JackGetClientNameRequest : public JackRequest +{ + char fUUID[JACK_UUID_SIZE]; + + JackGetClientNameRequest() + {} + + JackGetClientNameRequest(const char* uuid) + : JackRequest(JackRequest::kGetClientByUUID) + { + strncpy(fUUID, uuid, sizeof(fUUID)); + } + + int Read(JackChannelTransaction* trans) + { + CheckRes(trans->Read(&fUUID, sizeof(fUUID))); + return 0; + } + + int Write(JackChannelTransaction* trans) + { + CheckRes(JackRequest::Write(trans)); + CheckRes(trans->Write(&fUUID, sizeof(fUUID))); + return 0; + } + +}; + +struct JackReserveNameRequest : public JackRequest +{ + int fRefNum; + char fName[JACK_CLIENT_NAME_SIZE + 1]; + char fUUID[JACK_UUID_SIZE]; + + JackReserveNameRequest() + {} + + JackReserveNameRequest(int refnum, const char *name, const char* uuid) + : JackRequest(JackRequest::kReserveClientName), fRefNum(refnum) + { + strncpy(fName, name, sizeof(fName)); + strncpy(fUUID, uuid, sizeof(fUUID)); + } + + int Read(JackChannelTransaction* trans) + { + CheckRes(trans->Read(&fUUID, sizeof(fUUID))); + CheckRes(trans->Read(&fName, sizeof(fName))); + CheckRes(trans->Read(&fRefNum, sizeof(fRefNum))); + return 0; + } + + int Write(JackChannelTransaction* trans) + { + CheckRes(JackRequest::Write(trans)); + CheckRes(trans->Write(&fUUID, sizeof(fUUID))); + CheckRes(trans->Write(&fName, sizeof(fName))); + CheckRes(trans->Write(&fRefNum, sizeof(fRefNum))); + return 0; + } + +}; /*! \brief ClientNotification. @@ -1092,29 +1393,29 @@ struct JackClientNotification int Read(JackChannelTransaction* trans) { - CheckRes(trans->Read(&fName, JACK_CLIENT_NAME_SIZE + 1)); + CheckRes(trans->Read(&fName, sizeof(fName))); CheckRes(trans->Read(&fRefNum, sizeof(int))); CheckRes(trans->Read(&fNotify, sizeof(int))); CheckRes(trans->Read(&fValue1, sizeof(int))); CheckRes(trans->Read(&fValue2, sizeof(int))); CheckRes(trans->Read(&fSync, sizeof(int))); - CheckRes(trans->Read(&fMessage, JACK_MESSAGE_SIZE + 1)); + CheckRes(trans->Read(&fMessage, sizeof(fName))); return 0; } int Write(JackChannelTransaction* trans) { - CheckRes(trans->Write(&fName, JACK_CLIENT_NAME_SIZE + 1)); + CheckRes(trans->Write(&fName, sizeof(fName))); CheckRes(trans->Write(&fRefNum, sizeof(int))); CheckRes(trans->Write(&fNotify, sizeof(int))); CheckRes(trans->Write(&fValue1, sizeof(int))); CheckRes(trans->Write(&fValue2, sizeof(int))); CheckRes(trans->Write(&fSync, sizeof(int))); - CheckRes(trans->Write(&fMessage, JACK_MESSAGE_SIZE + 1)); + CheckRes(trans->Write(&fMessage, sizeof(fName))); return 0; } -} POST_PACKED_STRUCTURE; +}; } // end of namespace diff --git a/common/JackServer.cpp b/common/JackServer.cpp index e2676500..126e7c4f 100644 --- a/common/JackServer.cpp +++ b/common/JackServer.cpp @@ -72,22 +72,22 @@ int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params) { // TODO: move that in reworked JackServerGlobals::Init() JackMessageBuffer::Create(); + + if ((fAudioDriver = fDriverInfo->Open(driver_desc, fEngine, GetSynchroTable(), driver_params)) == NULL) { + jack_error("Cannot initialize driver"); + goto fail_close1; + } if (fChannel.Open(fEngineControl->fServerName, this) < 0) { jack_error("Server channel open error"); - goto fail_close1; + goto fail_close2; } if (fEngine->Open() < 0) { jack_error("Cannot open engine"); - goto fail_close2; - } - - if ((fAudioDriver = fDriverInfo->Open(driver_desc, fEngine, GetSynchroTable(), driver_params)) == NULL) { - jack_error("Cannot initialize driver"); goto fail_close3; } - + if (fFreewheelDriver->Open() < 0) { // before engine open jack_error("Cannot open driver"); goto fail_close4; @@ -109,13 +109,13 @@ fail_close5: fFreewheelDriver->Close(); fail_close4: - fAudioDriver->Close(); + fEngine->Close(); fail_close3: - fEngine->Close(); + fChannel.Close(); fail_close2: - fChannel.Close(); + fAudioDriver->Close(); fail_close1: JackMessageBuffer::Destroy(); @@ -136,25 +136,25 @@ int JackServer::Close() return 0; } -int JackServer::InternalClientLoad(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int* status) +int JackServer::InternalClientLoad(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int uuid, int* status) { JackLoadableInternalClient* client = new JackLoadableInternalClient1(JackServerGlobals::fInstance, GetSynchroTable(), objet_data); assert(client); - return InternalClientLoadAux(client, so_name, client_name, options, int_ref, status); + return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status); } -int JackServer::InternalClientLoad(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int* status) +int JackServer::InternalClientLoad(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int uuid, int* status) { JackLoadableInternalClient* client = new JackLoadableInternalClient2(JackServerGlobals::fInstance, GetSynchroTable(), parameters); assert(client); - return InternalClientLoadAux(client, so_name, client_name, options, int_ref, status); + return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status); } -int JackServer::InternalClientLoadAux(JackLoadableInternalClient* client, const char* so_name, const char* client_name, int options, int* int_ref, int* status) +int JackServer::InternalClientLoadAux(JackLoadableInternalClient* client, const char* so_name, const char* client_name, int options, int* int_ref, int uuid, int* status) { // Clear status *status = 0; - if ((client->Init(so_name) < 0) || (client->Open(JACK_DEFAULT_SERVER_NAME, client_name, (jack_options_t)options, (jack_status_t*)status) < 0)) { + if ((client->Init(so_name) < 0) || (client->Open(JACK_DEFAULT_SERVER_NAME, client_name, uuid, (jack_options_t)options, (jack_status_t*)status) < 0)) { delete client; int my_status1 = *status | JackFailure; *status = (jack_status_t)my_status1; diff --git a/common/JackServer.h b/common/JackServer.h index f99d7c20..9b07d60f 100644 --- a/common/JackServer.h +++ b/common/JackServer.h @@ -58,7 +58,7 @@ class SERVER_EXPORT JackServer JackSynchro fSynchroTable[CLIENT_NUM]; bool fFreewheel; - int InternalClientLoadAux(JackLoadableInternalClient* client, const char* so_name, const char* client_name, int options, int* int_ref, int* status); + int InternalClientLoadAux(JackLoadableInternalClient* client, const char* so_name, const char* client_name, int options, int* int_ref, int uuid, int* status); public: @@ -77,8 +77,8 @@ class SERVER_EXPORT JackServer // Command thread : API int SetBufferSize(jack_nframes_t buffer_size); int SetFreewheel(bool onoff); - int InternalClientLoad(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int* status); - int InternalClientLoad(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int* status); + int InternalClientLoad(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int uuid, int* status); + int InternalClientLoad(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int uuid, int* status); void ClientKill(int refnum); // Transport management diff --git a/common/JackServerAPI.cpp b/common/JackServerAPI.cpp index 50b4d291..5561f154 100644 --- a/common/JackServerAPI.cpp +++ b/common/JackServerAPI.cpp @@ -53,7 +53,7 @@ using namespace Jack; jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t* status) { - jack_varargs_t va; /* variable arguments */ + jack_varargs_t va; /* variable arguments */ jack_status_t my_status; JackClient* client; @@ -64,8 +64,8 @@ jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t optio jack_log("jack_client_new %s", client_name); - if (status == NULL) /* no status from caller? */ - status = &my_status; /* use local status word */ + if (status == NULL) /* no status from caller? */ + status = &my_status; /* use local status word */ *status = (jack_status_t)0; /* validate parameters */ @@ -90,7 +90,7 @@ jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t optio client = new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable()); } - int res = client->Open(va.server_name, client_name, options, status); + int res = client->Open(va.server_name, client_name, va.session_id, options, status); if (res < 0) { delete client; JackServerGlobals::Destroy(); // jack server destruction @@ -141,7 +141,7 @@ jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t opti client = new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable()); } - int res = client->Open(va.server_name, client_name, options, status); + int res = client->Open(va.server_name, client_name, va.session_id, options, status); if (res < 0) { delete client; JackServerGlobals::Destroy(); // jack server destruction @@ -191,7 +191,7 @@ EXPORT int jack_client_close(jack_client_t* ext_client) } else { res = client->Close(); delete client; - JackServerGlobals::Destroy(); // jack server destruction + JackServerGlobals::Destroy(); // jack server destruction jack_log("jack_client_close res = %d", res); } JackGlobals::fOpenMutex->Unlock(); diff --git a/common/JackThread.h b/common/JackThread.h index 9517a303..34dd798c 100644 --- a/common/JackThread.h +++ b/common/JackThread.h @@ -106,6 +106,7 @@ class SERVER_EXPORT JackThreadInterface int DropSelfRealTime(); // Used when called from thread itself pthread_t GetThreadID(); + bool IsThread(); static int AcquireRealTimeImp(pthread_t thread, int priority); static int AcquireRealTimeImp(pthread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint); diff --git a/common/JackTools.cpp b/common/JackTools.cpp index d74f34c0..bf21fbf5 100644 --- a/common/JackTools.cpp +++ b/common/JackTools.cpp @@ -20,6 +20,7 @@ #include "JackConstants.h" #include "JackDriverLoader.h" #include "JackTools.h" +#include "JackError.h" #include #include #include @@ -46,6 +47,15 @@ namespace Jack { { throw JackNetException(); } + + int JackTools::MkDir(const char* path) + { +#ifdef WIN32 + return CreateDirectory(path, NULL) == 0; +#else + return mkdir(path, 0777) != 0; +#endif + } #define DEFAULT_TMP_DIR "/tmp" char* jack_tmpdir = (char*)DEFAULT_TMP_DIR; diff --git a/common/JackTools.h b/common/JackTools.h index 2d058e81..50451e04 100644 --- a/common/JackTools.h +++ b/common/JackTools.h @@ -22,7 +22,10 @@ #ifdef WIN32 #include +#define DIR_SEPARATOR '\\' #else +#define DIR_SEPARATOR '/' +#include #include #include #include @@ -58,6 +61,7 @@ namespace Jack static void KillServer(); + static int MkDir(const char* path); static char* UserDir(); static char* ServerDir ( const char* server_name, char* server_dir ); static const char* DefaultServerName(); diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index fcf83a16..1eda4d11 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -196,7 +196,7 @@ int main(int argc, char* argv[]) { "help", 0, 0, 'h' }, { "port-max", 1, 0, 'p' }, { "no-mlock", 0, 0, 'm' }, - { "name", 0, 0, 'n' }, + { "name", 1, 0, 'n' }, { "unlock", 0, 0, 'u' }, { "realtime", 0, 0, 'R' }, { "no-realtime", 0, 0, 'r' }, @@ -439,7 +439,9 @@ int main(int argc, char* argv[]) goto fail_free1; } - // Start server + // Setup signals then start server + signals = jackctl_setup_signals(0); + if (!jackctl_server_start(server_ctl, audio_driver_ctl)) { fprintf(stderr, "Failed to start server\n"); goto fail_free1; @@ -474,7 +476,6 @@ int main(int argc, char* argv[]) notify_server_start(server_name); // Waits for signal - signals = jackctl_setup_signals(0); jackctl_wait_signals(signals); if (!jackctl_server_stop(server_ctl)) diff --git a/common/jack/jack.h b/common/jack/jack.h index 85e11fea..a63fcd12 100644 --- a/common/jack/jack.h +++ b/common/jack/jack.h @@ -625,13 +625,16 @@ float jack_cpu_load (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; * name. Exceeding that will cause the port registration to fail and * return NULL. * + * The @a port_name must be unique among all ports owned by this client. + * If the name is not unique, the registration will fail. + * * All ports have a type, which may be any non-NULL and non-zero * length string, passed as an argument. Some port types are built * into the JACK API, currently only JACK_DEFAULT_AUDIO_TYPE. * * @param client pointer to JACK client structure. * @param port_name non-empty short name for the new port (not - * including the leading @a "client_name:"). + * including the leading @a "client_name:"). Must be unique. * @param port_type port type name. If longer than * jack_port_type_size(), only that many characters are significant. * @param flags @ref JackPortFlags bit mask. diff --git a/common/jack/midiport.h b/common/jack/midiport.h index fd620b8d..e7e079a8 100644 --- a/common/jack/midiport.h +++ b/common/jack/midiport.h @@ -105,6 +105,10 @@ jack_midi_max_event_size(void* port_buffer) JACK_OPTIONAL_WEAK_EXPORT; * messages interspersed with other messages (realtime messages are fine * when they occur on their own, like other messages). * + * Events must be written in order, sorted by their sample offsets. + * JACK will not sort the events for you, and will refuse to store + * out-of-order events. + * * @param port_buffer Buffer to write event to. * @param time Sample offset of event. * @param data_size Length of event's raw data in bytes. @@ -122,6 +126,16 @@ jack_midi_event_reserve(void *port_buffer, * This function is simply a wrapper for @ref jack_midi_event_reserve * which writes the event data into the space reserved in the buffer. * The same restrictions on the MIDI data apply. + * + * Clients must not write more than + * @a data_size bytes into this buffer. Clients must write normalised + * MIDI data to the port - no running status and no (1-byte) realtime + * messages interspersed with other messages (realtime messages are fine + * when they occur on their own, like other messages). + * + * Events must be written in order, sorted by their sample offsets. + * JACK will not sort the events for you, and will refuse to store + * out-of-order events. * * @param port_buffer Buffer to write event to. * @param time Sample offset of event. diff --git a/common/jack/session.h b/common/jack/session.h new file mode 100644 index 00000000..f44048c0 --- /dev/null +++ b/common/jack/session.h @@ -0,0 +1,229 @@ +/* + Copyright (C) 2001 Paul Davis + Copyright (C) 2004 Jack O'Quin + Copyright (C) 2010 Torben Hohn + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __jack_session_h__ +#define __jack_session_h__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * @defgroup SessionClientFunctions Session API for clients. + * @{ + */ + + +/** + * session event types. + * + * if a client cant save templates, i might just do a normal save. + * + * the rationale, why there is no quit without save, is that a client + * might refuse to quit when it has unsaved data. + * however some other clients might have already quit. + * this results in too much confusion, so we just dont support that. + * the session manager can check, if the saved state is different from a previous + * save, and just remove the saved stuff. + * + * (an inquiry function, whether a quit is ok, followed by a quit event + * would have a race) + */ +enum JackSessionEventType { + JackSessionSave = 1, + JackSessionSaveAndQuit = 2, + JackSessionSaveTemplate = 3 +}; + +typedef enum JackSessionEventType jack_session_event_type_t; + +enum JackSessionFlags { + /** + * an error occured while saving. + */ + JackSessionSaveError = 0x01, + + /** + * this reply indicates that a client is part of a multiclient application. + * the command reply is left empty. but the session manager should still + * consider this client part of a session. it will come up due to invocation of another + * client. + */ + JackSessionChildClient = 0x02 +}; + +typedef enum JackSessionFlags jack_session_flags_t; + +struct _jack_session_event { + /** + * the actual type of this session event. + */ + jack_session_event_type_t type; + + /** + * session_directory with trailing separator + * this is per client. so the client can do whatever it likes in here. + */ + const char *session_dir; + + /** + * client_uuid which must be specified to jack_client_open on session reload. + * client can specify it in the returned commandline as an option, or just save it + * with the state file. + */ + const char *client_uuid; + + /** + * the command_line is the reply of the client. + * it specifies in a platform dependent way, how the client must be restarted upon session reload. + * + * probably it should contain ${SESSION_DIR} instead of the actual session dir. + * this would basically make the session dir moveable. + * + * ownership of the memory is handed to jack. + * initially set to NULL by jack; + */ + char *command_line; + + /** + * flags to be set by the client. normally left 0. + */ + jack_session_flags_t flags; +}; + +typedef struct _jack_session_event jack_session_event_t; + +/** + * Prototype for the client supplied function that is called + * whenever a session notification is sent via jack_session_notify(). + * + * The session_id must be passed to jack_client_open on session reload (this can be + * done by specifying it somehow on the returned command line). + * + * @param event the event_structure. + * @param arg pointer to a client supplied structure + */ +typedef void (*JackSessionCallback)(jack_session_event_t *event, void *arg); + +/** + * Tell the JACK server to call @a save_callback the session handler wants + * to save. + * + * @return 0 on success, otherwise a non-zero error code + */ +int jack_set_session_callback(jack_client_t *client, + JackSessionCallback session_callback, + void *arg) JACK_WEAK_EXPORT; + +/** + * reply to a session_event + * + * this can either be called directly from the callback, or later from a different thread. + * so its possible to just stick the event pointer into a pipe and execute the save code + * from the gui thread. + * + * @return 0 on success, otherwise a non-zero error code + */ + +int jack_session_reply( jack_client_t *client, jack_session_event_t *event ) JACK_WEAK_EXPORT; + + +/** + * free memory used by a jack_session_event_t + * this also frees the memory used by the command_line pointer. + * if its non NULL. + */ + +void jack_session_event_free (jack_session_event_t *event); + +/*@}*/ + + +/** + * @defgroup JackSessionManagerAPI this API is intended for a sessionmanager. + * this API could be server specific. if we dont reach consensus here, + * we can just drop it. + * i know its a bit clumsy. + * but this api isnt required to be as stable as the client api. + * @{ + */ + +typedef struct { + const char *uuid; + const char *client_name; + const char *command; + jack_session_flags_t flags; +} jack_session_command_t; + +/** + * send a save or quit event, to all clients listening for session + * callbacks. the returned strings of the clients are accumulated and + * returned as an array of jack_session_command_t. + * its terminated by ret[i].uuid == NULL + * target == NULL means send to all interested clients. otherwise a clientname + */ + +jack_session_command_t *jack_session_notify (jack_client_t* client, + const char *target, + jack_session_event_type_t type, + const char *path ) JACK_WEAK_EXPORT; + +/** + * free the memory allocated by a session command. + */ + +void jack_session_commands_free (jack_session_command_t *cmds) JACK_WEAK_EXPORT; + +/** + * get the sessionid for a client name. + * the sessionmanager needs this to reassociate a client_name to the session_id. + */ + +char *jack_get_uuid_for_client_name( jack_client_t *client, const char *client_name ) JACK_WEAK_EXPORT; + +/** + * get the client name for a session_id. + * in order to snapshot the graph connections, the sessionmanager needs to map + * session_ids to client names. + */ + +char *jack_get_client_name_by_uuid( jack_client_t *client, const char *client_uuid ) JACK_WEAK_EXPORT; + +/** + * reserve a client name and associate it to a uuid. + * when a client later call jack_client_open() and specifies the uuid, + * jackd will assign the reserved name. + * this allows a session manager to know in advance under which client name + * its managed clients will appear. + * + * @return 0 on success, otherwise a non-zero error code + */ + +int +jack_reserve_client_name( jack_client_t *client, const char *name, const char *uuid ) JACK_WEAK_EXPORT; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/common/jack/types.h b/common/jack/types.h index 3722d7f4..65c930d7 100644 --- a/common/jack/types.h +++ b/common/jack/types.h @@ -23,18 +23,17 @@ #include - typedef int32_t jack_shmsize_t; /** * Type used to represent sample frame counts. */ -typedef uint32_t jack_nframes_t; +typedef uint32_t jack_nframes_t; /** * Maximum value that can be stored in jack_nframes_t */ -#define JACK_MAX_FRAMES (4294967295U) /* This should be UINT32_MAX, but C++ has a problem with that. */ +#define JACK_MAX_FRAMES (4294967295U) /* This should be UINT32_MAX, but C++ has a problem with that. */ /** * Type used to represent the value of free running @@ -284,9 +283,9 @@ enum JackPortFlags { /** * JackPortIsTerminal means: * - * for an input port: the data received by the port + * for an input port: the data received by the port * will not be passed on or made - * available at any other port + * available at any other port * * for an output port: the data available at the port * does not originate from any other port @@ -345,11 +344,16 @@ enum JackOptions { * Pass optional (char *) load_init string to the * jack_initialize() entry point of an internal client. */ - JackLoadInit = 0x10 + JackLoadInit = 0x10, + + /** + * pass a SessionID Token this allows the sessionmanager to identify the client again. + */ + JackSessionID = 0x20 }; /** Valid options for opening an external client. */ -#define JackOpenOptions (JackServerName|JackNoStartServer|JackUseExactName) +#define JackOpenOptions (JackSessionID|JackServerName|JackNoStartServer|JackUseExactName) /** Valid options for loading an internal client. */ #define JackLoadOptions (JackLoadInit|JackLoadName|JackUseExactName) @@ -456,20 +460,20 @@ typedef enum { JackTransportRolling = 1, /**< Transport playing */ JackTransportLooping = 2, /**< For OLD_TRANSPORT, now ignored */ JackTransportStarting = 3, /**< Waiting for sync ready */ - JackTransportNetStarting = 4, /**< Waiting for sync ready on the network*/ + JackTransportNetStarting = 4, /**< Waiting for sync ready on the network*/ } jack_transport_state_t; -typedef uint64_t jack_unique_t; /**< Unique ID (opaque) */ +typedef uint64_t jack_unique_t; /**< Unique ID (opaque) */ /** * Optional struct jack_position_t fields. */ typedef enum { - JackPositionBBT = 0x10, /**< Bar, Beat, Tick */ - JackPositionTimecode = 0x20, /**< External timecode */ - JackBBTFrameOffset = 0x40, /**< Frame offset of BBT information */ + JackPositionBBT = 0x10, /**< Bar, Beat, Tick */ + JackPositionTimecode = 0x20, /**< External timecode */ + JackBBTFrameOffset = 0x40, /**< Frame offset of BBT information */ JackAudioVideoRatio = 0x80, /**< audio frames per video frame */ JackVideoFrameOffset = 0x100 /**< frame offset of first video frame */ @@ -482,31 +486,31 @@ typedef enum { typedef struct { /* these four cannot be set from clients: the server sets them */ - jack_unique_t unique_1; /**< unique ID */ - jack_time_t usecs; /**< monotonic, free-rolling */ - jack_nframes_t frame_rate; /**< current frame rate (per second) */ - jack_nframes_t frame; /**< frame number, always present */ + jack_unique_t unique_1; /**< unique ID */ + jack_time_t usecs; /**< monotonic, free-rolling */ + jack_nframes_t frame_rate; /**< current frame rate (per second) */ + jack_nframes_t frame; /**< frame number, always present */ - jack_position_bits_t valid; /**< which other fields are valid */ + jack_position_bits_t valid; /**< which other fields are valid */ /* JackPositionBBT fields: */ - int32_t bar; /**< current bar */ - int32_t beat; /**< current beat-within-bar */ - int32_t tick; /**< current tick-within-beat */ - double bar_start_tick; - - float beats_per_bar; /**< time signature "numerator" */ - float beat_type; /**< time signature "denominator" */ - double ticks_per_beat; - double beats_per_minute; - - /* JackPositionTimecode fields: (EXPERIMENTAL: could change) */ - double frame_time; /**< current time in seconds */ - double next_time; /**< next sequential frame_time + int32_t bar; /**< current bar */ + int32_t beat; /**< current beat-within-bar */ + int32_t tick; /**< current tick-within-beat */ + double bar_start_tick; + + float beats_per_bar; /**< time signature "numerator" */ + float beat_type; /**< time signature "denominator" */ + double ticks_per_beat; + double beats_per_minute; + + /* JackPositionTimecode fields: (EXPERIMENTAL: could change) */ + double frame_time; /**< current time in seconds */ + double next_time; /**< next sequential frame_time (unless repositioned) */ /* JackBBTFrameOffset fields: */ - jack_nframes_t bbt_offset; /**< frame offset for the BBT fields + jack_nframes_t bbt_offset; /**< frame offset for the BBT fields (the given bar, beat, and tick values actually refer to a time frame_offset frames before the @@ -540,10 +544,10 @@ typedef struct { /* For binary compatibility, new fields should be allocated from * this padding area with new valid bits controlling access, so * the existing structure size and offsets are preserved. */ - int32_t padding[7]; + int32_t padding[7]; /* When (unique_1 == unique_2) the contents are consistent. */ - jack_unique_t unique_2; /**< unique ID */ + jack_unique_t unique_2; /**< unique ID */ } jack_position_t; @@ -620,11 +624,11 @@ typedef void (*JackTimebaseCallback)(jack_transport_state_t state, */ typedef enum { - JackTransportState = 0x1, /**< Transport state */ - JackTransportPosition = 0x2, /**< Frame number */ - JackTransportLoop = 0x4, /**< Loop boundaries (ignored) */ - JackTransportSMPTE = 0x8, /**< SMPTE (ignored) */ - JackTransportBBT = 0x10 /**< Bar, Beat, Tick */ + JackTransportState = 0x1, /**< Transport state */ + JackTransportPosition = 0x2, /**< Frame number */ + JackTransportLoop = 0x4, /**< Loop boundaries (ignored) */ + JackTransportSMPTE = 0x8, /**< SMPTE (ignored) */ + JackTransportBBT = 0x10 /**< Bar, Beat, Tick */ } jack_transport_bits_t; @@ -638,17 +642,17 @@ typedef struct { /* these two cannot be set from clients: the server sets them */ - jack_nframes_t frame_rate; /**< current frame rate (per second) */ - jack_time_t usecs; /**< monotonic, free-rolling */ + jack_nframes_t frame_rate; /**< current frame rate (per second) */ + jack_time_t usecs; /**< monotonic, free-rolling */ - jack_transport_bits_t valid; /**< which fields are legal to read */ + jack_transport_bits_t valid; /**< which fields are legal to read */ jack_transport_state_t transport_state; jack_nframes_t frame; jack_nframes_t loop_start; jack_nframes_t loop_end; - long smpte_offset; /**< SMPTE offset (from frame 0) */ - float smpte_frame_rate; /**< 29.97, 30, 24 etc. */ + long smpte_offset; /**< SMPTE offset (from frame 0) */ + float smpte_frame_rate; /**< 29.97, 30, 24 etc. */ int bar; int beat; diff --git a/common/varargs.h b/common/varargs.h index d1442fd3..b7df00f6 100644 --- a/common/varargs.h +++ b/common/varargs.h @@ -32,14 +32,15 @@ extern "C" /* variable argument structure */ typedef struct { - char *server_name; /* server name */ - char *load_name; /* load module name */ - char *load_init; /* initialization string */ + char *server_name; /* server name */ + char *load_name; /* load module name */ + char *load_init; /* initialization string */ + int session_id; /* requested session_id */ } jack_varargs_t; static const char* jack_default_server_name (void) - { + { const char *server_name; if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL) server_name = "default"; @@ -47,13 +48,14 @@ extern "C" } static inline void jack_varargs_init (jack_varargs_t *va) - { + { memset (va, 0, sizeof(jack_varargs_t)); va->server_name = (char*)jack_default_server_name(); + va->session_id = -1; } static inline void jack_varargs_parse (jack_options_t options, va_list ap, jack_varargs_t *va) - { + { // initialize default settings jack_varargs_init (va); @@ -66,6 +68,11 @@ extern "C" va->load_name = va_arg(ap, char *); if ((options & JackLoadInit)) va->load_init = va_arg(ap, char *); + if ((options & JackSessionID)) { + char *sid = va_arg(ap, char *); + if (sid) + va->session_id = atoi( sid ); + } } #ifdef __cplusplus diff --git a/common/wscript b/common/wscript index 4af4f268..a3935904 100644 --- a/common/wscript +++ b/common/wscript @@ -97,7 +97,7 @@ def build(bld): '../posix/JackPosixThread.cpp', '../macosx/JackMachThread.cpp', '../macosx/JackMachSemaphore.cpp', - '../macosx/JackMachPort.cpp', + '../posix/JackSocket.cpp', '../macosx/JackMachTime.c', ] includes = ['../macosx', '../macosx/RPC', '../posix'] + includes @@ -152,11 +152,9 @@ def build(bld): if bld.env['IS_MACOSX']: serverlib.source += [ - '../macosx/JackMachServerChannel.cpp', - '../macosx/JackMachNotifyChannel.cpp', - '../macosx/JackMachServerNotifyChannel.cpp', - '../macosx/JackMacEngineRPC.cpp', - '../macosx/RPC/JackRPCClientUser.c', + '../posix/JackSocketServerChannel.cpp', + '../posix/JackSocketNotifyChannel.cpp', + '../posix/JackSocketServerNotifyChannel.cpp', '../posix/JackNetUnixSocket.cpp', ] @@ -237,9 +235,7 @@ def build(bld): if bld.env['IS_MACOSX']: clientlib.source += [ - '../macosx/JackMachClientChannel.cpp', - '../macosx/RPC/JackRPCEngineUser.c', - '../macosx/JackMacLibClientRPC.cpp', + '../posix/JackSocketClientChannel.cpp', '../posix/JackPosixServerLaunch.cpp', ] diff --git a/dbus/controller_iface_patchbay.c b/dbus/controller_iface_patchbay.c index ed477d7d..5acee604 100644 --- a/dbus/controller_iface_patchbay.c +++ b/dbus/controller_iface_patchbay.c @@ -323,7 +323,7 @@ jack_controller_patchbay_find_client( list_for_each(node_ptr, &patchbay_ptr->graph.clients) { client_ptr = list_entry(node_ptr, struct jack_graph_client, siblings); - if (strncmp(client_ptr->name, client_name, client_name_len) == 0) + if (strlen(client_ptr->name) == client_name_len && strncmp(client_ptr->name, client_name, client_name_len) == 0) { return client_ptr; } diff --git a/dbus/jackdbus.c b/dbus/jackdbus.c index eb86308b..cb9fd14d 100644 --- a/dbus/jackdbus.c +++ b/dbus/jackdbus.c @@ -1,6 +1,6 @@ /* -*- Mode: C ; c-basic-offset: 4 -*- */ /* - Copyright (C) 2007,2008 Nedko Arnaudov + Copyright (C) 2007,2008,2010 Nedko Arnaudov Copyright (C) 2007-2008 Juuso Alasuutari Copyright (C) 2008 Marc-Olivier Barre @@ -44,6 +44,8 @@ #include "sigsegv.h" #include "svnversion.h" +static char * g_log_filename; +static ino_t g_log_file_ino; FILE *g_logfile; char *g_jackdbus_config_dir; size_t g_jackdbus_config_dir_len; /* without terminating '\0' char */ @@ -550,6 +552,49 @@ fail: jack_error ("Ran out of memory trying to construct method return"); } +static bool jack_dbus_log_open(void) +{ + struct stat st; + int ret; + int retry; + + if (g_logfile != NULL) + { + ret = stat(g_log_filename, &st); + if (ret != 0 || g_log_file_ino != st.st_ino) + { + fclose(g_logfile); + } + else + { + return true; + } + } + + for (retry = 0; retry < 10; retry++) + { + g_logfile = fopen(g_log_filename, "a"); + if (g_logfile == NULL) + { + fprintf(stderr, "Cannot open jackdbus log file \"%s\": %d (%s)\n", g_log_filename, errno, strerror(errno)); + return false; + } + + ret = stat(g_log_filename, &st); + if (ret == 0) + { + g_log_file_ino = st.st_ino; + return true; + } + + fclose(g_logfile); + g_logfile = NULL; + } + + fprintf(stderr, "Cannot stat just opened jackdbus log file \"%s\": %d (%s). %d retries\n", g_log_filename, errno, strerror(errno), retry); + return false; +} + void jack_dbus_info_callback(const char *msg) { @@ -560,8 +605,11 @@ jack_dbus_info_callback(const char *msg) ctime_r(×tamp, timestamp_str); timestamp_str[24] = 0; - fprintf(g_logfile, "%s: %s\n", timestamp_str, msg); - fflush(g_logfile); + if (jack_dbus_log_open()) + { + fprintf(g_logfile, "%s: %s\n", timestamp_str, msg); + fflush(g_logfile); + } } #define ANSI_BOLD_ON "\033[1m" @@ -579,8 +627,11 @@ jack_dbus_error_callback(const char *msg) ctime_r(×tamp, timestamp_str); timestamp_str[24] = 0; - fprintf(g_logfile, "%s: " ANSI_BOLD_ON ANSI_COLOR_RED "ERROR: %s" ANSI_RESET "\n", timestamp_str, msg); - fflush(g_logfile); + if (jack_dbus_log_open()) + { + fprintf(g_logfile, "%s: " ANSI_BOLD_ON ANSI_COLOR_RED "ERROR: %s" ANSI_RESET "\n", timestamp_str, msg); + fflush(g_logfile); + } } bool @@ -695,42 +746,39 @@ paths_uninit() free(g_jackdbus_log_dir); } -int -log_init() +static bool log_init(void) { - char *log_filename; size_t log_len; log_len = strlen(JACKDBUS_LOG); - log_filename = malloc(g_jackdbus_log_dir_len + log_len + 1); - if (log_filename == NULL) + g_log_filename = malloc(g_jackdbus_log_dir_len + log_len + 1); + if (g_log_filename == NULL) { fprintf(stderr, "Out of memory\n"); - return FALSE; + return false; } - memcpy(log_filename, g_jackdbus_log_dir, g_jackdbus_log_dir_len); - memcpy(log_filename + g_jackdbus_log_dir_len, JACKDBUS_LOG, log_len); - log_filename[g_jackdbus_log_dir_len + log_len] = 0; + memcpy(g_log_filename, g_jackdbus_log_dir, g_jackdbus_log_dir_len); + memcpy(g_log_filename + g_jackdbus_log_dir_len, JACKDBUS_LOG, log_len); + g_log_filename[g_jackdbus_log_dir_len + log_len] = 0; - g_logfile = fopen(log_filename, "a"); - if (g_logfile == NULL) + if (!jack_dbus_log_open()) { - fprintf(stderr, "Cannot open jackdbus log file \"%s\": %d (%s)\n", log_filename, errno, strerror(errno)); - free(log_filename); - return FALSE; + return false; } - free(log_filename); - - return TRUE; + return true; } -void -log_uninit() +static void log_uninit(void) { - fclose(g_logfile); + if (g_logfile != NULL) + { + fclose(g_logfile); + } + + free(g_log_filename); } void diff --git a/doxyfile b/doxyfile index a0d35e99..8f1342a4 100644 --- a/doxyfile +++ b/doxyfile @@ -23,7 +23,7 @@ PROJECT_NAME = "Jack2" # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 1.9.6 +PROJECT_NUMBER = 1.9.7 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/example-clients/lsp.c b/example-clients/lsp.c index 5a3362f2..da25643e 100644 --- a/example-clients/lsp.c +++ b/example-clients/lsp.c @@ -146,7 +146,7 @@ main (int argc, char *argv[]) if (!ports) goto error; - for (i = 0; ports[i]; ++i) { + for (i = 0; ports && ports[i]; ++i) { // skip over any that don't match ALL of the strings presented at command line skip_port = 0; for(k = optind; k < argc; k++){ @@ -227,6 +227,8 @@ main (int argc, char *argv[]) } error: + if (ports) + jack_free (ports); jack_client_close (client); exit (0); } diff --git a/example-clients/netsource.c b/example-clients/netsource.c index a78dc8cb..9f995406 100644 --- a/example-clients/netsource.c +++ b/example-clients/netsource.c @@ -266,7 +266,7 @@ process (jack_nframes_t nframes, void *arg) jack_position_t local_trans_pos; - uint32_t *packet_buf, *packet_bufX; + uint32_t *packet_buf_tx, *packet_bufX; uint32_t *rx_packet_ptr; jack_time_t packet_recv_timestamp; @@ -280,9 +280,9 @@ process (jack_nframes_t nframes, void *arg) /* Allocate a buffer where both In and Out Buffer will fit */ - packet_buf = alloca ((rx_bufsize > tx_bufsize) ? rx_bufsize : tx_bufsize); + packet_buf_tx = alloca (tx_bufsize); - jacknet_packet_header *pkthdr = (jacknet_packet_header *) packet_buf; + jacknet_packet_header *pkthdr_tx = (jacknet_packet_header *) packet_buf_tx; /* * for latency==0 we need to send out the packet before we wait on the reply. @@ -293,38 +293,38 @@ process (jack_nframes_t nframes, void *arg) if( latency == 0 ) { /* reset packet_bufX... */ - packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); + packet_bufX = packet_buf_tx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); /* ---------- Send ---------- */ render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes, packet_bufX, net_period, dont_htonl_floats); /* fill in packet hdr */ - pkthdr->transport_state = jack_transport_query (client, &local_trans_pos); - pkthdr->transport_frame = local_trans_pos.frame; - pkthdr->framecnt = framecnt; - pkthdr->latency = latency; - pkthdr->reply_port = reply_port; - pkthdr->sample_rate = jack_get_sample_rate (client); - pkthdr->period_size = nframes; + pkthdr_tx->transport_state = jack_transport_query (client, &local_trans_pos); + pkthdr_tx->transport_frame = local_trans_pos.frame; + pkthdr_tx->framecnt = framecnt; + pkthdr_tx->latency = latency; + pkthdr_tx->reply_port = reply_port; + pkthdr_tx->sample_rate = jack_get_sample_rate (client); + pkthdr_tx->period_size = nframes; /* playback for us is capture on the other side */ - pkthdr->capture_channels_audio = playback_channels_audio; - pkthdr->playback_channels_audio = capture_channels_audio; - pkthdr->capture_channels_midi = playback_channels_midi; - pkthdr->playback_channels_midi = capture_channels_midi; - pkthdr->mtu = mtu; + pkthdr_tx->capture_channels_audio = playback_channels_audio; + pkthdr_tx->playback_channels_audio = capture_channels_audio; + pkthdr_tx->capture_channels_midi = playback_channels_midi; + pkthdr_tx->playback_channels_midi = capture_channels_midi; + pkthdr_tx->mtu = mtu; if( freewheeling!= 0 ) - pkthdr->sync_state = (jack_nframes_t)MASTER_FREEWHEELS; + pkthdr_tx->sync_state = (jack_nframes_t)MASTER_FREEWHEELS; else - pkthdr->sync_state = (jack_nframes_t)deadline_goodness; + pkthdr_tx->sync_state = (jack_nframes_t)deadline_goodness; //printf("goodness=%d\n", deadline_goodness ); - packet_header_hton (pkthdr); + packet_header_hton (pkthdr_tx); if (cont_miss < 3*latency+5) { int r; for( r=0; r 50+5*latency) { @@ -340,8 +340,6 @@ process (jack_nframes_t nframes, void *arg) * */ - /* reset packet_bufX... */ - packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); if( reply_port ) input_fd = insockfd; @@ -374,14 +372,14 @@ process (jack_nframes_t nframes, void *arg) * to the JACK ports so it can be played. */ if (size == rx_bufsize) { - packet_buf = rx_packet_ptr; - pkthdr = (jacknet_packet_header *) packet_buf; - packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); + uint32_t *packet_buf_rx = rx_packet_ptr; + jacknet_packet_header *pkthdr_rx = (jacknet_packet_header *) packet_buf_rx; + packet_bufX = packet_buf_rx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); // calculate how much time there would have been, if this packet was sent at the deadline. int recv_time_offset = (int) (jack_get_time() - packet_recv_timestamp); - packet_header_ntoh (pkthdr); - deadline_goodness = recv_time_offset - (int)pkthdr->latency; + packet_header_ntoh (pkthdr_rx); + deadline_goodness = recv_time_offset - (int)pkthdr_rx->latency; //printf( "deadline goodness = %d ---> off: %d\n", deadline_goodness, recv_time_offset ); if (cont_miss) @@ -395,7 +393,7 @@ process (jack_nframes_t nframes, void *arg) state_currentframe = framecnt; state_recv_packet_queue_time = recv_time_offset; state_connected = 1; - sync_state = pkthdr->sync_state; + sync_state = pkthdr_rx->sync_state; packet_cache_release_packet( global_packcache, framecnt - latency ); } /* Second alternative : we've received something that's not @@ -434,38 +432,38 @@ process (jack_nframes_t nframes, void *arg) } if( latency != 0 ) { /* reset packet_bufX... */ - packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); + packet_bufX = packet_buf_tx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); /* ---------- Send ---------- */ render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes, packet_bufX, net_period, dont_htonl_floats); /* fill in packet hdr */ - pkthdr->transport_state = jack_transport_query (client, &local_trans_pos); - pkthdr->transport_frame = local_trans_pos.frame; - pkthdr->framecnt = framecnt; - pkthdr->latency = latency; - pkthdr->reply_port = reply_port; - pkthdr->sample_rate = jack_get_sample_rate (client); - pkthdr->period_size = nframes; + pkthdr_tx->transport_state = jack_transport_query (client, &local_trans_pos); + pkthdr_tx->transport_frame = local_trans_pos.frame; + pkthdr_tx->framecnt = framecnt; + pkthdr_tx->latency = latency; + pkthdr_tx->reply_port = reply_port; + pkthdr_tx->sample_rate = jack_get_sample_rate (client); + pkthdr_tx->period_size = nframes; /* playback for us is capture on the other side */ - pkthdr->capture_channels_audio = playback_channels_audio; - pkthdr->playback_channels_audio = capture_channels_audio; - pkthdr->capture_channels_midi = playback_channels_midi; - pkthdr->playback_channels_midi = capture_channels_midi; - pkthdr->mtu = mtu; + pkthdr_tx->capture_channels_audio = playback_channels_audio; + pkthdr_tx->playback_channels_audio = capture_channels_audio; + pkthdr_tx->capture_channels_midi = playback_channels_midi; + pkthdr_tx->playback_channels_midi = capture_channels_midi; + pkthdr_tx->mtu = mtu; if( freewheeling!= 0 ) - pkthdr->sync_state = (jack_nframes_t)MASTER_FREEWHEELS; + pkthdr_tx->sync_state = (jack_nframes_t)MASTER_FREEWHEELS; else - pkthdr->sync_state = (jack_nframes_t)deadline_goodness; + pkthdr_tx->sync_state = (jack_nframes_t)deadline_goodness; //printf("goodness=%d\n", deadline_goodness ); - packet_header_hton (pkthdr); + packet_header_hton (pkthdr_tx); if (cont_miss < 3*latency+5) { int r; for( r=0; r 50+5*latency) { diff --git a/example-clients/session_notify.c b/example-clients/session_notify.c new file mode 100644 index 00000000..e8a6d517 --- /dev/null +++ b/example-clients/session_notify.c @@ -0,0 +1,184 @@ +/* + * session_notify.c -- ultra minimal session manager + * + * Copyright (C) 2010 Torben Hohn. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *package; /* program name */ +jack_client_t *client; + +jack_session_event_type_t notify_type; +char *save_path = NULL; + +void jack_shutdown(void *arg) +{ + fprintf(stderr, "JACK shut down, exiting ...\n"); + exit(1); +} + +void signal_handler(int sig) +{ + jack_client_close(client); + fprintf(stderr, "signal received, exiting ...\n"); + exit(0); +} + +void parse_arguments(int argc, char *argv[]) +{ + + /* basename $0 */ + package = strrchr(argv[0], '/'); + if (package == 0) + package = argv[0]; + else + package++; + + if (argc==2) { + if( !strcmp( argv[1], "quit" ) ) { + notify_type = JackSessionSaveAndQuit; + return; + } + } + if (argc==3) { + if( !strcmp( argv[1], "save" ) ) { + notify_type = JackSessionSave; + save_path = argv[2]; + return; + } + + } + fprintf(stderr, "usage: %s quit|save [path]\n", package); + exit(9); +} + +typedef struct { + char name[32]; + char uuid[16]; +} uuid_map_t; + +JSList *uuid_map = NULL; + +void add_uuid_mapping( const char *uuid ) { + char *clientname = jack_get_client_name_by_uuid( client, uuid ); + if( !clientname ) { + printf( "error... cant find client for uuid %s", uuid ); + + return; + } + + uuid_map_t *mapping = malloc( sizeof(uuid_map_t) ); + snprintf( mapping->uuid, sizeof(mapping->uuid), "%s", uuid ); + snprintf( mapping->name, sizeof(mapping->name), "%s", clientname ); + uuid_map = jack_slist_append( uuid_map, mapping ); +} + +char *map_port_name_to_uuid_port( const char *port_name ) +{ + JSList *node; + char retval[300]; + char *port_component = strchr( port_name,':' ); + char *client_component = strdup( port_name ); + strchr( client_component, ':' )[0] = '\0'; + + sprintf( retval, "%s", port_name ); + + for( node=uuid_map; node; node=jack_slist_next(node) ) { + uuid_map_t *mapping = node->data; + if( !strcmp( mapping->name, client_component ) ) { + sprintf( retval, "%s%s", mapping->uuid, port_component ); + break; + } + } + + return strdup(retval); +} + +int main(int argc, char *argv[]) +{ + parse_arguments(argc, argv); + jack_session_command_t *retval; + int k,i,j; + + + /* become a JACK client */ + if ((client = jack_client_open(package, JackNullOption, NULL)) == 0) { + fprintf(stderr, "JACK server not running?\n"); + exit(1); + } + + signal(SIGQUIT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGHUP, signal_handler); + signal(SIGINT, signal_handler); + + jack_on_shutdown(client, jack_shutdown, 0); + + jack_activate(client); + + + retval = jack_session_notify( client, NULL, notify_type, save_path ); + printf( "retval = %p\n", retval ); + for(i=0; retval[i].uuid; i++ ) { + printf( "export SESSION_DIR=\"%s%s/\"\n", save_path, retval[i].client_name ); + printf( "%s &\n", retval[i].command ); + add_uuid_mapping(retval[i].uuid); + } + + printf( "sleep 10\n" ); + + for(k=0; retval[k].uuid; k++ ) { + + char* port_regexp = alloca( jack_client_name_size()+3 ); + char* client_name = jack_get_client_name_by_uuid( client, retval[k].uuid ); + snprintf( port_regexp, jack_client_name_size()+3, "%s:.*", client_name ); + jack_free(client_name); + const char **ports = jack_get_ports( client, port_regexp, NULL, 0 ); + if( !ports ) { + continue; + } + for (i = 0; ports[i]; ++i) { + const char **connections; + if ((connections = jack_port_get_all_connections (client, jack_port_by_name(client, ports[i]))) != 0) { + for (j = 0; connections[j]; j++) { + char *src = map_port_name_to_uuid_port( ports[i] ); + char *dst = map_port_name_to_uuid_port( connections[j] ); + printf( "jack_connect -u \"%s\" \"%s\"\n", src, dst ); + } + jack_free (connections); + } + } + jack_free(ports); + + } + jack_session_commands_free(retval); + + jack_client_close(client); + + return 0; +} diff --git a/example-clients/simple_session_client.c b/example-clients/simple_session_client.c new file mode 100644 index 00000000..8d06127c --- /dev/null +++ b/example-clients/simple_session_client.c @@ -0,0 +1,202 @@ +/** @file simple_session_client.c + * + * @brief This simple client demonstrates the most basic features of JACK + * as they would be used by many applications. + * this version also adds session manager functionality. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +jack_port_t *input_port; +jack_port_t *output_port; +jack_client_t *client; + +int simple_quit = 0; + +/** + * The process callback for this JACK application is called in a + * special realtime thread once for each audio cycle. + * + * This client does nothing more than copy data from its input + * port to its output port. It will exit when stopped by + * the user (e.g. using Ctrl-C on a unix-ish operating system) + */ +int +process (jack_nframes_t nframes, void *arg) +{ + jack_default_audio_sample_t *in, *out; + + in = jack_port_get_buffer (input_port, nframes); + out = jack_port_get_buffer (output_port, nframes); + memcpy (out, in, + sizeof (jack_default_audio_sample_t) * nframes); + + return 0; +} + +void +session_callback (jack_session_event_t *event, void *arg) +{ + char retval[100]; + printf ("session notification\n"); + printf ("path %s, uuid %s, type: %s\n", event->session_dir, event->client_uuid, event->type == JackSessionSave ? "save" : "quit"); + + + snprintf (retval, 100, "jack_simple_session_client %s", event->client_uuid); + event->command_line = strdup (retval); + + jack_session_reply( client, event ); + + if (event->type == JackSessionSaveAndQuit) { + simple_quit = 1; + } + + jack_session_event_free (event); +} + +/** + * JACK calls this shutdown_callback if the server ever shuts down or + * decides to disconnect the client. + */ +void +jack_shutdown (void *arg) +{ + exit (1); +} + +int +main (int argc, char *argv[]) +{ + const char **ports; + const char *client_name = "simple"; + jack_status_t status; + + /* open a client connection to the JACK server */ + + if( argc == 1 ) + client = jack_client_open (client_name, JackNullOption, &status ); + else if( argc == 2 ) + client = jack_client_open (client_name, JackSessionID, &status, argv[1] ); + + if (client == NULL) { + fprintf (stderr, "jack_client_open() failed, " + "status = 0x%2.0x\n", status); + if (status & JackServerFailed) { + fprintf (stderr, "Unable to connect to JACK server\n"); + } + exit (1); + } + if (status & JackServerStarted) { + fprintf (stderr, "JACK server started\n"); + } + if (status & JackNameNotUnique) { + client_name = jack_get_client_name(client); + fprintf (stderr, "unique name `%s' assigned\n", client_name); + } + + /* tell the JACK server to call `process()' whenever + there is work to be done. + */ + + jack_set_process_callback (client, process, 0); + + /* tell the JACK server to call `jack_shutdown()' if + it ever shuts down, either entirely, or if it + just decides to stop calling us. + */ + + jack_on_shutdown (client, jack_shutdown, 0); + + /* tell the JACK server to call `session_callback()' if + the session is saved. + */ + + jack_set_session_callback (client, session_callback, NULL); + + /* display the current sample rate. + */ + + printf ("engine sample rate: %" PRIu32 "\n", + jack_get_sample_rate (client)); + + /* create two ports */ + + input_port = jack_port_register (client, "input", + JACK_DEFAULT_AUDIO_TYPE, + JackPortIsInput, 0); + output_port = jack_port_register (client, "output", + JACK_DEFAULT_AUDIO_TYPE, + JackPortIsOutput, 0); + + if ((input_port == NULL) || (output_port == NULL)) { + fprintf(stderr, "no more JACK ports available\n"); + exit (1); + } + + /* Tell the JACK server that we are ready to roll. Our + * process() callback will start running now. */ + + if (jack_activate (client)) { + fprintf (stderr, "cannot activate client"); + exit (1); + } + + /* Connect the ports. You can't do this before the client is + * activated, because we can't make connections to clients + * that aren't running. Note the confusing (but necessary) + * orientation of the driver backend ports: playback ports are + * "input" to the backend, and capture ports are "output" from + * it. + */ + + + /* only do the autoconnect when not reloading from a session. + * in case of a session reload, the SM will restore our connections + */ + + if (argc==1) { + + ports = jack_get_ports (client, NULL, NULL, + JackPortIsPhysical|JackPortIsOutput); + if (ports == NULL) { + fprintf(stderr, "no physical capture ports\n"); + exit (1); + } + + if (jack_connect (client, ports[0], jack_port_name (input_port))) { + fprintf (stderr, "cannot connect input ports\n"); + } + + free (ports); + + ports = jack_get_ports (client, NULL, NULL, + JackPortIsPhysical|JackPortIsInput); + if (ports == NULL) { + fprintf(stderr, "no physical playback ports\n"); + exit (1); + } + + if (jack_connect (client, jack_port_name (output_port), ports[0])) { + fprintf (stderr, "cannot connect output ports\n"); + } + + free (ports); + } + + /* keep running until until we get a quit event */ + + while (!simple_quit) + sleep(1); + + + jack_client_close (client); + exit (0); +} diff --git a/example-clients/wscript b/example-clients/wscript index 3f629cca..1b07b0b1 100644 --- a/example-clients/wscript +++ b/example-clients/wscript @@ -22,6 +22,8 @@ example_programs = { 'jack_monitor_client' : 'monitor_client.c', 'jack_thru' : 'thru_client.c', 'jack_cpu_load' : 'cpu_load.c', + 'jack_simple_session_client' : 'simple_session_client.c', + 'jack_session_notify' : 'session_notify.c', 'jack_server_control' : 'server_control.cpp', 'jack_net_slave' : 'netslave.c', 'jack_net_master' : 'netmaster.c', diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index cc86f2ed..efcc1f94 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -120,7 +120,7 @@ get_control_device_name (const char * device_name) char tmp[5]; strncpy(tmp, strstr(device_name, "hw"), 4); tmp[4] = '\0'; - //jack_log("control device %s", tmp); + jack_info("control device %s",tmp); ctl_name = strdup(tmp); } else { ctl_name = strdup(device_name); @@ -151,21 +151,16 @@ JackAlsaDriver::alsa_driver_check_card_type (alsa_driver_t *driver) if ((err = snd_ctl_open (&driver->ctl_handle, ctl_name, 0)) < 0) { jack_error ("control open \"%s\" (%s)", ctl_name, snd_strerror(err)); - return -1; - } - - if ((err = snd_ctl_card_info(driver->ctl_handle, card_info)) < 0) { + } else if ((err = snd_ctl_card_info(driver->ctl_handle, card_info)) < 0) { jack_error ("control hardware info \"%s\" (%s)", driver->alsa_name_playback, snd_strerror (err)); snd_ctl_close (driver->ctl_handle); - return -1; } driver->alsa_driver = strdup(snd_ctl_card_info_get_driver (card_info)); jack_info("Using ALSA driver %s running on card %i - %s", driver->alsa_driver, snd_ctl_card_info_get_card(card_info), snd_ctl_card_info_get_longname(card_info)); free(ctl_name); - return alsa_driver_check_capabilities (driver); } @@ -1171,7 +1166,6 @@ JackAlsaDriver::alsa_driver_restart (alsa_driver_t *driver) if (res && driver->midi) (driver->midi->stop)(driver->midi); - return res; } @@ -1181,8 +1175,6 @@ JackAlsaDriver::alsa_driver_xrun_recovery (alsa_driver_t *driver, float *delayed snd_pcm_status_t *status; int res; - jack_error("alsa_driver_xrun_recovery"); - snd_pcm_status_alloca(&status); if (driver->capture_handle) { @@ -1205,7 +1197,7 @@ JackAlsaDriver::alsa_driver_xrun_recovery (alsa_driver_t *driver, float *delayed snd_pcm_status_get_trigger_tstamp(status, &tstamp); timersub(&now, &tstamp, &diff); *delayed_usecs = diff.tv_sec * 1000000.0 + diff.tv_usec; - jack_error("\n\n**** alsa_pcm: xrun of at least %.3f msecs\n\n", *delayed_usecs / 1000.0); + jack_error("**** alsa_pcm: xrun of at least %.3f msecs", *delayed_usecs / 1000.0); } if (alsa_driver_restart (driver)) { @@ -1371,7 +1363,7 @@ JackAlsaDriver::alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *stat /* if POLLIN was the only bit set, we're OK */ *status = 0; - if (driver->pfd[nfds-1].revents == POLLIN) { + if (driver->pfd[nfds-1].revents != POLLIN) { jack_error("driver->pfd[nfds-1].revents == POLLIN"); } return (driver->pfd[nfds-1].revents == POLLIN) ? 0 : -1; @@ -1585,7 +1577,6 @@ JackAlsaDriver::alsa_driver_read (alsa_driver_t *driver, jack_nframes_t nframes) jack_error ("ALSA: could not complete read of %" PRIu32 " frames: error = %d\n", contiguous, err); - jack_error ("ALSA: could not complete read of %d frames: error = %d", contiguous, err); return -1; } @@ -1725,7 +1716,6 @@ JackAlsaDriver::alsa_driver_write (alsa_driver_t* driver, jack_nframes_t nframes offset, contiguous)) < 0) { jack_error ("ALSA: could not complete playback of %" PRIu32 " frames: error = %d", contiguous, err); - jack_error ("ALSA: could not complete playback of %d frames: error = %d", contiguous, err); if (err != EPIPE && err != ESTRPIPE) return -1; } @@ -1750,11 +1740,6 @@ JackAlsaDriver::alsa_driver_delete (alsa_driver_t *driver) } jack_slist_free (driver->clock_sync_listeners); - if (driver->ctl_handle) { - snd_ctl_close (driver->ctl_handle); - driver->ctl_handle = 0; - } - if (driver->ctl_handle) { snd_ctl_close (driver->ctl_handle); driver->ctl_handle = 0; @@ -2328,6 +2313,8 @@ int JackAlsaDriver::Read() jack_nframes_t nframes; fDelayedUsecs = 0.f; +retry: + nframes = alsa_driver_wait((alsa_driver_t *)fDriver, -1, &wait_status, &fDelayedUsecs); if (wait_status < 0) @@ -2339,11 +2326,11 @@ int JackAlsaDriver::Read() */ jack_log("ALSA XRun wait_status = %d", wait_status); NotifyXRun(fBeginDateUst, fDelayedUsecs); - return -1; + goto retry; /* recoverable error*/ } if (nframes != fEngineControl->fBufferSize) - jack_log("JackAlsaDriver::Read error nframes = %ld", nframes); + jack_log("JackAlsaDriver::Read warning nframes = %ld", nframes); // Has to be done before read JackDriver::CycleIncTime(); @@ -2631,352 +2618,352 @@ get_dither_constraint() return constraint_ptr; } - static int - dither_opt (char c, DitherAlgorithm* dither) - { - switch (c) { - case '-': - case 'n': - *dither = None; - break; - - case 'r': - *dither = Rectangular; - break; - - case 's': - *dither = Shaped; - break; - - case 't': - *dither = Triangular; - break; - - default: - fprintf (stderr, "ALSA driver: illegal dithering mode %c\n", c); - return -1; - } - return 0; +static int +dither_opt (char c, DitherAlgorithm* dither) +{ + switch (c) { + case '-': + case 'n': + *dither = None; + break; + + case 'r': + *dither = Rectangular; + break; + + case 's': + *dither = Shaped; + break; + + case 't': + *dither = Triangular; + break; + + default: + fprintf (stderr, "ALSA driver: illegal dithering mode %c\n", c); + return -1; } + return 0; +} - SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor () - { - jack_driver_desc_t * desc; - jack_driver_param_desc_t * params; - unsigned int i; - - desc = (jack_driver_desc_t*)calloc (1, sizeof (jack_driver_desc_t)); - - strcpy(desc->name, "alsa"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 - strcpy(desc->desc, "Linux ALSA API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - - desc->nparams = 18; - params = (jack_driver_param_desc_t*)calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); - - i = 0; - strcpy (params[i].name, "capture"); - params[i].character = 'C'; - params[i].type = JackDriverParamString; - strcpy (params[i].value.str, "none"); - strcpy (params[i].short_desc, - "Provide capture ports. Optionally set device"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "playback"); - params[i].character = 'P'; - params[i].type = JackDriverParamString; - strcpy (params[i].value.str, "none"); - strcpy (params[i].short_desc, - "Provide playback ports. Optionally set device"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "device"); - params[i].character = 'd'; - params[i].type = JackDriverParamString; - strcpy (params[i].value.str, "hw:0"); - strcpy (params[i].short_desc, "ALSA device name"); - strcpy (params[i].long_desc, params[i].short_desc); - params[i].constraint = enum_alsa_devices(); - - i++; - strcpy (params[i].name, "rate"); - params[i].character = 'r'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 48000U; - strcpy (params[i].short_desc, "Sample rate"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "period"); - params[i].character = 'p'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 1024U; - strcpy (params[i].short_desc, "Frames per period"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "nperiods"); - params[i].character = 'n'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 2U; - strcpy (params[i].short_desc, "Number of periods of playback latency"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "hwmon"); - params[i].character = 'H'; - params[i].type = JackDriverParamBool; - params[i].value.i = 0; - strcpy (params[i].short_desc, "Hardware monitoring, if available"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "hwmeter"); - params[i].character = 'M'; - params[i].type = JackDriverParamBool; - params[i].value.i = 0; - strcpy (params[i].short_desc, "Hardware metering, if available"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "duplex"); - params[i].character = 'D'; - params[i].type = JackDriverParamBool; - params[i].value.i = 1; - strcpy (params[i].short_desc, - "Provide both capture and playback ports"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "softmode"); - params[i].character = 's'; - params[i].type = JackDriverParamBool; - params[i].value.i = 0; - strcpy (params[i].short_desc, "Soft-mode, no xrun handling"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "monitor"); - params[i].character = 'm'; - params[i].type = JackDriverParamBool; - params[i].value.i = 0; - strcpy (params[i].short_desc, "Provide monitor ports for the output"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "dither"); - params[i].character = 'z'; - params[i].type = JackDriverParamChar; - params[i].value.c = 'n'; - strcpy (params[i].short_desc, "Dithering mode"); - strcpy (params[i].long_desc, - "Dithering mode:\n" - " n - none\n" - " r - rectangular\n" - " s - shaped\n" - " t - triangular"); - params[i].constraint = get_dither_constraint(); - - i++; - strcpy (params[i].name, "inchannels"); - params[i].character = 'i'; - params[i].type = JackDriverParamUInt; - params[i].value.i = 0; - strcpy (params[i].short_desc, - "Number of capture channels (defaults to hardware max)"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "outchannels"); - params[i].character = 'o'; - params[i].type = JackDriverParamUInt; - params[i].value.i = 0; - strcpy (params[i].short_desc, - "Number of playback channels (defaults to hardware max)"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "shorts"); - params[i].character = 'S'; - params[i].type = JackDriverParamBool; - params[i].value.i = FALSE; - strcpy (params[i].short_desc, "Try 16-bit samples before 32-bit"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "input-latency"); - params[i].character = 'I'; - params[i].type = JackDriverParamUInt; - params[i].value.i = 0; - strcpy (params[i].short_desc, "Extra input latency (frames)"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "output-latency"); - params[i].character = 'O'; - params[i].type = JackDriverParamUInt; - params[i].value.i = 0; - strcpy (params[i].short_desc, "Extra output latency (frames)"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "midi-driver"); - params[i].character = 'X'; - params[i].type = JackDriverParamString; - strcpy (params[i].value.str, "none"); - strcpy (params[i].short_desc, "ALSA MIDI driver name (seq|raw)"); - strcpy (params[i].long_desc, - "ALSA MIDI driver:\n" - " none - no MIDI driver\n" - " seq - ALSA Sequencer driver\n" - " raw - ALSA RawMIDI driver\n"); - params[i].constraint = get_midi_driver_constraint(); - - desc->params = params; - return desc; - } - - SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) - { - jack_nframes_t srate = 48000; - jack_nframes_t frames_per_interrupt = 1024; - unsigned long user_nperiods = 2; - const char *playback_pcm_name = "hw:0"; - const char *capture_pcm_name = "hw:0"; - int hw_monitoring = FALSE; - int hw_metering = FALSE; - int capture = FALSE; - int playback = FALSE; - int soft_mode = FALSE; - int monitor = FALSE; - DitherAlgorithm dither = None; - int user_capture_nchnls = 0; - int user_playback_nchnls = 0; - int shorts_first = FALSE; - jack_nframes_t systemic_input_latency = 0; - jack_nframes_t systemic_output_latency = 0; - const JSList * node; - const jack_driver_param_t * param; - const char *midi_driver = "none"; - - for (node = params; node; node = jack_slist_next (node)) { - param = (const jack_driver_param_t *) node->data; - - switch (param->character) { - - case 'C': - capture = TRUE; - if (strcmp (param->value.str, "none") != 0) { - capture_pcm_name = strdup (param->value.str); - jack_log("capture device %s", capture_pcm_name); - } - break; +SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor () +{ + jack_driver_desc_t * desc; + jack_driver_param_desc_t * params; + unsigned int i; - case 'P': - playback = TRUE; - if (strcmp (param->value.str, "none") != 0) { - playback_pcm_name = strdup (param->value.str); - jack_log("playback device %s", playback_pcm_name); - } - break; + desc = (jack_driver_desc_t*)calloc (1, sizeof (jack_driver_desc_t)); + + strcpy(desc->name, "alsa"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 + strcpy(desc->desc, "Linux ALSA API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 + + desc->nparams = 18; + params = (jack_driver_param_desc_t*)calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); + + i = 0; + strcpy (params[i].name, "capture"); + params[i].character = 'C'; + params[i].type = JackDriverParamString; + strcpy (params[i].value.str, "none"); + strcpy (params[i].short_desc, + "Provide capture ports. Optionally set device"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "playback"); + params[i].character = 'P'; + params[i].type = JackDriverParamString; + strcpy (params[i].value.str, "none"); + strcpy (params[i].short_desc, + "Provide playback ports. Optionally set device"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "device"); + params[i].character = 'd'; + params[i].type = JackDriverParamString; + strcpy (params[i].value.str, "hw:0"); + strcpy (params[i].short_desc, "ALSA device name"); + strcpy (params[i].long_desc, params[i].short_desc); + params[i].constraint = enum_alsa_devices(); + + i++; + strcpy (params[i].name, "rate"); + params[i].character = 'r'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 48000U; + strcpy (params[i].short_desc, "Sample rate"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "period"); + params[i].character = 'p'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1024U; + strcpy (params[i].short_desc, "Frames per period"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "nperiods"); + params[i].character = 'n'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 2U; + strcpy (params[i].short_desc, "Number of periods of playback latency"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "hwmon"); + params[i].character = 'H'; + params[i].type = JackDriverParamBool; + params[i].value.i = 0; + strcpy (params[i].short_desc, "Hardware monitoring, if available"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "hwmeter"); + params[i].character = 'M'; + params[i].type = JackDriverParamBool; + params[i].value.i = 0; + strcpy (params[i].short_desc, "Hardware metering, if available"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "duplex"); + params[i].character = 'D'; + params[i].type = JackDriverParamBool; + params[i].value.i = 1; + strcpy (params[i].short_desc, + "Provide both capture and playback ports"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "softmode"); + params[i].character = 's'; + params[i].type = JackDriverParamBool; + params[i].value.i = 0; + strcpy (params[i].short_desc, "Soft-mode, no xrun handling"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "monitor"); + params[i].character = 'm'; + params[i].type = JackDriverParamBool; + params[i].value.i = 0; + strcpy (params[i].short_desc, "Provide monitor ports for the output"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "dither"); + params[i].character = 'z'; + params[i].type = JackDriverParamChar; + params[i].value.c = 'n'; + strcpy (params[i].short_desc, "Dithering mode"); + strcpy (params[i].long_desc, + "Dithering mode:\n" + " n - none\n" + " r - rectangular\n" + " s - shaped\n" + " t - triangular"); + params[i].constraint = get_dither_constraint(); + + i++; + strcpy (params[i].name, "inchannels"); + params[i].character = 'i'; + params[i].type = JackDriverParamUInt; + params[i].value.i = 0; + strcpy (params[i].short_desc, + "Number of capture channels (defaults to hardware max)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "outchannels"); + params[i].character = 'o'; + params[i].type = JackDriverParamUInt; + params[i].value.i = 0; + strcpy (params[i].short_desc, + "Number of playback channels (defaults to hardware max)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "shorts"); + params[i].character = 'S'; + params[i].type = JackDriverParamBool; + params[i].value.i = FALSE; + strcpy (params[i].short_desc, "Try 16-bit samples before 32-bit"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "input-latency"); + params[i].character = 'I'; + params[i].type = JackDriverParamUInt; + params[i].value.i = 0; + strcpy (params[i].short_desc, "Extra input latency (frames)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "output-latency"); + params[i].character = 'O'; + params[i].type = JackDriverParamUInt; + params[i].value.i = 0; + strcpy (params[i].short_desc, "Extra output latency (frames)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "midi-driver"); + params[i].character = 'X'; + params[i].type = JackDriverParamString; + strcpy (params[i].value.str, "none"); + strcpy (params[i].short_desc, "ALSA MIDI driver name (seq|raw)"); + strcpy (params[i].long_desc, + "ALSA MIDI driver:\n" + " none - no MIDI driver\n" + " seq - ALSA Sequencer driver\n" + " raw - ALSA RawMIDI driver\n"); + params[i].constraint = get_midi_driver_constraint(); + + desc->params = params; + return desc; +} - case 'D': - playback = TRUE; - capture = TRUE; - break; +SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) +{ + jack_nframes_t srate = 48000; + jack_nframes_t frames_per_interrupt = 1024; + unsigned long user_nperiods = 2; + const char *playback_pcm_name = "hw:0"; + const char *capture_pcm_name = "hw:0"; + int hw_monitoring = FALSE; + int hw_metering = FALSE; + int capture = FALSE; + int playback = FALSE; + int soft_mode = FALSE; + int monitor = FALSE; + DitherAlgorithm dither = None; + int user_capture_nchnls = 0; + int user_playback_nchnls = 0; + int shorts_first = FALSE; + jack_nframes_t systemic_input_latency = 0; + jack_nframes_t systemic_output_latency = 0; + const JSList * node; + const jack_driver_param_t * param; + const char *midi_driver = "none"; + + for (node = params; node; node = jack_slist_next (node)) { + param = (const jack_driver_param_t *) node->data; + + switch (param->character) { + + case 'C': + capture = TRUE; + if (strcmp (param->value.str, "none") != 0) { + capture_pcm_name = strdup (param->value.str); + jack_log("capture device %s", capture_pcm_name); + } + break; - case 'd': + case 'P': + playback = TRUE; + if (strcmp (param->value.str, "none") != 0) { playback_pcm_name = strdup (param->value.str); - capture_pcm_name = strdup (param->value.str); jack_log("playback device %s", playback_pcm_name); - jack_log("capture device %s", capture_pcm_name); - break; + } + break; - case 'H': - hw_monitoring = param->value.i; - break; + case 'D': + playback = TRUE; + capture = TRUE; + break; - case 'm': - monitor = param->value.i; - break; + case 'd': + playback_pcm_name = strdup (param->value.str); + capture_pcm_name = strdup (param->value.str); + jack_log("playback device %s", playback_pcm_name); + jack_log("capture device %s", capture_pcm_name); + break; - case 'M': - hw_metering = param->value.i; - break; + case 'H': + hw_monitoring = param->value.i; + break; - case 'r': - srate = param->value.ui; - jack_log("apparent rate = %d", srate); - break; + case 'm': + monitor = param->value.i; + break; - case 'p': - frames_per_interrupt = param->value.ui; - jack_log("frames per period = %d", frames_per_interrupt); - break; + case 'M': + hw_metering = param->value.i; + break; - case 'n': - user_nperiods = param->value.ui; - if (user_nperiods < 2) /* enforce minimum value */ - user_nperiods = 2; - break; + case 'r': + srate = param->value.ui; + jack_log("apparent rate = %d", srate); + break; - case 's': - soft_mode = param->value.i; - break; + case 'p': + frames_per_interrupt = param->value.ui; + jack_log("frames per period = %d", frames_per_interrupt); + break; - case 'z': - if (dither_opt (param->value.c, &dither)) { - return NULL; - } - break; + case 'n': + user_nperiods = param->value.ui; + if (user_nperiods < 2) /* enforce minimum value */ + user_nperiods = 2; + break; - case 'i': - user_capture_nchnls = param->value.ui; - break; + case 's': + soft_mode = param->value.i; + break; - case 'o': - user_playback_nchnls = param->value.ui; - break; + case 'z': + if (dither_opt (param->value.c, &dither)) { + return NULL; + } + break; - case 'S': - shorts_first = param->value.i; - break; + case 'i': + user_capture_nchnls = param->value.ui; + break; - case 'I': - systemic_input_latency = param->value.ui; - break; + case 'o': + user_playback_nchnls = param->value.ui; + break; - case 'O': - systemic_output_latency = param->value.ui; - break; + case 'S': + shorts_first = param->value.i; + break; - case 'X': - midi_driver = strdup(param->value.str); - break; - } - } + case 'I': + systemic_input_latency = param->value.ui; + break; - /* duplex is the default */ - if (!capture && !playback) { - capture = TRUE; - playback = TRUE; - } + case 'O': + systemic_output_latency = param->value.ui; + break; - Jack::JackAlsaDriver* alsa_driver = new Jack::JackAlsaDriver("system", "alsa_pcm", engine, table); - Jack::JackDriverClientInterface* threaded_driver = new Jack::JackThreadedDriver(alsa_driver); - // Special open for ALSA driver... - if (alsa_driver->Open(frames_per_interrupt, user_nperiods, srate, hw_monitoring, hw_metering, capture, playback, dither, soft_mode, monitor, - user_capture_nchnls, user_playback_nchnls, shorts_first, capture_pcm_name, playback_pcm_name, - systemic_input_latency, systemic_output_latency, midi_driver) == 0) { - return threaded_driver; - } else { - delete threaded_driver; // Delete the decorated driver - return NULL; + case 'X': + midi_driver = strdup(param->value.str); + break; } } + /* duplex is the default */ + if (!capture && !playback) { + capture = TRUE; + playback = TRUE; + } + + Jack::JackAlsaDriver* alsa_driver = new Jack::JackAlsaDriver("system", "alsa_pcm", engine, table); + Jack::JackDriverClientInterface* threaded_driver = new Jack::JackThreadedDriver(alsa_driver); + // Special open for ALSA driver... + if (alsa_driver->Open(frames_per_interrupt, user_nperiods, srate, hw_monitoring, hw_metering, capture, playback, dither, soft_mode, monitor, + user_capture_nchnls, user_playback_nchnls, shorts_first, capture_pcm_name, playback_pcm_name, + systemic_input_latency, systemic_output_latency, midi_driver) == 0) { + return threaded_driver; + } else { + delete threaded_driver; // Delete the decorated driver + return NULL; + } +} + #ifdef __cplusplus } #endif diff --git a/linux/firewire/JackFFADODriver.cpp b/linux/firewire/JackFFADODriver.cpp index 9cb554e4..5400df76 100644 --- a/linux/firewire/JackFFADODriver.cpp +++ b/linux/firewire/JackFFADODriver.cpp @@ -664,6 +664,8 @@ int JackFFADODriver::Read() int wait_status = 0; fDelayedUsecs = 0.f; +retry: + jack_nframes_t nframes = ffado_driver_wait(driver, -1, &wait_status, &fDelayedUsecs); @@ -678,11 +680,11 @@ int JackFFADODriver::Read() */ jack_log("FFADO XRun"); NotifyXRun(fBeginDateUst, fDelayedUsecs); - return -1; + goto retry; /* recoverable error*/ } if (nframes != fEngineControl->fBufferSize) - jack_log("JackFFADODriver::Read nframes = %ld", nframes); + jack_log("JackFFADODriver::Read warning nframes = %ld", nframes); // Has to be done before read JackDriver::CycleIncTime(); diff --git a/linux/freebob/JackFreebobDriver.cpp b/linux/freebob/JackFreebobDriver.cpp index 348e4635..47860f21 100644 --- a/linux/freebob/JackFreebobDriver.cpp +++ b/linux/freebob/JackFreebobDriver.cpp @@ -854,6 +854,8 @@ int JackFreebobDriver::Read() int wait_status = 0; fDelayedUsecs = 0.f; +retry: + jack_nframes_t nframes = freebob_driver_wait (driver, -1, &wait_status, &fDelayedUsecs); @@ -868,11 +870,11 @@ int JackFreebobDriver::Read() */ jack_log("FreeBoB XRun"); NotifyXRun(fBeginDateUst, fDelayedUsecs); - return -1; + goto retry; /* recoverable error*/ } if (nframes != fEngineControl->fBufferSize) - jack_log("JackFreebobDriver::Read nframes = %ld", nframes); + jack_log("JackFreebobDriver::Read warning nframes = %ld", nframes); // Has to be done before read JackDriver::CycleIncTime(); diff --git a/macosx/Jack-Info.plist b/macosx/Jack-Info.plist index ce9bac00..ef3f8b07 100644 --- a/macosx/Jack-Info.plist +++ b/macosx/Jack-Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable Jackservermp CFBundleGetInfoString - Jackdmp 1.9.6, @03-10 Paul Davis, Grame + Jackdmp 1.9.7, @03-10 Paul Davis, Grame CFBundleIdentifier com.grame.Jackmp CFBundleInfoDictionaryVersion @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.9.6 + 1.9.7 diff --git a/macosx/JackCompilerDeps_os.h b/macosx/JackCompilerDeps_os.h new file mode 100644 index 00000000..d4ba208c --- /dev/null +++ b/macosx/JackCompilerDeps_os.h @@ -0,0 +1,55 @@ +/* +Copyright (C) 2004-2005 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 __JackCompilerDeps_APPLE__ +#define __JackCompilerDeps_APPLE__ + +#include "JackConstants.h" + +#if __GNUC__ + #ifndef POST_PACKED_STRUCTURE + /* POST_PACKED_STRUCTURE needs to be a macro which + expands into a compiler directive. The directive must + tell the compiler to arrange the preceding structure + declaration so that it is packed on byte-boundaries rather + than use the natural alignment of the processor and/or + compiler. + */ + #if defined(JACK_32_64) + #define POST_PACKED_STRUCTURE __attribute__((__packed__)) + #else + #define POST_PACKED_STRUCTURE + #endif + #endif + #define MEM_ALIGN(x,y) x __attribute__((aligned(y))) + #define EXPORT __attribute__((visibility("default"))) + #ifdef SERVER_SIDE + #define SERVER_EXPORT __attribute__((visibility("default"))) + #else + #define SERVER_EXPORT + #endif +#else + #define MEM_ALIGN(x,y) x + #define EXPORT + #define SERVER_EXPORT + /* Add other things here for non-gcc platforms for POST_PACKED_STRUCTURE */ +#endif + +#endif + diff --git a/macosx/JackMacEngineRPC.cpp b/macosx/JackMacEngineRPC.cpp deleted file mode 100644 index fb95621d..00000000 --- a/macosx/JackMacEngineRPC.cpp +++ /dev/null @@ -1,250 +0,0 @@ -/* -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. - -*/ - -#include "JackServer.h" -#include "JackNotification.h" -#include "JackLockedEngine.h" -#include "JackRPCEngine.h" -#include "JackMachServerChannel.h" -#include "JackException.h" -#include - -using namespace Jack; - -//------------------- -// Client management -//------------------- - -#define rpc_type kern_return_t // for astyle - -rpc_type server_rpc_jack_client_check(mach_port_t private_port, client_name_t name, client_name_t name_res, int protocol, int options, int* status, int* result) -{ - jack_log("rpc_jack_client_check"); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; - assert(channel); - channel->ClientCheck((char*)name, (char*)name_res, protocol, options, status, result); - return KERN_SUCCESS; -} - -rpc_type server_rpc_jack_client_open(mach_port_t server_port, client_name_t name, int pid, mach_port_t* private_port, int* shared_engine, int* shared_client, int* shared_graph, int* result) -{ - jack_log("rpc_jack_client_open name = %s", name); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[server_port]; - assert(channel); - channel->ClientOpen((char*)name, pid, private_port, shared_engine, shared_client, shared_graph, result); - return KERN_SUCCESS; -} - -rpc_type server_rpc_jack_client_close(mach_port_t private_port, int refnum, int* result) -{ - jack_log("rpc_jack_client_close"); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; - assert(channel); - channel->ClientClose(private_port, refnum); - *result = 0; - return KERN_SUCCESS; -} - -rpc_type server_rpc_jack_client_activate(mach_port_t private_port, int refnum, int is_real_time, int* result) -{ - jack_log("rpc_jack_client_activate"); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; - assert(channel); - *result = channel->GetEngine()->ClientActivate(refnum, is_real_time); - return KERN_SUCCESS; -} - -rpc_type server_rpc_jack_client_deactivate(mach_port_t private_port, int refnum, int* result) -{ - jack_log("rpc_jack_client_deactivate"); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; - assert(channel); - *result = channel->GetEngine()->ClientDeactivate(refnum); - return KERN_SUCCESS; -} - -//----------------- -// Port management -//----------------- - -rpc_type server_rpc_jack_port_register(mach_port_t private_port, int refnum, client_port_name_t name, client_port_type_t type, unsigned int flags, unsigned int buffer_size, unsigned int* port_index, int* result) -{ - jack_log("rpc_jack_port_register ref = %d name = %s", refnum, name); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; - assert(channel); - *result = channel->GetEngine()->PortRegister(refnum, name, type, flags, buffer_size, port_index); - return KERN_SUCCESS; -} - -rpc_type server_rpc_jack_port_unregister(mach_port_t private_port, int refnum, int port, int* result) -{ - jack_log("rpc_jack_port_unregister ref = %d port = %d ", refnum, port); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; - assert(channel); - *result = channel->GetEngine()->PortUnRegister(refnum, port); - return KERN_SUCCESS; -} - -rpc_type server_rpc_jack_port_connect_name(mach_port_t private_port, int refnum, client_port_name_t src, client_port_name_t dst, int* result) -{ - jack_log("rpc_jack_port_connect_name"); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; - assert(channel); - *result = channel->GetEngine()->PortConnect(refnum, src, dst); - return KERN_SUCCESS; -} - -rpc_type server_rpc_jack_port_disconnect_name(mach_port_t private_port, int refnum, client_port_name_t src, client_port_name_t dst, int* result) -{ - jack_log("rpc_jack_port_disconnect_name"); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; - assert(channel); - *result = channel->GetEngine()->PortDisconnect(refnum, src, dst); - return KERN_SUCCESS; -} - -rpc_type server_rpc_jack_port_connect(mach_port_t private_port, int refnum, int src, int dst, int* result) -{ - jack_log("rpc_jack_port_connect"); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; - assert(channel); - *result = channel->GetEngine()->PortConnect(refnum, src, dst); - return KERN_SUCCESS; -} - -rpc_type server_rpc_jack_port_disconnect(mach_port_t private_port, int refnum, int src, int dst, int* result) -{ - jack_log("rpc_jack_port_disconnect"); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; - assert(channel); - *result = channel->GetEngine()->PortDisconnect(refnum, src, dst); - return KERN_SUCCESS; -} - -rpc_type server_rpc_jack_port_rename(mach_port_t private_port, int refnum, int port, client_port_name_t name, int* result) -{ - jack_log("server_rpc_jack_port_rename"); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; - assert(channel); - *result = channel->GetEngine()->PortRename(refnum, port, name); - return KERN_SUCCESS; -} - -//------------------------ -// Buffer size, freewheel -//------------------------ - -rpc_type server_rpc_jack_set_buffer_size(mach_port_t private_port, int buffer_size, int* result) -{ - jack_log("server_rpc_jack_set_buffer_size"); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; - assert(channel); - *result = channel->GetServer()->SetBufferSize(buffer_size); - return KERN_SUCCESS; -} - -rpc_type server_rpc_jack_set_freewheel(mach_port_t private_port, int onoff, int* result) -{ - jack_log("server_rpc_jack_set_freewheel"); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; - assert(channel); - *result = channel->GetServer()->SetFreewheel(onoff); - return KERN_SUCCESS; -} - -//---------------------- -// Transport management -//---------------------- - -rpc_type server_rpc_jack_release_timebase(mach_port_t private_port, int refnum, int* result) -{ - jack_log("server_rpc_jack_release_timebase"); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; - assert(channel); - *result = channel->GetServer()->ReleaseTimebase(refnum); - return KERN_SUCCESS; -} - -rpc_type server_rpc_jack_set_timebase_callback(mach_port_t private_port, int refnum, int conditional, int* result) -{ - jack_log("server_rpc_jack_set_timebase_callback"); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; - assert(channel); - *result = channel->GetServer()->SetTimebaseCallback(refnum, conditional); - return KERN_SUCCESS; -} - -//------------------ -// Internal clients -//------------------ - -rpc_type server_rpc_jack_get_internal_clientname(mach_port_t private_port, int refnum, int int_ref, client_name_t name_res, int* result) -{ - jack_log("server_rpc_jack_get_internal_clientname"); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; - assert(channel); - *result = channel->GetServer()->GetEngine()->GetInternalClientName(int_ref, (char*)name_res); - return KERN_SUCCESS; -} - -rpc_type server_rpc_jack_internal_clienthandle(mach_port_t private_port, int refnum, client_name_t client_name, int* status, int* int_ref, int* result) -{ - jack_log("server_rpc_jack_internal_clienthandle"); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; - assert(channel); - *result = channel->GetServer()->GetEngine()->InternalClientHandle(client_name, status, int_ref); - return KERN_SUCCESS; -} - -rpc_type server_rpc_jack_internal_clientload(mach_port_t private_port, int refnum, client_name_t client_name, so_name_t so_name, objet_data_t objet_data, int options, int* status, int* int_ref, int* result) -{ - jack_log("server_rpc_jack_internal_clientload"); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; - assert(channel); - *result = channel->GetServer()->InternalClientLoad(client_name, so_name, objet_data, options, int_ref, status); - return KERN_SUCCESS; -} - -rpc_type server_rpc_jack_internal_clientunload(mach_port_t private_port, int refnum, int int_ref, int* status, int* result) -{ - jack_log("server_rpc_jack_internal_clientunload"); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; - assert(channel); - *result = channel->GetServer()->GetEngine()->InternalClientUnload(int_ref, status); - return KERN_SUCCESS; -} - -//----------------- -// RT notification -//----------------- - -rpc_type server_rpc_jack_client_rt_notify(mach_port_t server_port, int refnum, int notify, int value) -{ - jack_log("rpc_jack_client_rt_notify ref = %d notify = %d value = %d", refnum, notify, value); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[server_port]; - assert(channel); - assert(channel->GetServer()); - - if (notify == kQUIT) { - throw JackQuitException(); - } else { - channel->GetServer()->Notify(refnum, notify, value); - return KERN_SUCCESS; - } -} diff --git a/macosx/JackMacLibClientRPC.cpp b/macosx/JackMacLibClientRPC.cpp deleted file mode 100644 index b70878a1..00000000 --- a/macosx/JackMacLibClientRPC.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* -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. - -*/ - -#include "JackLibClient.h" -#include "JackMachClientChannel.h" -#include "JackRPCEngine.h" -#include "JackLibGlobals.h" -#include - -using namespace Jack; - -#define rpc_type kern_return_t // for astyle - -rpc_type rpc_jack_client_sync_notify(mach_port_t client_port, int refnum, client_name_t name, int notify, message_t message, int value1, int value2, int* result) -{ - jack_log("rpc_jack_client_sync_notify ref = %ld name = %s notify = %ld message %s val1 = %ld val2 = %ld", refnum, name, notify, message, value1, value2); - JackClient* client = gClientTable[client_port]; - assert(client); - *result = client->ClientNotify(refnum, name, notify, true, message, value1, value2); - return KERN_SUCCESS; -} - -rpc_type rpc_jack_client_async_notify(mach_port_t client_port, int refnum, client_name_t name, int notify, message_t message, int value1, int value2) -{ - jack_log("rpc_jack_client_async_notify ref = %ld name = %s notify = %ld message %s val1 = %ld val2 = %ld", refnum, name, notify, message, value1, value2); - JackClient* client = gClientTable[client_port]; - assert(client); - client->ClientNotify(refnum, name, notify, false, message, value1, value2); - return KERN_SUCCESS; -} - diff --git a/macosx/JackMachClientChannel.cpp b/macosx/JackMachClientChannel.cpp deleted file mode 100644 index f5f88504..00000000 --- a/macosx/JackMachClientChannel.cpp +++ /dev/null @@ -1,334 +0,0 @@ -/* -Copyright (C) 2004-2008 Grame - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 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 -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "JackMachClientChannel.h" -#include "JackRPCEngine.h" -#include "JackTools.h" -#include "JackRPCClientServer.c" -#include "JackError.h" -#include "JackLibClient.h" -#include "JackMachThread.h" -#include "JackConstants.h" - -namespace Jack -{ - -std::map gClientTable; - -JackMachClientChannel::JackMachClientChannel():fPrivatePort(0),fThread(this) -{} - -JackMachClientChannel::~JackMachClientChannel() -{} - -// Server <===> client - -int JackMachClientChannel::ServerCheck(const char* server_name) -{ - jack_log("JackMachClientChannel::ServerCheck = %s", server_name); - char jack_server_entry_name[512]; - snprintf(jack_server_entry_name, sizeof(jack_server_entry_name), "%s.%d_%s", jack_server_entry, JackTools::GetUID(), server_name); - - // Connect to server - if (!fServerPort.ConnectPort(jack_server_entry_name)) { - jack_error("Cannot connect to server Mach port"); - return -1; - } else { - return 0; - } -} - -int JackMachClientChannel::Open(const char* server_name, const char* name, char* name_res, JackClient* client, jack_options_t options, jack_status_t* status) -{ - jack_log("JackMachClientChannel::Open name = %s", name); - char jack_server_entry_name[512]; - snprintf(jack_server_entry_name, sizeof(jack_server_entry_name), "%s.%d_%s", jack_server_entry, JackTools::GetUID(), server_name); - - // Connect to server - if (!fServerPort.ConnectPort(jack_server_entry_name)) { - jack_error("Cannot connect to server Mach port"); - return -1; - } - - // Check name in server - int result = 0; - ClientCheck(name, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result); - if (result < 0) { - int status1 = *status; - if (status1 & JackVersionError) - jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION); - else - jack_error("Client name = %s conflits with another running client", name); - return -1; - } - - // Prepare local port using client name - char buf[JACK_CLIENT_NAME_SIZE + 1]; - snprintf(buf, sizeof(buf) - 1, "%s:%s", jack_client_entry, name_res); - - if (!fClientPort.AllocatePort(buf, 16)) { - jack_error("Cannot allocate client Mach port"); - return -1; - } - - gClientTable[fClientPort.GetPort()] = client; - return 0; -} - -void JackMachClientChannel::Close() -{ - jack_log("JackMachClientChannel::Close"); - gClientTable.erase(fClientPort.GetPort()); - fServerPort.DisconnectPort(); - fClientPort.DestroyPort(); - - if (fPrivatePort != 0) { - kern_return_t res; - if ((res = mach_port_destroy(mach_task_self(), fPrivatePort)) != KERN_SUCCESS) { - jack_error("JackMachClientChannel::Close err = %s", mach_error_string(res)); - } - } -} - -int JackMachClientChannel::Start() -{ - jack_log("JackMachClientChannel::Start"); - /* - To be sure notification thread is started before ClientOpen is called. - */ - if (fThread.StartSync() != 0) { - jack_error("Cannot start Jack client listener"); - return -1; - } else { - return 0; - } -} - -void JackMachClientChannel::Stop() -{ - jack_log("JackMachClientChannel::Stop"); - fThread.Kill(); -} - -void JackMachClientChannel::ClientCheck(const char* name, char* name_res, int protocol, int options, int* status, int* result) -{ - kern_return_t res = rpc_jack_client_check(fServerPort.GetPort(), (char*)name, name_res, protocol, options, status, result); - if (res != KERN_SUCCESS) { - *result = -1; - jack_error("JackMachClientChannel::ClientCheck err = %s", mach_error_string(res)); - } -} - -void JackMachClientChannel::ClientOpen(const char* name, int pid, int* shared_engine, int* shared_client, int* shared_graph, int* result) -{ - kern_return_t res = rpc_jack_client_open(fServerPort.GetPort(), (char*)name, pid, &fPrivatePort, shared_engine, shared_client, shared_graph, result); - if (res != KERN_SUCCESS) { - *result = -1; - jack_error("JackMachClientChannel::ClientOpen err = %s", mach_error_string(res)); - } -} - -void JackMachClientChannel::ClientClose(int refnum, int* result) -{ - kern_return_t res = rpc_jack_client_close(fPrivatePort, refnum, result); - if (res != KERN_SUCCESS) { - *result = -1; - jack_error("JackMachClientChannel::ClientClose err = %s", mach_error_string(res)); - } -} - -void JackMachClientChannel::ClientActivate(int refnum, int is_real_time, int* result) -{ - kern_return_t res = rpc_jack_client_activate(fPrivatePort, refnum, is_real_time, result); - if (res != KERN_SUCCESS) { - *result = -1; - jack_error("JackMachClientChannel::ClientActivate err = %s", mach_error_string(res)); - } -} - -void JackMachClientChannel::ClientDeactivate(int refnum, int* result) -{ - kern_return_t res = rpc_jack_client_deactivate(fPrivatePort, refnum, result); - if (res != KERN_SUCCESS) { - *result = -1; - jack_error("JackMachClientChannel::ClientDeactivate err = %s", mach_error_string(res)); - } -} - -void JackMachClientChannel::PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) -{ - kern_return_t res = rpc_jack_port_register(fPrivatePort, refnum, (char*)name, (char*)type, flags, buffer_size, port_index, result); - if (res != KERN_SUCCESS) { - *result = -1; - jack_error("JackMachClientChannel::PortRegister err = %s", mach_error_string(res)); - } -} - -void JackMachClientChannel::PortUnRegister(int refnum, jack_port_id_t port_index, int* result) -{ - kern_return_t res = rpc_jack_port_unregister(fPrivatePort, refnum, port_index, result); - if (res != KERN_SUCCESS) { - *result = -1; - jack_error("JackMachClientChannel::PortUnRegister err = %s", mach_error_string(res)); - } -} - -void JackMachClientChannel::PortConnect(int refnum, const char* src, const char* dst, int* result) -{ - kern_return_t res = rpc_jack_port_connect_name(fPrivatePort, refnum, (char*)src, (char*)dst, result); - if (res != KERN_SUCCESS) { - jack_error("JackMachClientChannel::PortConnect err = %s", mach_error_string(res)); - } -} - -void JackMachClientChannel::PortDisconnect(int refnum, const char* src, const char* dst, int* result) -{ - kern_return_t res = rpc_jack_port_disconnect_name(fPrivatePort, refnum, (char*)src, (char*)dst, result); - if (res != KERN_SUCCESS) { - *result = -1; - jack_error("JackMachClientChannel::PortDisconnect err = %s", mach_error_string(res)); - } -} - -void JackMachClientChannel::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result) -{ - kern_return_t res = rpc_jack_port_connect(fPrivatePort, refnum, src, dst, result); - if (res != KERN_SUCCESS) { - *result = -1; - jack_error("JackMachClientChannel::PortConnect err = %s", mach_error_string(res)); - } -} - -void JackMachClientChannel::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result) -{ - kern_return_t res = rpc_jack_port_disconnect(fPrivatePort, refnum, src, dst, result); - if (res != KERN_SUCCESS) { - *result = -1; - jack_error("JackMachClientChannel::PortDisconnect err = %s", mach_error_string(res)); - } -} - -void JackMachClientChannel::PortRename(int refnum, jack_port_id_t port, const char* name, int* result) -{ - kern_return_t res = rpc_jack_port_rename(fPrivatePort, refnum, port, (char*)name, result); - if (res != KERN_SUCCESS) { - *result = -1; - jack_error("JackMachClientChannel::PortRename err = %s", mach_error_string(res)); - } -} - -void JackMachClientChannel::SetBufferSize(jack_nframes_t buffer_size, int* result) -{ - kern_return_t res = rpc_jack_set_buffer_size(fPrivatePort, buffer_size, result); - if (res != KERN_SUCCESS) { - *result = -1; - jack_error("JackMachClientChannel::SetBufferSize err = %s", mach_error_string(res)); - } -} - -void JackMachClientChannel::SetFreewheel(int onoff, int* result) -{ - kern_return_t res = rpc_jack_set_freewheel(fPrivatePort, onoff, result); - if (res != KERN_SUCCESS) { - *result = -1; - jack_error("JackMachClientChannel::SetFreewheel err = %s", mach_error_string(res)); - } -} - -void JackMachClientChannel::ReleaseTimebase(int refnum, int* result) -{ - kern_return_t res = rpc_jack_release_timebase(fPrivatePort, refnum, result); - if (res != KERN_SUCCESS) { - *result = -1; - jack_error("JackMachClientChannel::ReleaseTimebase err = %s", mach_error_string(res)); - } -} - -void JackMachClientChannel::SetTimebaseCallback(int refnum, int conditional, int* result) -{ - kern_return_t res = rpc_jack_set_timebase_callback(fPrivatePort, refnum, conditional, result); - if (res != KERN_SUCCESS) { - *result = -1; - jack_error("JackMachClientChannel::SetTimebaseCallback err = %s", mach_error_string(res)); - } -} - -void JackMachClientChannel::GetInternalClientName(int refnum, int int_ref, char* name_res, int* result) -{ - kern_return_t res = rpc_jack_get_internal_clientname(fPrivatePort, refnum, int_ref, name_res, result); - if (res != KERN_SUCCESS) { - *result = -1; - jack_error("JackMachClientChannel::GetInternalClientName err = %s", mach_error_string(res)); - } -} - -void JackMachClientChannel::InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result) -{ - kern_return_t res = rpc_jack_internal_clienthandle(fPrivatePort, refnum, (char*)client_name, status, int_ref, result); - if (res != KERN_SUCCESS) { - *result = -1; - jack_error("JackMachClientChannel::InternalClientHandle err = %s", mach_error_string(res)); - } -} - -void JackMachClientChannel::InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int* result) -{ - const char* int_client_name = (client_name) ? client_name : ""; - const char* int_so_name = (so_name) ? so_name : ""; - const char* int_objet_data = (objet_data) ? objet_data : ""; - - kern_return_t res = rpc_jack_internal_clientload(fPrivatePort, refnum, (char*)int_client_name, (char*)int_so_name, (char*)int_objet_data, options, status, int_ref, result); - if (res != KERN_SUCCESS) { - *result = -1; - jack_error("JackMachClientChannel::InternalClientLoad err = %s", mach_error_string(res)); - } -} - -void JackMachClientChannel::InternalClientUnload(int refnum, int int_ref, int* status, int* result) -{ - kern_return_t res = rpc_jack_internal_clientunload(fPrivatePort, refnum, int_ref, status, result); - if (res != KERN_SUCCESS) { - *result = -1; - jack_error("JackMachClientChannel::InternalClientUnload err = %s", mach_error_string(res)); - } -} - -bool JackMachClientChannel::Init() -{ - jack_log("JackMachClientChannel::Init"); - JackClient* client = gClientTable[fClientPort.GetPort()]; - return client->Init(); -} - -bool JackMachClientChannel::Execute() -{ - kern_return_t res; - if ((res = mach_msg_server(JackRPCClient_server, 1024, fClientPort.GetPort(), 0)) != KERN_SUCCESS) { - jack_error("JackMachClientChannel::Execute err = %s", mach_error_string(res)); - JackClient* client = gClientTable[fClientPort.GetPort()]; - client->ShutDown(); - return false; - } else { - return true; - } -} - -} // end of namespace - - diff --git a/macosx/JackMachClientChannel.h b/macosx/JackMachClientChannel.h deleted file mode 100644 index 379fb535..00000000 --- a/macosx/JackMachClientChannel.h +++ /dev/null @@ -1,99 +0,0 @@ -/* -Copyright (C) 2004-2008 Grame - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 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 -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#ifndef __JackMachClientChannel__ -#define __JackMachClientChannel__ - -#include "JackChannel.h" -#include "JackMachPort.h" -#include "JackPlatformPlug.h" -#include - -namespace Jack -{ - -/*! -\brief JackClientChannel using Mach IPC. -*/ - -class JackMachClientChannel : public detail::JackClientChannelInterface, public JackRunnableInterface -{ - - private: - - JackMachPort fClientPort; /*! Mach port to communicate with the server : from server to client */ - JackMachPort fServerPort; /*! Mach port to communicate with the server : from client to server */ - mach_port_t fPrivatePort; - JackThread fThread; /*! Thread to execute the event loop */ - - public: - - JackMachClientChannel(); - ~JackMachClientChannel(); - - int Open(const char* server_name, const char* name, char* name_res, JackClient* client, jack_options_t options, jack_status_t* status); - void Close(); - - int Start(); - void Stop(); - - int ServerCheck(const char* server_name); - - void ClientCheck(const char* name, char* name_res, int protocol, int options, int* status, int* result); - void ClientOpen(const char* name, int pid, int* shared_engine, int* shared_client, int* shared_graph, int* result); - void ClientOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, int* result) - {} - void ClientClose(int refnum, int* result); - - void ClientActivate(int refnum, int is_real_time, int* result); - void ClientDeactivate(int refnum, int* result); - - void PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result); - void PortUnRegister(int refnum, jack_port_id_t port_index, int* result); - - void PortConnect(int refnum, const char* src, const char* dst, int* result); - void PortDisconnect(int refnum, const char* src, const char* dst, int* result); - - void PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result); - void PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result); - - void PortRename(int refnum, jack_port_id_t port, const char* name, int* result); - - void SetBufferSize(jack_nframes_t buffer_size, int* result); - void SetFreewheel(int onoff, int* result); - - void ReleaseTimebase(int refnum, int* result); - void SetTimebaseCallback(int refnum, int conditional, int* result); - - void GetInternalClientName(int refnum, int int_ref, char* name_res, int* result); - void InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result); - void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int* result); - void InternalClientUnload(int refnum, int int_ref, int* status, int* result); - - // JackRunnableInterface interface - bool Init(); - bool Execute(); -}; - -extern std::map gClientTable; - -} // end of namespace - -#endif - diff --git a/macosx/JackMachNotifyChannel.cpp b/macosx/JackMachNotifyChannel.cpp deleted file mode 100644 index 56d6b425..00000000 --- a/macosx/JackMachNotifyChannel.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* -Copyright (C) 2004-2008 Grame - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 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 -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "JackMachNotifyChannel.h" -#include "JackRPCClient.h" -#include "JackError.h" -#include "JackConstants.h" -#include - -namespace Jack -{ - -// Server side : server to client - -int JackMachNotifyChannel::Open(const char* name) -{ - jack_log("JackMachNotifyChannel::Open name = %s", name); - - char buf[256]; - snprintf(buf, sizeof(buf) - 1, "%s:%s", jack_client_entry, name); - - // Connect to client notification port using client name - if (!fClientPort.ConnectPort(buf)) { - jack_error("Cannot connect client port"); - return -1; - } else { - return 0; - } -} - -void JackMachNotifyChannel::Close() -{ - fClientPort.DisconnectPort(); -} - -void JackMachNotifyChannel::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2, int* result) -{ - kern_return_t res = (sync) - ? rpc_jack_client_sync_notify(fClientPort.GetPort(), refnum, (char*)name, notify, (char*)message, value1, value2, result) - : rpc_jack_client_async_notify(fClientPort.GetPort(), refnum, (char*)name, notify, (char*)message, value1, value2); - if (res == KERN_SUCCESS) { - *result = 0; - } else { - jack_error("JackMachNotifyChannel::ClientNotify: name = %s notify = %ld err = %s", name, notify, mach_error_string(res)); - *result = -1; - } -} - -} // end of namespace - - diff --git a/macosx/JackMachNotifyChannel.h b/macosx/JackMachNotifyChannel.h deleted file mode 100644 index ab99fef4..00000000 --- a/macosx/JackMachNotifyChannel.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright (C) 2004-2008 Grame - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 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 -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#ifndef __JackMachNotifyChannel__ -#define __JackMachNotifyChannel__ - -#include "JackMachPort.h" - -namespace Jack -{ - -/*! -\brief JackNotifyChannel using Mach IPC. -*/ - -class JackMachNotifyChannel -{ - - private: - - JackMachPort fClientPort; /*! Mach port to communicate with the client : from server to client */ - - public: - - JackMachNotifyChannel() - {} - - int Open(const char* name); // Open the Server/Client connection - void Close(); // Close the Server/Client connection - - void ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2, int* result); -}; - -} // end of namespace - -#endif - diff --git a/macosx/JackMachPort.cpp b/macosx/JackMachPort.cpp deleted file mode 100644 index d0d236b7..00000000 --- a/macosx/JackMachPort.cpp +++ /dev/null @@ -1,295 +0,0 @@ -/* -Copyright (C) 2004-2008 Grame - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 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 -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "JackMachPort.h" -#include "JackError.h" - -namespace Jack -{ - -// Server side : port is published to be accessible from other processes (clients) - -bool JackMachPort::AllocatePort(const char* name, int queue) -{ - mach_port_t task = mach_task_self(); - kern_return_t res; - - if ((res = task_get_bootstrap_port(task, &fBootPort)) != KERN_SUCCESS) { - jack_error("AllocatePort: Can't find bootstrap mach port err = %s", mach_error_string(res)); - return false; - } - - if ((res = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &fServerPort)) != KERN_SUCCESS) { - jack_error("AllocatePort: can't allocate mach port err = %s", mach_error_string(res)); - return false; - } - - if ((res = mach_port_insert_right(task, fServerPort, fServerPort, MACH_MSG_TYPE_MAKE_SEND)) != KERN_SUCCESS) { - jack_error("AllocatePort: error inserting mach rights err = %s", mach_error_string(res)); - return false; - } - - if ((res = bootstrap_register(fBootPort, (char*)name, fServerPort)) != KERN_SUCCESS) { - jack_error("Allocate: can't check in mach port name = %s err = %s", name, mach_error_string(res)); - return false; - } - - mach_port_limits_t qlimits; - mach_msg_type_number_t info_cnt = MACH_PORT_LIMITS_INFO_COUNT; - if ((res = mach_port_get_attributes(task, fServerPort, MACH_PORT_LIMITS_INFO, (mach_port_info_t) & qlimits, &info_cnt)) != KERN_SUCCESS) { - jack_error("Allocate: mach_port_get_attributes error err = %s", name, mach_error_string(res)); - } - - jack_log("AllocatePort: queue limit %ld", qlimits.mpl_qlimit); - - if (queue > 0) { - qlimits.mpl_qlimit = queue; - if ((res = mach_port_set_attributes(task, fServerPort, MACH_PORT_LIMITS_INFO, (mach_port_info_t) & qlimits, MACH_PORT_LIMITS_INFO_COUNT)) != KERN_SUCCESS) { - jack_error("Allocate: mach_port_set_attributes error name = %s err = %s", name, mach_error_string(res)); - } - } - - return true; -} - -// Server side : port is published to be accessible from other processes (clients) - -bool JackMachPort::AllocatePort(const char* name) -{ - return AllocatePort(name, -1); -} - -// Client side : get the published port from server - -bool JackMachPort::ConnectPort(const char* name) -{ - kern_return_t res; - - jack_log("JackMachPort::ConnectPort %s", name); - - if ((res = task_get_bootstrap_port(mach_task_self(), &fBootPort)) != KERN_SUCCESS) { - jack_error("ConnectPort: can't find bootstrap port err = %s", mach_error_string(res)); - return false; - } - - if ((res = bootstrap_look_up(fBootPort, (char*)name, &fServerPort)) != KERN_SUCCESS) { - jack_error("ConnectPort: can't find mach server port name = %s err = %s", name, mach_error_string(res)); - return false; - } - - return true; -} - -bool JackMachPort::DisconnectPort() -{ - jack_log("JackMacRPC::DisconnectPort"); - kern_return_t res; - mach_port_t task = mach_task_self(); - - if (fBootPort != 0) { - if ((res = mach_port_deallocate(task, fBootPort)) != KERN_SUCCESS) { - jack_error("JackMacRPC::DisconnectPort mach_port_deallocate fBootPort err = %s", mach_error_string(res)); - } - } - - if (fServerPort != 0) { - if ((res = mach_port_deallocate(task, fServerPort)) != KERN_SUCCESS) { - jack_error("JackMacRPC::DisconnectPort mach_port_deallocate fServerPort err = %s", mach_error_string(res)); - } - } - - return true; -} - -bool JackMachPort::DestroyPort() -{ - jack_log("JackMacRPC::DisconnectPort"); - kern_return_t res; - mach_port_t task = mach_task_self(); - - if (fBootPort != 0) { - if ((res = mach_port_deallocate(task, fBootPort)) != KERN_SUCCESS) { - jack_error("JackMacRPC::DisconnectPort mach_port_deallocate fBootPort err = %s", mach_error_string(res)); - } - } - - if (fServerPort != 0) { - if ((res = mach_port_destroy(task, fServerPort)) != KERN_SUCCESS) { - jack_error("JackMacRPC::DisconnectPort mach_port_destroy fServerPort err = %s", mach_error_string(res)); - } - } - - return true; -} - -mach_port_t JackMachPort::GetPort() -{ - return fServerPort; -} - -bool JackMachPortSet::AllocatePort(const char* name, int queue) -{ - kern_return_t res; - mach_port_t task = mach_task_self(); - - jack_log("JackMachPortSet::AllocatePort"); - - if ((res = task_get_bootstrap_port(task, &fBootPort)) != KERN_SUCCESS) { - jack_error("AllocatePort: Can't find bootstrap mach port err = %s", mach_error_string(res)); - return false; - } - - if ((res = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &fServerPort)) != KERN_SUCCESS) { - jack_error("AllocatePort: can't allocate mach port err = %s", mach_error_string(res)); - return false; - } - - if ((res = mach_port_insert_right(task, fServerPort, fServerPort, MACH_MSG_TYPE_MAKE_SEND)) != KERN_SUCCESS) { - jack_error("AllocatePort: error inserting mach rights err = %s", mach_error_string(res)); - return false; - } - - if ((res = mach_port_allocate(task, MACH_PORT_RIGHT_PORT_SET, &fPortSet)) != KERN_SUCCESS) { - jack_error("AllocatePort: can't allocate mach port err = %s", mach_error_string(res)); - return false; - } - - if ((res = mach_port_move_member(task, fServerPort, fPortSet)) != KERN_SUCCESS) { - jack_error("AllocatePort: error in mach_port_move_member err = %s", mach_error_string(res)); - return false; - } - - if ((res = bootstrap_register(fBootPort, (char*)name, fServerPort)) != KERN_SUCCESS) { - jack_error("Allocate: can't check in mach port name = %s err = %s", name, mach_error_string(res)); - return false; - } - - mach_port_limits_t qlimits; - mach_msg_type_number_t info_cnt = MACH_PORT_LIMITS_INFO_COUNT; - if ((res = mach_port_get_attributes(task, fServerPort, MACH_PORT_LIMITS_INFO, (mach_port_info_t) & qlimits, &info_cnt)) != KERN_SUCCESS) { - jack_error("Allocate: mach_port_get_attributes error name = %s err = %s", name, mach_error_string(res)); - } - - jack_log("AllocatePort: queue limit = %ld", qlimits.mpl_qlimit); - - if (queue > 0) { - qlimits.mpl_qlimit = queue; - - if ((res = mach_port_set_attributes(task, fServerPort, MACH_PORT_LIMITS_INFO, (mach_port_info_t) & qlimits, MACH_PORT_LIMITS_INFO_COUNT)) != KERN_SUCCESS) { - jack_error("Allocate: mach_port_set_attributes error name = %s err = %s", name, mach_error_string(res)); - } - } - - return true; -} - -// Server side : port is published to be accessible from other processes (clients) - -bool JackMachPortSet::AllocatePort(const char* name) -{ - return AllocatePort(name, -1); -} - -bool JackMachPortSet::DisconnectPort() -{ - kern_return_t res; - mach_port_t task = mach_task_self(); - - jack_log("JackMachPortSet::DisconnectPort"); - - if (fBootPort != 0) { - if ((res = mach_port_deallocate(task, fBootPort)) != KERN_SUCCESS) { - jack_error("JackMachPortSet::DisconnectPort mach_port_deallocate fBootPort err = %s", mach_error_string(res)); - } - } - - if (fServerPort != 0) { - if ((res = mach_port_deallocate(task, fServerPort)) != KERN_SUCCESS) { - jack_error("JackMachPortSet::DisconnectPort mach_port_deallocate fServerPort err = %s", mach_error_string(res)); - } - } - - return true; -} - -bool JackMachPortSet::DestroyPort() -{ - kern_return_t res; - mach_port_t task = mach_task_self(); - - jack_log("JackMachPortSet::DisconnectPort"); - - if (fBootPort != 0) { - if ((res = mach_port_deallocate(task, fBootPort)) != KERN_SUCCESS) { - jack_error("JackMachPortSet::DisconnectPort mach_port_deallocate err = %s", mach_error_string(res)); - } - } - - if (fServerPort != 0) { - if ((res = mach_port_destroy(task, fServerPort)) != KERN_SUCCESS) { - jack_error("JackMachPortSet::DisconnectPort mach_port_destroy fServerPort err = %s", mach_error_string(res)); - } - } - - return true; -} - -mach_port_t JackMachPortSet::GetPortSet() -{ - return fPortSet; -} - -mach_port_t JackMachPortSet::AddPort() -{ - kern_return_t res; - mach_port_t task = mach_task_self(); - mach_port_t old_port, result = 0; - - jack_log("JackMachPortSet::AddPort"); - - if ((res = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &result)) != KERN_SUCCESS) { - jack_error("AddPort: can't allocate mach port err = %s", mach_error_string(res)); - goto error; - } - - if ((res = mach_port_request_notification(task, result, MACH_NOTIFY_NO_SENDERS, - 1, result, MACH_MSG_TYPE_MAKE_SEND_ONCE, &old_port)) != KERN_SUCCESS) { - jack_error("AddPort: error in mach_port_request_notification err = %s", mach_error_string(res)); - goto error; - } - - if ((res = mach_port_move_member(task, result, fPortSet)) != KERN_SUCCESS) { - jack_error("AddPort: error in mach_port_move_member err = %s", mach_error_string(res)); - goto error; - } - - return result; - -error: - if (result) { - if ((res = mach_port_destroy(task, result)) != KERN_SUCCESS) { - jack_error("JackMacRPC::DisconnectPort mach_port_destroy err = %s", mach_error_string(res)); - } - } - return 0; -} - - -} // end of namespace - diff --git a/macosx/JackMachPort.h b/macosx/JackMachPort.h deleted file mode 100644 index 85176b3f..00000000 --- a/macosx/JackMachPort.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright (C) 2004-2008 Grame - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 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 -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#ifndef __JackMachPort__ -#define __JackMachPort__ - -#include -#include -#include -#include -#include - -namespace Jack -{ - -/*! -\brief Mach port. -*/ - -class JackMachPort -{ - - protected: - - mach_port_t fBootPort; - mach_port_t fServerPort; - - public: - - JackMachPort():fBootPort(0), fServerPort(0) - {} - virtual ~JackMachPort() - {} - - virtual bool AllocatePort(const char* name); - virtual bool AllocatePort(const char* name, int queue); - virtual bool ConnectPort(const char* name); - virtual bool DisconnectPort(); - virtual bool DestroyPort(); - virtual mach_port_t GetPort(); -}; - -/*! -\brief Mach port set. -*/ - -class JackMachPortSet : public JackMachPort -{ - - private: - - mach_port_t fPortSet; - - public: - - JackMachPortSet():fPortSet(0) - {} - virtual ~JackMachPortSet() - {} - - bool AllocatePort(const char* name); - bool AllocatePort(const char* name, int queue); - bool DisconnectPort(); - bool DestroyPort(); - mach_port_t GetPortSet(); - mach_port_t AddPort(); -}; - -} // end of namespace - -#endif - diff --git a/macosx/JackMachServerChannel.cpp b/macosx/JackMachServerChannel.cpp deleted file mode 100644 index 411886a7..00000000 --- a/macosx/JackMachServerChannel.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* -Copyright (C) 2004-2008 Grame - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 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 -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "JackTools.h" -#include "JackMachServerChannel.h" -#include "JackRPCEngineServer.c" -#include "JackError.h" -#include "JackServer.h" -#include "JackLockedEngine.h" -#include "JackNotification.h" -#include "JackServerGlobals.h" - -using namespace std; - -namespace Jack -{ - -map JackMachServerChannel::fPortTable; - -JackMachServerChannel::JackMachServerChannel():fThread(this) -{} - -JackMachServerChannel::~JackMachServerChannel() -{} - -int JackMachServerChannel::Open(const char* server_name, JackServer* server) -{ - jack_log("JackMachServerChannel::Open"); - char jack_server_entry_name[512]; - snprintf(jack_server_entry_name, sizeof(jack_server_entry_name), "%s.%d_%s", jack_server_entry, JackTools::GetUID(), server_name); - - if (!fServerPort.AllocatePort(jack_server_entry_name, 16)) { // 16 is the max possible value - jack_error("Cannot check in Jack server"); - return -1; - } - - fServer = server; - fPortTable[fServerPort.GetPort()] = this; - return 0; -} - -void JackMachServerChannel::Close() -{ - jack_log("JackMachServerChannel::Close"); - #ifdef MAC_OS_X_VERSION_10_5 - // Exception does not work in this case on pre Snow Loopard systems, see JackMachServerNotifyChannel::NotifyQuit() - fThread.Kill(); - #else - fThread.Stop(); - #endif - fServerPort.DestroyPort(); -} - -int JackMachServerChannel::Start() -{ - if (fThread.Start() != 0) { - jack_error("Cannot start Jack server listener"); - return -1; - } - - return 0; -} - -JackLockedEngine* JackMachServerChannel::GetEngine() -{ - return fServer->GetEngine(); -} - -JackServer* JackMachServerChannel::GetServer() -{ - return fServer; -} - -void JackMachServerChannel::ClientCheck(char* name, char* name_res, int protocol, int options, int* status, int* result) -{ - *result = GetEngine()->ClientCheck(name, name_res, protocol, options, status); -} - -void JackMachServerChannel::ClientOpen(char* name, int pid, mach_port_t* private_port, int* shared_engine, int* shared_client, int* shared_graph, int* result) -{ - int refnum = -1; - *result = GetEngine()->ClientExternalOpen(name, pid, &refnum, shared_engine, shared_client, shared_graph); - - if (*result == 0) { - mach_port_t port = fServerPort.AddPort(); - if (port != 0) { - fClientTable[port] = refnum; - fPortTable[port] = this; - *private_port = port; - } else { - jack_error("Cannot create private client mach port"); - *result = -1; - } - } else { - jack_error("Cannot create new client"); - } -} - -void JackMachServerChannel::ClientClose(mach_port_t private_port, int refnum) -{ - GetEngine()->ClientExternalClose(refnum); - fClientTable.erase(private_port); - - // Hum, hum.... - kern_return_t res; - if ((res = mach_port_destroy(mach_task_self(), private_port)) != KERN_SUCCESS) { - jack_error("server_rpc_jack_client_close mach_port_destroy %s", mach_error_string(res)); - } -} - -void JackMachServerChannel::ClientKill(mach_port_t private_port) -{ - jack_log("JackMachServerChannel::ClientKill"); - int refnum = fClientTable[private_port]; - assert(refnum > 0); - fServer->ClientKill(refnum); - fClientTable.erase(private_port); - - // Hum, hum.... - kern_return_t res; - if ((res = mach_port_destroy(mach_task_self(), private_port)) != KERN_SUCCESS) { - jack_error("server_rpc_jack_client_close mach_port_destroy %s", mach_error_string(res)); - } -} - -boolean_t JackMachServerChannel::MessageHandler(mach_msg_header_t* Request, mach_msg_header_t* Reply) -{ - if (Request->msgh_id == MACH_NOTIFY_NO_SENDERS) { - jack_log("MACH_NOTIFY_NO_SENDERS %ld", Request->msgh_local_port); - JackMachServerChannel* channel = JackMachServerChannel::fPortTable[Request->msgh_local_port]; - assert(channel); - channel->ClientKill(Request->msgh_local_port); - } else { - JackRPCEngine_server(Request, Reply); - } - return true; -} - -bool JackMachServerChannel::Execute() -{ - try { - - kern_return_t res; - if ((res = mach_msg_server(MessageHandler, 1024, fServerPort.GetPortSet(), 0)) != KERN_SUCCESS) { - jack_log("JackMachServerChannel::Execute: err = %s", mach_error_string(res)); - // A recoverable error, so keep running... - } - return true; - - } catch (JackQuitException& e) { - jack_log("JackMachServerChannel::Execute JackQuitException"); - return false; - } -} - -} // end of namespace - - diff --git a/macosx/JackMachServerChannel.h b/macosx/JackMachServerChannel.h deleted file mode 100644 index fc5a100b..00000000 --- a/macosx/JackMachServerChannel.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -Copyright (C) 2004-2008 Grame - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 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 -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#ifndef __JackMachServerChannel__ -#define __JackMachServerChannel__ - -#include "JackPlatformPlug.h" -#include "JackMachPort.h" -#include - -namespace Jack -{ - -class JackServer; -class JackLockedEngine; - -/*! -\brief JackServerChannel using Mach IPC. -*/ - -class JackMachServerChannel : public JackRunnableInterface -{ - - private: - - JackMachPortSet fServerPort; /*! Mach port to communicate with the server : from client to server */ - JackThread fThread; /*! Thread to execute the event loop */ - JackServer* fServer; - std::map fClientTable; - - static boolean_t MessageHandler(mach_msg_header_t* Request, mach_msg_header_t* Reply); - - public: - - JackMachServerChannel(); - ~JackMachServerChannel(); - - int Open(const char* server_name, JackServer* server); // Open the Server/Client connection - void Close(); // Close the Server/Client connection - - int Start(); - - JackLockedEngine* GetEngine(); - JackServer* GetServer(); - - void ClientCheck(char* name, char* name_res, int protocol, int options, int* status, int* result); - void ClientOpen(char* name, int pid, mach_port_t* private_port, int* shared_engine, int* shared_client, int* shared_graph, int* result); - void ClientClose(mach_port_t private_port, int refnum); - void ClientKill(mach_port_t private_port); - - bool Execute(); - - // Has to be public.. - static std::map fPortTable; -}; - -} // end of namespace - -#endif - diff --git a/macosx/JackMachServerNotifyChannel.cpp b/macosx/JackMachServerNotifyChannel.cpp deleted file mode 100644 index f55ce09e..00000000 --- a/macosx/JackMachServerNotifyChannel.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* -Copyright (C) 2004-2008 Grame - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 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 -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "JackMachServerNotifyChannel.h" -#include "JackRPCEngineUser.c" -#include "JackNotification.h" -#include "JackTools.h" -#include "JackConstants.h" -#include "JackError.h" -#include - -namespace Jack -{ - -int JackMachServerNotifyChannel::Open(const char* server_name) -{ - jack_log("JackMachServerChannel::Open"); - char jack_server_entry_name[512]; - snprintf(jack_server_entry_name, sizeof(jack_server_entry_name), "%s.%d_%s", jack_server_entry, JackTools::GetUID(), server_name); - - if (!fClientPort.ConnectPort(jack_server_entry_name)) { - jack_error("Cannot connect to server port"); - return -1; - } else { - return 0; - } -} - -void JackMachServerNotifyChannel::Close() -{} - -void JackMachServerNotifyChannel::Notify(int refnum, int notify, int value) -{ - kern_return_t res = rpc_jack_client_rt_notify(fClientPort.GetPort(), refnum, notify, value, 0); - if (res != KERN_SUCCESS) { - jack_error("Could not write request ref = %d notify = %d err = %s", refnum, notify, mach_error_string(res)); - } -} - -void JackMachServerNotifyChannel::NotifyQuit() -{ - #ifdef MAC_OS_X_VERSION_10_5 - // Nothing : since exception does not work in this case on pre Snow Loopard systems, see JackMachServerChannel::Close() - #else - kern_return_t res = rpc_jack_client_rt_notify(fClientPort.GetPort(), -1, kQUIT, 0, 0); - if (res != KERN_SUCCESS) { - jack_error("Could not write request ref = %d notify = %d err = %s", -1, kQUIT, mach_error_string(res)); - } -#endif -} - -} // end of namespace - - diff --git a/macosx/JackMachServerNotifyChannel.h b/macosx/JackMachServerNotifyChannel.h deleted file mode 100644 index 8eb7b72f..00000000 --- a/macosx/JackMachServerNotifyChannel.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright (C) 2004-2008 Grame - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 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 -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#ifndef __JackMachServerNotifyChannel__ -#define __JackMachServerNotifyChannel__ - -#include "JackChannel.h" -#include "JackMachPort.h" - -namespace Jack -{ - -/*! -\brief JackServerNotifyChannel using Mach IPC. -*/ - -class JackMachServerNotifyChannel -{ - - private: - - JackMachPort fClientPort; /*! Mach port to communicate with the server : from client to server */ - - public: - - JackMachServerNotifyChannel() - {} - - int Open(const char* server_name); // Open the Server/Client connection - void Close(); // Close the Server/Client connection - - void Notify(int refnum, int notify, int value); - void NotifyQuit(); -}; - -} // end of namespace - -#endif - diff --git a/macosx/JackPlatformPlug_os.h b/macosx/JackPlatformPlug_os.h index 44ab5c33..056002e0 100644 --- a/macosx/JackPlatformPlug_os.h +++ b/macosx/JackPlatformPlug_os.h @@ -28,14 +28,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { + struct JackRequest; + struct JackResult; + class JackPosixMutex; class JackMachThread; class JackMachSemaphore; - - class JackMachServerChannel; - class JackMachClientChannel; - class JackMachServerNotifyChannel; - class JackMachNotifyChannel; + + class JackSocketServerChannel; + class JackSocketClientChannel; + class JackSocketServerNotifyChannel; + class JackSocketNotifyChannel; + class JackNetUnixSocket; #ifdef MY_TARGET_OS_IPHONE @@ -60,26 +64,29 @@ namespace Jack { typedef JackMachThread JackThread; } namespace Jack { typedef JackMachSemaphore JackSynchro; } #endif +#include "JackSocket.h" +namespace Jack { typedef JackClientSocket JackChannelTransaction; } + /* __JackPlatformProcessSync__ */ #include "JackProcessSync.h" /* Only on windows a special JackProcessSync is used. It is directly defined by including JackProcessSync.h here */ #ifndef MY_TARGET_OS_IPHONE /* __JackPlatformServerChannel__ */ -#include "JackMachServerChannel.h" -namespace Jack { typedef JackMachServerChannel JackServerChannel; } +#include "JackSocketServerChannel.h" +namespace Jack { typedef JackSocketServerChannel JackServerChannel; } /* __JackPlatformClientChannel__ */ -#include "JackMachClientChannel.h" -namespace Jack { typedef JackMachClientChannel JackClientChannel; } +#include "JackSocketClientChannel.h" +namespace Jack { typedef JackSocketClientChannel JackClientChannel; } /* __JackPlatformServerNotifyChannel__ */ -#include "JackMachServerNotifyChannel.h" -namespace Jack { typedef JackMachServerNotifyChannel JackServerNotifyChannel; } +#include "JackSocketServerNotifyChannel.h" +namespace Jack { typedef JackSocketServerNotifyChannel JackServerNotifyChannel; } /* __JackPlatformNotifyChannel__ */ -#include "JackMachNotifyChannel.h" -namespace Jack { typedef JackMachNotifyChannel JackNotifyChannel; } +#include "JackSocketNotifyChannel.h" +namespace Jack { typedef JackSocketNotifyChannel JackNotifyChannel; } #endif /* __JackPlatformNetSocket__ */ diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index 486ae06c..8c457330 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -47,6 +47,7 @@ 4BFA833A0DF6AB540087B4E1 /* PBXTargetDependency */, 4BFA833C0DF6AB540087B4E1 /* PBXTargetDependency */, 4B32258F10A31AB400838A8E /* PBXTargetDependency */, + 4B66550E127C356E00753A79 /* PBXTargetDependency */, ); name = "All Universal 32/64 bits"; productName = All; @@ -132,7 +133,6 @@ 4B32258010A3195A00838A8E /* netjack_packet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224ED10A315C400838A8E /* netjack_packet.h */; }; 4B32258110A3195B00838A8E /* netsource.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B32256310A318E300838A8E /* netsource.c */; }; 4B35C41E0D4731D1000DE7AE /* Jackdmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2250834F06A00C94B91 /* Jackdmp.cpp */; }; - 4B35C4290D4731D1000DE7AE /* JackMachPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B799AD707899652003F3F15 /* JackMachPort.h */; }; 4B35C42A0D4731D1000DE7AE /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; }; 4B35C42B0D4731D1000DE7AE /* JackTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1830834EE5800C94B91 /* JackTime.h */; }; 4B35C42C0D4731D1000DE7AE /* JackShmMem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1870834EE7900C94B91 /* JackShmMem.h */; }; @@ -153,7 +153,6 @@ 4B35C43D0D4731D1000DE7AE /* JackMachSemaphore.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF6C1D608ACE64C001E2013 /* JackMachSemaphore.h */; }; 4B35C43E0D4731D1000DE7AE /* JackGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB73F608AD291A00DB99B8 /* JackGlobals.h */; }; 4B35C43F0D4731D1000DE7AE /* JackMachThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB741F08AD2B9900DB99B8 /* JackMachThread.h */; }; - 4B35C4400D4731D1000DE7AE /* JackMachClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB298708AF450200D450D4 /* JackMachClientChannel.h */; }; 4B35C4460D4731D1000DE7AE /* JackSynchro.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD561C708EEB910006BBC2A /* JackSynchro.h */; }; 4B35C4470D4731D1000DE7AE /* JackDebugClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B98AE010931D30C0091932A /* JackDebugClient.h */; }; 4B35C4480D4731D1000DE7AE /* JackConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66A8580934964500A89560 /* JackConstants.h */; }; @@ -170,9 +169,6 @@ 4B35C4530D4731D1000DE7AE /* JackMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */; }; 4B35C4540D4731D1000DE7AE /* midiport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6B9EF50CD0958B0051EE5A /* midiport.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C4550D4731D1000DE7AE /* JackTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE4CC000CDA153400CCF5BB /* JackTools.h */; }; - 4B35C4580D4731D1000DE7AE /* JackMacLibClientRPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF3937C0626BF3600CC67FA /* JackMacLibClientRPC.cpp */; }; - 4B35C4590D4731D1000DE7AE /* JackRPCEngineUser.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B89B769076B74D200D170DE /* JackRPCEngineUser.c */; }; - 4B35C45A0D4731D1000DE7AE /* JackMachPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B799AD607899652003F3F15 /* JackMachPort.cpp */; }; 4B35C45B0D4731D1000DE7AE /* JackShmMem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1880834EE7900C94B91 /* JackShmMem.cpp */; }; 4B35C45C0D4731D1000DE7AE /* shm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1900834EE8400C94B91 /* shm.c */; }; 4B35C45E0D4731D1000DE7AE /* JackActivationCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1A80834EEB400C94B91 /* JackActivationCount.cpp */; }; @@ -186,7 +182,6 @@ 4B35C4660D4731D1000DE7AE /* JackFrameTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */; }; 4B35C4680D4731D1000DE7AE /* JackMachSemaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF6C1D508ACE64C001E2013 /* JackMachSemaphore.cpp */; }; 4B35C4690D4731D1000DE7AE /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB741E08AD2B9900DB99B8 /* JackMachThread.cpp */; }; - 4B35C46A0D4731D1000DE7AE /* JackMachClientChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB29AE08AF45FD00D450D4 /* JackMachClientChannel.cpp */; }; 4B35C4700D4731D1000DE7AE /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */; }; 4B35C4720D4731D1000DE7AE /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B003AB008E2B2BA0060EFDC /* ringbuffer.c */; }; 4B35C4730D4731D1000DE7AE /* JackDebugClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B98AE000931D30C0091932A /* JackDebugClient.cpp */; }; @@ -198,7 +193,6 @@ 4B35C47A0D4731D1000DE7AE /* JackMidiAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */; }; 4B35C47B0D4731D1000DE7AE /* JackEngineControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6F7AEC0CD0CDBD00F48A9D /* JackEngineControl.cpp */; }; 4B35C47C0D4731D1000DE7AE /* JackTools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4CBFF0CDA153400CCF5BB /* JackTools.cpp */; }; - 4B35C4870D4731D1000DE7AE /* JackMachPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B799AD707899652003F3F15 /* JackMachPort.h */; }; 4B35C4880D4731D1000DE7AE /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; }; 4B35C4890D4731D1000DE7AE /* JackTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1830834EE5800C94B91 /* JackTime.h */; }; 4B35C48A0D4731D1000DE7AE /* JackShmMem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1870834EE7900C94B91 /* JackShmMem.h */; }; @@ -227,9 +221,6 @@ 4B35C4A90D4731D1000DE7AE /* JackEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2130834F02800C94B91 /* JackEngine.h */; }; 4B35C4AA0D4731D1000DE7AE /* JackExternalClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1F70834EFBD00C94B91 /* JackExternalClient.h */; }; 4B35C4AB0D4731D1000DE7AE /* JackServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2220834F05C00C94B91 /* JackServer.h */; }; - 4B35C4AE0D4731D1000DE7AE /* JackMachNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB298908AF450200D450D4 /* JackMachNotifyChannel.h */; }; - 4B35C4AF0D4731D1000DE7AE /* JackMachServerChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB297808AF44ED00D450D4 /* JackMachServerChannel.h */; }; - 4B35C4B00D4731D1000DE7AE /* JackMachServerNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB297A08AF44ED00D450D4 /* JackMachServerNotifyChannel.h */; }; 4B35C4B20D4731D1000DE7AE /* JackConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66A8580934964500A89560 /* JackConstants.h */; }; 4B35C4B30D4731D1000DE7AE /* JackTransportEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */; }; 4B35C4B40D4731D1000DE7AE /* JackServerGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC2168D0A444BED00BDA09F /* JackServerGlobals.h */; }; @@ -246,7 +237,6 @@ 4B35C4BF0D4731D1000DE7AE /* midiport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6B9EF50CD0958B0051EE5A /* midiport.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B35C4C00D4731D1000DE7AE /* JackDebugClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B98AE010931D30C0091932A /* JackDebugClient.h */; }; 4B35C4C10D4731D1000DE7AE /* JackTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE4CC000CDA153400CCF5BB /* JackTools.h */; }; - 4B35C4C40D4731D1000DE7AE /* JackMachPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B799AD607899652003F3F15 /* JackMachPort.cpp */; }; 4B35C4C50D4731D1000DE7AE /* JackShmMem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1880834EE7900C94B91 /* JackShmMem.cpp */; }; 4B35C4C60D4731D1000DE7AE /* shm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1900834EE8400C94B91 /* shm.c */; }; 4B35C4C80D4731D1000DE7AE /* JackActivationCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1A80834EEB400C94B91 /* JackActivationCount.cpp */; }; @@ -268,12 +258,7 @@ 4B35C4DD0D4731D1000DE7AE /* JackEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2140834F02800C94B91 /* JackEngine.cpp */; }; 4B35C4DE0D4731D1000DE7AE /* JackExternalClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1F80834EFBD00C94B91 /* JackExternalClient.cpp */; }; 4B35C4DF0D4731D1000DE7AE /* JackInternalClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1ED0834EF9200C94B91 /* JackInternalClient.cpp */; }; - 4B35C4E00D4731D1000DE7AE /* JackRPCClientUser.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B89B759076B731100D170DE /* JackRPCClientUser.c */; }; 4B35C4E20D4731D1000DE7AE /* JackServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2210834F05C00C94B91 /* JackServer.cpp */; }; - 4B35C4E60D4731D1000DE7AE /* JackMacEngineRPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4259E5076B635E00C1ECE1 /* JackMacEngineRPC.cpp */; }; - 4B35C4E70D4731D1000DE7AE /* JackMachNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB298808AF450200D450D4 /* JackMachNotifyChannel.cpp */; }; - 4B35C4E80D4731D1000DE7AE /* JackMachServerChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB297908AF44ED00D450D4 /* JackMachServerChannel.cpp */; }; - 4B35C4E90D4731D1000DE7AE /* JackMachServerNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB297708AF44ED00D450D4 /* JackMachServerNotifyChannel.cpp */; }; 4B35C4EB0D4731D1000DE7AE /* JackTransportEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */; }; 4B35C4EC0D4731D1000DE7AE /* JackServerAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1F50834EFB000C94B91 /* JackServerAPI.cpp */; }; 4B35C4ED0D4731D1000DE7AE /* JackServerGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC216880A444BDE00BDA09F /* JackServerGlobals.cpp */; }; @@ -322,7 +307,6 @@ 4B43A8CB1014605000E52943 /* JackLoopbackDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B43A8C91014605000E52943 /* JackLoopbackDriver.h */; }; 4B43A8DF1014615800E52943 /* JackLoopbackDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B43A8C91014605000E52943 /* JackLoopbackDriver.h */; }; 4B43A8E11014615800E52943 /* JackLoopbackDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B43A8C81014605000E52943 /* JackLoopbackDriver.cpp */; }; - 4B47AC8210B5890100469C67 /* JackMachPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B799AD707899652003F3F15 /* JackMachPort.h */; }; 4B47AC8310B5890100469C67 /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; }; 4B47AC8410B5890100469C67 /* JackTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1830834EE5800C94B91 /* JackTime.h */; }; 4B47AC8510B5890100469C67 /* JackShmMem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1870834EE7900C94B91 /* JackShmMem.h */; }; @@ -343,7 +327,6 @@ 4B47AC9410B5890100469C67 /* JackMachSemaphore.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF6C1D608ACE64C001E2013 /* JackMachSemaphore.h */; }; 4B47AC9510B5890100469C67 /* JackGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB73F608AD291A00DB99B8 /* JackGlobals.h */; }; 4B47AC9610B5890100469C67 /* JackMachThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB741F08AD2B9900DB99B8 /* JackMachThread.h */; }; - 4B47AC9710B5890100469C67 /* JackMachClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB298708AF450200D450D4 /* JackMachClientChannel.h */; }; 4B47AC9810B5890100469C67 /* JackSynchro.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD561C708EEB910006BBC2A /* JackSynchro.h */; }; 4B47AC9910B5890100469C67 /* JackDebugClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B98AE010931D30C0091932A /* JackDebugClient.h */; }; 4B47AC9A10B5890100469C67 /* JackConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66A8580934964500A89560 /* JackConstants.h */; }; @@ -364,9 +347,6 @@ 4B47ACA910B5890100469C67 /* JackMessageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4F9C8B0DC20C0400706CB0 /* JackMessageBuffer.h */; }; 4B47ACAA10B5890100469C67 /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; 4B47ACAB10B5890100469C67 /* JackProcessSync.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BECB2F40F4451C10091B70A /* JackProcessSync.h */; }; - 4B47ACAE10B5890100469C67 /* JackMacLibClientRPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF3937C0626BF3600CC67FA /* JackMacLibClientRPC.cpp */; }; - 4B47ACAF10B5890100469C67 /* JackRPCEngineUser.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B89B769076B74D200D170DE /* JackRPCEngineUser.c */; }; - 4B47ACB010B5890100469C67 /* JackMachPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B799AD607899652003F3F15 /* JackMachPort.cpp */; }; 4B47ACB110B5890100469C67 /* JackShmMem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1880834EE7900C94B91 /* JackShmMem.cpp */; }; 4B47ACB210B5890100469C67 /* shm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1900834EE8400C94B91 /* shm.c */; }; 4B47ACB310B5890100469C67 /* JackActivationCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1A80834EEB400C94B91 /* JackActivationCount.cpp */; }; @@ -380,7 +360,6 @@ 4B47ACBB10B5890100469C67 /* JackFrameTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */; }; 4B47ACBC10B5890100469C67 /* JackMachSemaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF6C1D508ACE64C001E2013 /* JackMachSemaphore.cpp */; }; 4B47ACBD10B5890100469C67 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB741E08AD2B9900DB99B8 /* JackMachThread.cpp */; }; - 4B47ACBE10B5890100469C67 /* JackMachClientChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB29AE08AF45FD00D450D4 /* JackMachClientChannel.cpp */; }; 4B47ACBF10B5890100469C67 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */; }; 4B47ACC010B5890100469C67 /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B003AB008E2B2BA0060EFDC /* ringbuffer.c */; }; 4B47ACC110B5890100469C67 /* JackDebugClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B98AE000931D30C0091932A /* JackDebugClient.cpp */; }; @@ -433,8 +412,8 @@ 4B5F253E0DEE9B8F0041E486 /* JackLockedEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B5F253D0DEE9B8F0041E486 /* JackLockedEngine.h */; }; 4B60CE490AAABA31004956AA /* connect.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B60CE480AAABA31004956AA /* connect.c */; }; 4B60CE4A0AAABA31004956AA /* connect.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B60CE480AAABA31004956AA /* connect.c */; }; + 4B6654FC127C350100753A79 /* server_control.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6654FB127C350100753A79 /* server_control.cpp */; }; 4B699BAA097D421600A18468 /* Jackdmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2250834F06A00C94B91 /* Jackdmp.cpp */; }; - 4B699C02097D421600A18468 /* JackMachPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B799AD707899652003F3F15 /* JackMachPort.h */; }; 4B699C03097D421600A18468 /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; }; 4B699C04097D421600A18468 /* JackTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1830834EE5800C94B91 /* JackTime.h */; }; 4B699C05097D421600A18468 /* JackShmMem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1870834EE7900C94B91 /* JackShmMem.h */; }; @@ -455,13 +434,9 @@ 4B699C16097D421600A18468 /* JackMachSemaphore.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF6C1D608ACE64C001E2013 /* JackMachSemaphore.h */; }; 4B699C17097D421600A18468 /* JackGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB73F608AD291A00DB99B8 /* JackGlobals.h */; }; 4B699C18097D421600A18468 /* JackMachThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB741F08AD2B9900DB99B8 /* JackMachThread.h */; }; - 4B699C19097D421600A18468 /* JackMachClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB298708AF450200D450D4 /* JackMachClientChannel.h */; }; 4B699C20097D421600A18468 /* JackSynchro.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD561C708EEB910006BBC2A /* JackSynchro.h */; }; 4B699C21097D421600A18468 /* JackDebugClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B98AE010931D30C0091932A /* JackDebugClient.h */; }; 4B699C22097D421600A18468 /* JackConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66A8580934964500A89560 /* JackConstants.h */; }; - 4B699C25097D421600A18468 /* JackMacLibClientRPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF3937C0626BF3600CC67FA /* JackMacLibClientRPC.cpp */; }; - 4B699C26097D421600A18468 /* JackRPCEngineUser.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B89B769076B74D200D170DE /* JackRPCEngineUser.c */; }; - 4B699C27097D421600A18468 /* JackMachPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B799AD607899652003F3F15 /* JackMachPort.cpp */; }; 4B699C28097D421600A18468 /* JackShmMem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1880834EE7900C94B91 /* JackShmMem.cpp */; }; 4B699C29097D421600A18468 /* shm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1900834EE8400C94B91 /* shm.c */; }; 4B699C2B097D421600A18468 /* JackActivationCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1A80834EEB400C94B91 /* JackActivationCount.cpp */; }; @@ -475,11 +450,9 @@ 4B699C33097D421600A18468 /* JackFrameTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */; }; 4B699C35097D421600A18468 /* JackMachSemaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF6C1D508ACE64C001E2013 /* JackMachSemaphore.cpp */; }; 4B699C36097D421600A18468 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB741E08AD2B9900DB99B8 /* JackMachThread.cpp */; }; - 4B699C37097D421600A18468 /* JackMachClientChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB29AE08AF45FD00D450D4 /* JackMachClientChannel.cpp */; }; 4B699C3D097D421600A18468 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */; }; 4B699C3F097D421600A18468 /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B003AB008E2B2BA0060EFDC /* ringbuffer.c */; }; 4B699C40097D421600A18468 /* JackDebugClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B98AE000931D30C0091932A /* JackDebugClient.cpp */; }; - 4B699C4E097D421600A18468 /* JackMachPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B799AD707899652003F3F15 /* JackMachPort.h */; }; 4B699C4F097D421600A18468 /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; }; 4B699C50097D421600A18468 /* JackTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1830834EE5800C94B91 /* JackTime.h */; }; 4B699C51097D421600A18468 /* JackShmMem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1870834EE7900C94B91 /* JackShmMem.h */; }; @@ -508,11 +481,7 @@ 4B699C71097D421600A18468 /* JackEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2130834F02800C94B91 /* JackEngine.h */; }; 4B699C73097D421600A18468 /* JackExternalClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1F70834EFBD00C94B91 /* JackExternalClient.h */; }; 4B699C74097D421600A18468 /* JackServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2220834F05C00C94B91 /* JackServer.h */; }; - 4B699C77097D421600A18468 /* JackMachNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB298908AF450200D450D4 /* JackMachNotifyChannel.h */; }; - 4B699C78097D421600A18468 /* JackMachServerChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB297808AF44ED00D450D4 /* JackMachServerChannel.h */; }; - 4B699C79097D421600A18468 /* JackMachServerNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB297A08AF44ED00D450D4 /* JackMachServerNotifyChannel.h */; }; 4B699C7B097D421600A18468 /* JackConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66A8580934964500A89560 /* JackConstants.h */; }; - 4B699C7E097D421600A18468 /* JackMachPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B799AD607899652003F3F15 /* JackMachPort.cpp */; }; 4B699C7F097D421600A18468 /* JackShmMem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1880834EE7900C94B91 /* JackShmMem.cpp */; }; 4B699C80097D421600A18468 /* shm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1900834EE8400C94B91 /* shm.c */; }; 4B699C82097D421600A18468 /* JackActivationCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1A80834EEB400C94B91 /* JackActivationCount.cpp */; }; @@ -534,12 +503,7 @@ 4B699C97097D421600A18468 /* JackEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2140834F02800C94B91 /* JackEngine.cpp */; }; 4B699C99097D421600A18468 /* JackExternalClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1F80834EFBD00C94B91 /* JackExternalClient.cpp */; }; 4B699C9A097D421600A18468 /* JackInternalClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1ED0834EF9200C94B91 /* JackInternalClient.cpp */; }; - 4B699C9B097D421600A18468 /* JackRPCClientUser.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B89B759076B731100D170DE /* JackRPCClientUser.c */; }; 4B699C9D097D421600A18468 /* JackServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2210834F05C00C94B91 /* JackServer.cpp */; }; - 4B699CA1097D421600A18468 /* JackMacEngineRPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4259E5076B635E00C1ECE1 /* JackMacEngineRPC.cpp */; }; - 4B699CA2097D421600A18468 /* JackMachNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB298808AF450200D450D4 /* JackMachNotifyChannel.cpp */; }; - 4B699CA3097D421600A18468 /* JackMachServerChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB297908AF44ED00D450D4 /* JackMachServerChannel.cpp */; }; - 4B699CA4097D421600A18468 /* JackMachServerNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB297708AF44ED00D450D4 /* JackMachServerNotifyChannel.cpp */; }; 4B699CB4097D421600A18468 /* metro.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D16B0834EDF000C94B91 /* metro.c */; }; 4B699CC4097D421600A18468 /* lsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1690834EDE600C94B91 /* lsp.c */; }; 4B699CF6097D421600A18468 /* freewheel.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1710834EE0F00C94B91 /* freewheel.c */; }; @@ -584,6 +548,18 @@ 4B88D04411298BEE007A87C1 /* weakmacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03A11298BEE007A87C1 /* weakmacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B88D04511298BEE007A87C1 /* weakjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03911298BEE007A87C1 /* weakjack.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B88D04611298BEE007A87C1 /* weakmacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B88D03A11298BEE007A87C1 /* weakmacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B8A38A7117B80D300664E07 /* JackSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6AD0E703B8D0066E42F /* JackSocket.cpp */; }; + 4B8A38A8117B80DA00664E07 /* JackSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6AE0E703B8D0066E42F /* JackSocket.h */; }; + 4B8A38AD117B810A00664E07 /* JackSocketNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B20E703B8D0066E42F /* JackSocketNotifyChannel.h */; }; + 4B8A38AE117B811100664E07 /* JackSocketNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B10E703B8D0066E42F /* JackSocketNotifyChannel.cpp */; }; + 4B8A38B0117B812500664E07 /* JackSocketServerChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B40E703B8D0066E42F /* JackSocketServerChannel.h */; }; + 4B8A38B1117B812D00664E07 /* JackSocketServerChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B30E703B8D0066E42F /* JackSocketServerChannel.cpp */; }; + 4B8A38B2117B813400664E07 /* JackSocketServerNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B50E703B8D0066E42F /* JackSocketServerNotifyChannel.cpp */; }; + 4B8A38C4117B814000664E07 /* JackSocketServerNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B60E703B8D0066E42F /* JackSocketServerNotifyChannel.h */; }; + 4B8A38F0117B827900664E07 /* JackSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6AE0E703B8D0066E42F /* JackSocket.h */; }; + 4B8A38F1117B827E00664E07 /* JackSocketClientChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6AF0E703B8D0066E42F /* JackSocketClientChannel.cpp */; }; + 4B8A38F6117B82AB00664E07 /* JackSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6AD0E703B8D0066E42F /* JackSocket.cpp */; }; + 4B8A38F7117B82B200664E07 /* JackSocketClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B00E703B8D0066E42F /* JackSocketClientChannel.h */; }; 4B93F1990E87992100E4ECCD /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; 4B93F19A0E87992200E4ECCD /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; 4B93F19C0E87998200E4ECCD /* JackPosixServerLaunch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBBA0E878B9C003D2374 /* JackPosixServerLaunch.cpp */; }; @@ -604,7 +580,6 @@ 4B9A26610DBF8ADD006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; 4B9A26640DBF8B14006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; 4B9A26790DBF8B88006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; - 4BA3393510B2E36800190E3B /* JackMachPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B799AD707899652003F3F15 /* JackMachPort.h */; }; 4BA3393610B2E36800190E3B /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; }; 4BA3393710B2E36800190E3B /* JackTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1830834EE5800C94B91 /* JackTime.h */; }; 4BA3393810B2E36800190E3B /* JackShmMem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1870834EE7900C94B91 /* JackShmMem.h */; }; @@ -633,9 +608,6 @@ 4BA3394F10B2E36800190E3B /* JackEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2130834F02800C94B91 /* JackEngine.h */; }; 4BA3395010B2E36800190E3B /* JackExternalClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1F70834EFBD00C94B91 /* JackExternalClient.h */; }; 4BA3395110B2E36800190E3B /* JackServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2220834F05C00C94B91 /* JackServer.h */; }; - 4BA3395210B2E36800190E3B /* JackMachNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB298908AF450200D450D4 /* JackMachNotifyChannel.h */; }; - 4BA3395310B2E36800190E3B /* JackMachServerChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB297808AF44ED00D450D4 /* JackMachServerChannel.h */; }; - 4BA3395410B2E36800190E3B /* JackMachServerNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB297A08AF44ED00D450D4 /* JackMachServerNotifyChannel.h */; }; 4BA3395510B2E36800190E3B /* JackConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66A8580934964500A89560 /* JackConstants.h */; }; 4BA3395610B2E36800190E3B /* JackTransportEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */; }; 4BA3395710B2E36800190E3B /* JackServerGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC2168D0A444BED00BDA09F /* JackServerGlobals.h */; }; @@ -663,7 +635,6 @@ 4BA3396D10B2E36800190E3B /* JackMidiDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF339200F8B873E0080FB5B /* JackMidiDriver.h */; }; 4BA3396E10B2E36800190E3B /* JackWaitThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BBC93B90DF9736C002DF220 /* JackWaitThreadedDriver.h */; }; 4BA3396F10B2E36800190E3B /* JackArgParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF284170F31B4BC00B05BE3 /* JackArgParser.h */; }; - 4BA3397210B2E36800190E3B /* JackMachPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B799AD607899652003F3F15 /* JackMachPort.cpp */; }; 4BA3397310B2E36800190E3B /* JackShmMem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1880834EE7900C94B91 /* JackShmMem.cpp */; }; 4BA3397410B2E36800190E3B /* shm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1900834EE8400C94B91 /* shm.c */; }; 4BA3397510B2E36800190E3B /* JackActivationCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1A80834EEB400C94B91 /* JackActivationCount.cpp */; }; @@ -685,12 +656,7 @@ 4BA3398510B2E36800190E3B /* JackEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2140834F02800C94B91 /* JackEngine.cpp */; }; 4BA3398610B2E36800190E3B /* JackExternalClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1F80834EFBD00C94B91 /* JackExternalClient.cpp */; }; 4BA3398710B2E36800190E3B /* JackInternalClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1ED0834EF9200C94B91 /* JackInternalClient.cpp */; }; - 4BA3398810B2E36800190E3B /* JackRPCClientUser.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B89B759076B731100D170DE /* JackRPCClientUser.c */; }; 4BA3398910B2E36800190E3B /* JackServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2210834F05C00C94B91 /* JackServer.cpp */; }; - 4BA3398A10B2E36800190E3B /* JackMacEngineRPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4259E5076B635E00C1ECE1 /* JackMacEngineRPC.cpp */; }; - 4BA3398B10B2E36800190E3B /* JackMachNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB298808AF450200D450D4 /* JackMachNotifyChannel.cpp */; }; - 4BA3398C10B2E36800190E3B /* JackMachServerChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB297908AF44ED00D450D4 /* JackMachServerChannel.cpp */; }; - 4BA3398D10B2E36800190E3B /* JackMachServerNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB297708AF44ED00D450D4 /* JackMachServerNotifyChannel.cpp */; }; 4BA3398E10B2E36800190E3B /* JackTransportEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */; }; 4BA3398F10B2E36800190E3B /* JackServerAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1F50834EFB000C94B91 /* JackServerAPI.cpp */; }; 4BA3399010B2E36800190E3B /* JackServerGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC216880A444BDE00BDA09F /* JackServerGlobals.cpp */; }; @@ -1146,6 +1112,13 @@ remoteGlobalIDString = 4B5A1BD00CD1CCE10005BF74; remoteInfo = jack_midisine; }; + 4B66550D127C356E00753A79 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B6654ED127C34AE00753A79; + remoteInfo = "jack_server_control 64 bits"; + }; 4B699DB3097D421700A18468 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; @@ -1497,7 +1470,6 @@ 4B37C20406DF1FBE0016E567 /* CALatencyLog.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CALatencyLog.h; path = /Developer/Examples/CoreAudio/PublicUtility/CALatencyLog.h; sourceTree = ""; }; 4B37C20906DF1FE20016E567 /* latency.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = latency.c; path = /Developer/Examples/CoreAudio/PublicUtility/latency.c; sourceTree = ""; }; 4B3F49070AD8503300491C6E /* cpu.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpu.c; path = ../tests/cpu.c; sourceTree = SOURCE_ROOT; }; - 4B4259E5076B635E00C1ECE1 /* JackMacEngineRPC.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMacEngineRPC.cpp; sourceTree = SOURCE_ROOT; }; 4B43A8BA10145F6F00E52943 /* jack_loopback.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_loopback.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B43A8C81014605000E52943 /* JackLoopbackDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackLoopbackDriver.cpp; path = ../common/JackLoopbackDriver.cpp; sourceTree = SOURCE_ROOT; }; 4B43A8C91014605000E52943 /* JackLoopbackDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackLoopbackDriver.h; path = ../common/JackLoopbackDriver.h; sourceTree = SOURCE_ROOT; }; @@ -1520,6 +1492,8 @@ 4B5E08E00E5B676C00BEE4E0 /* JackNetAdapter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackNetAdapter.h; path = ../common/JackNetAdapter.h; sourceTree = SOURCE_ROOT; }; 4B5F253D0DEE9B8F0041E486 /* JackLockedEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackLockedEngine.h; path = ../common/JackLockedEngine.h; sourceTree = SOURCE_ROOT; }; 4B60CE480AAABA31004956AA /* connect.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = connect.c; path = "../example-clients/connect.c"; sourceTree = SOURCE_ROOT; }; + 4B6654F7127C34AE00753A79 /* jack_server_control */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_server_control; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B6654FB127C350100753A79 /* server_control.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = server_control.cpp; path = "../example-clients/server_control.cpp"; sourceTree = SOURCE_ROOT; }; 4B66A8580934964500A89560 /* JackConstants.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackConstants.h; path = ../common/JackConstants.h; sourceTree = SOURCE_ROOT; }; 4B699BB1097D421600A18468 /* jackdmp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jackdmp; sourceTree = BUILT_PRODUCTS_DIR; }; 4B699C47097D421600A18468 /* Jackmp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackmp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1549,8 +1523,6 @@ 4B6F7AEC0CD0CDBD00F48A9D /* JackEngineControl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackEngineControl.cpp; path = ../common/JackEngineControl.cpp; sourceTree = SOURCE_ROOT; }; 4B76C7680E5AB2DB00E2AC21 /* JackNetInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetInterface.cpp; path = ../common/JackNetInterface.cpp; sourceTree = SOURCE_ROOT; }; 4B76C7690E5AB2DB00E2AC21 /* JackNetInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackNetInterface.h; path = ../common/JackNetInterface.h; sourceTree = SOURCE_ROOT; }; - 4B799AD607899652003F3F15 /* JackMachPort.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMachPort.cpp; sourceTree = ""; }; - 4B799AD707899652003F3F15 /* JackMachPort.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JackMachPort.h; sourceTree = ""; }; 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackMidiPort.h; path = ../common/JackMidiPort.h; sourceTree = SOURCE_ROOT; }; 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiPort.cpp; path = ../common/JackMidiPort.cpp; sourceTree = SOURCE_ROOT; }; 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiAPI.cpp; path = ../common/JackMidiAPI.cpp; sourceTree = SOURCE_ROOT; }; @@ -1559,8 +1531,6 @@ 4B869D7F08C9CB00001CF041 /* JackDriverLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackDriverLoader.cpp; path = ../common/JackDriverLoader.cpp; sourceTree = SOURCE_ROOT; }; 4B88D03911298BEE007A87C1 /* weakjack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = weakjack.h; path = ../common/jack/weakjack.h; sourceTree = SOURCE_ROOT; }; 4B88D03A11298BEE007A87C1 /* weakmacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = weakmacros.h; path = ../common/jack/weakmacros.h; sourceTree = SOURCE_ROOT; }; - 4B89B759076B731100D170DE /* JackRPCClientUser.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = JackRPCClientUser.c; path = RPC/JackRPCClientUser.c; sourceTree = SOURCE_ROOT; }; - 4B89B769076B74D200D170DE /* JackRPCEngineUser.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = JackRPCEngineUser.c; path = RPC/JackRPCEngineUser.c; sourceTree = SOURCE_ROOT; }; 4B940B9B06DDDE5B00D77F60 /* AudioHardware.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AudioHardware.h; path = /System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/AudioHardware.h; sourceTree = ""; }; 4B94334910A5E666002A187F /* systemdeps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = systemdeps.h; path = ../common/jack/systemdeps.h; sourceTree = SOURCE_ROOT; }; 4B95BCAD0D913073000F7695 /* control.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = control.h; path = ../common/jack/control.h; sourceTree = SOURCE_ROOT; }; @@ -1645,7 +1615,6 @@ 4BF339150F8B86DC0080FB5B /* JackCoreMidiDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreMidiDriver.cpp; path = coremidi/JackCoreMidiDriver.cpp; sourceTree = SOURCE_ROOT; }; 4BF3391F0F8B873E0080FB5B /* JackMidiDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiDriver.cpp; path = ../common/JackMidiDriver.cpp; sourceTree = SOURCE_ROOT; }; 4BF339200F8B873E0080FB5B /* JackMidiDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiDriver.h; path = ../common/JackMidiDriver.h; sourceTree = SOURCE_ROOT; }; - 4BF3937C0626BF3600CC67FA /* JackMacLibClientRPC.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMacLibClientRPC.cpp; sourceTree = SOURCE_ROOT; }; 4BF4BAB00E3480AB00403CDF /* JackAudioAdapterFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterFactory.cpp; path = ../common/JackAudioAdapterFactory.cpp; sourceTree = SOURCE_ROOT; }; 4BF520520CB8D0E80037470E /* timestamps.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = timestamps.c; path = ../common/timestamps.c; sourceTree = SOURCE_ROOT; }; 4BF520580CB8D1010037470E /* timestamps.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = timestamps.h; path = ../common/timestamps.h; sourceTree = SOURCE_ROOT; }; @@ -1718,14 +1687,6 @@ 4BFA82CF0DF6A9E40087B4E1 /* jack_impulse_grabber */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_impulse_grabber; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA99A20AAAF3B0009E916C /* jdelay */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jdelay; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA99A90AAAF40C009E916C /* jdelay.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = jdelay.cpp; path = ../tests/jdelay.cpp; sourceTree = SOURCE_ROOT; }; - 4BFB297708AF44ED00D450D4 /* JackMachServerNotifyChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMachServerNotifyChannel.cpp; sourceTree = ""; }; - 4BFB297808AF44ED00D450D4 /* JackMachServerChannel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JackMachServerChannel.h; sourceTree = ""; }; - 4BFB297908AF44ED00D450D4 /* JackMachServerChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMachServerChannel.cpp; sourceTree = ""; }; - 4BFB297A08AF44ED00D450D4 /* JackMachServerNotifyChannel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JackMachServerNotifyChannel.h; sourceTree = ""; }; - 4BFB298708AF450200D450D4 /* JackMachClientChannel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JackMachClientChannel.h; sourceTree = ""; }; - 4BFB298808AF450200D450D4 /* JackMachNotifyChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMachNotifyChannel.cpp; sourceTree = ""; }; - 4BFB298908AF450200D450D4 /* JackMachNotifyChannel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JackMachNotifyChannel.h; sourceTree = ""; }; - 4BFB29AE08AF45FD00D450D4 /* JackMachClientChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMachClientChannel.cpp; sourceTree = SOURCE_ROOT; }; 4BFB73F608AD291A00DB99B8 /* JackGlobals.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackGlobals.h; path = ../common/JackGlobals.h; sourceTree = SOURCE_ROOT; }; 4BFB741E08AD2B9900DB99B8 /* JackMachThread.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMachThread.cpp; sourceTree = SOURCE_ROOT; }; 4BFB741F08AD2B9900DB99B8 /* JackMachThread.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JackMachThread.h; sourceTree = SOURCE_ROOT; }; @@ -2072,6 +2033,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B6654F1127C34AE00753A79 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B699BAB097D421600A18468 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -2499,6 +2467,7 @@ 4B32257B10A3190C00838A8E /* jack_netsource */, 4BA339AC10B2E36800190E3B /* Jackservermp.framework */, 4B47ACD710B5890100469C67 /* Jackmp.framework */, + 4B6654F7127C34AE00753A79 /* jack_server_control */, ); name = Products; sourceTree = ""; @@ -2506,6 +2475,7 @@ 4B03383E0797E19900686131 /* Simple clients */ = { isa = PBXGroup; children = ( + 4B6654FB127C350100753A79 /* server_control.cpp */, 4B363F750DEB0D7D001F72D9 /* impulse_grabber.c */, 4B363F220DEB0AB0001F72D9 /* monitor_client.c */, 4B363EED0DEB094B001F72D9 /* capture_client.c */, @@ -2627,24 +2597,6 @@ name = Additional; sourceTree = ""; }; - 4B168CA3076A5319005B2802 /* MIG_RPC */ = { - isa = PBXGroup; - children = ( - 4B89B759076B731100D170DE /* JackRPCClientUser.c */, - 4B4259E5076B635E00C1ECE1 /* JackMacEngineRPC.cpp */, - ); - name = MIG_RPC; - sourceTree = ""; - }; - 4B168CA4076A5333005B2802 /* MIG_RPC */ = { - isa = PBXGroup; - children = ( - 4B89B769076B74D200D170DE /* JackRPCEngineUser.c */, - 4BF3937C0626BF3600CC67FA /* JackMacLibClientRPC.cpp */, - ); - name = MIG_RPC; - sourceTree = ""; - }; 4B19B3010E23629800DD4A82 /* Adapter */ = { isa = PBXGroup; children = ( @@ -2818,7 +2770,6 @@ 4BA550F905E241D900569492 /* Library */ = { isa = PBXGroup; children = ( - 4B168CA4076A5333005B2802 /* MIG_RPC */, 4BF8D1FB0834EFD100C94B91 /* JackLibGlobals.h */, 4BF8D1FC0834EFD100C94B91 /* JackLibClient.h */, 4BF8D1FD0834EFD100C94B91 /* JackLibClient.cpp */, @@ -2844,7 +2795,6 @@ 4BA550FB05E2420000569492 /* Engine */ = { isa = PBXGroup; children = ( - 4B168CA3076A5319005B2802 /* MIG_RPC */, 4B5F253D0DEE9B8F0041E486 /* JackLockedEngine.h */, 4BF8D2130834F02800C94B91 /* JackEngine.h */, 4BF8D2140834F02800C94B91 /* JackEngine.cpp */, @@ -2872,7 +2822,6 @@ 4BB371D40C1AD85A0050C1E4 /* JackNotification.h */, 4BF8D1B30834EED500C94B91 /* JackInternalClientChannel.h */, 4BFB299908AF452300D450D4 /* Socket */, - 4BFB299808AF451200D450D4 /* Mach */, ); name = Channels; sourceTree = ""; @@ -2963,23 +2912,6 @@ name = MIDI; sourceTree = ""; }; - 4BFB299808AF451200D450D4 /* Mach */ = { - isa = PBXGroup; - children = ( - 4B799AD707899652003F3F15 /* JackMachPort.h */, - 4B799AD607899652003F3F15 /* JackMachPort.cpp */, - 4BFB298708AF450200D450D4 /* JackMachClientChannel.h */, - 4BFB29AE08AF45FD00D450D4 /* JackMachClientChannel.cpp */, - 4BFB297808AF44ED00D450D4 /* JackMachServerChannel.h */, - 4BFB297908AF44ED00D450D4 /* JackMachServerChannel.cpp */, - 4BFB297A08AF44ED00D450D4 /* JackMachServerNotifyChannel.h */, - 4BFB297708AF44ED00D450D4 /* JackMachServerNotifyChannel.cpp */, - 4BFB298908AF450200D450D4 /* JackMachNotifyChannel.h */, - 4BFB298808AF450200D450D4 /* JackMachNotifyChannel.cpp */, - ); - name = Mach; - sourceTree = ""; - }; 4BFB299908AF452300D450D4 /* Socket */ = { isa = PBXGroup; children = ( @@ -3110,7 +3042,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 4B35C4290D4731D1000DE7AE /* JackMachPort.h in Headers */, 4B35C42A0D4731D1000DE7AE /* JackError.h in Headers */, 4B35C42B0D4731D1000DE7AE /* JackTime.h in Headers */, 4B35C42C0D4731D1000DE7AE /* JackShmMem.h in Headers */, @@ -3131,7 +3062,6 @@ 4B35C43D0D4731D1000DE7AE /* JackMachSemaphore.h in Headers */, 4B35C43E0D4731D1000DE7AE /* JackGlobals.h in Headers */, 4B35C43F0D4731D1000DE7AE /* JackMachThread.h in Headers */, - 4B35C4400D4731D1000DE7AE /* JackMachClientChannel.h in Headers */, 4B35C4460D4731D1000DE7AE /* JackSynchro.h in Headers */, 4B35C4470D4731D1000DE7AE /* JackDebugClient.h in Headers */, 4B35C4480D4731D1000DE7AE /* JackConstants.h in Headers */, @@ -3154,6 +3084,8 @@ 4BECB2FA0F4451C10091B70A /* JackProcessSync.h in Headers */, 4B88D03F11298BEE007A87C1 /* weakjack.h in Headers */, 4B88D04011298BEE007A87C1 /* weakmacros.h in Headers */, + 4B8A38F0117B827900664E07 /* JackSocket.h in Headers */, + 4B8A38F7117B82B200664E07 /* JackSocketClientChannel.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3161,7 +3093,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 4B35C4870D4731D1000DE7AE /* JackMachPort.h in Headers */, 4B35C4880D4731D1000DE7AE /* JackError.h in Headers */, 4B35C4890D4731D1000DE7AE /* JackTime.h in Headers */, 4B35C48A0D4731D1000DE7AE /* JackShmMem.h in Headers */, @@ -3190,9 +3121,6 @@ 4B35C4A90D4731D1000DE7AE /* JackEngine.h in Headers */, 4B35C4AA0D4731D1000DE7AE /* JackExternalClient.h in Headers */, 4B35C4AB0D4731D1000DE7AE /* JackServer.h in Headers */, - 4B35C4AE0D4731D1000DE7AE /* JackMachNotifyChannel.h in Headers */, - 4B35C4AF0D4731D1000DE7AE /* JackMachServerChannel.h in Headers */, - 4B35C4B00D4731D1000DE7AE /* JackMachServerNotifyChannel.h in Headers */, 4B35C4B20D4731D1000DE7AE /* JackConstants.h in Headers */, 4B35C4B30D4731D1000DE7AE /* JackTransportEngine.h in Headers */, 4B35C4B40D4731D1000DE7AE /* JackServerGlobals.h in Headers */, @@ -3226,6 +3154,10 @@ 4B88D04411298BEE007A87C1 /* weakmacros.h in Headers */, 4BC2CA5A113C6CB80076717C /* JackNetInterface.h in Headers */, 4BC2CA5C113C6CC00076717C /* JackNetUnixSocket.h in Headers */, + 4B8A38A8117B80DA00664E07 /* JackSocket.h in Headers */, + 4B8A38AD117B810A00664E07 /* JackSocketNotifyChannel.h in Headers */, + 4B8A38B0117B812500664E07 /* JackSocketServerChannel.h in Headers */, + 4B8A38C4117B814000664E07 /* JackSocketServerNotifyChannel.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3464,7 +3396,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 4B47AC8210B5890100469C67 /* JackMachPort.h in Headers */, 4B47AC8310B5890100469C67 /* JackError.h in Headers */, 4B47AC8410B5890100469C67 /* JackTime.h in Headers */, 4B47AC8510B5890100469C67 /* JackShmMem.h in Headers */, @@ -3485,7 +3416,6 @@ 4B47AC9410B5890100469C67 /* JackMachSemaphore.h in Headers */, 4B47AC9510B5890100469C67 /* JackGlobals.h in Headers */, 4B47AC9610B5890100469C67 /* JackMachThread.h in Headers */, - 4B47AC9710B5890100469C67 /* JackMachClientChannel.h in Headers */, 4B47AC9810B5890100469C67 /* JackSynchro.h in Headers */, 4B47AC9910B5890100469C67 /* JackDebugClient.h in Headers */, 4B47AC9A10B5890100469C67 /* JackConstants.h in Headers */, @@ -3536,6 +3466,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B6654EE127C34AE00753A79 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B699BA8097D421600A18468 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -3547,7 +3484,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 4B699C02097D421600A18468 /* JackMachPort.h in Headers */, 4B699C03097D421600A18468 /* JackError.h in Headers */, 4B699C04097D421600A18468 /* JackTime.h in Headers */, 4B699C05097D421600A18468 /* JackShmMem.h in Headers */, @@ -3568,7 +3504,6 @@ 4B699C16097D421600A18468 /* JackMachSemaphore.h in Headers */, 4B699C17097D421600A18468 /* JackGlobals.h in Headers */, 4B699C18097D421600A18468 /* JackMachThread.h in Headers */, - 4B699C19097D421600A18468 /* JackMachClientChannel.h in Headers */, 4B699C20097D421600A18468 /* JackSynchro.h in Headers */, 4B699C21097D421600A18468 /* JackDebugClient.h in Headers */, 4B699C22097D421600A18468 /* JackConstants.h in Headers */, @@ -3599,7 +3534,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 4B699C4E097D421600A18468 /* JackMachPort.h in Headers */, 4B699C4F097D421600A18468 /* JackError.h in Headers */, 4B699C50097D421600A18468 /* JackTime.h in Headers */, 4B699C51097D421600A18468 /* JackShmMem.h in Headers */, @@ -3628,9 +3562,6 @@ 4B699C71097D421600A18468 /* JackEngine.h in Headers */, 4B699C73097D421600A18468 /* JackExternalClient.h in Headers */, 4B699C74097D421600A18468 /* JackServer.h in Headers */, - 4B699C77097D421600A18468 /* JackMachNotifyChannel.h in Headers */, - 4B699C78097D421600A18468 /* JackMachServerChannel.h in Headers */, - 4B699C79097D421600A18468 /* JackMachServerNotifyChannel.h in Headers */, 4B699C7B097D421600A18468 /* JackConstants.h in Headers */, 4BD4B4D809BACD9600750C0F /* JackTransportEngine.h in Headers */, 4BC2168E0A444BED00BDA09F /* JackServerGlobals.h in Headers */, @@ -3784,7 +3715,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 4BA3393510B2E36800190E3B /* JackMachPort.h in Headers */, 4BA3393610B2E36800190E3B /* JackError.h in Headers */, 4BA3393710B2E36800190E3B /* JackTime.h in Headers */, 4BA3393810B2E36800190E3B /* JackShmMem.h in Headers */, @@ -3813,9 +3743,6 @@ 4BA3394F10B2E36800190E3B /* JackEngine.h in Headers */, 4BA3395010B2E36800190E3B /* JackExternalClient.h in Headers */, 4BA3395110B2E36800190E3B /* JackServer.h in Headers */, - 4BA3395210B2E36800190E3B /* JackMachNotifyChannel.h in Headers */, - 4BA3395310B2E36800190E3B /* JackMachServerChannel.h in Headers */, - 4BA3395410B2E36800190E3B /* JackMachServerNotifyChannel.h in Headers */, 4BA3395510B2E36800190E3B /* JackConstants.h in Headers */, 4BA3395610B2E36800190E3B /* JackTransportEngine.h in Headers */, 4BA3395710B2E36800190E3B /* JackServerGlobals.h in Headers */, @@ -4878,6 +4805,25 @@ productReference = 4B5E08D50E5B66EE00BEE4E0 /* netadapter.so */; productType = "com.apple.product-type.library.dynamic"; }; + 4B6654ED127C34AE00753A79 /* jack_server_control 64 bits */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B6654F3127C34AE00753A79 /* Build configuration list for PBXNativeTarget "jack_server_control 64 bits" */; + buildPhases = ( + 4B6654EE127C34AE00753A79 /* Headers */, + 4B6654EF127C34AE00753A79 /* Sources */, + 4B6654F1127C34AE00753A79 /* Frameworks */, + 4B6654F2127C34AE00753A79 /* Rez */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "jack_server_control 64 bits"; + productInstallPath = /usr/local/bin; + productName = testSem; + productReference = 4B6654F7127C34AE00753A79 /* jack_server_control */; + productType = "com.apple.product-type.tool"; + }; 4B699BA7097D421600A18468 /* jackdmp framework Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B699BAD097D421600A18468 /* Build configuration list for PBXNativeTarget "jackdmp framework Universal" */; @@ -5642,7 +5588,14 @@ isa = PBXProject; buildConfigurationList = 4B699DD5097D427F00A18468 /* Build configuration list for PBXProject "Jackdmp" */; compatibilityVersion = "Xcode 2.4"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 08FB7794FE84155DC02AAC07 /* JackServer */; projectDirPath = ""; projectRoot = ""; @@ -5722,6 +5675,7 @@ 4BFA82B90DF6A9E40087B4E1 /* jack_showtime 64 bits */, 4BFA82C50DF6A9E40087B4E1 /* jack_impulse_grabber 64 bits */, 4B32257110A3190C00838A8E /* jack_netsource 64 bits */, + 4B6654ED127C34AE00753A79 /* jack_server_control 64 bits */, 4B35C5D80D4731D2000DE7AE /* synchroServer 64 bits */, 4B35C5EC0D4731D2000DE7AE /* synchroClient 64 bits */, 4B35C6000D4731D2000DE7AE /* synchroServerClient 64 bits */, @@ -6038,6 +5992,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B6654F2127C34AE00753A79 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B699BAC097D421600A18468 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; @@ -6325,9 +6286,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4B35C4580D4731D1000DE7AE /* JackMacLibClientRPC.cpp in Sources */, - 4B35C4590D4731D1000DE7AE /* JackRPCEngineUser.c in Sources */, - 4B35C45A0D4731D1000DE7AE /* JackMachPort.cpp in Sources */, 4B35C45B0D4731D1000DE7AE /* JackShmMem.cpp in Sources */, 4B35C45C0D4731D1000DE7AE /* shm.c in Sources */, 4B35C45E0D4731D1000DE7AE /* JackActivationCount.cpp in Sources */, @@ -6341,7 +6299,6 @@ 4B35C4660D4731D1000DE7AE /* JackFrameTimer.cpp in Sources */, 4B35C4680D4731D1000DE7AE /* JackMachSemaphore.cpp in Sources */, 4B35C4690D4731D1000DE7AE /* JackMachThread.cpp in Sources */, - 4B35C46A0D4731D1000DE7AE /* JackMachClientChannel.cpp in Sources */, 4B35C4700D4731D1000DE7AE /* JackGlobals.cpp in Sources */, 4B35C4720D4731D1000DE7AE /* ringbuffer.c in Sources */, 4B35C4730D4731D1000DE7AE /* JackDebugClient.cpp in Sources */, @@ -6359,6 +6316,8 @@ 4B93F19D0E87998400E4ECCD /* JackPosixThread.cpp in Sources */, 4B93F1C00E87A35400E4ECCD /* JackMachTime.c in Sources */, 4BECB2F90F4451C10091B70A /* JackProcessSync.cpp in Sources */, + 4B8A38F1117B827E00664E07 /* JackSocketClientChannel.cpp in Sources */, + 4B8A38F6117B82AB00664E07 /* JackSocket.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6366,7 +6325,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4B35C4C40D4731D1000DE7AE /* JackMachPort.cpp in Sources */, 4B35C4C50D4731D1000DE7AE /* JackShmMem.cpp in Sources */, 4B35C4C60D4731D1000DE7AE /* shm.c in Sources */, 4B35C4C80D4731D1000DE7AE /* JackActivationCount.cpp in Sources */, @@ -6388,12 +6346,7 @@ 4B35C4DD0D4731D1000DE7AE /* JackEngine.cpp in Sources */, 4B35C4DE0D4731D1000DE7AE /* JackExternalClient.cpp in Sources */, 4B35C4DF0D4731D1000DE7AE /* JackInternalClient.cpp in Sources */, - 4B35C4E00D4731D1000DE7AE /* JackRPCClientUser.c in Sources */, 4B35C4E20D4731D1000DE7AE /* JackServer.cpp in Sources */, - 4B35C4E60D4731D1000DE7AE /* JackMacEngineRPC.cpp in Sources */, - 4B35C4E70D4731D1000DE7AE /* JackMachNotifyChannel.cpp in Sources */, - 4B35C4E80D4731D1000DE7AE /* JackMachServerChannel.cpp in Sources */, - 4B35C4E90D4731D1000DE7AE /* JackMachServerNotifyChannel.cpp in Sources */, 4B35C4EB0D4731D1000DE7AE /* JackTransportEngine.cpp in Sources */, 4B35C4EC0D4731D1000DE7AE /* JackServerAPI.cpp in Sources */, 4B35C4ED0D4731D1000DE7AE /* JackServerGlobals.cpp in Sources */, @@ -6421,6 +6374,10 @@ 4BCBCE6310C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */, 4BC2CA59113C6CB60076717C /* JackNetInterface.cpp in Sources */, 4BC2CA5B113C6CBE0076717C /* JackNetUnixSocket.cpp in Sources */, + 4B8A38A7117B80D300664E07 /* JackSocket.cpp in Sources */, + 4B8A38AE117B811100664E07 /* JackSocketNotifyChannel.cpp in Sources */, + 4B8A38B1117B812D00664E07 /* JackSocketServerChannel.cpp in Sources */, + 4B8A38B2117B813400664E07 /* JackSocketServerNotifyChannel.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6686,9 +6643,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4B47ACAE10B5890100469C67 /* JackMacLibClientRPC.cpp in Sources */, - 4B47ACAF10B5890100469C67 /* JackRPCEngineUser.c in Sources */, - 4B47ACB010B5890100469C67 /* JackMachPort.cpp in Sources */, 4B47ACB110B5890100469C67 /* JackShmMem.cpp in Sources */, 4B47ACB210B5890100469C67 /* shm.c in Sources */, 4B47ACB310B5890100469C67 /* JackActivationCount.cpp in Sources */, @@ -6702,7 +6656,6 @@ 4B47ACBB10B5890100469C67 /* JackFrameTimer.cpp in Sources */, 4B47ACBC10B5890100469C67 /* JackMachSemaphore.cpp in Sources */, 4B47ACBD10B5890100469C67 /* JackMachThread.cpp in Sources */, - 4B47ACBE10B5890100469C67 /* JackMachClientChannel.cpp in Sources */, 4B47ACBF10B5890100469C67 /* JackGlobals.cpp in Sources */, 4B47ACC010B5890100469C67 /* ringbuffer.c in Sources */, 4B47ACC110B5890100469C67 /* JackDebugClient.cpp in Sources */, @@ -6751,6 +6704,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B6654EF127C34AE00753A79 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B6654FC127C350100753A79 /* server_control.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B699BA9097D421600A18468 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -6763,9 +6724,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4B699C25097D421600A18468 /* JackMacLibClientRPC.cpp in Sources */, - 4B699C26097D421600A18468 /* JackRPCEngineUser.c in Sources */, - 4B699C27097D421600A18468 /* JackMachPort.cpp in Sources */, 4B699C28097D421600A18468 /* JackShmMem.cpp in Sources */, 4B699C29097D421600A18468 /* shm.c in Sources */, 4B699C2B097D421600A18468 /* JackActivationCount.cpp in Sources */, @@ -6779,7 +6737,6 @@ 4B699C33097D421600A18468 /* JackFrameTimer.cpp in Sources */, 4B699C35097D421600A18468 /* JackMachSemaphore.cpp in Sources */, 4B699C36097D421600A18468 /* JackMachThread.cpp in Sources */, - 4B699C37097D421600A18468 /* JackMachClientChannel.cpp in Sources */, 4B699C3D097D421600A18468 /* JackGlobals.cpp in Sources */, 4B699C3F097D421600A18468 /* ringbuffer.c in Sources */, 4B699C40097D421600A18468 /* JackDebugClient.cpp in Sources */, @@ -6804,7 +6761,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4B699C7E097D421600A18468 /* JackMachPort.cpp in Sources */, 4B699C7F097D421600A18468 /* JackShmMem.cpp in Sources */, 4B699C80097D421600A18468 /* shm.c in Sources */, 4B699C82097D421600A18468 /* JackActivationCount.cpp in Sources */, @@ -6826,12 +6782,7 @@ 4B699C97097D421600A18468 /* JackEngine.cpp in Sources */, 4B699C99097D421600A18468 /* JackExternalClient.cpp in Sources */, 4B699C9A097D421600A18468 /* JackInternalClient.cpp in Sources */, - 4B699C9B097D421600A18468 /* JackRPCClientUser.c in Sources */, 4B699C9D097D421600A18468 /* JackServer.cpp in Sources */, - 4B699CA1097D421600A18468 /* JackMacEngineRPC.cpp in Sources */, - 4B699CA2097D421600A18468 /* JackMachNotifyChannel.cpp in Sources */, - 4B699CA3097D421600A18468 /* JackMachServerChannel.cpp in Sources */, - 4B699CA4097D421600A18468 /* JackMachServerNotifyChannel.cpp in Sources */, 4BD4B4D909BACD9600750C0F /* JackTransportEngine.cpp in Sources */, 4BC216850A444BAD00BDA09F /* JackServerAPI.cpp in Sources */, 4BC216890A444BDE00BDA09F /* JackServerGlobals.cpp in Sources */, @@ -6986,7 +6937,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4BA3397210B2E36800190E3B /* JackMachPort.cpp in Sources */, 4BA3397310B2E36800190E3B /* JackShmMem.cpp in Sources */, 4BA3397410B2E36800190E3B /* shm.c in Sources */, 4BA3397510B2E36800190E3B /* JackActivationCount.cpp in Sources */, @@ -7008,12 +6958,7 @@ 4BA3398510B2E36800190E3B /* JackEngine.cpp in Sources */, 4BA3398610B2E36800190E3B /* JackExternalClient.cpp in Sources */, 4BA3398710B2E36800190E3B /* JackInternalClient.cpp in Sources */, - 4BA3398810B2E36800190E3B /* JackRPCClientUser.c in Sources */, 4BA3398910B2E36800190E3B /* JackServer.cpp in Sources */, - 4BA3398A10B2E36800190E3B /* JackMacEngineRPC.cpp in Sources */, - 4BA3398B10B2E36800190E3B /* JackMachNotifyChannel.cpp in Sources */, - 4BA3398C10B2E36800190E3B /* JackMachServerChannel.cpp in Sources */, - 4BA3398D10B2E36800190E3B /* JackMachServerNotifyChannel.cpp in Sources */, 4BA3398E10B2E36800190E3B /* JackTransportEngine.cpp in Sources */, 4BA3398F10B2E36800190E3B /* JackServerAPI.cpp in Sources */, 4BA3399010B2E36800190E3B /* JackServerGlobals.cpp in Sources */, @@ -7432,6 +7377,11 @@ target = 4B5A1BD00CD1CCE10005BF74 /* jack_midisine Universal */; targetProxy = 4B5A1BE10CD1CD730005BF74 /* PBXContainerItemProxy */; }; + 4B66550E127C356E00753A79 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4B6654ED127C34AE00753A79 /* jack_server_control 64 bits */; + targetProxy = 4B66550D127C356E00753A79 /* PBXContainerItemProxy */; + }; 4B699DB4097D421700A18468 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B699C4C097D421600A18468 /* Jackservermp.framework Universal */; @@ -8149,6 +8099,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = "-DJACK_32_64"; OTHER_CPLUSPLUSFLAGS = ( + "-DSERVER_SIDE", "-DHAVE_CELT", "-DHAVE_CELT_API_0_7", "-DMACH_RPC_MACH_SEMA", @@ -10909,6 +10860,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = "-DJACK_32_64"; OTHER_CPLUSPLUSFLAGS = ( + "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", "-DJACK_32_64", ); @@ -11206,6 +11158,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = "-DJACK_32_64"; OTHER_CPLUSPLUSFLAGS = ( + "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", "-DJACK_32_64", ); @@ -12370,6 +12323,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = "-DJACK_32_64"; OTHER_CPLUSPLUSFLAGS = ( + "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", "-DJACK_32_64", ); @@ -12967,6 +12921,94 @@ }; name = Default; }; + 4B6654F4127C34AE00753A79 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackservermp, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_test; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4B6654F5127C34AE00753A79 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 3; + HEADER_SEARCH_PATHS = ../common; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackservermp, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_server_control; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B6654F6127C34AE00753A79 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc64, + ppc, + i386, + x86_64, + ); + GCC_OPTIMIZATION_LEVEL = 3; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_test; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; 4B699B34097D421600A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { @@ -15959,6 +16001,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = "-DJACK_32_64"; OTHER_CPLUSPLUSFLAGS = ( + "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", "-DJACK_32_64", ); @@ -16103,6 +16146,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = "-DJACK_32_64"; OTHER_CPLUSPLUSFLAGS = ( + "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", "-DJACK_32_64", ); @@ -16243,7 +16287,10 @@ MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = "-DJACK_32_64"; - OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_CPLUSPLUSFLAGS = ( + "-DSERVER_SIDE", + "$(OTHER_CFLAGS)", + ); OTHER_LDFLAGS = ( "-framework", Jackservermp, @@ -16386,7 +16433,10 @@ MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = "-DJACK_32_64"; - OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_CPLUSPLUSFLAGS = ( + "-DSERVER_SIDE", + "$(OTHER_CFLAGS)", + ); OTHER_LDFLAGS = ( /opt/local/lib/libsamplerate.a, "-framework", @@ -16531,6 +16581,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = "-DJACK_32_64"; OTHER_CPLUSPLUSFLAGS = ( + "-DSERVER_SIDE", "-DMACH_RPC_MACH_SEMA", "-DJACK_32_64", ); @@ -18468,6 +18519,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; + 4B6654F3127C34AE00753A79 /* Build configuration list for PBXNativeTarget "jack_server_control 64 bits" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B6654F4127C34AE00753A79 /* Development */, + 4B6654F5127C34AE00753A79 /* Deployment */, + 4B6654F6127C34AE00753A79 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; 4B699B33097D421600A18468 /* Build configuration list for PBXAggregateTarget "All Universal 32 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/macosx/RPC/JackRPCClient.defs b/macosx/RPC/JackRPCClient.defs deleted file mode 100644 index 3c3eb515..00000000 --- a/macosx/RPC/JackRPCClient.defs +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (C) 2004 Grame - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 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 - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -subsystem JackRPCClient 1000; - -#include -#include -import "Jackdefs.h"; -waittime 5000; - -type client_name_t = c_string[64]; -type message_t = c_string[256]; - -routine rpc_jack_client_sync_notify( - client_port : mach_port_t; - refnum : int; - client_name : client_name_t; - notify : int; - message : message_t; - value1 : int; - value2 : int; - out result : int); - -simpleroutine rpc_jack_client_async_notify( - client_port : mach_port_t; - refnum : int; - client_name : client_name_t; - notify : int; - message : message_t; - value1 : int; - value2 : int); diff --git a/macosx/RPC/JackRPCClient.h b/macosx/RPC/JackRPCClient.h deleted file mode 100644 index d4462479..00000000 --- a/macosx/RPC/JackRPCClient.h +++ /dev/null @@ -1,194 +0,0 @@ -#ifndef _JackRPCClient_user_ -#define _JackRPCClient_user_ - -/* Module JackRPCClient */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef AUTOTEST -#ifndef FUNCTION_PTR_T -#define FUNCTION_PTR_T -typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); -typedef struct { - char *name; - function_ptr_t function; -} function_table_entry; -typedef function_table_entry *function_table_t; -#endif /* FUNCTION_PTR_T */ -#endif /* AUTOTEST */ - -#ifndef JackRPCClient_MSG_COUNT -#define JackRPCClient_MSG_COUNT 2 -#endif /* JackRPCClient_MSG_COUNT */ - -#include -#include -#include -#include -#include "Jackdefs.h" - -#ifdef __BeforeMigUserHeader -__BeforeMigUserHeader -#endif /* __BeforeMigUserHeader */ - -#include -__BEGIN_DECLS - - -/* Routine rpc_jack_client_sync_notify */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_client_sync_notify -( - mach_port_t client_port, - int refnum, - client_name_t client_name, - int notify, - message_t message, - int value1, - int value2, - int *result -); - -/* SimpleRoutine rpc_jack_client_async_notify */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_client_async_notify -( - mach_port_t client_port, - int refnum, - client_name_t client_name, - int notify, - message_t message, - int value1, - int value2 -); - -__END_DECLS - -/********************** Caution **************************/ -/* The following data types should be used to calculate */ -/* maximum message sizes only. The actual message may be */ -/* smaller, and the position of the arguments within the */ -/* message layout may vary from what is presented here. */ -/* For example, if any of the arguments are variable- */ -/* sized, and less than the maximum is sent, the data */ -/* will be packed tight in the actual message to reduce */ -/* the presence of holes. */ -/********************** Caution **************************/ - -/* typedefs for all requests */ - -#ifndef __Request__JackRPCClient_subsystem__defined -#define __Request__JackRPCClient_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_name_t client_name; - int notify; - message_t message; - int value1; - int value2; - } __Request__rpc_jack_client_sync_notify_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_name_t client_name; - int notify; - message_t message; - int value1; - int value2; - } __Request__rpc_jack_client_async_notify_t; -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Request__JackRPCClient_subsystem__defined */ - -/* union of all requests */ - -#ifndef __RequestUnion__JackRPCClient_subsystem__defined -#define __RequestUnion__JackRPCClient_subsystem__defined -union __RequestUnion__JackRPCClient_subsystem { - __Request__rpc_jack_client_sync_notify_t Request_rpc_jack_client_sync_notify; - __Request__rpc_jack_client_async_notify_t Request_rpc_jack_client_async_notify; -}; -#endif /* !__RequestUnion__JackRPCClient_subsystem__defined */ -/* typedefs for all replies */ - -#ifndef __Reply__JackRPCClient_subsystem__defined -#define __Reply__JackRPCClient_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_client_sync_notify_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - } __Reply__rpc_jack_client_async_notify_t; -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Reply__JackRPCClient_subsystem__defined */ - -/* union of all replies */ - -#ifndef __ReplyUnion__JackRPCClient_subsystem__defined -#define __ReplyUnion__JackRPCClient_subsystem__defined -union __ReplyUnion__JackRPCClient_subsystem { - __Reply__rpc_jack_client_sync_notify_t Reply_rpc_jack_client_sync_notify; - __Reply__rpc_jack_client_async_notify_t Reply_rpc_jack_client_async_notify; -}; -#endif /* !__RequestUnion__JackRPCClient_subsystem__defined */ - -#ifndef subsystem_to_name_map_JackRPCClient -#define subsystem_to_name_map_JackRPCClient \ - { "rpc_jack_client_sync_notify", 1000 },\ - { "rpc_jack_client_async_notify", 1001 } -#endif - -#ifdef __AfterMigUserHeader -__AfterMigUserHeader -#endif /* __AfterMigUserHeader */ - -#endif /* _JackRPCClient_user_ */ diff --git a/macosx/RPC/JackRPCClientServer.c b/macosx/RPC/JackRPCClientServer.c deleted file mode 100644 index 7f5af274..00000000 --- a/macosx/RPC/JackRPCClientServer.c +++ /dev/null @@ -1,1373 +0,0 @@ -/* - * IDENTIFICATION: - * stub generated Fri Oct 23 10:35:08 2009 - * with a MiG generated Mon May 18 09:59:33 PDT 2009 by root@sulitlana.apple.com - * OPTIONS: - */ - -/* Module JackRPCClient */ - -#define __MIG_check__Request__JackRPCClient_subsystem__ 1 -#define __NDR_convert__Request__JackRPCClient_subsystem__ 1 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "Jackdefs.h" - -#ifndef mig_internal -#define mig_internal static __inline__ -#endif /* mig_internal */ - -#ifndef mig_external -#define mig_external -#endif /* mig_external */ - -#if !defined(__MigTypeCheck) && defined(TypeCheck) -#define __MigTypeCheck TypeCheck /* Legacy setting */ -#endif /* !defined(__MigTypeCheck) */ - -#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) -#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ -#endif /* !defined(__MigKernelSpecificCode) */ - -#ifndef LimitCheck -#define LimitCheck 0 -#endif /* LimitCheck */ - -#ifndef min -#define min(a,b) ( ((a) < (b))? (a): (b) ) -#endif /* min */ - -#if !defined(_WALIGN_) -#define _WALIGN_(x) (((x) + 3) & ~3) -#endif /* !defined(_WALIGN_) */ - -#if !defined(_WALIGNSZ_) -#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) -#endif /* !defined(_WALIGNSZ_) */ - -#ifndef UseStaticTemplates -#define UseStaticTemplates 0 -#endif /* UseStaticTemplates */ - -#ifndef __DeclareRcvRpc -#define __DeclareRcvRpc(_NUM_, _NAME_) -#endif /* __DeclareRcvRpc */ - -#ifndef __BeforeRcvRpc -#define __BeforeRcvRpc(_NUM_, _NAME_) -#endif /* __BeforeRcvRpc */ - -#ifndef __AfterRcvRpc -#define __AfterRcvRpc(_NUM_, _NAME_) -#endif /* __AfterRcvRpc */ - -#ifndef __DeclareRcvSimple -#define __DeclareRcvSimple(_NUM_, _NAME_) -#endif /* __DeclareRcvSimple */ - -#ifndef __BeforeRcvSimple -#define __BeforeRcvSimple(_NUM_, _NAME_) -#endif /* __BeforeRcvSimple */ - -#ifndef __AfterRcvSimple -#define __AfterRcvSimple(_NUM_, _NAME_) -#endif /* __AfterRcvSimple */ - -#define novalue void - -#define msgh_request_port msgh_local_port -#define MACH_MSGH_BITS_REQUEST(bits) MACH_MSGH_BITS_LOCAL(bits) -#define msgh_reply_port msgh_remote_port -#define MACH_MSGH_BITS_REPLY(bits) MACH_MSGH_BITS_REMOTE(bits) - -#define MIG_RETURN_ERROR(X, code) {\ - ((mig_reply_error_t *)X)->RetCode = code;\ - ((mig_reply_error_t *)X)->NDR = NDR_record;\ - return;\ - } - -/* typedefs for all requests */ - -#ifndef __Request__JackRPCClient_subsystem__defined -#define __Request__JackRPCClient_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_name_t client_name; - int notify; - message_t message; - int value1; - int value2; - } __Request__rpc_jack_client_sync_notify_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_name_t client_name; - int notify; - message_t message; - int value1; - int value2; - } __Request__rpc_jack_client_async_notify_t; -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Request__JackRPCClient_subsystem__defined */ - -/* typedefs for all replies */ - -#ifndef __Reply__JackRPCClient_subsystem__defined -#define __Reply__JackRPCClient_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_client_sync_notify_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - } __Reply__rpc_jack_client_async_notify_t; -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Reply__JackRPCClient_subsystem__defined */ - - -/* union of all replies */ - -#ifndef __ReplyUnion__JackRPCClient_subsystem__defined -#define __ReplyUnion__JackRPCClient_subsystem__defined -union __ReplyUnion__JackRPCClient_subsystem { - __Reply__rpc_jack_client_sync_notify_t Reply_rpc_jack_client_sync_notify; - __Reply__rpc_jack_client_async_notify_t Reply_rpc_jack_client_async_notify; -}; -#endif /* __RequestUnion__JackRPCClient_subsystem__defined */ -/* Forward Declarations */ - - -mig_internal novalue _Xrpc_jack_client_sync_notify - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_client_async_notify - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCClient_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_client_sync_notify_t__defined) -#define __MIG_check__Request__rpc_jack_client_sync_notify_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined -#if defined(__NDR_convert__int_rep__JackRPCClient__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__refnum(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__refnum(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined -#if defined(__NDR_convert__int_rep__JackRPCClient__client_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCClient__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__client_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__int_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCClient__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCClient__string(a, f, 64) -#elif defined(__NDR_convert__int_rep__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify__defined -#if defined(__NDR_convert__int_rep__JackRPCClient__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify(a, f) \ - __NDR_convert__int_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify(a, f) \ - __NDR_convert__int_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined -#if defined(__NDR_convert__int_rep__JackRPCClient__message_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ - __NDR_convert__int_rep__JackRPCClient__message_t((message_t *)(a), f) -#elif defined(__NDR_convert__int_rep__message_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ - __NDR_convert__int_rep__message_t((message_t *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCClient__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ - __NDR_convert__int_rep__JackRPCClient__string(a, f, 256) -#elif defined(__NDR_convert__int_rep__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ - __NDR_convert__int_rep__string(a, f, 256) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1__defined -#if defined(__NDR_convert__int_rep__JackRPCClient__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1(a, f) \ - __NDR_convert__int_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1(a, f) \ - __NDR_convert__int_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value2__defined -#if defined(__NDR_convert__int_rep__JackRPCClient__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value2__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value2(a, f) \ - __NDR_convert__int_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value2__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value2(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value2__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value2(a, f) \ - __NDR_convert__int_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value2__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value2(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value2__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined -#if defined(__NDR_convert__char_rep__JackRPCClient__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__refnum(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__refnum(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined -#if defined(__NDR_convert__char_rep__JackRPCClient__client_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCClient__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__client_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__char_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCClient__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCClient__string(a, f, 64) -#elif defined(__NDR_convert__char_rep__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify__defined -#if defined(__NDR_convert__char_rep__JackRPCClient__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify(a, f) \ - __NDR_convert__char_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify(a, f) \ - __NDR_convert__char_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined -#if defined(__NDR_convert__char_rep__JackRPCClient__message_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ - __NDR_convert__char_rep__JackRPCClient__message_t((message_t *)(a), f) -#elif defined(__NDR_convert__char_rep__message_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ - __NDR_convert__char_rep__message_t((message_t *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCClient__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ - __NDR_convert__char_rep__JackRPCClient__string(a, f, 256) -#elif defined(__NDR_convert__char_rep__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ - __NDR_convert__char_rep__string(a, f, 256) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1__defined -#if defined(__NDR_convert__char_rep__JackRPCClient__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1(a, f) \ - __NDR_convert__char_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1(a, f) \ - __NDR_convert__char_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value2__defined -#if defined(__NDR_convert__char_rep__JackRPCClient__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value2__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value2(a, f) \ - __NDR_convert__char_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value2__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value2(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value2__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value2(a, f) \ - __NDR_convert__char_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value2__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value2(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value2__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined -#if defined(__NDR_convert__float_rep__JackRPCClient__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__refnum(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__refnum(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined -#if defined(__NDR_convert__float_rep__JackRPCClient__client_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCClient__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__client_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__float_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCClient__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCClient__string(a, f, 64) -#elif defined(__NDR_convert__float_rep__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify__defined -#if defined(__NDR_convert__float_rep__JackRPCClient__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify(a, f) \ - __NDR_convert__float_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify(a, f) \ - __NDR_convert__float_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined -#if defined(__NDR_convert__float_rep__JackRPCClient__message_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ - __NDR_convert__float_rep__JackRPCClient__message_t((message_t *)(a), f) -#elif defined(__NDR_convert__float_rep__message_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ - __NDR_convert__float_rep__message_t((message_t *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCClient__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ - __NDR_convert__float_rep__JackRPCClient__string(a, f, 256) -#elif defined(__NDR_convert__float_rep__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ - __NDR_convert__float_rep__string(a, f, 256) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1__defined -#if defined(__NDR_convert__float_rep__JackRPCClient__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1(a, f) \ - __NDR_convert__float_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1(a, f) \ - __NDR_convert__float_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value2__defined -#if defined(__NDR_convert__float_rep__JackRPCClient__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value2__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value2(a, f) \ - __NDR_convert__float_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value2__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value2(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value2__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value2(a, f) \ - __NDR_convert__float_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value2__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value2(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value2__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_sync_notify_t(__attribute__((__unused__)) __Request__rpc_jack_client_sync_notify_t *In0P) -{ - - typedef __Request__rpc_jack_client_sync_notify_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if __MigTypeCheck - { - char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; - size_t memchr_limit; - - memchr_limit = min((msg_limit - In0P->client_name), 64); - if (( memchr(In0P->client_name, '\0', memchr_limit) == NULL )) - return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! - memchr_limit = min((msg_limit - In0P->message), 256); - if (( memchr(In0P->message, '\0', memchr_limit) == NULL )) - return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! - } -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value2__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__refnum(&In0P->refnum, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name(&In0P->client_name, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify(&In0P->notify, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message(&In0P->message, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1(&In0P->value1, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value2__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value2(&In0P->value2, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value2__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value2__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__refnum(&In0P->refnum, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name(&In0P->client_name, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify(&In0P->notify, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message(&In0P->message, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1(&In0P->value1, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value2__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value2(&In0P->value2, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value2__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value2__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__refnum(&In0P->refnum, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name(&In0P->client_name, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify(&In0P->notify, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message(&In0P->message, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1(&In0P->value1, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value2__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value2(&In0P->value2, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value2__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_client_sync_notify_t__defined) */ -#endif /* __MIG_check__Request__JackRPCClient_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_client_sync_notify */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_client_sync_notify -( - mach_port_t client_port, - int refnum, - client_name_t client_name, - int notify, - message_t message, - int value1, - int value2, - int *result -); - -/* Routine rpc_jack_client_sync_notify */ -mig_internal novalue _Xrpc_jack_client_sync_notify - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_name_t client_name; - int notify; - message_t message; - int value1; - int value2; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_client_sync_notify_t __Request; - typedef __Reply__rpc_jack_client_sync_notify_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_client_sync_notify_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_client_sync_notify_t__defined */ - - __DeclareRcvRpc(1000, "rpc_jack_client_sync_notify") - __BeforeRcvRpc(1000, "rpc_jack_client_sync_notify") - -#if defined(__MIG_check__Request__rpc_jack_client_sync_notify_t__defined) - check_result = __MIG_check__Request__rpc_jack_client_sync_notify_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_client_sync_notify_t__defined) */ - - OutP->RetCode = rpc_jack_client_sync_notify(In0P->Head.msgh_request_port, In0P->refnum, In0P->client_name, In0P->notify, In0P->message, In0P->value1, In0P->value2, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1000, "rpc_jack_client_sync_notify") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCClient_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_client_async_notify_t__defined) -#define __MIG_check__Request__rpc_jack_client_async_notify_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__refnum__defined -#if defined(__NDR_convert__int_rep__JackRPCClient__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__refnum(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__refnum(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__refnum__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name__defined -#if defined(__NDR_convert__int_rep__JackRPCClient__client_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCClient__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__client_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__int_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCClient__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCClient__string(a, f, 64) -#elif defined(__NDR_convert__int_rep__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify__defined -#if defined(__NDR_convert__int_rep__JackRPCClient__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify(a, f) \ - __NDR_convert__int_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify(a, f) \ - __NDR_convert__int_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined -#if defined(__NDR_convert__int_rep__JackRPCClient__message_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ - __NDR_convert__int_rep__JackRPCClient__message_t((message_t *)(a), f) -#elif defined(__NDR_convert__int_rep__message_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ - __NDR_convert__int_rep__message_t((message_t *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCClient__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ - __NDR_convert__int_rep__JackRPCClient__string(a, f, 256) -#elif defined(__NDR_convert__int_rep__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ - __NDR_convert__int_rep__string(a, f, 256) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1__defined -#if defined(__NDR_convert__int_rep__JackRPCClient__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1(a, f) \ - __NDR_convert__int_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1(a, f) \ - __NDR_convert__int_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value2__defined -#if defined(__NDR_convert__int_rep__JackRPCClient__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value2__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value2(a, f) \ - __NDR_convert__int_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value2__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value2(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value2__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value2(a, f) \ - __NDR_convert__int_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value2__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value2(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value2__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__refnum__defined -#if defined(__NDR_convert__char_rep__JackRPCClient__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__refnum(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__refnum(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__refnum__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name__defined -#if defined(__NDR_convert__char_rep__JackRPCClient__client_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCClient__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__client_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__char_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCClient__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCClient__string(a, f, 64) -#elif defined(__NDR_convert__char_rep__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify__defined -#if defined(__NDR_convert__char_rep__JackRPCClient__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify(a, f) \ - __NDR_convert__char_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify(a, f) \ - __NDR_convert__char_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined -#if defined(__NDR_convert__char_rep__JackRPCClient__message_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ - __NDR_convert__char_rep__JackRPCClient__message_t((message_t *)(a), f) -#elif defined(__NDR_convert__char_rep__message_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ - __NDR_convert__char_rep__message_t((message_t *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCClient__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ - __NDR_convert__char_rep__JackRPCClient__string(a, f, 256) -#elif defined(__NDR_convert__char_rep__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ - __NDR_convert__char_rep__string(a, f, 256) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1__defined -#if defined(__NDR_convert__char_rep__JackRPCClient__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1(a, f) \ - __NDR_convert__char_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1(a, f) \ - __NDR_convert__char_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value2__defined -#if defined(__NDR_convert__char_rep__JackRPCClient__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value2__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value2(a, f) \ - __NDR_convert__char_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value2__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value2(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value2__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value2(a, f) \ - __NDR_convert__char_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value2__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value2(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value2__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__refnum__defined -#if defined(__NDR_convert__float_rep__JackRPCClient__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__refnum(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__refnum(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__refnum__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name__defined -#if defined(__NDR_convert__float_rep__JackRPCClient__client_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCClient__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__client_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__float_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCClient__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCClient__string(a, f, 64) -#elif defined(__NDR_convert__float_rep__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify__defined -#if defined(__NDR_convert__float_rep__JackRPCClient__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify(a, f) \ - __NDR_convert__float_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify(a, f) \ - __NDR_convert__float_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined -#if defined(__NDR_convert__float_rep__JackRPCClient__message_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ - __NDR_convert__float_rep__JackRPCClient__message_t((message_t *)(a), f) -#elif defined(__NDR_convert__float_rep__message_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ - __NDR_convert__float_rep__message_t((message_t *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCClient__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ - __NDR_convert__float_rep__JackRPCClient__string(a, f, 256) -#elif defined(__NDR_convert__float_rep__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ - __NDR_convert__float_rep__string(a, f, 256) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1__defined -#if defined(__NDR_convert__float_rep__JackRPCClient__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1(a, f) \ - __NDR_convert__float_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1(a, f) \ - __NDR_convert__float_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value2__defined -#if defined(__NDR_convert__float_rep__JackRPCClient__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value2__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value2(a, f) \ - __NDR_convert__float_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value2__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value2(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value2__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value2(a, f) \ - __NDR_convert__float_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value2__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value2(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value2__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_async_notify_t(__attribute__((__unused__)) __Request__rpc_jack_client_async_notify_t *In0P) -{ - - typedef __Request__rpc_jack_client_async_notify_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if __MigTypeCheck - { - char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; - size_t memchr_limit; - - memchr_limit = min((msg_limit - In0P->client_name), 64); - if (( memchr(In0P->client_name, '\0', memchr_limit) == NULL )) - return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! - memchr_limit = min((msg_limit - In0P->message), 256); - if (( memchr(In0P->message, '\0', memchr_limit) == NULL )) - return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! - } -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__refnum__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value2__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__refnum__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__refnum(&In0P->refnum, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__refnum__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name(&In0P->client_name, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify(&In0P->notify, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message(&In0P->message, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1(&In0P->value1, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value2__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value2(&In0P->value2, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value2__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__refnum__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value2__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__refnum__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__refnum(&In0P->refnum, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__refnum__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name(&In0P->client_name, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify(&In0P->notify, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message(&In0P->message, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1(&In0P->value1, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value2__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value2(&In0P->value2, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value2__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__refnum__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value2__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__refnum__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__refnum(&In0P->refnum, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__refnum__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name(&In0P->client_name, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify(&In0P->notify, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message(&In0P->message, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1(&In0P->value1, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value2__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value2(&In0P->value2, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value2__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_client_async_notify_t__defined) */ -#endif /* __MIG_check__Request__JackRPCClient_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* SimpleRoutine rpc_jack_client_async_notify */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_client_async_notify -( - mach_port_t client_port, - int refnum, - client_name_t client_name, - int notify, - message_t message, - int value1, - int value2 -); - -/* SimpleRoutine rpc_jack_client_async_notify */ -mig_internal novalue _Xrpc_jack_client_async_notify - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_name_t client_name; - int notify; - message_t message; - int value1; - int value2; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_client_async_notify_t __Request; - typedef __Reply__rpc_jack_client_async_notify_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_client_async_notify_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_client_async_notify_t__defined */ - - __DeclareRcvSimple(1001, "rpc_jack_client_async_notify") - __BeforeRcvSimple(1001, "rpc_jack_client_async_notify") - -#if defined(__MIG_check__Request__rpc_jack_client_async_notify_t__defined) - check_result = __MIG_check__Request__rpc_jack_client_async_notify_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_client_async_notify_t__defined) */ - - OutP->RetCode = rpc_jack_client_async_notify(In0P->Head.msgh_request_port, In0P->refnum, In0P->client_name, In0P->notify, In0P->message, In0P->value1, In0P->value2); - __AfterRcvSimple(1001, "rpc_jack_client_async_notify") -} - - -extern boolean_t JackRPCClient_server( - mach_msg_header_t *InHeadP, - mach_msg_header_t *OutHeadP); - -extern mig_routine_t JackRPCClient_server_routine( - mach_msg_header_t *InHeadP); - - -/* Description of this subsystem, for use in direct RPC */ -const struct JackRPCClient_subsystem { - mig_server_routine_t server; /* Server routine */ - mach_msg_id_t start; /* Min routine number */ - mach_msg_id_t end; /* Max routine number + 1 */ - unsigned int maxsize; /* Max msg size */ - vm_address_t reserved; /* Reserved */ - struct routine_descriptor /*Array of routine descriptors */ - routine[2]; -} JackRPCClient_subsystem = { - JackRPCClient_server_routine, - 1000, - 1002, - (mach_msg_size_t)sizeof(union __ReplyUnion__JackRPCClient_subsystem), - (vm_address_t)0, - { - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_sync_notify, 8, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_sync_notify_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_async_notify, 7, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_async_notify_t)}, - } -}; - -mig_external boolean_t JackRPCClient_server - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - register mig_routine_t routine; - - OutHeadP->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InHeadP->msgh_bits), 0); - OutHeadP->msgh_remote_port = InHeadP->msgh_reply_port; - /* Minimal size: routine() will update it if different */ - OutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t); - OutHeadP->msgh_local_port = MACH_PORT_NULL; - OutHeadP->msgh_id = InHeadP->msgh_id + 100; - - if ((InHeadP->msgh_id > 1001) || (InHeadP->msgh_id < 1000) || - ((routine = JackRPCClient_subsystem.routine[InHeadP->msgh_id - 1000].stub_routine) == 0)) { - ((mig_reply_error_t *)OutHeadP)->NDR = NDR_record; - ((mig_reply_error_t *)OutHeadP)->RetCode = MIG_BAD_ID; - return FALSE; - } - (*routine) (InHeadP, OutHeadP); - return TRUE; -} - -mig_external mig_routine_t JackRPCClient_server_routine - (mach_msg_header_t *InHeadP) -{ - register int msgh_id; - - msgh_id = InHeadP->msgh_id - 1000; - - if ((msgh_id > 1) || (msgh_id < 0)) - return 0; - - return JackRPCClient_subsystem.routine[msgh_id].stub_routine; -} diff --git a/macosx/RPC/JackRPCClientUser.c b/macosx/RPC/JackRPCClientUser.c deleted file mode 100644 index e6fef35e..00000000 --- a/macosx/RPC/JackRPCClientUser.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - * IDENTIFICATION: - * stub generated Fri Oct 23 10:35:08 2009 - * with a MiG generated Mon May 18 09:59:33 PDT 2009 by root@sulitlana.apple.com - * OPTIONS: - */ -#define __MIG_check__Reply__JackRPCClient_subsystem__ 1 -#define __NDR_convert__Reply__JackRPCClient_subsystem__ 1 -#define __NDR_convert__mig_reply_error_subsystem__ 1 - -#include "JackRPCClient.h" - - -#ifndef mig_internal -#define mig_internal static __inline__ -#endif /* mig_internal */ - -#ifndef mig_external -#define mig_external -#endif /* mig_external */ - -#if !defined(__MigTypeCheck) && defined(TypeCheck) -#define __MigTypeCheck TypeCheck /* Legacy setting */ -#endif /* !defined(__MigTypeCheck) */ - -#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) -#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ -#endif /* !defined(__MigKernelSpecificCode) */ - -#ifndef LimitCheck -#define LimitCheck 0 -#endif /* LimitCheck */ - -#ifndef min -#define min(a,b) ( ((a) < (b))? (a): (b) ) -#endif /* min */ - -#if !defined(_WALIGN_) -#define _WALIGN_(x) (((x) + 3) & ~3) -#endif /* !defined(_WALIGN_) */ - -#if !defined(_WALIGNSZ_) -#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) -#endif /* !defined(_WALIGNSZ_) */ - -#ifndef UseStaticTemplates -#define UseStaticTemplates 0 -#endif /* UseStaticTemplates */ - -#ifndef __MachMsgErrorWithTimeout -#define __MachMsgErrorWithTimeout(_R_) { \ - switch (_R_) { \ - case MACH_SEND_INVALID_DATA: \ - case MACH_SEND_INVALID_DEST: \ - case MACH_SEND_INVALID_HEADER: \ - mig_put_reply_port(InP->Head.msgh_reply_port); \ - break; \ - case MACH_SEND_TIMED_OUT: \ - case MACH_RCV_TIMED_OUT: \ - default: \ - mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ - } \ -} -#endif /* __MachMsgErrorWithTimeout */ - -#ifndef __MachMsgErrorWithoutTimeout -#define __MachMsgErrorWithoutTimeout(_R_) { \ - switch (_R_) { \ - case MACH_SEND_INVALID_DATA: \ - case MACH_SEND_INVALID_DEST: \ - case MACH_SEND_INVALID_HEADER: \ - mig_put_reply_port(InP->Head.msgh_reply_port); \ - break; \ - default: \ - mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ - } \ -} -#endif /* __MachMsgErrorWithoutTimeout */ - -#ifndef __DeclareSendRpc -#define __DeclareSendRpc(_NUM_, _NAME_) -#endif /* __DeclareSendRpc */ - -#ifndef __BeforeSendRpc -#define __BeforeSendRpc(_NUM_, _NAME_) -#endif /* __BeforeSendRpc */ - -#ifndef __AfterSendRpc -#define __AfterSendRpc(_NUM_, _NAME_) -#endif /* __AfterSendRpc */ - -#ifndef __DeclareSendSimple -#define __DeclareSendSimple(_NUM_, _NAME_) -#endif /* __DeclareSendSimple */ - -#ifndef __BeforeSendSimple -#define __BeforeSendSimple(_NUM_, _NAME_) -#endif /* __BeforeSendSimple */ - -#ifndef __AfterSendSimple -#define __AfterSendSimple(_NUM_, _NAME_) -#endif /* __AfterSendSimple */ - -#define msgh_request_port msgh_remote_port -#define msgh_reply_port msgh_local_port - - - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCClient_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_client_sync_notify_t__defined) -#define __MIG_check__Reply__rpc_jack_client_sync_notify_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCClient__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCClient__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCClient__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_client_sync_notify_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCClient__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_sync_notify_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_sync_notify_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_sync_notify_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_sync_notify_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_sync_notify_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_sync_notify_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_sync_notify_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_sync_notify_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_sync_notify_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_client_sync_notify_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCClient__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_sync_notify_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_sync_notify_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCClient__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_sync_notify_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_sync_notify_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCClient__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_sync_notify_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_sync_notify_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCClient__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_sync_notify_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_sync_notify_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_sync_notify_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_client_sync_notify_t(__Reply__rpc_jack_client_sync_notify_t *Out0P) -{ - - typedef __Reply__rpc_jack_client_sync_notify_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1100) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_sync_notify_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_client_sync_notify_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_client_sync_notify_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_client_sync_notify_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_sync_notify_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_client_sync_notify_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_client_sync_notify_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_client_sync_notify_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_sync_notify_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_client_sync_notify_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCClient_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_client_sync_notify */ -mig_external kern_return_t rpc_jack_client_sync_notify -( - mach_port_t client_port, - int refnum, - client_name_t client_name, - int notify, - message_t message, - int value1, - int value2, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_name_t client_name; - int notify; - message_t message; - int value1; - int value2; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_client_sync_notify_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_client_sync_notify_t__defined */ - - __DeclareSendRpc(1000, "rpc_jack_client_sync_notify") - - InP->NDR = NDR_record; - - InP->refnum = refnum; - - (void) mig_strncpy(InP->client_name, client_name, 64); - - InP->notify = notify; - - (void) mig_strncpy(InP->message, message, 256); - - InP->value1 = value1; - - InP->value2 = value2; - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = client_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1000; - - __BeforeSendRpc(1000, "rpc_jack_client_sync_notify") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_SEND_TIMEOUT|MACH_RCV_TIMEOUT|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, 5000, MACH_PORT_NULL); - __AfterSendRpc(1000, "rpc_jack_client_sync_notify") - - if (msg_result == MACH_SEND_TIMED_OUT) { - } - - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_client_sync_notify_t__defined) - check_result = __MIG_check__Reply__rpc_jack_client_sync_notify_t((__Reply__rpc_jack_client_sync_notify_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_client_sync_notify_t__defined) */ - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -/* SimpleRoutine rpc_jack_client_async_notify */ -mig_external kern_return_t rpc_jack_client_async_notify -( - mach_port_t client_port, - int refnum, - client_name_t client_name, - int notify, - message_t message, - int value1, - int value2 -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_name_t client_name; - int notify; - message_t message; - int value1; - int value2; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - } Mess; - - Request *InP = &Mess.In; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_client_async_notify_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_client_async_notify_t__defined */ - - __DeclareSendSimple(1001, "rpc_jack_client_async_notify") - - InP->NDR = NDR_record; - - InP->refnum = refnum; - - (void) mig_strncpy(InP->client_name, client_name, 64); - - InP->notify = notify; - - (void) mig_strncpy(InP->message, message, 256); - - InP->value1 = value1; - - InP->value2 = value2; - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, 0); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = client_port; - InP->Head.msgh_reply_port = MACH_PORT_NULL; - InP->Head.msgh_id = 1001; - - __BeforeSendSimple(1001, "rpc_jack_client_async_notify") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_SEND_TIMEOUT|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), 0, MACH_PORT_NULL, 5000, MACH_PORT_NULL); - __AfterSendSimple(1001, "rpc_jack_client_async_notify") - - if (msg_result == MACH_SEND_TIMED_OUT) { - } - - return msg_result; -} diff --git a/macosx/RPC/JackRPCEngine.defs b/macosx/RPC/JackRPCEngine.defs deleted file mode 100644 index 468b3775..00000000 --- a/macosx/RPC/JackRPCEngine.defs +++ /dev/null @@ -1,181 +0,0 @@ -/* - Copyright (C) 2004 Grame - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 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 - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -subsystem JackRPCEngine 1000; - -#include -#include -import "Jackdefs.h"; - -ServerPrefix server_; - -type client_name_t = c_string[64]; -type client_port_name_t = c_string[128]; -type client_port_type_t = c_string[128]; -type so_name_t = c_string[256]; -type objet_data_t = c_string[256]; - -routine rpc_jack_client_open( - server_port : mach_port_t; - client_name : client_name_t; - pid : int; - out private_port : mach_port_make_send_t; - out shared_engine : int; - out shared_client : int; - out shared_graph : int; - out result : int); - -routine rpc_jack_client_check( - server_port : mach_port_t; - client_name : client_name_t; - out client_name_res : client_name_t; - protocol : int; - options : int; - out status : int; - out result : int); - -routine rpc_jack_client_close( - server_port : mach_port_t; - refnum : int; - out result : int); - -routine rpc_jack_client_activate( - server_port : mach_port_t; - refnum : int; - state : int; - out result : int); - -routine rpc_jack_client_deactivate( - server_port : mach_port_t; - refnum : int; - out result : int); - -routine rpc_jack_port_register( - server_port : mach_port_t; - refnum : int; - name : client_port_name_t; - port_type : client_port_type_t; - flags : unsigned; - buffer_size : unsigned; - out port_index : unsigned; - out result : int); - -routine rpc_jack_port_unregister( - server_port : mach_port_t; - refnum : int; - port : int; - out result : int); - -routine rpc_jack_port_connect( - server_port : mach_port_t; - refnum : int; - src : int; - dst : int; - out result : int); - -routine rpc_jack_port_disconnect( - server_port : mach_port_t; - refnum : int; - src : int; - dst : int; - out result : int); - -routine rpc_jack_port_connect_name( - server_port : mach_port_t; - refnum : int; - src : client_port_name_t; - dst : client_port_name_t; - out result : int); - -routine rpc_jack_port_disconnect_name( - server_port : mach_port_t; - refnum : int; - src : client_port_name_t; - dst : client_port_name_t; - out result : int); - -routine rpc_jack_port_rename( - server_port : mach_port_t; - refnum : int; - src : int; - name : client_port_name_t; - out result : int); - -routine rpc_jack_set_buffer_size( - server_port : mach_port_t; - buffer_size : int; - out result : int); - -routine rpc_jack_set_freewheel( - server_port : mach_port_t; - onoff : int; - out result : int); - -routine rpc_jack_release_timebase( - server_port : mach_port_t; - refnum : int; - out result : int); - -routine rpc_jack_set_timebase_callback( - server_port : mach_port_t; - refnum : int; - conditional : int; - out result : int); - -routine rpc_jack_get_internal_clientname( - server_port : mach_port_t; - refnum : int; - int_ref : int; - out client_name_res : client_name_t; - out result : int); - -routine rpc_jack_internal_clienthandle( - server_port : mach_port_t; - refnum : int; - client_name : client_name_t; - out int_ref : int; - out status : int; - out result : int); - -routine rpc_jack_internal_clientload( - server_port : mach_port_t; - refnum : int; - client_name : client_name_t; - so_name : so_name_t; - objet_data : objet_data_t; - options : int; - out status : int; - out int_ref : int; - out result : int); - -routine rpc_jack_internal_clientunload( - server_port : mach_port_t; - refnum : int; - int_ref : int; - out status : int; - out result : int); - -simpleroutine rpc_jack_client_rt_notify( - client_port : mach_port_t; - refnum : int; - notify : int; - value : int; - waittime timeout : int); - - diff --git a/macosx/RPC/JackRPCEngine.h b/macosx/RPC/JackRPCEngine.h deleted file mode 100644 index b9ba07f0..00000000 --- a/macosx/RPC/JackRPCEngine.h +++ /dev/null @@ -1,1040 +0,0 @@ -#ifndef _JackRPCEngine_user_ -#define _JackRPCEngine_user_ - -/* Module JackRPCEngine */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef AUTOTEST -#ifndef FUNCTION_PTR_T -#define FUNCTION_PTR_T -typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); -typedef struct { - char *name; - function_ptr_t function; -} function_table_entry; -typedef function_table_entry *function_table_t; -#endif /* FUNCTION_PTR_T */ -#endif /* AUTOTEST */ - -#ifndef JackRPCEngine_MSG_COUNT -#define JackRPCEngine_MSG_COUNT 21 -#endif /* JackRPCEngine_MSG_COUNT */ - -#include -#include -#include -#include -#include "Jackdefs.h" - -#ifdef __BeforeMigUserHeader -__BeforeMigUserHeader -#endif /* __BeforeMigUserHeader */ - -#include -__BEGIN_DECLS - - -/* Routine rpc_jack_client_open */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_client_open -( - mach_port_t server_port, - client_name_t client_name, - int pid, - mach_port_t *private_port, - int *shared_engine, - int *shared_client, - int *shared_graph, - int *result -); - -/* Routine rpc_jack_client_check */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_client_check -( - mach_port_t server_port, - client_name_t client_name, - client_name_t client_name_res, - int protocol, - int options, - int *status, - int *result -); - -/* Routine rpc_jack_client_close */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_client_close -( - mach_port_t server_port, - int refnum, - int *result -); - -/* Routine rpc_jack_client_activate */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_client_activate -( - mach_port_t server_port, - int refnum, - int state, - int *result -); - -/* Routine rpc_jack_client_deactivate */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_client_deactivate -( - mach_port_t server_port, - int refnum, - int *result -); - -/* Routine rpc_jack_port_register */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_port_register -( - mach_port_t server_port, - int refnum, - client_port_name_t name, - client_port_type_t port_type, - unsigned flags, - unsigned buffer_size, - unsigned *port_index, - int *result -); - -/* Routine rpc_jack_port_unregister */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_port_unregister -( - mach_port_t server_port, - int refnum, - int port, - int *result -); - -/* Routine rpc_jack_port_connect */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_port_connect -( - mach_port_t server_port, - int refnum, - int src, - int dst, - int *result -); - -/* Routine rpc_jack_port_disconnect */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_port_disconnect -( - mach_port_t server_port, - int refnum, - int src, - int dst, - int *result -); - -/* Routine rpc_jack_port_connect_name */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_port_connect_name -( - mach_port_t server_port, - int refnum, - client_port_name_t src, - client_port_name_t dst, - int *result -); - -/* Routine rpc_jack_port_disconnect_name */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_port_disconnect_name -( - mach_port_t server_port, - int refnum, - client_port_name_t src, - client_port_name_t dst, - int *result -); - -/* Routine rpc_jack_port_rename */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_port_rename -( - mach_port_t server_port, - int refnum, - int src, - client_port_name_t name, - int *result -); - -/* Routine rpc_jack_set_buffer_size */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_set_buffer_size -( - mach_port_t server_port, - int buffer_size, - int *result -); - -/* Routine rpc_jack_set_freewheel */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_set_freewheel -( - mach_port_t server_port, - int onoff, - int *result -); - -/* Routine rpc_jack_release_timebase */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_release_timebase -( - mach_port_t server_port, - int refnum, - int *result -); - -/* Routine rpc_jack_set_timebase_callback */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_set_timebase_callback -( - mach_port_t server_port, - int refnum, - int conditional, - int *result -); - -/* Routine rpc_jack_get_internal_clientname */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_get_internal_clientname -( - mach_port_t server_port, - int refnum, - int int_ref, - client_name_t client_name_res, - int *result -); - -/* Routine rpc_jack_internal_clienthandle */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_internal_clienthandle -( - mach_port_t server_port, - int refnum, - client_name_t client_name, - int *int_ref, - int *status, - int *result -); - -/* Routine rpc_jack_internal_clientload */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_internal_clientload -( - mach_port_t server_port, - int refnum, - client_name_t client_name, - so_name_t so_name, - objet_data_t objet_data, - int options, - int *status, - int *int_ref, - int *result -); - -/* Routine rpc_jack_internal_clientunload */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_internal_clientunload -( - mach_port_t server_port, - int refnum, - int int_ref, - int *status, - int *result -); - -/* SimpleRoutine rpc_jack_client_rt_notify */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t rpc_jack_client_rt_notify -( - mach_port_t client_port, - int refnum, - int notify, - int value, - int timeout -); - -__END_DECLS - -/********************** Caution **************************/ -/* The following data types should be used to calculate */ -/* maximum message sizes only. The actual message may be */ -/* smaller, and the position of the arguments within the */ -/* message layout may vary from what is presented here. */ -/* For example, if any of the arguments are variable- */ -/* sized, and less than the maximum is sent, the data */ -/* will be packed tight in the actual message to reduce */ -/* the presence of holes. */ -/********************** Caution **************************/ - -/* typedefs for all requests */ - -#ifndef __Request__JackRPCEngine_subsystem__defined -#define __Request__JackRPCEngine_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - client_name_t client_name; - int pid; - } __Request__rpc_jack_client_open_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - client_name_t client_name; - int protocol; - int options; - } __Request__rpc_jack_client_check_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - } __Request__rpc_jack_client_close_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int state; - } __Request__rpc_jack_client_activate_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - } __Request__rpc_jack_client_deactivate_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_port_name_t name; - client_port_type_t port_type; - unsigned flags; - unsigned buffer_size; - } __Request__rpc_jack_port_register_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int port; - } __Request__rpc_jack_port_unregister_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int src; - int dst; - } __Request__rpc_jack_port_connect_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int src; - int dst; - } __Request__rpc_jack_port_disconnect_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_port_name_t src; - client_port_name_t dst; - } __Request__rpc_jack_port_connect_name_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_port_name_t src; - client_port_name_t dst; - } __Request__rpc_jack_port_disconnect_name_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int src; - client_port_name_t name; - } __Request__rpc_jack_port_rename_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int buffer_size; - } __Request__rpc_jack_set_buffer_size_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int onoff; - } __Request__rpc_jack_set_freewheel_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - } __Request__rpc_jack_release_timebase_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int conditional; - } __Request__rpc_jack_set_timebase_callback_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int int_ref; - } __Request__rpc_jack_get_internal_clientname_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_name_t client_name; - } __Request__rpc_jack_internal_clienthandle_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_name_t client_name; - so_name_t so_name; - objet_data_t objet_data; - int options; - } __Request__rpc_jack_internal_clientload_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int int_ref; - } __Request__rpc_jack_internal_clientunload_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int notify; - int value; - } __Request__rpc_jack_client_rt_notify_t; -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Request__JackRPCEngine_subsystem__defined */ - -/* union of all requests */ - -#ifndef __RequestUnion__JackRPCEngine_subsystem__defined -#define __RequestUnion__JackRPCEngine_subsystem__defined -union __RequestUnion__JackRPCEngine_subsystem { - __Request__rpc_jack_client_open_t Request_rpc_jack_client_open; - __Request__rpc_jack_client_check_t Request_rpc_jack_client_check; - __Request__rpc_jack_client_close_t Request_rpc_jack_client_close; - __Request__rpc_jack_client_activate_t Request_rpc_jack_client_activate; - __Request__rpc_jack_client_deactivate_t Request_rpc_jack_client_deactivate; - __Request__rpc_jack_port_register_t Request_rpc_jack_port_register; - __Request__rpc_jack_port_unregister_t Request_rpc_jack_port_unregister; - __Request__rpc_jack_port_connect_t Request_rpc_jack_port_connect; - __Request__rpc_jack_port_disconnect_t Request_rpc_jack_port_disconnect; - __Request__rpc_jack_port_connect_name_t Request_rpc_jack_port_connect_name; - __Request__rpc_jack_port_disconnect_name_t Request_rpc_jack_port_disconnect_name; - __Request__rpc_jack_port_rename_t Request_rpc_jack_port_rename; - __Request__rpc_jack_set_buffer_size_t Request_rpc_jack_set_buffer_size; - __Request__rpc_jack_set_freewheel_t Request_rpc_jack_set_freewheel; - __Request__rpc_jack_release_timebase_t Request_rpc_jack_release_timebase; - __Request__rpc_jack_set_timebase_callback_t Request_rpc_jack_set_timebase_callback; - __Request__rpc_jack_get_internal_clientname_t Request_rpc_jack_get_internal_clientname; - __Request__rpc_jack_internal_clienthandle_t Request_rpc_jack_internal_clienthandle; - __Request__rpc_jack_internal_clientload_t Request_rpc_jack_internal_clientload; - __Request__rpc_jack_internal_clientunload_t Request_rpc_jack_internal_clientunload; - __Request__rpc_jack_client_rt_notify_t Request_rpc_jack_client_rt_notify; -}; -#endif /* !__RequestUnion__JackRPCEngine_subsystem__defined */ -/* typedefs for all replies */ - -#ifndef __Reply__JackRPCEngine_subsystem__defined -#define __Reply__JackRPCEngine_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t private_port; - /* end of the kernel processed data */ - NDR_record_t NDR; - int shared_engine; - int shared_client; - int shared_graph; - int result; - } __Reply__rpc_jack_client_open_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - client_name_t client_name_res; - int status; - int result; - } __Reply__rpc_jack_client_check_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_client_close_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_client_activate_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_client_deactivate_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - unsigned port_index; - int result; - } __Reply__rpc_jack_port_register_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_port_unregister_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_port_connect_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_port_disconnect_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_port_connect_name_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_port_disconnect_name_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_port_rename_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_set_buffer_size_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_set_freewheel_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_release_timebase_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_set_timebase_callback_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - client_name_t client_name_res; - int result; - } __Reply__rpc_jack_get_internal_clientname_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int int_ref; - int status; - int result; - } __Reply__rpc_jack_internal_clienthandle_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int status; - int int_ref; - int result; - } __Reply__rpc_jack_internal_clientload_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int status; - int result; - } __Reply__rpc_jack_internal_clientunload_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - } __Reply__rpc_jack_client_rt_notify_t; -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Reply__JackRPCEngine_subsystem__defined */ - -/* union of all replies */ - -#ifndef __ReplyUnion__JackRPCEngine_subsystem__defined -#define __ReplyUnion__JackRPCEngine_subsystem__defined -union __ReplyUnion__JackRPCEngine_subsystem { - __Reply__rpc_jack_client_open_t Reply_rpc_jack_client_open; - __Reply__rpc_jack_client_check_t Reply_rpc_jack_client_check; - __Reply__rpc_jack_client_close_t Reply_rpc_jack_client_close; - __Reply__rpc_jack_client_activate_t Reply_rpc_jack_client_activate; - __Reply__rpc_jack_client_deactivate_t Reply_rpc_jack_client_deactivate; - __Reply__rpc_jack_port_register_t Reply_rpc_jack_port_register; - __Reply__rpc_jack_port_unregister_t Reply_rpc_jack_port_unregister; - __Reply__rpc_jack_port_connect_t Reply_rpc_jack_port_connect; - __Reply__rpc_jack_port_disconnect_t Reply_rpc_jack_port_disconnect; - __Reply__rpc_jack_port_connect_name_t Reply_rpc_jack_port_connect_name; - __Reply__rpc_jack_port_disconnect_name_t Reply_rpc_jack_port_disconnect_name; - __Reply__rpc_jack_port_rename_t Reply_rpc_jack_port_rename; - __Reply__rpc_jack_set_buffer_size_t Reply_rpc_jack_set_buffer_size; - __Reply__rpc_jack_set_freewheel_t Reply_rpc_jack_set_freewheel; - __Reply__rpc_jack_release_timebase_t Reply_rpc_jack_release_timebase; - __Reply__rpc_jack_set_timebase_callback_t Reply_rpc_jack_set_timebase_callback; - __Reply__rpc_jack_get_internal_clientname_t Reply_rpc_jack_get_internal_clientname; - __Reply__rpc_jack_internal_clienthandle_t Reply_rpc_jack_internal_clienthandle; - __Reply__rpc_jack_internal_clientload_t Reply_rpc_jack_internal_clientload; - __Reply__rpc_jack_internal_clientunload_t Reply_rpc_jack_internal_clientunload; - __Reply__rpc_jack_client_rt_notify_t Reply_rpc_jack_client_rt_notify; -}; -#endif /* !__RequestUnion__JackRPCEngine_subsystem__defined */ - -#ifndef subsystem_to_name_map_JackRPCEngine -#define subsystem_to_name_map_JackRPCEngine \ - { "rpc_jack_client_open", 1000 },\ - { "rpc_jack_client_check", 1001 },\ - { "rpc_jack_client_close", 1002 },\ - { "rpc_jack_client_activate", 1003 },\ - { "rpc_jack_client_deactivate", 1004 },\ - { "rpc_jack_port_register", 1005 },\ - { "rpc_jack_port_unregister", 1006 },\ - { "rpc_jack_port_connect", 1007 },\ - { "rpc_jack_port_disconnect", 1008 },\ - { "rpc_jack_port_connect_name", 1009 },\ - { "rpc_jack_port_disconnect_name", 1010 },\ - { "rpc_jack_port_rename", 1011 },\ - { "rpc_jack_set_buffer_size", 1012 },\ - { "rpc_jack_set_freewheel", 1013 },\ - { "rpc_jack_release_timebase", 1014 },\ - { "rpc_jack_set_timebase_callback", 1015 },\ - { "rpc_jack_get_internal_clientname", 1016 },\ - { "rpc_jack_internal_clienthandle", 1017 },\ - { "rpc_jack_internal_clientload", 1018 },\ - { "rpc_jack_internal_clientunload", 1019 },\ - { "rpc_jack_client_rt_notify", 1020 } -#endif - -#ifdef __AfterMigUserHeader -__AfterMigUserHeader -#endif /* __AfterMigUserHeader */ - -#endif /* _JackRPCEngine_user_ */ diff --git a/macosx/RPC/JackRPCEngineServer.c b/macosx/RPC/JackRPCEngineServer.c deleted file mode 100644 index 7ef5d556..00000000 --- a/macosx/RPC/JackRPCEngineServer.c +++ /dev/null @@ -1,6817 +0,0 @@ -/* - * IDENTIFICATION: - * stub generated Fri Oct 23 10:35:08 2009 - * with a MiG generated Mon May 18 09:59:33 PDT 2009 by root@sulitlana.apple.com - * OPTIONS: - */ - -/* Module JackRPCEngine */ - -#define __MIG_check__Request__JackRPCEngine_subsystem__ 1 -#define __NDR_convert__Request__JackRPCEngine_subsystem__ 1 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "Jackdefs.h" - -#ifndef mig_internal -#define mig_internal static __inline__ -#endif /* mig_internal */ - -#ifndef mig_external -#define mig_external -#endif /* mig_external */ - -#if !defined(__MigTypeCheck) && defined(TypeCheck) -#define __MigTypeCheck TypeCheck /* Legacy setting */ -#endif /* !defined(__MigTypeCheck) */ - -#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) -#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ -#endif /* !defined(__MigKernelSpecificCode) */ - -#ifndef LimitCheck -#define LimitCheck 0 -#endif /* LimitCheck */ - -#ifndef min -#define min(a,b) ( ((a) < (b))? (a): (b) ) -#endif /* min */ - -#if !defined(_WALIGN_) -#define _WALIGN_(x) (((x) + 3) & ~3) -#endif /* !defined(_WALIGN_) */ - -#if !defined(_WALIGNSZ_) -#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) -#endif /* !defined(_WALIGNSZ_) */ - -#ifndef UseStaticTemplates -#define UseStaticTemplates 0 -#endif /* UseStaticTemplates */ - -#ifndef __DeclareRcvRpc -#define __DeclareRcvRpc(_NUM_, _NAME_) -#endif /* __DeclareRcvRpc */ - -#ifndef __BeforeRcvRpc -#define __BeforeRcvRpc(_NUM_, _NAME_) -#endif /* __BeforeRcvRpc */ - -#ifndef __AfterRcvRpc -#define __AfterRcvRpc(_NUM_, _NAME_) -#endif /* __AfterRcvRpc */ - -#ifndef __DeclareRcvSimple -#define __DeclareRcvSimple(_NUM_, _NAME_) -#endif /* __DeclareRcvSimple */ - -#ifndef __BeforeRcvSimple -#define __BeforeRcvSimple(_NUM_, _NAME_) -#endif /* __BeforeRcvSimple */ - -#ifndef __AfterRcvSimple -#define __AfterRcvSimple(_NUM_, _NAME_) -#endif /* __AfterRcvSimple */ - -#define novalue void - -#define msgh_request_port msgh_local_port -#define MACH_MSGH_BITS_REQUEST(bits) MACH_MSGH_BITS_LOCAL(bits) -#define msgh_reply_port msgh_remote_port -#define MACH_MSGH_BITS_REPLY(bits) MACH_MSGH_BITS_REMOTE(bits) - -#define MIG_RETURN_ERROR(X, code) {\ - ((mig_reply_error_t *)X)->RetCode = code;\ - ((mig_reply_error_t *)X)->NDR = NDR_record;\ - return;\ - } - -/* typedefs for all requests */ - -#ifndef __Request__JackRPCEngine_subsystem__defined -#define __Request__JackRPCEngine_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - client_name_t client_name; - int pid; - } __Request__rpc_jack_client_open_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - client_name_t client_name; - int protocol; - int options; - } __Request__rpc_jack_client_check_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - } __Request__rpc_jack_client_close_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int state; - } __Request__rpc_jack_client_activate_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - } __Request__rpc_jack_client_deactivate_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_port_name_t name; - client_port_type_t port_type; - unsigned flags; - unsigned buffer_size; - } __Request__rpc_jack_port_register_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int port; - } __Request__rpc_jack_port_unregister_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int src; - int dst; - } __Request__rpc_jack_port_connect_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int src; - int dst; - } __Request__rpc_jack_port_disconnect_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_port_name_t src; - client_port_name_t dst; - } __Request__rpc_jack_port_connect_name_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_port_name_t src; - client_port_name_t dst; - } __Request__rpc_jack_port_disconnect_name_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int src; - client_port_name_t name; - } __Request__rpc_jack_port_rename_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int buffer_size; - } __Request__rpc_jack_set_buffer_size_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int onoff; - } __Request__rpc_jack_set_freewheel_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - } __Request__rpc_jack_release_timebase_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int conditional; - } __Request__rpc_jack_set_timebase_callback_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int int_ref; - } __Request__rpc_jack_get_internal_clientname_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_name_t client_name; - } __Request__rpc_jack_internal_clienthandle_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_name_t client_name; - so_name_t so_name; - objet_data_t objet_data; - int options; - } __Request__rpc_jack_internal_clientload_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int int_ref; - } __Request__rpc_jack_internal_clientunload_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int notify; - int value; - } __Request__rpc_jack_client_rt_notify_t; -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Request__JackRPCEngine_subsystem__defined */ - -/* typedefs for all replies */ - -#ifndef __Reply__JackRPCEngine_subsystem__defined -#define __Reply__JackRPCEngine_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t private_port; - /* end of the kernel processed data */ - NDR_record_t NDR; - int shared_engine; - int shared_client; - int shared_graph; - int result; - } __Reply__rpc_jack_client_open_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - client_name_t client_name_res; - int status; - int result; - } __Reply__rpc_jack_client_check_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_client_close_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_client_activate_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_client_deactivate_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - unsigned port_index; - int result; - } __Reply__rpc_jack_port_register_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_port_unregister_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_port_connect_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_port_disconnect_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_port_connect_name_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_port_disconnect_name_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_port_rename_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_set_buffer_size_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_set_freewheel_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_release_timebase_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply__rpc_jack_set_timebase_callback_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - client_name_t client_name_res; - int result; - } __Reply__rpc_jack_get_internal_clientname_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int int_ref; - int status; - int result; - } __Reply__rpc_jack_internal_clienthandle_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int status; - int int_ref; - int result; - } __Reply__rpc_jack_internal_clientload_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int status; - int result; - } __Reply__rpc_jack_internal_clientunload_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - } __Reply__rpc_jack_client_rt_notify_t; -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Reply__JackRPCEngine_subsystem__defined */ - - -/* union of all replies */ - -#ifndef __ReplyUnion__server_JackRPCEngine_subsystem__defined -#define __ReplyUnion__server_JackRPCEngine_subsystem__defined -union __ReplyUnion__server_JackRPCEngine_subsystem { - __Reply__rpc_jack_client_open_t Reply_rpc_jack_client_open; - __Reply__rpc_jack_client_check_t Reply_rpc_jack_client_check; - __Reply__rpc_jack_client_close_t Reply_rpc_jack_client_close; - __Reply__rpc_jack_client_activate_t Reply_rpc_jack_client_activate; - __Reply__rpc_jack_client_deactivate_t Reply_rpc_jack_client_deactivate; - __Reply__rpc_jack_port_register_t Reply_rpc_jack_port_register; - __Reply__rpc_jack_port_unregister_t Reply_rpc_jack_port_unregister; - __Reply__rpc_jack_port_connect_t Reply_rpc_jack_port_connect; - __Reply__rpc_jack_port_disconnect_t Reply_rpc_jack_port_disconnect; - __Reply__rpc_jack_port_connect_name_t Reply_rpc_jack_port_connect_name; - __Reply__rpc_jack_port_disconnect_name_t Reply_rpc_jack_port_disconnect_name; - __Reply__rpc_jack_port_rename_t Reply_rpc_jack_port_rename; - __Reply__rpc_jack_set_buffer_size_t Reply_rpc_jack_set_buffer_size; - __Reply__rpc_jack_set_freewheel_t Reply_rpc_jack_set_freewheel; - __Reply__rpc_jack_release_timebase_t Reply_rpc_jack_release_timebase; - __Reply__rpc_jack_set_timebase_callback_t Reply_rpc_jack_set_timebase_callback; - __Reply__rpc_jack_get_internal_clientname_t Reply_rpc_jack_get_internal_clientname; - __Reply__rpc_jack_internal_clienthandle_t Reply_rpc_jack_internal_clienthandle; - __Reply__rpc_jack_internal_clientload_t Reply_rpc_jack_internal_clientload; - __Reply__rpc_jack_internal_clientunload_t Reply_rpc_jack_internal_clientunload; - __Reply__rpc_jack_client_rt_notify_t Reply_rpc_jack_client_rt_notify; -}; -#endif /* __RequestUnion__server_JackRPCEngine_subsystem__defined */ -/* Forward Declarations */ - - -mig_internal novalue _Xrpc_jack_client_open - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_client_check - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_client_close - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_client_activate - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_client_deactivate - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_port_register - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_port_unregister - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_port_connect - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_port_disconnect - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_port_connect_name - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_port_disconnect_name - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_port_rename - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_set_buffer_size - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_set_freewheel - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_release_timebase - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_set_timebase_callback - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_get_internal_clientname - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_internal_clienthandle - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_internal_clientload - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_internal_clientunload - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xrpc_jack_client_rt_notify - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_client_open_t__defined) -#define __MIG_check__Request__rpc_jack_client_open_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__client_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__client_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__int_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 64) -#elif defined(__NDR_convert__int_rep__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_open_t__pid__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__pid__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__pid(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__pid__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__pid(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__pid__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__pid(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__pid__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__pid(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_open_t__pid__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__client_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__client_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__char_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 64) -#elif defined(__NDR_convert__char_rep__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_open_t__pid__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__pid__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__pid(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__pid__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__pid(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__pid__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__pid(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__pid__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__pid(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_open_t__pid__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__client_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__client_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__float_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 64) -#elif defined(__NDR_convert__float_rep__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_open_t__pid__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__pid__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__pid(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__pid__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__pid(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__pid__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__pid(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__pid__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__pid(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_open_t__pid__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_open_t(__attribute__((__unused__)) __Request__rpc_jack_client_open_t *In0P) -{ - - typedef __Request__rpc_jack_client_open_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if __MigTypeCheck - { - char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; - size_t memchr_limit; - - memchr_limit = min((msg_limit - In0P->client_name), 64); - if (( memchr(In0P->client_name, '\0', memchr_limit) == NULL )) - return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! - } -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_client_open_t__pid__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name(&In0P->client_name, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_open_t__pid__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_open_t__pid(&In0P->pid, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_open_t__pid__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_client_open_t__pid__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name(&In0P->client_name, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_open_t__pid__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_open_t__pid(&In0P->pid, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_open_t__pid__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_client_open_t__pid__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name(&In0P->client_name, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_open_t__pid__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_open_t__pid(&In0P->pid, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_open_t__pid__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_client_open_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_client_open */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_client_open -( - mach_port_t server_port, - client_name_t client_name, - int pid, - mach_port_t *private_port, - int *shared_engine, - int *shared_client, - int *shared_graph, - int *result -); - -/* Routine rpc_jack_client_open */ -mig_internal novalue _Xrpc_jack_client_open - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - client_name_t client_name; - int pid; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_client_open_t __Request; - typedef __Reply__rpc_jack_client_open_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_client_open_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_client_open_t__defined */ - -#if UseStaticTemplates - const static mach_msg_port_descriptor_t private_portTemplate = { - /* name = */ MACH_PORT_NULL, - /* pad1 = */ 0, - /* pad2 = */ 0, - /* disp = */ 20, - /* type = */ MACH_MSG_PORT_DESCRIPTOR, - }; -#endif /* UseStaticTemplates */ - - kern_return_t RetCode; - __DeclareRcvRpc(1000, "rpc_jack_client_open") - __BeforeRcvRpc(1000, "rpc_jack_client_open") - -#if defined(__MIG_check__Request__rpc_jack_client_open_t__defined) - check_result = __MIG_check__Request__rpc_jack_client_open_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_client_open_t__defined) */ - -#if UseStaticTemplates - OutP->private_port = private_portTemplate; -#else /* UseStaticTemplates */ - OutP->private_port.disposition = 20; - OutP->private_port.type = MACH_MSG_PORT_DESCRIPTOR; -#endif /* UseStaticTemplates */ - - - RetCode = server_rpc_jack_client_open(In0P->Head.msgh_request_port, In0P->client_name, In0P->pid, &OutP->private_port.name, &OutP->shared_engine, &OutP->shared_client, &OutP->shared_graph, &OutP->result); - if (RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_bits |= MACH_MSGH_BITS_COMPLEX; - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - OutP->msgh_body.msgh_descriptor_count = 1; - __AfterRcvRpc(1000, "rpc_jack_client_open") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_client_check_t__defined) -#define __MIG_check__Request__rpc_jack_client_check_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__client_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__client_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__int_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 64) -#elif defined(__NDR_convert__int_rep__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_check_t__protocol__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__protocol__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__protocol(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__protocol__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__protocol(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__protocol__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__protocol(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__protocol__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__protocol(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_check_t__protocol__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_check_t__options__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__options__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__options(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__options__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__options(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__options__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__options(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__options__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__options(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_check_t__options__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__client_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__client_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__char_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 64) -#elif defined(__NDR_convert__char_rep__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_check_t__protocol__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__protocol__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__protocol(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__protocol__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__protocol(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__protocol__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__protocol(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__protocol__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__protocol(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_check_t__protocol__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_check_t__options__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__options__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__options(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__options__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__options(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__options__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__options(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__options__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__options(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_check_t__options__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__client_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__client_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__float_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 64) -#elif defined(__NDR_convert__float_rep__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_check_t__protocol__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__protocol__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__protocol(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__protocol__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__protocol(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__protocol__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__protocol(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__protocol__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__protocol(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_check_t__protocol__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_check_t__options__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__options__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__options(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__options__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__options(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__options__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__options(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__options__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__options(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_check_t__options__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_check_t(__attribute__((__unused__)) __Request__rpc_jack_client_check_t *In0P) -{ - - typedef __Request__rpc_jack_client_check_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if __MigTypeCheck - { - char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; - size_t memchr_limit; - - memchr_limit = min((msg_limit - In0P->client_name), 64); - if (( memchr(In0P->client_name, '\0', memchr_limit) == NULL )) - return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! - } -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_client_check_t__protocol__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_client_check_t__options__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name(&In0P->client_name, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_check_t__protocol__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_check_t__protocol(&In0P->protocol, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_check_t__protocol__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_check_t__options__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_check_t__options(&In0P->options, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_check_t__options__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_client_check_t__protocol__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_client_check_t__options__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name(&In0P->client_name, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_check_t__protocol__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_check_t__protocol(&In0P->protocol, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_check_t__protocol__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_check_t__options__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_check_t__options(&In0P->options, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_check_t__options__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_client_check_t__protocol__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_client_check_t__options__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name(&In0P->client_name, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_check_t__protocol__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_check_t__protocol(&In0P->protocol, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_check_t__protocol__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_check_t__options__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_check_t__options(&In0P->options, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_check_t__options__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_client_check_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_client_check */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_client_check -( - mach_port_t server_port, - client_name_t client_name, - client_name_t client_name_res, - int protocol, - int options, - int *status, - int *result -); - -/* Routine rpc_jack_client_check */ -mig_internal novalue _Xrpc_jack_client_check - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - client_name_t client_name; - int protocol; - int options; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_client_check_t __Request; - typedef __Reply__rpc_jack_client_check_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_client_check_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_client_check_t__defined */ - - __DeclareRcvRpc(1001, "rpc_jack_client_check") - __BeforeRcvRpc(1001, "rpc_jack_client_check") - -#if defined(__MIG_check__Request__rpc_jack_client_check_t__defined) - check_result = __MIG_check__Request__rpc_jack_client_check_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_client_check_t__defined) */ - - OutP->RetCode = server_rpc_jack_client_check(In0P->Head.msgh_request_port, In0P->client_name, OutP->client_name_res, In0P->protocol, In0P->options, &OutP->status, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1001, "rpc_jack_client_check") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_client_close_t__defined) -#define __MIG_check__Request__rpc_jack_client_close_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_close_t__refnum__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_close_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_close_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_close_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_close_t__refnum(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_close_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_close_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_close_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_close_t__refnum(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_close_t__refnum__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_close_t__refnum__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_close_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_close_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_close_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_close_t__refnum(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_close_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_close_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_close_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_close_t__refnum(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_close_t__refnum__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_close_t__refnum__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_close_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_close_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_close_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_close_t__refnum(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_close_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_close_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_close_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_close_t__refnum(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_close_t__refnum__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_close_t(__attribute__((__unused__)) __Request__rpc_jack_client_close_t *In0P) -{ - - typedef __Request__rpc_jack_client_close_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_close_t__refnum__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_close_t__refnum__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_close_t__refnum(&In0P->refnum, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_close_t__refnum__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_close_t__refnum__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_close_t__refnum__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_close_t__refnum(&In0P->refnum, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_close_t__refnum__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_close_t__refnum__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_close_t__refnum__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_close_t__refnum(&In0P->refnum, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_close_t__refnum__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_client_close_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_client_close */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_client_close -( - mach_port_t server_port, - int refnum, - int *result -); - -/* Routine rpc_jack_client_close */ -mig_internal novalue _Xrpc_jack_client_close - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_client_close_t __Request; - typedef __Reply__rpc_jack_client_close_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_client_close_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_client_close_t__defined */ - - __DeclareRcvRpc(1002, "rpc_jack_client_close") - __BeforeRcvRpc(1002, "rpc_jack_client_close") - -#if defined(__MIG_check__Request__rpc_jack_client_close_t__defined) - check_result = __MIG_check__Request__rpc_jack_client_close_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_client_close_t__defined) */ - - OutP->RetCode = server_rpc_jack_client_close(In0P->Head.msgh_request_port, In0P->refnum, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1002, "rpc_jack_client_close") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_client_activate_t__defined) -#define __MIG_check__Request__rpc_jack_client_activate_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__refnum__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__refnum(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__refnum(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__refnum__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__state__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__state__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__state(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__state__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__state(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__state__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__state(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__state__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__state(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__state__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__refnum__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__refnum(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__refnum(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__refnum__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__state__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__state__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__state(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__state__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__state(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__state__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__state(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__state__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__state(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__state__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__refnum__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__refnum(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__refnum(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__refnum__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__state__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__state__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__state(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__state__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__state(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__state__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__state(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__state__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__state(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__state__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_activate_t(__attribute__((__unused__)) __Request__rpc_jack_client_activate_t *In0P) -{ - - typedef __Request__rpc_jack_client_activate_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_activate_t__refnum__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_client_activate_t__state__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_activate_t__refnum__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__refnum(&In0P->refnum, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__refnum__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_activate_t__state__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__state(&In0P->state, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_activate_t__state__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_activate_t__refnum__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_client_activate_t__state__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_activate_t__refnum__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__refnum(&In0P->refnum, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__refnum__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_activate_t__state__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__state(&In0P->state, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_activate_t__state__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_activate_t__refnum__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_client_activate_t__state__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_activate_t__refnum__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__refnum(&In0P->refnum, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__refnum__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_activate_t__state__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__state(&In0P->state, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_activate_t__state__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_client_activate_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_client_activate */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_client_activate -( - mach_port_t server_port, - int refnum, - int state, - int *result -); - -/* Routine rpc_jack_client_activate */ -mig_internal novalue _Xrpc_jack_client_activate - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int state; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_client_activate_t __Request; - typedef __Reply__rpc_jack_client_activate_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_client_activate_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_client_activate_t__defined */ - - __DeclareRcvRpc(1003, "rpc_jack_client_activate") - __BeforeRcvRpc(1003, "rpc_jack_client_activate") - -#if defined(__MIG_check__Request__rpc_jack_client_activate_t__defined) - check_result = __MIG_check__Request__rpc_jack_client_activate_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_client_activate_t__defined) */ - - OutP->RetCode = server_rpc_jack_client_activate(In0P->Head.msgh_request_port, In0P->refnum, In0P->state, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1003, "rpc_jack_client_activate") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_client_deactivate_t__defined) -#define __MIG_check__Request__rpc_jack_client_deactivate_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_deactivate_t__refnum__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_deactivate_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_deactivate_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_deactivate_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_deactivate_t__refnum(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_deactivate_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_deactivate_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_deactivate_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_deactivate_t__refnum(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_deactivate_t__refnum__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_deactivate_t__refnum__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_deactivate_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_deactivate_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_deactivate_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_deactivate_t__refnum(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_deactivate_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_deactivate_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_deactivate_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_deactivate_t__refnum(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_deactivate_t__refnum__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_deactivate_t__refnum__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_deactivate_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_deactivate_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_deactivate_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_deactivate_t__refnum(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_deactivate_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_deactivate_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_deactivate_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_deactivate_t__refnum(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_deactivate_t__refnum__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_deactivate_t(__attribute__((__unused__)) __Request__rpc_jack_client_deactivate_t *In0P) -{ - - typedef __Request__rpc_jack_client_deactivate_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_deactivate_t__refnum__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_deactivate_t__refnum__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_deactivate_t__refnum(&In0P->refnum, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_deactivate_t__refnum__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_deactivate_t__refnum__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_deactivate_t__refnum__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_deactivate_t__refnum(&In0P->refnum, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_deactivate_t__refnum__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_deactivate_t__refnum__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_deactivate_t__refnum__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_deactivate_t__refnum(&In0P->refnum, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_deactivate_t__refnum__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_client_deactivate_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_client_deactivate */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_client_deactivate -( - mach_port_t server_port, - int refnum, - int *result -); - -/* Routine rpc_jack_client_deactivate */ -mig_internal novalue _Xrpc_jack_client_deactivate - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_client_deactivate_t __Request; - typedef __Reply__rpc_jack_client_deactivate_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_client_deactivate_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_client_deactivate_t__defined */ - - __DeclareRcvRpc(1004, "rpc_jack_client_deactivate") - __BeforeRcvRpc(1004, "rpc_jack_client_deactivate") - -#if defined(__MIG_check__Request__rpc_jack_client_deactivate_t__defined) - check_result = __MIG_check__Request__rpc_jack_client_deactivate_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_client_deactivate_t__defined) */ - - OutP->RetCode = server_rpc_jack_client_deactivate(In0P->Head.msgh_request_port, In0P->refnum, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1004, "rpc_jack_client_deactivate") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_port_register_t__defined) -#define __MIG_check__Request__rpc_jack_port_register_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_register_t__refnum__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__refnum(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__refnum(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_register_t__refnum__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_register_t__name__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__client_port_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__client_port_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__name(a, f) \ - __NDR_convert__int_rep__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__int_rep__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__name(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_register_t__name__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__client_port_type_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__client_port_type_t((client_port_type_t *)(a), f) -#elif defined(__NDR_convert__int_rep__client_port_type_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ - __NDR_convert__int_rep__client_port_type_t((client_port_type_t *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__int_rep__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__unsigned__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__unsigned((unsigned *)(a), f) -#elif defined(__NDR_convert__int_rep__unsigned__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags(a, f) \ - __NDR_convert__int_rep__unsigned((unsigned *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__uint32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__uint32_t((uint32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__uint32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags(a, f) \ - __NDR_convert__int_rep__uint32_t((uint32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_register_t__buffer_size__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__unsigned__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__buffer_size__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__buffer_size(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__unsigned((unsigned *)(a), f) -#elif defined(__NDR_convert__int_rep__unsigned__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__buffer_size__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__buffer_size(a, f) \ - __NDR_convert__int_rep__unsigned((unsigned *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__uint32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__buffer_size__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__buffer_size(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__uint32_t((uint32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__uint32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__buffer_size__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__buffer_size(a, f) \ - __NDR_convert__int_rep__uint32_t((uint32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_register_t__buffer_size__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_register_t__refnum__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__refnum(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__refnum(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_register_t__refnum__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_register_t__name__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__client_port_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__client_port_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__name(a, f) \ - __NDR_convert__char_rep__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__char_rep__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__name(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_register_t__name__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__client_port_type_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__client_port_type_t((client_port_type_t *)(a), f) -#elif defined(__NDR_convert__char_rep__client_port_type_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ - __NDR_convert__char_rep__client_port_type_t((client_port_type_t *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__char_rep__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__unsigned__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__unsigned((unsigned *)(a), f) -#elif defined(__NDR_convert__char_rep__unsigned__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags(a, f) \ - __NDR_convert__char_rep__unsigned((unsigned *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__uint32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__uint32_t((uint32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__uint32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags(a, f) \ - __NDR_convert__char_rep__uint32_t((uint32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_register_t__buffer_size__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__unsigned__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__buffer_size__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__buffer_size(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__unsigned((unsigned *)(a), f) -#elif defined(__NDR_convert__char_rep__unsigned__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__buffer_size__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__buffer_size(a, f) \ - __NDR_convert__char_rep__unsigned((unsigned *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__uint32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__buffer_size__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__buffer_size(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__uint32_t((uint32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__uint32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__buffer_size__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__buffer_size(a, f) \ - __NDR_convert__char_rep__uint32_t((uint32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_register_t__buffer_size__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_register_t__refnum__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__refnum(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__refnum(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_register_t__refnum__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_register_t__name__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__client_port_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__client_port_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__name(a, f) \ - __NDR_convert__float_rep__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__float_rep__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__name(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_register_t__name__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__client_port_type_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__client_port_type_t((client_port_type_t *)(a), f) -#elif defined(__NDR_convert__float_rep__client_port_type_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ - __NDR_convert__float_rep__client_port_type_t((client_port_type_t *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__float_rep__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__unsigned__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__unsigned((unsigned *)(a), f) -#elif defined(__NDR_convert__float_rep__unsigned__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags(a, f) \ - __NDR_convert__float_rep__unsigned((unsigned *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__uint32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__uint32_t((uint32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__uint32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags(a, f) \ - __NDR_convert__float_rep__uint32_t((uint32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_register_t__buffer_size__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__unsigned__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__buffer_size__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__buffer_size(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__unsigned((unsigned *)(a), f) -#elif defined(__NDR_convert__float_rep__unsigned__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__buffer_size__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__buffer_size(a, f) \ - __NDR_convert__float_rep__unsigned((unsigned *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__uint32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__buffer_size__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__buffer_size(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__uint32_t((uint32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__uint32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__buffer_size__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__buffer_size(a, f) \ - __NDR_convert__float_rep__uint32_t((uint32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_register_t__buffer_size__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_register_t(__attribute__((__unused__)) __Request__rpc_jack_port_register_t *In0P) -{ - - typedef __Request__rpc_jack_port_register_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if __MigTypeCheck - { - char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; - size_t memchr_limit; - - memchr_limit = min((msg_limit - In0P->name), 128); - if (( memchr(In0P->name, '\0', memchr_limit) == NULL )) - return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! - memchr_limit = min((msg_limit - In0P->port_type), 128); - if (( memchr(In0P->port_type, '\0', memchr_limit) == NULL )) - return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! - } -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__refnum__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__name__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__buffer_size__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__refnum__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_register_t__refnum(&In0P->refnum, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_register_t__refnum__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__name__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_register_t__name(&In0P->name, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_register_t__name__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type(&In0P->port_type, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags(&In0P->flags, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__buffer_size__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_register_t__buffer_size(&In0P->buffer_size, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_register_t__buffer_size__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_register_t__refnum__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_port_register_t__name__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_port_register_t__buffer_size__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_register_t__refnum__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_register_t__refnum(&In0P->refnum, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_register_t__refnum__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_register_t__name__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_register_t__name(&In0P->name, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_register_t__name__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type(&In0P->port_type, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags(&In0P->flags, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_register_t__buffer_size__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_register_t__buffer_size(&In0P->buffer_size, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_register_t__buffer_size__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_register_t__refnum__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_port_register_t__name__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_port_register_t__buffer_size__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_register_t__refnum__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_register_t__refnum(&In0P->refnum, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_register_t__refnum__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_register_t__name__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_register_t__name(&In0P->name, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_register_t__name__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type(&In0P->port_type, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags(&In0P->flags, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_register_t__buffer_size__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_register_t__buffer_size(&In0P->buffer_size, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_register_t__buffer_size__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_port_register_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_port_register */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_port_register -( - mach_port_t server_port, - int refnum, - client_port_name_t name, - client_port_type_t port_type, - unsigned flags, - unsigned buffer_size, - unsigned *port_index, - int *result -); - -/* Routine rpc_jack_port_register */ -mig_internal novalue _Xrpc_jack_port_register - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_port_name_t name; - client_port_type_t port_type; - unsigned flags; - unsigned buffer_size; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_port_register_t __Request; - typedef __Reply__rpc_jack_port_register_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_port_register_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_port_register_t__defined */ - - __DeclareRcvRpc(1005, "rpc_jack_port_register") - __BeforeRcvRpc(1005, "rpc_jack_port_register") - -#if defined(__MIG_check__Request__rpc_jack_port_register_t__defined) - check_result = __MIG_check__Request__rpc_jack_port_register_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_port_register_t__defined) */ - - OutP->RetCode = server_rpc_jack_port_register(In0P->Head.msgh_request_port, In0P->refnum, In0P->name, In0P->port_type, In0P->flags, In0P->buffer_size, &OutP->port_index, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1005, "rpc_jack_port_register") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_port_unregister_t__defined) -#define __MIG_check__Request__rpc_jack_port_unregister_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__refnum__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__refnum(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__refnum(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__refnum__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__port__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__port__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__port(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__port__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__port(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__port__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__port(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__port__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__port(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__port__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__refnum__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__refnum(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__refnum(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__refnum__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__port__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__port__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__port(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__port__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__port(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__port__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__port(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__port__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__port(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__port__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__refnum__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__refnum(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__refnum(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__refnum__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__port__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__port__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__port(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__port__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__port(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__port__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__port(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__port__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__port(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__port__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_unregister_t(__attribute__((__unused__)) __Request__rpc_jack_port_unregister_t *In0P) -{ - - typedef __Request__rpc_jack_port_unregister_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__refnum__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__port__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__refnum__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__refnum(&In0P->refnum, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__refnum__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__port__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__port(&In0P->port, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_unregister_t__port__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__refnum__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__port__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__refnum__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__refnum(&In0P->refnum, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__refnum__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__port__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__port(&In0P->port, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_unregister_t__port__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__refnum__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__port__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__refnum__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__refnum(&In0P->refnum, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__refnum__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__port__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__port(&In0P->port, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_unregister_t__port__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_port_unregister_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_port_unregister */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_port_unregister -( - mach_port_t server_port, - int refnum, - int port, - int *result -); - -/* Routine rpc_jack_port_unregister */ -mig_internal novalue _Xrpc_jack_port_unregister - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int port; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_port_unregister_t __Request; - typedef __Reply__rpc_jack_port_unregister_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_port_unregister_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_port_unregister_t__defined */ - - __DeclareRcvRpc(1006, "rpc_jack_port_unregister") - __BeforeRcvRpc(1006, "rpc_jack_port_unregister") - -#if defined(__MIG_check__Request__rpc_jack_port_unregister_t__defined) - check_result = __MIG_check__Request__rpc_jack_port_unregister_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_port_unregister_t__defined) */ - - OutP->RetCode = server_rpc_jack_port_unregister(In0P->Head.msgh_request_port, In0P->refnum, In0P->port, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1006, "rpc_jack_port_unregister") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_port_connect_t__defined) -#define __MIG_check__Request__rpc_jack_port_connect_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__refnum__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__refnum(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__refnum(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__refnum__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__src__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__src(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__src(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__src(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__src(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__src__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__dst__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__dst__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__dst(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__dst__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__dst(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__dst__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__dst(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__dst__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__dst(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__dst__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__refnum__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__refnum(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__refnum(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__refnum__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__src__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__src(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__src(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__src(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__src(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__src__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__dst__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__dst__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__dst(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__dst__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__dst(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__dst__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__dst(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__dst__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__dst(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__dst__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__refnum__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__refnum(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__refnum(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__refnum__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__src__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__src(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__src(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__src(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__src(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__src__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__dst__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__dst__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__dst(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__dst__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__dst(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__dst__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__dst(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__dst__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__dst(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__dst__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_connect_t(__attribute__((__unused__)) __Request__rpc_jack_port_connect_t *In0P) -{ - - typedef __Request__rpc_jack_port_connect_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_connect_t__refnum__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_port_connect_t__src__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_port_connect_t__dst__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_connect_t__refnum__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__refnum(&In0P->refnum, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__refnum__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_connect_t__src__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__src(&In0P->src, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__src__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_connect_t__dst__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__dst(&In0P->dst, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_connect_t__dst__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_connect_t__refnum__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_port_connect_t__src__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_port_connect_t__dst__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_connect_t__refnum__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__refnum(&In0P->refnum, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__refnum__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_connect_t__src__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__src(&In0P->src, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__src__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_connect_t__dst__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__dst(&In0P->dst, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_connect_t__dst__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_connect_t__refnum__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_port_connect_t__src__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_port_connect_t__dst__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_connect_t__refnum__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__refnum(&In0P->refnum, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__refnum__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_connect_t__src__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__src(&In0P->src, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__src__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_connect_t__dst__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__dst(&In0P->dst, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_connect_t__dst__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_port_connect_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_port_connect */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_port_connect -( - mach_port_t server_port, - int refnum, - int src, - int dst, - int *result -); - -/* Routine rpc_jack_port_connect */ -mig_internal novalue _Xrpc_jack_port_connect - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int src; - int dst; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_port_connect_t __Request; - typedef __Reply__rpc_jack_port_connect_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_port_connect_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_port_connect_t__defined */ - - __DeclareRcvRpc(1007, "rpc_jack_port_connect") - __BeforeRcvRpc(1007, "rpc_jack_port_connect") - -#if defined(__MIG_check__Request__rpc_jack_port_connect_t__defined) - check_result = __MIG_check__Request__rpc_jack_port_connect_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_port_connect_t__defined) */ - - OutP->RetCode = server_rpc_jack_port_connect(In0P->Head.msgh_request_port, In0P->refnum, In0P->src, In0P->dst, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1007, "rpc_jack_port_connect") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_port_disconnect_t__defined) -#define __MIG_check__Request__rpc_jack_port_disconnect_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__refnum__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__refnum(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__refnum(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__refnum__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__src__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__src(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__src(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__src(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__src(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__src__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__dst__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__dst__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__dst(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__dst__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__dst(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__dst__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__dst(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__dst__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__dst(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__dst__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__refnum__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__refnum(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__refnum(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__refnum__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__src__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__src(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__src(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__src(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__src(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__src__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__dst__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__dst__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__dst(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__dst__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__dst(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__dst__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__dst(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__dst__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__dst(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__dst__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__refnum__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__refnum(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__refnum(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__refnum__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__src__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__src(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__src(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__src(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__src(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__src__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__dst__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__dst__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__dst(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__dst__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__dst(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__dst__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__dst(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__dst__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__dst(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__dst__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_disconnect_t(__attribute__((__unused__)) __Request__rpc_jack_port_disconnect_t *In0P) -{ - - typedef __Request__rpc_jack_port_disconnect_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__refnum__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__src__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__dst__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__refnum__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__refnum(&In0P->refnum, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__refnum__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__src__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__src(&In0P->src, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__src__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__dst__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__dst(&In0P->dst, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_t__dst__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__refnum__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__src__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__dst__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__refnum__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__refnum(&In0P->refnum, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__refnum__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__src__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__src(&In0P->src, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__src__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__dst__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__dst(&In0P->dst, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_t__dst__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__refnum__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__src__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__dst__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__refnum__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__refnum(&In0P->refnum, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__refnum__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__src__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__src(&In0P->src, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__src__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__dst__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__dst(&In0P->dst, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_t__dst__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_port_disconnect_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_port_disconnect */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_port_disconnect -( - mach_port_t server_port, - int refnum, - int src, - int dst, - int *result -); - -/* Routine rpc_jack_port_disconnect */ -mig_internal novalue _Xrpc_jack_port_disconnect - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int src; - int dst; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_port_disconnect_t __Request; - typedef __Reply__rpc_jack_port_disconnect_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_port_disconnect_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_port_disconnect_t__defined */ - - __DeclareRcvRpc(1008, "rpc_jack_port_disconnect") - __BeforeRcvRpc(1008, "rpc_jack_port_disconnect") - -#if defined(__MIG_check__Request__rpc_jack_port_disconnect_t__defined) - check_result = __MIG_check__Request__rpc_jack_port_disconnect_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_port_disconnect_t__defined) */ - - OutP->RetCode = server_rpc_jack_port_disconnect(In0P->Head.msgh_request_port, In0P->refnum, In0P->src, In0P->dst, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1008, "rpc_jack_port_disconnect") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_port_connect_name_t__defined) -#define __MIG_check__Request__rpc_jack_port_connect_name_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__refnum__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__refnum(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__refnum(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__refnum__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__src__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__client_port_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__src(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__client_port_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__src(a, f) \ - __NDR_convert__int_rep__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__src(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__int_rep__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__src(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__src__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__dst__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__client_port_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__dst__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__dst(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__client_port_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__dst__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__dst(a, f) \ - __NDR_convert__int_rep__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__dst__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__dst(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__int_rep__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__dst__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__dst(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__dst__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__refnum__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__refnum(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__refnum(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__refnum__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__src__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__client_port_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__src(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__client_port_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__src(a, f) \ - __NDR_convert__char_rep__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__src(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__char_rep__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__src(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__src__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__dst__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__client_port_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__dst__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__dst(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__client_port_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__dst__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__dst(a, f) \ - __NDR_convert__char_rep__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__dst__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__dst(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__char_rep__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__dst__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__dst(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__dst__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__refnum__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__refnum(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__refnum(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__refnum__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__src__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__client_port_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__src(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__client_port_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__src(a, f) \ - __NDR_convert__float_rep__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__src(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__float_rep__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__src(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__src__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__dst__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__client_port_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__dst__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__dst(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__client_port_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__dst__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__dst(a, f) \ - __NDR_convert__float_rep__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__dst__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__dst(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__float_rep__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__dst__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__dst(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__dst__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_connect_name_t(__attribute__((__unused__)) __Request__rpc_jack_port_connect_name_t *In0P) -{ - - typedef __Request__rpc_jack_port_connect_name_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if __MigTypeCheck - { - char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; - size_t memchr_limit; - - memchr_limit = min((msg_limit - In0P->src), 128); - if (( memchr(In0P->src, '\0', memchr_limit) == NULL )) - return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! - memchr_limit = min((msg_limit - In0P->dst), 128); - if (( memchr(In0P->dst, '\0', memchr_limit) == NULL )) - return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! - } -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__refnum__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__src__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__dst__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__refnum__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__refnum(&In0P->refnum, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__refnum__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__src__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__src(&In0P->src, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__src__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__dst__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__dst(&In0P->dst, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__dst__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__refnum__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__src__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__dst__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__refnum__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__refnum(&In0P->refnum, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__refnum__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__src__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__src(&In0P->src, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__src__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__dst__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__dst(&In0P->dst, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_connect_name_t__dst__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__refnum__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__src__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__dst__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__refnum__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__refnum(&In0P->refnum, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__refnum__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__src__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__src(&In0P->src, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__src__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__dst__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__dst(&In0P->dst, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_connect_name_t__dst__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_port_connect_name_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_port_connect_name */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_port_connect_name -( - mach_port_t server_port, - int refnum, - client_port_name_t src, - client_port_name_t dst, - int *result -); - -/* Routine rpc_jack_port_connect_name */ -mig_internal novalue _Xrpc_jack_port_connect_name - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_port_name_t src; - client_port_name_t dst; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_port_connect_name_t __Request; - typedef __Reply__rpc_jack_port_connect_name_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_port_connect_name_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_port_connect_name_t__defined */ - - __DeclareRcvRpc(1009, "rpc_jack_port_connect_name") - __BeforeRcvRpc(1009, "rpc_jack_port_connect_name") - -#if defined(__MIG_check__Request__rpc_jack_port_connect_name_t__defined) - check_result = __MIG_check__Request__rpc_jack_port_connect_name_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_port_connect_name_t__defined) */ - - OutP->RetCode = server_rpc_jack_port_connect_name(In0P->Head.msgh_request_port, In0P->refnum, In0P->src, In0P->dst, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1009, "rpc_jack_port_connect_name") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_port_disconnect_name_t__defined) -#define __MIG_check__Request__rpc_jack_port_disconnect_name_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__refnum(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__refnum(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__src__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__client_port_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__src(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__client_port_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__src(a, f) \ - __NDR_convert__int_rep__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__src(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__int_rep__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__src(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__src__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__client_port_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__dst(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__client_port_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__dst(a, f) \ - __NDR_convert__int_rep__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__dst(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__int_rep__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__dst(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__refnum(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__refnum(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__src__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__client_port_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__src(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__client_port_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__src(a, f) \ - __NDR_convert__char_rep__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__src(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__char_rep__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__src(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__src__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__client_port_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__dst(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__client_port_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__dst(a, f) \ - __NDR_convert__char_rep__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__dst(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__char_rep__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__dst(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__refnum(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__refnum(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__src__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__client_port_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__src(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__client_port_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__src(a, f) \ - __NDR_convert__float_rep__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__src(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__float_rep__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__src(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__src__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__client_port_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__dst(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__client_port_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__dst(a, f) \ - __NDR_convert__float_rep__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__dst(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__float_rep__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__dst(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_disconnect_name_t(__attribute__((__unused__)) __Request__rpc_jack_port_disconnect_name_t *In0P) -{ - - typedef __Request__rpc_jack_port_disconnect_name_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if __MigTypeCheck - { - char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; - size_t memchr_limit; - - memchr_limit = min((msg_limit - In0P->src), 128); - if (( memchr(In0P->src, '\0', memchr_limit) == NULL )) - return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! - memchr_limit = min((msg_limit - In0P->dst), 128); - if (( memchr(In0P->dst, '\0', memchr_limit) == NULL )) - return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! - } -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__src__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__refnum(&In0P->refnum, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__src__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__src(&In0P->src, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__src__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__dst(&In0P->dst, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__src__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__refnum(&In0P->refnum, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__src__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__src(&In0P->src, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__src__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__dst(&In0P->dst, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__src__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__refnum(&In0P->refnum, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__src__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__src(&In0P->src, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__src__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__dst(&In0P->dst, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_port_disconnect_name_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_port_disconnect_name */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_port_disconnect_name -( - mach_port_t server_port, - int refnum, - client_port_name_t src, - client_port_name_t dst, - int *result -); - -/* Routine rpc_jack_port_disconnect_name */ -mig_internal novalue _Xrpc_jack_port_disconnect_name - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_port_name_t src; - client_port_name_t dst; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_port_disconnect_name_t __Request; - typedef __Reply__rpc_jack_port_disconnect_name_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_port_disconnect_name_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_port_disconnect_name_t__defined */ - - __DeclareRcvRpc(1010, "rpc_jack_port_disconnect_name") - __BeforeRcvRpc(1010, "rpc_jack_port_disconnect_name") - -#if defined(__MIG_check__Request__rpc_jack_port_disconnect_name_t__defined) - check_result = __MIG_check__Request__rpc_jack_port_disconnect_name_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_port_disconnect_name_t__defined) */ - - OutP->RetCode = server_rpc_jack_port_disconnect_name(In0P->Head.msgh_request_port, In0P->refnum, In0P->src, In0P->dst, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1010, "rpc_jack_port_disconnect_name") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_port_rename_t__defined) -#define __MIG_check__Request__rpc_jack_port_rename_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__refnum__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__refnum(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__refnum(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__refnum__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__src__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__src(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__src(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__src(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__src__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__src(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__src__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__name__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__client_port_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__client_port_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__name(a, f) \ - __NDR_convert__int_rep__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__int_rep__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__name(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__name__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__refnum__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__refnum(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__refnum(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__refnum__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__src__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__src(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__src(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__src(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__src__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__src(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__src__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__name__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__client_port_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__client_port_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__name(a, f) \ - __NDR_convert__char_rep__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__char_rep__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__name(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__name__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__refnum__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__refnum(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__refnum(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__refnum__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__src__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__src(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__src(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__src(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__src__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__src(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__src__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__name__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__client_port_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__client_port_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__name(a, f) \ - __NDR_convert__float_rep__client_port_name_t((client_port_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) -#elif defined(__NDR_convert__float_rep__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__name(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__name__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_rename_t(__attribute__((__unused__)) __Request__rpc_jack_port_rename_t *In0P) -{ - - typedef __Request__rpc_jack_port_rename_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if __MigTypeCheck - { - char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; - size_t memchr_limit; - - memchr_limit = min((msg_limit - In0P->name), 128); - if (( memchr(In0P->name, '\0', memchr_limit) == NULL )) - return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! - } -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_rename_t__refnum__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_port_rename_t__src__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_port_rename_t__name__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_rename_t__refnum__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__refnum(&In0P->refnum, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__refnum__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_rename_t__src__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__src(&In0P->src, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__src__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_rename_t__name__defined) - __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__name(&In0P->name, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_rename_t__name__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_rename_t__refnum__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_port_rename_t__src__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_port_rename_t__name__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_rename_t__refnum__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__refnum(&In0P->refnum, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__refnum__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_rename_t__src__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__src(&In0P->src, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__src__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_rename_t__name__defined) - __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__name(&In0P->name, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_rename_t__name__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_rename_t__refnum__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_port_rename_t__src__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_port_rename_t__name__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_rename_t__refnum__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__refnum(&In0P->refnum, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__refnum__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_rename_t__src__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__src(&In0P->src, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__src__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_rename_t__name__defined) - __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__name(&In0P->name, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_rename_t__name__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_port_rename_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_port_rename */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_port_rename -( - mach_port_t server_port, - int refnum, - int src, - client_port_name_t name, - int *result -); - -/* Routine rpc_jack_port_rename */ -mig_internal novalue _Xrpc_jack_port_rename - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int src; - client_port_name_t name; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_port_rename_t __Request; - typedef __Reply__rpc_jack_port_rename_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_port_rename_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_port_rename_t__defined */ - - __DeclareRcvRpc(1011, "rpc_jack_port_rename") - __BeforeRcvRpc(1011, "rpc_jack_port_rename") - -#if defined(__MIG_check__Request__rpc_jack_port_rename_t__defined) - check_result = __MIG_check__Request__rpc_jack_port_rename_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_port_rename_t__defined) */ - - OutP->RetCode = server_rpc_jack_port_rename(In0P->Head.msgh_request_port, In0P->refnum, In0P->src, In0P->name, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1011, "rpc_jack_port_rename") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_set_buffer_size_t__defined) -#define __MIG_check__Request__rpc_jack_set_buffer_size_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined -#define __NDR_convert__int_rep__Request__rpc_jack_set_buffer_size_t__buffer_size(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined -#define __NDR_convert__int_rep__Request__rpc_jack_set_buffer_size_t__buffer_size(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined -#define __NDR_convert__int_rep__Request__rpc_jack_set_buffer_size_t__buffer_size(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined -#define __NDR_convert__int_rep__Request__rpc_jack_set_buffer_size_t__buffer_size(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined -#define __NDR_convert__char_rep__Request__rpc_jack_set_buffer_size_t__buffer_size(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined -#define __NDR_convert__char_rep__Request__rpc_jack_set_buffer_size_t__buffer_size(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined -#define __NDR_convert__char_rep__Request__rpc_jack_set_buffer_size_t__buffer_size(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined -#define __NDR_convert__char_rep__Request__rpc_jack_set_buffer_size_t__buffer_size(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined -#define __NDR_convert__float_rep__Request__rpc_jack_set_buffer_size_t__buffer_size(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined -#define __NDR_convert__float_rep__Request__rpc_jack_set_buffer_size_t__buffer_size(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined -#define __NDR_convert__float_rep__Request__rpc_jack_set_buffer_size_t__buffer_size(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined -#define __NDR_convert__float_rep__Request__rpc_jack_set_buffer_size_t__buffer_size(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_set_buffer_size_t(__attribute__((__unused__)) __Request__rpc_jack_set_buffer_size_t *In0P) -{ - - typedef __Request__rpc_jack_set_buffer_size_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined) - __NDR_convert__int_rep__Request__rpc_jack_set_buffer_size_t__buffer_size(&In0P->buffer_size, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined) - __NDR_convert__char_rep__Request__rpc_jack_set_buffer_size_t__buffer_size(&In0P->buffer_size, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined) - __NDR_convert__float_rep__Request__rpc_jack_set_buffer_size_t__buffer_size(&In0P->buffer_size, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_set_buffer_size_t__buffer_size__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_set_buffer_size_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_set_buffer_size */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_set_buffer_size -( - mach_port_t server_port, - int buffer_size, - int *result -); - -/* Routine rpc_jack_set_buffer_size */ -mig_internal novalue _Xrpc_jack_set_buffer_size - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int buffer_size; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_set_buffer_size_t __Request; - typedef __Reply__rpc_jack_set_buffer_size_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_set_buffer_size_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_set_buffer_size_t__defined */ - - __DeclareRcvRpc(1012, "rpc_jack_set_buffer_size") - __BeforeRcvRpc(1012, "rpc_jack_set_buffer_size") - -#if defined(__MIG_check__Request__rpc_jack_set_buffer_size_t__defined) - check_result = __MIG_check__Request__rpc_jack_set_buffer_size_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_set_buffer_size_t__defined) */ - - OutP->RetCode = server_rpc_jack_set_buffer_size(In0P->Head.msgh_request_port, In0P->buffer_size, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1012, "rpc_jack_set_buffer_size") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_set_freewheel_t__defined) -#define __MIG_check__Request__rpc_jack_set_freewheel_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_set_freewheel_t__onoff__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_set_freewheel_t__onoff__defined -#define __NDR_convert__int_rep__Request__rpc_jack_set_freewheel_t__onoff(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_set_freewheel_t__onoff__defined -#define __NDR_convert__int_rep__Request__rpc_jack_set_freewheel_t__onoff(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_set_freewheel_t__onoff__defined -#define __NDR_convert__int_rep__Request__rpc_jack_set_freewheel_t__onoff(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_set_freewheel_t__onoff__defined -#define __NDR_convert__int_rep__Request__rpc_jack_set_freewheel_t__onoff(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_set_freewheel_t__onoff__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_set_freewheel_t__onoff__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_set_freewheel_t__onoff__defined -#define __NDR_convert__char_rep__Request__rpc_jack_set_freewheel_t__onoff(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_set_freewheel_t__onoff__defined -#define __NDR_convert__char_rep__Request__rpc_jack_set_freewheel_t__onoff(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_set_freewheel_t__onoff__defined -#define __NDR_convert__char_rep__Request__rpc_jack_set_freewheel_t__onoff(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_set_freewheel_t__onoff__defined -#define __NDR_convert__char_rep__Request__rpc_jack_set_freewheel_t__onoff(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_set_freewheel_t__onoff__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_set_freewheel_t__onoff__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_set_freewheel_t__onoff__defined -#define __NDR_convert__float_rep__Request__rpc_jack_set_freewheel_t__onoff(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_set_freewheel_t__onoff__defined -#define __NDR_convert__float_rep__Request__rpc_jack_set_freewheel_t__onoff(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_set_freewheel_t__onoff__defined -#define __NDR_convert__float_rep__Request__rpc_jack_set_freewheel_t__onoff(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_set_freewheel_t__onoff__defined -#define __NDR_convert__float_rep__Request__rpc_jack_set_freewheel_t__onoff(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_set_freewheel_t__onoff__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_set_freewheel_t(__attribute__((__unused__)) __Request__rpc_jack_set_freewheel_t *In0P) -{ - - typedef __Request__rpc_jack_set_freewheel_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_set_freewheel_t__onoff__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_set_freewheel_t__onoff__defined) - __NDR_convert__int_rep__Request__rpc_jack_set_freewheel_t__onoff(&In0P->onoff, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_set_freewheel_t__onoff__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_set_freewheel_t__onoff__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_set_freewheel_t__onoff__defined) - __NDR_convert__char_rep__Request__rpc_jack_set_freewheel_t__onoff(&In0P->onoff, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_set_freewheel_t__onoff__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_set_freewheel_t__onoff__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_set_freewheel_t__onoff__defined) - __NDR_convert__float_rep__Request__rpc_jack_set_freewheel_t__onoff(&In0P->onoff, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_set_freewheel_t__onoff__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_set_freewheel_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_set_freewheel */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_set_freewheel -( - mach_port_t server_port, - int onoff, - int *result -); - -/* Routine rpc_jack_set_freewheel */ -mig_internal novalue _Xrpc_jack_set_freewheel - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int onoff; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_set_freewheel_t __Request; - typedef __Reply__rpc_jack_set_freewheel_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_set_freewheel_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_set_freewheel_t__defined */ - - __DeclareRcvRpc(1013, "rpc_jack_set_freewheel") - __BeforeRcvRpc(1013, "rpc_jack_set_freewheel") - -#if defined(__MIG_check__Request__rpc_jack_set_freewheel_t__defined) - check_result = __MIG_check__Request__rpc_jack_set_freewheel_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_set_freewheel_t__defined) */ - - OutP->RetCode = server_rpc_jack_set_freewheel(In0P->Head.msgh_request_port, In0P->onoff, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1013, "rpc_jack_set_freewheel") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_release_timebase_t__defined) -#define __MIG_check__Request__rpc_jack_release_timebase_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_release_timebase_t__refnum__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_release_timebase_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_release_timebase_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_release_timebase_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_release_timebase_t__refnum(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_release_timebase_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_release_timebase_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_release_timebase_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_release_timebase_t__refnum(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_release_timebase_t__refnum__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_release_timebase_t__refnum__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_release_timebase_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_release_timebase_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_release_timebase_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_release_timebase_t__refnum(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_release_timebase_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_release_timebase_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_release_timebase_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_release_timebase_t__refnum(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_release_timebase_t__refnum__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_release_timebase_t__refnum__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_release_timebase_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_release_timebase_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_release_timebase_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_release_timebase_t__refnum(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_release_timebase_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_release_timebase_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_release_timebase_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_release_timebase_t__refnum(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_release_timebase_t__refnum__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_release_timebase_t(__attribute__((__unused__)) __Request__rpc_jack_release_timebase_t *In0P) -{ - - typedef __Request__rpc_jack_release_timebase_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_release_timebase_t__refnum__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_release_timebase_t__refnum__defined) - __NDR_convert__int_rep__Request__rpc_jack_release_timebase_t__refnum(&In0P->refnum, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_release_timebase_t__refnum__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_release_timebase_t__refnum__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_release_timebase_t__refnum__defined) - __NDR_convert__char_rep__Request__rpc_jack_release_timebase_t__refnum(&In0P->refnum, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_release_timebase_t__refnum__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_release_timebase_t__refnum__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_release_timebase_t__refnum__defined) - __NDR_convert__float_rep__Request__rpc_jack_release_timebase_t__refnum(&In0P->refnum, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_release_timebase_t__refnum__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_release_timebase_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_release_timebase */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_release_timebase -( - mach_port_t server_port, - int refnum, - int *result -); - -/* Routine rpc_jack_release_timebase */ -mig_internal novalue _Xrpc_jack_release_timebase - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_release_timebase_t __Request; - typedef __Reply__rpc_jack_release_timebase_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_release_timebase_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_release_timebase_t__defined */ - - __DeclareRcvRpc(1014, "rpc_jack_release_timebase") - __BeforeRcvRpc(1014, "rpc_jack_release_timebase") - -#if defined(__MIG_check__Request__rpc_jack_release_timebase_t__defined) - check_result = __MIG_check__Request__rpc_jack_release_timebase_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_release_timebase_t__defined) */ - - OutP->RetCode = server_rpc_jack_release_timebase(In0P->Head.msgh_request_port, In0P->refnum, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1014, "rpc_jack_release_timebase") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_set_timebase_callback_t__defined) -#define __MIG_check__Request__rpc_jack_set_timebase_callback_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__refnum(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__refnum(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined -#define __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__conditional(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined -#define __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__conditional(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined -#define __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__conditional(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined -#define __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__conditional(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__refnum(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__refnum(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined -#define __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__conditional(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined -#define __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__conditional(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined -#define __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__conditional(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined -#define __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__conditional(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__refnum(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__refnum(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined -#define __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__conditional(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined -#define __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__conditional(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined -#define __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__conditional(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined -#define __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__conditional(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_set_timebase_callback_t(__attribute__((__unused__)) __Request__rpc_jack_set_timebase_callback_t *In0P) -{ - - typedef __Request__rpc_jack_set_timebase_callback_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined) - __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__refnum(&In0P->refnum, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined) - __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__conditional(&In0P->conditional, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined) - __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__refnum(&In0P->refnum, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined) - __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__conditional(&In0P->conditional, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined) - __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__refnum(&In0P->refnum, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__refnum__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined) - __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__conditional(&In0P->conditional, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_set_timebase_callback_t__conditional__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_set_timebase_callback_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_set_timebase_callback */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_set_timebase_callback -( - mach_port_t server_port, - int refnum, - int conditional, - int *result -); - -/* Routine rpc_jack_set_timebase_callback */ -mig_internal novalue _Xrpc_jack_set_timebase_callback - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int conditional; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_set_timebase_callback_t __Request; - typedef __Reply__rpc_jack_set_timebase_callback_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_set_timebase_callback_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_set_timebase_callback_t__defined */ - - __DeclareRcvRpc(1015, "rpc_jack_set_timebase_callback") - __BeforeRcvRpc(1015, "rpc_jack_set_timebase_callback") - -#if defined(__MIG_check__Request__rpc_jack_set_timebase_callback_t__defined) - check_result = __MIG_check__Request__rpc_jack_set_timebase_callback_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_set_timebase_callback_t__defined) */ - - OutP->RetCode = server_rpc_jack_set_timebase_callback(In0P->Head.msgh_request_port, In0P->refnum, In0P->conditional, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1015, "rpc_jack_set_timebase_callback") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_get_internal_clientname_t__defined) -#define __MIG_check__Request__rpc_jack_get_internal_clientname_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__refnum(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__refnum(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined -#define __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__int_ref(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined -#define __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__int_ref(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined -#define __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__int_ref(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined -#define __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__int_ref(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__refnum(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__refnum(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined -#define __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__int_ref(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined -#define __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__int_ref(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined -#define __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__int_ref(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined -#define __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__int_ref(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__refnum(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__refnum(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined -#define __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__int_ref(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined -#define __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__int_ref(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined -#define __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__int_ref(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined -#define __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__int_ref(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_get_internal_clientname_t(__attribute__((__unused__)) __Request__rpc_jack_get_internal_clientname_t *In0P) -{ - - typedef __Request__rpc_jack_get_internal_clientname_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined) - __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__refnum(&In0P->refnum, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined) - __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__int_ref(&In0P->int_ref, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined) - __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__refnum(&In0P->refnum, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined) - __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__int_ref(&In0P->int_ref, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined) - __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__refnum(&In0P->refnum, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__refnum__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined) - __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__int_ref(&In0P->int_ref, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_get_internal_clientname_t__int_ref__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_get_internal_clientname_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_get_internal_clientname */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_get_internal_clientname -( - mach_port_t server_port, - int refnum, - int int_ref, - client_name_t client_name_res, - int *result -); - -/* Routine rpc_jack_get_internal_clientname */ -mig_internal novalue _Xrpc_jack_get_internal_clientname - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int int_ref; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_get_internal_clientname_t __Request; - typedef __Reply__rpc_jack_get_internal_clientname_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_get_internal_clientname_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_get_internal_clientname_t__defined */ - - __DeclareRcvRpc(1016, "rpc_jack_get_internal_clientname") - __BeforeRcvRpc(1016, "rpc_jack_get_internal_clientname") - -#if defined(__MIG_check__Request__rpc_jack_get_internal_clientname_t__defined) - check_result = __MIG_check__Request__rpc_jack_get_internal_clientname_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_get_internal_clientname_t__defined) */ - - OutP->RetCode = server_rpc_jack_get_internal_clientname(In0P->Head.msgh_request_port, In0P->refnum, In0P->int_ref, OutP->client_name_res, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1016, "rpc_jack_get_internal_clientname") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_internal_clienthandle_t__defined) -#define __MIG_check__Request__rpc_jack_internal_clienthandle_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__refnum(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__refnum(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__client_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__client_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__int_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 64) -#elif defined(__NDR_convert__int_rep__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__refnum(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__refnum(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__client_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__client_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__char_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 64) -#elif defined(__NDR_convert__char_rep__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__refnum(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__refnum(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__client_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__client_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__float_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 64) -#elif defined(__NDR_convert__float_rep__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_internal_clienthandle_t(__attribute__((__unused__)) __Request__rpc_jack_internal_clienthandle_t *In0P) -{ - - typedef __Request__rpc_jack_internal_clienthandle_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if __MigTypeCheck - { - char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; - size_t memchr_limit; - - memchr_limit = min((msg_limit - In0P->client_name), 64); - if (( memchr(In0P->client_name, '\0', memchr_limit) == NULL )) - return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! - } -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined) - __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__refnum(&In0P->refnum, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined) - __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name(&In0P->client_name, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined) - __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__refnum(&In0P->refnum, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined) - __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name(&In0P->client_name, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined) - __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__refnum(&In0P->refnum, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined) - __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name(&In0P->client_name, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_internal_clienthandle_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_internal_clienthandle */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_internal_clienthandle -( - mach_port_t server_port, - int refnum, - client_name_t client_name, - int *int_ref, - int *status, - int *result -); - -/* Routine rpc_jack_internal_clienthandle */ -mig_internal novalue _Xrpc_jack_internal_clienthandle - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_name_t client_name; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_internal_clienthandle_t __Request; - typedef __Reply__rpc_jack_internal_clienthandle_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_internal_clienthandle_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_internal_clienthandle_t__defined */ - - __DeclareRcvRpc(1017, "rpc_jack_internal_clienthandle") - __BeforeRcvRpc(1017, "rpc_jack_internal_clienthandle") - -#if defined(__MIG_check__Request__rpc_jack_internal_clienthandle_t__defined) - check_result = __MIG_check__Request__rpc_jack_internal_clienthandle_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_internal_clienthandle_t__defined) */ - - OutP->RetCode = server_rpc_jack_internal_clienthandle(In0P->Head.msgh_request_port, In0P->refnum, In0P->client_name, &OutP->int_ref, &OutP->status, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1017, "rpc_jack_internal_clienthandle") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_internal_clientload_t__defined) -#define __MIG_check__Request__rpc_jack_internal_clientload_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__refnum__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__refnum(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__refnum(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__refnum__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__client_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__client_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__int_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 64) -#elif defined(__NDR_convert__int_rep__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__so_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__so_name_t((so_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__so_name_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__int_rep__so_name_t((so_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 256) -#elif defined(__NDR_convert__int_rep__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 256) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__objet_data_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__objet_data_t((objet_data_t *)(a), f) -#elif defined(__NDR_convert__int_rep__objet_data_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__int_rep__objet_data_t((objet_data_t *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 256) -#elif defined(__NDR_convert__int_rep__string__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__int_rep__string(a, f, 256) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__options__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__options__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__options(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__options__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__options(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__options__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__options(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__options__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__options(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__options__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__refnum__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__refnum(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__refnum(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__refnum__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__client_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__client_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__char_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 64) -#elif defined(__NDR_convert__char_rep__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__so_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__so_name_t((so_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__so_name_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__char_rep__so_name_t((so_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 256) -#elif defined(__NDR_convert__char_rep__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 256) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__objet_data_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__objet_data_t((objet_data_t *)(a), f) -#elif defined(__NDR_convert__char_rep__objet_data_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__char_rep__objet_data_t((objet_data_t *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 256) -#elif defined(__NDR_convert__char_rep__string__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__char_rep__string(a, f, 256) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__options__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__options__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__options(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__options__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__options(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__options__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__options(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__options__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__options(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__options__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__refnum__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__refnum(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__refnum(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__refnum__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__client_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__client_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__float_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 64) -#elif defined(__NDR_convert__float_rep__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__so_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__so_name_t((so_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__so_name_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__float_rep__so_name_t((so_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 256) -#elif defined(__NDR_convert__float_rep__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 256) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__objet_data_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__objet_data_t((objet_data_t *)(a), f) -#elif defined(__NDR_convert__float_rep__objet_data_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__float_rep__objet_data_t((objet_data_t *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 256) -#elif defined(__NDR_convert__float_rep__string__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__float_rep__string(a, f, 256) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__options__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__options__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__options(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__options__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__options(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__options__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__options(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__options__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__options(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__options__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_internal_clientload_t(__attribute__((__unused__)) __Request__rpc_jack_internal_clientload_t *In0P) -{ - - typedef __Request__rpc_jack_internal_clientload_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if __MigTypeCheck - { - char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; - size_t memchr_limit; - - memchr_limit = min((msg_limit - In0P->client_name), 64); - if (( memchr(In0P->client_name, '\0', memchr_limit) == NULL )) - return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! - memchr_limit = min((msg_limit - In0P->so_name), 256); - if (( memchr(In0P->so_name, '\0', memchr_limit) == NULL )) - return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! - memchr_limit = min((msg_limit - In0P->objet_data), 256); - if (( memchr(In0P->objet_data, '\0', memchr_limit) == NULL )) - return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! - } -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__refnum__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__options__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__refnum__defined) - __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__refnum(&In0P->refnum, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__refnum__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name__defined) - __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name(&In0P->client_name, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name__defined) - __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name(&In0P->so_name, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined) - __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data(&In0P->objet_data, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__options__defined) - __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__options(&In0P->options, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__options__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__refnum__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__options__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__refnum__defined) - __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__refnum(&In0P->refnum, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__refnum__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name__defined) - __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name(&In0P->client_name, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name__defined) - __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name(&In0P->so_name, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined) - __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data(&In0P->objet_data, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__options__defined) - __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__options(&In0P->options, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__options__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__refnum__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__options__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__refnum__defined) - __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__refnum(&In0P->refnum, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__refnum__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name__defined) - __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name(&In0P->client_name, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name__defined) - __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name(&In0P->so_name, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined) - __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data(&In0P->objet_data, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__options__defined) - __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__options(&In0P->options, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__options__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_internal_clientload_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_internal_clientload */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_internal_clientload -( - mach_port_t server_port, - int refnum, - client_name_t client_name, - so_name_t so_name, - objet_data_t objet_data, - int options, - int *status, - int *int_ref, - int *result -); - -/* Routine rpc_jack_internal_clientload */ -mig_internal novalue _Xrpc_jack_internal_clientload - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_name_t client_name; - so_name_t so_name; - objet_data_t objet_data; - int options; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_internal_clientload_t __Request; - typedef __Reply__rpc_jack_internal_clientload_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_internal_clientload_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_internal_clientload_t__defined */ - - __DeclareRcvRpc(1018, "rpc_jack_internal_clientload") - __BeforeRcvRpc(1018, "rpc_jack_internal_clientload") - -#if defined(__MIG_check__Request__rpc_jack_internal_clientload_t__defined) - check_result = __MIG_check__Request__rpc_jack_internal_clientload_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_internal_clientload_t__defined) */ - - OutP->RetCode = server_rpc_jack_internal_clientload(In0P->Head.msgh_request_port, In0P->refnum, In0P->client_name, In0P->so_name, In0P->objet_data, In0P->options, &OutP->status, &OutP->int_ref, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1018, "rpc_jack_internal_clientload") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_internal_clientunload_t__defined) -#define __MIG_check__Request__rpc_jack_internal_clientunload_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__refnum(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__refnum(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__int_ref(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__int_ref(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__int_ref(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined -#define __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__int_ref(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__refnum(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__refnum(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__int_ref(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__int_ref(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__int_ref(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined -#define __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__int_ref(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__refnum(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__refnum(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__int_ref(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__int_ref(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__int_ref(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined -#define __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__int_ref(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_internal_clientunload_t(__attribute__((__unused__)) __Request__rpc_jack_internal_clientunload_t *In0P) -{ - - typedef __Request__rpc_jack_internal_clientunload_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined) - __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__refnum(&In0P->refnum, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined) - __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__int_ref(&In0P->int_ref, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined) - __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__refnum(&In0P->refnum, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined) - __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__int_ref(&In0P->int_ref, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined) - __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__refnum(&In0P->refnum, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__refnum__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined) - __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__int_ref(&In0P->int_ref, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientunload_t__int_ref__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_internal_clientunload_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_internal_clientunload */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_internal_clientunload -( - mach_port_t server_port, - int refnum, - int int_ref, - int *status, - int *result -); - -/* Routine rpc_jack_internal_clientunload */ -mig_internal novalue _Xrpc_jack_internal_clientunload - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int int_ref; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_internal_clientunload_t __Request; - typedef __Reply__rpc_jack_internal_clientunload_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_internal_clientunload_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_internal_clientunload_t__defined */ - - __DeclareRcvRpc(1019, "rpc_jack_internal_clientunload") - __BeforeRcvRpc(1019, "rpc_jack_internal_clientunload") - -#if defined(__MIG_check__Request__rpc_jack_internal_clientunload_t__defined) - check_result = __MIG_check__Request__rpc_jack_internal_clientunload_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_internal_clientunload_t__defined) */ - - OutP->RetCode = server_rpc_jack_internal_clientunload(In0P->Head.msgh_request_port, In0P->refnum, In0P->int_ref, &OutP->status, &OutP->result); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); - __AfterRcvRpc(1019, "rpc_jack_internal_clientunload") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Request__rpc_jack_client_rt_notify_t__defined) -#define __MIG_check__Request__rpc_jack_client_rt_notify_t__defined -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__refnum(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__refnum(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__refnum(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__notify__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__notify__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__notify(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__notify__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__notify(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__notify__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__notify(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__notify__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__notify(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__notify__defined */ - -#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__value__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__value__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__value(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__value__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__value(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__value__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__value(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__value__defined -#define __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__value(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__value__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__refnum(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__refnum(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__refnum(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__notify__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__notify__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__notify(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__notify__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__notify(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__notify__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__notify(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__notify__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__notify(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__notify__defined */ - -#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__value__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__value__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__value(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__value__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__value(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__value__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__value(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__value__defined -#define __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__value(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__value__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__refnum(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__refnum(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__refnum(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__notify__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__notify__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__notify(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__notify__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__notify(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__notify__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__notify(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__notify__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__notify(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__notify__defined */ - -#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__value__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__value__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__value(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__value__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__value(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__value__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__value(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__value__defined -#define __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__value(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__value__defined */ - - -mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_rt_notify_t(__attribute__((__unused__)) __Request__rpc_jack_client_rt_notify_t *In0P) -{ - - typedef __Request__rpc_jack_client_rt_notify_t __Request; -#if __MigTypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__notify__defined) || \ - defined(__NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__value__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__refnum(&In0P->refnum, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__notify__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__notify(&In0P->notify, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__notify__defined */ -#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__value__defined) - __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__value(&In0P->value, In0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_rt_notify_t__value__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__notify__defined) || \ - defined(__NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__value__defined) - if (In0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__refnum(&In0P->refnum, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__notify__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__notify(&In0P->notify, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__notify__defined */ -#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__value__defined) - __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__value(&In0P->value, In0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_rt_notify_t__value__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__notify__defined) || \ - defined(__NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__value__defined) - if (In0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__refnum(&In0P->refnum, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__refnum__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__notify__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__notify(&In0P->notify, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__notify__defined */ -#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__value__defined) - __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__value(&In0P->value, In0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_rt_notify_t__value__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__rpc_jack_client_rt_notify_t__defined) */ -#endif /* __MIG_check__Request__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* SimpleRoutine rpc_jack_client_rt_notify */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t server_rpc_jack_client_rt_notify -( - mach_port_t client_port, - int refnum, - int notify, - int value -); - -/* SimpleRoutine rpc_jack_client_rt_notify */ -mig_internal novalue _Xrpc_jack_client_rt_notify - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int notify; - int value; - mach_msg_trailer_t trailer; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - typedef __Request__rpc_jack_client_rt_notify_t __Request; - typedef __Reply__rpc_jack_client_rt_notify_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; -#ifdef __MIG_check__Request__rpc_jack_client_rt_notify_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Request__rpc_jack_client_rt_notify_t__defined */ - - __DeclareRcvSimple(1020, "rpc_jack_client_rt_notify") - __BeforeRcvSimple(1020, "rpc_jack_client_rt_notify") - -#if defined(__MIG_check__Request__rpc_jack_client_rt_notify_t__defined) - check_result = __MIG_check__Request__rpc_jack_client_rt_notify_t((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } -#endif /* defined(__MIG_check__Request__rpc_jack_client_rt_notify_t__defined) */ - - OutP->RetCode = server_rpc_jack_client_rt_notify(In0P->Head.msgh_request_port, In0P->refnum, In0P->notify, In0P->value); - __AfterRcvSimple(1020, "rpc_jack_client_rt_notify") -} - - -extern boolean_t JackRPCEngine_server( - mach_msg_header_t *InHeadP, - mach_msg_header_t *OutHeadP); - -extern mig_routine_t JackRPCEngine_server_routine( - mach_msg_header_t *InHeadP); - - -/* Description of this subsystem, for use in direct RPC */ -const struct server_JackRPCEngine_subsystem { - mig_server_routine_t server; /* Server routine */ - mach_msg_id_t start; /* Min routine number */ - mach_msg_id_t end; /* Max routine number + 1 */ - unsigned int maxsize; /* Max msg size */ - vm_address_t reserved; /* Reserved */ - struct routine_descriptor /*Array of routine descriptors */ - routine[21]; -} server_JackRPCEngine_subsystem = { - JackRPCEngine_server_routine, - 1000, - 1021, - (mach_msg_size_t)sizeof(union __ReplyUnion__server_JackRPCEngine_subsystem), - (vm_address_t)0, - { - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_open, 8, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_open_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_check, 7, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_check_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_close, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_close_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_activate, 4, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_activate_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_deactivate, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_deactivate_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_port_register, 8, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_register_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_port_unregister, 4, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_unregister_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_port_connect, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_connect_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_port_disconnect, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_disconnect_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_port_connect_name, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_connect_name_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_port_disconnect_name, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_disconnect_name_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_port_rename, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_rename_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_set_buffer_size, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_set_buffer_size_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_set_freewheel, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_set_freewheel_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_release_timebase, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_release_timebase_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_set_timebase_callback, 4, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_set_timebase_callback_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_get_internal_clientname, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_get_internal_clientname_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_internal_clienthandle, 6, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_internal_clienthandle_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_internal_clientload, 9, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_internal_clientload_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_internal_clientunload, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_internal_clientunload_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_rt_notify, 4, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_rt_notify_t)}, - } -}; - -mig_external boolean_t JackRPCEngine_server - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - register mig_routine_t routine; - - OutHeadP->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InHeadP->msgh_bits), 0); - OutHeadP->msgh_remote_port = InHeadP->msgh_reply_port; - /* Minimal size: routine() will update it if different */ - OutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t); - OutHeadP->msgh_local_port = MACH_PORT_NULL; - OutHeadP->msgh_id = InHeadP->msgh_id + 100; - - if ((InHeadP->msgh_id > 1020) || (InHeadP->msgh_id < 1000) || - ((routine = server_JackRPCEngine_subsystem.routine[InHeadP->msgh_id - 1000].stub_routine) == 0)) { - ((mig_reply_error_t *)OutHeadP)->NDR = NDR_record; - ((mig_reply_error_t *)OutHeadP)->RetCode = MIG_BAD_ID; - return FALSE; - } - (*routine) (InHeadP, OutHeadP); - return TRUE; -} - -mig_external mig_routine_t JackRPCEngine_server_routine - (mach_msg_header_t *InHeadP) -{ - register int msgh_id; - - msgh_id = InHeadP->msgh_id - 1000; - - if ((msgh_id > 20) || (msgh_id < 0)) - return 0; - - return server_JackRPCEngine_subsystem.routine[msgh_id].stub_routine; -} diff --git a/macosx/RPC/JackRPCEngineUser.c b/macosx/RPC/JackRPCEngineUser.c deleted file mode 100644 index e86e8cfc..00000000 --- a/macosx/RPC/JackRPCEngineUser.c +++ /dev/null @@ -1,6302 +0,0 @@ -/* - * IDENTIFICATION: - * stub generated Fri Oct 23 10:35:08 2009 - * with a MiG generated Mon May 18 09:59:33 PDT 2009 by root@sulitlana.apple.com - * OPTIONS: - */ -#define __MIG_check__Reply__JackRPCEngine_subsystem__ 1 -#define __NDR_convert__Reply__JackRPCEngine_subsystem__ 1 -#define __NDR_convert__mig_reply_error_subsystem__ 1 - -#include "JackRPCEngine.h" - - -#ifndef mig_internal -#define mig_internal static __inline__ -#endif /* mig_internal */ - -#ifndef mig_external -#define mig_external -#endif /* mig_external */ - -#if !defined(__MigTypeCheck) && defined(TypeCheck) -#define __MigTypeCheck TypeCheck /* Legacy setting */ -#endif /* !defined(__MigTypeCheck) */ - -#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) -#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ -#endif /* !defined(__MigKernelSpecificCode) */ - -#ifndef LimitCheck -#define LimitCheck 0 -#endif /* LimitCheck */ - -#ifndef min -#define min(a,b) ( ((a) < (b))? (a): (b) ) -#endif /* min */ - -#if !defined(_WALIGN_) -#define _WALIGN_(x) (((x) + 3) & ~3) -#endif /* !defined(_WALIGN_) */ - -#if !defined(_WALIGNSZ_) -#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) -#endif /* !defined(_WALIGNSZ_) */ - -#ifndef UseStaticTemplates -#define UseStaticTemplates 0 -#endif /* UseStaticTemplates */ - -#ifndef __MachMsgErrorWithTimeout -#define __MachMsgErrorWithTimeout(_R_) { \ - switch (_R_) { \ - case MACH_SEND_INVALID_DATA: \ - case MACH_SEND_INVALID_DEST: \ - case MACH_SEND_INVALID_HEADER: \ - mig_put_reply_port(InP->Head.msgh_reply_port); \ - break; \ - case MACH_SEND_TIMED_OUT: \ - case MACH_RCV_TIMED_OUT: \ - default: \ - mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ - } \ -} -#endif /* __MachMsgErrorWithTimeout */ - -#ifndef __MachMsgErrorWithoutTimeout -#define __MachMsgErrorWithoutTimeout(_R_) { \ - switch (_R_) { \ - case MACH_SEND_INVALID_DATA: \ - case MACH_SEND_INVALID_DEST: \ - case MACH_SEND_INVALID_HEADER: \ - mig_put_reply_port(InP->Head.msgh_reply_port); \ - break; \ - default: \ - mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ - } \ -} -#endif /* __MachMsgErrorWithoutTimeout */ - -#ifndef __DeclareSendRpc -#define __DeclareSendRpc(_NUM_, _NAME_) -#endif /* __DeclareSendRpc */ - -#ifndef __BeforeSendRpc -#define __BeforeSendRpc(_NUM_, _NAME_) -#endif /* __BeforeSendRpc */ - -#ifndef __AfterSendRpc -#define __AfterSendRpc(_NUM_, _NAME_) -#endif /* __AfterSendRpc */ - -#ifndef __DeclareSendSimple -#define __DeclareSendSimple(_NUM_, _NAME_) -#endif /* __DeclareSendSimple */ - -#ifndef __BeforeSendSimple -#define __BeforeSendSimple(_NUM_, _NAME_) -#endif /* __BeforeSendSimple */ - -#ifndef __AfterSendSimple -#define __AfterSendSimple(_NUM_, _NAME_) -#endif /* __AfterSendSimple */ - -#define msgh_request_port msgh_remote_port -#define msgh_reply_port msgh_local_port - - - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_client_open_t__defined) -#define __MIG_check__Reply__rpc_jack_client_open_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_engine__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_engine__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_engine(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_engine__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_engine(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_engine__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_engine(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_engine__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_engine(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_engine__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_client__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_client__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_client(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_client__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_client(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_client__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_client(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_client__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_client(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_client__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_graph__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_graph__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_graph(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_graph__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_graph(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_graph__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_graph(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_graph__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_graph(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_graph__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__result__defined */ - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_engine__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_engine__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_engine(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_engine__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_engine(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_engine__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_engine(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_engine__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_engine(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_engine__defined */ - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_client__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_client__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_client(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_client__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_client(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_client__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_client(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_client__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_client(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_client__defined */ - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_graph__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_graph__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_graph(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_graph__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_graph(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_graph__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_graph(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_graph__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_graph(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_graph__defined */ - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__result__defined */ - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_engine__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_engine__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_engine(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_engine__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_engine(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_engine__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_engine(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_engine__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_engine(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_engine__defined */ - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_client__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_client__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_client(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_client__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_client(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_client__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_client(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_client__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_client(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_client__defined */ - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_graph__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_graph__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_graph(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_graph__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_graph(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_graph__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_graph(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_graph__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_graph(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_graph__defined */ - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_client_open_t(__Reply__rpc_jack_client_open_t *Out0P) -{ - - typedef __Reply__rpc_jack_client_open_t __Reply; - boolean_t msgh_simple; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1100) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - - msgh_simple = !(Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX); -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((msgh_simple || Out0P->msgh_body.msgh_descriptor_count != 1 || - msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (!msgh_simple || msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - ((mig_reply_error_t *)Out0P)->RetCode == KERN_SUCCESS)) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (msgh_simple) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if __MigTypeCheck - if (Out0P->private_port.type != MACH_MSG_PORT_DESCRIPTOR || - Out0P->private_port.disposition != 17) { - return MIG_TYPE_ERROR; - } -#endif /* __MigTypeCheck */ - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_engine__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_client__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_graph__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_client_open_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_engine__defined) - __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_engine(&Out0P->shared_engine, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_engine__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_client__defined) - __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_client(&Out0P->shared_client, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_client__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_graph__defined) - __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_graph(&Out0P->shared_graph, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_graph__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_open_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_open_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_engine__defined) || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_client__defined) || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_graph__defined) || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_client_open_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_engine__defined) - __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_engine(&Out0P->shared_engine, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_engine__defined */ -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_client__defined) - __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_client(&Out0P->shared_client, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_client__defined */ -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_graph__defined) - __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_graph(&Out0P->shared_graph, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__shared_graph__defined */ -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_client_open_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_open_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_engine__defined) || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_client__defined) || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_graph__defined) || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_client_open_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_engine__defined) - __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_engine(&Out0P->shared_engine, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_engine__defined */ -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_client__defined) - __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_client(&Out0P->shared_client, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_client__defined */ -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_graph__defined) - __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_graph(&Out0P->shared_graph, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__shared_graph__defined */ -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_client_open_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_open_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_client_open_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_client_open */ -mig_external kern_return_t rpc_jack_client_open -( - mach_port_t server_port, - client_name_t client_name, - int pid, - mach_port_t *private_port, - int *shared_engine, - int *shared_client, - int *shared_graph, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - client_name_t client_name; - int pid; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t private_port; - /* end of the kernel processed data */ - NDR_record_t NDR; - int shared_engine; - int shared_client; - int shared_graph; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t private_port; - /* end of the kernel processed data */ - NDR_record_t NDR; - int shared_engine; - int shared_client; - int shared_graph; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_client_open_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_client_open_t__defined */ - - __DeclareSendRpc(1000, "rpc_jack_client_open") - - InP->NDR = NDR_record; - - (void) mig_strncpy(InP->client_name, client_name, 64); - - InP->pid = pid; - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1000; - - __BeforeSendRpc(1000, "rpc_jack_client_open") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1000, "rpc_jack_client_open") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_client_open_t__defined) - check_result = __MIG_check__Reply__rpc_jack_client_open_t((__Reply__rpc_jack_client_open_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_client_open_t__defined) */ - - *private_port = Out0P->private_port.name; - *shared_engine = Out0P->shared_engine; - - *shared_client = Out0P->shared_client; - - *shared_graph = Out0P->shared_graph; - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_client_check_t__defined) -#define __MIG_check__Reply__rpc_jack_client_check_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__client_name_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__client_name_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__int_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 64) -#elif defined(__NDR_convert__int_rep__string__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__int_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__status__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__status__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__status(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__status__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__status(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__status__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__status(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__status__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__status(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__status__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__client_name_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__client_name_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__char_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 64) -#elif defined(__NDR_convert__char_rep__string__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__char_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res__defined */ - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__status__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__status__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__status(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__status__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__status(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__status__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__status(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__status__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__status(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__status__defined */ - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__client_name_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__client_name_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__float_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 64) -#elif defined(__NDR_convert__float_rep__string__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__float_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res__defined */ - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__status__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__status__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__status(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__status__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__status(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__status__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__status(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__status__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__status(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__status__defined */ - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_client_check_t(__Reply__rpc_jack_client_check_t *Out0P) -{ - - typedef __Reply__rpc_jack_client_check_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1101) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_check_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_client_check_t__status__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_client_check_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_check_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res__defined) - __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res(&Out0P->client_name_res, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_check_t__status__defined) - __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__status(&Out0P->status, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__status__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_check_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res__defined) || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_client_check_t__status__defined) || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_client_check_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res__defined) - __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res(&Out0P->client_name_res, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res__defined */ -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_client_check_t__status__defined) - __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__status(&Out0P->status, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__status__defined */ -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_client_check_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res__defined) || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_client_check_t__status__defined) || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_client_check_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res__defined) - __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res(&Out0P->client_name_res, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res__defined */ -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_client_check_t__status__defined) - __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__status(&Out0P->status, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__status__defined */ -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_client_check_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_client_check_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_client_check */ -mig_external kern_return_t rpc_jack_client_check -( - mach_port_t server_port, - client_name_t client_name, - client_name_t client_name_res, - int protocol, - int options, - int *status, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - client_name_t client_name; - int protocol; - int options; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - client_name_t client_name_res; - int status; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - client_name_t client_name_res; - int status; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_client_check_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_client_check_t__defined */ - - __DeclareSendRpc(1001, "rpc_jack_client_check") - - InP->NDR = NDR_record; - - (void) mig_strncpy(InP->client_name, client_name, 64); - - InP->protocol = protocol; - - InP->options = options; - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1001; - - __BeforeSendRpc(1001, "rpc_jack_client_check") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1001, "rpc_jack_client_check") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_client_check_t__defined) - check_result = __MIG_check__Reply__rpc_jack_client_check_t((__Reply__rpc_jack_client_check_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_client_check_t__defined) */ - - (void) mig_strncpy(client_name_res, Out0P->client_name_res, 64); - - *status = Out0P->status; - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_client_close_t__defined) -#define __MIG_check__Reply__rpc_jack_client_close_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_client_close_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_close_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_close_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_close_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_close_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_close_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_close_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_close_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_close_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_close_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_client_close_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_close_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_close_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_close_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_close_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_close_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_close_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_close_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_close_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_close_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_client_close_t(__Reply__rpc_jack_client_close_t *Out0P) -{ - - typedef __Reply__rpc_jack_client_close_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1102) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_close_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_client_close_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_close_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_close_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_close_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_client_close_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_client_close_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_client_close_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_close_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_client_close_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_client_close_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_client_close_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_close_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_client_close_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_client_close */ -mig_external kern_return_t rpc_jack_client_close -( - mach_port_t server_port, - int refnum, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_client_close_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_client_close_t__defined */ - - __DeclareSendRpc(1002, "rpc_jack_client_close") - - InP->NDR = NDR_record; - - InP->refnum = refnum; - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1002; - - __BeforeSendRpc(1002, "rpc_jack_client_close") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1002, "rpc_jack_client_close") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_client_close_t__defined) - check_result = __MIG_check__Reply__rpc_jack_client_close_t((__Reply__rpc_jack_client_close_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_client_close_t__defined) */ - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_client_activate_t__defined) -#define __MIG_check__Reply__rpc_jack_client_activate_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_client_activate_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_activate_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_activate_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_activate_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_activate_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_activate_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_activate_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_activate_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_activate_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_activate_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_client_activate_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_activate_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_activate_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_activate_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_activate_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_activate_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_activate_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_activate_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_activate_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_activate_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_client_activate_t(__Reply__rpc_jack_client_activate_t *Out0P) -{ - - typedef __Reply__rpc_jack_client_activate_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1103) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_activate_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_client_activate_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_client_activate_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_client_activate_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_activate_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_client_activate_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_client_activate_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_client_activate_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_activate_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_client_activate_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_client_activate */ -mig_external kern_return_t rpc_jack_client_activate -( - mach_port_t server_port, - int refnum, - int state, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int state; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_client_activate_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_client_activate_t__defined */ - - __DeclareSendRpc(1003, "rpc_jack_client_activate") - - InP->NDR = NDR_record; - - InP->refnum = refnum; - - InP->state = state; - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1003; - - __BeforeSendRpc(1003, "rpc_jack_client_activate") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1003, "rpc_jack_client_activate") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_client_activate_t__defined) - check_result = __MIG_check__Reply__rpc_jack_client_activate_t((__Reply__rpc_jack_client_activate_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_client_activate_t__defined) */ - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_client_deactivate_t__defined) -#define __MIG_check__Reply__rpc_jack_client_deactivate_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_client_deactivate_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_deactivate_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_deactivate_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_deactivate_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_deactivate_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_deactivate_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_deactivate_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_client_deactivate_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_client_deactivate_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_deactivate_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_client_deactivate_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_deactivate_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_deactivate_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_deactivate_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_deactivate_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_deactivate_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_deactivate_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_client_deactivate_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_client_deactivate_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_deactivate_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_client_deactivate_t(__Reply__rpc_jack_client_deactivate_t *Out0P) -{ - - typedef __Reply__rpc_jack_client_deactivate_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1104) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_deactivate_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_client_deactivate_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_client_deactivate_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_client_deactivate_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_deactivate_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_client_deactivate_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_client_deactivate_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_client_deactivate_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_deactivate_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_client_deactivate_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_client_deactivate */ -mig_external kern_return_t rpc_jack_client_deactivate -( - mach_port_t server_port, - int refnum, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_client_deactivate_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_client_deactivate_t__defined */ - - __DeclareSendRpc(1004, "rpc_jack_client_deactivate") - - InP->NDR = NDR_record; - - InP->refnum = refnum; - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1004; - - __BeforeSendRpc(1004, "rpc_jack_client_deactivate") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1004, "rpc_jack_client_deactivate") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_client_deactivate_t__defined) - check_result = __MIG_check__Reply__rpc_jack_client_deactivate_t((__Reply__rpc_jack_client_deactivate_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_client_deactivate_t__defined) */ - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_port_register_t__defined) -#define __MIG_check__Reply__rpc_jack_port_register_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__port_index__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__unsigned__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__port_index__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__port_index(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__unsigned((unsigned *)(a), f) -#elif defined(__NDR_convert__int_rep__unsigned__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__port_index__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__port_index(a, f) \ - __NDR_convert__int_rep__unsigned((unsigned *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__uint32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__port_index__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__port_index(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__uint32_t((uint32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__uint32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__port_index__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__port_index(a, f) \ - __NDR_convert__int_rep__uint32_t((uint32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__port_index__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__port_index__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__unsigned__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__port_index__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__port_index(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__unsigned((unsigned *)(a), f) -#elif defined(__NDR_convert__char_rep__unsigned__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__port_index__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__port_index(a, f) \ - __NDR_convert__char_rep__unsigned((unsigned *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__uint32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__port_index__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__port_index(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__uint32_t((uint32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__uint32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__port_index__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__port_index(a, f) \ - __NDR_convert__char_rep__uint32_t((uint32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__port_index__defined */ - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__port_index__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__unsigned__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__port_index__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__port_index(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__unsigned((unsigned *)(a), f) -#elif defined(__NDR_convert__float_rep__unsigned__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__port_index__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__port_index(a, f) \ - __NDR_convert__float_rep__unsigned((unsigned *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__uint32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__port_index__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__port_index(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__uint32_t((uint32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__uint32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__port_index__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__port_index(a, f) \ - __NDR_convert__float_rep__uint32_t((uint32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__port_index__defined */ - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_port_register_t(__Reply__rpc_jack_port_register_t *Out0P) -{ - - typedef __Reply__rpc_jack_port_register_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1105) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_register_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_port_register_t__port_index__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_port_register_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_register_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_register_t__port_index__defined) - __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__port_index(&Out0P->port_index, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__port_index__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_register_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_register_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_port_register_t__port_index__defined) || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_port_register_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_port_register_t__port_index__defined) - __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__port_index(&Out0P->port_index, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__port_index__defined */ -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_port_register_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_port_register_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_port_register_t__port_index__defined) || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_port_register_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_port_register_t__port_index__defined) - __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__port_index(&Out0P->port_index, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__port_index__defined */ -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_port_register_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_port_register_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_port_register_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_port_register */ -mig_external kern_return_t rpc_jack_port_register -( - mach_port_t server_port, - int refnum, - client_port_name_t name, - client_port_type_t port_type, - unsigned flags, - unsigned buffer_size, - unsigned *port_index, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_port_name_t name; - client_port_type_t port_type; - unsigned flags; - unsigned buffer_size; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - unsigned port_index; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - unsigned port_index; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_port_register_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_port_register_t__defined */ - - __DeclareSendRpc(1005, "rpc_jack_port_register") - - InP->NDR = NDR_record; - - InP->refnum = refnum; - - (void) mig_strncpy(InP->name, name, 128); - - (void) mig_strncpy(InP->port_type, port_type, 128); - - InP->flags = flags; - - InP->buffer_size = buffer_size; - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1005; - - __BeforeSendRpc(1005, "rpc_jack_port_register") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1005, "rpc_jack_port_register") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_port_register_t__defined) - check_result = __MIG_check__Reply__rpc_jack_port_register_t((__Reply__rpc_jack_port_register_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_port_register_t__defined) */ - - *port_index = Out0P->port_index; - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_port_unregister_t__defined) -#define __MIG_check__Reply__rpc_jack_port_unregister_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_port_unregister_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_unregister_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_unregister_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_unregister_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_unregister_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_unregister_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_unregister_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_unregister_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_unregister_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_port_unregister_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_port_unregister_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_unregister_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_unregister_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_unregister_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_unregister_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_unregister_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_unregister_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_unregister_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_unregister_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_port_unregister_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_port_unregister_t(__Reply__rpc_jack_port_unregister_t *Out0P) -{ - - typedef __Reply__rpc_jack_port_unregister_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1106) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_unregister_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_port_unregister_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_port_unregister_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_port_unregister_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_port_unregister_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_port_unregister_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_port_unregister_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_port_unregister_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_port_unregister_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_port_unregister_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_port_unregister */ -mig_external kern_return_t rpc_jack_port_unregister -( - mach_port_t server_port, - int refnum, - int port, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int port; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_port_unregister_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_port_unregister_t__defined */ - - __DeclareSendRpc(1006, "rpc_jack_port_unregister") - - InP->NDR = NDR_record; - - InP->refnum = refnum; - - InP->port = port; - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1006; - - __BeforeSendRpc(1006, "rpc_jack_port_unregister") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1006, "rpc_jack_port_unregister") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_port_unregister_t__defined) - check_result = __MIG_check__Reply__rpc_jack_port_unregister_t((__Reply__rpc_jack_port_unregister_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_port_unregister_t__defined) */ - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_port_connect_t__defined) -#define __MIG_check__Reply__rpc_jack_port_connect_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_port_connect_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_connect_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_connect_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_connect_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_connect_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_connect_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_connect_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_connect_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_connect_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_port_connect_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_port_connect_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_connect_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_connect_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_connect_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_connect_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_connect_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_connect_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_connect_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_connect_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_port_connect_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_port_connect_t(__Reply__rpc_jack_port_connect_t *Out0P) -{ - - typedef __Reply__rpc_jack_port_connect_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1107) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_connect_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_port_connect_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_port_connect_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_port_connect_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_port_connect_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_port_connect_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_port_connect_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_port_connect_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_port_connect_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_port_connect_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_port_connect */ -mig_external kern_return_t rpc_jack_port_connect -( - mach_port_t server_port, - int refnum, - int src, - int dst, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int src; - int dst; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_port_connect_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_port_connect_t__defined */ - - __DeclareSendRpc(1007, "rpc_jack_port_connect") - - InP->NDR = NDR_record; - - InP->refnum = refnum; - - InP->src = src; - - InP->dst = dst; - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1007; - - __BeforeSendRpc(1007, "rpc_jack_port_connect") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1007, "rpc_jack_port_connect") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_port_connect_t__defined) - check_result = __MIG_check__Reply__rpc_jack_port_connect_t((__Reply__rpc_jack_port_connect_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_port_connect_t__defined) */ - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_port_disconnect_t__defined) -#define __MIG_check__Reply__rpc_jack_port_disconnect_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_port_disconnect_t(__Reply__rpc_jack_port_disconnect_t *Out0P) -{ - - typedef __Reply__rpc_jack_port_disconnect_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1108) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_port_disconnect_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_port_disconnect */ -mig_external kern_return_t rpc_jack_port_disconnect -( - mach_port_t server_port, - int refnum, - int src, - int dst, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int src; - int dst; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_port_disconnect_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_port_disconnect_t__defined */ - - __DeclareSendRpc(1008, "rpc_jack_port_disconnect") - - InP->NDR = NDR_record; - - InP->refnum = refnum; - - InP->src = src; - - InP->dst = dst; - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1008; - - __BeforeSendRpc(1008, "rpc_jack_port_disconnect") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1008, "rpc_jack_port_disconnect") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_port_disconnect_t__defined) - check_result = __MIG_check__Reply__rpc_jack_port_disconnect_t((__Reply__rpc_jack_port_disconnect_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_port_disconnect_t__defined) */ - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_port_connect_name_t__defined) -#define __MIG_check__Reply__rpc_jack_port_connect_name_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_port_connect_name_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_connect_name_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_connect_name_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_connect_name_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_connect_name_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_connect_name_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_connect_name_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_connect_name_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_connect_name_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_port_connect_name_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_port_connect_name_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_connect_name_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_connect_name_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_connect_name_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_connect_name_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_connect_name_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_connect_name_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_connect_name_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_connect_name_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_port_connect_name_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_port_connect_name_t(__Reply__rpc_jack_port_connect_name_t *Out0P) -{ - - typedef __Reply__rpc_jack_port_connect_name_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1109) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_connect_name_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_port_connect_name_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_port_connect_name_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_port_connect_name_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_port_connect_name_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_port_connect_name_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_port_connect_name_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_port_connect_name_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_port_connect_name_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_port_connect_name_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_port_connect_name */ -mig_external kern_return_t rpc_jack_port_connect_name -( - mach_port_t server_port, - int refnum, - client_port_name_t src, - client_port_name_t dst, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_port_name_t src; - client_port_name_t dst; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_port_connect_name_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_port_connect_name_t__defined */ - - __DeclareSendRpc(1009, "rpc_jack_port_connect_name") - - InP->NDR = NDR_record; - - InP->refnum = refnum; - - (void) mig_strncpy(InP->src, src, 128); - - (void) mig_strncpy(InP->dst, dst, 128); - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1009; - - __BeforeSendRpc(1009, "rpc_jack_port_connect_name") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1009, "rpc_jack_port_connect_name") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_port_connect_name_t__defined) - check_result = __MIG_check__Reply__rpc_jack_port_connect_name_t((__Reply__rpc_jack_port_connect_name_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_port_connect_name_t__defined) */ - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_port_disconnect_name_t__defined) -#define __MIG_check__Reply__rpc_jack_port_disconnect_name_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_name_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_name_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_name_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_name_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_name_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_name_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_name_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_name_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_port_disconnect_name_t(__Reply__rpc_jack_port_disconnect_name_t *Out0P) -{ - - typedef __Reply__rpc_jack_port_disconnect_name_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1110) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_name_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_name_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_port_disconnect_name_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_port_disconnect_name_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_port_disconnect_name */ -mig_external kern_return_t rpc_jack_port_disconnect_name -( - mach_port_t server_port, - int refnum, - client_port_name_t src, - client_port_name_t dst, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_port_name_t src; - client_port_name_t dst; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_port_disconnect_name_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_port_disconnect_name_t__defined */ - - __DeclareSendRpc(1010, "rpc_jack_port_disconnect_name") - - InP->NDR = NDR_record; - - InP->refnum = refnum; - - (void) mig_strncpy(InP->src, src, 128); - - (void) mig_strncpy(InP->dst, dst, 128); - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1010; - - __BeforeSendRpc(1010, "rpc_jack_port_disconnect_name") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1010, "rpc_jack_port_disconnect_name") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_port_disconnect_name_t__defined) - check_result = __MIG_check__Reply__rpc_jack_port_disconnect_name_t((__Reply__rpc_jack_port_disconnect_name_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_port_disconnect_name_t__defined) */ - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_port_rename_t__defined) -#define __MIG_check__Reply__rpc_jack_port_rename_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_port_rename_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_rename_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_rename_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_rename_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_rename_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_rename_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_rename_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_port_rename_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_port_rename_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_port_rename_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_port_rename_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_rename_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_rename_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_rename_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_rename_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_rename_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_rename_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_port_rename_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_port_rename_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_port_rename_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_port_rename_t(__Reply__rpc_jack_port_rename_t *Out0P) -{ - - typedef __Reply__rpc_jack_port_rename_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1111) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_port_rename_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_port_rename_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_port_rename_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_port_rename_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_port_rename_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_port_rename_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_port_rename_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_port_rename_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_port_rename_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_port_rename_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_port_rename */ -mig_external kern_return_t rpc_jack_port_rename -( - mach_port_t server_port, - int refnum, - int src, - client_port_name_t name, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int src; - client_port_name_t name; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_port_rename_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_port_rename_t__defined */ - - __DeclareSendRpc(1011, "rpc_jack_port_rename") - - InP->NDR = NDR_record; - - InP->refnum = refnum; - - InP->src = src; - - (void) mig_strncpy(InP->name, name, 128); - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1011; - - __BeforeSendRpc(1011, "rpc_jack_port_rename") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1011, "rpc_jack_port_rename") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_port_rename_t__defined) - check_result = __MIG_check__Reply__rpc_jack_port_rename_t((__Reply__rpc_jack_port_rename_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_port_rename_t__defined) */ - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_set_buffer_size_t__defined) -#define __MIG_check__Reply__rpc_jack_set_buffer_size_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_set_buffer_size_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_set_buffer_size_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_set_buffer_size_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_set_buffer_size_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_set_buffer_size_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_set_buffer_size_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_set_buffer_size_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_set_buffer_size_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_set_buffer_size_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_set_buffer_size_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_set_buffer_size_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_set_buffer_size_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_set_buffer_size_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_set_buffer_size_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_set_buffer_size_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_set_buffer_size_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_set_buffer_size_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_set_buffer_size_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_set_buffer_size_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_set_buffer_size_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_set_buffer_size_t(__Reply__rpc_jack_set_buffer_size_t *Out0P) -{ - - typedef __Reply__rpc_jack_set_buffer_size_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1112) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_set_buffer_size_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_set_buffer_size_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_set_buffer_size_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_set_buffer_size_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_set_buffer_size_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_set_buffer_size_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_set_buffer_size_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_set_buffer_size_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_set_buffer_size_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_set_buffer_size_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_set_buffer_size */ -mig_external kern_return_t rpc_jack_set_buffer_size -( - mach_port_t server_port, - int buffer_size, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int buffer_size; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_set_buffer_size_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_set_buffer_size_t__defined */ - - __DeclareSendRpc(1012, "rpc_jack_set_buffer_size") - - InP->NDR = NDR_record; - - InP->buffer_size = buffer_size; - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1012; - - __BeforeSendRpc(1012, "rpc_jack_set_buffer_size") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1012, "rpc_jack_set_buffer_size") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_set_buffer_size_t__defined) - check_result = __MIG_check__Reply__rpc_jack_set_buffer_size_t((__Reply__rpc_jack_set_buffer_size_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_set_buffer_size_t__defined) */ - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_set_freewheel_t__defined) -#define __MIG_check__Reply__rpc_jack_set_freewheel_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_set_freewheel_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_set_freewheel_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_set_freewheel_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_set_freewheel_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_set_freewheel_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_set_freewheel_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_set_freewheel_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_set_freewheel_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_set_freewheel_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_set_freewheel_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_set_freewheel_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_set_freewheel_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_set_freewheel_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_set_freewheel_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_set_freewheel_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_set_freewheel_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_set_freewheel_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_set_freewheel_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_set_freewheel_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_set_freewheel_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_set_freewheel_t(__Reply__rpc_jack_set_freewheel_t *Out0P) -{ - - typedef __Reply__rpc_jack_set_freewheel_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1113) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_set_freewheel_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_set_freewheel_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_set_freewheel_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_set_freewheel_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_set_freewheel_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_set_freewheel_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_set_freewheel_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_set_freewheel_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_set_freewheel_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_set_freewheel_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_set_freewheel */ -mig_external kern_return_t rpc_jack_set_freewheel -( - mach_port_t server_port, - int onoff, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int onoff; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_set_freewheel_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_set_freewheel_t__defined */ - - __DeclareSendRpc(1013, "rpc_jack_set_freewheel") - - InP->NDR = NDR_record; - - InP->onoff = onoff; - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1013; - - __BeforeSendRpc(1013, "rpc_jack_set_freewheel") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1013, "rpc_jack_set_freewheel") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_set_freewheel_t__defined) - check_result = __MIG_check__Reply__rpc_jack_set_freewheel_t((__Reply__rpc_jack_set_freewheel_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_set_freewheel_t__defined) */ - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_release_timebase_t__defined) -#define __MIG_check__Reply__rpc_jack_release_timebase_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_release_timebase_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_release_timebase_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_release_timebase_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_release_timebase_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_release_timebase_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_release_timebase_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_release_timebase_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_release_timebase_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_release_timebase_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_release_timebase_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_release_timebase_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_release_timebase_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_release_timebase_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_release_timebase_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_release_timebase_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_release_timebase_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_release_timebase_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_release_timebase_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_release_timebase_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_release_timebase_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_release_timebase_t(__Reply__rpc_jack_release_timebase_t *Out0P) -{ - - typedef __Reply__rpc_jack_release_timebase_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1114) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_release_timebase_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_release_timebase_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_release_timebase_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_release_timebase_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_release_timebase_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_release_timebase_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_release_timebase_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_release_timebase_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_release_timebase_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_release_timebase_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_release_timebase */ -mig_external kern_return_t rpc_jack_release_timebase -( - mach_port_t server_port, - int refnum, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_release_timebase_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_release_timebase_t__defined */ - - __DeclareSendRpc(1014, "rpc_jack_release_timebase") - - InP->NDR = NDR_record; - - InP->refnum = refnum; - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1014; - - __BeforeSendRpc(1014, "rpc_jack_release_timebase") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1014, "rpc_jack_release_timebase") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_release_timebase_t__defined) - check_result = __MIG_check__Reply__rpc_jack_release_timebase_t((__Reply__rpc_jack_release_timebase_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_release_timebase_t__defined) */ - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_set_timebase_callback_t__defined) -#define __MIG_check__Reply__rpc_jack_set_timebase_callback_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_set_timebase_callback_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_set_timebase_callback_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_set_timebase_callback_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_set_timebase_callback_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_set_timebase_callback_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_set_timebase_callback_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_set_timebase_callback_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_set_timebase_callback_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_set_timebase_callback_t(__Reply__rpc_jack_set_timebase_callback_t *Out0P) -{ - - typedef __Reply__rpc_jack_set_timebase_callback_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1115) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_set_timebase_callback_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_set_timebase_callback_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_set_timebase_callback_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_set_timebase_callback_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_set_timebase_callback */ -mig_external kern_return_t rpc_jack_set_timebase_callback -( - mach_port_t server_port, - int refnum, - int conditional, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int conditional; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_set_timebase_callback_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_set_timebase_callback_t__defined */ - - __DeclareSendRpc(1015, "rpc_jack_set_timebase_callback") - - InP->NDR = NDR_record; - - InP->refnum = refnum; - - InP->conditional = conditional; - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1015; - - __BeforeSendRpc(1015, "rpc_jack_set_timebase_callback") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1015, "rpc_jack_set_timebase_callback") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_set_timebase_callback_t__defined) - check_result = __MIG_check__Reply__rpc_jack_set_timebase_callback_t((__Reply__rpc_jack_set_timebase_callback_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_set_timebase_callback_t__defined) */ - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_get_internal_clientname_t__defined) -#define __MIG_check__Reply__rpc_jack_get_internal_clientname_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__client_name_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__client_name_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__int_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 64) -#elif defined(__NDR_convert__int_rep__string__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__int_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__client_name_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__client_name_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__char_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 64) -#elif defined(__NDR_convert__char_rep__string__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__char_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined */ - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__client_name_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__client_name_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__float_rep__client_name_t((client_name_t *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 64) -#elif defined(__NDR_convert__float_rep__string__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__float_rep__string(a, f, 64) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined */ - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_get_internal_clientname_t(__Reply__rpc_jack_get_internal_clientname_t *Out0P) -{ - - typedef __Reply__rpc_jack_get_internal_clientname_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1116) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined) - __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(&Out0P->client_name_res, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined) || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined) - __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(&Out0P->client_name_res, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined */ -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined) || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined) - __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(&Out0P->client_name_res, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined */ -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_get_internal_clientname_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_get_internal_clientname */ -mig_external kern_return_t rpc_jack_get_internal_clientname -( - mach_port_t server_port, - int refnum, - int int_ref, - client_name_t client_name_res, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int int_ref; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - client_name_t client_name_res; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - client_name_t client_name_res; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_get_internal_clientname_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_get_internal_clientname_t__defined */ - - __DeclareSendRpc(1016, "rpc_jack_get_internal_clientname") - - InP->NDR = NDR_record; - - InP->refnum = refnum; - - InP->int_ref = int_ref; - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1016; - - __BeforeSendRpc(1016, "rpc_jack_get_internal_clientname") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1016, "rpc_jack_get_internal_clientname") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_get_internal_clientname_t__defined) - check_result = __MIG_check__Reply__rpc_jack_get_internal_clientname_t((__Reply__rpc_jack_get_internal_clientname_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_get_internal_clientname_t__defined) */ - - (void) mig_strncpy(client_name_res, Out0P->client_name_res, 64); - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_internal_clienthandle_t__defined) -#define __MIG_check__Reply__rpc_jack_internal_clienthandle_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__status(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__status(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__status(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__status(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined */ - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__status(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__status(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__status(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__status(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined */ - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined */ - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__status(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__status(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__status(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__status(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined */ - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_internal_clienthandle_t(__Reply__rpc_jack_internal_clienthandle_t *Out0P) -{ - - typedef __Reply__rpc_jack_internal_clienthandle_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1117) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined) - __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref(&Out0P->int_ref, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined) - __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__status(&Out0P->status, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined) || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined) || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined) - __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref(&Out0P->int_ref, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined */ -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined) - __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__status(&Out0P->status, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined */ -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined) || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined) || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined) - __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref(&Out0P->int_ref, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__int_ref__defined */ -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined) - __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__status(&Out0P->status, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__status__defined */ -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_internal_clienthandle_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_internal_clienthandle_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_internal_clienthandle */ -mig_external kern_return_t rpc_jack_internal_clienthandle -( - mach_port_t server_port, - int refnum, - client_name_t client_name, - int *int_ref, - int *status, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_name_t client_name; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int int_ref; - int status; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int int_ref; - int status; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_internal_clienthandle_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_internal_clienthandle_t__defined */ - - __DeclareSendRpc(1017, "rpc_jack_internal_clienthandle") - - InP->NDR = NDR_record; - - InP->refnum = refnum; - - (void) mig_strncpy(InP->client_name, client_name, 64); - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1017; - - __BeforeSendRpc(1017, "rpc_jack_internal_clienthandle") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1017, "rpc_jack_internal_clienthandle") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_internal_clienthandle_t__defined) - check_result = __MIG_check__Reply__rpc_jack_internal_clienthandle_t((__Reply__rpc_jack_internal_clienthandle_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_internal_clienthandle_t__defined) */ - - *int_ref = Out0P->int_ref; - - *status = Out0P->status; - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_internal_clientload_t__defined) -#define __MIG_check__Reply__rpc_jack_internal_clientload_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__status__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__status__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__status(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__status__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__status(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__status__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__status(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__status__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__status(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__status__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__int_ref(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__int_ref(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__int_ref(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__int_ref(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__status__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__status__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__status(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__status__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__status(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__status__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__status(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__status__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__status(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__status__defined */ - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__int_ref(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__int_ref(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__int_ref(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__int_ref(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined */ - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__status__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__status__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__status(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__status__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__status(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__status__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__status(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__status__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__status(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__status__defined */ - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__int_ref(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__int_ref(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__int_ref(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__int_ref(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined */ - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_internal_clientload_t(__Reply__rpc_jack_internal_clientload_t *Out0P) -{ - - typedef __Reply__rpc_jack_internal_clientload_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1118) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__status__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__status__defined) - __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__status(&Out0P->status, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__status__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined) - __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__int_ref(&Out0P->int_ref, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clientload_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__status__defined) || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined) || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__status__defined) - __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__status(&Out0P->status, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__status__defined */ -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined) - __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__int_ref(&Out0P->int_ref, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined */ -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_internal_clientload_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__status__defined) || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined) || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__status__defined) - __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__status(&Out0P->status, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__status__defined */ -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined) - __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__int_ref(&Out0P->int_ref, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__int_ref__defined */ -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_internal_clientload_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_internal_clientload_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_internal_clientload */ -mig_external kern_return_t rpc_jack_internal_clientload -( - mach_port_t server_port, - int refnum, - client_name_t client_name, - so_name_t so_name, - objet_data_t objet_data, - int options, - int *status, - int *int_ref, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - client_name_t client_name; - so_name_t so_name; - objet_data_t objet_data; - int options; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int status; - int int_ref; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int status; - int int_ref; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_internal_clientload_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_internal_clientload_t__defined */ - - __DeclareSendRpc(1018, "rpc_jack_internal_clientload") - - InP->NDR = NDR_record; - - InP->refnum = refnum; - - (void) mig_strncpy(InP->client_name, client_name, 64); - - (void) mig_strncpy(InP->so_name, so_name, 256); - - (void) mig_strncpy(InP->objet_data, objet_data, 256); - - InP->options = options; - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1018; - - __BeforeSendRpc(1018, "rpc_jack_internal_clientload") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1018, "rpc_jack_internal_clientload") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_internal_clientload_t__defined) - check_result = __MIG_check__Reply__rpc_jack_internal_clientload_t((__Reply__rpc_jack_internal_clientload_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_internal_clientload_t__defined) */ - - *status = Out0P->status; - - *int_ref = Out0P->int_ref; - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__JackRPCEngine_subsystem__ -#if !defined(__MIG_check__Reply__rpc_jack_internal_clientunload_t__defined) -#define __MIG_check__Reply__rpc_jack_internal_clientunload_t__defined -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__RetCode__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__RetCode(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__status__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__status__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__status(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__status__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__status(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__status__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__status(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__status__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__status(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__status__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__result__defined -#if defined(__NDR_convert__int_rep__JackRPCEngine__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__result(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__result(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__result__defined -#define __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__result(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__result__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__status__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__status__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__status(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__status__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__status(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__status__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__status(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__status__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__status(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__status__defined */ - - -#ifndef __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__result__defined -#if defined(__NDR_convert__char_rep__JackRPCEngine__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__result(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__result(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__result__defined -#define __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__result(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__result__defined */ - - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__status__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__status__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__status(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__status__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__status(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__status__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__status(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__status__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__status(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__status__defined */ - - -#ifndef __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__result__defined -#if defined(__NDR_convert__float_rep__JackRPCEngine__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__result(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__JackRPCEngine__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__result(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__result__defined -#define __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__result(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__result__defined */ - - - -mig_internal kern_return_t __MIG_check__Reply__rpc_jack_internal_clientunload_t(__Reply__rpc_jack_internal_clientunload_t *Out0P) -{ - - typedef __Reply__rpc_jack_internal_clientunload_t __Reply; -#if __MigTypeCheck - unsigned int msgh_size; -#endif /* __MigTypeCheck */ - if (Out0P->Head.msgh_id != 1119) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - -#if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } -#endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { -#ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); -#endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__status__defined) || \ - defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__result__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__RetCode__defined) - __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__RetCode__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__status__defined) - __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__status(&Out0P->status, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__status__defined */ -#if defined(__NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__result__defined) - __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__result(&Out0P->result, Out0P->NDR.int_rep); -#endif /* __NDR_convert__int_rep__Reply__rpc_jack_internal_clientunload_t__result__defined */ - } -#endif /* defined(__NDR_convert__int_rep...) */ - -#if 0 || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__status__defined) || \ - defined(__NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__result__defined) - if (Out0P->NDR.char_rep != NDR_record.char_rep) { -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__status__defined) - __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__status(&Out0P->status, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__status__defined */ -#if defined(__NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__result__defined) - __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__result(&Out0P->result, Out0P->NDR.char_rep); -#endif /* __NDR_convert__char_rep__Reply__rpc_jack_internal_clientunload_t__result__defined */ - } -#endif /* defined(__NDR_convert__char_rep...) */ - -#if 0 || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__status__defined) || \ - defined(__NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__result__defined) - if (Out0P->NDR.float_rep != NDR_record.float_rep) { -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__status__defined) - __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__status(&Out0P->status, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__status__defined */ -#if defined(__NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__result__defined) - __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__result(&Out0P->result, Out0P->NDR.float_rep); -#endif /* __NDR_convert__float_rep__Reply__rpc_jack_internal_clientunload_t__result__defined */ - } -#endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__rpc_jack_internal_clientunload_t__defined) */ -#endif /* __MIG_check__Reply__JackRPCEngine_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine rpc_jack_internal_clientunload */ -mig_external kern_return_t rpc_jack_internal_clientunload -( - mach_port_t server_port, - int refnum, - int int_ref, - int *status, - int *result -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int int_ref; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int status; - int result; - mach_msg_trailer_t trailer; - } Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int status; - int result; - } __Reply; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_internal_clientunload_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_internal_clientunload_t__defined */ - - __DeclareSendRpc(1019, "rpc_jack_internal_clientunload") - - InP->NDR = NDR_record; - - InP->refnum = refnum; - - InP->int_ref = int_ref; - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = server_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 1019; - - __BeforeSendRpc(1019, "rpc_jack_internal_clientunload") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(1019, "rpc_jack_internal_clientunload") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - -#if defined(__MIG_check__Reply__rpc_jack_internal_clientunload_t__defined) - check_result = __MIG_check__Reply__rpc_jack_internal_clientunload_t((__Reply__rpc_jack_internal_clientunload_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } -#endif /* defined(__MIG_check__Reply__rpc_jack_internal_clientunload_t__defined) */ - - *status = Out0P->status; - - *result = Out0P->result; - - return KERN_SUCCESS; -} - -/* SimpleRoutine rpc_jack_client_rt_notify */ -mig_external kern_return_t rpc_jack_client_rt_notify -( - mach_port_t client_port, - int refnum, - int notify, - int value, - int timeout -) -{ - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - int refnum; - int notify; - int value; - } Request; -#ifdef __MigPackStructs -#pragma pack() -#endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - } Mess; - - Request *InP = &Mess.In; - - mach_msg_return_t msg_result; - -#ifdef __MIG_check__Reply__rpc_jack_client_rt_notify_t__defined - kern_return_t check_result; -#endif /* __MIG_check__Reply__rpc_jack_client_rt_notify_t__defined */ - - __DeclareSendSimple(1020, "rpc_jack_client_rt_notify") - - InP->NDR = NDR_record; - - InP->refnum = refnum; - - InP->notify = notify; - - InP->value = value; - - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, 0); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = client_port; - InP->Head.msgh_reply_port = MACH_PORT_NULL; - InP->Head.msgh_id = 1020; - - __BeforeSendSimple(1020, "rpc_jack_client_rt_notify") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_SEND_TIMEOUT|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), 0, MACH_PORT_NULL, timeout, MACH_PORT_NULL); - __AfterSendSimple(1020, "rpc_jack_client_rt_notify") - - if (msg_result == MACH_SEND_TIMED_OUT) { - } - - return msg_result; -} diff --git a/macosx/RPC/Jackdefs.h b/macosx/RPC/Jackdefs.h deleted file mode 100644 index 5e73d984..00000000 --- a/macosx/RPC/Jackdefs.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -Copyright (C) 2004-2006 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. - -*/ - -typedef char client_name_t[64]; -typedef char client_port_name_t[128]; -typedef char client_port_type_t[128]; -typedef char so_name_t[256]; -typedef char objet_data_t[256]; -typedef char message_t[256]; diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index a1403df3..3b02ae9c 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -216,8 +216,8 @@ OSStatus JackCoreAudioDriver::Render(void *inRefCon, int JackCoreAudioDriver::Read() { - AudioUnitRender(fAUHAL, fActionFags, fCurrentTime, 1, fEngineControl->fBufferSize, fJackInputData); - return 0; + OSStatus err = AudioUnitRender(fAUHAL, fActionFags, fCurrentTime, 1, fEngineControl->fBufferSize, fJackInputData); + return (err == noErr) ? 0 : -1; } int JackCoreAudioDriver::Write() @@ -1366,7 +1366,7 @@ int JackCoreAudioDriver::SetupBuffers(int inchannels) // Prepare buffers fJackInputData = (AudioBufferList*)malloc(sizeof(UInt32) + inchannels * sizeof(AudioBuffer)); fJackInputData->mNumberBuffers = inchannels; - for (int i = 0; i < fCaptureChannels; i++) { + for (int i = 0; i < inchannels; i++) { fJackInputData->mBuffers[i].mNumberChannels = 1; fJackInputData->mBuffers[i].mDataByteSize = fEngineControl->fBufferSize * sizeof(float); } @@ -1478,11 +1478,6 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, char playback_driver_name[256]; // Keep initial state - fCapturing = capturing; - fPlaying = playing; - fInChannels = inchannels; - fOutChannels = outchannels; - fMonitor = monitor; strcpy(fCaptureUID, capture_driver_uid); strcpy(fPlaybackUID, playback_driver_uid); fCaptureLatency = capture_latency; diff --git a/macosx/coreaudio/JackCoreAudioDriver.h b/macosx/coreaudio/JackCoreAudioDriver.h index 9f827dfc..b0ccbe10 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.h +++ b/macosx/coreaudio/JackCoreAudioDriver.h @@ -68,17 +68,9 @@ class JackCoreAudioDriver : public JackAudioDriver bool fState; bool fHogged; - // Initial state - bool fCapturing; - bool fPlaying; - - int fInChannels; - int fOutChannels; - char fCaptureUID[256]; char fPlaybackUID[256]; - bool fMonitor; float fIOUsage; float fComputationGrain; bool fClockDriftCompensate; diff --git a/posix/JackCompilerDeps_os.h b/posix/JackCompilerDeps_os.h index 767674e1..83afb8e9 100644 --- a/posix/JackCompilerDeps_os.h +++ b/posix/JackCompilerDeps_os.h @@ -48,7 +48,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #define SERVER_EXPORT __attribute__((visibility("default"))) #endif #else - #define SERVER_EXPORT + #define SERVER_EXPORT __attribute__((visibility("hidden"))) #endif #else #define MEM_ALIGN(x,y) x diff --git a/posix/JackPosixThread.cpp b/posix/JackPosixThread.cpp index 67d2d0c8..4b4315db 100644 --- a/posix/JackPosixThread.cpp +++ b/posix/JackPosixThread.cpp @@ -117,7 +117,7 @@ int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, voi if ((res = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED))) { jack_error("Cannot request explicit scheduling for RT thread res = %d", res); return -1; - } + } if ((res = pthread_attr_setschedpolicy(&attributes, JACK_SCHED_POLICY))) { jack_error("Cannot set RR scheduling class for RT thread res = %d", res); @@ -270,6 +270,11 @@ pthread_t JackPosixThread::GetThreadID() return fThread; } +bool JackPosixThread::IsThread() +{ + return pthread_self() == fThread; +} + void JackPosixThread::Terminate() { jack_log("JackPosixThread::Terminate"); diff --git a/posix/JackPosixThread.h b/posix/JackPosixThread.h index 73345e17..d38c573c 100644 --- a/posix/JackPosixThread.h +++ b/posix/JackPosixThread.h @@ -68,10 +68,11 @@ class SERVER_EXPORT JackPosixThread : public detail::JackThreadInterface int DropSelfRealTime(); // Used when called from thread itself pthread_t GetThreadID(); + bool IsThread(); static int AcquireRealTimeImp(pthread_t thread, int priority); static int AcquireRealTimeImp(pthread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) - { return JackPosixThread::AcquireRealTimeImp(thread, priority); } + { return JackPosixThread::AcquireRealTimeImp(thread, priority); } static int DropRealTimeImp(pthread_t thread); static int StartImp(pthread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg); static int StopImp(pthread_t thread); diff --git a/posix/JackSocket.cpp b/posix/JackSocket.cpp index ec891acb..e1984195 100644 --- a/posix/JackSocket.cpp +++ b/posix/JackSocket.cpp @@ -129,7 +129,7 @@ int JackClientSocket::Connect(const char* dir, const char* name, int which) // A } #ifdef __APPLE__ - int on = 1 ; + int on = 1; if (setsockopt(fSocket, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) { jack_log("setsockopt SO_NOSIGPIPE fd = %ld err = %s", fSocket, strerror(errno)); } @@ -260,7 +260,7 @@ int JackServerSocket::Bind(const char* dir, const char* name, int which) // A re goto error; } - if (listen(fSocket, 1) < 0) { + if (listen(fSocket, 100) < 0) { jack_error("Cannot enable listen on server socket err = %s", strerror(errno)); goto error; } diff --git a/posix/JackSocketClientChannel.cpp b/posix/JackSocketClientChannel.cpp index d2d4b676..1a6d7ad5 100644 --- a/posix/JackSocketClientChannel.cpp +++ b/posix/JackSocketClientChannel.cpp @@ -51,7 +51,7 @@ int JackSocketClientChannel::ServerCheck(const char* server_name) } } -int JackSocketClientChannel::Open(const char* server_name, const char* name, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status) +int JackSocketClientChannel::Open(const char* server_name, const char* name, int uuid, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status) { int result = 0; jack_log("JackSocketClientChannel::Open name = %s", name); @@ -62,7 +62,7 @@ int JackSocketClientChannel::Open(const char* server_name, const char* name, cha } // Check name in server - ClientCheck(name, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result); + ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result); if (result < 0) { int status1 = *status; if (status1 & JackVersionError) @@ -142,18 +142,18 @@ void JackSocketClientChannel::ServerAsyncCall(JackRequest* req, JackResult* res, } } -void JackSocketClientChannel::ClientCheck(const char* name, char* name_res, int protocol, int options, int* status, int* result) +void JackSocketClientChannel::ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result) { - JackClientCheckRequest req(name, protocol, options); + JackClientCheckRequest req(name, protocol, options, uuid); JackClientCheckResult res; ServerSyncCall(&req, &res, result); *status = res.fStatus; strcpy(name_res, res.fName); } -void JackSocketClientChannel::ClientOpen(const char* name, int pid, int* shared_engine, int* shared_client, int* shared_graph, int* result) +void JackSocketClientChannel::ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result) { - JackClientOpenRequest req(name, pid); + JackClientOpenRequest req(name, pid, uuid); JackClientOpenResult res; ServerSyncCall(&req, &res, result); *shared_engine = res.fSharedEngine; @@ -246,6 +246,64 @@ void JackSocketClientChannel::SetFreewheel(int onoff, int* result) ServerSyncCall(&req, &res, result); } +void JackSocketClientChannel::SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t ** result) +{ + JackSessionNotifyRequest req(refnum, path, type, target); + JackSessionNotifyResult res; + int intresult; + ServerSyncCall(&req, &res, &intresult); + + jack_session_command_t *session_command = (jack_session_command_t *)malloc( sizeof(jack_session_command_t) * (res.fCommandList.size()+1) ); + int i=0; + + for (std::list::iterator ci=res.fCommandList.begin(); ci!=res.fCommandList.end(); ci++) { + session_command[i].uuid = strdup( ci->fUUID ); + session_command[i].client_name = strdup( ci->fClientName ); + session_command[i].command = strdup( ci->fCommand ); + session_command[i].flags = ci->fFlags; + + i+=1; + } + + session_command[i].uuid = NULL; + session_command[i].client_name = NULL; + session_command[i].command = NULL; + session_command[i].flags = (jack_session_flags_t)0; + + + *result = session_command; +} + +void JackSocketClientChannel::SessionReply(int refnum, int* result) +{ + JackSessionReplyRequest req(refnum); + JackResult res; + ServerSyncCall(&req, &res, result); +} + +void JackSocketClientChannel::GetUUIDForClientName( int refnum, const char *client_name, char *uuid_res, int *result ) +{ + JackGetUUIDRequest req(client_name); + JackUUIDResult res; + ServerSyncCall(&req, &res, result); + strncpy( uuid_res, res.fUUID, JACK_UUID_SIZE ); +} + +void JackSocketClientChannel::GetClientNameForUUID( int refnum, const char *uuid, char *name_res, int *result ) +{ + JackGetClientNameRequest req(uuid); + JackClientNameResult res; + ServerSyncCall(&req, &res, result); + strncpy( name_res, res.fName, JACK_CLIENT_NAME_SIZE ); +} + +void JackSocketClientChannel::ReserveClientName( int refnum, const char *client_name, const char *uuid, int *result ) +{ + JackReserveNameRequest req(refnum, client_name, uuid); + JackResult res; + ServerSyncCall(&req, &res, result); +} + void JackSocketClientChannel::ReleaseTimebase(int refnum, int* result) { JackReleaseTimebaseRequest req(refnum); @@ -277,9 +335,9 @@ void JackSocketClientChannel::InternalClientHandle(int refnum, const char* clien *status = res.fStatus; } -void JackSocketClientChannel::InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int* result) +void JackSocketClientChannel::InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result) { - JackInternalClientLoadRequest req(refnum, client_name, so_name, objet_data, options); + JackInternalClientLoadRequest req(refnum, client_name, so_name, objet_data, options, uuid); JackInternalClientLoadResult res; ServerSyncCall(&req, &res, result); *int_ref = res.fIntRefNum; diff --git a/posix/JackSocketClientChannel.h b/posix/JackSocketClientChannel.h index c9004293..225887e7 100644 --- a/posix/JackSocketClientChannel.h +++ b/posix/JackSocketClientChannel.h @@ -38,11 +38,11 @@ class JackSocketClientChannel : public detail::JackClientChannelInterface, publi private: - JackClientSocket fRequestSocket; // Socket to communicate with the server - JackServerSocket fNotificationListenSocket; // Socket listener for server notification - JackClientSocket* fNotificationSocket; // Socket for server notification + JackClientSocket fRequestSocket; // Socket to communicate with the server + JackServerSocket fNotificationListenSocket; // Socket listener for server notification + JackClientSocket* fNotificationSocket; // Socket for server notification JackThread fThread; // Thread to execute the event loop - JackClient* fClient; + JackClient* fClient; void ServerSyncCall(JackRequest* req, JackResult* res, int* result); void ServerAsyncCall(JackRequest* req, JackResult* res, int* result); @@ -52,7 +52,7 @@ class JackSocketClientChannel : public detail::JackClientChannelInterface, publi JackSocketClientChannel(); virtual ~JackSocketClientChannel(); - int Open(const char* server_name, const char* name, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status); + int Open(const char* server_name, const char* name, int uuid, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status); void Close(); int Start(); @@ -60,9 +60,9 @@ class JackSocketClientChannel : public detail::JackClientChannelInterface, publi int ServerCheck(const char* server_name); - void ClientCheck(const char* name, char* name_res, int protocol, int options, int* status, int* result); - void ClientOpen(const char* name, int pid, int* shared_engine, int* shared_client, int* shared_graph, int* result); - void ClientOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, int* result) + void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result); + void ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result); + void ClientOpen(const char* name, int* ref, int uuid, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, int* result) {} void ClientClose(int refnum, int* result); @@ -88,12 +88,22 @@ class JackSocketClientChannel : public detail::JackClientChannelInterface, publi void GetInternalClientName(int refnum, int int_ref, char* name_res, int* result); void InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result); - void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int* result); + void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result); void InternalClientUnload(int refnum, int int_ref, int* status, int* result); + // Session Stuff + void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t** result); + void SessionReply(int refnum, int* result); + void GetUUIDForClientName( int refnum, const char *client_name, char *uuid_res, int *result ); + void GetClientNameForUUID( int refnum, const char *uuid, char *name_res, int *result ); + void ReserveClientName( int refnum, const char *client_name, const char *uuid, int *result ); + // JackRunnableInterface interface bool Init(); bool Execute(); + + + bool IsChannelThread() { return fThread.IsThread(); } }; } // end of namespace diff --git a/posix/JackSocketServerChannel.cpp b/posix/JackSocketServerChannel.cpp index d2a59b33..e9176230 100644 --- a/posix/JackSocketServerChannel.cpp +++ b/posix/JackSocketServerChannel.cpp @@ -102,14 +102,20 @@ void JackSocketServerChannel::ClientCreate() } } -void JackSocketServerChannel::ClientAdd(int fd, char* name, int pid, int* shared_engine, int* shared_client, int* shared_graph, int* result) +void JackSocketServerChannel::ClientAdd(int fd, char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result) { jack_log("JackSocketServerChannel::ClientAdd"); int refnum = -1; - *result = fServer->GetEngine()->ClientExternalOpen(name, pid, &refnum, shared_engine, shared_client, shared_graph); + *result = fServer->GetEngine()->ClientExternalOpen(name, pid, uuid, &refnum, shared_engine, shared_client, shared_graph); if (*result == 0) { fSocketTable[fd].first = refnum; fRebuild = true; + #ifdef __APPLE__ + int on = 1; + if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) { + jack_log("setsockopt SO_NOSIGPIPE fd = %ld err = %s", fd, strerror(errno)); + } + #endif } else { jack_error("Cannot create new client"); } @@ -170,7 +176,7 @@ bool JackSocketServerChannel::HandleRequest(int fd) JackClientCheckRequest req; JackClientCheckResult res; if (req.Read(socket) == 0) - res.fResult = fServer->GetEngine()->ClientCheck(req.fName, res.fName, req.fProtocol, req.fOptions, &res.fStatus); + res.fResult = fServer->GetEngine()->ClientCheck(req.fName, req.fUUID, res.fName, req.fProtocol, req.fOptions, &res.fStatus); if (res.Write(socket) < 0) jack_error("JackRequest::ClientCheck write error name = %s", req.fName); break; @@ -181,7 +187,7 @@ bool JackSocketServerChannel::HandleRequest(int fd) JackClientOpenRequest req; JackClientOpenResult res; if (req.Read(socket) == 0) - ClientAdd(fd, req.fName, req.fPID, &res.fSharedEngine, &res.fSharedClient, &res.fSharedGraph, &res.fResult); + ClientAdd(fd, req.fName, req.fPID, req.fUUID, &res.fSharedEngine, &res.fSharedClient, &res.fSharedGraph, &res.fResult); if (res.Write(socket) < 0) jack_error("JackRequest::ClientOpen write error name = %s", req.fName); break; @@ -369,7 +375,7 @@ bool JackSocketServerChannel::HandleRequest(int fd) JackInternalClientLoadRequest req; JackInternalClientLoadResult res; if (req.Read(socket) == 0) - res.fResult = fServer->InternalClientLoad(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, &res.fStatus); + res.fResult = fServer->InternalClientLoad(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, req.fUUID, &res.fStatus); if (res.Write(socket) < 0) jack_error("JackRequest::InternalClientLoad write error name = %s", req.fName); break; @@ -400,6 +406,66 @@ bool JackSocketServerChannel::HandleRequest(int fd) break; } + case JackRequest::kSessionNotify: { + jack_log("JackRequest::SessionNotify"); + JackSessionNotifyRequest req; + JackSessionNotifyResult res; + if (req.Read(socket) == 0) { + fServer->GetEngine()->SessionNotify(req.fRefNum, req.fDst, req.fEventType, req.fPath, socket); + } + break; + } + + case JackRequest::kSessionReply: { + jack_log("JackRequest::SessionReply"); + JackSessionReplyRequest req; + JackResult res; + if (req.Read(socket) == 0) { + fServer->GetEngine()->SessionReply(req.fRefNum); + res.fResult = 0; + } + if (res.Write(socket) < 0) + jack_error("JackRequest::SessionReply write error"); + break; + } + + case JackRequest::kGetClientByUUID: { + jack_log("JackRequest::GetClientNameForUUID"); + JackGetClientNameRequest req; + JackClientNameResult res; + if (req.Read(socket) == 0) { + fServer->GetEngine()->GetClientNameForUUID(req.fUUID, res.fName, &res.fResult); + } + if (res.Write(socket) < 0) + jack_error("JackRequest::GetClientNameForUUID write error"); + break; + } + + case JackRequest::kGetUUIDByClient: { + jack_log("JackRequest::GetUUIDForClientName"); + JackGetUUIDRequest req; + JackUUIDResult res; + if (req.Read(socket) == 0) { + fServer->GetEngine()->GetUUIDForClientName(req.fName, res.fUUID, &res.fResult); + res.fResult = 0; + } + if (res.Write(socket) < 0) + jack_error("JackRequest::GetUUIDForClientName write error"); + break; + } + + case JackRequest::kReserveClientName: { + jack_log("JackRequest::ReserveClientName"); + JackReserveNameRequest req; + JackResult res; + if (req.Read(socket) == 0) { + fServer->GetEngine()->ReserveClientName(req.fName, req.fUUID, &res.fResult); + } + if (res.Write(socket) < 0) + jack_error("JackRequest::ReserveClientName write error"); + break; + } + default: jack_error("Unknown request %ld", header.fType); break; diff --git a/posix/JackSocketServerChannel.h b/posix/JackSocketServerChannel.h index 60b86325..59c1a0d0 100644 --- a/posix/JackSocketServerChannel.h +++ b/posix/JackSocketServerChannel.h @@ -39,10 +39,10 @@ class JackSocketServerChannel : public JackRunnableInterface private: - JackServerSocket fRequestListenSocket; // Socket to create request socket for the client + JackServerSocket fRequestListenSocket; // Socket to create request socket for the client JackThread fThread; // Thread to execute the event loop - JackServer* fServer; - pollfd* fPollTable; + JackServer* fServer; + pollfd* fPollTable; bool fRebuild; std::map > fSocketTable; @@ -50,7 +50,7 @@ class JackSocketServerChannel : public JackRunnableInterface void BuildPoolTable(); void ClientCreate(); - void ClientAdd(int fd, char* name, int pid, int* shared_engine, int* shared_client, int* shared_graph, int* result); + void ClientAdd(int fd, char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result); void ClientRemove(int fd, int refnum); void ClientKill(int fd); diff --git a/solaris/oss/JackBoomerDriver.cpp b/solaris/oss/JackBoomerDriver.cpp index f10b2e89..fc054541 100644 --- a/solaris/oss/JackBoomerDriver.cpp +++ b/solaris/oss/JackBoomerDriver.cpp @@ -634,6 +634,7 @@ bool JackBoomerDriver::JackBoomerDriverInput::Init() return true; } +// TODO : better error handling bool JackBoomerDriver::JackBoomerDriverInput::Execute() { @@ -721,6 +722,7 @@ bool JackBoomerDriver::JackBoomerDriverOutput::Init() return true; } +// TODO : better error handling bool JackBoomerDriver::JackBoomerDriverOutput::Execute() { memset(fDriver->fOutputBuffer, 0, fDriver->fOutputBufferSize); diff --git a/solaris/oss/JackBoomerDriver.h b/solaris/oss/JackBoomerDriver.h index 61fc5c50..c98e28a3 100644 --- a/solaris/oss/JackBoomerDriver.h +++ b/solaris/oss/JackBoomerDriver.h @@ -152,10 +152,7 @@ class JackBoomerDriver : public JackAudioDriver } int SetBufferSize(jack_nframes_t buffer_size); - - bool Init(); - bool Execute(); - + }; } // end of namespace diff --git a/solaris/oss/JackOSSDriver.cpp b/solaris/oss/JackOSSDriver.cpp index 7890f6ae..3b66740a 100644 --- a/solaris/oss/JackOSSDriver.cpp +++ b/solaris/oss/JackOSSDriver.cpp @@ -707,7 +707,7 @@ int JackOSSDriver::ProcessSync() // Read input buffers for the current cycle if (Read() < 0) { jack_error("ProcessSync: read error, skip cycle"); - return 0; // Skip cycle, but continue processing... + return 0; // Non fatal error here, skip cycle, but continue processing... } if (fIsMaster) { @@ -719,7 +719,7 @@ int JackOSSDriver::ProcessSync() // Write output buffers for the current cycle if (Write() < 0) { jack_error("JackAudioDriver::ProcessSync: write error, skip cycle"); - return 0; // Skip cycle, but continue processing... + return 0; // Non fatal error here, skip cycle, but continue processing... } return 0; diff --git a/tests/test.cpp b/tests/test.cpp index 4e181f65..1a6e4a05 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -169,7 +169,7 @@ void Jack_Thread_Init_Callback(void *arg) void Jack_Freewheel_Callback(int starting, void *arg) { - Log("Freewhell callback has been successfully called with value %i. (msg from callback)\n", starting); + Log("Freewheel callback has been successfully called with value %i. (msg from callback)\n", starting); FW = starting; } @@ -633,39 +633,39 @@ int main (int argc, char *argv[]) if (status & JackServerStarted) { fprintf(stderr, "JACK server started\n"); } - + /** * Internal client tests... * */ jack_intclient_t intclient; - + Log("trying to load the \"inprocess\" server internal client \n"); - + intclient = jack_internal_client_load (client1, "inprocess", (jack_options_t)(JackLoadName|JackLoadInit), &status, "inprocess", ""); - + if (intclient == 0 || status & JackFailure) { printf("!!! ERROR !!! cannot load internal client \"inprocess\" intclient %d status 0x%2.0x !\n", intclient, status); } else { - + Log("\"inprocess\" server internal client loaded\n"); - + char* internal_name = jack_get_internal_client_name(client1, intclient); if (strcmp(internal_name, "inprocess") == 0) { Log("jack_get_internal_client_name returns %s\n", internal_name); } else { printf("!!! ERROR !!! jack_get_internal_client_name returns incorrect name %s\n", internal_name); } - + jack_intclient_t intclient1 = jack_internal_client_handle(client1, "inprocess", &status); if (intclient1 == intclient) { Log("jack_internal_client_handle returns correct handle\n"); } else { printf("!!! ERROR !!! jack_internal_client_handle returns incorrect handle %d\n", intclient1); } - + // Unload internal client status = jack_internal_client_unload (client1, intclient); if (status == 0) { @@ -673,7 +673,7 @@ int main (int argc, char *argv[]) } else { printf("!!! ERROR !!! jack_internal_client_unload returns incorrect value 0x%2.0x\n", status); } - + // Unload internal client second time status = jack_internal_client_unload (client1, intclient); if (status & JackFailure && status & JackNoSuchClient) { @@ -682,8 +682,8 @@ int main (int argc, char *argv[]) printf("!!! ERROR !!! jack_internal_client_unload returns incorrect value 0x%2.0x\n", status); } } - - + + /** * try to register another one with the same name... * @@ -738,7 +738,7 @@ int main (int argc, char *argv[]) printf("!!! ERROR !!! while calling jack_set_thread_init_callback()...\n"); if (jack_set_freewheel_callback(client1, Jack_Freewheel_Callback, 0) != 0 ) printf("\n!!! ERROR !!! while calling jack_set_freewheel_callback()...\n"); - + if (jack_set_process_callback(client1, process1, 0) != 0) { printf("Error when calling jack_set_process_callback() !\n"); @@ -754,7 +754,7 @@ int main (int argc, char *argv[]) if (jack_set_graph_order_callback(client1, Jack_Graph_Order_Callback, 0) != 0) { printf("Error when calling Jack_Graph_Order_Callback() !\n"); } - + if (jack_set_port_rename_callback(client1, Jack_Port_Rename_Callback, 0) != 0 ) printf("\n!!! ERROR !!! while calling jack_set_rename_callback()...\n"); @@ -874,7 +874,7 @@ int main (int argc, char *argv[]) } port_callback_reg = 0; // number of port registration received by the callback - + /** * Activate the client * @@ -883,31 +883,31 @@ int main (int argc, char *argv[]) printf ("Fatal error : cannot activate client1\n"); exit(1); } - + /** * Test if portrename callback have been called. * */ jack_port_set_name (output_port1, "renamed-port#"); - jack_sleep(1 * 1000); + jack_sleep(1 * 1000); if (port_rename_clbk == 0) printf("!!! ERROR !!! Jack_Port_Rename_Callback was not called !!.\n"); - - + + /** * Test if portregistration callback have been called. * */ - - jack_sleep(1 * 1000); + + jack_sleep(1 * 1000); if (1 == port_callback_reg) { Log("%i ports have been successfully created, and %i callback reg ports have been received... ok\n", 1, port_callback_reg); } else { printf("!!! ERROR !!! %i ports have been created, and %i callback reg ports have been received !\n", 1, port_callback_reg); } - + /** * Test if init callback initThread have been called. * @@ -1162,14 +1162,14 @@ int main (int argc, char *argv[]) } jack_sleep(1 * 1000); // To hope all port registration and reorder callback have been received... - + // Check port registration callback if (j == port_callback_reg) { Log("%i ports have been successfully created, and %i callback reg ports have been received... ok\n", j, port_callback_reg); } else { printf("!!! ERROR !!! %i ports have been created, and %i callback reg ports have been received !\n", j, port_callback_reg); } - + if (reorder == (2 * j)) { Log("%i graph reorder callback have been received... ok\n", reorder); } else { @@ -1231,9 +1231,9 @@ int main (int argc, char *argv[]) } a++; } - + // Check port registration callback again - if (j == port_callback_reg) { + if (j == port_callback_reg) { Log("%i ports have been successfully created, and %i callback reg ports have been received... ok\n", j, port_callback_reg); } else { printf("!!! ERROR !!! %i ports have been created, and %i callback reg ports have been received !\n", j, port_callback_reg); diff --git a/windows/JackWinNamedPipeClientChannel.cpp b/windows/JackWinNamedPipeClientChannel.cpp index 9b3e2473..af390d21 100644 --- a/windows/JackWinNamedPipeClientChannel.cpp +++ b/windows/JackWinNamedPipeClientChannel.cpp @@ -48,7 +48,7 @@ int JackWinNamedPipeClientChannel::ServerCheck(const char* server_name) } } -int JackWinNamedPipeClientChannel::Open(const char* server_name, const char* name, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status) +int JackWinNamedPipeClientChannel::Open(const char* server_name, const char* name, int uuid, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status) { int result = 0; jack_log("JackWinNamedPipeClientChannel::Open name = %s", name); @@ -67,7 +67,7 @@ int JackWinNamedPipeClientChannel::Open(const char* server_name, const char* nam } // Check name in server - ClientCheck(name, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result); + ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result); if (result < 0) { jack_error("Client name = %s conflits with another running client", name); goto error; @@ -142,18 +142,18 @@ void JackWinNamedPipeClientChannel::ServerAsyncCall(JackRequest* req, JackResult } } -void JackWinNamedPipeClientChannel::ClientCheck(const char* name, char* name_res, int protocol, int options, int* status, int* result) +void JackWinNamedPipeClientChannel::ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result) { - JackClientCheckRequest req(name, protocol, options); + JackClientCheckRequest req(name, protocol, options, uuid); JackClientCheckResult res; ServerSyncCall(&req, &res, result); *status = res.fStatus; strcpy(name_res, res.fName); } -void JackWinNamedPipeClientChannel::ClientOpen(const char* name, int pid, int* shared_engine, int* shared_client, int* shared_graph, int* result) +void JackWinNamedPipeClientChannel::ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result) { - JackClientOpenRequest req(name, pid); + JackClientOpenRequest req(name, pid, uuid); JackClientOpenResult res; ServerSyncCall(&req, &res, result); *shared_engine = res.fSharedEngine; @@ -246,6 +246,16 @@ void JackWinNamedPipeClientChannel::SetFreewheel(int onoff, int* result) ServerSyncCall(&req, &res, result); } +void JackWinNamedPipeClientChannel::SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t** result) +{ + JackSessionNotifyRequest req(refnum, target, type, path); + JackResult res; + int intresult; + ServerSyncCall(&req, &res, &intresult); + + *result = NULL; +} + void JackWinNamedPipeClientChannel::ReleaseTimebase(int refnum, int* result) { JackReleaseTimebaseRequest req(refnum); @@ -277,9 +287,9 @@ void JackWinNamedPipeClientChannel::InternalClientHandle(int refnum, const char* *status = res.fStatus; } -void JackWinNamedPipeClientChannel::InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int* result) +void JackWinNamedPipeClientChannel::InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result) { - JackInternalClientLoadRequest req(refnum, client_name, so_name, objet_data, options); + JackInternalClientLoadRequest req(refnum, client_name, so_name, objet_data, options, uuid); JackInternalClientLoadResult res; ServerSyncCall(&req, &res, result); *int_ref = res.fIntRefNum; diff --git a/windows/JackWinNamedPipeClientChannel.h b/windows/JackWinNamedPipeClientChannel.h index fc5617e7..aa23266b 100644 --- a/windows/JackWinNamedPipeClientChannel.h +++ b/windows/JackWinNamedPipeClientChannel.h @@ -1,20 +1,20 @@ /* Copyright (C) 2004-2008 Grame - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 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 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - + */ @@ -51,7 +51,7 @@ class JackWinNamedPipeClientChannel : public detail::JackClientChannelInterface, JackWinNamedPipeClientChannel(); virtual ~JackWinNamedPipeClientChannel(); - int Open(const char* server_name, const char* name, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status); + int Open(const char* server_name, const char* name, int uuid, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status); void Close(); int Start(); @@ -59,8 +59,8 @@ class JackWinNamedPipeClientChannel : public detail::JackClientChannelInterface, int ServerCheck(const char* server_name); - void ClientCheck(const char* name, char* name_res, int protocol, int options, int* status, int* result); - void ClientOpen(const char* name, int pid, int* shared_engine, int* shared_client, int* shared_graph, int* result); + void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result); + void ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result); void ClientOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, int* result) {} void ClientClose(int refnum, int* result); @@ -76,7 +76,7 @@ class JackWinNamedPipeClientChannel : public detail::JackClientChannelInterface, void PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result); void PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result); - + void PortRename(int refnum, jack_port_id_t port, const char* name, int* result); void SetBufferSize(jack_nframes_t buffer_size, int* result); @@ -87,9 +87,11 @@ class JackWinNamedPipeClientChannel : public detail::JackClientChannelInterface, void GetInternalClientName(int refnum, int int_ref, char* name_res, int* result); void InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result); - void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int* result); + void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result); void InternalClientUnload(int refnum, int int_ref, int* status, int* result); + void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t** result); + // JackRunnableInterface interface bool Init(); bool Execute(); diff --git a/windows/JackWinNamedPipeServerChannel.cpp b/windows/JackWinNamedPipeServerChannel.cpp index a8ce3a22..a8093ecb 100644 --- a/windows/JackWinNamedPipeServerChannel.cpp +++ b/windows/JackWinNamedPipeServerChannel.cpp @@ -53,7 +53,7 @@ JackClientPipeThread::~JackClientPipeThread() delete fPipe; } -int JackClientPipeThread::Open(JackServer* server) // Open the Server/Client connection +int JackClientPipeThread::Open(JackServer* server) // Open the Server/Client connection { // Start listening if (fThread.Start() != 0) { @@ -65,13 +65,13 @@ int JackClientPipeThread::Open(JackServer* server) // Open the Server/Client con return 0; } -void JackClientPipeThread::Close() // Close the Server/Client connection +void JackClientPipeThread::Close() // Close the Server/Client connection { jack_log("JackClientPipeThread::Close %x %ld", this, fRefNum); /* - TODO : solve WIN32 thread Kill issue - This would hang.. since Close will be followed by a delete, - all ressources will be desallocated at the end. + TODO : solve WIN32 thread Kill issue + This would hang.. since Close will be followed by a delete, + all ressources will be desallocated at the end. */ fThread.Kill(); @@ -115,7 +115,7 @@ bool JackClientPipeThread::HandleRequest() JackClientCheckRequest req; JackClientCheckResult res; if (req.Read(fPipe) == 0) - res.fResult = fServer->GetEngine()->ClientCheck(req.fName, res.fName, req.fProtocol, req.fOptions, &res.fStatus); + res.fResult = fServer->GetEngine()->ClientCheck(req.fName, req.fUUID, res.fName, req.fProtocol, req.fOptions, &res.fStatus); res.Write(fPipe); break; } @@ -125,7 +125,7 @@ bool JackClientPipeThread::HandleRequest() JackClientOpenRequest req; JackClientOpenResult res; if (req.Read(fPipe) == 0) - ClientAdd(req.fName, req.fPID, &res.fSharedEngine, &res.fSharedClient, &res.fSharedGraph, &res.fResult); + ClientAdd(req.fName, req.fPID, req.fUUID, &res.fSharedEngine, &res.fSharedClient, &res.fSharedGraph, &res.fResult); res.Write(fPipe); break; } @@ -297,7 +297,7 @@ bool JackClientPipeThread::HandleRequest() JackInternalClientLoadRequest req; JackInternalClientLoadResult res; if (req.Read(fPipe) == 0) - res.fResult = fServer->InternalClientLoad(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, &res.fStatus); + res.fResult = fServer->InternalClientLoad(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, req.fUUID, &res.fStatus); res.Write(fPipe); break; } @@ -326,6 +326,63 @@ bool JackClientPipeThread::HandleRequest() break; } + case JackRequest::kSessionNotify: { + jack_log("JackRequest::SessionNotify"); + JackSessionNotifyRequest req; + JackSessionNotifyResult res; + if (req.Read(fPipe) == 0) { + fServer->GetEngine()->SessionNotify(req.fRefNum, req.fDst, req.fEventType, req.fPath, fPipe); + } + res.Write(fPipe); + break; + } + + case JackRequest::kSessionReply: { + jack_log("JackRequest::SessionReply"); + JackSessionReplyRequest req; + JackResult res; + if (req.Read(fPipe) == 0) { + fServer->GetEngine()->SessionReply(req.fRefNum); + res.fResult = 0; + } + break; + } + + case JackRequest::kGetClientByUUID: { + jack_log("JackRequest::GetClientNameForUUID"); + JackGetClientNameRequest req; + JackClientNameResult res; + if (req.Read(fPipe) == 0) { + fServer->GetEngine()->GetClientNameForUUID(req.fUUID, res.fName, &res.fResult); + } + res.Write(fPipe); + break; + } + + case JackRequest::kGetUUIDByClient: { + jack_log("JackRequest::GetUUIDForClientName"); + JackGetUUIDRequest req; + JackUUIDResult res; + if (req.Read(fPipe) == 0) { + fServer->GetEngine()->GetUUIDForClientName(req.fName, res.fUUID, &res.fResult); + res.fResult = 0; + } + res.Write(fPipe); + break; + } + + case JackRequest::kReserveClientName: { + jack_log("JackRequest::ReserveClientName"); + JackReserveNameRequest req; + JackResult res; + if (req.Read(fPipe) == 0) { + fServer->GetEngine()->ReserveClientName(req.fName, req.fUUID, &res.fResult); + res.fResult = 0; + } + res.Write(fPipe); + break; + } + default: jack_log("Unknown request %ld", header.fType); break; @@ -337,11 +394,11 @@ bool JackClientPipeThread::HandleRequest() return ret; } -void JackClientPipeThread::ClientAdd(char* name, int pid, int* shared_engine, int* shared_client, int* shared_graph, int* result) +void JackClientPipeThread::ClientAdd(char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result) { jack_log("JackClientPipeThread::ClientAdd %s", name); fRefNum = -1; - *result = fServer->GetEngine()->ClientExternalOpen(name, pid, &fRefNum, shared_engine, shared_client, shared_graph); + *result = fServer->GetEngine()->ClientExternalOpen(name, pid, uuid, &fRefNum, shared_engine, shared_client, shared_graph); } void JackClientPipeThread::ClientRemove() @@ -358,7 +415,7 @@ void JackClientPipeThread::ClientKill() { jack_log("JackClientPipeThread::ClientKill ref = %d", fRefNum); - if (fRefNum == -1) { // Correspond to an already removed client. + if (fRefNum == -1) { // Correspond to an already removed client. jack_log("Kill a closed client"); } else if (fRefNum == 0) { // Correspond to a still not opened client. jack_log("Kill a not opened client"); @@ -401,10 +458,10 @@ int JackWinNamedPipeServerChannel::Open(const char* server_name, JackServer* ser void JackWinNamedPipeServerChannel::Close() { /* TODO : solve WIN32 thread Kill issue - This would hang the server... since we are quitting it, its not really problematic, - all ressources will be desallocated at the end. + This would hang the server... since we are quitting it, its not really problematic, + all ressources will be desallocated at the end. - fRequestListenPipe.Close(); + fRequestListenPipe.Close(); fThread.Stop(); */ diff --git a/windows/JackWinNamedPipeServerChannel.h b/windows/JackWinNamedPipeServerChannel.h index 21fad162..ffc6f9bb 100644 --- a/windows/JackWinNamedPipeServerChannel.h +++ b/windows/JackWinNamedPipeServerChannel.h @@ -1,20 +1,20 @@ /* Copyright (C) 2004-2008 Grame - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 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 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - + */ @@ -40,7 +40,7 @@ class JackClientPipeThread : public JackRunnableInterface JackThread fThread; int fRefNum; - void ClientAdd(char* name, int pid, int* shared_engine, int* shared_client, int* shared_graph, int* result); + void ClientAdd(char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result); void ClientRemove(); void ClientKill(); @@ -53,7 +53,7 @@ class JackClientPipeThread : public JackRunnableInterface int Open(JackServer* server); // Open the Server/Client connection void Close(); // Close the Server/Client connection - + bool HandleRequest(); // JackRunnableInterface interface @@ -91,7 +91,7 @@ class JackWinNamedPipeServerChannel : public JackRunnableInterface int Open(const char* server_name, JackServer* server); // Open the Server/Client connection void Close(); // Close the Server/Client connection - + int Start(); // JackRunnableInterface interface diff --git a/windows/JackWinThread.cpp b/windows/JackWinThread.cpp index 99aed2ff..ec884c45 100644 --- a/windows/JackWinThread.cpp +++ b/windows/JackWinThread.cpp @@ -235,6 +235,11 @@ pthread_t JackWinThread::GetThreadID() return fThread; } +bool JackWinThread::IsThread() +{ + return GetCurrentThread() == fThread; +} + void JackWinThread::Terminate() { jack_log("JackWinThread::Terminate"); diff --git a/windows/JackWinThread.h b/windows/JackWinThread.h index 7bb745b2..317d6aeb 100644 --- a/windows/JackWinThread.h +++ b/windows/JackWinThread.h @@ -1,20 +1,20 @@ /* Copyright (C) 2004-2008 Grame - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 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 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - + */ @@ -59,24 +59,25 @@ class SERVER_EXPORT JackWinThread : public detail::JackThreadInterface int AcquireRealTime(); // Used when called from another thread int AcquireSelfRealTime(); // Used when called from thread itself - + int AcquireRealTime(int priority); // Used when called from another thread int AcquireSelfRealTime(int priority); // Used when called from thread itself - + int DropRealTime(); // Used when called from another thread int DropSelfRealTime(); // Used when called from thread itself - + pthread_t GetThreadID(); + bool IsThread(); static int AcquireRealTimeImp(pthread_t thread, int priority); static int AcquireRealTimeImp(pthread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) - { - return JackWinThread::AcquireRealTimeImp(thread, priority); + { + return JackWinThread::AcquireRealTimeImp(thread, priority); } static int DropRealTimeImp(pthread_t thread); static int StartImp(pthread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg) - { - return JackWinThread::StartImp(thread, priority, realtime, (ThreadCallback) start_routine, arg); + { + return JackWinThread::StartImp(thread, priority, realtime, (ThreadCallback) start_routine, arg); } static int StartImp(pthread_t* thread, int priority, int realtime, ThreadCallback start_routine, void* arg); static int StopImp(pthread_t thread); diff --git a/windows/Setup/JackRouter.dll b/windows/Setup/JackRouter.dll index d74a292500d9b170a2a8cb73bce7dec9755fd54b..04d69ebdbc62190d3e62ed9d4081bc267f720047 100644 GIT binary patch delta 153 zcmZo@U}|V!n(%=|rM%i_JqL|7>7qY~JDHVGIDwv@I6^ delta 153 zcmZo@U}|V!n(%>Tx^9X0#xFnYEpIb0H1IPrG+YAGPk{Ih5Q_u(XMi*-kQN1E0U*8( iKM*Kf%dJg|JlIK*u2BX!x#YQo-K0# diff --git a/windows/Setup/jack.ci b/windows/Setup/jack.ci index df6e3871..7ad82cb3 100644 --- a/windows/Setup/jack.ci +++ b/windows/Setup/jack.ci @@ -1,9 +1,9 @@ <*project version = 4 civer = "Free v4.14.5" winver = "2.6/5.1.2600" > . - Jack_v1.9.6_setup.exe + Jack_v1.9.7_setup.exe - Jack v1.9.6 + Jack v1.9.7 Default - 2 diff --git a/windows/jack_dummy.cbp b/windows/jack_dummy.cbp index ad23c3bd..f10fce95 100644 --- a/windows/jack_dummy.cbp +++ b/windows/jack_dummy.cbp @@ -1,95 +1,98 @@ - - - - - - + + + + + + diff --git a/windows/jack_loopback.cbp b/windows/jack_loopback.cbp index 87edea4f..c9314e79 100644 --- a/windows/jack_loopback.cbp +++ b/windows/jack_loopback.cbp @@ -80,6 +80,9 @@ + + diff --git a/windows/jackaudioadapter.rc b/windows/jackaudioadapter.rc index aa57cf89..ceb43d62 100644 --- a/windows/jackaudioadapter.rc +++ b/windows/jackaudioadapter.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,6,0 - PRODUCTVERSION 1,9,6,0 + FILEVERSION 1,9,7,0 + PRODUCTVERSION 1,9,7,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Audio Adapter for Windows\0" - VALUE "FileVersion", "1, 9, 6, 0\0" + VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "audioadapter\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "audioadapter.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "audioadapter\0" - VALUE "ProductVersion", "1, 9, 6, 0\0" + VALUE "ProductVersion", "1, 9, 7, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackd.rc b/windows/jackd.rc index acdd0501..4fdf0bb4 100644 --- a/windows/jackd.rc +++ b/windows/jackd.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,6,0 - PRODUCTVERSION 1,9,6,0 + FILEVERSION 1,9,7,0 + PRODUCTVERSION 1,9,7,0 FILEOS VOS_UNKNOWN FILETYPE VFT_APP BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack server for Windows\0" - VALUE "FileVersion", "1, 9, 6, 0\0" + VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "jackd\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jackd.exe\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jackd\0" - VALUE "ProductVersion", "1, 9, 6, 0\0" + VALUE "ProductVersion", "1, 9, 7, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackdummydriver.rc b/windows/jackdummydriver.rc new file mode 100644 index 00000000..2a364608 --- /dev/null +++ b/windows/jackdummydriver.rc @@ -0,0 +1,41 @@ +// Generated by ResEdit 1.4.3 +// Copyright (C) 2006-2008 +// http://www.resedit.net + +#include "resource.h" +#include "afxres.h" + + +// +// Version Information resources +// +LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT +1 VERSIONINFO + FILEVERSION 1,9,7,0 + PRODUCTVERSION 1,9,7,0 + FILEOS VOS_UNKNOWN + FILETYPE VFT_DLL +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040c04b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "Grame\0" + VALUE "FileDescription", "Jackmp Dummy Driver for Windows\0" + VALUE "FileVersion", "1, 9, 7, 0\0" + VALUE "InternalName", "jack_dummy\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "jack_dummy.dll\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "jack_dummy\0" + VALUE "ProductVersion", "1, 9, 7, 0\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 1036, 1200 + END +END diff --git a/windows/jackloopbackdriver.rc b/windows/jackloopbackdriver.rc new file mode 100644 index 00000000..4249c39d --- /dev/null +++ b/windows/jackloopbackdriver.rc @@ -0,0 +1,41 @@ +// Generated by ResEdit 1.4.3 +// Copyright (C) 2006-2008 +// http://www.resedit.net + +#include "resource.h" +#include "afxres.h" + + +// +// Version Information resources +// +LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT +1 VERSIONINFO + FILEVERSION 1,9,7,0 + PRODUCTVERSION 1,9,7,0 + FILEOS VOS_UNKNOWN + FILETYPE VFT_DLL +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040c04b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "Grame\0" + VALUE "FileDescription", "Jackmp Loopback Driver for Windows\0" + VALUE "FileVersion", "1, 9, 7, 0\0" + VALUE "InternalName", "jack_loopback\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "jack_loopback.dll\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "jack_loopback\0" + VALUE "ProductVersion", "1, 9, 7, 0\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 1036, 1200 + END +END diff --git a/windows/jacknetadapter.rc b/windows/jacknetadapter.rc index 415b9fbd..e756d2bf 100644 --- a/windows/jacknetadapter.rc +++ b/windows/jacknetadapter.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,6,0 - PRODUCTVERSION 1,9,6,0 + FILEVERSION 1,9,7,0 + PRODUCTVERSION 1,9,7,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Adapter for Windows\0" - VALUE "FileVersion", "1, 9, 6, 0\0" + VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "netadapter\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "netadapter.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "netadapter\0" - VALUE "ProductVersion", "1, 9, 6, 0\0" + VALUE "ProductVersion", "1, 9, 7, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetdriver.rc b/windows/jacknetdriver.rc index a1157d17..dd2228ce 100644 --- a/windows/jacknetdriver.rc +++ b/windows/jacknetdriver.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,6,0 - PRODUCTVERSION 1,9,6,0 + FILEVERSION 1,9,7,0 + PRODUCTVERSION 1,9,7,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Driver for Windows\0" - VALUE "FileVersion", "1, 9, 6, 0\0" + VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "jack_netdriver\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_netdriver.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_netdriver\0" - VALUE "ProductVersion", "1, 9, 6, 0\0" + VALUE "ProductVersion", "1, 9, 7, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetmanager.rc b/windows/jacknetmanager.rc index f417048d..9e4701f8 100644 --- a/windows/jacknetmanager.rc +++ b/windows/jacknetmanager.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,6,0 - PRODUCTVERSION 1,9,6,0 + FILEVERSION 1,9,7,0 + PRODUCTVERSION 1,9,7,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Manager for Windows\0" - VALUE "FileVersion", "1, 9, 6, 0\0" + VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "netmanager\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "netmanager.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "netmanager\0" - VALUE "ProductVersion", "1, 9, 6, 0\0" + VALUE "ProductVersion", "1, 9, 7, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetonedriver.rc b/windows/jacknetonedriver.rc index 9c184d36..1dee018a 100644 --- a/windows/jacknetonedriver.rc +++ b/windows/jacknetonedriver.rc @@ -1,41 +1,41 @@ -// Generated by ResEdit 1.4.3 -// Copyright (C) 2006-2008 -// http://www.resedit.net - -#include "resource.h" -#include "afxres.h" - - -// -// Version Information resources -// -LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT -1 VERSIONINFO - FILEVERSION 1,9,5,0 - PRODUCTVERSION 1,9,5,0 - FILEOS VOS_UNKNOWN - FILETYPE VFT_DLL -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040c04b0" - BEGIN - VALUE "Comments", "\0" - VALUE "CompanyName", "Grame\0" - VALUE "FileDescription", "Jackmp NetOne Driver for Windows\0" - VALUE "FileVersion", "1, 9, 5, 0\0" - VALUE "InternalName", "jack_netonedriver\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" - VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "jack_netonedriver.dll\0" - VALUE "PrivateBuild", "\0" - VALUE "ProductName", "jack_netonedriver\0" - VALUE "ProductVersion", "1, 9, 5, 0\0" - VALUE "SpecialBuild", "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 1036, 1200 - END -END +// Generated by ResEdit 1.4.3 +// Copyright (C) 2006-2008 +// http://www.resedit.net + +#include "resource.h" +#include "afxres.h" + + +// +// Version Information resources +// +LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT +1 VERSIONINFO + FILEVERSION 1,9,7,0 + PRODUCTVERSION 1,9,7,0 + FILEOS VOS_UNKNOWN + FILETYPE VFT_DLL +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040c04b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "Grame\0" + VALUE "FileDescription", "Jackmp NetOne Driver for Windows\0" + VALUE "FileVersion", "1, 9, 7, 0\0" + VALUE "InternalName", "jack_netonedriver\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "jack_netonedriver.dll\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "jack_netonedriver\0" + VALUE "ProductVersion", "1, 9, 7, 0\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 1036, 1200 + END +END diff --git a/windows/jackportaudio.rc b/windows/jackportaudio.rc index df292330..651d8ec3 100644 --- a/windows/jackportaudio.rc +++ b/windows/jackportaudio.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,6,0 - PRODUCTVERSION 1,9,6,0 + FILEVERSION 1,9,7,0 + PRODUCTVERSION 1,9,7,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp PortAudio Driver for Windows\0" - VALUE "FileVersion", "1, 9, 6, 0\0" + VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "jack_portaudio\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_portaudio.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_portaudio\0" - VALUE "ProductVersion", "1, 9, 6, 0\0" + VALUE "ProductVersion", "1, 9, 7, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackwinmme.rc b/windows/jackwinmme.rc index a11da0d1..509b2715 100644 --- a/windows/jackwinmme.rc +++ b/windows/jackwinmme.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,6,0 - PRODUCTVERSION 1,9,6,0 + FILEVERSION 1,9,7,0 + PRODUCTVERSION 1,9,7,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -22,15 +22,15 @@ BEGIN BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" - VALUE "FileDescription", "Jackmp WinMMEo Driver for Windows\0" - VALUE "FileVersion", "1, 9, 6, 0\0" + VALUE "FileDescription", "Jackmp WinMME Driver for Windows\0" + VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "jack_portaudio\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_winmme.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_winmme\0" - VALUE "ProductVersion", "1, 9, 6, 0\0" + VALUE "ProductVersion", "1, 9, 7, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/libjack.rc b/windows/libjack.rc index b24e3f07..7e99dfdb 100644 --- a/windows/libjack.rc +++ b/windows/libjack.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,6,0 - PRODUCTVERSION 1,9,6,0 + FILEVERSION 1,9,7,0 + PRODUCTVERSION 1,9,7,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack client library for Windows\0" - VALUE "FileVersion", "1, 9, 6, 0\0" + VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "libjack\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjack.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjack\0" - VALUE "ProductVersion", "1, 9, 6, 0\0" + VALUE "ProductVersion", "1, 9, 7, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/libjackserver.rc b/windows/libjackserver.rc index 6fe89a1c..299d84a6 100644 --- a/windows/libjackserver.rc +++ b/windows/libjackserver.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,6,0 - PRODUCTVERSION 1,9,6,0 + FILEVERSION 1,9,7,0 + PRODUCTVERSION 1,9,7,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack server library for Windows\0" - VALUE "FileVersion", "1, 9, 56, 0\0" + VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "libjackserver\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjackserver.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjackserver\0" - VALUE "ProductVersion", "1, 9, 6, 0\0" + VALUE "ProductVersion", "1, 9, 7, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/resource.rc b/windows/resource.rc index 6b41c2a7..a0988d1f 100644 --- a/windows/resource.rc +++ b/windows/resource.rc @@ -14,8 +14,8 @@ LANGUAGE LANG_FRENCH, SUBLANG_FRENCH #ifndef _MAC VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,9,6,0 - PRODUCTVERSION 1,9,6,0 + FILEVERSION 1,9,7,0 + PRODUCTVERSION 1,9,7,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -33,14 +33,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp for Windows\0" - VALUE "FileVersion", "1, 9, 6, 0\0" + VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "libjackmp\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjackmp.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjackmp\0" - VALUE "ProductVersion", "1, 9, 6, 0\0" + VALUE "ProductVersion", "1, 9, 7, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/wscript b/wscript index 52f01f63..12a59563 100644 --- a/wscript +++ b/wscript @@ -11,7 +11,7 @@ import Task import re import Logs -VERSION='1.9.6' +VERSION='1.9.7' APPNAME='jack' JACK_API_VERSION = '0.1.0' From a7e8377441852d675a8c26bdbf3ae9d847a5ca91 Mon Sep 17 00:00:00 2001 From: sletz Date: Fri, 11 Mar 2011 14:11:10 +0000 Subject: [PATCH 055/472] rebase from trunk 4083:4180 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@4181 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 63 +- common/JackAPI.cpp | 408 +++--- common/JackAudioDriver.cpp | 100 +- common/JackAudioDriver.h | 14 +- common/JackAudioPort.cpp | 23 +- common/JackChannel.h | 31 +- common/JackClient.cpp | 324 +++-- common/JackClient.h | 32 +- common/JackClientControl.h | 6 +- common/JackConnectionManager.cpp | 45 +- common/JackConnectionManager.h | 35 +- common/JackDebugClient.cpp | 12 +- common/JackDebugClient.h | 4 +- common/JackDriver.cpp | 10 +- common/JackDriver.h | 88 +- common/JackDummyDriver.cpp | 6 + common/JackEngine.cpp | 125 +- common/JackEngine.h | 8 +- common/JackEngineControl.cpp | 28 +- common/JackError.h | 11 +- common/JackFrameTimer.h | 22 +- common/JackGraphManager.cpp | 115 +- common/JackGraphManager.h | 16 +- common/JackInternalClientChannel.h | 17 +- common/JackLockedEngine.h | 28 +- common/JackMessageBuffer.cpp | 27 +- common/JackMidiPort.cpp | 18 +- common/JackNetDriver.cpp | 45 +- common/JackNetManager.cpp | 80 +- common/JackNetManager.h | 6 +- common/JackNetOneDriver.cpp | 1380 ++++++++++----------- common/JackNetOneDriver.h | 54 +- common/JackNotification.h | 3 +- common/JackPort.cpp | 56 +- common/JackPort.h | 14 +- common/JackPortType.cpp | 12 +- common/JackPortType.h | 5 +- common/JackRequest.h | 118 +- common/JackServer.cpp | 34 +- common/JackServerGlobals.cpp | 10 +- common/JackServerGlobals.h | 7 +- common/JackThread.h | 56 +- common/JackTime.h | 1 - common/JackTypes.h | 6 + common/Jackdmp.cpp | 38 +- common/jack/jack.h | 464 +++++-- common/jack/midiport.h | 52 +- common/jack/session.h | 230 ++-- common/jack/systemdeps.h | 23 +- common/jack/thread.h | 14 +- common/jack/types.h | 393 +++--- common/jack/weakjack.h | 67 +- common/jack/weakmacros.h | 32 +- common/netjack.c | 129 +- common/netjack.h | 10 + common/netjack_packet.c | 74 +- common/netjack_packet.h | 6 - common/timestamps.c | 11 +- example-clients/alsa_in.c | 66 +- example-clients/alsa_out.c | 62 +- example-clients/bufsize.c | 15 +- example-clients/connect.c | 210 +++- example-clients/latent_client.c | 215 ++++ example-clients/lsp.c | 44 +- example-clients/midi_dump.c | 114 ++ example-clients/netsource.c | 58 +- example-clients/session_notify.c | 237 ++-- example-clients/wscript | 8 +- linux/JackAtomic_os.h | 7 +- linux/JackLinuxTime.c | 1 + linux/alsa/JackAlsaDriver.cpp | 146 ++- linux/alsa/alsa_rawmidi.c | 26 +- linux/alsa/alsa_seqmidi.c | 16 +- linux/alsa/usx2y.c | 10 +- linux/cycles.h | 18 - linux/firewire/JackFFADODriver.cpp | 23 +- linux/freebob/JackFreebobDriver.cpp | 17 +- macosx/Jack-Info.plist | 2 +- macosx/JackMachThread.cpp | 26 +- macosx/JackMachThread.h | 28 +- macosx/Jackdmp.xcodeproj/project.pbxproj | 942 ++++++++++++-- macosx/coreaudio/JackCoreAudioAdapter.cpp | 294 ++--- macosx/coreaudio/JackCoreAudioDriver.cpp | 304 ++--- macosx/wscript | 6 - man/jack_iodelay.0 | 53 + posix/JackPosixMutex.h | 34 +- posix/JackPosixThread.cpp | 64 +- posix/JackPosixThread.h | 26 +- posix/JackSocket.cpp | 40 +- posix/JackSocketClientChannel.cpp | 63 +- posix/JackSocketClientChannel.h | 24 +- posix/JackSocketServerChannel.cpp | 64 +- posix/JackSocketServerChannel.h | 6 +- posix/JackSocketServerNotifyChannel.cpp | 6 +- posix/JackSocketServerNotifyChannel.h | 2 +- posix/JackSystemDeps_os.h | 2 + posix/JackTypes_os.h | 2 + tests/{jdelay.cpp => iodelay.cpp} | 66 +- tests/wscript | 2 +- windows/JackRouter/JackRouter.dsp | 2 +- windows/JackSystemDeps_os.h | 2 + windows/JackTypes_os.h | 15 +- windows/JackWinNamedPipeClientChannel.cpp | 76 +- windows/JackWinNamedPipeClientChannel.h | 8 + windows/JackWinNamedPipeServerChannel.cpp | 28 +- windows/JackWinThread.cpp | 44 +- windows/JackWinThread.h | 16 +- windows/Setup/JackRouter.dll | Bin 32768 -> 32768 bytes windows/jack_latent_client.cbp | 91 ++ windows/jackaudioadapter.rc | 2 +- windows/jackd.rc | 2 +- windows/jackd.workspace | 5 +- windows/jackdummydriver.rc | 2 +- windows/jackloopbackdriver.rc | 2 +- windows/jacknetadapter.rc | 2 +- windows/jacknetdriver.rc | 2 +- windows/jacknetmanager.rc | 2 +- windows/jacknetonedriver.rc | 2 +- windows/jackportaudio.rc | 2 +- windows/jackwinmme.rc | 2 +- windows/libjack.cbp | 3 + windows/libjack.rc | 2 +- windows/libjackserver.rc | 2 +- windows/portaudio/JackPortAudioDriver.h | 6 + windows/resource.rc | 2 +- wscript | 55 +- 126 files changed, 5738 insertions(+), 3034 deletions(-) create mode 100644 example-clients/latent_client.c create mode 100644 example-clients/midi_dump.c create mode 100644 man/jack_iodelay.0 rename tests/{jdelay.cpp => iodelay.cpp} (79%) create mode 100644 windows/jack_latent_client.cbp diff --git a/ChangeLog b/ChangeLog index 4b05b3e7..fbb75e3c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,16 +27,75 @@ Mario Lang Arnold Krille Jan Engelhardt Adrian Knoth -David Garcia Garzon +David Garcia Garzon +Valerio Pilo --------------------------- Jackdmp changes log --------------------------- +2011-03-11 Stephane Letz + + * Correct JackNetMaster::SetBufferSize. + +2011-03-10 Stephane Letz + + * Latency callback must always be activated. + * Correct TopologicalSort. + * Add jack_midi_dump client. + * Synchronize netjack1 with JACK1 version. + * Synchronize jack_connect/jack_disconnect with JACK1 version. + +2011-03-09 Stephane Letz + + * jack_client_has_session_callback implementation. + * Fix jdelay for new latency API. + * Check requested buffer size and limit to 1..8192 - avoids wierd behaviour caused by jack_bufsize foobar. + * jack_port_type_get_buffer_size implementation. + * Stop using alloca and allocate buffer on the heap for alsa_io. + * Rename jdelay to jack_iodelay as per Fons' request. + * Call buffer size callback in activate (actually this is done on client side in the RT thread Init method). + * JackEngine::ComputeTotalLatencies in progress. + +2011-03-08 Stephane Letz + + * Use of latency range in all backends. + * ComputeTotalLatencies now a client/server call. + * Add latent test client for latency API. + * Also print playback and capture latency in jack_lsp. + +2011-03-04 Stephane Letz + + * Revert r4119 (RT notification in the server). JackAudioDriver::ProcessSync now skip backend write in case of graph process failure. + * Fix incorrect error codes in alsa/usx2y.c and alsa/JackAlsaDriver.cpp. + * Synchronize public headers with JACK1. Update OSX project. + * New latency API implementation (in progress). + +2011-02-09 Stephane Letz + + * Remove JackPortIsActive flag. + +2011-02-07 Stephane Letz + + * Valerio Pilo second CAS for ARMv7 patch. + +2011-02-03 Stephane Letz + + * Valerio Pilo CAS for ARMv7 patch. + +2011-01-11 Stephane Letz + + * Adrian Knoth jack_lsp patch. + +2010-11-17 Stephane Letz + + * ALSA backend : suspend/resume handling (jack1 r4075). + * Correct dummy driver. + 2010-11-05 Stephane Letz * In jackdmp.cpp, jackctl_setup_signals moved before jackctl_server_start. - * Correct symbols export in backends. + * Correct symbols export in backends on OSX. 2010-11-03 Stephane Letz diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index fe60ebe2..550133cb 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -41,7 +41,7 @@ extern "C" { #endif - typedef void (*print_function)(const char *); + typedef void (*print_function)(const char*); typedef void *(*thread_routine)(void*); EXPORT @@ -53,198 +53,219 @@ extern "C" int *proto_ptr); EXPORT - const char * + const char* jack_get_version_string(); - jack_client_t * jack_client_new_aux (const char *client_name, + jack_client_t * jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t *status); - EXPORT jack_client_t * jack_client_open (const char *client_name, + EXPORT jack_client_t * jack_client_open(const char* client_name, jack_options_t options, jack_status_t *status, ...); - EXPORT jack_client_t * jack_client_new (const char *client_name); - EXPORT int jack_client_name_size (void); - EXPORT char* jack_get_client_name (jack_client_t *client); - EXPORT int jack_internal_client_new (const char *client_name, - const char *load_name, - const char *load_init); - EXPORT void jack_internal_client_close (const char *client_name); - EXPORT int jack_is_realtime (jack_client_t *client); - EXPORT void jack_on_shutdown (jack_client_t *client, + EXPORT jack_client_t * jack_client_new(const char* client_name); + EXPORT int jack_client_name_size(void); + EXPORT char* jack_get_client_name(jack_client_t *client); + EXPORT int jack_internal_client_new(const char* client_name, + const char* load_name, + const char* load_init); + EXPORT void jack_internal_client_close(const char* client_name); + EXPORT int jack_is_realtime(jack_client_t *client); + EXPORT void jack_on_shutdown(jack_client_t *client, JackShutdownCallback shutdown_callback, void *arg); - EXPORT void jack_on_info_shutdown (jack_client_t *client, + EXPORT void jack_on_info_shutdown(jack_client_t *client, JackInfoShutdownCallback shutdown_callback, void *arg); - EXPORT int jack_set_process_callback (jack_client_t *client, + EXPORT int jack_set_process_callback(jack_client_t *client, JackProcessCallback process_callback, void *arg); EXPORT jack_nframes_t jack_thread_wait(jack_client_t *client, int status); // new - EXPORT jack_nframes_t jack_cycle_wait (jack_client_t*); - EXPORT void jack_cycle_signal (jack_client_t*, int status); + EXPORT jack_nframes_t jack_cycle_wait(jack_client_t*); + EXPORT void jack_cycle_signal(jack_client_t*, int status); EXPORT int jack_set_process_thread(jack_client_t* client, JackThreadCallback fun, void *arg); - EXPORT int jack_set_thread_init_callback (jack_client_t *client, + EXPORT int jack_set_thread_init_callback(jack_client_t *client, JackThreadInitCallback thread_init_callback, void *arg); - EXPORT int jack_set_freewheel_callback (jack_client_t *client, + EXPORT int jack_set_freewheel_callback(jack_client_t *client, JackFreewheelCallback freewheel_callback, void *arg); EXPORT int jack_set_freewheel(jack_client_t* client, int onoff); - EXPORT int jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes); - EXPORT int jack_set_buffer_size_callback (jack_client_t *client, + EXPORT int jack_set_buffer_size(jack_client_t *client, jack_nframes_t nframes); + EXPORT int jack_set_buffer_size_callback(jack_client_t *client, JackBufferSizeCallback bufsize_callback, void *arg); - EXPORT int jack_set_sample_rate_callback (jack_client_t *client, + EXPORT int jack_set_sample_rate_callback(jack_client_t *client, JackSampleRateCallback srate_callback, void *arg); - EXPORT int jack_set_client_registration_callback (jack_client_t *, + EXPORT int jack_set_client_registration_callback(jack_client_t *, JackClientRegistrationCallback registration_callback, void *arg); - EXPORT int jack_set_port_registration_callback (jack_client_t *, + EXPORT int jack_set_port_registration_callback(jack_client_t *, JackPortRegistrationCallback registration_callback, void *arg); - EXPORT int jack_set_port_connect_callback (jack_client_t *, + EXPORT int jack_set_port_connect_callback(jack_client_t *, JackPortConnectCallback connect_callback, void *arg); - EXPORT int jack_set_port_rename_callback (jack_client_t *, + EXPORT int jack_set_port_rename_callback(jack_client_t *, JackPortRenameCallback rename_callback, void *arg); - EXPORT int jack_set_graph_order_callback (jack_client_t *, + EXPORT int jack_set_graph_order_callback(jack_client_t *, JackGraphOrderCallback graph_callback, void *); - EXPORT int jack_set_xrun_callback (jack_client_t *, + EXPORT int jack_set_xrun_callback(jack_client_t *, JackXRunCallback xrun_callback, void *arg); - EXPORT int jack_activate (jack_client_t *client); - EXPORT int jack_deactivate (jack_client_t *client); - EXPORT jack_port_t * jack_port_register (jack_client_t *client, - const char *port_name, - const char *port_type, + EXPORT int jack_set_latency_callback(jack_client_t *client, + JackLatencyCallback callback, void *arg); + + EXPORT int jack_activate(jack_client_t *client); + EXPORT int jack_deactivate(jack_client_t *client); + EXPORT jack_port_t * jack_port_register(jack_client_t *client, + const char* port_name, + const char* port_type, unsigned long flags, unsigned long buffer_size); - EXPORT int jack_port_unregister (jack_client_t *, jack_port_t *); - EXPORT void * jack_port_get_buffer (jack_port_t *, jack_nframes_t); - EXPORT const char * jack_port_name (const jack_port_t *port); - EXPORT const char * jack_port_short_name (const jack_port_t *port); - EXPORT int jack_port_flags (const jack_port_t *port); - EXPORT const char * jack_port_type (const jack_port_t *port); - EXPORT jack_port_type_id_t jack_port_type_id (const jack_port_t *port); - EXPORT int jack_port_is_mine (const jack_client_t *, const jack_port_t *port); - EXPORT int jack_port_connected (const jack_port_t *port); - EXPORT int jack_port_connected_to (const jack_port_t *port, - const char *port_name); - EXPORT const char ** jack_port_get_connections (const jack_port_t *port); - EXPORT const char ** jack_port_get_all_connections (const jack_client_t *client, + EXPORT int jack_port_unregister(jack_client_t *, jack_port_t *); + EXPORT void * jack_port_get_buffer(jack_port_t *, jack_nframes_t); + EXPORT const char* jack_port_name(const jack_port_t *port); + EXPORT const char* jack_port_short_name(const jack_port_t *port); + EXPORT int jack_port_flags(const jack_port_t *port); + EXPORT const char* jack_port_type(const jack_port_t *port); + EXPORT jack_port_type_id_t jack_port_type_id(const jack_port_t *port); + EXPORT int jack_port_is_mine(const jack_client_t *, const jack_port_t *port); + EXPORT int jack_port_connected(const jack_port_t *port); + EXPORT int jack_port_connected_to(const jack_port_t *port, + const char* port_name); + EXPORT const char* * jack_port_get_connections(const jack_port_t *port); + EXPORT const char* * jack_port_get_all_connections(const jack_client_t *client, const jack_port_t *port); - EXPORT int jack_port_tie (jack_port_t *src, jack_port_t *dst); - EXPORT int jack_port_untie (jack_port_t *port); - EXPORT jack_nframes_t jack_port_get_latency (jack_port_t *port); - EXPORT jack_nframes_t jack_port_get_total_latency (jack_client_t *, + EXPORT int jack_port_tie(jack_port_t *src, jack_port_t *dst); + EXPORT int jack_port_untie(jack_port_t *port); + + // Old latency API + EXPORT jack_nframes_t jack_port_get_latency(jack_port_t *port); + EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t *, jack_port_t *port); - EXPORT void jack_port_set_latency (jack_port_t *, jack_nframes_t); - EXPORT int jack_recompute_total_latency (jack_client_t*, jack_port_t* port); - EXPORT int jack_recompute_total_latencies (jack_client_t*); - EXPORT int jack_port_set_name (jack_port_t *port, const char *port_name); - EXPORT int jack_port_set_alias (jack_port_t *port, const char *alias); - EXPORT int jack_port_unset_alias (jack_port_t *port, const char *alias); - EXPORT int jack_port_get_aliases (const jack_port_t *port, char* const aliases[2]); - EXPORT int jack_port_request_monitor (jack_port_t *port, int onoff); - EXPORT int jack_port_request_monitor_by_name (jack_client_t *client, - const char *port_name, int onoff); - EXPORT int jack_port_ensure_monitor (jack_port_t *port, int onoff); - EXPORT int jack_port_monitoring_input (jack_port_t *port); - EXPORT int jack_connect (jack_client_t *, - const char *source_port, - const char *destination_port); - EXPORT int jack_disconnect (jack_client_t *, - const char *source_port, - const char *destination_port); - EXPORT int jack_port_disconnect (jack_client_t *, jack_port_t *); + EXPORT void jack_port_set_latency(jack_port_t *, jack_nframes_t); + EXPORT int jack_recompute_total_latency(jack_client_t*, jack_port_t* port); + + // New latency API + EXPORT void jack_port_get_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range); + EXPORT void jack_port_set_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range); + EXPORT int jack_recompute_total_latencies(jack_client_t*); + + EXPORT int jack_port_set_name(jack_port_t *port, const char* port_name); + EXPORT int jack_port_set_alias(jack_port_t *port, const char* alias); + EXPORT int jack_port_unset_alias(jack_port_t *port, const char* alias); + EXPORT int jack_port_get_aliases(const jack_port_t *port, char* const aliases[2]); + EXPORT int jack_port_request_monitor(jack_port_t *port, int onoff); + EXPORT int jack_port_request_monitor_by_name(jack_client_t *client, + const char* port_name, int onoff); + EXPORT int jack_port_ensure_monitor(jack_port_t *port, int onoff); + EXPORT int jack_port_monitoring_input(jack_port_t *port); + EXPORT int jack_connect(jack_client_t *, + const char* source_port, + const char* destination_port); + EXPORT int jack_disconnect(jack_client_t *, + const char* source_port, + const char* destination_port); + EXPORT int jack_port_disconnect(jack_client_t *, jack_port_t *); EXPORT int jack_port_name_size(void); EXPORT int jack_port_type_size(void); - EXPORT jack_nframes_t jack_get_sample_rate (jack_client_t *); - EXPORT jack_nframes_t jack_get_buffer_size (jack_client_t *); - EXPORT const char ** jack_get_ports (jack_client_t *, - const char *port_name_pattern, - const char *type_name_pattern, + EXPORT size_t jack_port_type_get_buffer_size(jack_client_t *client, const char* port_type); + EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t *); + EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t *); + EXPORT const char* * jack_get_ports(jack_client_t *, + const char* port_name_pattern, + const char* type_name_pattern, unsigned long flags); - EXPORT jack_port_t * jack_port_by_name (jack_client_t *, const char *port_name); - EXPORT jack_port_t * jack_port_by_id (jack_client_t *client, + EXPORT jack_port_t * jack_port_by_name(jack_client_t *, const char* port_name); + EXPORT jack_port_t * jack_port_by_id(jack_client_t *client, jack_port_id_t port_id); - EXPORT int jack_engine_takeover_timebase (jack_client_t *); - EXPORT jack_nframes_t jack_frames_since_cycle_start (const jack_client_t *); + EXPORT int jack_engine_takeover_timebase(jack_client_t *); + EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t *); EXPORT jack_time_t jack_get_time(); EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t *client, jack_time_t time); EXPORT jack_time_t jack_frames_to_time(const jack_client_t *client, jack_nframes_t frames); - EXPORT jack_nframes_t jack_frame_time (const jack_client_t *); - EXPORT jack_nframes_t jack_last_frame_time (const jack_client_t *client); - EXPORT float jack_cpu_load (jack_client_t *client); - EXPORT pthread_t jack_client_thread_id (jack_client_t *); - EXPORT void jack_set_error_function (print_function); - EXPORT void jack_set_info_function (print_function); - - EXPORT float jack_get_max_delayed_usecs (jack_client_t *client); - EXPORT float jack_get_xrun_delayed_usecs (jack_client_t *client); - EXPORT void jack_reset_max_delayed_usecs (jack_client_t *client); - - EXPORT int jack_release_timebase (jack_client_t *client); - EXPORT int jack_set_sync_callback (jack_client_t *client, + EXPORT jack_nframes_t jack_frame_time(const jack_client_t *); + EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t *client); + EXPORT float jack_cpu_load(jack_client_t *client); + EXPORT jack_native_thread_t jack_client_thread_id(jack_client_t *); + EXPORT void jack_set_error_function(print_function); + EXPORT void jack_set_info_function(print_function); + + EXPORT float jack_get_max_delayed_usecs(jack_client_t *client); + EXPORT float jack_get_xrun_delayed_usecs(jack_client_t *client); + EXPORT void jack_reset_max_delayed_usecs(jack_client_t *client); + + EXPORT int jack_release_timebase(jack_client_t *client); + EXPORT int jack_set_sync_callback(jack_client_t *client, JackSyncCallback sync_callback, void *arg); - EXPORT int jack_set_sync_timeout (jack_client_t *client, + EXPORT int jack_set_sync_timeout(jack_client_t *client, jack_time_t timeout); - EXPORT int jack_set_timebase_callback (jack_client_t *client, + EXPORT int jack_set_timebase_callback(jack_client_t *client, int conditional, JackTimebaseCallback timebase_callback, void *arg); - EXPORT int jack_transport_locate (jack_client_t *client, + EXPORT int jack_transport_locate(jack_client_t *client, jack_nframes_t frame); - EXPORT jack_transport_state_t jack_transport_query (const jack_client_t *client, + EXPORT jack_transport_state_t jack_transport_query(const jack_client_t *client, jack_position_t *pos); - EXPORT jack_nframes_t jack_get_current_transport_frame (const jack_client_t *client); - EXPORT int jack_transport_reposition (jack_client_t *client, + EXPORT jack_nframes_t jack_get_current_transport_frame(const jack_client_t *client); + EXPORT int jack_transport_reposition(jack_client_t *client, jack_position_t *pos); - EXPORT void jack_transport_start (jack_client_t *client); - EXPORT void jack_transport_stop (jack_client_t *client); - EXPORT void jack_get_transport_info (jack_client_t *client, + EXPORT void jack_transport_start(jack_client_t *client); + EXPORT void jack_transport_stop(jack_client_t *client); + EXPORT void jack_get_transport_info(jack_client_t *client, jack_transport_info_t *tinfo); - EXPORT void jack_set_transport_info (jack_client_t *client, + EXPORT void jack_set_transport_info(jack_client_t *client, jack_transport_info_t *tinfo); - EXPORT int jack_client_real_time_priority (jack_client_t*); - EXPORT int jack_client_max_real_time_priority (jack_client_t*); - EXPORT int jack_acquire_real_time_scheduling (pthread_t thread, int priority); - EXPORT int jack_client_create_thread (jack_client_t* client, - pthread_t *thread, + EXPORT int jack_client_real_time_priority(jack_client_t*); + EXPORT int jack_client_max_real_time_priority(jack_client_t*); + EXPORT int jack_acquire_real_time_scheduling(jack_native_thread_t thread, int priority); + EXPORT int jack_client_create_thread(jack_client_t* client, + jack_native_thread_t *thread, int priority, int realtime, // boolean thread_routine routine, void *arg); - EXPORT int jack_drop_real_time_scheduling (pthread_t thread); + EXPORT int jack_drop_real_time_scheduling(jack_native_thread_t thread); - EXPORT int jack_client_stop_thread (jack_client_t* client, pthread_t thread); - EXPORT int jack_client_kill_thread (jack_client_t* client, pthread_t thread); + EXPORT int jack_client_stop_thread(jack_client_t* client, jack_native_thread_t thread); + EXPORT int jack_client_kill_thread(jack_client_t* client, jack_native_thread_t thread); #ifndef WIN32 - EXPORT void jack_set_thread_creator (jack_thread_creator_t jtc); + EXPORT void jack_set_thread_creator(jack_thread_creator_t jtc); #endif - EXPORT char * jack_get_internal_client_name (jack_client_t *client, + EXPORT char * jack_get_internal_client_name(jack_client_t *client, jack_intclient_t intclient); - EXPORT jack_intclient_t jack_internal_client_handle (jack_client_t *client, - const char *client_name, + EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t *client, + const char* client_name, jack_status_t *status); - EXPORT jack_intclient_t jack_internal_client_load (jack_client_t *client, - const char *client_name, + EXPORT jack_intclient_t jack_internal_client_load(jack_client_t *client, + const char* client_name, jack_options_t options, jack_status_t *status, ...); - EXPORT jack_intclient_t jack_internal_client_load_aux (jack_client_t *client, - const char *client_name, + EXPORT jack_intclient_t jack_internal_client_load_aux(jack_client_t *client, + const char* client_name, jack_options_t options, jack_status_t *status, va_list ap); - EXPORT jack_status_t jack_internal_client_unload (jack_client_t *client, + EXPORT jack_status_t jack_internal_client_unload(jack_client_t *client, jack_intclient_t intclient); EXPORT void jack_free(void* ptr); + EXPORT int jack_set_session_callback(jack_client_t* ext_client, JackSessionCallback session_callback, void* arg); + EXPORT jack_session_command_t *jack_session_notify(jack_client_t* ext_client, const char* target, jack_session_event_type_t ev_type, const char* path); + EXPORT int jack_session_reply(jack_client_t* ext_client, jack_session_event_t *event); + EXPORT void jack_session_event_free(jack_session_event_t* ev); + EXPORT char* jack_get_uuid_for_client_name(jack_client_t* ext_client, const char* client_name); + EXPORT char* jack_get_client_name_by_uuid(jack_client_t* ext_client, const char* client_uuid); + EXPORT int jack_reserve_client_name(jack_client_t* ext_client, const char* name, const char* uuid); + EXPORT void jack_session_commands_free(jack_session_command_t *cmds); + EXPORT int jack_client_has_session_callback(jack_client_t *client, const char* client_name); + #ifdef __cplusplus } #endif @@ -256,7 +277,7 @@ static inline bool CheckPort(jack_port_id_t port_index) static inline bool CheckBufferSize(jack_nframes_t buffer_size) { - return (buffer_size <= BUFFER_SIZE_MAX); + return (buffer_size >= 1 && buffer_size <= BUFFER_SIZE_MAX); } static inline void WaitGraphChange() @@ -278,12 +299,12 @@ static inline void WaitGraphChange() } } -EXPORT void jack_set_error_function (print_function func) +EXPORT void jack_set_error_function(print_function func) { jack_error_callback = (func == NULL) ? &default_jack_error_callback : func; } -EXPORT void jack_set_info_function (print_function func) +EXPORT void jack_set_info_function(print_function func) { jack_info_callback = (func == NULL) ? &default_jack_info_callback : func; } @@ -526,6 +547,40 @@ EXPORT void jack_port_set_latency(jack_port_t* port, jack_nframes_t frames) } } +EXPORT void jack_port_get_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range) +{ +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_port_get_latency_range"); +#endif + uintptr_t port_aux = (uintptr_t)port; + jack_port_id_t myport = (jack_port_id_t)port_aux; + if (!CheckPort(myport)) { + jack_error("jack_port_get_latency_range called with an incorrect port %ld", myport); + } else { + WaitGraphChange(); + JackGraphManager* manager = GetGraphManager(); + if (manager) + manager->GetPort(myport)->GetLatencyRange(mode, range); + } +} + +EXPORT void jack_port_set_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range) +{ +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_port_set_latency_range"); +#endif + uintptr_t port_aux = (uintptr_t)port; + jack_port_id_t myport = (jack_port_id_t)port_aux; + if (!CheckPort(myport)) { + jack_error("jack_port_set_latency_range called with an incorrect port %ld", myport); + } else { + WaitGraphChange(); + JackGraphManager* manager = GetGraphManager(); + if (manager) + manager->GetPort(myport)->SetLatencyRange(mode, range); + } +} + EXPORT int jack_recompute_total_latency(jack_client_t* ext_client, jack_port_t* port) { #ifdef __CLIENTDEBUG__ @@ -536,10 +591,10 @@ EXPORT int jack_recompute_total_latency(jack_client_t* ext_client, jack_port_t* uintptr_t port_aux = (uintptr_t)port; jack_port_id_t myport = (jack_port_id_t)port_aux; if (client == NULL) { - jack_error("jack_recompute_total_latencies called with a NULL client"); + jack_error("jack_recompute_total_latency called with a NULL client"); return -1; } else if (!CheckPort(myport)) { - jack_error("jack_recompute_total_latencies called with a NULL port"); + jack_error("jack_recompute_total_latency called with a NULL port"); return -1; } else { WaitGraphChange(); @@ -559,9 +614,7 @@ EXPORT int jack_recompute_total_latencies(jack_client_t* ext_client) jack_error("jack_recompute_total_latencies called with a NULL client"); return -1; } else { - WaitGraphChange(); - JackGraphManager* manager = GetGraphManager(); - return (manager ? manager->ComputeTotalLatencies() : -1); + return client->ComputeTotalLatencies(); } } @@ -988,6 +1041,20 @@ EXPORT int jack_set_xrun_callback(jack_client_t* ext_client, JackXRunCallback xr } } +EXPORT int jack_set_latency_callback(jack_client_t* ext_client, JackLatencyCallback latency_callback, void *arg) +{ +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_set_latency_callback"); +#endif + JackClient* client = (JackClient*)ext_client; + if (client == NULL) { + jack_error("jack_set_latency_callback called with a NULL client"); + return -1; + } else { + return client->SetLatencyCallback(latency_callback, arg); + } +} + EXPORT int jack_set_thread_init_callback(jack_client_t* ext_client, JackThreadInitCallback init_callback, void *arg) { #ifdef __CLIENTDEBUG__ @@ -1396,7 +1463,7 @@ EXPORT float jack_cpu_load(jack_client_t* ext_client) } } -EXPORT pthread_t jack_client_thread_id(jack_client_t* ext_client) +EXPORT jack_native_thread_t jack_client_thread_id(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_client_thread_id"); @@ -1404,7 +1471,7 @@ EXPORT pthread_t jack_client_thread_id(jack_client_t* ext_client) JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_client_thread_id called with a NULL client"); - return (pthread_t)NULL; + return (jack_native_thread_t)NULL; } else { return client->GetThreadID(); } @@ -1439,6 +1506,26 @@ EXPORT int jack_port_type_size(void) return JACK_PORT_TYPE_SIZE; } +EXPORT size_t jack_port_type_get_buffer_size(jack_client_t* ext_client, const char* port_type) +{ +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_port_type_get_buffer_size"); +#endif + JackClient* client = (JackClient*)ext_client; + if (client == NULL) { + jack_error("jack_port_type_get_buffer_size called with a NULL client"); + return 0; + } else { + jack_port_type_id_t port_id = GetPortTypeId(port_type); + if (port_id == PORT_TYPES_MAX) { + jack_error("jack_port_type_get_buffer_size called with an unknown port type = %s", port_type); + return 0; + } else { + return GetPortType(port_id)->size(); + } + } +} + // transport.h EXPORT int jack_release_timebase(jack_client_t* ext_client) { @@ -1595,7 +1682,7 @@ EXPORT void jack_set_transport_info(jack_client_t* ext_client, jack_transport_in { #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_set_transport_info"); -#endif +#endif jack_error("jack_set_transport_info: deprecated"); if (tinfo) memset(tinfo, 0, sizeof(jack_transport_info_t)); @@ -1677,14 +1764,14 @@ EXPORT int jack_client_max_real_time_priority(jack_client_t* ext_client) } } -EXPORT int jack_acquire_real_time_scheduling(pthread_t thread, int priority) +EXPORT int jack_acquire_real_time_scheduling(jack_native_thread_t thread, int priority) { JackEngineControl* control = GetEngineControl(); return (control ? JackThread::AcquireRealTimeImp(thread, priority, GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint) : -1); } EXPORT int jack_client_create_thread(jack_client_t* client, - pthread_t *thread, + jack_native_thread_t *thread, int priority, int realtime, /* boolean */ thread_routine routine, @@ -1692,28 +1779,28 @@ EXPORT int jack_client_create_thread(jack_client_t* client, { #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_client_create_thread"); -#endif +#endif return JackThread::StartImp(thread, priority, realtime, routine, arg); } -EXPORT int jack_drop_real_time_scheduling(pthread_t thread) +EXPORT int jack_drop_real_time_scheduling(jack_native_thread_t thread) { return JackThread::DropRealTimeImp(thread); } -EXPORT int jack_client_stop_thread(jack_client_t* client, pthread_t thread) +EXPORT int jack_client_stop_thread(jack_client_t* client, jack_native_thread_t thread) { #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_client_stop_thread"); -#endif +#endif return JackThread::StopImp(thread); } -EXPORT int jack_client_kill_thread(jack_client_t* client, pthread_t thread) +EXPORT int jack_client_kill_thread(jack_client_t* client, jack_native_thread_t thread) { #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_client_kill_thread"); -#endif +#endif return JackThread::KillImp(thread); } @@ -1725,15 +1812,15 @@ EXPORT void jack_set_thread_creator (jack_thread_creator_t jtc) #endif // intclient.h -EXPORT int jack_internal_client_new (const char *client_name, - const char *load_name, - const char *load_init) +EXPORT int jack_internal_client_new (const char* client_name, + const char* load_name, + const char* load_init) { jack_error("jack_internal_client_new: deprecated"); return -1; } -EXPORT void jack_internal_client_close (const char *client_name) +EXPORT void jack_internal_client_close (const char* client_name) { jack_error("jack_internal_client_close: deprecated"); } @@ -1803,7 +1890,7 @@ EXPORT jack_intclient_t jack_internal_client_load_aux(jack_client_t* ext_client, } } -EXPORT jack_intclient_t jack_internal_client_load(jack_client_t *client, const char *client_name, jack_options_t options, jack_status_t *status, ...) +EXPORT jack_intclient_t jack_internal_client_load(jack_client_t *client, const char* client_name, jack_options_t options, jack_status_t *status, ...) { va_list ap; va_start(ap, status); @@ -1847,7 +1934,7 @@ jack_get_version( } EXPORT -const char * +const char* jack_get_version_string() { return VERSION; @@ -1876,7 +1963,7 @@ EXPORT int jack_set_session_callback(jack_client_t* ext_client, JackSessionCallb } } -EXPORT jack_session_command_t *jack_session_notify(jack_client_t* ext_client, const char* target, jack_session_event_type_t ev_type, const char *path) +EXPORT jack_session_command_t *jack_session_notify(jack_client_t* ext_client, const char* target, jack_session_event_type_t ev_type, const char* path) { #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_session_notify"); @@ -1891,7 +1978,7 @@ EXPORT jack_session_command_t *jack_session_notify(jack_client_t* ext_client, co } } -EXPORT int jack_session_reply(jack_client_t *ext_client, jack_session_event_t *event) +EXPORT int jack_session_reply(jack_client_t* ext_client, jack_session_event_t *event) { #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_session_reply"); @@ -1919,7 +2006,7 @@ EXPORT void jack_session_event_free(jack_session_event_t* ev) } } -EXPORT char *jack_get_uuid_for_client_name( jack_client_t *ext_client, const char *client_name ) +EXPORT char *jack_get_uuid_for_client_name(jack_client_t* ext_client, const char* client_name) { #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_get_uuid_for_client_name"); @@ -1934,7 +2021,7 @@ EXPORT char *jack_get_uuid_for_client_name( jack_client_t *ext_client, const cha } } -EXPORT char *jack_get_client_name_by_uuid( jack_client_t *ext_client, const char *client_uuid ) +EXPORT char *jack_get_client_name_by_uuid(jack_client_t* ext_client, const char* client_uuid) { #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_get_client_name_by_uuid"); @@ -1945,11 +2032,11 @@ EXPORT char *jack_get_client_name_by_uuid( jack_client_t *ext_client, const char jack_error("jack_get_client_name_by_uuid called with a NULL client"); return NULL; } else { - return client->GetClientNameForUUID(client_uuid); + return client->GetClientNameByUUID(client_uuid); } } -EXPORT int jack_reserve_client_name( jack_client_t *ext_client, const char *name, const char *uuid ) +EXPORT int jack_reserve_client_name(jack_client_t* ext_client, const char* client_name, const char* uuid) { #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_reserve_client_name"); @@ -1960,17 +2047,17 @@ EXPORT int jack_reserve_client_name( jack_client_t *ext_client, const char *name jack_error("jack_reserve_client_name called with a NULL client"); return -1; } else { - return client->ReserveClientName(name, uuid); + return client->ReserveClientName(client_name, uuid); } } -EXPORT void jack_session_commands_free( jack_session_command_t *cmds ) +EXPORT void jack_session_commands_free(jack_session_command_t *cmds) { if (!cmds) return; - int i=0; - while(1) { + int i = 0; + while (1) { if (cmds[i].client_name) free ((char *)cmds[i].client_name); if (cmds[i].command) @@ -1985,3 +2072,18 @@ EXPORT void jack_session_commands_free( jack_session_command_t *cmds ) free(cmds); } + +EXPORT int jack_client_has_session_callback(jack_client_t* ext_client, const char* client_name) +{ +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_client_has_session_callback"); +#endif + JackClient* client = (JackClient*)ext_client; + jack_log("jack_client_has_session_callback ext_client %x client %x ", ext_client, client); + if (client == NULL) { + jack_error("jack_client_has_session_callback called with a NULL client"); + return -1; + } else { + return client->ClientHasSessionCallback(client_name); + } +} diff --git a/common/JackAudioDriver.cpp b/common/JackAudioDriver.cpp index 9748b46a..1e02f213 100644 --- a/common/JackAudioDriver.cpp +++ b/common/JackAudioDriver.cpp @@ -101,6 +101,7 @@ int JackAudioDriver::Attach() jack_port_id_t port_index; char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + jack_latency_range_t range; int i; jack_log("JackAudioDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); @@ -114,7 +115,8 @@ int JackAudioDriver::Attach() } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - port->SetLatency(fEngineControl->fBufferSize + fCaptureLatency); + range.min = range.max = fEngineControl->fBufferSize + fCaptureLatency; + port->SetLatencyRange(JackCaptureLatency, &range); fCapturePortList[i] = port_index; jack_log("JackAudioDriver::Attach fCapturePortList[i] port_index = %ld", port_index); } @@ -129,7 +131,8 @@ int JackAudioDriver::Attach() port = fGraphManager->GetPort(port_index); port->SetAlias(alias); // Add more latency if "async" mode is used... - port->SetLatency(fEngineControl->fBufferSize + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + fPlaybackLatency); + range.min = range.max = fEngineControl->fBufferSize + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + fPlaybackLatency; + port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[i] = port_index; jack_log("JackAudioDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); @@ -143,7 +146,8 @@ int JackAudioDriver::Attach() } else { port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - port->SetLatency(fEngineControl->fBufferSize); + range.min = range.max = fEngineControl->fBufferSize; + port->SetLatencyRange(JackCaptureLatency, &range); fMonitorPortList[i] = port_index; } } @@ -188,13 +192,13 @@ int JackAudioDriver::ProcessNull() { // Keep begin cycle time JackDriver::CycleTakeBeginTime(); - + if (fEngineControl->fSyncMode) { ProcessGraphSync(); } else { ProcessGraphAsync(); } - + // Keep end cycle time JackDriver::CycleTakeEndTime(); WaitUntilNextCycle(); @@ -214,23 +218,24 @@ synchronize to the end of client graph execution. int JackAudioDriver::ProcessAsync() { // Read input buffers for the current cycle - if (Read() < 0) { + if (Read() < 0) { jack_error("JackAudioDriver::ProcessAsync: read error, stopping..."); - return -1; + return -1; } // Write output buffers from the previous cycle if (Write() < 0) { jack_error("JackAudioDriver::ProcessAsync: write error, stopping..."); - return -1; + return -1; } + // Process graph if (fIsMaster) { ProcessGraphAsync(); } else { fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); } - + // Keep end cycle time JackDriver::CycleTakeEndTime(); return 0; @@ -238,29 +243,38 @@ int JackAudioDriver::ProcessAsync() /* The driver SYNC mode: the server does synchronize to the end of client graph execution, -output buffers computed at the *current cycle* are used. +if graph process succeed, output buffers computed at the *current cycle* are used. */ int JackAudioDriver::ProcessSync() { // Read input buffers for the current cycle - if (Read() < 0) { + if (Read() < 0) { jack_error("JackAudioDriver::ProcessSync: read error, stopping..."); - return -1; + return -1; } + // Process graph if (fIsMaster) { - ProcessGraphSync(); + if (ProcessGraphSync() < 0) { + jack_error("JackAudioDriver::ProcessSync: process error, skip cycle..."); + goto end; + } } else { - fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); + if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { + jack_error("JackAudioDriver::ProcessSync: process error, skip cycle..."); + goto end; + } } - + // Write output buffers from the current cycle if (Write() < 0) { jack_error("JackAudioDriver::ProcessSync: write error, stopping..."); - return -1; + return -1; } - + +end: + // Keep end cycle time JackDriver::CycleTakeEndTime(); return 0; @@ -269,25 +283,34 @@ int JackAudioDriver::ProcessSync() void JackAudioDriver::ProcessGraphAsync() { // fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle - if (!fEngine->Process(fBeginDateUst, fEndDateUst)) + if (!fEngine->Process(fBeginDateUst, fEndDateUst)) jack_error("JackAudioDriver::ProcessGraphAsync: Process error"); fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); if (ProcessSlaves() < 0) jack_error("JackAudioDriver::ProcessGraphAsync: ProcessSlaves error"); } -void JackAudioDriver::ProcessGraphSync() +int JackAudioDriver::ProcessGraphSync() { + int res = 0; + // fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle - if (fEngine->Process(fBeginDateUst, fEndDateUst)) { + if (fEngine->Process(fBeginDateUst, fEndDateUst)) { fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); - if (ProcessSlaves() < 0) + if (ProcessSlaves() < 0) { jack_error("JackAudioDriver::ProcessGraphSync: ProcessSlaves error, engine may now behave abnormally!!"); - if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) + res = -1; + } + if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) { jack_error("JackAudioDriver::ProcessGraphSync: SuspendRefNum error, engine may now behave abnormally!!"); + res = -1; + } } else { // Graph not finished: do not activate it jack_error("JackAudioDriver::ProcessGraphSync: Process error"); + res = -1; } + + return res; } void JackAudioDriver::WaitUntilNextCycle() @@ -316,4 +339,37 @@ jack_default_audio_sample_t* JackAudioDriver::GetMonitorBuffer(int port_index) return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[port_index], fEngineControl->fBufferSize); } +int JackAudioDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) +{ + switch (notify) { + + case kLatencyCallback: + HandleLatencyCallback(value1); + break; + + default: + JackDriver::ClientNotify(refnum, name, notify, sync, message, value1, value2); + break; + } + + return 0; +} + +void JackAudioDriver::HandleLatencyCallback(int status) +{ + jack_latency_callback_mode_t mode = (status == 0) ? JackCaptureLatency : JackPlaybackLatency; + + for (int i = 0; i < fCaptureChannels; i++) { + if (mode == JackPlaybackLatency) { + fGraphManager->RecalculateLatency(fCapturePortList[i], mode); + } + } + + for (int i = 0; i < fPlaybackChannels; i++) { + if (mode == JackCaptureLatency) { + fGraphManager->RecalculateLatency(fPlaybackPortList[i], mode); + } + } +} + } // end of namespace diff --git a/common/JackAudioDriver.h b/common/JackAudioDriver.h index 6fb64e64..3127f4c1 100644 --- a/common/JackAudioDriver.h +++ b/common/JackAudioDriver.h @@ -36,12 +36,12 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver protected: void ProcessGraphAsync(); - void ProcessGraphSync(); + int ProcessGraphSync(); void WaitUntilNextCycle(); virtual int ProcessAsync(); virtual int ProcessSync(); - + int fCaptureChannels; int fPlaybackChannels; @@ -57,6 +57,8 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver jack_default_audio_sample_t* GetOutputBuffer(int port_index); jack_default_audio_sample_t* GetMonitorBuffer(int port_index); + void HandleLatencyCallback(int status); + public: JackAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); @@ -73,7 +75,7 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency); - + virtual int Open(bool capturing, bool playing, int inchannels, @@ -83,18 +85,20 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency); - + virtual int Process(); virtual int ProcessNull(); virtual int Attach(); virtual int Detach(); - + virtual int Write(); 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); + }; } // end of namespace diff --git a/common/JackAudioPort.cpp b/common/JackAudioPort.cpp index 20cf1e8c..c006b1cf 100644 --- a/common/JackAudioPort.cpp +++ b/common/JackAudioPort.cpp @@ -18,7 +18,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "JackGlobals.h" +#include "JackEngineControl.h" #include "JackPortType.h" + #include #if defined (__APPLE__) @@ -46,7 +49,7 @@ static inline void MixAudioBuffer(float* mixbuffer, float* buffer, jack_nframes_ frames = frames % 4; while (frames_group > 0) { -#if defined (__SSE__) && !defined (__sun__) +#if defined (__SSE__) && !defined (__sun__) __m128 vec = _mm_add_ps(_mm_load_ps(mixbuffer), _mm_load_ps(buffer)); _mm_store_ps(mixbuffer, vec); @@ -97,7 +100,7 @@ static void AudioBufferMixdown(void* mixbuffer, void** src_buffers, int src_coun void* buffer; // Copy first buffer -#if defined (__SSE__) && !defined (__sun__) +#if defined (__SSE__) && !defined (__sun__) jack_nframes_t frames_group = nframes / 4; jack_nframes_t remaining_frames = nframes % 4; @@ -127,12 +130,18 @@ static void AudioBufferMixdown(void* mixbuffer, void** src_buffers, int src_coun } } +static size_t AudioBufferSize() +{ + return GetEngineControl()->fBufferSize * sizeof(float); +} + const JackPortType gAudioPortType = - { - JACK_DEFAULT_AUDIO_TYPE, - AudioBufferInit, - AudioBufferMixdown - }; +{ + JACK_DEFAULT_AUDIO_TYPE, + AudioBufferSize, + AudioBufferInit, + AudioBufferMixdown +}; } // namespace Jack diff --git a/common/JackChannel.h b/common/JackChannel.h index 40cfd264..c9ee89e5 100644 --- a/common/JackChannel.h +++ b/common/JackChannel.h @@ -12,7 +12,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. */ @@ -20,7 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __JackChannel__ #define __JackChannel__ -#include "types.h" #include "session.h" namespace Jack @@ -108,43 +107,39 @@ class JackClientChannelInterface {} virtual void SetFreewheel(int onoff, int* result) {} + virtual void ComputeTotalLatencies(int* result) + {} virtual void ReleaseTimebase(int refnum, int* result) {} - virtual void SetTimebaseCallback(int refnum, int conditional, int* result) {} virtual void GetInternalClientName(int refnum, int int_ref, char* name_res, int* result) {} - virtual void InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result) {} - virtual void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result) {} - virtual void InternalClientUnload(int refnum, int int_ref, int* status, int* result) {} - - virtual void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char *path, jack_session_command_t **result) - {} - virtual void SessionReply(int refnum, int *result) + virtual void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t** result) {} - - virtual void GetUUIDForClientName(int refnum, const char *client_name, char *uuid_res, int *result) + virtual void SessionReply(int refnum, int* result) {} - - virtual void GetClientNameForUUID(int refnum, const char *uuid, char *name_res, int *result) + virtual void GetUUIDForClientName(int refnum, const char* client_name, char* uuid_res, int* result) {} - - virtual void ReserveClientName(int refnum, const char *client_name, const char *uuid, int *result) + virtual void GetClientNameForUUID(int refnum, const char* uuid, char* name_res, int* result) + {} + virtual void ReserveClientName(int refnum, const char* client_name, const char *uuid, int* result) + {} + virtual void ClientHasSessionCallback(const char* client_name, int* result) {} virtual bool IsChannelThread() - { - return false; + { + return false; } }; diff --git a/common/JackClient.cpp b/common/JackClient.cpp index 3a59140e..ae244688 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -13,12 +13,12 @@ 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. */ -#include "JackClient.h" +#include "JackSystemDeps.h" #include "JackGraphManager.h" #include "JackClientControl.h" #include "JackEngineControl.h" @@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "driver_interface.h" #include "JackLibGlobals.h" + #include #include #include @@ -60,6 +61,9 @@ JackClient::JackClient(JackSynchro* table):fThread(this) fTimebase = NULL; fSync = NULL; fThreadFun = NULL; + fSession = NULL; + fLatency = NULL; + fProcessArg = NULL; fGraphOrderArg = NULL; fXrunArg = NULL; @@ -75,6 +79,8 @@ JackClient::JackClient(JackSynchro* table):fThread(this) fSyncArg = NULL; fTimebaseArg = NULL; fThreadFunArg = NULL; + fSessionArg = NULL; + fLatencyArg = NULL; } JackClient::~JackClient() @@ -84,17 +90,17 @@ int JackClient::Close() { jack_log("JackClient::Close ref = %ld", GetClientControl()->fRefNum); int result = 0; - + Deactivate(); fChannel->Stop(); // Channels is stopped first to avoid receiving notifications while closing - + // Request close only if server is still running if (JackGlobals::fServerRunning) { fChannel->ClientClose(GetClientControl()->fRefNum, &result); } else { - jack_log("JackClient::Close server is shutdown"); + jack_log("JackClient::Close server is shutdown"); } - + fChannel->Close(); fSynchroTable[GetClientControl()->fRefNum].Disconnect(); JackGlobals::fClientTable[GetClientControl()->fRefNum] = NULL; @@ -106,7 +112,7 @@ bool JackClient::IsActive() return (GetClientControl()) ? GetClientControl()->fActive : false; } -pthread_t JackClient::GetThreadID() +jack_native_thread_t JackClient::GetThreadID() { return fThread.GetThreadID(); } @@ -156,7 +162,7 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, case kActivateClient: jack_log("JackClient::kActivateClient name = %s ref = %ld ", name, refnum); - Init(); + InitAux(); break; } @@ -188,7 +194,7 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, res = fBufferSize(value1, fBufferSizeArg); } break; - + case kSampleRateCallback: jack_log("JackClient::kSampleRateCallback sample_rate = %ld", value1); if (fSampleRate) { @@ -219,7 +225,9 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, fFreewheel(0, fFreewheelArg); } if (GetEngineControl()->fRealTime) { - fThread.AcquireRealTime(); + if (fThread.AcquireRealTime() < 0) { + jack_error("JackClient::AcquireRealTime error"); + } } break; @@ -250,7 +258,7 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, fPortConnect(value1, value2, 0, fPortConnectArg); } break; - + case kPortRenameCallback: jack_log("JackClient::kPortRenameCallback port = %ld", value1); if (fPortRename) { @@ -264,7 +272,7 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, res = fXrun(fXrunArg); } break; - + case kShutDownCallback: jack_log("JackClient::kShutDownCallback"); if (fInfoShutdown) { @@ -289,15 +297,109 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, res = (fImmediateSessionReply) ? 1 : 2; } break; + + case kLatencyCallback: + res = HandleLatencyCallback(value1); + break; } } return res; } +int JackClient::HandleLatencyCallback(int status) +{ + jack_latency_callback_mode_t mode = (status == 0) ? JackCaptureLatency : JackPlaybackLatency; + jack_latency_range_t latency = { UINT32_MAX, 0 }; + + /* first setup all latency values of the ports. + * this is based on the connections of the ports. + */ + list::iterator it; + + for (it = fPortList.begin(); it != fPortList.end(); it++) { + JackPort* port = GetGraphManager()->GetPort(*it); + if ((port->GetFlags() & JackPortIsOutput) && (mode == JackPlaybackLatency)) { + GetGraphManager()->RecalculateLatency(*it, mode); + } + if ((port->GetFlags() & JackPortIsInput) && (mode == JackCaptureLatency)) { + GetGraphManager()->RecalculateLatency(*it, mode); + } + } + + if (!fLatency) { + /* + * default action is to assume all ports depend on each other. + * then always take the maximum latency. + */ + + if (mode == JackPlaybackLatency) { + /* iterate over all OutputPorts, to find maximum playback latency + */ + for (it = fPortList.begin(); it != fPortList.end(); it++) { + JackPort* port = GetGraphManager()->GetPort(*it); + if (port->GetFlags() & JackPortIsOutput) { + jack_latency_range_t other_latency; + port->GetLatencyRange(mode, &other_latency); + if (other_latency.max > latency.max) + latency.max = other_latency.max; + if (other_latency.min < latency.min) + latency.min = other_latency.min; + } + } + + if (latency.min == UINT32_MAX) + latency.min = 0; + + /* now set the found latency on all input ports + */ + for (it = fPortList.begin(); it != fPortList.end(); it++) { + JackPort* port = GetGraphManager()->GetPort(*it); + if (port->GetFlags() & JackPortIsInput) { + port->SetLatencyRange(mode, &latency); + } + } + } + if (mode == JackCaptureLatency) { + /* iterate over all InputPorts, to find maximum playback latency + */ + for (it = fPortList.begin(); it != fPortList.end(); it++) { + JackPort* port = GetGraphManager()->GetPort(*it); + if (port->GetFlags() & JackPortIsInput) { + jack_latency_range_t other_latency; + port->GetLatencyRange(mode, &other_latency); + if (other_latency.max > latency.max) + latency.max = other_latency.max; + if (other_latency.min < latency.min) + latency.min = other_latency.min; + } + } + + if (latency.min == UINT32_MAX) + latency.min = 0; + + /* now set the found latency on all output ports + */ + for (it = fPortList.begin(); it != fPortList.end(); it++) { + JackPort* port = GetGraphManager()->GetPort(*it); + if (port->GetFlags() & JackPortIsOutput) { + port->SetLatencyRange(mode, &latency); + } + } + } + return 0; + } + + /* we have a latency callback setup by the client, + * lets use it... + */ + fLatency(mode, fLatencyArg); + return 0; +} + /*! \brief We need to start thread before activating in the server, otherwise the FW driver - connected to the client may not be activated. +connected to the client may not be activated. */ int JackClient::Activate() { @@ -310,13 +412,13 @@ int JackClient::Activate() if (StartThread() < 0) return -1; } - + /* - Insertion of client in the graph will cause a kGraphOrderCallback notification + Insertion of client in the graph will cause a kGraphOrderCallback notification to be delivered by the server, the client wants to receive it. */ GetClientControl()->fActive = true; - + // Transport related callback become "active" GetClientControl()->fTransportSync = true; GetClientControl()->fTransportTimebase = true; @@ -337,18 +439,18 @@ int JackClient::Deactivate() return 0; GetClientControl()->fActive = false; - + // Transport related callback become "unactive" GetClientControl()->fTransportSync = false; GetClientControl()->fTransportTimebase = false; - + // We need to wait for the new engine cycle before stopping the RT thread, but this is done by ClientDeactivate int result = -1; fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result); jack_log("JackClient::Deactivate res = %ld", result); - + // RT thread is stopped only when needed... - if (IsRealTime()) + if (IsRealTime()) fThread.Kill(); return result; } @@ -357,15 +459,48 @@ int JackClient::Deactivate() // RT thread management //---------------------- +void JackClient::InitAux() +{ + if (fInit) { + jack_log("JackClient::Init calling client thread init callback"); + fInit(fInitArg); + } +} + /*! \brief Called once when the thread starts. */ bool JackClient::Init() { - if (fInit) { - jack_log("JackClient::Init calling client thread init callback"); - fInit(fInitArg); + /* + Execute buffer_size callback. + + Since StartThread uses fThread.StartSync, we are sure that buffer_size callback + is executed before StartThread returns (and then IsActive will be true). + So no RT callback can be called at the same time. + */ + jack_log("JackClient::kBufferSizeCallback buffer_size = %ld", GetEngineControl()->fBufferSize); + if (fBufferSize) { + fBufferSize(GetEngineControl()->fBufferSize, fBufferSizeArg); + } + + // Init callback + InitAux(); + + // Setup context + if (!jack_tls_set(JackGlobals::fRealTime, this)) + jack_error("failed to set thread realtime key"); + + if (GetEngineControl()->fRealTime) + set_threaded_log_function(); + + // Setup RT + if (GetEngineControl()->fRealTime) { + if (fThread.AcquireRealTime(GetEngineControl()->fClientPriority) < 0) { + jack_error("JackClient::AcquireRealTime error"); + } } + return true; } @@ -384,12 +519,6 @@ int JackClient::StartThread() return -1; } - if (GetEngineControl()->fRealTime) { - if (fThread.AcquireRealTime(GetEngineControl()->fClientPriority) < 0) { - jack_error("AcquireRealTime error"); - } - } - return 0; } @@ -399,21 +528,15 @@ int JackClient::StartThread() bool JackClient::Execute() { - if (!jack_tls_set(JackGlobals::fRealTime, this)) - jack_error("failed to set thread realtime key"); - - if (GetEngineControl()->fRealTime) - set_threaded_log_function(); - // Execute a dummy cycle to be sure thread has the correct properties DummyCycle(); - + if (fThreadFun) { fThreadFun(fThreadFunArg); } else { ExecuteThread(); } - return false; + return false; } void JackClient::DummyCycle() @@ -424,15 +547,15 @@ void JackClient::DummyCycle() inline void JackClient::ExecuteThread() { - while (true) { + while (true) { CycleWaitAux(); - CycleSignalAux(CallProcessCallback()); - } + CycleSignalAux(CallProcessCallback()); + } } inline jack_nframes_t JackClient::CycleWaitAux() { - if (!WaitSync()) + if (!WaitSync()) Error(); // Terminates the thread CallSyncCallbackAux(); return GetEngineControl()->fBufferSize; @@ -443,7 +566,7 @@ inline void JackClient::CycleSignalAux(int status) if (status == 0) CallTimebaseCallbackAux(); SignalSync(); - if (status != 0) + if (status != 0) End(); // Terminates the thread } @@ -531,7 +654,7 @@ int JackClient::PortRegister(const char* port_name, const char* port_type, unsig int result = -1; jack_port_id_t port_index = NO_PORT; fChannel->PortRegister(GetClientControl()->fRefNum, name.c_str(), port_type, flags, buffer_size, &port_index, &result); - + if (result == 0) { jack_log("JackClient::PortRegister ref = %ld name = %s type = %s port_index = %ld", GetClientControl()->fRefNum, name.c_str(), port_type, port_index); fPortList.push_back(port_index); @@ -612,6 +735,13 @@ int JackClient::SetFreeWheel(int onoff) return result; } +int JackClient::ComputeTotalLatencies() +{ + int result = -1; + fChannel->ComputeTotalLatencies(&result); + return result; +} + /* ShutDown is called: - from the RT thread when Execute method fails @@ -621,9 +751,9 @@ ShutDown is called: void JackClient::ShutDown() { - jack_log("ShutDown"); + jack_log("JackClient::ShutDown"); JackGlobals::fServerRunning = false; - + if (fInfoShutdown) { fInfoShutdown(JackFailure, "JACK server has been closed", fInfoShutdownArg); fInfoShutdown = NULL; @@ -641,18 +771,18 @@ inline int JackClient::ActivateAux() { // If activated without RT thread... if (IsActive() && fThread.GetStatus() != JackThread::kRunning) { - - jack_log("ActivateAux"); - + + jack_log("JackClient::ActivateAux"); + // RT thread is started if (StartThread() < 0) return -1; - + int result = -1; GetClientControl()->fCallback[kRealTimeCallback] = IsRealTime(); fChannel->ClientActivate(GetClientControl()->fRefNum, IsRealTime(), &result); return result; - + } else { return 0; } @@ -683,7 +813,7 @@ int JackClient::SetTimebaseCallback(int conditional, JackTimebaseCallback timeba { int result = -1; fChannel->SetTimebaseCallback(GetClientControl()->fRefNum, conditional, &result); - + if (result == 0) { GetClientControl()->fTransportTimebase = true; fTimebase = timebase_callback; @@ -709,14 +839,14 @@ void JackClient::TransportLocate(jack_nframes_t frame) jack_position_t pos; pos.frame = frame; pos.valid = (jack_position_bits_t)0; - jack_log("TransportLocate pos = %ld", pos.frame); + jack_log("JackClient::TransportLocate pos = %ld", pos.frame); GetEngineControl()->fTransport.RequestNewPos(&pos); } int JackClient::TransportReposition(jack_position_t* pos) { jack_position_t tmp = *pos; - jack_log("TransportReposition pos = %ld", pos->frame); + jack_log("JackClient::TransportReposition pos = %ld", pos->frame); if (tmp.valid & ~JACK_POSITION_MASK) { return EINVAL; } else { @@ -758,11 +888,11 @@ void JackClient::CallSyncCallback() inline void JackClient::CallSyncCallbackAux() { if (GetClientControl()->fTransportSync) { - + JackTransportEngine& transport = GetEngineControl()->fTransport; jack_position_t* cur_pos = transport.ReadCurrentState(); jack_transport_state_t transport_state = transport.GetState(); - + if (fSync != NULL) { if (fSync(transport_state, cur_pos, fSyncArg)) { GetClientControl()->fTransportState = JackTransportRolling; @@ -785,21 +915,21 @@ inline void JackClient::CallTimebaseCallbackAux() JackTransportEngine& transport = GetEngineControl()->fTransport; int master; bool unused; - + transport.GetTimebaseMaster(master, unused); - + if (GetClientControl()->fRefNum == master && fTimebase) { // Client *is* timebase... - + jack_transport_state_t transport_state = transport.GetState(); jack_position_t* cur_pos = transport.WriteNextStateStart(1); - + if (GetClientControl()->fTransportTimebase) { - fTimebase(transport_state, GetEngineControl()->fBufferSize, cur_pos, true, fTimebaseArg); - GetClientControl()->fTransportTimebase = false; // Callback is called only once with "new_pos" = true + fTimebase(transport_state, GetEngineControl()->fBufferSize, cur_pos, true, fTimebaseArg); + GetClientControl()->fTransportTimebase = false; // Callback is called only once with "new_pos" = true } else if (transport_state == JackTransportRolling) { fTimebase(transport_state, GetEngineControl()->fBufferSize, cur_pos, false, fTimebaseArg); - } - + } + transport.WriteNextStateStop(1); } } @@ -817,7 +947,7 @@ void JackClient::OnShutdown(JackShutdownCallback callback, void *arg) fShutdown = callback; } } - + void JackClient::OnInfoShutdown(JackInfoShutdownCallback callback, void *arg) { if (IsActive()) { @@ -873,8 +1003,6 @@ int JackClient::SetInitCallback(JackThreadInitCallback callback, void *arg) int JackClient::SetGraphOrderCallback(JackGraphOrderCallback callback, void *arg) { - jack_log("SetGraphOrderCallback "); - if (IsActive()) { jack_error("You cannot set callbacks on an active client"); return -1; @@ -908,8 +1036,8 @@ int JackClient::SetSampleRateCallback(JackSampleRateCallback callback, void *arg GetClientControl()->fCallback[kSampleRateCallback] = (callback != NULL); fSampleRateArg = arg; fSampleRate = callback; - // Now invoke it - if (callback) + // Now invoke it + if (callback) callback(GetEngineControl()->fSampleRate, arg); return 0; } @@ -1011,6 +1139,19 @@ int JackClient::SetSessionCallback(JackSessionCallback callback, void *arg) } } +int JackClient::SetLatencyCallback(JackLatencyCallback callback, void *arg) +{ + if (IsActive()) { + jack_error("You cannot set callbacks on an active client"); + return -1; + } else { + // fCallback[kLatencyCallback] must always be 'true' + fLatencyArg = arg; + fLatency = callback; + return 0; + } +} + //------------------ // Internal clients //------------------ @@ -1072,65 +1213,64 @@ void JackClient::InternalClientUnload(int ref, jack_status_t* status) // Session API //------------------ -jack_session_command_t *JackClient::SessionNotify( const char* target, jack_session_event_type_t type, const char* path ) +jack_session_command_t* JackClient::SessionNotify(const char* target, jack_session_event_type_t type, const char* path) { - jack_session_command_t *res; - fChannel->SessionNotify( GetClientControl()->fRefNum, target, type, path, &res ); + jack_session_command_t* res; + fChannel->SessionNotify(GetClientControl()->fRefNum, target, type, path, &res); return res; } -int JackClient::SessionReply( jack_session_event_t *ev ) +int JackClient::SessionReply(jack_session_event_t* ev) { if (ev->command_line) { - strncpy( GetClientControl()->fSessionCommand, ev->command_line, sizeof(GetClientControl()->fSessionCommand) ); + strncpy(GetClientControl()->fSessionCommand, ev->command_line, sizeof(GetClientControl()->fSessionCommand)); } else { GetClientControl()->fSessionCommand[0] = '\0'; } GetClientControl()->fSessionFlags = ev->flags; - jack_log( "JackClient::SessionReply... we are here" ); + jack_log("JackClient::SessionReply... we are here"); if (fChannel->IsChannelThread()) { - jack_log( "JackClient::SessionReply... in callback reply" ); + jack_log( "JackClient::SessionReply... in callback reply"); fImmediateSessionReply = true; return 0; } - jack_log( "JackClient::SessionReply... out of cb" ); + jack_log("JackClient::SessionReply... out of cb"); - int res; - fChannel->SessionReply( GetClientControl()->fRefNum, &res); - return res; + int result = -1; + fChannel->SessionReply(GetClientControl()->fRefNum, &result); + return result; } char* JackClient::GetUUIDForClientName(const char* client_name) { char uuid_res[JACK_UUID_SIZE]; int result = -1; - fChannel->GetUUIDForClientName( GetClientControl()->fRefNum, client_name, uuid_res, &result); - - if (result) - return NULL; - - return strdup(uuid_res); + fChannel->GetUUIDForClientName(GetClientControl()->fRefNum, client_name, uuid_res, &result); + return (result) ? NULL : strdup(uuid_res); } -char* JackClient::GetClientNameForUUID(const char* uuid) +char* JackClient::GetClientNameByUUID(const char* uuid) { char name_res[JACK_CLIENT_NAME_SIZE + 1]; int result = -1; fChannel->GetClientNameForUUID(GetClientControl()->fRefNum, uuid, name_res, &result); + return (result) ? NULL : strdup(name_res); +} - if (result) - return NULL; - - return strdup(name_res); +int JackClient::ReserveClientName(const char* client_name, const char* uuid) +{ + int result = -1; + fChannel->ReserveClientName( GetClientControl()->fRefNum, client_name, uuid, &result); + return result; } -int JackClient::ReserveClientName(const char *name, const char* uuid) +int JackClient::ClientHasSessionCallback(const char* client_name) { int result = -1; - fChannel->ReserveClientName( GetClientControl()->fRefNum, name, uuid, &result); + fChannel->ClientHasSessionCallback(client_name, &result); return result; } diff --git a/common/JackClient.h b/common/JackClient.h index cd5ab090..230edf53 100644 --- a/common/JackClient.h +++ b/common/JackClient.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. */ @@ -27,7 +27,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackSynchro.h" #include "JackPlatformPlug.h" #include "JackChannel.h" -#include "types.h" #include "session.h" #include "varargs.h" #include @@ -68,6 +67,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface JackSyncCallback fSync; JackThreadCallback fThreadFun; JackSessionCallback fSession; + JackLatencyCallback fLatency; void* fProcessArg; void* fGraphOrderArg; @@ -86,6 +86,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface void* fSyncArg; void* fThreadFunArg; void* fSessionArg; + void* fLatencyArg; char fServerName[64]; JackThread fThread; /*! Thread to execute the Process function */ @@ -94,14 +95,14 @@ class JackClient : public JackClientInterface, public JackRunnableInterface std::list fPortList; bool fImmediateSessionReply; - + int StartThread(); void SetupDriverSync(bool freewheel); bool IsActive(); void CallSyncCallback(); void CallTimebaseCallback(); - + virtual int ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value); inline void DummyCycle(); @@ -116,7 +117,10 @@ class JackClient : public JackClientInterface, public JackRunnableInterface inline void CallSyncCallbackAux(); inline void CallTimebaseCallbackAux(); inline int ActivateAux(); - + inline void InitAux(); + + int HandleLatencyCallback(int status); + public: JackClient(); @@ -138,8 +142,9 @@ class JackClient : public JackClientInterface, public JackRunnableInterface // Context virtual int SetBufferSize(jack_nframes_t buffer_size); virtual int SetFreeWheel(int onoff); + virtual int ComputeTotalLatencies(); virtual void ShutDown(); - virtual pthread_t GetThreadID(); + virtual jack_native_thread_t GetThreadID(); // Port management virtual int PortRegister(const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size); @@ -179,6 +184,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface virtual int SetPortConnectCallback(JackPortConnectCallback callback, void *arg); virtual int SetPortRenameCallback(JackPortRenameCallback callback, void *arg); virtual int SetSessionCallback(JackSessionCallback callback, void *arg); + virtual int SetLatencyCallback(JackLatencyCallback callback, void *arg); // Internal clients virtual char* GetInternalClientName(int ref); @@ -186,16 +192,18 @@ class JackClient : public JackClientInterface, public JackRunnableInterface virtual int InternalClientLoad(const char* client_name, jack_options_t options, jack_status_t* status, jack_varargs_t* va); virtual void InternalClientUnload(int ref, jack_status_t* status); + // RT Thread jack_nframes_t CycleWait(); void CycleSignal(int status); int SetProcessThread(JackThreadCallback fun, void *arg); - // Session api - virtual jack_session_command_t *SessionNotify(const char *target, jack_session_event_type_t type, const char *path); - virtual int SessionReply(jack_session_event_t *ev); -char* GetUUIDForClientName(const char* client_name); -char* GetClientNameForUUID(const char* uuid); -int ReserveClientName(const char *name, const char* uuid); + // Session API + virtual jack_session_command_t* SessionNotify(const char* target, jack_session_event_type_t type, const char* path); + virtual int SessionReply(jack_session_event_t* ev); + char* GetUUIDForClientName(const char* client_name); + char* GetClientNameByUUID(const char* uuid); + int ReserveClientName(const char* client_name, const char* uuid); + int ClientHasSessionCallback(const char* client_name); // JackRunnableInterface interface bool Init(); diff --git a/common/JackClientControl.h b/common/JackClientControl.h index 98f2ad31..29e4a5b7 100644 --- a/common/JackClientControl.h +++ b/common/JackClientControl.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. */ @@ -25,8 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackPort.h" #include "JackSynchro.h" #include "JackNotification.h" - -#include "jack/session.h" +#include "session.h" namespace Jack { @@ -74,6 +73,7 @@ struct JackClientControl : public JackShmMemAble fCallback[kAddClient] = true; fCallback[kRemoveClient] = true; fCallback[kActivateClient] = true; + fCallback[kLatencyCallback] = true; // So that driver synchro are correctly setup in "flush" or "normal" mode fCallback[kStartFreewheelCallback] = true; fCallback[kStopFreewheelCallback] = true; diff --git a/common/JackConnectionManager.cpp b/common/JackConnectionManager.cpp index f6a74dca..2be93fc9 100644 --- a/common/JackConnectionManager.cpp +++ b/common/JackConnectionManager.cpp @@ -12,7 +12,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. */ @@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackEngineControl.h" #include "JackGlobals.h" #include "JackError.h" +#include #include #include @@ -246,7 +247,7 @@ int JackConnectionManager::SuspendRefNum(JackClientControl* control, JackSynchro int JackConnectionManager::ResumeRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing) { jack_time_t current_date = GetMicroSeconds(); - const jack_int_t* outputRef = fConnectionRef.GetItems(control->fRefNum); + const jack_int_t* output_ref = fConnectionRef.GetItems(control->fRefNum); int res = 0; // Update state and timestamp of current client @@ -256,7 +257,7 @@ int JackConnectionManager::ResumeRefNum(JackClientControl* control, JackSynchro* for (int i = 0; i < CLIENT_NUM; i++) { // Signal connected clients or drivers - if (outputRef[i] > 0) { + if (output_ref[i] > 0) { // Update state and timestamp of destination clients timing[i].fStatus = Triggered; @@ -272,6 +273,44 @@ int JackConnectionManager::ResumeRefNum(JackClientControl* control, JackSynchro* return res; } +static bool HasNoConnection(jack_int_t* table) +{ + for (int ref = 0; ref < CLIENT_NUM; ref++) { + if (table[ref] > 0) return false; + } + return true; +} + +// Using http://en.wikipedia.org/wiki/Topological_sorting + +void JackConnectionManager::TopologicalSort(std::vector& sorted) +{ + JackFixedMatrix tmp; + std::set level; + + fConnectionRef.Copy(tmp); + + // Inputs of the graph + level.insert(AUDIO_DRIVER_REFNUM); + level.insert(FREEWHEEL_DRIVER_REFNUM); + + while (level.size() > 0) { + jack_int_t refnum = *level.begin(); + sorted.push_back(refnum); + level.erase(level.begin()); + const jack_int_t* output_ref1 = tmp.GetItems(refnum); + for (int dst = 0; dst < CLIENT_NUM; dst++) { + if (output_ref1[dst] > 0) { + tmp.ClearItem(refnum, dst); + jack_int_t output_ref2[CLIENT_NUM]; + tmp.GetOutputTable1(dst, output_ref2); + if (HasNoConnection(output_ref2)) + level.insert(dst); + } + } + } +} + /*! \brief Increment the number of ports between 2 clients, if the 2 clients become connected, then the Activation counter is updated. */ diff --git a/common/JackConnectionManager.h b/common/JackConnectionManager.h index 5d5b8c62..804ffcc3 100644 --- a/common/JackConnectionManager.h +++ b/common/JackConnectionManager.h @@ -12,7 +12,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. */ @@ -24,7 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackActivationCount.h" #include "JackError.h" #include "JackCompilerDeps.h" - +#include #include namespace Jack @@ -151,7 +151,7 @@ class JackFixedArray1 : public JackFixedArray return true; } } - + } POST_PACKED_STRUCTURE; /*! @@ -200,6 +200,11 @@ class JackFixedMatrix return fTable[index1][index2]; } + void ClearItem(jack_int_t index1, jack_int_t index2) + { + fTable[index1][index2] = 0; + } + /*! \brief Get the output indexes of a given index. */ @@ -218,6 +223,13 @@ class JackFixedMatrix } } + void GetOutputTable1(jack_int_t index, jack_int_t* output) const + { + for (int i = 0; i < SIZE; i++) { + output[i] = fTable[i][index]; + } + } + bool IsInsideTable(jack_int_t index, jack_int_t* output) const { for (int i = 0; i < SIZE && output[i] != EMPTY; i++) { @@ -227,6 +239,14 @@ class JackFixedMatrix return false; } + void Copy(JackFixedMatrix& copy) + { + for (int i = 0; i < SIZE; i++) { + memcpy(copy.fTable[i], fTable[i], sizeof(jack_int_t) * SIZE); + } + } + + } POST_PACKED_STRUCTURE; /*! @@ -359,7 +379,7 @@ struct JackClientTiming } ~JackClientTiming() {} - + void Init() { fSignaledAt = 0; @@ -367,7 +387,7 @@ struct JackClientTiming fFinishedAt = 0; fStatus = NotTriggered; } - + } POST_PACKED_STRUCTURE; /*! @@ -375,11 +395,9 @@ struct JackClientTiming

  • The fConnection array contains the list (array line) of connected ports for a given port. -
  • The fConnectionCount array contains the number of connected ports to a given port.
  • The fInputPort array contains the list (array line) of input connected ports for a given client.
  • The fOutputPort array contains the list (array line) of ouput connected ports for a given client.
  • The fConnectionRef array contains the number of ports connected between two clients. -
  • The fInputRef array contains the number of input clients connected to a given client.
  • The fInputCounter array contains the number of input clients connected to a given for activation purpose.
*/ @@ -461,7 +479,8 @@ class SERVER_EXPORT JackConnectionManager void ResetGraph(JackClientTiming* timing); int ResumeRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing); int SuspendRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing, long time_out_usec); - + void TopologicalSort(std::vector& sorted); + } POST_PACKED_STRUCTURE; } // end of namespace diff --git a/common/JackDebugClient.cpp b/common/JackDebugClient.cpp index 77a6df28..3c389abc 100644 --- a/common/JackDebugClient.cpp +++ b/common/JackDebugClient.cpp @@ -12,7 +12,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. */ @@ -116,17 +116,17 @@ int JackDebugClient::Close() void JackDebugClient::CheckClient(const char* function_name) const { *fStream << "CheckClient : " << function_name << ", calling thread : " << pthread_self() << endl; - + if (fIsClosed > 0) { - *fStream << "!!! ERROR !!! : Accessing a client '" << fClientName << "' already closed " << "from " << function_name << endl; + *fStream << "!!! ERROR !!! : Accessing a client '" << fClientName << "' already closed " << "from " << function_name << endl; *fStream << "This is likely to cause crash !'" << endl; #ifdef __APPLE__ // Debugger(); - #endif + #endif } } -pthread_t JackDebugClient::GetThreadID() +jack_native_thread_t JackDebugClient::GetThreadID() { CheckClient("GetThreadID"); return fClient->GetThreadID(); @@ -428,7 +428,7 @@ void JackDebugClient::OnInfoShutdown(JackInfoShutdownCallback callback, void *ar CheckClient("OnInfoShutdown"); fClient->OnInfoShutdown(callback, arg); } - + int JackDebugClient::TimeCallback(jack_nframes_t nframes, void *arg) { JackDebugClient* client = (JackDebugClient*)arg; diff --git a/common/JackDebugClient.h b/common/JackDebugClient.h index fc9ebf55..6a19deca 100644 --- a/common/JackDebugClient.h +++ b/common/JackDebugClient.h @@ -12,7 +12,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. */ @@ -84,7 +84,7 @@ class JackDebugClient : public JackClient int SetBufferSize(jack_nframes_t buffer_size); int SetFreeWheel(int onoff); void ShutDown(); - pthread_t GetThreadID(); + jack_native_thread_t GetThreadID(); // Port management int PortRegister(const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size); diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index a485d810..a2c6ccd6 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -167,7 +167,7 @@ int JackDriver::Open(jack_nframes_t buffer_size, int JackDriver::Close() { - if (fClientControl.fRefNum >= 0) { + if (fClientControl.fRefNum >= 0) { jack_log("JackDriver::Close"); fGraphManager->DirectDisconnect(fClientControl.fRefNum, fClientControl.fRefNum); // Disconnect driver from itself for sync fClientControl.fActive = false; @@ -207,7 +207,7 @@ int JackDriver::ClientNotify(int refnum, const char* name, int notify, int sync, jack_log("JackDriver::kStopFreewheel"); SetupDriverSync(fClientControl.fRefNum, false); break; - } + } return 0; } @@ -223,13 +223,13 @@ void JackDriver::CycleIncTime() } void JackDriver::CycleTakeBeginTime() -{ +{ fBeginDateUst = GetMicroSeconds(); // Take callback date here fEngineControl->CycleIncTime(fBeginDateUst); } void JackDriver::CycleTakeEndTime() -{ +{ fEndDateUst = GetMicroSeconds(); // Take end date here } @@ -254,7 +254,7 @@ void JackDriver::NotifySampleRate(jack_nframes_t sample_rate) fEngine->NotifySampleRate(sample_rate); fEngineControl->InitFrameTime(); } - + void JackDriver::NotifyFailure(int code, const char* reason) { fEngine->NotifyFailure(code, reason); 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/JackDummyDriver.cpp b/common/JackDummyDriver.cpp index 5f31cb88..fb996a11 100644 --- a/common/JackDummyDriver.cpp +++ b/common/JackDummyDriver.cpp @@ -56,6 +56,12 @@ int JackDummyDriver::Open(jack_nframes_t buffer_size, fEngineControl->fPeriod = 0; fEngineControl->fComputation = 500 * 1000; fEngineControl->fConstraint = 500 * 1000; + int buffer_size = int((fWaitTime * fEngineControl->fSampleRate) / 1000000.0f); + if (buffer_size > BUFFER_SIZE_MAX) { + buffer_size = BUFFER_SIZE_MAX; + jack_error("Buffer size set to %d ", BUFFER_SIZE_MAX); + } + SetBufferSize(buffer_size); return 0; } else { return -1; diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index 28f54432..338e5a42 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -19,6 +19,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include +#include #include #include "JackSystemDeps.h" @@ -90,7 +91,7 @@ int JackEngine::Close() return 0; } - + void JackEngine::NotifyQuit() { fChannel.NotifyQuit(); @@ -137,8 +138,10 @@ void JackEngine::ReleaseRefnum(int ref) void JackEngine::ProcessNext(jack_time_t cur_cycle_begin) { fLastSwitchUsecs = cur_cycle_begin; - if (fGraphManager->RunNextGraph()) // True if the graph actually switched to a new state + if (fGraphManager->RunNextGraph()) { // True if the graph actually switched to a new state fChannel.Notify(ALL_CLIENTS, kGraphOrderCallback, 0); + //NotifyGraphReorder(); + } fSignal.Signal(); // Signal for threads waiting for next cycle } @@ -195,16 +198,44 @@ void JackEngine::CheckXRun(jack_time_t callback_usecs) // REVOIR les conditions if (status != NotTriggered && status != Finished) { jack_error("JackEngine::XRun: client = %s was not run: state = %ld", client->GetClientControl()->fName, status); fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); // Notify all clients + //NotifyXRun(ALL_CLIENTS); } if (status == Finished && (long)(finished_date - callback_usecs) > 0) { jack_error("JackEngine::XRun: client %s finished after current callback", client->GetClientControl()->fName); fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); // Notify all clients + //NotifyXRun(ALL_CLIENTS); } } } } +int JackEngine::ComputeTotalLatencies() +{ + std::vector sorted; + std::vector::iterator it; + std::vector::reverse_iterator rit; + + fGraphManager->TopologicalSort(sorted); + + /* iterate over all clients in graph order, and emit + * capture latency callback. + */ + + for (it = sorted.begin(); it != sorted.end(); it++) { + jack_log("Sorted %d", *it); + NotifyClient(*it, kLatencyCallback, true, "", 0, 0); + } + + /* now issue playback latency callbacks in reverse graph order. + */ + for (rit = sorted.rbegin(); rit != sorted.rend(); rit++) { + NotifyClient(*rit, kLatencyCallback, true, "", 1, 0); + } + + return 0; +} + //--------------- // Notifications //--------------- @@ -215,8 +246,8 @@ void JackEngine::NotifyClient(int refnum, int event, int sync, const char* messa // The client may be notified by the RT thread while closing if (client) { - - if (client && client->GetClientControl()->fCallback[event]) { + + if (client->GetClientControl()->fCallback[event]) { /* Important for internal clients : unlock before calling the notification callbacks. */ @@ -225,7 +256,7 @@ void JackEngine::NotifyClient(int refnum, int event, int sync, const char* messa jack_error("NotifyClient fails name = %s event = %ld val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2); if (res) fMutex.Lock(); - + } else { jack_log("JackEngine::NotifyClient: no callback for event = %ld", event); } @@ -277,6 +308,7 @@ void JackEngine::NotifyXRun(jack_time_t callback_usecs, float delayed_usecs) // Use the audio thread => request thread communication channel fEngineControl->NotifyXRun(callback_usecs, delayed_usecs); fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); + //NotifyXRun(ALL_CLIENTS); } void JackEngine::NotifyXRun(int refnum) @@ -290,6 +322,7 @@ void JackEngine::NotifyXRun(int refnum) void JackEngine::NotifyGraphReorder() { + ComputeTotalLatencies(); NotifyClients(kGraphOrderCallback, false, "", 0, 0); } @@ -307,7 +340,7 @@ void JackEngine::NotifyFailure(int code, const char* reason) { NotifyClients(kShutDownCallback, false, reason, code, 0); } - + void JackEngine::NotifyFreewheel(bool onoff) { if (onoff) { @@ -406,7 +439,7 @@ int JackEngine::ClientCheck(const char* name, int uuid, char* name_res, int prot std::map::iterator res = fReservationMap.find(uuid); if (res != fReservationMap.end()) { - strncpy( name_res, res->second.c_str(), JACK_CLIENT_NAME_SIZE ); + strncpy(name_res, res->second.c_str(), JACK_CLIENT_NAME_SIZE); } else if (ClientCheckName(name)) { *status |= JackNameNotUnique; @@ -467,7 +500,7 @@ bool JackEngine::ClientCheckName(const char* name) return true; } - for (std::map::iterator i=fReservationMap.begin(); i!=fReservationMap.end(); i++) { + for (std::map::iterator i = fReservationMap.begin(); i != fReservationMap.end(); i++) { if (i->second == name) return true; } @@ -522,14 +555,14 @@ int JackEngine::ClientExternalOpen(const char* name, int pid, int uuid, int* ref if (uuid < 0) { uuid = GetNewUUID(); - strncpy( real_name, name, JACK_CLIENT_NAME_SIZE ); + strncpy(real_name, name, JACK_CLIENT_NAME_SIZE); } else { std::map::iterator res = fReservationMap.find(uuid); if (res != fReservationMap.end()) { - strncpy( real_name, res->second.c_str(), JACK_CLIENT_NAME_SIZE ); + strncpy(real_name, res->second.c_str(), JACK_CLIENT_NAME_SIZE); fReservationMap.erase(uuid); } else { - strncpy( real_name, name, JACK_CLIENT_NAME_SIZE ); + strncpy(real_name, name, JACK_CLIENT_NAME_SIZE); } EnsureUUID(uuid); @@ -689,7 +722,7 @@ int JackEngine::ClientActivate(int refnum, bool is_real_time) { JackClientInterface* client = fClientTable[refnum]; jack_log("JackEngine::ClientActivate ref = %ld name = %s", refnum, client->GetClientControl()->fName); - + if (is_real_time) fGraphManager->Activate(refnum); @@ -702,18 +735,10 @@ int JackEngine::ClientActivate(int refnum, bool is_real_time) jack_int_t output_ports[PORT_NUM_FOR_CLIENT]; 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); - + // Then issue port registration notification for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { NotifyPortRegistation(input_ports[i], true); @@ -740,13 +765,11 @@ 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 for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { NotifyPortRegistation(input_ports[i], false); @@ -867,7 +890,7 @@ int JackEngine::PortDisconnect(int refnum, const char* src, const char* dst) int JackEngine::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst) { jack_log("JackEngine::PortDisconnect src = %d dst = %d", src, dst); - + if (dst == ALL_PORTS) { jack_int_t connections[CONNECTION_NUM_FOR_PORT]; @@ -910,6 +933,10 @@ int JackEngine::PortRename(int refnum, jack_port_id_t port, const char* name) return 0; } +//-------------------- +// Session management +//-------------------- + void JackEngine::SessionNotify(int refnum, const char *target, jack_session_event_type_t type, const char *path, JackChannelTransaction *socket) { if (fSessionPendingReplies != 0) { @@ -940,11 +967,11 @@ void JackEngine::SessionNotify(int refnum, const char *target, jack_session_even char path_buf[JACK_PORT_NAME_SIZE]; snprintf( path_buf, sizeof(path_buf), "%s%s%c", path, client->GetClientControl()->fName, DIR_SEPARATOR ); - + int res = JackTools::MkDir(path_buf); - if (res) + if (res) jack_error( "JackEngine::SessionNotify: can not create session directory '%s'", path_buf ); - + int result = client->ClientNotify(i, client->GetClientControl()->fName, kSessionCallback, true, path_buf, (int) type, 0); if (result == 2) { @@ -952,9 +979,9 @@ void JackEngine::SessionNotify(int refnum, const char *target, jack_session_even } else if (result == 1) { char uuid_buf[JACK_UUID_SIZE]; snprintf( uuid_buf, sizeof(uuid_buf), "%d", client->GetClientControl()->fSessionID ); - fSessionResult->fCommandList.push_back( JackSessionCommand( uuid_buf, + fSessionResult->fCommandList.push_back( JackSessionCommand( uuid_buf, client->GetClientControl()->fName, - client->GetClientControl()->fSessionCommand, + client->GetClientControl()->fSessionCommand, client->GetClientControl()->fSessionFlags )); } } @@ -973,11 +1000,11 @@ void JackEngine::SessionReply(int refnum) { JackClientInterface* client = fClientTable[refnum]; char uuid_buf[JACK_UUID_SIZE]; - snprintf( uuid_buf, sizeof(uuid_buf), "%d", client->GetClientControl()->fSessionID ); - fSessionResult->fCommandList.push_back( JackSessionCommand( uuid_buf, - client->GetClientControl()->fName, - client->GetClientControl()->fSessionCommand, - client->GetClientControl()->fSessionFlags )); + snprintf( uuid_buf, sizeof(uuid_buf), "%d", client->GetClientControl()->fSessionID); + fSessionResult->fCommandList.push_back(JackSessionCommand(uuid_buf, + client->GetClientControl()->fName, + client->GetClientControl()->fSessionCommand, + client->GetClientControl()->fSessionFlags)); fSessionPendingReplies -= 1; if (fSessionPendingReplies == 0) { @@ -998,9 +1025,8 @@ void JackEngine::GetUUIDForClientName(const char *client_name, char *uuid_res, i return; } } - // did not find name. + // Did not find name. *result = -1; - return; } void JackEngine::GetClientNameForUUID(const char *uuid, char *name_res, int *result) @@ -1020,18 +1046,17 @@ void JackEngine::GetClientNameForUUID(const char *uuid, char *name_res, int *res return; } } - // did not find uuid. + // Did not find uuid. *result = -1; - return; } void JackEngine::ReserveClientName(const char *name, const char *uuid, int *result) { - jack_log( "JackEngine::ReserveClientName ( name = %s, uuid = %s )", name, uuid ); + jack_log("JackEngine::ReserveClientName ( name = %s, uuid = %s )", name, uuid); if (ClientCheckName(name)) { *result = -1; - jack_log( "name already taken" ); + jack_log("name already taken"); return; } @@ -1040,5 +1065,21 @@ void JackEngine::ReserveClientName(const char *name, const char *uuid, int *resu *result = 0; } +void JackEngine::ClientHasSessionCallbackRequest(const char *name, int *result) +{ + JackClientInterface* client = NULL; + for (int i = 0; i < CLIENT_NUM; i++) { + JackClientInterface* client = fClientTable[i]; + if (client && (strcmp(client->GetClientControl()->fName, name) == 0)) + break; + } + + if (client) { + *result = client->GetClientControl()->fCallback[kSessionCallback]; + } else { + *result = -1; + } +} + } // end of namespace diff --git a/common/JackEngine.h b/common/JackEngine.h index ae969cb7..185c1b16 100644 --- a/common/JackEngine.h +++ b/common/JackEngine.h @@ -129,6 +129,8 @@ class SERVER_EXPORT JackEngine : public JackLockAble int PortRename(int refnum, jack_port_id_t port, const char* name); + int ComputeTotalLatencies(); + // Graph bool Process(jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end); @@ -142,12 +144,14 @@ class SERVER_EXPORT JackEngine : public JackLockAble void NotifyFreewheel(bool onoff); void NotifyQuit(); - void SessionNotify( int refnum, const char *target, jack_session_event_type_t type, const char *path, JackChannelTransaction *socket ); - void SessionReply( int refnum ); + // Session management + void SessionNotify(int refnum, const char *target, jack_session_event_type_t type, const char *path, JackChannelTransaction *socket); + void SessionReply(int refnum); void GetUUIDForClientName(const char *client_name, char *uuid_res, int *result); void GetClientNameForUUID(const char *uuid, char *name_res, int *result); void ReserveClientName(const char *name, const char *uuid, int *result); + void ClientHasSessionCallbackRequest(const char *name, int *result); }; diff --git a/common/JackEngineControl.cpp b/common/JackEngineControl.cpp index db13ae78..d9ab2b16 100644 --- a/common/JackEngineControl.cpp +++ b/common/JackEngineControl.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. */ @@ -33,39 +33,39 @@ static inline jack_time_t JACK_MAX(jack_time_t a, jack_time_t b) return (a < b) ? b : a; } -void JackEngineControl::CalcCPULoad(JackClientInterface** table, - JackGraphManager* manager, - jack_time_t cur_cycle_begin, +void JackEngineControl::CalcCPULoad(JackClientInterface** table, + JackGraphManager* manager, + jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end) { fPrevCycleTime = fCurCycleTime; fCurCycleTime = cur_cycle_begin; jack_time_t last_cycle_end = prev_cycle_end; - + // In Asynchronous mode, last cycle end is the max of client end dates if (!fSyncMode) { for (int i = fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; JackClientTiming* timing = manager->GetClientTiming(i); - if (client && client->GetClientControl()->fActive && timing->fStatus == Finished) + if (client && client->GetClientControl()->fActive && timing->fStatus == Finished) last_cycle_end = JACK_MAX(last_cycle_end, timing->fFinishedAt); } } - // Store the execution time for later averaging + // Store the execution time for later averaging fRollingClientUsecs[fRollingClientUsecsIndex++] = last_cycle_end - fPrevCycleTime; - if (fRollingClientUsecsIndex >= JACK_ENGINE_ROLLING_COUNT) + if (fRollingClientUsecsIndex >= JACK_ENGINE_ROLLING_COUNT) fRollingClientUsecsIndex = 0; - + // Every so often, recompute the current maximum use over the // last JACK_ENGINE_ROLLING_COUNT client iterations. - + if (++fRollingClientUsecsCnt % fRollingInterval == 0) { jack_time_t max_usecs = 0; - for (int i = 0; i < JACK_ENGINE_ROLLING_COUNT; i++) + for (int i = 0; i < JACK_ENGINE_ROLLING_COUNT; i++) max_usecs = JACK_MAX(fRollingClientUsecs[i], max_usecs); - + fMaxUsecs = JACK_MAX(fMaxUsecs, max_usecs); fSpareUsecs = jack_time_t((max_usecs < fPeriodUsecs) ? fPeriodUsecs - max_usecs : 0); fCPULoad = ((1.f - (float(fSpareUsecs) / float(fPeriodUsecs))) * 50.f + (fCPULoad * 0.5f)); @@ -80,7 +80,7 @@ void JackEngineControl::ResetRollingUsecs() fSpareUsecs = 0; fRollingInterval = int(floor((JACK_ENGINE_ROLLING_INTERVAL * 1000.f) / fPeriodUsecs)); } - + void JackEngineControl::NotifyXRun(jack_time_t callback_usecs, float delayed_usecs) { ResetFrameTime(callback_usecs); @@ -88,5 +88,5 @@ void JackEngineControl::NotifyXRun(jack_time_t callback_usecs, float delayed_use if (delayed_usecs > fMaxDelayedUsecs) fMaxDelayedUsecs = delayed_usecs; } - + } // end of namespace diff --git a/common/JackError.h b/common/JackError.h index 425266f9..15e39f86 100644 --- a/common/JackError.h +++ b/common/JackError.h @@ -7,12 +7,12 @@ it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 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 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. @@ -25,7 +25,6 @@ #include #include #include "JackCompilerDeps.h" -#include "types.h" #ifdef __cplusplus extern "C" @@ -44,17 +43,17 @@ extern "C" EXPORT extern void (*jack_error_callback)(const char *desc); EXPORT extern void (*jack_info_callback)(const char *desc); - + EXPORT extern void default_jack_error_callback(const char *desc); EXPORT extern void default_jack_info_callback(const char *desc); - + EXPORT extern void silent_jack_error_callback(const char *desc); EXPORT extern void silent_jack_info_callback(const char *desc); typedef void (* jack_log_function_t)(int level, const char *message); void jack_log_function(int level, const char *message); - + EXPORT int set_threaded_log_function(); #ifdef __cplusplus diff --git a/common/JackFrameTimer.h b/common/JackFrameTimer.h index aca70add..afac2f78 100644 --- a/common/JackFrameTimer.h +++ b/common/JackFrameTimer.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,9 +36,9 @@ class SERVER_EXPORT JackTimer { friend class JackFrameTimer; - - private: - + + private: + jack_nframes_t fFrames; jack_time_t fCurrentWakeup; jack_time_t fCurrentCallback; @@ -47,21 +47,21 @@ class SERVER_EXPORT JackTimer float fFilterCoefficient; /* set once, never altered */ bool fInitialized; - public: - + public: + JackTimer(); ~JackTimer() {} - + jack_nframes_t Time2Frames(jack_time_t time, jack_nframes_t buffer_size); jack_time_t Frames2Time(jack_nframes_t frames, jack_nframes_t buffer_size); jack_nframes_t FramesSinceCycleStart(jack_time_t cur_time, jack_nframes_t frames_rate); - + jack_nframes_t CurFrame() { return fFrames; } - + jack_time_t CurTime() { return fCurrentWakeup; @@ -75,7 +75,7 @@ class SERVER_EXPORT JackTimer class SERVER_EXPORT JackFrameTimer : public JackAtomicState { - + private: bool fFirstWakeUp; @@ -93,7 +93,7 @@ class SERVER_EXPORT JackFrameTimer : public JackAtomicState void ResetFrameTime(jack_nframes_t frames_rate, jack_time_t callback_usecs, jack_time_t period_usecs); void IncFrameTime(jack_nframes_t buffer_size, jack_time_t callback_usecs, jack_time_t period_usecs); void ReadFrameTime(JackTimer* timer); - + } POST_PACKED_STRUCTURE; diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index 1a92191c..451d8cce 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); @@ -127,6 +127,19 @@ int JackGraphManager::SuspendRefNum(JackClientControl* control, JackSynchro* tab return manager->SuspendRefNum(control, table, fClientTiming, usec); } +void JackGraphManager::TopologicalSort(std::vector& sorted) +{ + UInt16 cur_index; + UInt16 next_index; + + do { + cur_index = GetCurrentIndex(); + sorted.clear(); + ReadCurrentState()->TopologicalSort(sorted); + next_index = GetCurrentIndex(); + } while (cur_index != next_index); // Until a coherent state has been read +} + // Server void JackGraphManager::DirectConnect(int ref1, int ref2) { @@ -176,14 +189,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 +207,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 +233,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; */ @@ -245,7 +258,7 @@ int JackGraphManager::RequestMonitor(jack_port_id_t port_index, bool onoff) // C // Client jack_nframes_t JackGraphManager::ComputeTotalLatencyAux(jack_port_id_t port_index, jack_port_id_t src_port_index, JackConnectionManager* manager, int hop_count) { - const jack_int_t* connections = manager->GetConnections(port_index); + const jack_int_t* connections = ReadCurrentState()->GetConnections(port_index); jack_nframes_t max_latency = 0; jack_port_id_t dst_index; @@ -296,6 +309,46 @@ int JackGraphManager::ComputeTotalLatencies() return 0; } +void JackGraphManager::RecalculateLatencyAux(jack_port_id_t port_index, jack_latency_callback_mode_t mode) +{ + const jack_int_t* connections = ReadCurrentState()->GetConnections(port_index); + JackPort* port = GetPort(port_index); + jack_latency_range_t latency = { UINT32_MAX, 0 }; + jack_port_id_t dst_index; + + for (int i = 0; (i < CONNECTION_NUM_FOR_PORT) && ((dst_index = connections[i]) != EMPTY); i++) { + AssertPort(dst_index); + JackPort* dst_port = GetPort(dst_index); + jack_latency_range_t other_latency; + + dst_port->GetLatencyRange(mode, &other_latency); + + if (other_latency.max > latency.max) + latency.max = other_latency.max; + if (other_latency.min < latency.min) + latency.min = other_latency.min; + } + + if (latency.min == UINT32_MAX) + latency.min = 0; + + port->SetLatencyRange(mode, &latency); +} + +void JackGraphManager::RecalculateLatency(jack_port_id_t port_index, jack_latency_callback_mode_t mode) +{ + UInt16 cur_index; + UInt16 next_index; + + do { + cur_index = GetCurrentIndex(); + RecalculateLatencyAux(port_index, mode); + next_index = GetCurrentIndex(); + } while (cur_index != next_index); // Until a coherent state has been read + + jack_log("JackGraphManager::RecalculateLatency port_index = %ld", port_index); +} + // Server void JackGraphManager::SetBufferSize(jack_nframes_t buffer_size) { @@ -376,18 +429,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 +471,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 +758,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 +781,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 +804,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 +864,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..5db84209 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. */ @@ -29,14 +29,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackPlatformPlug.h" #include "JackSystemDeps.h" - namespace Jack { /*! \brief Graph manager: contains the connection manager and the port array. */ - + class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState { @@ -53,6 +52,7 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState float* GetBuffer(jack_port_id_t port_index); void* GetBufferAux(JackConnectionManager* manager, jack_port_id_t port_index, jack_nframes_t frames); jack_nframes_t ComputeTotalLatencyAux(jack_port_id_t port_index, jack_port_id_t src_port_index, JackConnectionManager* manager, int hop_count); + void RecalculateLatencyAux(jack_port_id_t port_index, jack_latency_callback_mode_t mode); public: @@ -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); @@ -74,10 +72,13 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState JackPort* GetPort(jack_port_id_t index); jack_port_id_t GetPort(const char* name); + int ComputeTotalLatency(jack_port_id_t port_index); int ComputeTotalLatencies(); + void RecalculateLatency(jack_port_id_t port_index, jack_latency_callback_mode_t mode); + 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); @@ -122,6 +123,7 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState void InitRefNum(int refnum); int ResumeRefNum(JackClientControl* control, JackSynchro* table); int SuspendRefNum(JackClientControl* control, JackSynchro* table, long usecs); + void TopologicalSort(std::vector& sorted); JackClientTiming* GetClientTiming(int refnum) { @@ -130,7 +132,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/JackInternalClientChannel.h b/common/JackInternalClientChannel.h index 8deb6b7b..6b0772ce 100644 --- a/common/JackInternalClientChannel.h +++ b/common/JackInternalClientChannel.h @@ -80,7 +80,6 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface { *result = fEngine->PortUnRegister(refnum, port_index); } - void PortConnect(int refnum, const char* src, const char* dst, int* result) { *result = fEngine->PortConnect(refnum, src, dst); @@ -89,7 +88,6 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface { *result = fEngine->PortDisconnect(refnum, src, dst); } - void PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result) { *result = fEngine->PortConnect(refnum, src, dst); @@ -111,10 +109,9 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface { *result = fServer->SetFreewheel(onoff); } - - void SessionNotify( int refnum, const char *target, jack_session_event_type_t type, const char *path, jack_session_command_t **result ) + void ComputeTotalLatencies(int* result) { - *result = NULL; + *result = fEngine->ComputeTotalLatencies(); } void ReleaseTimebase(int refnum, int* result) @@ -126,7 +123,7 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface { *result = fServer->SetTimebaseCallback(refnum, conditional); } - + void GetInternalClientName(int refnum, int int_ref, char* name_res, int* result) { *result = fEngine->GetInternalClientName(int_ref, name_res); @@ -139,7 +136,7 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result) { - *result = fServer->InternalClientLoad(client_name, so_name, objet_data, options, int_ref, uuid, status); + *result = fServer->InternalClientLoad(client_name, so_name, objet_data, options, int_ref, uuid, status); } void InternalClientUnload(int refnum, int int_ref, int* status, int* result) @@ -147,6 +144,12 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface *result = fEngine->InternalClientUnload(int_ref, status); } + void SessionNotify(int refnum, const char *target, jack_session_event_type_t type, const char *path, jack_session_command_t** result) + { + *result = NULL; + } + + }; } // end of namespace diff --git a/common/JackLockedEngine.h b/common/JackLockedEngine.h index b1620859..c311f57d 100644 --- a/common/JackLockedEngine.h +++ b/common/JackLockedEngine.h @@ -66,7 +66,7 @@ catch (...) { \brief Locked Engine, access to methods is serialized using a mutex. */ -class SERVER_EXPORT JackLockedEngine +class SERVER_EXPORT JackLockedEngine { private: @@ -94,7 +94,7 @@ class SERVER_EXPORT JackLockedEngine return fEngine.Close(); CATCH_EXCEPTION_RETURN } - + // Client management int ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status) { @@ -226,6 +226,14 @@ class SERVER_EXPORT JackLockedEngine CATCH_EXCEPTION_RETURN } + int ComputeTotalLatencies() + { + TRY_CALL + JackLock lock(&fEngine); + return fEngine.ComputeTotalLatencies(); + CATCH_EXCEPTION_RETURN + } + // Graph bool Process(jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end) { @@ -245,7 +253,7 @@ class SERVER_EXPORT JackLockedEngine // RT : no lock fEngine.NotifyXRun(refnum); } - + void NotifyGraphReorder() { TRY_CALL @@ -298,7 +306,7 @@ class SERVER_EXPORT JackLockedEngine return fEngine.GetClientRefNum(name); CATCH_EXCEPTION_RETURN } - + void NotifyQuit() { TRY_CALL @@ -314,7 +322,7 @@ class SERVER_EXPORT JackLockedEngine fEngine.SessionNotify(refnum, target, type, path, socket); CATCH_EXCEPTION } - + void SessionReply(int refnum) { TRY_CALL @@ -322,7 +330,7 @@ class SERVER_EXPORT JackLockedEngine fEngine.SessionReply(refnum); CATCH_EXCEPTION } - + void GetUUIDForClientName(const char *client_name, char *uuid_res, int *result) { TRY_CALL @@ -344,6 +352,14 @@ class SERVER_EXPORT JackLockedEngine fEngine.ReserveClientName(name, uuid, result); CATCH_EXCEPTION } + + void ClientHasSessionCallbackRequest(const char *name, int *result) + { + TRY_CALL + JackLock lock(&fEngine); + fEngine.ClientHasSessionCallbackRequest(name, result); + CATCH_EXCEPTION + } }; } // end of namespace diff --git a/common/JackMessageBuffer.cpp b/common/JackMessageBuffer.cpp index b9f28463..d867933d 100644 --- a/common/JackMessageBuffer.cpp +++ b/common/JackMessageBuffer.cpp @@ -2,19 +2,19 @@ * Copyright (C) 2004 Rui Nuno Capela, Steve Harris * Copyright (C) 2008 Nedko Arnaudov * Copyright (C) 2008 Grame - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 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 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. * */ @@ -34,7 +34,7 @@ JackMessageBuffer::JackMessageBuffer() JackMessageBuffer::~JackMessageBuffer() {} - + void JackMessageBuffer::Start() { fRunning = true; @@ -44,9 +44,9 @@ void JackMessageBuffer::Start() void JackMessageBuffer::Stop() { if (fOverruns > 0) { - jack_error("WARNING: %d message buffer overruns!", fOverruns); + jack_error("WARNING: %d message buffer overruns!", fOverruns); } else { - jack_log("no message buffer overruns"); + jack_log("no message buffer overruns"); } fGuard.Lock(); fRunning = false; @@ -55,7 +55,7 @@ void JackMessageBuffer::Stop() fThread.Stop(); Flush(); } - + void JackMessageBuffer::Flush() { while (fOutBuffer != fInBuffer) { @@ -76,7 +76,7 @@ void JackMessageBuffer::AddMessage(int level, const char *message) INC_ATOMIC(&fOverruns); } } - + bool JackMessageBuffer::Execute() { while (fRunning) { @@ -94,10 +94,10 @@ bool JackMessageBuffer::Execute() Flush(); fGuard.Unlock(); } - return false; + return false; } -void JackMessageBuffer::Create() +void JackMessageBuffer::Create() { if (fInstance == NULL) { fInstance = new JackMessageBuffer(); @@ -105,7 +105,7 @@ void JackMessageBuffer::Create() } } -void JackMessageBuffer::Destroy() +void JackMessageBuffer::Destroy() { if (fInstance != NULL) { fInstance->Stop(); @@ -114,7 +114,7 @@ void JackMessageBuffer::Destroy() } } -void JackMessageBufferAdd(int level, const char *message) +void JackMessageBufferAdd(int level, const char *message) { if (Jack::JackMessageBuffer::fInstance == NULL) { /* Unable to print message with realtime safety. Complain and print it anyway. */ @@ -137,7 +137,6 @@ void JackMessageBuffer::SetInitCallback(JackThreadInitCallback callback, void *a /* and we're done */ fGuard.Unlock(); } - }; diff --git a/common/JackMidiPort.cpp b/common/JackMidiPort.cpp index fb933c85..117b7a70 100644 --- a/common/JackMidiPort.cpp +++ b/common/JackMidiPort.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. */ @@ -133,11 +133,17 @@ static void MidiBufferMixdown(void* mixbuffer, void** src_buffers, int src_count mix->lost_events += event_count - events_done; } +static size_t MidiBufferSize() +{ + return BUFFER_SIZE_MAX * sizeof(float); +} + const JackPortType gMidiPortType = - { - JACK_DEFAULT_MIDI_TYPE, - MidiBufferInit, - MidiBufferMixdown - }; +{ + JACK_DEFAULT_MIDI_TYPE, + MidiBufferSize, + MidiBufferInit, + MidiBufferMixdown +}; } // namespace Jack diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index 5f36c3f9..f587411d 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -118,10 +118,10 @@ namespace Jack //init and restart-------------------------------------------------------------------- /* - JackNetDriver is wrapped in a JackWaitThreadedDriver decorator that behaves + JackNetDriver is wrapped in a JackWaitThreadedDriver decorator that behaves as a "dummy driver, until Init method returns. */ - + bool JackNetDriver::Initialize() { jack_log("JackNetDriver::Initialize()"); @@ -221,7 +221,7 @@ namespace Jack void JackNetDriver::FreeAll() { FreePorts(); - + delete[] fTxBuffer; delete[] fRxBuffer; delete fNetAudioCaptureBuffer; @@ -230,7 +230,7 @@ namespace Jack delete fNetMidiPlaybackBuffer; delete[] fMidiCapturePortList; delete[] fMidiPlaybackPortList; - + fTxBuffer = NULL; fRxBuffer = NULL; fNetAudioCaptureBuffer = NULL; @@ -239,7 +239,7 @@ namespace Jack fNetMidiPlaybackBuffer = NULL; fMidiCapturePortList = NULL; fMidiPlaybackPortList = NULL; - + #ifdef JACK_MONITOR delete fNetTimeMon; fNetTimeMon = NULL; @@ -258,6 +258,7 @@ namespace Jack unsigned long port_flags; int audio_port_index; uint midi_port_index; + jack_latency_range_t range; //audio port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; @@ -274,7 +275,8 @@ namespace Jack port = fGraphManager->GetPort ( port_id ); port->SetAlias ( alias ); //port latency - port->SetLatency ( fEngineControl->fBufferSize ); + range.min = range.max = fEngineControl->fBufferSize; + port->SetLatencyRange(JackCaptureLatency, &range); fCapturePortList[audio_port_index] = port_id; jack_log ( "JackNetDriver::AllocPorts() fCapturePortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_id, port->GetLatency() ); } @@ -295,15 +297,16 @@ namespace Jack switch ( fParams.fNetworkMode ) { case 'f' : - port->SetLatency ( ( fEngineControl->fSyncMode ) ? 0 : fEngineControl->fBufferSize ); + range.min = range.max = (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize; break; case 'n' : - port->SetLatency ( fEngineControl->fBufferSize + ( fEngineControl->fSyncMode ) ? 0 : fEngineControl->fBufferSize ); + range.min = range.max = (fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize); break; case 's' : - port->SetLatency ( 2 * fEngineControl->fBufferSize + ( fEngineControl->fSyncMode ) ? 0 : fEngineControl->fBufferSize ); + range.min = range.max = (2 * fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize); break; } + port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[audio_port_index] = port_id; jack_log ( "JackNetDriver::AllocPorts() fPlaybackPortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_id, port->GetLatency() ); } @@ -321,7 +324,8 @@ namespace Jack } port = fGraphManager->GetPort ( port_id ); //port latency - port->SetLatency ( fEngineControl->fBufferSize ); + range.min = range.max = fEngineControl->fBufferSize; + port->SetLatencyRange(JackCaptureLatency, &range); fMidiCapturePortList[midi_port_index] = port_id; jack_log ( "JackNetDriver::AllocPorts() fMidiCapturePortList[%d] midi_port_index = %ld fPortLatency = %ld", midi_port_index, port_id, port->GetLatency() ); } @@ -342,15 +346,16 @@ namespace Jack switch ( fParams.fNetworkMode ) { case 'f' : - port->SetLatency ( ( fEngineControl->fSyncMode ) ? 0 : fEngineControl->fBufferSize ); + range.min = range.max = (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize; break; case 'n' : - port->SetLatency ( fEngineControl->fBufferSize + ( fEngineControl->fSyncMode ) ? 0 : fEngineControl->fBufferSize ) ; + range.min = range.max = (fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize); break; case 's' : - port->SetLatency ( 2 * fEngineControl->fBufferSize + ( fEngineControl->fSyncMode ) ? 0 : fEngineControl->fBufferSize ); + range.min = range.max = (2 * fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize); break; } + port->SetLatencyRange(JackPlaybackLatency, &range); fMidiPlaybackPortList[midi_port_index] = port_id; jack_log ( "JackNetDriver::AllocPorts() fMidiPlaybackPortList[%d] midi_port_index = %ld fPortLatency = %ld", midi_port_index, port_id, port->GetLatency() ); } @@ -409,7 +414,7 @@ namespace Jack //is there a transport state change to handle ? if ( fSendTransportData.fNewState && ( fSendTransportData.fState != fEngineControl->fTransport.GetState() ) ) { - + switch ( fSendTransportData.fState ) { case JackTransportStopped : @@ -458,13 +463,13 @@ namespace Jack else fReturnTransportData.fTimebaseMaster = NO_CHANGE; */ - + //update transport state and position fReturnTransportData.fState = fEngineControl->fTransport.Query ( &fReturnTransportData.fPosition ); - + //is it a new state (that the master need to know...) ? fReturnTransportData.fNewState = (( fReturnTransportData.fState == JackTransportNetStarting) && - ( fReturnTransportData.fState != fLastTransportState ) && + ( fReturnTransportData.fState != fLastTransportState ) && ( fReturnTransportData.fState != fSendTransportData.fState ) ); if ( fReturnTransportData.fNewState ) jack_info ( "Sending '%s'.", GetTransportState ( fReturnTransportData.fState ) ); @@ -492,14 +497,14 @@ namespace Jack return 0; #ifdef JACK_MONITOR - // For timing + // For timing fRcvSyncUst = GetMicroSeconds(); #endif //decode sync //if there is an error, don't return -1, it will skip Write() and the network error probably won't be identified DecodeSyncPacket(); - + #ifdef JACK_MONITOR fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - fRcvSyncUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); #endif @@ -534,7 +539,7 @@ namespace Jack //sync EncodeSyncPacket(); - + //send sync if ( SyncSend() == SOCKET_ERROR ) return SOCKET_ERROR; diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index 123c513a..fbe8aef1 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -134,7 +134,7 @@ namespace Jack if (jack_set_process_callback(fJackClient, SetProcess, this ) < 0) goto fail; - + if (jack_set_buffer_size_callback(fJackClient, SetBufferSize, this) < 0) goto fail; @@ -153,7 +153,7 @@ namespace Jack jack_error ( "Can't activate jack client." ); goto fail; } - + if (auto_connect) ConnectPorts(); jack_info ( "New NetMaster started." ); @@ -172,7 +172,8 @@ namespace Jack uint i; char name[24]; jack_nframes_t port_latency = jack_get_buffer_size ( fJackClient ); - + jack_latency_range_t range; + jack_log ( "JackNetMaster::AllocPorts" ); //audio @@ -182,9 +183,10 @@ namespace Jack if ( ( fAudioCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput | JackPortIsTerminal, 0 ) ) == NULL ) return -1; //port latency - jack_port_set_latency ( fAudioCapturePorts[i], 0 ); + range.min = range.max = 0; + jack_port_set_latency_range(fAudioCapturePorts[i], JackCaptureLatency, &range); } - + for ( i = 0; i < fParams.fReturnAudioChannels; i++ ) { sprintf ( name, "from_slave_%d", i+1 ); @@ -194,17 +196,20 @@ namespace Jack switch ( fParams.fNetworkMode ) { case 'f' : - jack_port_set_latency ( fAudioPlaybackPorts[i], ( fParams.fSlaveSyncMode ) ? 0 : port_latency ); + range.min = range.max = (fParams.fSlaveSyncMode) ? 0 : port_latency; + jack_port_set_latency_range(fAudioPlaybackPorts[i], JackPlaybackLatency, &range); break; case 'n' : - jack_port_set_latency ( fAudioPlaybackPorts[i], port_latency + ( fParams.fSlaveSyncMode ) ? 0 : port_latency ); + range.min = range.max = port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency; + jack_port_set_latency_range(fAudioPlaybackPorts[i], JackPlaybackLatency, &range); break; case 's' : - jack_port_set_latency ( fAudioPlaybackPorts[i], 2 * port_latency + ( fParams.fSlaveSyncMode ) ? 0 : port_latency ); + range.min = range.max = 2 * port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency; + jack_port_set_latency_range(fAudioPlaybackPorts[i], JackPlaybackLatency, &range); break; } } - + //midi for ( i = 0; i < fParams.fSendMidiChannels; i++ ) { @@ -212,7 +217,8 @@ namespace Jack if ( ( fMidiCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput | JackPortIsTerminal, 0 ) ) == NULL ) return -1; //port latency - jack_port_set_latency ( fMidiCapturePorts[i], 0 ); + range.min = range.max = 0; + jack_port_set_latency_range(fMidiCapturePorts[i], JackCaptureLatency, &range); } for ( i = 0; i < fParams.fReturnMidiChannels; i++ ) { @@ -223,23 +229,26 @@ namespace Jack switch ( fParams.fNetworkMode ) { case 'f' : - jack_port_set_latency ( fMidiPlaybackPorts[i], ( fParams.fSlaveSyncMode ) ? 0 : port_latency ); + range.min = range.max = (fParams.fSlaveSyncMode) ? 0 : port_latency; + jack_port_set_latency_range(fMidiPlaybackPorts[i], JackPlaybackLatency, &range); break; case 'n' : - jack_port_set_latency ( fMidiPlaybackPorts[i], port_latency + ( fParams.fSlaveSyncMode ) ? 0 : port_latency ); + range.min = range.max = port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency; + jack_port_set_latency_range(fMidiPlaybackPorts[i], JackPlaybackLatency, &range); break; case 's' : - jack_port_set_latency ( fMidiPlaybackPorts[i], 2 * port_latency + ( fParams.fSlaveSyncMode ) ? 0 : port_latency ); + range.min = range.max = 2 * port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency; + jack_port_set_latency_range(fMidiPlaybackPorts[i], JackPlaybackLatency, &range); break; } } return 0; } - + void JackNetMaster::ConnectPorts() { const char **ports; - + ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); if (ports != NULL) { for (unsigned int i = 0; i < fParams.fSendAudioChannels && ports[i]; i++) { @@ -247,7 +256,7 @@ namespace Jack } free(ports); } - + ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput); if (ports != NULL) { for (unsigned int i = 0; i < fParams.fReturnAudioChannels && ports[i]; i++) { @@ -309,7 +318,7 @@ namespace Jack else jack_info ( "'%s' isn't the timebase master anymore.", fParams.fName ); break; - + case TIMEBASEMASTER : timebase = jack_set_timebase_callback ( fJackClient, 0, SetTimebaseCallback, this ); if ( timebase < 0 ) @@ -317,7 +326,7 @@ namespace Jack else jack_info ( "'%s' is the new timebase master.", fParams.fName ); break; - + case CONDITIONAL_TIMEBASEMASTER : timebase = jack_set_timebase_callback ( fJackClient, 1, SetTimebaseCallback, this ); if ( timebase != EBUSY ) @@ -340,18 +349,18 @@ namespace Jack jack_transport_stop ( fJackClient ); jack_info ( "'%s' stops transport.", fParams.fName ); break; - + case JackTransportStarting : if ( jack_transport_reposition ( fJackClient, &fReturnTransportData.fPosition ) == EINVAL ) jack_error ( "Can't set new position." ); jack_transport_start ( fJackClient ); jack_info ( "'%s' starts transport frame = %d", fParams.fName, fReturnTransportData.fPosition.frame); break; - + case JackTransportNetStarting : jack_info ( "'%s' is ready to roll..", fParams.fName ); break; - + case JackTransportRolling : jack_info ( "'%s' is rolling.", fParams.fName ); break; @@ -377,16 +386,19 @@ namespace Jack } //sync-------------------------------------------------------------------------------- - + bool JackNetMaster::IsSlaveReadyToRoll() { return ( fReturnTransportData.fState == JackTransportNetStarting ); } - - int JackNetMaster::SetBufferSize (jack_nframes_t nframes, void* arg) + + int JackNetMaster::SetBufferSize(jack_nframes_t nframes, void* arg) { - jack_error("Cannot handle bufer size change, so proxy will be removed..."); - static_cast ( arg )->Exit(); + JackNetMaster* obj = static_cast(arg); + if (nframes != obj->fParams.fPeriodSize) { + jack_error("Cannot handle bufer size change, so JackNetMaster proxy will be removed..."); + obj->Exit(); + } return 0; } @@ -424,10 +436,10 @@ namespace Jack fParams.fPeriodSize ) ) ); if (IsSynched()) { // only send if connection is "synched" - + //encode the first packet EncodeSyncPacket(); - + //send sync if ( SyncSend() == SOCKET_ERROR ) return SOCKET_ERROR; @@ -443,7 +455,7 @@ namespace Jack #ifdef JACK_MONITOR fNetTimeMon->Add ( ( ( ( float ) (GetMicroSeconds() - begin_time ) ) / ( float ) fPeriodUsecs ) * 100.f ); #endif - + } else { jack_error("Connection is not synched, skip cycle..."); } @@ -459,7 +471,7 @@ namespace Jack //decode sync DecodeSyncPacket(); - + //receive data res = DataRecv(); if ( ( res == 0 ) || ( res == SOCKET_ERROR ) ) @@ -498,11 +510,11 @@ namespace Jack else jack_error("Can't use multicast address %s, using default %s", param->value.ui, DEFAULT_MULTICAST_IP); break; - + case 'p': fSocket.SetPort ( param->value.ui ); break; - + case 'c': fAutoConnect = param->value.i; break; @@ -646,7 +658,7 @@ namespace Jack JackNetMaster* JackNetMasterManager::InitMaster ( session_params_t& params ) { jack_log ( "JackNetMasterManager::InitMaster, Slave : %s", params.fName ); - + //check MASTER <<==> SLAVE network protocol coherency if (params.fProtocolVersion != MASTER_PROTOCOL) { jack_error ( "Error : slave is running with a different protocol %s", params.fName ); @@ -740,7 +752,7 @@ extern "C" desc->params[i].value.i = DEFAULT_PORT; strcpy ( desc->params[i].short_desc, "UDP port" ); strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); - + i++; strcpy ( desc->params[i].name, "auto_connect" ); desc->params[i].character = 'c'; diff --git a/common/JackNetManager.h b/common/JackNetManager.h index 29c8386d..cbeaee9e 100644 --- a/common/JackNetManager.h +++ b/common/JackNetManager.h @@ -54,7 +54,7 @@ namespace Jack //sync and transport int fLastTransportState; - + //monitoring #ifdef JACK_MONITOR jack_time_t fPeriodUsecs; @@ -64,7 +64,7 @@ namespace Jack bool Init(bool auto_connect); int AllocPorts(); void FreePorts(); - + //transport void EncodeTransportData(); void DecodeTransportData(); @@ -98,7 +98,7 @@ namespace Jack const char* fManagerName; char fMulticastIP[32]; JackNetSocket fSocket; - pthread_t fManagerThread; + jack_native_thread_t fManagerThread; master_list_t fMasterList; uint32_t fGlobalID; bool fRunning; diff --git a/common/JackNetOneDriver.cpp b/common/JackNetOneDriver.cpp index 4364606b..5b1b8cdd 100644 --- a/common/JackNetOneDriver.cpp +++ b/common/JackNetOneDriver.cpp @@ -46,10 +46,10 @@ using namespace std; namespace Jack { JackNetOneDriver::JackNetOneDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, - int port, int mtu, int capture_ports, int playback_ports, int midi_input_ports, int midi_output_ports, - int sample_rate, int period_size, int resample_factor, - const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig, - int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val ) + int port, int mtu, int capture_ports, int playback_ports, int midi_input_ports, int midi_output_ports, + int sample_rate, int period_size, int resample_factor, + const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig, + int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val ) : JackAudioDriver ( name, alias, engine, table ) { jack_log ( "JackNetOneDriver::JackNetOneDriver port %d", port ); @@ -157,23 +157,23 @@ namespace Jack jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); if( netj.bitdepth == CELT_MODE ) { - #if HAVE_CELT - #if HAVE_CELT_API_0_7 - celt_int32 lookahead; - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); - netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); - #else - celt_int32_t lookahead; - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); - netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode ) ); - #endif - celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); - netj.codec_latency = 2*lookahead; - #endif + #if HAVE_CELT + #if HAVE_CELT_API_0_7 + celt_int32 lookahead; + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); + netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); + #else + celt_int32_t lookahead; + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); + netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode ) ); + #endif + celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); + netj.codec_latency = 2*lookahead; + #endif } else { - #if HAVE_SAMPLERATE - netj.capture_srcs = jack_slist_append(netj.capture_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); - #endif + #if HAVE_SAMPLERATE + netj.capture_srcs = jack_slist_append(netj.capture_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); + #endif } } for (chn = netj.capture_channels_audio; chn < netj.capture_channels; chn++) { @@ -206,19 +206,19 @@ namespace Jack jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); if( netj.bitdepth == CELT_MODE ) { - #if HAVE_CELT - #if HAVE_CELT_API_0_7 - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); - netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); - #else - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); - netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode ) ); - #endif - #endif - } else { - #if HAVE_SAMPLERATE - netj.playback_srcs = jack_slist_append(netj.playback_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); - #endif + #if HAVE_CELT + #if HAVE_CELT_API_0_7 + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); + netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); + #else + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); + netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode ) ); + #endif + #endif + } else { + #if HAVE_SAMPLERATE + netj.playback_srcs = jack_slist_append(netj.playback_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); + #endif } } for (chn = netj.playback_channels_audio; chn < netj.playback_channels; chn++) { @@ -243,10 +243,8 @@ namespace Jack { jack_log ( "JackNetOneDriver::Init()" ); - if( global_packcache != NULL ) { - FreePorts(); - netjack_release( &netj ); - } + FreePorts(); + netjack_release( &netj ); //display some additional infos jack_info ( "NetOne driver started" ); @@ -330,63 +328,64 @@ namespace Jack // Now check if we have to start or stop local transport to sync to remote... switch (pkthdr->transport_state) { - case JackTransportStarting: - // the master transport is starting... so we set our reply to the sync_callback; - if (local_trans_state == JackTransportStopped) { - fEngineControl->fTransport.SetCommand ( TransportCommandStart ); - //jack_transport_start(netj.client); - //last_transport_state = JackTransportStopped; - netj.sync_state = 0; - jack_info("locally stopped... starting..."); - } - if (local_trans_pos.frame != compensated_tranport_pos) - { - jack_position_t new_pos = local_trans_pos; - new_pos.frame = compensated_tranport_pos + 2*netj.period_size; - new_pos.valid = (jack_position_bits_t) 0; + case JackTransportStarting: + // the master transport is starting... so we set our reply to the sync_callback; + if (local_trans_state == JackTransportStopped) { + fEngineControl->fTransport.SetCommand ( TransportCommandStart ); + //jack_transport_start(netj.client); + //last_transport_state = JackTransportStopped; + netj.sync_state = 0; + jack_info("locally stopped... starting..."); + } + if (local_trans_pos.frame != compensated_tranport_pos) { + jack_position_t new_pos = local_trans_pos; + new_pos.frame = compensated_tranport_pos + 2*netj.period_size; + new_pos.valid = (jack_position_bits_t) 0; - fEngineControl->fTransport.RequestNewPos ( &new_pos ); - //jack_transport_locate(netj.client, compensated_tranport_pos); - //last_transport_state = JackTransportRolling; - netj.sync_state = 0; - jack_info("starting locate to %d", compensated_tranport_pos ); - } - break; - case JackTransportStopped: - netj.sync_state = 1; - if (local_trans_pos.frame != (pkthdr->transport_frame)) { - jack_position_t new_pos = local_trans_pos; - new_pos.frame = pkthdr->transport_frame; - new_pos.valid = (jack_position_bits_t)0; - fEngineControl->fTransport.RequestNewPos ( &new_pos ); - //jack_transport_locate(netj.client, (pkthdr->transport_frame)); - jack_info("transport is stopped locate to %d", pkthdr->transport_frame); - } - if (local_trans_state != JackTransportStopped) - //jack_transport_stop(netj.client); - fEngineControl->fTransport.SetCommand ( TransportCommandStop ); - break; - case JackTransportRolling: - netj.sync_state = 1; - // if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * netj.period_size)) { - // jack_transport_locate(netj.client, (pkthdr->transport_frame + (pkthdr->latency + 2) * netj.period_size)); - // jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*netj.period_size); - // } - if (local_trans_state != JackTransportRolling) - fEngineControl->fTransport.SetState ( JackTransportRolling ); - - break; - - case JackTransportLooping: - break; + + fEngineControl->fTransport.RequestNewPos ( &new_pos ); + //jack_transport_locate(netj.client, compensated_tranport_pos); + //last_transport_state = JackTransportRolling; + netj.sync_state = 0; + jack_info("starting locate to %d", compensated_tranport_pos ); + } + break; + + case JackTransportStopped: + netj.sync_state = 1; + if (local_trans_pos.frame != (pkthdr->transport_frame)) { + jack_position_t new_pos = local_trans_pos; + new_pos.frame = pkthdr->transport_frame; + new_pos.valid = (jack_position_bits_t)0; + fEngineControl->fTransport.RequestNewPos ( &new_pos ); + //jack_transport_locate(netj.client, (pkthdr->transport_frame)); + jack_info("transport is stopped locate to %d", pkthdr->transport_frame); + } + if (local_trans_state != JackTransportStopped) + //jack_transport_stop(netj.client); + fEngineControl->fTransport.SetCommand ( TransportCommandStop ); + break; + + case JackTransportRolling: + netj.sync_state = 1; + // if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * netj.period_size)) { + // jack_transport_locate(netj.client, (pkthdr->transport_frame + (pkthdr->latency + 2) * netj.period_size)); + // jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*netj.period_size); + // } + if (local_trans_state != JackTransportRolling) + fEngineControl->fTransport.SetState ( JackTransportRolling ); + break; + + case JackTransportLooping: + break; } #endif } render_payload_to_jack_ports (netj.bitdepth, packet_bufX, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats ); - packet_cache_release_packet(global_packcache, netj.expected_framecnt ); + packet_cache_release_packet(netj.packcache, netj.expected_framecnt ); return 0; } @@ -419,12 +418,7 @@ namespace Jack if (netj.srcaddress_valid) { unsigned int r; - - #ifdef __APPLE__ static const int flag = 0; - #else - static const int flag = 0; - #endif if (netj.reply_port) netj.syncsource_address.sin_port = htons(netj.reply_port); @@ -436,690 +430,692 @@ namespace Jack return 0; } -void -JackNetOneDriver::FreePorts () -{ - JSList *node = netj.capture_ports; - - while( node != NULL ) { - JSList *this_node = node; - jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; - node = jack_slist_remove_link( node, this_node ); - jack_slist_free_1( this_node ); - fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); - } - netj.capture_ports = NULL; - - node = netj.playback_ports; - while( node != NULL ) { - JSList *this_node = node; - jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; - node = jack_slist_remove_link( node, this_node ); - jack_slist_free_1( this_node ); - fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); - } - netj.playback_ports = NULL; + void + JackNetOneDriver::FreePorts () + { + JSList *node = netj.capture_ports; + + while( node != NULL ) { + JSList *this_node = node; + jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); + } + netj.capture_ports = NULL; + + node = netj.playback_ports; + while( node != NULL ) { + JSList *this_node = node; + jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); + } + netj.playback_ports = NULL; - if( netj.bitdepth == CELT_MODE ) { -#if HAVE_CELT - node = netj.playback_srcs; - while( node != NULL ) { - JSList *this_node = node; - CELTEncoder *enc = (CELTEncoder *) node->data; - node = jack_slist_remove_link( node, this_node ); - jack_slist_free_1( this_node ); - celt_encoder_destroy( enc ); - } - netj.playback_srcs = NULL; - - node = netj.capture_srcs; - while( node != NULL ) { - JSList *this_node = node; - CELTDecoder *dec = (CELTDecoder *) node->data; - node = jack_slist_remove_link( node, this_node ); - jack_slist_free_1( this_node ); - celt_decoder_destroy( dec ); - } - netj.capture_srcs = NULL; -#endif - } else { -#if HAVE_SAMPLERATE - node = netj.playback_srcs; - while( node != NULL ) { - JSList *this_node = node; - SRC_STATE *state = (SRC_STATE *) node->data; - node = jack_slist_remove_link( node, this_node ); - jack_slist_free_1( this_node ); - src_delete( state ); - } - netj.playback_srcs = NULL; - - node = netj.capture_srcs; - while( node != NULL ) { - JSList *this_node = node; - SRC_STATE *state = (SRC_STATE *) node->data; - node = jack_slist_remove_link( node, this_node ); - jack_slist_free_1( this_node ); - src_delete( state ); - } - netj.capture_srcs = NULL; -#endif + if( netj.bitdepth == CELT_MODE ) { + #if HAVE_CELT + node = netj.playback_srcs; + while( node != NULL ) { + JSList *this_node = node; + CELTEncoder *enc = (CELTEncoder *) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + celt_encoder_destroy( enc ); + } + netj.playback_srcs = NULL; + + node = netj.capture_srcs; + while( node != NULL ) { + JSList *this_node = node; + CELTDecoder *dec = (CELTDecoder *) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + celt_decoder_destroy( dec ); + } + netj.capture_srcs = NULL; + #endif + } else { + #if HAVE_SAMPLERATE + node = netj.playback_srcs; + while( node != NULL ) { + JSList *this_node = node; + SRC_STATE *state = (SRC_STATE *) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + src_delete( state ); + } + netj.playback_srcs = NULL; + + node = netj.capture_srcs; + while( node != NULL ) { + JSList *this_node = node; + SRC_STATE *state = (SRC_STATE *) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + src_delete( state ); + } + netj.capture_srcs = NULL; + #endif + } } -} + //Render functions-------------------------------------------------------------------- // render functions for float -void -JackNetOneDriver::render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) -{ - uint32_t chn = 0; - JSList *node = capture_ports; -#if HAVE_SAMPLERATE - JSList *src_node = capture_srcs; -#endif + void + JackNetOneDriver::render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) + { + uint32_t chn = 0; + JSList *node = capture_ports; + #if HAVE_SAMPLERATE + JSList *src_node = capture_srcs; + #endif - uint32_t *packet_bufX = (uint32_t *)packet_payload; + uint32_t *packet_bufX = (uint32_t *)packet_payload; - if( !packet_payload ) - return; + if( !packet_payload ) + return; - while (node != NULL) - { - unsigned int i; - int_float_t val; -#if HAVE_SAMPLERATE - SRC_DATA src; -#endif - jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; - JackPort *port = fGraphManager->GetPort( port_id ); + while (node != NULL) + { + unsigned int i; + int_float_t val; + #if HAVE_SAMPLERATE + SRC_DATA src; + #endif + jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; + JackPort *port = fGraphManager->GetPort( port_id ); - jack_default_audio_sample_t* buf = - (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); + jack_default_audio_sample_t* buf = + (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); - const char *porttype = port->GetType(); + const char *porttype = port->GetType(); - if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) - { -#if HAVE_SAMPLERATE - // audio port, resample if necessary - if (net_period_down != nframes) + if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) { - SRC_STATE *src_state = (SRC_STATE *)src_node->data; - for (i = 0; i < net_period_down; i++) + #if HAVE_SAMPLERATE + // audio port, resample if necessary + if (net_period_down != nframes) { - packet_bufX[i] = ntohl (packet_bufX[i]); - } + SRC_STATE *src_state = (SRC_STATE *)src_node->data; + for (i = 0; i < net_period_down; i++) + { + packet_bufX[i] = ntohl (packet_bufX[i]); + } - src.data_in = (float *) packet_bufX; - src.input_frames = net_period_down; + src.data_in = (float *) packet_bufX; + src.input_frames = net_period_down; - src.data_out = buf; - src.output_frames = nframes; + src.data_out = buf; + src.output_frames = nframes; - src.src_ratio = (float) nframes / (float) net_period_down; - src.end_of_input = 0; + src.src_ratio = (float) nframes / (float) net_period_down; + src.end_of_input = 0; - src_set_ratio (src_state, src.src_ratio); - src_process (src_state, &src); - src_node = jack_slist_next (src_node); - } - else -#endif - { - if( dont_htonl_floats ) - { - memcpy( buf, packet_bufX, net_period_down*sizeof(jack_default_audio_sample_t)); + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); + src_node = jack_slist_next (src_node); } else + #endif { - for (i = 0; i < net_period_down; i++) + if( dont_htonl_floats ) + { + memcpy( buf, packet_bufX, net_period_down*sizeof(jack_default_audio_sample_t)); + } + else { - val.i = packet_bufX[i]; - val.i = ntohl (val.i); - buf[i] = val.f; + for (i = 0; i < net_period_down; i++) + { + val.i = packet_bufX[i]; + val.i = ntohl (val.i); + buf[i] = val.f; + } } } } + else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) + { + // midi port, decode midi events + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_down; + uint32_t * buffer_uint32 = (uint32_t*)packet_bufX; + decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_down); + node = jack_slist_next (node); + chn++; } - else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) - { - // midi port, decode midi events - // convert the data buffer to a standard format (uint32_t based) - unsigned int buffer_size_uint32 = net_period_down; - uint32_t * buffer_uint32 = (uint32_t*)packet_bufX; - decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); - } - packet_bufX = (packet_bufX + net_period_down); - node = jack_slist_next (node); - chn++; - } } -void -JackNetOneDriver::render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ) -{ - uint32_t chn = 0; - JSList *node = playback_ports; -#if HAVE_SAMPLERATE - JSList *src_node = playback_srcs; -#endif + void + JackNetOneDriver::render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ) + { + uint32_t chn = 0; + JSList *node = playback_ports; + #if HAVE_SAMPLERATE + JSList *src_node = playback_srcs; + #endif - uint32_t *packet_bufX = (uint32_t *) packet_payload; + uint32_t *packet_bufX = (uint32_t *) packet_payload; - while (node != NULL) - { -#if HAVE_SAMPLERATE - SRC_DATA src; -#endif - unsigned int i; - int_float_t val; - jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; - JackPort *port = fGraphManager->GetPort( port_id ); + while (node != NULL) + { + #if HAVE_SAMPLERATE + SRC_DATA src; + #endif + unsigned int i; + int_float_t val; + jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; + JackPort *port = fGraphManager->GetPort( port_id ); - jack_default_audio_sample_t* buf = - (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); + jack_default_audio_sample_t* buf = + (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); - const char *porttype = port->GetType(); + const char *porttype = port->GetType(); - if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) - { - // audio port, resample if necessary + if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) + { + // audio port, resample if necessary -#if HAVE_SAMPLERATE - if (net_period_up != nframes) { - SRC_STATE *src_state = (SRC_STATE *) src_node->data; - src.data_in = buf; - src.input_frames = nframes; + #if HAVE_SAMPLERATE + if (net_period_up != nframes) { + SRC_STATE *src_state = (SRC_STATE *) src_node->data; + src.data_in = buf; + src.input_frames = nframes; - src.data_out = (float *) packet_bufX; - src.output_frames = net_period_up; + src.data_out = (float *) packet_bufX; + src.output_frames = net_period_up; - src.src_ratio = (float) net_period_up / (float) nframes; - src.end_of_input = 0; + src.src_ratio = (float) net_period_up / (float) nframes; + src.end_of_input = 0; - src_set_ratio (src_state, src.src_ratio); - src_process (src_state, &src); + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); - for (i = 0; i < net_period_up; i++) - { - packet_bufX[i] = htonl (packet_bufX[i]); - } - src_node = jack_slist_next (src_node); - } - else -#endif - { - if( dont_htonl_floats ) - { - memcpy( packet_bufX, buf, net_period_up*sizeof(jack_default_audio_sample_t) ); + for (i = 0; i < net_period_up; i++) + { + packet_bufX[i] = htonl (packet_bufX[i]); + } + src_node = jack_slist_next (src_node); } else + #endif { - for (i = 0; i < net_period_up; i++) + if( dont_htonl_floats ) + { + memcpy( packet_bufX, buf, net_period_up*sizeof(jack_default_audio_sample_t) ); + } + else { - val.f = buf[i]; - val.i = htonl (val.i); - packet_bufX[i] = val.i; + for (i = 0; i < net_period_up; i++) + { + val.f = buf[i]; + val.i = htonl (val.i); + packet_bufX[i] = val.i; + } } } } + else if (strncmp(porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) + { + // encode midi events from port to packet + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_up; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_up); + node = jack_slist_next (node); + chn++; } - else if (strncmp(porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) - { - // encode midi events from port to packet - // convert the data buffer to a standard format (uint32_t based) - unsigned int buffer_size_uint32 = net_period_up; - uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; - encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); - } - packet_bufX = (packet_bufX + net_period_up); - node = jack_slist_next (node); - chn++; } -} -#if HAVE_CELT -// render functions for celt. -void -JackNetOneDriver::render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes) -{ - uint32_t chn = 0; - JSList *node = capture_ports; - JSList *src_node = capture_srcs; + #if HAVE_CELT + // render functions for celt. + void + JackNetOneDriver::render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes) + { + uint32_t chn = 0; + JSList *node = capture_ports; + JSList *src_node = capture_srcs; + unsigned char *packet_bufX = (unsigned char *)packet_payload; - unsigned char *packet_bufX = (unsigned char *)packet_payload; + while (node != NULL) + { + jack_port_id_t port_id = (jack_port_id_t) (intptr_t)node->data; + JackPort *port = fGraphManager->GetPort( port_id ); - while (node != NULL) - { - jack_port_id_t port_id = (jack_port_id_t) (intptr_t)node->data; - JackPort *port = fGraphManager->GetPort( port_id ); + jack_default_audio_sample_t* buf = + (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); - jack_default_audio_sample_t* buf = - (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); + const char *portname = port->GetType(); - const char *portname = port->GetType(); + if (strncmp(portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) + { + // audio port, decode celt data. + CELTDecoder *decoder = (CELTDecoder *)src_node->data; + if( !packet_payload ) + celt_decode_float( decoder, NULL, net_period_down, buf ); + else + celt_decode_float( decoder, packet_bufX, net_period_down, buf ); - if (strncmp(portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) - { - // audio port, decode celt data. - CELTDecoder *decoder = (CELTDecoder *)src_node->data; - if( !packet_payload ) - celt_decode_float( decoder, NULL, net_period_down, buf ); - else - celt_decode_float( decoder, packet_bufX, net_period_down, buf ); - - src_node = jack_slist_next (src_node); - } - else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) - { - // midi port, decode midi events - // convert the data buffer to a standard format (uint32_t based) - unsigned int buffer_size_uint32 = net_period_down / 2; - uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; - if( packet_payload ) - decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + src_node = jack_slist_next (src_node); + } + else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) + { + // midi port, decode midi events + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_down / 2; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + if( packet_payload ) + decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_down); + node = jack_slist_next (node); + chn++; } - packet_bufX = (packet_bufX + net_period_down); - node = jack_slist_next (node); - chn++; } -} -void -JackNetOneDriver::render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up) -{ - uint32_t chn = 0; - JSList *node = playback_ports; - JSList *src_node = playback_srcs; + void + JackNetOneDriver::render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up) + { + uint32_t chn = 0; + JSList *node = playback_ports; + JSList *src_node = playback_srcs; - unsigned char *packet_bufX = (unsigned char *)packet_payload; + unsigned char *packet_bufX = (unsigned char *)packet_payload; - while (node != NULL) - { - jack_port_id_t port_id = (jack_port_id_t) (intptr_t) node->data; - JackPort *port = fGraphManager->GetPort( port_id ); + while (node != NULL) + { + jack_port_id_t port_id = (jack_port_id_t) (intptr_t) node->data; + JackPort *port = fGraphManager->GetPort( port_id ); - jack_default_audio_sample_t* buf = - (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); + jack_default_audio_sample_t* buf = + (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); - const char *portname = port->GetType(); + const char *portname = port->GetType(); - if (strncmp (portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) - { - // audio port, encode celt data. - - int encoded_bytes; - float *floatbuf = (float *)alloca (sizeof(float) * nframes ); - memcpy( floatbuf, buf, nframes*sizeof(float) ); - CELTEncoder *encoder = (CELTEncoder *)src_node->data; - encoded_bytes = celt_encode_float( encoder, floatbuf, NULL, packet_bufX, net_period_up ); - if( encoded_bytes != (int)net_period_up ) - jack_error( "something in celt changed. netjack needs to be changed to handle this." ); - src_node = jack_slist_next( src_node ); - } - else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) - { - // encode midi events from port to packet - // convert the data buffer to a standard format (uint32_t based) - unsigned int buffer_size_uint32 = net_period_up / 2; - uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; - encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + if (strncmp (portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) + { + // audio port, encode celt data. + + int encoded_bytes; + float *floatbuf = (float *)alloca (sizeof(float) * nframes ); + memcpy( floatbuf, buf, nframes*sizeof(float) ); + CELTEncoder *encoder = (CELTEncoder *)src_node->data; + encoded_bytes = celt_encode_float( encoder, floatbuf, NULL, packet_bufX, net_period_up ); + if( encoded_bytes != (int)net_period_up ) + jack_error( "something in celt changed. netjack needs to be changed to handle this." ); + src_node = jack_slist_next( src_node ); + } + else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) + { + // encode midi events from port to packet + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_up / 2; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_up); + node = jack_slist_next (node); + chn++; } - packet_bufX = (packet_bufX + net_period_up); - node = jack_slist_next (node); - chn++; } -} -#endif -/* Wrapper functions with bitdepth argument... */ -void -JackNetOneDriver::render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) -{ -#if HAVE_CELT - if (bitdepth == CELT_MODE) - render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); - else -#endif - render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats); -} + #endif + /* Wrapper functions with bitdepth argument... */ + void + JackNetOneDriver::render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) + { + #if HAVE_CELT + if (bitdepth == CELT_MODE) + render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); + else + #endif + render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats); + } -void -JackNetOneDriver::render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats) -{ -#if HAVE_CELT - if (bitdepth == CELT_MODE) - render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); - else -#endif - render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats); -} + void + JackNetOneDriver::render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats) + { + #if HAVE_CELT + if (bitdepth == CELT_MODE) + render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); + else + #endif + render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats); + } -//driver loader----------------------------------------------------------------------- + //driver loader----------------------------------------------------------------------- -#ifdef __cplusplus - extern "C" - { -#endif - SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor () - { - jack_driver_desc_t* desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) ); - jack_driver_param_desc_t * params; - - strcpy ( desc->name, "netone" ); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 - strcpy ( desc->desc, "netjack one slave backend component" ); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - - desc->nparams = 18; - params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) ); - - int i = 0; - strcpy (params[i].name, "audio-ins"); - params[i].character = 'i'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 2U; - strcpy (params[i].short_desc, "Number of capture channels (defaults to 2)"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "audio-outs"); - params[i].character = 'o'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 2U; - strcpy (params[i].short_desc, "Number of playback channels (defaults to 2)"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "midi-ins"); - params[i].character = 'I'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 1U; - strcpy (params[i].short_desc, "Number of midi capture channels (defaults to 1)"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "midi-outs"); - params[i].character = 'O'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 1U; - strcpy (params[i].short_desc, "Number of midi playback channels (defaults to 1)"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "rate"); - params[i].character = 'r'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 48000U; - strcpy (params[i].short_desc, "Sample rate"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "period"); - params[i].character = 'p'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 1024U; - strcpy (params[i].short_desc, "Frames per period"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "num-periods"); - params[i].character = 'n'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 5U; - strcpy (params[i].short_desc, - "Network latency setting in no. of periods"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "listen-port"); - params[i].character = 'l'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 3000U; - strcpy (params[i].short_desc, - "The socket port we are listening on for sync packets"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "factor"); - params[i].character = 'f'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 1U; - strcpy (params[i].short_desc, - "Factor for sample rate reduction"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "upstream-factor"); - params[i].character = 'u'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 0U; - strcpy (params[i].short_desc, - "Factor for sample rate reduction on the upstream"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "celt"); - params[i].character = 'c'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 0U; - strcpy (params[i].short_desc, - "sets celt encoding and number of kbits per channel"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "bit-depth"); - params[i].character = 'b'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 0U; - strcpy (params[i].short_desc, - "Sample bit-depth (0 for float, 8 for 8bit and 16 for 16bit)"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "transport-sync"); - params[i].character = 't'; - params[i].type = JackDriverParamBool; - params[i].value.ui = 1U; - strcpy (params[i].short_desc, - "Whether to slave the transport to the master transport"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "autoconf"); - params[i].character = 'a'; - params[i].type = JackDriverParamBool; - params[i].value.ui = 1U; - strcpy (params[i].short_desc, - "Whether to use Autoconfig, or just start."); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "redundancy"); - params[i].character = 'R'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 1U; - strcpy (params[i].short_desc, - "Send packets N times"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "native-endian"); - params[i].character = 'e'; - params[i].type = JackDriverParamBool; - params[i].value.ui = 0U; - strcpy (params[i].short_desc, - "Dont convert samples to network byte order."); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "jitterval"); - params[i].character = 'J'; - params[i].type = JackDriverParamInt; - params[i].value.i = 0; - strcpy (params[i].short_desc, - "attempted jitterbuffer microseconds on master"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "always-deadline"); - params[i].character = 'D'; - params[i].type = JackDriverParamBool; - params[i].value.ui = 0U; - strcpy (params[i].short_desc, - "always use deadline"); - strcpy (params[i].long_desc, params[i].short_desc); - - desc->params = params; - - return desc; - } - - SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize ( Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params ) + #ifdef __cplusplus + extern "C" { - jack_nframes_t sample_rate = 48000; - jack_nframes_t resample_factor = 1; - jack_nframes_t period_size = 1024; - unsigned int capture_ports = 2; - unsigned int playback_ports = 2; - unsigned int capture_ports_midi = 1; - unsigned int playback_ports_midi = 1; - unsigned int listen_port = 3000; - unsigned int bitdepth = 0; - unsigned int handle_transport_sync = 1; - unsigned int use_autoconfig = 1; - unsigned int latency = 5; - unsigned int redundancy = 1; - unsigned int mtu = 1400; - unsigned int resample_factor_up = 1; - int dont_htonl_floats = 0; - int always_deadline = 0; - int jitter_val = 0; - const JSList * node; - const jack_driver_param_t * param; - - for ( node = params; node; node = jack_slist_next ( node ) ) + #endif + SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor () + { + jack_driver_desc_t* desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) ); + jack_driver_param_desc_t * params; + + strcpy ( desc->name, "netone" ); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 + strcpy ( desc->desc, "netjack one slave backend component" ); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 + + desc->nparams = 18; + params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) ); + + int i = 0; + strcpy (params[i].name, "audio-ins"); + params[i].character = 'i'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 2U; + strcpy (params[i].short_desc, "Number of capture channels (defaults to 2)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "audio-outs"); + params[i].character = 'o'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 2U; + strcpy (params[i].short_desc, "Number of playback channels (defaults to 2)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "midi-ins"); + params[i].character = 'I'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, "Number of midi capture channels (defaults to 1)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "midi-outs"); + params[i].character = 'O'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, "Number of midi playback channels (defaults to 1)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "rate"); + params[i].character = 'r'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 48000U; + strcpy (params[i].short_desc, "Sample rate"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "period"); + params[i].character = 'p'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1024U; + strcpy (params[i].short_desc, "Frames per period"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "num-periods"); + params[i].character = 'n'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 5U; + strcpy (params[i].short_desc, + "Network latency setting in no. of periods"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "listen-port"); + params[i].character = 'l'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 3000U; + strcpy (params[i].short_desc, + "The socket port we are listening on for sync packets"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "factor"); + params[i].character = 'f'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, + "Factor for sample rate reduction"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "upstream-factor"); + params[i].character = 'u'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, + "Factor for sample rate reduction on the upstream"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "celt"); + params[i].character = 'c'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, + "sets celt encoding and number of kbits per channel"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "bit-depth"); + params[i].character = 'b'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, + "Sample bit-depth (0 for float, 8 for 8bit and 16 for 16bit)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "transport-sync"); + params[i].character = 't'; + params[i].type = JackDriverParamBool; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, + "Whether to slave the transport to the master transport"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "autoconf"); + params[i].character = 'a'; + params[i].type = JackDriverParamBool; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, + "Whether to use Autoconfig, or just start."); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "redundancy"); + params[i].character = 'R'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, + "Send packets N times"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "native-endian"); + params[i].character = 'e'; + params[i].type = JackDriverParamBool; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, + "Dont convert samples to network byte order."); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "jitterval"); + params[i].character = 'J'; + params[i].type = JackDriverParamInt; + params[i].value.i = 0; + strcpy (params[i].short_desc, + "attempted jitterbuffer microseconds on master"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "always-deadline"); + params[i].character = 'D'; + params[i].type = JackDriverParamBool; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, + "always use deadline"); + strcpy (params[i].long_desc, params[i].short_desc); + + desc->params = params; + + return desc; + } + + SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize ( Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params ) { - param = ( const jack_driver_param_t* ) node->data; - switch ( param->character ) + jack_nframes_t sample_rate = 48000; + jack_nframes_t resample_factor = 1; + jack_nframes_t period_size = 1024; + unsigned int capture_ports = 2; + unsigned int playback_ports = 2; + unsigned int capture_ports_midi = 1; + unsigned int playback_ports_midi = 1; + unsigned int listen_port = 3000; + unsigned int bitdepth = 0; + unsigned int handle_transport_sync = 1; + unsigned int use_autoconfig = 1; + unsigned int latency = 5; + unsigned int redundancy = 1; + unsigned int mtu = 1400; + #if HAVE_SAMPLERATE + unsigned int resample_factor_up = 1; + #endif + int dont_htonl_floats = 0; + int always_deadline = 0; + int jitter_val = 0; + const JSList * node; + const jack_driver_param_t * param; + + for ( node = params; node; node = jack_slist_next ( node ) ) { - case 'i': - capture_ports = param->value.ui; - break; - - case 'o': - playback_ports = param->value.ui; - break; - - case 'I': - capture_ports_midi = param->value.ui; - break; - - case 'O': - playback_ports_midi = param->value.ui; - break; - - case 'r': - sample_rate = param->value.ui; - break; - - case 'p': - period_size = param->value.ui; - break; - - case 'l': - listen_port = param->value.ui; - break; - - case 'f': - #if HAVE_SAMPLERATE - resample_factor = param->value.ui; - #else - jack_error( "not built with libsamplerate support" ); - return NULL; - #endif - break; - - case 'u': - #if HAVE_SAMPLERATE - resample_factor_up = param->value.ui; - #else - jack_error( "not built with libsamplerate support" ); - return NULL; - #endif - break; - - case 'b': - bitdepth = param->value.ui; - break; - - case 'c': - #if HAVE_CELT - bitdepth = CELT_MODE; - resample_factor = param->value.ui; - #else - jack_error( "not built with celt support" ); - return NULL; - #endif - break; + param = ( const jack_driver_param_t* ) node->data; + switch ( param->character ) + { + case 'i': + capture_ports = param->value.ui; + break; + + case 'o': + playback_ports = param->value.ui; + break; + + case 'I': + capture_ports_midi = param->value.ui; + break; + + case 'O': + playback_ports_midi = param->value.ui; + break; + + case 'r': + sample_rate = param->value.ui; + break; + + case 'p': + period_size = param->value.ui; + break; + + case 'l': + listen_port = param->value.ui; + break; + + case 'f': + #if HAVE_SAMPLERATE + resample_factor = param->value.ui; + #else + jack_error( "not built with libsamplerate support" ); + return NULL; + #endif + break; + + case 'u': + #if HAVE_SAMPLERATE + resample_factor_up = param->value.ui; + #else + jack_error( "not built with libsamplerate support" ); + return NULL; + #endif + break; + + case 'b': + bitdepth = param->value.ui; + break; + + case 'c': + #if HAVE_CELT + bitdepth = CELT_MODE; + resample_factor = param->value.ui; + #else + jack_error( "not built with celt support" ); + return NULL; + #endif + break; - case 't': - handle_transport_sync = param->value.ui; - break; + case 't': + handle_transport_sync = param->value.ui; + break; - case 'a': - use_autoconfig = param->value.ui; - break; + case 'a': + use_autoconfig = param->value.ui; + break; - case 'n': - latency = param->value.ui; - break; + case 'n': + latency = param->value.ui; + break; - case 'R': - redundancy = param->value.ui; - break; + case 'R': + redundancy = param->value.ui; + break; - case 'H': - dont_htonl_floats = param->value.ui; - break; + case 'H': + dont_htonl_floats = param->value.ui; + break; - case 'J': - jitter_val = param->value.i; - break; + case 'J': + jitter_val = param->value.i; + break; - case 'D': - always_deadline = param->value.ui; - break; + case 'D': + always_deadline = param->value.ui; + break; + } } - } - try - { - Jack::JackDriverClientInterface* driver = - new Jack::JackWaitThreadedDriver ( - new Jack::JackNetOneDriver ( "system", "net_pcm", engine, table, listen_port, mtu, - capture_ports_midi, playback_ports_midi, capture_ports, playback_ports, - sample_rate, period_size, resample_factor, - "net_pcm", handle_transport_sync, bitdepth, use_autoconfig, latency, redundancy, - dont_htonl_floats, always_deadline, jitter_val ) ); - - if ( driver->Open ( period_size, sample_rate, 1, 1, capture_ports, playback_ports, - 0, "from_master_", "to_master_", 0, 0 ) == 0 ) + try { - return driver; + Jack::JackDriverClientInterface* driver = + new Jack::JackWaitThreadedDriver ( + new Jack::JackNetOneDriver ( "system", "net_pcm", engine, table, listen_port, mtu, + capture_ports_midi, playback_ports_midi, capture_ports, playback_ports, + sample_rate, period_size, resample_factor, + "net_pcm", handle_transport_sync, bitdepth, use_autoconfig, latency, redundancy, + dont_htonl_floats, always_deadline, jitter_val ) ); + + if ( driver->Open ( period_size, sample_rate, 1, 1, capture_ports, playback_ports, + 0, "from_master_", "to_master_", 0, 0 ) == 0 ) + { + return driver; + } + else + { + delete driver; + return NULL; + } + } - else + catch ( ... ) { - delete driver; return NULL; } - } - catch ( ... ) - { - return NULL; - } - } -#ifdef __cplusplus - } -#endif + #ifdef __cplusplus + } + #endif } diff --git a/common/JackNetOneDriver.h b/common/JackNetOneDriver.h index b288c91f..348b4628 100644 --- a/common/JackNetOneDriver.h +++ b/common/JackNetOneDriver.h @@ -34,45 +34,47 @@ namespace Jack class JackNetOneDriver : public JackAudioDriver { private: - netjack_driver_state_t netj; - -void -render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats); -void -render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ); -#ifdef HAVE_CELT -void -render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes); -void -render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up); -#endif -void -render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats); -void -render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats); + + netjack_driver_state_t netj; + + void + render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats); + void + render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ); + #ifdef HAVE_CELT + void + render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes); + void + render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up); + #endif + void + render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats); + void + render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats); public: - JackNetOneDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, - int port, int mtu, int capture_ports, int playback_ports, int midi_input_ports, int midi_output_ports, - int sample_rate, int period_size, int resample_factor, - const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig, - int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val ); - ~JackNetOneDriver(); + + JackNetOneDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, + int port, int mtu, int capture_ports, int playback_ports, int midi_input_ports, int midi_output_ports, + int sample_rate, int period_size, int resample_factor, + const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig, + int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val ); + ~JackNetOneDriver(); int Open ( jack_nframes_t frames_per_cycle, jack_nframes_t rate, bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency ); - int Close(); + int Close(); int Attach(); int Detach(); int Read(); int Write(); - bool Initialize(); - int AllocPorts(); - void FreePorts(); + bool Initialize(); + int AllocPorts(); + void FreePorts(); // BufferSize can't be changed bool IsFixedBufferSize() diff --git a/common/JackNotification.h b/common/JackNotification.h index bca178af..673ab838 100644 --- a/common/JackNotification.h +++ b/common/JackNotification.h @@ -12,7 +12,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. */ @@ -46,6 +46,7 @@ enum NotificationType { kShutDownCallback = 15, kQUIT = 16, kSessionCallback = 17, + kLatencyCallback = 18, kMaxNotification }; diff --git a/common/JackPort.cpp b/common/JackPort.cpp index f8c62d67..e3dd12f6 100644 --- a/common/JackPort.cpp +++ b/common/JackPort.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. */ @@ -44,6 +44,8 @@ bool JackPort::Allocate(int refnum, const char* port_name, const char* port_type fInUse = true; fLatency = 0; fTotalLatency = 0; + fPlaybackLatency.min = fPlaybackLatency.max = 0; + fCaptureLatency.min = fCaptureLatency.max = 0; fTied = NO_PORT; // DB: At this point we do not know current buffer size in frames, // but every time buffer will be returned to any user, @@ -86,6 +88,48 @@ jack_nframes_t JackPort::GetTotalLatency() const void JackPort::SetLatency(jack_nframes_t nframes) { fLatency = nframes; + + /* setup the new latency values here, + * so we dont need to change the backend codes. + */ + if (fFlags & JackPortIsOutput) { + fCaptureLatency.min = nframes; + fCaptureLatency.max = nframes; + } + if (fFlags & JackPortIsInput) { + fPlaybackLatency.min = nframes; + fPlaybackLatency.max = nframes; + } +} + +void JackPort::SetLatencyRange(jack_latency_callback_mode_t mode, jack_latency_range_t* range) +{ + if (mode == JackCaptureLatency) { + fCaptureLatency = *range; + + /* hack to set port->shared->latency up for + * backend ports + */ + if ((fFlags & JackPortIsOutput) && (fFlags & JackPortIsPhysical)) + fLatency = (range->min + range->max) / 2; + } else { + fPlaybackLatency = *range; + + /* hack to set port->shared->latency up for + * backend ports + */ + if ((fFlags & JackPortIsInput) && (fFlags & JackPortIsPhysical)) + fLatency = (range->min + range->max) / 2; + } +} + +void JackPort::GetLatencyRange(jack_latency_callback_mode_t mode, jack_latency_range_t* range) const +{ + if (mode == JackCaptureLatency) { + *range = fCaptureLatency; + } else { + *range = fPlaybackLatency; + } } int JackPort::Tie(jack_port_id_t port_index) @@ -103,10 +147,10 @@ int JackPort::UnTie() int JackPort::RequestMonitor(bool onoff) { /** - 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; */ @@ -123,10 +167,10 @@ int JackPort::RequestMonitor(bool onoff) int JackPort::EnsureMonitor(bool onoff) { /** - 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; */ @@ -165,7 +209,7 @@ int JackPort::GetFlags() const const char* JackPort::GetType() const { const JackPortType* type = GetPortType(fTypeId); - return type->name; + return type->fName; } void JackPort::SetName(const char* new_name) diff --git a/common/JackPort.h b/common/JackPort.h index 45f90733..758e402b 100644 --- a/common/JackPort.h +++ b/common/JackPort.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. */ @@ -51,12 +51,14 @@ class SERVER_EXPORT JackPort jack_nframes_t fLatency; jack_nframes_t fTotalLatency; + jack_latency_range_t fPlaybackLatency; + jack_latency_range_t fCaptureLatency; uint8_t fMonitorRequests; bool fInUse; jack_port_id_t fTied; // Locally tied source port float fBuffer[BUFFER_SIZE_MAX + 4]; - + bool IsUsed() const { return fInUse; @@ -88,9 +90,13 @@ class SERVER_EXPORT JackPort int UnTie(); jack_nframes_t GetLatency() const; - jack_nframes_t GetTotalLatency() const; void SetLatency(jack_nframes_t latency); + void SetLatencyRange(jack_latency_callback_mode_t mode, jack_latency_range_t* range); + void GetLatencyRange(jack_latency_callback_mode_t mode, jack_latency_range_t* range) const; + + jack_nframes_t GetTotalLatency() const; + int RequestMonitor(bool onoff); int EnsureMonitor(bool onoff); bool MonitoringInput() @@ -105,7 +111,7 @@ class SERVER_EXPORT JackPort } int GetRefNum() const; - + } POST_PACKED_STRUCTURE; } // end of namespace diff --git a/common/JackPortType.cpp b/common/JackPortType.cpp index 7f720805..d2150562 100644 --- a/common/JackPortType.cpp +++ b/common/JackPortType.cpp @@ -12,7 +12,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. */ @@ -24,20 +24,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -static const JackPortType* port_types[] = +static const JackPortType* gPortTypes[] = { &gAudioPortType, &gMidiPortType, }; -jack_port_type_id_t PORT_TYPES_MAX = sizeof(port_types) / sizeof(port_types[0]); +jack_port_type_id_t PORT_TYPES_MAX = sizeof(gPortTypes) / sizeof(gPortTypes[0]); jack_port_type_id_t GetPortTypeId(const char* port_type) { for (jack_port_type_id_t i = 0; i < PORT_TYPES_MAX; ++i) { - const JackPortType* type = port_types[i]; + const JackPortType* type = gPortTypes[i]; assert(type != 0); - if (strcmp(port_type, type->name) == 0) + if (strcmp(port_type, type->fName) == 0) return i; } return PORT_TYPES_MAX; @@ -46,7 +46,7 @@ jack_port_type_id_t GetPortTypeId(const char* port_type) const JackPortType* GetPortType(jack_port_type_id_t type_id) { assert(type_id >= 0 && type_id <= PORT_TYPES_MAX); - const JackPortType* type = port_types[type_id]; + const JackPortType* type = gPortTypes[type_id]; assert(type != 0); return type; } diff --git a/common/JackPortType.h b/common/JackPortType.h index 616e0ae9..efb8ca2f 100644 --- a/common/JackPortType.h +++ b/common/JackPortType.h @@ -12,7 +12,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. */ @@ -31,7 +31,8 @@ extern jack_port_type_id_t PORT_TYPES_MAX; struct JackPortType { - const char* name; + const char* fName; + size_t (*size)(); void (*init)(void* buffer, size_t buffer_size, jack_nframes_t nframes); void (*mixdown)(void *mixbuffer, void** src_buffers, int src_count, jack_nframes_t nframes); }; diff --git a/common/JackRequest.h b/common/JackRequest.h index c83753a3..90d0644a 100644 --- a/common/JackRequest.h +++ b/common/JackRequest.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. */ @@ -71,7 +71,9 @@ struct JackRequest kSessionReply = 34, kGetClientByUUID = 35, kReserveClientName = 36, - kGetUUIDByClient = 37 + kGetUUIDByClient = 37, + kClientHasSessionCallback = 38, + kComputeTotalLatencies = 39 }; RequestType fType; @@ -122,7 +124,7 @@ struct JackResult { return trans->Write(&fResult, sizeof(int)); } - + }; /*! @@ -161,7 +163,7 @@ struct JackClientCheckRequest : public JackRequest CheckRes(trans->Write(&fOptions, sizeof(int))); return trans->Write(&fUUID, sizeof(int)); } - + }; /*! @@ -197,7 +199,7 @@ struct JackClientCheckResult : public JackResult CheckRes(trans->Write(&fStatus, sizeof(int))); return 0; } - + }; /*! @@ -210,7 +212,7 @@ struct JackClientOpenRequest : public JackRequest int fPID; int fUUID; char fName[JACK_CLIENT_NAME_SIZE + 1]; - + JackClientOpenRequest() {} JackClientOpenRequest(const char* name, int pid, int uuid): JackRequest(JackRequest::kClientOpen) @@ -234,7 +236,7 @@ struct JackClientOpenRequest : public JackRequest CheckRes(trans->Write(&fUUID, sizeof(int))); return trans->Write(&fName, sizeof(fName)); } - + }; /*! @@ -247,7 +249,7 @@ struct JackClientOpenResult : public JackResult int fSharedEngine; int fSharedClient; int fSharedGraph; - + JackClientOpenResult() : JackResult(), fSharedEngine(-1), fSharedClient(-1), fSharedGraph(-1) {} @@ -272,7 +274,7 @@ struct JackClientOpenResult : public JackResult CheckRes(trans->Write(&fSharedGraph, sizeof(int))); return 0; } - + }; /*! @@ -299,7 +301,7 @@ struct JackClientCloseRequest : public JackRequest CheckRes(JackRequest::Write(trans)); return trans->Write(&fRefNum, sizeof(int)); } - + }; /*! @@ -402,7 +404,7 @@ struct JackPortRegisterRequest : public JackRequest CheckRes(trans->Write(&fBufferSize, sizeof(unsigned int))); return 0; } - + }; /*! @@ -428,7 +430,7 @@ struct JackPortRegisterResult : public JackResult CheckRes(JackResult::Write(trans)); return trans->Write(&fPortIndex, sizeof(jack_port_id_t)); } - + }; /*! @@ -461,7 +463,7 @@ struct JackPortUnRegisterRequest : public JackRequest CheckRes(trans->Write(&fPortIndex, sizeof(jack_port_id_t))); return 0; } - + }; /*! @@ -501,7 +503,7 @@ struct JackPortConnectNameRequest : public JackRequest CheckRes(trans->Write(&fDst, sizeof(fDst))); return 0; } - + }; /*! @@ -540,7 +542,7 @@ struct JackPortDisconnectNameRequest : public JackRequest CheckRes(trans->Write(&fDst, sizeof(fDst))); return 0; } - + }; /*! @@ -576,7 +578,7 @@ struct JackPortConnectRequest : public JackRequest CheckRes(trans->Write(&fDst, sizeof(jack_port_id_t))); return 0; } - + }; /*! @@ -612,7 +614,7 @@ struct JackPortDisconnectRequest : public JackRequest CheckRes(trans->Write(&fDst, sizeof(jack_port_id_t))); return 0; } - + }; /*! @@ -651,7 +653,7 @@ struct JackPortRenameRequest : public JackRequest return 0; } - + }; /*! @@ -679,7 +681,7 @@ struct JackSetBufferSizeRequest : public JackRequest CheckRes(JackRequest::Write(trans)); return trans->Write(&fBufferSize, sizeof(jack_nframes_t)); } - + }; /*! @@ -707,7 +709,31 @@ struct JackSetFreeWheelRequest : public JackRequest CheckRes(JackRequest::Write(trans)); return trans->Write(&fOnOff, sizeof(int)); } - + +}; + +/*! +\brief ComputeTotalLatencies request. +*/ + +struct JackComputeTotalLatenciesRequest : public JackRequest +{ + + JackComputeTotalLatenciesRequest() + : JackRequest(JackRequest::kComputeTotalLatencies) + {} + + int Read(JackChannelTransaction* trans) + { + return 0; + } + + int Write(JackChannelTransaction* trans) + { + CheckRes(JackRequest::Write(trans)); + return 0; + } + }; /*! @@ -735,7 +761,7 @@ struct JackReleaseTimebaseRequest : public JackRequest CheckRes(JackRequest::Write(trans)); return trans->Write(&fRefNum, sizeof(int)); } - + }; /*! @@ -766,7 +792,7 @@ struct JackSetTimebaseCallbackRequest : public JackRequest CheckRes(trans->Write(&fRefNum, sizeof(int))); return trans->Write(&fConditionnal, sizeof(int)); } - + }; /*! @@ -797,7 +823,7 @@ struct JackGetInternalClientNameRequest : public JackRequest CheckRes(trans->Write(&fRefNum, sizeof(int))); return trans->Write(&fIntRefNum, sizeof(int)); } - + }; /*! @@ -830,7 +856,7 @@ struct JackGetInternalClientNameResult : public JackResult CheckRes(trans->Write(&fName, sizeof(fName))); return 0; } - + }; /*! @@ -863,7 +889,7 @@ struct JackInternalClientHandleRequest : public JackRequest CheckRes(trans->Write(&fRefNum, sizeof(int))); return trans->Write(&fName, sizeof(fName)); } - + }; /*! @@ -897,7 +923,7 @@ struct JackInternalClientHandleResult : public JackResult CheckRes(trans->Write(&fIntRefNum, sizeof(int))); return 0; } - + }; /*! @@ -949,7 +975,7 @@ struct JackInternalClientLoadRequest : public JackRequest CheckRes(trans->Write(&fUUID, sizeof(int))); return trans->Write(&fOptions, sizeof(int)); } - + }; /*! @@ -983,7 +1009,7 @@ struct JackInternalClientLoadResult : public JackResult CheckRes(trans->Write(&fIntRefNum, sizeof(int))); return 0; } - + }; /*! @@ -1044,7 +1070,7 @@ struct JackInternalClientUnloadResult : public JackResult CheckRes(trans->Write(&fStatus, sizeof(int))); return 0; } - + }; /*! @@ -1147,7 +1173,7 @@ struct JackSessionNotifyResult : public JackResult CheckRes(trans->Write(terminator, sizeof(terminator))); return 0; } - + }; /*! @@ -1245,7 +1271,7 @@ struct JackClientNameResult : public JackResult CheckRes(trans->Write(&fName, sizeof(fName))); return 0; } - + }; struct JackUUIDResult : public JackResult @@ -1274,7 +1300,7 @@ struct JackUUIDResult : public JackResult CheckRes(trans->Write(&fUUID, sizeof(fUUID))); return 0; } - + }; struct JackGetUUIDRequest : public JackRequest @@ -1368,6 +1394,34 @@ struct JackReserveNameRequest : public JackRequest }; +struct JackClientHasSessionCallbackRequest : public JackRequest +{ + char fName[JACK_CLIENT_NAME_SIZE + 1]; + + JackClientHasSessionCallbackRequest() + {} + + JackClientHasSessionCallbackRequest(const char *name) + : JackRequest(JackRequest::kClientHasSessionCallback) + { + strncpy(fName, name, sizeof(fName)); + } + + int Read(JackChannelTransaction* trans) + { + CheckRes(trans->Read(&fName, sizeof(fName))); + return 0; + } + + int Write(JackChannelTransaction* trans) + { + CheckRes(JackRequest::Write(trans)); + CheckRes(trans->Write(&fName, sizeof(fName))); + return 0; + } + +}; + /*! \brief ClientNotification. */ diff --git a/common/JackServer.cpp b/common/JackServer.cpp index 126e7c4f..50894529 100644 --- a/common/JackServer.cpp +++ b/common/JackServer.cpp @@ -45,7 +45,7 @@ JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int prio } else { jack_info("JACK server starting in non-realtime mode"); } - + fGraphManager = JackGraphManager::Allocate(port_max); fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, clock, server_name); fEngine = new JackLockedEngine(fGraphManager, GetSynchroTable(), fEngineControl); @@ -72,17 +72,17 @@ int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params) { // TODO: move that in reworked JackServerGlobals::Init() JackMessageBuffer::Create(); - + if ((fAudioDriver = fDriverInfo->Open(driver_desc, fEngine, GetSynchroTable(), driver_params)) == NULL) { jack_error("Cannot initialize driver"); goto fail_close1; } - + if (fChannel.Open(fEngineControl->fServerName, this) < 0) { jack_error("Server channel open error"); goto fail_close2; } - + if (fEngine->Open() < 0) { jack_error("Cannot open engine"); goto fail_close3; @@ -92,12 +92,12 @@ int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params) jack_error("Cannot open driver"); goto fail_close4; } - + if (fAudioDriver->Attach() < 0) { jack_error("Cannot attach audio driver"); goto fail_close5; } - + fFreewheelDriver->SetMaster(false); fAudioDriver->SetMaster(true); fAudioDriver->AddSlave(fFreewheelDriver); // After ??? @@ -113,11 +113,11 @@ fail_close4: fail_close3: fChannel.Close(); - -fail_close2: + +fail_close2: fAudioDriver->Close(); -fail_close1: +fail_close1: JackMessageBuffer::Destroy(); return -1; } @@ -190,7 +190,7 @@ int JackServer::SetBufferSize(jack_nframes_t buffer_size) jack_log("SetBufferSize: requirement for new buffer size equals current value"); return 0; } - + if (fAudioDriver->IsFixedBufferSize()) { jack_log("SetBufferSize: driver only supports a fixed buffer size"); return -1; @@ -316,37 +316,37 @@ int JackServer::SwitchMaster(jack_driver_desc_t* driver_desc, JSList* driver_par fAudioDriver->Stop(); fAudioDriver->Detach(); fAudioDriver->Close(); - + // Open new master JackDriverInfo* info = new JackDriverInfo(); JackDriverClientInterface* master = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params); - + if (master == NULL || info == NULL) { delete info; delete master; return -1; } else { - + // Get slaves list std::list slave_list = fAudioDriver->GetSlaves(); std::list::const_iterator it; - + // Move slaves in new master for (it = slave_list.begin(); it != slave_list.end(); it++) { JackDriverInterface* slave = *it; master->AddSlave(slave); } - + // Delete old master delete fAudioDriver; delete fDriverInfo; - + // Activate master fAudioDriver = master; fDriverInfo = info; fAudioDriver->Attach(); fAudioDriver->SetMaster(true); - return fAudioDriver->Start(); + return fAudioDriver->Start(); } } diff --git a/common/JackServerGlobals.cpp b/common/JackServerGlobals.cpp index fcad0a71..04489190 100644 --- a/common/JackServerGlobals.cpp +++ b/common/JackServerGlobals.cpp @@ -28,8 +28,10 @@ static char* server_name = NULL; namespace Jack { -JackServer* JackServerGlobals::fInstance; +JackServer* JackServerGlobals::fInstance; unsigned int JackServerGlobals::fUserCount; +int JackServerGlobals::fRTNotificationSocket; + bool (* JackServerGlobals::on_device_acquire)(const char * device_name) = NULL; void (* JackServerGlobals::on_device_release)(const char * device_name) = NULL; @@ -95,7 +97,7 @@ bool JackServerGlobals::Init() int argc = 0; char* argv[32]; jack_timer_type_t clock_source = JACK_TIMER_SYSTEM_CLOCK; - + // First user starts the server if (fUserCount++ == 0) { @@ -158,7 +160,7 @@ bool JackServerGlobals::Init() (opt = getopt_long(argc, argv, options, long_options, &option_index)) != EOF) { switch (opt) { - + case 'c': if (tolower (optarg[0]) == 'h') { clock_source = JACK_TIMER_HPET; @@ -168,7 +170,7 @@ bool JackServerGlobals::Init() clock_source = JACK_TIMER_SYSTEM_CLOCK; } else { jack_error("unknown option character %c", optopt); - } + } break; case 'd': diff --git a/common/JackServerGlobals.h b/common/JackServerGlobals.h index b4b688c1..f7d6e439 100644 --- a/common/JackServerGlobals.h +++ b/common/JackServerGlobals.h @@ -38,9 +38,10 @@ struct SERVER_EXPORT JackServerGlobals { static JackServer* fInstance; static unsigned int fUserCount; - static bool (* on_device_acquire)(const char * device_name); - static void (* on_device_release)(const char * device_name); - + static int fRTNotificationSocket; // For debugging purpose + static bool (* on_device_acquire)(const char* device_name); + static void (* on_device_release)(const char* device_name); + JackServerGlobals(); ~JackServerGlobals(); diff --git a/common/JackThread.h b/common/JackThread.h index 34dd798c..a61c5ab1 100644 --- a/common/JackThread.h +++ b/common/JackThread.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 Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 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. - + */ #ifndef __JackThread__ @@ -26,23 +26,23 @@ namespace Jack { - + /*! \brief The base class for runnable objects, that have an Init and Execute method to be called in a thread. */ class JackRunnableInterface { - + protected: - + JackRunnableInterface() {} virtual ~JackRunnableInterface() {} - + public: - + virtual bool Init() /*! Called once when the thread is started */ { return true; @@ -61,23 +61,23 @@ class SERVER_EXPORT JackThreadInterface { public: - + enum kThreadState {kIdle, kStarting, kIniting, kRunning}; - + protected: - + JackRunnableInterface* fRunnable; int fPriority; bool fRealTime; volatile kThreadState fStatus; int fCancellation; - + public: - + JackThreadInterface(JackRunnableInterface* runnable, int priority, bool real_time, int cancellation): fRunnable(runnable), fPriority(priority), fRealTime(real_time), fStatus(kIdle), fCancellation(cancellation) {} - + kThreadState GetStatus() { return fStatus; @@ -86,10 +86,10 @@ class SERVER_EXPORT JackThreadInterface { fStatus = status; } - + void SetParams(UInt64 period, UInt64 computation, UInt64 constraint) // Empty implementation, will only make sense on OSX... {} - + int Start(); int StartSync(); int Kill(); @@ -98,24 +98,24 @@ class SERVER_EXPORT JackThreadInterface int AcquireRealTime(); // Used when called from another thread int AcquireSelfRealTime(); // Used when called from thread itself - + int AcquireRealTime(int priority); // Used when called from another thread int AcquireSelfRealTime(int priority); // Used when called from thread itself - + int DropRealTime(); // Used when called from another thread int DropSelfRealTime(); // Used when called from thread itself - pthread_t GetThreadID(); + jack_native_thread_t GetThreadID(); bool IsThread(); - static int AcquireRealTimeImp(pthread_t thread, int priority); - static int AcquireRealTimeImp(pthread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint); - static int DropRealTimeImp(pthread_t thread); - static int StartImp(pthread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg); - static int StopImp(pthread_t thread); - static int KillImp(pthread_t thread); + static int AcquireRealTimeImp(jack_native_thread_t thread, int priority); + static int AcquireRealTimeImp(jack_native_thread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint); + static int DropRealTimeImp(jack_native_thread_t thread); + static int StartImp(jack_native_thread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg); + static int StopImp(jack_native_thread_t thread); + static int KillImp(jack_native_thread_t thread); }; - + } } // end of namespace diff --git a/common/JackTime.h b/common/JackTime.h index 10ef1e8c..505903c6 100644 --- a/common/JackTime.h +++ b/common/JackTime.h @@ -21,7 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __JackTime__ #define __JackTime__ -#include "types.h" #include "JackCompilerDeps.h" #include "JackTypes.h" diff --git a/common/JackTypes.h b/common/JackTypes.h index 234be17a..b4bad8d6 100644 --- a/common/JackTypes.h +++ b/common/JackTypes.h @@ -34,6 +34,12 @@ typedef signed long SInt32; #include "JackTypes_os.h" +/** + * Type used to represent the value of free running + * monotonic clock with units of microseconds. + */ +typedef uint64_t jack_time_t; + typedef uint16_t jack_int_t; // Internal type for ports and refnum typedef enum { diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index 1eda4d11..1d05eeb8 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -33,7 +33,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackDriverLoader.h" #if defined(JACK_DBUS) && defined(__linux__) -#include +#include #include "audio_reserve.h" #endif @@ -85,7 +85,7 @@ static void copyright(FILE* file) { fprintf(file, "jackdmp " VERSION "\n" "Copyright 2001-2005 Paul Davis and others.\n" - "Copyright 2004-2010 Grame.\n" + "Copyright 2004-2011 Grame.\n" "jackdmp comes with ABSOLUTELY NO WARRANTY\n" "This is free software, and you are welcome to redistribute it\n" "under certain conditions; see the file COPYING for details\n"); @@ -114,10 +114,10 @@ static void usage(FILE* file) " -d backend [ ... backend args ... ]\n" #ifdef __APPLE__ " Available backends may include: coreaudio, dummy or net.\n\n" -#endif +#endif #ifdef WIN32 " Available backends may include: portaudio, dummy or net.\n\n" -#endif +#endif #ifdef __linux__ " Available backends may include: alsa, dummy, freebob, firewire or net\n\n" #endif @@ -178,13 +178,13 @@ int main(int argc, char* argv[]) jackctl_driver_t * midi_driver_ctl; jackctl_driver_t * loopback_driver_ctl; int replace_registry = 0; - + const char *options = "-d:X:P:uvshVrRL:STFl:t:mn:p:" #ifdef __linux__ "c:" #endif ; - + struct option long_options[] = { #ifdef __linux__ { "clock-source", 1, 0, 'c' }, @@ -199,7 +199,7 @@ int main(int argc, char* argv[]) { "name", 1, 0, 'n' }, { "unlock", 0, 0, 'u' }, { "realtime", 0, 0, 'R' }, - { "no-realtime", 0, 0, 'r' }, + { "no-realtime", 0, 0, 'r' }, { "replace-registry", 0, &replace_registry, 0 }, { "loopback", 0, 0, 'L' }, { "realtime-priority", 1, 0, 'P' }, @@ -239,23 +239,23 @@ int main(int argc, char* argv[]) fprintf(stderr, "Failed to create server object\n"); return -1; } - + server_parameters = jackctl_server_get_parameters(server_ctl); - + // Default setting param = jackctl_get_parameter(server_parameters, "realtime"); if (param != NULL) { value.b = true; jackctl_parameter_set_value(param, &value); } - + opterr = 0; while (!seen_audio_driver && (opt = getopt_long(argc, argv, options, long_options, &option_index)) != EOF) { switch (opt) { - #ifdef __linux__ + #ifdef __linux__ case 'c': param = jackctl_get_parameter(server_parameters, "clock-source"); if (param != NULL) { @@ -280,7 +280,7 @@ int main(int argc, char* argv[]) seen_audio_driver = true; audio_driver_name = optarg; break; - + case 'L': loopback = atoi(optarg); break; @@ -342,7 +342,7 @@ int main(int argc, char* argv[]) jackctl_parameter_set_value(param, &value); } break; - + case 'r': param = jackctl_get_parameter(server_parameters, "realtime"); if (param != NULL) { @@ -388,14 +388,14 @@ int main(int argc, char* argv[]) goto fail_free1; } } - + // Long option with no letter so treated separately param = jackctl_get_parameter(server_parameters, "replace-registry"); if (param != NULL) { value.b = replace_registry; jackctl_parameter_set_value(param, &value); } - + if (show_version) { printf( "jackdmp version " VERSION " tmpdir " jack_server_dir @@ -441,7 +441,7 @@ int main(int argc, char* argv[]) // Setup signals then start server signals = jackctl_setup_signals(0); - + if (!jackctl_server_start(server_ctl, audio_driver_ctl)) { fprintf(stderr, "Failed to start server\n"); goto fail_free1; @@ -458,7 +458,7 @@ int main(int argc, char* argv[]) jackctl_server_add_slave(server_ctl, midi_driver_ctl); } - + // Loopback driver if (loopback > 0) { loopback_driver_ctl = jackctl_server_get_driver(server_ctl, "loopback"); @@ -480,7 +480,7 @@ int main(int argc, char* argv[]) if (!jackctl_server_stop(server_ctl)) fprintf(stderr, "Cannot stop server...\n"); - + jackctl_server_destroy(server_ctl); notify_server_stop(server_name); return 0; @@ -488,7 +488,7 @@ int main(int argc, char* argv[]) fail_free1: jackctl_server_destroy(server_ctl); return -1; - + fail_free2: jackctl_server_stop(server_ctl); jackctl_server_destroy(server_ctl); diff --git a/common/jack/jack.h b/common/jack/jack.h index a63fcd12..40f06ddd 100644 --- a/common/jack/jack.h +++ b/common/jack/jack.h @@ -1,19 +1,19 @@ /* Copyright (C) 2001 Paul Davis Copyright (C) 2004 Jack O'Quin - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 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. */ @@ -33,21 +33,21 @@ extern "C" /** * Note: More documentation can be found in jack/types.h. */ - + /************************************************************* * NOTE: JACK_WEAK_EXPORT ***MUST*** be used on every function * added to the JACK API after the 0.116.2 release. - * - * Functions that predate this release are marked with + * + * Functions that predate this release are marked with * JACK_WEAK_OPTIONAL_EXPORT which can be defined at compile * time in a variety of ways. The default definition is empty, * so that these symbols get normal linkage. If you wish to - * use all JACK symbols with weak linkage, include + * use all JACK symbols with weak linkage, include * before jack.h. *************************************************************/ - + #include - + /** * Call this function to get version of the JACK, in form of several numbers * @@ -200,7 +200,7 @@ int jack_get_client_pid (const char *name) JACK_OPTIONAL_WEAK_EXPORT; * @return the pthread ID of the thread running the JACK client side * code. */ -pthread_t jack_client_thread_id (jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT; +jack_native_thread_t jack_client_thread_id (jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ @@ -228,7 +228,7 @@ jack_nframes_t jack_thread_wait (jack_client_t*, int status) JACK_OPTIONAL_WEAK_ /** * Wait until this JACK client should process data. - * + * * @param client - pointer to a JACK client structure * * @return the number of frames of data to process @@ -237,7 +237,7 @@ jack_nframes_t jack_thread_wait (jack_client_t*, int status) JACK_OPTIONAL_WEAK_ /** * Signal next clients in the graph. - * + * * @param client - pointer to a JACK client structure * @param status - if non-zero, calling thread should exit */ @@ -254,7 +254,7 @@ void jack_cycle_signal (jack_client_t* client, int status) JACK_OPTIONAL_WEAK_EX * http://jackit.sourceforge.net/docs/design/design.html#SECTION00411000000000000000 * for more information. * - * NOTE: this function cannot be called while the client is activated + * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code. @@ -270,13 +270,13 @@ int jack_set_process_thread(jack_client_t* client, JackThreadCallback thread_cal /** * Tell JACK to call @a thread_init_callback once just after - * the creation of the thread in which all other callbacks + * the creation of the thread in which all other callbacks * will be handled. * * The code in the supplied function does not need to be * suitable for real-time execution. * - * NOTE: this function cannot be called while the client is activated + * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code, causing JACK @@ -337,7 +337,7 @@ void jack_on_shutdown (jack_client_t *client, */ void jack_on_info_shutdown (jack_client_t *client, JackInfoShutdownCallback shutdown_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; - + /** * Tell the Jack server to call @a process_callback whenever there is * work be done, passing @a arg as the second argument. @@ -350,7 +350,7 @@ void jack_on_info_shutdown (jack_client_t *client, * http://jackit.sourceforge.net/docs/design/design.html#SECTION00411000000000000000 * for more information. * - * NOTE: this function cannot be called while the client is activated + * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code. @@ -370,7 +370,7 @@ int jack_set_process_callback (jack_client_t *client, * the code in the supplied function does not need to be * suitable for real-time execution. * - * NOTE: this function cannot be called while the client is activated + * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code. @@ -389,7 +389,7 @@ int jack_set_freewheel_callback (jack_client_t *client, * the code in the supplied function does not need to be * suitable for real-time execution. * - * NOTE: this function cannot be called while the client is activated + * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @param client pointer to JACK client structure. @@ -410,7 +410,7 @@ int jack_set_buffer_size_callback (jack_client_t *client, * the code in the supplied function does not need to be * suitable for real-time execution. * - * NOTE: this function cannot be called while the client is activated + * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code @@ -427,7 +427,7 @@ int jack_set_sample_rate_callback (jack_client_t *client, * the code in the supplied function does not need to be * suitable for real-time execution. * - * NOTE: this function cannot be called while the client is activated + * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code @@ -444,7 +444,7 @@ int jack_set_client_registration_callback (jack_client_t *, * the code in the supplied function does not need to be * suitable for real-time execution. * - * NOTE: this function cannot be called while the client is activated + * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code @@ -452,7 +452,7 @@ int jack_set_client_registration_callback (jack_client_t *, int jack_set_port_registration_callback (jack_client_t *, JackPortRegistrationCallback registration_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; - + /** * Tell the JACK server to call @a connect_callback whenever a * port is connected or disconnected, passing @a arg as a parameter. @@ -461,7 +461,7 @@ int jack_set_client_registration_callback (jack_client_t *, * the code in the supplied function does not need to be * suitable for real-time execution. * - * NOTE: this function cannot be called while the client is activated + * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code @@ -478,7 +478,7 @@ int jack_set_port_connect_callback (jack_client_t *, * the code in the supplied function does not need to be * suitable for real-time execution. * - * NOTE: this function cannot be called while the client is activated + * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code @@ -495,7 +495,7 @@ int jack_set_port_rename_callback (jack_client_t *, * the code in the supplied function does not need to be * suitable for real-time execution. * - * NOTE: this function cannot be called while the client is activated + * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code @@ -512,39 +512,97 @@ int jack_set_graph_order_callback (jack_client_t *, * the code in the supplied function does not need to be * suitable for real-time execution. * - * NOTE: this function cannot be called while the client is activated + * NOTE: this function cannot be called while the client is activated * (after jack_activate has been called.) * * @return 0 on success, otherwise a non-zero error code */ int jack_set_xrun_callback (jack_client_t *, JackXRunCallback xrun_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; - + +/*@}*/ + +/** + * Tell the Jack server to call @a latency_callback whenever it + * is necessary to recompute the latencies for some or all + * Jack ports. + * + * @a latency_callback will be called twice each time it is + * needed, once being passed JackCaptureLatency and once + * JackPlaybackLatency. See @ref LatencyFunctions for + * the definition of each type of latency and related functions. + * + * IMPORTANT: Most JACK clients do NOT need to register a latency + * callback. + * + * Clients that meet any of the following conditions do NOT + * need to register a latency callback: + * + * - have only input ports + * - have only output ports + * - their output is totally unrelated to their input + * - their output is not delayed relative to their input + * (i.e. data that arrives in a given process() + * callback is processed and output again in the + * same callback) + * + * Clients NOT registering a latency callback MUST also + * satisfy this condition: + * + * - have no multiple distinct internal signal pathways + * + * This means that if your client has more than 1 input and + * output port, and considers them always "correlated" + * (e.g. as a stereo pair), then there is only 1 (e.g. stereo) + * signal pathway through the client. This would be true, + * for example, of a stereo FX rack client that has a + * left/right input pair and a left/right output pair. + * + * However, this is somewhat a matter of perspective. The + * same FX rack client could be connected so that its + * two input ports were connected to entirely separate + * sources. Under these conditions, the fact that the client + * does not register a latency callback MAY result + * in port latency values being incorrect. + * + * Clients that do not meet any of those conditions SHOULD + * register a latency callback. + * + * See the documentation for @ref jack_port_set_latency_range() + * on how the callback should operate. Remember that the @a mode + * argument given to the latency callback will need to be + * passed into @ref jack_port_set_latency_range() + * + * @return 0 on success, otherwise a non-zero error code + */ +int jack_set_latency_callback (jack_client_t *, + JackLatencyCallback latency_callback, + void *) JACK_WEAK_EXPORT; /*@}*/ /** * @defgroup ServerClientControl Controlling & querying JACK server operation * @{ */ - + /** * Start/Stop JACK's "freewheel" mode. * * When in "freewheel" mode, JACK no longer waits for * any external event to begin the start of the next process - * cycle. + * cycle. * * As a result, freewheel mode causes "faster than realtime" * execution of a JACK graph. If possessed, real-time * scheduling is dropped when entering freewheel mode, and * if appropriate it is reacquired when stopping. - * + * * IMPORTANT: on systems using capabilities to provide real-time * scheduling (i.e. Linux kernel 2.4), if onoff is zero, this function - * must be called from the thread that originally called jack_activate(). - * This restriction does not apply to other systems (e.g. Linux kernel 2.6 + * must be called from the thread that originally called jack_activate(). + * This restriction does not apply to other systems (e.g. Linux kernel 2.6 * or OS X). - * + * * @param client pointer to JACK client structure * @param onoff if non-zero, freewheel mode starts. Otherwise * freewheel mode ends. @@ -569,7 +627,7 @@ int jack_set_freewheel(jack_client_t* client, int onoff) JACK_OPTIONAL_WEAK_EXPO * @return 0 on success, otherwise a non-zero error code */ int jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes) JACK_OPTIONAL_WEAK_EXPORT; - + /** * @return the sample rate of the jack system, as set by the user when * jackd was started. @@ -613,7 +671,7 @@ float jack_cpu_load (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; * @defgroup PortFunctions Creating & manipulating ports * @{ */ - + /** * Create a new port for the client. This is an object used for moving * data of any type in or out of the client. Ports may be connected @@ -625,16 +683,16 @@ float jack_cpu_load (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; * name. Exceeding that will cause the port registration to fail and * return NULL. * - * The @a port_name must be unique among all ports owned by this client. - * If the name is not unique, the registration will fail. - * + * The @a port_name must be unique among all ports owned by this client. + * If the name is not unique, the registration will fail. + * * All ports have a type, which may be any non-NULL and non-zero * length string, passed as an argument. Some port types are built * into the JACK API, currently only JACK_DEFAULT_AUDIO_TYPE. * * @param client pointer to JACK client structure. * @param port_name non-empty short name for the new port (not - * including the leading @a "client_name:"). Must be unique. + * including the leading @a "client_name:"). Must be unique. * @param port_type port type name. If longer than * jack_port_type_size(), only that many characters are significant. * @param flags @ref JackPortFlags bit mask. @@ -663,7 +721,7 @@ int jack_port_unregister (jack_client_t *, jack_port_t *) JACK_OPTIONAL_WEAK_EXP * that can be written to; for an input port, it will be an area * containing the data from the port's connection(s), or * zero-filled. if there are multiple inbound connections, the data - * will be mixed appropriately. + * will be mixed appropriately. * * FOR OUTPUT PORTS ONLY : DEPRECATED in Jack 2.0 !! * --------------------------------------------------- @@ -672,9 +730,9 @@ int jack_port_unregister (jack_client_t *, jack_port_t *) JACK_OPTIONAL_WEAK_EXP * either never cache the return value or ensure you have * a "blocksize" callback and be sure to invalidate the cached * address from there. - * + * * Caching output ports is DEPRECATED in Jack 2.0, due to some new optimization (like "pipelining"). - * Port buffers have to be retrieved in each callback for proper functionning. + * Port buffers have to be retrieved in each callback for proper functionning. */ void * jack_port_get_buffer (jack_port_t *, jack_nframes_t) JACK_OPTIONAL_WEAK_EXPORT; @@ -759,7 +817,7 @@ const char ** jack_port_get_connections (const jack_port_t *port) JACK_OPTIONAL_ * you cannot use it in a GraphReordered handler. * * 2) You need not be the owner of the port to get information - * about its connections. + * about its connections. * * @see jack_port_name_size() */ @@ -768,8 +826,8 @@ const char ** jack_port_get_all_connections (const jack_client_t *client, /** * - * @deprecated This function will be removed from a future version - * of JACK. Do not use it. There is no replacement. It has + * @deprecated This function will be removed from a future version + * of JACK. Do not use it. There is no replacement. It has * turned out to serve essentially no purpose in real-life * JACK clients. */ @@ -777,73 +835,13 @@ int jack_port_tie (jack_port_t *src, jack_port_t *dst) JACK_OPTIONAL_WEAK_DEPREC /** * - * @deprecated This function will be removed from a future version - * of JACK. Do not use it. There is no replacement. It has + * @deprecated This function will be removed from a future version + * of JACK. Do not use it. There is no replacement. It has * turned out to serve essentially no purpose in real-life * JACK clients. */ int jack_port_untie (jack_port_t *port) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; - /** - * @return the time (in frames) between data being available or - * delivered at/to a port, and the time at which it arrived at or is - * delivered to the "other side" of the port. E.g. for a physical - * audio output port, this is the time between writing to the port and - * when the signal will leave the connector. For a physical audio - * input port, this is the time between the sound arriving at the - * connector and the corresponding frames being readable from the - * port. - */ -jack_nframes_t jack_port_get_latency (jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; - -/** - * The maximum of the sum of the latencies in every - * connection path that can be drawn between the port and other - * ports with the @ref JackPortIsTerminal flag set. - */ -jack_nframes_t jack_port_get_total_latency (jack_client_t *, - jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; - -/** - * The port latency is zero by default. Clients that control - * physical hardware with non-zero latency should call this - * to set the latency to its correct value. Note that the value - * should include any systemic latency present "outside" the - * physical hardware controlled by the client. For example, - * for a client controlling a digital audio interface connected - * to an external digital converter, the latency setting should - * include both buffering by the audio interface *and* the converter. - */ -void jack_port_set_latency (jack_port_t *, jack_nframes_t) JACK_OPTIONAL_WEAK_EXPORT; - -/** -* Request a complete recomputation of a port's total latency. This -* can be called by a client that has just changed the internal -* latency of its port using @function jack_port_set_latency -* and wants to ensure that all signal pathways in the graph -* are updated with respect to the values that will be returned -* by @function jack_port_get_total_latency. -* -* @return zero for successful execution of the request. non-zero -* otherwise. -*/ -int jack_recompute_total_latency (jack_client_t*, jack_port_t* port) JACK_OPTIONAL_WEAK_EXPORT; - -/** -* Request a complete recomputation of all port latencies. This -* can be called by a client that has just changed the internal -* latency of its port using @function jack_port_set_latency -* and wants to ensure that all signal pathways in the graph -* are updated with respect to the values that will be returned -* by @function jack_port_get_total_latency. It allows a client -* to change multiple port latencies without triggering a -* recompute for each change. -* -* @return zero for successful execution of the request. non-zero -* otherwise. -*/ - int jack_recompute_total_latencies (jack_client_t*) JACK_OPTIONAL_WEAK_EXPORT; - /** * Modify a port's short name. May be called at any time. If the * resulting full name (including the @a "client_name:" prefix) is @@ -856,12 +854,12 @@ int jack_port_set_name (jack_port_t *port, const char *port_name) JACK_OPTIONAL_ /** * Set @a alias as an alias for @a port. May be called at any time. * If the alias is longer than jack_port_name_size(), it will be truncated. - * + * * After a successful call, and until JACK exits or * @function jack_port_unset_alias() is called, @alias may be * used as a alternate name for the port. * - * Ports can have up to two aliases - if both are already + * Ports can have up to two aliases - if both are already * set, this function will return an error. * * @return 0 on success, otherwise a non-zero error code. @@ -870,8 +868,8 @@ int jack_port_set_alias (jack_port_t *port, const char *alias) JACK_OPTIONAL_WEA /** * Remove @a alias as an alias for @a port. May be called at any time. - * - * After a successful call, @a alias can no longer be + * + * After a successful call, @a alias can no longer be * used as a alternate name for the port. * * @return 0 on success, otherwise a non-zero error code. @@ -981,6 +979,224 @@ int jack_port_name_size(void) JACK_OPTIONAL_WEAK_EXPORT; */ int jack_port_type_size(void) JACK_OPTIONAL_WEAK_EXPORT; +/** + * @return the buffersize of a port of type @arg port_type. + * + * this function may only be called in a buffer_size callback. + */ +size_t jack_port_type_get_buffer_size (jack_client_t *client, const char *port_type) JACK_WEAK_EXPORT; + +/*@}*/ + +/** + * @defgroup LatencyFunctions Managing and determining latency + * + * The purpose of JACK's latency API is to allow clients to + * easily answer two questions: + * + * - How long has it been since the data read from a port arrived + * at the edge of the JACK graph (either via a physical port + * or being synthesized from scratch)? + * + * - How long will it be before the data written to a port arrives + * at the edge of a JACK graph? + + * To help answering these two questions, all JACK ports have two + * latency values associated with them, both measured in frames: + * + * capture latency: how long since the data read from + * the buffer of a port arrived at at + * a port marked with JackPortIsTerminal. + * The data will have come from the "outside + * world" if the terminal port is also + * marked with JackPortIsPhysical, or + * will have been synthesized by the client + * that owns the terminal port. + * + * playback latency: how long until the data + * written to the buffer of port will reach a port + * marked with JackPortIsTerminal. + * + * Both latencies might potentially have more than one value + * because there may be multiple pathways to/from a given port + * and a terminal port. Latency is therefore generally + * expressed a min/max pair. + * + * In most common setups, the minimum and maximum latency + * are the same, but this design accomodates more complex + * routing, and allows applications (and thus users) to + * detect cases where routing is creating an anomalous + * situation that may either need fixing or more + * sophisticated handling by clients that care about + * latency. + * + * See also @ref jack_set_latency_callback for details on how + * clients that add latency to the signal path should interact + * with JACK to ensure that the correct latency figures are + * used. + * @{ + */ + +/** + * The port latency is zero by default. Clients that control + * physical hardware with non-zero latency should call this + * to set the latency to its correct value. Note that the value + * should include any systemic latency present "outside" the + * physical hardware controlled by the client. For example, + * for a client controlling a digital audio interface connected + * to an external digital converter, the latency setting should + * include both buffering by the audio interface *and* the converter. + * + * @deprecated This method will be removed in the next major + * release of JACK. It should not be used in new code, and should + * be replaced by a latency callback that calls @ref + * jack_port_set_latency_range(). + */ +void jack_port_set_latency (jack_port_t *, jack_nframes_t) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; + +/** + * return the latency range defined by @a mode for + * @a port, in frames. + * + * See @ref LatencyFunctions for the definition of each latency value. + * + * This is normally used in the LatencyCallback. + * and therefor safe to execute from callbacks. + */ +void jack_port_get_latency_range (jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range) JACK_WEAK_EXPORT; + +/** + * set the minimum and maximum latencies defined by + * @a mode for @a port, in frames. + * + * See @ref LatencyFunctions for the definition of each latency value. + * + * This function should ONLY be used inside a latency + * callback. The client should determine the current + * value of the latency using @ref jack_port_get_latency_range() + * (called using the same mode as @a mode) + * and then add some number of frames to that reflects + * latency added by the client. + * + * How much latency a client adds will vary + * dramatically. For most clients, the answer is zero + * and there is no reason for them to register a latency + * callback and thus they should never call this + * function. + * + * More complex clients that take an input signal, + * transform it in some way and output the result but + * not during the same process() callback will + * generally know a single constant value to add + * to the value returned by @ref jack_port_get_latency_range(). + * + * Such clients would register a latency callback (see + * @ref jack_set_latency_callback) and must know what input + * ports feed which output ports as part of their + * internal state. Their latency callback will update + * the ports' latency values appropriately. + * + * A pseudo-code example will help. The @a mode argument to the latency + * callback will determine whether playback or capture + * latency is being set. The callback will use + * @ref jack_port_set_latency_range() as follows: + * + * \code + * jack_latency_range_t range; + * if (mode == JackPlaybackLatency) { + * foreach input_port in (all self-registered port) { + * jack_port_get_latency_range (port_feeding_input_port, JackPlaybackLatency, &range); + * range.min += min_delay_added_as_signal_flows_from port_feeding to input_port; + * range.max += max_delay_added_as_signal_flows_from port_feeding to input_port; + * jack_port_set_latency_range (input_port, JackPlaybackLatency, &range); + * } + * } else if (mode == JackCaptureLatency) { + * foreach output_port in (all self-registered port) { + * jack_port_get_latency_range (port_fed_by_output_port, JackCaptureLatency, &range); + * range.min += min_delay_added_as_signal_flows_from_output_port_to_fed_by_port; + * range.max += max_delay_added_as_signal_flows_from_output_port_to_fed_by_port; + * jack_port_set_latency_range (output_port, JackCaptureLatency, &range); + * } + * } + * \endcode + * + * In this relatively simple pseudo-code example, it is assumed that + * each input port or output is connected to only 1 output or input + * port respectively. + * + * If a port is connected to more than 1 other port, then the + * range.min and range.max values passed to @ref + * jack_port_set_latency_range() should reflect the minimum and + * maximum values across all connected ports. + * + * See the description of @ref jack_set_latency_callback for more + * information. + */ +void jack_port_set_latency_range (jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range) JACK_WEAK_EXPORT; + +/** + * Request a complete recomputation of all port latencies. This + * can be called by a client that has just changed the internal + * latency of its port using jack_port_set_latency + * and wants to ensure that all signal pathways in the graph + * are updated with respect to the values that will be returned + * by jack_port_get_total_latency. It allows a client + * to change multiple port latencies without triggering a + * recompute for each change. + * + * @return zero for successful execution of the request. non-zero + * otherwise. + */ +int jack_recompute_total_latencies (jack_client_t*) JACK_OPTIONAL_WEAK_EXPORT; + +/** + * @return the time (in frames) between data being available or + * delivered at/to a port, and the time at which it arrived at or is + * delivered to the "other side" of the port. E.g. for a physical + * audio output port, this is the time between writing to the port and + * when the signal will leave the connector. For a physical audio + * input port, this is the time between the sound arriving at the + * connector and the corresponding frames being readable from the + * port. + * + * @deprecated This method will be removed in the next major + * release of JACK. It should not be used in new code, and should + * be replaced by jack_port_get_latency_range() in any existing + * use cases. + */ +jack_nframes_t jack_port_get_latency (jack_port_t *port) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; + +/** + * The maximum of the sum of the latencies in every + * connection path that can be drawn between the port and other + * ports with the @ref JackPortIsTerminal flag set. + * + * @deprecated This method will be removed in the next major + * release of JACK. It should not be used in new code, and should + * be replaced by jack_port_get_latency_range() in any existing + * use cases. + */ +jack_nframes_t jack_port_get_total_latency (jack_client_t *, + jack_port_t *port) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; + +/** + * Request a complete recomputation of a port's total latency. This + * can be called by a client that has just changed the internal + * latency of its port using jack_port_set_latency + * and wants to ensure that all signal pathways in the graph + * are updated with respect to the values that will be returned + * by jack_port_get_total_latency. + * + * @return zero for successful execution of the request. non-zero + * otherwise. + * + * @deprecated This method will be removed in the next major + * release of JACK. It should not be used in new code, and should + * be replaced by jack_recompute_total_latencies() in any existing + * use cases. + */ +int jack_recompute_total_latency (jack_client_t*, jack_port_t* port) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; + /*@}*/ /** @@ -989,13 +1205,13 @@ int jack_port_type_size(void) JACK_OPTIONAL_WEAK_EXPORT; */ /** - * @param port_name_pattern A regular expression used to select - * ports by name. If NULL or of zero length, no selection based + * @param port_name_pattern A regular expression used to select + * ports by name. If NULL or of zero length, no selection based * on name will be carried out. - * @param type_name_pattern A regular expression used to select - * ports by type. If NULL or of zero length, no selection based + * @param type_name_pattern A regular expression used to select + * ports by type. If NULL or of zero length, no selection based * on type will be carried out. - * @param flags A value used to select ports by their flags. + * @param flags A value used to select ports by their flags. * If zero, no selection based on flags will be carried out. * * @return a NULL-terminated array of ports that match the specified @@ -1021,8 +1237,8 @@ jack_port_t * jack_port_by_name (jack_client_t *, const char *port_name) JACK_OP */ jack_port_t * jack_port_by_id (jack_client_t *client, jack_port_id_t port_id) JACK_OPTIONAL_WEAK_EXPORT; - -/*@}*/ + +/*@}*/ /** * @defgroup TimeFunctions Handling time @@ -1052,7 +1268,7 @@ jack_nframes_t jack_frame_time (const jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT * This function may only be used from the process callback, and can * be used to interpret timestamps generated by jack_frame_time() in * other threads with respect to the current process cycle. - * + * * This is the only jack time function that returns exact time: * when used during the process callback it always returns the same * value (until the next process callback, where it will return @@ -1075,8 +1291,8 @@ jack_nframes_t jack_time_to_frames(const jack_client_t *client, jack_time_t) JAC /** * @return return JACK's current system time in microseconds, - * using the JACK clock source. - * + * using the JACK clock source. + * * The value returned is guaranteed to be monotonic, but not linear. */ jack_time_t jack_get_time() JACK_OPTIONAL_WEAK_EXPORT; @@ -1129,7 +1345,7 @@ void jack_set_info_function (void (*func)(const char *)) JACK_OPTIONAL_WEAK_EXPO /*@}*/ /** - * The free function to be used on memory returned by jack_port_get_connections, + * The free function to be used on memory returned by jack_port_get_connections, * jack_port_get_all_connections and jack_get_ports functions. * This is MANDATORY on Windows when otherwise all nasty runtime version related crashes can occur. * Developers are strongly encouraged to use this function instead of the standard "free" function in new code. diff --git a/common/jack/midiport.h b/common/jack/midiport.h index e7e079a8..72780740 100644 --- a/common/jack/midiport.h +++ b/common/jack/midiport.h @@ -1,18 +1,18 @@ /* Copyright (C) 2004 Ian Esten - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 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. */ @@ -24,11 +24,12 @@ #ifdef __cplusplus extern "C" { #endif - + +#include #include #include -#include - + + /** Type for raw event data contained in @ref jack_midi_event_t. */ typedef unsigned char jack_midi_data_t; @@ -43,7 +44,7 @@ typedef struct _jack_midi_event /** - * @defgroup MIDIAPI Reading and writing MIDI data + * @defgroup MIDIAPI Reading and writing MIDI data * @{ */ @@ -57,7 +58,7 @@ jack_midi_get_event_count(void* port_buffer) JACK_OPTIONAL_WEAK_EXPORT; /** Get a MIDI event from an event port buffer. - * + * * Jack MIDI is normalised, the MIDI event returned by this function is * guaranteed to be a complete MIDI event (the status byte will always be * present, and no realtime events will interspered with the event). @@ -74,7 +75,7 @@ jack_midi_event_get(jack_midi_event_t *event, /** Clear an event buffer. - * + * * This should be called at the beginning of each process cycle before calling * @ref jack_midi_event_reserve or @ref jack_midi_event_write. This * function may not be called on an input port's buffer. @@ -105,10 +106,10 @@ jack_midi_max_event_size(void* port_buffer) JACK_OPTIONAL_WEAK_EXPORT; * messages interspersed with other messages (realtime messages are fine * when they occur on their own, like other messages). * - * Events must be written in order, sorted by their sample offsets. - * JACK will not sort the events for you, and will refuse to store - * out-of-order events. - * + * Events must be written in order, sorted by their sample offsets. + * JACK will not sort the events for you, and will refuse to store + * out-of-order events. + * * @param port_buffer Buffer to write event to. * @param time Sample offset of event. * @param data_size Length of event's raw data in bytes. @@ -117,7 +118,7 @@ jack_midi_max_event_size(void* port_buffer) JACK_OPTIONAL_WEAK_EXPORT; */ jack_midi_data_t* jack_midi_event_reserve(void *port_buffer, - jack_nframes_t time, + jack_nframes_t time, size_t data_size) JACK_OPTIONAL_WEAK_EXPORT; @@ -125,18 +126,17 @@ jack_midi_event_reserve(void *port_buffer, * * This function is simply a wrapper for @ref jack_midi_event_reserve * which writes the event data into the space reserved in the buffer. - * The same restrictions on the MIDI data apply. - * - * Clients must not write more than - * @a data_size bytes into this buffer. Clients must write normalised - * MIDI data to the port - no running status and no (1-byte) realtime - * messages interspersed with other messages (realtime messages are fine - * when they occur on their own, like other messages). - * - * Events must be written in order, sorted by their sample offsets. - * JACK will not sort the events for you, and will refuse to store + * + * Clients must not write more than + * @a data_size bytes into this buffer. Clients must write normalised + * MIDI data to the port - no running status and no (1-byte) realtime + * messages interspersed with other messages (realtime messages are fine + * when they occur on their own, like other messages). + * + * Events must be written in order, sorted by their sample offsets. + * JACK will not sort the events for you, and will refuse to store * out-of-order events. - * + * * @param port_buffer Buffer to write event to. * @param time Sample offset of event. * @param data Message data to be written. diff --git a/common/jack/session.h b/common/jack/session.h index f44048c0..fd0469c6 100644 --- a/common/jack/session.h +++ b/common/jack/session.h @@ -2,21 +2,20 @@ Copyright (C) 2001 Paul Davis Copyright (C) 2004 Jack O'Quin Copyright (C) 2010 Torben Hohn - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 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. - */ #ifndef __jack_session_h__ @@ -36,80 +35,114 @@ extern "C" { /** - * session event types. + * Session event type. * * if a client cant save templates, i might just do a normal save. * - * the rationale, why there is no quit without save, is that a client - * might refuse to quit when it has unsaved data. - * however some other clients might have already quit. - * this results in too much confusion, so we just dont support that. - * the session manager can check, if the saved state is different from a previous - * save, and just remove the saved stuff. - * - * (an inquiry function, whether a quit is ok, followed by a quit event - * would have a race) + * There is no "quit without saving" event because a client might refuse to + * quit when it has unsaved data, but other clients may have already quit. + * This results in too much confusion, so it is unsupported. */ enum JackSessionEventType { + /** + * Save the session completely. + * + * The client may save references to data outside the provided directory, + * but it must do so by creating a link inside the provided directory and + * referring to that in any save files. The client must not refer to data + * files outside the provided directory directly in save files, because + * this makes it impossible for the session manager to create a session + * archive for distribution or archival. + */ JackSessionSave = 1, + + /** + * Save the session completly, then quit. + * + * The rules for saving are exactly the same as for JackSessionSave. + */ JackSessionSaveAndQuit = 2, + + /** + * Save a session template. + * + * A session template is a "skeleton" of the session, but without any data. + * Clients must save a session that, when restored, will create the same + * ports as a full save would have. However, the actual data contained in + * the session may not be saved (e.g. a DAW would create the necessary + * tracks, but not save the actual recorded data). + */ JackSessionSaveTemplate = 3 }; typedef enum JackSessionEventType jack_session_event_type_t; +/** + * @ref jack_session_flags_t bits + */ enum JackSessionFlags { /** - * an error occured while saving. + * An error occured while saving. */ JackSessionSaveError = 0x01, /** - * this reply indicates that a client is part of a multiclient application. - * the command reply is left empty. but the session manager should still - * consider this client part of a session. it will come up due to invocation of another - * client. + * Client needs to be run in a terminal. */ - JackSessionChildClient = 0x02 + JackSessionNeedTerminal = 0x02 }; +/** + * Session flags. + */ typedef enum JackSessionFlags jack_session_flags_t; struct _jack_session_event { /** - * the actual type of this session event. + * The type of this session event. */ jack_session_event_type_t type; /** - * session_directory with trailing separator - * this is per client. so the client can do whatever it likes in here. + * Session directory path, with trailing separator. + * + * This directory is exclusive to the client; when saving the client may + * create any files it likes in this directory. */ const char *session_dir; /** - * client_uuid which must be specified to jack_client_open on session reload. - * client can specify it in the returned commandline as an option, or just save it - * with the state file. + * Client UUID which must be passed to jack_client_open on session load. + * + * The client can specify this in the returned command line, or save it + * in a state file within the session directory. */ const char *client_uuid; /** - * the command_line is the reply of the client. - * it specifies in a platform dependent way, how the client must be restarted upon session reload. + * Reply (set by client): the command line needed to restore the client. * - * probably it should contain ${SESSION_DIR} instead of the actual session dir. - * this would basically make the session dir moveable. + * This is a platform dependent command line. It must contain + * ${SESSION_DIR} instead of the actual session directory path. More + * generally, just as in session files, clients should not include any + * paths outside the session directory here as this makes + * archival/distribution impossible. * - * ownership of the memory is handed to jack. - * initially set to NULL by jack; + * This field is set to NULL by Jack when the event is delivered to the + * client. The client must set to allocated memory that is safe to + * free(). This memory will be freed by jack_session_event_free. */ char *command_line; /** - * flags to be set by the client. normally left 0. + * Reply (set by client): Session flags. */ jack_session_flags_t flags; + + /** + * Future flags. Set to zero for now. + */ + uint32_t future; }; typedef struct _jack_session_event jack_session_event_t; @@ -118,35 +151,42 @@ typedef struct _jack_session_event jack_session_event_t; * Prototype for the client supplied function that is called * whenever a session notification is sent via jack_session_notify(). * - * The session_id must be passed to jack_client_open on session reload (this can be - * done by specifying it somehow on the returned command line). + * Ownership of the memory of @a event is passed to the application. + * It must be freed using jack_session_event_free when its not used anymore. + * + * The client must promptly call jack_session_reply for this event. * - * @param event the event_structure. - * @param arg pointer to a client supplied structure + * @param event The event structure. + * @param arg Pointer to a client supplied structure. */ -typedef void (*JackSessionCallback)(jack_session_event_t *event, void *arg); +typedef void (*JackSessionCallback)(jack_session_event_t *event, + void *arg); /** - * Tell the JACK server to call @a save_callback the session handler wants - * to save. + * Tell the JACK server to call @a session_callback when a session event + * is to be delivered. + * + * setting more than one session_callback per process is probably a design + * error. if you have a multiclient application its more sensible to create + * a jack_client with only a session callback set. * * @return 0 on success, otherwise a non-zero error code */ -int jack_set_session_callback(jack_client_t *client, - JackSessionCallback session_callback, - void *arg) JACK_WEAK_EXPORT; +int jack_set_session_callback (jack_client_t *client, + JackSessionCallback session_callback, + void *arg) JACK_WEAK_EXPORT; /** - * reply to a session_event + * Reply to a session event. * - * this can either be called directly from the callback, or later from a different thread. - * so its possible to just stick the event pointer into a pipe and execute the save code - * from the gui thread. + * This can either be called directly from the callback, or later from a + * different thread. For example, it is possible to push the event through a + * queue and execute the save code from the GUI thread. * * @return 0 on success, otherwise a non-zero error code */ - -int jack_session_reply( jack_client_t *client, jack_session_event_t *event ) JACK_WEAK_EXPORT; +int jack_session_reply (jack_client_t *client, + jack_session_event_t *event) JACK_WEAK_EXPORT; /** @@ -154,74 +194,90 @@ int jack_session_reply( jack_client_t *client, jack_session_event_t *event ) JAC * this also frees the memory used by the command_line pointer. * if its non NULL. */ +void jack_session_event_free (jack_session_event_t *event) JACK_WEAK_EXPORT; -void jack_session_event_free (jack_session_event_t *event); -/*@}*/ +/** + * get the assigned uuid for client. + * safe to call from callback and all other threads. + * memory needs to be freed. + */ +char *jack_client_get_uuid (jack_client_t *client) JACK_WEAK_EXPORT; /** - * @defgroup JackSessionManagerAPI this API is intended for a sessionmanager. - * this API could be server specific. if we dont reach consensus here, - * we can just drop it. - * i know its a bit clumsy. - * but this api isnt required to be as stable as the client api. + * @} + */ + +/** + * @defgroup JackSessionManagerAPI API for a session manager. + * * @{ */ typedef struct { - const char *uuid; - const char *client_name; - const char *command; - jack_session_flags_t flags; + const char *uuid; + const char *client_name; + const char *command; + jack_session_flags_t flags; } jack_session_command_t; /** - * send a save or quit event, to all clients listening for session - * callbacks. the returned strings of the clients are accumulated and - * returned as an array of jack_session_command_t. - * its terminated by ret[i].uuid == NULL - * target == NULL means send to all interested clients. otherwise a clientname + * Send an event to all clients listening for session callbacks. + * + * The returned strings of the clients are accumulated and returned as an array + * of jack_session_command_t. its terminated by ret[i].uuid == NULL target == + * NULL means send to all interested clients. otherwise a clientname */ - -jack_session_command_t *jack_session_notify (jack_client_t* client, - const char *target, - jack_session_event_type_t type, - const char *path ) JACK_WEAK_EXPORT; +jack_session_command_t *jack_session_notify ( + jack_client_t* client, + const char *target, + jack_session_event_type_t type, + const char *path) JACK_WEAK_EXPORT; /** - * free the memory allocated by a session command. + * Free the memory allocated by a session command. */ - void jack_session_commands_free (jack_session_command_t *cmds) JACK_WEAK_EXPORT; /** - * get the sessionid for a client name. - * the sessionmanager needs this to reassociate a client_name to the session_id. + * Get the session ID for a client name. + * The session manager needs this to reassociate a client name to the session_id. */ - -char *jack_get_uuid_for_client_name( jack_client_t *client, const char *client_name ) JACK_WEAK_EXPORT; +char *jack_get_uuid_for_client_name (jack_client_t *client, + const char *client_name) JACK_WEAK_EXPORT; /** - * get the client name for a session_id. - * in order to snapshot the graph connections, the sessionmanager needs to map + * Get the client name for a session_id. + * + * In order to snapshot the graph connections, the session manager needs to map * session_ids to client names. */ - -char *jack_get_client_name_by_uuid( jack_client_t *client, const char *client_uuid ) JACK_WEAK_EXPORT; +char *jack_get_client_name_by_uuid (jack_client_t *client, + const char *client_uuid ) JACK_WEAK_EXPORT; /** - * reserve a client name and associate it to a uuid. - * when a client later call jack_client_open() and specifies the uuid, - * jackd will assign the reserved name. - * this allows a session manager to know in advance under which client name - * its managed clients will appear. + * Reserve a client name and associate it with a UUID. + * + * When a client later calls jack_client_open() and specifies the UUID, jackd + * will assign the reserved name. This allows a session manager to know in + * advance under which client name its managed clients will appear. * * @return 0 on success, otherwise a non-zero error code */ +int +jack_reserve_client_name (jack_client_t *client, + const char *name, + const char *uuid) JACK_WEAK_EXPORT; +/** + * Find out whether a client has set up a session callback. + * + * @return 0 when the client has no session callback, 1 when it has one. + * -1 on error. + */ int -jack_reserve_client_name( jack_client_t *client, const char *name, const char *uuid ) JACK_WEAK_EXPORT; +jack_client_has_session_callback (jack_client_t *client, const char *client_name) JACK_WEAK_EXPORT; #ifdef __cplusplus } diff --git a/common/jack/systemdeps.h b/common/jack/systemdeps.h index eadecd40..ee79ad3f 100644 --- a/common/jack/systemdeps.h +++ b/common/jack/systemdeps.h @@ -36,15 +36,19 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. typedef LONGLONG int64_t; typedef ULONGLONG uint64_t; #endif - #ifndef pthread_t - typedef HANDLE pthread_t; - #endif + /** + * to make jack API independent of different thread implementations, + * we define jack_native_thread_t to HANDLE here. + */ + typedef HANDLE jack_native_thread_t; #elif __MINGW32__ /* MINGW */ #include #include - #ifndef pthread_t - typedef HANDLE pthread_t; - #endif + /** + * to make jack API independent of different thread implementations, + * we define jack_native_thread_t to HANDLE here. + */ + typedef HANDLE jack_native_thread_t; #else /* other compilers ...*/ #include #include @@ -57,6 +61,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include #include + + /** + * to make jack API independent of different thread implementations, + * we define jack_native_thread_t to pthread_t here. + */ + typedef pthread_t jack_native_thread_t; + #endif /* __APPLE__ || __linux__ || __sun__ || sun */ #endif diff --git a/common/jack/thread.h b/common/jack/thread.h index 5d002afa..28c8cd10 100644 --- a/common/jack/thread.h +++ b/common/jack/thread.h @@ -28,6 +28,10 @@ extern "C" #include #include +/* use 512KB stack per thread - the default is way too high to be feasible + * with mlockall() on many systems */ +#define THREAD_STACK 524288 + /** @file thread.h * * Library functions to standardize thread creation for JACK and its @@ -66,7 +70,7 @@ int jack_client_max_real_time_priority (jack_client_t*) JACK_OPTIONAL_WEAK_EXPOR * @returns 0, if successful; EPERM, if the calling process lacks * required realtime privileges; otherwise some other error number. */ -int jack_acquire_real_time_scheduling (pthread_t thread, int priority) JACK_OPTIONAL_WEAK_EXPORT; +int jack_acquire_real_time_scheduling (jack_native_thread_t thread, int priority) JACK_OPTIONAL_WEAK_EXPORT; /** * Create a thread for JACK or one of its clients. The thread is @@ -85,7 +89,7 @@ int jack_acquire_real_time_scheduling (pthread_t thread, int priority) JACK_OPTI * @returns 0, if successful; otherwise some error number. */ int jack_client_create_thread (jack_client_t* client, - pthread_t *thread, + jack_native_thread_t *thread, int priority, int realtime, /* boolean */ void *(*start_routine)(void*), @@ -98,7 +102,7 @@ int jack_client_create_thread (jack_client_t* client, * * @returns 0, if successful; otherwise an error number. */ -int jack_drop_real_time_scheduling (pthread_t thread) JACK_OPTIONAL_WEAK_EXPORT; +int jack_drop_real_time_scheduling (jack_native_thread_t thread) JACK_OPTIONAL_WEAK_EXPORT; /** * Stop the thread, waiting for the thread handler to terminate. @@ -107,7 +111,7 @@ int jack_drop_real_time_scheduling (pthread_t thread) JACK_OPTIONAL_WEAK_EXPORT; * * @returns 0, if successful; otherwise an error number. */ -int jack_client_stop_thread(jack_client_t* client, pthread_t thread) JACK_OPTIONAL_WEAK_EXPORT; +int jack_client_stop_thread(jack_client_t* client, jack_native_thread_t thread) JACK_OPTIONAL_WEAK_EXPORT; /** * Cancel the thread then waits for the thread handler to terminate. @@ -116,7 +120,7 @@ int jack_client_stop_thread(jack_client_t* client, pthread_t thread) JACK_OPTION * * @returns 0, if successful; otherwise an error number. */ - int jack_client_kill_thread(jack_client_t* client, pthread_t thread) JACK_OPTIONAL_WEAK_EXPORT; + int jack_client_kill_thread(jack_client_t* client, jack_native_thread_t thread) JACK_OPTIONAL_WEAK_EXPORT; #ifndef WIN32 diff --git a/common/jack/types.h b/common/jack/types.h index 65c930d7..a7d06983 100644 --- a/common/jack/types.h +++ b/common/jack/types.h @@ -74,6 +74,205 @@ typedef uint32_t jack_port_id_t; typedef uint32_t jack_port_type_id_t; +/** + * @ref jack_options_t bits + */ +enum JackOptions { + + /** + * Null value to use when no option bits are needed. + */ + JackNullOption = 0x00, + + /** + * Do not automatically start the JACK server when it is not + * already running. This option is always selected if + * \$JACK_NO_START_SERVER is defined in the calling process + * environment. + */ + JackNoStartServer = 0x01, + + /** + * Use the exact client name requested. Otherwise, JACK + * automatically generates a unique one, if needed. + */ + JackUseExactName = 0x02, + + /** + * Open with optional (char *) server_name parameter. + */ + JackServerName = 0x04, + + /** + * Load internal client from optional (char *) + * load_name. Otherwise use the @a client_name. + */ + JackLoadName = 0x08, + + /** + * Pass optional (char *) load_init string to the + * jack_initialize() entry point of an internal client. + */ + JackLoadInit = 0x10, + + /** + * pass a SessionID Token this allows the sessionmanager to identify the client again. + */ + JackSessionID = 0x20 +}; + +/** Valid options for opening an external client. */ +#define JackOpenOptions (JackSessionID|JackServerName|JackNoStartServer|JackUseExactName) + +/** Valid options for loading an internal client. */ +#define JackLoadOptions (JackLoadInit|JackLoadName|JackUseExactName) + +/** + * Options for several JACK operations, formed by OR-ing together the + * relevant @ref JackOptions bits. + */ +typedef enum JackOptions jack_options_t; + +/** + * @ref jack_status_t bits + */ +enum JackStatus { + + /** + * Overall operation failed. + */ + JackFailure = 0x01, + + /** + * The operation contained an invalid or unsupported option. + */ + JackInvalidOption = 0x02, + + /** + * The desired client name was not unique. With the @ref + * JackUseExactName option this situation is fatal. Otherwise, + * the name was modified by appending a dash and a two-digit + * number in the range "-01" to "-99". The + * jack_get_client_name() function will return the exact string + * that was used. If the specified @a client_name plus these + * extra characters would be too long, the open fails instead. + */ + JackNameNotUnique = 0x04, + + /** + * The JACK server was started as a result of this operation. + * Otherwise, it was running already. In either case the caller + * is now connected to jackd, so there is no race condition. + * When the server shuts down, the client will find out. + */ + JackServerStarted = 0x08, + + /** + * Unable to connect to the JACK server. + */ + JackServerFailed = 0x10, + + /** + * Communication error with the JACK server. + */ + JackServerError = 0x20, + + /** + * Requested client does not exist. + */ + JackNoSuchClient = 0x40, + + /** + * Unable to load internal client + */ + JackLoadFailure = 0x80, + + /** + * Unable to initialize client + */ + JackInitFailure = 0x100, + + /** + * Unable to access shared memory + */ + JackShmFailure = 0x200, + + /** + * Client's protocol version does not match + */ + JackVersionError = 0x400, + + /** + * Backend error + */ + JackBackendError = 0x800, + + /** + * Client zombified failure + */ + JackClientZombie = 0x1000 +}; + +/** + * Status word returned from several JACK operations, formed by + * OR-ing together the relevant @ref JackStatus bits. + */ +typedef enum JackStatus jack_status_t; + +/** + * @ref jack_latency_callback_mode_t + */ +enum JackLatencyCallbackMode { + + /** + * Latency Callback for Capture Latency. + * Input Ports have their latency value setup. + * In the Callback the client needs to set the latency of the output ports + */ + JackCaptureLatency, + + /** + * Latency Callback for Playback Latency. + * Output Ports have their latency value setup. + * In the Callback the client needs to set the latency of the input ports + */ + JackPlaybackLatency + +}; + +/** + * Type of Latency Callback (Capture or Playback) + */ +typedef enum JackLatencyCallbackMode jack_latency_callback_mode_t; + +/** + * Prototype for the client supplied function that is called + * by the engine when port latencies need to be recalculated + * + * @param mode playback or capture latency + * @param arg pointer to a client supplied data + * + * @return zero on success, non-zero on error + */ +typedef void (*JackLatencyCallback)(jack_latency_callback_mode_t mode, void *arg); + +/** + * the new latency API operates on Ranges. + */ +struct _jack_latency_range +{ + /** + * minimum latency + */ + jack_nframes_t min; + /** + * maximum latency + */ + jack_nframes_t max; +}; + +typedef struct _jack_latency_range jack_latency_range_t; + /** * Prototype for the client supplied function that is called * by the engine anytime there is work to be done. @@ -164,9 +363,12 @@ typedef int (*JackSampleRateCallback)(jack_nframes_t nframes, void *arg); * Prototype for the client supplied function that is called * whenever a port is registered or unregistered. * - * @param arg pointer to a client supplied structure + * @param port the ID of the port + * @param arg pointer to a client supplied data + * @param register non-zero if the port is being registered, + * zero if the port is being unregistered */ -typedef void (*JackPortRegistrationCallback)(jack_port_id_t port, int, void *arg); +typedef void (*JackPortRegistrationCallback)(jack_port_id_t port, int register, void *arg); /** * Prototype for the client supplied function that is called @@ -177,7 +379,7 @@ typedef void (*JackPortRegistrationCallback)(jack_port_id_t port, int, void *arg * zero if the client is being unregistered * @param arg pointer to a client supplied structure */ -typedef void (*JackClientRegistrationCallback)(const char* name, int val, void *arg); +typedef void (*JackClientRegistrationCallback)(const char* name, int register, void *arg); /** * Prototype for the client supplied function that is called @@ -214,7 +416,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 @@ -225,6 +427,21 @@ typedef void (*JackFreewheelCallback)(int starting, void *arg); */ typedef void (*JackShutdownCallback)(void *arg); +/** + * Prototype for the client supplied function that is called + * 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 + */ +typedef void (*JackInfoShutdownCallback)(jack_status_t code, const char* reason, void *arg); + /** * Used for the type argument of jack_port_register() for default * audio ports and midi ports. @@ -295,161 +512,9 @@ 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 -}; - -/** - * @ref jack_options_t bits - */ -enum JackOptions { - - /** - * Null value to use when no option bits are needed. - */ - JackNullOption = 0x00, - - /** - * Do not automatically start the JACK server when it is not - * already running. This option is always selected if - * \$JACK_NO_START_SERVER is defined in the calling process - * environment. - */ - JackNoStartServer = 0x01, - - /** - * Use the exact client name requested. Otherwise, JACK - * automatically generates a unique one, if needed. - */ - JackUseExactName = 0x02, - - /** - * Open with optional (char *) server_name parameter. - */ - JackServerName = 0x04, - - /** - * Load internal client from optional (char *) - * load_name. Otherwise use the @a client_name. - */ - JackLoadName = 0x08, - - /** - * Pass optional (char *) load_init string to the - * jack_initialize() entry point of an internal client. - */ - JackLoadInit = 0x10, - - /** - * pass a SessionID Token this allows the sessionmanager to identify the client again. - */ - JackSessionID = 0x20 -}; - -/** Valid options for opening an external client. */ -#define JackOpenOptions (JackSessionID|JackServerName|JackNoStartServer|JackUseExactName) - -/** Valid options for loading an internal client. */ -#define JackLoadOptions (JackLoadInit|JackLoadName|JackUseExactName) - -/** - * Options for several JACK operations, formed by OR-ing together the - * relevant @ref JackOptions bits. - */ -typedef enum JackOptions jack_options_t; - -/** - * @ref jack_status_t bits - */ -enum JackStatus { - - /** - * Overall operation failed. - */ - JackFailure = 0x01, - - /** - * The operation contained an invalid or unsupported option. - */ - JackInvalidOption = 0x02, - - /** - * The desired client name was not unique. With the @ref - * JackUseExactName option this situation is fatal. Otherwise, - * the name was modified by appending a dash and a two-digit - * number in the range "-01" to "-99". The - * jack_get_client_name() function will return the exact string - * that was used. If the specified @a client_name plus these - * extra characters would be too long, the open fails instead. - */ - JackNameNotUnique = 0x04, - - /** - * The JACK server was started as a result of this operation. - * Otherwise, it was running already. In either case the caller - * is now connected to jackd, so there is no race condition. - * When the server shuts down, the client will find out. - */ - JackServerStarted = 0x08, - - /** - * Unable to connect to the JACK server. - */ - JackServerFailed = 0x10, - - /** - * Communication error with the JACK server. - */ - JackServerError = 0x20, - /** - * Requested client does not exist. - */ - JackNoSuchClient = 0x40, - - /** - * Unable to load internal client - */ - JackLoadFailure = 0x80, - - /** - * Unable to initialize client - */ - JackInitFailure = 0x100, - - /** - * Unable to access shared memory - */ - JackShmFailure = 0x200, - - /** - * Client's protocol version does not match - */ - JackVersionError = 0x400, - - /** - * Backend error - */ - JackBackendError = 0x800, - - /** - * Client zombified failure - */ - JackClientZombie = 0x1000 }; -/** - * Status word returned from several JACK operations, formed by - * OR-ing together the relevant @ref JackStatus bits. - */ -typedef enum JackStatus jack_status_t; - /** * Transport states. */ @@ -476,7 +541,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 */ @@ -666,19 +731,5 @@ typedef struct { } jack_transport_info_t; -/** - * Prototype for the client supplied function that is called - * 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 - */ -typedef void (*JackInfoShutdownCallback)(jack_status_t code, const char* reason, void *arg); #endif /* __jack_types_h__ */ diff --git a/common/jack/weakjack.h b/common/jack/weakjack.h index 11d2acaa..83f05ab2 100644 --- a/common/jack/weakjack.h +++ b/common/jack/weakjack.h @@ -1,18 +1,18 @@ /* Copyright (C) 2010 Paul Davis - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 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. */ @@ -20,10 +20,63 @@ #ifndef __weakjack_h__ #define __weakjack_h__ +/** + * @defgroup WeakLinkage managing support for newer/older versions of JACK + * @{ One challenge faced by developers is that of taking advantage of new features introduced in new versions of [ JACK ] while still + * supporting older versions of the system. Normally, if an application uses a new feature in a library/API, it is unable to run on + * earlier versions of the library/API that do not support that feature. Such applications would either fail to launch or crash when + * an attempt to use the feature was made. This problem cane be solved using weakly-linked symbols. + * + * When a symbol in a framework is defined as weakly linked, the symbol does not have to be present at runtime for a process to + * continue running. The static linker identifies a weakly linked symbol as such in any code module that references the symbol. The + * dynamic linker uses this same information at runtime to determine whether a process can continue running. If a weakly linked symbol + * is not present in the framework, the code module can continue to run as long as it does not reference the symbol. However, if the + * symbol is present, the code can use it normally. + * + * (adapted from: http://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html) + * + * A concrete example will help. Suppose that someone uses a version + * of a JACK client we'll call "Jill". Jill was linked against a version + * of JACK that contains a newer part of the API (say, jack_set_latency_callback()) + * and would like to use it if it is available. + * + * When Jill is run on a system that has a suitably "new" version of + * JACK, this function will be available entirely normally. But if Jill + * is run on a system with an old version of JACK, the function isn't + * available. + * + * With normal symbol linkage, this would create a startup error whenever + * someone tries to run Jill with the "old" version of JACK. However, functions + * added to JACK after version 0.116.2 are all declared to have "weak" linkage + * which means that their abscence doesn't cause an error during program + * startup. Instead, Jill can test whether or not the symbol jack_set_latency_callback + * is null or not. If its null, it means that the JACK installed on this machine + * is too old to support this function. If its not null, then Jill can use it + * just like any other function in the API. For example: + * + * \code + * if (jack_set_latency_callback) { + * jack_set_latency_callback (jill_client, jill_latency_callback, arg); + * } + * \endcode + * + * However, there are clients that may want to use this approach to parts of the + * the JACK API that predate 0.116.2. For example, they might want to see if even + * really old basic parts of the API like jack_client_open() exist at runtime. + * + * Such clients should include before any other JACK header. + * This will make the \b entire JACK API be subject to weak linkage, so that any + * and all functions can be checked for existence at runtime. It is important + * to understand that very few clients need to do this - if you use this + * feature you should have a clear reason to do so. + * + * + */ + #ifndef JACK_OPTIONAL_WEAK_EXPORT /* JACK_OPTIONAL_WEAK_EXPORT needs to be a macro which - expands into a compiler directive. If non-null, the directive - must tell the compiler to arrange for weak linkage of + expands into a compiler directive. If non-null, the directive + must tell the compiler to arrange for weak linkage of the symbol it used with. For this to work fully may require linker arguments for the client as well. */ @@ -49,4 +102,6 @@ #endif #endif +/*@}*/ + #endif /* weakjack */ diff --git a/common/jack/weakmacros.h b/common/jack/weakmacros.h index b3207f6a..d5818b34 100644 --- a/common/jack/weakmacros.h +++ b/common/jack/weakmacros.h @@ -1,18 +1,18 @@ /* Copyright (C) 2010 Paul Davis - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 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. */ @@ -23,27 +23,31 @@ /************************************************************* * NOTE: JACK_WEAK_EXPORT ***MUST*** be used on every function * added to the JACK API after the 0.116.2 release. - * - * Functions that predate this release are marked with + * + * Functions that predate this release are marked with * JACK_WEAK_OPTIONAL_EXPORT which can be defined at compile * time in a variety of ways. The default definition is empty, * so that these symbols get normal linkage. If you wish to - * use all JACK symbols with weak linkage, include + * use all JACK symbols with weak linkage, include * before jack.h. *************************************************************/ #ifndef JACK_WEAK_EXPORT #ifdef __GNUC__ /* JACK_WEAK_EXPORT needs to be a macro which - expands into a compiler directive. If non-null, the directive - must tell the compiler to arrange for weak linkage of + expands into a compiler directive. If non-null, the directive + must tell the compiler to arrange for weak linkage of the symbol it used with. For this to work full may require linker arguments in the client as well. */ #define JACK_WEAK_EXPORT __attribute__((weak)) #else /* Add other things here for non-gcc platforms */ -#define JACK_WEAK_EXPORT + +#ifdef WIN32 +#define JACK_WEAK_EXPORT +#endif + #endif #endif @@ -54,9 +58,13 @@ #ifndef JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT #ifdef __GNUC__ #define JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT __attribute__((__deprecated__)) -#else +#else /* Add other things here for non-gcc platforms */ -#define JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT + +#ifdef WIN32 +#define JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT +#endif + #endif /* __GNUC__ */ #endif diff --git a/common/netjack.c b/common/netjack.c index 077fad8c..ce97da5c 100644 --- a/common/netjack.c +++ b/common/netjack.c @@ -25,7 +25,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: net_driver.c,v 1.17 2006/04/16 20:16:10 torbenh Exp $ */ - #include #include #include @@ -48,8 +47,6 @@ $Id: net_driver.c,v 1.17 2006/04/16 20:16:10 torbenh Exp $ #include #endif -#include "netjack.h" - #ifdef __linux__ #include "config.h" #endif @@ -58,15 +55,11 @@ $Id: net_driver.c,v 1.17 2006/04/16 20:16:10 torbenh Exp $ #include #endif -#if HAVE_CELT -#include -#endif - #include "netjack.h" #include "netjack_packet.h" // JACK2 -#include "jack/control.h" +#include "control.h" #define MIN(x,y) ((x)<(y) ? (x) : (y)) @@ -105,8 +98,8 @@ int netjack_wait( netjack_driver_state_t *netj ) netj->expected_framecnt += 1; } else { // starting up.... lets look into the packetcache, and fetch the highest packet. - packet_cache_drain_socket( global_packcache, netj->sockfd ); - if( packet_cache_get_highest_available_framecnt( global_packcache, &next_frame_avail ) ) { + packet_cache_drain_socket( netj->packcache, netj->sockfd ); + if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail ) ) { netj->expected_framecnt = next_frame_avail; netj->expected_framecnt_valid = 1; } else { @@ -122,7 +115,7 @@ int netjack_wait( netjack_driver_state_t *netj ) // then poll (have deadline calculated) // then drain socket, rinse and repeat. while(1) { - if( packet_cache_get_next_available_framecnt( global_packcache, netj->expected_framecnt, &next_frame_avail) ) { + if( packet_cache_get_next_available_framecnt( netj->packcache, netj->expected_framecnt, &next_frame_avail) ) { if( next_frame_avail == netj->expected_framecnt ) { we_have_the_expected_frame = 1; if( !netj->always_deadline ) @@ -133,13 +126,13 @@ int netjack_wait( netjack_driver_state_t *netj ) break; } - packet_cache_drain_socket( global_packcache, netj->sockfd ); + packet_cache_drain_socket( netj->packcache, netj->sockfd ); } // check if we know who to send our packets too. if (!netj->srcaddress_valid) - if( global_packcache->master_address_valid ) { - memcpy (&(netj->syncsource_address), &(global_packcache->master_address), sizeof( struct sockaddr_in ) ); + if( netj->packcache->master_address_valid ) { + memcpy (&(netj->syncsource_address), &(netj->packcache->master_address), sizeof( struct sockaddr_in ) ); netj->srcaddress_valid = 1; } @@ -161,7 +154,7 @@ int netjack_wait( netjack_driver_state_t *netj ) else netj->time_to_deadline = 0; - packet_cache_retreive_packet_pointer( global_packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize , &packet_recv_time_stamp); + packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize , &packet_recv_time_stamp); pkthdr = (jacknet_packet_header *) netj->rx_buf; packet_header_ntoh(pkthdr); netj->deadline_goodness = (int)pkthdr->sync_state; @@ -203,7 +196,7 @@ int netjack_wait( netjack_driver_state_t *netj ) // lets check if we have the next packets, we will just run a cycle without data. // in that case. - if( packet_cache_get_next_available_framecnt( global_packcache, netj->expected_framecnt, &next_frame_avail) ) + if( packet_cache_get_next_available_framecnt( netj->packcache, netj->expected_framecnt, &next_frame_avail) ) { jack_nframes_t offset = next_frame_avail - netj->expected_framecnt; @@ -221,7 +214,7 @@ int netjack_wait( netjack_driver_state_t *netj ) // I also found this happening, when the packet queue, is too full. // but wtf ? use a smaller latency. this link can handle that ;S - if( packet_cache_get_fill( global_packcache, netj->expected_framecnt ) > 80.0 ) + if( packet_cache_get_fill( netj->packcache, netj->expected_framecnt ) > 80.0 ) netj->next_deadline -= netj->period_usecs/2; @@ -229,7 +222,7 @@ int netjack_wait( netjack_driver_state_t *netj ) // the diff is too high. but we have a packet in the future. // lets resync. netj->expected_framecnt = next_frame_avail; - packet_cache_retreive_packet_pointer( global_packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize, NULL ); + packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize, NULL ); pkthdr = (jacknet_packet_header *) netj->rx_buf; packet_header_ntoh(pkthdr); //netj->deadline_goodness = 0; @@ -257,7 +250,7 @@ int netjack_wait( netjack_driver_state_t *netj ) // i will make the packet cache drop redundant packets, // that have already been retreived. // - if( packet_cache_get_highest_available_framecnt( global_packcache, &next_frame_avail) ) { + if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail) ) { if( next_frame_avail == (netj->expected_framecnt - 1) ) { // Ok. the last packet is there now. // and it had not been retrieved. @@ -277,9 +270,9 @@ int netjack_wait( netjack_driver_state_t *netj ) // But now we can check for any new frame available. // - if( packet_cache_get_highest_available_framecnt( global_packcache, &next_frame_avail) ) { + if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail) ) { netj->expected_framecnt = next_frame_avail; - packet_cache_retreive_packet_pointer( global_packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize, NULL ); + packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize, NULL ); pkthdr = (jacknet_packet_header *) netj->rx_buf; packet_header_ntoh(pkthdr); netj->deadline_goodness = pkthdr->sync_state; @@ -300,7 +293,7 @@ int netjack_wait( netjack_driver_state_t *netj ) // reply address changes port. if (netj->num_lost_packets > 200 ) { netj->srcaddress_valid = 0; - packet_cache_reset_master_address( global_packcache ); + packet_cache_reset_master_address( netj->packcache ); } } } @@ -369,6 +362,21 @@ void netjack_attach( netjack_driver_state_t *netj ) int port_flags; + if( netj->bitdepth == CELT_MODE ) + { +#if HAVE_CELT +#if HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 + celt_int32 lookahead; + netj->celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); +#else + celt_int32_t lookahead; + netj->celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL ); +#endif + celt_mode_info( netj->celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); + netj->codec_latency = 2*lookahead; +#endif + } + if (netj->handle_transport_sync) jack_set_sync_callback(netj->client, (JackSyncCallback) net_driver_sync_cb, NULL); @@ -390,17 +398,11 @@ void netjack_attach( netjack_driver_state_t *netj ) if( netj->bitdepth == CELT_MODE ) { #if HAVE_CELT -#if HAVE_CELT_API_0_7 - celt_int32 lookahead; - CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); - netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); +#if HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 + netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode, 1, NULL ) ); #else - celt_int32_t lookahead; - CELTMode *celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL ); - netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( celt_mode ) ); + netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode ) ); #endif - celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); - netj->codec_latency = 2*lookahead; #endif } else { #if HAVE_SAMPLERATE @@ -408,6 +410,7 @@ void netjack_attach( netjack_driver_state_t *netj ) #endif } } + for (chn = netj->capture_channels_audio; chn < netj->capture_channels; chn++) { snprintf (buf, sizeof(buf) - 1, "capture_%u", chn + 1); @@ -441,7 +444,7 @@ void netjack_attach( netjack_driver_state_t *netj ) jack_slist_append (netj->playback_ports, port); if( netj->bitdepth == CELT_MODE ) { #if HAVE_CELT -#if HAVE_CELT_API_0_7 +#if HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); #else @@ -479,7 +482,6 @@ void netjack_detach( netjack_driver_state_t *netj ) { JSList * node; - for (node = netj->capture_ports; node; node = jack_slist_next (node)) jack_port_unregister (netj->client, ((jack_port_t *) node->data)); @@ -487,12 +489,57 @@ void netjack_detach( netjack_driver_state_t *netj ) jack_slist_free (netj->capture_ports); netj->capture_ports = NULL; + for (node = netj->capture_srcs; node; node = jack_slist_next (node)) + { +#if HAVE_CELT + if( netj->bitdepth == CELT_MODE ) + { + CELTDecoder * decoder = node->data; + celt_decoder_destroy(decoder); + } + else +#endif + { +#if HAVE_SAMPLERATE + SRC_STATE * src = node->data; + src_delete(src); +#endif + } + } + jack_slist_free (netj->capture_srcs); + netj->playback_srcs = NULL; + for (node = netj->playback_ports; node; node = jack_slist_next (node)) jack_port_unregister (netj->client, ((jack_port_t *) node->data)); jack_slist_free (netj->playback_ports); netj->playback_ports = NULL; + + for (node = netj->playback_srcs; node; node = jack_slist_next (node)) + { +#if HAVE_CELT + if( netj->bitdepth == CELT_MODE ) + { + CELTEncoder * encoder = node->data; + celt_encoder_destroy(encoder); + } + else +#endif + { +#if HAVE_SAMPLERATE + SRC_STATE * src = node->data; + src_delete(src); +#endif + } + } + jack_slist_free (netj->playback_srcs); + netj->playback_srcs = NULL; + +#if HAVE_CELT + if( netj->bitdepth == CELT_MODE ) + celt_mode_destroy(netj->celt_mode); +#endif } @@ -574,8 +621,8 @@ void netjack_release( netjack_driver_state_t *netj ) close( netj->sockfd ); close( netj->outsockfd ); - packet_cache_free( global_packcache ); - global_packcache = NULL; + packet_cache_free( netj->packcache ); + netj->packcache = NULL; } int @@ -585,13 +632,7 @@ netjack_startup( netjack_driver_state_t *netj ) struct sockaddr_in address; // Now open the socket, and wait for the first packet to arrive... netj->sockfd = socket (AF_INET, SOCK_DGRAM, 0); - #ifdef WIN32 - u_long parm = 1; - DWORD bufsize = 262144; - //ioctlsocket( netj->sockfd, FIONBIO, &parm ); - setsockopt( netj->sockfd, SOL_SOCKET, SO_RCVBUF, (char *)&bufsize, sizeof(bufsize) ); - setsockopt( netj->sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&bufsize, sizeof(bufsize) ); if (netj->sockfd == INVALID_SOCKET) #else if (netj->sockfd == -1) @@ -632,6 +673,10 @@ netjack_startup( netjack_driver_state_t *netj ) //jack_info ("*** IMPORTANT *** Dont connect a client to jackd until the driver is attached to a clock source !!!"); while(1) { + if( ! netjack_poll( netj->sockfd, 1000 ) ) { + jack_info ("Waiting aborted"); + return -1; + } first_pack_len = recvfrom (netj->sockfd, (char *)first_packet, sizeof (jacknet_packet_header), 0, (struct sockaddr*) & netj->syncsource_address, &address_size); #ifdef WIN32 if( first_pack_len == -1 ) { @@ -735,7 +780,7 @@ netjack_startup( netjack_driver_state_t *netj ) } netj->rx_bufsize = sizeof (jacknet_packet_header) + netj->net_period_down * netj->capture_channels * get_sample_size (netj->bitdepth); - global_packcache = packet_cache_new (netj->latency + 50, netj->rx_bufsize, netj->mtu); + netj->packcache = packet_cache_new (netj->latency + 50, netj->rx_bufsize, netj->mtu); netj->expected_framecnt_valid = 0; netj->num_lost_packets = 0; diff --git a/common/netjack.h b/common/netjack.h index edac28a0..2bdd092c 100644 --- a/common/netjack.h +++ b/common/netjack.h @@ -30,6 +30,10 @@ #include "jack/jslist.h" +#if HAVE_CELT +#include +#endif + //#include #ifdef __cplusplus @@ -37,6 +41,8 @@ extern "C" { #endif +struct _packet_cache; + typedef struct _netjack_driver_state netjack_driver_state_t; struct _netjack_driver_state { @@ -106,6 +112,10 @@ struct _netjack_driver_state { unsigned int resample_factor; unsigned int resample_factor_up; int jitter_val; + struct _packet_cache * packcache; +#if HAVE_CELT + CELTMode *celt_mode; +#endif }; int netjack_wait( netjack_driver_state_t *netj ); diff --git a/common/netjack_packet.c b/common/netjack_packet.c index dfe3b9e2..d03d49f0 100644 --- a/common/netjack_packet.c +++ b/common/netjack_packet.c @@ -75,7 +75,7 @@ #include "netjack_packet.h" // JACK2 specific. -#include "jack/control.h" +#include "control.h" #ifdef NO_JACK_ERROR #define jack_error printf @@ -83,8 +83,6 @@ int fraggo = 0; -packet_cache *global_packcache = NULL; - void packet_header_hton (jacknet_packet_header *pkthdr) { @@ -388,7 +386,7 @@ netjack_poll_deadline (int sockfd, jack_time_t deadline) #if HAVE_PPOLL timeout_spec.tv_nsec = (deadline - now) * 1000; #else - timeout = (deadline - now + 500) / 1000; + timeout = lrintf( (float)(deadline - now) / 1000.0 ); #endif @@ -565,7 +563,7 @@ packet_cache_drain_socket( packet_cache *pcache, int sockfd ) if( pcache->last_framecnt_retreived_valid && (framecnt <= pcache->last_framecnt_retreived )) continue; - cpack = packet_cache_get_packet (global_packcache, framecnt); + cpack = packet_cache_get_packet (pcache, framecnt); cache_packet_add_fragment (cpack, rx_packet, rcv_len); cpack->recv_timestamp = jack_get_time(); } @@ -774,61 +772,6 @@ packet_cache_find_latency( packet_cache *pcache, jack_nframes_t expected_framecn return retval; } // fragmented packet IO -int -netjack_recvfrom (int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, size_t *addr_size, int mtu) -{ - int retval; - socklen_t from_len = *addr_size; - if (pkt_size <= mtu) { - retval = recvfrom (sockfd, packet_buf, pkt_size, flags, addr, &from_len); - *addr_size = from_len; - return retval; - } - - char *rx_packet = alloca (mtu); - jacknet_packet_header *pkthdr = (jacknet_packet_header *) rx_packet; - int rcv_len; - jack_nframes_t framecnt; - cache_packet *cpack; - do - { - rcv_len = recvfrom (sockfd, rx_packet, mtu, 0, addr, &from_len); - if (rcv_len < 0) - return rcv_len; - framecnt = ntohl (pkthdr->framecnt); - cpack = packet_cache_get_packet (global_packcache, framecnt); - cache_packet_add_fragment (cpack, rx_packet, rcv_len); - } while (!cache_packet_is_complete (cpack)); - memcpy (packet_buf, cpack->packet_buf, pkt_size); - cache_packet_reset (cpack); - *addr_size = from_len; - return pkt_size; -} - -int -netjack_recv (int sockfd, char *packet_buf, int pkt_size, int flags, int mtu) -{ - if (pkt_size <= mtu) - return recv (sockfd, packet_buf, pkt_size, flags); - char *rx_packet = alloca (mtu); - jacknet_packet_header *pkthdr = (jacknet_packet_header *) rx_packet; - int rcv_len; - jack_nframes_t framecnt; - cache_packet *cpack; - do - { - rcv_len = recv (sockfd, rx_packet, mtu, flags); - if (rcv_len < 0) - return rcv_len; - framecnt = ntohl (pkthdr->framecnt); - cpack = packet_cache_get_packet (global_packcache, framecnt); - cache_packet_add_fragment (cpack, rx_packet, rcv_len); - } while (!cache_packet_is_complete (cpack)); - memcpy (packet_buf, cpack->packet_buf, pkt_size); - cache_packet_reset (cpack); - return pkt_size; -} - void netjack_sendto (int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, int addr_size, int mtu) { @@ -1427,10 +1370,17 @@ render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_peri // audio port, decode celt data. CELTDecoder *decoder = src_node->data; +#if HAVE_CELT_API_0_8 + if( !packet_payload ) + celt_decode_float( decoder, NULL, net_period_down, buf, nframes ); + else + celt_decode_float( decoder, packet_bufX, net_period_down, buf, nframes ); +#else if( !packet_payload ) celt_decode_float( decoder, NULL, net_period_down, buf ); else celt_decode_float( decoder, packet_bufX, net_period_down, buf ); +#endif src_node = jack_slist_next (src_node); } @@ -1472,7 +1422,11 @@ render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs float *floatbuf = alloca (sizeof(float) * nframes ); memcpy( floatbuf, buf, nframes*sizeof(float) ); CELTEncoder *encoder = src_node->data; +#if HAVE_CELT_API_0_8 + encoded_bytes = celt_encode_float( encoder, floatbuf, nframes, packet_bufX, net_period_up ); +#else encoded_bytes = celt_encode_float( encoder, floatbuf, NULL, packet_bufX, net_period_up ); +#endif if( encoded_bytes != net_period_up ) printf( "something in celt changed. netjack needs to be changed to handle this.\n" ); src_node = jack_slist_next( src_node ); diff --git a/common/netjack_packet.h b/common/netjack_packet.h index 4617310e..c60f7bec 100644 --- a/common/netjack_packet.h +++ b/common/netjack_packet.h @@ -107,8 +107,6 @@ struct _packet_cache int last_framecnt_retreived_valid; }; -extern packet_cache *global_packcache; - // fragment cache function prototypes // XXX: Some of these are private. packet_cache *packet_cache_new(int num_packets, int pkt_size, int mtu); @@ -152,10 +150,6 @@ void render_jack_ports_to_payload(int bitdepth, JSList *playback_ports, JSList * // This one waits forever. an is not using ppoll int netjack_poll(int sockfd, int timeout); -// TODO: these are deprecated. -//int netjack_recvfrom(int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, socklen_t *addr_size, int mtu); -//int netjack_recv(int sockfd, char *packet_buf, int pkt_size, int flags, int mtu); - void decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf); void encode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf); #ifdef __cplusplus diff --git a/common/timestamps.c b/common/timestamps.c index 7a48e8a9..d8a2cda9 100644 --- a/common/timestamps.c +++ b/common/timestamps.c @@ -1,24 +1,25 @@ /* Copyright (C) 2002-2003 Paul Davis - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 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. */ #include #include +#include #include "timestamps.h" #include "JackTime.h" @@ -60,7 +61,7 @@ jack_dump_timestamps (FILE *out) unsigned long i; for (i = 0; i < timestamp_index; ++i) { - fprintf (out, "%-.32s %" PRIu64 " %" PRIu64, + fprintf (out, "%-.32s %" PRIu64 " %" PRIu64, timestamps[i].what, timestamps[i].when, timestamps[i].when - timestamps[0].when); if (i > 0) { diff --git a/example-clients/alsa_in.c b/example-clients/alsa_in.c index 85259cde..7007fffd 100644 --- a/example-clients/alsa_in.c +++ b/example-clients/alsa_in.c @@ -11,12 +11,11 @@ #include #include -#include #include #include #include -#include +#include #include "alsa/asoundlib.h" @@ -77,6 +76,12 @@ volatile float output_diff = 0.0; snd_pcm_uframes_t real_buffer_size; snd_pcm_uframes_t real_period_size; +// buffers + +char *tmpbuf; +char *outbuf; +float *resampbuf; + // format selection, and corresponding functions from memops in a nice set of structs. typedef struct alsa_format { @@ -307,8 +312,6 @@ double hann( double x ) */ int process (jack_nframes_t nframes, void *arg) { - char *outbuf; - float *resampbuf; int rlen; int err; snd_pcm_sframes_t delay = target_delay; @@ -322,10 +325,15 @@ int process (jack_nframes_t nframes, void *arg) { // this is for compensating xruns etc... if( delay > (target_delay+max_diff) ) { - char *tmp = alloca( (delay-target_delay) * formats[format].sample_size * num_channels ); - snd_pcm_readi( alsa_handle, tmp, delay-target_delay ); + output_new_delay = (int) delay; + while ((delay-target_delay) > 0) { + snd_pcm_uframes_t to_read = ((delay-target_delay) > 512) ? 512 : (delay-target_delay); + snd_pcm_readi( alsa_handle, tmpbuf, to_read ); + delay -= to_read; + } + delay = target_delay; // Set the resample_rate... we need to adjust the offset integral, to do this. @@ -399,13 +407,6 @@ int process (jack_nframes_t nframes, void *arg) { // Calculate resample_mean so we can init ourselves to saner values. resample_mean = 0.9999 * resample_mean + 0.0001 * current_resample_factor; - /* - * now this should do it... - */ - - outbuf = alloca( rlen * formats[format].sample_size * num_channels ); - - resampbuf = alloca( rlen * sizeof( float ) ); // get the data... again: @@ -465,6 +466,32 @@ again: return 0; } +/** + * the latency callback. + * sets up the latencies on the ports. + */ + +void +latency_cb (jack_latency_callback_mode_t mode, void *arg) +{ + jack_latency_range_t range; + JSList *node; + + range.min = range.max = target_delay; + + if (mode == JackCaptureLatency) { + for (node = capture_ports; node; node = jack_slist_next (node)) { + jack_port_t *port = node->data; + jack_port_set_latency_range (port, mode, &range); + } + } else { + for (node = playback_ports; node; node = jack_slist_next (node)) { + jack_port_t *port = node->data; + jack_port_set_latency_range (port, mode, &range); + } + } +} + /** * Allocate the necessary jack ports... @@ -661,6 +688,8 @@ int main (int argc, char *argv[]) { jack_on_shutdown (client, jack_shutdown, 0); + if (jack_set_latency_callback) + jack_set_latency_callback (client, latency_cb, 0); // get jack sample_rate @@ -716,6 +745,17 @@ int main (int argc, char *argv[]) { // alloc input ports, which are blasted out to alsa... alloc_ports( num_channels, 0 ); + outbuf = malloc( num_periods * period_size * formats[format].sample_size * num_channels ); + resampbuf = malloc( num_periods * period_size * sizeof( float ) ); + tmpbuf = malloc( 512 * formats[format].sample_size * num_channels ); + + if ((outbuf == NULL) || (resampbuf == NULL) || (tmpbuf == NULL)) + { + fprintf( stderr, "no memory for buffers.\n" ); + exit(20); + } + + memset( tmpbuf, 0, 512 * formats[format].sample_size * num_channels); /* tell the JACK server that we are ready to roll */ diff --git a/example-clients/alsa_out.c b/example-clients/alsa_out.c index 85b00e12..0dfb839f 100644 --- a/example-clients/alsa_out.c +++ b/example-clients/alsa_out.c @@ -11,12 +11,11 @@ #include #include -#include #include #include #include -#include +#include #include "alsa/asoundlib.h" @@ -35,6 +34,7 @@ snd_pcm_t *alsa_handle; int jack_sample_rate; int jack_buffer_size; +int quit = 0; double resample_mean = 1.0; double static_resample_factor = 1.0; double resample_lower_limit = 0.25; @@ -45,7 +45,6 @@ double *window_array; int offset_differential_index = 0; double offset_integral = 0; -int quit = 0; // ------------------------------------------------------ commandline parameters @@ -77,6 +76,12 @@ volatile float output_diff = 0.0; snd_pcm_uframes_t real_buffer_size; snd_pcm_uframes_t real_period_size; +// buffers + +char *tmpbuf; +char *outbuf; +float *resampbuf; + // format selection, and corresponding functions from memops in a nice set of structs. typedef struct alsa_format { @@ -90,6 +95,7 @@ typedef struct alsa_format { alsa_format_t formats[] = { { SND_PCM_FORMAT_FLOAT_LE, 4, sample_move_dS_floatLE, sample_move_floatLE_sSs, "float" }, { SND_PCM_FORMAT_S32, 4, sample_move_d32u24_sS, sample_move_dS_s32u24, "32bit" }, + { SND_PCM_FORMAT_S24_3LE, 3, sample_move_d24_sS, sample_move_dS_s24, "24bit - real" }, { SND_PCM_FORMAT_S24, 4, sample_move_d24_sS, sample_move_dS_s24, "24bit" }, { SND_PCM_FORMAT_S16, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit" } }; @@ -311,8 +317,6 @@ double hann( double x ) */ int process (jack_nframes_t nframes, void *arg) { - char *outbuf; - float *resampbuf; int rlen; int err; snd_pcm_sframes_t delay = target_delay; @@ -321,7 +325,6 @@ int process (jack_nframes_t nframes, void *arg) { delay = (num_periods*period_size)-snd_pcm_avail( alsa_handle ) ; delay -= jack_frames_since_cycle_start( client ); - delay += jack_get_buffer_size( client ) / 2; // Do it the hard way. // this is for compensating xruns etc... @@ -340,12 +343,15 @@ int process (jack_nframes_t nframes, void *arg) { offset_array[i] = 0.0; } if( delay < (target_delay-max_diff) ) { - char *tmp = alloca( (target_delay-delay) * formats[format].sample_size * num_channels ); - memset( tmp, 0, formats[format].sample_size * num_channels * (target_delay-delay) ); - snd_pcm_writei( alsa_handle, tmp, target_delay-delay ); output_new_delay = (int) delay; + while ((target_delay-delay) > 0) { + snd_pcm_uframes_t to_write = ((target_delay-delay) > 512) ? 512 : (target_delay-delay); + snd_pcm_writei( alsa_handle, tmpbuf, to_write ); + delay += to_write; + } + delay = target_delay; // Set the resample_rate... we need to adjust the offset integral, to do this. @@ -463,6 +469,32 @@ again: return 0; } +/** + * the latency callback. + * sets up the latencies on the ports. + */ + +void +latency_cb (jack_latency_callback_mode_t mode, void *arg) +{ + jack_latency_range_t range; + JSList *node; + + range.min = range.max = target_delay; + + if (mode == JackCaptureLatency) { + for (node = capture_ports; node; node = jack_slist_next (node)) { + jack_port_t *port = node->data; + jack_port_set_latency_range (port, mode, &range); + } + } else { + for (node = playback_ports; node; node = jack_slist_next (node)) { + jack_port_t *port = node->data; + jack_port_set_latency_range (port, mode, &range); + } + } +} + /** * Allocate the necessary jack ports... @@ -659,6 +691,8 @@ int main (int argc, char *argv[]) { jack_on_shutdown (client, jack_shutdown, 0); + if (jack_set_latency_callback) + jack_set_latency_callback (client, latency_cb, 0); // get jack sample_rate @@ -714,6 +748,16 @@ int main (int argc, char *argv[]) { // alloc input ports, which are blasted out to alsa... alloc_ports( 0, num_channels ); + outbuf = malloc( num_periods * period_size * formats[format].sample_size * num_channels ); + resampbuf = malloc( num_periods * period_size * sizeof( float ) ); + tmpbuf = malloc( 512 * formats[format].sample_size * num_channels ); + + if ((outbuf == NULL) || (resampbuf == NULL) || (tmpbuf == NULL)) + { + fprintf( stderr, "no memory for buffers.\n" ); + exit(20); + } + /* tell the JACK server that we are ready to roll */ diff --git a/example-clients/bufsize.c b/example-clients/bufsize.c index 72a0f9e8..09567f6c 100644 --- a/example-clients/bufsize.c +++ b/example-clients/bufsize.c @@ -2,7 +2,7 @@ * bufsize.c -- change JACK buffer size. * * Copyright (C) 2003 Jack O'Quin. - * + * * 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 @@ -64,12 +64,23 @@ void parse_arguments(int argc, char *argv[]) exit(9); } + if (strspn (argv[1], "0123456789") != strlen (argv[1])) { + fprintf(stderr, "usage: %s \n", package); + exit(8); + } + nframes = strtoul(argv[1], NULL, 0); if (errno == ERANGE) { - fprintf(stderr, "%s: invalid buffer size: %s\n", + fprintf(stderr, "%s: invalid buffer size: %s (range is 1-8182)\n", package, argv[1]); exit(2); } + + if (nframes < 1 || nframes > 8182) { + fprintf(stderr, "%s: invalid buffer size: %s (range is 1-8182)\n", + package, argv[1]); + exit(3); + } } int main(int argc, char *argv[]) diff --git a/example-clients/connect.c b/example-clients/connect.c index 635b2361..a4132cea 100644 --- a/example-clients/connect.c +++ b/example-clients/connect.c @@ -24,7 +24,9 @@ #include #include #include +#include #include +#include jack_port_t *input_port; jack_port_t *output_port; @@ -33,17 +35,84 @@ int done = 0; #define TRUE 1 #define FALSE 0 - void port_connect_callback(jack_port_id_t a, jack_port_id_t b, int connect, void* arg) { done = 1; } +void +show_version (char *my_name) +{ + //fprintf (stderr, "%s: JACK Audio Connection Kit version " VERSION "\n", my_name); +} + +void +show_usage (char *my_name) +{ + show_version (my_name); + fprintf (stderr, "\nusage: %s [options] port1 port2\n", my_name); + fprintf (stderr, "Connects two JACK ports together.\n\n"); + fprintf (stderr, " -s, --server Connect to the jack server named \n"); + fprintf (stderr, " -v, --version Output version information and exit\n"); + fprintf (stderr, " -h, --help Display this help message\n\n"); + fprintf (stderr, "For more information see http://jackaudio.org/\n"); +} + + int main (int argc, char *argv[]) { - jack_client_t* client = NULL; + jack_client_t *client; + jack_status_t status; + char *server_name = NULL; + int c; + int option_index; + jack_options_t options = JackNoStartServer; char *my_name = strrchr(argv[0], '/'); + jack_port_t *src_port = 0; + jack_port_t *dst_port = 0; + jack_port_t *port1 = 0; + jack_port_t *port2 = 0; + char portA[300]; + char portB[300]; + int use_uuid=0; + int connecting, disconnecting; + int port1_flags, port2_flags; + int rc = 1; + + struct option long_options[] = { + { "server", 1, 0, 's' }, + { "help", 0, 0, 'h' }, + { "version", 0, 0, 'v' }, + { "uuid", 0, 0, 'u' }, + { 0, 0, 0, 0 } + }; + + while ((c = getopt_long (argc, argv, "s:hvu", long_options, &option_index)) >= 0) { + switch (c) { + case 's': + server_name = (char *) malloc (sizeof (char) * strlen(optarg)); + strcpy (server_name, optarg); + options |= JackServerName; + break; + case 'u': + use_uuid = 1; + break; + case 'h': + show_usage (my_name); + return 1; + break; + case 'v': + show_version (my_name); + return 1; + break; + default: + show_usage (my_name); + return 1; + break; + } + } + connecting = disconnecting = FALSE; if (my_name == 0) { my_name = argv[0]; @@ -51,90 +120,121 @@ main (int argc, char *argv[]) my_name ++; } - printf("name %s\n", my_name); - - if (strstr(my_name, "jack_disconnect")) { - disconnecting = TRUE; - } else - if (strstr(my_name, "jack_connect")) { - connecting = TRUE; + if (strstr(my_name, "disconnect")) { + disconnecting = 1; + } else if (strstr(my_name, "connect")) { + connecting = 1; } else { fprintf(stderr, "ERROR! client should be called jack_connect or jack_disconnect. client is called %s\n", my_name); return 1; } - if (argc != 3) { - fprintf (stderr, "usage: %s \n", my_name); - fprintf(stderr, "The source port must be an output port of the source client.\n"); - fprintf (stderr, "The destination port must be an input port of the destination client.\n"); - return 1; - } + if (argc < 3) show_usage(my_name); /* try to become a client of the JACK server */ - if ((client = jack_client_open (my_name, JackNullOption, NULL)) == 0) { + if ((client = jack_client_open (my_name, options, &status, server_name)) == 0) { fprintf (stderr, "jack server not running?\n"); return 1; } jack_set_port_connect_callback(client, port_connect_callback, NULL); - /* display the current sample rate. once the client is activated - (see below), you should rely on your own sample rate - callback (see above) for this value. - */ - /* find the two ports */ - if ((input_port = jack_port_by_name(client, argv[1])) == 0) { - fprintf (stderr, "ERROR %s not a valid port\n", argv[1]); - goto error; + if( use_uuid ) { + char *tmpname; + char *clientname; + char *portname; + tmpname = strdup( argv[argc-1] ); + portname = strchr( tmpname, ':' ); + portname[0] = '\0'; + portname+=1; + clientname = jack_get_client_name_by_uuid( client, tmpname ); + if( clientname ) { + + snprintf( portA, sizeof(portA), "%s:%s", clientname, portname ); + jack_free( clientname ); + } else { + snprintf( portA, sizeof(portA), "%s", argv[argc-1] ); + } + free( tmpname ); + + tmpname = strdup( argv[argc-2] ); + portname = strchr( tmpname, ':' ); + portname[0] = '\0'; + portname+=1; + clientname = jack_get_client_name_by_uuid( client, tmpname ); + if( clientname ) { + snprintf( portB, sizeof(portB), "%s:%s", clientname, portname ); + jack_free( clientname ); + } else { + snprintf( portB, sizeof(portB), "%s", argv[argc-2] ); + } + + free( tmpname ); + + } else { + snprintf( portA, sizeof(portA), "%s", argv[argc-1] ); + snprintf( portB, sizeof(portB), "%s", argv[argc-2] ); } - if ((output_port = jack_port_by_name(client, argv[2])) == 0) { - fprintf (stderr, "ERROR %s not a valid port\n", argv[2]); - goto error; + if ((port1 = jack_port_by_name(client, portA)) == 0) { + fprintf (stderr, "ERROR %s not a valid port\n", portA); + goto exit; + } + if ((port2 = jack_port_by_name(client, portB)) == 0) { + fprintf (stderr, "ERROR %s not a valid port\n", portB); + goto exit; + } + + port1_flags = jack_port_flags (port1); + port2_flags = jack_port_flags (port2); + + if (port1_flags & JackPortIsInput) { + if (port2_flags & JackPortIsOutput) { + src_port = port2; + dst_port = port1; + } + } else { + if (port2_flags & JackPortIsInput) { + src_port = port1; + dst_port = port2; + } } - /* tell the JACK server that we are ready to roll */ - - if (jack_activate (client)) { - fprintf (stderr, "cannot activate client"); - goto error; + if (!src_port || !dst_port) { + fprintf (stderr, "arguments must include 1 input port and 1 output port\n"); + goto exit; } /* connect the ports. Note: you can't do this before the client is activated (this may change in the future). */ - if (connecting) { - if (jack_connect(client, jack_port_name(input_port), jack_port_name(output_port))) { - fprintf (stderr, "cannot connect ports\n"); - goto error; - } + if (connecting) { + if (jack_connect(client, jack_port_name(src_port), jack_port_name(dst_port))) { + goto exit; + } } if (disconnecting) { - if (jack_disconnect(client, jack_port_name(input_port), jack_port_name(output_port))) { - fprintf (stderr, "cannot disconnect ports\n"); - goto error; - } + if (jack_disconnect(client, jack_port_name(src_port), jack_port_name(dst_port))) { + goto exit; + } } // Wait for connection/disconnection to be effective - while(!done) { - #ifdef WIN32 - Sleep(10); - #else - usleep(10000); - #endif + while(!done) { + #ifdef WIN32 + Sleep(10); + #else + usleep(10000); + #endif } - jack_deactivate (client); - jack_client_close (client); - return 0; + /* everything was ok, so setting exitcode to 0 */ + rc = 0; -error: - if (client) - jack_client_close (client); - return 1; +exit: + jack_client_close (client); + exit (rc); } - diff --git a/example-clients/latent_client.c b/example-clients/latent_client.c new file mode 100644 index 00000000..67217832 --- /dev/null +++ b/example-clients/latent_client.c @@ -0,0 +1,215 @@ +/** @file simple_client.c + * + * @brief This simple client demonstrates the most basic features of JACK + * as they would be used by many applications. + */ + +#include +#include +#include +#include +#include +#include + +#include + +jack_port_t *input_port; +jack_port_t *output_port; +jack_client_t *client; + +jack_default_audio_sample_t *delay_line; +jack_nframes_t delay_index; +jack_nframes_t latency = 1024; + +#ifdef WIN32 +#define jack_sleep(val) Sleep((val)) +#else +#define jack_sleep(val) usleep((val) * 1000) +#endif + +/** + * The process callback for this JACK application is called in a + * special realtime thread once for each audio cycle. + * + * This client does nothing more than copy data from its input + * port to its output port. It will exit when stopped by + * the user (e.g. using Ctrl-C on a unix-ish operating system) + */ +int +process (jack_nframes_t nframes, void *arg) +{ + jack_default_audio_sample_t *in, *out; + int k; + + in = jack_port_get_buffer (input_port, nframes); + out = jack_port_get_buffer (output_port, nframes); + + for (k=0; k #endif #include -#include +#include +#include #include char * my_name; @@ -39,6 +40,7 @@ show_usage (void) fprintf (stderr, "List active Jack ports, and optionally display extra information.\n"); fprintf (stderr, "Optionally filter ports which match ALL strings provided after any options.\n\n"); fprintf (stderr, "Display options:\n"); + fprintf (stderr, " -s, --server Connect to the jack server named \n"); fprintf (stderr, " -A, --aliases List aliases for each port\n"); fprintf (stderr, " -c, --connections List connections to/from each port\n"); fprintf (stderr, " -l, --latency Display per-port latency in frames at each port\n"); @@ -56,6 +58,7 @@ main (int argc, char *argv[]) { jack_client_t *client; jack_status_t status; + jack_options_t options = JackNoStartServer; const char **ports, **connections; unsigned int i, j, k; int skip_port; @@ -68,9 +71,11 @@ main (int argc, char *argv[]) int c; int option_index; char* aliases[2]; + char *server_name = NULL; jack_port_t *port; - + struct option long_options[] = { + { "server", 1, 0, 's' }, { "aliases", 0, 0, 'A' }, { "connections", 0, 0, 'c' }, { "port-latency", 0, 0, 'l' }, @@ -89,8 +94,13 @@ main (int argc, char *argv[]) my_name ++; } - while ((c = getopt_long (argc, argv, "AclLphvt", long_options, &option_index)) >= 0) { + while ((c = getopt_long (argc, argv, "s:AclLphvt", long_options, &option_index)) >= 0) { switch (c) { + case 's': + server_name = (char *) malloc (sizeof (char) * strlen(optarg)); + strcpy (server_name, optarg); + options |= JackServerName; + break; case 'A': aliases[0] = (char *) malloc (jack_port_name_size()); aliases[1] = (char *) malloc (jack_port_name_size()); @@ -131,7 +141,7 @@ main (int argc, char *argv[]) * specify JackNoStartServer. */ //JOQ: need a new server name option - client = jack_client_open ("lsp", JackNoStartServer, &status); + client = jack_client_open ("lsp", options, &status, server_name); if (client == NULL) { if (status & JackServerFailed) { fprintf (stderr, "JACK server not running\n"); @@ -143,7 +153,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) { @@ -168,19 +178,28 @@ 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) { - printf (" port latency = %d frames\n", + jack_latency_range_t range; + printf (" port latency = %" PRIu32 " frames\n", jack_port_get_latency (port)); + + jack_port_get_latency_range (port, JackPlaybackLatency, &range); + printf (" port playback latency = [ %" PRIu32 " %" PRIu32 " ] frames\n", + range.min, range.max); + + jack_port_get_latency_range (port, JackCaptureLatency, &range); + printf (" port capture latency = [ %" PRIu32 " %" PRIu32 " ] frames\n", + range.min, range.max); } } if (show_total_latency) { @@ -208,12 +227,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); } } @@ -225,7 +239,7 @@ main (int argc, char *argv[]) } } } - + error: if (ports) jack_free (ports); diff --git a/example-clients/midi_dump.c b/example-clients/midi_dump.c new file mode 100644 index 00000000..81926283 --- /dev/null +++ b/example-clients/midi_dump.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include +#include + +static jack_port_t* port; + +static void +describe (jack_midi_event_t* event, char* buffer, size_t buflen) +{ + assert (buflen > 0); + + buffer[0] = '\0'; + + if (event->size == 0) { + return; + } + + int type = event->buffer[0] & 0xf0; + int channel = event->buffer[0] & 0xf; + + switch (type) { + case 0x90: + assert (event->size == 3); + snprintf (buffer, buflen, "note on (channel %d): pitch %d, velocity %d", channel, event->buffer[1], event->buffer[2]); + break; + case 0x80: + assert (event->size == 3); + snprintf (buffer, buflen, "note off (channel %d): pitch %d, velocity %d", channel, event->buffer[1], event->buffer[2]); + break; + case 0xb0: + assert (event->size == 3); + snprintf (buffer, buflen, "control change (channel %d): controller %d, value %d", channel, event->buffer[1], event->buffer[2]); + break; + default: + break; + } +} + +int +process (jack_nframes_t frames, void* arg) +{ + void* buffer; + jack_nframes_t N; + jack_nframes_t i; + char description[256]; + + buffer = jack_port_get_buffer (port, frames); + assert (buffer); + + N = jack_midi_get_event_count (buffer); + for (i = 0; i < N; ++i) { + jack_midi_event_t event; + int r; + + r = jack_midi_event_get (&event, buffer, i); + if (r == 0) { + size_t j; + + printf ("%d:", event.time); + for (j = 0; j < event.size; ++j) { + printf (" %x", event.buffer[j]); + } + + describe (&event, description, sizeof (description)); + printf (" %s", description); + + printf ("\n"); + } + } + + return 0; +} + + +int +main (int argc, char* argv[]) +{ + jack_client_t* client; + char const default_name[] = "midi-monitor"; + char const * client_name; + int r; + + if (argc == 2) { + client_name = argv[1]; + } else { + client_name = default_name; + } + + client = jack_client_open (client_name, JackNullOption, NULL); + if (client == NULL) { + fprintf (stderr, "Could not create JACK client.\n"); + exit (EXIT_FAILURE); + } + + jack_set_process_callback (client, process, 0); + + port = jack_port_register (client, "input", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); + if (port == NULL) { + fprintf (stderr, "Could not register port.\n"); + exit (EXIT_FAILURE); + } + + r = jack_activate (client); + if (r != 0) { + fprintf (stderr, "Could not activate client.\n"); + exit (EXIT_FAILURE); + } + + sleep (-1); + + return 0; +} diff --git a/example-clients/netsource.c b/example-clients/netsource.c index 9f995406..f3cd8274 100644 --- a/example-clients/netsource.c +++ b/example-clients/netsource.c @@ -86,6 +86,7 @@ int reply_port = 0; int bind_port = 0; int redundancy = 1; jack_client_t *client; +packet_cache * packcache = 0; int state_connected = 0; int state_latency = 0; @@ -140,7 +141,7 @@ alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int } if( bitdepth == 1000 ) { #if HAVE_CELT -#if HAVE_CELT_API_0_7 +#if HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL ); capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); #else @@ -183,7 +184,7 @@ alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int } if( bitdepth == 1000 ) { #if HAVE_CELT -#if HAVE_CELT_API_0_7 +#if HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL ); playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); #else @@ -224,6 +225,9 @@ sync_cb (jack_transport_state_t state, jack_position_t *pos, void *arg) static int latency_count = 0; int retval = sync_state; + if (! state_connected) { + return 1; + } if (latency_count) { latency_count--; retval = 0; @@ -329,7 +333,7 @@ process (jack_nframes_t nframes, void *arg) else if (cont_miss > 50+5*latency) { state_connected = 0; - packet_cache_reset_master_address( global_packcache ); + packet_cache_reset_master_address( packcache ); //printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss); cont_miss = 0; } @@ -355,19 +359,19 @@ process (jack_nframes_t nframes, void *arg) if ( ! netjack_poll_deadline( input_fd, deadline ) ) break; - packet_cache_drain_socket(global_packcache, input_fd); + packet_cache_drain_socket(packcache, input_fd); - if (packet_cache_get_next_available_framecnt( global_packcache, framecnt - latency, &got_frame )) + if (packet_cache_get_next_available_framecnt( packcache, framecnt - latency, &got_frame )) if( got_frame == (framecnt - latency) ) break; } } else { // normally: // only drain socket. - packet_cache_drain_socket(global_packcache, input_fd); + packet_cache_drain_socket(packcache, input_fd); } - size = packet_cache_retreive_packet_pointer( global_packcache, framecnt - latency, (char**)&rx_packet_ptr, rx_bufsize, &packet_recv_timestamp ); + size = packet_cache_retreive_packet_pointer( packcache, framecnt - latency, (char**)&rx_packet_ptr, rx_bufsize, &packet_recv_timestamp ); /* First alternative : we received what we expected. Render the data * to the JACK ports so it can be played. */ if (size == rx_bufsize) @@ -394,7 +398,7 @@ process (jack_nframes_t nframes, void *arg) state_recv_packet_queue_time = recv_time_offset; state_connected = 1; sync_state = pkthdr_rx->sync_state; - packet_cache_release_packet( global_packcache, framecnt - latency ); + packet_cache_release_packet( packcache, framecnt - latency ); } /* Second alternative : we've received something that's not * as big as expected or we missed a packet. We render silence @@ -402,7 +406,7 @@ process (jack_nframes_t nframes, void *arg) else { jack_nframes_t latency_estimate; - if( packet_cache_find_latency( global_packcache, framecnt, &latency_estimate ) ) + if( packet_cache_find_latency( packcache, framecnt, &latency_estimate ) ) //if( (state_latency == 0) || (latency_estimate < state_latency) ) state_latency = latency_estimate; @@ -468,7 +472,7 @@ process (jack_nframes_t nframes, void *arg) else if (cont_miss > 50+5*latency) { state_connected = 0; - packet_cache_reset_master_address( global_packcache ); + packet_cache_reset_master_address( packcache ); //printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss); cont_miss = 0; } @@ -501,12 +505,11 @@ init_sockaddr_in (struct sockaddr_in *name , const char *hostname , uint16_t por if (hostinfo == NULL) { fprintf (stderr, "init_sockaddr_in: unknown host: %s.\n", hostname); fflush( stderr ); - return; } #ifdef WIN32 - name->sin_addr.s_addr = inet_addr( hostname ); + name->sin_addr.s_addr = inet_addr( hostname ); #else - name->sin_addr = *(struct in_addr *) hostinfo->h_addr ; + name->sin_addr = *(struct in_addr *) hostinfo->h_addr ; #endif } else @@ -621,15 +624,15 @@ main (int argc, char *argv[]) case 'b': bitdepth = atoi (optarg); break; - case 'c': - #if HAVE_CELT - bitdepth = 1000; + case 'c': +#if HAVE_CELT + bitdepth = 1000; factor = atoi (optarg); - #else +#else printf( "not built with celt supprt\n" ); exit(10); - #endif - break; +#endif + break; case 'm': mtu = atoi (optarg); break; @@ -676,17 +679,18 @@ main (int argc, char *argv[]) } init_sockaddr_in ((struct sockaddr_in *) &destaddr, peer_ip, peer_port); - if (bind_port) { + if(bind_port) { init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, bind_port); if( bind (outsockfd, &bindaddr, sizeof (bindaddr)) ) { - fprintf (stderr, "bind failure\n" ); - } + fprintf (stderr, "bind failure\n" ); + } } - if (reply_port) { + if(reply_port) + { init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port); if( bind (insockfd, &bindaddr, sizeof (bindaddr)) ) { - fprintf (stderr, "bind failure\n" ); - } + fprintf (stderr, "bind failure\n" ); + } } /* try to become a client of the JACK server */ @@ -712,7 +716,7 @@ main (int argc, char *argv[]) net_period = ceilf((float) jack_get_buffer_size (client) / (float) factor); int rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header); - global_packcache = packet_cache_new (latency + 50, rx_bufsize, mtu); + packcache = packet_cache_new (latency + 50, rx_bufsize, mtu); /* tell the JACK server that we are ready to roll */ if (jack_activate (client)) @@ -778,6 +782,6 @@ main (int argc, char *argv[]) } jack_client_close (client); - packet_cache_free (global_packcache); + packet_cache_free (packcache); exit (0); } diff --git a/example-clients/session_notify.c b/example-clients/session_notify.c index e8a6d517..9cb3f894 100644 --- a/example-clients/session_notify.c +++ b/example-clients/session_notify.c @@ -25,12 +25,11 @@ #include #include #include -#include #include #include #include -char *package; /* program name */ +char *package; /* program name */ jack_client_t *client; jack_session_event_type_t notify_type; @@ -38,147 +37,145 @@ char *save_path = NULL; void jack_shutdown(void *arg) { - fprintf(stderr, "JACK shut down, exiting ...\n"); - exit(1); + fprintf(stderr, "JACK shut down, exiting ...\n"); + exit(1); } void signal_handler(int sig) { - jack_client_close(client); - fprintf(stderr, "signal received, exiting ...\n"); - exit(0); + jack_client_close(client); + fprintf(stderr, "signal received, exiting ...\n"); + exit(0); } void parse_arguments(int argc, char *argv[]) { - /* basename $0 */ - package = strrchr(argv[0], '/'); - if (package == 0) - package = argv[0]; - else - package++; - - if (argc==2) { - if( !strcmp( argv[1], "quit" ) ) { - notify_type = JackSessionSaveAndQuit; - return; - } - } - if (argc==3) { - if( !strcmp( argv[1], "save" ) ) { - notify_type = JackSessionSave; - save_path = argv[2]; - return; - } - - } - fprintf(stderr, "usage: %s quit|save [path]\n", package); - exit(9); + /* basename $0 */ + package = strrchr(argv[0], '/'); + if (package == 0) + package = argv[0]; + else + package++; + + if (argc==2) { + if( !strcmp( argv[1], "quit" ) ) { + notify_type = JackSessionSaveAndQuit; + return; + } + } + if (argc==3) { + if( !strcmp( argv[1], "save" ) ) { + notify_type = JackSessionSave; + save_path = argv[2]; + return; + } + + } + fprintf(stderr, "usage: %s quit|save [path]\n", package); + exit(9); } typedef struct { - char name[32]; - char uuid[16]; + char name[32]; + char uuid[16]; } uuid_map_t; JSList *uuid_map = NULL; void add_uuid_mapping( const char *uuid ) { - char *clientname = jack_get_client_name_by_uuid( client, uuid ); - if( !clientname ) { - printf( "error... cant find client for uuid %s", uuid ); - - return; - } - - uuid_map_t *mapping = malloc( sizeof(uuid_map_t) ); - snprintf( mapping->uuid, sizeof(mapping->uuid), "%s", uuid ); - snprintf( mapping->name, sizeof(mapping->name), "%s", clientname ); - uuid_map = jack_slist_append( uuid_map, mapping ); + char *clientname = jack_get_client_name_by_uuid( client, uuid ); + if( !clientname ) { + printf( "error... cant find client for uuid" ); + return; + } + + uuid_map_t *mapping = malloc( sizeof(uuid_map_t) ); + snprintf( mapping->uuid, sizeof(mapping->uuid), "%s", uuid ); + snprintf( mapping->name, sizeof(mapping->name), "%s", clientname ); + uuid_map = jack_slist_append( uuid_map, mapping ); } char *map_port_name_to_uuid_port( const char *port_name ) { - JSList *node; - char retval[300]; - char *port_component = strchr( port_name,':' ); - char *client_component = strdup( port_name ); - strchr( client_component, ':' )[0] = '\0'; - - sprintf( retval, "%s", port_name ); - - for( node=uuid_map; node; node=jack_slist_next(node) ) { - uuid_map_t *mapping = node->data; - if( !strcmp( mapping->name, client_component ) ) { - sprintf( retval, "%s%s", mapping->uuid, port_component ); - break; - } - } - - return strdup(retval); + JSList *node; + char retval[300]; + char *port_component = strchr( port_name,':' ); + char *client_component = strdup( port_name ); + strchr( client_component, ':' )[0] = '\0'; + + sprintf( retval, "%s", port_name ); + + for( node=uuid_map; node; node=jack_slist_next(node) ) { + uuid_map_t *mapping = node->data; + if( !strcmp( mapping->name, client_component ) ) { + sprintf( retval, "%s%s", mapping->uuid, port_component ); + break; + } + } + + return strdup(retval); } int main(int argc, char *argv[]) { - parse_arguments(argc, argv); - jack_session_command_t *retval; - int k,i,j; - - - /* become a JACK client */ - if ((client = jack_client_open(package, JackNullOption, NULL)) == 0) { - fprintf(stderr, "JACK server not running?\n"); - exit(1); - } - - signal(SIGQUIT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGHUP, signal_handler); - signal(SIGINT, signal_handler); - - jack_on_shutdown(client, jack_shutdown, 0); - - jack_activate(client); - - - retval = jack_session_notify( client, NULL, notify_type, save_path ); - printf( "retval = %p\n", retval ); - for(i=0; retval[i].uuid; i++ ) { - printf( "export SESSION_DIR=\"%s%s/\"\n", save_path, retval[i].client_name ); - printf( "%s &\n", retval[i].command ); - add_uuid_mapping(retval[i].uuid); - } - - printf( "sleep 10\n" ); - - for(k=0; retval[k].uuid; k++ ) { - - char* port_regexp = alloca( jack_client_name_size()+3 ); - char* client_name = jack_get_client_name_by_uuid( client, retval[k].uuid ); - snprintf( port_regexp, jack_client_name_size()+3, "%s:.*", client_name ); - jack_free(client_name); - const char **ports = jack_get_ports( client, port_regexp, NULL, 0 ); - if( !ports ) { - continue; - } - for (i = 0; ports[i]; ++i) { - const char **connections; - if ((connections = jack_port_get_all_connections (client, jack_port_by_name(client, ports[i]))) != 0) { - for (j = 0; connections[j]; j++) { - char *src = map_port_name_to_uuid_port( ports[i] ); - char *dst = map_port_name_to_uuid_port( connections[j] ); - printf( "jack_connect -u \"%s\" \"%s\"\n", src, dst ); - } - jack_free (connections); - } - } - jack_free(ports); - - } - jack_session_commands_free(retval); - - jack_client_close(client); - - return 0; + parse_arguments(argc, argv); + jack_session_command_t *retval; + int k,i,j; + + + /* become a JACK client */ + if ((client = jack_client_open(package, JackNullOption, NULL)) == 0) { + fprintf(stderr, "JACK server not running?\n"); + exit(1); + } + + signal(SIGQUIT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGHUP, signal_handler); + signal(SIGINT, signal_handler); + + jack_on_shutdown(client, jack_shutdown, 0); + + jack_activate(client); + + + retval = jack_session_notify( client, NULL, notify_type, save_path ); + for(i=0; retval[i].uuid; i++ ) { + printf( "export SESSION_DIR=\"%s%s/\"\n", save_path, retval[i].client_name ); + printf( "%s &\n", retval[i].command ); + add_uuid_mapping(retval[i].uuid); + } + + printf( "sleep 10\n" ); + + for(k=0; retval[k].uuid; k++ ) { + + char* port_regexp = alloca( jack_client_name_size()+3 ); + char* client_name = jack_get_client_name_by_uuid( client, retval[k].uuid ); + snprintf( port_regexp, jack_client_name_size()+3, "%s:.*", client_name ); + jack_free(client_name); + const char **ports = jack_get_ports( client, port_regexp, NULL, 0 ); + if( !ports ) { + continue; + } + for (i = 0; ports[i]; ++i) { + const char **connections; + if ((connections = jack_port_get_all_connections (client, jack_port_by_name(client, ports[i]))) != 0) { + for (j = 0; connections[j]; j++) { + char *src = map_port_name_to_uuid_port( ports[i] ); + char *dst = map_port_name_to_uuid_port( connections[j] ); + printf( "jack_connect -u \"%s\" \"%s\"\n", src, dst ); + } + jack_free (connections); + } + } + jack_free(ports); + + } + jack_session_commands_free(retval); + + jack_client_close(client); + + return 0; } diff --git a/example-clients/wscript b/example-clients/wscript index 1b07b0b1..54a6a599 100644 --- a/example-clients/wscript +++ b/example-clients/wscript @@ -27,6 +27,8 @@ example_programs = { 'jack_server_control' : 'server_control.cpp', 'jack_net_slave' : 'netslave.c', 'jack_net_master' : 'netmaster.c', + 'jack_latent_client' : 'latent_client.c', + 'jack_midi_dump' : 'midi_dump.c', } example_libs = { @@ -130,12 +132,6 @@ def build(bld): prog.includes = os_incdir + ['../common/jack', '../common'] prog.source = ['netsource.c', '../common/netjack_packet.c'] prog.env.append_value("CCFLAGS", "-DNO_JACK_ERROR") - # Seems uneeded here... - #if bld.env['HAVE_CELT']: - #if bld.env['HAVE_CELT_API_0_5']: - # prog.defines = ['HAVE_CELT', 'HAVE_CELT_API_0_5'] - #elif bld.env['HAVE_CELT_API_0_7']: - # prog.defines = ['HAVE_CELT', 'HAVE_CELT_API_0_7'] prog.uselib = 'CELT SAMPLERATE' prog.uselib_local = 'clientlib' prog.target = 'jack_netsource' diff --git a/linux/JackAtomic_os.h b/linux/JackAtomic_os.h index 37181e04..e201d0d6 100644 --- a/linux/JackAtomic_os.h +++ b/linux/JackAtomic_os.h @@ -69,12 +69,15 @@ static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* ad #endif + + + #if !defined(__i386__) && !defined(__x86_64__) && !defined(__PPC__) -#warning using builtin gcc (version > 4.1) atomic + static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr) { - return __sync_bool_compare_and_swap (&addr, value, newvalue); + return __sync_bool_compare_and_swap ((UInt32*)addr, value, newvalue); } #endif diff --git a/linux/JackLinuxTime.c b/linux/JackLinuxTime.c index 37ae9fb0..d8b474eb 100644 --- a/linux/JackLinuxTime.c +++ b/linux/JackLinuxTime.c @@ -36,6 +36,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include +#include static jack_time_t __jack_cpu_mhz = 0; jack_time_t (*_jack_get_microseconds)(void) = 0; diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index efcc1f94..fdf5a0cb 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -276,7 +276,7 @@ JackAlsaDriver::alsa_driver_setup_io_function_pointers (alsa_driver_t *driver) } else { driver->channel_copy = memcpy_fake; } - + switch (driver->dither) { case Rectangular: jack_info("Rectangular dithering at 16 bits"); @@ -284,42 +284,42 @@ JackAlsaDriver::alsa_driver_setup_io_function_pointers (alsa_driver_t *driver) sample_move_dither_rect_d16_sSs: sample_move_dither_rect_d16_sS; break; - + case Triangular: jack_info("Triangular dithering at 16 bits"); driver->write_via_copy = driver->quirk_bswap? sample_move_dither_tri_d16_sSs: sample_move_dither_tri_d16_sS; break; - + case Shaped: jack_info("Noise-shaped dithering at 16 bits"); driver->write_via_copy = driver->quirk_bswap? sample_move_dither_shaped_d16_sSs: sample_move_dither_shaped_d16_sS; break; - + default: driver->write_via_copy = driver->quirk_bswap? - sample_move_d16_sSs : + sample_move_d16_sSs : sample_move_d16_sS; break; } break; - + case 3: /* NO DITHER */ if (driver->playback_interleaved) { driver->channel_copy = memcpy_interleave_d24_s24; } else { driver->channel_copy = memcpy_fake; } - + driver->write_via_copy = driver->quirk_bswap? - sample_move_d24_sSs: + sample_move_d24_sSs: sample_move_d24_sS; break; - + case 4: /* NO DITHER */ if (driver->playback_interleaved) { driver->channel_copy = memcpy_interleave_d32_s32; @@ -328,7 +328,7 @@ JackAlsaDriver::alsa_driver_setup_io_function_pointers (alsa_driver_t *driver) } driver->write_via_copy = driver->quirk_bswap? - sample_move_d32u24_sSs: + sample_move_d32u24_sSs: sample_move_d32u24_sS; break; @@ -339,27 +339,27 @@ JackAlsaDriver::alsa_driver_setup_io_function_pointers (alsa_driver_t *driver) } } } - + if (driver->capture_handle) { switch (driver->capture_sample_bytes) { case 2: driver->read_via_copy = driver->quirk_bswap? - sample_move_dS_s16s: + sample_move_dS_s16s: sample_move_dS_s16; break; case 3: driver->read_via_copy = driver->quirk_bswap? - sample_move_dS_s24s: + sample_move_dS_s24s: sample_move_dS_s24; break; case 4: driver->read_via_copy = driver->quirk_bswap? - sample_move_dS_s32u24s: + sample_move_dS_s32u24s: sample_move_dS_s32u24; break; } } - + return 0; } @@ -418,7 +418,7 @@ JackAlsaDriver::alsa_driver_configure_stream (alsa_driver_t *driver, char *devic } } } - + format = (sample_width == 4) ? 0 : NUMFORMATS - 1; while (1) { @@ -444,7 +444,7 @@ JackAlsaDriver::alsa_driver_configure_stream (alsa_driver_t *driver, char *devic jack_info ("ALSA: final selected sample format for %s: %s", stream_name, formats[format].Name); break; } - } + } frame_rate = driver->frame_rate ; err = snd_pcm_hw_params_set_rate_near (handle, hw_params, @@ -464,7 +464,7 @@ JackAlsaDriver::alsa_driver_configure_stream (alsa_driver_t *driver, char *devic &channels_max); *nchns = channels_max ; - if (*nchns > 1024) { + if (*nchns > 1024) { /* the hapless user is an unwitting victim of the "default" ALSA PCM device, which can @@ -481,9 +481,9 @@ JackAlsaDriver::alsa_driver_configure_stream (alsa_driver_t *driver, char *devic "instead rather than using the plug layer. Usually the name of the\n" "hardware device that corresponds to the first sound card is hw:0\n" ); - *nchns = 2; + *nchns = 2; } - } + } if ((err = snd_pcm_hw_params_set_channels (handle, hw_params, *nchns)) < 0) { @@ -491,7 +491,7 @@ JackAlsaDriver::alsa_driver_configure_stream (alsa_driver_t *driver, char *devic *nchns, stream_name); return -1; } - + if ((err = snd_pcm_hw_params_set_period_size (handle, hw_params, driver->frames_per_cycle, 0)) @@ -520,7 +520,7 @@ JackAlsaDriver::alsa_driver_configure_stream (alsa_driver_t *driver, char *devic return -1; } jack_info ("ALSA: use %d periods for %s", *nperiodsp, stream_name); -#if 0 +#if 0 if (!jack_power_of_two(driver->frames_per_cycle)) { jack_error("JACK: frames must be a power of two " "(64, 512, 1024, ...)\n"); @@ -557,7 +557,7 @@ JackAlsaDriver::alsa_driver_configure_stream (alsa_driver_t *driver, char *devic if (driver->soft_mode) { stop_th = (snd_pcm_uframes_t)-1; } - + if ((err = snd_pcm_sw_params_set_stop_threshold ( handle, sw_params, stop_th)) < 0) { jack_error ("ALSA: cannot set stop mode for %s", @@ -594,7 +594,7 @@ JackAlsaDriver::alsa_driver_configure_stream (alsa_driver_t *driver, char *devic else err = snd_pcm_sw_params_set_avail_min ( handle, sw_params, driver->frames_per_cycle); - + if (err < 0) { jack_error ("ALSA: cannot set avail min for %s", stream_name); return -1; @@ -1158,7 +1158,7 @@ int JackAlsaDriver::alsa_driver_restart (alsa_driver_t *driver) { int res; - + driver->xrun_recovery = 1; if ((res = Stop()) == 0) res = Start(); @@ -1189,11 +1189,24 @@ JackAlsaDriver::alsa_driver_xrun_recovery (alsa_driver_t *driver, float *delayed } } + if (snd_pcm_status_get_state(status) == SND_PCM_STATE_SUSPENDED) { + jack_error("**** alsa_pcm: pcm in suspended state, resuming it" ); + if (driver->capture_handle) { + if ((res = snd_pcm_prepare(driver->capture_handle)) < 0) { + jack_error("error preparing after suspend: %s", snd_strerror(res)); + } + } else { + if ((res = snd_pcm_prepare(driver->playback_handle)) < 0) { + jack_error("error preparing after suspend: %s", snd_strerror(res)); + } + } + } + if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN && driver->process_count > XRUN_REPORT_DELAY) { struct timeval now, diff, tstamp; driver->xrun_count++; - snd_pcm_status_get_tstamp(status,&now); + snd_pcm_status_get_tstamp(status,&now); snd_pcm_status_get_trigger_tstamp(status, &tstamp); timersub(&now, &tstamp, &diff); *delayed_usecs = diff.tv_sec * 1000000.0 + diff.tv_usec; @@ -1253,7 +1266,7 @@ JackAlsaDriver::alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *stat } again: - + while (need_playback || need_capture) { int poll_result; @@ -1269,7 +1282,7 @@ JackAlsaDriver::alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *stat driver->playback_nfds); nfds += driver->playback_nfds; } - + if (need_capture) { snd_pcm_poll_descriptors (driver->capture_handle, &driver->pfd[nfds], @@ -1279,7 +1292,7 @@ JackAlsaDriver::alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *stat } /* ALSA doesn't set POLLERR in some versions of 0.9.X */ - + for (i = 0; i < nfds; i++) { driver->pfd[i].events |= POLLERR; } @@ -1316,12 +1329,12 @@ JackAlsaDriver::alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *stat *status = -2; return 0; } - + jack_error ("ALSA: poll call failed (%s)", strerror (errno)); *status = -3; return 0; - + } poll_ret = jack_get_microseconds (); @@ -1332,12 +1345,12 @@ JackAlsaDriver::alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *stat if (extra_fd < 0) { if (driver->poll_next && poll_ret > driver->poll_next) { *delayed_usecs = poll_ret - driver->poll_next; - } + } driver->poll_last = poll_ret; driver->poll_next = poll_ret + driver->period_usecs; // steph /* - driver->engine->transport_cycle_start (driver->engine, + driver->engine->transport_cycle_start (driver->engine, poll_ret); */ } @@ -1358,7 +1371,7 @@ JackAlsaDriver::alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *stat *status = -4; return -1; - } + } /* if POLLIN was the only bit set, we're OK */ @@ -1414,14 +1427,14 @@ JackAlsaDriver::alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *stat #endif } } - + if (poll_result == 0) { jack_error ("ALSA: poll time out, polled for %" PRIu64 " usecs", poll_ret - poll_enter); *status = -5; return 0; - } + } } @@ -1437,7 +1450,7 @@ JackAlsaDriver::alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *stat } } else { /* odd, but see min() computation below */ - capture_avail = INT_MAX; + capture_avail = INT_MAX; } if (driver->playback_handle) { @@ -1452,7 +1465,7 @@ JackAlsaDriver::alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *stat } } else { /* odd, but see min() computation below */ - playback_avail = INT_MAX; + playback_avail = INT_MAX; } if (xrun_detected) { @@ -1531,7 +1544,7 @@ JackAlsaDriver::alsa_driver_read (alsa_driver_t *driver, jack_nframes_t nframes) if (!driver->capture_handle) { return 0; } - + nread = 0; contiguous = 0; orig_nframes = nframes; @@ -1559,11 +1572,11 @@ JackAlsaDriver::alsa_driver_read (alsa_driver_t *driver, jack_nframes_t nframes) /* // steph for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) { - + port = (jack_port_t *) node->data; - + if (!jack_port_connected (port)) { - // no-copy optimization + // no-copy optimization continue; } buf = jack_port_get_buffer (port, orig_nframes); @@ -1574,7 +1587,7 @@ JackAlsaDriver::alsa_driver_read (alsa_driver_t *driver, jack_nframes_t nframes) if ((err = snd_pcm_mmap_commit (driver->capture_handle, offset, contiguous)) < 0) { - + jack_error ("ALSA: could not complete read of %" PRIu32 " frames: error = %d\n", contiguous, err); return -1; @@ -1702,7 +1715,7 @@ JackAlsaDriver::alsa_driver_write (alsa_driver_t* driver, jack_nframes_t nframes } monbuf = jack_port_get_buffer (port, orig_nframes); memcpy (monbuf + nwritten, buf + nwritten, contiguous * sizeof(jack_default_audio_sample_t)); - mon_node = jack_slist_next (mon_node); + mon_node = jack_slist_next (mon_node); } } */ @@ -1716,7 +1729,7 @@ JackAlsaDriver::alsa_driver_write (alsa_driver_t* driver, jack_nframes_t nframes offset, contiguous)) < 0) { jack_error ("ALSA: could not complete playback of %" PRIu32 " frames: error = %d", contiguous, err); - if (err != EPIPE && err != ESTRPIPE) + if (err != -EPIPE && err != -ESTRPIPE) return -1; } @@ -1739,11 +1752,11 @@ JackAlsaDriver::alsa_driver_delete (alsa_driver_t *driver) free (node->data); } jack_slist_free (driver->clock_sync_listeners); - + if (driver->ctl_handle) { snd_ctl_close (driver->ctl_handle); driver->ctl_handle = 0; - } + } if (driver->capture_handle) { snd_pcm_close (driver->capture_handle); @@ -1821,14 +1834,14 @@ JackAlsaDriver::alsa_driver_new (const char *name, char *playback_alsa_device, jack_info ("creating alsa driver ... %s|%s|%" PRIu32 "|%" PRIu32 "|%" PRIu32"|%" PRIu32"|%" PRIu32 "|%s|%s|%s|%s", playing ? playback_alsa_device : "-", - capturing ? capture_alsa_device : "-", + capturing ? capture_alsa_device : "-", frames_per_cycle, user_nperiods, rate, user_capture_nchnls,user_playback_nchnls, hw_monitoring ? "hwmon": "nomon", hw_metering ? "hwmeter":"swmeter", soft_mode ? "soft-mode":"-", shorts_first ? "16bit":"32bit"); - + driver = (alsa_driver_t *) calloc (1, sizeof (alsa_driver_t)); jack_driver_nt_init ((jack_driver_nt_t *) driver); @@ -1862,8 +1875,8 @@ JackAlsaDriver::alsa_driver_new (const char *name, char *playback_alsa_device, driver->playback_addr = 0; driver->capture_addr = 0; - driver->playback_interleave_skip = NULL; - driver->capture_interleave_skip = NULL; + driver->playback_interleave_skip = NULL; + driver->capture_interleave_skip = NULL; driver->silent = 0; driver->all_monitor_in = FALSE; @@ -2071,6 +2084,7 @@ int JackAlsaDriver::Attach() unsigned long port_flags; char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + jack_latency_range_t range; assert(fCaptureChannels < DRIVER_PORT_NUM); assert(fPlaybackChannels < DRIVER_PORT_NUM); @@ -2097,7 +2111,8 @@ int JackAlsaDriver::Attach() } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - port->SetLatency(alsa_driver->frames_per_cycle + alsa_driver->capture_frame_latency); + range.min = range.max = alsa_driver->frames_per_cycle + alsa_driver->capture_frame_latency; + port->SetLatencyRange(JackCaptureLatency, &range); fCapturePortList[i] = port_index; jack_log("JackAudioDriver::Attach fCapturePortList[i] %ld ", port_index); } @@ -2114,8 +2129,10 @@ int JackAlsaDriver::Attach() port = fGraphManager->GetPort(port_index); port->SetAlias(alias); // Add one buffer more latency if "async" mode is used... - port->SetLatency((alsa_driver->frames_per_cycle * (alsa_driver->user_nperiods - 1)) + - ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + alsa_driver->playback_frame_latency); + range.min = range.max = (alsa_driver->frames_per_cycle * (alsa_driver->user_nperiods - 1)) + + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + alsa_driver->playback_frame_latency; + + port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[i] = port_index; jack_log("JackAudioDriver::Attach fPlaybackPortList[i] %ld ", port_index); @@ -2127,7 +2144,8 @@ int JackAlsaDriver::Attach() jack_error ("ALSA: cannot register monitor port for %s", name); } else { port = fGraphManager->GetPort(port_index); - port->SetLatency(alsa_driver->frames_per_cycle); + range.min = range.max = alsa_driver->frames_per_cycle; + port->SetLatencyRange(JackCaptureLatency, &range); fMonitorPortList[i] = port_index; } } @@ -2151,7 +2169,7 @@ int JackAlsaDriver::Detach() return JackAudioDriver::Detach(); } -static int card_to_num(const char* device) +static int card_to_num(const char* device) { int err; char* ctl_name; @@ -2316,13 +2334,13 @@ int JackAlsaDriver::Read() retry: nframes = alsa_driver_wait((alsa_driver_t *)fDriver, -1, &wait_status, &fDelayedUsecs); - + if (wait_status < 0) return -1; /* driver failed */ if (nframes == 0) { /* we detected an xrun and restarted: notify - * clients about the delay. + * clients about the delay. */ jack_log("ALSA XRun wait_status = %d", wait_status); NotifyXRun(fBeginDateUst, fDelayedUsecs); @@ -2331,7 +2349,7 @@ retry: if (nframes != fEngineControl->fBufferSize) jack_log("JackAlsaDriver::Read warning nframes = %ld", nframes); - + // Has to be done before read JackDriver::CycleIncTime(); @@ -2619,7 +2637,7 @@ get_dither_constraint() } static int -dither_opt (char c, DitherAlgorithm* dither) +dither_opt (char c, DitherAlgorithm* dither) { switch (c) { case '-': @@ -2646,17 +2664,17 @@ dither_opt (char c, DitherAlgorithm* dither) return 0; } -SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor () +SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor () { jack_driver_desc_t * desc; jack_driver_param_desc_t * params; unsigned int i; desc = (jack_driver_desc_t*)calloc (1, sizeof (jack_driver_desc_t)); - + strcpy(desc->name, "alsa"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->desc, "Linux ALSA API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - + desc->nparams = 18; params = (jack_driver_param_desc_t*)calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); @@ -2825,7 +2843,7 @@ SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor () 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 = 48000; jack_nframes_t frames_per_interrupt = 1024; 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/linux/alsa/usx2y.c b/linux/alsa/usx2y.c index 92236925..a6b696dd 100644 --- a/linux/alsa/usx2y.c +++ b/linux/alsa/usx2y.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2001 Paul Davis + Copyright (C) 2001 Paul Davis Copyright (C) 2005 Karsten Wiese, Rui Nuno Capela This program is free software; you can redistribute it and/or modify @@ -33,14 +33,14 @@ int dbg_offset; char dbg_buffer[8096]; #endif -static +static int usx2y_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask) { return -1; } static -int usx2y_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) +int usx2y_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) { return -1; } @@ -52,7 +52,7 @@ usx2y_release (jack_hardware_t *hw) if (h == 0) return; - + if (h->hwdep_handle) snd_hwdep_close(h->hwdep_handle); @@ -622,7 +622,7 @@ usx2y_driver_write (alsa_driver_t* driver, jack_nframes_t nframes) offset, nframes_)) < 0) { jack_error ("ALSA/USX2Y: could not complete playback of %" PRIu32 " frames: error = %d", nframes_, err); - if (err != EPIPE && err != ESTRPIPE) + if (err != -EPIPE && err != -ESTRPIPE) return -1; } diff --git a/linux/cycles.h b/linux/cycles.h index 20477a2e..d96b7b5e 100644 --- a/linux/cycles.h +++ b/linux/cycles.h @@ -37,8 +37,6 @@ * regardless of how fast the machine is. */ -#ifdef __linux__ - #ifdef __x86_64__ typedef unsigned long cycles_t; @@ -127,21 +125,5 @@ static inline cycles_t get_cycles(void) #endif /* everything else but x86, amd64, sparcv9 or ppc */ -#endif /* __linux__ */ - - -#if defined(__FreeBSD_kernel__) - -#warning No suitable get_cycles() implementation. Returning 0 instead - -typedef unsigned long long cycles_t; - -static inline cycles_t get_cycles(void) -{ - return 0; -} - -#endif /* __FreeBSD_kernel__ */ - #endif /* __jack_cycles_h__ */ diff --git a/linux/firewire/JackFFADODriver.cpp b/linux/firewire/JackFFADODriver.cpp index 5400df76..486c3794 100644 --- a/linux/firewire/JackFFADODriver.cpp +++ b/linux/firewire/JackFFADODriver.cpp @@ -272,7 +272,7 @@ JackFFADODriver::SetBufferSize (jack_nframes_t nframes) printError("Buffer size change requested but not supported!!!"); /* - driver->period_size = nframes; + driver->period_size = nframes; driver->period_usecs = (jack_time_t) floor ((((float) nframes) / driver->sample_rate) * 1000000.0f); @@ -362,6 +362,7 @@ int JackFFADODriver::Attach() int port_index; char buf[JACK_PORT_NAME_SIZE]; char portname[JACK_PORT_NAME_SIZE]; + jack_latency_range_t range; ffado_driver_t* driver = (ffado_driver_t*)fDriver; @@ -447,7 +448,8 @@ int JackFFADODriver::Attach() ffado_streaming_capture_stream_onoff(driver->dev, chn, 0); port = fGraphManager->GetPort(port_index); - port->SetLatency(driver->period_size + driver->capture_frame_latency); + range.min = range.max = driver->period_size + driver->capture_frame_latency; + port->SetLatencyRange(JackCaptureLatency, &range); // capture port aliases (jackd1 style port names) snprintf(buf, sizeof(buf) - 1, "%s:capture_%i", fClientControl.fName, (int) chn + 1); port->SetAlias(buf); @@ -479,7 +481,8 @@ int JackFFADODriver::Attach() driver->capture_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t)); port = fGraphManager->GetPort(port_index); - port->SetLatency(driver->period_size + driver->capture_frame_latency); + range.min = range.max = driver->period_size + driver->capture_frame_latency; + port->SetLatencyRange(JackCaptureLatency, &range); fCapturePortList[chn] = port_index; jack_log("JackFFADODriver::Attach fCapturePortList[i] %ld ", port_index); fCaptureChannels++; @@ -523,7 +526,8 @@ int JackFFADODriver::Attach() port = fGraphManager->GetPort(port_index); // Add one buffer more latency if "async" mode is used... - port->SetLatency((driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency); + range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency + port->SetLatencyRange(JackPlaybackLatency, &range); // playback port aliases (jackd1 style port names) snprintf(buf, sizeof(buf) - 1, "%s:playback_%i", fClientControl.fName, (int) chn + 1); port->SetAlias(buf); @@ -549,7 +553,7 @@ int JackFFADODriver::Attach() printError(" cannot enable port %s", buf); } // setup the midi buffer - + // This constructor optionally accepts arguments for the // non-realtime buffer size and the realtime buffer size. Ideally, // these would become command-line options for the FFADO driver. @@ -558,7 +562,8 @@ int JackFFADODriver::Attach() driver->playback_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t)); port = fGraphManager->GetPort(port_index); - port->SetLatency((driver->period_size * (driver->device_options.nb_buffers - 1)) + driver->playback_frame_latency); + range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + driver->playback_frame_latency; + port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[chn] = port_index; jack_log("JackFFADODriver::Attach fPlaybackPortList[i] %ld ", port_index); fPlaybackChannels++; @@ -676,7 +681,7 @@ retry: if (nframes == 0) { /* we detected an xrun and restarted: notify - * clients about the delay. + * clients about the delay. */ jack_log("FFADO XRun"); NotifyXRun(fBeginDateUst, fDelayedUsecs); @@ -685,7 +690,7 @@ retry: if (nframes != fEngineControl->fBufferSize) jack_log("JackFFADODriver::Read warning nframes = %ld", nframes); - + // Has to be done before read JackDriver::CycleIncTime(); @@ -755,7 +760,7 @@ extern "C" strcpy (desc->name, "firewire"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->desc, "Linux FFADO API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - + desc->nparams = 13; params = (jack_driver_param_desc_t *)calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); diff --git a/linux/freebob/JackFreebobDriver.cpp b/linux/freebob/JackFreebobDriver.cpp index 47860f21..552e9927 100644 --- a/linux/freebob/JackFreebobDriver.cpp +++ b/linux/freebob/JackFreebobDriver.cpp @@ -260,7 +260,7 @@ JackFreebobDriver::SetBufferSize (jack_nframes_t nframes) printError("Buffer size change requested but not supported!!!"); /* - driver->period_size = nframes; + driver->period_size = nframes; driver->period_usecs = (jack_time_t) floor ((((float) nframes) / driver->sample_rate) * 1000000.0f); @@ -667,9 +667,10 @@ int JackFreebobDriver::Attach() { JackPort* port; int port_index; - + char buf[JACK_PORT_NAME_SIZE]; char portname[JACK_PORT_NAME_SIZE]; + jack_latency_range_t range; freebob_driver_t* driver = (freebob_driver_t*)fDriver; @@ -737,7 +738,8 @@ int JackFreebobDriver::Attach() return -1; } port = fGraphManager->GetPort(port_index); - port->SetLatency(driver->period_size + driver->capture_frame_latency); + range.min = range.max = driver->period_size + driver->capture_frame_latency; + port->SetLatencyRange(JackCaptureLatency, &range); fCapturePortList[i] = port_index; jack_log("JackFreebobDriver::Attach fCapturePortList[i] %ld ", port_index); driver->capture_nchannels_audio++; @@ -766,7 +768,8 @@ int JackFreebobDriver::Attach() } port = fGraphManager->GetPort(port_index); // Add one buffer more latency if "async" mode is used... - port->SetLatency((driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency); + range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency); + port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[i] = port_index; jack_log("JackFreebobDriver::Attach fPlaybackPortList[i] %ld ", port_index); driver->playback_nchannels_audio++; @@ -866,7 +869,7 @@ retry: if (nframes == 0) { /* we detected an xrun and restarted: notify - * clients about the delay. + * clients about the delay. */ jack_log("FreeBoB XRun"); NotifyXRun(fBeginDateUst, fDelayedUsecs); @@ -878,7 +881,7 @@ retry: // Has to be done before read JackDriver::CycleIncTime(); - + printExit(); return freebob_driver_read((freebob_driver_t *)fDriver, fEngineControl->fBufferSize); } @@ -944,7 +947,7 @@ extern "C" strcpy (desc->name, "freebob"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->desc, "Linux FreeBob API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - + desc->nparams = 11; params = (jack_driver_param_desc_t *)calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); diff --git a/macosx/Jack-Info.plist b/macosx/Jack-Info.plist index ef3f8b07..0d714313 100644 --- a/macosx/Jack-Info.plist +++ b/macosx/Jack-Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable Jackservermp CFBundleGetInfoString - Jackdmp 1.9.7, @03-10 Paul Davis, Grame + Jackdmp 1.9.7, @03-11 Paul Davis, Grame CFBundleIdentifier com.grame.Jackmp CFBundleInfoDictionaryVersion diff --git a/macosx/JackMachThread.cpp b/macosx/JackMachThread.cpp index 0faaf941..19f99b54 100644 --- a/macosx/JackMachThread.cpp +++ b/macosx/JackMachThread.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. */ @@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -int JackMachThread::SetThreadToPriority(pthread_t thread, UInt32 inPriority, Boolean inIsFixed, UInt64 period, UInt64 computation, UInt64 constraint) +int JackMachThread::SetThreadToPriority(jack_native_thread_t thread, UInt32 inPriority, Boolean inIsFixed, UInt64 period, UInt64 computation, UInt64 constraint) { if (inPriority == 96) { // REAL-TIME / TIME-CONSTRAINT THREAD @@ -73,18 +73,18 @@ int JackMachThread::SetThreadToPriority(pthread_t thread, UInt32 inPriority, Boo } // returns the thread's priority as it was last set by the API -UInt32 JackMachThread::GetThreadSetPriority(pthread_t thread) +UInt32 JackMachThread::GetThreadSetPriority(jack_native_thread_t thread) { return GetThreadPriority(thread, THREAD_SET_PRIORITY); } // returns the thread's priority as it was last scheduled by the Kernel -UInt32 JackMachThread::GetThreadScheduledPriority(pthread_t thread) +UInt32 JackMachThread::GetThreadScheduledPriority(jack_native_thread_t thread) { return GetThreadPriority(thread, THREAD_SCHEDULED_PRIORITY); } -UInt32 JackMachThread::GetThreadPriority(pthread_t thread, int inWhichPriority) +UInt32 JackMachThread::GetThreadPriority(jack_native_thread_t thread, int inWhichPriority) { thread_basic_info_data_t threadInfo; policy_info_data_t thePolicyInfo; @@ -127,7 +127,7 @@ UInt32 JackMachThread::GetThreadPriority(pthread_t thread, int inWhichPriority) return 0; } -int JackMachThread::GetParams(pthread_t thread, UInt64* period, UInt64* computation, UInt64* constraint) +int JackMachThread::GetParams(jack_native_thread_t thread, UInt64* period, UInt64* computation, UInt64* constraint) { thread_time_constraint_policy_data_t theTCPolicy; mach_msg_type_number_t count = THREAD_TIME_CONSTRAINT_POLICY_COUNT; @@ -160,11 +160,11 @@ int JackMachThread::Kill() { // pthread_cancel still not yet implemented in Darwin (TO CHECK ON TIGER) jack_log("JackMachThread::Kill"); - - if (fThread != (pthread_t)NULL) { // If thread has been started + + if (fThread != (jack_native_thread_t)NULL) { // If thread has been started mach_port_t machThread = pthread_mach_thread_np(fThread); int res = (thread_terminate(machThread) == KERN_SUCCESS) ? 0 : -1; - fThread = (pthread_t)NULL; + fThread = (jack_native_thread_t)NULL; return res; } else { return -1; @@ -175,7 +175,7 @@ int JackMachThread::AcquireRealTime() { jack_log("JackMachThread::AcquireRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld", long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000)); - return (fThread != (pthread_t)NULL) ? AcquireRealTimeImp(fThread, fPeriod, fComputation, fConstraint) : -1; + return (fThread != (jack_native_thread_t)NULL) ? AcquireRealTimeImp(fThread, fPeriod, fComputation, fConstraint) : -1; } int JackMachThread::AcquireSelfRealTime() @@ -197,7 +197,7 @@ int JackMachThread::AcquireSelfRealTime(int priority) return AcquireSelfRealTime(); } -int JackMachThread::AcquireRealTimeImp(pthread_t thread, UInt64 period, UInt64 computation, UInt64 constraint) +int JackMachThread::AcquireRealTimeImp(jack_native_thread_t thread, UInt64 period, UInt64 computation, UInt64 constraint) { SetThreadToPriority(thread, 96, true, period, computation, constraint); return 0; @@ -205,7 +205,7 @@ int JackMachThread::AcquireRealTimeImp(pthread_t thread, UInt64 period, UInt64 c int JackMachThread::DropRealTime() { - return (fThread != (pthread_t)NULL) ? DropRealTimeImp(fThread) : -1; + return (fThread != (jack_native_thread_t)NULL) ? DropRealTimeImp(fThread) : -1; } int JackMachThread::DropSelfRealTime() @@ -213,7 +213,7 @@ int JackMachThread::DropSelfRealTime() return DropRealTimeImp(pthread_self()); } -int JackMachThread::DropRealTimeImp(pthread_t thread) +int JackMachThread::DropRealTimeImp(jack_native_thread_t thread) { SetThreadToPriority(thread, 63, false, 0, 0, 0); return 0; diff --git a/macosx/JackMachThread.h b/macosx/JackMachThread.h index d25331d2..eae474f2 100644 --- a/macosx/JackMachThread.h +++ b/macosx/JackMachThread.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. */ @@ -98,9 +98,9 @@ class SERVER_EXPORT JackMachThread : public JackPosixThread UInt64 fComputation; UInt64 fConstraint; - static UInt32 GetThreadSetPriority(pthread_t thread); - static UInt32 GetThreadScheduledPriority(pthread_t thread); - static UInt32 GetThreadPriority(pthread_t thread, int inWhichPriority); + static UInt32 GetThreadSetPriority(jack_native_thread_t thread); + static UInt32 GetThreadScheduledPriority(jack_native_thread_t thread); + static UInt32 GetThreadPriority(jack_native_thread_t thread, int inWhichPriority); public: @@ -116,23 +116,23 @@ class SERVER_EXPORT JackMachThread : public JackPosixThread int AcquireRealTime(); // Used when called from another thread int AcquireSelfRealTime(); // Used when called from thread itself - + int AcquireRealTime(int priority); // Used when called from another thread int AcquireSelfRealTime(int priority); // Used when called from thread itself - + int DropRealTime(); // Used when called from another thread int DropSelfRealTime(); // Used when called from thread itself - + void SetParams(UInt64 period, UInt64 computation, UInt64 constraint); - static int GetParams(pthread_t thread, UInt64* period, UInt64* computation, UInt64* constraint); - static int SetThreadToPriority(pthread_t thread, UInt32 inPriority, Boolean inIsFixed, UInt64 period, UInt64 computation, UInt64 constraint); + static int GetParams(jack_native_thread_t thread, UInt64* period, UInt64* computation, UInt64* constraint); + static int SetThreadToPriority(jack_native_thread_t thread, UInt32 inPriority, Boolean inIsFixed, UInt64 period, UInt64 computation, UInt64 constraint); - static int AcquireRealTimeImp(pthread_t thread, UInt64 period, UInt64 computation, UInt64 constraint); - static int AcquireRealTimeImp(pthread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) - { - return JackMachThread::AcquireRealTimeImp(thread, period, computation, constraint); + static int AcquireRealTimeImp(jack_native_thread_t thread, UInt64 period, UInt64 computation, UInt64 constraint); + static int AcquireRealTimeImp(jack_native_thread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) + { + return JackMachThread::AcquireRealTimeImp(thread, period, computation, constraint); } - static int DropRealTimeImp(pthread_t thread); + static int DropRealTimeImp(jack_native_thread_t thread); }; } // end of namespace diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index 8c457330..1c3370aa 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -48,6 +48,8 @@ 4BFA833C0DF6AB540087B4E1 /* PBXTargetDependency */, 4B32258F10A31AB400838A8E /* PBXTargetDependency */, 4B66550E127C356E00753A79 /* PBXTargetDependency */, + 4B38120313269CCB00C61B14 /* PBXTargetDependency */, + 4B8F16FC1329169F0002AD73 /* PBXTargetDependency */, ); name = "All Universal 32/64 bits"; productName = All; @@ -94,6 +96,8 @@ 4B363F530DEB0CFE001F72D9 /* PBXTargetDependency */, 4B363F780DEB0D85001F72D9 /* PBXTargetDependency */, 4B32258B10A31A9000838A8E /* PBXTargetDependency */, + 4B38120113269CB600C61B14 /* PBXTargetDependency */, + 4B8F16FA132916910002AD73 /* PBXTargetDependency */, ); name = "All Universal 32 bits"; productName = All; @@ -110,6 +114,18 @@ 4B19B31B0E2362E800DD4A82 /* JackLibSampleRateResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B30E0E2362E700DD4A82 /* JackLibSampleRateResampler.cpp */; }; 4B19B31C0E2362E800DD4A82 /* JackLibSampleRateResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */; }; 4B19B31F0E2362E800DD4A82 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */; }; + 4B2209E112F6BBF300E5DC26 /* JackSocketServerChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B30E703B8D0066E42F /* JackSocketServerChannel.cpp */; }; + 4B2209E212F6BBF400E5DC26 /* JackSocketServerChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B40E703B8D0066E42F /* JackSocketServerChannel.h */; }; + 4B2209E312F6BBF500E5DC26 /* JackSocketServerNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B50E703B8D0066E42F /* JackSocketServerNotifyChannel.cpp */; }; + 4B2209E412F6BBF600E5DC26 /* JackSocketServerNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B60E703B8D0066E42F /* JackSocketServerNotifyChannel.h */; }; + 4B2209E612F6BC0200E5DC26 /* JackSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6AD0E703B8D0066E42F /* JackSocket.cpp */; }; + 4B2209E712F6BC0300E5DC26 /* JackSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6AE0E703B8D0066E42F /* JackSocket.h */; }; + 4B2209E912F6BC1500E5DC26 /* JackSocketNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B10E703B8D0066E42F /* JackSocketNotifyChannel.cpp */; }; + 4B2209EA12F6BC1600E5DC26 /* JackSocketNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B20E703B8D0066E42F /* JackSocketNotifyChannel.h */; }; + 4B2209EC12F6BC2100E5DC26 /* JackSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6AD0E703B8D0066E42F /* JackSocket.cpp */; }; + 4B2209ED12F6BC2200E5DC26 /* JackSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6AE0E703B8D0066E42F /* JackSocket.h */; }; + 4B2209EE12F6BC2300E5DC26 /* JackSocketClientChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6AF0E703B8D0066E42F /* JackSocketClientChannel.cpp */; }; + 4B2209EF12F6BC2500E5DC26 /* JackSocketClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B00E703B8D0066E42F /* JackSocketClientChannel.h */; }; 4B3224EA10A315B100838A8E /* JackNetOneDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224E810A315B100838A8E /* JackNetOneDriver.cpp */; }; 4B3224EB10A315B100838A8E /* JackNetOneDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224E910A315B100838A8E /* JackNetOneDriver.h */; }; 4B3224F010A315C400838A8E /* netjack_packet.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EC10A315C400838A8E /* netjack_packet.c */; }; @@ -277,7 +293,6 @@ 4B35C53D0D4731D1000DE7AE /* connect.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B60CE480AAABA31004956AA /* connect.c */; }; 4B35C5490D4731D1000DE7AE /* connect.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B60CE480AAABA31004956AA /* connect.c */; }; 4B35C5570D4731D2000DE7AE /* freewheel.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1710834EE0F00C94B91 /* freewheel.c */; }; - 4B35C5630D4731D2000DE7AE /* jdelay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFA99A90AAAF40C009E916C /* jdelay.cpp */; }; 4B35C57D0D4731D2000DE7AE /* testAtomic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D23E0834F1C300C94B91 /* testAtomic.cpp */; }; 4B35C58D0D4731D2000DE7AE /* testSem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2470834F20600C94B91 /* testSem.cpp */; }; 4B35C59F0D4731D2000DE7AE /* zombie.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1670834EDD900C94B91 /* zombie.c */; }; @@ -302,6 +317,10 @@ 4B363F230DEB0AB0001F72D9 /* monitor_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363F220DEB0AB0001F72D9 /* monitor_client.c */; }; 4B363F3E0DEB0C31001F72D9 /* showtime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363F3D0DEB0C31001F72D9 /* showtime.c */; }; 4B363F760DEB0D7D001F72D9 /* impulse_grabber.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363F750DEB0D7D001F72D9 /* impulse_grabber.c */; }; + 4B3811FB13269C8300C61B14 /* latent_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3811FA13269C8300C61B14 /* latent_client.c */; }; + 4B3811FC13269C8300C61B14 /* latent_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3811FA13269C8300C61B14 /* latent_client.c */; }; + 4B3814201327AA6800C61B14 /* iodelay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B38141F1327AA6800C61B14 /* iodelay.cpp */; }; + 4B3814211327AA6800C61B14 /* iodelay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B38141F1327AA6800C61B14 /* iodelay.cpp */; }; 4B3F49080AD8503300491C6E /* cpu.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3F49070AD8503300491C6E /* cpu.c */; }; 4B43A8CA1014605000E52943 /* JackLoopbackDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B43A8C81014605000E52943 /* JackLoopbackDriver.cpp */; }; 4B43A8CB1014605000E52943 /* JackLoopbackDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B43A8C91014605000E52943 /* JackLoopbackDriver.h */; }; @@ -396,6 +415,10 @@ 4B4F9C930DC20C0400706CB0 /* JackMessageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4F9C8B0DC20C0400706CB0 /* JackMessageBuffer.h */; }; 4B4F9D820DC2178E00706CB0 /* JackMessageBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4F9C8A0DC20C0400706CB0 /* JackMessageBuffer.cpp */; }; 4B4F9D830DC2178F00706CB0 /* JackMessageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4F9C8B0DC20C0400706CB0 /* JackMessageBuffer.h */; }; + 4B5160A813215E8B00BB7DCB /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B5160A913215EBF00BB7DCB /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B5160AA13215ED900BB7DCB /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B5160AE13215EF900BB7DCB /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B5A1BBE0CD1CC110005BF74 /* midiseq.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B5A1BBD0CD1CC110005BF74 /* midiseq.c */; }; 4B5A1BDD0CD1CD420005BF74 /* midisine.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B5A1BDC0CD1CD420005BF74 /* midisine.c */; }; 4B5DB9830CD2429A00EBA5EE /* JackDebugClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B98AE000931D30C0091932A /* JackDebugClient.cpp */; }; @@ -560,6 +583,8 @@ 4B8A38F1117B827E00664E07 /* JackSocketClientChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6AF0E703B8D0066E42F /* JackSocketClientChannel.cpp */; }; 4B8A38F6117B82AB00664E07 /* JackSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6AD0E703B8D0066E42F /* JackSocket.cpp */; }; 4B8A38F7117B82B200664E07 /* JackSocketClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B00E703B8D0066E42F /* JackSocketClientChannel.h */; }; + 4B8F16F51329161E0002AD73 /* midi_dump.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B8F16F41329161E0002AD73 /* midi_dump.c */; }; + 4B8F16F61329161E0002AD73 /* midi_dump.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B8F16F41329161E0002AD73 /* midi_dump.c */; }; 4B93F1990E87992100E4ECCD /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; 4B93F19A0E87992200E4ECCD /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; 4B93F19C0E87998200E4ECCD /* JackPosixServerLaunch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBBA0E878B9C003D2374 /* JackPosixServerLaunch.cpp */; }; @@ -819,7 +844,6 @@ 4BFA82B00DF6A9E40087B4E1 /* monitor_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363F220DEB0AB0001F72D9 /* monitor_client.c */; }; 4BFA82BC0DF6A9E40087B4E1 /* showtime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363F3D0DEB0C31001F72D9 /* showtime.c */; }; 4BFA82C80DF6A9E40087B4E1 /* impulse_grabber.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363F750DEB0D7D001F72D9 /* impulse_grabber.c */; }; - 4BFA99AA0AAAF40C009E916C /* jdelay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFA99A90AAAF40C009E916C /* jdelay.cpp */; }; BA047C760E14E79D0041F3B6 /* JackNetSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = BA047C710E14E7540041F3B6 /* JackNetSocket.h */; }; BA222AD80DC88268001A17F4 /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA222AD60DC88268001A17F4 /* JackNetTool.cpp */; }; BA222AD90DC88269001A17F4 /* JackNetTool.h in Headers */ = {isa = PBXBuildFile; fileRef = BA222AD70DC88268001A17F4 /* JackNetTool.h */; }; @@ -1084,6 +1108,20 @@ remoteGlobalIDString = 4B363F680DEB0D4E001F72D9; remoteInfo = "jack_impulse_grabber Universal"; }; + 4B38120013269CB600C61B14 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B3811551326878E00C61B14; + remoteInfo = "jack_latent_client Universal"; + }; + 4B38120213269CCB00C61B14 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B38118D1326884E00C61B14; + remoteInfo = "jack_latent_client 64 bits"; + }; 4B43A8CC1014607100E52943 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; @@ -1161,6 +1199,20 @@ remoteGlobalIDString = 4B699D03097D421600A18468; remoteInfo = "jack_external_metro Universal"; }; + 4B8F16F9132916910002AD73 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B8F16DB13290DC80002AD73; + remoteInfo = "jack_midi_dump Universal"; + }; + 4B8F16FB1329169F0002AD73 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B8F16E813290E0E0002AD73; + remoteInfo = "jack_midi_dump 64 bits"; + }; 4BA693E80CBE5BBA00EAD520 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; @@ -1436,7 +1488,7 @@ 4B35C5440D4731D1000DE7AE /* jack_connect */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_connect; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5500D4731D1000DE7AE /* jack_disconnect */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_disconnect; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C55E0D4731D2000DE7AE /* jack_freewheel */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_freewheel; sourceTree = BUILT_PRODUCTS_DIR; }; - 4B35C56A0D4731D2000DE7AE /* jdelay */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jdelay; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B35C56A0D4731D2000DE7AE /* jack_iodelay */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_iodelay; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5760D4731D2000DE7AE /* jack_external_metro */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_external_metro; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C5860D4731D2000DE7AE /* testAtomic */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testAtomic; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C59A0D4731D2000DE7AE /* testSem */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testSem; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1469,6 +1521,10 @@ 4B37C20306DF1FBE0016E567 /* CALatencyLog.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CALatencyLog.cpp; path = /Developer/Examples/CoreAudio/PublicUtility/CALatencyLog.cpp; sourceTree = ""; }; 4B37C20406DF1FBE0016E567 /* CALatencyLog.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CALatencyLog.h; path = /Developer/Examples/CoreAudio/PublicUtility/CALatencyLog.h; sourceTree = ""; }; 4B37C20906DF1FE20016E567 /* latency.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = latency.c; path = /Developer/Examples/CoreAudio/PublicUtility/latency.c; sourceTree = ""; }; + 4B38115F1326878E00C61B14 /* jack_latent_client */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_latent_client; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B3811971326884E00C61B14 /* jack_latent_client */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_latent_client; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B3811FA13269C8300C61B14 /* latent_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = latent_client.c; path = "../example-clients/latent_client.c"; sourceTree = SOURCE_ROOT; }; + 4B38141F1327AA6800C61B14 /* iodelay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = iodelay.cpp; path = ../tests/iodelay.cpp; sourceTree = SOURCE_ROOT; }; 4B3F49070AD8503300491C6E /* cpu.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpu.c; path = ../tests/cpu.c; sourceTree = SOURCE_ROOT; }; 4B43A8BA10145F6F00E52943 /* jack_loopback.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_loopback.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B43A8C81014605000E52943 /* JackLoopbackDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackLoopbackDriver.cpp; path = ../common/JackLoopbackDriver.cpp; sourceTree = SOURCE_ROOT; }; @@ -1531,6 +1587,9 @@ 4B869D7F08C9CB00001CF041 /* JackDriverLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackDriverLoader.cpp; path = ../common/JackDriverLoader.cpp; sourceTree = SOURCE_ROOT; }; 4B88D03911298BEE007A87C1 /* weakjack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = weakjack.h; path = ../common/jack/weakjack.h; sourceTree = SOURCE_ROOT; }; 4B88D03A11298BEE007A87C1 /* weakmacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = weakmacros.h; path = ../common/jack/weakmacros.h; sourceTree = SOURCE_ROOT; }; + 4B8F16E513290DC80002AD73 /* jack_midi_dump */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midi_dump; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B8F16F213290E0E0002AD73 /* jack_midi_dump */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midi_dump; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B8F16F41329161E0002AD73 /* midi_dump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = midi_dump.c; path = "../example-clients/midi_dump.c"; sourceTree = SOURCE_ROOT; }; 4B940B9B06DDDE5B00D77F60 /* AudioHardware.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AudioHardware.h; path = /System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/AudioHardware.h; sourceTree = ""; }; 4B94334910A5E666002A187F /* systemdeps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = systemdeps.h; path = ../common/jack/systemdeps.h; sourceTree = SOURCE_ROOT; }; 4B95BCAD0D913073000F7695 /* control.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = control.h; path = ../common/jack/control.h; sourceTree = SOURCE_ROOT; }; @@ -1685,8 +1744,7 @@ 4BFA82B70DF6A9E40087B4E1 /* jack_monitor_client */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_monitor_client; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA82C30DF6A9E40087B4E1 /* jack_showtime */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_showtime; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA82CF0DF6A9E40087B4E1 /* jack_impulse_grabber */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_impulse_grabber; sourceTree = BUILT_PRODUCTS_DIR; }; - 4BFA99A20AAAF3B0009E916C /* jdelay */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jdelay; sourceTree = BUILT_PRODUCTS_DIR; }; - 4BFA99A90AAAF40C009E916C /* jdelay.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = jdelay.cpp; path = ../tests/jdelay.cpp; sourceTree = SOURCE_ROOT; }; + 4BFA99A20AAAF3B0009E916C /* jack_iodelay */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_iodelay; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFB73F608AD291A00DB99B8 /* JackGlobals.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackGlobals.h; path = ../common/JackGlobals.h; sourceTree = SOURCE_ROOT; }; 4BFB741E08AD2B9900DB99B8 /* JackMachThread.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMachThread.cpp; sourceTree = SOURCE_ROOT; }; 4BFB741F08AD2B9900DB99B8 /* JackMachThread.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JackMachThread.h; sourceTree = SOURCE_ROOT; }; @@ -1990,6 +2048,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B3811591326878E00C61B14 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B3811911326884E00C61B14 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B43A8B510145F6F00E52943 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -2161,6 +2233,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B8F16DF13290DC80002AD73 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B8F16EC13290E0E0002AD73 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B978DB60A31CF4A009E2DD1 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -2397,7 +2483,7 @@ 4B699DB0097D421700A18468 /* jack_dummy.so */, 4B978DBB0A31CF4A009E2DD1 /* jack_portaudio.so */, 4BE6C6A30A3E096F005A203A /* jack_test */, - 4BFA99A20AAAF3B0009E916C /* jdelay */, + 4BFA99A20AAAF3B0009E916C /* jack_iodelay */, 4BE99D300AD7A04800C59091 /* jack_cpu */, 4BD623F70CBCF0F000DE782F /* inprocess.so */, 4BA692B00CBE4BC700EAD520 /* jack_load */, @@ -2414,7 +2500,7 @@ 4B35C5440D4731D1000DE7AE /* jack_connect */, 4B35C5500D4731D1000DE7AE /* jack_disconnect */, 4B35C55E0D4731D2000DE7AE /* jack_freewheel */, - 4B35C56A0D4731D2000DE7AE /* jdelay */, + 4B35C56A0D4731D2000DE7AE /* jack_iodelay */, 4B35C5760D4731D2000DE7AE /* jack_external_metro */, 4B35C5860D4731D2000DE7AE /* testAtomic */, 4B35C59A0D4731D2000DE7AE /* testSem */, @@ -2468,6 +2554,10 @@ 4BA339AC10B2E36800190E3B /* Jackservermp.framework */, 4B47ACD710B5890100469C67 /* Jackmp.framework */, 4B6654F7127C34AE00753A79 /* jack_server_control */, + 4B38115F1326878E00C61B14 /* jack_latent_client */, + 4B3811971326884E00C61B14 /* jack_latent_client */, + 4B8F16E513290DC80002AD73 /* jack_midi_dump */, + 4B8F16F213290E0E0002AD73 /* jack_midi_dump */, ); name = Products; sourceTree = ""; @@ -2475,6 +2565,8 @@ 4B03383E0797E19900686131 /* Simple clients */ = { isa = PBXGroup; children = ( + 4B8F16F41329161E0002AD73 /* midi_dump.c */, + 4B3811FA13269C8300C61B14 /* latent_client.c */, 4B6654FB127C350100753A79 /* server_control.cpp */, 4B363F750DEB0D7D001F72D9 /* impulse_grabber.c */, 4B363F220DEB0AB0001F72D9 /* monitor_client.c */, @@ -2628,8 +2720,8 @@ 4B6BEB4A07A6CCDC00A5DBDA /* Tests */ = { isa = PBXGroup; children = ( + 4B38141F1327AA6800C61B14 /* iodelay.cpp */, 4B3F49070AD8503300491C6E /* cpu.c */, - 4BFA99A90AAAF40C009E916C /* jdelay.cpp */, 4BF8D23E0834F1C300C94B91 /* testAtomic.cpp */, 4BF8D2470834F20600C94B91 /* testSem.cpp */, 4BA577BC08BF8BE200F82DE1 /* testSynchroClient.cpp */, @@ -3086,6 +3178,7 @@ 4B88D04011298BEE007A87C1 /* weakmacros.h in Headers */, 4B8A38F0117B827900664E07 /* JackSocket.h in Headers */, 4B8A38F7117B82B200664E07 /* JackSocketClientChannel.h in Headers */, + 4B5160A813215E8B00BB7DCB /* systemdeps.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3158,6 +3251,7 @@ 4B8A38AD117B810A00664E07 /* JackSocketNotifyChannel.h in Headers */, 4B8A38B0117B812500664E07 /* JackSocketServerChannel.h in Headers */, 4B8A38C4117B814000664E07 /* JackSocketServerNotifyChannel.h in Headers */, + 4B5160AA13215ED900BB7DCB /* systemdeps.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3376,6 +3470,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B3811561326878E00C61B14 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B38118E1326884E00C61B14 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B43A8B110145F6F00E52943 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -3438,6 +3546,7 @@ 4B47ACAB10B5890100469C67 /* JackProcessSync.h in Headers */, 4B88D04111298BEE007A87C1 /* weakjack.h in Headers */, 4B88D04211298BEE007A87C1 /* weakmacros.h in Headers */, + 4B5160A913215EBF00BB7DCB /* systemdeps.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3527,6 +3636,8 @@ 4B94334A10A5E666002A187F /* systemdeps.h in Headers */, 4B88D03B11298BEE007A87C1 /* weakjack.h in Headers */, 4B88D03C11298BEE007A87C1 /* weakmacros.h in Headers */, + 4B2209ED12F6BC2200E5DC26 /* JackSocket.h in Headers */, + 4B2209EF12F6BC2500E5DC26 /* JackSocketClientChannel.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3599,6 +3710,10 @@ 4B88D03E11298BEE007A87C1 /* weakmacros.h in Headers */, 4BC2CA56113C6C940076717C /* JackNetInterface.h in Headers */, 4BC2CA58113C6C9C0076717C /* JackNetUnixSocket.h in Headers */, + 4B2209E212F6BBF400E5DC26 /* JackSocketServerChannel.h in Headers */, + 4B2209E412F6BBF600E5DC26 /* JackSocketServerNotifyChannel.h in Headers */, + 4B2209E712F6BC0300E5DC26 /* JackSocket.h in Headers */, + 4B2209EA12F6BC1600E5DC26 /* JackSocketNotifyChannel.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3702,6 +3817,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B8F16DC13290DC80002AD73 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B8F16E913290E0E0002AD73 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B978DB20A31CF4A009E2DD1 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -3776,6 +3905,7 @@ 4B88D04611298BEE007A87C1 /* weakmacros.h in Headers */, 4BC2CA5E113C6CCA0076717C /* JackNetInterface.h in Headers */, 4BC2CA60113C6CD20076717C /* JackNetUnixSocket.h in Headers */, + 4B5160AE13215EF900BB7DCB /* systemdeps.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4268,9 +4398,9 @@ productReference = 4B35C55E0D4731D2000DE7AE /* jack_freewheel */; productType = "com.apple.product-type.tool"; }; - 4B35C5600D4731D2000DE7AE /* jdelay 64 bits */ = { + 4B35C5600D4731D2000DE7AE /* jack_iodelay 64 bits */ = { isa = PBXNativeTarget; - buildConfigurationList = 4B35C5660D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jdelay 64 bits" */; + buildConfigurationList = 4B35C5660D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_iodelay 64 bits" */; buildPhases = ( 4B35C5610D4731D2000DE7AE /* Headers */, 4B35C5620D4731D2000DE7AE /* Sources */, @@ -4281,10 +4411,10 @@ ); dependencies = ( ); - name = "jdelay 64 bits"; + name = "jack_iodelay 64 bits"; productInstallPath = /usr/local/bin; productName = jack_lsp; - productReference = 4B35C56A0D4731D2000DE7AE /* jdelay */; + productReference = 4B35C56A0D4731D2000DE7AE /* jack_iodelay */; productType = "com.apple.product-type.tool"; }; 4B35C56C0D4731D2000DE7AE /* jack_external_metro 64 bits */ = { @@ -4697,6 +4827,44 @@ productReference = 4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */; productType = "com.apple.product-type.tool"; }; + 4B3811551326878E00C61B14 /* jack_latent_client Universal */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B38115B1326878E00C61B14 /* Build configuration list for PBXNativeTarget "jack_latent_client Universal" */; + buildPhases = ( + 4B3811561326878E00C61B14 /* Headers */, + 4B3811571326878E00C61B14 /* Sources */, + 4B3811591326878E00C61B14 /* Frameworks */, + 4B38115A1326878E00C61B14 /* Rez */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "jack_latent_client Universal"; + productInstallPath = /usr/local/bin; + productName = jack_metro; + productReference = 4B38115F1326878E00C61B14 /* jack_latent_client */; + productType = "com.apple.product-type.tool"; + }; + 4B38118D1326884E00C61B14 /* jack_latent_client 64 bits */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B3811931326884E00C61B14 /* Build configuration list for PBXNativeTarget "jack_latent_client 64 bits" */; + buildPhases = ( + 4B38118E1326884E00C61B14 /* Headers */, + 4B38118F1326884E00C61B14 /* Sources */, + 4B3811911326884E00C61B14 /* Frameworks */, + 4B3811921326884E00C61B14 /* Rez */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "jack_latent_client 64 bits"; + productInstallPath = /usr/local/bin; + productName = jack_metro; + productReference = 4B3811971326884E00C61B14 /* jack_latent_client */; + productType = "com.apple.product-type.tool"; + }; 4B43A8B010145F6F00E52943 /* jack_loopback Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B43A8B610145F6F00E52943 /* Build configuration list for PBXNativeTarget "jack_loopback Universal" */; @@ -5144,6 +5312,44 @@ productReference = 4B699DB0097D421700A18468 /* jack_dummy.so */; productType = "com.apple.product-type.library.dynamic"; }; + 4B8F16DB13290DC80002AD73 /* jack_midi_dump Universal */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B8F16E113290DC80002AD73 /* Build configuration list for PBXNativeTarget "jack_midi_dump Universal" */; + buildPhases = ( + 4B8F16DC13290DC80002AD73 /* Headers */, + 4B8F16DD13290DC80002AD73 /* Sources */, + 4B8F16DF13290DC80002AD73 /* Frameworks */, + 4B8F16E013290DC80002AD73 /* Rez */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "jack_midi_dump Universal"; + productInstallPath = /usr/local/bin; + productName = jack_metro; + productReference = 4B8F16E513290DC80002AD73 /* jack_midi_dump */; + productType = "com.apple.product-type.tool"; + }; + 4B8F16E813290E0E0002AD73 /* jack_midi_dump 64 bits */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B8F16EE13290E0E0002AD73 /* Build configuration list for PBXNativeTarget "jack_midi_dump 64 bits" */; + buildPhases = ( + 4B8F16E913290E0E0002AD73 /* Headers */, + 4B8F16EA13290E0E0002AD73 /* Sources */, + 4B8F16EC13290E0E0002AD73 /* Frameworks */, + 4B8F16ED13290E0E0002AD73 /* Rez */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "jack_midi_dump 64 bits"; + productInstallPath = /usr/local/bin; + productName = jack_metro; + productReference = 4B8F16F213290E0E0002AD73 /* jack_midi_dump */; + productType = "com.apple.product-type.tool"; + }; 4B978DB10A31CF4A009E2DD1 /* jack_portaudio Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B978DB70A31CF4A009E2DD1 /* Build configuration list for PBXNativeTarget "jack_portaudio Universal" */; @@ -5527,9 +5733,9 @@ productReference = 4BFA82CF0DF6A9E40087B4E1 /* jack_impulse_grabber */; productType = "com.apple.product-type.tool"; }; - 4BFA99980AAAF3B0009E916C /* jdelay Universal */ = { + 4BFA99980AAAF3B0009E916C /* jack_iodelay Universal */ = { isa = PBXNativeTarget; - buildConfigurationList = 4BFA999E0AAAF3B0009E916C /* Build configuration list for PBXNativeTarget "jdelay Universal" */; + buildConfigurationList = 4BFA999E0AAAF3B0009E916C /* Build configuration list for PBXNativeTarget "jack_iodelay Universal" */; buildPhases = ( 4BFA99990AAAF3B0009E916C /* Headers */, 4BFA999A0AAAF3B0009E916C /* Sources */, @@ -5540,10 +5746,10 @@ ); dependencies = ( ); - name = "jdelay Universal"; + name = "jack_iodelay Universal"; productInstallPath = /usr/local/bin; productName = jack_lsp; - productReference = 4BFA99A20AAAF3B0009E916C /* jdelay */; + productReference = 4BFA99A20AAAF3B0009E916C /* jack_iodelay */; productType = "com.apple.product-type.tool"; }; BA222AC50DC88132001A17F4 /* jack_net Universal */ = { @@ -5607,13 +5813,14 @@ 4B699C4C097D421600A18468 /* Jackservermp.framework Universal */, 4B5A1BB10CD1CB9E0005BF74 /* jack_midiseq Universal */, 4B5A1BD00CD1CCE10005BF74 /* jack_midisine Universal */, + 4B8F16DB13290DC80002AD73 /* jack_midi_dump Universal */, 4B363DCE0DEB02F6001F72D9 /* jack_alias Universal */, 4B699CB1097D421600A18468 /* jack_metro Universal */, 4B699CC1097D421600A18468 /* jack_lsp Universal */, 4B699CD1097D421600A18468 /* jack_connect Universal */, 4B699CE1097D421600A18468 /* jack_disconnect Universal */, 4B699CF1097D421600A18468 /* jack_freewheel Universal */, - 4BFA99980AAAF3B0009E916C /* jdelay Universal */, + 4BFA99980AAAF3B0009E916C /* jack_iodelay Universal */, 4B699D03097D421600A18468 /* jack_external_metro Universal */, 4B699D13097D421600A18468 /* testAtomic Universal */, 4B699D27097D421600A18468 /* testSem Universal */, @@ -5628,6 +5835,7 @@ 4B363E100DEB03C5001F72D9 /* jack_evmon Universal */, 4B363E440DEB0775001F72D9 /* jack_bufsize Universal */, 4B363EDF0DEB091C001F72D9 /* jack_rec Universal */, + 4B3811551326878E00C61B14 /* jack_latent_client Universal */, 4B363F140DEB0A6A001F72D9 /* jack_monitor_client Universal */, 4B363F2B0DEB0BD1001F72D9 /* jack_showtime Universal */, 4B363F680DEB0D4E001F72D9 /* jack_impulse_grabber Universal */, @@ -5653,12 +5861,13 @@ 4BA3393310B2E36800190E3B /* Jackservermp.framework 64 bits profiling */, 4B35C50A0D4731D1000DE7AE /* jack_midiseq 64 bits */, 4B35C5160D4731D1000DE7AE /* jack_midisine 64 bits */, + 4B8F16E813290E0E0002AD73 /* jack_midi_dump 64 bits */, 4B35C5220D4731D1000DE7AE /* jack_metro 64 bits */, 4B35C52E0D4731D1000DE7AE /* jack_lsp 64 bits */, 4B35C53A0D4731D1000DE7AE /* jack_connect 64 bits */, 4B35C5460D4731D1000DE7AE /* jack_disconnect 64 bits */, 4B35C5520D4731D2000DE7AE /* jack_freewheel 64 bits */, - 4B35C5600D4731D2000DE7AE /* jdelay 64 bits */, + 4B35C5600D4731D2000DE7AE /* jack_iodelay 64 bits */, 4B35C56C0D4731D2000DE7AE /* jack_external_metro 64 bits */, 4B35C5780D4731D2000DE7AE /* testAtomic 64 bits */, 4B35C5880D4731D2000DE7AE /* testSem 64 bits */, @@ -5671,6 +5880,7 @@ 4BFA82820DF6A9E40087B4E1 /* jack_evmon 64 bits */, 4BFA82950DF6A9E40087B4E1 /* jack_bufsize 64 bits */, 4BFA82A10DF6A9E40087B4E1 /* jack_rec 64 bits */, + 4B38118D1326884E00C61B14 /* jack_latent_client 64 bits */, 4BFA82AD0DF6A9E40087B4E1 /* jack_monitor_client 64 bits */, 4BFA82B90DF6A9E40087B4E1 /* jack_showtime 64 bits */, 4BFA82C50DF6A9E40087B4E1 /* jack_impulse_grabber 64 bits */, @@ -5971,6 +6181,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B38115A1326878E00C61B14 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B3811921326884E00C61B14 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B47ACD010B5890100469C67 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; @@ -6104,6 +6328,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B8F16E013290DC80002AD73 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B8F16ED13290E0E0002AD73 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BA339A510B2E36800190E3B /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; @@ -6441,7 +6679,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4B35C5630D4731D2000DE7AE /* jdelay.cpp in Sources */, + 4B3814211327AA6800C61B14 /* iodelay.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6623,6 +6861,22 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B3811571326878E00C61B14 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B3811FC13269C8300C61B14 /* latent_client.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B38118F1326884E00C61B14 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B3811FB13269C8300C61B14 /* latent_client.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B43A8B310145F6F00E52943 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -6754,6 +7008,8 @@ 4BF5FBBC0E878B9C003D2374 /* JackPosixServerLaunch.cpp in Sources */, 4BF5FBCB0E878D24003D2374 /* JackMachTime.c in Sources */, 4BECB2F70F4451C10091B70A /* JackProcessSync.cpp in Sources */, + 4B2209EC12F6BC2100E5DC26 /* JackSocket.cpp in Sources */, + 4B2209EE12F6BC2300E5DC26 /* JackSocketClientChannel.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6810,6 +7066,10 @@ 4BCBCE5F10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */, 4BC2CA55113C6C930076717C /* JackNetInterface.cpp in Sources */, 4BC2CA57113C6C9B0076717C /* JackNetUnixSocket.cpp in Sources */, + 4B2209E112F6BBF300E5DC26 /* JackSocketServerChannel.cpp in Sources */, + 4B2209E312F6BBF500E5DC26 /* JackSocketServerNotifyChannel.cpp in Sources */, + 4B2209E612F6BC0200E5DC26 /* JackSocket.cpp in Sources */, + 4B2209E912F6BC1500E5DC26 /* JackSocketNotifyChannel.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6924,6 +7184,22 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B8F16DD13290DC80002AD73 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B8F16F51329161E0002AD73 /* midi_dump.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B8F16EA13290E0E0002AD73 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B8F16F61329161E0002AD73 /* midi_dump.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B978DB40A31CF4A009E2DD1 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -7154,7 +7430,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4BFA99AA0AAAF40C009E916C /* jdelay.cpp in Sources */, + 4B3814201327AA6800C61B14 /* iodelay.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7279,7 +7555,7 @@ }; 4B35C6940D4733B9000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4B35C5600D4731D2000DE7AE /* jdelay 64 bits */; + target = 4B35C5600D4731D2000DE7AE /* jack_iodelay 64 bits */; targetProxy = 4B35C6930D4733B9000DE7AE /* PBXContainerItemProxy */; }; 4B35C6960D4733B9000DE7AE /* PBXTargetDependency */ = { @@ -7357,6 +7633,16 @@ target = 4B363F680DEB0D4E001F72D9 /* jack_impulse_grabber Universal */; targetProxy = 4B363F770DEB0D85001F72D9 /* PBXContainerItemProxy */; }; + 4B38120113269CB600C61B14 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4B3811551326878E00C61B14 /* jack_latent_client Universal */; + targetProxy = 4B38120013269CB600C61B14 /* PBXContainerItemProxy */; + }; + 4B38120313269CCB00C61B14 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4B38118D1326884E00C61B14 /* jack_latent_client 64 bits */; + targetProxy = 4B38120213269CCB00C61B14 /* PBXContainerItemProxy */; + }; 4B43A8CD1014607100E52943 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B43A8B010145F6F00E52943 /* jack_loopback Universal */; @@ -7412,6 +7698,16 @@ target = 4B699D03097D421600A18468 /* jack_external_metro Universal */; targetProxy = 4B699DBF097D421700A18468 /* PBXContainerItemProxy */; }; + 4B8F16FA132916910002AD73 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4B8F16DB13290DC80002AD73 /* jack_midi_dump Universal */; + targetProxy = 4B8F16F9132916910002AD73 /* PBXContainerItemProxy */; + }; + 4B8F16FC1329169F0002AD73 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4B8F16E813290E0E0002AD73 /* jack_midi_dump 64 bits */; + targetProxy = 4B8F16FB1329169F0002AD73 /* PBXContainerItemProxy */; + }; 4BA693E90CBE5BBA00EAD520 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4BA692A60CBE4BC700EAD520 /* jack_load Universal */; @@ -7534,7 +7830,7 @@ }; 4BFA99AC0AAAF41D009E916C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4BFA99980AAAF3B0009E916C /* jdelay Universal */; + target = 4BFA99980AAAF3B0009E916C /* jack_iodelay Universal */; targetProxy = 4BFA99AB0AAAF41D009E916C /* PBXContainerItemProxy */; }; BA222AF00DC883EF001A17F4 /* PBXTargetDependency */ = { @@ -7744,6 +8040,7 @@ GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( + /opt/local/include, ., ../posix, ../common/jack, @@ -7767,7 +8064,7 @@ ); OTHER_REZFLAGS = ""; PREBINDING = NO; - PRODUCT_NAME = netmanager; + PRODUCT_NAME = audioadapter; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( @@ -7793,6 +8090,7 @@ GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( + /opt/local/include, ., ../posix, ../common/jack, @@ -9613,7 +9911,7 @@ Jackmp, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jdelay; + PRODUCT_NAME = jack_iodelay; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -9642,7 +9940,7 @@ Jackmp, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jdelay; + PRODUCT_NAME = jack_iodelay; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -11442,7 +11740,7 @@ CoreFoundation, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midiseq; + PRODUCT_NAME = jack_alias; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -11539,7 +11837,7 @@ CoreFoundation, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midiseq; + PRODUCT_NAME = jack_evmon; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -11636,7 +11934,7 @@ CoreFoundation, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midiseq; + PRODUCT_NAME = jack_bufsize; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -11738,7 +12036,7 @@ CoreFoundation, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midiseq; + PRODUCT_NAME = jack_rec; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -11840,7 +12138,7 @@ CoreFoundation, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midiseq; + PRODUCT_NAME = jack_monitor_client; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -12034,7 +12332,7 @@ CoreFoundation, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midiseq; + PRODUCT_NAME = jack_impulse_grabber; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -12109,7 +12407,7 @@ }; name = Default; }; - 4B43A8B710145F6F00E52943 /* Development */ = { + 4B38115C1326878E00C61B14 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( @@ -12117,39 +12415,23 @@ ppc, ); COPY_PHASE_STRIP = NO; - DEBUGGING_SYMBOLS = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - EXECUTABLE_EXTENSION = so; + FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; - GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; - HEADER_SEARCH_PATHS = ( - ../common, - ../common/jack, - ., - ../posix, - ); - INSTALL_PATH = /usr/local/lib; - LIBRARY_STYLE = DYNAMIC; - MACH_O_TYPE = mh_dylib; + HEADER_SEARCH_PATHS = ../common; + LIBRARY_SEARCH_PATHS = ""; OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", - Jackservermp, - "-framework", - CoreAudio, - "-framework", - CoreServices, + Jackmp, "-framework", - AudioUnit, + CoreFoundation, ); OTHER_REZFLAGS = ""; - PREBINDING = NO; - PRODUCT_NAME = jack_dummy; + PRODUCT_NAME = jack_latent_client; + REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( @@ -12161,7 +12443,7 @@ }; name = Development; }; - 4B43A8B810145F6F00E52943 /* Deployment */ = { + 4B38115D1326878E00C61B14 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( @@ -12169,33 +12451,21 @@ ppc, ); COPY_PHASE_STRIP = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - EXECUTABLE_EXTENSION = so; + FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; - GCC_MODEL_TUNING = G4; - HEADER_SEARCH_PATHS = ( - ../common, - ../common/jack, - ., - ../posix, - ); - INSTALL_PATH = /usr/local/lib; - LIBRARY_STYLE = DYNAMIC; - MACH_O_TYPE = mh_dylib; + HEADER_SEARCH_PATHS = ../common; + LIBRARY_SEARCH_PATHS = ""; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", - Jackservermp, + Jackmp, "-framework", - CoreServices, + CoreFoundation, ); OTHER_REZFLAGS = ""; - PREBINDING = NO; - PRODUCT_NAME = jack_loopback; + PRODUCT_NAME = jack_latent_client; + REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( @@ -12207,32 +12477,252 @@ }; name = Deployment; }; - 4B43A8B910145F6F00E52943 /* Default */ = { + 4B38115E1326878E00C61B14 /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( i386, ppc, ); - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - EXECUTABLE_EXTENSION = so; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; - GCC_MODEL_TUNING = G4; - INSTALL_PATH = /usr/local/lib; - LIBRARY_STYLE = DYNAMIC; - MACH_O_TYPE = mh_dylib; + FRAMEWORK_SEARCH_PATHS = ""; + HEADER_SEARCH_PATHS = ../common; OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", - Jackdmp, - "-framework", - AudioToolBox, - "-framework", - CoreAudio, - "-framework", - CoreServices, + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midiseq; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4B3811941326884E00C61B14 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_latent_client; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4B3811951326884E00C61B14 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + HEADER_SEARCH_PATHS = ../common; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_latent_client; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B3811961326884E00C61B14 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + FRAMEWORK_SEARCH_PATHS = ""; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midiseq; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4B43A8B710145F6F00E52943 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + COPY_PHASE_STRIP = NO; + DEBUGGING_SYMBOLS = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G4; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ( + ../common, + ../common/jack, + ., + ../posix, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + "-framework", + Jackservermp, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_loopback; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4B43A8B810145F6F00E52943 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + COPY_PHASE_STRIP = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + HEADER_SEARCH_PATHS = ( + ../common, + ../common/jack, + ., + ../posix, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + "-framework", + Jackservermp, + "-framework", + CoreServices, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_loopback; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B43A8B910145F6F00E52943 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + "-framework", + Jackdmp, + "-framework", + AudioToolBox, + "-framework", + CoreAudio, + "-framework", + CoreServices, "-framework", AudioUnit, ); @@ -12287,7 +12777,7 @@ ); OTHER_REZFLAGS = ""; PREBINDING = NO; - PRODUCT_NAME = jack_dummy; + PRODUCT_NAME = jack_loopback; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( @@ -12792,6 +13282,7 @@ GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( + /opt/local/include, ., ../posix, ../common/jack, @@ -12815,7 +13306,7 @@ ); OTHER_REZFLAGS = ""; PREBINDING = NO; - PRODUCT_NAME = netmanager; + PRODUCT_NAME = netadapter; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( @@ -12841,6 +13332,7 @@ GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( + /opt/local/include, ., ../posix, ../common, @@ -12938,7 +13430,7 @@ Jackservermp, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_test; + PRODUCT_NAME = jack_server_control; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -15173,6 +15665,198 @@ }; name = Default; }; + 4B8F16E213290DC80002AD73 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midi_dump; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4B8F16E313290DC80002AD73 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + HEADER_SEARCH_PATHS = ../common; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midi_dump; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B8F16E413290DC80002AD73 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + FRAMEWORK_SEARCH_PATHS = ""; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midisine; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4B8F16EF13290E0E0002AD73 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midi_dump; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4B8F16F013290E0E0002AD73 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + HEADER_SEARCH_PATHS = ../common; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midi_dump; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B8F16F113290E0E0002AD73 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc64, + ppc, + i386, + x86_64, + ); + FRAMEWORK_SEARCH_PATHS = ""; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midisine; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; 4B978DB80A31CF4A009E2DD1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { @@ -15716,7 +16400,7 @@ Jackmp, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_lsp; + PRODUCT_NAME = jack_server_control; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -16375,6 +17059,7 @@ GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( + /opt/local/include, ., ../posix, ../common/jack, @@ -16398,7 +17083,7 @@ ); OTHER_REZFLAGS = ""; PREBINDING = NO; - PRODUCT_NAME = netmanager; + PRODUCT_NAME = audioadapter; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( @@ -16423,6 +17108,7 @@ GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( + /opt/local/include, ., ../posix, ../common/jack, @@ -16522,6 +17208,7 @@ GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( + /opt/local/include, ., ../posix, ../common/jack, @@ -16545,7 +17232,7 @@ ); OTHER_REZFLAGS = ""; PREBINDING = NO; - PRODUCT_NAME = netmanager; + PRODUCT_NAME = netadapter; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( @@ -16570,6 +17257,7 @@ GCC_MODEL_TUNING = G4; GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( + /opt/local/include, ., ../posix, ../common, @@ -17117,7 +17805,7 @@ CoreFoundation, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midiseq; + PRODUCT_NAME = jack_evmon; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -17212,7 +17900,7 @@ CoreFoundation, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midiseq; + PRODUCT_NAME = jack_bufsize; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -17310,7 +17998,7 @@ CoreFoundation, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midiseq; + PRODUCT_NAME = jack_rec; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -17408,7 +18096,7 @@ CoreFoundation, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midiseq; + PRODUCT_NAME = jack_monitor_client; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -17594,7 +18282,7 @@ CoreFoundation, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midiseq; + PRODUCT_NAME = jack_impulse_grabber; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -17687,7 +18375,7 @@ Jackmp, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jdelay; + PRODUCT_NAME = jack_iodelay; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -17718,7 +18406,7 @@ Jackmp, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jdelay; + PRODUCT_NAME = jack_iodelay; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -18219,7 +18907,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; - 4B35C5660D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jdelay 64 bits" */ = { + 4B35C5660D4731D2000DE7AE /* Build configuration list for PBXNativeTarget "jack_iodelay 64 bits" */ = { isa = XCConfigurationList; buildConfigurations = ( 4B35C5670D4731D2000DE7AE /* Development */, @@ -18459,6 +19147,26 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; + 4B38115B1326878E00C61B14 /* Build configuration list for PBXNativeTarget "jack_latent_client Universal" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B38115C1326878E00C61B14 /* Development */, + 4B38115D1326878E00C61B14 /* Deployment */, + 4B38115E1326878E00C61B14 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 4B3811931326884E00C61B14 /* Build configuration list for PBXNativeTarget "jack_latent_client 64 bits" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B3811941326884E00C61B14 /* Development */, + 4B3811951326884E00C61B14 /* Deployment */, + 4B3811961326884E00C61B14 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; 4B43A8B610145F6F00E52943 /* Build configuration list for PBXNativeTarget "jack_loopback Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -18719,6 +19427,26 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; + 4B8F16E113290DC80002AD73 /* Build configuration list for PBXNativeTarget "jack_midi_dump Universal" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B8F16E213290DC80002AD73 /* Development */, + 4B8F16E313290DC80002AD73 /* Deployment */, + 4B8F16E413290DC80002AD73 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 4B8F16EE13290E0E0002AD73 /* Build configuration list for PBXNativeTarget "jack_midi_dump 64 bits" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B8F16EF13290E0E0002AD73 /* Development */, + 4B8F16F013290E0E0002AD73 /* Deployment */, + 4B8F16F113290E0E0002AD73 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; 4B978DB70A31CF4A009E2DD1 /* Build configuration list for PBXNativeTarget "jack_portaudio Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -18929,7 +19657,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; - 4BFA999E0AAAF3B0009E916C /* Build configuration list for PBXNativeTarget "jdelay Universal" */ = { + 4BFA999E0AAAF3B0009E916C /* Build configuration list for PBXNativeTarget "jack_iodelay Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( 4BFA999F0AAAF3B0009E916C /* Development */, 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..03e22adf 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,8 @@ 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_latency_range_t range; + jack_log("JackCoreAudioDriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); for (int i = 0; i < fCaptureChannels; i++) { @@ -1597,7 +1606,8 @@ int JackCoreAudioDriver::Attach() port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - port->SetLatency(fEngineControl->fBufferSize + value1 + value2 + fCaptureLatency); + range.min = range.max = fEngineControl->fBufferSize + value1 + value2 + fCaptureLatency; + port->SetLatencyRange(JackCaptureLatency, &range); fCapturePortList[i] = port_index; } @@ -1635,7 +1645,8 @@ int JackCoreAudioDriver::Attach() port = fGraphManager->GetPort(port_index); port->SetAlias(alias); // Add more latency if "async" mode is used... - port->SetLatency(fEngineControl->fBufferSize + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize * fIOUsage) + value1 + value2 + fPlaybackLatency); + range.min = range.max = fEngineControl->fBufferSize + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize * fIOUsage) + value1 + value2 + fPlaybackLatency; + port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[i] = port_index; // Monitor ports @@ -1648,7 +1659,8 @@ int JackCoreAudioDriver::Attach() } else { port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - port->SetLatency(fEngineControl->fBufferSize); + range.min = range.max = fEngineControl->fBufferSize; + port->SetLatencyRange(JackCaptureLatency, &range); fMonitorPortList[i] = port_index; } } @@ -1670,7 +1682,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 +1690,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 +1750,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 +1775,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 +1798,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 +1806,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 +1910,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 +1918,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 +1926,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 +1934,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 +1946,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 +1965,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 +2030,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 +2056,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/macosx/wscript b/macosx/wscript index 8fa9bd37..25ca9b3d 100644 --- a/macosx/wscript +++ b/macosx/wscript @@ -6,12 +6,6 @@ def create_jack_driver_obj(bld, target, sources, uselib = None): driver.features.append('cc') driver.env['shlib_PATTERN'] = 'jack_%s.so' driver.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] - # Seems uneeded here... - #if bld.env['HAVE_CELT']: - #if bld.env['HAVE_CELT_API_0_5']: - # driver.defines += ['HAVE_CELT', 'HAVE_CELT_API_0_5'] - #elif bld.env['HAVE_CELT_API_0_7']: - # driver.defines += ['HAVE_CELT', 'HAVE_CELT_API_0_7'] driver.includes = ['.', '../macosx', '../posix', '../common', '../common/jack'] driver.target = target driver.source = sources diff --git a/man/jack_iodelay.0 b/man/jack_iodelay.0 new file mode 100644 index 00000000..007e65a1 --- /dev/null +++ b/man/jack_iodelay.0 @@ -0,0 +1,53 @@ +.TH JACK_IODELAY "1" "!DATE!" "!VERSION!" +.SH NAME +jack_iodelay \- JACK toolkit client to measure roundtrip latency +.SH SYNOPSIS +.B jack_iodelay +.SH DESCRIPTION +.B jack_iodelay +will create one input and one output port, and then +measures the latency (signal delay) between them. For this to work, +the output port must be connected to its input port. The measurement +is accurate to a resolution of greater than 1 sample. +.PP +The expected use is to connect jack_iodelay's output port to a +hardware playback port, then use a physical loopback cable from the +corresponding hardware output connector to an input connector, and to +connect that corresponding hardware capture port to jack_iodelay's +input port. This creates a roundtrip that goes through any +analog-to-digital or digital-converters that are present in the audio +hardware. +.PP +Although the hardware loopback latency is the expected use, it is also +possible to use jack_iodelay to measure the latency along any fully +connected signal path, such as those involving other JACK clients. +.PP +Once jack_iodelay completes its measurement it will print the total +latency it has detected. This will include the JACK period length in +addition to any other latency in the signal path. It will continue to +print the value every 0.5 seconds or so so that if you wish you can +vary aspects of the signal path to see their effect on the measured +latency. +.PP +If no incoming signal is detected from the input port, jack_iodelay +will print +.PP +\fT Signal below threshold... .\fR +.PP +every second until this changes (e.g. until you establish the correct connections). +.PP +To use the value measured by jack_iodelay with the -I and -O arguments +of a JACK backend (also called Input Latency and Output Latency in the +setup dialog of qjackctl), you must subtract the JACK period size from +the result. Then, if you believe that the latency is equally +distributed between the input and output parts of your audio hardware +(extremely likely), divide the result by two and use that for input +and/or output latency value. Doing this measurement will enable JACK +clients that use the JACK latency API to accurately position/delay +audio to keep signals synchronized even when there are inherent delays +in the end-to-end signal pathways. +.SH AUTHOR +Originally written in C++ by Fons Adriensen, ported to C by Torben Hohn. + + + 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); } diff --git a/posix/JackPosixThread.cpp b/posix/JackPosixThread.cpp index 4b4315db..aed3796b 100644 --- a/posix/JackPosixThread.cpp +++ b/posix/JackPosixThread.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. */ @@ -40,19 +40,19 @@ void* JackPosixThread::ThreadHandler(void* arg) if ((err = pthread_setcanceltype(obj->fCancellation, NULL)) != 0) { jack_error("pthread_setcanceltype err = %s", strerror(err)); } - + // Signal creation thread when started with StartSync jack_log("ThreadHandler: start"); obj->fStatus = kIniting; - + // Call Init method if (!runnable->Init()) { jack_error("Thread init fails: thread quits"); return 0; } - + obj->fStatus = kRunning; - + // If Init succeed, start the thread loop bool res = true; while (obj->fStatus == kRunning && res) { @@ -76,11 +76,11 @@ int JackPosixThread::Start() return 0; } } - + int JackPosixThread::StartSync() { fStatus = kStarting; - + if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) { fStatus = kIdle; return -1; @@ -90,10 +90,10 @@ int JackPosixThread::StartSync() JackSleep(1000); } return (count == 1000) ? -1 : 0; - } + } } - -int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg) + +int JackPosixThread::StartImp(jack_native_thread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg) { pthread_attr_t attributes; struct sched_param rt_param; @@ -111,19 +111,19 @@ int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, voi } if (realtime) { - + jack_log("Create RT thread"); if ((res = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED))) { jack_error("Cannot request explicit scheduling for RT thread res = %d", res); return -1; } - + if ((res = pthread_attr_setschedpolicy(&attributes, JACK_SCHED_POLICY))) { jack_error("Cannot set RR scheduling class for RT thread res = %d", res); return -1; } - + memset(&rt_param, 0, sizeof(rt_param)); rt_param.sched_priority = priority; @@ -152,13 +152,13 @@ int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, voi int JackPosixThread::Kill() { - if (fThread != (pthread_t)NULL) { // If thread has been started + if (fThread != (jack_native_thread_t)NULL) { // If thread has been started jack_log("JackPosixThread::Kill"); void* status; pthread_cancel(fThread); pthread_join(fThread, &status); fStatus = kIdle; - fThread = (pthread_t)NULL; + fThread = (jack_native_thread_t)NULL; return 0; } else { return -1; @@ -167,21 +167,21 @@ int JackPosixThread::Kill() int JackPosixThread::Stop() { - if (fThread != (pthread_t)NULL) { // If thread has been started + if (fThread != (jack_native_thread_t)NULL) { // If thread has been started jack_log("JackPosixThread::Stop"); void* status; fStatus = kIdle; // Request for the thread to stop pthread_join(fThread, &status); - fThread = (pthread_t)NULL; + fThread = (jack_native_thread_t)NULL; return 0; } else { return -1; } } -int JackPosixThread::KillImp(pthread_t thread) +int JackPosixThread::KillImp(jack_native_thread_t thread) { - if (thread != (pthread_t)NULL) { // If thread has been started + if (thread != (jack_native_thread_t)NULL) { // If thread has been started jack_log("JackPosixThread::Kill"); void* status; pthread_cancel(thread); @@ -192,9 +192,9 @@ int JackPosixThread::KillImp(pthread_t thread) } } -int JackPosixThread::StopImp(pthread_t thread) +int JackPosixThread::StopImp(jack_native_thread_t thread) { - if (thread != (pthread_t)NULL) { // If thread has been started + if (thread != (jack_native_thread_t)NULL) { // If thread has been started jack_log("JackPosixThread::Stop"); void* status; pthread_join(thread, &status); @@ -206,7 +206,7 @@ int JackPosixThread::StopImp(pthread_t thread) int JackPosixThread::AcquireRealTime() { - return (fThread != (pthread_t)NULL) ? AcquireRealTimeImp(fThread, fPriority) : -1; + return (fThread != (jack_native_thread_t)NULL) ? AcquireRealTimeImp(fThread, fPriority) : -1; } int JackPosixThread::AcquireSelfRealTime() @@ -225,7 +225,7 @@ int JackPosixThread::AcquireSelfRealTime(int priority) fPriority = priority; return AcquireSelfRealTime(); } -int JackPosixThread::AcquireRealTimeImp(pthread_t thread, int priority) +int JackPosixThread::AcquireRealTimeImp(jack_native_thread_t thread, int priority) { struct sched_param rtparam; int res; @@ -243,7 +243,7 @@ int JackPosixThread::AcquireRealTimeImp(pthread_t thread, int priority) int JackPosixThread::DropRealTime() { - return (fThread != (pthread_t)NULL) ? DropRealTimeImp(fThread) : -1; + return (fThread != (jack_native_thread_t)NULL) ? DropRealTimeImp(fThread) : -1; } int JackPosixThread::DropSelfRealTime() @@ -251,7 +251,7 @@ int JackPosixThread::DropSelfRealTime() return DropRealTimeImp(pthread_self()); } -int JackPosixThread::DropRealTimeImp(pthread_t thread) +int JackPosixThread::DropRealTimeImp(jack_native_thread_t thread) { struct sched_param rtparam; int res; @@ -265,7 +265,7 @@ int JackPosixThread::DropRealTimeImp(pthread_t thread) return 0; } -pthread_t JackPosixThread::GetThreadID() +jack_native_thread_t JackPosixThread::GetThreadID() { return fThread; } @@ -320,42 +320,42 @@ bool jack_get_thread_realtime_priority_range(int * min_ptr, int * max_ptr) bool jack_tls_allocate_key(jack_tls_key *key_ptr) { int ret; - + ret = pthread_key_create(key_ptr, NULL); if (ret != 0) { jack_error("pthread_key_create() failed with error %d", ret); return false; } - + return true; } bool jack_tls_free_key(jack_tls_key key) { int ret; - + ret = pthread_key_delete(key); if (ret != 0) { jack_error("pthread_key_delete() failed with error %d", ret); return false; } - + return true; } bool jack_tls_set(jack_tls_key key, void *data_ptr) { int ret; - + ret = pthread_setspecific(key, (const void *)data_ptr); if (ret != 0) { jack_error("pthread_setspecific() failed with error %d", ret); return false; } - + return true; } diff --git a/posix/JackPosixThread.h b/posix/JackPosixThread.h index d38c573c..764a48df 100644 --- a/posix/JackPosixThread.h +++ b/posix/JackPosixThread.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. */ @@ -40,16 +40,16 @@ class SERVER_EXPORT JackPosixThread : public detail::JackThreadInterface protected: - pthread_t fThread; + jack_native_thread_t fThread; static void* ThreadHandler(void* arg); public: JackPosixThread(JackRunnableInterface* runnable, bool real_time, int priority, int cancellation) - : JackThreadInterface(runnable, priority, real_time, cancellation), fThread((pthread_t)NULL) + : JackThreadInterface(runnable, priority, real_time, cancellation), fThread((jack_native_thread_t)NULL) {} JackPosixThread(JackRunnableInterface* runnable, int cancellation = PTHREAD_CANCEL_ASYNCHRONOUS) - : JackThreadInterface(runnable, 0, false, cancellation), fThread((pthread_t)NULL) + : JackThreadInterface(runnable, 0, false, cancellation), fThread((jack_native_thread_t)NULL) {} int Start(); @@ -60,23 +60,23 @@ class SERVER_EXPORT JackPosixThread : public detail::JackThreadInterface int AcquireRealTime(); // Used when called from another thread int AcquireSelfRealTime(); // Used when called from thread itself - + int AcquireRealTime(int priority); // Used when called from another thread int AcquireSelfRealTime(int priority); // Used when called from thread itself - + int DropRealTime(); // Used when called from another thread int DropSelfRealTime(); // Used when called from thread itself - pthread_t GetThreadID(); + jack_native_thread_t GetThreadID(); bool IsThread(); - static int AcquireRealTimeImp(pthread_t thread, int priority); - static int AcquireRealTimeImp(pthread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) + static int AcquireRealTimeImp(jack_native_thread_t thread, int priority); + static int AcquireRealTimeImp(jack_native_thread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) { return JackPosixThread::AcquireRealTimeImp(thread, priority); } - static int DropRealTimeImp(pthread_t thread); - static int StartImp(pthread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg); - static int StopImp(pthread_t thread); - static int KillImp(pthread_t thread); + static int DropRealTimeImp(jack_native_thread_t thread); + static int StartImp(jack_native_thread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg); + static int StopImp(jack_native_thread_t thread); + static int KillImp(jack_native_thread_t thread); }; SERVER_EXPORT void ThreadExit(); diff --git a/posix/JackSocket.cpp b/posix/JackSocket.cpp index e1984195..6d7d6879 100644 --- a/posix/JackSocket.cpp +++ b/posix/JackSocket.cpp @@ -12,7 +12,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. */ @@ -45,12 +45,12 @@ void JackClientSocket::SetReadTimeOut(long sec) { int flags; fTimeOut = sec; - + if ((flags = fcntl(fSocket, F_GETFL, 0)) < 0) { jack_error("JackClientSocket::SetReadTimeOut error in fcntl F_GETFL"); return; } - + flags |= O_NONBLOCK; if (fcntl(fSocket, F_SETFL, flags) < 0) { jack_error("JackClientSocket::SetReadTimeOut error in fcntl F_SETFL"); @@ -62,12 +62,12 @@ void JackClientSocket::SetWriteTimeOut(long sec) { int flags; fTimeOut = sec; - + if ((flags = fcntl(fSocket, F_GETFL, 0)) < 0) { jack_error("JackClientSocket::SetWriteTimeOut error in fcntl F_GETFL"); return; } - + flags |= O_NONBLOCK; if (fcntl(fSocket, F_SETFL, flags) < 0) { jack_error("JackClientSocket::SetWriteTimeOut error in fcntl F_SETFL"); @@ -100,7 +100,7 @@ void JackClientSocket::SetWriteTimeOut(long sec) #endif void JackClientSocket::SetNonBlocking(bool onoff) -{ +{ if (onoff) { long flags = 0; if (fcntl(fSocket, F_SETFL, flags | O_NONBLOCK) < 0) { @@ -140,7 +140,7 @@ int JackClientSocket::Connect(const char* dir, const char* name, int which) // A int JackClientSocket::Close() { - jack_log("JackClientSocket::Close"); + jack_log("JackClientSocket::Close"); if (fSocket > 0) { shutdown(fSocket, SHUT_RDWR); close(fSocket); @@ -161,17 +161,17 @@ int JackClientSocket::Read(void* data, int len) struct timeval tv; fd_set fdset; ssize_t res; - + tv.tv_sec = fTimeOut; tv.tv_usec = 0; - + FD_ZERO(&fdset); FD_SET(fSocket, &fdset); - + do { res = select(fSocket + 1, &fdset, NULL, NULL, &tv); } while (res < 0 && errno == EINTR); - + if (res < 0) { return res; } else if (res == 0) { @@ -179,9 +179,9 @@ int JackClientSocket::Read(void* data, int len) } } #endif - + if ((res = read(fSocket, data, len)) != len) { - if (errno == EWOULDBLOCK) { + if (errno == EWOULDBLOCK || errno == EAGAIN) { jack_error("JackClientSocket::Read time out"); return 0; // For a non blocking socket, a read failure is not considered as an error } else if (res != 0) { @@ -201,21 +201,21 @@ int JackClientSocket::Write(void* data, int len) #if defined(__sun__) || defined(sun) if (fTimeOut > 0) { - + struct timeval tv; fd_set fdset; ssize_t res; - + tv.tv_sec = fTimeOut; tv.tv_usec = 0; - + FD_ZERO(&fdset); FD_SET(fSocket, &fdset); - + do { res = select(fSocket + 1, NULL, &fdset, NULL, &tv); } while (res < 0 && errno == EINTR); - + if (res < 0) { return res; } else if (res == 0) { @@ -225,7 +225,7 @@ int JackClientSocket::Write(void* data, int len) #endif if ((res = write(fSocket, data, len)) != len) { - if (errno == EWOULDBLOCK) { + if (errno == EWOULDBLOCK || errno == EAGAIN) { jack_log("JackClientSocket::Write time out"); return 0; // For a non blocking socket, a write failure is not considered as an error } else if (res != 0) { @@ -251,7 +251,7 @@ int JackServerSocket::Bind(const char* dir, const char* name, int which) // A re addr.sun_family = AF_UNIX; BuildName(name, fName, dir, which); strncpy(addr.sun_path, fName, sizeof(addr.sun_path) - 1); - + jack_log("Bind: addr.sun_path %s", addr.sun_path); unlink(fName); // Security... diff --git a/posix/JackSocketClientChannel.cpp b/posix/JackSocketClientChannel.cpp index 1a6d7ad5..23555c1d 100644 --- a/posix/JackSocketClientChannel.cpp +++ b/posix/JackSocketClientChannel.cpp @@ -12,7 +12,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. */ @@ -108,7 +108,6 @@ int JackSocketClientChannel::Start() } } - void JackSocketClientChannel::Stop() { jack_log("JackSocketClientChannel::Stop"); @@ -246,61 +245,73 @@ void JackSocketClientChannel::SetFreewheel(int onoff, int* result) ServerSyncCall(&req, &res, result); } -void JackSocketClientChannel::SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t ** result) +void JackSocketClientChannel::ComputeTotalLatencies(int* result) +{ + JackComputeTotalLatenciesRequest req; + JackResult res; + ServerSyncCall(&req, &res, result); +} + +void JackSocketClientChannel::SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t** result) { JackSessionNotifyRequest req(refnum, path, type, target); - JackSessionNotifyResult res; + JackSessionNotifyResult res; int intresult; ServerSyncCall(&req, &res, &intresult); - jack_session_command_t *session_command = (jack_session_command_t *)malloc( sizeof(jack_session_command_t) * (res.fCommandList.size()+1) ); - int i=0; - + jack_session_command_t* session_command = (jack_session_command_t *)malloc(sizeof(jack_session_command_t) * (res.fCommandList.size() + 1)); + int i = 0; + for (std::list::iterator ci=res.fCommandList.begin(); ci!=res.fCommandList.end(); ci++) { - session_command[i].uuid = strdup( ci->fUUID ); - session_command[i].client_name = strdup( ci->fClientName ); - session_command[i].command = strdup( ci->fCommand ); - session_command[i].flags = ci->fFlags; - - i+=1; - } - + session_command[i].uuid = strdup( ci->fUUID ); + session_command[i].client_name = strdup( ci->fClientName ); + session_command[i].command = strdup( ci->fCommand ); + session_command[i].flags = ci->fFlags; + i += 1; + } + session_command[i].uuid = NULL; session_command[i].client_name = NULL; session_command[i].command = NULL; session_command[i].flags = (jack_session_flags_t)0; - *result = session_command; } void JackSocketClientChannel::SessionReply(int refnum, int* result) { JackSessionReplyRequest req(refnum); - JackResult res; + JackResult res; ServerSyncCall(&req, &res, result); } -void JackSocketClientChannel::GetUUIDForClientName( int refnum, const char *client_name, char *uuid_res, int *result ) +void JackSocketClientChannel::GetUUIDForClientName(int refnum, const char* client_name, char* uuid_res, int* result) { JackGetUUIDRequest req(client_name); - JackUUIDResult res; + JackUUIDResult res; ServerSyncCall(&req, &res, result); - strncpy( uuid_res, res.fUUID, JACK_UUID_SIZE ); + strncpy(uuid_res, res.fUUID, JACK_UUID_SIZE); } -void JackSocketClientChannel::GetClientNameForUUID( int refnum, const char *uuid, char *name_res, int *result ) +void JackSocketClientChannel::GetClientNameForUUID(int refnum, const char* uuid, char* name_res, int* result) { JackGetClientNameRequest req(uuid); - JackClientNameResult res; + JackClientNameResult res; + ServerSyncCall(&req, &res, result); + strncpy(name_res, res.fName, JACK_CLIENT_NAME_SIZE); +} + +void JackSocketClientChannel::ClientHasSessionCallback(const char* client_name, int* result) +{ + JackClientHasSessionCallbackRequest req(client_name); + JackResult res; ServerSyncCall(&req, &res, result); - strncpy( name_res, res.fName, JACK_CLIENT_NAME_SIZE ); } -void JackSocketClientChannel::ReserveClientName( int refnum, const char *client_name, const char *uuid, int *result ) +void JackSocketClientChannel::ReserveClientName(int refnum, const char* client_name, const char* uuid, int* result) { JackReserveNameRequest req(refnum, client_name, uuid); - JackResult res; + JackResult res; ServerSyncCall(&req, &res, result); } @@ -363,7 +374,7 @@ bool JackSocketClientChannel::Init() jack_error("JackSocketClientChannel: cannot establish notication socket"); return false; } else { - return fClient->Init(); + return true; } } diff --git a/posix/JackSocketClientChannel.h b/posix/JackSocketClientChannel.h index 225887e7..8e2b0e30 100644 --- a/posix/JackSocketClientChannel.h +++ b/posix/JackSocketClientChannel.h @@ -12,7 +12,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. */ @@ -38,11 +38,11 @@ class JackSocketClientChannel : public detail::JackClientChannelInterface, publi private: - JackClientSocket fRequestSocket; // Socket to communicate with the server - JackServerSocket fNotificationListenSocket; // Socket listener for server notification - JackClientSocket* fNotificationSocket; // Socket for server notification + JackClientSocket fRequestSocket; // Socket to communicate with the server + JackServerSocket fNotificationListenSocket; // Socket listener for server notification + JackClientSocket* fNotificationSocket; // Socket for server notification JackThread fThread; // Thread to execute the event loop - JackClient* fClient; + JackClient* fClient; void ServerSyncCall(JackRequest* req, JackResult* res, int* result); void ServerAsyncCall(JackRequest* req, JackResult* res, int* result); @@ -77,12 +77,14 @@ class JackSocketClientChannel : public detail::JackClientChannelInterface, publi void PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result); void PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result); - + void PortRename(int refnum, jack_port_id_t port, const char* name, int* result); void SetBufferSize(jack_nframes_t buffer_size, int* result); void SetFreewheel(int onoff, int* result); + void ComputeTotalLatencies(int* result); + void ReleaseTimebase(int refnum, int* result); void SetTimebaseCallback(int refnum, int conditional, int* result); @@ -91,18 +93,18 @@ class JackSocketClientChannel : public detail::JackClientChannelInterface, publi void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result); void InternalClientUnload(int refnum, int int_ref, int* status, int* result); - // Session Stuff + // Session API void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t** result); void SessionReply(int refnum, int* result); - void GetUUIDForClientName( int refnum, const char *client_name, char *uuid_res, int *result ); - void GetClientNameForUUID( int refnum, const char *uuid, char *name_res, int *result ); - void ReserveClientName( int refnum, const char *client_name, const char *uuid, int *result ); + void GetUUIDForClientName(int refnum, const char* client_name, char* uuid_res, int* result); + void GetClientNameForUUID(int refnum, const char* uuid, char* name_res, int* result); + void ReserveClientName(int refnum, const char* client_name, const char *uuid, int* result); + void ClientHasSessionCallback(const char* client_name, int* result); // JackRunnableInterface interface bool Init(); bool Execute(); - bool IsChannelThread() { return fThread.IsThread(); } }; diff --git a/posix/JackSocketServerChannel.cpp b/posix/JackSocketServerChannel.cpp index e9176230..ac857de2 100644 --- a/posix/JackSocketServerChannel.cpp +++ b/posix/JackSocketServerChannel.cpp @@ -12,7 +12,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. */ @@ -51,7 +51,7 @@ JackSocketServerChannel::~JackSocketServerChannel() int JackSocketServerChannel::Open(const char* server_name, JackServer* server) { jack_log("JackSocketServerChannel::Open"); - + // Prepare request socket if (fRequestListenSocket.Bind(jack_server_dir, server_name, 0) < 0) { jack_log("JackSocketServerChannel::Open : cannot create result listen socket"); @@ -79,14 +79,14 @@ void JackSocketServerChannel::Close() delete socket; } } - + int JackSocketServerChannel::Start() { if (fThread.Start() != 0) { jack_error("Cannot start Jack server listener"); return -1; - } - + } + return 0; } @@ -168,6 +168,12 @@ bool JackSocketServerChannel::HandleRequest(int fd) return false; } + if (fd == JackServerGlobals::fRTNotificationSocket && header.fType != JackRequest::kNotification) { + jack_error("fRTNotificationSocket = %d", JackServerGlobals::fRTNotificationSocket); + jack_error("JackSocketServerChannel::HandleRequest : incorrect notification !!"); + return true; + } + // Read data switch (header.fType) { @@ -292,7 +298,7 @@ bool JackSocketServerChannel::HandleRequest(int fd) jack_error("JackRequest::DisconnectPorts write error ref = %d", req.fRefNum); break; } - + case JackRequest::kPortRename: { jack_log("JackRequest::PortRename"); JackPortRenameRequest req; @@ -326,6 +332,17 @@ bool JackSocketServerChannel::HandleRequest(int fd) break; } + case JackRequest::kComputeTotalLatencies: { + jack_log("JackRequest::ComputeTotalLatencies"); + JackComputeTotalLatenciesRequest req; + JackResult res; + if (req.Read(socket) == 0) + res.fResult = fServer->GetEngine()->ComputeTotalLatencies(); + if (res.Write(socket) < 0) + jack_error("JackRequest::ComputeTotalLatencies write error"); + break; + } + case JackRequest::kReleaseTimebase: { jack_log("JackRequest::ReleaseTimebase"); JackReleaseTimebaseRequest req; @@ -430,27 +447,26 @@ bool JackSocketServerChannel::HandleRequest(int fd) } case JackRequest::kGetClientByUUID: { - jack_log("JackRequest::GetClientNameForUUID"); + jack_log("JackRequest::GetClientByUUID"); JackGetClientNameRequest req; JackClientNameResult res; if (req.Read(socket) == 0) { fServer->GetEngine()->GetClientNameForUUID(req.fUUID, res.fName, &res.fResult); } if (res.Write(socket) < 0) - jack_error("JackRequest::GetClientNameForUUID write error"); + jack_error("JackRequest::GetClientByUUID write error"); break; } case JackRequest::kGetUUIDByClient: { - jack_log("JackRequest::GetUUIDForClientName"); + jack_log("JackRequest::GetUUIDByClient"); JackGetUUIDRequest req; JackUUIDResult res; if (req.Read(socket) == 0) { fServer->GetEngine()->GetUUIDForClientName(req.fName, res.fUUID, &res.fResult); - res.fResult = 0; } if (res.Write(socket) < 0) - jack_error("JackRequest::GetUUIDForClientName write error"); + jack_error("JackRequest::GetUUIDByClient write error"); break; } @@ -466,11 +482,23 @@ bool JackSocketServerChannel::HandleRequest(int fd) break; } + case JackRequest::kClientHasSessionCallback: { + jack_log("JackRequest::ClientHasSessionCallback"); + JackClientHasSessionCallbackRequest req; + JackResult res; + if (req.Read(socket) == 0) { + fServer->GetEngine()->ClientHasSessionCallbackRequest(req.fName, &res.fResult); + } + if (res.Write(socket) < 0) + jack_error("JackRequest::ClientHasSessionCallback write error"); + break; + } + default: jack_error("Unknown request %ld", header.fType); break; } - + return true; } @@ -511,7 +539,7 @@ bool JackSocketServerChannel::Init() bool JackSocketServerChannel::Execute() { try { - + // Global poll if ((poll(fPollTable, fSocketTable.size() + 1, 10000) < 0) && (errno != EINTR)) { jack_error("Engine poll failed err = %s request thread quits...", strerror(errno)); @@ -526,22 +554,22 @@ bool JackSocketServerChannel::Execute() jack_log("Poll client error err = %s", strerror(errno)); ClientKill(fd); } else if (fPollTable[i].revents & POLLIN) { - if (!HandleRequest(fd)) + if (!HandleRequest(fd)) jack_log("Could not handle external client request"); } } // Check the server request socket */ - if (fPollTable[0].revents & POLLERR) + if (fPollTable[0].revents & POLLERR) jack_error("Error on server request socket err = %s", strerror(errno)); - - if (fPollTable[0].revents & POLLIN) + + if (fPollTable[0].revents & POLLIN) ClientCreate(); } BuildPoolTable(); return true; - + } catch (JackQuitException& e) { jack_log("JackMachServerChannel::Execute JackQuitException"); return false; diff --git a/posix/JackSocketServerChannel.h b/posix/JackSocketServerChannel.h index 59c1a0d0..af61291a 100644 --- a/posix/JackSocketServerChannel.h +++ b/posix/JackSocketServerChannel.h @@ -12,7 +12,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. */ @@ -41,7 +41,7 @@ class JackSocketServerChannel : public JackRunnableInterface JackServerSocket fRequestListenSocket; // Socket to create request socket for the client JackThread fThread; // Thread to execute the event loop - JackServer* fServer; + JackServer* fServer; pollfd* fPollTable; bool fRebuild; std::map > fSocketTable; @@ -61,7 +61,7 @@ class JackSocketServerChannel : public JackRunnableInterface int Open(const char* server_name, JackServer* server); // Open the Server/Client connection void Close(); // Close the Server/Client connection - + int Start(); // JackRunnableInterface interface diff --git a/posix/JackSocketServerNotifyChannel.cpp b/posix/JackSocketServerNotifyChannel.cpp index df7381f1..c9d25509 100644 --- a/posix/JackSocketServerNotifyChannel.cpp +++ b/posix/JackSocketServerNotifyChannel.cpp @@ -12,7 +12,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. */ @@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackRequest.h" #include "JackConstants.h" #include "JackNotification.h" +#include "JackServerGlobals.h" namespace Jack { @@ -33,6 +34,7 @@ int JackSocketServerNotifyChannel::Open(const char* server_name) return -1; } else { fRequestSocket.SetNonBlocking(true); + JackServerGlobals::fRTNotificationSocket = fRequestSocket.GetFd(); return 0; } } @@ -63,7 +65,7 @@ void JackSocketServerNotifyChannel::NotifyQuit() jack_error("Could not write request ref = %d notify = %d", -1, kQUIT); } } - + } // end of namespace diff --git a/posix/JackSocketServerNotifyChannel.h b/posix/JackSocketServerNotifyChannel.h index 261ddbd4..31008164 100644 --- a/posix/JackSocketServerNotifyChannel.h +++ b/posix/JackSocketServerNotifyChannel.h @@ -12,7 +12,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. */ diff --git a/posix/JackSystemDeps_os.h b/posix/JackSystemDeps_os.h index cbddb0b1..41ee9528 100644 --- a/posix/JackSystemDeps_os.h +++ b/posix/JackSystemDeps_os.h @@ -25,6 +25,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include +#define UINT32_MAX 4294967295U + #define DRIVER_HANDLE void* #define LoadDriverModule(name) dlopen((name), RTLD_NOW | RTLD_GLOBAL) #define UnloadDriverModule(handle) dlclose((handle)) diff --git a/posix/JackTypes_os.h b/posix/JackTypes_os.h index 01e6c9b9..896d91ea 100644 --- a/posix/JackTypes_os.h +++ b/posix/JackTypes_os.h @@ -26,6 +26,8 @@ typedef unsigned long long UInt64; typedef pthread_key_t jack_tls_key; +typedef pthread_t jack_native_thread_t; + typedef int (*jack_thread_creator_t)(pthread_t*, const pthread_attr_t*, void* (*function)(void*), void* arg); #endif diff --git a/tests/jdelay.cpp b/tests/iodelay.cpp similarity index 79% rename from tests/jdelay.cpp rename to tests/iodelay.cpp index 709fd7e2..4ef90fb0 100644 --- a/tests/jdelay.cpp +++ b/tests/iodelay.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2003-2008 Fons Adriaensen - + 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 @@ -95,14 +95,14 @@ int MTDM::process (size_t len, float *ip, float *op) vip = *ip++; for (i = 0, F = _freq; i < 5; i++, F++) { - a = 2 * (float) M_PI * (F->p & 65535) / 65536.0; + a = 2 * (float) M_PI * (F->p & 65535) / 65536.0; F->p += F->f; - c = cosf (a); - s = -sinf (a); + c = cosf (a); + s = -sinf (a); vop += F->a * s; F->xa += s * vip; F->ya += c * vip; - } + } *op++ = vop; if (++_cnt == 16) { @@ -142,10 +142,10 @@ int MTDM::resolve (void) k = (int)(floor (p + 0.5)); e = fabs (p - k); if (e > _err) _err = e; - if (e > 0.4) return 1; + if (e > 0.4) return 1; d += m * (k & 7); m *= 8; - } + } _del = 16 * d; return 0; @@ -158,6 +158,34 @@ static jack_client_t *jack_handle; static jack_port_t *jack_capt; static jack_port_t *jack_play; +jack_latency_range_t capture_latency = {-1, -1}; +jack_latency_range_t playback_latency = {-1, -1}; + +void +latency_cb (jack_latency_callback_mode_t mode, void *arg) +{ + jack_latency_range_t range; + + range.min = range.max = 0; + + if (mode == JackCaptureLatency) { + jack_port_set_latency_range (jack_play, mode, &range); + jack_port_get_latency_range (jack_capt, mode, &range); + if ((range.min != capture_latency.min) || (range.max != capture_latency.max)) { + capture_latency = range; + printf ("new capture latency: [%d, %d]\n", range.min, range.max); + } + } else { + jack_port_set_latency_range (jack_capt, mode, &range); + jack_port_get_latency_range (jack_play, mode, &range); + if ((range.min != playback_latency.min) || (range.max != playback_latency.max)) { + playback_latency = range; + printf ("new playback latency: [%d, %d]\n", range.min, range.max); + } + } + +} + int jack_callback (jack_nframes_t nframes, void *arg) { float *ip, *op; @@ -182,14 +210,12 @@ int main (int ac, char *av []) jack_set_process_callback (jack_handle, jack_callback, 0); + if (jack_set_latency_callback) + jack_set_latency_callback (jack_handle, latency_cb, 0); + jack_capt = jack_port_register (jack_handle, "in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); jack_play = jack_port_register (jack_handle, "out", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); - printf ("capture latency = %d\n", - jack_port_get_latency (jack_port_by_name (jack_handle, "system:capture_1"))); - printf ("playback_latency = %d\n", - jack_port_get_latency (jack_port_by_name (jack_handle, "system:playback_1"))); - t = 1000.0f / jack_get_sample_rate (jack_handle); if (jack_activate (jack_handle)) @@ -200,16 +226,16 @@ int main (int ac, char *av []) while (1) { - - #ifdef WIN32 - Sleep (250); - #else - usleep (250000); - #endif + + #ifdef WIN32 + Sleep (250); + #else + usleep (250000); + #endif if (mtdm.resolve () < 0) printf ("Signal below threshold...\n"); - else + else { - if (mtdm.err () > 0.3) + if (mtdm.err () > 0.3) { mtdm.invert (); mtdm.resolve (); diff --git a/tests/wscript b/tests/wscript index 6693ebad..c5e031fb 100644 --- a/tests/wscript +++ b/tests/wscript @@ -9,7 +9,7 @@ test_programs = { #'testSem': ['testSem.cpp'], 'jack_test': ['test.cpp'], 'jack_cpu': ['cpu.c'], - 'jack_delay': ['jdelay.cpp'], + 'jack_iodelay': ['iodelay.cpp'], 'jack_multiple_metro' : ['external_metro.cpp'], } diff --git a/windows/JackRouter/JackRouter.dsp b/windows/JackRouter/JackRouter.dsp index c92ddf99..f059568e 100644 --- a/windows/JackRouter/JackRouter.dsp +++ b/windows/JackRouter/JackRouter.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\..\..\ASIOSDK2\common" /I "..\..\common" /I "..\..\common\jack" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\..\..\ASIOSDK2\common" /I "..\..\common" /I "..\..\common\jack" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" diff --git a/windows/JackSystemDeps_os.h b/windows/JackSystemDeps_os.h index cf64509e..c74830d0 100644 --- a/windows/JackSystemDeps_os.h +++ b/windows/JackSystemDeps_os.h @@ -23,6 +23,8 @@ #include +#define UINT32_MAX 4294967295U + #define DRIVER_HANDLE HINSTANCE #define LoadDriverModule(name) LoadLibrary((name)) #define UnloadDriverModule(handle) (FreeLibrary(((HMODULE)handle))) diff --git a/windows/JackTypes_os.h b/windows/JackTypes_os.h index 6551378f..35b92644 100644 --- a/windows/JackTypes_os.h +++ b/windows/JackTypes_os.h @@ -1,20 +1,20 @@ /* Copyright (C) 2004-2008 Grame - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 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 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - + */ @@ -22,11 +22,12 @@ #define __JackTypes_WIN32__ #include -#include "types.h" -typedef ULONGLONG UInt64; +typedef ULONGLONG UInt64; +typedef UInt64 uint64_t; typedef unsigned short uint16_t; -typedef DWORD jack_tls_key; +typedef DWORD jack_tls_key; +typedef HANDLE jack_native_thread_t; #endif diff --git a/windows/JackWinNamedPipeClientChannel.cpp b/windows/JackWinNamedPipeClientChannel.cpp index af390d21..f29f7ff5 100644 --- a/windows/JackWinNamedPipeClientChannel.cpp +++ b/windows/JackWinNamedPipeClientChannel.cpp @@ -1,20 +1,20 @@ /* Copyright (C) 2004-2008 Grame - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 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 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - + */ @@ -246,14 +246,74 @@ void JackWinNamedPipeClientChannel::SetFreewheel(int onoff, int* result) ServerSyncCall(&req, &res, result); } -void JackWinNamedPipeClientChannel::SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t** result) +void JackWinNamedPipeClientChannel::ComputeTotalLatencies(int* result) { - JackSessionNotifyRequest req(refnum, target, type, path); + JackComputeTotalLatenciesRequest req; JackResult res; + ServerSyncCall(&req, &res, result); +} + +void JackWinNamedPipeClientChannel::SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t** result) +{ + JackSessionNotifyRequest req(refnum, path, type, target); + JackSessionNotifyResult res; int intresult; ServerSyncCall(&req, &res, &intresult); - *result = NULL; + jack_session_command_t* session_command = (jack_session_command_t *)malloc(sizeof(jack_session_command_t) * (res.fCommandList.size() + 1)); + int i = 0; + + for (std::list::iterator ci=res.fCommandList.begin(); ci!=res.fCommandList.end(); ci++) { + session_command[i].uuid = strdup( ci->fUUID ); + session_command[i].client_name = strdup( ci->fClientName ); + session_command[i].command = strdup( ci->fCommand ); + session_command[i].flags = ci->fFlags; + i += 1; + } + + session_command[i].uuid = NULL; + session_command[i].client_name = NULL; + session_command[i].command = NULL; + session_command[i].flags = (jack_session_flags_t)0; + + *result = session_command; +} + +void JackWinNamedPipeClientChannel::SessionReply(int refnum, int* result) +{ + JackSessionReplyRequest req(refnum); + JackResult res; + ServerSyncCall(&req, &res, result); +} + +void JackWinNamedPipeClientChannel::GetUUIDForClientName(int refnum, const char* client_name, char* uuid_res, int* result) +{ + JackGetUUIDRequest req(client_name); + JackUUIDResult res; + ServerSyncCall(&req, &res, result); + strncpy(uuid_res, res.fUUID, JACK_UUID_SIZE); +} + +void JackWinNamedPipeClientChannel::GetClientNameForUUID(int refnum, const char* uuid, char* name_res, int* result) +{ + JackGetClientNameRequest req(uuid); + JackClientNameResult res; + ServerSyncCall(&req, &res, result); + strncpy(name_res, res.fName, JACK_CLIENT_NAME_SIZE); +} + +void JackWinNamedPipeClientChannel::ClientHasSessionCallback(const char* client_name, int* result) +{ + JackClientHasSessionCallbackRequest req(client_name); + JackResult res; + ServerSyncCall(&req, &res, result); +} + +void JackWinNamedPipeClientChannel::ReserveClientName(int refnum, const char* client_name, const char* uuid, int* result) +{ + JackReserveNameRequest req(refnum, client_name, uuid); + JackResult res; + ServerSyncCall(&req, &res, result); } void JackWinNamedPipeClientChannel::ReleaseTimebase(int refnum, int* result) @@ -312,7 +372,7 @@ bool JackWinNamedPipeClientChannel::Init() jack_error("JackWinNamedPipeClientChannel: cannot establish notification pipe"); return false; } else { - return fClient->Init(); + return true; } } diff --git a/windows/JackWinNamedPipeClientChannel.h b/windows/JackWinNamedPipeClientChannel.h index aa23266b..479e3271 100644 --- a/windows/JackWinNamedPipeClientChannel.h +++ b/windows/JackWinNamedPipeClientChannel.h @@ -81,6 +81,7 @@ class JackWinNamedPipeClientChannel : public detail::JackClientChannelInterface, void SetBufferSize(jack_nframes_t buffer_size, int* result); void SetFreewheel(int onoff, int* result); + void ComputeTotalLatencies(int* result); void ReleaseTimebase(int refnum, int* result); void SetTimebaseCallback(int refnum, int conditional, int* result); @@ -91,10 +92,17 @@ class JackWinNamedPipeClientChannel : public detail::JackClientChannelInterface, void InternalClientUnload(int refnum, int int_ref, int* status, int* result); void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t** result); + void SessionReply(int refnum, int* result); + void GetUUIDForClientName(int refnum, const char* client_name, char* uuid_res, int* result); + void GetClientNameForUUID(int refnum, const char* uuid, char* name_res, int* result); + void ReserveClientName(int refnum, const char* client_name, const char *uuid, int* result); + void ClientHasSessionCallback(const char* client_name, int* result); // JackRunnableInterface interface bool Init(); bool Execute(); + + bool IsChannelThread() { return fThread.IsThread(); } }; } // end of namespace diff --git a/windows/JackWinNamedPipeServerChannel.cpp b/windows/JackWinNamedPipeServerChannel.cpp index a8093ecb..b4d4d622 100644 --- a/windows/JackWinNamedPipeServerChannel.cpp +++ b/windows/JackWinNamedPipeServerChannel.cpp @@ -252,6 +252,16 @@ bool JackClientPipeThread::HandleRequest() break; } + case JackRequest::kComputeTotalLatencies: { + jack_log("JackRequest::ComputeTotalLatencies"); + JackComputeTotalLatenciesRequest req; + JackResult res; + if (req.Read(fPipe) == 0) + res.fResult = fServer->GetEngine()->ComputeTotalLatencies(); + res.Write(fPipe); + break; + } + case JackRequest::kReleaseTimebase: { jack_log("JackRequest::ReleaseTimebase"); JackReleaseTimebaseRequest req; @@ -345,11 +355,12 @@ bool JackClientPipeThread::HandleRequest() fServer->GetEngine()->SessionReply(req.fRefNum); res.fResult = 0; } + res.Write(fPipe); break; } case JackRequest::kGetClientByUUID: { - jack_log("JackRequest::GetClientNameForUUID"); + jack_log("JackRequest::GetClientByUUID"); JackGetClientNameRequest req; JackClientNameResult res; if (req.Read(fPipe) == 0) { @@ -360,12 +371,11 @@ bool JackClientPipeThread::HandleRequest() } case JackRequest::kGetUUIDByClient: { - jack_log("JackRequest::GetUUIDForClientName"); + jack_log("JackRequest::GetUUIDByClient"); JackGetUUIDRequest req; JackUUIDResult res; if (req.Read(fPipe) == 0) { fServer->GetEngine()->GetUUIDForClientName(req.fName, res.fUUID, &res.fResult); - res.fResult = 0; } res.Write(fPipe); break; @@ -377,7 +387,17 @@ bool JackClientPipeThread::HandleRequest() JackResult res; if (req.Read(fPipe) == 0) { fServer->GetEngine()->ReserveClientName(req.fName, req.fUUID, &res.fResult); - res.fResult = 0; + } + res.Write(fPipe); + break; + } + + case JackRequest::kClientHasSessionCallback: { + jack_log("JackRequest::ClientHasSessionCallback"); + JackClientHasSessionCallbackRequest req; + JackResult res; + if (req.Read(fPipe) == 0) { + fServer->GetEngine()->ClientHasSessionCallbackRequest(req.fName, &res.fResult); } res.Write(fPipe); break; diff --git a/windows/JackWinThread.cpp b/windows/JackWinThread.cpp index ec884c45..e3f2cdd9 100644 --- a/windows/JackWinThread.cpp +++ b/windows/JackWinThread.cpp @@ -1,20 +1,20 @@ /* Copyright (C) 2004-2008 Grame - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 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 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - + */ @@ -30,19 +30,19 @@ DWORD WINAPI JackWinThread::ThreadHandler(void* arg) { JackWinThread* obj = (JackWinThread*)arg; JackRunnableInterface* runnable = obj->fRunnable; - + // Signal creation thread when started with StartSync jack_log("ThreadHandler: start"); obj->fStatus = kIniting; - + // Call Init method if (!runnable->Init()) { jack_error("Thread init fails: thread quits"); return 0; } - + obj->fStatus = kRunning; - + // If Init succeed, start the thread loop bool res = true; while (obj->fStatus == kRunning && res) { @@ -80,11 +80,11 @@ int JackWinThread::Start() return 0; } } - + int JackWinThread::StartSync() { fStatus = kStarting; - + if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) { fStatus = kIdle; return -1; @@ -97,7 +97,7 @@ int JackWinThread::StartSync() } } -int JackWinThread::StartImp(pthread_t* thread, int priority, int realtime, ThreadCallback start_routine, void* arg) +int JackWinThread::StartImp(jack_native_thread_t* thread, int priority, int realtime, ThreadCallback start_routine, void* arg) { DWORD id; *thread = CreateThread(NULL, 0, start_routine, arg, 0, &id); @@ -108,7 +108,7 @@ int JackWinThread::StartImp(pthread_t* thread, int priority, int realtime, Threa } if (realtime) { - + jack_log("Create RT thread"); if (!SetThreadPriority(*thread, THREAD_PRIORITY_TIME_CRITICAL)) { jack_error("Cannot set priority class = %d", GetLastError()); @@ -118,7 +118,7 @@ int JackWinThread::StartImp(pthread_t* thread, int priority, int realtime, Threa } else { jack_log("Create non RT thread"); } - + return 0; } @@ -153,7 +153,7 @@ int JackWinThread::Stop() } } -int JackWinThread::KillImp(pthread_t thread) +int JackWinThread::KillImp(jack_native_thread_t thread) { if (thread != (HANDLE)NULL) { // If thread has been started TerminateThread(thread, 0); @@ -165,7 +165,7 @@ int JackWinThread::KillImp(pthread_t thread) } } -int JackWinThread::StopImp(pthread_t thread) +int JackWinThread::StopImp(jack_native_thread_t thread) { if (thread) { // If thread has been started WaitForSingleObject(thread, INFINITE); @@ -198,7 +198,7 @@ int JackWinThread::AcquireSelfRealTime(int priority) return AcquireSelfRealTime(); } -int JackWinThread::AcquireRealTimeImp(pthread_t thread, int priority) +int JackWinThread::AcquireRealTimeImp(jack_native_thread_t thread, int priority) { jack_log("JackWinThread::AcquireRealTime"); @@ -220,7 +220,7 @@ int JackWinThread::DropSelfRealTime() return DropRealTimeImp(GetCurrentThread()); } -int JackWinThread::DropRealTimeImp(pthread_t thread) +int JackWinThread::DropRealTimeImp(jack_native_thread_t thread) { if (SetThreadPriority(thread, THREAD_PRIORITY_NORMAL)) { return 0; @@ -230,7 +230,7 @@ int JackWinThread::DropRealTimeImp(pthread_t thread) } } -pthread_t JackWinThread::GetThreadID() +jack_native_thread_t JackWinThread::GetThreadID() { return fThread; } @@ -262,14 +262,14 @@ bool jack_get_thread_realtime_priority_range(int * min_ptr, int * max_ptr) bool jack_tls_allocate_key(jack_tls_key *key_ptr) { DWORD key; - + key = TlsAlloc(); if (key == TLS_OUT_OF_INDEXES) { jack_error("TlsAlloc() failed. Error is %d", (unsigned int)GetLastError()); return false; } - + *key_ptr = key; return true; } @@ -281,7 +281,7 @@ bool jack_tls_free_key(jack_tls_key key) jack_error("TlsFree() failed. Error is %d", (unsigned int)GetLastError()); return false; } - + return true; } @@ -292,7 +292,7 @@ bool jack_tls_set(jack_tls_key key, void *data_ptr) jack_error("TlsSetValue() failed. Error is %d", (unsigned int)GetLastError()); return false; } - + return true; } diff --git a/windows/JackWinThread.h b/windows/JackWinThread.h index 317d6aeb..6861b6fc 100644 --- a/windows/JackWinThread.h +++ b/windows/JackWinThread.h @@ -66,22 +66,22 @@ class SERVER_EXPORT JackWinThread : public detail::JackThreadInterface int DropRealTime(); // Used when called from another thread int DropSelfRealTime(); // Used when called from thread itself - pthread_t GetThreadID(); + jack_native_thread_t GetThreadID(); bool IsThread(); - static int AcquireRealTimeImp(pthread_t thread, int priority); - static int AcquireRealTimeImp(pthread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) + static int AcquireRealTimeImp(jack_native_thread_t thread, int priority); + static int AcquireRealTimeImp(jack_native_thread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) { return JackWinThread::AcquireRealTimeImp(thread, priority); } - static int DropRealTimeImp(pthread_t thread); - static int StartImp(pthread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg) + static int DropRealTimeImp(jack_native_thread_t thread); + static int StartImp(jack_native_thread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg) { return JackWinThread::StartImp(thread, priority, realtime, (ThreadCallback) start_routine, arg); } - static int StartImp(pthread_t* thread, int priority, int realtime, ThreadCallback start_routine, void* arg); - static int StopImp(pthread_t thread); - static int KillImp(pthread_t thread); + static int StartImp(jack_native_thread_t* thread, int priority, int realtime, ThreadCallback start_routine, void* arg); + static int StopImp(jack_native_thread_t thread); + static int KillImp(jack_native_thread_t thread); }; diff --git a/windows/Setup/JackRouter.dll b/windows/Setup/JackRouter.dll index 04d69ebdbc62190d3e62ed9d4081bc267f720047..829f6e106b5f03290f60129a70e137c2726dcd74 100644 GIT binary patch delta 161 zcmZo@U}|V!n(%=o?Ng=i#xFnYZ67i)G>9`YG~5KzuYmY75Gw%rmw+@ckd^~t2_U`; lnagIOpvVyEkGHn4Lx@9^<31^^iVGGPD! delta 161 zcmZo@U}|V!n(%=|rM%i_CKvs!7LOSvD5W88`wFUcldZ10{}+LFSP&w diff --git a/windows/jack_latent_client.cbp b/windows/jack_latent_client.cbp new file mode 100644 index 00000000..57cb91b4 --- /dev/null +++ b/windows/jack_latent_client.cbp @@ -0,0 +1,91 @@ + + + + + + diff --git a/windows/jackaudioadapter.rc b/windows/jackaudioadapter.rc index ceb43d62..f9c115f3 100644 --- a/windows/jackaudioadapter.rc +++ b/windows/jackaudioadapter.rc @@ -25,7 +25,7 @@ BEGIN VALUE "FileDescription", "Jackmp Audio Adapter for Windows\0" VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "audioadapter\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "audioadapter.dll\0" VALUE "PrivateBuild", "\0" diff --git a/windows/jackd.rc b/windows/jackd.rc index 4fdf0bb4..f61abc0e 100644 --- a/windows/jackd.rc +++ b/windows/jackd.rc @@ -25,7 +25,7 @@ BEGIN VALUE "FileDescription", "Jack server for Windows\0" VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "jackd\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jackd.exe\0" VALUE "PrivateBuild", "\0" diff --git a/windows/jackd.workspace b/windows/jackd.workspace index d26dfe36..c94a7a94 100644 --- a/windows/jackd.workspace +++ b/windows/jackd.workspace @@ -20,7 +20,7 @@ - + @@ -36,6 +36,9 @@ + + + diff --git a/windows/jackdummydriver.rc b/windows/jackdummydriver.rc index 2a364608..da787e2e 100644 --- a/windows/jackdummydriver.rc +++ b/windows/jackdummydriver.rc @@ -25,7 +25,7 @@ BEGIN VALUE "FileDescription", "Jackmp Dummy Driver for Windows\0" VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "jack_dummy\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_dummy.dll\0" VALUE "PrivateBuild", "\0" diff --git a/windows/jackloopbackdriver.rc b/windows/jackloopbackdriver.rc index 4249c39d..b4d32b0e 100644 --- a/windows/jackloopbackdriver.rc +++ b/windows/jackloopbackdriver.rc @@ -25,7 +25,7 @@ BEGIN VALUE "FileDescription", "Jackmp Loopback Driver for Windows\0" VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "jack_loopback\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_loopback.dll\0" VALUE "PrivateBuild", "\0" diff --git a/windows/jacknetadapter.rc b/windows/jacknetadapter.rc index e756d2bf..8142ce61 100644 --- a/windows/jacknetadapter.rc +++ b/windows/jacknetadapter.rc @@ -25,7 +25,7 @@ BEGIN VALUE "FileDescription", "Jackmp Net Adapter for Windows\0" VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "netadapter\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "netadapter.dll\0" VALUE "PrivateBuild", "\0" diff --git a/windows/jacknetdriver.rc b/windows/jacknetdriver.rc index dd2228ce..edac06c3 100644 --- a/windows/jacknetdriver.rc +++ b/windows/jacknetdriver.rc @@ -25,7 +25,7 @@ BEGIN VALUE "FileDescription", "Jackmp Net Driver for Windows\0" VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "jack_netdriver\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_netdriver.dll\0" VALUE "PrivateBuild", "\0" diff --git a/windows/jacknetmanager.rc b/windows/jacknetmanager.rc index 9e4701f8..f30dc040 100644 --- a/windows/jacknetmanager.rc +++ b/windows/jacknetmanager.rc @@ -25,7 +25,7 @@ BEGIN VALUE "FileDescription", "Jackmp Net Manager for Windows\0" VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "netmanager\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "netmanager.dll\0" VALUE "PrivateBuild", "\0" diff --git a/windows/jacknetonedriver.rc b/windows/jacknetonedriver.rc index 1dee018a..57518a2d 100644 --- a/windows/jacknetonedriver.rc +++ b/windows/jacknetonedriver.rc @@ -25,7 +25,7 @@ BEGIN VALUE "FileDescription", "Jackmp NetOne Driver for Windows\0" VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "jack_netonedriver\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_netonedriver.dll\0" VALUE "PrivateBuild", "\0" diff --git a/windows/jackportaudio.rc b/windows/jackportaudio.rc index 651d8ec3..d953dbd9 100644 --- a/windows/jackportaudio.rc +++ b/windows/jackportaudio.rc @@ -25,7 +25,7 @@ BEGIN VALUE "FileDescription", "Jackmp PortAudio Driver for Windows\0" VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "jack_portaudio\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_portaudio.dll\0" VALUE "PrivateBuild", "\0" diff --git a/windows/jackwinmme.rc b/windows/jackwinmme.rc index 509b2715..dfe7bfe2 100644 --- a/windows/jackwinmme.rc +++ b/windows/jackwinmme.rc @@ -25,7 +25,7 @@ BEGIN VALUE "FileDescription", "Jackmp WinMME Driver for Windows\0" VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "jack_portaudio\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_winmme.dll\0" VALUE "PrivateBuild", "\0" diff --git a/windows/libjack.cbp b/windows/libjack.cbp index 41a71885..02932c57 100644 --- a/windows/libjack.cbp +++ b/windows/libjack.cbp @@ -174,6 +174,9 @@ + + diff --git a/windows/libjack.rc b/windows/libjack.rc index 7e99dfdb..d1aaae1e 100644 --- a/windows/libjack.rc +++ b/windows/libjack.rc @@ -25,7 +25,7 @@ BEGIN VALUE "FileDescription", "Jack client library for Windows\0" VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "libjack\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjack.dll\0" VALUE "PrivateBuild", "\0" diff --git a/windows/libjackserver.rc b/windows/libjackserver.rc index 299d84a6..d0c02280 100644 --- a/windows/libjackserver.rc +++ b/windows/libjackserver.rc @@ -25,7 +25,7 @@ BEGIN VALUE "FileDescription", "Jack server library for Windows\0" VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "libjackserver\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjackserver.dll\0" VALUE "PrivateBuild", "\0" diff --git a/windows/portaudio/JackPortAudioDriver.h b/windows/portaudio/JackPortAudioDriver.h index a5995cdc..d18da9b8 100644 --- a/windows/portaudio/JackPortAudioDriver.h +++ b/windows/portaudio/JackPortAudioDriver.h @@ -82,6 +82,12 @@ class JackPortAudioDriver : public JackAudioDriver int Read(); int Write(); + // BufferSize can be changed + bool IsFixedBufferSize() + { + return false; + } + int SetBufferSize(jack_nframes_t buffer_size); }; diff --git a/windows/resource.rc b/windows/resource.rc index a0988d1f..65851b24 100644 --- a/windows/resource.rc +++ b/windows/resource.rc @@ -35,7 +35,7 @@ BEGIN VALUE "FileDescription", "Jackmp for Windows\0" VALUE "FileVersion", "1, 9, 7, 0\0" VALUE "InternalName", "libjackmp\0" - VALUE "LegalCopyright", "Copyright Grame © 2006-2010\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjackmp.dll\0" VALUE "PrivateBuild", "\0" diff --git a/wscript b/wscript index 12a59563..43ab73a2 100644 --- a/wscript +++ b/wscript @@ -108,8 +108,8 @@ def configure(conf): # conf.check_tool('compiler_cxx') # conf.check_tool('compiler_cc') - conf.env.append_unique('CXXFLAGS', '-O3 -Wall') - conf.env.append_unique('CCFLAGS', '-O3 -Wall') + conf.env.append_unique('CXXFLAGS', '-Wall') + conf.env.append_unique('CCFLAGS', '-Wall') conf.sub_config('common') if conf.env['IS_LINUX']: @@ -129,18 +129,26 @@ def configure(conf): conf.fatal('jackdbus was explicitly requested but cannot be built') conf.sub_config('example-clients') - if conf.check_cfg(package='celt', atleast_version='0.7.0', args='--cflags --libs'): + if conf.check_cfg(package='celt', atleast_version='0.8.0', args='--cflags --libs'): conf.define('HAVE_CELT', 1) + conf.define('HAVE_CELT_API_0_8', 1) + conf.define('HAVE_CELT_API_0_7', 0) + conf.define('HAVE_CELT_API_0_5', 0) + elif conf.check_cfg(package='celt', atleast_version='0.7.0', args='--cflags --libs'): + conf.define('HAVE_CELT', 1) + conf.define('HAVE_CELT_API_0_8', 0) conf.define('HAVE_CELT_API_0_7', 1) conf.define('HAVE_CELT_API_0_5', 0) elif conf.check_cfg(package='celt', atleast_version='0.5.0', args='--cflags --libs', required=True): conf.define('HAVE_CELT', 1) - conf.define('HAVE_CELT_API_0_5', 1) + conf.define('HAVE_CELT_API_0_8', 0) conf.define('HAVE_CELT_API_0_7', 0) + conf.define('HAVE_CELT_API_0_5', 1) else: conf.define('HAVE_CELT', 0) - conf.define('HAVE_CELT_API_0_5', 0) + conf.define('HAVE_CELT_API_0_8', 0) conf.define('HAVE_CELT_API_0_7', 0) + conf.define('HAVE_CELT_API_0_5', 0) conf.env['LIB_PTHREAD'] = ['pthread'] conf.env['LIB_DL'] = ['dl'] @@ -164,7 +172,7 @@ def configure(conf): else: conf.env['LIBDIR'] = conf.env['PREFIX'] + '/lib' - if Options.options.libdir: + if Options.options.mandir: conf.env['MANDIR'] = conf.env['PREFIX'] + Options.options.mandir else: conf.env['MANDIR'] = conf.env['PREFIX'] + '/share/man/man1' @@ -198,6 +206,22 @@ def configure(conf): if m != None: svnrev = m.group(1) + conf.env.append_unique('LINKFLAGS', '-lm -lstdc++') + + if Options.options.mixed == True: + env_variant2 = conf.env.copy() + conf.set_env_name('lib32', env_variant2) + env_variant2.set_variant('lib32') + conf.setenv('lib32') + conf.env.append_unique('CXXFLAGS', '-m32') + conf.env.append_unique('CCFLAGS', '-m32') + conf.env.append_unique('LINKFLAGS', '-m32') + if Options.options.libdir32: + conf.env['LIBDIR'] = conf.env['PREFIX'] + Options.options.libdir32 + else: + conf.env['LIBDIR'] = conf.env['PREFIX'] + '/lib32' + conf.write_config_header('config.h') + print display_msg("==================") version_msg = "JACK " + VERSION @@ -214,6 +238,9 @@ def configure(conf): display_msg("Library directory", conf.env['LIBDIR'], 'CYAN') display_msg("Drivers directory", conf.env['ADDON_DIR'], 'CYAN') display_feature('Build debuggable binaries', conf.env['BUILD_DEBUG']) + display_msg('C compiler flags', repr(conf.env['CCFLAGS'])) + display_msg('C++ compiler flags', repr(conf.env['CXXFLAGS'])) + display_msg('Linker flags', repr(conf.env['LINKFLAGS'])) display_feature('Build doxygen documentation', conf.env['BUILD_DOXYGEN_DOCS']) display_feature('Build with engine profiling', conf.env['BUILD_WITH_PROFILE']) display_feature('Build with 32/64 bits mixed mode', conf.env['BUILD_WITH_32_64']) @@ -248,22 +275,6 @@ def configure(conf): print Logs.colors.NORMAL, print - conf.env.append_unique('LINKFLAGS', '-lm -lstdc++') - - if Options.options.mixed == True: - env_variant2 = conf.env.copy() - conf.set_env_name('lib32', env_variant2) - env_variant2.set_variant('lib32') - conf.setenv('lib32') - conf.env.append_unique('CXXFLAGS', '-m32') - conf.env.append_unique('CCFLAGS', '-m32') - conf.env.append_unique('LINKFLAGS', '-m32') - if Options.options.libdir32: - conf.env['LIBDIR'] = conf.env['PREFIX'] + Options.options.libdir32 - else: - conf.env['LIBDIR'] = conf.env['PREFIX'] + '/lib32' - conf.write_config_header('config.h') - def build(bld): print ("make[1]: Entering directory `" + os.getcwd() + "/" + blddir + "'" ) if not os.access('svnversion.h', os.R_OK): From 4bd1bef24c4b4bc0722fa92f7aa3ab07f49a0db8 Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Fri, 18 Mar 2011 22:42:34 -0700 Subject: [PATCH 056/472] Added MIDI queues, FFADO objects, etc. - see 'http://trac.jackaudio.org/ticket/187' for more details --- common/JackMidiAsyncQueue.cpp | 94 +++ common/JackMidiAsyncQueue.h | 92 +++ common/JackMidiAsyncWaitQueue.cpp | 85 +++ common/JackMidiAsyncWaitQueue.h | 97 +++ common/JackMidiBufferReadQueue.cpp | 57 ++ common/JackMidiBufferReadQueue.h | 60 ++ common/JackMidiBufferWriteQueue.cpp | 57 ++ common/JackMidiBufferWriteQueue.h | 62 ++ common/JackMidiRawInputWriteQueue.cpp | 300 +++++++++ common/JackMidiRawInputWriteQueue.h | 170 +++++ common/JackMidiRawOutputWriteQueue.cpp | 228 +++++++ common/JackMidiRawOutputWriteQueue.h | 147 +++++ common/JackMidiReadQueue.cpp | 27 + common/JackMidiReadQueue.h | 55 ++ common/JackMidiReceiveQueue.cpp | 27 + common/JackMidiReceiveQueue.h | 42 ++ common/JackMidiSendQueue.cpp | 34 + common/JackMidiSendQueue.h | 52 ++ common/JackMidiUtil.cpp | 120 ++++ common/JackMidiUtil.h | 102 +++ common/JackMidiWriteQueue.cpp | 27 + common/JackMidiWriteQueue.h | 79 +++ common/JackPhysicalMidiInput.cpp | 287 --------- common/JackPhysicalMidiInput.h | 146 ----- common/JackPhysicalMidiOutput.cpp | 320 ---------- common/JackPhysicalMidiOutput.h | 118 ---- common/wscript | 17 +- example-clients/midi_latency_test.c | 588 ++++++++++++++++++ example-clients/wscript | 1 + linux/firewire/JackFFADODriver.cpp | 38 +- linux/firewire/JackFFADOMidiInput.cpp | 59 -- linux/firewire/JackFFADOMidiInputPort.cpp | 94 +++ linux/firewire/JackFFADOMidiInputPort.h | 51 ++ linux/firewire/JackFFADOMidiOutput.cpp | 60 -- linux/firewire/JackFFADOMidiOutputPort.cpp | 98 +++ linux/firewire/JackFFADOMidiOutputPort.h | 53 ++ linux/firewire/JackFFADOMidiReceiveQueue.cpp | 55 ++ ...idiInput.h => JackFFADOMidiReceiveQueue.h} | 34 +- linux/firewire/JackFFADOMidiSendQueue.cpp | 64 ++ ...OMidiOutput.h => JackFFADOMidiSendQueue.h} | 37 +- linux/wscript | 8 +- 41 files changed, 3082 insertions(+), 1060 deletions(-) create mode 100644 common/JackMidiAsyncQueue.cpp create mode 100644 common/JackMidiAsyncQueue.h create mode 100644 common/JackMidiAsyncWaitQueue.cpp create mode 100644 common/JackMidiAsyncWaitQueue.h create mode 100644 common/JackMidiBufferReadQueue.cpp create mode 100644 common/JackMidiBufferReadQueue.h create mode 100644 common/JackMidiBufferWriteQueue.cpp create mode 100644 common/JackMidiBufferWriteQueue.h create mode 100644 common/JackMidiRawInputWriteQueue.cpp create mode 100644 common/JackMidiRawInputWriteQueue.h create mode 100644 common/JackMidiRawOutputWriteQueue.cpp create mode 100644 common/JackMidiRawOutputWriteQueue.h create mode 100644 common/JackMidiReadQueue.cpp create mode 100644 common/JackMidiReadQueue.h create mode 100644 common/JackMidiReceiveQueue.cpp create mode 100644 common/JackMidiReceiveQueue.h create mode 100644 common/JackMidiSendQueue.cpp create mode 100644 common/JackMidiSendQueue.h create mode 100644 common/JackMidiUtil.cpp create mode 100644 common/JackMidiUtil.h create mode 100644 common/JackMidiWriteQueue.cpp create mode 100644 common/JackMidiWriteQueue.h delete mode 100644 common/JackPhysicalMidiInput.cpp delete mode 100644 common/JackPhysicalMidiInput.h delete mode 100644 common/JackPhysicalMidiOutput.cpp delete mode 100644 common/JackPhysicalMidiOutput.h create mode 100644 example-clients/midi_latency_test.c delete mode 100644 linux/firewire/JackFFADOMidiInput.cpp create mode 100644 linux/firewire/JackFFADOMidiInputPort.cpp create mode 100644 linux/firewire/JackFFADOMidiInputPort.h delete mode 100644 linux/firewire/JackFFADOMidiOutput.cpp create mode 100644 linux/firewire/JackFFADOMidiOutputPort.cpp create mode 100644 linux/firewire/JackFFADOMidiOutputPort.h create mode 100644 linux/firewire/JackFFADOMidiReceiveQueue.cpp rename linux/firewire/{JackFFADOMidiInput.h => JackFFADOMidiReceiveQueue.h} (59%) create mode 100644 linux/firewire/JackFFADOMidiSendQueue.cpp rename linux/firewire/{JackFFADOMidiOutput.h => JackFFADOMidiSendQueue.h} (58%) diff --git a/common/JackMidiAsyncQueue.cpp b/common/JackMidiAsyncQueue.cpp new file mode 100644 index 00000000..28018b56 --- /dev/null +++ b/common/JackMidiAsyncQueue.cpp @@ -0,0 +1,94 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include + +#include "JackMidiAsyncQueue.h" + +using Jack::JackMidiAsyncQueue; + +JackMidiAsyncQueue::JackMidiAsyncQueue(size_t max_bytes, size_t max_messages) +{ + data_buffer = new jack_midi_data_t[max_bytes]; + byte_ring = jack_ringbuffer_create(max_bytes + 1); + if (byte_ring) { + info_ring = jack_ringbuffer_create((max_messages * INFO_SIZE) + 1); + if (info_ring) { + jack_ringbuffer_mlock(byte_ring); + jack_ringbuffer_mlock(info_ring); + advance_space = 0; + this->max_bytes = max_bytes; + return; + } + jack_ringbuffer_free(byte_ring); + } + delete data_buffer; + throw std::bad_alloc(); +} + +JackMidiAsyncQueue::~JackMidiAsyncQueue() +{ + jack_ringbuffer_free(byte_ring); + jack_ringbuffer_free(info_ring); + delete[] data_buffer; +} + +jack_midi_event_t * +JackMidiAsyncQueue::DequeueEvent() +{ + jack_midi_event_t *event = 0; + if (jack_ringbuffer_read_space(info_ring) >= INFO_SIZE) { + if (advance_space) { + jack_ringbuffer_read_advance(byte_ring, advance_space); + } + event = &dequeue_event; + jack_ringbuffer_read(info_ring, (char *) &(event->time), + sizeof(jack_nframes_t)); + size_t size; + jack_ringbuffer_read(info_ring, (char *) &size, sizeof(size_t)); + event->size = size; + jack_ringbuffer_data_t vector[2]; + jack_ringbuffer_get_read_vector(byte_ring, vector); + size_t size1 = vector[0].len; + if (size1 >= size) { + event->buffer = (jack_midi_data_t *) vector[0].buf; + } else { + event->buffer = data_buffer; + memcpy(data_buffer, vector[0].buf, size1); + memcpy(data_buffer + size1, vector[1].buf, size - size1); + } + advance_space = size; + } + return event; +} + +Jack::JackMidiWriteQueue::EnqueueResult +JackMidiAsyncQueue::EnqueueEvent(jack_nframes_t time, size_t size, + jack_midi_data_t *buffer) +{ + if (! ((jack_ringbuffer_write_space(info_ring) >= INFO_SIZE) && + (jack_ringbuffer_write_space(byte_ring) >= size))) { + return size > max_bytes ? BUFFER_TOO_SMALL : BUFFER_FULL; + } + jack_ringbuffer_write(byte_ring, (const char *) buffer, size); + jack_ringbuffer_write(info_ring, (const char *) (&time), + sizeof(jack_nframes_t)); + jack_ringbuffer_write(info_ring, (const char *) (&size), sizeof(size_t)); + return OK; +} diff --git a/common/JackMidiAsyncQueue.h b/common/JackMidiAsyncQueue.h new file mode 100644 index 00000000..630b5ab1 --- /dev/null +++ b/common/JackMidiAsyncQueue.h @@ -0,0 +1,92 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackMidiAsyncQueue__ +#define __JackMidiAsyncQueue__ + +#include "JackMidiPort.h" +#include "JackMidiReadQueue.h" +#include "JackMidiWriteQueue.h" +#include "ringbuffer.h" + +namespace Jack { + + /** + * This is a MIDI message queue designed to allow two threads to pass MIDI + * messages between two threads (though it can also be used to buffer + * events internally). This is especially useful if the MIDI API + * you're attempting to interface with doesn't provide the ability to + * schedule MIDI events ahead of time and/or has blocking send/receive + * calls, as it allows a separate thread to handle input/output while the + * JACK process thread copies events from a `JackMidiBufferReadQueue` to + * this queue, or from this queue to a `JackMidiBufferWriteQueue`. + */ + + class SERVER_EXPORT JackMidiAsyncQueue: + public JackMidiReadQueue, public JackMidiWriteQueue { + + private: + + static const size_t INFO_SIZE = + sizeof(jack_nframes_t) + sizeof(size_t); + + size_t advance_space; + jack_ringbuffer_t *byte_ring; + jack_midi_data_t *data_buffer; + jack_midi_event_t dequeue_event; + jack_ringbuffer_t *info_ring; + size_t max_bytes; + + public: + + using JackMidiWriteQueue::EnqueueEvent; + + /** + * Creates a new asynchronous MIDI message queue. The queue can store + * up to `max_messages` MIDI messages and up to `max_bytes` of MIDI + * data before it starts rejecting messages. + */ + + JackMidiAsyncQueue(size_t max_bytes=4096, size_t max_messages=1024); + + virtual ~JackMidiAsyncQueue(); + + /** + * Dequeues and returns a MIDI event. Returns '0' if there are no MIDI + * events available. This method may be overridden. + */ + + virtual jack_midi_event_t * + DequeueEvent(); + + /** + * Enqueues the MIDI event specified by the arguments. The return + * value indiciates whether or not the event was successfully enqueued. + * This method may be overridden. + */ + + virtual EnqueueResult + EnqueueEvent(jack_nframes_t time, size_t size, + jack_midi_data_t *buffer); + + }; + +} + +#endif diff --git a/common/JackMidiAsyncWaitQueue.cpp b/common/JackMidiAsyncWaitQueue.cpp new file mode 100644 index 00000000..016737cb --- /dev/null +++ b/common/JackMidiAsyncWaitQueue.cpp @@ -0,0 +1,85 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include + +#include "JackMidiAsyncWaitQueue.h" +#include "JackMidiUtil.h" +#include "JackTime.h" + +using Jack::JackMidiAsyncWaitQueue; + +JackMidiAsyncWaitQueue::JackMidiAsyncWaitQueue(size_t max_bytes, + size_t max_messages): + JackMidiAsyncQueue(max_bytes, max_messages) +{ + if (semaphore.Allocate("JackMidiAsyncWaitQueue", "midi-thread", 0)) { + throw std::bad_alloc(); + } +} + +JackMidiAsyncWaitQueue::~JackMidiAsyncWaitQueue() +{ + semaphore.Destroy(); +} + +jack_midi_event_t * +JackMidiAsyncWaitQueue::DequeueEvent() +{ + return DequeueEvent((long) 0); +} + +jack_midi_event_t * +JackMidiAsyncWaitQueue::DequeueEvent(jack_nframes_t frame) +{ + + // XXX: I worry about timer resolution on Solaris and Windows. When the + // resolution for the `JackSynchro` object is milliseconds, the worst-case + // scenario for processor objects is that the wait time becomes less than a + // millisecond, and the processor object continually calls this method, + // expecting to wait a certain amount of microseconds, and ends up not + // waiting at all each time, essentially busy-waiting until the current + // frame is reached. Perhaps there should be a #define that indicates the + // wait time resolution for `JackSynchro` objects so that we can wait a + // little longer if necessary. + + jack_time_t frame_time = GetTimeFromFrames(frame); + jack_time_t current_time = GetMicroSeconds(); + return DequeueEvent((frame_time < current_time) ? 0 : + (long) (frame_time - current_time)); +} + +jack_midi_event_t * +JackMidiAsyncWaitQueue::DequeueEvent(long usec) +{ + return ((usec < 0) ? semaphore.Wait() : semaphore.TimedWait(usec)) ? + JackMidiAsyncQueue::DequeueEvent() : 0; +} + +Jack::JackMidiWriteQueue::EnqueueResult +JackMidiAsyncWaitQueue::EnqueueEvent(jack_nframes_t time, size_t size, + jack_midi_data_t *buffer) +{ + EnqueueResult result = JackMidiAsyncQueue::EnqueueEvent(time, size, + buffer); + if (result == OK) { + semaphore.Signal(); + } + return result; +} diff --git a/common/JackMidiAsyncWaitQueue.h b/common/JackMidiAsyncWaitQueue.h new file mode 100644 index 00000000..d35dd8b6 --- /dev/null +++ b/common/JackMidiAsyncWaitQueue.h @@ -0,0 +1,97 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackMidiAsyncWaitQueue__ +#define __JackMidiAsyncWaitQueue__ + +#include "JackMidiAsyncQueue.h" + +namespace Jack { + + /** + * This is an asynchronous wait queue that allows a thread to wait for a + * message, either indefinitely or for a specified time. This is one + * example of a way that the `JackMidiAsyncQueue` class can be extended so + * that process threads can interact with non-process threads to send MIDI + * events. + * + * XXX: As of right now, this code hasn't been tested. Also, note the + * warning in the JackMidiAsyncWaitQueue.cpp about semaphore wait + * resolution. + */ + + class SERVER_EXPORT JackMidiAsyncWaitQueue: public JackMidiAsyncQueue { + + private: + + JackSynchro semaphore; + + public: + + /** + * Creates a new asynchronous MIDI wait message queue. The queue can + * store up to `max_messages` MIDI messages and up to `max_bytes` of + * MIDI data before it starts rejecting messages. + */ + + JackMidiAsyncWaitQueue(size_t max_bytes=4096, + size_t max_messages=1024); + + ~JackMidiAsyncWaitQueue(); + + /** + * Dequeues and returns a MIDI event. Returns '0' if there are no MIDI + * events available right now. + */ + + jack_midi_event_t * + DequeueEvent(); + + /** + * Waits a specified time for a MIDI event to be available, or + * indefinitely if the time is negative. Returns the MIDI event, or + * '0' if time runs out and no MIDI event is available. + */ + + jack_midi_event_t * + DequeueEvent(long usecs); + + /** + * Waits until the specified frame for a MIDI event to be available. + * Returns the MIDI event, or '0' if time runs out and no MIDI event is + * available. + */ + + jack_midi_event_t * + DequeueEvent(jack_nframes_t frame); + + /** + * Enqueues the MIDI event specified by the arguments. The return + * value indiciates whether or not the event was successfully enqueued. + */ + + EnqueueResult + EnqueueEvent(jack_nframes_t time, size_t size, + jack_midi_data_t *buffer); + + }; + +} + +#endif diff --git a/common/JackMidiBufferReadQueue.cpp b/common/JackMidiBufferReadQueue.cpp new file mode 100644 index 00000000..66777eb0 --- /dev/null +++ b/common/JackMidiBufferReadQueue.cpp @@ -0,0 +1,57 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "JackMidiBufferReadQueue.h" +#include "JackMidiUtil.h" + +using Jack::JackMidiBufferReadQueue; + +JackMidiBufferReadQueue::JackMidiBufferReadQueue() +{ + event_count = 0; + index = 0; +} + +jack_midi_event_t * +JackMidiBufferReadQueue::DequeueEvent() +{ + jack_midi_event_t *e = 0; + if (index < event_count) { + JackMidiEvent *event = &(buffer->events[index]); + midi_event.buffer = event->GetData(buffer); + midi_event.size = event->size; + midi_event.time = last_frame_time + event->time; + e = &midi_event; + index++; + } + return e; +} + +void +JackMidiBufferReadQueue::ResetMidiBuffer(JackMidiBuffer *buffer) +{ + index = 0; + if (buffer) { + this->buffer = buffer; + event_count = buffer->event_count; + last_frame_time = GetLastFrame(); + } else { + event_count = 0; + } +} diff --git a/common/JackMidiBufferReadQueue.h b/common/JackMidiBufferReadQueue.h new file mode 100644 index 00000000..84337e42 --- /dev/null +++ b/common/JackMidiBufferReadQueue.h @@ -0,0 +1,60 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackMidiBufferReadQueue__ +#define __JackMidiBufferReadQueue__ + +#include "JackMidiReadQueue.h" + +namespace Jack { + + /** + * Wrapper class to present a JackMidiBuffer in a read queue interface. + */ + + class SERVER_EXPORT JackMidiBufferReadQueue: public JackMidiReadQueue { + + private: + + JackMidiBuffer *buffer; + jack_nframes_t event_count; + jack_nframes_t index; + jack_nframes_t last_frame_time; + jack_midi_event_t midi_event; + + public: + + JackMidiBufferReadQueue(); + + jack_midi_event_t * + DequeueEvent(); + + /** + * This method must be called each period to reset the MIDI buffer for + * processing. + */ + + void + ResetMidiBuffer(JackMidiBuffer *buffer); + + }; + +} + +#endif diff --git a/common/JackMidiBufferWriteQueue.cpp b/common/JackMidiBufferWriteQueue.cpp new file mode 100644 index 00000000..5caab49d --- /dev/null +++ b/common/JackMidiBufferWriteQueue.cpp @@ -0,0 +1,57 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "JackMidiBufferWriteQueue.h" +#include "JackMidiUtil.h" + +using Jack::JackMidiBufferWriteQueue; + +JackMidiBufferWriteQueue::JackMidiBufferWriteQueue() +{ + // Empty +} + +Jack::JackMidiWriteQueue::EnqueueResult +JackMidiBufferWriteQueue::EnqueueEvent(jack_nframes_t time, size_t size, + jack_midi_data_t *data) +{ + if (time >= next_frame_time) { + return EVENT_EARLY; + } + if (time < last_frame_time) { + time = last_frame_time; + } + jack_midi_data_t *dst = buffer->ReserveEvent(time - last_frame_time, size); + if (! dst) { + return size > max_bytes ? BUFFER_TOO_SMALL : BUFFER_FULL; + } + memcpy(dst, data, size); + return OK; +} + +void +JackMidiBufferWriteQueue::ResetMidiBuffer(JackMidiBuffer *buffer, + jack_nframes_t frames) +{ + this->buffer = buffer; + buffer->Reset(frames); + last_frame_time = GetLastFrame(); + max_bytes = buffer->MaxEventSize(); + next_frame_time = last_frame_time + frames; +} diff --git a/common/JackMidiBufferWriteQueue.h b/common/JackMidiBufferWriteQueue.h new file mode 100644 index 00000000..90d5cbf1 --- /dev/null +++ b/common/JackMidiBufferWriteQueue.h @@ -0,0 +1,62 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackMidiBufferWriteQueue__ +#define __JackMidiBufferWriteQueue__ + +#include "JackMidiWriteQueue.h" + +namespace Jack { + + /** + * Wrapper class to present a JackMidiBuffer in a write queue interface. + */ + + class SERVER_EXPORT JackMidiBufferWriteQueue: public JackMidiWriteQueue { + + private: + + JackMidiBuffer *buffer; + jack_nframes_t last_frame_time; + size_t max_bytes; + jack_nframes_t next_frame_time; + + public: + + using JackMidiWriteQueue::EnqueueEvent; + + JackMidiBufferWriteQueue(); + + EnqueueResult + EnqueueEvent(jack_nframes_t time, size_t size, + jack_midi_data_t *buffer); + + /** + * This method must be called each period to reset the MIDI buffer for + * processing. + */ + + void + ResetMidiBuffer(JackMidiBuffer *buffer, jack_nframes_t frames); + + }; + +} + +#endif diff --git a/common/JackMidiRawInputWriteQueue.cpp b/common/JackMidiRawInputWriteQueue.cpp new file mode 100644 index 00000000..e2ff4453 --- /dev/null +++ b/common/JackMidiRawInputWriteQueue.cpp @@ -0,0 +1,300 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include +#include +#include + +#include "JackMidiRawInputWriteQueue.h" + +using Jack::JackMidiRawInputWriteQueue; + +JackMidiRawInputWriteQueue:: +JackMidiRawInputWriteQueue(JackMidiWriteQueue *write_queue, + size_t max_packet_data, size_t max_packets) +{ + packet_queue = new JackMidiAsyncQueue(max_packet_data, max_packets); + std::auto_ptr packet_queue_ptr(packet_queue); + input_ring = jack_ringbuffer_create(max_packet_data + 1); + if (! input_ring) { + throw std::bad_alloc(); + } + jack_ringbuffer_mlock(input_ring); + Clear(); + expected_bytes = 0; + event_pending = false; + packet = 0; + status_byte = 0; + this->write_queue = write_queue; + packet_queue_ptr.release(); +} + +JackMidiRawInputWriteQueue::~JackMidiRawInputWriteQueue() +{ + jack_ringbuffer_free(input_ring); + delete packet_queue; +} + +void +JackMidiRawInputWriteQueue::Clear() +{ + jack_ringbuffer_reset(input_ring); + total_bytes = 0; + unbuffered_bytes = 0; +} + +Jack::JackMidiWriteQueue::EnqueueResult +JackMidiRawInputWriteQueue::EnqueueEvent(jack_nframes_t time, size_t size, + jack_midi_data_t *buffer) +{ + return packet_queue->EnqueueEvent(time, size, buffer); +} + +void +JackMidiRawInputWriteQueue::HandleBufferFailure(size_t unbuffered_bytes, + size_t total_bytes) +{ + jack_error("JackMidiRawInputWriteQueue::HandleBufferFailure - %d MIDI " + "byte(s) of a %d byte message could not be buffered. The " + "message has been dropped.", unbuffered_bytes, total_bytes); +} + +void +JackMidiRawInputWriteQueue::HandleEventLoss(jack_midi_event_t *event) +{ + jack_error("JackMidiRawInputWriteQueue::HandleEventLoss - A %d byte MIDI " + "event scheduled for frame '%d' could not be processed because " + "the write queue cannot accomodate an event of that size. The " + "event has been discarded.", event->size, event->time); +} + +void +JackMidiRawInputWriteQueue::HandleIncompleteMessage(size_t total_bytes) +{ + jack_error("JackMidiRawInputWriteQueue::HandleIncompleteMessage - " + "Discarding %d MIDI byte(s) of an incomplete message. The " + "MIDI cable may have been unplugged.", total_bytes); +} + +void +JackMidiRawInputWriteQueue::HandleInvalidStatusByte(jack_midi_data_t byte) +{ + jack_error("JackMidiRawInputWriteQueue::HandleInvalidStatusByte - " + "Dropping invalid MIDI status byte '%x'.", (unsigned int) byte); +} + +void +JackMidiRawInputWriteQueue::HandleUnexpectedSysexEnd(size_t total_bytes) +{ + jack_error("JackMidiRawInputWriteQueue::HandleUnexpectedSysexEnd - " + "Received a sysex end byte without first receiving a sysex " + "start byte. Discarding %d MIDI byte(s). The cable may have " + "been unplugged.", total_bytes); +} + +bool +JackMidiRawInputWriteQueue::PrepareBufferedEvent(jack_nframes_t time) +{ + bool result = ! unbuffered_bytes; + if (! result) { + HandleBufferFailure(unbuffered_bytes, total_bytes); + } else { + size_t size = jack_ringbuffer_read_space(input_ring); + jack_ringbuffer_data_t vector[2]; + jack_ringbuffer_get_read_vector(input_ring, vector); + // We don't worry about the second part of the vector, as we reset the + // ringbuffer after each parsed message. + PrepareEvent(time, size, (jack_midi_data_t *) vector[0].buf); + } + Clear(); + if (status_byte >= 0xf0) { + expected_bytes = 0; + status_byte = 0; + } + return result; +} + +bool +JackMidiRawInputWriteQueue::PrepareByteEvent(jack_nframes_t time, + jack_midi_data_t byte) +{ + event_byte = byte; + PrepareEvent(time, 1, &event_byte); + return true; +} + +void +JackMidiRawInputWriteQueue::PrepareEvent(jack_nframes_t time, size_t size, + jack_midi_data_t *buffer) +{ + event.buffer = buffer; + event.size = size; + event.time = time; + event_pending = true; +} + +jack_nframes_t +JackMidiRawInputWriteQueue::Process(jack_nframes_t boundary_frame) +{ + if (event_pending) { + if (! WriteEvent(boundary_frame)) { + return event.time; + } + } + if (! packet) { + packet = packet_queue->DequeueEvent(); + } + for (; packet; packet = packet_queue->DequeueEvent()) { + for (; packet->size; (packet->buffer)++, (packet->size)--) { + if (ProcessByte(packet->time, *(packet->buffer))) { + if (! WriteEvent(boundary_frame)) { + (packet->buffer)++; + (packet->size)--; + return event.time; + } + } + } + } + return 0; +} + +bool +JackMidiRawInputWriteQueue::ProcessByte(jack_nframes_t time, + jack_midi_data_t byte) +{ + if (byte >= 0xf8) { + // Realtime + if (byte == 0xfd) { + HandleInvalidStatusByte(byte); + return false; + } + return PrepareByteEvent(time, byte); + } + if (byte == 0xf7) { + // Sysex end + if (status_byte == 0xf0) { + RecordByte(byte); + return PrepareBufferedEvent(time); + } + HandleUnexpectedSysexEnd(total_bytes); + Clear(); + expected_bytes = 0; + status_byte = 0; + return false; + } + if (byte >= 0x80) { + // Non-realtime status byte + if (total_bytes) { + HandleIncompleteMessage(total_bytes); + Clear(); + } + status_byte = byte; + switch (byte & 0xf0) { + case 0x80: + case 0x90: + case 0xa0: + case 0xb0: + case 0xe0: + // Note On, Note Off, Aftertouch, Control Change, Pitch Wheel + expected_bytes = 3; + break; + case 0xc0: + case 0xd0: + // Program Change, Channel Pressure + expected_bytes = 2; + break; + case 0xf0: + switch (byte) { + case 0xf0: + // Sysex + expected_bytes = 0; + break; + case 0xf1: + case 0xf3: + // MTC Quarter Frame, Song Select + expected_bytes = 2; + break; + case 0xf2: + // Song Position + expected_bytes = 3; + break; + case 0xf4: + case 0xf5: + // Undefined + HandleInvalidStatusByte(byte); + expected_bytes = 0; + status_byte = 0; + return false; + case 0xf6: + // Tune Request + bool result = PrepareByteEvent(time, byte); + if (result) { + expected_bytes = 0; + status_byte = 0; + } + return result; + } + } + RecordByte(byte); + return false; + } + // Data byte + if (! status_byte) { + // Data bytes without a status will be discarded. + total_bytes++; + unbuffered_bytes++; + return false; + } + if (! total_bytes) { + // Apply running status. + RecordByte(status_byte); + } + RecordByte(byte); + return (total_bytes == expected_bytes) ? PrepareBufferedEvent(time) : + false; +} + +void +JackMidiRawInputWriteQueue::RecordByte(jack_midi_data_t byte) +{ + if (jack_ringbuffer_write(input_ring, (const char *) &byte, 1) != 1) { + unbuffered_bytes++; + } + total_bytes++; +} + +bool +JackMidiRawInputWriteQueue::WriteEvent(jack_nframes_t boundary_frame) +{ + if (event.time < boundary_frame) { + switch (write_queue->EnqueueEvent(&event)) { + case BUFFER_TOO_SMALL: + HandleEventLoss(&event); + // Fallthrough on purpose + case OK: + event_pending = false; + return true; + default: + // This is here to stop compilers from warning us about not + // handling enumeration values. + ; + } + } + return false; +} diff --git a/common/JackMidiRawInputWriteQueue.h b/common/JackMidiRawInputWriteQueue.h new file mode 100644 index 00000000..2feff527 --- /dev/null +++ b/common/JackMidiRawInputWriteQueue.h @@ -0,0 +1,170 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackMidiRawInputWriteQueue__ +#define __JackMidiRawInputWriteQueue__ + +#include "JackMidiAsyncQueue.h" +#include "JackMidiWriteQueue.h" +#include "ringbuffer.h" + +namespace Jack { + + /** + * This queue enqueues raw, unparsed MIDI packets, and outputs complete + * MIDI messages to a write queue. + * + * Use this queue if the MIDI API you're interfacing with gives you raw + * MIDI bytes that must be parsed. + */ + + class SERVER_EXPORT JackMidiRawInputWriteQueue: public JackMidiWriteQueue { + + private: + + jack_midi_event_t event; + jack_midi_data_t event_byte; + bool event_pending; + size_t expected_bytes; + jack_ringbuffer_t *input_ring; + jack_midi_event_t *packet; + JackMidiAsyncQueue *packet_queue; + jack_midi_data_t status_byte; + size_t total_bytes; + size_t unbuffered_bytes; + JackMidiWriteQueue *write_queue; + + void + Clear(); + + bool + PrepareBufferedEvent(jack_nframes_t time); + + bool + PrepareByteEvent(jack_nframes_t time, jack_midi_data_t byte); + + void + PrepareEvent(jack_nframes_t time, size_t size, + jack_midi_data_t *buffer); + + bool + ProcessByte(jack_nframes_t time, jack_midi_data_t byte); + + void + RecordByte(jack_midi_data_t byte); + + bool + WriteEvent(jack_nframes_t boundary_frame); + + protected: + + /** + * Override this method to specify what happens when there isn't enough + * room in the ringbuffer to contain a parsed event. The default + * method outputs an error message. + */ + + virtual void + HandleBufferFailure(size_t unbuffered_bytes, size_t total_bytes); + + /** + * Override this method to specify what happens when a parsed event + * can't be written to the write queue because the event's size exceeds + * the total possible space in the write queue. The default method + * outputs an error message. + */ + + virtual void + HandleEventLoss(jack_midi_event_t *event); + + /** + * Override this method to specify what happens when an incomplete MIDI + * message is parsed. The default method outputs an error message. + */ + + virtual void + HandleIncompleteMessage(size_t total_bytes); + + /** + * Override this method to specify what happens when an invalid MIDI + * status byte is parsed. The default method outputs an error message. + */ + + virtual void + HandleInvalidStatusByte(jack_midi_data_t byte); + + /** + * Override this method to specify what happens when a sysex end byte + * is parsed without first parsing a sysex begin byte. The default + * method outputs an error message. + */ + + virtual void + HandleUnexpectedSysexEnd(size_t total_bytes); + + public: + + using JackMidiWriteQueue::EnqueueEvent; + + /** + * Called to create a new raw input write queue. The `write_queue` + * argument is the queue to write parsed messages to. The optional + * `max_packets` argument specifies the number of packets that can be + * enqueued in the internal queue. The optional `max_packet_data` + * argument specifies the total number of MIDI bytes that can be put in + * the internal queue, AND the maximum size for an event that can be + * written to the write queue. + */ + + JackMidiRawInputWriteQueue(JackMidiWriteQueue *write_queue, + size_t max_packet_data=4096, + size_t max_packets=1024); + + ~JackMidiRawInputWriteQueue(); + + EnqueueResult + EnqueueEvent(jack_nframes_t time, size_t size, + jack_midi_data_t *buffer); + + /** + * The `Process()` method should be called each time the + * `EnqueueEvent()` method returns `OK`. The `Process()` method will + * return the next frame at which an event should be sent. The return + * value from `Process()` depends upon the result of writing bytes to + * the write queue: + * + * -If the return value is '0', then all *complete* events have been + * sent successfully to the write queue. Don't call `Process()` again + * until another event has been enqueued. + * + * -If the return value is a non-zero value, then it specifies the + * frame that a pending event is scheduled to sent at. If the frame is + * in the future, then `Process()` should be called again at that time; + * otherwise, `Process()` should be called as soon as the write queue + * will accept events again. + */ + + jack_nframes_t + Process(jack_nframes_t boundary_frame); + + }; + +} + +#endif diff --git a/common/JackMidiRawOutputWriteQueue.cpp b/common/JackMidiRawOutputWriteQueue.cpp new file mode 100644 index 00000000..6624c47c --- /dev/null +++ b/common/JackMidiRawOutputWriteQueue.cpp @@ -0,0 +1,228 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include +#include + +#include "JackError.h" +#include "JackMidiRawOutputWriteQueue.h" +#include "JackMidiUtil.h" + +using Jack::JackMidiRawOutputWriteQueue; + +#define STILL_TIME(c, b) ((! (b)) || ((c) < (b))) + +JackMidiRawOutputWriteQueue:: +JackMidiRawOutputWriteQueue(JackMidiSendQueue *send_queue, size_t non_rt_size, + size_t max_non_rt_messages, size_t max_rt_messages) +{ + non_rt_queue = new JackMidiAsyncQueue(non_rt_size, max_non_rt_messages); + std::auto_ptr non_rt_ptr(non_rt_queue); + rt_queue = new JackMidiAsyncQueue(max_rt_messages, max_rt_messages); + std::auto_ptr rt_ptr(rt_queue); + non_rt_event = 0; + rt_event = 0; + running_status = 0; + this->send_queue = send_queue; + rt_ptr.release(); + non_rt_ptr.release(); +} + +JackMidiRawOutputWriteQueue::~JackMidiRawOutputWriteQueue() +{ + delete non_rt_queue; + delete rt_queue; +} + +bool +JackMidiRawOutputWriteQueue::DequeueNonRealtimeEvent() +{ + non_rt_event = non_rt_queue->DequeueEvent(); + bool result = non_rt_event != 0; + if (result) { + non_rt_event_time = non_rt_event->time; + running_status = ApplyRunningStatus(non_rt_event, running_status); + } + return result; +} + +bool +JackMidiRawOutputWriteQueue::DequeueRealtimeEvent() +{ + rt_event = rt_queue->DequeueEvent(); + bool result = rt_event != 0; + if (result) { + rt_event_time = rt_event->time; + } + return result; +} + +Jack::JackMidiWriteQueue::EnqueueResult +JackMidiRawOutputWriteQueue::EnqueueEvent(jack_nframes_t time, size_t size, + jack_midi_data_t *buffer) +{ + JackMidiAsyncQueue *queue = (size == 1) && (*buffer >= 0xf8) ? rt_queue : + non_rt_queue; + EnqueueResult result = queue->EnqueueEvent(time, size, buffer); + if (result == OK) { + last_enqueued_message_time = time; + } + return result; +} + +void +JackMidiRawOutputWriteQueue::HandleWriteQueueBug(jack_nframes_t time, + jack_midi_data_t byte) +{ + jack_error("JackMidiRawOutputWriteQueue::HandleWriteQueueBug - **BUG** " + "The write queue told us that it couldn't enqueue a 1-byte " + "MIDI event scheduled for frame '%d'. This is probably a bug " + "in the write queue implementation.", time); +} + +jack_nframes_t +JackMidiRawOutputWriteQueue::Process(jack_nframes_t boundary_frame) +{ + jack_nframes_t current_frame = send_queue->GetNextScheduleFrame(); + while (STILL_TIME(current_frame, boundary_frame)) { + if (! non_rt_event) { + DequeueNonRealtimeEvent(); + } + if (! rt_event) { + DequeueRealtimeEvent(); + } + if (! (non_rt_event || rt_event)) { + return 0; + } + if (! WriteRealtimeEvents(boundary_frame)) { + break; + } + jack_nframes_t non_rt_boundary = + rt_event && STILL_TIME(rt_event_time, boundary_frame) ? + rt_event_time : boundary_frame; + if (! WriteNonRealtimeEvents(non_rt_boundary)) { + break; + } + current_frame = send_queue->GetNextScheduleFrame(); + } + + // If we get here, that means there is some sort of message available, and + // that either we can't currently write to the write queue or we have + // reached the boundary frame. Return the earliest time that a message is + // scheduled to be sent. + + return ! non_rt_event ? rt_event_time : + non_rt_event->size > 1 ? current_frame : + ! rt_event ? non_rt_event_time : + non_rt_event_time < rt_event_time ? non_rt_event_time : rt_event_time; +} + +bool +JackMidiRawOutputWriteQueue::SendByte(jack_nframes_t time, + jack_midi_data_t byte) +{ + switch (send_queue->EnqueueEvent(time, 1, &byte)) { + case BUFFER_TOO_SMALL: + HandleWriteQueueBug(time, byte); + case OK: + return true; + default: + // This is here to stop compilers from warning us about not handling + // enumeration values. + ; + } + return false; +} + +bool +JackMidiRawOutputWriteQueue:: +WriteNonRealtimeEvents(jack_nframes_t boundary_frame) +{ + if (! non_rt_event) { + if (! DequeueNonRealtimeEvent()) { + return true; + } + } + jack_nframes_t current_frame = send_queue->GetNextScheduleFrame(); + do { + + // Send out as much of the non-realtime buffer as we can, save for one + // byte which we will send out when the message is supposed to arrive. + + for (; non_rt_event->size > 1; + (non_rt_event->size)--, (non_rt_event->buffer)++) { + if (! STILL_TIME(current_frame, boundary_frame)) { + return true; + } + if (! SendByte(current_frame, *(non_rt_event->buffer))) { + return false; + } + current_frame = send_queue->GetNextScheduleFrame(); + } + if (! (STILL_TIME(current_frame, boundary_frame) && + STILL_TIME(non_rt_event_time, boundary_frame))) { + return true; + } + + // There's still time. Try to send the byte. + + if (! SendByte(non_rt_event_time, *(non_rt_event->buffer))) { + return false; + } + current_frame = send_queue->GetNextScheduleFrame(); + if (! DequeueNonRealtimeEvent()) { + break; + } + } while (STILL_TIME(current_frame, boundary_frame)); + return true; +} + +bool +JackMidiRawOutputWriteQueue::WriteRealtimeEvents(jack_nframes_t boundary_frame) +{ + jack_nframes_t current_frame = send_queue->GetNextScheduleFrame(); + if (! rt_event) { + if (! DequeueRealtimeEvent()) { + return true; + } + } + for (;;) { + if (! STILL_TIME(current_frame, boundary_frame)) { + return false; + } + + // If: + // -there's still time before we need to send the realtime event + // -there's a non-realtime event available for sending + // -non-realtime data can be scheduled before this event + + if ((rt_event_time > current_frame) && non_rt_event && + ((non_rt_event->size > 1) || + (non_rt_event_time < rt_event_time))) { + return true; + } + if (! SendByte(rt_event_time, *(rt_event->buffer))) { + return false; + } + current_frame = send_queue->GetNextScheduleFrame(); + if (! DequeueRealtimeEvent()) { + return true; + } + } +} diff --git a/common/JackMidiRawOutputWriteQueue.h b/common/JackMidiRawOutputWriteQueue.h new file mode 100644 index 00000000..b5e336dc --- /dev/null +++ b/common/JackMidiRawOutputWriteQueue.h @@ -0,0 +1,147 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackMidiRawOutputWriteQueue__ +#define __JackMidiRawOutputWriteQueue__ + +#include "JackMidiAsyncQueue.h" +#include "JackMidiSendQueue.h" + +namespace Jack { + + /** + * This queue enqueues valid MIDI events and modifies them for raw output + * to a write queue. It has a number of advantages over straight MIDI + * event copying: + * + * -Running status: Status bytes can be omitted when the status byte of the + * current MIDI message is the same as the status byte of the last sent + * MIDI message. + * + * -Realtime messages: Realtime messages are given priority over + * non-realtime messages. Realtime bytes are interspersed with + * non-realtime bytes so that realtime messages can be sent as close as + * possible to the time they're scheduled for sending. + * + * -Time optimization: Bytes in non-realtime messages are sent out early + * when possible, with the last byte of the message being sent out as close + * to the specified event time as possible. + * + * Use this queue if the MIDI API you're interfacing with allows you to + * send raw MIDI bytes. + */ + + class SERVER_EXPORT JackMidiRawOutputWriteQueue: + public JackMidiWriteQueue { + + private: + + jack_nframes_t last_enqueued_message_time; + jack_midi_event_t *non_rt_event; + jack_nframes_t non_rt_event_time; + JackMidiAsyncQueue *non_rt_queue; + jack_midi_event_t *rt_event; + jack_nframes_t rt_event_time; + JackMidiAsyncQueue *rt_queue; + jack_midi_data_t running_status; + JackMidiSendQueue *send_queue; + + bool + DequeueNonRealtimeEvent(); + + bool + DequeueRealtimeEvent(); + + bool + SendByte(jack_nframes_t time, jack_midi_data_t byte); + + bool + WriteNonRealtimeEvents(jack_nframes_t boundary_frame); + + bool + WriteRealtimeEvents(jack_nframes_t boundary_frame); + + protected: + + /** + * Override this method to specify what happens when the write queue + * says that a 1-byte event is too large for its buffer. Basically, + * this should never happen. + */ + + virtual void + HandleWriteQueueBug(jack_nframes_t time, jack_midi_data_t byte); + + public: + + using JackMidiWriteQueue::EnqueueEvent; + + /** + * Called to create a new raw write queue. The `send_queue` argument + * is the queue to write raw bytes to. The optional `max_rt_messages` + * argument specifies the number of messages that can be enqueued in + * the internal realtime queue. The optional `max_non_rt_messages` + * argument specifies the number of messages that can be enqueued in + * the internal non-realtime queue. The optional `non_rt_size` + * argument specifies the total number of MIDI bytes that can be put in + * the non-realtime queue. + */ + + JackMidiRawOutputWriteQueue(JackMidiSendQueue *send_queue, + size_t non_rt_size=4096, + size_t max_non_rt_messages=1024, + size_t max_rt_messages=128); + + ~JackMidiRawOutputWriteQueue(); + + EnqueueResult + EnqueueEvent(jack_nframes_t time, size_t size, + jack_midi_data_t *buffer); + + /** + * The `Process()` method should be called each time the + * `EnqueueEvent()` method returns 'OK'. The `Process()` method will + * return the next frame at which an event should be sent. The return + * value from `Process()` depends upon the result of writing bytes to + * the write queue: + * + * -If the return value is '0', then all events that have been enqueued + * in this queue have been sent successfully to the write queue. Don't + * call `Process()` again until another event has been enqueued. + * + * -If the return value is an earlier frame or the current frame, it + * means that the write queue returned 'BUFFER_FULL', 'ERROR', or + * 'EVENT_EARLY' when this queue attempted to send the next byte, and + * that the byte should have already been sent, or is scheduled to be + * sent *now*. `Process()` should be called again when the write queue + * can enqueue events again successfully. How to determine when this + * will happen is left up to the caller. + * + * -If the return value is in the future, then `Process()` should be + * called again at that time, or after another event is enqueued. + */ + + jack_nframes_t + Process(jack_nframes_t boundary_frame); + + }; + +} + +#endif diff --git a/common/JackMidiReadQueue.cpp b/common/JackMidiReadQueue.cpp new file mode 100644 index 00000000..a6869691 --- /dev/null +++ b/common/JackMidiReadQueue.cpp @@ -0,0 +1,27 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "JackMidiReadQueue.h" + +using Jack::JackMidiReadQueue; + +JackMidiReadQueue::~JackMidiReadQueue() +{ + // Empty +} diff --git a/common/JackMidiReadQueue.h b/common/JackMidiReadQueue.h new file mode 100644 index 00000000..0f4ca692 --- /dev/null +++ b/common/JackMidiReadQueue.h @@ -0,0 +1,55 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackMidiReadQueue__ +#define __JackMidiReadQueue__ + +#include "JackMidiPort.h" + +namespace Jack { + + /** + * Interface for objects that MIDI events can be read from. + */ + + class SERVER_EXPORT JackMidiReadQueue { + + public: + + virtual + ~JackMidiReadQueue(); + + /** + * Dequeues an event from the queue. Returns the event, or 0 if no + * events are available for reading. + * + * An event dequeued from the read queue is guaranteed to be valid up + * until another event is dequeued, at which all bets are off. Make + * sure that you handle each event you dequeue before dequeueing the + * next event. + */ + + virtual jack_midi_event_t * + DequeueEvent() = 0; + + }; + +} + +#endif diff --git a/common/JackMidiReceiveQueue.cpp b/common/JackMidiReceiveQueue.cpp new file mode 100644 index 00000000..3eb3573e --- /dev/null +++ b/common/JackMidiReceiveQueue.cpp @@ -0,0 +1,27 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "JackMidiReceiveQueue.h" + +using Jack::JackMidiReceiveQueue; + +JackMidiReceiveQueue::~JackMidiReceiveQueue() +{ + // Empty +} diff --git a/common/JackMidiReceiveQueue.h b/common/JackMidiReceiveQueue.h new file mode 100644 index 00000000..1d19c3c1 --- /dev/null +++ b/common/JackMidiReceiveQueue.h @@ -0,0 +1,42 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackMidiReceiveQueue__ +#define __JackMidiReceiveQueue__ + +#include "JackMidiReadQueue.h" + +namespace Jack { + + /** + * Implemented by MIDI input connections. + */ + + class SERVER_EXPORT JackMidiReceiveQueue: public JackMidiReadQueue { + + public: + + virtual + ~JackMidiReceiveQueue(); + + }; + +} + +#endif diff --git a/common/JackMidiSendQueue.cpp b/common/JackMidiSendQueue.cpp new file mode 100644 index 00000000..ac66d812 --- /dev/null +++ b/common/JackMidiSendQueue.cpp @@ -0,0 +1,34 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "JackMidiSendQueue.h" +#include "JackMidiUtil.h" + +using Jack::JackMidiSendQueue; + +JackMidiSendQueue::~JackMidiSendQueue() +{ + // Empty +} + +jack_nframes_t +JackMidiSendQueue::GetNextScheduleFrame() +{ + return GetCurrentFrame(); +} diff --git a/common/JackMidiSendQueue.h b/common/JackMidiSendQueue.h new file mode 100644 index 00000000..0cb8df44 --- /dev/null +++ b/common/JackMidiSendQueue.h @@ -0,0 +1,52 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackMidiSendQueue__ +#define __JackMidiSendQueue__ + +#include "JackMidiWriteQueue.h" + +namespace Jack { + + /** + * Implemented by MIDI output connections. + */ + + class SERVER_EXPORT JackMidiSendQueue: public JackMidiWriteQueue { + + public: + + using JackMidiWriteQueue::EnqueueEvent; + + virtual + ~JackMidiSendQueue(); + + /** + * Returns the next frame that a MIDI message can be sent at. The + * default method returns the current frame. + */ + + virtual jack_nframes_t + GetNextScheduleFrame(); + + }; + +} + +#endif diff --git a/common/JackMidiUtil.cpp b/common/JackMidiUtil.cpp new file mode 100644 index 00000000..94871ce5 --- /dev/null +++ b/common/JackMidiUtil.cpp @@ -0,0 +1,120 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "JackEngineControl.h" +#include "JackFrameTimer.h" +#include "JackGlobals.h" +#include "JackMidiUtil.h" +#include "JackTime.h" + +jack_midi_data_t +Jack::ApplyRunningStatus(size_t *size, jack_midi_data_t **buffer, + jack_midi_data_t running_status) +{ + + // Stolen and modified from alsa/midi_pack.h + + jack_midi_data_t status = **buffer; + if ((status >= 0x80) && (status < 0xf0)) { + if (status == running_status) { + (*buffer)++; + (*size)--; + } else { + running_status = status; + } + } else if (status < 0xf8) { + running_status = 0; + } + return running_status; +} + +jack_midi_data_t +Jack::ApplyRunningStatus(jack_midi_event_t *event, + jack_midi_data_t running_status) +{ + return ApplyRunningStatus(&(event->size), &(event->buffer), + running_status); +} + +jack_nframes_t +Jack::GetCurrentFrame() +{ + JackEngineControl *control = GetEngineControl(); + JackTimer timer; + control->ReadFrameTime(&timer); + return timer.Time2Frames(GetMicroSeconds(), control->fBufferSize); +} + +jack_nframes_t +Jack::GetFramesFromTime(jack_time_t time) +{ + JackEngineControl* control = GetEngineControl(); + JackTimer timer; + control->ReadFrameTime(&timer); + return timer.Time2Frames(time, control->fBufferSize); +} + +jack_nframes_t +Jack::GetLastFrame() +{ + return GetEngineControl()->fFrameTimer.ReadCurrentState()->CurFrame(); +} + +int +Jack::GetMessageLength(jack_midi_data_t status_byte) +{ + switch (status_byte & 0xf0) { + case 0x80: + case 0x90: + case 0xa0: + case 0xb0: + case 0xe0: + return 3; + case 0xc0: + case 0xd0: + return 2; + case 0xf0: + switch (status_byte) { + case 0xf0: + return 0; + case 0xf1: + case 0xf3: + return 2; + case 0xf2: + return 3; + case 0xf4: + case 0xf5: + case 0xf7: + case 0xfd: + break; + default: + return 1; + } + } + return -1; +} + +jack_time_t +Jack::GetTimeFromFrames(jack_nframes_t frames) +{ + JackEngineControl* control = GetEngineControl(); + JackTimer timer; + control->ReadFrameTime(&timer); + return timer.Frames2Time(frames, control->fBufferSize); +} diff --git a/common/JackMidiUtil.h b/common/JackMidiUtil.h new file mode 100644 index 00000000..52db64c8 --- /dev/null +++ b/common/JackMidiUtil.h @@ -0,0 +1,102 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackMidiUtil__ +#define __JackMidiUtil__ + +#include "JackMidiPort.h" + +namespace Jack { + + /** + * Use this function to optimize MIDI output by omitting unnecessary status + * bytes. This can't be used with all MIDI APIs, so before using this + * function, make sure that your MIDI API doesn't require complete MIDI + * messages to be sent. + * + * To start using this function, call this method with pointers to the + * `size` and `buffer` arguments of the MIDI message you want to send, and + * set the `running_status` argument to '0'. For each subsequent MIDI + * message, call this method with pointers to its `size` and `buffer` + * arguments, and set the `running_status` argument to the return value of + * the previous call to this function. + * + * Note: This function will alter the `size` and `buffer` of your MIDI + * message for each message that can be optimized. + */ + + SERVER_EXPORT jack_midi_data_t + ApplyRunningStatus(size_t *size, jack_midi_data_t **buffer, + jack_midi_data_t running_status=0); + + /** + * A wrapper function for the above `ApplyRunningStatus` function. + */ + + SERVER_EXPORT jack_midi_data_t + ApplyRunningStatus(jack_midi_event_t *event, + jack_midi_data_t running_status); + + /** + * Gets the estimated current time in frames. This function has the same + * functionality as the JACK client API function `jack_frame_time`. + */ + + SERVER_EXPORT jack_nframes_t + GetCurrentFrame(); + + /** + * Gets the estimated frame that will be occurring at the given time. This + * function has the same functionality as the JACK client API function + * `jack_time_to_frames`. + */ + + SERVER_EXPORT jack_nframes_t + GetFramesFromTime(jack_time_t time); + + /** + * Gets the precise time at the start of the current process cycle. This + * function has the same functionality as the JACK client API function + * `jack_last_frame_time`. + */ + + SERVER_EXPORT jack_nframes_t + GetLastFrame(); + + /** + * Returns the expected message length for the status byte. Returns 0 if + * the status byte is a system exclusive status byte, or -1 if the status + * byte is invalid. + */ + + SERVER_EXPORT int + GetMessageLength(jack_midi_data_t status_byte); + + /** + * Gets the estimated time at which the given frame will occur. This + * function has the same functionality as the JACK client API function + * `jack_frames_to_time`. + */ + + SERVER_EXPORT jack_time_t + GetTimeFromFrames(jack_nframes_t frames); + +}; + +#endif diff --git a/common/JackMidiWriteQueue.cpp b/common/JackMidiWriteQueue.cpp new file mode 100644 index 00000000..37fd9067 --- /dev/null +++ b/common/JackMidiWriteQueue.cpp @@ -0,0 +1,27 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "JackMidiWriteQueue.h" + +using Jack::JackMidiWriteQueue; + +JackMidiWriteQueue::~JackMidiWriteQueue() +{ + // Empty +} diff --git a/common/JackMidiWriteQueue.h b/common/JackMidiWriteQueue.h new file mode 100644 index 00000000..8a51bafa --- /dev/null +++ b/common/JackMidiWriteQueue.h @@ -0,0 +1,79 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackMidiWriteQueue__ +#define __JackMidiWriteQueue__ + +#include "JackMidiPort.h" + +namespace Jack { + + /** + * Interface for classes that act as write queues for MIDI messages. Write + * queues are used by processors to transfer data to the next processor. + */ + + class SERVER_EXPORT JackMidiWriteQueue { + + public: + + enum EnqueueResult { + BUFFER_FULL, + BUFFER_TOO_SMALL, + EVENT_EARLY, + ERROR, + OK + }; + + virtual ~JackMidiWriteQueue(); + + /** + * Enqueues a data packet in the write queue of `size` bytes contained + * in `buffer` that will be sent the absolute time specified by `time`. + * This method should not block unless 1.) this write queue represents + * the actual outbound MIDI connection, 2.) the MIDI event is being + * sent *now*, meaning that `time` is less than or equal to *now*, and + * 3.) the method is *not* being called in the process thread. The + * method should return `OK` if the event was enqueued, `BUFFER_FULL` + * if the write queue isn't able to accept the event right now, + * `BUFFER_TOO_SMALL` if this write queue will never be able to accept + * the event because the event is too large, `EVENT_EARLY` if this + * queue cannot schedule events ahead of time, and `ERROR` if an error + * occurs that cannot be specified by another return code. + */ + + virtual EnqueueResult + EnqueueEvent(jack_nframes_t time, size_t size, + jack_midi_data_t *buffer) = 0; + + /** + * A wrapper method for the `EnqueueEvent` method above. + */ + + inline EnqueueResult + EnqueueEvent(jack_midi_event_t *event) + { + return EnqueueEvent(event->time, event->size, event->buffer); + } + + }; + +} + +#endif diff --git a/common/JackPhysicalMidiInput.cpp b/common/JackPhysicalMidiInput.cpp deleted file mode 100644 index 311dad0b..00000000 --- a/common/JackPhysicalMidiInput.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* -Copyright (C) 2009 Devin Anderson - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 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 -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include -#include -#include - -#include "JackError.h" -#include "JackPhysicalMidiInput.h" - -namespace Jack { - -JackPhysicalMidiInput::JackPhysicalMidiInput(size_t buffer_size) -{ - size_t datum_size = sizeof(jack_midi_data_t); - assert(buffer_size > 0); - input_ring = jack_ringbuffer_create((buffer_size + 1) * datum_size); - if (! input_ring) { - throw std::bad_alloc(); - } - jack_ringbuffer_mlock(input_ring); - Clear(); - expected_data_bytes = 0; - status_byte = 0; -} - -JackPhysicalMidiInput::~JackPhysicalMidiInput() -{ - jack_ringbuffer_free(input_ring); -} - -void -JackPhysicalMidiInput::Clear() -{ - jack_ringbuffer_reset(input_ring); - buffered_bytes = 0; - unbuffered_bytes = 0; -} - -void -JackPhysicalMidiInput::HandleBufferFailure(size_t unbuffered_bytes, - size_t total_bytes) -{ - jack_error("%d MIDI byte(s) of a %d byte message could not be buffered - " - "message dropped", unbuffered_bytes, total_bytes); -} - -void -JackPhysicalMidiInput::HandleIncompleteMessage(size_t bytes) -{ - jack_error("Discarding %d MIDI byte(s) - incomplete message (cable " - "unplugged?)", bytes); -} - -void -JackPhysicalMidiInput::HandleInvalidStatusByte(jack_midi_data_t status) -{ - jack_error("Dropping invalid MIDI status byte '%x'", - (unsigned int) status); -} - -void -JackPhysicalMidiInput::HandleUnexpectedSysexEnd(size_t bytes) -{ - jack_error("Discarding %d MIDI byte(s) - received sysex end without sysex " - "start (cable unplugged?)", bytes); -} - -void -JackPhysicalMidiInput::HandleWriteFailure(size_t bytes) -{ - jack_error("Failed to write a %d byte MIDI message to the port buffer", - bytes); -} - -void -JackPhysicalMidiInput::Process(jack_nframes_t frames) -{ - assert(port_buffer); - port_buffer->Reset(frames); - jack_nframes_t current_frame = 0; - size_t datum_size = sizeof(jack_midi_data_t); - for (;;) { - jack_midi_data_t datum; - current_frame = Receive(&datum, current_frame, frames); - if (current_frame >= frames) { - break; - } - - jack_log("JackPhysicalMidiInput::Process (%d) - Received '%x' byte", - current_frame, (unsigned int) datum); - - if (datum >= 0xf8) { - // Realtime - if (datum == 0xfd) { - HandleInvalidStatusByte(datum); - } else { - - jack_log("JackPhysicalMidiInput::Process - Writing realtime " - "event."); - - WriteByteEvent(current_frame, datum); - } - continue; - } - if (datum == 0xf7) { - // Sysex end - if (status_byte != 0xf0) { - HandleUnexpectedSysexEnd(buffered_bytes + unbuffered_bytes); - Clear(); - expected_data_bytes = 0; - status_byte = 0; - } else { - - jack_log("JackPhysicalMidiInput::Process - Writing sysex " - "event."); - - WriteBufferedSysexEvent(current_frame); - } - continue; - } - if (datum >= 0x80) { - - // We're handling a non-realtime status byte - - jack_log("JackPhysicalMidiInput::Process - Handling non-realtime " - "status byte."); - - if (buffered_bytes || unbuffered_bytes) { - HandleIncompleteMessage(buffered_bytes + unbuffered_bytes + 1); - Clear(); - } - status_byte = datum; - switch (datum & 0xf0) { - case 0x80: - case 0x90: - case 0xa0: - case 0xb0: - case 0xe0: - // Note On, Note Off, Aftertouch, Control Change, Pitch Wheel - expected_data_bytes = 2; - break; - case 0xc0: - case 0xd0: - // Program Change, Channel Pressure - expected_data_bytes = 1; - break; - case 0xf0: - switch (datum) { - case 0xf0: - // Sysex message - expected_data_bytes = 0; - break; - case 0xf1: - case 0xf3: - // MTC Quarter frame, Song Select - expected_data_bytes = 1; - break; - case 0xf2: - // Song Position - expected_data_bytes = 2; - break; - case 0xf4: - case 0xf5: - // Undefined - HandleInvalidStatusByte(datum); - expected_data_bytes = 0; - status_byte = 0; - break; - case 0xf6: - // Tune Request - WriteByteEvent(current_frame, datum); - expected_data_bytes = 0; - status_byte = 0; - } - break; - } - continue; - } - - // We're handling a data byte - - jack_log("JackPhysicalMidiInput::Process - Buffering data byte."); - - if (jack_ringbuffer_write(input_ring, (const char *) &datum, - datum_size) == datum_size) { - buffered_bytes++; - } else { - unbuffered_bytes++; - } - unsigned long total_bytes = buffered_bytes + unbuffered_bytes; - assert((! expected_data_bytes) || - (total_bytes <= expected_data_bytes)); - if (total_bytes == expected_data_bytes) { - if (! unbuffered_bytes) { - - jack_log("JackPhysicalMidiInput::Process - Writing buffered " - "event."); - - WriteBufferedEvent(current_frame); - } else { - HandleBufferFailure(unbuffered_bytes, total_bytes); - Clear(); - } - if (status_byte >= 0xf0) { - expected_data_bytes = 0; - status_byte = 0; - } - } - } -} - -void -JackPhysicalMidiInput::WriteBufferedEvent(jack_nframes_t frame) -{ - assert(port_buffer && port_buffer->IsValid()); - size_t space = jack_ringbuffer_read_space(input_ring); - jack_midi_data_t *event = port_buffer->ReserveEvent(frame, space + 1); - if (event) { - jack_ringbuffer_data_t vector[2]; - jack_ringbuffer_get_read_vector(input_ring, vector); - event[0] = status_byte; - size_t data_length_1 = vector[0].len; - memcpy(event + 1, vector[0].buf, data_length_1); - size_t data_length_2 = vector[1].len; - if (data_length_2) { - memcpy(event + data_length_1 + 1, vector[1].buf, data_length_2); - } - } else { - HandleWriteFailure(space + 1); - } - Clear(); -} - -void -JackPhysicalMidiInput::WriteBufferedSysexEvent(jack_nframes_t frame) -{ - assert(port_buffer && port_buffer->IsValid()); - size_t space = jack_ringbuffer_read_space(input_ring); - jack_midi_data_t *event = port_buffer->ReserveEvent(frame, space + 2); - if (event) { - jack_ringbuffer_data_t vector[2]; - jack_ringbuffer_get_read_vector(input_ring, vector); - event[0] = status_byte; - size_t data_length_1 = vector[0].len; - memcpy(event + 1, vector[0].buf, data_length_1); - size_t data_length_2 = vector[1].len; - if (data_length_2) { - memcpy(event + data_length_1 + 1, vector[1].buf, data_length_2); - } - event[data_length_1 + data_length_2 + 1] = 0xf7; - } else { - HandleWriteFailure(space + 2); - } - Clear(); -} - -void -JackPhysicalMidiInput::WriteByteEvent(jack_nframes_t frame, - jack_midi_data_t datum) -{ - assert(port_buffer && port_buffer->IsValid()); - jack_midi_data_t *event = port_buffer->ReserveEvent(frame, 1); - if (event) { - event[0] = datum; - } else { - HandleWriteFailure(1); - } -} - -} diff --git a/common/JackPhysicalMidiInput.h b/common/JackPhysicalMidiInput.h deleted file mode 100644 index a05de6d0..00000000 --- a/common/JackPhysicalMidiInput.h +++ /dev/null @@ -1,146 +0,0 @@ -/* -Copyright (C) 2009 Devin Anderson - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 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 -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#ifndef __JackPhysicalMidiInput__ -#define __JackPhysicalMidiInput__ - -#include "JackMidiPort.h" -#include "ringbuffer.h" - -namespace Jack { - - class JackPhysicalMidiInput { - - private: - - size_t buffered_bytes; - size_t expected_data_bytes; - jack_ringbuffer_t *input_ring; - JackMidiBuffer *port_buffer; - jack_midi_data_t status_byte; - size_t unbuffered_bytes; - - void - Clear(); - - void - WriteBufferedEvent(jack_nframes_t); - - void - WriteBufferedSysexEvent(jack_nframes_t); - - void - WriteByteEvent(jack_nframes_t, jack_midi_data_t); - - protected: - - /** - * Override to specify how to react when 1 or more bytes of a MIDI - * message are lost because there wasn't enough room in the input - * buffer. The first argument is the amount of bytes that couldn't be - * buffered, and the second argument is the total amount of bytes in - * the MIDI message. The default implementation calls 'jack_error' - * with a basic error message. - */ - - virtual void - HandleBufferFailure(size_t, size_t); - - /** - * Override to specify how to react when a new status byte is received - * before all of the data bytes in a message are received. The - * argument is the number of bytes being discarded. The default - * implementation calls 'jack_error' with a basic error message. - */ - - virtual void - HandleIncompleteMessage(size_t); - - /** - * Override to specify how to react when an invalid status byte (0xf4, - * 0xf5, 0xfd) is received. The argument contains the invalid status - * byte. The default implementation calls 'jack_error' with a basic - * error message. - */ - - virtual void - HandleInvalidStatusByte(jack_midi_data_t); - - /** - * Override to specify how to react when a sysex end byte (0xf7) is - * received without first receiving a sysex start byte (0xf0). The - * argument contains the amount of bytes that will be discarded. The - * default implementation calls 'jack_error' with a basic error - * message. - */ - - virtual void - HandleUnexpectedSysexEnd(size_t); - - /** - * Override to specify how to react when a MIDI message can not be - * written to the port buffer. The argument specifies the length of - * the MIDI message. The default implementation calls 'jack_error' - * with a basic error message. - */ - - virtual void - HandleWriteFailure(size_t); - - /** - * This method *must* be overridden to handle receiving MIDI bytes. - * The first argument is a pointer to the memory location at which the - * MIDI byte should be stored. The second argument is the last frame - * at which a MIDI byte was received, except at the beginning of the - * period when the value is 0. The third argument is the total number - * of frames in the period. The return value is the frame at which the - * MIDI byte is received at, or the value of the third argument is no - * more MIDI bytes can be received in this period. - */ - - virtual jack_nframes_t - Receive(jack_midi_data_t *, jack_nframes_t, jack_nframes_t) = 0; - - public: - - JackPhysicalMidiInput(size_t buffer_size=1024); - virtual ~JackPhysicalMidiInput(); - - /** - * Called to process MIDI data during a period. - */ - - void - Process(jack_nframes_t); - - /** - * Set the MIDI buffer that will receive incoming messages. - */ - - inline void - SetPortBuffer(JackMidiBuffer *port_buffer) - { - this->port_buffer = port_buffer; - } - - }; - -} - -#endif diff --git a/common/JackPhysicalMidiOutput.cpp b/common/JackPhysicalMidiOutput.cpp deleted file mode 100644 index 8f41d443..00000000 --- a/common/JackPhysicalMidiOutput.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/* -Copyright (C) 2009 Devin Anderson - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 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 -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include - -#include "JackError.h" -#include "JackPhysicalMidiOutput.h" - -namespace Jack { - -JackPhysicalMidiOutput::JackPhysicalMidiOutput(size_t non_rt_buffer_size, - size_t rt_buffer_size) -{ - size_t datum_size = sizeof(jack_midi_data_t); - assert(non_rt_buffer_size > 0); - assert(rt_buffer_size > 0); - output_ring = jack_ringbuffer_create((non_rt_buffer_size + 1) * - datum_size); - if (! output_ring) { - throw std::bad_alloc(); - } - rt_output_ring = jack_ringbuffer_create((rt_buffer_size + 1) * - datum_size); - if (! rt_output_ring) { - jack_ringbuffer_free(output_ring); - throw std::bad_alloc(); - } - jack_ringbuffer_mlock(output_ring); - jack_ringbuffer_mlock(rt_output_ring); - running_status = 0; -} - -JackPhysicalMidiOutput::~JackPhysicalMidiOutput() -{ - jack_ringbuffer_free(output_ring); - jack_ringbuffer_free(rt_output_ring); -} - -jack_nframes_t -JackPhysicalMidiOutput::Advance(jack_nframes_t frame) -{ - return frame; -} - -inline jack_midi_data_t -JackPhysicalMidiOutput::ApplyRunningStatus(jack_midi_data_t **buffer, - size_t *size) -{ - - // Stolen and modified from alsa/midi_pack.h - - jack_midi_data_t status = (*buffer)[0]; - if ((status >= 0x80) && (status < 0xf0)) { - if (status == running_status) { - (*buffer)++; - (*size)--; - } else { - running_status = status; - } - } else if (status < 0xf8) { - running_status = 0; - } - return status; -} - -void -JackPhysicalMidiOutput::HandleEventLoss(JackMidiEvent *event) -{ - jack_error("%d byte MIDI event lost", event->size); -} - -void -JackPhysicalMidiOutput::Process(jack_nframes_t frames) -{ - assert(port_buffer); - jack_nframes_t current_frame = Advance(0); - jack_nframes_t current_midi_event = 0; - jack_midi_data_t datum; - size_t datum_size = sizeof(jack_midi_data_t); - JackMidiEvent *midi_event; - jack_midi_data_t *midi_event_buffer; - size_t midi_event_size; - jack_nframes_t midi_events = port_buffer->event_count; - - // First, send any realtime MIDI data that's left from last cycle. - - if ((current_frame < frames) && - jack_ringbuffer_read_space(rt_output_ring)) { - - jack_log("JackPhysicalMidiOutput::Process (%d) - Sending buffered " - "realtime data from last period.", current_frame); - - current_frame = SendBufferedData(rt_output_ring, current_frame, - frames); - - jack_log("JackPhysicalMidiOutput::Process (%d) - Sent", current_frame); - - } - - // Iterate through the events in this cycle. - - for (; (current_midi_event < midi_events) && (current_frame < frames); - current_midi_event++) { - - // Once we're inside this loop, we know that the realtime buffer - // is empty. As long as we don't find a realtime message, we can - // concentrate on sending non-realtime data. - - midi_event = &(port_buffer->events[current_midi_event]); - jack_nframes_t midi_event_time = midi_event->time; - midi_event_buffer = midi_event->GetData(port_buffer); - midi_event_size = midi_event->size; - datum = ApplyRunningStatus(&midi_event_buffer, &midi_event_size); - if (current_frame < midi_event_time) { - - // We have time before this event is scheduled to be sent. - // Send data in the non-realtime buffer. - - if (jack_ringbuffer_read_space(output_ring)) { - - jack_log("JackPhysicalMidiOutput::Process (%d) - Sending " - "buffered non-realtime data from last period.", - current_frame); - - current_frame = SendBufferedData(output_ring, current_frame, - midi_event_time); - - jack_log("JackPhysicalMidiOutput::Process (%d) - Sent", - current_frame); - - } - if (current_frame < midi_event_time) { - - // We _still_ have time before this event is scheduled to - // be sent. Let's send as much of this event as we can - // (save for one byte, which will need to be sent at or - // after its scheduled time). First though, we need to - // make sure that we can buffer this data if we need to. - // Otherwise, we might start sending a message that we - // can't finish. - - if (midi_event_size > 1) { - if (jack_ringbuffer_write_space(output_ring) < - ((midi_event_size - 1) * datum_size)) { - HandleEventLoss(midi_event); - continue; - } - - // Send as much of the event as possible (save for one - // byte). - - do { - - jack_log("JackPhysicalMidiOutput::Process (%d) - " - "Sending unbuffered event byte early.", - current_frame); - - current_frame = Send(current_frame, - *midi_event_buffer); - - jack_log("JackPhysicalMidiOutput::Process (%d) - " - "Sent.", current_frame); - - midi_event_buffer++; - midi_event_size--; - if (current_frame >= midi_event_time) { - - // The event we're processing must be a - // non-realtime event. It has more than one - // byte. - - goto buffer_non_realtime_data; - } - } while (midi_event_size > 1); - } - - jack_log("JackPhysicalMidiOutput::Process (%d) - Advancing to " - ">= %d", current_frame, midi_event_time); - - current_frame = Advance(midi_event_time); - - jack_log("JackPhysicalMidiOutput::Process (%d) - Advanced.", - current_frame); - - } - } - - // If the event is realtime, then we'll send the event now. - // Otherwise, we attempt to put the rest of the event bytes in the - // non-realtime buffer. - - if (datum >= 0xf8) { - - jack_log("JackPhysicalMidiOutput::Process (%d) - Sending " - "unbuffered realtime event.", current_frame); - - current_frame = Send(current_frame, datum); - - jack_log("JackPhysicalMidiOutput::Process (%d) - Sent.", - current_frame); - - } else if (jack_ringbuffer_write_space(output_ring) >= - (midi_event_size * datum_size)) { - buffer_non_realtime_data: - - jack_log("JackPhysicalMidiOutput::Process (%d) - Buffering %d " - "byte(s) of non-realtime data.", current_frame, - midi_event_size); - - jack_ringbuffer_write(output_ring, - (const char *) midi_event_buffer, - midi_event_size); - } else { - HandleEventLoss(midi_event); - } - } - - if (current_frame < frames) { - - // If we have time left to send data, then we know that all of the - // data in the realtime buffer has been sent, and that all of the - // non-realtime messages have either been sent, or buffered. We - // use whatever time is left to send data in the non-realtime - // buffer. - - if (jack_ringbuffer_read_space(output_ring)) { - - jack_log("JackPhysicalMidiOutput::Process (%d) - All events " - "processed. Sending buffered non-realtime data.", - current_frame); - - current_frame = SendBufferedData(output_ring, current_frame, - frames); - - jack_log("JackPhysicalMidiOutput::Process (%d) - Sent.", - current_frame); - - } - } else { - - // Since we have no time left, we need to put all remaining midi - // events in their appropriate buffers, and send them next period. - - for (; current_midi_event < midi_events; current_midi_event++) { - midi_event = &(port_buffer->events[current_midi_event]); - midi_event_buffer = midi_event->GetData(port_buffer); - midi_event_size = midi_event->size; - datum = ApplyRunningStatus(&midi_event_buffer, &midi_event_size); - if (datum >= 0xf8) { - - // Realtime. - - if (jack_ringbuffer_write_space(rt_output_ring) >= - datum_size) { - - jack_log("JackPhysicalMidiOutput::Process - Buffering " - "realtime event for next period."); - - jack_ringbuffer_write(rt_output_ring, - (const char *) &datum, datum_size); - continue; - } - } else { - - // Non-realtime. - - if (jack_ringbuffer_write_space(output_ring) >= - (midi_event_size * datum_size)) { - - jack_log("JackPhysicalMidiOutput::Process - Buffering " - "non-realtime event for next period."); - - jack_ringbuffer_write(output_ring, - (const char *) midi_event_buffer, - midi_event_size * datum_size); - continue; - } - } - HandleEventLoss(midi_event); - } - } -} - -jack_nframes_t -JackPhysicalMidiOutput::SendBufferedData(jack_ringbuffer_t *buffer, - jack_nframes_t current_frame, - jack_nframes_t boundary) -{ - assert(buffer); - assert(current_frame < boundary); - size_t datum_size = sizeof(jack_midi_data_t); - size_t data_length = jack_ringbuffer_read_space(buffer) / datum_size; - for (size_t i = 0; i < data_length; i++) { - jack_midi_data_t datum; - jack_ringbuffer_read(buffer, (char *) &datum, datum_size); - current_frame = Send(current_frame, datum); - if (current_frame >= boundary) { - break; - } - } - return current_frame; -} - -} diff --git a/common/JackPhysicalMidiOutput.h b/common/JackPhysicalMidiOutput.h deleted file mode 100644 index 9b4804b7..00000000 --- a/common/JackPhysicalMidiOutput.h +++ /dev/null @@ -1,118 +0,0 @@ -/* -Copyright (C) 2009 Devin Anderson - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 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 -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#ifndef __JackPhysicalMidiOutput__ -#define __JackPhysicalMidiOutput__ - -#include "JackMidiPort.h" -#include "ringbuffer.h" - -namespace Jack { - - class JackPhysicalMidiOutput { - - private: - - jack_midi_data_t - ApplyRunningStatus(jack_midi_data_t **, size_t *); - - jack_ringbuffer_t *output_ring; - JackMidiBuffer *port_buffer; - jack_ringbuffer_t *rt_output_ring; - jack_midi_data_t running_status; - - protected: - - /** - * Override to specify the next frame at which a midi byte can be sent. - * The returned frame must be greater than or equal to the frame - * argument. The default returns the frame passed to it. - */ - - virtual jack_nframes_t - Advance(jack_nframes_t); - - /** - * Override to customize how to react when a MIDI event can't be - * buffered and can't be sent immediately. The default calls - * 'jack_error' and specifies the number of bytes lost. - */ - - virtual void - HandleEventLoss(JackMidiEvent *); - - /** - * This method *must* be overridden to specify what happens when a MIDI - * byte is sent at the specfied frame. The frame argument specifies - * the frame at which the MIDI byte should be sent, and the second - * argument specifies the byte itself. The return value is the next - * frame at which a MIDI byte can be sent, and must be greater than or - * equal to the frame argument. - */ - - virtual jack_nframes_t - Send(jack_nframes_t, jack_midi_data_t) = 0; - - /** - * Override to optimize behavior when sending MIDI data that's in the - * ringbuffer. The first frame argument is the current frame, and the - * second frame argument is the boundary frame. The function returns - * the next frame at which MIDI data can be sent, regardless of whether - * or not the boundary is reached. The default implementation calls - * 'Send' with each byte in the ringbuffer until either the ringbuffer - * is empty, or a frame beyond the boundary frame is returned by - * 'Send'. - */ - - virtual jack_nframes_t - SendBufferedData(jack_ringbuffer_t *, jack_nframes_t, jack_nframes_t); - - public: - - /** - * The non-realtime buffer size and the realtime buffer size are both - * optional arguments. - */ - - JackPhysicalMidiOutput(size_t non_rt_buffer_size=1024, - size_t rt_buffer_size=64); - virtual ~JackPhysicalMidiOutput(); - - /** - * Called to process MIDI data during a period. - */ - - void - Process(jack_nframes_t); - - /** - * Set the MIDI buffer that will contain the outgoing MIDI messages. - */ - - inline void - SetPortBuffer(JackMidiBuffer *port_buffer) - { - this->port_buffer = port_buffer; - } - - }; - -} - -#endif diff --git a/common/wscript b/common/wscript index 31542b17..8b10f1b7 100644 --- a/common/wscript +++ b/common/wscript @@ -130,8 +130,21 @@ def build(bld): 'JackNetTool.cpp', 'JackNetInterface.cpp', 'JackArgParser.cpp', - 'JackPhysicalMidiInput.cpp', - 'JackPhysicalMidiOutput.cpp', + + #'JackPhysicalMidiInput.cpp', + #'JackPhysicalMidiOutput.cpp', + + 'JackMidiAsyncQueue.cpp', + 'JackMidiAsyncWaitQueue.cpp', + 'JackMidiBufferReadQueue.cpp', + 'JackMidiBufferWriteQueue.cpp', + 'JackMidiRawInputWriteQueue.cpp', + 'JackMidiRawOutputWriteQueue.cpp', + 'JackMidiReadQueue.cpp', + 'JackMidiReceiveQueue.cpp', + 'JackMidiSendQueue.cpp', + 'JackMidiUtil.cpp', + 'JackMidiWriteQueue.cpp' ] if bld.env['IS_LINUX']: diff --git a/example-clients/midi_latency_test.c b/example-clients/midi_latency_test.c new file mode 100644 index 00000000..2d9e1686 --- /dev/null +++ b/example-clients/midi_latency_test.c @@ -0,0 +1,588 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +/* + * This program is used to measure MIDI latency and jitter. It writes MIDI + * messages to one port and calculates how long it takes before it reads the + * same MIDI message over another port. It was written to calculate the + * latency and jitter of hardware and JACK hardware drivers, but might have + * other practical applications. + * + * The latency results of the program include the latency introduced by the + * JACK system. Because JACK has sample accurate MIDI, the same latency + * imposed on audio is also imposed on MIDI going through the system. Make + * sure you take this into account before complaining to me or (*especially*) + * other JACK developers about reported MIDI latency. + * + * The jitter results are a little more interesting. The program attempts to + * calculate 'average jitter' and 'peak jitter', as defined here: + * + * http://openmuse.org/transport/fidelity.html + * + * It also outputs a jitter plot, which gives you a more specific idea about + * the MIDI jitter for the ports you're testing. This is useful for catching + * extreme jitter values, and for analyzing the amount of truth in the + * technical specifications for your MIDI interface(s). :) + * + * This program is loosely based on 'alsa-midi-latency-test' in the ALSA test + * suite. + * + * To port this program to non-POSIX platforms, you'll have to include + * implementations for mutexes, semaphores, and command-line argument handling. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#define ABS(x) (((x) >= 0) ? (x) : (-(x))) + +const char *ERROR_UNEXPECTED = "in port received unexpected MIDI message"; +const char *ERROR_UNEXPECTED_EXTRA = "received more than one MIDI message"; +const char *ERROR_RESERVE = "could not reserve MIDI event on port buffer"; +const char *ERROR_TIMEOUT = "timed out while waiting for MIDI message"; +const char *SOURCE_EVENT_RESERVE = "jack_midi_event_reserve"; +const char *SOURCE_PROCESS = "handle_process"; +const char *SOURCE_TRYLOCK = "pthread_mutex_trylock"; +const char *SOURCE_UNLOCK = "pthread_mutex_unlock"; + +jack_client_t *client; +const char *error_message; +const char *error_source; +jack_nframes_t highest_latency; +jack_time_t highest_latency_time; +jack_latency_range_t in_latency_range; +jack_port_t *in_port; +jack_nframes_t last_activity; +jack_time_t last_activity_time; +jack_time_t *latency_time_values; +jack_nframes_t *latency_values; +jack_nframes_t lowest_latency; +jack_time_t lowest_latency_time; +jack_midi_data_t *message_1; +jack_midi_data_t *message_2; +size_t messages_processed; +size_t message_size; +jack_latency_range_t out_latency_range; +jack_port_t *out_port; +int process_state; +char *program_name; +jack_port_t *remote_in_port; +jack_port_t *remote_out_port; +size_t samples; +sem_t semaphore; +pthread_mutex_t start_mutex; +int timeout; +jack_nframes_t total_latency; +jack_time_t total_latency_time; +size_t unexpected_messages; + +static void +output_error(const char *source, const char *message); + +static void +output_usage(); + +static void +set_process_error(const char *source, const char *message); + +static void +die(char *source, char *error_message) +{ + output_error(source, error_message); + output_usage(); + exit(EXIT_FAILURE); +} + +static void +handle_info(const char *message) +{ + /* Suppress info */ +} + +static int +handle_process(jack_nframes_t frames, void *arg) +{ + jack_midi_data_t *buffer; + int code; + jack_midi_event_t event; + jack_nframes_t event_count; + jack_nframes_t event_time; + jack_nframes_t frame; + size_t i; + jack_nframes_t last_frame_time; + jack_midi_data_t *message; + void *port_buffer; + jack_time_t time; + switch (process_state) { + + case 0: + /* State: initializing */ + code = pthread_mutex_trylock(&start_mutex); + if (code) { + if (code != EBUSY) { + set_process_error(SOURCE_TRYLOCK, strerror(code)); + } + break; + } + code = pthread_mutex_unlock(&start_mutex); + if (code) { + set_process_error(SOURCE_UNLOCK, strerror(code)); + break; + } + highest_latency = 0; + lowest_latency = 0; + messages_processed = 0; + process_state = 1; + total_latency = 0; + total_latency_time = 0; + unexpected_messages = 0; + jack_port_get_latency_range(remote_in_port, JackCaptureLatency, + &in_latency_range); + jack_port_get_latency_range(remote_out_port, JackPlaybackLatency, + &out_latency_range); + goto send_message; + + case 1: + /* State: processing */ + jack_midi_clear_buffer(jack_port_get_buffer(out_port, frames)); + port_buffer = jack_port_get_buffer(in_port, frames); + event_count = jack_midi_get_event_count(port_buffer); + last_frame_time = jack_last_frame_time(client); + for (i = 0; i < event_count; i++) { + jack_midi_event_get(&event, port_buffer, i); + message = (messages_processed % 2) ? message_2 : message_1; + if ((event.size == message_size) && + (! memcmp(message, event.buffer, + message_size * sizeof(jack_midi_data_t)))) { + goto found_message; + } + unexpected_messages++; + } + jack_time_t microseconds = + jack_frames_to_time(client, last_frame_time) - last_activity_time; + if ((microseconds / 1000000) >= timeout) { + set_process_error(SOURCE_PROCESS, ERROR_TIMEOUT); + } + break; + found_message: + event_time = last_frame_time + event.time; + frame = event_time - last_activity; + time = jack_frames_to_time(client, event_time) - last_activity_time; + if ((! highest_latency) || (frame > highest_latency)) { + highest_latency = frame; + highest_latency_time = time; + } + if ((! lowest_latency) || (frame < lowest_latency)) { + lowest_latency = frame; + lowest_latency_time = time; + } + latency_time_values[messages_processed] = time; + latency_values[messages_processed] = frame; + total_latency += frame; + total_latency_time += time; + messages_processed++; + if (messages_processed == samples) { + process_state = 2; + sem_post(&semaphore); + break; + } + send_message: + frame = (jack_nframes_t) ((((double) rand()) / RAND_MAX) * frames); + if (frame == frames) { + frame--; + } + port_buffer = jack_port_get_buffer(out_port, frames); + jack_midi_clear_buffer(port_buffer); + buffer = jack_midi_event_reserve(port_buffer, frame, message_size); + if (buffer == NULL) { + set_process_error(SOURCE_EVENT_RESERVE, ERROR_RESERVE); + break; + } + message = (messages_processed % 2) ? message_2 : message_1; + memcpy(buffer, message, message_size * sizeof(jack_midi_data_t)); + last_activity = jack_last_frame_time(client) + frame; + last_activity_time = jack_frames_to_time(client, last_activity); + + case 2: + /* State: finished - do nothing */ + + case -1: + /* State: error - do nothing */ + ; + + } + return 0; +} + +static void +handle_shutdown(void *arg) +{ + set_process_error("handle_shutdown", "The JACK server has been shutdown"); +} + +static void +output_error(const char *source, const char *message) +{ + fprintf(stderr, "%s: %s: %s\n", program_name, source, message); +} + +static void +output_usage() +{ + fprintf(stderr, "Usage: %s [options] out-port-name in-port-name\n\n" + "\t-h, --help print program usage\n" + "\t-m, --message-size=size set size of MIDI messages to send\n" + "\t-s, --samples=n number of MIDI messages to send\n" + "\t-t, --timeout=seconds wait time before giving up on message\n" + "\n", program_name); +} + +static unsigned long +parse_positive_number_arg(char *s, char *name) +{ + char *end_ptr; + unsigned long result; + errno = 0; + result = strtoul(s, &end_ptr, 10); + if (errno) { + die(name, strerror(errno)); + } + if (*s == '\0') { + die(name, "argument value cannot be empty"); + } + if (*end_ptr != '\0') { + die(name, "invalid value"); + } + if (! result) { + die(name, "must be a positive number"); + } + return result; +} + +static void +set_process_error(const char *source, const char *message) +{ + error_source = source; + error_message = message; + process_state = -1; + sem_post(&semaphore); +} + +int +main(int argc, char **argv) +{ + int code; + size_t jitter_plot[101]; + int long_index = 0; + struct option long_options[] = { + {"help", 0, NULL, 'h'}, + {"message-size", 1, NULL, 'm'}, + {"samples", 1, NULL, 's'}, + {"timeout", 1, NULL, 't'} + }; + char *option_string = "hm:s:t:"; + int show_usage = 0; + error_message = NULL; + message_size = 3; + program_name = argv[0]; + samples = 1024; + timeout = 5; + for (;;) { + char c = getopt_long(argc, argv, option_string, long_options, + &long_index); + switch (c) { + case 'h': + show_usage = 1; + break; + case 'm': + message_size = parse_positive_number_arg(optarg, "message-size"); + break; + case 's': + samples = parse_positive_number_arg(optarg, "samples"); + break; + case 't': + timeout = parse_positive_number_arg(optarg, "timeout"); + break; + default: + { + char *s = "'- '"; + s[2] = c; + die(s, "invalid switch"); + } + case -1: + if (show_usage) { + output_usage(); + exit(EXIT_SUCCESS); + } + goto parse_port_names; + case 1: + /* end of switch :) */ + ; + } + } + parse_port_names: + if ((argc - optind) != 2) { + output_usage(); + return EXIT_FAILURE; + } + latency_values = malloc(sizeof(jack_nframes_t) * samples); + if (latency_values == NULL) { + error_message = strerror(errno); + error_source = "malloc"; + goto show_error; + } + latency_time_values = malloc(sizeof(jack_time_t) * samples); + if (latency_time_values == NULL) { + error_message = strerror(errno); + error_source = "malloc"; + goto free_latency_values; + } + message_1 = malloc(message_size * sizeof(jack_midi_data_t)); + if (message_1 == NULL) { + error_message = strerror(errno); + error_source = "malloc"; + goto free_latency_time_values; + } + message_2 = malloc(message_size * sizeof(jack_midi_data_t)); + if (message_2 == NULL) { + error_message = strerror(errno); + error_source = "malloc"; + goto free_message_1; + } + switch (message_size) { + case 1: + message_1[0] = 0xf6; + message_2[0] = 0xf8; + break; + case 2: + message_1[0] = 0xc0; + message_1[1] = 0x00; + message_2[0] = 0xd0; + message_2[1] = 0x7f; + break; + case 3: + message_1[0] = 0x80; + message_1[1] = 0x00; + message_1[2] = 0x00; + message_2[0] = 0x90; + message_2[1] = 0x7f; + message_2[2] = 0x7f; + break; + default: + message_1[0] = 0xf0; + memset(message_1 + 1, 0, + (message_size - 2) * sizeof(jack_midi_data_t)); + message_1[message_size - 1] = 0xf7; + message_2[0] = 0xf0; + memset(message_2 + 1, 0x7f, + (message_size - 2) * sizeof(jack_midi_data_t)); + message_2[message_size - 1] = 0xf7; + } + client = jack_client_open(program_name, JackNullOption, NULL); + if (client == NULL) { + error_message = "failed to open JACK client"; + error_source = "jack_client_open"; + goto free_message_2; + } + remote_in_port = jack_port_by_name(client, argv[optind + 1]); + if (remote_in_port == NULL) { + error_message = "invalid port name"; + error_source = argv[optind + 1]; + goto close_client; + } + remote_out_port = jack_port_by_name(client, argv[optind]); + if (remote_out_port == NULL) { + error_message = "invalid port name"; + error_source = argv[optind]; + goto close_client; + } + in_port = jack_port_register(client, "in", JACK_DEFAULT_MIDI_TYPE, + JackPortIsInput, 0); + if (in_port == NULL) { + error_message = "failed to register MIDI-in port"; + error_source = "jack_port_register"; + goto close_client; + } + out_port = jack_port_register(client, "out", JACK_DEFAULT_MIDI_TYPE, + JackPortIsOutput, 0); + if (out_port == NULL) { + error_message = "failed to register MIDI-out port"; + error_source = "jack_port_register"; + goto unregister_in_port; + } + if (jack_set_process_callback(client, handle_process, NULL)) { + error_message = "failed to set process callback"; + error_source = "jack_set_process_callback"; + goto unregister_out_port; + } + jack_on_shutdown(client, handle_shutdown, NULL); + jack_set_info_function(handle_info); + process_state = 0; + if (sem_init(&semaphore, 0, 0)) { + error_message = strerror(errno); + error_source = "sem_init"; + goto unregister_out_port; + } + code = pthread_mutex_init(&start_mutex, NULL); + if (code) { + error_message = strerror(errno); + error_source = "pthread_mutex_init"; + goto destroy_semaphore; + } + code = pthread_mutex_trylock(&start_mutex); + if (code) { + error_message = strerror(code); + error_source = "pthread_mutex_trylock"; + goto destroy_mutex; + } + if (jack_activate(client)) { + error_message = "could not activate client"; + error_source = "jack_activate"; + goto destroy_mutex; + } + if (jack_connect(client, jack_port_name(out_port), + jack_port_name(remote_out_port))) { + error_message = "could not connect MIDI out port"; + error_source = "jack_connect"; + goto deactivate_client; + } + if (jack_connect(client, jack_port_name(remote_in_port), + jack_port_name(in_port))) { + error_message = "could not connect MIDI in port"; + error_source = "jack_connect"; + goto deactivate_client; + } + jack_port_get_latency_range(remote_in_port, JackCaptureLatency, + &in_latency_range); + jack_port_get_latency_range(remote_out_port, JackPlaybackLatency, + &out_latency_range); + code = pthread_mutex_unlock(&start_mutex); + if (code) { + error_message = strerror(code); + error_source = "pthread_mutex_unlock"; + goto deactivate_client; + } + if (sem_wait(&semaphore)) { + error_message = strerror(errno); + error_source = "sem_wait"; + goto deactivate_client; + } + if (process_state == 2) { + double average_latency = ((double) total_latency) / samples; + double average_latency_time = total_latency_time / samples; + double high_jitter = highest_latency - average_latency; + size_t i; + double low_jitter = average_latency - lowest_latency; + double peak_jitter; + double peak_jitter_time; + double sample_rate = (double) jack_get_sample_rate(client); + jack_nframes_t total_jitter = 0; + jack_time_t total_jitter_time = 0; + if (high_jitter > low_jitter) { + peak_jitter = high_jitter; + peak_jitter_time = highest_latency_time - average_latency_time; + } else { + peak_jitter = low_jitter; + peak_jitter_time = average_latency_time - lowest_latency_time; + } + for (i = 0; i <= 100; i++) { + jitter_plot[i] = 0; + } + for (i = 0; i < samples; i++) { + double jitter_time = ABS(average_latency_time - + ((double) latency_time_values[i])); + if (jitter_time >= 10000.0) { + (jitter_plot[100])++; + } else { + (jitter_plot[(int) (jitter_time / 100.0)])++; + } + total_jitter += ABS(average_latency - + ((double) latency_values[i])); + total_jitter_time += jitter_time; + } + printf("Reported out-port latency: %.2f-%.2f ms (%u-%u frames)\n" + "Reported in-port latency: %.2f-%.2f ms (%u-%u frames)\n" + "Average latency: %.2f ms (%.2f frames)\n" + "Best latency: %.2f ms (%u frames)\n" + "Worst latency: %.2f ms (%u frames)\n" + "Peak MIDI jitter: %.2f ms (%.2f frames)\n" + "Average MIDI jitter: %.2f ms (%.2f frames)\n", + (out_latency_range.min / sample_rate) * 1000.0, + (out_latency_range.max / sample_rate) * 1000.0, + out_latency_range.min, out_latency_range.max, + (in_latency_range.min / sample_rate) * 1000.0, + (in_latency_range.max / sample_rate) * 1000.0, + in_latency_range.min, in_latency_range.max, + average_latency_time / 1000.0, average_latency, + lowest_latency_time / 1000.0, lowest_latency, + highest_latency_time / 1000.0, highest_latency, + peak_jitter_time / 1000.0, peak_jitter, + (total_jitter_time / 1000.0) / samples, + ((double) total_jitter) / samples); + printf("\nJitter Plot:\n"); + for (i = 0; i < 100; i++) { + if (jitter_plot[i]) { + printf("%.1f - %.1f ms: %u\n", ((float) i) / 10.0, + ((float) (i + 1)) / 10.0, jitter_plot[i]); + } + } + if (jitter_plot[100]) { + printf(" > 10 ms: %u\n", jitter_plot[100]); + } + if (unexpected_messages) { + printf("\nUnexpected messages received: %d\n", + unexpected_messages); + } + } + deactivate_client: + jack_deactivate(client); + destroy_mutex: + pthread_mutex_destroy(&start_mutex); + destroy_semaphore: + sem_destroy(&semaphore); + unregister_out_port: + jack_port_unregister(client, out_port); + unregister_in_port: + jack_port_unregister(client, in_port); + close_client: + jack_client_close(client); + free_message_2: + free(message_2); + free_message_1: + free(message_1); + free_latency_time_values: + free(latency_time_values); + free_latency_values: + free(latency_values); + if (error_message != NULL) { + show_error: + output_error(error_source, error_message); + exit(EXIT_FAILURE); + } + return EXIT_SUCCESS; +} diff --git a/example-clients/wscript b/example-clients/wscript index 9d477e35..8f6dae62 100644 --- a/example-clients/wscript +++ b/example-clients/wscript @@ -27,6 +27,7 @@ example_programs = { 'jack_server_control' : 'server_control.cpp', 'jack_latent_client' : 'latent_client.c', 'jack_midi_dump' : 'midi_dump.c', + 'jack_midi_latency_test' : 'midi_latency_test.c' } example_libs = { diff --git a/linux/firewire/JackFFADODriver.cpp b/linux/firewire/JackFFADODriver.cpp index 0966b1da..e0a2e556 100644 --- a/linux/firewire/JackFFADODriver.cpp +++ b/linux/firewire/JackFFADODriver.cpp @@ -36,8 +36,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include "JackFFADODriver.h" -#include "JackFFADOMidiInput.h" -#include "JackFFADOMidiOutput.h" +#include "JackFFADOMidiInputPort.h" +#include "JackFFADOMidiOutputPort.h" #include "JackEngineControl.h" #include "JackClientControl.h" #include "JackPort.h" @@ -94,14 +94,9 @@ JackFFADODriver::ffado_driver_read (ffado_driver_t * driver, jack_nframes_t nfra /* process the midi data */ for (chn = 0; chn < driver->capture_nchannels; chn++) { if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) { - JackFFADOMidiInput *midi_input = (JackFFADOMidiInput *) driver->capture_channels[chn].midi_input; + JackFFADOMidiInputPort *midi_input = (JackFFADOMidiInputPort *) driver->capture_channels[chn].midi_input; JackMidiBuffer *buffer = (JackMidiBuffer *) fGraphManager->GetBuffer(fCapturePortList[chn], nframes); - if (! buffer) { - continue; - } - midi_input->SetInputBuffer(driver->capture_channels[chn].midi_buffer); - midi_input->SetPortBuffer(buffer); - midi_input->Process(nframes); + midi_input->Process(buffer, driver->capture_channels[chn].midi_buffer, nframes); } } @@ -138,16 +133,9 @@ JackFFADODriver::ffado_driver_write (ffado_driver_t * driver, jack_nframes_t nfr memset(midi_buffer, 0, nframes * sizeof(uint32_t)); buf = (jack_default_audio_sample_t *) fGraphManager->GetBuffer(fPlaybackPortList[chn], nframes); ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(midi_buffer)); - /* if the returned buffer is invalid, continue */ - if (!buf) { - ffado_streaming_playback_stream_onoff(driver->dev, chn, 0); - continue; - } - ffado_streaming_playback_stream_onoff(driver->dev, chn, 1); - JackFFADOMidiOutput *midi_output = (JackFFADOMidiOutput *) driver->playback_channels[chn].midi_output; - midi_output->SetPortBuffer((JackMidiBuffer *) buf); - midi_output->SetOutputBuffer(midi_buffer); - midi_output->Process(nframes); + ffado_streaming_playback_stream_onoff(driver->dev, chn, buf ? 1 : 0); + JackFFADOMidiOutputPort *midi_output = (JackFFADOMidiOutputPort *) driver->playback_channels[chn].midi_output; + midi_output->Process((JackMidiBuffer *) buf, midi_buffer, nframes); } else { // always have a valid buffer ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(driver->nullbuffer)); @@ -155,9 +143,7 @@ JackFFADODriver::ffado_driver_write (ffado_driver_t * driver, jack_nframes_t nfr } } } - ffado_streaming_transfer_playback_buffers(driver->dev); - printExit(); return 0; } @@ -476,7 +462,7 @@ int JackFFADODriver::Attach() printError(" cannot enable port %s", buf); } - driver->capture_channels[chn].midi_input = new JackFFADOMidiInput(); + driver->capture_channels[chn].midi_input = new JackFFADOMidiInputPort(); // setup the midi buffer driver->capture_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t)); @@ -557,12 +543,12 @@ int JackFFADODriver::Attach() // This constructor optionally accepts arguments for the // non-realtime buffer size and the realtime buffer size. Ideally, // these would become command-line options for the FFADO driver. - driver->playback_channels[chn].midi_output = new JackFFADOMidiOutput(); + driver->playback_channels[chn].midi_output = new JackFFADOMidiOutputPort(); driver->playback_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t)); port = fGraphManager->GetPort(port_index); - range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + driver->playback_frame_latency; + range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency; port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[chn] = port_index; jack_log("JackFFADODriver::Attach fPlaybackPortList[i] %ld ", port_index); @@ -600,7 +586,7 @@ int JackFFADODriver::Detach() if (driver->capture_channels[chn].midi_buffer) free(driver->capture_channels[chn].midi_buffer); if (driver->capture_channels[chn].midi_input) - delete ((JackFFADOMidiInput *) (driver->capture_channels[chn].midi_input)); + delete ((JackFFADOMidiInputPort *) (driver->capture_channels[chn].midi_input)); } free(driver->capture_channels); @@ -608,7 +594,7 @@ int JackFFADODriver::Detach() if (driver->playback_channels[chn].midi_buffer) free(driver->playback_channels[chn].midi_buffer); if (driver->playback_channels[chn].midi_output) - delete ((JackFFADOMidiOutput *) (driver->playback_channels[chn].midi_output)); + delete ((JackFFADOMidiOutputPort *) (driver->playback_channels[chn].midi_output)); } free(driver->playback_channels); diff --git a/linux/firewire/JackFFADOMidiInput.cpp b/linux/firewire/JackFFADOMidiInput.cpp deleted file mode 100644 index 38ed539b..00000000 --- a/linux/firewire/JackFFADOMidiInput.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* -Copyright (C) 2009 Devin Anderson - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 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 -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include - -#include "JackFFADOMidiInput.h" - -namespace Jack { - -JackFFADOMidiInput::JackFFADOMidiInput(size_t buffer_size): - JackPhysicalMidiInput(buffer_size) -{ - new_period = true; -} - -JackFFADOMidiInput::~JackFFADOMidiInput() -{ - // Empty -} - -jack_nframes_t -JackFFADOMidiInput::Receive(jack_midi_data_t *datum, - jack_nframes_t current_frame, - jack_nframes_t total_frames) -{ - assert(input_buffer); - if (! new_period) { - current_frame += 8; - } else { - new_period = false; - } - for (; current_frame < total_frames; current_frame += 8) { - uint32_t data = input_buffer[current_frame]; - if (data & 0xff000000) { - *datum = (jack_midi_data_t) (data & 0xff); - return current_frame; - } - } - new_period = true; - return total_frames; -} - -} diff --git a/linux/firewire/JackFFADOMidiInputPort.cpp b/linux/firewire/JackFFADOMidiInputPort.cpp new file mode 100644 index 00000000..3923bbe0 --- /dev/null +++ b/linux/firewire/JackFFADOMidiInputPort.cpp @@ -0,0 +1,94 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include + +#include "JackFFADOMidiInputPort.h" +#include "JackMidiUtil.h" + +using Jack::JackFFADOMidiInputPort; + +JackFFADOMidiInputPort::JackFFADOMidiInputPort(size_t max_bytes) +{ + event = 0; + receive_queue = new JackFFADOMidiReceiveQueue(); + std::auto_ptr receive_queue_ptr(receive_queue); + write_queue = new JackMidiBufferWriteQueue(); + std::auto_ptr write_queue_ptr(write_queue); + raw_queue = new JackMidiRawInputWriteQueue(write_queue, max_bytes, + max_bytes); + write_queue_ptr.release(); + receive_queue_ptr.release(); +} + +JackFFADOMidiInputPort::~JackFFADOMidiInputPort() +{ + delete raw_queue; + delete receive_queue; + delete write_queue; +} + +void +JackFFADOMidiInputPort::Process(JackMidiBuffer *port_buffer, + uint32_t *input_buffer, jack_nframes_t frames) +{ + receive_queue->ResetInputBuffer(input_buffer, frames); + write_queue->ResetMidiBuffer(port_buffer, frames); + jack_nframes_t boundary_frame = GetLastFrame() + frames; + if (! event) { + event = receive_queue->DequeueEvent(); + } + for (; event; event = receive_queue->DequeueEvent()) { + switch (raw_queue->EnqueueEvent(event)) { + case JackMidiWriteQueue::BUFFER_FULL: + + // Processing events early might free up some space in the raw + // input queue. + + raw_queue->Process(boundary_frame); + switch (raw_queue->EnqueueEvent(event)) { + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + // This shouldn't really happen. It indicates a bug if it + // does. + jack_error("JackFFADOMidiInputPort::Process - **BUG** " + "JackMidiRawInputWriteQueue::EnqueueEvent returned " + "`BUFFER_FULL`, and then returned " + "`BUFFER_TOO_SMALL` after a `Process()` call."); + // Fallthrough on purpose + case JackMidiWriteQueue::OK: + continue; + default: + return; + } + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + jack_error("JackFFADOMidiInputPort::Process - The write queue " + "couldn't enqueue a %d-byte event. Dropping event.", + event->size); + // Fallthrough on purpose + case JackMidiWriteQueue::OK: + continue; + default: + // This is here to stop compliers from warning us about not + // handling enumeration values. + ; + } + break; + } + raw_queue->Process(boundary_frame); +} diff --git a/linux/firewire/JackFFADOMidiInputPort.h b/linux/firewire/JackFFADOMidiInputPort.h new file mode 100644 index 00000000..f4c70a80 --- /dev/null +++ b/linux/firewire/JackFFADOMidiInputPort.h @@ -0,0 +1,51 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackFFADOMidiInputPort__ +#define __JackFFADOMidiInputPort__ + +#include "JackFFADOMidiReceiveQueue.h" +#include "JackMidiBufferWriteQueue.h" +#include "JackMidiRawInputWriteQueue.h" + +namespace Jack { + + class JackFFADOMidiInputPort { + + private: + + jack_midi_event_t *event; + JackMidiRawInputWriteQueue *raw_queue; + JackFFADOMidiReceiveQueue *receive_queue; + JackMidiBufferWriteQueue *write_queue; + + public: + + JackFFADOMidiInputPort(size_t max_bytes=4096); + ~JackFFADOMidiInputPort(); + + void + Process(JackMidiBuffer *port_buffer, uint32_t *input_buffer, + jack_nframes_t frames); + + }; + +} + +#endif diff --git a/linux/firewire/JackFFADOMidiOutput.cpp b/linux/firewire/JackFFADOMidiOutput.cpp deleted file mode 100644 index 995f2d28..00000000 --- a/linux/firewire/JackFFADOMidiOutput.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright (C) 2009 Devin Anderson - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 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 -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include - -#include "JackError.h" -#include "JackFFADOMidiOutput.h" - -namespace Jack { - -JackFFADOMidiOutput::JackFFADOMidiOutput(size_t non_rt_buffer_size, - size_t rt_buffer_size): - JackPhysicalMidiOutput(non_rt_buffer_size, rt_buffer_size) -{ - // Empty -} - -JackFFADOMidiOutput::~JackFFADOMidiOutput() -{ - // Empty -} - -jack_nframes_t -JackFFADOMidiOutput::Advance(jack_nframes_t current_frame) -{ - if (current_frame % 8) { - current_frame = (current_frame & (~ ((jack_nframes_t) 7))) + 8; - } - return current_frame; -} - -jack_nframes_t -JackFFADOMidiOutput::Send(jack_nframes_t current_frame, jack_midi_data_t datum) -{ - assert(output_buffer); - - jack_log("JackFFADOMidiOutput::Send (%d) - Sending '%x' byte.", - current_frame, (unsigned int) datum); - - output_buffer[current_frame] = 0x01000000 | ((uint32_t) datum); - return current_frame + 8; -} - -} diff --git a/linux/firewire/JackFFADOMidiOutputPort.cpp b/linux/firewire/JackFFADOMidiOutputPort.cpp new file mode 100644 index 00000000..3a7c21f5 --- /dev/null +++ b/linux/firewire/JackFFADOMidiOutputPort.cpp @@ -0,0 +1,98 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include + +#include "JackFFADOMidiOutputPort.h" +#include "JackMidiUtil.h" + +using Jack::JackFFADOMidiOutputPort; + +JackFFADOMidiOutputPort::JackFFADOMidiOutputPort(size_t non_rt_size, + size_t max_non_rt_messages, + size_t max_rt_messages) +{ + event = 0; + read_queue = new JackMidiBufferReadQueue(); + std::auto_ptr read_queue_ptr(read_queue); + send_queue = new JackFFADOMidiSendQueue(); + std::auto_ptr send_queue_ptr(send_queue); + raw_queue = new JackMidiRawOutputWriteQueue(send_queue, max_rt_messages, + max_non_rt_messages, + non_rt_size); + send_queue_ptr.release(); + read_queue_ptr.release(); +} + +JackFFADOMidiOutputPort::~JackFFADOMidiOutputPort() +{ + delete raw_queue; + delete read_queue; + delete send_queue; +} + +void +JackFFADOMidiOutputPort::Process(JackMidiBuffer *port_buffer, + uint32_t *output_buffer, + jack_nframes_t frames) +{ + read_queue->ResetMidiBuffer(port_buffer); + send_queue->ResetOutputBuffer(output_buffer, frames); + jack_nframes_t boundary_frame = GetLastFrame() + frames; + if (! event) { + event = read_queue->DequeueEvent(); + } + for (; event; event = read_queue->DequeueEvent()) { + switch (raw_queue->EnqueueEvent(event)) { + case JackMidiWriteQueue::BUFFER_FULL: + + // Processing events early might free up some space in the raw + // output queue. + + raw_queue->Process(boundary_frame); + switch (raw_queue->EnqueueEvent(event)) { + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + // This shouldn't really happen. It indicates a bug if it + // does. + jack_error("JackFFADOMidiOutputPort::Process - **BUG** " + "JackMidiRawOutputWriteQueue::EnqueueEvent " + "returned `BUFFER_FULL`, and then returned " + "`BUFFER_TOO_SMALL` after a `Process()` call."); + // Fallthrough on purpose + case JackMidiWriteQueue::OK: + continue; + default: + return; + } + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + jack_error("JackFFADOMidiOutputPort::Process - The write queue " + "couldn't enqueue a %d-byte event. Dropping event.", + event->size); + // Fallthrough on purpose + case JackMidiWriteQueue::OK: + continue; + default: + // This is here to stop compliers from warning us about not + // handling enumeration values. + ; + } + break; + } + raw_queue->Process(boundary_frame); +} diff --git a/linux/firewire/JackFFADOMidiOutputPort.h b/linux/firewire/JackFFADOMidiOutputPort.h new file mode 100644 index 00000000..4ca309bb --- /dev/null +++ b/linux/firewire/JackFFADOMidiOutputPort.h @@ -0,0 +1,53 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackFFADOMidiOutputPort__ +#define __JackFFADOMidiOutputPort__ + +#include "JackFFADOMidiSendQueue.h" +#include "JackMidiBufferReadQueue.h" +#include "JackMidiRawOutputWriteQueue.h" + +namespace Jack { + + class JackFFADOMidiOutputPort { + + private: + + jack_midi_event_t *event; + JackMidiRawOutputWriteQueue *raw_queue; + JackMidiBufferReadQueue *read_queue; + JackFFADOMidiSendQueue *send_queue; + + public: + + JackFFADOMidiOutputPort(size_t non_rt_size=4096, + size_t max_non_rt_messages=1024, + size_t max_rt_messages=128); + ~JackFFADOMidiOutputPort(); + + void + Process(JackMidiBuffer *port_buffer, uint32_t *output_buffer, + jack_nframes_t frames); + + }; + +} + +#endif diff --git a/linux/firewire/JackFFADOMidiReceiveQueue.cpp b/linux/firewire/JackFFADOMidiReceiveQueue.cpp new file mode 100644 index 00000000..4b67f329 --- /dev/null +++ b/linux/firewire/JackFFADOMidiReceiveQueue.cpp @@ -0,0 +1,55 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "JackFFADOMidiReceiveQueue.h" +#include "JackMidiUtil.h" + +using Jack::JackFFADOMidiReceiveQueue; + +JackFFADOMidiReceiveQueue::JackFFADOMidiReceiveQueue() +{ + // Empty +} + +jack_midi_event_t * +JackFFADOMidiReceiveQueue::DequeueEvent() +{ + for (; index < length; index += 8) { + uint32_t data = input_buffer[index]; + if (data & 0xff000000) { + byte = (jack_midi_data_t) (data & 0xff); + event.buffer = &byte; + event.size = 1; + event.time = last_frame + index; + index += 8; + return &event; + } + } + return 0; +} + +void +JackFFADOMidiReceiveQueue::ResetInputBuffer(uint32_t *input_buffer, + jack_nframes_t length) +{ + this->input_buffer = input_buffer; + index = 0; + last_frame = GetLastFrame(); + this->length = length; +} diff --git a/linux/firewire/JackFFADOMidiInput.h b/linux/firewire/JackFFADOMidiReceiveQueue.h similarity index 59% rename from linux/firewire/JackFFADOMidiInput.h rename to linux/firewire/JackFFADOMidiReceiveQueue.h index 12dc043c..7647869d 100644 --- a/linux/firewire/JackFFADOMidiInput.h +++ b/linux/firewire/JackFFADOMidiReceiveQueue.h @@ -1,5 +1,5 @@ /* -Copyright (C) 2009 Devin Anderson +Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -17,35 +17,33 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __JackFFADOMidiInput__ -#define __JackFFADOMidiInput__ +#ifndef __JackFFADOMidiReceiveQueue__ +#define __JackFFADOMidiReceiveQueue__ -#include "JackPhysicalMidiInput.h" +#include "JackMidiReceiveQueue.h" namespace Jack { - class JackFFADOMidiInput: public JackPhysicalMidiInput { + class JackFFADOMidiReceiveQueue: public JackMidiReceiveQueue { private: + jack_midi_data_t byte; + jack_midi_event_t event; + jack_nframes_t index; uint32_t *input_buffer; - bool new_period; - - protected: - - jack_nframes_t - Receive(jack_midi_data_t *, jack_nframes_t, jack_nframes_t); + jack_nframes_t last_frame; + jack_nframes_t length; public: - JackFFADOMidiInput(size_t buffer_size=1024); - ~JackFFADOMidiInput(); + JackFFADOMidiReceiveQueue(); + + jack_midi_event_t * + DequeueEvent(); - inline void - SetInputBuffer(uint32_t *input_buffer) - { - this->input_buffer = input_buffer; - } + void + ResetInputBuffer(uint32_t *input_buffer, jack_nframes_t length); }; diff --git a/linux/firewire/JackFFADOMidiSendQueue.cpp b/linux/firewire/JackFFADOMidiSendQueue.cpp new file mode 100644 index 00000000..97fdf17d --- /dev/null +++ b/linux/firewire/JackFFADOMidiSendQueue.cpp @@ -0,0 +1,64 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 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 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include + +#include "JackFFADOMidiSendQueue.h" +#include "JackMidiUtil.h" + +using Jack::JackFFADOMidiSendQueue; + +JackFFADOMidiSendQueue::JackFFADOMidiSendQueue() +{ + // Empty +} + +Jack::JackMidiWriteQueue::EnqueueResult +JackFFADOMidiSendQueue::EnqueueEvent(jack_nframes_t time, size_t size, + jack_midi_data_t *buffer) +{ + assert(size == 1); + jack_nframes_t relative_time = (time < last_frame) ? 0 : time - last_frame; + if (index < relative_time) { + index = (relative_time % 8) ? + (relative_time & (~ ((jack_nframes_t) 7))) + 8 : relative_time; + } + if (index >= length) { + return BUFFER_FULL; + } + output_buffer[index] = 0x01000000 | ((uint32_t) *buffer); + index += 8; + return OK; +} + +jack_nframes_t +JackFFADOMidiSendQueue::GetNextScheduleFrame() +{ + return last_frame + index; +} + +void +JackFFADOMidiSendQueue::ResetOutputBuffer(uint32_t *output_buffer, + jack_nframes_t length) +{ + index = 0; + last_frame = GetLastFrame(); + this->length = length; + this->output_buffer = output_buffer; +} diff --git a/linux/firewire/JackFFADOMidiOutput.h b/linux/firewire/JackFFADOMidiSendQueue.h similarity index 58% rename from linux/firewire/JackFFADOMidiOutput.h rename to linux/firewire/JackFFADOMidiSendQueue.h index 309e7f61..f395f13d 100644 --- a/linux/firewire/JackFFADOMidiOutput.h +++ b/linux/firewire/JackFFADOMidiSendQueue.h @@ -1,5 +1,5 @@ /* -Copyright (C) 2009 Devin Anderson +Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -17,38 +17,35 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __JackFFADOMidiOutput__ -#define __JackFFADOMidiOutput__ +#ifndef __JackFFADOMidiSendQueue__ +#define __JackFFADOMidiSendQueue__ -#include "JackPhysicalMidiOutput.h" +#include "JackMidiSendQueue.h" namespace Jack { - class JackFFADOMidiOutput: public JackPhysicalMidiOutput { + class JackFFADOMidiSendQueue: public JackMidiSendQueue { private: + jack_nframes_t index; + jack_nframes_t last_frame; + jack_nframes_t length; uint32_t *output_buffer; - protected: - - jack_nframes_t - Advance(jack_nframes_t); + public: - jack_nframes_t - Send(jack_nframes_t, jack_midi_data_t); + JackFFADOMidiSendQueue(); - public: + EnqueueResult + EnqueueEvent(jack_nframes_t time, size_t size, + jack_midi_data_t *buffer); - JackFFADOMidiOutput(size_t non_rt_buffer_size=1024, - size_t rt_buffer_size=64); - ~JackFFADOMidiOutput(); + jack_nframes_t + GetNextScheduleFrame(); - inline void - SetOutputBuffer(uint32_t *output_buffer) - { - this->output_buffer = output_buffer; - } + void + ResetOutputBuffer(uint32_t *output_buffer, jack_nframes_t length); }; diff --git a/linux/wscript b/linux/wscript index 545d9628..c28da170 100644 --- a/linux/wscript +++ b/linux/wscript @@ -58,10 +58,10 @@ def build(bld): ] ffado_driver_src = ['firewire/JackFFADODriver.cpp', - 'firewire/JackFFADOMidiInput.cpp', - 'firewire/JackFFADOMidiOutput.cpp', - '../common/JackPhysicalMidiInput.cpp', - '../common/JackPhysicalMidiOutput.cpp' + 'firewire/JackFFADOMidiInputPort.cpp', + 'firewire/JackFFADOMidiOutputPort.cpp', + 'firewire/JackFFADOMidiReceiveQueue.cpp', + 'firewire/JackFFADOMidiSendQueue.cpp' ] if bld.env['BUILD_DRIVER_ALSA'] == True: From b426ca5e5df9bc71148685795f55c4c69bd16bbb Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Fri, 18 Mar 2011 22:54:31 -0700 Subject: [PATCH 057/472] Fix minor syntax error --- linux/firewire/JackFFADODriver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/firewire/JackFFADODriver.cpp b/linux/firewire/JackFFADODriver.cpp index e0a2e556..814ac357 100644 --- a/linux/firewire/JackFFADODriver.cpp +++ b/linux/firewire/JackFFADODriver.cpp @@ -512,7 +512,7 @@ int JackFFADODriver::Attach() port = fGraphManager->GetPort(port_index); // Add one buffer more latency if "async" mode is used... - range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency + range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency; port->SetLatencyRange(JackPlaybackLatency, &range); // playback port aliases (jackd1 style port names) snprintf(buf, sizeof(buf) - 1, "%s:playback_%i", fClientControl.fName, (int) chn + 1); From 61ae5bc2ad715126a63fcbe33c89ff1bee1e110f Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Sat, 19 Mar 2011 14:18:25 -0700 Subject: [PATCH 058/472] Fix MIDI queue bugs. Make latency test output unexpected message count even if an error occurs. --- common/JackMidiAsyncQueue.cpp | 32 +++++++++++--------- common/JackMidiAsyncQueue.h | 1 - example-clients/midi_latency_test.c | 7 ++--- linux/firewire/JackFFADOMidiOutputPort.cpp | 4 +-- linux/firewire/JackFFADOMidiReceiveQueue.cpp | 7 ++++- linux/firewire/JackFFADOMidiReceiveQueue.h | 2 ++ linux/firewire/JackFFADOMidiSendQueue.cpp | 6 +++- linux/firewire/JackFFADOMidiSendQueue.h | 2 ++ 8 files changed, 37 insertions(+), 24 deletions(-) diff --git a/common/JackMidiAsyncQueue.cpp b/common/JackMidiAsyncQueue.cpp index 28018b56..85a93b18 100644 --- a/common/JackMidiAsyncQueue.cpp +++ b/common/JackMidiAsyncQueue.cpp @@ -26,13 +26,13 @@ using Jack::JackMidiAsyncQueue; JackMidiAsyncQueue::JackMidiAsyncQueue(size_t max_bytes, size_t max_messages) { data_buffer = new jack_midi_data_t[max_bytes]; - byte_ring = jack_ringbuffer_create(max_bytes + 1); + byte_ring = jack_ringbuffer_create((max_bytes * sizeof(jack_midi_data_t)) + + 1); if (byte_ring) { info_ring = jack_ringbuffer_create((max_messages * INFO_SIZE) + 1); if (info_ring) { jack_ringbuffer_mlock(byte_ring); jack_ringbuffer_mlock(info_ring); - advance_space = 0; this->max_bytes = max_bytes; return; } @@ -54,26 +54,23 @@ JackMidiAsyncQueue::DequeueEvent() { jack_midi_event_t *event = 0; if (jack_ringbuffer_read_space(info_ring) >= INFO_SIZE) { - if (advance_space) { - jack_ringbuffer_read_advance(byte_ring, advance_space); - } event = &dequeue_event; jack_ringbuffer_read(info_ring, (char *) &(event->time), sizeof(jack_nframes_t)); size_t size; jack_ringbuffer_read(info_ring, (char *) &size, sizeof(size_t)); + event->buffer = data_buffer; event->size = size; jack_ringbuffer_data_t vector[2]; jack_ringbuffer_get_read_vector(byte_ring, vector); size_t size1 = vector[0].len; - if (size1 >= size) { - event->buffer = (jack_midi_data_t *) vector[0].buf; - } else { - event->buffer = data_buffer; - memcpy(data_buffer, vector[0].buf, size1); - memcpy(data_buffer + size1, vector[1].buf, size - size1); + memcpy(data_buffer, vector[0].buf, size1 * sizeof(jack_midi_data_t)); + if (size1 < size) { + memcpy(data_buffer + size1, vector[1].buf, + (size - size1) * sizeof(jack_midi_data_t)); } - advance_space = size; + jack_ringbuffer_read_advance(byte_ring, + size * sizeof(jack_midi_data_t)); } return event; } @@ -82,11 +79,16 @@ Jack::JackMidiWriteQueue::EnqueueResult JackMidiAsyncQueue::EnqueueEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer) { + if (size > max_bytes) { + return BUFFER_TOO_SMALL; + } if (! ((jack_ringbuffer_write_space(info_ring) >= INFO_SIZE) && - (jack_ringbuffer_write_space(byte_ring) >= size))) { - return size > max_bytes ? BUFFER_TOO_SMALL : BUFFER_FULL; + (jack_ringbuffer_write_space(byte_ring) >= + (size * sizeof(jack_midi_data_t))))) { + return BUFFER_FULL; } - jack_ringbuffer_write(byte_ring, (const char *) buffer, size); + jack_ringbuffer_write(byte_ring, (const char *) buffer, + size * sizeof(jack_midi_data_t)); jack_ringbuffer_write(info_ring, (const char *) (&time), sizeof(jack_nframes_t)); jack_ringbuffer_write(info_ring, (const char *) (&size), sizeof(size_t)); diff --git a/common/JackMidiAsyncQueue.h b/common/JackMidiAsyncQueue.h index 630b5ab1..22948cc9 100644 --- a/common/JackMidiAsyncQueue.h +++ b/common/JackMidiAsyncQueue.h @@ -46,7 +46,6 @@ namespace Jack { static const size_t INFO_SIZE = sizeof(jack_nframes_t) + sizeof(size_t); - size_t advance_space; jack_ringbuffer_t *byte_ring; jack_midi_data_t *data_buffer; jack_midi_event_t dequeue_event; diff --git a/example-clients/midi_latency_test.c b/example-clients/midi_latency_test.c index 2d9e1686..bcf54641 100644 --- a/example-clients/midi_latency_test.c +++ b/example-clients/midi_latency_test.c @@ -554,10 +554,9 @@ main(int argc, char **argv) if (jitter_plot[100]) { printf(" > 10 ms: %u\n", jitter_plot[100]); } - if (unexpected_messages) { - printf("\nUnexpected messages received: %d\n", - unexpected_messages); - } + } + if (unexpected_messages) { + printf("\nUnexpected messages received: %d\n", unexpected_messages); } deactivate_client: jack_deactivate(client); diff --git a/linux/firewire/JackFFADOMidiOutputPort.cpp b/linux/firewire/JackFFADOMidiOutputPort.cpp index 3a7c21f5..b916c8c5 100644 --- a/linux/firewire/JackFFADOMidiOutputPort.cpp +++ b/linux/firewire/JackFFADOMidiOutputPort.cpp @@ -33,9 +33,9 @@ JackFFADOMidiOutputPort::JackFFADOMidiOutputPort(size_t non_rt_size, std::auto_ptr read_queue_ptr(read_queue); send_queue = new JackFFADOMidiSendQueue(); std::auto_ptr send_queue_ptr(send_queue); - raw_queue = new JackMidiRawOutputWriteQueue(send_queue, max_rt_messages, + raw_queue = new JackMidiRawOutputWriteQueue(send_queue, non_rt_size, max_non_rt_messages, - non_rt_size); + max_rt_messages); send_queue_ptr.release(); read_queue_ptr.release(); } diff --git a/linux/firewire/JackFFADOMidiReceiveQueue.cpp b/linux/firewire/JackFFADOMidiReceiveQueue.cpp index 4b67f329..16f24636 100644 --- a/linux/firewire/JackFFADOMidiReceiveQueue.cpp +++ b/linux/firewire/JackFFADOMidiReceiveQueue.cpp @@ -24,7 +24,7 @@ using Jack::JackFFADOMidiReceiveQueue; JackFFADOMidiReceiveQueue::JackFFADOMidiReceiveQueue() { - // Empty + bytes_received = 0; } jack_midi_event_t * @@ -38,6 +38,11 @@ JackFFADOMidiReceiveQueue::DequeueEvent() event.size = 1; event.time = last_frame + index; index += 8; + bytes_received++; + + jack_info("Jack::JackFFADOMidiReceiveQueue: %d bytes received", + bytes_received); + return &event; } } diff --git a/linux/firewire/JackFFADOMidiReceiveQueue.h b/linux/firewire/JackFFADOMidiReceiveQueue.h index 7647869d..04c35f7f 100644 --- a/linux/firewire/JackFFADOMidiReceiveQueue.h +++ b/linux/firewire/JackFFADOMidiReceiveQueue.h @@ -28,6 +28,8 @@ namespace Jack { private: + unsigned long bytes_received; + jack_midi_data_t byte; jack_midi_event_t event; jack_nframes_t index; diff --git a/linux/firewire/JackFFADOMidiSendQueue.cpp b/linux/firewire/JackFFADOMidiSendQueue.cpp index 97fdf17d..a20bde54 100644 --- a/linux/firewire/JackFFADOMidiSendQueue.cpp +++ b/linux/firewire/JackFFADOMidiSendQueue.cpp @@ -26,7 +26,7 @@ using Jack::JackFFADOMidiSendQueue; JackFFADOMidiSendQueue::JackFFADOMidiSendQueue() { - // Empty + bytes_sent = 0; } Jack::JackMidiWriteQueue::EnqueueResult @@ -44,6 +44,10 @@ JackFFADOMidiSendQueue::EnqueueEvent(jack_nframes_t time, size_t size, } output_buffer[index] = 0x01000000 | ((uint32_t) *buffer); index += 8; + + bytes_sent++; + jack_info("Jack::JackFFADOMidiSendQueue: %d bytes sent", bytes_sent); + return OK; } diff --git a/linux/firewire/JackFFADOMidiSendQueue.h b/linux/firewire/JackFFADOMidiSendQueue.h index f395f13d..25fe7c0c 100644 --- a/linux/firewire/JackFFADOMidiSendQueue.h +++ b/linux/firewire/JackFFADOMidiSendQueue.h @@ -28,6 +28,8 @@ namespace Jack { private: + unsigned long bytes_sent; + jack_nframes_t index; jack_nframes_t last_frame; jack_nframes_t length; From 725c7c4ff29d95b50228d823730ab404ef75d88f Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Sat, 19 Mar 2011 14:25:45 -0700 Subject: [PATCH 059/472] Kill temporary FFADO debug code. --- linux/firewire/JackFFADOMidiReceiveQueue.cpp | 7 +------ linux/firewire/JackFFADOMidiReceiveQueue.h | 2 -- linux/firewire/JackFFADOMidiSendQueue.cpp | 6 +----- linux/firewire/JackFFADOMidiSendQueue.h | 2 -- 4 files changed, 2 insertions(+), 15 deletions(-) diff --git a/linux/firewire/JackFFADOMidiReceiveQueue.cpp b/linux/firewire/JackFFADOMidiReceiveQueue.cpp index 16f24636..4b67f329 100644 --- a/linux/firewire/JackFFADOMidiReceiveQueue.cpp +++ b/linux/firewire/JackFFADOMidiReceiveQueue.cpp @@ -24,7 +24,7 @@ using Jack::JackFFADOMidiReceiveQueue; JackFFADOMidiReceiveQueue::JackFFADOMidiReceiveQueue() { - bytes_received = 0; + // Empty } jack_midi_event_t * @@ -38,11 +38,6 @@ JackFFADOMidiReceiveQueue::DequeueEvent() event.size = 1; event.time = last_frame + index; index += 8; - bytes_received++; - - jack_info("Jack::JackFFADOMidiReceiveQueue: %d bytes received", - bytes_received); - return &event; } } diff --git a/linux/firewire/JackFFADOMidiReceiveQueue.h b/linux/firewire/JackFFADOMidiReceiveQueue.h index 04c35f7f..7647869d 100644 --- a/linux/firewire/JackFFADOMidiReceiveQueue.h +++ b/linux/firewire/JackFFADOMidiReceiveQueue.h @@ -28,8 +28,6 @@ namespace Jack { private: - unsigned long bytes_received; - jack_midi_data_t byte; jack_midi_event_t event; jack_nframes_t index; diff --git a/linux/firewire/JackFFADOMidiSendQueue.cpp b/linux/firewire/JackFFADOMidiSendQueue.cpp index a20bde54..97fdf17d 100644 --- a/linux/firewire/JackFFADOMidiSendQueue.cpp +++ b/linux/firewire/JackFFADOMidiSendQueue.cpp @@ -26,7 +26,7 @@ using Jack::JackFFADOMidiSendQueue; JackFFADOMidiSendQueue::JackFFADOMidiSendQueue() { - bytes_sent = 0; + // Empty } Jack::JackMidiWriteQueue::EnqueueResult @@ -44,10 +44,6 @@ JackFFADOMidiSendQueue::EnqueueEvent(jack_nframes_t time, size_t size, } output_buffer[index] = 0x01000000 | ((uint32_t) *buffer); index += 8; - - bytes_sent++; - jack_info("Jack::JackFFADOMidiSendQueue: %d bytes sent", bytes_sent); - return OK; } diff --git a/linux/firewire/JackFFADOMidiSendQueue.h b/linux/firewire/JackFFADOMidiSendQueue.h index 25fe7c0c..f395f13d 100644 --- a/linux/firewire/JackFFADOMidiSendQueue.h +++ b/linux/firewire/JackFFADOMidiSendQueue.h @@ -28,8 +28,6 @@ namespace Jack { private: - unsigned long bytes_sent; - jack_nframes_t index; jack_nframes_t last_frame; jack_nframes_t length; From 4916a78906451b6260817f98d1888a0b9936b292 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Mon, 21 Mar 2011 12:16:24 +0100 Subject: [PATCH 060/472] Update XCode project. --- macosx/Jackdmp.xcodeproj/project.pbxproj | 32 ------------------------ 1 file changed, 32 deletions(-) diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index 96daca3a..705de7c9 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -754,18 +754,6 @@ 4BC3B6A50E703B2E0066E42F /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; 4BC3B6A60E703B2E0066E42F /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; 4BC3B6A70E703B2E0066E42F /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; - 4BCBCE5D10C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5910C4FE3F00450FFE /* JackPhysicalMidiInput.cpp */; }; - 4BCBCE5E10C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCBCE5A10C4FE3F00450FFE /* JackPhysicalMidiInput.h */; }; - 4BCBCE5F10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5B10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp */; }; - 4BCBCE6010C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCBCE5C10C4FE3F00450FFE /* JackPhysicalMidiOutput.h */; }; - 4BCBCE6110C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5910C4FE3F00450FFE /* JackPhysicalMidiInput.cpp */; }; - 4BCBCE6210C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCBCE5A10C4FE3F00450FFE /* JackPhysicalMidiInput.h */; }; - 4BCBCE6310C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5B10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp */; }; - 4BCBCE6410C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCBCE5C10C4FE3F00450FFE /* JackPhysicalMidiOutput.h */; }; - 4BCBCE6510C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5910C4FE3F00450FFE /* JackPhysicalMidiInput.cpp */; }; - 4BCBCE6610C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCBCE5A10C4FE3F00450FFE /* JackPhysicalMidiInput.h */; }; - 4BCBCE6710C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5B10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp */; }; - 4BCBCE6810C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCBCE5C10C4FE3F00450FFE /* JackPhysicalMidiOutput.h */; }; 4BCC87960D57168300A7FEB1 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; 4BCC87970D57168300A7FEB1 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; 4BCC87980D57168300A7FEB1 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; @@ -1642,10 +1630,6 @@ 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetUnixSocket.cpp; path = ../posix/JackNetUnixSocket.cpp; sourceTree = SOURCE_ROOT; }; 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackNetUnixSocket.h; path = ../posix/JackNetUnixSocket.h; sourceTree = SOURCE_ROOT; }; 4BC8326D0DF42C7D00DD1C93 /* JackMutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMutex.h; path = ../common/JackMutex.h; sourceTree = SOURCE_ROOT; }; - 4BCBCE5910C4FE3F00450FFE /* JackPhysicalMidiInput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackPhysicalMidiInput.cpp; path = ../common/JackPhysicalMidiInput.cpp; sourceTree = SOURCE_ROOT; }; - 4BCBCE5A10C4FE3F00450FFE /* JackPhysicalMidiInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackPhysicalMidiInput.h; path = ../common/JackPhysicalMidiInput.h; sourceTree = SOURCE_ROOT; }; - 4BCBCE5B10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackPhysicalMidiOutput.cpp; path = ../common/JackPhysicalMidiOutput.cpp; sourceTree = SOURCE_ROOT; }; - 4BCBCE5C10C4FE3F00450FFE /* JackPhysicalMidiOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackPhysicalMidiOutput.h; path = ../common/JackPhysicalMidiOutput.h; sourceTree = SOURCE_ROOT; }; 4BCC87950D57168300A7FEB1 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = /System/Library/Frameworks/Accelerate.framework; sourceTree = ""; }; 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackTransportEngine.h; path = ../common/JackTransportEngine.h; sourceTree = SOURCE_ROOT; }; 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackTransportEngine.cpp; path = ../common/JackTransportEngine.cpp; sourceTree = SOURCE_ROOT; }; @@ -2994,10 +2978,6 @@ 4BF3390D0F8B86AF0080FB5B /* MIDI */ = { isa = PBXGroup; children = ( - 4BCBCE5910C4FE3F00450FFE /* JackPhysicalMidiInput.cpp */, - 4BCBCE5A10C4FE3F00450FFE /* JackPhysicalMidiInput.h */, - 4BCBCE5B10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp */, - 4BCBCE5C10C4FE3F00450FFE /* JackPhysicalMidiOutput.h */, 4BF3391F0F8B873E0080FB5B /* JackMidiDriver.cpp */, 4BF339200F8B873E0080FB5B /* JackMidiDriver.h */, 4BF339140F8B86DC0080FB5B /* JackCoreMidiDriver.h */, @@ -3243,8 +3223,6 @@ 4BF339220F8B873E0080FB5B /* JackMidiDriver.h in Headers */, 4BDCDBD21001FD0200B15929 /* JackWaitThreadedDriver.h in Headers */, 4BDCDC0A1001FDA800B15929 /* JackArgParser.h in Headers */, - 4BCBCE6210C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */, - 4BCBCE6410C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */, 4B88D04311298BEE007A87C1 /* weakjack.h in Headers */, 4B88D04411298BEE007A87C1 /* weakmacros.h in Headers */, 4BC2CA5A113C6CB80076717C /* JackNetInterface.h in Headers */, @@ -3706,8 +3684,6 @@ 4BECB2F60F4451C10091B70A /* JackProcessSync.h in Headers */, 4BF339240F8B873E0080FB5B /* JackMidiDriver.h in Headers */, 4B94334B10A5E666002A187F /* systemdeps.h in Headers */, - 4BCBCE5E10C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */, - 4BCBCE6010C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */, 4B88D03D11298BEE007A87C1 /* weakjack.h in Headers */, 4B88D03E11298BEE007A87C1 /* weakmacros.h in Headers */, 4BC2CA56113C6C940076717C /* JackNetInterface.h in Headers */, @@ -3901,8 +3877,6 @@ 4BA3396D10B2E36800190E3B /* JackMidiDriver.h in Headers */, 4BA3396E10B2E36800190E3B /* JackWaitThreadedDriver.h in Headers */, 4BA3396F10B2E36800190E3B /* JackArgParser.h in Headers */, - 4BCBCE6610C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */, - 4BCBCE6810C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */, 4B88D04511298BEE007A87C1 /* weakjack.h in Headers */, 4B88D04611298BEE007A87C1 /* weakmacros.h in Headers */, 4BC2CA5E113C6CCA0076717C /* JackNetInterface.h in Headers */, @@ -6610,8 +6584,6 @@ 4BF339210F8B873E0080FB5B /* JackMidiDriver.cpp in Sources */, 4BDCDBD11001FD0100B15929 /* JackWaitThreadedDriver.cpp in Sources */, 4BDCDC091001FDA800B15929 /* JackArgParser.cpp in Sources */, - 4BCBCE6110C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */, - 4BCBCE6310C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */, 4BC2CA59113C6CB60076717C /* JackNetInterface.cpp in Sources */, 4BC2CA5B113C6CBE0076717C /* JackNetUnixSocket.cpp in Sources */, 4B8A38A7117B80D300664E07 /* JackSocket.cpp in Sources */, @@ -7064,8 +7036,6 @@ 4BBAE4110F42FA6100B8BD3F /* JackEngineProfiling.cpp in Sources */, 4BECB2F50F4451C10091B70A /* JackProcessSync.cpp in Sources */, 4BF339230F8B873E0080FB5B /* JackMidiDriver.cpp in Sources */, - 4BCBCE5D10C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */, - 4BCBCE5F10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */, 4BC2CA55113C6C930076717C /* JackNetInterface.cpp in Sources */, 4BC2CA57113C6C9B0076717C /* JackNetUnixSocket.cpp in Sources */, 4B2209E112F6BBF300E5DC26 /* JackSocketServerChannel.cpp in Sources */, @@ -7260,8 +7230,6 @@ 4BA339A210B2E36800190E3B /* JackMidiDriver.cpp in Sources */, 4BA339A310B2E36800190E3B /* JackWaitThreadedDriver.cpp in Sources */, 4BA339A410B2E36800190E3B /* JackArgParser.cpp in Sources */, - 4BCBCE6510C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */, - 4BCBCE6710C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */, 4BC2CA5D113C6CC90076717C /* JackNetInterface.cpp in Sources */, 4BC2CA5F113C6CD10076717C /* JackNetUnixSocket.cpp in Sources */, ); From 6e92bd8020ecf88fc8ccb6c3bec8b7ef6727480c Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Tue, 22 Mar 2011 15:10:59 -0700 Subject: [PATCH 061/472] Add 'alsarawmidi' driver, which is a slave MIDI driver that makes ALSA MIDI ports available to JACK. The driver uses the rawmidi devices, and uses the raw MIDI queues to optimize output. --- common/JackMidiRawInputWriteQueue.h | 2 +- common/JackMidiRawOutputWriteQueue.h | 2 +- example-clients/midi_latency_test.c | 4 - linux/alsarawmidi/JackALSARawMidiDriver.cpp | 586 ++++++++++++++++++ linux/alsarawmidi/JackALSARawMidiDriver.h | 79 +++ .../alsarawmidi/JackALSARawMidiInputPort.cpp | 121 ++++ linux/alsarawmidi/JackALSARawMidiInputPort.h | 43 ++ .../alsarawmidi/JackALSARawMidiOutputPort.cpp | 146 +++++ linux/alsarawmidi/JackALSARawMidiOutputPort.h | 44 ++ linux/alsarawmidi/JackALSARawMidiPort.cpp | 158 +++++ linux/alsarawmidi/JackALSARawMidiPort.h | 51 ++ .../JackALSARawMidiReceiveQueue.cpp | 35 ++ .../alsarawmidi/JackALSARawMidiReceiveQueue.h | 32 + .../alsarawmidi/JackALSARawMidiSendQueue.cpp | 40 ++ linux/alsarawmidi/JackALSARawMidiSendQueue.h | 32 + linux/wscript | 10 + 16 files changed, 1379 insertions(+), 6 deletions(-) create mode 100755 linux/alsarawmidi/JackALSARawMidiDriver.cpp create mode 100755 linux/alsarawmidi/JackALSARawMidiDriver.h create mode 100755 linux/alsarawmidi/JackALSARawMidiInputPort.cpp create mode 100755 linux/alsarawmidi/JackALSARawMidiInputPort.h create mode 100755 linux/alsarawmidi/JackALSARawMidiOutputPort.cpp create mode 100755 linux/alsarawmidi/JackALSARawMidiOutputPort.h create mode 100755 linux/alsarawmidi/JackALSARawMidiPort.cpp create mode 100755 linux/alsarawmidi/JackALSARawMidiPort.h create mode 100755 linux/alsarawmidi/JackALSARawMidiReceiveQueue.cpp create mode 100755 linux/alsarawmidi/JackALSARawMidiReceiveQueue.h create mode 100755 linux/alsarawmidi/JackALSARawMidiSendQueue.cpp create mode 100755 linux/alsarawmidi/JackALSARawMidiSendQueue.h diff --git a/common/JackMidiRawInputWriteQueue.h b/common/JackMidiRawInputWriteQueue.h index 2feff527..4639107f 100644 --- a/common/JackMidiRawInputWriteQueue.h +++ b/common/JackMidiRawInputWriteQueue.h @@ -161,7 +161,7 @@ namespace Jack { */ jack_nframes_t - Process(jack_nframes_t boundary_frame); + Process(jack_nframes_t boundary_frame=0); }; diff --git a/common/JackMidiRawOutputWriteQueue.h b/common/JackMidiRawOutputWriteQueue.h index b5e336dc..0437ec93 100644 --- a/common/JackMidiRawOutputWriteQueue.h +++ b/common/JackMidiRawOutputWriteQueue.h @@ -138,7 +138,7 @@ namespace Jack { */ jack_nframes_t - Process(jack_nframes_t boundary_frame); + Process(jack_nframes_t boundary_frame=0); }; diff --git a/example-clients/midi_latency_test.c b/example-clients/midi_latency_test.c index bcf54641..27c651c8 100644 --- a/example-clients/midi_latency_test.c +++ b/example-clients/midi_latency_test.c @@ -477,10 +477,6 @@ main(int argc, char **argv) error_source = "jack_connect"; goto deactivate_client; } - jack_port_get_latency_range(remote_in_port, JackCaptureLatency, - &in_latency_range); - jack_port_get_latency_range(remote_out_port, JackPlaybackLatency, - &out_latency_range); code = pthread_mutex_unlock(&start_mutex); if (code) { error_message = strerror(code); diff --git a/linux/alsarawmidi/JackALSARawMidiDriver.cpp b/linux/alsarawmidi/JackALSARawMidiDriver.cpp new file mode 100755 index 00000000..adbb89fb --- /dev/null +++ b/linux/alsarawmidi/JackALSARawMidiDriver.cpp @@ -0,0 +1,586 @@ +#include +#include +#include + +#include + +#include "JackALSARawMidiDriver.h" +#include "JackEngineControl.h" +#include "JackError.h" +#include "JackMidiUtil.h" + +using Jack::JackALSARawMidiDriver; + +JackALSARawMidiDriver::JackALSARawMidiDriver(const char *name, + const char *alias, + JackLockedEngine *engine, + JackSynchro *table): + JackMidiDriver(name, alias, engine, table) +{ + thread = new JackThread(this); + fCaptureChannels = 0; + fds[0] = -1; + fds[1] = -1; + fPlaybackChannels = 0; + input_ports = 0; + output_ports = 0; + poll_fds = 0; +} + +JackALSARawMidiDriver::~JackALSARawMidiDriver() +{ + Stop(); + delete thread; + Close(); +} + +int +JackALSARawMidiDriver::Attach() +{ + jack_nframes_t buffer_size = fEngineControl->fBufferSize; + jack_port_id_t index; + const char *name; + JackPort *port; + for (int i = 0; i < fCaptureChannels; i++) { + JackALSARawMidiInputPort *input_port = input_ports[i]; + name = input_port->GetName(); + index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, + JACK_DEFAULT_MIDI_TYPE, + CaptureDriverFlags, buffer_size); + if (index == NO_PORT) { + jack_error("JackALSARawMidiDriver::Attach - cannot register input " + "port with name '%s'.", name); + // X: Do we need to deallocate ports? + return -1; + } + port = fGraphManager->GetPort(index); + port->SetAlias(input_port->GetAlias()); + port->SetLatency(buffer_size); + fCapturePortList[i] = index; + } + for (int i = 0; i < fPlaybackChannels; i++) { + JackALSARawMidiOutputPort *output_port = output_ports[i]; + name = output_port->GetName(); + index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, + JACK_DEFAULT_MIDI_TYPE, + PlaybackDriverFlags, buffer_size); + if (index == NO_PORT) { + jack_error("JackALSARawMidiDriver::Attach - cannot register " + "output port with name '%s'.", name); + // X: Do we need to deallocate ports? + return -1; + } + port = fGraphManager->GetPort(index); + port->SetAlias(output_port->GetAlias()); + port->SetLatency(buffer_size); + fPlaybackPortList[i] = index; + } + return 0; +} + +int +JackALSARawMidiDriver::Close() +{ + if (input_ports) { + for (int i = 0; i < fCaptureChannels; i++) { + delete input_ports[i]; + } + delete[] input_ports; + input_ports = 0; + } + if (output_ports) { + for (int i = 0; i < fPlaybackChannels; i++) { + delete output_ports[i]; + } + delete[] output_ports; + output_ports = 0; + } + return 0; +} + +bool +JackALSARawMidiDriver::Execute() +{ + jack_nframes_t timeout_frame = 0; + for (;;) { + jack_time_t wait_time; + unsigned short revents; + if (! timeout_frame) { + wait_time = 0; + } else { + jack_time_t next_time = GetTimeFromFrames(timeout_frame); + jack_time_t now = GetMicroSeconds(); + + if (next_time <= now) { + goto handle_ports; + } + wait_time = next_time - now; + } + + jack_info("Calling 'Poll' with wait time '%d'.", wait_time); + + if (Poll(wait_time) == -1) { + if (errno == EINTR) { + continue; + } + jack_error("JackALSARawMidiDriver::Execute - poll error: %s", + strerror(errno)); + break; + } + revents = poll_fds[0].revents; + if (revents & POLLHUP) { + close(fds[0]); + fds[0] = -1; + break; + } + if (revents & (~(POLLHUP | POLLIN))) { + jack_error("JackALSARawMidiDriver::Execute - unexpected poll " + "event on pipe file descriptor."); + break; + } + handle_ports: + jack_nframes_t process_frame; + jack_nframes_t timeout_frame = 0; + for (int i = 0; i < fCaptureChannels; i++) { + process_frame = input_ports[i]->ProcessALSA(); + if (process_frame && ((! timeout_frame) || + (process_frame < timeout_frame))) { + timeout_frame = process_frame; + } + } + for (int i = 0; i < fPlaybackChannels; i++) { + process_frame = output_ports[i]->ProcessALSA(fds[0]); + if (process_frame && ((! timeout_frame) || + (process_frame < timeout_frame))) { + timeout_frame = process_frame; + } + } + } + + jack_info("ALSA thread is exiting."); + + return false; +} + +void +JackALSARawMidiDriver:: +GetDeviceInfo(snd_ctl_t *control, snd_rawmidi_info_t *info, + std::vector *info_list) +{ + snd_rawmidi_info_set_subdevice(info, 0); + int code = snd_ctl_rawmidi_info(control, info); + if (code) { + if (code != -ENOENT) { + HandleALSAError("GetDeviceInfo", "snd_ctl_rawmidi_info", code); + } + return; + } + unsigned int count = snd_rawmidi_info_get_subdevices_count(info); + for (unsigned int i = 0; i < count; i++) { + snd_rawmidi_info_set_subdevice(info, i); + int code = snd_ctl_rawmidi_info(control, info); + if (code) { + HandleALSAError("GetDeviceInfo", "snd_ctl_rawmidi_info", code); + continue; + } + snd_rawmidi_info_t *info_copy; + code = snd_rawmidi_info_malloc(&info_copy); + if (code) { + HandleALSAError("GetDeviceInfo", "snd_rawmidi_info_malloc", code); + continue; + } + snd_rawmidi_info_copy(info_copy, info); + try { + info_list->push_back(info_copy); + } catch (std::bad_alloc &e) { + snd_rawmidi_info_free(info_copy); + jack_error("JackALSARawMidiDriver::GetDeviceInfo - " + "std::vector::push_back: %s", e.what()); + } + } +} + +void +JackALSARawMidiDriver::HandleALSAError(const char *driver_func, + const char *alsa_func, int code) +{ + jack_error("JackALSARawMidiDriver::%s - %s: %s", driver_func, alsa_func, + snd_strerror(code)); +} + +bool +JackALSARawMidiDriver::Init() +{ + set_threaded_log_function(); + if (thread->AcquireSelfRealTime(fEngineControl->fServerPriority + 1)) { + jack_error("JackALSARawMidiDriver::Init - could not acquire realtime " + "scheduling. Continuing anyway."); + } + return true; +} + +int +JackALSARawMidiDriver::Open(bool capturing, bool playing, int in_channels, + int out_channels, bool monitor, + const char *capture_driver_name, + const char *playback_driver_name, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency) +{ + snd_rawmidi_info_t *info; + int code = snd_rawmidi_info_malloc(&info); + if (code) { + HandleALSAError("Open", "snd_rawmidi_info_malloc", code); + return -1; + } + std::vector in_info_list; + std::vector out_info_list; + for (int card = -1;;) { + int code = snd_card_next(&card); + if (code) { + HandleALSAError("Open", "snd_card_next", code); + continue; + } + if (card == -1) { + break; + } + char name[32]; + snprintf(name, sizeof(name), "hw:%d", card); + snd_ctl_t *control; + code = snd_ctl_open(&control, name, SND_CTL_NONBLOCK); + if (code) { + HandleALSAError("Open", "snd_ctl_open", code); + continue; + } + for (int device = -1;;) { + code = snd_ctl_rawmidi_next_device(control, &device); + if (code) { + HandleALSAError("Open", "snd_ctl_rawmidi_next_device", code); + continue; + } + if (device == -1) { + break; + } + snd_rawmidi_info_set_device(info, device); + snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_INPUT); + GetDeviceInfo(control, info, &in_info_list); + snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_OUTPUT); + GetDeviceInfo(control, info, &out_info_list); + } + snd_ctl_close(control); + } + snd_rawmidi_info_free(info); + size_t potential_inputs = in_info_list.size(); + size_t potential_outputs = out_info_list.size(); + if (! (potential_inputs || potential_outputs)) { + jack_error("JackALSARawMidiDriver::Open - no ALSA raw MIDI input or " + "output ports found."); + return -1; + } + + // XXX: Can't use auto_ptr here. These are arrays, and require the + // delete[] operator. + std::auto_ptr input_ptr; + if (potential_inputs) { + input_ports = new JackALSARawMidiInputPort *[potential_inputs]; + input_ptr.reset(input_ports); + } + std::auto_ptr output_ptr; + if (potential_outputs) { + output_ports = new JackALSARawMidiOutputPort *[potential_outputs]; + output_ptr.reset(output_ports); + } + + size_t num_inputs = 0; + size_t num_outputs = 0; + for (size_t i = 0; i < potential_inputs; i++) { + snd_rawmidi_info_t *info = in_info_list.at(i); + try { + input_ports[num_inputs] = new JackALSARawMidiInputPort(info, i); + + jack_info("JackALSARawMidiDriver::Open - Input port: card=%d, " + "device=%d, subdevice=%d, id=%s, name=%s, subdevice " + "name=%s", + snd_rawmidi_info_get_card(info), + snd_rawmidi_info_get_device(info), + snd_rawmidi_info_get_subdevice(info), + snd_rawmidi_info_get_id(info), + snd_rawmidi_info_get_name(info), + snd_rawmidi_info_get_subdevice_name(info)); + + num_inputs++; + } catch (std::exception e) { + jack_error("JackALSARawMidiDriver::Open - while creating new " + "JackALSARawMidiInputPort: %s", e.what()); + } + snd_rawmidi_info_free(info); + } + for (size_t i = 0; i < potential_outputs; i++) { + snd_rawmidi_info_t *info = out_info_list.at(i); + try { + output_ports[num_outputs] = new JackALSARawMidiOutputPort(info, i); + + jack_info("JackALSARawMidiDriver::Open - Output port: card=%d, " + "device=%d, subdevice=%d, id=%s, name=%s, subdevice " + "name=%s", + snd_rawmidi_info_get_card(info), + snd_rawmidi_info_get_device(info), + snd_rawmidi_info_get_subdevice(info), + snd_rawmidi_info_get_id(info), + snd_rawmidi_info_get_name(info), + snd_rawmidi_info_get_subdevice_name(info)); + + num_outputs++; + } catch (std::exception e) { + jack_error("JackALSARawMidiDriver::Open - while creating new " + "JackALSARawMidiOutputPort: %s", e.what()); + } + snd_rawmidi_info_free(info); + } + if (num_inputs || num_outputs) { + if (! JackMidiDriver::Open(capturing, playing, num_inputs, num_outputs, + monitor, capture_driver_name, + playback_driver_name, capture_latency, + playback_latency)) { + if (potential_inputs) { + input_ptr.release(); + } + if (potential_outputs) { + output_ptr.release(); + } + return 0; + } + jack_error("JackALSARawMidiDriver::Open - JackMidiDriver::Open error"); + } else { + jack_error("JackALSARawMidiDriver::Open - none of the potential " + "inputs or outputs were successfully opened."); + } + Close(); + return -1; +} + +#ifdef HAVE_PPOLL + +int +JackALSARawMidiDriver::Poll(jack_time_t wait_time) +{ + struct timespec timeout; + struct timespec *timeout_ptr; + if (! wait_time) { + timeout_ptr = 0; + } else { + timeout.tv_sec = wait_time / 1000000; + timeout.tv_nsec = (wait_time % 1000000) * 1000; + timeout_ptr = &timeout; + } + return ppoll(poll_fds, poll_fd_count, timeout_ptr, 0); +} + +#else + +int +JackALSARawMidiDriver::Poll(jack_time_t wait_time) +{ + int result = poll(poll_fds, poll_fd_count, + ! wait_time ? -1 : (int) (wait_time / 1000)); + if ((! result) && wait_time) { + wait_time %= 1000; + if (wait_time) { + // Cheap hack. + usleep(wait_time); + result = poll(poll_fds, poll_fd_count, 0); + } + } + return result; +} + +#endif + +int +JackALSARawMidiDriver::Read() +{ + for (int i = 0; i < fCaptureChannels; i++) { + input_ports[i]->ProcessJack(GetInputBuffer(i), + fEngineControl->fBufferSize); + } + return 0; +} + +int +JackALSARawMidiDriver::Start() +{ + + jack_info("JackALSARawMidiDriver::Start - Starting 'alsarawmidi' driver."); + + // JackMidiDriver::Start(); + + poll_fd_count = 1; + for (int i = 0; i < fCaptureChannels; i++) { + poll_fd_count += input_ports[i]->GetPollDescriptorCount(); + } + for (int i = 0; i < fPlaybackChannels; i++) { + poll_fd_count += output_ports[i]->GetPollDescriptorCount(); + } + try { + poll_fds = new pollfd[poll_fd_count]; + } catch (std::bad_alloc e) { + jack_error("JackALSARawMidiDriver::Start - creating poll descriptor " + "structures failed: %s", e.what()); + return -1; + } + int flags; + struct pollfd *poll_fd_iter; + if (pipe(fds) == -1) { + jack_error("JackALSARawMidiDriver::Start - while creating wake pipe: " + "%s", strerror(errno)); + goto free_poll_descriptors; + } + flags = fcntl(fds[0], F_GETFL); + if (flags == -1) { + jack_error("JackALSARawMidiDriver::Start = while getting flags for " + "read file descriptor: %s", strerror(errno)); + goto close_fds; + } + if (fcntl(fds[0], F_SETFL, flags | O_NONBLOCK) == -1) { + jack_error("JackALSARawMidiDriver::Start - while setting non-blocking " + "mode for read file descriptor: %s", strerror(errno)); + goto close_fds; + } + flags = fcntl(fds[1], F_GETFL); + if (flags == -1) { + jack_error("JackALSARawMidiDriver::Start = while getting flags for " + "write file descriptor: %s", strerror(errno)); + goto close_fds; + } + if (fcntl(fds[1], F_SETFL, flags | O_NONBLOCK) == -1) { + jack_error("JackALSARawMidiDriver::Start - while setting non-blocking " + "mode for write file descriptor: %s", strerror(errno)); + goto close_fds; + } + poll_fds[0].events = POLLERR | POLLIN | POLLNVAL; + poll_fds[0].fd = fds[0]; + poll_fd_iter = poll_fds + 1; + for (int i = 0; i < fCaptureChannels; i++) { + JackALSARawMidiInputPort *input_port = input_ports[i]; + input_port->PopulatePollDescriptors(poll_fd_iter); + poll_fd_iter += input_port->GetPollDescriptorCount(); + } + for (int i = 0; i < fPlaybackChannels; i++) { + JackALSARawMidiOutputPort *output_port = output_ports[i]; + output_port->PopulatePollDescriptors(poll_fd_iter); + poll_fd_iter += output_port->GetPollDescriptorCount(); + } + + jack_info("Starting ALSA thread ..."); + + if (! thread->StartSync()) { + + jack_info("Started ALSA thread."); + + return 0; + } + jack_error("JackALSARawMidiDriver::Start - failed to start MIDI " + "processing thread."); + close_fds: + close(fds[1]); + fds[1] = -1; + close(fds[0]); + fds[0] = -1; + free_poll_descriptors: + delete[] poll_fds; + poll_fds = 0; + return -1; +} + +int +JackALSARawMidiDriver::Stop() +{ + + jack_info("Stopping 'alsarawmidi' driver."); + + if (fds[1] != -1) { + close(fds[1]); + fds[1] = -1; + } + int result; + const char *verb; + switch (thread->GetStatus()) { + case JackThread::kIniting: + case JackThread::kStarting: + result = thread->Kill(); + verb = "kill"; + break; + case JackThread::kRunning: + result = thread->Stop(); + verb = "stop"; + break; + default: + result = 0; + verb = 0; + } + if (fds[0] != -1) { + close(fds[0]); + fds[0] = -1; + } + if (poll_fds) { + delete[] poll_fds; + poll_fds = 0; + } + if (result) { + jack_error("JackALSARawMidiDriver::Stop - could not %s MIDI " + "processing thread.", verb); + } + return result; +} + +int +JackALSARawMidiDriver::Write() +{ + jack_nframes_t buffer_size = fEngineControl->fBufferSize; + int write_fd = fds[1]; + for (int i = 0; i < fPlaybackChannels; i++) { + output_ports[i]->ProcessJack(GetOutputBuffer(i), buffer_size, + write_fd); + } + return 0; +} + +#ifdef __cplusplus +extern "C" { +#endif + + SERVER_EXPORT jack_driver_desc_t * + driver_get_descriptor() + { + jack_driver_desc_t *desc = + (jack_driver_desc_t *) malloc(sizeof(jack_driver_desc_t)); + if (desc) { + strcpy(desc->desc, "Alternative ALSA raw MIDI backend."); + strcpy(desc->name, "alsarawmidi"); + + // X: There could be parameters here regarding setting I/O buffer + // sizes. I don't think MIDI drivers can accept parameters right + // now without being set as the main driver. + desc->nparams = 0; + desc->params = 0; + } + return desc; + } + + SERVER_EXPORT Jack::JackDriverClientInterface * + driver_initialize(Jack::JackLockedEngine *engine, Jack::JackSynchro *table, + const JSList *params) + { + Jack::JackDriverClientInterface *driver = + new Jack::JackALSARawMidiDriver("system", "alsarawmidi", engine, + table); + if (driver->Open(1, 1, 0, 0, false, "midi in", "midi out", 0, 0)) { + delete driver; + driver = 0; + } + return driver; + } + +#ifdef __cplusplus +} +#endif diff --git a/linux/alsarawmidi/JackALSARawMidiDriver.h b/linux/alsarawmidi/JackALSARawMidiDriver.h new file mode 100755 index 00000000..5a793ebb --- /dev/null +++ b/linux/alsarawmidi/JackALSARawMidiDriver.h @@ -0,0 +1,79 @@ +#ifndef __JackALSARawMidiDriver__ +#define __JackALSARawMidiDriver__ + +#include + +#include +#include + +#include "JackALSARawMidiInputPort.h" +#include "JackALSARawMidiOutputPort.h" +#include "JackMidiDriver.h" +#include "JackThread.h" + +namespace Jack { + + class JackALSARawMidiDriver: + public JackMidiDriver, public JackRunnableInterface { + + private: + + int fds[2]; + JackALSARawMidiInputPort **input_ports; + JackALSARawMidiOutputPort **output_ports; + nfds_t poll_fd_count; + struct pollfd *poll_fds; + JackThread *thread; + + void + GetDeviceInfo(snd_ctl_t *control, snd_rawmidi_info_t *info, + std::vector *info_list); + + void + HandleALSAError(const char *driver_func, const char *alsa_func, + int code); + + int + Poll(jack_time_t wait_time); + + public: + + JackALSARawMidiDriver(const char *name, const char *alias, + JackLockedEngine *engine, JackSynchro *table); + ~JackALSARawMidiDriver(); + + int + Attach(); + + int + Close(); + + bool + Execute(); + + bool + Init(); + + int + Open(bool capturing, bool playing, int in_channels, int out_channels, + bool monitoring, const char *capture_driver_name, + const char *playback_driver_name, jack_nframes_t capture_latency, + jack_nframes_t playback_latency); + + int + Read(); + + int + Start(); + + int + Stop(); + + int + Write(); + + }; + +} + +#endif diff --git a/linux/alsarawmidi/JackALSARawMidiInputPort.cpp b/linux/alsarawmidi/JackALSARawMidiInputPort.cpp new file mode 100755 index 00000000..fe0d7911 --- /dev/null +++ b/linux/alsarawmidi/JackALSARawMidiInputPort.cpp @@ -0,0 +1,121 @@ +#include + +#include "JackALSARawMidiInputPort.h" +#include "JackMidiUtil.h" + +using Jack::JackALSARawMidiInputPort; + +JackALSARawMidiInputPort::JackALSARawMidiInputPort(snd_rawmidi_info_t *info, + size_t index, + size_t max_bytes, + size_t max_messages): + JackALSARawMidiPort(info, index) +{ + alsa_event = 0; + jack_event = 0; + receive_queue = new JackALSARawMidiReceiveQueue(rawmidi, max_bytes); + std::auto_ptr receive_ptr(receive_queue); + thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); + std::auto_ptr thread_ptr(thread_queue); + write_queue = new JackMidiBufferWriteQueue(); + std::auto_ptr write_ptr(write_queue); + raw_queue = new JackMidiRawInputWriteQueue(thread_queue, max_bytes, + max_messages); + write_ptr.release(); + thread_ptr.release(); + receive_ptr.release(); +} + +JackALSARawMidiInputPort::~JackALSARawMidiInputPort() +{ + delete raw_queue; + delete receive_queue; + delete thread_queue; + delete write_queue; +} + +jack_nframes_t +JackALSARawMidiInputPort::EnqueueALSAEvent() +{ + switch (raw_queue->EnqueueEvent(alsa_event)) { + case JackMidiWriteQueue::BUFFER_FULL: + // Processing events early might free up some space in the raw queue. + raw_queue->Process(); + switch (raw_queue->EnqueueEvent(alsa_event)) { + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + jack_error("JackALSARawMidiInputPort::Process - **BUG** " + "JackMidiRawInputWriteQueue::EnqueueEvent returned " + "`BUFFER_FULL` and then returned `BUFFER_TOO_SMALL` " + "after a `Process()` call."); + // Fallthrough on purpose + case JackMidiWriteQueue::OK: + return 0; + default: + ; + } + break; + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + jack_error("JackALSARawMidiInputPort::Execute - The thread queue " + "couldn't enqueue a %d-byte packet. Dropping event.", + alsa_event->size); + // Fallthrough on purpose + case JackMidiWriteQueue::OK: + return 0; + default: + ; + } + jack_nframes_t alsa_time = alsa_event->time; + jack_nframes_t next_time = raw_queue->Process(); + return (next_time < alsa_time) ? next_time : alsa_time; +} + +jack_nframes_t +JackALSARawMidiInputPort::ProcessALSA() +{ + unsigned short revents = ProcessPollEvents(); + jack_nframes_t frame; + if (alsa_event) { + frame = EnqueueALSAEvent(); + if (frame) { + return frame; + } + } + if (revents & POLLIN) { + for (alsa_event = receive_queue->DequeueEvent(); alsa_event; + alsa_event = receive_queue->DequeueEvent()) { + frame = EnqueueALSAEvent(); + if (frame) { + return frame; + } + } + } + return raw_queue->Process(); +} + +void +JackALSARawMidiInputPort::ProcessJack(JackMidiBuffer *port_buffer, + jack_nframes_t frames) +{ + write_queue->ResetMidiBuffer(port_buffer, frames); + if (! jack_event) { + jack_event = thread_queue->DequeueEvent(); + } + for (; jack_event; jack_event = thread_queue->DequeueEvent()) { + // We add `frames` so that MIDI events align with audio as closely as + // possible. + switch (write_queue->EnqueueEvent(jack_event->time + frames, + jack_event->size, + jack_event->buffer)) { + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + jack_error("JackALSARawMidiInputPort::Process - The write queue " + "couldn't enqueue a %d-byte event. Dropping event.", + jack_event->size); + // Fallthrough on purpose + case JackMidiWriteQueue::OK: + continue; + default: + ; + } + break; + } +} diff --git a/linux/alsarawmidi/JackALSARawMidiInputPort.h b/linux/alsarawmidi/JackALSARawMidiInputPort.h new file mode 100755 index 00000000..a5d5a2da --- /dev/null +++ b/linux/alsarawmidi/JackALSARawMidiInputPort.h @@ -0,0 +1,43 @@ +#ifndef __JackALSARawMidiInputPort__ +#define __JackALSARawMidiInputPort__ + +#include "JackALSARawMidiPort.h" +#include "JackALSARawMidiReceiveQueue.h" +#include "JackMidiAsyncQueue.h" +#include "JackMidiBufferWriteQueue.h" +#include "JackMidiRawInputWriteQueue.h" + +namespace Jack { + + class JackALSARawMidiInputPort: public JackALSARawMidiPort { + + private: + + jack_midi_event_t *alsa_event; + jack_midi_event_t *jack_event; + JackMidiRawInputWriteQueue *raw_queue; + JackALSARawMidiReceiveQueue *receive_queue; + JackMidiAsyncQueue *thread_queue; + JackMidiBufferWriteQueue *write_queue; + + jack_nframes_t + EnqueueALSAEvent(); + + public: + + JackALSARawMidiInputPort(snd_rawmidi_info_t *info, size_t index, + size_t max_bytes=4096, + size_t max_messages=1024); + ~JackALSARawMidiInputPort(); + + jack_nframes_t + ProcessALSA(); + + void + ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames); + + }; + +} + +#endif diff --git a/linux/alsarawmidi/JackALSARawMidiOutputPort.cpp b/linux/alsarawmidi/JackALSARawMidiOutputPort.cpp new file mode 100755 index 00000000..640d13f6 --- /dev/null +++ b/linux/alsarawmidi/JackALSARawMidiOutputPort.cpp @@ -0,0 +1,146 @@ +#include + +#include "JackALSARawMidiOutputPort.h" + +using Jack::JackALSARawMidiOutputPort; + +JackALSARawMidiOutputPort::JackALSARawMidiOutputPort(snd_rawmidi_info_t *info, + size_t index, + size_t max_bytes, + size_t max_messages): + JackALSARawMidiPort(info, index) +{ + alsa_event = 0; + blocked = false; + read_queue = new JackMidiBufferReadQueue(); + std::auto_ptr read_ptr(read_queue); + send_queue = new JackALSARawMidiSendQueue(rawmidi); + std::auto_ptr send_ptr(send_queue); + thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); + std::auto_ptr thread_ptr(thread_queue); + raw_queue = new JackMidiRawOutputWriteQueue(send_queue, max_bytes, + max_messages, max_messages); + thread_ptr.release(); + send_ptr.release(); + read_ptr.release(); +} + +JackALSARawMidiOutputPort::~JackALSARawMidiOutputPort() +{ + delete raw_queue; + delete read_queue; + delete send_queue; + delete thread_queue; +} + +jack_midi_event_t * +JackALSARawMidiOutputPort::DequeueALSAEvent(int read_fd) +{ + jack_midi_event_t *event = thread_queue->DequeueEvent(); + if (event) { + char c; + ssize_t result = read(read_fd, &c, 1); + if (! result) { + jack_error("JackALSARawMidiOutputPort::DequeueALSAEvent - **BUG** " + "An event was dequeued from the thread queue, but no " + "byte was available for reading from the pipe file " + "descriptor."); + } else if (result < 0) { + jack_error("JackALSARawMidiOutputPort::DequeueALSAEvent - error " + "reading a byte from the pipe file descriptor: %s", + strerror(errno)); + } + } + return event; +} + +jack_nframes_t +JackALSARawMidiOutputPort::ProcessALSA(int read_fd) +{ + unsigned short revents = ProcessPollEvents(); + if (blocked) { + if (! (revents & POLLOUT)) { + return 0; + } + blocked = false; + } + if (! alsa_event) { + alsa_event = DequeueALSAEvent(read_fd); + } + for (; alsa_event; alsa_event = DequeueALSAEvent(read_fd)) { + switch (raw_queue->EnqueueEvent(alsa_event)) { + case JackMidiWriteQueue::BUFFER_FULL: + // Try to free up some space by processing events early. + raw_queue->Process(); + switch (raw_queue->EnqueueEvent(alsa_event)) { + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + jack_error("JackALSARawMidiOutputPort::ProcessALSA - **BUG** " + "JackMidiRawOutputWriteQueue::EnqueueEvent " + "returned `BUFFER_FULL`, and then returned " + "`BUFFER_TOO_SMALL` after a Process() call."); + // Fallthrough on purpose + case JackMidiWriteQueue::OK: + continue; + default: + ; + } + goto process_events; + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + jack_error("JackALSARawMidiOutputPort::ProcessALSA - The raw " + "output queue couldn't enqueue a %d-byte event. " + "Dropping event.", alsa_event->size); + // Fallthrough on purpose + case JackMidiWriteQueue::OK: + continue; + default: + ; + } + break; + } + process_events: + jack_nframes_t next_frame = raw_queue->Process(); + blocked = send_queue->IsBlocked(); + if (blocked) { + SetPollEventMask(POLLERR | POLLNVAL | POLLOUT); + return 0; + } + SetPollEventMask(POLLERR | POLLNVAL); + return next_frame; +} + +void +JackALSARawMidiOutputPort::ProcessJack(JackMidiBuffer *port_buffer, + jack_nframes_t frames, int write_fd) +{ + read_queue->ResetMidiBuffer(port_buffer); + for (jack_midi_event_t *event = read_queue->DequeueEvent(); event; + event = read_queue->DequeueEvent()) { + if (event->size > thread_queue->GetAvailableSpace()) { + jack_error("JackALSARawMidiOutputPort::ProcessJack - The thread " + "queue doesn't have enough room to enqueue a %d-byte " + "event. Dropping event.", event->size); + continue; + } + char c = 1; + + jack_info("Attempting to write to file descriptor '%d'", write_fd); + + ssize_t result = write(write_fd, &c, 1); + assert(result <= 1); + if (! result) { + jack_error("JackALSARawMidiOutputPort::ProcessJack - Couldn't " + "write a byte to the pipe file descriptor. Dropping " + "event."); + } else if (result < 0) { + jack_error("JackALSARawMidiOutputPort::ProcessJack - error " + "writing a byte to the pipe file descriptor: %s", + strerror(errno)); + } else if (thread_queue->EnqueueEvent(event->time + frames, + event->size, event->buffer) != + JackMidiWriteQueue::OK) { + jack_error("JackALSARawMidiOutputPort::ProcessJack - **BUG** The " + "thread queue said it had enough space to enqueue a " + "%d-byte event, but failed to enqueue the event."); + } + } +} diff --git a/linux/alsarawmidi/JackALSARawMidiOutputPort.h b/linux/alsarawmidi/JackALSARawMidiOutputPort.h new file mode 100755 index 00000000..aea8f2ea --- /dev/null +++ b/linux/alsarawmidi/JackALSARawMidiOutputPort.h @@ -0,0 +1,44 @@ +#ifndef __JackALSARawMidiOutputPort__ +#define __JackALSARawMidiOutputPort__ + +#include "JackALSARawMidiPort.h" +#include "JackALSARawMidiSendQueue.h" +#include "JackMidiAsyncQueue.h" +#include "JackMidiBufferReadQueue.h" +#include "JackMidiRawOutputWriteQueue.h" + +namespace Jack { + + class JackALSARawMidiOutputPort: public JackALSARawMidiPort { + + private: + + jack_midi_event_t *alsa_event; + bool blocked; + JackMidiRawOutputWriteQueue *raw_queue; + JackMidiBufferReadQueue *read_queue; + JackALSARawMidiSendQueue *send_queue; + JackMidiAsyncQueue *thread_queue; + + jack_midi_event_t * + DequeueALSAEvent(int read_fd); + + public: + + JackALSARawMidiOutputPort(snd_rawmidi_info_t *info, size_t index, + size_t max_bytes=4096, + size_t max_messages=1024); + ~JackALSARawMidiOutputPort(); + + jack_nframes_t + ProcessALSA(int read_fd); + + void + ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames, + int write_fd); + + }; + +} + +#endif diff --git a/linux/alsarawmidi/JackALSARawMidiPort.cpp b/linux/alsarawmidi/JackALSARawMidiPort.cpp new file mode 100755 index 00000000..db476003 --- /dev/null +++ b/linux/alsarawmidi/JackALSARawMidiPort.cpp @@ -0,0 +1,158 @@ +#include +#include + +#include "JackALSARawMidiPort.h" +#include "JackError.h" + +using Jack::JackALSARawMidiPort; + +JackALSARawMidiPort::JackALSARawMidiPort(snd_rawmidi_info_t *info, + size_t index) +{ + char device_id[32]; + snprintf(device_id, sizeof(device_id), "hw:%d,%d,%d", + snd_rawmidi_info_get_card(info), + snd_rawmidi_info_get_device(info), + snd_rawmidi_info_get_subdevice(info)); + const char *alias_prefix; + const char *error_message; + snd_rawmidi_t **in; + snd_rawmidi_t **out; + const char *name_suffix; + if (snd_rawmidi_info_get_stream(info) == SND_RAWMIDI_STREAM_OUTPUT) { + alias_prefix = "system:midi_playback_"; + in = 0; + name_suffix = "out"; + out = &rawmidi; + } else { + alias_prefix = "system:midi_capture_"; + in = &rawmidi; + name_suffix = "in"; + out = 0; + } + const char *device_name; + const char *func; + int code = snd_rawmidi_open(in, out, device_id, SND_RAWMIDI_NONBLOCK); + if (code) { + error_message = snd_strerror(code); + func = "snd_rawmidi_open"; + goto handle_error; + } + snd_rawmidi_params_t *params; + code = snd_rawmidi_params_malloc(¶ms); + if (code) { + error_message = snd_strerror(code); + func = "snd_rawmidi_params_malloc"; + goto close; + } + code = snd_rawmidi_params_current(rawmidi, params); + if (code) { + error_message = snd_strerror(code); + func = "snd_rawmidi_params_current"; + goto close; + } + code = snd_rawmidi_params_set_avail_min(rawmidi, params, 1); + if (code) { + error_message = snd_strerror(code); + func = "snd_rawmidi_params_set_avail_min"; + goto free_params; + } + code = snd_rawmidi_params_set_no_active_sensing(rawmidi, params, 1); + if (code) { + error_message = snd_strerror(code); + func = "snd_rawmidi_params_set_no_active_sensing"; + goto free_params; + } + snd_rawmidi_params_free(params); + num_fds = snd_rawmidi_poll_descriptors_count(rawmidi); + if (! num_fds) { + error_message = "returned '0' count for poll descriptors"; + func = "snd_rawmidi_poll_descriptors_count"; + goto close; + } + snprintf(alias, sizeof(alias), "%s%d", alias_prefix, index); + device_name = snd_rawmidi_info_get_subdevice_name(info); + if (! strlen(device_name)) { + device_name = snd_rawmidi_info_get_name(info); + } + snprintf(name, sizeof(name), "system:%s %s", device_name, name_suffix); + return; + free_params: + snd_rawmidi_params_free(params); + close: + snd_rawmidi_close(rawmidi); + handle_error: + throw std::runtime_error(std::string(func) + ": " + error_message); +} + +JackALSARawMidiPort::~JackALSARawMidiPort() +{ + if (rawmidi) { + int code = snd_rawmidi_close(rawmidi); + if (code) { + jack_error("JackALSARawMidiPort::~JackALSARawMidiPort - " + "snd_rawmidi_close: %s", snd_strerror(code)); + } + rawmidi = 0; + } +} + +const char * +JackALSARawMidiPort::GetAlias() +{ + return alias; +} + +const char * +JackALSARawMidiPort::GetName() +{ + return name; +} + +int +JackALSARawMidiPort::GetPollDescriptorCount() +{ + return num_fds; +} + +bool +JackALSARawMidiPort::PopulatePollDescriptors(struct pollfd *poll_fd) +{ + bool result = snd_rawmidi_poll_descriptors(rawmidi, poll_fd, num_fds) == + num_fds; + if (result) { + poll_fds = poll_fd; + } + return result; +} + +int +JackALSARawMidiPort::ProcessPollEvents() +{ + unsigned short revents; + int code = snd_rawmidi_poll_descriptors_revents(rawmidi, poll_fds, num_fds, + &revents); + if (code) { + jack_error("JackALSARawMidiInputPort::ProcessPollEvents - " + "snd_rawmidi_poll_descriptors_revents: %s", + snd_strerror(code)); + return 0; + } + if (revents & POLLNVAL) { + jack_error("JackALSARawMidiInputPort::ProcessPollEvents - the file " + "descriptor is invalid."); + } + if (revents & POLLERR) { + jack_error("JackALSARawMidiInputPort::ProcessPollEvents - an error " + "has occurred on the device or stream."); + } + return revents; +} + +void +JackALSARawMidiPort::SetPollEventMask(unsigned short events) +{ + for (int i = 0; i < num_fds; i++) { + (poll_fds + i)->events = events; + } +} diff --git a/linux/alsarawmidi/JackALSARawMidiPort.h b/linux/alsarawmidi/JackALSARawMidiPort.h new file mode 100755 index 00000000..31ffd078 --- /dev/null +++ b/linux/alsarawmidi/JackALSARawMidiPort.h @@ -0,0 +1,51 @@ +#ifndef __JackALSARawMidiPort__ +#define __JackALSARawMidiPort__ + +#include +#include + +#include "JackConstants.h" + +namespace Jack { + + class JackALSARawMidiPort { + + private: + + char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + int num_fds; + struct pollfd *poll_fds; + + protected: + + snd_rawmidi_t *rawmidi; + + int + ProcessPollEvents(); + + void + SetPollEventMask(unsigned short events); + + public: + + JackALSARawMidiPort(snd_rawmidi_info_t *info, size_t index); + virtual ~JackALSARawMidiPort(); + + const char * + GetAlias(); + + const char * + GetName(); + + int + GetPollDescriptorCount(); + + bool + PopulatePollDescriptors(struct pollfd *poll_fd); + + }; + +} + +#endif diff --git a/linux/alsarawmidi/JackALSARawMidiReceiveQueue.cpp b/linux/alsarawmidi/JackALSARawMidiReceiveQueue.cpp new file mode 100755 index 00000000..a4b24bef --- /dev/null +++ b/linux/alsarawmidi/JackALSARawMidiReceiveQueue.cpp @@ -0,0 +1,35 @@ +#include "JackALSARawMidiReceiveQueue.h" +#include "JackError.h" +#include "JackMidiUtil.h" + +using Jack::JackALSARawMidiReceiveQueue; + +JackALSARawMidiReceiveQueue:: +JackALSARawMidiReceiveQueue(snd_rawmidi_t *rawmidi, size_t buffer_size) +{ + buffer = new jack_midi_data_t[buffer_size]; + this->buffer_size = buffer_size; + this->rawmidi = rawmidi; +} + +JackALSARawMidiReceiveQueue::~JackALSARawMidiReceiveQueue() +{ + delete[] buffer; +} + +jack_midi_event_t * +JackALSARawMidiReceiveQueue::DequeueEvent() +{ + ssize_t result = snd_rawmidi_read(rawmidi, buffer, buffer_size); + if (result > 0) { + event.buffer = buffer; + event.size = (size_t) result; + event.time = GetCurrentFrame(); + return &event; + } + if (result && (result != -EWOULDBLOCK)) { + jack_error("JackALSARawMidiReceiveQueue::DequeueEvent - " + "snd_rawmidi_read: %s", snd_strerror(result)); + } + return 0; +} diff --git a/linux/alsarawmidi/JackALSARawMidiReceiveQueue.h b/linux/alsarawmidi/JackALSARawMidiReceiveQueue.h new file mode 100755 index 00000000..a76c1e54 --- /dev/null +++ b/linux/alsarawmidi/JackALSARawMidiReceiveQueue.h @@ -0,0 +1,32 @@ +#ifndef __JackALSARawMidiReceiveQueue__ +#define __JackALSARawMidiReceiveQueue__ + +#include + +#include "JackMidiReceiveQueue.h" + +namespace Jack { + + class JackALSARawMidiReceiveQueue: public JackMidiReceiveQueue { + + private: + + jack_midi_data_t *buffer; + size_t buffer_size; + jack_midi_event_t event; + snd_rawmidi_t *rawmidi; + + public: + + JackALSARawMidiReceiveQueue(snd_rawmidi_t *rawmidi, + size_t buffer_size=4096); + ~JackALSARawMidiReceiveQueue(); + + jack_midi_event_t * + DequeueEvent(); + + }; + +} + +#endif diff --git a/linux/alsarawmidi/JackALSARawMidiSendQueue.cpp b/linux/alsarawmidi/JackALSARawMidiSendQueue.cpp new file mode 100755 index 00000000..5f314263 --- /dev/null +++ b/linux/alsarawmidi/JackALSARawMidiSendQueue.cpp @@ -0,0 +1,40 @@ +#include + +#include "JackALSARawMidiSendQueue.h" +#include "JackMidiUtil.h" + +using Jack::JackALSARawMidiSendQueue; + +JackALSARawMidiSendQueue::JackALSARawMidiSendQueue(snd_rawmidi_t *rawmidi) +{ + this->rawmidi = rawmidi; + blocked = false; +} + +Jack::JackMidiWriteQueue::EnqueueResult +JackALSARawMidiSendQueue::EnqueueEvent(jack_nframes_t time, size_t size, + jack_midi_data_t *buffer) +{ + assert(size == 1); + if (time > GetCurrentFrame()) { + return EVENT_EARLY; + } + ssize_t result = snd_rawmidi_write(rawmidi, buffer, 1); + switch (result) { + case 1: + blocked = false; + return OK; + case -EWOULDBLOCK: + blocked = true; + return BUFFER_FULL; + } + jack_error("JackALSARawMidiSendQueue::EnqueueEvent - snd_rawmidi_write: " + "%s", snd_strerror(result)); + return ERROR; +} + +bool +JackALSARawMidiSendQueue::IsBlocked() +{ + return blocked; +} diff --git a/linux/alsarawmidi/JackALSARawMidiSendQueue.h b/linux/alsarawmidi/JackALSARawMidiSendQueue.h new file mode 100755 index 00000000..f3f6542c --- /dev/null +++ b/linux/alsarawmidi/JackALSARawMidiSendQueue.h @@ -0,0 +1,32 @@ +#ifndef __JackALSARawMidiSendQueue__ +#define __JackALSARawMidiSendQueue__ + +#include + +#include "JackMidiSendQueue.h" + +namespace Jack { + + class JackALSARawMidiSendQueue: public JackMidiSendQueue { + + private: + + bool blocked; + snd_rawmidi_t *rawmidi; + + public: + + JackALSARawMidiSendQueue(snd_rawmidi_t *rawmidi); + + JackMidiWriteQueue::EnqueueResult + EnqueueEvent(jack_nframes_t time, size_t size, + jack_midi_data_t *buffer); + + bool + IsBlocked(); + + }; + +} + +#endif diff --git a/linux/wscript b/linux/wscript index c28da170..9c45817b 100644 --- a/linux/wscript +++ b/linux/wscript @@ -57,6 +57,14 @@ def build(bld): 'alsa/ice1712.c' ] + alsarawmidi_driver_src = ['alsarawmidi/JackALSARawMidiDriver.cpp', + 'alsarawmidi/JackALSARawMidiInputPort.cpp', + 'alsarawmidi/JackALSARawMidiOutputPort.cpp', + 'alsarawmidi/JackALSARawMidiPort.cpp', + 'alsarawmidi/JackALSARawMidiReceiveQueue.cpp', + 'alsarawmidi/JackALSARawMidiSendQueue.cpp' + ] + ffado_driver_src = ['firewire/JackFFADODriver.cpp', 'firewire/JackFFADOMidiInputPort.cpp', 'firewire/JackFFADOMidiOutputPort.cpp', @@ -66,6 +74,8 @@ def build(bld): if bld.env['BUILD_DRIVER_ALSA'] == True: create_jack_driver_obj(bld, 'alsa', alsa_driver_src, "ALSA") + create_jack_driver_obj(bld, 'alsarawmidi', alsarawmidi_driver_src, + "ALSA") if bld.env['BUILD_DRIVER_FREEBOB'] == True: create_jack_driver_obj(bld, 'freebob', 'freebob/JackFreebobDriver.cpp', "LIBFREEBOB") From 4ced89b41c7bb0d67d074439044e3fcd29e51d00 Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Tue, 22 Mar 2011 15:13:10 -0700 Subject: [PATCH 062/472] Minor library change that I forgot to add to the last commit. Adds a method to asynchronous queues that checks to available write space in the queue. --- common/JackMidiAsyncQueue.cpp | 7 +++++++ common/JackMidiAsyncQueue.h | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/common/JackMidiAsyncQueue.cpp b/common/JackMidiAsyncQueue.cpp index 85a93b18..0cfa42dc 100644 --- a/common/JackMidiAsyncQueue.cpp +++ b/common/JackMidiAsyncQueue.cpp @@ -94,3 +94,10 @@ JackMidiAsyncQueue::EnqueueEvent(jack_nframes_t time, size_t size, jack_ringbuffer_write(info_ring, (const char *) (&size), sizeof(size_t)); return OK; } + +size_t +JackMidiAsyncQueue::GetAvailableSpace() +{ + return jack_ringbuffer_write_space(info_ring) < INFO_SIZE ? 0 : + max_bytes - jack_ringbuffer_read_space(byte_ring); +} diff --git a/common/JackMidiAsyncQueue.h b/common/JackMidiAsyncQueue.h index 22948cc9..a9ac84ce 100644 --- a/common/JackMidiAsyncQueue.h +++ b/common/JackMidiAsyncQueue.h @@ -84,6 +84,13 @@ namespace Jack { EnqueueEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer); + /** + * Returns the maximum size event that can be enqueued right *now*. + */ + + size_t + GetAvailableSpace(); + }; } From e2683cb02435b91f43dfbc943c31831a55881bf5 Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Wed, 23 Mar 2011 02:44:24 -0700 Subject: [PATCH 063/472] Fix 'alsarawmidi' driver so that it actually works. Add functionality to 'midi_latency_test'. Fix bug in raw write queue implementation. Output error message when a source MIDI port isn't valid during mixdown. Output error messages for error conditions detected in buffer read and write queues. --- common/JackMidiBufferReadQueue.cpp | 16 ++++- common/JackMidiBufferWriteQueue.cpp | 18 ++++-- common/JackMidiPort.cpp | 7 +- common/JackMidiRawInputWriteQueue.cpp | 2 +- example-clients/midi_latency_test.c | 39 +++++++---- linux/alsarawmidi/JackALSARawMidiDriver.cpp | 64 +++++++++---------- linux/alsarawmidi/JackALSARawMidiDriver.h | 2 +- .../alsarawmidi/JackALSARawMidiInputPort.cpp | 1 + .../alsarawmidi/JackALSARawMidiOutputPort.cpp | 7 +- linux/alsarawmidi/JackALSARawMidiPort.cpp | 12 ++-- linux/alsarawmidi/JackALSARawMidiPort.h | 4 +- 11 files changed, 106 insertions(+), 66 deletions(-) diff --git a/common/JackMidiBufferReadQueue.cpp b/common/JackMidiBufferReadQueue.cpp index 66777eb0..c53e596c 100644 --- a/common/JackMidiBufferReadQueue.cpp +++ b/common/JackMidiBufferReadQueue.cpp @@ -46,12 +46,22 @@ JackMidiBufferReadQueue::DequeueEvent() void JackMidiBufferReadQueue::ResetMidiBuffer(JackMidiBuffer *buffer) { + event_count = 0; index = 0; - if (buffer) { + if (! buffer) { + jack_error("JackMidiBufferReadQueue::ResetMidiBuffer - buffer reset " + "to NULL"); + } else if (! buffer->IsValid()) { + jack_error("JackMidiBufferReadQueue::ResetMidiBuffer - buffer reset " + "to invalid buffer"); + } else { + uint32_t lost_events = buffer->lost_events; + if (lost_events) { + jack_error("JackMidiBufferReadQueue::ResetMidiBuffer - %d events " + "lost during mixdown", lost_events); + } this->buffer = buffer; event_count = buffer->event_count; last_frame_time = GetLastFrame(); - } else { - event_count = 0; } } diff --git a/common/JackMidiBufferWriteQueue.cpp b/common/JackMidiBufferWriteQueue.cpp index 5caab49d..7e6ae67f 100644 --- a/common/JackMidiBufferWriteQueue.cpp +++ b/common/JackMidiBufferWriteQueue.cpp @@ -49,9 +49,17 @@ void JackMidiBufferWriteQueue::ResetMidiBuffer(JackMidiBuffer *buffer, jack_nframes_t frames) { - this->buffer = buffer; - buffer->Reset(frames); - last_frame_time = GetLastFrame(); - max_bytes = buffer->MaxEventSize(); - next_frame_time = last_frame_time + frames; + if (! buffer) { + jack_error("JackMidiBufferWriteQueue::ResetMidiBuffer - buffer reset " + "to NULL"); + } else if (! buffer->IsValid()) { + jack_error("JackMidiBufferWriteQueue::ResetMidiBuffer - buffer reset " + "to invalid buffer"); + } else { + this->buffer = buffer; + buffer->Reset(frames); + last_frame_time = GetLastFrame(); + max_bytes = buffer->MaxEventSize(); + next_frame_time = last_frame_time + frames; + } } diff --git a/common/JackMidiPort.cpp b/common/JackMidiPort.cpp index 42ee245c..5bd82341 100644 --- a/common/JackMidiPort.cpp +++ b/common/JackMidiPort.cpp @@ -55,7 +55,6 @@ SERVER_EXPORT jack_midi_data_t* JackMidiBuffer::ReserveEvent(jack_nframes_t time lost_events++; return 0; } - JackMidiEvent* event = &events[event_count++]; event->time = time; event->size = size; @@ -90,7 +89,7 @@ static void MidiBufferMixdown(void* mixbuffer, void** src_buffers, int src_count { JackMidiBuffer* mix = static_cast(mixbuffer); if (!mix->IsValid()) { - jack_error("MIDI: invalid mix buffer"); + jack_error("Jack::MidiBufferMixdown - invalid mix buffer"); return; } mix->Reset(nframes); @@ -98,8 +97,10 @@ static void MidiBufferMixdown(void* mixbuffer, void** src_buffers, int src_count int event_count = 0; for (int i = 0; i < src_count; ++i) { JackMidiBuffer* buf = static_cast(src_buffers[i]); - if (!buf->IsValid()) + if (!buf->IsValid()) { + jack_error("Jack::MidiBufferMixdown - invalid source buffer"); return; + } buf->mix_index = 0; event_count += buf->event_count; mix->lost_events += buf->lost_events; diff --git a/common/JackMidiRawInputWriteQueue.cpp b/common/JackMidiRawInputWriteQueue.cpp index e2ff4453..f2853160 100644 --- a/common/JackMidiRawInputWriteQueue.cpp +++ b/common/JackMidiRawInputWriteQueue.cpp @@ -282,7 +282,7 @@ JackMidiRawInputWriteQueue::RecordByte(jack_midi_data_t byte) bool JackMidiRawInputWriteQueue::WriteEvent(jack_nframes_t boundary_frame) { - if (event.time < boundary_frame) { + if ((! boundary_frame) || (event.time < boundary_frame)) { switch (write_queue->EnqueueEvent(&event)) { case BUFFER_TOO_SMALL: HandleEventLoss(&event); diff --git a/example-clients/midi_latency_test.c b/example-clients/midi_latency_test.c index 27c651c8..732fe2ab 100644 --- a/example-clients/midi_latency_test.c +++ b/example-clients/midi_latency_test.c @@ -85,7 +85,8 @@ jack_nframes_t lowest_latency; jack_time_t lowest_latency_time; jack_midi_data_t *message_1; jack_midi_data_t *message_2; -size_t messages_processed; +size_t messages_received; +size_t messages_sent; size_t message_size; jack_latency_range_t out_latency_range; jack_port_t *out_port; @@ -100,6 +101,7 @@ int timeout; jack_nframes_t total_latency; jack_time_t total_latency_time; size_t unexpected_messages; +size_t xrun_count; static void output_error(const char *source, const char *message); @@ -156,11 +158,13 @@ handle_process(jack_nframes_t frames, void *arg) } highest_latency = 0; lowest_latency = 0; - messages_processed = 0; + messages_received = 0; + messages_sent = 0; process_state = 1; total_latency = 0; total_latency_time = 0; unexpected_messages = 0; + xrun_count = 0; jack_port_get_latency_range(remote_in_port, JackCaptureLatency, &in_latency_range); jack_port_get_latency_range(remote_out_port, JackPlaybackLatency, @@ -175,7 +179,7 @@ handle_process(jack_nframes_t frames, void *arg) last_frame_time = jack_last_frame_time(client); for (i = 0; i < event_count; i++) { jack_midi_event_get(&event, port_buffer, i); - message = (messages_processed % 2) ? message_2 : message_1; + message = (messages_received % 2) ? message_2 : message_1; if ((event.size == message_size) && (! memcmp(message, event.buffer, message_size * sizeof(jack_midi_data_t)))) { @@ -201,20 +205,20 @@ handle_process(jack_nframes_t frames, void *arg) lowest_latency = frame; lowest_latency_time = time; } - latency_time_values[messages_processed] = time; - latency_values[messages_processed] = frame; + latency_time_values[messages_received] = time; + latency_values[messages_received] = frame; total_latency += frame; total_latency_time += time; - messages_processed++; - if (messages_processed == samples) { + messages_received++; + if (messages_received == samples) { process_state = 2; sem_post(&semaphore); break; } send_message: frame = (jack_nframes_t) ((((double) rand()) / RAND_MAX) * frames); - if (frame == frames) { - frame--; + if (frame >= frames) { + frame = frames - 1; } port_buffer = jack_port_get_buffer(out_port, frames); jack_midi_clear_buffer(port_buffer); @@ -223,10 +227,11 @@ handle_process(jack_nframes_t frames, void *arg) set_process_error(SOURCE_EVENT_RESERVE, ERROR_RESERVE); break; } - message = (messages_processed % 2) ? message_2 : message_1; + message = (messages_sent % 2) ? message_2 : message_1; memcpy(buffer, message, message_size * sizeof(jack_midi_data_t)); last_activity = jack_last_frame_time(client) + frame; last_activity_time = jack_frames_to_time(client, last_activity); + messages_sent++; case 2: /* State: finished - do nothing */ @@ -245,6 +250,12 @@ handle_shutdown(void *arg) set_process_error("handle_shutdown", "The JACK server has been shutdown"); } +static void +handle_xrun(void *arg) +{ + xrun_count++; +} + static void output_error(const char *source, const char *message) { @@ -551,8 +562,14 @@ main(int argc, char **argv) printf(" > 10 ms: %u\n", jitter_plot[100]); } } + printf("\nMessages sent: %d\n" + "Messages received: %d\n", + messages_sent, messages_received); if (unexpected_messages) { - printf("\nUnexpected messages received: %d\n", unexpected_messages); + printf("Unexpected messages received: %d\n", unexpected_messages); + } + if (xrun_count) { + printf("Xruns: %d (messages may have been lost)", xrun_count); } deactivate_client: jack_deactivate(client); diff --git a/linux/alsarawmidi/JackALSARawMidiDriver.cpp b/linux/alsarawmidi/JackALSARawMidiDriver.cpp index adbb89fb..8e564c76 100755 --- a/linux/alsarawmidi/JackALSARawMidiDriver.cpp +++ b/linux/alsarawmidi/JackALSARawMidiDriver.cpp @@ -39,8 +39,12 @@ JackALSARawMidiDriver::Attach() { jack_nframes_t buffer_size = fEngineControl->fBufferSize; jack_port_id_t index; + jack_nframes_t latency = buffer_size; + jack_latency_range_t latency_range; const char *name; JackPort *port; + latency_range.max = latency; + latency_range.min = latency; for (int i = 0; i < fCaptureChannels; i++) { JackALSARawMidiInputPort *input_port = input_ports[i]; name = input_port->GetName(); @@ -55,9 +59,14 @@ JackALSARawMidiDriver::Attach() } port = fGraphManager->GetPort(index); port->SetAlias(input_port->GetAlias()); - port->SetLatency(buffer_size); + port->SetLatencyRange(JackCaptureLatency, &latency_range); fCapturePortList[i] = index; } + if (! fEngineControl->fSyncMode) { + latency += buffer_size; + latency_range.max = latency; + latency_range.min = latency; + } for (int i = 0; i < fPlaybackChannels; i++) { JackALSARawMidiOutputPort *output_port = output_ports[i]; name = output_port->GetName(); @@ -72,7 +81,7 @@ JackALSARawMidiDriver::Attach() } port = fGraphManager->GetPort(index); port->SetAlias(output_port->GetAlias()); - port->SetLatency(buffer_size); + port->SetLatencyRange(JackPlaybackLatency, &latency_range); fPlaybackPortList[i] = index; } return 0; @@ -103,23 +112,19 @@ JackALSARawMidiDriver::Execute() { jack_nframes_t timeout_frame = 0; for (;;) { + jack_nframes_t process_frame; jack_time_t wait_time; + jack_time_t *wait_time_ptr; unsigned short revents; if (! timeout_frame) { - wait_time = 0; + wait_time_ptr = 0; } else { jack_time_t next_time = GetTimeFromFrames(timeout_frame); jack_time_t now = GetMicroSeconds(); - - if (next_time <= now) { - goto handle_ports; - } - wait_time = next_time - now; + wait_time = next_time <= now ? 0 : next_time - now; + wait_time_ptr = &wait_time; } - - jack_info("Calling 'Poll' with wait time '%d'.", wait_time); - - if (Poll(wait_time) == -1) { + if (Poll(wait_time_ptr) == -1) { if (errno == EINTR) { continue; } @@ -139,8 +144,7 @@ JackALSARawMidiDriver::Execute() break; } handle_ports: - jack_nframes_t process_frame; - jack_nframes_t timeout_frame = 0; + timeout_frame = 0; for (int i = 0; i < fCaptureChannels; i++) { process_frame = input_ports[i]->ProcessALSA(); if (process_frame && ((! timeout_frame) || @@ -156,9 +160,6 @@ JackALSARawMidiDriver::Execute() } } } - - jack_info("ALSA thread is exiting."); - return false; } @@ -362,15 +363,15 @@ JackALSARawMidiDriver::Open(bool capturing, bool playing, int in_channels, #ifdef HAVE_PPOLL int -JackALSARawMidiDriver::Poll(jack_time_t wait_time) +JackALSARawMidiDriver::Poll(const jack_time_t *wait_time) { struct timespec timeout; struct timespec *timeout_ptr; if (! wait_time) { timeout_ptr = 0; } else { - timeout.tv_sec = wait_time / 1000000; - timeout.tv_nsec = (wait_time % 1000000) * 1000; + timeout.tv_sec = (*wait_time) / 1000000; + timeout.tv_nsec = ((*wait_time) % 1000000) * 1000; timeout_ptr = &timeout; } return ppoll(poll_fds, poll_fd_count, timeout_ptr, 0); @@ -379,15 +380,15 @@ JackALSARawMidiDriver::Poll(jack_time_t wait_time) #else int -JackALSARawMidiDriver::Poll(jack_time_t wait_time) +JackALSARawMidiDriver::Poll(const jack_time_t *wait_time) { int result = poll(poll_fds, poll_fd_count, - ! wait_time ? -1 : (int) (wait_time / 1000)); + ! wait_time ? -1 : (int) ((*wait_time) / 1000)); if ((! result) && wait_time) { - wait_time %= 1000; - if (wait_time) { + jack_time_t time_left = (*wait_time) % 1000; + if (time_left) { // Cheap hack. - usleep(wait_time); + usleep(time_left); result = poll(poll_fds, poll_fd_count, 0); } } @@ -399,9 +400,9 @@ JackALSARawMidiDriver::Poll(jack_time_t wait_time) int JackALSARawMidiDriver::Read() { + jack_nframes_t buffer_size = fEngineControl->fBufferSize; for (int i = 0; i < fCaptureChannels; i++) { - input_ports[i]->ProcessJack(GetInputBuffer(i), - fEngineControl->fBufferSize); + input_ports[i]->ProcessJack(GetInputBuffer(i), buffer_size); } return 0; } @@ -412,8 +413,7 @@ JackALSARawMidiDriver::Start() jack_info("JackALSARawMidiDriver::Start - Starting 'alsarawmidi' driver."); - // JackMidiDriver::Start(); - + JackMidiDriver::Start(); poll_fd_count = 1; for (int i = 0; i < fCaptureChannels; i++) { poll_fd_count += input_ports[i]->GetPollDescriptorCount(); @@ -471,11 +471,11 @@ JackALSARawMidiDriver::Start() poll_fd_iter += output_port->GetPollDescriptorCount(); } - jack_info("Starting ALSA thread ..."); + jack_info("JackALSARawMidiDriver::Start - starting ALSA thread ..."); if (! thread->StartSync()) { - jack_info("Started ALSA thread."); + jack_info("JackALSARawMidiDriver::Start - started ALSA thread."); return 0; } @@ -496,7 +496,7 @@ int JackALSARawMidiDriver::Stop() { - jack_info("Stopping 'alsarawmidi' driver."); + jack_info("JackALSARawMidiDriver::Stop - stopping 'alsarawmidi' driver."); if (fds[1] != -1) { close(fds[1]); diff --git a/linux/alsarawmidi/JackALSARawMidiDriver.h b/linux/alsarawmidi/JackALSARawMidiDriver.h index 5a793ebb..0ffc4e52 100755 --- a/linux/alsarawmidi/JackALSARawMidiDriver.h +++ b/linux/alsarawmidi/JackALSARawMidiDriver.h @@ -34,7 +34,7 @@ namespace Jack { int code); int - Poll(jack_time_t wait_time); + Poll(const jack_time_t *wait_time); public: diff --git a/linux/alsarawmidi/JackALSARawMidiInputPort.cpp b/linux/alsarawmidi/JackALSARawMidiInputPort.cpp index fe0d7911..94ae8c4a 100755 --- a/linux/alsarawmidi/JackALSARawMidiInputPort.cpp +++ b/linux/alsarawmidi/JackALSARawMidiInputPort.cpp @@ -101,6 +101,7 @@ JackALSARawMidiInputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_event = thread_queue->DequeueEvent(); } for (; jack_event; jack_event = thread_queue->DequeueEvent()) { + // We add `frames` so that MIDI events align with audio as closely as // possible. switch (write_queue->EnqueueEvent(jack_event->time + frames, diff --git a/linux/alsarawmidi/JackALSARawMidiOutputPort.cpp b/linux/alsarawmidi/JackALSARawMidiOutputPort.cpp index 640d13f6..df1fc268 100755 --- a/linux/alsarawmidi/JackALSARawMidiOutputPort.cpp +++ b/linux/alsarawmidi/JackALSARawMidiOutputPort.cpp @@ -101,6 +101,10 @@ JackALSARawMidiOutputPort::ProcessALSA(int read_fd) jack_nframes_t next_frame = raw_queue->Process(); blocked = send_queue->IsBlocked(); if (blocked) { + + jack_info("JackALSARawMidiOutputPort::ProcessALSA - MIDI port is " + "blocked"); + SetPollEventMask(POLLERR | POLLNVAL | POLLOUT); return 0; } @@ -122,9 +126,6 @@ JackALSARawMidiOutputPort::ProcessJack(JackMidiBuffer *port_buffer, continue; } char c = 1; - - jack_info("Attempting to write to file descriptor '%d'", write_fd); - ssize_t result = write(write_fd, &c, 1); assert(result <= 1); if (! result) { diff --git a/linux/alsarawmidi/JackALSARawMidiPort.cpp b/linux/alsarawmidi/JackALSARawMidiPort.cpp index db476003..a2d3d8fc 100755 --- a/linux/alsarawmidi/JackALSARawMidiPort.cpp +++ b/linux/alsarawmidi/JackALSARawMidiPort.cpp @@ -49,7 +49,7 @@ JackALSARawMidiPort::JackALSARawMidiPort(snd_rawmidi_info_t *info, if (code) { error_message = snd_strerror(code); func = "snd_rawmidi_params_current"; - goto close; + goto free_params; } code = snd_rawmidi_params_set_avail_min(rawmidi, params, 1); if (code) { @@ -129,22 +129,22 @@ JackALSARawMidiPort::PopulatePollDescriptors(struct pollfd *poll_fd) int JackALSARawMidiPort::ProcessPollEvents() { - unsigned short revents; + unsigned short revents = 0; int code = snd_rawmidi_poll_descriptors_revents(rawmidi, poll_fds, num_fds, &revents); if (code) { - jack_error("JackALSARawMidiInputPort::ProcessPollEvents - " + jack_error("JackALSARawMidiPort::ProcessPollEvents - " "snd_rawmidi_poll_descriptors_revents: %s", snd_strerror(code)); return 0; } if (revents & POLLNVAL) { - jack_error("JackALSARawMidiInputPort::ProcessPollEvents - the file " + jack_error("JackALSARawMidiPort::ProcessPollEvents - the file " "descriptor is invalid."); } if (revents & POLLERR) { - jack_error("JackALSARawMidiInputPort::ProcessPollEvents - an error " - "has occurred on the device or stream."); + jack_error("JackALSARawMidiPort::ProcessPollEvents - an error has " + "occurred on the device or stream."); } return revents; } diff --git a/linux/alsarawmidi/JackALSARawMidiPort.h b/linux/alsarawmidi/JackALSARawMidiPort.h index 31ffd078..564e5b7b 100755 --- a/linux/alsarawmidi/JackALSARawMidiPort.h +++ b/linux/alsarawmidi/JackALSARawMidiPort.h @@ -30,7 +30,9 @@ namespace Jack { public: JackALSARawMidiPort(snd_rawmidi_info_t *info, size_t index); - virtual ~JackALSARawMidiPort(); + + virtual + ~JackALSARawMidiPort(); const char * GetAlias(); From 6c5a4ceb84139d56d58850705a4541c4045a04b0 Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Wed, 23 Mar 2011 02:48:34 -0700 Subject: [PATCH 064/472] Strangeness concerning the 'Process()' implementation in the JackMidiDriver class: In async mode, if the Write method is run before ResumeRefNum, then events are occasionally lost. This also happens in sync mode, though it shouldn't. I'm committing what I *think* should be the proper implementation, but it's still buggy in sync mode (works in async mode), and I'm not sure why. Someone that's more familiar with JACK 2 threading should take a look at this, remembering that the MIDI drivers are slave drivers. --- common/JackMidiDriver.cpp | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/common/JackMidiDriver.cpp b/common/JackMidiDriver.cpp index 15d507b1..82a3e29a 100644 --- a/common/JackMidiDriver.cpp +++ b/common/JackMidiDriver.cpp @@ -140,26 +140,36 @@ int JackMidiDriver::ProcessNull() int JackMidiDriver::Process() { - // Read input buffers for the current cycle if (Read() < 0) { jack_error("JackMidiDriver::Process: read error, skip cycle"); return 0; // Skip cycle, but continue processing... } - fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); if (fEngineControl->fSyncMode) { - if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, fEngineControl->fTimeOutUsecs) < 0) { - jack_error("JackFreewheelDriver::ProcessSync SuspendRefNum error"); - return -1; + int res = 0; + if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { + jack_error("JackMidiDriver::Process - ResumeRefNum error"); + res = -1; + } + if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, + DRIVER_TIMEOUT_FACTOR * + fEngineControl->fTimeOutUsecs) < 0) { + jack_error("JackMidiDriver::Process - SuspendRefNum error"); + res = -1; + } + if (Write() < 0) { + jack_error("JackMidiDriver::Process - Write error"); } + return res; } - // Write output buffers for the current cycle + // Not in sync mode + if (Write() < 0) { - jack_error("JackMidiDriver::Process: write error, skip cycle"); - return 0; // Skip cycle, but continue processing... + jack_error("JackMidiDriver::Process - Write error"); + } else { + fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); } - return 0; } From ea20f7f4b81f4a37e4590cc202c961794bf2b589 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Wed, 23 Mar 2011 14:54:06 +0100 Subject: [PATCH 065/472] JackMidiDriver::Process in progress. --- common/JackMidiDriver.cpp | 60 +++++++++++++++++++++++++++++++++++++++ common/JackMidiDriver.h | 14 +++++---- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/common/JackMidiDriver.cpp b/common/JackMidiDriver.cpp index 82a3e29a..b8993e7a 100644 --- a/common/JackMidiDriver.cpp +++ b/common/JackMidiDriver.cpp @@ -138,6 +138,7 @@ int JackMidiDriver::ProcessNull() return 0; } +/* int JackMidiDriver::Process() { if (Read() < 0) { @@ -172,6 +173,65 @@ int JackMidiDriver::Process() } return 0; } +*/ + +int JackMidiDriver::Process() +{ + return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync(); +} + +int JackMidiDriver::ProcessSync() +{ + int res = 0; + + // Read input buffers for the current cycle + if (Read() < 0) { + jack_error("JackMidiDriver::ProcessSync: read error, skip cycle"); + return 0; // Skip cycle, but continue processing... + } + + if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { + jack_error("JackMidiDriver::ProcessSync - ResumeRefNum error"); + res = -1; + } + + if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, + DRIVER_TIMEOUT_FACTOR * + fEngineControl->fTimeOutUsecs) < 0) { + jack_error("JackMidiDriver::ProcessSync - SuspendRefNum error"); + res = -1; + } + + // Write output buffers from the current cycle + if (Write() < 0) { + jack_error("JackMidiDriver::ProcessSync - Write error"); + } + + return res; +} + +int JackMidiDriver::ProcessAsync() +{ + int res = 0; + + // Read input buffers for the current cycle + if (Read() < 0) { + jack_error("JackMidiDriver::ProcessAsync: read error, skip cycle"); + return 0; // Skip cycle, but continue processing... + } + + // Write output buffers from the previous cycle + if (Write() < 0) { + jack_error("JackMidiDriver::ProcessAsync - Write error"); + } + + if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { + jack_error("JackMidiDriver::ProcessAsync - ResumeRefNum error"); + res = -1; + } + + return res; +} JackMidiBuffer* JackMidiDriver::GetInputBuffer(int port_index) { diff --git a/common/JackMidiDriver.h b/common/JackMidiDriver.h index 7c5bc5e0..1ce627d3 100644 --- a/common/JackMidiDriver.h +++ b/common/JackMidiDriver.h @@ -39,15 +39,15 @@ class SERVER_EXPORT JackMidiDriver : public JackDriver int fCaptureChannels; int fPlaybackChannels; - + jack_ringbuffer_t* fRingBuffer[DRIVER_PORT_NUM]; jack_port_id_t fCapturePortList[DRIVER_PORT_NUM]; jack_port_id_t fPlaybackPortList[DRIVER_PORT_NUM]; - + JackMidiBuffer* GetInputBuffer(int port_index); JackMidiBuffer* GetOutputBuffer(int port_index); - + public: JackMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); @@ -62,16 +62,18 @@ class SERVER_EXPORT JackMidiDriver : public JackDriver const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency); - + virtual int Process(); + virtual int ProcessSync(); + virtual int ProcessAsync(); virtual int ProcessNull(); virtual int Attach(); virtual int Detach(); - + virtual int Read(); virtual int Write(); - + }; } // end of namespace From 6b57fcbc7461790406fff38675b8f9bd9a7cbe0d Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Wed, 23 Mar 2011 18:23:17 -0700 Subject: [PATCH 066/472] Change system to system_midi to avoid simple semaphore name clashes. --- linux/alsarawmidi/JackALSARawMidiDriver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linux/alsarawmidi/JackALSARawMidiDriver.cpp b/linux/alsarawmidi/JackALSARawMidiDriver.cpp index 8e564c76..7bbae0a1 100755 --- a/linux/alsarawmidi/JackALSARawMidiDriver.cpp +++ b/linux/alsarawmidi/JackALSARawMidiDriver.cpp @@ -572,8 +572,8 @@ extern "C" { const JSList *params) { Jack::JackDriverClientInterface *driver = - new Jack::JackALSARawMidiDriver("system", "alsarawmidi", engine, - table); + new Jack::JackALSARawMidiDriver("system_midi", "alsarawmidi", + engine, table); if (driver->Open(1, 1, 0, 0, false, "midi in", "midi out", 0, 0)) { delete driver; driver = 0; From 625af9c67718def913e3f9886c8a9023b50be928 Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Wed, 23 Mar 2011 23:09:52 -0700 Subject: [PATCH 067/472] Correct peak jitter measurement to be the difference between the highest latency and lowest latency events instead of the difference between the latency of the event with latency farthest from the average latency and the average latency itself. Actually use the xrun callback. --- example-clients/midi_latency_test.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/example-clients/midi_latency_test.c b/example-clients/midi_latency_test.c index 732fe2ab..1bece0d3 100644 --- a/example-clients/midi_latency_test.c +++ b/example-clients/midi_latency_test.c @@ -250,10 +250,11 @@ handle_shutdown(void *arg) set_process_error("handle_shutdown", "The JACK server has been shutdown"); } -static void +static int handle_xrun(void *arg) { xrun_count++; + return 0; } static void @@ -451,6 +452,11 @@ main(int argc, char **argv) error_source = "jack_set_process_callback"; goto unregister_out_port; } + if (jack_set_xrun_callback(client, handle_xrun, NULL)) { + error_message = "failed to set xrun callback"; + error_source = "jack_set_xrun_callback"; + goto unregister_out_port; + } jack_on_shutdown(client, handle_shutdown, NULL); jack_set_info_function(handle_info); process_state = 0; @@ -502,21 +508,10 @@ main(int argc, char **argv) if (process_state == 2) { double average_latency = ((double) total_latency) / samples; double average_latency_time = total_latency_time / samples; - double high_jitter = highest_latency - average_latency; size_t i; - double low_jitter = average_latency - lowest_latency; - double peak_jitter; - double peak_jitter_time; double sample_rate = (double) jack_get_sample_rate(client); jack_nframes_t total_jitter = 0; jack_time_t total_jitter_time = 0; - if (high_jitter > low_jitter) { - peak_jitter = high_jitter; - peak_jitter_time = highest_latency_time - average_latency_time; - } else { - peak_jitter = low_jitter; - peak_jitter_time = average_latency_time - lowest_latency_time; - } for (i = 0; i <= 100; i++) { jitter_plot[i] = 0; } @@ -537,7 +532,7 @@ main(int argc, char **argv) "Average latency: %.2f ms (%.2f frames)\n" "Best latency: %.2f ms (%u frames)\n" "Worst latency: %.2f ms (%u frames)\n" - "Peak MIDI jitter: %.2f ms (%.2f frames)\n" + "Peak MIDI jitter: %.2f ms (%u frames)\n" "Average MIDI jitter: %.2f ms (%.2f frames)\n", (out_latency_range.min / sample_rate) * 1000.0, (out_latency_range.max / sample_rate) * 1000.0, @@ -548,7 +543,8 @@ main(int argc, char **argv) average_latency_time / 1000.0, average_latency, lowest_latency_time / 1000.0, lowest_latency, highest_latency_time / 1000.0, highest_latency, - peak_jitter_time / 1000.0, peak_jitter, + (highest_latency_time - lowest_latency_time) / 1000.0, + highest_latency - lowest_latency, (total_jitter_time / 1000.0) / samples, ((double) total_jitter) / samples); printf("\nJitter Plot:\n"); @@ -569,7 +565,7 @@ main(int argc, char **argv) printf("Unexpected messages received: %d\n", unexpected_messages); } if (xrun_count) { - printf("Xruns: %d (messages may have been lost)", xrun_count); + printf("Xruns: %d (messages may have been lost)\n", xrun_count); } deactivate_client: jack_deactivate(client); From 916203bcca5359cfbec782ba61dea562179d151d Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Thu, 24 Mar 2011 11:28:24 +0100 Subject: [PATCH 068/472] Update XCode project. --- macosx/Jackdmp.xcodeproj/project.pbxproj | 251 +++++++++++++++++++++-- 1 file changed, 236 insertions(+), 15 deletions(-) diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index 705de7c9..efe5e9eb 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -50,6 +50,7 @@ 4B66550E127C356E00753A79 /* PBXTargetDependency */, 4B38120313269CCB00C61B14 /* PBXTargetDependency */, 4B8F16FC1329169F0002AD73 /* PBXTargetDependency */, + 4B20220C133A9C370019E213 /* PBXTargetDependency */, ); name = "All Universal 32/64 bits"; productName = All; @@ -114,6 +115,7 @@ 4B19B31B0E2362E800DD4A82 /* JackLibSampleRateResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B30E0E2362E700DD4A82 /* JackLibSampleRateResampler.cpp */; }; 4B19B31C0E2362E800DD4A82 /* JackLibSampleRateResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */; }; 4B19B31F0E2362E800DD4A82 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */; }; + 4B20220A133A9C1C0019E213 /* midi_latency_test.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B202209133A9C1C0019E213 /* midi_latency_test.c */; }; 4B2209E112F6BBF300E5DC26 /* JackSocketServerChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B30E703B8D0066E42F /* JackSocketServerChannel.cpp */; }; 4B2209E212F6BBF400E5DC26 /* JackSocketServerChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B40E703B8D0066E42F /* JackSocketServerChannel.h */; }; 4B2209E312F6BBF500E5DC26 /* JackSocketServerNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B50E703B8D0066E42F /* JackSocketServerNotifyChannel.cpp */; }; @@ -865,6 +867,13 @@ remoteGlobalIDString = 4B19B2F60E23620F00DD4A82; remoteInfo = audioadapter; }; + 4B20220B133A9C370019E213 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B2021DC133A9BA40019E213 /* jack_midi_latency 64 bits */; + remoteInfo = "jack_midi_latency 64 bits"; + }; 4B224B330E65BA330066BE5B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; @@ -1418,9 +1427,6 @@ 4B05A0640DF72BC000840F4C /* usx2y.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = usx2y.c; path = ../linux/alsa/usx2y.c; sourceTree = SOURCE_ROOT; }; 4B05A0650DF72BC000840F4C /* usx2y.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = usx2y.h; path = ../linux/alsa/usx2y.h; sourceTree = SOURCE_ROOT; }; 4B05A07D0DF72BC000840F4C /* driver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = driver.h; path = ../linux/driver.h; sourceTree = SOURCE_ROOT; }; - 4B05A07F0DF72BC000840F4C /* ffado_driver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ffado_driver.h; path = ../linux/firewire/ffado_driver.h; sourceTree = SOURCE_ROOT; }; - 4B05A0800DF72BC000840F4C /* JackFFADODriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackFFADODriver.cpp; path = ../linux/firewire/JackFFADODriver.cpp; sourceTree = SOURCE_ROOT; }; - 4B05A0810DF72BC000840F4C /* JackFFADODriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackFFADODriver.h; path = ../linux/firewire/JackFFADODriver.h; sourceTree = SOURCE_ROOT; }; 4B05A0830DF72BC000840F4C /* freebob_driver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = freebob_driver.h; path = ../linux/freebob/freebob_driver.h; sourceTree = SOURCE_ROOT; }; 4B05A0840DF72BC000840F4C /* JackFreebobDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackFreebobDriver.cpp; path = ../linux/freebob/JackFreebobDriver.cpp; sourceTree = SOURCE_ROOT; }; 4B05A0850DF72BC000840F4C /* JackFreebobDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackFreebobDriver.h; path = ../linux/freebob/JackFreebobDriver.h; sourceTree = SOURCE_ROOT; }; @@ -1454,6 +1460,8 @@ 4B19B30E0E2362E700DD4A82 /* JackLibSampleRateResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackLibSampleRateResampler.cpp; path = ../common/JackLibSampleRateResampler.cpp; sourceTree = SOURCE_ROOT; }; 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackLibSampleRateResampler.h; path = ../common/JackLibSampleRateResampler.h; sourceTree = SOURCE_ROOT; }; 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackResampler.cpp; path = ../common/JackResampler.cpp; sourceTree = SOURCE_ROOT; }; + 4B2021E6133A9BA40019E213 /* jack_midi_latency_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midi_latency_test; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B202209133A9C1C0019E213 /* midi_latency_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = midi_latency_test.c; path = "../example-clients/midi_latency_test.c"; sourceTree = SOURCE_ROOT; }; 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackGlobals.cpp; path = ../common/JackGlobals.cpp; sourceTree = SOURCE_ROOT; }; 4B3224E510A3156800838A8E /* jack_netone.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_netone.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B3224E810A315B100838A8E /* JackNetOneDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetOneDriver.cpp; path = ../common/JackNetOneDriver.cpp; sourceTree = SOURCE_ROOT; }; @@ -1466,6 +1474,29 @@ 4B32256110A3187800838A8E /* jack_netsource */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_netsource; sourceTree = BUILT_PRODUCTS_DIR; }; 4B32256310A318E300838A8E /* netsource.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = netsource.c; path = "../example-clients/netsource.c"; sourceTree = SOURCE_ROOT; }; 4B32257B10A3190C00838A8E /* jack_netsource */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_netsource; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B349826133A6AF500D130AB /* JackALSARawMidiDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackALSARawMidiDriver.cpp; path = ../linux/alsarawmidi/JackALSARawMidiDriver.cpp; sourceTree = SOURCE_ROOT; }; + 4B349827133A6AF500D130AB /* JackALSARawMidiDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackALSARawMidiDriver.h; path = ../linux/alsarawmidi/JackALSARawMidiDriver.h; sourceTree = SOURCE_ROOT; }; + 4B349828133A6AF500D130AB /* JackALSARawMidiInputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackALSARawMidiInputPort.cpp; path = ../linux/alsarawmidi/JackALSARawMidiInputPort.cpp; sourceTree = SOURCE_ROOT; }; + 4B349829133A6AF500D130AB /* JackALSARawMidiInputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackALSARawMidiInputPort.h; path = ../linux/alsarawmidi/JackALSARawMidiInputPort.h; sourceTree = SOURCE_ROOT; }; + 4B34982A133A6AF500D130AB /* JackALSARawMidiOutputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackALSARawMidiOutputPort.cpp; path = ../linux/alsarawmidi/JackALSARawMidiOutputPort.cpp; sourceTree = SOURCE_ROOT; }; + 4B34982B133A6AF500D130AB /* JackALSARawMidiOutputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackALSARawMidiOutputPort.h; path = ../linux/alsarawmidi/JackALSARawMidiOutputPort.h; sourceTree = SOURCE_ROOT; }; + 4B34982C133A6AF500D130AB /* JackALSARawMidiPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackALSARawMidiPort.cpp; path = ../linux/alsarawmidi/JackALSARawMidiPort.cpp; sourceTree = SOURCE_ROOT; }; + 4B34982D133A6AF500D130AB /* JackALSARawMidiPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackALSARawMidiPort.h; path = ../linux/alsarawmidi/JackALSARawMidiPort.h; sourceTree = SOURCE_ROOT; }; + 4B34982E133A6AF500D130AB /* JackALSARawMidiReceiveQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackALSARawMidiReceiveQueue.cpp; path = ../linux/alsarawmidi/JackALSARawMidiReceiveQueue.cpp; sourceTree = SOURCE_ROOT; }; + 4B34982F133A6AF500D130AB /* JackALSARawMidiReceiveQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackALSARawMidiReceiveQueue.h; path = ../linux/alsarawmidi/JackALSARawMidiReceiveQueue.h; sourceTree = SOURCE_ROOT; }; + 4B349830133A6AF500D130AB /* JackALSARawMidiSendQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackALSARawMidiSendQueue.cpp; path = ../linux/alsarawmidi/JackALSARawMidiSendQueue.cpp; sourceTree = SOURCE_ROOT; }; + 4B349831133A6AF500D130AB /* JackALSARawMidiSendQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackALSARawMidiSendQueue.h; path = ../linux/alsarawmidi/JackALSARawMidiSendQueue.h; sourceTree = SOURCE_ROOT; }; + 4B349838133A6B6F00D130AB /* ffado_driver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ffado_driver.h; path = ../linux/firewire/ffado_driver.h; sourceTree = SOURCE_ROOT; }; + 4B349839133A6B6F00D130AB /* JackFFADODriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackFFADODriver.cpp; path = ../linux/firewire/JackFFADODriver.cpp; sourceTree = SOURCE_ROOT; }; + 4B34983A133A6B6F00D130AB /* JackFFADODriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackFFADODriver.h; path = ../linux/firewire/JackFFADODriver.h; sourceTree = SOURCE_ROOT; }; + 4B34983B133A6B6F00D130AB /* JackFFADOMidiInputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackFFADOMidiInputPort.cpp; path = ../linux/firewire/JackFFADOMidiInputPort.cpp; sourceTree = SOURCE_ROOT; }; + 4B34983C133A6B6F00D130AB /* JackFFADOMidiInputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackFFADOMidiInputPort.h; path = ../linux/firewire/JackFFADOMidiInputPort.h; sourceTree = SOURCE_ROOT; }; + 4B34983D133A6B6F00D130AB /* JackFFADOMidiOutputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackFFADOMidiOutputPort.cpp; path = ../linux/firewire/JackFFADOMidiOutputPort.cpp; sourceTree = SOURCE_ROOT; }; + 4B34983E133A6B6F00D130AB /* JackFFADOMidiOutputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackFFADOMidiOutputPort.h; path = ../linux/firewire/JackFFADOMidiOutputPort.h; sourceTree = SOURCE_ROOT; }; + 4B34983F133A6B6F00D130AB /* JackFFADOMidiReceiveQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackFFADOMidiReceiveQueue.cpp; path = ../linux/firewire/JackFFADOMidiReceiveQueue.cpp; sourceTree = SOURCE_ROOT; }; + 4B349840133A6B6F00D130AB /* JackFFADOMidiReceiveQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackFFADOMidiReceiveQueue.h; path = ../linux/firewire/JackFFADOMidiReceiveQueue.h; sourceTree = SOURCE_ROOT; }; + 4B349841133A6B6F00D130AB /* JackFFADOMidiSendQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackFFADOMidiSendQueue.cpp; path = ../linux/firewire/JackFFADOMidiSendQueue.cpp; sourceTree = SOURCE_ROOT; }; + 4B349842133A6B6F00D130AB /* JackFFADOMidiSendQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackFFADOMidiSendQueue.h; path = ../linux/firewire/JackFFADOMidiSendQueue.h; sourceTree = SOURCE_ROOT; }; 4B35C4250D4731D1000DE7AE /* jackdmp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jackdmp; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C4830D4731D1000DE7AE /* Jackmp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackmp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackservermp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1767,6 +1798,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B2021E0133A9BA40019E213 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B3224E010A3156800838A8E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -2543,6 +2581,7 @@ 4B3811971326884E00C61B14 /* jack_latent_client */, 4B8F16E513290DC80002AD73 /* jack_midi_dump */, 4B8F16F213290E0E0002AD73 /* jack_midi_dump */, + 4B2021E6133A9BA40019E213 /* jack_midi_latency_test */, ); name = Products; sourceTree = ""; @@ -2550,6 +2589,7 @@ 4B03383E0797E19900686131 /* Simple clients */ = { isa = PBXGroup; children = ( + 4B202209133A9C1C0019E213 /* midi_latency_test.c */, 4B8F16F41329161E0002AD73 /* midi_dump.c */, 4B3811FA13269C8300C61B14 /* latent_client.c */, 4B6654FB127C350100753A79 /* server_control.cpp */, @@ -2579,9 +2619,10 @@ 4B05A0420DF72B8500840F4C /* Linux */ = { isa = PBXGroup; children = ( + 4B349837133A6B6F00D130AB /* firewire */, + 4B349825133A6AF500D130AB /* alsarawmidi */, 4B05A04C0DF72BC000840F4C /* alsa */, 4B05A07D0DF72BC000840F4C /* driver.h */, - 4B05A07E0DF72BC000840F4C /* firewire */, 4B05A0820DF72BC000840F4C /* freebob */, ); name = Linux; @@ -2618,17 +2659,6 @@ path = ../linux/alsa; sourceTree = SOURCE_ROOT; }; - 4B05A07E0DF72BC000840F4C /* firewire */ = { - isa = PBXGroup; - children = ( - 4B05A07F0DF72BC000840F4C /* ffado_driver.h */, - 4B05A0800DF72BC000840F4C /* JackFFADODriver.cpp */, - 4B05A0810DF72BC000840F4C /* JackFFADODriver.h */, - ); - name = firewire; - path = ../linux/firewire; - sourceTree = SOURCE_ROOT; - }; 4B05A0820DF72BC000840F4C /* freebob */ = { isa = PBXGroup; children = ( @@ -2693,6 +2723,45 @@ name = Adapter; sourceTree = ""; }; + 4B349825133A6AF500D130AB /* alsarawmidi */ = { + isa = PBXGroup; + children = ( + 4B349826133A6AF500D130AB /* JackALSARawMidiDriver.cpp */, + 4B349827133A6AF500D130AB /* JackALSARawMidiDriver.h */, + 4B349828133A6AF500D130AB /* JackALSARawMidiInputPort.cpp */, + 4B349829133A6AF500D130AB /* JackALSARawMidiInputPort.h */, + 4B34982A133A6AF500D130AB /* JackALSARawMidiOutputPort.cpp */, + 4B34982B133A6AF500D130AB /* JackALSARawMidiOutputPort.h */, + 4B34982C133A6AF500D130AB /* JackALSARawMidiPort.cpp */, + 4B34982D133A6AF500D130AB /* JackALSARawMidiPort.h */, + 4B34982E133A6AF500D130AB /* JackALSARawMidiReceiveQueue.cpp */, + 4B34982F133A6AF500D130AB /* JackALSARawMidiReceiveQueue.h */, + 4B349830133A6AF500D130AB /* JackALSARawMidiSendQueue.cpp */, + 4B349831133A6AF500D130AB /* JackALSARawMidiSendQueue.h */, + ); + name = alsarawmidi; + path = ../linux/alsarawmidi; + sourceTree = SOURCE_ROOT; + }; + 4B349837133A6B6F00D130AB /* firewire */ = { + isa = PBXGroup; + children = ( + 4B349838133A6B6F00D130AB /* ffado_driver.h */, + 4B349839133A6B6F00D130AB /* JackFFADODriver.cpp */, + 4B34983A133A6B6F00D130AB /* JackFFADODriver.h */, + 4B34983B133A6B6F00D130AB /* JackFFADOMidiInputPort.cpp */, + 4B34983C133A6B6F00D130AB /* JackFFADOMidiInputPort.h */, + 4B34983D133A6B6F00D130AB /* JackFFADOMidiOutputPort.cpp */, + 4B34983E133A6B6F00D130AB /* JackFFADOMidiOutputPort.h */, + 4B34983F133A6B6F00D130AB /* JackFFADOMidiReceiveQueue.cpp */, + 4B349840133A6B6F00D130AB /* JackFFADOMidiReceiveQueue.h */, + 4B349841133A6B6F00D130AB /* JackFFADOMidiSendQueue.cpp */, + 4B349842133A6B6F00D130AB /* JackFFADOMidiSendQueue.h */, + ); + name = firewire; + path = ../linux/firewire; + sourceTree = SOURCE_ROOT; + }; 4B37C20006DF1F900016E567 /* Latency */ = { isa = PBXGroup; children = ( @@ -3066,6 +3135,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B2021DD133A9BA40019E213 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B3224D810A3156800838A8E /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -4111,6 +4187,25 @@ productReference = 4B19B3000E23620F00DD4A82 /* audioadapter.so */; productType = "com.apple.product-type.library.dynamic"; }; + 4B2021DC133A9BA40019E213 /* jack_midi_latency 64 bits */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B2021E2133A9BA40019E213 /* Build configuration list for PBXNativeTarget "jack_midi_latency 64 bits" */; + buildPhases = ( + 4B2021DD133A9BA40019E213 /* Headers */, + 4B2021DE133A9BA40019E213 /* Sources */, + 4B2021E0133A9BA40019E213 /* Frameworks */, + 4B2021E1133A9BA40019E213 /* Rez */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "jack_midi_latency 64 bits"; + productInstallPath = /usr/local/bin; + productName = jack_metro; + productReference = 4B2021E6133A9BA40019E213 /* jack_midi_latency_test */; + productType = "com.apple.product-type.tool"; + }; 4B3224D710A3156800838A8E /* jack_netone Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B3224E110A3156800838A8E /* Build configuration list for PBXNativeTarget "jack_netone Universal" */; @@ -5838,6 +5933,7 @@ 4B35C50A0D4731D1000DE7AE /* jack_midiseq 64 bits */, 4B35C5160D4731D1000DE7AE /* jack_midisine 64 bits */, 4B8F16E813290E0E0002AD73 /* jack_midi_dump 64 bits */, + 4B2021DC133A9BA40019E213 /* jack_midi_latency 64 bits */, 4B35C5220D4731D1000DE7AE /* jack_metro 64 bits */, 4B35C52E0D4731D1000DE7AE /* jack_lsp 64 bits */, 4B35C53A0D4731D1000DE7AE /* jack_connect 64 bits */, @@ -5940,6 +6036,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B2021E1133A9BA40019E213 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B32255C10A3187800838A8E /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; @@ -6448,6 +6551,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B2021DE133A9BA40019E213 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B20220A133A9C1C0019E213 /* midi_latency_test.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B3224DC10A3156800838A8E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -7438,6 +7549,11 @@ target = 4B19B2F60E23620F00DD4A82 /* audioadapter Universal */; targetProxy = 4B19B32B0E23636E00DD4A82 /* PBXContainerItemProxy */; }; + 4B20220C133A9C370019E213 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4B2021DC133A9BA40019E213 /* jack_midi_latency 64 bits */; + targetProxy = 4B20220B133A9C370019E213 /* PBXContainerItemProxy */; + }; 4B224B340E65BA330066BE5B /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B5E08BF0E5B66EE00BEE4E0 /* netadapter Universal */; @@ -8141,6 +8257,101 @@ }; name = Default; }; + 4B2021E3133A9BA40019E213 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midi_latency_test; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4B2021E4133A9BA40019E213 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + HEADER_SEARCH_PATHS = ../common; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midi_latency_test; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B2021E5133A9BA40019E213 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc64, + ppc, + i386, + x86_64, + ); + FRAMEWORK_SEARCH_PATHS = ""; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midisine; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; 4B3224E210A3156800838A8E /* Development */ = { isa = XCBuildConfiguration; buildSettings = { @@ -18735,6 +18946,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; + 4B2021E2133A9BA40019E213 /* Build configuration list for PBXNativeTarget "jack_midi_latency 64 bits" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B2021E3133A9BA40019E213 /* Development */, + 4B2021E4133A9BA40019E213 /* Deployment */, + 4B2021E5133A9BA40019E213 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; 4B3224E110A3156800838A8E /* Build configuration list for PBXNativeTarget "jack_netone Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( From 5360ec7522b28d8e89ef1f7431f85c63b6e5ff68 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Thu, 24 Mar 2011 12:41:20 +0100 Subject: [PATCH 069/472] Fix midi_latency_test.c for OSX. --- example-clients/midi_latency_test.c | 34 ++++++++++++++++++++++++ macosx/Jackdmp.xcodeproj/project.pbxproj | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/example-clients/midi_latency_test.c b/example-clients/midi_latency_test.c index 1bece0d3..d9e6fb08 100644 --- a/example-clients/midi_latency_test.c +++ b/example-clients/midi_latency_test.c @@ -95,7 +95,11 @@ char *program_name; jack_port_t *remote_in_port; jack_port_t *remote_out_port; size_t samples; +#ifdef __APPLE__ +sem_t* semaphore; +#else sem_t semaphore; +#endif pthread_mutex_t start_mutex; int timeout; jack_nframes_t total_latency; @@ -212,7 +216,11 @@ handle_process(jack_nframes_t frames, void *arg) messages_received++; if (messages_received == samples) { process_state = 2; + #ifdef __APPLE__ + sem_post(semaphore); + #else sem_post(&semaphore); + #endif break; } send_message: @@ -302,7 +310,11 @@ set_process_error(const char *source, const char *message) error_source = source; error_message = message; process_state = -1; + #ifdef __APPLE__ + sem_post(semaphore); +#else sem_post(&semaphore); +#endif } int @@ -460,11 +472,22 @@ main(int argc, char **argv) jack_on_shutdown(client, handle_shutdown, NULL); jack_set_info_function(handle_info); process_state = 0; +#ifdef __APPLE__ + // sem_init is not implemented on OSX + char name[128]; + sprintf(name, "midi_sem_%p", client); + if ((semaphore = sem_open(name, O_CREAT, 0777, 0)) == (sem_t*)SEM_FAILED) { + error_message = strerror(errno); + error_source = "sem_open"; + goto unregister_out_port; + } +#else if (sem_init(&semaphore, 0, 0)) { error_message = strerror(errno); error_source = "sem_init"; goto unregister_out_port; } +#endif code = pthread_mutex_init(&start_mutex, NULL); if (code) { error_message = strerror(errno); @@ -500,11 +523,15 @@ main(int argc, char **argv) error_source = "pthread_mutex_unlock"; goto deactivate_client; } +#ifdef __APPLE__ + while (sem_wait(semaphore) != 0) {} +#else if (sem_wait(&semaphore)) { error_message = strerror(errno); error_source = "sem_wait"; goto deactivate_client; } +#endif if (process_state == 2) { double average_latency = ((double) total_latency) / samples; double average_latency_time = total_latency_time / samples; @@ -572,7 +599,11 @@ main(int argc, char **argv) destroy_mutex: pthread_mutex_destroy(&start_mutex); destroy_semaphore: +#ifdef __APPLE__ + sem_destroy(semaphore); +#else sem_destroy(&semaphore); +#endif unregister_out_port: jack_port_unregister(client, out_port); unregister_in_port: @@ -592,5 +623,8 @@ main(int argc, char **argv) output_error(error_source, error_message); exit(EXIT_FAILURE); } +#ifdef __APPLE__ + sem_unlink(name); +#endif return EXIT_SUCCESS; } diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index efe5e9eb..edfbae28 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -871,7 +871,7 @@ isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4B2021DC133A9BA40019E213 /* jack_midi_latency 64 bits */; + remoteGlobalIDString = 4B2021DC133A9BA40019E213; remoteInfo = "jack_midi_latency 64 bits"; }; 4B224B330E65BA330066BE5B /* PBXContainerItemProxy */ = { From 885381fc9764e4ae327d9f52392f8dedc0177d6c Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Thu, 24 Mar 2011 12:12:16 -0700 Subject: [PATCH 070/472] Add error handling to 'alsarawmidi' driver to make driver fail more gracefully if an ALSA error is detected (i.e. device is unplugged, etc.). Add optional frame_offset parameter to JackMidiWriteQueue::EnqueueEvent. --- common/JackMidiWriteQueue.h | 9 ++-- linux/alsarawmidi/JackALSARawMidiDriver.cpp | 34 ++++++++++---- .../alsarawmidi/JackALSARawMidiInputPort.cpp | 28 +++++++----- linux/alsarawmidi/JackALSARawMidiInputPort.h | 6 +-- .../alsarawmidi/JackALSARawMidiOutputPort.cpp | 44 +++++++++++-------- linux/alsarawmidi/JackALSARawMidiOutputPort.h | 6 +-- linux/alsarawmidi/JackALSARawMidiPort.cpp | 17 +++---- linux/alsarawmidi/JackALSARawMidiPort.h | 4 +- 8 files changed, 89 insertions(+), 59 deletions(-) diff --git a/common/JackMidiWriteQueue.h b/common/JackMidiWriteQueue.h index 8a51bafa..a39776c9 100644 --- a/common/JackMidiWriteQueue.h +++ b/common/JackMidiWriteQueue.h @@ -63,13 +63,16 @@ namespace Jack { jack_midi_data_t *buffer) = 0; /** - * A wrapper method for the `EnqueueEvent` method above. + * A wrapper method for the `EnqueueEvent` method above. The optional + * 'frame_offset' argument is an amount of frames to add to the event's + * time. */ inline EnqueueResult - EnqueueEvent(jack_midi_event_t *event) + EnqueueEvent(jack_midi_event_t *event, jack_nframes_t frame_offset=0) { - return EnqueueEvent(event->time, event->size, event->buffer); + return EnqueueEvent(event->time + frame_offset, event->size, + event->buffer); } }; diff --git a/linux/alsarawmidi/JackALSARawMidiDriver.cpp b/linux/alsarawmidi/JackALSARawMidiDriver.cpp index 7bbae0a1..3f4761e0 100755 --- a/linux/alsarawmidi/JackALSARawMidiDriver.cpp +++ b/linux/alsarawmidi/JackALSARawMidiDriver.cpp @@ -134,32 +134,44 @@ JackALSARawMidiDriver::Execute() } revents = poll_fds[0].revents; if (revents & POLLHUP) { - close(fds[0]); - fds[0] = -1; + // Driver is being stopped. break; } - if (revents & (~(POLLHUP | POLLIN))) { + if (revents & (~ POLLIN)) { jack_error("JackALSARawMidiDriver::Execute - unexpected poll " "event on pipe file descriptor."); break; } - handle_ports: timeout_frame = 0; for (int i = 0; i < fCaptureChannels; i++) { - process_frame = input_ports[i]->ProcessALSA(); + if (! input_ports[i]->ProcessALSA(&process_frame)) { + jack_error("JackALSARawMidiDriver::Execute - a fatal error " + "occurred while processing ALSA input events."); + goto cleanup; + } if (process_frame && ((! timeout_frame) || (process_frame < timeout_frame))) { timeout_frame = process_frame; } } for (int i = 0; i < fPlaybackChannels; i++) { - process_frame = output_ports[i]->ProcessALSA(fds[0]); + if (! output_ports[i]->ProcessALSA(fds[0], &process_frame)) { + jack_error("JackALSARawMidiDriver::Execute - a fatal error " + "occurred while processing ALSA output events."); + goto cleanup; + } if (process_frame && ((! timeout_frame) || (process_frame < timeout_frame))) { timeout_frame = process_frame; } } } + cleanup: + close(fds[0]); + fds[0] = -1; + + jack_info("JackALSARawMidiDriver::Execute - ALSA thread exiting."); + return false; } @@ -402,7 +414,9 @@ JackALSARawMidiDriver::Read() { jack_nframes_t buffer_size = fEngineControl->fBufferSize; for (int i = 0; i < fCaptureChannels; i++) { - input_ports[i]->ProcessJack(GetInputBuffer(i), buffer_size); + if (! input_ports[i]->ProcessJack(GetInputBuffer(i), buffer_size)) { + return -1; + } } return 0; } @@ -539,8 +553,10 @@ JackALSARawMidiDriver::Write() jack_nframes_t buffer_size = fEngineControl->fBufferSize; int write_fd = fds[1]; for (int i = 0; i < fPlaybackChannels; i++) { - output_ports[i]->ProcessJack(GetOutputBuffer(i), buffer_size, - write_fd); + if (! output_ports[i]->ProcessJack(GetOutputBuffer(i), buffer_size, + write_fd)) { + return -1; + } } return 0; } diff --git a/linux/alsarawmidi/JackALSARawMidiInputPort.cpp b/linux/alsarawmidi/JackALSARawMidiInputPort.cpp index 94ae8c4a..7167c8b8 100755 --- a/linux/alsarawmidi/JackALSARawMidiInputPort.cpp +++ b/linux/alsarawmidi/JackALSARawMidiInputPort.cpp @@ -69,30 +69,33 @@ JackALSARawMidiInputPort::EnqueueALSAEvent() return (next_time < alsa_time) ? next_time : alsa_time; } -jack_nframes_t -JackALSARawMidiInputPort::ProcessALSA() +bool +JackALSARawMidiInputPort::ProcessALSA(jack_nframes_t *frame) { - unsigned short revents = ProcessPollEvents(); - jack_nframes_t frame; + unsigned short revents; + if (! ProcessPollEvents(&revents)) { + return false; + } if (alsa_event) { - frame = EnqueueALSAEvent(); - if (frame) { - return frame; + *frame = EnqueueALSAEvent(); + if (*frame) { + return true; } } if (revents & POLLIN) { for (alsa_event = receive_queue->DequeueEvent(); alsa_event; alsa_event = receive_queue->DequeueEvent()) { - frame = EnqueueALSAEvent(); - if (frame) { - return frame; + *frame = EnqueueALSAEvent(); + if (*frame) { + return true; } } } - return raw_queue->Process(); + *frame = raw_queue->Process(); + return true; } -void +bool JackALSARawMidiInputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames) { @@ -119,4 +122,5 @@ JackALSARawMidiInputPort::ProcessJack(JackMidiBuffer *port_buffer, } break; } + return true; } diff --git a/linux/alsarawmidi/JackALSARawMidiInputPort.h b/linux/alsarawmidi/JackALSARawMidiInputPort.h index a5d5a2da..38b8985b 100755 --- a/linux/alsarawmidi/JackALSARawMidiInputPort.h +++ b/linux/alsarawmidi/JackALSARawMidiInputPort.h @@ -30,10 +30,10 @@ namespace Jack { size_t max_messages=1024); ~JackALSARawMidiInputPort(); - jack_nframes_t - ProcessALSA(); + bool + ProcessALSA(jack_nframes_t *frame); - void + bool ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames); }; diff --git a/linux/alsarawmidi/JackALSARawMidiOutputPort.cpp b/linux/alsarawmidi/JackALSARawMidiOutputPort.cpp index df1fc268..c1a2bfb8 100755 --- a/linux/alsarawmidi/JackALSARawMidiOutputPort.cpp +++ b/linux/alsarawmidi/JackALSARawMidiOutputPort.cpp @@ -54,13 +54,17 @@ JackALSARawMidiOutputPort::DequeueALSAEvent(int read_fd) return event; } -jack_nframes_t -JackALSARawMidiOutputPort::ProcessALSA(int read_fd) +bool +JackALSARawMidiOutputPort::ProcessALSA(int read_fd, jack_nframes_t *frame) { - unsigned short revents = ProcessPollEvents(); + unsigned short revents; + if (! ProcessPollEvents(&revents)) { + return false; + } if (blocked) { if (! (revents & POLLOUT)) { - return 0; + *frame = 0; + return true; } blocked = false; } @@ -98,7 +102,7 @@ JackALSARawMidiOutputPort::ProcessALSA(int read_fd) break; } process_events: - jack_nframes_t next_frame = raw_queue->Process(); + *frame = raw_queue->Process(); blocked = send_queue->IsBlocked(); if (blocked) { @@ -106,13 +110,14 @@ JackALSARawMidiOutputPort::ProcessALSA(int read_fd) "blocked"); SetPollEventMask(POLLERR | POLLNVAL | POLLOUT); - return 0; + *frame = 0; + } else { + SetPollEventMask(POLLERR | POLLNVAL); } - SetPollEventMask(POLLERR | POLLNVAL); - return next_frame; + return true; } -void +bool JackALSARawMidiOutputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames, int write_fd) { @@ -128,20 +133,21 @@ JackALSARawMidiOutputPort::ProcessJack(JackMidiBuffer *port_buffer, char c = 1; ssize_t result = write(write_fd, &c, 1); assert(result <= 1); + if (result < 0) { + jack_error("JackALSARawMidiOutputPort::ProcessJack - error " + "writing a byte to the pipe file descriptor: %s", + strerror(errno)); + return false; + } if (! result) { + // Recoverable. jack_error("JackALSARawMidiOutputPort::ProcessJack - Couldn't " "write a byte to the pipe file descriptor. Dropping " "event."); - } else if (result < 0) { - jack_error("JackALSARawMidiOutputPort::ProcessJack - error " - "writing a byte to the pipe file descriptor: %s", - strerror(errno)); - } else if (thread_queue->EnqueueEvent(event->time + frames, - event->size, event->buffer) != - JackMidiWriteQueue::OK) { - jack_error("JackALSARawMidiOutputPort::ProcessJack - **BUG** The " - "thread queue said it had enough space to enqueue a " - "%d-byte event, but failed to enqueue the event."); + } else { + assert(thread_queue->EnqueueEvent(event, frames) == + JackMidiWriteQueue::OK); } } + return true; } diff --git a/linux/alsarawmidi/JackALSARawMidiOutputPort.h b/linux/alsarawmidi/JackALSARawMidiOutputPort.h index aea8f2ea..816ab6a2 100755 --- a/linux/alsarawmidi/JackALSARawMidiOutputPort.h +++ b/linux/alsarawmidi/JackALSARawMidiOutputPort.h @@ -30,10 +30,10 @@ namespace Jack { size_t max_messages=1024); ~JackALSARawMidiOutputPort(); - jack_nframes_t - ProcessALSA(int read_fd); + bool + ProcessALSA(int read_fd, jack_nframes_t *frame); - void + bool ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames, int write_fd); diff --git a/linux/alsarawmidi/JackALSARawMidiPort.cpp b/linux/alsarawmidi/JackALSARawMidiPort.cpp index a2d3d8fc..a37f9d93 100755 --- a/linux/alsarawmidi/JackALSARawMidiPort.cpp +++ b/linux/alsarawmidi/JackALSARawMidiPort.cpp @@ -126,27 +126,28 @@ JackALSARawMidiPort::PopulatePollDescriptors(struct pollfd *poll_fd) return result; } -int -JackALSARawMidiPort::ProcessPollEvents() +bool +JackALSARawMidiPort::ProcessPollEvents(unsigned short *revents) { - unsigned short revents = 0; int code = snd_rawmidi_poll_descriptors_revents(rawmidi, poll_fds, num_fds, - &revents); + revents); if (code) { jack_error("JackALSARawMidiPort::ProcessPollEvents - " "snd_rawmidi_poll_descriptors_revents: %s", snd_strerror(code)); - return 0; + return false; } - if (revents & POLLNVAL) { + if ((*revents) & POLLNVAL) { jack_error("JackALSARawMidiPort::ProcessPollEvents - the file " "descriptor is invalid."); + return false; } - if (revents & POLLERR) { + if ((*revents) & POLLERR) { jack_error("JackALSARawMidiPort::ProcessPollEvents - an error has " "occurred on the device or stream."); + return false; } - return revents; + return true; } void diff --git a/linux/alsarawmidi/JackALSARawMidiPort.h b/linux/alsarawmidi/JackALSARawMidiPort.h index 564e5b7b..07fb4c0f 100755 --- a/linux/alsarawmidi/JackALSARawMidiPort.h +++ b/linux/alsarawmidi/JackALSARawMidiPort.h @@ -21,8 +21,8 @@ namespace Jack { snd_rawmidi_t *rawmidi; - int - ProcessPollEvents(); + bool + ProcessPollEvents(unsigned short *revents); void SetPollEventMask(unsigned short events); From 5e19eacbeab3365f6f5639421abdafbfc9c33fa0 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Fri, 25 Mar 2011 15:06:45 +0100 Subject: [PATCH 071/472] Correct latency for MIDI backend. --- common/JackMidiDriver.cpp | 10 ++++++++++ macosx/coremidi/JackCoreMidiDriver.cpp | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/common/JackMidiDriver.cpp b/common/JackMidiDriver.cpp index b8993e7a..454f046d 100644 --- a/common/JackMidiDriver.cpp +++ b/common/JackMidiDriver.cpp @@ -74,9 +74,12 @@ int JackMidiDriver::Attach() jack_port_id_t port_index; char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + jack_latency_range_t latency_range; + jack_nframes_t latency = fEngineControl->fBufferSize; int i; jack_log("JackMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); + latency_range.max = latency_range.min = latency; for (i = 0; i < fCaptureChannels; i++) { snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); @@ -87,10 +90,16 @@ int JackMidiDriver::Attach() } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); + port->SetLatencyRange(JackCaptureLatency, &latency_range); fCapturePortList[i] = port_index; jack_log("JackMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index); } + if (!fEngineControl->fSyncMode) { + latency += fEngineControl->fBufferSize;; + latency_range.max = latency_range.min = latency; + } + for (i = 0; i < fPlaybackChannels; i++) { snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); @@ -100,6 +109,7 @@ int JackMidiDriver::Attach() } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); + port->SetLatencyRange(JackPlaybackLatency, &latency_range); fPlaybackPortList[i] = port_index; jack_log("JackMidiDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); } diff --git a/macosx/coremidi/JackCoreMidiDriver.cpp b/macosx/coremidi/JackCoreMidiDriver.cpp index 1cb7176b..233ac8dd 100644 --- a/macosx/coremidi/JackCoreMidiDriver.cpp +++ b/macosx/coremidi/JackCoreMidiDriver.cpp @@ -227,9 +227,12 @@ int JackCoreMidiDriver::Attach() char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char endpoint_name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + jack_latency_range_t latency_range; + jack_nframes_t latency = fEngineControl->fBufferSize; int i; jack_log("JackCoreMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); + latency_range.max = latency_range.min = latency; for (i = 0; i < fCaptureChannels; i++) { @@ -249,10 +252,16 @@ int JackCoreMidiDriver::Attach() } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); + port->SetLatencyRange(JackCaptureLatency, &latency_range); fCapturePortList[i] = port_index; jack_log("JackCoreMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index); } + if (!fEngineControl->fSyncMode) { + latency += fEngineControl->fBufferSize;; + latency_range.max = latency_range.min = latency; + } + for (i = 0; i < fPlaybackChannels; i++) { err = MIDIObjectGetStringProperty(fMidiSource[i], kMIDIPropertyName, &pname); @@ -271,6 +280,7 @@ int JackCoreMidiDriver::Attach() } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); + port->SetLatencyRange(JackPlaybackLatency, &latency_range); fPlaybackPortList[i] = port_index; jack_log("JackCoreMidiDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); } From 981ff8cf459ff4adb7c7c14a45f99bc7497e4355 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Fri, 25 Mar 2011 17:18:37 +0100 Subject: [PATCH 072/472] Major redesign of driver activation (master and salve mode). --- common/JackAudioDriver.cpp | 58 +++++++++++++++++++------- common/JackAudioDriver.h | 8 +++- common/JackDriver.cpp | 27 ++++++++++++- common/JackDriver.h | 34 ++++++++++++++-- common/JackFreewheelDriver.cpp | 74 +++++++++++++++++++++++++++------- common/JackFreewheelDriver.h | 10 +++++ common/JackMidiDriver.cpp | 62 ++++++++++------------------ common/JackMidiDriver.h | 12 ++++-- common/JackThreadedDriver.cpp | 19 ++++++++- common/JackThreadedDriver.h | 9 ++++- 10 files changed, 231 insertions(+), 82 deletions(-) diff --git a/common/JackAudioDriver.cpp b/common/JackAudioDriver.cpp index 272c1e66..dedf02b0 100644 --- a/common/JackAudioDriver.cpp +++ b/common/JackAudioDriver.cpp @@ -193,9 +193,9 @@ int JackAudioDriver::ProcessNull() JackDriver::CycleTakeBeginTime(); if (fEngineControl->fSyncMode) { - ProcessGraphSync(); + ProcessGraphSyncMaster(); } else { - ProcessGraphAsync(); + ProcessGraphAsyncMaster(); } // Keep end cycle time @@ -230,9 +230,9 @@ int JackAudioDriver::ProcessAsync() // Process graph if (fIsMaster) { - ProcessGraphAsync(); + ProcessGraphAsyncMaster(); } else { - fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); + ProcessGraphAsyncSlave(); } // Keep end cycle time @@ -255,12 +255,12 @@ int JackAudioDriver::ProcessSync() // Process graph if (fIsMaster) { - if (ProcessGraphSync() < 0) { + if (ProcessGraphSyncMaster() < 0) { jack_error("JackAudioDriver::ProcessSync: process error, skip cycle..."); goto end; } } else { - if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { + if (ProcessGraphSyncSlave() < 0) { jack_error("JackAudioDriver::ProcessSync: process error, skip cycle..."); goto end; } @@ -279,27 +279,50 @@ end: return 0; } -void JackAudioDriver::ProcessGraphAsync() +void JackAudioDriver::ProcessGraphAsyncMaster() { // fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle if (!fEngine->Process(fBeginDateUst, fEndDateUst)) - jack_error("JackAudioDriver::ProcessGraphAsync: Process error"); - fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); - if (ProcessSlaves() < 0) - jack_error("JackAudioDriver::ProcessGraphAsync: ProcessSlaves error"); + jack_error("JackAudioDriver::ProcessGraphAsyncMaster: Process error"); + + if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) + jack_error("JackAudioDriver::ProcessGraphAsyncMaster: ResumeRefNum error"); + + if (ProcessReadSlaves() < 0) + jack_error("JackAudioDriver::ProcessGraphAsyncMaster: ProcessReadSlaves error"); + + if (ProcessWriteSlaves() < 0) + jack_error("JackAudioDriver::ProcessGraphAsyncMaster: ProcessWriteSlaves error"); +} + +void JackAudioDriver::ProcessGraphAsyncSlave() +{ + if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) + jack_error("JackAudioDriver::ProcessGraphAsyncSlave: ResumeRefNum error"); } -int JackAudioDriver::ProcessGraphSync() +int JackAudioDriver::ProcessGraphSyncMaster() { int res = 0; // fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle if (fEngine->Process(fBeginDateUst, fEndDateUst)) { - fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); - if (ProcessSlaves() < 0) { - jack_error("JackAudioDriver::ProcessGraphSync: ProcessSlaves error, engine may now behave abnormally!!"); + + if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { + jack_error("JackAudioDriver::ProcessGraphSyncMaster: ResumeRefNum error"); res = -1; } + + if (ProcessReadSlaves() < 0) { + jack_error("JackAudioDriver::ProcessGraphSync: ProcessReadSlaves error, engine may now behave abnormally!!"); + res = -1; + } + + if (ProcessWriteSlaves() < 0) { + jack_error("JackAudioDriver::ProcessGraphSync: ProcessWriteSlaves error, engine may now behave abnormally!!"); + res = -1; + } + if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) { jack_error("JackAudioDriver::ProcessGraphSync: SuspendRefNum error, engine may now behave abnormally!!"); res = -1; @@ -312,6 +335,11 @@ int JackAudioDriver::ProcessGraphSync() return res; } +int JackAudioDriver::ProcessGraphSyncSlave() +{ + return fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); +} + int JackAudioDriver::Start() { int res = JackDriver::Start(); diff --git a/common/JackAudioDriver.h b/common/JackAudioDriver.h index 8eaca692..cb0ebefe 100644 --- a/common/JackAudioDriver.h +++ b/common/JackAudioDriver.h @@ -35,8 +35,12 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver protected: - void ProcessGraphAsync(); - int ProcessGraphSync(); + void ProcessGraphAsyncMaster(); + void ProcessGraphAsyncSlave(); + + int ProcessGraphSyncMaster(); + int ProcessGraphSyncSlave(); + void WaitUntilNextCycle(); virtual int ProcessAsync(); diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index 657524bd..77b3850e 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -282,19 +282,42 @@ void JackDriver::RemoveSlave(JackDriverInterface* slave) fSlaveList.remove(slave); } -int JackDriver::ProcessSlaves() +int JackDriver::ProcessReadSlaves() { int res = 0; list::const_iterator it; for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { JackDriverInterface* slave = *it; - if (slave->Process() < 0) + if (slave->ProcessRead() < 0) res = -1; } return res; } +int JackDriver::ProcessWriteSlaves() +{ + int res = 0; + list::const_iterator it; + for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { + JackDriverInterface* slave = *it; + if (slave->ProcessWrite() < 0) + res = -1; + + } + return res; +} + +int JackDriver::ProcessRead() +{ + return 0; +} + +int JackDriver::ProcessWrite() +{ + return 0; +} + int JackDriver::Process() { return 0; diff --git a/common/JackDriver.h b/common/JackDriver.h index 68f937c2..e619f6e4 100644 --- a/common/JackDriver.h +++ b/common/JackDriver.h @@ -34,6 +34,7 @@ namespace Jack class JackLockedEngine; class JackGraphManager; struct JackEngineControl; +class JackSlaveDriverInterface; /*! \brief The base interface for drivers. @@ -91,10 +92,17 @@ class SERVER_EXPORT JackDriverInterface virtual void SetMaster(bool onoff) = 0; virtual bool GetMaster() = 0; + virtual void AddSlave(JackDriverInterface* slave) = 0; virtual void RemoveSlave(JackDriverInterface* slave) = 0; + virtual std::list GetSlaves() = 0; - virtual int ProcessSlaves() = 0; + + virtual int ProcessReadSlaves() = 0; + virtual int ProcessWriteSlaves() = 0; + + virtual int ProcessRead() = 0; + virtual int ProcessWrite() = 0; virtual bool IsRealTime() const = 0; virtual bool IsRunning() const = 0; @@ -159,11 +167,11 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface void AddSlave(JackDriverInterface* slave); void RemoveSlave(JackDriverInterface* slave); + std::list GetSlaves() { return fSlaveList; } - int ProcessSlaves(); virtual int Open(); @@ -200,10 +208,17 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface virtual int Write(); virtual int Start(); - virtual int StartSlaves(); virtual int Stop(); + + virtual int StartSlaves(); virtual int StopSlaves(); + int ProcessReadSlaves(); + int ProcessWriteSlaves(); + + int ProcessRead(); + int ProcessWrite(); + virtual bool IsFixedBufferSize(); virtual int SetBufferSize(jack_nframes_t buffer_size); virtual int SetSampleRate(jack_nframes_t sample_rate); @@ -217,6 +232,19 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface }; +/* +class SERVER_EXPORT JackSlaveDriverInterface +{ + + public: + + virtual int ProcessRead() { return 0; } + virtual int ProcessWrite() { return 0; } + +}; + +*/ + } // end of namespace #endif diff --git a/common/JackFreewheelDriver.cpp b/common/JackFreewheelDriver.cpp index c28e30c3..2928b211 100644 --- a/common/JackFreewheelDriver.cpp +++ b/common/JackFreewheelDriver.cpp @@ -28,26 +28,72 @@ namespace Jack int JackFreewheelDriver::Process() { - if (fIsMaster) { - jack_log("JackFreewheelDriver::Process master %lld", fEngineControl->fTimeOutUsecs); - JackDriver::CycleTakeBeginTime(); - fEngine->Process(fBeginDateUst, fEndDateUst); - fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); // Signal all clients + int res = 0; + + jack_log("JackFreewheelDriver::Process master %lld", fEngineControl->fTimeOutUsecs); + JackDriver::CycleTakeBeginTime(); + + if (fEngine->Process(fBeginDateUst, fEndDateUst)) { + + if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable)) { // Signal all clients + jack_error("JackFreewheelDriver::Process: ResumeRefNum error"); + res = -1; + } + if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, FREEWHEEL_DRIVER_TIMEOUT * 1000000) < 0) { // Wait for all clients to finish for 10 sec - jack_error("JackFreewheelDriver::ProcessSync SuspendRefNum error"); + jack_error("JackFreewheelDriver::ProcessSync: SuspendRefNum error"); /* We have a client time-out error, but still continue to process, until a better recovery strategy is chosen */ return 0; } - } else { - fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); // Signal all clients - if (fEngineControl->fSyncMode) { - if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) { - jack_error("JackFreewheelDriver::ProcessSync SuspendRefNum error"); - return -1; - } - } + + } else { // Graph not finished: do not activate it + jack_error("JackFreewheelDriver::Process: Process error"); + res = -1; + } + + return res; +} + +int JackFreewheelDriver::ProcessRead() +{ + return (fEngineControl->fSyncMode) ? ProcessReadSync() : ProcessReadAsync(); +} + +int JackFreewheelDriver::ProcessWrite() +{ + return (fEngineControl->fSyncMode) ? ProcessWriteSync() : ProcessWriteAsync(); +} + +int JackFreewheelDriver::ProcessReadSync() +{ + if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { // Signal all clients + jack_error("JackFreewheelDriver::ProcessReadSync: ResumeRefNum error"); + return -1; + } + return 0; +} + +int JackFreewheelDriver::ProcessWriteSync() +{ + if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) { + jack_error("JackFreewheelDriver::ProcessSync SuspendRefNum error"); + return -1; + } + return 0; +} + +int JackFreewheelDriver::ProcessReadAsync() +{ + if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { // Signal all clients + jack_error("JackFreewheelDriver::ProcessReadAsync: ResumeRefNum error"); + return -1; } return 0; } +int JackFreewheelDriver::ProcessWriteAsync() +{ + return 0; +} + } // end of namespace diff --git a/common/JackFreewheelDriver.h b/common/JackFreewheelDriver.h index b988ffb0..02a9cf76 100644 --- a/common/JackFreewheelDriver.h +++ b/common/JackFreewheelDriver.h @@ -46,6 +46,16 @@ class JackFreewheelDriver : public JackDriver } int Process(); + + int ProcessRead(); + int ProcessWrite(); + + int ProcessReadSync(); + int ProcessWriteSync(); + + int ProcessReadAsync(); + int ProcessWriteAsync(); + }; } // end of namespace diff --git a/common/JackMidiDriver.cpp b/common/JackMidiDriver.cpp index 454f046d..a2fffa83 100644 --- a/common/JackMidiDriver.cpp +++ b/common/JackMidiDriver.cpp @@ -148,56 +148,24 @@ int JackMidiDriver::ProcessNull() return 0; } -/* -int JackMidiDriver::Process() +int JackMidiDriver::ProcessRead() { - if (Read() < 0) { - jack_error("JackMidiDriver::Process: read error, skip cycle"); - return 0; // Skip cycle, but continue processing... - } - - if (fEngineControl->fSyncMode) { - int res = 0; - if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { - jack_error("JackMidiDriver::Process - ResumeRefNum error"); - res = -1; - } - if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, - DRIVER_TIMEOUT_FACTOR * - fEngineControl->fTimeOutUsecs) < 0) { - jack_error("JackMidiDriver::Process - SuspendRefNum error"); - res = -1; - } - if (Write() < 0) { - jack_error("JackMidiDriver::Process - Write error"); - } - return res; - } - - // Not in sync mode - - if (Write() < 0) { - jack_error("JackMidiDriver::Process - Write error"); - } else { - fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); - } - return 0; + return (fEngineControl->fSyncMode) ? ProcessReadSync() : ProcessReadAsync(); } -*/ -int JackMidiDriver::Process() +int JackMidiDriver::ProcessWrite() { - return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync(); + return (fEngineControl->fSyncMode) ? ProcessWriteSync() : ProcessWriteAsync(); } -int JackMidiDriver::ProcessSync() +int JackMidiDriver::ProcessReadSync() { int res = 0; // Read input buffers for the current cycle if (Read() < 0) { jack_error("JackMidiDriver::ProcessSync: read error, skip cycle"); - return 0; // Skip cycle, but continue processing... + res = -1; } if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { @@ -205,6 +173,13 @@ int JackMidiDriver::ProcessSync() res = -1; } + return res; +} + +int JackMidiDriver::ProcessWriteSync() +{ + int res = 0; + if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) { @@ -215,24 +190,26 @@ int JackMidiDriver::ProcessSync() // Write output buffers from the current cycle if (Write() < 0) { jack_error("JackMidiDriver::ProcessSync - Write error"); + res = -1; } return res; } -int JackMidiDriver::ProcessAsync() +int JackMidiDriver::ProcessReadAsync() { int res = 0; // Read input buffers for the current cycle if (Read() < 0) { jack_error("JackMidiDriver::ProcessAsync: read error, skip cycle"); - return 0; // Skip cycle, but continue processing... + res = -1; } // Write output buffers from the previous cycle if (Write() < 0) { jack_error("JackMidiDriver::ProcessAsync - Write error"); + res = -1; } if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { @@ -243,6 +220,11 @@ int JackMidiDriver::ProcessAsync() return res; } +int JackMidiDriver::ProcessWriteAsync() +{ + return 0; +} + JackMidiBuffer* JackMidiDriver::GetInputBuffer(int port_index) { assert(fCapturePortList[port_index]); diff --git a/common/JackMidiDriver.h b/common/JackMidiDriver.h index 1ce627d3..45fe484c 100644 --- a/common/JackMidiDriver.h +++ b/common/JackMidiDriver.h @@ -48,6 +48,12 @@ class SERVER_EXPORT JackMidiDriver : public JackDriver JackMidiBuffer* GetInputBuffer(int port_index); JackMidiBuffer* GetOutputBuffer(int port_index); + virtual int ProcessReadSync(); + virtual int ProcessWriteSync(); + + virtual int ProcessReadAsync(); + virtual int ProcessWriteAsync(); + public: JackMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); @@ -63,9 +69,9 @@ class SERVER_EXPORT JackMidiDriver : public JackDriver jack_nframes_t capture_latency, jack_nframes_t playback_latency); - virtual int Process(); - virtual int ProcessSync(); - virtual int ProcessAsync(); + virtual int ProcessRead(); + virtual int ProcessWrite(); + virtual int ProcessNull(); virtual int Attach(); diff --git a/common/JackThreadedDriver.cpp b/common/JackThreadedDriver.cpp index 88323fe5..62260e59 100644 --- a/common/JackThreadedDriver.cpp +++ b/common/JackThreadedDriver.cpp @@ -127,9 +127,24 @@ void JackThreadedDriver::RemoveSlave(JackDriverInterface* slave) fDriver->RemoveSlave(slave); } -int JackThreadedDriver::ProcessSlaves() +int JackThreadedDriver::ProcessReadSlaves() { - return fDriver->ProcessSlaves(); + return fDriver->ProcessReadSlaves(); +} + +int JackThreadedDriver::ProcessWriteSlaves() +{ + return fDriver->ProcessWriteSlaves(); +} + +int JackThreadedDriver::ProcessRead() +{ + return fDriver->ProcessRead(); +} + +int JackThreadedDriver::ProcessWrite() +{ + return fDriver->ProcessWrite(); } std::list JackThreadedDriver::GetSlaves() diff --git a/common/JackThreadedDriver.h b/common/JackThreadedDriver.h index 92ec1d26..9d4876b1 100644 --- a/common/JackThreadedDriver.h +++ b/common/JackThreadedDriver.h @@ -89,10 +89,17 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi virtual void SetMaster(bool onoff); virtual bool GetMaster(); + virtual void AddSlave(JackDriverInterface* slave); virtual void RemoveSlave(JackDriverInterface* slave); + virtual std::list GetSlaves(); - virtual int ProcessSlaves(); + + virtual int ProcessReadSlaves(); + virtual int ProcessWriteSlaves(); + + virtual int ProcessRead(); + virtual int ProcessWrite(); virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); virtual JackClientControl* GetClientControl() const; From faf29128cf7925735ac671ae50dfe55fff89639b Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Fri, 25 Mar 2011 18:40:14 +0100 Subject: [PATCH 073/472] Cleanup JackCoreAudioAdapter. --- macosx/coreaudio/JackCoreAudioAdapter.cpp | 67 +++++++++++------------ macosx/coreaudio/JackCoreAudioDriver.cpp | 11 ++-- 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/macosx/coreaudio/JackCoreAudioAdapter.cpp b/macosx/coreaudio/JackCoreAudioAdapter.cpp index c1e9dc5e..d086a877 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.cpp +++ b/macosx/coreaudio/JackCoreAudioAdapter.cpp @@ -168,7 +168,7 @@ OSStatus JackCoreAudioAdapter::SRNotificationCallback(AudioDeviceID inDevice, switch (inPropertyID) { case kAudioDevicePropertyNominalSampleRate: { - jack_log("JackCoreAudioDriver::SRNotificationCallback kAudioDevicePropertyNominalSampleRate"); + jack_log("JackCoreAudioAdapter::SRNotificationCallback kAudioDevicePropertyNominalSampleRate"); driver->fState = true; break; } @@ -430,12 +430,15 @@ OSStatus JackCoreAudioAdapter::GetDefaultDevice(AudioDeviceID* id) jack_log("GetDefaultDevice: input = %ld output = %ld", inDefault, outDefault); // Get the device only if default input and output are the same - if (inDefault == outDefault) { - *id = inDefault; - return noErr; - } else { + if (inDefault != outDefault) { jack_error("Default input and output devices are not the same !!"); return kAudioHardwareBadDeviceError; + } else if (inDefault == 0) { + jack_error("Default input and output devices are null !!"); + return kAudioHardwareBadDeviceError; + } else { + *id = inDefault; + return noErr; } } @@ -444,20 +447,16 @@ OSStatus JackCoreAudioAdapter::GetTotalChannels(AudioDeviceID device, int& chann OSStatus err = noErr; UInt32 outSize; Boolean outWritable; - AudioBufferList* bufferList = 0; channelCount = 0; err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, &outWritable); if (err == noErr) { - bufferList = (AudioBufferList*)malloc(outSize); + AudioBufferList bufferList[outSize]; err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, bufferList); if (err == noErr) { for (unsigned int i = 0; i < bufferList->mNumberBuffers; i++) channelCount += bufferList->mBuffers[i].mNumberChannels; } - - if (bufferList) - free(bufferList); } return err; @@ -604,7 +603,7 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, // Use default driver in duplex mode } else { - jack_log("JackCoreAudioDriver::Open default driver"); + jack_log("JackCoreAudioAdapter::Open default driver"); if (GetDefaultDevice(&fDeviceID) != noErr) { jack_error("Cannot open default device in duplex mode, so aggregate default input and default output"); @@ -1030,14 +1029,14 @@ OSStatus JackCoreAudioAdapter::DestroyAggregateDevice() osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); if (osErr != noErr) { - jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyDataSize error"); + jack_error("JackCoreAudioAdapter::DestroyAggregateDevice : AudioObjectGetPropertyDataSize error"); printError(osErr); return osErr; } osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, 0, NULL, &outDataSize, &fDeviceID); if (osErr != noErr) { - jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyData error"); + jack_error("JackCoreAudioAdapter::DestroyAggregateDevice : AudioObjectGetPropertyData error"); printError(osErr); return osErr; } @@ -1115,18 +1114,18 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector ca for (UInt32 i = 0; i < captureDeviceID.size(); i++) { if (SetupSampleRateAux(captureDeviceID[i], samplerate) < 0) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of input device"); + jack_error("JackCoreAudioAdapter::CreateAggregateDevice : cannot set SR of input device"); } else { // Check clock domain osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); if (osErr != 0) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); + jack_error("JackCoreAudioAdapter::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); printError(osErr); } else { keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; - jack_log("JackCoreAudioDriver::CreateAggregateDevice : input clockdomain = %d", clockdomain); + jack_log("JackCoreAudioAdapter::CreateAggregateDevice : input clockdomain = %d", clockdomain); if (clockdomain != 0 && clockdomain != keptclockdomain) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); + jack_error("JackCoreAudioAdapter::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); need_clock_drift_compensation = true; } } @@ -1135,18 +1134,18 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector ca for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { if (SetupSampleRateAux(playbackDeviceID[i], samplerate) < 0) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of output device"); + jack_error("JackCoreAudioAdapter::CreateAggregateDevice : cannot set SR of output device"); } else { // Check clock domain osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); if (osErr != 0) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); + jack_error("JackCoreAudioAdapter::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); printError(osErr); } else { keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; - jack_log("JackCoreAudioDriver::CreateAggregateDevice : output clockdomain = %d", clockdomain); + jack_log("JackCoreAudioAdapter::CreateAggregateDevice : output clockdomain = %d", clockdomain); if (clockdomain != 0 && clockdomain != keptclockdomain) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); + jack_error("JackCoreAudioAdapter::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); need_clock_drift_compensation = true; } } @@ -1175,7 +1174,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector ca osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable); if (osErr != noErr) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error"); + jack_error("JackCoreAudioAdapter::CreateAggregateDevice : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error"); printError(osErr); return osErr; } @@ -1191,7 +1190,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector ca osErr = AudioHardwareGetProperty(kAudioHardwarePropertyPlugInForBundleID, &outSize, &pluginAVT); if (osErr != noErr) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioHardwareGetProperty kAudioHardwarePropertyPlugInForBundleID error"); + jack_error("JackCoreAudioAdapter::CreateAggregateDevice : AudioHardwareGetProperty kAudioHardwarePropertyPlugInForBundleID error"); printError(osErr); return osErr; } @@ -1218,13 +1217,13 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector ca SInt32 system; Gestalt(gestaltSystemVersion, &system); - jack_log("JackCoreAudioDriver::CreateAggregateDevice : system version = %x limit = %x", system, 0x00001054); + jack_log("JackCoreAudioAdapter::CreateAggregateDevice : system version = %x limit = %x", system, 0x00001054); // Starting with 10.5.4 systems, the AD can be internal... (better) if (system < 0x00001054) { - jack_log("JackCoreAudioDriver::CreateAggregateDevice : public aggregate device...."); + jack_log("JackCoreAudioAdapter::CreateAggregateDevice : public aggregate device...."); } else { - jack_log("JackCoreAudioDriver::CreateAggregateDevice : private aggregate device...."); + jack_log("JackCoreAudioAdapter::CreateAggregateDevice : private aggregate device...."); CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef); } @@ -1306,14 +1305,14 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector ca osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); if (osErr != noErr) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectGetPropertyDataSize error"); + jack_error("JackCoreAudioAdapter::CreateAggregateDevice : AudioObjectGetPropertyDataSize error"); printError(osErr); goto error; } osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice); if (osErr != noErr) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectGetPropertyData error"); + jack_error("JackCoreAudioAdapter::CreateAggregateDevice : AudioObjectGetPropertyData error"); printError(osErr); goto error; } @@ -1332,7 +1331,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector ca outDataSize = sizeof(CFMutableArrayRef); osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &subDevicesArray); if (osErr != noErr) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectSetPropertyData for sub-device list error"); + jack_error("JackCoreAudioAdapter::CreateAggregateDevice : AudioObjectSetPropertyData for sub-device list error"); printError(osErr); goto error; } @@ -1352,7 +1351,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector ca outDataSize = sizeof(CFStringRef); osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID[0]); // First apture is master... if (osErr != noErr) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectSetPropertyData for master device error"); + jack_error("JackCoreAudioAdapter::CreateAggregateDevice : AudioObjectSetPropertyData for master device error"); printError(osErr); goto error; } @@ -1370,19 +1369,19 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector ca // Get the property data size osErr = AudioObjectGetPropertyDataSize(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize); if (osErr != noErr) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); + jack_error("JackCoreAudioAdapter::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); printError(osErr); } // Calculate the number of object IDs subDevicesNum = outSize / sizeof(AudioObjectID); - jack_info("JackCoreAudioDriver::CreateAggregateDevice clock drift compensation, number of sub-devices = %d", subDevicesNum); + jack_info("JackCoreAudioAdapter::CreateAggregateDevice clock drift compensation, number of sub-devices = %d", subDevicesNum); AudioObjectID subDevices[subDevicesNum]; outSize = sizeof(subDevices); osErr = AudioObjectGetPropertyData(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize, subDevices); if (osErr != noErr) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); + jack_error("JackCoreAudioAdapter::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); printError(osErr); } @@ -1391,7 +1390,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector ca UInt32 theDriftCompensationValue = 1; osErr = AudioObjectSetPropertyData(subDevices[index], &theAddressDrift, 0, NULL, sizeof(UInt32), &theDriftCompensationValue); if (osErr != noErr) { - jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioSubDevicePropertyDriftCompensation error"); + jack_error("JackCoreAudioAdapter::CreateAggregateDevice kAudioSubDevicePropertyDriftCompensation error"); printError(osErr); } } diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 83806646..383babf5 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -386,12 +386,15 @@ OSStatus JackCoreAudioDriver::GetDefaultDevice(AudioDeviceID* id) jack_log("GetDefaultDevice: input = %ld output = %ld", inDefault, outDefault); // Get the device only if default input and output are the same - if (inDefault == outDefault) { - *id = inDefault; - return noErr; - } else { + if (inDefault != outDefault) { jack_error("Default input and output devices are not the same !!"); return kAudioHardwareBadDeviceError; + } else if (inDefault == 0) { + jack_error("Default input and output devices are null !!"); + return kAudioHardwareBadDeviceError; + } else { + *id = inDefault; + return noErr; } } From 280bf48a5ff9e78cef92a3563909146cd1a00165 Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Fri, 25 Mar 2011 18:45:30 -0700 Subject: [PATCH 074/472] Have JackALSARawMidiInputPort use inline 'EnqueueEvent' equivalent. --- linux/alsarawmidi/JackALSARawMidiInputPort.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/linux/alsarawmidi/JackALSARawMidiInputPort.cpp b/linux/alsarawmidi/JackALSARawMidiInputPort.cpp index 7167c8b8..5ed14882 100755 --- a/linux/alsarawmidi/JackALSARawMidiInputPort.cpp +++ b/linux/alsarawmidi/JackALSARawMidiInputPort.cpp @@ -107,13 +107,11 @@ JackALSARawMidiInputPort::ProcessJack(JackMidiBuffer *port_buffer, // We add `frames` so that MIDI events align with audio as closely as // possible. - switch (write_queue->EnqueueEvent(jack_event->time + frames, - jack_event->size, - jack_event->buffer)) { + switch (write_queue->EnqueueEvent(jack_event, frames)) { case JackMidiWriteQueue::BUFFER_TOO_SMALL: - jack_error("JackALSARawMidiInputPort::Process - The write queue " - "couldn't enqueue a %d-byte event. Dropping event.", - jack_event->size); + jack_error("JackALSARawMidiInputPort::ProcessJack - The write " + "queue couldn't enqueue a %d-byte event. Dropping " + "event.", jack_event->size); // Fallthrough on purpose case JackMidiWriteQueue::OK: continue; From 0429665581710d47f01560be597562386c137010 Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Fri, 25 Mar 2011 20:59:22 -0700 Subject: [PATCH 075/472] Overhaulled the CoreMIDI driver. Added queue objects. Added proper event times (I think). WARNING: I've never programmed for Mac. I don't have a Mac development environment. I haven't tested or compiled the code I'm committing (Stephane said he'd take care of that). Don't expect this code to run without a thorough debug and fix session. That said, I hope this code can be turned into something workable. --- macosx/coremidi/JackCoreMidiDriver.cpp | 787 ++++++++++++------ macosx/coremidi/JackCoreMidiDriver.h | 94 ++- macosx/coremidi/JackCoreMidiInputPort.cpp | 181 ++++ macosx/coremidi/JackCoreMidiInputPort.h | 73 ++ macosx/coremidi/JackCoreMidiOutputPort.cpp | 203 +++++ macosx/coremidi/JackCoreMidiOutputPort.h | 83 ++ .../JackCoreMidiPhysicalInputPort.cpp | 53 ++ .../coremidi/JackCoreMidiPhysicalInputPort.h | 45 + .../JackCoreMidiPhysicalOutputPort.cpp | 65 ++ .../coremidi/JackCoreMidiPhysicalOutputPort.h | 56 ++ macosx/coremidi/JackCoreMidiPort.cpp | 90 ++ macosx/coremidi/JackCoreMidiPort.h | 67 ++ macosx/coremidi/JackCoreMidiUtil.cpp | 44 + macosx/coremidi/JackCoreMidiUtil.h | 38 + .../coremidi/JackCoreMidiVirtualInputPort.cpp | 75 ++ .../coremidi/JackCoreMidiVirtualInputPort.h | 50 ++ .../JackCoreMidiVirtualOutputPort.cpp | 72 ++ .../coremidi/JackCoreMidiVirtualOutputPort.h | 50 ++ 18 files changed, 1828 insertions(+), 298 deletions(-) create mode 100644 macosx/coremidi/JackCoreMidiInputPort.cpp create mode 100644 macosx/coremidi/JackCoreMidiInputPort.h create mode 100644 macosx/coremidi/JackCoreMidiOutputPort.cpp create mode 100644 macosx/coremidi/JackCoreMidiOutputPort.h create mode 100644 macosx/coremidi/JackCoreMidiPhysicalInputPort.cpp create mode 100644 macosx/coremidi/JackCoreMidiPhysicalInputPort.h create mode 100644 macosx/coremidi/JackCoreMidiPhysicalOutputPort.cpp create mode 100644 macosx/coremidi/JackCoreMidiPhysicalOutputPort.h create mode 100644 macosx/coremidi/JackCoreMidiPort.cpp create mode 100644 macosx/coremidi/JackCoreMidiPort.h create mode 100644 macosx/coremidi/JackCoreMidiUtil.cpp create mode 100644 macosx/coremidi/JackCoreMidiUtil.h create mode 100644 macosx/coremidi/JackCoreMidiVirtualInputPort.cpp create mode 100644 macosx/coremidi/JackCoreMidiVirtualInputPort.h create mode 100644 macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp create mode 100644 macosx/coremidi/JackCoreMidiVirtualOutputPort.h diff --git a/macosx/coremidi/JackCoreMidiDriver.cpp b/macosx/coremidi/JackCoreMidiDriver.cpp index 1cb7176b..4be05c2d 100644 --- a/macosx/coremidi/JackCoreMidiDriver.cpp +++ b/macosx/coremidi/JackCoreMidiDriver.cpp @@ -1,5 +1,6 @@ /* Copyright (C) 2009 Grame +Copyright (C) 2011 Devin Anderson 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 @@ -17,345 +18,616 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include + +#include + #include "JackCoreMidiDriver.h" -#include "JackGraphManager.h" -#include "JackServer.h" +#include "JackCoreMidiUtil.h" #include "JackEngineControl.h" -#include "JackDriverLoader.h" -#include -#include -#include -#include -#include +/////////////////////////////////////////////////////////////////////////////// +// Static callbacks +/////////////////////////////////////////////////////////////////////////////// -namespace Jack +void +JackCoreMidiDriver::HandleInputEvent(const MIDIPacketList *packet_list, + void *driver, void *port) { + ((JackCoreMidiPhysicalInputPort *) port)->ProcessCoreMidi(packet_list); +} -static MIDITimeStamp MIDIGetCurrentHostTime() +void +JackCoreMidiDriver::HandleNotificationEvent(const MIDINotification *message, + void *driver) { - return mach_absolute_time(); + ((JackCoreMidiDriver *) driver)->HandleNotification(message); } -void JackCoreMidiDriver::ReadProcAux(const MIDIPacketList *pktlist, jack_ringbuffer_t* ringbuffer) +/////////////////////////////////////////////////////////////////////////////// +// Class +/////////////////////////////////////////////////////////////////////////////// + +JackCoreMidiDriver::JackCoreMidiDriver(const char *name, const char *alias, + JackLockedEngine *engine, + JackSynchro *table): + JackMidiDriver(name, alias, engine, table) { - // Write the number of packets - size_t size = jack_ringbuffer_write_space(ringbuffer); - if (size < sizeof(UInt32)) { - jack_error("ReadProc : ring buffer is full, skip events..."); - return; + mach_timebase_info_data_t info; + kern_return_t result = mach_timebase_info(&info); + if (result != KERN_SUCCESS) { + throw std::runtime_error(mach_error_string(result)); } + client = 0; + fCaptureChannels = 0; + fPlaybackChannels = 0; + num_physical_inputs = 0; + num_physical_outputs = 0; + num_virtual_inputs = 0; + num_virtual_outputs = 0; + physical_input_ports = 0; + physical_output_ports = 0; + time_ratio = (((double) info.numer) / info.denom) / 1000.0; + virtual_input_ports = 0; + virtual_output_ports = 0; +} - jack_ringbuffer_write(ringbuffer, (char*)&pktlist->numPackets, sizeof(UInt32)); +JackCoreMidiDriver::~JackCoreMidiDriver() +{ + Stop(); + Close(); +} - for (unsigned int i = 0; i < pktlist->numPackets; ++i) { +int +JackCoreMidiDriver::Attach() +{ + jack_nframes_t buffer_size = fEngineControl->fBufferSize; + jack_port_id_t index; + jack_nframes_t latency = buffer_size; + jack_latency_range_t latency_range; + const char *name; + JackPort *port; + JackCoreMidiPort *port_obj; + latency_range.max = latency; + latency_range.min = latency; + + // Physical inputs + for (int i = 0; i < num_physical_inputs; i++) { + port_obj = physical_input_ports[i]; + name = port_obj->GetName(); + index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, + JACK_DEFAULT_MIDI_TYPE, + CaptureDriverFlags, buffer_size); + if (index == NO_PORT) { + jack_error("JackCoreMidiDriver::Attach - cannot register physical " + "input port with name '%s'.", name); + // X: Do we need to deallocate ports? + return -1; + } + port = fGraphManager->GetPort(index); + port->SetAlias(port_obj->GetAlias()); + port->SetLatencyRange(JackCaptureLatency, &latency_range); + fCapturePortList[i] = index; + } - MIDIPacket *packet = (MIDIPacket *)pktlist->packet; + // Virtual inputs + for (int i = 0; i < num_virtual_inputs; i++) { + port_obj = virtual_input_ports[i]; + name = port_obj->GetName(); + index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, + JACK_DEFAULT_MIDI_TYPE, + CaptureDriverFlags, buffer_size); + if (index == NO_PORT) { + jack_error("JackCoreMidiDriver::Attach - cannot register virtual " + "input port with name '%s'.", name); + // X: Do we need to deallocate ports? + return -1; + } + port = fGraphManager->GetPort(index); + port->SetAlias(port_obj->GetAlias()); + port->SetLatencyRange(JackCaptureLatency, &latency_range); + fCapturePortList[num_physical_inputs + i] = index; + } - // TODO : use timestamp + if (! fEngineControl->fSyncMode) { + latency += buffer_size; + latency_range.max = latency; + latency_range.min = latency; + } - // Check available size first.. - size = jack_ringbuffer_write_space(ringbuffer); - if (size < (sizeof(UInt16) + packet->length)) { - jack_error("ReadProc : ring buffer is full, skip events..."); - return; + // Physical outputs + for (int i = 0; i < num_physical_outputs; i++) { + port_obj = physical_output_ports[i]; + name = port_obj->GetName(); + index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, + JACK_DEFAULT_MIDI_TYPE, + PlaybackDriverFlags, buffer_size); + if (index == NO_PORT) { + jack_error("JackCoreMidiDriver::Attach - cannot register physical " + "output port with name '%s'.", name); + // X: Do we need to deallocate ports? + return -1; } - // Write length of each packet first - jack_ringbuffer_write(ringbuffer, (char*)&packet->length, sizeof(UInt16)); - // Write event actual data - jack_ringbuffer_write(ringbuffer, (char*)packet->data, packet->length); + port = fGraphManager->GetPort(index); + port->SetAlias(port_obj->GetAlias()); + port->SetLatencyRange(JackPlaybackLatency, &latency_range); + fPlaybackPortList[i] = index; + } - packet = MIDIPacketNext(packet); + // Virtual outputs + for (int i = 0; i < num_virtual_outputs; i++) { + port_obj = virtual_output_ports[i]; + name = port_obj->GetName(); + index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, + JACK_DEFAULT_MIDI_TYPE, + PlaybackDriverFlags, buffer_size); + if (index == NO_PORT) { + jack_error("JackCoreMidiDriver::Attach - cannot register virtual " + "output port with name '%s'.", name); + // X: Do we need to deallocate ports? + return -1; + } + port = fGraphManager->GetPort(index); + port->SetAlias(port_obj->GetAlias()); + port->SetLatencyRange(JackPlaybackLatency, &latency_range); + fPlaybackPortList[num_physical_outputs + i] = index; } -} -void JackCoreMidiDriver::ReadProc(const MIDIPacketList *pktlist, void *refCon, void *connRefCon) -{ - jack_ringbuffer_t* ringbuffer = (jack_ringbuffer_t*)connRefCon; - ReadProcAux(pktlist, ringbuffer); + return 0; } -void JackCoreMidiDriver::ReadVirtualProc(const MIDIPacketList *pktlist, void *refCon, void *connRefCon) +int +JackCoreMidiDriver::Close() { - jack_ringbuffer_t* ringbuffer = (jack_ringbuffer_t*)refCon; - ReadProcAux(pktlist, ringbuffer); + int result = 0; + OSStatus status; + if (physical_input_ports) { + for (int i = 0; i < num_physical_inputs; i++) { + delete physical_input_ports[i]; + } + delete[] physical_input_ports; + num_physical_inputs = 0; + physical_input_ports = 0; + status = MIDIPortDispose(internal_input); + if (status != noErr) { + WriteMacOSError("JackCoreMidiDriver::Close", "MIDIPortDispose", + status); + result = -1; + } + } + if (physical_output_ports) { + for (int i = 0; i < num_physical_outputs; i++) { + delete physical_output_ports[i]; + } + delete[] physical_output_ports; + num_physical_outputs = 0; + physical_output_ports = 0; + status = MIDIPortDispose(internal_output); + if (status != noErr) { + WriteMacOSError("JackCoreMidiDriver::Close", "MIDIPortDispose", + status); + result = -1; + } + } + if (virtual_input_ports) { + for (int i = 0; i < num_virtual_inputs; i++) { + delete virtual_input_ports[i]; + } + delete[] virtual_input_ports; + num_virtual_inputs = 0; + virtual_input_ports = 0; + } + if (virtual_output_ports) { + for (int i = 0; i < num_virtual_outputs; i++) { + delete virtual_output_ports[i]; + } + delete[] virtual_output_ports; + num_virtual_outputs = 0; + virtual_output_ports = 0; + } + if (client) { + status = MIDIClientDispose(client); + if (status != noErr) { + WriteMacOSError("JackCoreMidiDriver::Close", "MIDIClientDispose", + status); + result = -1; + } + client = 0; + } + return result; } -void JackCoreMidiDriver::NotifyProc(const MIDINotification *message, void *refCon) +void +JackCoreMidiDriver::HandleNotification(const MIDINotification *message) { - jack_log("NotifyProc %d", message->messageID); + // Empty } -JackCoreMidiDriver::JackCoreMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) - : JackMidiDriver(name, alias, engine, table), fMidiClient(NULL), fInputPort(NULL), fOutputPort(NULL), fRealCaptureChannels(0), fRealPlaybackChannels(0) -{} - -JackCoreMidiDriver::~JackCoreMidiDriver() -{} - -int JackCoreMidiDriver::Open(bool capturing, - bool playing, - int inchannels, - int outchannels, - bool monitor, - const char* capture_driver_name, - const char* playback_driver_name, - jack_nframes_t capture_latency, - jack_nframes_t playback_latency) - { - OSStatus err; - CFStringRef coutputStr; - std::string str; - - // Get real input/output number - fRealCaptureChannels = MIDIGetNumberOfSources(); - fRealPlaybackChannels = MIDIGetNumberOfDestinations(); - - // Generic JackMidiDriver Open - if (JackMidiDriver::Open(capturing, playing, inchannels + fRealCaptureChannels, outchannels + fRealPlaybackChannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0) +int +JackCoreMidiDriver::Open(bool capturing, bool playing, int in_channels, + int out_channels, bool monitor, + const char* capture_driver_name, + const char* playback_driver_name, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency) +{ + int pi_count = 0; + int po_count = 0; + int vi_count = 0; + int vo_count = 0; + CFStringRef name = CFStringCreateWithCString(0, "JackMidi", + CFStringGetSystemEncoding()); + if (! name) { + jack_error("JackCoreMidiDriver::Open - failed to allocate memory for " + "client name string"); return -1; + } + OSStatus status = MIDIClientCreate(name, HandleNotificationEvent, this, + &client); + CFRelease(name); + if (status != noErr) { + WriteMacOSError("JackCoreMidiDriver::Close", "MIDIClientCreate", + status); + return -1; + } + char *client_name = fClientControl.fName; + int port_rt_priority = fEngineControl->fServerPriority + 1; + + // Allocate and connect virtual inputs + if (in_channels) { + try { + virtual_input_ports = + new JackCoreMidiVirtualInputPort[in_channels]; + } catch (std::exception e) { + jack_error("JackCoreMidiDriver::Open - while creating virtual " + "input port array: %s", e.what()); + goto destroy_client; + } + for (vi_count = 0; vi_count < in_channels; vi_count++) { + try { + virtual_input_ports[vi_count] = + new JackCoreMidiVirtualInputPort(fAliasName, client_name, + capture_driver_name, + vi_count, client, + time_ratio); + } catch (std::exception e) { + jack_error("JackCoreMidiDriver::Open - while creating virtual " + "input port: %s", e.what()); + goto destroy_virtual_input_ports; + } + } + } - coutputStr = CFStringCreateWithCString(0, "JackMidi", CFStringGetSystemEncoding()); - err = MIDIClientCreate(coutputStr, NotifyProc, this, &fMidiClient); - CFRelease(coutputStr); - if (!fMidiClient) { - jack_error("Cannot create CoreMidi client"); - goto error; - } - - err = MIDIInputPortCreate(fMidiClient, CFSTR("Input port"), ReadProc, this, &fInputPort); - if (!fInputPort) { - jack_error("Cannot open CoreMidi in port\n"); - goto error; - } - - err = MIDIOutputPortCreate(fMidiClient, CFSTR("Output port"), &fOutputPort); - if (!fOutputPort) { - jack_error("Cannot open CoreMidi out port\n"); - goto error; - } - - fMidiDestination = new MIDIEndpointRef[inchannels + fRealCaptureChannels]; - assert(fMidiDestination); + // Allocate and connect virtual outputs + if (out_channels) { + try { + virtual_output_ports = + new JackCoreMidiVirtualOutputPort[out_channels]; + } catch (std::exception e) { + jack_error("JackCoreMidiDriver::Open - while creating virtual " + "output port array: %s", e.what()); + goto destroy_virtual_input_ports; + } + for (vo_count = 0; vo_count < out_channels; vo_count++) { + try { + virtual_output_ports[vo_count] = + new JackCoreMidiVirtualOutputPort(fAliasName, client_name, + playback_driver_name, + vo_count, client, + time_ratio, + port_rt_priority); + } catch (std::exception e) { + jack_error("JackCoreMidiDriver::Open - while creating virtual " + "output port: %s", e.what()); + goto destroy_virtual_output_ports; + } + } + } - // Virtual input - for (int i = 0; i < inchannels; i++) { - std::stringstream num; - num << i; - str = "JackMidi" + num.str(); - coutputStr = CFStringCreateWithCString(0, str.c_str(), CFStringGetSystemEncoding()); - err = MIDIDestinationCreate(fMidiClient, coutputStr, ReadVirtualProc, fRingBuffer[i], &fMidiDestination[i]); - CFRelease(coutputStr); - if (!fMidiDestination[i]) { - jack_error("Cannot create CoreMidi destination"); - goto error; + // Allocate and connect physical inputs + ItemCount potential_pi_count = MIDIGetNumberOfSources(); + if (potential_pi_count) { + status = MIDIInputPortCreate(client, CFSTR("Physical Input Port"), + HandleInputEvent, this, &internal_input); + if (status != noErr) { + WriteMacOSError("JackCoreMidiDriver::Open", "MIDIInputPortCreate", + status); + goto destroy_virtual_output_ports; + } + try { + physical_input_ports = + new JackCoreMidiPhysicalInputPort[potential_pi_count]; + } catch (std::exception e) { + jack_error("JackCoreMidiDriver::Open - while creating physical " + "input port array: %s", e.what()); + goto destroy_internal_input_port; + } + for (ItemCount i = 0; i < potential_pi_count; i++) { + try { + physical_input_ports[pi_count] = + new JackCoreMidiPhysicalInputPort(fAliasName, client_name, + capture_driver_name, i, + client, internal_input, + time_ratio); + } catch (std::exception e) { + jack_error("JackCoreMidiDriver::Open - while creating " + "physical input port: %s", e.what()); + continue; + } + pi_count++; } } - // Real input - for (int i = 0; i < fRealCaptureChannels; i++) { - fMidiDestination[i + inchannels] = MIDIGetSource(i); - MIDIPortConnectSource(fInputPort, fMidiDestination[i + inchannels], fRingBuffer[i + inchannels]); + // Allocate and connect physical outputs + ItemCount potential_po_count = MIDIGetNumberOfDestinations(); + if (potential_po_count) { + status = MIDIOutputPortCreate(client, CFSTR("Physical Output Port"), + &internal_output); + if (status != noErr) { + WriteMacOSError("JackCoreMidiDriver::Open", "MIDIOutputPortCreate", + status); + goto destroy_physical_input_ports; + } + try { + physical_output_ports = + new JackCoreMidiPhysicalOutputPort[potential_po_count]; + } catch (std::exception e) { + jack_error("JackCoreMidiDriver::Open - while creating physical " + "output port array: %s", e.what()); + goto destroy_internal_output_port; + } + for (ItemCount i = 0; i < potential_po_count; i++) { + try { + physical_output_ports[po_count] = + new JackCoreMidiPhysicalOutputPort(fAliasName, client_name, + playback_driver_name, i, + client, internal_output, + time_ratio, + port_rt_priority); + } catch (std::exception e) { + jack_error("JackCoreMidiDriver::Open - while creating " + "physical output port: %s", e.what()); + continue; + } + po_count++; + } } - fMidiSource = new MIDIEndpointRef[outchannels + fRealPlaybackChannels]; - assert(fMidiSource); + if (! (pi_count || po_count || in_channels || out_channels)) { + jack_error("JackCoreMidiDriver::Open - no CoreMIDI inputs or outputs " + "found, and no virtual ports allocated."); + } else if (! JackMidiDriver::Open(capturing, playing, + in_channels + pi_count, + out_channels + po_count, monitor, + capture_driver_name, + playback_driver_name, capture_latency, + playback_latency)) { + num_physical_inputs = pi_count; + num_physical_outputs = po_count; + num_virtual_inputs = in_channels; + num_virtual_outputs = out_channels; + return 0; + } - // Virtual output - for (int i = 0; i < outchannels; i++) { - std::stringstream num; - num << i; - str = "JackMidi" + num.str(); - coutputStr = CFStringCreateWithCString(0, str.c_str(), CFStringGetSystemEncoding()); - err = MIDISourceCreate(fMidiClient, coutputStr, &fMidiSource[i]); - CFRelease(coutputStr); - if (!fMidiSource[i]) { - jack_error("Cannot create CoreMidi source"); - goto error; + // Cleanup + if (physical_output_ports) { + for (int i = 0; i < po_count; i++) { + delete physical_output_ports[i]; } + delete[] physical_output_ports; + physical_output_ports = 0; } - - // Real output - for (int i = 0; i < fRealPlaybackChannels; i++) { - fMidiSource[i + outchannels] = MIDIGetDestination(i); + destroy_internal_output_port: + status = MIDIPortDispose(internal_output); + if (status != noErr) { + WriteMacOSError("JackCoreMidiDriver::Open", "MIDIPortDispose", status); } + destroy_physical_input_ports: + if (physical_input_ports) { + for (int i = 0; i < pi_count; i++) { + delete physical_input_ports[i]; + } + delete[] physical_input_ports; + physical_input_ports = 0; + } + destroy_internal_input_port: + status = MIDIPortDispose(internal_input); + if (status != noErr) { + WriteMacOSError("JackCoreMidiDriver::Open", "MIDIPortDispose", status); + } + destroy_virtual_output_ports: + if (virtual_output_ports) { + for (int i = 0; i < vo_count; i++) { + delete virtual_output_ports[i]; + } + delete[] virtual_output_ports; + virtual_output_ports = 0; + } + destroy_virtual_input_ports: + if (virtual_input_ports) { + for (int i = 0; i < vi_count; i++) { + delete virtual_input_ports[i]; + } + delete[] virtual_input_ports; + virtual_input_ports = 0; + } + destroy_client: + status = MIDIClientDispose(client); + if (status != noErr) { + WriteMacOSError("JackCoreMidiDriver::Open", "MIDIClientDispose", + status); + } + client = 0; + return -1; +} +int +JackCoreMidiDriver::Read() +{ + jack_nframes_t buffer_size = fEngineControl->fBufferSize; + for (int i = 0; i < num_physical_inputs; i++) { + physical_input_ports[i]->ProcessJack(GetInputBuffer(i), buffer_size); + } + for (int i = 0; i < num_virtual_inputs; i++) { + virtual_input_ports[i]-> + ProcessJack(GetInputBuffer(num_physical_inputs + i), buffer_size); + } return 0; - -error: - Close(); - return -1; } -int JackCoreMidiDriver::Close() +int +JackCoreMidiDriver::Start() { - // Generic midi driver close - int res = JackMidiDriver::Close(); + jack_info("JackCoreMidiDriver::Start - Starting driver."); - if (fInputPort) - MIDIPortDispose(fInputPort); + JackMidiDriver::Start(); - if (fOutputPort) - MIDIPortDispose(fOutputPort); + int pi_count = 0; + int po_count = 0; + int vi_count = 0; + int vo_count = 0; - // Only dispose "virtual" endpoints - for (int i = 0; i < fCaptureChannels - fRealCaptureChannels; i++) { - if (fMidiDestination) - MIDIEndpointDispose(fMidiDestination[i]); - } - delete[] fMidiDestination; + jack_info("JackCoreMidiDriver::Start - Enabling physical input ports."); - // Only dispose "virtual" endpoints - for (int i = 0; i < fPlaybackChannels - fRealPlaybackChannels; i++) { - if (fMidiSource[i]) - MIDIEndpointDispose(fMidiSource[i]); + for (; pi_count < num_physical_inputs; pi_count++) { + if (physical_input_ports[pi_count]->Start() < 0) { + jack_error("JackCoreMidiDriver::Start - Failed to enable physical " + "input port."); + goto stop_physical_input_ports; + } } - delete[] fMidiSource; - if (fMidiClient) - MIDIClientDispose(fMidiClient); + jack_info("JackCoreMidiDriver::Start - Enabling physical output ports."); - return res; -} - -int JackCoreMidiDriver::Attach() -{ - OSStatus err; - JackPort* port; - CFStringRef pname; - jack_port_id_t port_index; - char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - char endpoint_name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - int i; - - jack_log("JackCoreMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); - - for (i = 0; i < fCaptureChannels; i++) { - - err = MIDIObjectGetStringProperty(fMidiDestination[i], kMIDIPropertyName, &pname); - if (err == noErr) { - CFStringGetCString(pname, endpoint_name, sizeof(endpoint_name), 0); - CFRelease(pname); - snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, endpoint_name, i + 1); - } else { - snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); + for (; po_count < num_physical_outputs; po_count++) { + if (physical_output_ports[po_count]->Start() < 0) { + jack_error("JackCoreMidiDriver::Start - Failed to enable physical " + "output port."); + goto stop_physical_output_ports; } - - snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { - jack_error("driver: cannot register port for %s", name); - return -1; - } - port = fGraphManager->GetPort(port_index); - port->SetAlias(alias); - fCapturePortList[i] = port_index; - jack_log("JackCoreMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index); } - for (i = 0; i < fPlaybackChannels; i++) { + jack_info("JackCoreMidiDriver::Start - Enabling virtual input ports."); - err = MIDIObjectGetStringProperty(fMidiSource[i], kMIDIPropertyName, &pname); - if (err == noErr) { - CFStringGetCString(pname, endpoint_name, sizeof(endpoint_name), 0); - CFRelease(pname); - snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, endpoint_name, i + 1); - } else { - snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); + for (; vi_count < num_virtual_inputs; vi_count++) { + if (virtual_input_ports[vi_count]->Start() < 0) { + jack_error("JackCoreMidiDriver::Start - Failed to enable virtual " + "input port."); + goto stop_virtual_input_ports; } + } - snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { - jack_error("driver: cannot register port for %s", name); - return -1; + jack_info("JackCoreMidiDriver::Start - Enabling virtual output ports."); + + for (; vo_count < num_virtual_outputs; vo_count++) { + if (virtual_output_ports[vo_count]->Start() < 0) { + jack_error("JackCoreMidiDriver::Start - Failed to enable virtual " + "output port."); + goto stop_virtual_output_ports; } - port = fGraphManager->GetPort(port_index); - port->SetAlias(alias); - fPlaybackPortList[i] = port_index; - jack_log("JackCoreMidiDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); } - return 0; -} -int JackCoreMidiDriver::Read() -{ - for (int chan = 0; chan < fCaptureChannels; chan++) { - - if (fGraphManager->GetConnectionsNum(fCapturePortList[chan]) > 0) { + jack_info("JackCoreMidiDriver::Start - Driver started."); - // Get JACK port - JackMidiBuffer* midi_buffer = GetInputBuffer(chan); + return 0; - if (jack_ringbuffer_read_space(fRingBuffer[chan]) == 0) { - // Reset buffer - midi_buffer->Reset(midi_buffer->nframes); - } else { + stop_virtual_output_ports: + for (int i = 0; i < vo_count; i++) { + if (virtual_output_ports[i]->Stop() < 0) { + jack_error("JackCoreMidiDriver::Start - Failed to disable virtual " + "output port."); + } + } + stop_virtual_input_ports: + for (int i = 0; i < vi_count; i++) { + if (virtual_input_ports[i]->Stop() < 0) { + jack_error("JackCoreMidiDriver::Start - Failed to disable virtual " + "input port."); + } + } + stop_physical_output_ports: + for (int i = 0; i < po_count; i++) { + if (physical_output_ports[i]->Stop() < 0) { + jack_error("JackCoreMidiDriver::Start - Failed to disable " + "physical output port."); + } + } + stop_physical_input_ports: + for (int i = 0; i < pi_count; i++) { + if (physical_input_ports[i]->Stop() < 0) { + jack_error("JackCoreMidiDriver::Start - Failed to disable " + "physical input port."); + } + } - while (jack_ringbuffer_read_space(fRingBuffer[chan]) > 0) { + return -1; +} - // Read event number - int ev_count = 0; - jack_ringbuffer_read(fRingBuffer[chan], (char*)&ev_count, sizeof(int)); +int +JackCoreMidiDriver::Stop() +{ + int result = 0; - for (int j = 0; j < ev_count; j++) { - // Read event length - UInt16 event_len; - jack_ringbuffer_read(fRingBuffer[chan], (char*)&event_len, sizeof(UInt16)); - // Read event actual data - jack_midi_data_t* dest = midi_buffer->ReserveEvent(0, event_len); - jack_ringbuffer_read(fRingBuffer[chan], (char*)dest, event_len); - } - } - } + jack_info("JackCoreMidiDriver::Stop - disabling physical input ports."); - } else { - // Consume ring buffer - jack_ringbuffer_read_advance(fRingBuffer[chan], jack_ringbuffer_read_space(fRingBuffer[chan])); + for (int i = 0; i < num_physical_inputs; i++) { + if (physical_input_ports[i]->Stop() < 0) { + jack_error("JackCoreMidiDriver::Stop - Failed to disable physical " + "input port."); + result = -1; } } - return 0; -} - -int JackCoreMidiDriver::Write() -{ - MIDIPacketList* pktlist = (MIDIPacketList*)fMIDIBuffer; - for (int chan = 0; chan < fPlaybackChannels; chan++) { + jack_info("JackCoreMidiDriver::Stop - disabling physical output ports."); - if (fGraphManager->GetConnectionsNum(fPlaybackPortList[chan]) > 0) { + for (int i = 0; i < num_physical_outputs; i++) { + if (physical_output_ports[i]->Stop() < 0) { + jack_error("JackCoreMidiDriver::Stop - Failed to disable physical " + "output port."); + result = -1; + } + } - MIDIPacket* packet = MIDIPacketListInit(pktlist); - JackMidiBuffer* midi_buffer = GetOutputBuffer(chan); + jack_info("JackCoreMidiDriver::Stop - disabling virtual input ports."); - // TODO : use timestamp + for (int i = 0; i < num_virtual_inputs; i++) { + if (virtual_input_ports[i]->Stop() < 0) { + jack_error("JackCoreMidiDriver::Stop - Failed to disable virtual " + "input port."); + result = -1; + } + } - for (unsigned int j = 0; j < midi_buffer->event_count; j++) { - JackMidiEvent* ev = &midi_buffer->events[j]; - packet = MIDIPacketListAdd(pktlist, sizeof(fMIDIBuffer), packet, MIDIGetCurrentHostTime(), ev->size, ev->GetData(midi_buffer)); - } + jack_info("JackCoreMidiDriver::Stop - disabling virtual output ports."); - if (packet) { - if (chan < fPlaybackChannels - fRealPlaybackChannels) { - OSStatus err = MIDIReceived(fMidiSource[chan], pktlist); - if (err != noErr) - jack_error("MIDIReceived error"); - } else { - OSStatus err = MIDISend(fOutputPort, fMidiSource[chan], pktlist); - if (err != noErr) - jack_error("MIDISend error"); - } - } + for (int i = 0; i < num_virtual_outputs; i++) { + if (virtual_output_ports[i]->Stop() < 0) { + jack_error("JackCoreMidiDriver::Stop - Failed to disable virtual " + "output port."); + result = -1; } } - return 0; + return result; } -} // end of namespace +int +JackCoreMidiDriver::Write() +{ + jack_nframes_t buffer_size = fEngineControl->fBufferSize; + for (int i = 0; i < num_physical_outputs; i++) { + physical_output_ports[i]->ProcessJack(GetOutputBuffer(i), buffer_size); + } + for (int i = 0; i < num_virtual_outputs; i++) { + virtual_output_ports[i]-> + ProcessJack(GetOutputBuffer(num_physical_outputs + i), + buffer_size); + } + return 0; +} #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor() @@ -423,4 +695,3 @@ extern "C" #ifdef __cplusplus } #endif - diff --git a/macosx/coremidi/JackCoreMidiDriver.h b/macosx/coremidi/JackCoreMidiDriver.h index a99b35a0..34056c33 100644 --- a/macosx/coremidi/JackCoreMidiDriver.h +++ b/macosx/coremidi/JackCoreMidiDriver.h @@ -1,5 +1,6 @@ /* Copyright (C) 2009 Grame +Copyright (C) 2011 Devin Anderson 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 @@ -20,61 +21,74 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifndef __JackCoreMidiDriver__ #define __JackCoreMidiDriver__ -#include +#include "JackCoreMidiPhysicalInputPort.h" +#include "JackCoreMidiPhysicalOutputPort.h" +#include "JackCoreMidiVirtualInputPort.h" +#include "JackCoreMidiVirtualOutputPort.h" #include "JackMidiDriver.h" -#include "JackTime.h" -namespace Jack -{ +namespace Jack { -/*! -\brief The CoreMidi driver. -*/ - -class JackCoreMidiDriver : public JackMidiDriver -{ + class JackCoreMidiDriver: public JackMidiDriver { private: - MIDIClientRef fMidiClient; - MIDIPortRef fInputPort; - MIDIPortRef fOutputPort; - MIDIEndpointRef* fMidiDestination; - MIDIEndpointRef* fMidiSource; + static void + HandleInputEvent(const MIDIPacketList *packet_list, void *driver, + void *port); + + static void + HandleNotificationEvent(const MIDINotification *message, void *driver); + + void + HandleNotification(const MIDINotification *message); + + MIDIClientRef client; + MIDIPortRef internal_input; + MIDIPortRef internal_output; + int num_physical_inputs; + int num_physical_outputs; + int num_virtual_inputs; + int num_virtual_outputs; + JackCoreMidiPhysicalInputPort *physical_input_ports; + JackCoreMidiPhysicalOutputPort *physical_output_ports; + double time_ratio; + JackCoreMidiVirtualInputPort *virtual_input_ports; + JackCoreMidiVirtualOutputPort *virtual_output_ports; + + public: - char fMIDIBuffer[BUFFER_SIZE_MAX * sizeof(jack_default_audio_sample_t)]; + JackCoreMidiDriver(const char* name, const char* alias, + JackLockedEngine* engine, JackSynchro* table); - int fRealCaptureChannels; - int fRealPlaybackChannels; + ~JackCoreMidiDriver(); - static void ReadProcAux(const MIDIPacketList *pktlist, jack_ringbuffer_t* ringbuffer); - static void ReadProc(const MIDIPacketList *pktlist, void *refCon, void *connRefCon); - static void ReadVirtualProc(const MIDIPacketList *pktlist, void *refCon, void *connRefCon); - static void NotifyProc(const MIDINotification *message, void *refCon); + int + Attach(); - public: + int + Close(); + + int + Open(bool capturing, bool playing, int num_inputs, int num_outputs, + bool monitor, const char* capture_driver_name, + const char* playback_driver_name, jack_nframes_t capture_latency, + jack_nframes_t playback_latency); - JackCoreMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); - virtual ~JackCoreMidiDriver(); + int + Read(); - int Open( bool capturing, - bool playing, - int chan_in, - int chan_out, - bool monitor, - const char* capture_driver_name, - const char* playback_driver_name, - jack_nframes_t capture_latency, - jack_nframes_t playback_latency); - int Close(); + int + Start(); - int Attach(); + int + Stop(); - int Read(); - int Write(); + int + Write(); -}; + }; -} // end of namespace +} #endif diff --git a/macosx/coremidi/JackCoreMidiInputPort.cpp b/macosx/coremidi/JackCoreMidiInputPort.cpp new file mode 100644 index 00000000..20d2af0c --- /dev/null +++ b/macosx/coremidi/JackCoreMidiInputPort.cpp @@ -0,0 +1,181 @@ +/* +Copyright (C) 2011 Devin Anderson + +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. + +*/ + +#include +#include + +#include "JackCoreMidiInputPort.h" +#include "JackMidiUtil.h" + +using Jack::JackCoreMidiInputPort; + +JackCoreMidiInputPort::JackCoreMidiInputPort(double time_ratio, + size_t max_bytes, + size_t max_messages): + JackCoreMidiPort(time_ratio) +{ + thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); + std::auto_ptr thread_queue_ptr(thread_queue); + write_queue = new JackMidiBufferWriteQueue(); + std::auto_ptr write_queue_ptr(write_queue); + sysex_buffer = new jack_midi_data_t[max_bytes]; + write_queue_ptr.release(); + thread_queue_ptr.release(); + jack_event = 0; +} + +JackCoreMidiInputPort::~JackCoreMidiInputPort() +{ + delete thread_queue; + delete write_queue; + delete[] sysex_buffer; +} + +jack_frames_t +JackCoreMidiPort::GetFramesFromTimeStamp(MIDITimeStamp timestamp) +{ + return GetFramesFromTime((jack_time_t) (timestamp * time_ratio)); +} + +void +JackCoreMidiInputPort::Initialize(const char *alias_name, + const char *client_name, + const char *driver_name, int index, + MIDIEndpointRef endpoint) +{ + Initialize(alias_name, client_name, driver_name, index, endpoint, false); +} + +void +JackCoreMidiInputPort::ProcessCoreMidi(const MIDIPacketList *packet_list) +{ + unsigned int packet_count = packet_list->numPackets; + assert(packet_count); + MIDIPacket *packet = (MIDIPacket *) packet_list->packet; + for (unsigned int i = 0; i < packet_count; i++) { + jack_midi_data_t *data = packet->data; + size_t size = packet->length; + assert(size); + jack_midi_event_t event; + + // XX: There might be dragons in my spaghetti. This code is begging + // for a rewrite. + + if (sysex_bytes_sent) { + if (data[0] & 0x80) { + jack_error("JackCoreMidiInputPort::ProcessCoreMidi - System " + "exclusive message aborted."); + sysex_bytes_sent = 0; + goto parse_event; + } + buffer_sysex_bytes: + if ((sysex_bytes_sent + size) <= sizeof(sysex_buffer)) { + memcpy(sysex_buffer + sysex_bytes_sent, packet, + size * sizeof(jack_midi_data_t)); + } + sysex_bytes_sent += size; + if (data[size - 1] == 0xf7) { + if (sysex_bytes_sent > sizeof(sysex_buffer)) { + jack_error("JackCoreMidiInputPort::ProcessCoreMidi - " + "Could not buffer a %d-byte system exclusive " + "message. Discarding message.", + sysex_bytes_sent); + sysex_bytes_sent = 0; + goto get_next_packet; + } + event.data = sysex_buffer; + event.size = sysex_bytes_sent; + event.time = ; + sysex_bytes_sent = 0; + goto send_event; + } + goto get_next_packet; + } + + parse_event: + if (data[0] == 0xf0) { + if (data[size - 1] != 0xf7) { + goto buffer_sysex_bytes; + } + } + event.data = data; + event.size = size; + + send_event: + event.time = GetFramesFromTimeStamp(packet->timeStamp); + switch (thread_queue->EnqueueEvent(&event)) { + case JackMidiWriteQueue::BUFFER_FULL: + jack_error("JackCoreMidiInputPort::ProcessCoreMidi - The thread " + "queue buffer is full. Dropping event."); + break; + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + jack_error("JackCoreMidiInputPort::ProcessCoreMidi - The thread " + "queue couldn't enqueue a %d-byte packet. Dropping " + "event.", event->size); + break; + default: + ; + } + + get_next_packet: + packet = MIDIPacketNext(packet); + assert(packet); + } +} + +void +JackCoreMidiInputPort::ProcessJack(JackMidiBuffer *port_buffer, + jack_nframes_t frames) +{ + write_queue->ResetMidiBuffer(port_buffer); + if (! jack_event) { + jack_event = thread_queue->DequeueEvent(); + } + for (; jack_event; jack_event = thread_queue->DequeueEvent()) { + // Add 'frames' to MIDI events to align with audio. + switch (write_queue->EnqueueEvent(jack_event, frames)) { + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + jack_error("JackCoreMidiInputPort::ProcessJack - The write queue " + "couldn't enqueue a %d-byte event. Dropping event.", + jack_event->size); + // Fallthrough on purpose + case JackMidiWriteQueue::OK: + continue; + default: + ; + } + break; + } +} + +bool +JackCoreMidiInputPort::Start() +{ + // Hack: Get rid of any messages that might have come in before starting + // the engine. + while (thread_queue->DequeueEvent()); + sysex_bytes_sent = 0; + return true; +} + +bool +JackCoreMidiInputPort::Stop() +{ + return true; +} diff --git a/macosx/coremidi/JackCoreMidiInputPort.h b/macosx/coremidi/JackCoreMidiInputPort.h new file mode 100644 index 00000000..3950c70c --- /dev/null +++ b/macosx/coremidi/JackCoreMidiInputPort.h @@ -0,0 +1,73 @@ +/* +Copyright (C) 2011 Devin Anderson + +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 __JackCoreMidiInputPort__ +#define __JackCoreMidiInputPort__ + +#include "JackCoreMidiPort.h" +#include "JackMidiAsyncQueue.h" +#include "JackMidiBufferWriteQueue.h" + +namespace Jack { + + class JackCoreMidiInputPort: public JackCoreMidiPort { + + private: + + jack_nframes_t + GetFramesFromTimeStamp(MIDITimeStamp timestamp); + + jack_midi_event_t *jack_event; + jack_midi_data_t *sysex_buffer; + size_t sysex_bytes_sent; + JackMidiAsyncQueue *thread_queue; + JackMidiBufferWriteQueue *write_queue; + + protected: + + void + Initialize(const char *alias_name, const char *client_name, + const char *driver_name, int index, + MIDIEndpointRef endpoint); + + public: + + JackCoreMidiInputPort(double time_ratio, size_t max_bytes=4096, + size_t max_messages=1024); + + virtual + ~JackCoreMidiInputPort(); + + void + ProcessCoreMidi(const MIDIPacketList *packet_list); + + void + ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames); + + bool + Start(); + + bool + Stop(); + + }; + +} + +#endif diff --git a/macosx/coremidi/JackCoreMidiOutputPort.cpp b/macosx/coremidi/JackCoreMidiOutputPort.cpp new file mode 100644 index 00000000..dced4fab --- /dev/null +++ b/macosx/coremidi/JackCoreMidiOutputPort.cpp @@ -0,0 +1,203 @@ +/* +Copyright (C) 2011 Devin Anderson + +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. + +*/ + +#include +#include + +#include "JackCoreMidiOutputPort.h" + +using Jack::JackCoreMidiOutputPort; + +JackCoreMidiOutputPort::JackCoreMidiOutputPort(double time_ratio, + int realtime_priority, + size_t max_bytes, + size_t max_messages): + JackCoreMidiPort(time_ratio) +{ + read_queue = new JackMidiBufferReadQueue(); + std::auto_ptr read_ptr(read_queue); + thread_queue = new JackMidiAsyncWaitQueue(max_bytes, max_messages); + std::auto_ptr thread_ptr(thread_queue); + thread = new JackThread(this); + this->realtime_priority = realtime_priority; + thread_ptr.release(); + read_ptr.release(); +} + +JackCoreMidiOutputPort::~JackCoreMidiOutputPort() +{ + Stop(); + delete thread; + delete read_queue; + delete thread_queue; +} + +bool +JackCoreMidiOutputPort::Execute() +{ + jack_midi_event_t *event = 0; + MIDIPacketList *packet_list = (MIDIPacketList *) packet_buffer; + for (;;) { + MIDIPacket *packet = MIDIPacketListInit(packet_list); + assert(packet); + if (! event) { + event = thread_queue->DequeueEvent((long) 0); + } + jack_midi_data_t *data = event->data; + + // This is the latest time that the packet list can be sent out. We + // may want to consider subtracting some frames to leave room for the + // CoreMIDI driver/client to handle all of the events. There's a + // property called 'kMIDIPropertyAdvanceScheduleTimeMuSec' that might + // be useful in this case. + jack_nframes_t send_time = event->time; + + size_t size = event->size; + MIDITimeStamp timestamp = GetTimeStampFromFrames(send_time); + packet = MIDIPacketListAdd(packet_list, PACKET_BUFFER_SIZE, packet, + timestamp, size, data); + if (packet) { + while (GetCurrentFrame() < send_time) { + event = thread_queue->DequeueEvent(); + if (! event) { + break; + } + packet = MIDIPacketListAdd(packet_list, midi_buffer_size, + packet, + GetTimeStampFromFrames(event->time), + event->size, event->data); + if (! packet) { + break; + } + } + SendPacketList(packet_list); + } else { + + // We have a large system exclusive event. We'll have to send it + // out in multiple packets. + size_t bytes_sent = 0; + do { + packet = MIDIPacketListInit(packet_list); + assert(packet); + size_t num_bytes = 0; + for (; bytes_sent < size; bytes_sent += num_bytes) { + size_t num_bytes = size - bytes_sent; + + // We use 256 because the MIDIPacket struct defines the + // size of the 'data' member to be 256 bytes. I believe + // this prevents packets from being dynamically allocated + // by 'MIDIPacketListAdd', but I might be wrong. + if (num_bytes > 256) { + num_bytes = 256; + } + packet = MIDIPacketListAdd(packet_list, midi_buffer_size, + packet, timestamp, num_bytes, + data + bytes_sent); + if (! packet) { + break; + } + } + if (! SendPacketList(packet_list)) { + // An error occurred. The error message has already been + // output. We lick our wounds and move along. + break; + } + } while (bytes_sent < size); + event = 0; + } + } + return false; +} + +MIDITimeStamp +JackCoreMidiPort::GetTimeStampFromFrames(jack_nframes_t frames) +{ + return GetTimeFromFrames(frames) / time_ratio; +} + +bool +JackCoreMidiOutputPort::Init() +{ + set_threaded_log_function(); + if (thread->AcquireSelfRealTime(realtime_priority)) { + jack_error("JackCoreMidiOutputPort::Init - could not acquire realtime " + "scheduling. Continuing anyway."); + } + return true; +} + +void +JackCoreMidiOutputPort::Initialize(const char *alias_name, + const char *client_name, + const char *driver_name, int index, + MIDIEndpointRef endpoint) +{ + Initialize(alias_name, client_name, driver_name, index, endpoint, true); +} + +void +JackCoreMidiOutputPort::ProcessJack(JackMidiBuffer *port_buffer, + jack_nframes_t frames) +{ + read_queue->ResetMidiBuffer(port_buffer); + for (jack_midi_event_t *event = read_queue->DequeueEvent(); event; + event = read_queue->DequeueEvent()) { + switch (thread_queue->EnqueueEvent(event, frames)) { + case JackMidiWriteQueue::BUFFER_FULL: + jack_error("JackCoreMidiOutputPort::ProcessJack - The thread " + "queue buffer is full. Dropping event."); + continue; + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + jack_error("JackCoreMidiOutputPort::ProcessJack - The thread " + "queue couldn't enqueue a %d-byte event. Dropping " + "event.", event->size); + // Fallthrough on purpose + default: + ; + } + } +} + +bool +JackCoreMidiOutputPort::Start() +{ + bool result = thread->GetStatus() != JackThread::kIdle; + if (! result) { + result = ! thread->StartSync(); + if (! result) { + jack_error("JackCoreMidiOutputPort::Start - failed to start MIDI " + "processing thread."); + } + } + return result; +} + +bool +JackCoreMidiOutputPort::Stop() +{ + bool result = thread->GetStatus() == JackThread::kIdle; + if (! result) { + result = ! thread->Kill(); + if (! result) { + jack_error("JackCoreMidiOutputPort::Stop - failed to stop MIDI " + "processing thread."); + } + } + return result; +} diff --git a/macosx/coremidi/JackCoreMidiOutputPort.h b/macosx/coremidi/JackCoreMidiOutputPort.h new file mode 100644 index 00000000..0108770e --- /dev/null +++ b/macosx/coremidi/JackCoreMidiOutputPort.h @@ -0,0 +1,83 @@ +/* +Copyright (C) 2011 Devin Anderson + +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 __JackCoreMidiOutputPort__ +#define __JackCoreMidiOutputPort__ + +#include "JackCoreMidiPort.h" +#include "JackMidiAsyncWaitQueue.h" +#include "JackMidiBufferReadQueue.h" +#include "JackThread.h" + +namespace Jack { + + class JackCoreMidiOutputPort: + public JackCoreMidiPort, public JackRunnableInterface { + + private: + + MIDITimeStamp + GetTimeStampFromFrames(jack_nframes_t frames); + + void + Initialize(const char *alias_name, const char *client_name, + const char *driver_name, int index, + MIDIEndpointRef endpoint); + + static const size_t PACKET_BUFFER_SIZE = 65536; + + char packet_buffer[PACKET_BUFFER_SIZE]; + JackMidiBufferReadQueue *read_queue; + int realtime_priority; + JackThread *thread; + JackMidiAsyncWaitQueue *thread_queue; + + protected: + + virtual void + SendPacketList(MIDIPacketList *packet_list) = 0; + + public: + + JackCoreMidiOutputPort(double time_ratio, size_t max_bytes=4096, + size_t max_messages=1024); + + virtual + ~JackCoreMidiOutputPort(); + + bool + Execute(); + + bool + Init(); + + void + ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames); + + bool + Start(); + + bool + Stop(); + + }; + +} + +#endif diff --git a/macosx/coremidi/JackCoreMidiPhysicalInputPort.cpp b/macosx/coremidi/JackCoreMidiPhysicalInputPort.cpp new file mode 100644 index 00000000..748dbc17 --- /dev/null +++ b/macosx/coremidi/JackCoreMidiPhysicalInputPort.cpp @@ -0,0 +1,53 @@ +/* +Copyright (C) 2011 Devin Anderson + +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. + +*/ + +#include +#include + +#include "JackCoreMidiPhysicalInputPort.h" +#include "JackCoreMidiUtil.h" + +using Jack::JackCoreMidiPhysicalInputPort; + +JackCoreMidiPhysicalInputPort:: +JackCoreMidiPhysicalInputPort(const char *alias_name, const char *client_name, + const char *driver_name, int index, + MIDIClientRef client, MIDIPortRef internal_input, + double time_ratio, size_t max_bytes, + size_t max_messages): + JackCoreMidiInputPort(time_ratio, max_bytes, max_messages) +{ + MIDIEndpointRef source = MIDIGetSource(index); + if (! source) { + // X: Is there a way to get a better error message? + std::stringstream stream; + stream << "The source at index '" << index << "' is not available"; + throw std::runtime_error(stream.str().c_str()); + } + OSStatus status = MIDIPortConnectSource(internal_input, source, this); + if (status != noErr) { + throw std::runtime_error(GetMacOSErrorString(status)); + } + Initialize(alias_name, client_name, driver_name, index, source); +} + +JackCoreMidiPhysicalInputPort::~JackCoreMidiPhysicalInputPort() +{ + // Empty +} diff --git a/macosx/coremidi/JackCoreMidiPhysicalInputPort.h b/macosx/coremidi/JackCoreMidiPhysicalInputPort.h new file mode 100644 index 00000000..83f0f2dd --- /dev/null +++ b/macosx/coremidi/JackCoreMidiPhysicalInputPort.h @@ -0,0 +1,45 @@ +/* +Copyright (C) 2011 Devin Anderson + +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 __JackCoreMidiPhysicalInputPort__ +#define __JackCoreMidiPhysicalInputPort__ + +#include "JackCoreMidiInputPort.h" + +namespace Jack { + + class JackCoreMidiPhysicalInputPort: public JackCoreMidiInputPort { + + public: + + JackCoreMidiPhysicalInputPort(const char *alias_name, + const char *client_name, + const char *driver_name, int index, + MIDIClientRef client, + MIDIPortRef internal_input, + double time_ratio, size_t max_bytes=4096, + size_t max_messages=1024); + + ~JackCoreMidiPhysicalInputPort(); + + }; + +} + +#endif diff --git a/macosx/coremidi/JackCoreMidiPhysicalOutputPort.cpp b/macosx/coremidi/JackCoreMidiPhysicalOutputPort.cpp new file mode 100644 index 00000000..1af6b2c6 --- /dev/null +++ b/macosx/coremidi/JackCoreMidiPhysicalOutputPort.cpp @@ -0,0 +1,65 @@ +/* +Copyright (C) 2011 Devin Anderson + +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. + +*/ + +#include +#include + +#include "JackCoreMidiPhysicalOutputPort.h" +#include "JackCoreMidiUtil.h" + +using Jack::JackCoreMidiPhysicalOutputPort; + +JackCoreMidiPhysicalOutputPort:: +JackCoreMidiPhysicalOutputPort(const char *alias_name, const char *client_name, + const char *driver_name, int index, + MIDIClientRef client, + MIDIPortRef internal_output, double time_ratio, + int realtime_priority, size_t max_bytes, + size_t max_messages): + JackCoreMidiOutputPort(time_ratio, realtime_priority, max_bytes, + max_messages) +{ + MIDIEndpointRef destination = MIDIGetDestination(index); + if (! destination) { + // X: Can we get a better error message? + std::stringstream stream; + stream << "The destination at index '" << index + << "' is not available"; + throw std::runtime_error(stream.str().c_str()); + } + Initialize(alias_name, client_name, driver_name, index, destination); + this->internal_output = internal_output; +} + +JackCoreMidiPhysicalOutputPort::~JackCoreMidiPhysicalOutputPort() +{ + // Empty +} + +bool +JackCoreMidiPhysicalOutputPort::SendPacketList(MIDIPacketList *packet_list) +{ + OSStatus status = MIDISend(internal_output, source, packet_list); + bool result = status == noErr; + if (! result) { + WriteMacOSError("JackCoreMidiPhysicalOutputPort::SendPacketList", + "MIDISend", status); + } + return result; +} diff --git a/macosx/coremidi/JackCoreMidiPhysicalOutputPort.h b/macosx/coremidi/JackCoreMidiPhysicalOutputPort.h new file mode 100644 index 00000000..fb922f84 --- /dev/null +++ b/macosx/coremidi/JackCoreMidiPhysicalOutputPort.h @@ -0,0 +1,56 @@ +/* +Copyright (C) 2011 Devin Anderson + +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 __JackCoreMidiPhysicalOutputPort__ +#define __JackCoreMidiPhysicalOutputPort__ + +#include "JackCoreMidiOutputPort.h" + +namespace Jack { + + class JackCoreMidiPhysicalOutputPort: public JackCoreMidiOutputPort { + + private: + + MIDIPortRef internal_output; + + protected: + + bool + SendPacketList(MIDIPacketList *packet_list); + + public: + + JackCoreMidiPhysicalOutputPort(const char *alias_name, + const char *client_name, + const char *driver_name, int index, + MIDIClientRef client, + MIDIPortRef internal_output, + double time_ratio, + int realtime_priority, + size_t max_bytes=4096, + size_t max_messages=1024); + + ~JackCoreMidiPhysicalOutputPort(); + + }; + +} + +#endif diff --git a/macosx/coremidi/JackCoreMidiPort.cpp b/macosx/coremidi/JackCoreMidiPort.cpp new file mode 100644 index 00000000..1783f34e --- /dev/null +++ b/macosx/coremidi/JackCoreMidiPort.cpp @@ -0,0 +1,90 @@ +/* +Copyright (C) 2011 Devin Anderson + +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. + +*/ + +#include + +#include "JackCoreMidiPort.h" + +using Jack::JackCoreMidiPort; + +JackCoreMidiPort::JackCoreMidiPort(double time_ratio) +{ + initialized = false; + this->time_ratio = time_ratio; +} + +JackCoreMidiPort::~JackCoreMidiPort() +{ + // Empty +} + +const char * +JackCoreMidiPort::GetAlias() +{ + assert(initialized); + return alias; +} + +MIDIEndpointRef +JackCoreMidiPort::GetEndpoint() +{ + assert(initialized); + return endpoint; +} + +const char * +JackCoreMidiPort::GetName() +{ + assert(initialized); + return name; +} + +void +JackCoreMidiPort::Initialize(const char *alias_name, const char *client_name, + const char *driver_name, int index, + MIDIEndpointRef endpoint, bool is_output) +{ + char endpoint_name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + CFStringRef endpoint_name_ref; + int num = index + 1; + OSStatus result = MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, + &endpoint_name_ref); + if (result != noErr) { + WriteMacOSError("JackCoreMidiPort::Initialize", + "MIDIObjectGetStringProperty", result); + goto get_basic_alias; + } + result = CFStringGetCString(endpoint_name_ref, endpoint_name, + sizeof(endpoint_name), 0); + CFRelease(endpoint_name_ref); + if (result != noErr) { + jack_error("JackCoreMidiPort::Initialize - failed to allocate memory " + "for endpoint name."); + get_basic_alias: + snprintf(alias, sizeof(alias) - 1, "%s:%s:%s%d", alias_name, + driver_name, is_output ? "out" : "in", num); + } else { + snprintf(alias, sizeof(alias) - 1, "%s:%s:%s%d", alias_name, + endpoint_name, is_output ? "out" : "in", num); + } + snprintf(name, sizeof(name) - 1, "%s:%s_%d", client_name, + is_output ? "playback" : "capture", num); + this->endpoint = endpoint; + initialized = true; +} diff --git a/macosx/coremidi/JackCoreMidiPort.h b/macosx/coremidi/JackCoreMidiPort.h new file mode 100644 index 00000000..e8dd64e4 --- /dev/null +++ b/macosx/coremidi/JackCoreMidiPort.h @@ -0,0 +1,67 @@ +/* +Copyright (C) 2011 Devin Anderson + +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 __JackCoreMidiPort__ +#define __JackCoreMidiPort__ + +#include + +#include "JackConstants.h" + +namespace Jack { + + class JackCoreMidiPort { + + private: + + char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + MIDIEndpointRef endpoint; + bool initialized; + char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + + protected: + + MIDIEndpointRef + GetEndpoint(); + + void + Initialize(const char *alias_name, const char *client_name, + const char *driver_name, int index, + MIDIEndpointRef endpoint, bool is_output); + + double time_ratio; + + public: + + JackCoreMidiPort(double time_ratio); + + virtual + ~JackCoreMidiPort(); + + const char * + GetAlias(); + + const char * + GetName(); + + }; + +} + +#endif diff --git a/macosx/coremidi/JackCoreMidiUtil.cpp b/macosx/coremidi/JackCoreMidiUtil.cpp new file mode 100644 index 00000000..80b8746e --- /dev/null +++ b/macosx/coremidi/JackCoreMidiUtil.cpp @@ -0,0 +1,44 @@ +/* +Copyright (C) 2011 Devin Anderson + +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. + +*/ + +#include + +#include "JackError.h" + +std::string +Jack::GetMacOSErrorString(OSStatus status) +{ + char message[kMaxErrorLength + 1]; + OSStatus result = GetErrorLongString(error, message, + (long) sizeof(message)); + if (result != noErr) { + std::stringstream stream; + stream << "error (code: '" << status << "')"; + return stream.str(); + } + return std::string(message); +} + +void +Jack::WriteMacOSError(const char *jack_function, const char *mac_function, + OSStatus status) +{ + jack_error("%s - %s: %s", jack_function, mac_function, + GetMacOSStatusString(status).c_str()); +} diff --git a/macosx/coremidi/JackCoreMidiUtil.h b/macosx/coremidi/JackCoreMidiUtil.h new file mode 100644 index 00000000..5c9aac00 --- /dev/null +++ b/macosx/coremidi/JackCoreMidiUtil.h @@ -0,0 +1,38 @@ +/* +Copyright (C) 2011 Devin Anderson + +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 __JackCoreMidiUtil__ +#define __JackCoreMidiUtil__ + +#include + +#include + +namespace Jack { + + std::string + GetMacOSErrorString(OSStatus status); + + void + WriteMacOSError(const char *jack_function, const char *mac_function, + OSStatus status); + +} + +#endif diff --git a/macosx/coremidi/JackCoreMidiVirtualInputPort.cpp b/macosx/coremidi/JackCoreMidiVirtualInputPort.cpp new file mode 100644 index 00000000..6c6ec015 --- /dev/null +++ b/macosx/coremidi/JackCoreMidiVirtualInputPort.cpp @@ -0,0 +1,75 @@ +/* +Copyright (C) 2011 Devin Anderson + +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. + +*/ + +#include +#include + +#include "JackCoreMidiUtil.h" +#include "JackCoreMidiVirtualInputPort.h" + +using Jack::JackCoreMidiVirtualInputPort; + +/////////////////////////////////////////////////////////////////////////////// +// Static callbacks +/////////////////////////////////////////////////////////////////////////////// + +void +JackCoreMidiVirtualInputPort:: +HandleInputEvent(const MIDIPacketList *packet_list, void *port, + void */*src_ref*/) +{ + ((JackCoreMidiVirtualInputPort *) port)->ProcessCoreMidi(packet_list); +} + +/////////////////////////////////////////////////////////////////////////////// +// Class +/////////////////////////////////////////////////////////////////////////////// + +JackCoreMidiVirtualInputPort:: +JackCoreMidiVirtualInputPort(const char *alias_name, const char *client_name, + const char *driver_name, int index, + MIDIClientRef client, double time_ratio, + size_t max_bytes, size_t max_messages): + JackCoreMidiInputPort(time_ratio, max_bytes, max_messages) +{ + std::stringstream stream; + stream << "JackMidi" << (index + 1); + CFStringRef name = CFStringCreateWithString(0, stream.str().c_str(), + CFStringGetSystemEncoding()); + if (! name) { + throw std::bad_alloc(); + } + MIDIEndpointRef destination; + OSStatus status = MIDIDestinationCreate(client, name, HandleInputEvent, + this, &destination); + CFRelease(name); + if (status != noErr) { + throw std::runtime_error(GetMacOSErrorString(status)); + } + Initialize(alias_name, client_name, driver_name, index, destination); +} + +JackCoreMidiVirtualInputPort::~JackCoreMidiVirtualInputPort() +{ + OSStatus status = MIDIEndpointDispose(GetEndpoint()); + if (status != noErr) { + WriteMacOSError("JackCoreMidiVirtualInputPort [destructor]", + "MIDIEndpointDispose", status); + } +} diff --git a/macosx/coremidi/JackCoreMidiVirtualInputPort.h b/macosx/coremidi/JackCoreMidiVirtualInputPort.h new file mode 100644 index 00000000..62c970da --- /dev/null +++ b/macosx/coremidi/JackCoreMidiVirtualInputPort.h @@ -0,0 +1,50 @@ +/* +Copyright (C) 2011 Devin Anderson + +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 __JackCoreMidiVirtualInputPort__ +#define __JackCoreMidiVirtualInputPort__ + +#include "JackCoreMidiInputPort.h" + +namespace Jack { + + class JackCoreMidiVirtualInputPort: public JackCoreMidiInputPort { + + private: + + static void + HandleInputEvent(const MIDIPacketList *packet_list, void *port, + void *src_ref) + + public: + + JackCoreMidiVirtualInputPort(const char *alias_name, + const char *client_name, + const char *driver_name, int index, + MIDIClientRef client, double time_ratio, + size_t max_bytes=4096, + size_t max_messages=1024); + + ~JackCoreMidiVirtualInputPort(); + + }; + +} + +#endif diff --git a/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp b/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp new file mode 100644 index 00000000..2fa3f2cf --- /dev/null +++ b/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp @@ -0,0 +1,72 @@ +/* +Copyright (C) 2011 Devin Anderson + +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. + +*/ + +#include +#include + +#include "JackCoreMidiUtil.h" +#include "JackCoreMidiVirtualOutputPort.h" + +using Jack::JackCoreMidiVirtualOutputPort; + +JackCoreMidiVirtualOutputPort:: +JackCoreMidiVirtualOutputPort(const char *alias_name, const char *client_name, + const char *driver_name, int index, + MIDIClientRef client, double time_ratio, + int realtime_priority, size_t max_bytes, + size_t max_messages): + JackCoreMidiOutputPort(time_ratio, realtime_priority, max_bytes, + max_messages) +{ + std::stringstream stream; + stream << "JackMidi" << (index + 1); + CFStringRef name = CFStringCreateWithCString(0, stream.str().c_str(), + CFStringGetSystemEncoding()); + if (! name) { + throw std::bad_alloc(); + } + MIDIEndpointRef source; + OSStatus status = MIDISourceCreate(client, name, &source); + CFRelease(name); + if (status != noErr) { + throw std::runtime_error(GetMacOSErrorString(status)); + } + Initialize(alias_name, client_name, driver_name, index, source); +} + +JackCoreMidiVirtualOutputPort::~JackCoreMidiVirtualOutputPort() +{ + OSStatus status = MIDIEndpointDispose(GetEndpoint()); + if (status != noErr) { + WriteMacOSError("JackCoreMidiVirtualOutputPort [destructor]", + "MIDIEndpointDispose", status); + } +} + +bool +JackCoreMidiVirtualOutputPort::SendPacketList(MIDIPacketList *packet_list) +{ + OSStatus status = MIDIReceived(source, packet_list); + bool result = status == noErr; + if (! result) { + WriteMacOSError("JackCoreMidiVirtualOutputPort::SendPacketList", + "MIDIReceived" status); + } + return result; +} diff --git a/macosx/coremidi/JackCoreMidiVirtualOutputPort.h b/macosx/coremidi/JackCoreMidiVirtualOutputPort.h new file mode 100644 index 00000000..2b828553 --- /dev/null +++ b/macosx/coremidi/JackCoreMidiVirtualOutputPort.h @@ -0,0 +1,50 @@ +/* +Copyright (C) 2011 Devin Anderson + +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 __JackCoreMidiVirtualOutputPort__ +#define __JackCoreMidiVirtualOutputPort__ + +#include "JackCoreMidiOutputPort.h" + +namespace Jack { + + class JackCoreMidiVirtualOutputPort: public JackCoreMidiOutputPort { + + protected: + + bool + SendPacketList(MIDIPacketList *packet_list); + + public: + + JackCoreMidiVirtualOutputPort(const char *alias_name, + const char *client_name, + const char *driver_name, int index, + MIDIClientRef client, double time_ratio, + int realtime_priority, + size_t max_bytes=4096, + size_t max_messages=1024); + + ~JackCoreMidiVirtualOutputPort(); + + }; + +} + +#endif From 955c051f72741e727e05bd25a7438bbc1a2ed5f3 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Sat, 26 Mar 2011 11:18:22 +0100 Subject: [PATCH 076/472] Compilation on OSX in progress. --- macosx/Jackdmp.xcodeproj/project.pbxproj | 96 +++++++++++++++++++ macosx/coremidi/JackCoreMidiDriver.cpp | 20 ++-- macosx/coremidi/JackCoreMidiDriver.h | 8 +- macosx/coremidi/JackCoreMidiInputPort.cpp | 11 ++- macosx/coremidi/JackCoreMidiOutputPort.cpp | 5 +- macosx/coremidi/JackCoreMidiOutputPort.h | 14 +-- .../JackCoreMidiPhysicalOutputPort.cpp | 2 +- macosx/coremidi/JackCoreMidiPort.cpp | 2 + macosx/coremidi/JackCoreMidiPort.h | 2 +- macosx/coremidi/JackCoreMidiUtil.cpp | 3 + macosx/coremidi/JackCoreMidiUtil.h | 3 +- .../coremidi/JackCoreMidiVirtualInputPort.cpp | 2 +- .../coremidi/JackCoreMidiVirtualInputPort.h | 2 +- .../JackCoreMidiVirtualOutputPort.cpp | 5 +- 14 files changed, 143 insertions(+), 32 deletions(-) diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index edfbae28..3ba3fc40 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -319,6 +319,38 @@ 4B363F230DEB0AB0001F72D9 /* monitor_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363F220DEB0AB0001F72D9 /* monitor_client.c */; }; 4B363F3E0DEB0C31001F72D9 /* showtime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363F3D0DEB0C31001F72D9 /* showtime.c */; }; 4B363F760DEB0D7D001F72D9 /* impulse_grabber.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B363F750DEB0D7D001F72D9 /* impulse_grabber.c */; }; + 4B370A24133DD7E300237B68 /* JackCoreMidiInputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A14133DD7E200237B68 /* JackCoreMidiInputPort.cpp */; }; + 4B370A25133DD7E300237B68 /* JackCoreMidiInputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A15133DD7E200237B68 /* JackCoreMidiInputPort.h */; }; + 4B370A26133DD7E300237B68 /* JackCoreMidiOutputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A16133DD7E200237B68 /* JackCoreMidiOutputPort.cpp */; }; + 4B370A27133DD7E300237B68 /* JackCoreMidiOutputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A17133DD7E200237B68 /* JackCoreMidiOutputPort.h */; }; + 4B370A28133DD7E300237B68 /* JackCoreMidiPhysicalInputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A18133DD7E200237B68 /* JackCoreMidiPhysicalInputPort.cpp */; }; + 4B370A29133DD7E300237B68 /* JackCoreMidiPhysicalInputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A19133DD7E200237B68 /* JackCoreMidiPhysicalInputPort.h */; }; + 4B370A2A133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A1A133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.cpp */; }; + 4B370A2B133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A1B133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.h */; }; + 4B370A2C133DD7E300237B68 /* JackCoreMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A1C133DD7E300237B68 /* JackCoreMidiPort.cpp */; }; + 4B370A2D133DD7E300237B68 /* JackCoreMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A1D133DD7E300237B68 /* JackCoreMidiPort.h */; }; + 4B370A2E133DD7E300237B68 /* JackCoreMidiUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A1E133DD7E300237B68 /* JackCoreMidiUtil.cpp */; }; + 4B370A2F133DD7E300237B68 /* JackCoreMidiUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A1F133DD7E300237B68 /* JackCoreMidiUtil.h */; }; + 4B370A30133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A20133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp */; }; + 4B370A31133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A21133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h */; }; + 4B370A32133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A22133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp */; }; + 4B370A33133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A23133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h */; }; + 4B370A34133DD7E300237B68 /* JackCoreMidiInputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A14133DD7E200237B68 /* JackCoreMidiInputPort.cpp */; }; + 4B370A35133DD7E300237B68 /* JackCoreMidiInputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A15133DD7E200237B68 /* JackCoreMidiInputPort.h */; }; + 4B370A36133DD7E300237B68 /* JackCoreMidiOutputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A16133DD7E200237B68 /* JackCoreMidiOutputPort.cpp */; }; + 4B370A37133DD7E300237B68 /* JackCoreMidiOutputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A17133DD7E200237B68 /* JackCoreMidiOutputPort.h */; }; + 4B370A38133DD7E300237B68 /* JackCoreMidiPhysicalInputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A18133DD7E200237B68 /* JackCoreMidiPhysicalInputPort.cpp */; }; + 4B370A39133DD7E300237B68 /* JackCoreMidiPhysicalInputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A19133DD7E200237B68 /* JackCoreMidiPhysicalInputPort.h */; }; + 4B370A3A133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A1A133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.cpp */; }; + 4B370A3B133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A1B133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.h */; }; + 4B370A3C133DD7E300237B68 /* JackCoreMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A1C133DD7E300237B68 /* JackCoreMidiPort.cpp */; }; + 4B370A3D133DD7E300237B68 /* JackCoreMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A1D133DD7E300237B68 /* JackCoreMidiPort.h */; }; + 4B370A3E133DD7E300237B68 /* JackCoreMidiUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A1E133DD7E300237B68 /* JackCoreMidiUtil.cpp */; }; + 4B370A3F133DD7E300237B68 /* JackCoreMidiUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A1F133DD7E300237B68 /* JackCoreMidiUtil.h */; }; + 4B370A40133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A20133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp */; }; + 4B370A41133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A21133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h */; }; + 4B370A42133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B370A22133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp */; }; + 4B370A43133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B370A23133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h */; }; 4B3811FB13269C8300C61B14 /* latent_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3811FA13269C8300C61B14 /* latent_client.c */; }; 4B3811FC13269C8300C61B14 /* latent_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3811FA13269C8300C61B14 /* latent_client.c */; }; 4B3814201327AA6800C61B14 /* iodelay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B38141F1327AA6800C61B14 /* iodelay.cpp */; }; @@ -1537,6 +1569,22 @@ 4B363F3D0DEB0C31001F72D9 /* showtime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = showtime.c; path = "../example-clients/showtime.c"; sourceTree = SOURCE_ROOT; }; 4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_impulse_grabber; sourceTree = BUILT_PRODUCTS_DIR; }; 4B363F750DEB0D7D001F72D9 /* impulse_grabber.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = impulse_grabber.c; path = "../example-clients/impulse_grabber.c"; sourceTree = SOURCE_ROOT; }; + 4B370A14133DD7E200237B68 /* JackCoreMidiInputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreMidiInputPort.cpp; path = ../../coremidi/JackCoreMidiInputPort.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B370A15133DD7E200237B68 /* JackCoreMidiInputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackCoreMidiInputPort.h; path = ../../coremidi/JackCoreMidiInputPort.h; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B370A16133DD7E200237B68 /* JackCoreMidiOutputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreMidiOutputPort.cpp; path = ../../coremidi/JackCoreMidiOutputPort.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B370A17133DD7E200237B68 /* JackCoreMidiOutputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackCoreMidiOutputPort.h; path = ../../coremidi/JackCoreMidiOutputPort.h; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B370A18133DD7E200237B68 /* JackCoreMidiPhysicalInputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreMidiPhysicalInputPort.cpp; path = ../../coremidi/JackCoreMidiPhysicalInputPort.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B370A19133DD7E200237B68 /* JackCoreMidiPhysicalInputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackCoreMidiPhysicalInputPort.h; path = ../../coremidi/JackCoreMidiPhysicalInputPort.h; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B370A1A133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreMidiPhysicalOutputPort.cpp; path = ../../coremidi/JackCoreMidiPhysicalOutputPort.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B370A1B133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackCoreMidiPhysicalOutputPort.h; path = ../../coremidi/JackCoreMidiPhysicalOutputPort.h; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B370A1C133DD7E300237B68 /* JackCoreMidiPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreMidiPort.cpp; path = ../../coremidi/JackCoreMidiPort.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B370A1D133DD7E300237B68 /* JackCoreMidiPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackCoreMidiPort.h; path = ../../coremidi/JackCoreMidiPort.h; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B370A1E133DD7E300237B68 /* JackCoreMidiUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreMidiUtil.cpp; path = ../../coremidi/JackCoreMidiUtil.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B370A1F133DD7E300237B68 /* JackCoreMidiUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackCoreMidiUtil.h; path = ../../coremidi/JackCoreMidiUtil.h; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B370A20133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreMidiVirtualInputPort.cpp; path = ../../coremidi/JackCoreMidiVirtualInputPort.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B370A21133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackCoreMidiVirtualInputPort.h; path = ../../coremidi/JackCoreMidiVirtualInputPort.h; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B370A22133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreMidiVirtualOutputPort.cpp; path = ../../coremidi/JackCoreMidiVirtualOutputPort.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B370A23133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackCoreMidiVirtualOutputPort.h; path = ../../coremidi/JackCoreMidiVirtualOutputPort.h; sourceTree = BUILT_PRODUCTS_DIR; }; 4B37C20306DF1FBE0016E567 /* CALatencyLog.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CALatencyLog.cpp; path = /Developer/Examples/CoreAudio/PublicUtility/CALatencyLog.cpp; sourceTree = ""; }; 4B37C20406DF1FBE0016E567 /* CALatencyLog.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CALatencyLog.h; path = /Developer/Examples/CoreAudio/PublicUtility/CALatencyLog.h; sourceTree = ""; }; 4B37C20906DF1FE20016E567 /* latency.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = latency.c; path = /Developer/Examples/CoreAudio/PublicUtility/latency.c; sourceTree = ""; }; @@ -3047,6 +3095,22 @@ 4BF3390D0F8B86AF0080FB5B /* MIDI */ = { isa = PBXGroup; children = ( + 4B370A14133DD7E200237B68 /* JackCoreMidiInputPort.cpp */, + 4B370A15133DD7E200237B68 /* JackCoreMidiInputPort.h */, + 4B370A16133DD7E200237B68 /* JackCoreMidiOutputPort.cpp */, + 4B370A17133DD7E200237B68 /* JackCoreMidiOutputPort.h */, + 4B370A18133DD7E200237B68 /* JackCoreMidiPhysicalInputPort.cpp */, + 4B370A19133DD7E200237B68 /* JackCoreMidiPhysicalInputPort.h */, + 4B370A1A133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.cpp */, + 4B370A1B133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.h */, + 4B370A1C133DD7E300237B68 /* JackCoreMidiPort.cpp */, + 4B370A1D133DD7E300237B68 /* JackCoreMidiPort.h */, + 4B370A1E133DD7E300237B68 /* JackCoreMidiUtil.cpp */, + 4B370A1F133DD7E300237B68 /* JackCoreMidiUtil.h */, + 4B370A20133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp */, + 4B370A21133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h */, + 4B370A22133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp */, + 4B370A23133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h */, 4BF3391F0F8B873E0080FB5B /* JackMidiDriver.cpp */, 4BF339200F8B873E0080FB5B /* JackMidiDriver.h */, 4BF339140F8B86DC0080FB5B /* JackCoreMidiDriver.h */, @@ -3994,6 +4058,14 @@ buildActionMask = 2147483647; files = ( 4BDCDB951001FB9C00B15929 /* JackCoreMidiDriver.h in Headers */, + 4B370A35133DD7E300237B68 /* JackCoreMidiInputPort.h in Headers */, + 4B370A37133DD7E300237B68 /* JackCoreMidiOutputPort.h in Headers */, + 4B370A39133DD7E300237B68 /* JackCoreMidiPhysicalInputPort.h in Headers */, + 4B370A3B133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.h in Headers */, + 4B370A3D133DD7E300237B68 /* JackCoreMidiPort.h in Headers */, + 4B370A3F133DD7E300237B68 /* JackCoreMidiUtil.h in Headers */, + 4B370A41133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h in Headers */, + 4B370A43133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4054,6 +4126,14 @@ buildActionMask = 2147483647; files = ( 4BF3391A0F8B86DC0080FB5B /* JackCoreMidiDriver.h in Headers */, + 4B370A25133DD7E300237B68 /* JackCoreMidiInputPort.h in Headers */, + 4B370A27133DD7E300237B68 /* JackCoreMidiOutputPort.h in Headers */, + 4B370A29133DD7E300237B68 /* JackCoreMidiPhysicalInputPort.h in Headers */, + 4B370A2B133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.h in Headers */, + 4B370A2D133DD7E300237B68 /* JackCoreMidiPort.h in Headers */, + 4B370A2F133DD7E300237B68 /* JackCoreMidiUtil.h in Headers */, + 4B370A31133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h in Headers */, + 4B370A33133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7383,6 +7463,14 @@ buildActionMask = 2147483647; files = ( 4BDCDB971001FB9C00B15929 /* JackCoreMidiDriver.cpp in Sources */, + 4B370A34133DD7E300237B68 /* JackCoreMidiInputPort.cpp in Sources */, + 4B370A36133DD7E300237B68 /* JackCoreMidiOutputPort.cpp in Sources */, + 4B370A38133DD7E300237B68 /* JackCoreMidiPhysicalInputPort.cpp in Sources */, + 4B370A3A133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.cpp in Sources */, + 4B370A3C133DD7E300237B68 /* JackCoreMidiPort.cpp in Sources */, + 4B370A3E133DD7E300237B68 /* JackCoreMidiUtil.cpp in Sources */, + 4B370A40133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp in Sources */, + 4B370A42133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7448,6 +7536,14 @@ buildActionMask = 2147483647; files = ( 4BF3391B0F8B86DC0080FB5B /* JackCoreMidiDriver.cpp in Sources */, + 4B370A24133DD7E300237B68 /* JackCoreMidiInputPort.cpp in Sources */, + 4B370A26133DD7E300237B68 /* JackCoreMidiOutputPort.cpp in Sources */, + 4B370A28133DD7E300237B68 /* JackCoreMidiPhysicalInputPort.cpp in Sources */, + 4B370A2A133DD7E300237B68 /* JackCoreMidiPhysicalOutputPort.cpp in Sources */, + 4B370A2C133DD7E300237B68 /* JackCoreMidiPort.cpp in Sources */, + 4B370A2E133DD7E300237B68 /* JackCoreMidiUtil.cpp in Sources */, + 4B370A30133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp in Sources */, + 4B370A32133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/macosx/coremidi/JackCoreMidiDriver.cpp b/macosx/coremidi/JackCoreMidiDriver.cpp index 4be05c2d..b006c333 100644 --- a/macosx/coremidi/JackCoreMidiDriver.cpp +++ b/macosx/coremidi/JackCoreMidiDriver.cpp @@ -26,6 +26,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackCoreMidiUtil.h" #include "JackEngineControl.h" +namespace Jack +{ + /////////////////////////////////////////////////////////////////////////////// // Static callbacks /////////////////////////////////////////////////////////////////////////////// @@ -255,6 +258,9 @@ JackCoreMidiDriver::Open(bool capturing, bool playing, int in_channels, int po_count = 0; int vi_count = 0; int vo_count = 0; + ItemCount potential_po_count; + ItemCount potential_pi_count; + CFStringRef name = CFStringCreateWithCString(0, "JackMidi", CFStringGetSystemEncoding()); if (! name) { @@ -277,7 +283,7 @@ JackCoreMidiDriver::Open(bool capturing, bool playing, int in_channels, if (in_channels) { try { virtual_input_ports = - new JackCoreMidiVirtualInputPort[in_channels]; + new JackCoreMidiVirtualInputPort*[in_channels]; } catch (std::exception e) { jack_error("JackCoreMidiDriver::Open - while creating virtual " "input port array: %s", e.what()); @@ -302,7 +308,7 @@ JackCoreMidiDriver::Open(bool capturing, bool playing, int in_channels, if (out_channels) { try { virtual_output_ports = - new JackCoreMidiVirtualOutputPort[out_channels]; + new JackCoreMidiVirtualOutputPort*[out_channels]; } catch (std::exception e) { jack_error("JackCoreMidiDriver::Open - while creating virtual " "output port array: %s", e.what()); @@ -325,7 +331,7 @@ JackCoreMidiDriver::Open(bool capturing, bool playing, int in_channels, } // Allocate and connect physical inputs - ItemCount potential_pi_count = MIDIGetNumberOfSources(); + potential_pi_count = MIDIGetNumberOfSources(); if (potential_pi_count) { status = MIDIInputPortCreate(client, CFSTR("Physical Input Port"), HandleInputEvent, this, &internal_input); @@ -336,7 +342,7 @@ JackCoreMidiDriver::Open(bool capturing, bool playing, int in_channels, } try { physical_input_ports = - new JackCoreMidiPhysicalInputPort[potential_pi_count]; + new JackCoreMidiPhysicalInputPort*[potential_pi_count]; } catch (std::exception e) { jack_error("JackCoreMidiDriver::Open - while creating physical " "input port array: %s", e.what()); @@ -359,7 +365,7 @@ JackCoreMidiDriver::Open(bool capturing, bool playing, int in_channels, } // Allocate and connect physical outputs - ItemCount potential_po_count = MIDIGetNumberOfDestinations(); + potential_po_count = MIDIGetNumberOfDestinations(); if (potential_po_count) { status = MIDIOutputPortCreate(client, CFSTR("Physical Output Port"), &internal_output); @@ -370,7 +376,7 @@ JackCoreMidiDriver::Open(bool capturing, bool playing, int in_channels, } try { physical_output_ports = - new JackCoreMidiPhysicalOutputPort[potential_po_count]; + new JackCoreMidiPhysicalOutputPort*[potential_po_count]; } catch (std::exception e) { jack_error("JackCoreMidiDriver::Open - while creating physical " "output port array: %s", e.what()); @@ -626,6 +632,8 @@ JackCoreMidiDriver::Write() return 0; } +} // end of namespace + #ifdef __cplusplus extern "C" { #endif diff --git a/macosx/coremidi/JackCoreMidiDriver.h b/macosx/coremidi/JackCoreMidiDriver.h index 34056c33..c5a26f5b 100644 --- a/macosx/coremidi/JackCoreMidiDriver.h +++ b/macosx/coremidi/JackCoreMidiDriver.h @@ -50,11 +50,11 @@ namespace Jack { int num_physical_outputs; int num_virtual_inputs; int num_virtual_outputs; - JackCoreMidiPhysicalInputPort *physical_input_ports; - JackCoreMidiPhysicalOutputPort *physical_output_ports; + JackCoreMidiPhysicalInputPort **physical_input_ports; + JackCoreMidiPhysicalOutputPort **physical_output_ports; double time_ratio; - JackCoreMidiVirtualInputPort *virtual_input_ports; - JackCoreMidiVirtualOutputPort *virtual_output_ports; + JackCoreMidiVirtualInputPort **virtual_input_ports; + JackCoreMidiVirtualOutputPort **virtual_output_ports; public: diff --git a/macosx/coremidi/JackCoreMidiInputPort.cpp b/macosx/coremidi/JackCoreMidiInputPort.cpp index 20d2af0c..e28d62b2 100644 --- a/macosx/coremidi/JackCoreMidiInputPort.cpp +++ b/macosx/coremidi/JackCoreMidiInputPort.cpp @@ -22,6 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackCoreMidiInputPort.h" #include "JackMidiUtil.h" +//#include "types.h" using Jack::JackCoreMidiInputPort; @@ -47,8 +48,8 @@ JackCoreMidiInputPort::~JackCoreMidiInputPort() delete[] sysex_buffer; } -jack_frames_t -JackCoreMidiPort::GetFramesFromTimeStamp(MIDITimeStamp timestamp) +jack_nframes_t +JackCoreMidiInputPort::GetFramesFromTimeStamp(MIDITimeStamp timestamp) { return GetFramesFromTime((jack_time_t) (timestamp * time_ratio)); } @@ -59,7 +60,7 @@ JackCoreMidiInputPort::Initialize(const char *alias_name, const char *driver_name, int index, MIDIEndpointRef endpoint) { - Initialize(alias_name, client_name, driver_name, index, endpoint, false); + JackCoreMidiPort::Initialize(alias_name, client_name, driver_name, index, endpoint, false); } void @@ -127,7 +128,7 @@ JackCoreMidiInputPort::ProcessCoreMidi(const MIDIPacketList *packet_list) case JackMidiWriteQueue::BUFFER_TOO_SMALL: jack_error("JackCoreMidiInputPort::ProcessCoreMidi - The thread " "queue couldn't enqueue a %d-byte packet. Dropping " - "event.", event->size); + "event.", event.size); break; default: ; @@ -143,7 +144,7 @@ void JackCoreMidiInputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames) { - write_queue->ResetMidiBuffer(port_buffer); + write_queue->ResetMidiBuffer(port_buffer, frames); if (! jack_event) { jack_event = thread_queue->DequeueEvent(); } diff --git a/macosx/coremidi/JackCoreMidiOutputPort.cpp b/macosx/coremidi/JackCoreMidiOutputPort.cpp index dced4fab..9bf9a5a3 100644 --- a/macosx/coremidi/JackCoreMidiOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiOutputPort.cpp @@ -21,6 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include "JackCoreMidiOutputPort.h" +#include "JackMidiUtil.h" using Jack::JackCoreMidiOutputPort; @@ -126,7 +127,7 @@ JackCoreMidiOutputPort::Execute() } MIDITimeStamp -JackCoreMidiPort::GetTimeStampFromFrames(jack_nframes_t frames) +JackCoreMidiOutputPort::GetTimeStampFromFrames(jack_nframes_t frames) { return GetTimeFromFrames(frames) / time_ratio; } @@ -148,7 +149,7 @@ JackCoreMidiOutputPort::Initialize(const char *alias_name, const char *driver_name, int index, MIDIEndpointRef endpoint) { - Initialize(alias_name, client_name, driver_name, index, endpoint, true); + JackCoreMidiPort::Initialize(alias_name, client_name, driver_name, index, endpoint, true); } void diff --git a/macosx/coremidi/JackCoreMidiOutputPort.h b/macosx/coremidi/JackCoreMidiOutputPort.h index 0108770e..cddda999 100644 --- a/macosx/coremidi/JackCoreMidiOutputPort.h +++ b/macosx/coremidi/JackCoreMidiOutputPort.h @@ -35,11 +35,6 @@ namespace Jack { MIDITimeStamp GetTimeStampFromFrames(jack_nframes_t frames); - void - Initialize(const char *alias_name, const char *client_name, - const char *driver_name, int index, - MIDIEndpointRef endpoint); - static const size_t PACKET_BUFFER_SIZE = 65536; char packet_buffer[PACKET_BUFFER_SIZE]; @@ -50,12 +45,17 @@ namespace Jack { protected: - virtual void + virtual bool SendPacketList(MIDIPacketList *packet_list) = 0; + void + Initialize(const char *alias_name, const char *client_name, + const char *driver_name, int index, + MIDIEndpointRef endpoint); + public: - JackCoreMidiOutputPort(double time_ratio, size_t max_bytes=4096, + JackCoreMidiOutputPort(double time_ratio, int realtime_priority, size_t max_bytes=4096, size_t max_messages=1024); virtual diff --git a/macosx/coremidi/JackCoreMidiPhysicalOutputPort.cpp b/macosx/coremidi/JackCoreMidiPhysicalOutputPort.cpp index 1af6b2c6..9716359a 100644 --- a/macosx/coremidi/JackCoreMidiPhysicalOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiPhysicalOutputPort.cpp @@ -55,7 +55,7 @@ JackCoreMidiPhysicalOutputPort::~JackCoreMidiPhysicalOutputPort() bool JackCoreMidiPhysicalOutputPort::SendPacketList(MIDIPacketList *packet_list) { - OSStatus status = MIDISend(internal_output, source, packet_list); + OSStatus status = MIDISend(internal_output, endpoint, packet_list); bool result = status == noErr; if (! result) { WriteMacOSError("JackCoreMidiPhysicalOutputPort::SendPacketList", diff --git a/macosx/coremidi/JackCoreMidiPort.cpp b/macosx/coremidi/JackCoreMidiPort.cpp index 1783f34e..e3c027c3 100644 --- a/macosx/coremidi/JackCoreMidiPort.cpp +++ b/macosx/coremidi/JackCoreMidiPort.cpp @@ -20,6 +20,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include "JackCoreMidiPort.h" +#include "JackCoreMidiUtil.h" +#include "JackError.h" using Jack::JackCoreMidiPort; diff --git a/macosx/coremidi/JackCoreMidiPort.h b/macosx/coremidi/JackCoreMidiPort.h index e8dd64e4..8a5641bb 100644 --- a/macosx/coremidi/JackCoreMidiPort.h +++ b/macosx/coremidi/JackCoreMidiPort.h @@ -31,7 +31,6 @@ namespace Jack { private: char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - MIDIEndpointRef endpoint; bool initialized; char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; @@ -46,6 +45,7 @@ namespace Jack { MIDIEndpointRef endpoint, bool is_output); double time_ratio; + MIDIEndpointRef endpoint; public: diff --git a/macosx/coremidi/JackCoreMidiUtil.cpp b/macosx/coremidi/JackCoreMidiUtil.cpp index 80b8746e..1652036a 100644 --- a/macosx/coremidi/JackCoreMidiUtil.cpp +++ b/macosx/coremidi/JackCoreMidiUtil.cpp @@ -20,6 +20,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include "JackError.h" +#include "JackCoreMidiUtil.h" +#import std::string Jack::GetMacOSErrorString(OSStatus status) @@ -42,3 +44,4 @@ Jack::WriteMacOSError(const char *jack_function, const char *mac_function, jack_error("%s - %s: %s", jack_function, mac_function, GetMacOSStatusString(status).c_str()); } + diff --git a/macosx/coremidi/JackCoreMidiUtil.h b/macosx/coremidi/JackCoreMidiUtil.h index 5c9aac00..291cabe6 100644 --- a/macosx/coremidi/JackCoreMidiUtil.h +++ b/macosx/coremidi/JackCoreMidiUtil.h @@ -20,8 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifndef __JackCoreMidiUtil__ #define __JackCoreMidiUtil__ -#include - +#import #include namespace Jack { diff --git a/macosx/coremidi/JackCoreMidiVirtualInputPort.cpp b/macosx/coremidi/JackCoreMidiVirtualInputPort.cpp index 6c6ec015..42d9b52f 100644 --- a/macosx/coremidi/JackCoreMidiVirtualInputPort.cpp +++ b/macosx/coremidi/JackCoreMidiVirtualInputPort.cpp @@ -50,7 +50,7 @@ JackCoreMidiVirtualInputPort(const char *alias_name, const char *client_name, { std::stringstream stream; stream << "JackMidi" << (index + 1); - CFStringRef name = CFStringCreateWithString(0, stream.str().c_str(), + CFStringRef name = CFStringCreateWithCString(0, stream.str().c_str(), CFStringGetSystemEncoding()); if (! name) { throw std::bad_alloc(); diff --git a/macosx/coremidi/JackCoreMidiVirtualInputPort.h b/macosx/coremidi/JackCoreMidiVirtualInputPort.h index 62c970da..e48126c4 100644 --- a/macosx/coremidi/JackCoreMidiVirtualInputPort.h +++ b/macosx/coremidi/JackCoreMidiVirtualInputPort.h @@ -30,7 +30,7 @@ namespace Jack { static void HandleInputEvent(const MIDIPacketList *packet_list, void *port, - void *src_ref) + void *src_ref); public: diff --git a/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp b/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp index 2fa3f2cf..f295449d 100644 --- a/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp @@ -19,6 +19,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include +#import #include "JackCoreMidiUtil.h" #include "JackCoreMidiVirtualOutputPort.h" @@ -62,11 +63,11 @@ JackCoreMidiVirtualOutputPort::~JackCoreMidiVirtualOutputPort() bool JackCoreMidiVirtualOutputPort::SendPacketList(MIDIPacketList *packet_list) { - OSStatus status = MIDIReceived(source, packet_list); + OSStatus status = MIDIReceived(endpoint, packet_list); bool result = status == noErr; if (! result) { WriteMacOSError("JackCoreMidiVirtualOutputPort::SendPacketList", - "MIDIReceived" status); + "MIDIReceived", status); } return result; } From 03e695ba1e3af55d685f58b534f4ada1cc592185 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Sat, 26 Mar 2011 12:52:52 +0100 Subject: [PATCH 077/472] Correct loopback driver for new activation model. --- common/JackDriver.h | 13 --------- common/JackLoopbackDriver.cpp | 55 ++++++++++++++++++++++++++++++----- common/JackLoopbackDriver.h | 11 ++++++- common/JackMidiDriver.cpp | 14 ++++----- 4 files changed, 65 insertions(+), 28 deletions(-) diff --git a/common/JackDriver.h b/common/JackDriver.h index e619f6e4..45d695af 100644 --- a/common/JackDriver.h +++ b/common/JackDriver.h @@ -232,19 +232,6 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface }; -/* -class SERVER_EXPORT JackSlaveDriverInterface -{ - - public: - - virtual int ProcessRead() { return 0; } - virtual int ProcessWrite() { return 0; } - -}; - -*/ - } // end of namespace #endif diff --git a/common/JackLoopbackDriver.cpp b/common/JackLoopbackDriver.cpp index e91cce1e..07778417 100644 --- a/common/JackLoopbackDriver.cpp +++ b/common/JackLoopbackDriver.cpp @@ -30,20 +30,61 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { -int JackLoopbackDriver::Process() +int JackLoopbackDriver::ProcessRead() { + return (fEngineControl->fSyncMode) ? ProcessReadSync() : ProcessReadAsync(); +} + +int JackLoopbackDriver::ProcessWrite() +{ + return (fEngineControl->fSyncMode) ? ProcessWriteSync() : ProcessWriteAsync(); +} + +int JackLoopbackDriver::ProcessReadSync() +{ + int res = 0; + // Loopback copy for (int i = 0; i < fCaptureChannels; i++) { memcpy(GetInputBuffer(i), GetOutputBuffer(i), sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); } - fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); // Signal all clients - if (fEngineControl->fSyncMode) { - if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) { - jack_error("JackLoopbackDriver::ProcessSync SuspendRefNum error"); - return -1; - } + if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { + jack_error("JackLoopbackDriver::ProcessReadSync - ResumeRefNum error"); + res = -1; + } + + return res; +} + +int JackLoopbackDriver::ProcessWriteSync() +{ + if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) { + jack_error("JackLoopbackDriver::ProcessWriteSync SuspendRefNum error"); + return -1; + } + return 0; +} + +int JackLoopbackDriver::ProcessReadAsync() +{ + int res = 0; + + // Loopback copy + for (int i = 0; i < fCaptureChannels; i++) { + memcpy(GetInputBuffer(i), GetOutputBuffer(i), sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); + } + + if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { + jack_error("JackLoopbackDriver::ProcessReadAsync - ResumeRefNum error"); + res = -1; } + + return res; +} + +int JackLoopbackDriver::ProcessWriteAsync() +{ return 0; } diff --git a/common/JackLoopbackDriver.h b/common/JackLoopbackDriver.h index 5c542e3a..8fe22266 100644 --- a/common/JackLoopbackDriver.h +++ b/common/JackLoopbackDriver.h @@ -33,6 +33,14 @@ namespace Jack class JackLoopbackDriver : public JackAudioDriver { + private: + + virtual int ProcessReadSync(); + virtual int ProcessWriteSync(); + + virtual int ProcessReadAsync(); + virtual int ProcessWriteAsync(); + public: JackLoopbackDriver(JackLockedEngine* engine, JackSynchro* table) @@ -41,7 +49,8 @@ class JackLoopbackDriver : public JackAudioDriver virtual ~JackLoopbackDriver() {} - int Process(); + virtual int ProcessRead(); + virtual int ProcessWrite(); }; } // end of namespace diff --git a/common/JackMidiDriver.cpp b/common/JackMidiDriver.cpp index a2fffa83..4de11989 100644 --- a/common/JackMidiDriver.cpp +++ b/common/JackMidiDriver.cpp @@ -164,12 +164,12 @@ int JackMidiDriver::ProcessReadSync() // Read input buffers for the current cycle if (Read() < 0) { - jack_error("JackMidiDriver::ProcessSync: read error, skip cycle"); + jack_error("JackMidiDriver::ProcessReadSync: read error, skip cycle"); res = -1; } if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { - jack_error("JackMidiDriver::ProcessSync - ResumeRefNum error"); + jack_error("JackMidiDriver::ProcessReadSync - ResumeRefNum error"); res = -1; } @@ -183,13 +183,13 @@ int JackMidiDriver::ProcessWriteSync() if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) { - jack_error("JackMidiDriver::ProcessSync - SuspendRefNum error"); + jack_error("JackMidiDriver::ProcessWriteSync - SuspendRefNum error"); res = -1; } // Write output buffers from the current cycle if (Write() < 0) { - jack_error("JackMidiDriver::ProcessSync - Write error"); + jack_error("JackMidiDriver::ProcessWriteSync - Write error"); res = -1; } @@ -202,18 +202,18 @@ int JackMidiDriver::ProcessReadAsync() // Read input buffers for the current cycle if (Read() < 0) { - jack_error("JackMidiDriver::ProcessAsync: read error, skip cycle"); + jack_error("JackMidiDriver::ProcessReadAsync: read error, skip cycle"); res = -1; } // Write output buffers from the previous cycle if (Write() < 0) { - jack_error("JackMidiDriver::ProcessAsync - Write error"); + jack_error("JackMidiDriver::ProcessReadAsync - Write error"); res = -1; } if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { - jack_error("JackMidiDriver::ProcessAsync - ResumeRefNum error"); + jack_error("JackMidiDriver::ProcessReadAsync - ResumeRefNum error"); res = -1; } From 94cd8d0be595999a5b53303e2e0463c4bad4b569 Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Sat, 26 Mar 2011 14:59:31 -0700 Subject: [PATCH 078/472] Fix compilation errors sent from Stephane. --- common/JackMidiAsyncWaitQueue.h | 2 ++ macosx/coremidi/JackCoreMidiDriver.cpp | 5 +---- macosx/coremidi/JackCoreMidiInputPort.cpp | 5 ++--- macosx/coremidi/JackCoreMidiOutputPort.cpp | 11 ++++++----- macosx/coremidi/JackCoreMidiUtil.cpp | 10 +++------- macosx/coremidi/JackCoreMidiUtil.h | 7 ++++++- macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp | 1 - 7 files changed, 20 insertions(+), 21 deletions(-) diff --git a/common/JackMidiAsyncWaitQueue.h b/common/JackMidiAsyncWaitQueue.h index d35dd8b6..8499f688 100644 --- a/common/JackMidiAsyncWaitQueue.h +++ b/common/JackMidiAsyncWaitQueue.h @@ -44,6 +44,8 @@ namespace Jack { public: + using JackMidiAsyncQueue::EnqueueEvent; + /** * Creates a new asynchronous MIDI wait message queue. The queue can * store up to `max_messages` MIDI messages and up to `max_bytes` of diff --git a/macosx/coremidi/JackCoreMidiDriver.cpp b/macosx/coremidi/JackCoreMidiDriver.cpp index b006c333..4be27180 100644 --- a/macosx/coremidi/JackCoreMidiDriver.cpp +++ b/macosx/coremidi/JackCoreMidiDriver.cpp @@ -26,8 +26,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackCoreMidiUtil.h" #include "JackEngineControl.h" -namespace Jack -{ +using Jack::JackCoreMidiDriver; /////////////////////////////////////////////////////////////////////////////// // Static callbacks @@ -632,8 +631,6 @@ JackCoreMidiDriver::Write() return 0; } -} // end of namespace - #ifdef __cplusplus extern "C" { #endif diff --git a/macosx/coremidi/JackCoreMidiInputPort.cpp b/macosx/coremidi/JackCoreMidiInputPort.cpp index e28d62b2..6bf19a1e 100644 --- a/macosx/coremidi/JackCoreMidiInputPort.cpp +++ b/macosx/coremidi/JackCoreMidiInputPort.cpp @@ -100,9 +100,8 @@ JackCoreMidiInputPort::ProcessCoreMidi(const MIDIPacketList *packet_list) sysex_bytes_sent = 0; goto get_next_packet; } - event.data = sysex_buffer; + event.buffer = sysex_buffer; event.size = sysex_bytes_sent; - event.time = ; sysex_bytes_sent = 0; goto send_event; } @@ -115,7 +114,7 @@ JackCoreMidiInputPort::ProcessCoreMidi(const MIDIPacketList *packet_list) goto buffer_sysex_bytes; } } - event.data = data; + event.buffer = data; event.size = size; send_event: diff --git a/macosx/coremidi/JackCoreMidiOutputPort.cpp b/macosx/coremidi/JackCoreMidiOutputPort.cpp index 9bf9a5a3..fcc4102e 100644 --- a/macosx/coremidi/JackCoreMidiOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiOutputPort.cpp @@ -60,7 +60,7 @@ JackCoreMidiOutputPort::Execute() if (! event) { event = thread_queue->DequeueEvent((long) 0); } - jack_midi_data_t *data = event->data; + jack_midi_data_t *data = event->buffer; // This is the latest time that the packet list can be sent out. We // may want to consider subtracting some frames to leave room for the @@ -79,10 +79,10 @@ JackCoreMidiOutputPort::Execute() if (! event) { break; } - packet = MIDIPacketListAdd(packet_list, midi_buffer_size, + packet = MIDIPacketListAdd(packet_list, sizeof(packet_buffer), packet, GetTimeStampFromFrames(event->time), - event->size, event->data); + event->size, event->buffer); if (! packet) { break; } @@ -107,8 +107,9 @@ JackCoreMidiOutputPort::Execute() if (num_bytes > 256) { num_bytes = 256; } - packet = MIDIPacketListAdd(packet_list, midi_buffer_size, - packet, timestamp, num_bytes, + packet = MIDIPacketListAdd(packet_list, + sizeof(packet_buffer), packet, + timestamp, num_bytes, data + bytes_sent); if (! packet) { break; diff --git a/macosx/coremidi/JackCoreMidiUtil.cpp b/macosx/coremidi/JackCoreMidiUtil.cpp index 1652036a..d976e936 100644 --- a/macosx/coremidi/JackCoreMidiUtil.cpp +++ b/macosx/coremidi/JackCoreMidiUtil.cpp @@ -21,15 +21,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackError.h" #include "JackCoreMidiUtil.h" -#import std::string Jack::GetMacOSErrorString(OSStatus status) { - char message[kMaxErrorLength + 1]; - OSStatus result = GetErrorLongString(error, message, - (long) sizeof(message)); - if (result != noErr) { + const char *message = GetMacOSStatusErrorString(status); + if (! message) { std::stringstream stream; stream << "error (code: '" << status << "')"; return stream.str(); @@ -42,6 +39,5 @@ Jack::WriteMacOSError(const char *jack_function, const char *mac_function, OSStatus status) { jack_error("%s - %s: %s", jack_function, mac_function, - GetMacOSStatusString(status).c_str()); + GetMacOSErrorString(status).c_str()); } - diff --git a/macosx/coremidi/JackCoreMidiUtil.h b/macosx/coremidi/JackCoreMidiUtil.h index 291cabe6..2b8fe6fe 100644 --- a/macosx/coremidi/JackCoreMidiUtil.h +++ b/macosx/coremidi/JackCoreMidiUtil.h @@ -20,9 +20,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifndef __JackCoreMidiUtil__ #define __JackCoreMidiUtil__ -#import #include +#include + +// Import? What does this line do? Is it necessary now that I'm not including +// the same library I was including? +#import + namespace Jack { std::string diff --git a/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp b/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp index f295449d..51e3f69c 100644 --- a/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp @@ -19,7 +19,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include -#import #include "JackCoreMidiUtil.h" #include "JackCoreMidiVirtualOutputPort.h" From 62496d8ba8fafa22d2fb8a2c2908648ea2f2972f Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Sun, 27 Mar 2011 10:52:48 +0200 Subject: [PATCH 079/472] Now compiles on OSX. --- macosx/JackMachThread.h | 2 +- macosx/Jackdmp.xcodeproj/project.pbxproj | 122 +++++++++++++++++++++++ macosx/coremidi/JackCoreMidiUtil.h | 7 +- 3 files changed, 125 insertions(+), 6 deletions(-) diff --git a/macosx/JackMachThread.h b/macosx/JackMachThread.h index c22ce20a..92f77d9e 100644 --- a/macosx/JackMachThread.h +++ b/macosx/JackMachThread.h @@ -62,7 +62,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define __JackMachThread__ #include "JackPosixThread.h" -#import +#include #include #include diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index 3ba3fc40..d7041d38 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -108,6 +108,48 @@ /* Begin PBXBuildFile section */ 4B0A28ED0D520852002EFF74 /* tw.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B0A28EC0D520852002EFF74 /* tw.c */; }; 4B0A29260D52108E002EFF74 /* tw.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B0A28EC0D520852002EFF74 /* tw.c */; }; + 4B193933133F311400547810 /* JackMidiAsyncQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193931133F311400547810 /* JackMidiAsyncQueue.cpp */; }; + 4B193934133F311400547810 /* JackMidiAsyncQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193932133F311400547810 /* JackMidiAsyncQueue.h */; }; + 4B193935133F311400547810 /* JackMidiAsyncQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193931133F311400547810 /* JackMidiAsyncQueue.cpp */; }; + 4B193936133F311400547810 /* JackMidiAsyncQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193932133F311400547810 /* JackMidiAsyncQueue.h */; }; + 4B19393D133F313000547810 /* JackMidiAsyncWaitQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19393B133F313000547810 /* JackMidiAsyncWaitQueue.cpp */; }; + 4B19393E133F313000547810 /* JackMidiAsyncWaitQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19393C133F313000547810 /* JackMidiAsyncWaitQueue.h */; }; + 4B19393F133F313000547810 /* JackMidiAsyncWaitQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19393B133F313000547810 /* JackMidiAsyncWaitQueue.cpp */; }; + 4B193940133F313000547810 /* JackMidiAsyncWaitQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19393C133F313000547810 /* JackMidiAsyncWaitQueue.h */; }; + 4B193947133F315300547810 /* JackMidiReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193945133F315200547810 /* JackMidiReadQueue.cpp */; }; + 4B193948133F315300547810 /* JackMidiReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193946133F315200547810 /* JackMidiReadQueue.h */; }; + 4B193949133F315300547810 /* JackMidiReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193945133F315200547810 /* JackMidiReadQueue.cpp */; }; + 4B19394A133F315300547810 /* JackMidiReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193946133F315200547810 /* JackMidiReadQueue.h */; }; + 4B19395F133F317300547810 /* JackMidiBufferReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19395D133F317300547810 /* JackMidiBufferReadQueue.cpp */; }; + 4B193960133F317300547810 /* JackMidiBufferReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19395E133F317300547810 /* JackMidiBufferReadQueue.h */; }; + 4B193961133F317300547810 /* JackMidiBufferReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19395D133F317300547810 /* JackMidiBufferReadQueue.cpp */; }; + 4B193962133F317300547810 /* JackMidiBufferReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19395E133F317300547810 /* JackMidiBufferReadQueue.h */; }; + 4B19396A133F319000547810 /* JackMidiBufferWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193968133F319000547810 /* JackMidiBufferWriteQueue.cpp */; }; + 4B19396B133F319000547810 /* JackMidiBufferWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193969133F319000547810 /* JackMidiBufferWriteQueue.h */; }; + 4B19396C133F319000547810 /* JackMidiBufferWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193968133F319000547810 /* JackMidiBufferWriteQueue.cpp */; }; + 4B19396D133F319000547810 /* JackMidiBufferWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193969133F319000547810 /* JackMidiBufferWriteQueue.h */; }; + 4B19397B133F31CB00547810 /* JackMidiReceiveQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193973133F31CB00547810 /* JackMidiReceiveQueue.cpp */; }; + 4B19397C133F31CB00547810 /* JackMidiReceiveQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193974133F31CB00547810 /* JackMidiReceiveQueue.h */; }; + 4B19397D133F31CB00547810 /* JackMidiSendQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193975133F31CB00547810 /* JackMidiSendQueue.cpp */; }; + 4B19397E133F31CB00547810 /* JackMidiSendQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193976133F31CB00547810 /* JackMidiSendQueue.h */; }; + 4B19397F133F31CB00547810 /* JackMidiUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193977133F31CB00547810 /* JackMidiUtil.cpp */; }; + 4B193980133F31CB00547810 /* JackMidiUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193978133F31CB00547810 /* JackMidiUtil.h */; }; + 4B193981133F31CB00547810 /* JackMidiWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193979133F31CB00547810 /* JackMidiWriteQueue.cpp */; }; + 4B193982133F31CB00547810 /* JackMidiWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19397A133F31CB00547810 /* JackMidiWriteQueue.h */; }; + 4B193983133F31CB00547810 /* JackMidiReceiveQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193973133F31CB00547810 /* JackMidiReceiveQueue.cpp */; }; + 4B193984133F31CB00547810 /* JackMidiReceiveQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193974133F31CB00547810 /* JackMidiReceiveQueue.h */; }; + 4B193985133F31CB00547810 /* JackMidiSendQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193975133F31CB00547810 /* JackMidiSendQueue.cpp */; }; + 4B193986133F31CB00547810 /* JackMidiSendQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193976133F31CB00547810 /* JackMidiSendQueue.h */; }; + 4B193987133F31CB00547810 /* JackMidiUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193977133F31CB00547810 /* JackMidiUtil.cpp */; }; + 4B193988133F31CB00547810 /* JackMidiUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193978133F31CB00547810 /* JackMidiUtil.h */; }; + 4B193989133F31CB00547810 /* JackMidiWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193979133F31CB00547810 /* JackMidiWriteQueue.cpp */; }; + 4B19398A133F31CB00547810 /* JackMidiWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19397A133F31CB00547810 /* JackMidiWriteQueue.h */; }; + 4B193991133F321500547810 /* JackFilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193990133F321500547810 /* JackFilters.h */; }; + 4B193992133F321500547810 /* JackFilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193990133F321500547810 /* JackFilters.h */; }; + 4B193993133F321500547810 /* JackFilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193990133F321500547810 /* JackFilters.h */; }; + 4B193994133F321500547810 /* JackFilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193990133F321500547810 /* JackFilters.h */; }; + 4B193995133F321500547810 /* JackFilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193990133F321500547810 /* JackFilters.h */; }; + 4B193996133F321500547810 /* JackFilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193990133F321500547810 /* JackFilters.h */; }; 4B19B3130E2362E800DD4A82 /* JackAudioAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3060E2362E700DD4A82 /* JackAudioAdapter.cpp */; }; 4B19B3140E2362E800DD4A82 /* JackAudioAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B3070E2362E700DD4A82 /* JackAudioAdapter.h */; }; 4B19B3150E2362E800DD4A82 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3080E2362E700DD4A82 /* JackAudioAdapterInterface.cpp */; }; @@ -1483,6 +1525,25 @@ 4B0A28E60D52073D002EFF74 /* jack_thread_wait */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_thread_wait; sourceTree = BUILT_PRODUCTS_DIR; }; 4B0A28EC0D520852002EFF74 /* tw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tw.c; path = "../example-clients/tw.c"; sourceTree = SOURCE_ROOT; }; 4B0A292D0D52108E002EFF74 /* jack_thread_wait */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_thread_wait; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B193931133F311400547810 /* JackMidiAsyncQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiAsyncQueue.cpp; path = ../common/JackMidiAsyncQueue.cpp; sourceTree = SOURCE_ROOT; }; + 4B193932133F311400547810 /* JackMidiAsyncQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiAsyncQueue.h; path = ../common/JackMidiAsyncQueue.h; sourceTree = SOURCE_ROOT; }; + 4B19393B133F313000547810 /* JackMidiAsyncWaitQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiAsyncWaitQueue.cpp; path = ../common/JackMidiAsyncWaitQueue.cpp; sourceTree = SOURCE_ROOT; }; + 4B19393C133F313000547810 /* JackMidiAsyncWaitQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiAsyncWaitQueue.h; path = ../common/JackMidiAsyncWaitQueue.h; sourceTree = SOURCE_ROOT; }; + 4B193945133F315200547810 /* JackMidiReadQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiReadQueue.cpp; path = ../common/JackMidiReadQueue.cpp; sourceTree = SOURCE_ROOT; }; + 4B193946133F315200547810 /* JackMidiReadQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiReadQueue.h; path = ../common/JackMidiReadQueue.h; sourceTree = SOURCE_ROOT; }; + 4B19395D133F317300547810 /* JackMidiBufferReadQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiBufferReadQueue.cpp; path = ../common/JackMidiBufferReadQueue.cpp; sourceTree = SOURCE_ROOT; }; + 4B19395E133F317300547810 /* JackMidiBufferReadQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiBufferReadQueue.h; path = ../common/JackMidiBufferReadQueue.h; sourceTree = SOURCE_ROOT; }; + 4B193968133F319000547810 /* JackMidiBufferWriteQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiBufferWriteQueue.cpp; path = ../common/JackMidiBufferWriteQueue.cpp; sourceTree = SOURCE_ROOT; }; + 4B193969133F319000547810 /* JackMidiBufferWriteQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiBufferWriteQueue.h; path = ../common/JackMidiBufferWriteQueue.h; sourceTree = SOURCE_ROOT; }; + 4B193973133F31CB00547810 /* JackMidiReceiveQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiReceiveQueue.cpp; path = ../common/JackMidiReceiveQueue.cpp; sourceTree = SOURCE_ROOT; }; + 4B193974133F31CB00547810 /* JackMidiReceiveQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiReceiveQueue.h; path = ../common/JackMidiReceiveQueue.h; sourceTree = SOURCE_ROOT; }; + 4B193975133F31CB00547810 /* JackMidiSendQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiSendQueue.cpp; path = ../common/JackMidiSendQueue.cpp; sourceTree = SOURCE_ROOT; }; + 4B193976133F31CB00547810 /* JackMidiSendQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiSendQueue.h; path = ../common/JackMidiSendQueue.h; sourceTree = SOURCE_ROOT; }; + 4B193977133F31CB00547810 /* JackMidiUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiUtil.cpp; path = ../common/JackMidiUtil.cpp; sourceTree = SOURCE_ROOT; }; + 4B193978133F31CB00547810 /* JackMidiUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiUtil.h; path = ../common/JackMidiUtil.h; sourceTree = SOURCE_ROOT; }; + 4B193979133F31CB00547810 /* JackMidiWriteQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiWriteQueue.cpp; path = ../common/JackMidiWriteQueue.cpp; sourceTree = SOURCE_ROOT; }; + 4B19397A133F31CB00547810 /* JackMidiWriteQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMidiWriteQueue.h; path = ../common/JackMidiWriteQueue.h; sourceTree = SOURCE_ROOT; }; + 4B193990133F321500547810 /* JackFilters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackFilters.h; path = ../common/JackFilters.h; sourceTree = SOURCE_ROOT; }; 4B19B3000E23620F00DD4A82 /* audioadapter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = audioadapter.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B19B3060E2362E700DD4A82 /* JackAudioAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapter.cpp; path = ../common/JackAudioAdapter.cpp; sourceTree = SOURCE_ROOT; }; 4B19B3070E2362E700DD4A82 /* JackAudioAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioAdapter.h; path = ../common/JackAudioAdapter.h; sourceTree = SOURCE_ROOT; }; @@ -2990,6 +3051,7 @@ 4BA550FB05E2420000569492 /* Engine */ = { isa = PBXGroup; children = ( + 4B193990133F321500547810 /* JackFilters.h */, 4B5F253D0DEE9B8F0041E486 /* JackLockedEngine.h */, 4BF8D2130834F02800C94B91 /* JackEngine.h */, 4BF8D2140834F02800C94B91 /* JackEngine.cpp */, @@ -3095,6 +3157,24 @@ 4BF3390D0F8B86AF0080FB5B /* MIDI */ = { isa = PBXGroup; children = ( + 4B193973133F31CB00547810 /* JackMidiReceiveQueue.cpp */, + 4B193974133F31CB00547810 /* JackMidiReceiveQueue.h */, + 4B193975133F31CB00547810 /* JackMidiSendQueue.cpp */, + 4B193976133F31CB00547810 /* JackMidiSendQueue.h */, + 4B193977133F31CB00547810 /* JackMidiUtil.cpp */, + 4B193978133F31CB00547810 /* JackMidiUtil.h */, + 4B193979133F31CB00547810 /* JackMidiWriteQueue.cpp */, + 4B19397A133F31CB00547810 /* JackMidiWriteQueue.h */, + 4B193968133F319000547810 /* JackMidiBufferWriteQueue.cpp */, + 4B193969133F319000547810 /* JackMidiBufferWriteQueue.h */, + 4B19395D133F317300547810 /* JackMidiBufferReadQueue.cpp */, + 4B19395E133F317300547810 /* JackMidiBufferReadQueue.h */, + 4B193945133F315200547810 /* JackMidiReadQueue.cpp */, + 4B193946133F315200547810 /* JackMidiReadQueue.h */, + 4B19393B133F313000547810 /* JackMidiAsyncWaitQueue.cpp */, + 4B19393C133F313000547810 /* JackMidiAsyncWaitQueue.h */, + 4B193931133F311400547810 /* JackMidiAsyncQueue.cpp */, + 4B193932133F311400547810 /* JackMidiAsyncQueue.h */, 4B370A14133DD7E200237B68 /* JackCoreMidiInputPort.cpp */, 4B370A15133DD7E200237B68 /* JackCoreMidiInputPort.h */, 4B370A16133DD7E200237B68 /* JackCoreMidiOutputPort.cpp */, @@ -3301,6 +3381,7 @@ 4B8A38F0117B827900664E07 /* JackSocket.h in Headers */, 4B8A38F7117B82B200664E07 /* JackSocketClientChannel.h in Headers */, 4B5160A813215E8B00BB7DCB /* systemdeps.h in Headers */, + 4B193993133F321500547810 /* JackFilters.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3372,6 +3453,7 @@ 4B8A38B0117B812500664E07 /* JackSocketServerChannel.h in Headers */, 4B8A38C4117B814000664E07 /* JackSocketServerNotifyChannel.h in Headers */, 4B5160AA13215ED900BB7DCB /* systemdeps.h in Headers */, + 4B193995133F321500547810 /* JackFilters.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3667,6 +3749,7 @@ 4B88D04111298BEE007A87C1 /* weakjack.h in Headers */, 4B88D04211298BEE007A87C1 /* weakmacros.h in Headers */, 4B5160A913215EBF00BB7DCB /* systemdeps.h in Headers */, + 4B193994133F321500547810 /* JackFilters.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3758,6 +3841,7 @@ 4B88D03C11298BEE007A87C1 /* weakmacros.h in Headers */, 4B2209ED12F6BC2200E5DC26 /* JackSocket.h in Headers */, 4B2209EF12F6BC2500E5DC26 /* JackSocketClientChannel.h in Headers */, + 4B193991133F321500547810 /* JackFilters.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3832,6 +3916,7 @@ 4B2209E412F6BBF600E5DC26 /* JackSocketServerNotifyChannel.h in Headers */, 4B2209E712F6BC0300E5DC26 /* JackSocket.h in Headers */, 4B2209EA12F6BC1600E5DC26 /* JackSocketNotifyChannel.h in Headers */, + 4B193992133F321500547810 /* JackFilters.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4022,6 +4107,7 @@ 4BC2CA5E113C6CCA0076717C /* JackNetInterface.h in Headers */, 4BC2CA60113C6CD20076717C /* JackNetUnixSocket.h in Headers */, 4B5160AE13215EF900BB7DCB /* systemdeps.h in Headers */, + 4B193996133F321500547810 /* JackFilters.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4066,6 +4152,15 @@ 4B370A3F133DD7E300237B68 /* JackCoreMidiUtil.h in Headers */, 4B370A41133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h in Headers */, 4B370A43133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h in Headers */, + 4B193936133F311400547810 /* JackMidiAsyncQueue.h in Headers */, + 4B193940133F313000547810 /* JackMidiAsyncWaitQueue.h in Headers */, + 4B19394A133F315300547810 /* JackMidiReadQueue.h in Headers */, + 4B193962133F317300547810 /* JackMidiBufferReadQueue.h in Headers */, + 4B19396D133F319000547810 /* JackMidiBufferWriteQueue.h in Headers */, + 4B193984133F31CB00547810 /* JackMidiReceiveQueue.h in Headers */, + 4B193986133F31CB00547810 /* JackMidiSendQueue.h in Headers */, + 4B193988133F31CB00547810 /* JackMidiUtil.h in Headers */, + 4B19398A133F31CB00547810 /* JackMidiWriteQueue.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4134,6 +4229,15 @@ 4B370A2F133DD7E300237B68 /* JackCoreMidiUtil.h in Headers */, 4B370A31133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h in Headers */, 4B370A33133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h in Headers */, + 4B193934133F311400547810 /* JackMidiAsyncQueue.h in Headers */, + 4B19393E133F313000547810 /* JackMidiAsyncWaitQueue.h in Headers */, + 4B193948133F315300547810 /* JackMidiReadQueue.h in Headers */, + 4B193960133F317300547810 /* JackMidiBufferReadQueue.h in Headers */, + 4B19396B133F319000547810 /* JackMidiBufferWriteQueue.h in Headers */, + 4B19397C133F31CB00547810 /* JackMidiReceiveQueue.h in Headers */, + 4B19397E133F31CB00547810 /* JackMidiSendQueue.h in Headers */, + 4B193980133F31CB00547810 /* JackMidiUtil.h in Headers */, + 4B193982133F31CB00547810 /* JackMidiWriteQueue.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7471,6 +7575,15 @@ 4B370A3E133DD7E300237B68 /* JackCoreMidiUtil.cpp in Sources */, 4B370A40133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp in Sources */, 4B370A42133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp in Sources */, + 4B193935133F311400547810 /* JackMidiAsyncQueue.cpp in Sources */, + 4B19393F133F313000547810 /* JackMidiAsyncWaitQueue.cpp in Sources */, + 4B193949133F315300547810 /* JackMidiReadQueue.cpp in Sources */, + 4B193961133F317300547810 /* JackMidiBufferReadQueue.cpp in Sources */, + 4B19396C133F319000547810 /* JackMidiBufferWriteQueue.cpp in Sources */, + 4B193983133F31CB00547810 /* JackMidiReceiveQueue.cpp in Sources */, + 4B193985133F31CB00547810 /* JackMidiSendQueue.cpp in Sources */, + 4B193987133F31CB00547810 /* JackMidiUtil.cpp in Sources */, + 4B193989133F31CB00547810 /* JackMidiWriteQueue.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7544,6 +7657,15 @@ 4B370A2E133DD7E300237B68 /* JackCoreMidiUtil.cpp in Sources */, 4B370A30133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp in Sources */, 4B370A32133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp in Sources */, + 4B193933133F311400547810 /* JackMidiAsyncQueue.cpp in Sources */, + 4B19393D133F313000547810 /* JackMidiAsyncWaitQueue.cpp in Sources */, + 4B193947133F315300547810 /* JackMidiReadQueue.cpp in Sources */, + 4B19395F133F317300547810 /* JackMidiBufferReadQueue.cpp in Sources */, + 4B19396A133F319000547810 /* JackMidiBufferWriteQueue.cpp in Sources */, + 4B19397B133F31CB00547810 /* JackMidiReceiveQueue.cpp in Sources */, + 4B19397D133F31CB00547810 /* JackMidiSendQueue.cpp in Sources */, + 4B19397F133F31CB00547810 /* JackMidiUtil.cpp in Sources */, + 4B193981133F31CB00547810 /* JackMidiWriteQueue.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/macosx/coremidi/JackCoreMidiUtil.h b/macosx/coremidi/JackCoreMidiUtil.h index 2b8fe6fe..4f24fc5b 100644 --- a/macosx/coremidi/JackCoreMidiUtil.h +++ b/macosx/coremidi/JackCoreMidiUtil.h @@ -22,11 +22,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include -#include - -// Import? What does this line do? Is it necessary now that I'm not including -// the same library I was including? -#import +#include +#include namespace Jack { From c8e5d8d3ffffdd470614b26c0c05622cd83ef4a8 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Sun, 27 Mar 2011 11:10:27 +0200 Subject: [PATCH 080/472] Update XCode project. --- macosx/Jackdmp.xcodeproj/project.pbxproj | 26 ++++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index d7041d38..4d002151 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -1861,7 +1861,7 @@ 4BF8D2470834F20600C94B91 /* testSem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSem.cpp; path = ../tests/testSem.cpp; sourceTree = SOURCE_ROOT; }; 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackFrameTimer.cpp; path = ../common/JackFrameTimer.cpp; sourceTree = SOURCE_ROOT; }; 4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackFrameTimer.h; path = ../common/JackFrameTimer.h; sourceTree = SOURCE_ROOT; }; - 4BFA5E980DEC4D9C00FA4CDB /* testMutex */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testMutex; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BFA5E980DEC4D9C00FA4CDB /* testSem */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testSem; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA5E9E0DEC4DD900FA4CDB /* testMutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = testMutex.cpp; path = ../tests/testMutex.cpp; sourceTree = SOURCE_ROOT; }; 4BFA828C0DF6A9E40087B4E1 /* jack_evmon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_evmon; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA829F0DF6A9E40087B4E1 /* jack_bufsize */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_bufsize; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -2662,7 +2662,7 @@ 4B363F1E0DEB0A6A001F72D9 /* jack_monitor_client */, 4B363F350DEB0BD1001F72D9 /* jack_showtime */, 4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */, - 4BFA5E980DEC4D9C00FA4CDB /* testMutex */, + 4BFA5E980DEC4D9C00FA4CDB /* testSem */, 4BFA828C0DF6A9E40087B4E1 /* jack_evmon */, 4BFA829F0DF6A9E40087B4E1 /* jack_bufsize */, 4BFA82AB0DF6A9E40087B4E1 /* jack_rec */, @@ -5871,7 +5871,7 @@ name = "testMutex Universal"; productInstallPath = /usr/local/bin; productName = testSem; - productReference = 4BFA5E980DEC4D9C00FA4CDB /* testMutex */; + productReference = 4BFA5E980DEC4D9C00FA4CDB /* testSem */; productType = "com.apple.product-type.tool"; }; 4BFA82820DF6A9E40087B4E1 /* jack_evmon 64 bits */ = { @@ -8356,7 +8356,7 @@ OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( - /usr/local/lib/libsamplerate.a, + /opt/local/lib/libsamplerate.a, "-framework", Jackservermp, "-framework", @@ -9131,7 +9131,7 @@ ); OTHER_LDFLAGS = ( "-framework", - Jackdmp, + Jackservermp, "-framework", CoreAudio, "-framework", @@ -9511,7 +9511,7 @@ CoreAudio, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = Jackdmp; + PRODUCT_NAME = Jackservermp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -11508,7 +11508,7 @@ OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", - Jackdmp, + Jackservermp, "-framework", CoreAudio, "-framework", @@ -11658,7 +11658,7 @@ OTHER_LDFLAGS = ( libportaudio.a, "-framework", - Jackdmp, + Jackservermp, "-framework", AudioToolbox, "-framework", @@ -11807,7 +11807,7 @@ OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", - Jackdmp, + Jackservermp, "-framework", CoreAudio, "-framework", @@ -11945,7 +11945,7 @@ OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( "-framework", - Jackdmp, + Jackservermp, "-framework", CoreAudio, "-framework", @@ -16457,7 +16457,7 @@ CoreAudio, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = Jackdmp; + PRODUCT_NAME = Jackservermp; REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -17468,7 +17468,7 @@ OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ( - /usr/local/lib/libsamplerate.a, + /opt/local/lib/libsamplerate.a, "-framework", Jackservermp, "-framework", @@ -17617,7 +17617,7 @@ OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( - /usr/local/lib/libsamplerate.a, + /opt/local/lib/libsamplerate.a, "-framework", Jackservermp, "-framework", From e843289af872b1c21730faea9b3b9020d3e31bae Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Sun, 27 Mar 2011 11:46:09 +0200 Subject: [PATCH 081/472] MIDI thread RT priority reworked a bit on OSX. --- macosx/Jackdmp.xcodeproj/project.pbxproj | 7 ++++--- macosx/coremidi/JackCoreMidiDriver.cpp | 9 ++++----- macosx/coremidi/JackCoreMidiOutputPort.cpp | 12 +++++++++--- macosx/coremidi/JackCoreMidiOutputPort.h | 3 +-- macosx/coremidi/JackCoreMidiPhysicalOutputPort.cpp | 4 ++-- macosx/coremidi/JackCoreMidiPhysicalOutputPort.h | 1 - macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp | 4 ++-- macosx/coremidi/JackCoreMidiVirtualOutputPort.h | 1 - 8 files changed, 22 insertions(+), 19 deletions(-) diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index 4d002151..195dd976 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -1861,7 +1861,7 @@ 4BF8D2470834F20600C94B91 /* testSem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSem.cpp; path = ../tests/testSem.cpp; sourceTree = SOURCE_ROOT; }; 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackFrameTimer.cpp; path = ../common/JackFrameTimer.cpp; sourceTree = SOURCE_ROOT; }; 4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackFrameTimer.h; path = ../common/JackFrameTimer.h; sourceTree = SOURCE_ROOT; }; - 4BFA5E980DEC4D9C00FA4CDB /* testSem */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testSem; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BFA5E980DEC4D9C00FA4CDB /* testMutex */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testMutex; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA5E9E0DEC4DD900FA4CDB /* testMutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = testMutex.cpp; path = ../tests/testMutex.cpp; sourceTree = SOURCE_ROOT; }; 4BFA828C0DF6A9E40087B4E1 /* jack_evmon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_evmon; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA829F0DF6A9E40087B4E1 /* jack_bufsize */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_bufsize; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -2662,7 +2662,7 @@ 4B363F1E0DEB0A6A001F72D9 /* jack_monitor_client */, 4B363F350DEB0BD1001F72D9 /* jack_showtime */, 4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */, - 4BFA5E980DEC4D9C00FA4CDB /* testSem */, + 4BFA5E980DEC4D9C00FA4CDB /* testMutex */, 4BFA828C0DF6A9E40087B4E1 /* jack_evmon */, 4BFA829F0DF6A9E40087B4E1 /* jack_bufsize */, 4BFA82AB0DF6A9E40087B4E1 /* jack_rec */, @@ -5871,7 +5871,7 @@ name = "testMutex Universal"; productInstallPath = /usr/local/bin; productName = testSem; - productReference = 4BFA5E980DEC4D9C00FA4CDB /* testSem */; + productReference = 4BFA5E980DEC4D9C00FA4CDB /* testMutex */; productType = "com.apple.product-type.tool"; }; 4BFA82820DF6A9E40087B4E1 /* jack_evmon 64 bits */ = { @@ -9502,6 +9502,7 @@ "-D__SMP__", "-DMACH_RPC_MACH_SEMA", "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", ); OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_LDFLAGS = ( diff --git a/macosx/coremidi/JackCoreMidiDriver.cpp b/macosx/coremidi/JackCoreMidiDriver.cpp index 4be27180..85d01fcf 100644 --- a/macosx/coremidi/JackCoreMidiDriver.cpp +++ b/macosx/coremidi/JackCoreMidiDriver.cpp @@ -267,8 +267,10 @@ JackCoreMidiDriver::Open(bool capturing, bool playing, int in_channels, "client name string"); return -1; } + OSStatus status = MIDIClientCreate(name, HandleNotificationEvent, this, &client); + CFRelease(name); if (status != noErr) { WriteMacOSError("JackCoreMidiDriver::Close", "MIDIClientCreate", @@ -276,7 +278,6 @@ JackCoreMidiDriver::Open(bool capturing, bool playing, int in_channels, return -1; } char *client_name = fClientControl.fName; - int port_rt_priority = fEngineControl->fServerPriority + 1; // Allocate and connect virtual inputs if (in_channels) { @@ -319,8 +320,7 @@ JackCoreMidiDriver::Open(bool capturing, bool playing, int in_channels, new JackCoreMidiVirtualOutputPort(fAliasName, client_name, playback_driver_name, vo_count, client, - time_ratio, - port_rt_priority); + time_ratio); } catch (std::exception e) { jack_error("JackCoreMidiDriver::Open - while creating virtual " "output port: %s", e.what()); @@ -387,8 +387,7 @@ JackCoreMidiDriver::Open(bool capturing, bool playing, int in_channels, new JackCoreMidiPhysicalOutputPort(fAliasName, client_name, playback_driver_name, i, client, internal_output, - time_ratio, - port_rt_priority); + time_ratio); } catch (std::exception e) { jack_error("JackCoreMidiDriver::Open - while creating " "physical output port: %s", e.what()); diff --git a/macosx/coremidi/JackCoreMidiOutputPort.cpp b/macosx/coremidi/JackCoreMidiOutputPort.cpp index fcc4102e..fe1f2d6f 100644 --- a/macosx/coremidi/JackCoreMidiOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiOutputPort.cpp @@ -26,7 +26,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. using Jack::JackCoreMidiOutputPort; JackCoreMidiOutputPort::JackCoreMidiOutputPort(double time_ratio, - int realtime_priority, size_t max_bytes, size_t max_messages): JackCoreMidiPort(time_ratio) @@ -36,7 +35,6 @@ JackCoreMidiOutputPort::JackCoreMidiOutputPort(double time_ratio, thread_queue = new JackMidiAsyncWaitQueue(max_bytes, max_messages); std::auto_ptr thread_ptr(thread_queue); thread = new JackThread(this); - this->realtime_priority = realtime_priority; thread_ptr.release(); read_ptr.release(); } @@ -137,7 +135,15 @@ bool JackCoreMidiOutputPort::Init() { set_threaded_log_function(); - if (thread->AcquireSelfRealTime(realtime_priority)) { + + // OSX only... + UInt64 period = 0; + UInt64 computation = 500 * 1000; + UInt64 constraint = 500 * 1000; + thread->SetParams(period, computation, constraint); + + // Use the server priority : y + if (thread->AcquireSelfRealTime()) { jack_error("JackCoreMidiOutputPort::Init - could not acquire realtime " "scheduling. Continuing anyway."); } diff --git a/macosx/coremidi/JackCoreMidiOutputPort.h b/macosx/coremidi/JackCoreMidiOutputPort.h index cddda999..54df1562 100644 --- a/macosx/coremidi/JackCoreMidiOutputPort.h +++ b/macosx/coremidi/JackCoreMidiOutputPort.h @@ -39,7 +39,6 @@ namespace Jack { char packet_buffer[PACKET_BUFFER_SIZE]; JackMidiBufferReadQueue *read_queue; - int realtime_priority; JackThread *thread; JackMidiAsyncWaitQueue *thread_queue; @@ -55,7 +54,7 @@ namespace Jack { public: - JackCoreMidiOutputPort(double time_ratio, int realtime_priority, size_t max_bytes=4096, + JackCoreMidiOutputPort(double time_ratio, size_t max_bytes=4096, size_t max_messages=1024); virtual diff --git a/macosx/coremidi/JackCoreMidiPhysicalOutputPort.cpp b/macosx/coremidi/JackCoreMidiPhysicalOutputPort.cpp index 9716359a..e5b19d59 100644 --- a/macosx/coremidi/JackCoreMidiPhysicalOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiPhysicalOutputPort.cpp @@ -30,9 +30,9 @@ JackCoreMidiPhysicalOutputPort(const char *alias_name, const char *client_name, const char *driver_name, int index, MIDIClientRef client, MIDIPortRef internal_output, double time_ratio, - int realtime_priority, size_t max_bytes, + size_t max_bytes, size_t max_messages): - JackCoreMidiOutputPort(time_ratio, realtime_priority, max_bytes, + JackCoreMidiOutputPort(time_ratio, max_bytes, max_messages) { MIDIEndpointRef destination = MIDIGetDestination(index); diff --git a/macosx/coremidi/JackCoreMidiPhysicalOutputPort.h b/macosx/coremidi/JackCoreMidiPhysicalOutputPort.h index fb922f84..9d641180 100644 --- a/macosx/coremidi/JackCoreMidiPhysicalOutputPort.h +++ b/macosx/coremidi/JackCoreMidiPhysicalOutputPort.h @@ -43,7 +43,6 @@ namespace Jack { MIDIClientRef client, MIDIPortRef internal_output, double time_ratio, - int realtime_priority, size_t max_bytes=4096, size_t max_messages=1024); diff --git a/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp b/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp index 51e3f69c..5e69a170 100644 --- a/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp @@ -29,9 +29,9 @@ JackCoreMidiVirtualOutputPort:: JackCoreMidiVirtualOutputPort(const char *alias_name, const char *client_name, const char *driver_name, int index, MIDIClientRef client, double time_ratio, - int realtime_priority, size_t max_bytes, + size_t max_bytes, size_t max_messages): - JackCoreMidiOutputPort(time_ratio, realtime_priority, max_bytes, + JackCoreMidiOutputPort(time_ratio, max_bytes, max_messages) { std::stringstream stream; diff --git a/macosx/coremidi/JackCoreMidiVirtualOutputPort.h b/macosx/coremidi/JackCoreMidiVirtualOutputPort.h index 2b828553..61529a98 100644 --- a/macosx/coremidi/JackCoreMidiVirtualOutputPort.h +++ b/macosx/coremidi/JackCoreMidiVirtualOutputPort.h @@ -37,7 +37,6 @@ namespace Jack { const char *client_name, const char *driver_name, int index, MIDIClientRef client, double time_ratio, - int realtime_priority, size_t max_bytes=4096, size_t max_messages=1024); From 8ff7bfe6f73ce332fb49463ddca35d8863af75c1 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Sun, 27 Mar 2011 11:49:11 +0200 Subject: [PATCH 082/472] MIDI thread RT priority reworked a bit on OSX. --- macosx/coremidi/JackCoreMidiOutputPort.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/macosx/coremidi/JackCoreMidiOutputPort.cpp b/macosx/coremidi/JackCoreMidiOutputPort.cpp index fe1f2d6f..72eea5d4 100644 --- a/macosx/coremidi/JackCoreMidiOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiOutputPort.cpp @@ -55,6 +55,7 @@ JackCoreMidiOutputPort::Execute() for (;;) { MIDIPacket *packet = MIDIPacketListInit(packet_list); assert(packet); + assert(thread_queue); if (! event) { event = thread_queue->DequeueEvent((long) 0); } From 810ec14d11f1ba8f17ad65a7e2e562c4b3aac633 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Sun, 27 Mar 2011 12:34:40 +0200 Subject: [PATCH 083/472] Improve error handling. --- common/JackMidiAsyncWaitQueue.cpp | 2 ++ common/Jackdmp.cpp | 12 +++++++++--- macosx/coremidi/JackCoreMidiDriver.cpp | 8 ++++++-- macosx/coremidi/JackCoreMidiPort.cpp | 5 +++-- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/common/JackMidiAsyncWaitQueue.cpp b/common/JackMidiAsyncWaitQueue.cpp index 016737cb..7eea9fb1 100644 --- a/common/JackMidiAsyncWaitQueue.cpp +++ b/common/JackMidiAsyncWaitQueue.cpp @@ -68,6 +68,8 @@ JackMidiAsyncWaitQueue::DequeueEvent(jack_nframes_t frame) jack_midi_event_t * JackMidiAsyncWaitQueue::DequeueEvent(long usec) { +printf("JackMidiAsyncWaitQueue::DequeueEvent 0 %d\n", semaphore); + return ((usec < 0) ? semaphore.Wait() : semaphore.TimedWait(usec)) ? JackMidiAsyncQueue::DequeueEvent() : 0; } diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index 602aca31..1cd5968f 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -476,7 +476,9 @@ int main(int argc, char* argv[]) fprintf(stderr, "Unknown driver \"%s\"\n", *it); goto close_server; } - jackctl_server_add_slave(server_ctl, slave_driver_ctl); + if (!jackctl_server_add_slave(server_ctl, slave_driver_ctl)) { + fprintf(stderr, "Driver \"%s\" cannot be loaded\n", *it); + } } // Loopback driver @@ -491,7 +493,9 @@ int main(int argc, char* argv[]) value.ui = loopback; jackctl_parameter_set_value(param, &value); } - jackctl_server_add_slave(server_ctl, loopback_driver_ctl); + if (!jackctl_server_add_slave(server_ctl, loopback_driver_ctl)) { + fprintf(stderr, "Driver \"loopback\" cannot be loaded\n"); + } } } @@ -509,7 +513,9 @@ int main(int argc, char* argv[]) fprintf(stderr, "Unknown internal \"%s\"\n", *it); goto stop_server; } - jackctl_server_load_internal(server_ctl, internal_driver_ctl); + if (!jackctl_server_load_internal(server_ctl, internal_driver_ctl)) { + fprintf(stderr, "Internal client \"%s\" cannot be loaded\n", *it); + } } notify_server_start(server_name); diff --git a/macosx/coremidi/JackCoreMidiDriver.cpp b/macosx/coremidi/JackCoreMidiDriver.cpp index 85d01fcf..c7d8d07a 100644 --- a/macosx/coremidi/JackCoreMidiDriver.cpp +++ b/macosx/coremidi/JackCoreMidiDriver.cpp @@ -357,7 +357,9 @@ JackCoreMidiDriver::Open(bool capturing, bool playing, int in_channels, } catch (std::exception e) { jack_error("JackCoreMidiDriver::Open - while creating " "physical input port: %s", e.what()); - continue; + //continue; + // SL : seems safer to fail here? + goto destroy_internal_input_port; } pi_count++; } @@ -391,7 +393,9 @@ JackCoreMidiDriver::Open(bool capturing, bool playing, int in_channels, } catch (std::exception e) { jack_error("JackCoreMidiDriver::Open - while creating " "physical output port: %s", e.what()); - continue; + //continue; + // SL : seems safer to fail here? + goto destroy_internal_output_port; } po_count++; } diff --git a/macosx/coremidi/JackCoreMidiPort.cpp b/macosx/coremidi/JackCoreMidiPort.cpp index e3c027c3..82a92fa1 100644 --- a/macosx/coremidi/JackCoreMidiPort.cpp +++ b/macosx/coremidi/JackCoreMidiPort.cpp @@ -65,6 +65,7 @@ JackCoreMidiPort::Initialize(const char *alias_name, const char *client_name, char endpoint_name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; CFStringRef endpoint_name_ref; int num = index + 1; + Boolean res; OSStatus result = MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &endpoint_name_ref); if (result != noErr) { @@ -72,10 +73,10 @@ JackCoreMidiPort::Initialize(const char *alias_name, const char *client_name, "MIDIObjectGetStringProperty", result); goto get_basic_alias; } - result = CFStringGetCString(endpoint_name_ref, endpoint_name, + res = CFStringGetCString(endpoint_name_ref, endpoint_name, sizeof(endpoint_name), 0); CFRelease(endpoint_name_ref); - if (result != noErr) { + if (!res) { jack_error("JackCoreMidiPort::Initialize - failed to allocate memory " "for endpoint name."); get_basic_alias: From 9a538cbddc453f959f59692f67414e52ffae3c15 Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Sun, 27 Mar 2011 12:36:11 -0700 Subject: [PATCH 084/472] Make JackCoreMidiOutputPort use the standard JackMidiAsyncQueue with native semaphores. --- macosx/coremidi/JackCoreMidiOutputPort.cpp | 60 ++++++++++++++++++---- macosx/coremidi/JackCoreMidiOutputPort.h | 11 +++- 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/macosx/coremidi/JackCoreMidiOutputPort.cpp b/macosx/coremidi/JackCoreMidiOutputPort.cpp index 72eea5d4..c1761075 100644 --- a/macosx/coremidi/JackCoreMidiOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiOutputPort.cpp @@ -18,7 +18,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include +#include +#include #include +#include #include "JackCoreMidiOutputPort.h" #include "JackMidiUtil.h" @@ -31,18 +34,27 @@ JackCoreMidiOutputPort::JackCoreMidiOutputPort(double time_ratio, JackCoreMidiPort(time_ratio) { read_queue = new JackMidiBufferReadQueue(); - std::auto_ptr read_ptr(read_queue); - thread_queue = new JackMidiAsyncWaitQueue(max_bytes, max_messages); - std::auto_ptr thread_ptr(thread_queue); + std::auto_ptr read_queue_ptr(read_queue); + thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); + std::auto_ptr thread_queue_ptr(thread_queue); thread = new JackThread(this); + std::auto_ptr thread_ptr(thread); + sprintf(semaphore_name, "coremidi_thread_queue_semaphore_%p", this); + thread_queue_semaphore = sem_open(semaphore_name, O_CREAT, 0777, 0); + if (thread_queue_semaphore == (sem_t *) SEM_FAILED) { + throw std::runtime_error(strerror(errno)); + } thread_ptr.release(); - read_ptr.release(); + thread_queue_ptr.release(); + read_queue_ptr.release(); } JackCoreMidiOutputPort::~JackCoreMidiOutputPort() { Stop(); delete thread; + sem_destroy(thread_queue_semaphore); + sem_unlink(semaphore_name); delete read_queue; delete thread_queue; } @@ -57,7 +69,7 @@ JackCoreMidiOutputPort::Execute() assert(packet); assert(thread_queue); if (! event) { - event = thread_queue->DequeueEvent((long) 0); + event = GetCoreMidiEvent(true); } jack_midi_data_t *data = event->buffer; @@ -74,7 +86,7 @@ JackCoreMidiOutputPort::Execute() timestamp, size, data); if (packet) { while (GetCurrentFrame() < send_time) { - event = thread_queue->DequeueEvent(); + event = GetCoreMidiEvent(false); if (! event) { break; } @@ -126,6 +138,29 @@ JackCoreMidiOutputPort::Execute() return false; } +jack_midi_event_t * +JackCoreMidiOutputPort::GetCoreMidiEvent(bool block) +{ + if (! block) { + if (sem_trywait(thread_queue_semaphore)) { + if (errno != ETIMEDOUT) { + jack_error("JackCoreMidiOutputPort::Execute - sem_trywait: %s", + strerror(errno)); + } + return 0; + } + } else { + while (sem_wait(thread_queue_semaphore)) { + if (errno != EINTR) { + jack_error("JackCoreMidiOutputPort::Execute - sem_wait: %s", + strerror(errno)); + return 0; + } + } + } + return thread_queue->DequeueEvent(); +} + MIDITimeStamp JackCoreMidiOutputPort::GetTimeStampFromFrames(jack_nframes_t frames) { @@ -157,7 +192,8 @@ JackCoreMidiOutputPort::Initialize(const char *alias_name, const char *driver_name, int index, MIDIEndpointRef endpoint) { - JackCoreMidiPort::Initialize(alias_name, client_name, driver_name, index, endpoint, true); + JackCoreMidiPort::Initialize(alias_name, client_name, driver_name, index, + endpoint, true); } void @@ -171,14 +207,18 @@ JackCoreMidiOutputPort::ProcessJack(JackMidiBuffer *port_buffer, case JackMidiWriteQueue::BUFFER_FULL: jack_error("JackCoreMidiOutputPort::ProcessJack - The thread " "queue buffer is full. Dropping event."); - continue; + break; case JackMidiWriteQueue::BUFFER_TOO_SMALL: jack_error("JackCoreMidiOutputPort::ProcessJack - The thread " "queue couldn't enqueue a %d-byte event. Dropping " "event.", event->size); - // Fallthrough on purpose + break; default: - ; + if (sem_post(thread_queue_semaphore)) { + jack_error("JackCoreMidiOutputPort::ProcessJack - unexpected " + "error while posting to thread queue semaphore: %s", + strerror(errno)); + } } } } diff --git a/macosx/coremidi/JackCoreMidiOutputPort.h b/macosx/coremidi/JackCoreMidiOutputPort.h index 54df1562..d713c314 100644 --- a/macosx/coremidi/JackCoreMidiOutputPort.h +++ b/macosx/coremidi/JackCoreMidiOutputPort.h @@ -20,8 +20,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifndef __JackCoreMidiOutputPort__ #define __JackCoreMidiOutputPort__ +#include + #include "JackCoreMidiPort.h" -#include "JackMidiAsyncWaitQueue.h" +#include "JackMidiAsyncQueue.h" #include "JackMidiBufferReadQueue.h" #include "JackThread.h" @@ -32,6 +34,9 @@ namespace Jack { private: + jack_midi_event_t * + GetCoreMidiEvent(bool block); + MIDITimeStamp GetTimeStampFromFrames(jack_nframes_t frames); @@ -39,8 +44,10 @@ namespace Jack { char packet_buffer[PACKET_BUFFER_SIZE]; JackMidiBufferReadQueue *read_queue; + char semaphore_name[128]; JackThread *thread; - JackMidiAsyncWaitQueue *thread_queue; + JackMidiAsyncQueue *thread_queue; + sem_t *thread_queue_semaphore; protected: From dd4012c6caf11a7fa2d912902afb733a83a4ec5c Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Sun, 27 Mar 2011 22:24:09 -0700 Subject: [PATCH 085/472] Minor cleanup for 'midi_latency_test.c'. --- example-clients/midi_latency_test.c | 38 +++++++++++++++++++---------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/example-clients/midi_latency_test.c b/example-clients/midi_latency_test.c index d9e6fb08..1b14b13c 100644 --- a/example-clients/midi_latency_test.c +++ b/example-clients/midi_latency_test.c @@ -95,11 +95,13 @@ char *program_name; jack_port_t *remote_in_port; jack_port_t *remote_out_port; size_t samples; + #ifdef __APPLE__ sem_t* semaphore; #else sem_t semaphore; #endif + pthread_mutex_t start_mutex; int timeout; jack_nframes_t total_latency; @@ -216,11 +218,13 @@ handle_process(jack_nframes_t frames, void *arg) messages_received++; if (messages_received == samples) { process_state = 2; - #ifdef __APPLE__ + +#ifdef __APPLE__ sem_post(semaphore); - #else +#else sem_post(&semaphore); - #endif +#endif + break; } send_message: @@ -310,11 +314,13 @@ set_process_error(const char *source, const char *message) error_source = source; error_message = message; process_state = -1; - #ifdef __APPLE__ + +#ifdef __APPLE__ sem_post(semaphore); #else sem_post(&semaphore); #endif + } int @@ -472,6 +478,7 @@ main(int argc, char **argv) jack_on_shutdown(client, handle_shutdown, NULL); jack_set_info_function(handle_info); process_state = 0; + #ifdef __APPLE__ // sem_init is not implemented on OSX char name[128]; @@ -488,6 +495,7 @@ main(int argc, char **argv) goto unregister_out_port; } #endif + code = pthread_mutex_init(&start_mutex, NULL); if (code) { error_message = strerror(errno); @@ -523,15 +531,19 @@ main(int argc, char **argv) error_source = "pthread_mutex_unlock"; goto deactivate_client; } + #ifdef __APPLE__ - while (sem_wait(semaphore) != 0) {} + while (sem_wait(semaphore) != 0) { #else - if (sem_wait(&semaphore)) { - error_message = strerror(errno); - error_source = "sem_wait"; - goto deactivate_client; - } + while (sem_wait(&semaphore) != 0) { #endif + + if (errno != EINTR) { + error_message = strerror(errno); + error_source = "sem_wait"; + goto deactivate_client; + } + } if (process_state == 2) { double average_latency = ((double) total_latency) / samples; double average_latency_time = total_latency_time / samples; @@ -599,11 +611,14 @@ main(int argc, char **argv) destroy_mutex: pthread_mutex_destroy(&start_mutex); destroy_semaphore: + #ifdef __APPLE__ sem_destroy(semaphore); + sem_unlink(name); #else sem_destroy(&semaphore); #endif + unregister_out_port: jack_port_unregister(client, out_port); unregister_in_port: @@ -623,8 +638,5 @@ main(int argc, char **argv) output_error(error_source, error_message); exit(EXIT_FAILURE); } -#ifdef __APPLE__ - sem_unlink(name); -#endif return EXIT_SUCCESS; } From 950945cd7df5c6e6e4102576cfc54be0b12e5480 Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Sun, 27 Mar 2011 23:18:21 -0700 Subject: [PATCH 086/472] Make midi_latency_test.c use an 'active sense' message instead of a 'midi clock' message when testing one byte messages. Some MIDI interfaces eat up sync messages. Of course, they could very well eat up 'active sense' messages too ... --- example-clients/midi_latency_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example-clients/midi_latency_test.c b/example-clients/midi_latency_test.c index 1b14b13c..42e7f1ed 100644 --- a/example-clients/midi_latency_test.c +++ b/example-clients/midi_latency_test.c @@ -407,7 +407,7 @@ main(int argc, char **argv) switch (message_size) { case 1: message_1[0] = 0xf6; - message_2[0] = 0xf8; + message_2[0] = 0xfe; break; case 2: message_1[0] = 0xc0; From bdde2d110beaa2a5400cf02d4e6792d1bd618b05 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Mon, 28 Mar 2011 17:05:03 +0200 Subject: [PATCH 087/472] CoreMidi driver starting to work. --- common/JackMidiAsyncWaitQueue.cpp | 2 -- common/Jackdmp.cpp | 3 +++ macosx/coremidi/JackCoreMidiInputPort.cpp | 1 + macosx/coremidi/JackCoreMidiOutputPort.cpp | 6 +++--- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/common/JackMidiAsyncWaitQueue.cpp b/common/JackMidiAsyncWaitQueue.cpp index 7eea9fb1..016737cb 100644 --- a/common/JackMidiAsyncWaitQueue.cpp +++ b/common/JackMidiAsyncWaitQueue.cpp @@ -68,8 +68,6 @@ JackMidiAsyncWaitQueue::DequeueEvent(jack_nframes_t frame) jack_midi_event_t * JackMidiAsyncWaitQueue::DequeueEvent(long usec) { -printf("JackMidiAsyncWaitQueue::DequeueEvent 0 %d\n", semaphore); - return ((usec < 0) ? semaphore.Wait() : semaphore.TimedWait(usec)) ? JackMidiAsyncQueue::DequeueEvent() : 0; } diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index 1cd5968f..9123b3c7 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -478,6 +478,7 @@ int main(int argc, char* argv[]) } if (!jackctl_server_add_slave(server_ctl, slave_driver_ctl)) { fprintf(stderr, "Driver \"%s\" cannot be loaded\n", *it); + goto close_server; } } @@ -495,6 +496,7 @@ int main(int argc, char* argv[]) } if (!jackctl_server_add_slave(server_ctl, loopback_driver_ctl)) { fprintf(stderr, "Driver \"loopback\" cannot be loaded\n"); + goto close_server; } } @@ -515,6 +517,7 @@ int main(int argc, char* argv[]) } if (!jackctl_server_load_internal(server_ctl, internal_driver_ctl)) { fprintf(stderr, "Internal client \"%s\" cannot be loaded\n", *it); + goto stop_server; } } diff --git a/macosx/coremidi/JackCoreMidiInputPort.cpp b/macosx/coremidi/JackCoreMidiInputPort.cpp index 6bf19a1e..86fa9bf0 100644 --- a/macosx/coremidi/JackCoreMidiInputPort.cpp +++ b/macosx/coremidi/JackCoreMidiInputPort.cpp @@ -147,6 +147,7 @@ JackCoreMidiInputPort::ProcessJack(JackMidiBuffer *port_buffer, if (! jack_event) { jack_event = thread_queue->DequeueEvent(); } + for (; jack_event; jack_event = thread_queue->DequeueEvent()) { // Add 'frames' to MIDI events to align with audio. switch (write_queue->EnqueueEvent(jack_event, frames)) { diff --git a/macosx/coremidi/JackCoreMidiOutputPort.cpp b/macosx/coremidi/JackCoreMidiOutputPort.cpp index c1761075..05e1786f 100644 --- a/macosx/coremidi/JackCoreMidiOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiOutputPort.cpp @@ -36,10 +36,10 @@ JackCoreMidiOutputPort::JackCoreMidiOutputPort(double time_ratio, read_queue = new JackMidiBufferReadQueue(); std::auto_ptr read_queue_ptr(read_queue); thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); - std::auto_ptr thread_queue_ptr(thread_queue); + std::auto_ptr thread_queue_ptr(thread_queue); thread = new JackThread(this); std::auto_ptr thread_ptr(thread); - sprintf(semaphore_name, "coremidi_thread_queue_semaphore_%p", this); + sprintf(semaphore_name, "coremidi_%p", this); thread_queue_semaphore = sem_open(semaphore_name, O_CREAT, 0777, 0); if (thread_queue_semaphore == (sem_t *) SEM_FAILED) { throw std::runtime_error(strerror(errno)); @@ -202,7 +202,7 @@ JackCoreMidiOutputPort::ProcessJack(JackMidiBuffer *port_buffer, { read_queue->ResetMidiBuffer(port_buffer); for (jack_midi_event_t *event = read_queue->DequeueEvent(); event; - event = read_queue->DequeueEvent()) { + event = read_queue->DequeueEvent()) { switch (thread_queue->EnqueueEvent(event, frames)) { case JackMidiWriteQueue::BUFFER_FULL: jack_error("JackCoreMidiOutputPort::ProcessJack - The thread " From c1c9a7c4cd2137f9cca8d19b15afcc4f6b4315f3 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Mon, 28 Mar 2011 17:52:25 +0200 Subject: [PATCH 088/472] Correct JackCoreAudioDriver::Close. --- macosx/coreaudio/JackCoreAudioDriver.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 383babf5..6fed74be 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -1552,7 +1552,6 @@ error: int JackCoreAudioDriver::Close() { jack_log("JackCoreAudioDriver::Close"); - Stop(); // Generic audio driver close int res = JackAudioDriver::Close(); From 33534bd8a73279774c4db04c4091a7a92a3795ab Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Mon, 28 Mar 2011 18:02:41 +0200 Subject: [PATCH 089/472] Cleanup. --- macosx/coremidi/JackCoreMidiDriver.cpp | 4 ---- macosx/coremidi/JackCoreMidiOutputPort.cpp | 1 - 2 files changed, 5 deletions(-) diff --git a/macosx/coremidi/JackCoreMidiDriver.cpp b/macosx/coremidi/JackCoreMidiDriver.cpp index c7d8d07a..acdd5136 100644 --- a/macosx/coremidi/JackCoreMidiDriver.cpp +++ b/macosx/coremidi/JackCoreMidiDriver.cpp @@ -357,8 +357,6 @@ JackCoreMidiDriver::Open(bool capturing, bool playing, int in_channels, } catch (std::exception e) { jack_error("JackCoreMidiDriver::Open - while creating " "physical input port: %s", e.what()); - //continue; - // SL : seems safer to fail here? goto destroy_internal_input_port; } pi_count++; @@ -393,8 +391,6 @@ JackCoreMidiDriver::Open(bool capturing, bool playing, int in_channels, } catch (std::exception e) { jack_error("JackCoreMidiDriver::Open - while creating " "physical output port: %s", e.what()); - //continue; - // SL : seems safer to fail here? goto destroy_internal_output_port; } po_count++; diff --git a/macosx/coremidi/JackCoreMidiOutputPort.cpp b/macosx/coremidi/JackCoreMidiOutputPort.cpp index 05e1786f..796d40bf 100644 --- a/macosx/coremidi/JackCoreMidiOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiOutputPort.cpp @@ -67,7 +67,6 @@ JackCoreMidiOutputPort::Execute() for (;;) { MIDIPacket *packet = MIDIPacketListInit(packet_list); assert(packet); - assert(thread_queue); if (! event) { event = GetCoreMidiEvent(true); } From 691694696132bac4da671a4c9e12c9ef798aeb51 Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Mon, 28 Mar 2011 09:35:57 -0700 Subject: [PATCH 090/472] Use EAGAIN with 'sem_trywait' instead of ETIMEDOUT. --- macosx/coremidi/JackCoreMidiOutputPort.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/macosx/coremidi/JackCoreMidiOutputPort.cpp b/macosx/coremidi/JackCoreMidiOutputPort.cpp index c1761075..ced499e4 100644 --- a/macosx/coremidi/JackCoreMidiOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiOutputPort.cpp @@ -143,7 +143,7 @@ JackCoreMidiOutputPort::GetCoreMidiEvent(bool block) { if (! block) { if (sem_trywait(thread_queue_semaphore)) { - if (errno != ETIMEDOUT) { + if (errno != EAGAIN) { jack_error("JackCoreMidiOutputPort::Execute - sem_trywait: %s", strerror(errno)); } From 6341e378598ef830714832c221bc7a045136bbec Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Mon, 28 Mar 2011 18:50:43 +0200 Subject: [PATCH 091/472] Correct some naming stuff. --- common/JackLoopbackDriver.h | 2 +- macosx/coremidi/JackCoreMidiPort.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/common/JackLoopbackDriver.h b/common/JackLoopbackDriver.h index 8fe22266..247f852e 100644 --- a/common/JackLoopbackDriver.h +++ b/common/JackLoopbackDriver.h @@ -44,7 +44,7 @@ class JackLoopbackDriver : public JackAudioDriver public: JackLoopbackDriver(JackLockedEngine* engine, JackSynchro* table) - : JackAudioDriver("loopback", "", engine, table) + : JackAudioDriver("loopback", "loopback", engine, table) {} virtual ~JackLoopbackDriver() {} diff --git a/macosx/coremidi/JackCoreMidiPort.cpp b/macosx/coremidi/JackCoreMidiPort.cpp index 82a92fa1..7b2fd6db 100644 --- a/macosx/coremidi/JackCoreMidiPort.cpp +++ b/macosx/coremidi/JackCoreMidiPort.cpp @@ -81,10 +81,10 @@ JackCoreMidiPort::Initialize(const char *alias_name, const char *client_name, "for endpoint name."); get_basic_alias: snprintf(alias, sizeof(alias) - 1, "%s:%s:%s%d", alias_name, - driver_name, is_output ? "out" : "in", num); + driver_name, is_output ? "in" : "out", num); } else { snprintf(alias, sizeof(alias) - 1, "%s:%s:%s%d", alias_name, - endpoint_name, is_output ? "out" : "in", num); + endpoint_name, is_output ? "in" : "out", num); } snprintf(name, sizeof(name) - 1, "%s:%s_%d", client_name, is_output ? "playback" : "capture", num); From f21223cf60078db56464c67760cf5bdcecb8ec75 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Mon, 28 Mar 2011 21:20:18 +0200 Subject: [PATCH 092/472] Correct MIDI threads priority. --- macosx/coremidi/JackCoreMidiOutputPort.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/macosx/coremidi/JackCoreMidiOutputPort.cpp b/macosx/coremidi/JackCoreMidiOutputPort.cpp index ad333504..15a04f76 100644 --- a/macosx/coremidi/JackCoreMidiOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiOutputPort.cpp @@ -171,13 +171,12 @@ JackCoreMidiOutputPort::Init() { set_threaded_log_function(); - // OSX only... + // OSX only, values read in RT CoreMidi thread UInt64 period = 0; - UInt64 computation = 500 * 1000; + UInt64 computation = 250 * 1000; UInt64 constraint = 500 * 1000; thread->SetParams(period, computation, constraint); - // Use the server priority : y if (thread->AcquireSelfRealTime()) { jack_error("JackCoreMidiOutputPort::Init - could not acquire realtime " "scheduling. Continuing anyway."); From c362b8b0bb29f3e15e9e8294be4091e993393868 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Tue, 29 Mar 2011 09:17:52 +0200 Subject: [PATCH 093/472] Add set_threaded_log_function in CoreMidi RT thread. --- macosx/coreaudio/JackCoreAudioDriver.cpp | 2 +- macosx/coremidi/JackCoreMidiInputPort.cpp | 2 ++ macosx/coremidi/JackCoreMidiPort.h | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 6fed74be..bf4e3195 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -195,7 +195,7 @@ OSStatus JackCoreAudioDriver::Render(void *inRefCon, driver->fCurrentTime = (AudioTimeStamp *)inTimeStamp; driver->fDriverOutputData = ioData; - // Setup threadded based log function once... + // Setup threaded based log function et get RT thread parameters once... if (set_threaded_log_function()) { jack_log("set_threaded_log_function"); diff --git a/macosx/coremidi/JackCoreMidiInputPort.cpp b/macosx/coremidi/JackCoreMidiInputPort.cpp index 86fa9bf0..fb4bc961 100644 --- a/macosx/coremidi/JackCoreMidiInputPort.cpp +++ b/macosx/coremidi/JackCoreMidiInputPort.cpp @@ -66,6 +66,8 @@ JackCoreMidiInputPort::Initialize(const char *alias_name, void JackCoreMidiInputPort::ProcessCoreMidi(const MIDIPacketList *packet_list) { + set_threaded_log_function(); + unsigned int packet_count = packet_list->numPackets; assert(packet_count); MIDIPacket *packet = (MIDIPacket *) packet_list->packet; diff --git a/macosx/coremidi/JackCoreMidiPort.h b/macosx/coremidi/JackCoreMidiPort.h index 8a5641bb..21055c31 100644 --- a/macosx/coremidi/JackCoreMidiPort.h +++ b/macosx/coremidi/JackCoreMidiPort.h @@ -45,7 +45,7 @@ namespace Jack { MIDIEndpointRef endpoint, bool is_output); double time_ratio; - MIDIEndpointRef endpoint; + MIDIEndpointRef endpoint; public: From 20831f45ea19094d2d12d4f00faba62d9e1169dd Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Tue, 29 Mar 2011 08:55:11 -0700 Subject: [PATCH 094/472] Overhaul WinMME driver to use MIDI queue system. WARNING: I don't have a Windows development environment, and haven't compiled/tested this code. --- windows/winmme/JackWinMMEDriver.cpp | 549 ++++++++++-------------- windows/winmme/JackWinMMEDriver.h | 77 ++-- windows/winmme/JackWinMMEInputPort.cpp | 287 +++++++++++++ windows/winmme/JackWinMMEInputPort.h | 89 ++++ windows/winmme/JackWinMMEOutputPort.cpp | 352 +++++++++++++++ windows/winmme/JackWinMMEOutputPort.h | 93 ++++ 6 files changed, 1069 insertions(+), 378 deletions(-) create mode 100644 windows/winmme/JackWinMMEInputPort.cpp create mode 100644 windows/winmme/JackWinMMEInputPort.h create mode 100644 windows/winmme/JackWinMMEOutputPort.cpp create mode 100644 windows/winmme/JackWinMMEOutputPort.h diff --git a/windows/winmme/JackWinMMEDriver.cpp b/windows/winmme/JackWinMMEDriver.cpp index d3635c64..455118a2 100644 --- a/windows/winmme/JackWinMMEDriver.cpp +++ b/windows/winmme/JackWinMMEDriver.cpp @@ -1,5 +1,6 @@ /* Copyright (C) 2009 Grame +Copyright (C) 2011 Devin Anderson 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 @@ -17,401 +18,285 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "JackWinMMEDriver.h" -#include "JackGraphManager.h" #include "JackEngineControl.h" -#include "JackDriverLoader.h" - -#include -#include -#include -#include - -#include -#include -#include +#include "JackWinMMEDriver.h" -namespace Jack -{ +using Jack::JackWinMMEDriver; -static bool InitHeaders(MidiSlot* slot) +JackWinMMEDriver::JackWinMMEDriver(const char *name, const char *alias, + JackLockedEngine *engine, + JackSynchro *table): + JackMidiDriver(name, alias, engine, table) { - slot->fHeader = (LPMIDIHDR)GlobalAllocPtr(GMEM_MOVEABLE|GMEM_SHARE|GMEM_ZEROINIT, sizeof(MIDIHDR) + kBuffSize); - if (!slot->fHeader) - return false; - - slot->fHeader->lpData = (LPSTR)((LPBYTE)slot->fHeader + sizeof(MIDIHDR)); - slot->fHeader->dwBufferLength = kBuffSize; - slot->fHeader->dwFlags = 0; - slot->fHeader->dwUser = 0; - slot->fHeader->lpNext = 0; - slot->fHeader->dwBytesRecorded = 0; - return true; + fCaptureChannels = 0; + fPlaybackChannels = 0; + input_ports = 0; + output_ports = 0; } -void CALLBACK JackWinMMEDriver::MidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD userData, DWORD dwParam1, DWORD dwParam2) +JackWinMMEDriver::~JackWinMMEDriver() { - jack_ringbuffer_t* ringbuffer = (jack_ringbuffer_t*)userData; - //jack_info("JackWinMMEDriver::MidiInProc 0\n"); - - switch (wMsg) { - case MIM_OPEN: - break; - - case MIM_ERROR: - case MIM_DATA: { - - //jack_info("JackWinMMEDriver::MidiInProc"); - - // One event - unsigned int num_packet = 1; - jack_ringbuffer_write(ringbuffer, (char*)&num_packet, sizeof(unsigned int)); - - // Write event actual data - jack_ringbuffer_write(ringbuffer, (char*)&dwParam1, 3); - break; - } - - case MIM_LONGERROR: - case MIM_LONGDATA: - /* - Nothing for now - */ - break; - } + Stop(); + Close(); } -JackWinMMEDriver::JackWinMMEDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) - : JackMidiDriver(name, alias, engine, table), - fRealCaptureChannels(0), - fRealPlaybackChannels(0), - fMidiSource(NULL), - fMidiDestination(NULL) -{} - -JackWinMMEDriver::~JackWinMMEDriver() -{} - -int JackWinMMEDriver::Open(bool capturing, - bool playing, - int inchannels, - int outchannels, - bool monitor, - const char* capture_driver_name, - const char* playback_driver_name, - jack_nframes_t capture_latency, - jack_nframes_t playback_latency) +int +JackWinMMEDriver::Attach() { + jack_nframes_t buffer_size = fEngineControl->fBufferSize; + jack_port_id_t index; + jack_nframes_t latency = buffer_size; + jack_latency_range_t latency_range; + const char *name; + JackPort *port; + latency_range.max = latency; + latency_range.min = latency; + + // Inputs + for (int i = 0; i < fCaptureChannels; i++) { + JackWinMMEInputPort *input_port = input_ports[i]; + name = input_port->GetName(); + index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, + JACK_DEFAULT_MIDI_TYPE, + CaptureDriverFlags, buffer_size); + if (index == NO_PORT) { + jack_error("JackWinMMEDriver::Attach - cannot register input port " + "with name '%s'.", name); + // X: Do we need to deallocate ports? + return -1; + } + port = fGraphManager->GetPort(index); + port->SetAlias(input_port->GetAlias()); + port->SetLatencyRange(JackCaptureLatency, &latency_range); + fCapturePortList[i] = index; + } - jack_log("JackWinMMEDriver::Open"); - - fRealCaptureChannels = midiInGetNumDevs(); - fRealPlaybackChannels = midiOutGetNumDevs(); - - // Generic JackMidiDriver Open - if (JackMidiDriver::Open(capturing, playing, fRealCaptureChannels, fRealPlaybackChannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0) - return -1; - - fMidiDestination = new MidiSlot[fRealCaptureChannels]; - assert(fMidiDestination); + if (! fEngineControl->fSyncMode) { + latency += buffer_size; + latency_range.max = latency; + latency_range.min = latency; + } - // Real input - int devindex = 0; - for (int i = 0; i < fRealCaptureChannels; i++) { + // Outputs + for (int i = 0; i < fPlaybackChannels; i++) { + JackWinMMEOutputPort *output_port = output_ports[i]; + name = output_port->GetName(); + index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, + JACK_DEFAULT_MIDI_TYPE, + PlaybackDriverFlags, buffer_size); + if (index == NO_PORT) { + jack_error("JackWinMMEDriver::Attach - cannot register output " + "port with name '%s'.", name); + // X: Do we need to deallocate ports? + return -1; + } + port = fGraphManager->GetPort(index); + port->SetAlias(output_port->GetAlias()); + port->SetLatencyRange(JackPlaybackLatency, &latency_range); + fPlaybackPortList[i] = index; + } - HMIDIIN handle; - fMidiDestination[devindex].fIndex = i; - MMRESULT ret = midiInOpen(&handle, fMidiDestination[devindex].fIndex, (DWORD)MidiInProc, (DWORD)fRingBuffer[devindex], CALLBACK_FUNCTION); + return 0; +} - if (ret == MMSYSERR_NOERROR) { - fMidiDestination[devindex].fHandle = handle; - if (!InitHeaders(&fMidiDestination[devindex])) { - jack_error("memory allocation failed"); - midiInClose(handle); - continue; - } - ret = midiInPrepareHeader(handle, fMidiDestination[devindex].fHeader, sizeof(MIDIHDR)); - - if (ret == MMSYSERR_NOERROR) { - fMidiDestination[devindex].fHeader->dwUser = 1; - ret = midiInAddBuffer(handle, fMidiDestination[devindex].fHeader, sizeof(MIDIHDR)); - if (ret == MMSYSERR_NOERROR) { - ret = midiInStart(handle); - if (ret != MMSYSERR_NOERROR) { - jack_error("midiInStart error"); - CloseInput(&fMidiDestination[devindex]); - continue; - } - } else { - jack_error ("midiInAddBuffer error"); - CloseInput(&fMidiDestination[devindex]); - continue; - } - } else { - jack_error("midiInPrepareHeader error"); - midiInClose(handle); - continue; - } - } else { - jack_error ("midiInOpen error"); - continue; +int +JackWinMMEDriver::Close() +{ + int result = JackMidiDriver::Close(); + if (input_ports) { + for (int i = 0; i < fCaptureChannels; i++) { + delete input_ports[i]; } - devindex += 1; + delete[] input_ports; + input_ports = 0; } - fRealCaptureChannels = devindex; - fCaptureChannels = devindex; - - fMidiSource = new MidiSlot[fRealPlaybackChannels]; - assert(fMidiSource); - - // Real output - devindex = 0; - for (int i = 0; i < fRealPlaybackChannels; i++) { - MMRESULT res; - HMIDIOUT handle; - fMidiSource[devindex].fIndex = i; - UINT ret = midiOutOpen(&handle, fMidiSource[devindex].fIndex, 0L, 0L, CALLBACK_NULL); - if (ret == MMSYSERR_NOERROR) { - fMidiSource[devindex].fHandle = handle; - if (!InitHeaders(&fMidiSource[devindex])) { - jack_error("memory allocation failed"); - midiOutClose(handle); - continue; - } - res = midiOutPrepareHeader(handle, fMidiSource[devindex].fHeader, sizeof(MIDIHDR)); - if (res != MMSYSERR_NOERROR) { - jack_error("midiOutPrepareHeader error %d %d %d", i, handle, res); - continue; - } else { - fMidiSource[devindex].fHeader->dwUser = 1; - } - } else { - jack_error("midiOutOpen error"); - continue; + if (output_ports) { + for (int i = 0; i < fPlaybackChannels; i++) { + delete output_ports[i]; } - devindex += 1; + delete[] output_ports; + output_ports = 0; } - fRealPlaybackChannels = devindex; - fPlaybackChannels = devindex; - return 0; + return result; } -void JackWinMMEDriver::CloseInput(MidiSlot* slot) +int +JackWinMMEDriver::Open(bool capturing, bool playing, int in_channels, + int out_channels, bool monitor, + const char* capture_driver_name, + const char* playback_driver_name, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency) { - MMRESULT res; - int retry = 0; - - if (slot->fHandle == 0) - return; - - HMIDIIN handle = (HMIDIIN)slot->fHandle; - slot->fHeader->dwUser = 0; - res = midiInStop(handle); - if (res != MMSYSERR_NOERROR) { - jack_error("midiInStop error"); + const char *client_name = fClientControl.fName; + int input_count = 0; + int num_potential_inputs = midiInGetNumDevs(); + int num_potential_outputs = midiOutGetNumDevs(); + int output_count = 0; + if (num_potential_inputs) { + try { + input_ports = new JackWinMMEInputPort *[num_potential_inputs]; + } catch (std::exception e) { + jack_error("JackWinMMEDriver::Open - while creating input port " + "array: %s", e.what()); + return -1; + } + for (int i = 0; i < num_potential_inputs; i++) { + try { + input_ports[input_count] = + new JackWinMMEInputPort(fAliasName, client_name, + capture_driver_name, i); + } catch (std::exception e) { + jack_error("JackWinMMEDriver::Open - while creating input " + "port: %s", e.what()); + continue; + } + input_count++; + } } - res = midiInReset(handle); - if (res != MMSYSERR_NOERROR) { - jack_error("midiInReset error"); + if (num_potential_outputs) { + try { + output_ports = new JackWinMMEOutputPort *[num_potential_outputs]; + } catch (std::exception e) { + jack_error("JackWinMMEDriver::Open - while creating output port " + "array: %s", e.what()); + goto destroy_input_ports; + } + for (int i = 0; i < num_potential_outputs; i++) { + try { + output_ports[output_count] = + new JackWinMMEOutputPort(fAliasName, client_name, + playback_driver_name, i); + } catch (std::exception e) { + jack_error("JackWinMMEDriver::Open - while creating output " + "port: %s", e.what()); + continue; + } + output_count++; + } } - res = midiInUnprepareHeader(handle, slot->fHeader, sizeof(MIDIHDR)); - if (res != MMSYSERR_NOERROR) { - jack_error("midiInUnprepareHeader error"); + if (! (input_count || output_count)) { + jack_error("JackWinMMEDriver::Open - no WinMME inputs or outputs " + "allocated."); + } else if (! JackMidiDriver::Open(capturing, playing, input_count, + output_count, monitor, + capture_driver_name, + playback_driver_name, capture_latency, + playback_latency)) { + return 0; } - do { - res = midiInClose(handle); - if (res != MMSYSERR_NOERROR) { - jack_error("midiInClose error"); + + destroy_input_ports: + if (input_ports) { + for (int i = 0; i < input_count; i++) { + delete input_ports[i]; } - if (res == MIDIERR_STILLPLAYING) - midiInReset(handle); - Sleep (10); - retry++; - } while ((res == MIDIERR_STILLPLAYING) && (retry < 10)); - - if (slot->fHeader) { - GlobalFreePtr(slot->fHeader); + delete[] input_ports; + input_ports = 0; } + return -1; } -void JackWinMMEDriver::CloseOutput(MidiSlot* slot) +int +JackWinMMEDriver::Read() { - MMRESULT res; - int retry = 0; - - if (slot->fHandle == 0) - return; - - HMIDIOUT handle = (HMIDIOUT)slot->fHandle; - res = midiOutReset(handle); - if (res != MMSYSERR_NOERROR) - jack_error("midiOutReset error"); - midiOutUnprepareHeader(handle, slot->fHeader, sizeof(MIDIHDR)); - do { - res = midiOutClose(handle); - if (res != MMSYSERR_NOERROR) - jack_error("midiOutClose error"); - Sleep(10); - retry++; - } while ((res == MIDIERR_STILLPLAYING) && (retry < 10)); - - if (slot->fHeader) { - GlobalFreePtr(slot->fHeader); + jack_nframes_t buffer_size = fEngineControl->fBufferSize; + for (int i = 0; i < fCaptureChannels; i++) { + input_ports[i]->ProcessJack(GetInputBuffer(i), buffer_size); } + return 0; } -int JackWinMMEDriver::Close() +int +JackWinMMEDriver::Start() { - jack_log("JackWinMMEDriver::Close"); + jack_info("JackWinMMEDriver::Start - Starting driver."); + + JackMidiDriver::Start(); + + int input_count = 0; + int output_count = 0; - // Generic midi driver close - int res = JackMidiDriver::Close(); + jack_info("JackWinMMEDriver::Start - Enabling input ports."); - // Close input - if (fMidiDestination) { - for (int i = 0; i < fRealCaptureChannels; i++) { - CloseInput(&fMidiDestination[i]); + for (; input_count < fCaptureChannels; input_count++) { + if (input_ports[input_count]->Start() < 0) { + jack_error("JackWinMMEDriver::Start - Failed to enable input " + "port."); + goto stop_input_ports; } - delete[] fMidiDestination; } - // Close output - if (fMidiSource) { - for (int i = 0; i < fRealPlaybackChannels; i++) { - CloseOutput(&fMidiSource[i]); + jack_info("JackWinMMEDriver::Start - Enabling output ports."); + + for (; output_count < fPlaybackChannels; output_count++) { + if (output_ports[output_count]->Start() < 0) { + jack_error("JackWinMMEDriver::Start - Failed to enable output " + "port."); + goto stop_output_ports; } - delete[] fMidiSource; } - return res; -} + jack_info("JackWinMMEDriver::Start - Driver started."); -int JackWinMMEDriver::Attach() -{ - JackPort* port; - jack_port_id_t port_index; - char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - MMRESULT res; - int i; - - jack_log("JackMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); - - for (i = 0; i < fCaptureChannels; i++) { - MIDIINCAPS caps; - res = midiInGetDevCaps(fMidiDestination[i].fIndex, &caps, sizeof(caps)); - if (res == MMSYSERR_NOERROR) { - snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, caps.szPname, i + 1); - } else { - snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); - } - snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); - - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { - jack_error("driver: cannot register port for %s", name); - return -1; + return 0; + + stop_output_ports: + for (int i = 0; i < output_count; i++) { + if (output_ports[i]->Stop() < 0) { + jack_error("JackWinMMEDriver::Start - Failed to disable output " + "port."); } - port = fGraphManager->GetPort(port_index); - port->SetAlias(alias); - fCapturePortList[i] = port_index; - jack_log("JackMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index); } - - for (i = 0; i < fPlaybackChannels; i++) { - MIDIOUTCAPS caps; - res = midiOutGetDevCaps(fMidiSource[i].fIndex, &caps, sizeof(caps)); - if (res == MMSYSERR_NOERROR) { - snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, caps.szPname, i + 1); - } else { - snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fPlaybackDriverName, i + 1); - } - snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); - - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { - jack_error("driver: cannot register port for %s", name); - return -1; + stop_input_ports: + for (int i = 0; i < input_count; i++) { + if (input_ports[i]->Stop() < 0) { + jack_error("JackWinMMEDriver::Start - Failed to disable input " + "port."); } - port = fGraphManager->GetPort(port_index); - port->SetAlias(alias); - fPlaybackPortList[i] = port_index; - jack_log("JackMidiDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); } - return 0; + return -1; } -int JackWinMMEDriver::Read() +int +JackWinMMEDriver::Stop() { - size_t size; + int result = 0; - for (int chan = 0; chan < fCaptureChannels; chan++) { + jack_info("JackWinMMEDriver::Stop - disabling input ports."); - if (fGraphManager->GetConnectionsNum(fCapturePortList[chan]) > 0) { - - JackMidiBuffer* midi_buffer = GetInputBuffer(chan); - - if (jack_ringbuffer_read_space (fRingBuffer[chan]) == 0) { - // Reset buffer - midi_buffer->Reset(midi_buffer->nframes); - } else { - - while ((size = jack_ringbuffer_read_space (fRingBuffer[chan])) > 0) { + for (int i = 0; i < fCaptureChannels; i++) { + if (input_ports[i]->Stop() < 0) { + jack_error("JackWinMMEDriver::Stop - Failed to disable input " + "port."); + result = -1; + } + } - //jack_info("jack_ringbuffer_read_space %d", size); - int ev_count = 0; - jack_ringbuffer_read(fRingBuffer[chan], (char*)&ev_count, sizeof(int)); + jack_info("JackWinMMEDriver::Stop - disabling output ports."); - if (ev_count > 0) { - for (int j = 0; j < ev_count; j++) { - unsigned int event_len = 3; - // Read event actual data - jack_midi_data_t* dest = midi_buffer->ReserveEvent(0, event_len); - jack_ringbuffer_read(fRingBuffer[chan], (char*)dest, event_len); - } - } - } - } - } else { - //jack_info("Consume ring buffer"); - jack_ringbuffer_read_advance(fRingBuffer[chan], jack_ringbuffer_read_space(fRingBuffer[chan])); + for (int i = 0; i < fPlaybackChannels; i++) { + if (output_ports[i]->Stop() < 0) { + jack_error("JackWinMMEDriver::Stop - Failed to disable output " + "port."); + result = -1; } } - return 0; + + return result; } -int JackWinMMEDriver::Write() +int +JackWinMMEDriver::Write() { - for (int chan = 0; chan < fPlaybackChannels; chan++) { - - if (fGraphManager->GetConnectionsNum(fPlaybackPortList[chan]) > 0) { - - JackMidiBuffer* midi_buffer = GetOutputBuffer(chan); - - // TODO : use timestamp - - for (unsigned int j = 0; j < midi_buffer->event_count; j++) { - JackMidiEvent* ev = &midi_buffer->events[j]; - if (ev->size <= 3) { - jack_midi_data_t *d = ev->GetData(midi_buffer); - DWORD winev = 0; - if (ev->size > 0) winev |= d[0]; - if (ev->size > 1) winev |= (d[1] << 8); - if (ev->size > 2) winev |= (d[2] << 16); - MMRESULT res = midiOutShortMsg((HMIDIOUT)fMidiSource[chan].fHandle, winev); - if (res != MMSYSERR_NOERROR) - jack_error ("midiOutShortMsg error res %d", res); - } else { - - } - } - } + jack_nframes_t buffer_size = fEngineControl->fBufferSize; + for (int i = 0; i < fPlaybackChannels; i++) { + output_ports[i]->ProcessJack(GetOutputBuffer(i), buffer_size); } - return 0; } -} // end of namespace - #ifdef __cplusplus extern "C" { diff --git a/windows/winmme/JackWinMMEDriver.h b/windows/winmme/JackWinMMEDriver.h index 6c28a0ef..52ae5f2b 100644 --- a/windows/winmme/JackWinMMEDriver.h +++ b/windows/winmme/JackWinMMEDriver.h @@ -1,5 +1,6 @@ /* Copyright (C) 2009 Grame +Copyright (C) 2011 Devin Anderson 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 @@ -21,67 +22,51 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #define __JackWinMMEDriver__ #include "JackMidiDriver.h" -#include "JackTime.h" +#include "JackWinMMEInputPort.h" +#include "JackWinMMEOutputPort.h" -namespace Jack -{ +namespace Jack { -/*! -\brief The WinMME driver. -*/ - -#define kBuffSize 512 - -struct MidiSlot { - - LPVOID fHandle; // MMSystem handler - short fIndex; // MMSystem dev index - LPMIDIHDR fHeader; // for long msg output - - MidiSlot():fHandle(0),fIndex(0) - {} + class JackWinMMEDriver : public JackMidiDriver { -}; + private: -class JackWinMMEDriver : public JackMidiDriver -{ + JackWinMMEInputPort **input_ports; + JackWinMMEOutputPort **output_ports; - private: + public: - int fRealCaptureChannels; - int fRealPlaybackChannels; + JackWinMMEDriver(const char* name, const char* alias, + JackLockedEngine* engine, JackSynchro* table); - MidiSlot* fMidiSource; - MidiSlot* fMidiDestination; + ~JackWinMMEDriver(); - void CloseInput(MidiSlot* slot); - void CloseOutput(MidiSlot* slot); + int + Attach(); - static void CALLBACK MidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2); + int + Close(); - public: + int + Open(bool capturing, bool playing, int num_inputs, int num_outputs, + bool monitor, const char* capture_driver_name, + const char* playback_driver_name, jack_nframes_t capture_latency, + jack_nframes_t playback_latency); - JackWinMMEDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); - virtual ~JackWinMMEDriver(); + int + Read(); - int Open(bool capturing, - bool playing, - int chan_in, - int chan_out, - bool monitor, - const char* capture_driver_name, - const char* playback_driver_name, - jack_nframes_t capture_latency, - jack_nframes_t playback_latency); - int Close(); + int + Start(); - int Attach(); + int + Stop(); - int Read(); - int Write(); + int + Write(); -}; + }; -} // end of namespace +} #endif diff --git a/windows/winmme/JackWinMMEInputPort.cpp b/windows/winmme/JackWinMMEInputPort.cpp new file mode 100644 index 00000000..f5c74023 --- /dev/null +++ b/windows/winmme/JackWinMMEInputPort.cpp @@ -0,0 +1,287 @@ +/* +Copyright (C) 2011 Devin Anderson + +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. + +*/ + +#include +#include +#include + +#include "JackError.h" +#include "JackMidiUtil.h" +#include "JackWinMMEInputPort.h" + +using Jack::JackWinMMEInputPort; + +/////////////////////////////////////////////////////////////////////////////// +// Static callbacks +/////////////////////////////////////////////////////////////////////////////// + +void CALLBACK +JackWinMMEInputPort::HandleMidiInputEvent(HMIDIIN handle, UINT message, + DWORD port, DWORD param1, + DWORD param2) +{ + ((JackWinMMEInputPort *) port)->ProcessWinMME(message, param1, param2); +} + +/////////////////////////////////////////////////////////////////////////////// +// Class +/////////////////////////////////////////////////////////////////////////////// + +JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, + const char *client_name, + const char *driver_name, UINT index, + size_t max_bytes, size_t max_messages) +{ + thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); + std::auto_ptr thread_queue_ptr(thread_queue); + write_queue = new JackMidiBufferWriteQueue(); + std::auto_ptr write_queue_ptr(write_queue); + sysex_buffer = new jack_midi_data_t[max_bytes]; + char error_message[MAXERRORLENGTH]; + MMRESULT result = midiInOpen(&handle, index, HandleMidiInputEvent, this, + CALLBACK_FUNCTION); + if (result != MMSYSERR_NOERROR) { + GetErrorString(result, error_message); + goto delete_sysex_buffer; + } + sysex_header.dwBufferLength = max_bytes; + sysex_header.dwBytesRecorded = 0; + sysex_header.dwFlags = 0; + sysex_header.dwUser = 0; + sysex_header.lpData = (((LPBYTE) sysex_header) + sizeof(MIDIHDR)); + sysex_header.lpNext = 0; + result = midiInPrepareHeader(handle, &sysex_header, sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) { + GetErrorString(result, error_message); + goto close_handle; + } + result = midiInAddBuffer(handle, &sysex_header, sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) { + GetErrorString(result, error_message); + goto unprepare_header; + } + + jack_event = 0; + started = false; + write_queue_ptr.release(); + thread_queue_ptr.release(); + return; + + unprepare_header: + result = midiInUnprepareHeader(handle, sysex_header, sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) { + WriteError("JackWinMMEInputPort [constructor]", + "midiInUnprepareHeader", result); + } + close_handle: + result = midiInClose(handle); + if (result != MMSYSERR_NOERROR) { + WriteError("JackWinMMEInputPort [constructor]", "midiInClose", result); + } + delete_sysex_buffer: + delete[] sysex_buffer; + throw std::runtime_error(error_message); +} + +JackWinMMEInputPort::~JackWinMMEInputPort() +{ + Stop(); + MMRESULT result = midiInReset(handle); + if (result != MMSYSERR_NOERROR) { + WriteError("JackWinMMEInputPort [destructor]", "midiInReset", result); + } + result = midiInUnprepareHeader(handle, sysex_header, sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) { + WriteError("JackWinMMEInputPort [destructor]", "midiInUnprepareHeader", + result); + } + result = midiInClose(handle); + if (result != MMSYSERR_NOERROR) { + WriteError("JackWinMMEInputPort [destructor]", "midiInClose", result); + } + delete[] sysex_buffer; + delete thread_queue; + delete write_queue; +} + +void +JackWinMMEInputPort::EnqueueMessage(jack_nframes_t time, size_t length, + jack_midi_data_t *data) +{ + switch (thread_queue->EnqueueEvent(time, length, data)) { + case JackMidiWriteQueue::BUFFER_FULL: + jack_error("JackWinMMEInputPort::EnqueueMessage - The thread queue " + "cannot currently accept a %d-byte event. Dropping event.", + size); + break; + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + jack_error("JackWinMMEInputPort::EnqueueMessage - The thread queue " + "buffer is too small to enqueue a %d-byte event. Dropping " + "event.", size); + break; + default: + ; + } +} + +const char * +JackWinMMEInputPort::GetAlias() +{ + return alias; +} + +void +JackWinMMEInputPort::GetErrorString(MMRESULT error, LPTSTR text) +{ + MMRESULT result = midiInGetErrorText(error, text, MAXERRORLENGTH); + if (result != MMSYSERR_NOERROR) { + snprintf(text, MAXERRORLENGTH, "Unknown error code '%d'", error); + } +} + +const char * +JackWinMMEInputPort::GetName() +{ + return name; +} + +void +JackWinMMEInputPort::ProcessJack() +{ + write_queue->ResetMidiBuffer(port_buffer, frames); + if (! jack_event) { + jack_event = thread_queue->DequeueEvent(); + } + for (; jack_event; jack_event = thread_queue->DequeueEvent()) { + switch (write_queue->EnqueueEvent(event)) { + case BUFFER_TOO_SMALL: + jack_error("JackWinMMEMidiInputPort::Process - The buffer write " + "queue couldn't enqueue a %d-byte event. Dropping " + "event.", event->size); + // Fallthrough on purpose + case OK: + continue; + } + break; + } +} + +void +JackWinMMEInputPort::ProcessWinMME(UINT message, DWORD param1, DWORD param2) +{ + jack_nframes_t current_frame = GetCurrentFrame(); + switch (message) { + case MIM_CLOSE: + jack_info("JackWinMMEInputPort::ProcessWinMME - MIDI device closed."); + break; + case MIM_MOREDATA: + jack_info("JackWinMMEInputPort::ProcessWinMME - The MIDI input device " + "driver thinks that JACK is not processing messages fast " + "enough."); + // Fallthrough on purpose. + case MIM_DATA: + jack_midi_data_t message_buffer[3]; + jack_midi_data_t status = param1 & 0xff; + int length = GetMessageLength(status); + switch (length) { + case 3: + message_buffer[2] = param1 & 0xff0000; + // Fallthrough on purpose. + case 2: + message_buffer[1] = param1 & 0xff00; + // Fallthrough on purpose. + case 1: + message_buffer[0] = status; + break; + case 0: + jack_error("JackWinMMEInputPort::ProcessWinMME - **BUG** MIDI " + "input driver sent an MIM_DATA message with a sysex " + "status byte."); + return; + case -1: + jack_error("JackWinMMEInputPort::ProcessWinMME - **BUG** MIDI " + "input driver sent an MIM_DATA message with an invalid " + "status byte."); + return; + } + EnqueueMessage(current_frame, (size_t) length, message_buffer); + break; + case MIM_LONGDATA: + LPMIDIHDR header = (LPMIDIHDR) dwParam1; + jack_midi_data_t *data = (jack_midi_data_t *) header->lpData; + size_t length = header->dwBytesRecorded; + if ((data[0] != 0xf0) || (data[length - 1] != 0xf7)) { + jack_error("JackWinMMEInputPort::ProcessWinMME - Discarding " + "%d-byte sysex chunk.", length); + } else { + EnqueueMessage(current_frame, length, data); + } + // Is this realtime-safe? This function isn't run in the JACK thread, + // but we still want it to perform as quickly as possible. Even if + // this isn't realtime safe, it may not be avoidable. + MMRESULT result = midiInAddBuffer(handle, &sysex_header, + sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) { + WriteError("JackWinMMEInputPort::ProcessWinMME", "midiInAddBuffer", + result); + } + break; + case MIM_LONGERROR: + jack_error("JackWinMMEInputPort::ProcessWinMME - Invalid or " + "incomplete sysex message received."); + break; + case MIM_OPEN: + jack_info("JackWinMMEInputPort::ProcessWinMME - MIDI device opened."); + } +} + +bool +JackWinMMEInputPort::Start() +{ + if (! started) { + MMRESULT result = midiInStart(handle); + started = result == MMSYSERR_NOERROR; + if (! started) { + WriteError("JackWinMMEInputPort::Start", "midiInStart", result); + } + } + return started; +} + +bool +JackWinMMEInputPort::Stop() +{ + if (started) { + MMRESULT result = midiInStop(handle); + started = result != MMSYSERR_NOERROR; + if (started) { + WriteError("JackWinMMEInputPort::Stop", "midiInStop", result); + } + } + return ! started; +} + +void +JackWinMMEInputPort::WriteError(const char *jack_func, const char *mm_func, + MMRESULT result) +{ + const char error_message[MAXERRORLENGTH]; + GetErrorString(result, error_message); + jack_error("%s - %s: %s", jack_func, mm_func, error_message); +} diff --git a/windows/winmme/JackWinMMEInputPort.h b/windows/winmme/JackWinMMEInputPort.h new file mode 100644 index 00000000..5ce042b9 --- /dev/null +++ b/windows/winmme/JackWinMMEInputPort.h @@ -0,0 +1,89 @@ +/* +Copyright (C) 2011 Devin Anderson + +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 __JackWinMMEInputPort__ +#define __JackWinMMEInputPort__ + +#include + +#include "JackMidiAsyncQueue.h" +#include "JackMidiBufferWriteQueue.h" + +namespace Jack { + + class JackWinMMEInputPort { + + private: + + static void CALLBACK + HandleMidiInputEvent(HMIDIIN handle, UINT message, DWORD port, + DWORD param1, DWORD param2); + + void + EnqueueMessage(jack_nframes_t time, size_t length, + jack_midi_data_t *data); + + void + GetErrorString(MMRESULT error, LPTSTR text); + + void + ProcessWinMME(UINT message, DWORD param1, DWORD param2); + + void + WriteError(const char *jack_func, const char *mm_func, + MMRESULT result); + + char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + HMIDIIN handle; + jack_midi_event_t *jack_event; + char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + bool started; + jack_midi_data_t *sysex_buffer; + MIDIHDR sysex_header + JackMidiAsyncQueue *thread_queue; + JackMidiBufferWriteQueue *write_queue; + + public: + + JackWinMMEInputPort(const char *alias_name, const char *client_name, + const char *driver_name, UINT index, + size_t max_bytes=4096, size_t max_messages=1024); + + ~JackWinMMEInputPort(); + + const char * + GetAlias(); + + const char * + GetName(); + + void + ProcessJack(); + + bool + Start(); + + bool + Stop(); + + }; + +} + +#endif diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp new file mode 100644 index 00000000..8f25feaf --- /dev/null +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -0,0 +1,352 @@ +/* +Copyright (C) 2011 Devin Anderson + +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. + +*/ + +#include +#include + +#include "JackMidiUtil.h" +#include "JackTime.h" +#include "JackWinMMEOutputPort.h" + +using Jack::JackWinMMEOutputPort; + +/////////////////////////////////////////////////////////////////////////////// +// Static callbacks +/////////////////////////////////////////////////////////////////////////////// + +void CALLBACK +JackWinMMEOutputPort::HandleMessageEvent(HMIDIOUT handle, UINT message, + DWORD_PTR port, DWORD_PTR param1, + DWORD_PTR param2) +{ + ((JackWinMMEOutputPort *) port)->HandleMessage(message, param1, param2); +} + +/////////////////////////////////////////////////////////////////////////////// +// Class +/////////////////////////////////////////////////////////////////////////////// + +JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, + const char *client_name, + const char *driver_name, UINT index, + size_t max_bytes, + size_t max_messages) +{ + read_queue = new JackMidiBufferReadQueue(); + std::auto_ptr read_queue_ptr(read_queue); + thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); + std::auto_ptr thread_queue_ptr(thread_queue); + char error_message[MAXERRORLENGTH]; + MMRESULT result = midiOutOpen(&handle, index, HandleMessageEvent, this, + CALLBACK_FUNCTION); + if (result != MMSYSERR_NOERROR) { + GetErrorString(result, error_message); + goto raise_exception; + } + thread_queue_semaphore = CreateSemaphore(NULL, 0, max_messages, NULL); + if (thread_queue_semaphore == NULL) { + GetOSErrorString(error_message); + goto close_handle; + } + sysex_semaphore = CreateSemaphore(NULL, 0, 1, NULL); + if (sysex_semaphore == NULL) { + GetOSErrorString(error_message); + goto destroy_thread_queue_semaphore; + } + MIDIINCAPS capabilities; + char *name; + result = midiOutGetDevCaps(index, &capabilities, sizeof(capabilities)); + if (result != MMSYSERR_NOERROR) { + WriteMMError("JackWinMMEOutputPort [constructor]", "midiOutGetDevCaps", + result); + name = driver_name; + } else { + name = capabilities.szPname; + } + snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", alias_name, driver_name, + index + 1); + snprintf(name, sizeof(name) - 1, "%s:playback_%d", client_name, index + 1); + write_queue_ptr.release(); + thread_queue_ptr.release(); + return; + + destroy_thread_queue_semaphore: + if (! CloseHandle(thread_queue_semaphore)) { + WriteOSError("JackWinMMEOutputPort [constructor]", "CloseHandle"); + } + close_handle: + result = midiOutClose(handle); + if (result != MMSYSERR_NOERROR) { + WriteMMError("JackWinMMEOutputPort [constructor]", "midiOutClose", + result); + } + raise_exception: + throw std::runtime_error(error_message); +} + +JackWinMMEOutputPort::~JackWinMMEOutputPort() +{ + Stop(); + MMRESULT result = midiOutReset(handle); + if (result != MMSYSERR_NOERROR) { + WriteMMError("JackWinMMEOutputPort [destructor]", "midiOutReset", + result); + } + result = midiOutClose(handle); + if (result != MMSYSERR_NOERROR) { + WriteMMError("JackWinMMEOutputPort [destructor]", "midiOutClose", + result); + } + if (! CloseHandle(sysex_semaphore)) { + WriteOSError("JackWinMMEOutputPort [destructor]", "CloseHandle"); + } + if (! CloseHandle(thread_queue_semaphore)) { + WriteOSError("JackWinMMEOutputPort [destructor]", "CloseHandle"); + } + delete read_queue; + delete thread_queue; +} + +bool +JackWinMMEOutputPort::Execute() +{ + for (;;) { + if (! Wait(thread_queue_semaphore)) { + break; + } + jack_midi_event_t *event = thread_queue->DequeueEvent(); + if (! event) { + break; + } + jack_time_t frame_time = GetTimeFromFrames(event->time); + for (jack_time_t current_time = GetMicroSeconds(); + frame_time > current_time; current_time = GetMicroSeconds()) { + jack_time_t sleep_time = frame_time - current_time; + + // Windows has a millisecond sleep resolution for its Sleep calls. + // This is unfortunate, as MIDI timing often requires a higher + // resolution. For now, we attempt to compensate by letting an + // event be sent if we're less than 500 microseconds from sending + // the event. We assume that it's better to let an event go out + // 499 microseconds early than let an event go out 501 microseconds + // late. Of course, that's assuming optimal sleep times, which is + // a whole different Windows issue ... + if (sleep_time < 500) { + break; + } + + if (sleep_time < 1000) { + sleep_time = 1000; + } + JackSleep(sleep_time); + } + jack_midi_data_t *data = event->buffer; + DWORD message = 0; + MMRESULT result; + size_t size = event->size; + switch (size) { + case 3: + message |= (((DWORD) data[2]) << 16); + // Fallthrough on purpose. + case 2: + message |= (((DWORD) data[1]) << 8); + // Fallthrough on purpose. + case 1: + message |= (DWORD) data[0]; + result = midiOutShortMsg(handle, message); + if (result != MMSYSERR_NOERROR) { + WriteMMError("JackWinMMEOutputPort::Execute", + "midiOutShortMsg", result); + } + continue; + } + MIDIHDR header; + header.dwFlags = 0; + header.dwLength = size; + header.lpData = data; + result = midiOutPrepareHeader(handle, &header, sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) { + WriteMMError("JackWinMMEOutputPort::Execute", + "midiOutPrepareHeader", result); + continue; + } + result = midiOutLongMsg(handle, &header, sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) { + WriteMMError("JackWinMMEOutputPort::Execute", "midiOutLongMsg", + result); + continue; + } + + // System exclusive messages may be sent synchronously or + // asynchronously. The choice is up to the WinMME driver. So, we wait + // until the message is sent, regardless of the driver's choice. + if (! Wait(sysex_semaphore)) { + break; + } + + result = midiOutUnprepareHeader(handle, &header, sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) { + WriteMMError("JackWinMMEOutputPort::Execute", + "midiOutUnprepareHeader", result); + break; + } + } + stop_execution: + return false; +} + +void +JackWinMMEOutputPort::GetMMErrorString(MMRESULT error, LPTSTR text) +{ + MMRESULT result = midiOutGetErrorText(error, text, MAXERRORLENGTH); + if (result != MMSYSERR_NOERROR) { + snprintf(text, MAXERRORLENGTH, "Unknown MM error code '%d'", error); + } +} + +void +JackWinMMEOutputPort::GetOSErrorString(LPTSTR text) +{ + DWORD error = GetLastError(); + if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &text, + MAXERRORLENGTH, NULL)) { + snprintf(text, MAXERRORLENGTH, "Unknown OS error code '%d'", error); + } +} + +void +JackWinMMEOutputPort::HandleMessage(UINT message, DWORD_PTR param1, + DWORD_PTR param2) +{ + switch (message) { + case MOM_CLOSE: + jack_info("JackWinMMEOutputPort::HandleMessage - MIDI device closed."); + break; + case MOM_DONE: + if (! ReleaseSemaphore(sysex_semaphore, 1, NULL)) { + WriteOSError("JackWinMMEOutputPort::HandleMessage", + "ReleaseSemaphore"); + } + break; + case MOM_OPEN: + jack_info("JackWinMMEOutputPort::HandleMessage - MIDI device opened."); + } +} + +bool +JackWinMMEOutputPort::Init() +{ + set_threaded_log_function(); + // XX: Can more be done? Ideally, this thread should have the JACK server + // thread priority + 1. + if (thread->AcquireSelfRealTime()) { + jack_error("JackWinMMEOutputPort::Init - could not acquire realtime " + "scheduling. Continuing anyway."); + } + return true; +} + +void +JackWinMMEOutputPort::ProcessJack(JackMidiBuffer *port_buffer, + jack_nframes_t frames) +{ + read_queue->ResetMidiBuffer(port_buffer); + for (jack_midi_event_t *event = read_queue->DequeueEvent(); event; + event = read_queue->DequeueEvent()) { + switch (thread_queue->EnqueueEvent(event, frames)) { + case JackMidiWriteQueue::BUFFER_FULL: + jack_error("JackWinMMEOutputPort::ProcessJack - The thread queue " + "buffer is full. Dropping event."); + break; + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + jack_error("JackWinMMEOutputPort::ProcessJack - The thread queue " + "couldn't enqueue a %d-byte event. Dropping event.", + event->size); + break; + default: + if (! ReleaseSemaphore(thread_queue_semaphore, 1, NULL)) { + WriteOSError("JackWinMMEOutputPort::ProcessJack", + "ReleaseSemaphore"); + } + } + } +} + +bool +JackWinMMEOutputPort::Start() +{ + bool result = thread->GetStatus() != JackThread::kIdle; + if (! result) { + result = ! thread->StartSync(); + if (! result) { + jack_error("JackWinMMEOutputPort::Start - failed to start MIDI " + "processing thread."); + } + } + return result; +} + +bool +JackWinMMEOutputPort::Stop() +{ + bool result = thread->GetStatus() == JackThread::kIdle; + if (! result) { + result = ! thread->Kill(); + if (! result) { + jack_error("JackWinMMEOutputPort::Stop - failed to stop MIDI " + "processing thread."); + } + } + return result; +} + +bool +JackWinMMEOutputPort::Wait(Handle semaphore) +{ + DWORD result = WaitForSingleObject(semaphore, INFINITE); + switch (result) { + case WAIT_FAILED: + WriteOSError("JackWinMMEOutputPort::Wait", "WaitForSingleObject"); + break; + case WAIT_OBJECT_0: + return true; + default: + jack_error("JackWinMMEOutputPort::Wait - unexpected result from " + "'WaitForSingleObject'."); + } + return false; +} + +void +JackWinMMEOutputPort::WriteMMError(const char *jack_func, const char *mm_func, + MMRESULT result) +{ + const char error_message[MAXERRORLENGTH]; + GetMMErrorString(result, error_message); + jack_error("%s - %s: %s", jack_func, mm_func, error_message); +} + +void +JackWinMMEOutputPort::WriteOSError(const char *jack_func, const char *os_func) +{ + const char error_message[MAXERRORLENGTH]; + GetOSErrorString(result, error_message); + jack_error("%s - %s: %s", jack_func, os_func, error_message); +} diff --git a/windows/winmme/JackWinMMEOutputPort.h b/windows/winmme/JackWinMMEOutputPort.h new file mode 100644 index 00000000..8da32066 --- /dev/null +++ b/windows/winmme/JackWinMMEOutputPort.h @@ -0,0 +1,93 @@ +/* +Copyright (C) 2011 Devin Anderson + +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 __JackWinMMEOutputPort__ +#define __JackWinMMEOutputPort__ + +#include +#include + +#include "JackMidiAsyncQueue.h" +#include "JackMidiBufferReadQueue.h" + +namespace Jack { + + class JackWinMMEOutputPort { + + private: + + static void CALLBACK + HandleMessageEvent(HMIDIOUT handle, UINT message, DWORD_PTR port, + DWORD_PTR param1, DWORD_PTR param2); + + void + GetMMErrorString(MMRESULT error, LPTSTR text); + + void + GetOSErrorString(LPTSTR text); + + void + HandleMessage(UINT message, DWORD_PTR param1, DWORD_PTR param2); + + bool + Wait(Handle semaphore); + + void + WriteMMError(const char *jack_func, const char *mm_func, + MMRESULT result); + + void + WriteOSError(const char *jack_func, const char *os_func); + + char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + HMIDIOUT handle; + char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + JackMidiBufferReadQueue *read_queue; + HANDLE sysex_semaphore; + JackMidiAsyncQueue *thread_queue; + HANDLE thread_queue_semaphore; + + public: + + JackWinMMEOutputPort(const char *alias_name, const char *client_name, + const char *driver_name, UINT index, + size_t max_bytes=4096, size_t max_messages=1024); + + ~JackWinMMEOutputPort(); + + bool + Execute(); + + bool + Init(); + + void + ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames); + + bool + Start(); + + bool + Stop(); + + }; + +} + +#endif From 8c7cabfe3dd13df72a2ed6fc1f39f606d3c1b64d Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Tue, 29 Mar 2011 09:41:28 -0700 Subject: [PATCH 095/472] Add missing thread functionality to JackWinMMEOutputPort. --- windows/winmme/JackWinMMEOutputPort.cpp | 3 +++ windows/winmme/JackWinMMEOutputPort.h | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index 8f25feaf..7c6789f8 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -52,6 +52,8 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, std::auto_ptr read_queue_ptr(read_queue); thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); std::auto_ptr thread_queue_ptr(thread_queue); + thread = new JackThread(this); + std::auto_ptr thread_ptr(thread); char error_message[MAXERRORLENGTH]; MMRESULT result = midiOutOpen(&handle, index, HandleMessageEvent, this, CALLBACK_FUNCTION); @@ -82,6 +84,7 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", alias_name, driver_name, index + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", client_name, index + 1); + thread_ptr.release(); write_queue_ptr.release(); thread_queue_ptr.release(); return; diff --git a/windows/winmme/JackWinMMEOutputPort.h b/windows/winmme/JackWinMMEOutputPort.h index 8da32066..ef1bd65d 100644 --- a/windows/winmme/JackWinMMEOutputPort.h +++ b/windows/winmme/JackWinMMEOutputPort.h @@ -25,10 +25,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackMidiAsyncQueue.h" #include "JackMidiBufferReadQueue.h" +#include "JackThread.h" namespace Jack { - class JackWinMMEOutputPort { + class JackWinMMEOutputPort: public JackRunnableInterface { private: @@ -60,6 +61,7 @@ namespace Jack { char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; JackMidiBufferReadQueue *read_queue; HANDLE sysex_semaphore; + JackThread *thread; JackMidiAsyncQueue *thread_queue; HANDLE thread_queue_semaphore; From 194ce1cd57d30a92669159fd5bf59fcd9a900cd0 Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Tue, 29 Mar 2011 11:15:39 -0700 Subject: [PATCH 096/472] Make sure threaded log functions are set. Add MOM_POSITIONCB info. --- windows/winmme/JackWinMMEInputPort.cpp | 3 ++- windows/winmme/JackWinMMEOutputPort.cpp | 12 +++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/windows/winmme/JackWinMMEInputPort.cpp b/windows/winmme/JackWinMMEInputPort.cpp index f5c74023..c9b9cbb1 100644 --- a/windows/winmme/JackWinMMEInputPort.cpp +++ b/windows/winmme/JackWinMMEInputPort.cpp @@ -55,7 +55,7 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, sysex_buffer = new jack_midi_data_t[max_bytes]; char error_message[MAXERRORLENGTH]; MMRESULT result = midiInOpen(&handle, index, HandleMidiInputEvent, this, - CALLBACK_FUNCTION); + CALLBACK_FUNCTION | MIDI_IO_STATUS); if (result != MMSYSERR_NOERROR) { GetErrorString(result, error_message); goto delete_sysex_buffer; @@ -185,6 +185,7 @@ JackWinMMEInputPort::ProcessJack() void JackWinMMEInputPort::ProcessWinMME(UINT message, DWORD param1, DWORD param2) { + set_threaded_log_function(); jack_nframes_t current_frame = GetCurrentFrame(); switch (message) { case MIM_CLOSE: diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index 7c6789f8..3e615742 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -180,8 +180,11 @@ JackWinMMEOutputPort::Execute() continue; } MIDIHDR header; + header.dwBufferLength = size; + header.dwBytesRecorded = size; header.dwFlags = 0; - header.dwLength = size; + header.dwOffset = 0; + header.dwUser = 0; header.lpData = data; result = midiOutPrepareHeader(handle, &header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { @@ -238,6 +241,7 @@ void JackWinMMEOutputPort::HandleMessage(UINT message, DWORD_PTR param1, DWORD_PTR param2) { + set_threaded_log_function(); switch (message) { case MOM_CLOSE: jack_info("JackWinMMEOutputPort::HandleMessage - MIDI device closed."); @@ -250,6 +254,12 @@ JackWinMMEOutputPort::HandleMessage(UINT message, DWORD_PTR param1, break; case MOM_OPEN: jack_info("JackWinMMEOutputPort::HandleMessage - MIDI device opened."); + break; + case MOM_POSITIONCB: + LPMIDIHDR header = (LPMIDIHDR) param2; + jack_info("JackWinMMEOutputPort::HandleMessage - %d bytes out of %d " + "bytes of the current sysex message have been sent.", + header->dwOffset, header->dwBytesRecorded); } } From 8e4ee25c7f9e6a8a18b25fbe6e9c5c2f43c40a93 Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Tue, 29 Mar 2011 11:27:21 -0700 Subject: [PATCH 097/472] Make thread termination more elegant. --- windows/winmme/JackWinMMEOutputPort.cpp | 52 +++++++++++++++++-------- windows/winmme/JackWinMMEOutputPort.h | 3 ++ 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index 3e615742..aa87de0f 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -247,10 +247,7 @@ JackWinMMEOutputPort::HandleMessage(UINT message, DWORD_PTR param1, jack_info("JackWinMMEOutputPort::HandleMessage - MIDI device closed."); break; case MOM_DONE: - if (! ReleaseSemaphore(sysex_semaphore, 1, NULL)) { - WriteOSError("JackWinMMEOutputPort::HandleMessage", - "ReleaseSemaphore"); - } + Signal(sysex_semaphore); break; case MOM_OPEN: jack_info("JackWinMMEOutputPort::HandleMessage - MIDI device opened."); @@ -294,14 +291,21 @@ JackWinMMEOutputPort::ProcessJack(JackMidiBuffer *port_buffer, event->size); break; default: - if (! ReleaseSemaphore(thread_queue_semaphore, 1, NULL)) { - WriteOSError("JackWinMMEOutputPort::ProcessJack", - "ReleaseSemaphore"); - } + Signal(thread_queue_semaphore); } } } +bool +JackWinMMEOutputPort::Signal(Handle semaphore) +{ + bool result = (bool) ReleaseSemaphore(semaphore, 1, NULL); + if (! result) { + WriteOSError("JackWinMMEOutputPort::Signal", "ReleaseSemaphore"); + } + return result; +} + bool JackWinMMEOutputPort::Start() { @@ -319,15 +323,31 @@ JackWinMMEOutputPort::Start() bool JackWinMMEOutputPort::Stop() { - bool result = thread->GetStatus() == JackThread::kIdle; - if (! result) { - result = ! thread->Kill(); - if (! result) { - jack_error("JackWinMMEOutputPort::Stop - failed to stop MIDI " - "processing thread."); - } + + jack_info("JackWinMMEOutputPort::Stop - stopping MIDI output port " + "processing thread."); + + int result; + const char *verb; + switch (thread->GetStatus()) { + case JackThread::kIniting: + case JackThread::kStarting: + result = thread->Kill(); + verb = "kill"; + break; + case JackThread::kRunning: + Signal(thread_queue_semaphore); + result = thread->Stop(); + verb = "stop"; + break; + default: + return true; } - return result; + if (result) { + jack_error("JackWinMMEOutputPort::Stop - could not %s MIDI processing " + "thread.", verb); + } + return ! result; } bool diff --git a/windows/winmme/JackWinMMEOutputPort.h b/windows/winmme/JackWinMMEOutputPort.h index ef1bd65d..1033ec3e 100644 --- a/windows/winmme/JackWinMMEOutputPort.h +++ b/windows/winmme/JackWinMMEOutputPort.h @@ -46,6 +46,9 @@ namespace Jack { void HandleMessage(UINT message, DWORD_PTR param1, DWORD_PTR param2); + bool + Signal(Handle semaphore); + bool Wait(Handle semaphore); From 66200176dc62008e87f69fd7c2837840b351589a Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Tue, 29 Mar 2011 12:24:26 -0700 Subject: [PATCH 098/472] Add support for advance scheduling via driver preferences. Hope this doesn't break anything. --- macosx/coremidi/JackCoreMidiOutputPort.cpp | 25 +++++++++---------- macosx/coremidi/JackCoreMidiOutputPort.h | 3 ++- .../JackCoreMidiPhysicalOutputPort.cpp | 15 ++++++++++- .../JackCoreMidiVirtualOutputPort.cpp | 2 +- 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/macosx/coremidi/JackCoreMidiOutputPort.cpp b/macosx/coremidi/JackCoreMidiOutputPort.cpp index 15a04f76..48058c92 100644 --- a/macosx/coremidi/JackCoreMidiOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiOutputPort.cpp @@ -44,6 +44,7 @@ JackCoreMidiOutputPort::JackCoreMidiOutputPort(double time_ratio, if (thread_queue_semaphore == (sem_t *) SEM_FAILED) { throw std::runtime_error(strerror(errno)); } + advance_schedule_time = 0; thread_ptr.release(); thread_queue_ptr.release(); read_queue_ptr.release(); @@ -71,20 +72,15 @@ JackCoreMidiOutputPort::Execute() event = GetCoreMidiEvent(true); } jack_midi_data_t *data = event->buffer; - - // This is the latest time that the packet list can be sent out. We - // may want to consider subtracting some frames to leave room for the - // CoreMIDI driver/client to handle all of the events. There's a - // property called 'kMIDIPropertyAdvanceScheduleTimeMuSec' that might - // be useful in this case. - jack_nframes_t send_time = event->time; - + jack_nframes_t send_frame = event->time; + jack_time_t send_time = + GetTimeFromFrames(send_frame) - advance_schedule_time; size_t size = event->size; - MIDITimeStamp timestamp = GetTimeStampFromFrames(send_time); + MIDITimeStamp timestamp = GetTimeStampFromFrames(send_frame); packet = MIDIPacketListAdd(packet_list, PACKET_BUFFER_SIZE, packet, timestamp, size, data); if (packet) { - while (GetCurrentFrame() < send_time) { + while (GetMicroSeconds() < send_time) { event = GetCoreMidiEvent(false); if (! event) { break; @@ -186,12 +182,15 @@ JackCoreMidiOutputPort::Init() void JackCoreMidiOutputPort::Initialize(const char *alias_name, - const char *client_name, - const char *driver_name, int index, - MIDIEndpointRef endpoint) + const char *client_name, + const char *driver_name, int index, + MIDIEndpointRef endpoint, + SInt32 advance_schedule_time) { JackCoreMidiPort::Initialize(alias_name, client_name, driver_name, index, endpoint, true); + assert(advance_schedule_time >= 0); + this->advance_schedule_time = advance_schedule_time; } void diff --git a/macosx/coremidi/JackCoreMidiOutputPort.h b/macosx/coremidi/JackCoreMidiOutputPort.h index d713c314..a04d98b3 100644 --- a/macosx/coremidi/JackCoreMidiOutputPort.h +++ b/macosx/coremidi/JackCoreMidiOutputPort.h @@ -42,6 +42,7 @@ namespace Jack { static const size_t PACKET_BUFFER_SIZE = 65536; + SInt32 advance_schedule_time; char packet_buffer[PACKET_BUFFER_SIZE]; JackMidiBufferReadQueue *read_queue; char semaphore_name[128]; @@ -57,7 +58,7 @@ namespace Jack { void Initialize(const char *alias_name, const char *client_name, const char *driver_name, int index, - MIDIEndpointRef endpoint); + MIDIEndpointRef endpoint, SInt32 advance_schedule_time); public: diff --git a/macosx/coremidi/JackCoreMidiPhysicalOutputPort.cpp b/macosx/coremidi/JackCoreMidiPhysicalOutputPort.cpp index e5b19d59..d8a4af25 100644 --- a/macosx/coremidi/JackCoreMidiPhysicalOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiPhysicalOutputPort.cpp @@ -43,7 +43,20 @@ JackCoreMidiPhysicalOutputPort(const char *alias_name, const char *client_name, << "' is not available"; throw std::runtime_error(stream.str().c_str()); } - Initialize(alias_name, client_name, driver_name, index, destination); + SInt32 advance_schedule_time; + OSStatus status = + MIDIObjectGetIntegerProperty(destination, + kMIDIPropertyAdvanceScheduleTimeMuSec, + &advance_schedule_time); + if (status != noErr) { + WriteMacOSError("JackCoreMidiPhysicalOutputPort [constructor]", + "MIDIObjectGetIntegerProperty", status); + advance_schedule_time = 0; + } else if (advance_schedule_time < 0) { + advance_schedule_time = 0; + } + Initialize(alias_name, client_name, driver_name, index, destination, + advance_schedule_time); this->internal_output = internal_output; } diff --git a/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp b/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp index 5e69a170..88b46d06 100644 --- a/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp @@ -47,7 +47,7 @@ JackCoreMidiVirtualOutputPort(const char *alias_name, const char *client_name, if (status != noErr) { throw std::runtime_error(GetMacOSErrorString(status)); } - Initialize(alias_name, client_name, driver_name, index, source); + Initialize(alias_name, client_name, driver_name, index, source, 0); } JackCoreMidiVirtualOutputPort::~JackCoreMidiVirtualOutputPort() From e75eea7e67ff79d8ca69d79bffbf1623954fb978 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Tue, 29 Mar 2011 23:01:56 +0200 Subject: [PATCH 099/472] Add missing include. --- macosx/coremidi/JackCoreMidiOutputPort.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/macosx/coremidi/JackCoreMidiOutputPort.cpp b/macosx/coremidi/JackCoreMidiOutputPort.cpp index 48058c92..f014d478 100644 --- a/macosx/coremidi/JackCoreMidiOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiOutputPort.cpp @@ -25,6 +25,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackCoreMidiOutputPort.h" #include "JackMidiUtil.h" +#include "JackTime.h" using Jack::JackCoreMidiOutputPort; From c9342fc058e01ad5df90b46a961b03bbd9a939ce Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Tue, 29 Mar 2011 16:54:37 -0700 Subject: [PATCH 100/472] Add default 'SetBufferSize' implementation for 'JackMidiDriver'. --- common/JackMidiDriver.cpp | 21 +++++++++++++++++++++ common/JackMidiDriver.h | 2 ++ 2 files changed, 23 insertions(+) diff --git a/common/JackMidiDriver.cpp b/common/JackMidiDriver.cpp index 4de11989..6b3f2935 100644 --- a/common/JackMidiDriver.cpp +++ b/common/JackMidiDriver.cpp @@ -143,6 +143,27 @@ int JackMidiDriver::Write() return 0; } +int JackMidiDriver::SetBufferSize(jack_nframes_t buffer_size) +{ + jack_latency_range_t latency_range; + latency_range.max = buffer_size; + latency_range.min = buffer_size; + for (int i = 0; i < fCaptureChannels; i++) { + fGraphManager->GetPort(fCapturePortList[i])-> + SetLatencyRange(JackCaptureLatency, &latency_range); + } + if (! fEngineControl->fSyncMode) { + buffer_size *= 2; + latency_range.max = buffer_size; + latency_range.min = buffer_size; + } + for (int i = 0; i < fPlaybackChannels; i++) { + fGraphManager->GetPort(fPlaybackPortList[i])-> + SetLatencyRange(JackPlaybackLatency, &latency_range); + } + return 0; +} + int JackMidiDriver::ProcessNull() { return 0; diff --git a/common/JackMidiDriver.h b/common/JackMidiDriver.h index 45fe484c..044e8d23 100644 --- a/common/JackMidiDriver.h +++ b/common/JackMidiDriver.h @@ -69,6 +69,8 @@ class SERVER_EXPORT JackMidiDriver : public JackDriver jack_nframes_t capture_latency, jack_nframes_t playback_latency); + virtual int SetBufferSize(jack_nframes_t buffer_size); + virtual int ProcessRead(); virtual int ProcessWrite(); From cf98c33ef8678e948667235f0061494ba0a627cd Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Wed, 30 Mar 2011 11:41:00 +0200 Subject: [PATCH 101/472] Correct SetBufferSize for drivers. --- common/JackAudioDriver.cpp | 43 ++++++++---- common/JackAudioDriver.h | 1 + common/JackDriver.cpp | 20 +++++- common/JackDummyDriver.cpp | 1 + common/JackMidiDriver.cpp | 1 + common/JackNetManager.cpp | 2 +- common/JackServer.cpp | 2 - linux/alsa/JackAlsaDriver.cpp | 40 +++++++---- linux/alsa/JackAlsaDriver.h | 2 + macosx/coreaudio/JackCoreAudioDriver.cpp | 86 ++++++++++++++--------- macosx/coreaudio/JackCoreAudioDriver.h | 16 +++-- windows/portaudio/JackPortAudioDriver.cpp | 39 ++++------ windows/portaudio/JackPortAudioDriver.h | 2 + 13 files changed, 163 insertions(+), 92 deletions(-) diff --git a/common/JackAudioDriver.cpp b/common/JackAudioDriver.cpp index dedf02b0..f284a8cf 100644 --- a/common/JackAudioDriver.cpp +++ b/common/JackAudioDriver.cpp @@ -44,12 +44,17 @@ JackAudioDriver::~JackAudioDriver() int JackAudioDriver::SetBufferSize(jack_nframes_t buffer_size) { + // Update engine and graph manager state fEngineControl->fBufferSize = buffer_size; fGraphManager->SetBufferSize(buffer_size); fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec if (!fEngineControl->fTimeOut) fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs); - return 0; + + UpdateLatencies(); + + // Redirect on slaves drivers... + return JackDriver::SetBufferSize(buffer_size); } int JackAudioDriver::SetSampleRate(jack_nframes_t sample_rate) @@ -58,7 +63,8 @@ int JackAudioDriver::SetSampleRate(jack_nframes_t sample_rate) fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec if (!fEngineControl->fTimeOut) fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs); - return 0; + + return JackDriver::SetSampleRate(sample_rate); } int JackAudioDriver::Open(jack_nframes_t buffer_size, @@ -95,13 +101,33 @@ int JackAudioDriver::Open(bool capturing, return JackDriver::Open(capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); } +void JackAudioDriver::UpdateLatencies() +{ + jack_latency_range_t range; + + for (int i = 0; i < fCaptureChannels; i++) { + range.max = range.min = fEngineControl->fBufferSize; + fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &range); + } + + for (int i = 0; i < fPlaybackChannels; i++) { + if (! fEngineControl->fSyncMode) { + range.max = range.min = fEngineControl->fBufferSize * 2; + } + fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &range); + if (fWithMonitorPorts) { + range.min = range.max = fEngineControl->fBufferSize; + fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &range); + } + } +} + int JackAudioDriver::Attach() { JackPort* port; jack_port_id_t port_index; char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - jack_latency_range_t range; int i; jack_log("JackAudioDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); @@ -115,8 +141,6 @@ int JackAudioDriver::Attach() } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - range.min = range.max = fEngineControl->fBufferSize + fCaptureLatency; - port->SetLatencyRange(JackCaptureLatency, &range); fCapturePortList[i] = port_index; jack_log("JackAudioDriver::Attach fCapturePortList[i] port_index = %ld", port_index); } @@ -130,9 +154,6 @@ int JackAudioDriver::Attach() } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - // Add more latency if "async" mode is used... - range.min = range.max = fEngineControl->fBufferSize + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + fPlaybackLatency; - port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[i] = port_index; jack_log("JackAudioDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); @@ -144,14 +165,12 @@ int JackAudioDriver::Attach() jack_error("Cannot register monitor port for %s", name); return -1; } else { - port = fGraphManager->GetPort(port_index); - range.min = range.max = fEngineControl->fBufferSize; - port->SetLatencyRange(JackCaptureLatency, &range); - fMonitorPortList[i] = port_index; + fMonitorPortList[i] = port_index; } } } + UpdateLatencies(); return 0; } diff --git a/common/JackAudioDriver.h b/common/JackAudioDriver.h index cb0ebefe..83b0ba53 100644 --- a/common/JackAudioDriver.h +++ b/common/JackAudioDriver.h @@ -62,6 +62,7 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver jack_default_audio_sample_t* GetMonitorBuffer(int port_index); void HandleLatencyCallback(int status); + void UpdateLatencies(); public: diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index e94b1a35..5fab3f4f 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -418,12 +418,28 @@ bool JackDriver::IsFixedBufferSize() int JackDriver::SetBufferSize(jack_nframes_t buffer_size) { - return 0; + int res = 0; + + list::const_iterator it; + for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { + JackDriverInterface* slave = *it; + if (slave->SetBufferSize(buffer_size) < 0) + res = -1; + } + + return res; } int JackDriver::SetSampleRate(jack_nframes_t sample_rate) { - return 0; + int res = 0; + list::const_iterator it; + for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { + JackDriverInterface* slave = *it; + if (slave->SetSampleRate(sample_rate) < 0) + res = -1; + } + return res; } bool JackDriver::Initialize() diff --git a/common/JackDummyDriver.cpp b/common/JackDummyDriver.cpp index fb996a11..4c084f06 100644 --- a/common/JackDummyDriver.cpp +++ b/common/JackDummyDriver.cpp @@ -78,6 +78,7 @@ int JackDummyDriver::Process() int JackDummyDriver::SetBufferSize(jack_nframes_t buffer_size) { + // Generic change, never fails JackAudioDriver::SetBufferSize(buffer_size); fWaitTime = (unsigned long)((((float)buffer_size) / ((float)fEngineControl->fSampleRate)) * 1000000.0f); return 0; diff --git a/common/JackMidiDriver.cpp b/common/JackMidiDriver.cpp index 6b3f2935..5c0604d5 100644 --- a/common/JackMidiDriver.cpp +++ b/common/JackMidiDriver.cpp @@ -145,6 +145,7 @@ int JackMidiDriver::Write() int JackMidiDriver::SetBufferSize(jack_nframes_t buffer_size) { + // Update latencies jack_latency_range_t latency_range; latency_range.max = buffer_size; latency_range.min = buffer_size; diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index e882cb6e..ab97637b 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -392,7 +392,7 @@ namespace Jack { JackNetMaster* obj = static_cast(arg); if (nframes != obj->fParams.fPeriodSize) { - jack_error("Cannot handle bufer size change, so JackNetMaster proxy will be removed..."); + jack_error("Cannot handle buffer size change, so JackNetMaster proxy will be removed..."); obj->Exit(); } return 0; diff --git a/common/JackServer.cpp b/common/JackServer.cpp index cd1915fb..e1bcbb8a 100644 --- a/common/JackServer.cpp +++ b/common/JackServer.cpp @@ -223,13 +223,11 @@ int JackServer::SetBufferSize(jack_nframes_t buffer_size) } if (fAudioDriver->SetBufferSize(buffer_size) == 0) { - fFreewheelDriver->SetBufferSize(buffer_size); fEngine->NotifyBufferSize(buffer_size); return fAudioDriver->Start(); } else { // Failure: try to restore current value jack_error("Cannot SetBufferSize for audio driver, restore current value %ld", current_buffer_size); fAudioDriver->SetBufferSize(current_buffer_size); - fFreewheelDriver->SetBufferSize(current_buffer_size); fAudioDriver->Start(); // SetBufferSize actually failed, so return an error... return -1; diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index b42e9693..f8eaf22b 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -55,8 +55,11 @@ int JackAlsaDriver::SetBufferSize(jack_nframes_t buffer_size) ((alsa_driver_t *)fDriver)->frame_rate); if (res == 0) { // update fEngineControl and fGraphManager - JackAudioDriver::SetBufferSize(buffer_size); // never fails + JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails + // ALSA specific + UpdateLatencies(); } else { + // Restore old values alsa_driver_reset_parameters((alsa_driver_t *)fDriver, fEngineControl->fBufferSize, ((alsa_driver_t *)fDriver)->user_nperiods, ((alsa_driver_t *)fDriver)->frame_rate); @@ -65,6 +68,28 @@ int JackAlsaDriver::SetBufferSize(jack_nframes_t buffer_size) return res; } +void JackAlsaDriver::UpdateLatencies() +{ + jack_latency_range_t range; + + for (int i = 0; i < fCaptureChannels; i++) { + range.min = range.max = alsa_driver->frames_per_cycle + alsa_driver->capture_frame_latency; + fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &range); + } + + for (int i = 0; i < fPlaybackChannels; i++) { + // Add one buffer more latency if "async" mode is used... + range.min = range.max = (alsa_driver->frames_per_cycle * (alsa_driver->user_nperiods - 1)) + + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + alsa_driver->playback_frame_latency; + fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &range); + // Monitor port + if (fWithMonitorPorts) { + range.min = range.max = alsa_driver->frames_per_cycle; + fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &range); + } + } +} + int JackAlsaDriver::Attach() { JackPort* port; @@ -72,7 +97,6 @@ int JackAlsaDriver::Attach() unsigned long port_flags = (unsigned long)CaptureDriverFlags; char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - jack_latency_range_t range; assert(fCaptureChannels < DRIVER_PORT_NUM); assert(fPlaybackChannels < DRIVER_PORT_NUM); @@ -97,8 +121,6 @@ int JackAlsaDriver::Attach() } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - range.min = range.max = alsa_driver->frames_per_cycle + alsa_driver->capture_frame_latency; - port->SetLatencyRange(JackCaptureLatency, &range); fCapturePortList[i] = port_index; jack_log("JackAlsaDriver::Attach fCapturePortList[i] %ld ", port_index); } @@ -114,11 +136,6 @@ int JackAlsaDriver::Attach() } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - // Add one buffer more latency if "async" mode is used... - range.min = range.max = (alsa_driver->frames_per_cycle * (alsa_driver->user_nperiods - 1)) + - ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + alsa_driver->playback_frame_latency; - - port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[i] = port_index; jack_log("JackAlsaDriver::Attach fPlaybackPortList[i] %ld ", port_index); @@ -129,14 +146,13 @@ int JackAlsaDriver::Attach() if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, MonitorDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error ("ALSA: cannot register monitor port for %s", name); } else { - port = fGraphManager->GetPort(port_index); - range.min = range.max = alsa_driver->frames_per_cycle; - port->SetLatencyRange(JackCaptureLatency, &range); fMonitorPortList[i] = port_index; } } } + UpdateLatencies(); + if (alsa_driver->midi) { int err = (alsa_driver->midi->attach)(alsa_driver->midi); if (err) diff --git a/linux/alsa/JackAlsaDriver.h b/linux/alsa/JackAlsaDriver.h index 6d42b91a..a88d4a01 100644 --- a/linux/alsa/JackAlsaDriver.h +++ b/linux/alsa/JackAlsaDriver.h @@ -42,6 +42,8 @@ class JackAlsaDriver : public JackAudioDriver int fReservedCaptureDevice; int fReservedPlaybackDevice; + void UpdateLatencies(); + public: JackAlsaDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index bf4e3195..97352bca 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -1563,6 +1563,53 @@ int JackCoreAudioDriver::Close() return res; } +void JackCoreAudioDriver::UpdateLatencies() +{ + UInt32 size; + OSStatus err; + jack_latency_range_t range; + range.max = fEngineControl->fBufferSize; + range.min = fEngineControl->fBufferSize; + + for (int i = 0; i < fCaptureChannels; i++) { + size = sizeof(UInt32); + UInt32 value1 = 0; + UInt32 value2 = 0; + err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertyLatency, &size, &value1); + if (err != noErr) + jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error"); + err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertySafetyOffset, &size, &value2); + if (err != noErr) + jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error"); + + range.min = range.max = fEngineControl->fBufferSize + value1 + value2 + fCaptureLatency; + fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &range); + } + + for (int i = 0; i < fPlaybackChannels; i++) { + size = sizeof(UInt32); + UInt32 value1 = 0; + UInt32 value2 = 0; + err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertyLatency, &size, &value1); + if (err != noErr) + jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error"); + err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertySafetyOffset, &size, &value2); + if (err != noErr) + jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error"); + + // Add more latency if "async" mode is used... + range.min = range.max + = fEngineControl->fBufferSize + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize * fIOUsage) + value1 + value2 + fPlaybackLatency; + fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &range); + + // Monitor port + if (fWithMonitorPorts) { + range.min = range.max = fEngineControl->fBufferSize; + fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &range); + } + } +} + int JackCoreAudioDriver::Attach() { OSStatus err; @@ -1573,7 +1620,6 @@ 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_latency_range_t range; jack_log("JackCoreAudioDriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); @@ -1598,20 +1644,8 @@ int JackCoreAudioDriver::Attach() return -1; } - size = sizeof(UInt32); - UInt32 value1 = 0; - UInt32 value2 = 0; - err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertyLatency, &size, &value1); - if (err != noErr) - jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error"); - err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertySafetyOffset, &size, &value2); - if (err != noErr) - jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error"); - port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - range.min = range.max = fEngineControl->fBufferSize + value1 + value2 + fCaptureLatency; - port->SetLatencyRange(JackCaptureLatency, &range); fCapturePortList[i] = port_index; } @@ -1636,21 +1670,8 @@ int JackCoreAudioDriver::Attach() return -1; } - size = sizeof(UInt32); - UInt32 value1 = 0; - UInt32 value2 = 0; - err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertyLatency, &size, &value1); - if (err != noErr) - jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error"); - err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertySafetyOffset, &size, &value2); - if (err != noErr) - jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error"); - port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - // Add more latency if "async" mode is used... - range.min = range.max = fEngineControl->fBufferSize + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize * fIOUsage) + value1 + value2 + fPlaybackLatency; - port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[i] = port_index; // Monitor ports @@ -1661,14 +1682,13 @@ int JackCoreAudioDriver::Attach() jack_error("Cannot register monitor port for %s", name); return -1; } else { - port = fGraphManager->GetPort(port_index); - range.min = range.max = fEngineControl->fBufferSize; - port->SetLatencyRange(JackCaptureLatency, &range); fMonitorPortList[i] = port_index; } } } + UpdateLatencies(); + // Input buffers do no change : prepare them only once for (int i = 0; i < fCaptureChannels; i++) { fJackInputData->mBuffers[i].mData = GetInputBuffer(i); @@ -1716,17 +1736,19 @@ int JackCoreAudioDriver::Stop() int JackCoreAudioDriver::SetBufferSize(jack_nframes_t buffer_size) { - OSStatus err; UInt32 outSize = sizeof(UInt32); - err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, outSize, &buffer_size); + OSStatus err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, outSize, &buffer_size); if (err != noErr) { jack_error("Cannot set buffer size %ld", buffer_size); printError(err); return -1; } - JackAudioDriver::SetBufferSize(buffer_size); // never fails + JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails + + // CoreAudio specific + UpdateLatencies(); // Input buffers do no change : prepare them only once for (int i = 0; i < fCaptureChannels; i++) { diff --git a/macosx/coreaudio/JackCoreAudioDriver.h b/macosx/coreaudio/JackCoreAudioDriver.h index b0ccbe10..c0513609 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.h +++ b/macosx/coreaudio/JackCoreAudioDriver.h @@ -40,7 +40,7 @@ typedef UInt8 CAAudioHardwareDeviceSectionID; #define kAudioDeviceSectionOutput ((CAAudioHardwareDeviceSectionID)0x00) #define kAudioDeviceSectionGlobal ((CAAudioHardwareDeviceSectionID)0x00) #define kAudioDeviceSectionWildcard ((CAAudioHardwareDeviceSectionID)0xFF) - + #define WAIT_COUNTER 60 /*! @@ -74,13 +74,13 @@ class JackCoreAudioDriver : public JackAudioDriver float fIOUsage; float fComputationGrain; bool fClockDriftCompensate; - - /* + + /* #ifdef MAC_OS_X_VERSION_10_5 AudioDeviceIOProcID fMesureCallbackID; #endif */ - + static OSStatus Render(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, @@ -106,13 +106,13 @@ class JackCoreAudioDriver : public JackAudioDriver OSStatus GetDefaultOutputDevice(AudioDeviceID* id); OSStatus GetDeviceNameFromID(AudioDeviceID id, char* name); OSStatus GetTotalChannels(AudioDeviceID device, int& channelCount, bool isInput); - + // Setup OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); OSStatus CreateAggregateDeviceAux(vector captureDeviceID, vector playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); OSStatus DestroyAggregateDevice(); bool IsAggregateDevice(AudioDeviceID device); - + int SetupDevices(const char* capture_driver_uid, const char* playback_driver_uid, char* capture_driver_name, @@ -146,10 +146,12 @@ class JackCoreAudioDriver : public JackAudioDriver int AddListeners(); void RemoveListeners(); - + bool TakeHogAux(AudioDeviceID deviceID, bool isInput); bool TakeHog(); + void UpdateLatencies(); + public: JackCoreAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); diff --git a/windows/portaudio/JackPortAudioDriver.cpp b/windows/portaudio/JackPortAudioDriver.cpp index 41a3deb2..790bcda1 100644 --- a/windows/portaudio/JackPortAudioDriver.cpp +++ b/windows/portaudio/JackPortAudioDriver.cpp @@ -86,13 +86,11 @@ namespace Jack return -1; //get devices - if (capturing) - { + if (capturing) { if (fPaDevices->GetInputDeviceFromName(capture_driver_uid, fInputDevice, in_max) < 0) goto error; } - if (playing) - { + if (playing) { if (fPaDevices->GetOutputDeviceFromName(playback_driver_uid, fOutputDevice, out_max) < 0) goto error; } @@ -100,25 +98,21 @@ namespace Jack jack_log("JackPortAudioDriver::Open fInputDevice = %d, fOutputDevice %d", fInputDevice, fOutputDevice); //default channels number required - if (inchannels == 0) - { + if (inchannels == 0) { jack_log("JackPortAudioDriver::Open setup max in channels = %ld", in_max); inchannels = in_max; } - if (outchannels == 0) - { + if (outchannels == 0) { jack_log("JackPortAudioDriver::Open setup max out channels = %ld", out_max); outchannels = out_max; } //too many channels required, take max available - if (inchannels > in_max) - { + if (inchannels > in_max) { jack_error("This device has only %d available input channels.", in_max); inchannels = in_max; } - if (outchannels > out_max) - { + if (outchannels > out_max) { jack_error("This device has only %d available output channels.", out_max); outchannels = out_max; } @@ -148,8 +142,7 @@ namespace Jack paNoFlag, // Clipping is on... Render, this); - if (err != paNoError) - { + if (err != paNoError) { jack_error("Pa_OpenStream error = %s", Pa_GetErrorText(err)); goto error; } @@ -218,13 +211,12 @@ error: PaStreamParameters inputParameters; PaStreamParameters outputParameters; - if ((err = Pa_CloseStream(fStream)) != paNoError) - { + if ((err = Pa_CloseStream(fStream)) != paNoError) { jack_error("Pa_CloseStream error = %s", Pa_GetErrorText(err)); return -1; } - //change parametering + // Update parameters inputParameters.device = fInputDevice; inputParameters.channelCount = fCaptureChannels; inputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output @@ -250,15 +242,14 @@ error: Render, this); - if (err != paNoError) - { + if (err != paNoError) { jack_error("Pa_OpenStream error = %s", Pa_GetErrorText(err)); return -1; - } - else - { - // Only done when success - return JackAudioDriver::SetBufferSize(buffer_size); // never fails + } else { + JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails + // PortAudio specific + UpdateLatencies(); + return 0; } } diff --git a/windows/portaudio/JackPortAudioDriver.h b/windows/portaudio/JackPortAudioDriver.h index c4945f44..564d5a4e 100644 --- a/windows/portaudio/JackPortAudioDriver.h +++ b/windows/portaudio/JackPortAudioDriver.h @@ -48,6 +48,8 @@ class JackPortAudioDriver : public JackAudioDriver PaStreamCallbackFlags statusFlags, void* userData); + void UpdateLatencies(); + public: JackPortAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, PortAudioDevices* pa_devices) From 3240743a8c6a4b0d70120984bbf9b7cb582d0294 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Wed, 30 Mar 2011 11:51:32 +0200 Subject: [PATCH 102/472] Cleanup SetBufferSize for JackMidiDriver. --- common/JackMidiDriver.cpp | 40 ++++++++++++++++----------------------- common/JackMidiDriver.h | 2 ++ 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/common/JackMidiDriver.cpp b/common/JackMidiDriver.cpp index 5c0604d5..b98b8daa 100644 --- a/common/JackMidiDriver.cpp +++ b/common/JackMidiDriver.cpp @@ -74,12 +74,9 @@ int JackMidiDriver::Attach() jack_port_id_t port_index; char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - jack_latency_range_t latency_range; - jack_nframes_t latency = fEngineControl->fBufferSize; int i; jack_log("JackMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); - latency_range.max = latency_range.min = latency; for (i = 0; i < fCaptureChannels; i++) { snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); @@ -90,16 +87,10 @@ int JackMidiDriver::Attach() } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - port->SetLatencyRange(JackCaptureLatency, &latency_range); fCapturePortList[i] = port_index; jack_log("JackMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index); } - if (!fEngineControl->fSyncMode) { - latency += fEngineControl->fBufferSize;; - latency_range.max = latency_range.min = latency; - } - for (i = 0; i < fPlaybackChannels; i++) { snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); @@ -109,11 +100,11 @@ int JackMidiDriver::Attach() } port = fGraphManager->GetPort(port_index); port->SetAlias(alias); - port->SetLatencyRange(JackPlaybackLatency, &latency_range); fPlaybackPortList[i] = port_index; jack_log("JackMidiDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); } + UpdateLatencies(); return 0; } @@ -143,25 +134,26 @@ int JackMidiDriver::Write() return 0; } -int JackMidiDriver::SetBufferSize(jack_nframes_t buffer_size) +void JackMidiDriver::UpdateLatencies() { - // Update latencies - jack_latency_range_t latency_range; - latency_range.max = buffer_size; - latency_range.min = buffer_size; + jack_latency_range_t range; + for (int i = 0; i < fCaptureChannels; i++) { - fGraphManager->GetPort(fCapturePortList[i])-> - SetLatencyRange(JackCaptureLatency, &latency_range); - } - if (! fEngineControl->fSyncMode) { - buffer_size *= 2; - latency_range.max = buffer_size; - latency_range.min = buffer_size; + range.max = range.min = fEngineControl->fBufferSize; + fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &range); } + for (int i = 0; i < fPlaybackChannels; i++) { - fGraphManager->GetPort(fPlaybackPortList[i])-> - SetLatencyRange(JackPlaybackLatency, &latency_range); + if (! fEngineControl->fSyncMode) { + range.max = range.min = fEngineControl->fBufferSize * 2; + } + fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &range); } +} + +int JackMidiDriver::SetBufferSize(jack_nframes_t buffer_size) +{ + UpdateLatencies(); return 0; } diff --git a/common/JackMidiDriver.h b/common/JackMidiDriver.h index 044e8d23..fa471627 100644 --- a/common/JackMidiDriver.h +++ b/common/JackMidiDriver.h @@ -54,6 +54,8 @@ class SERVER_EXPORT JackMidiDriver : public JackDriver virtual int ProcessReadAsync(); virtual int ProcessWriteAsync(); + virtual void UpdateLatencies(); + public: JackMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); From 51e07561ad3541f26e88923e67c66b46740f6112 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Wed, 30 Mar 2011 11:44:27 +0200 Subject: [PATCH 103/472] Correct JackAlsaDriver::UpdateLatencies. --- linux/alsa/JackAlsaDriver.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index f8eaf22b..fb816453 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -71,6 +71,7 @@ int JackAlsaDriver::SetBufferSize(jack_nframes_t buffer_size) void JackAlsaDriver::UpdateLatencies() { jack_latency_range_t range; + alsa_driver_t* alsa_driver = (alsa_driver_t*)fDriver; for (int i = 0; i < fCaptureChannels; i++) { range.min = range.max = alsa_driver->frames_per_cycle + alsa_driver->capture_frame_latency; From 7254ce1ebcb88637e7c491325ef2d167312608d2 Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 30 Mar 2011 16:37:38 +0000 Subject: [PATCH 104/472] rebase from trunk 4180:4238 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@4239 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 29 + README | 67 +- common/JackAPI.cpp | 2 +- common/JackAudioAdapter.cpp | 10 +- common/JackAudioAdapterInterface.h | 24 +- common/JackAudioDriver.cpp | 27 +- common/JackAudioDriver.h | 3 + common/JackAudioPort.cpp | 34 +- common/JackClient.cpp | 4 +- common/JackClient.h | 12 +- common/JackControlAPI.cpp | 79 +- common/JackControlAPI.h | 12 +- common/JackDebugClient.cpp | 48 + common/JackDebugClient.h | 12 +- common/JackDriver.cpp | 59 +- common/JackDriver.h | 5 + common/JackDriverLoader.cpp | 28 +- common/JackDriverLoader.h | 33 +- common/JackEngine.cpp | 17 +- common/JackGraphManager.cpp | 2 +- common/JackGraphManager.h | 2 +- common/JackInternalClient.cpp | 16 +- common/JackInternalClientChannel.h | 2 +- common/JackLibClient.h | 4 +- common/JackLibGlobals.h | 18 +- common/JackLibSampleRateResampler.cpp | 66 +- common/JackLibSampleRateResampler.h | 18 +- common/JackLoopbackDriver.cpp | 12 +- common/JackMidiDriver.cpp | 16 +- common/JackMidiPort.cpp | 4 +- common/JackMidiPort.h | 4 +- common/JackNetOneDriver.cpp | 42 +- common/JackPort.cpp | 2 +- common/JackPort.h | 6 +- common/JackResampler.cpp | 36 +- common/JackResampler.h | 33 +- common/JackServer.cpp | 93 +- common/JackServer.h | 12 +- common/JackServerAPI.cpp | 16 +- common/JackServerGlobals.cpp | 197 +- common/JackServerGlobals.h | 4 + common/JackThreadedDriver.cpp | 17 +- common/JackThreadedDriver.h | 21 +- common/JackWeakAPI.cpp | 62 +- common/Jackdmp.cpp | 177 +- common/jack/control.h | 218 +- common/netjack.c | 191 +- common/netjack.h | 26 +- common/netjack_packet.c | 201 +- common/varargs.h | 12 +- dbus/controller.c | 23 +- doxyfile | 1564 ++++++++++---- example-clients/alsa_in.c | 2 +- example-clients/alsa_out.c | 2 +- example-clients/connect.c | 15 +- example-clients/control.c | 24 +- example-clients/netsource.c | 203 +- example-clients/server_control.cpp | 55 +- example-clients/wscript | 32 +- linux/JackLinuxTime.c | 22 +- linux/alsa/JackAlsaAdapter.cpp | 10 +- linux/alsa/JackAlsaAdapter.h | 48 +- linux/alsa/JackAlsaDriver.cpp | 2198 ++------------------ linux/alsa/JackAlsaDriver.h | 87 +- linux/alsa/alsa_driver.c | 2172 +++++++++++++++++++ linux/alsa/alsa_driver.h | 195 +- linux/firewire/JackFFADODriver.cpp | 24 +- linux/freebob/JackFreebobDriver.cpp | 22 +- linux/wscript | 4 +- macosx/Jackdmp.xcodeproj/project.pbxproj | 2 + macosx/coreaudio/JackCoreAudioAdapter.cpp | 22 +- macosx/coreaudio/JackCoreAudioDriver.cpp | 90 +- macosx/coremidi/JackCoreMidiDriver.cpp | 111 +- macosx/coremidi/JackCoreMidiDriver.h | 12 +- posix/JackSocketServerChannel.cpp | 2 +- posix/JackSystemDeps_os.h | 2 + windows/JackRouter/JackRouter.cpp | 110 +- windows/JackWinNamedPipeServerChannel.cpp | 2 +- windows/JackWinProcessSync.cpp | 10 +- windows/Setup/JackRouter.dll | Bin 32768 -> 32768 bytes windows/portaudio/JackPortAudioAdapter.cpp | 2 +- windows/portaudio/JackPortAudioDriver.cpp | 27 +- windows/portaudio/JackPortAudioDriver.h | 4 +- windows/winmme/JackWinMMEDriver.cpp | 5 +- wscript | 12 +- 85 files changed, 5314 insertions(+), 3836 deletions(-) create mode 100644 linux/alsa/alsa_driver.c diff --git a/ChangeLog b/ChangeLog index fbb75e3c..06afa7d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -34,9 +34,38 @@ Valerio Pilo Jackdmp changes log --------------------------- +2011-03-29 Stephane Letz + + * Synchronize JackWeakAPI.cpp with new APIs. + +2011-03-28 Stephane Letz + + * Correction of jack_connect/jack_disconnect: use of jack_activate and volatile keyword for thread shared variable. + * Correction of JackNetOneDriver for latest CELT API. + +2011-03-24 Stephane Letz + + * Implement renaming in JackDriver::Open to avoid name collision (thanks Devin Anderson). + * Correct alsa_driver_restart (thanks Devin Anderson). + +2011-03-23 Stephane Letz + + * Devin Anderson server-ctl-proposal branch merged on trunk: improved control API, slave backend reworked. + +2011-03-14 Stephane Letz + + * Correct JackEngine::NotifyGraphReorder, update JackDebugClient with latest API. + +2011-03-13 Stephane Letz + + * Rework internal slave driver management, JackServerGlobals now handle same parameters as jackdmp. + 2011-03-11 Stephane Letz * Correct JackNetMaster::SetBufferSize. + * Use jack_default_audio_sample_t instead of float consistently, fix ticket #201." + * -X now allows to add several slave backends, add -I to load several internal clients. + 2011-03-10 Stephane Letz diff --git a/README b/README index 92eb746d..b9a0a533 100644 --- a/README +++ b/README @@ -1,14 +1,14 @@ ------------------------------------------------ -jackdmp for Linux, MacOSX, Windows and Solaris ------------------------------------------------ +----------------------------------------------------------- +jackdmp (aka JACK2) for Linux, MacOSX, Windows and Solaris +----------------------------------------------------------- -jackdmp is a C++ version of the JACK low-latency audio server for multi-processor machines. It is a new implementation of the JACK server core features that aims in removing some limitations of the current design. The activation system has been changed for a data flow model and lock-free programming techniques for graph access have been used to have a more dynamic and robust system. +jackdmp is a C++ version of the JACK low-latency audio server for multi-processor machines. It is a new implementation of the JACK server core features that aims in removing some limitations of the JACK1 design. The activation system has been changed for a data flow model and lock-free programming techniques for graph access have been used to have a more dynamic and robust system. - jackdmp use a new client activation model that allows simultaneous client execution (on a smp machine) when parallel clients exist in the graph (client that have the same inputs). This activation model allows to better use available CPU on a smp machine, but also works on mono-processor machine. - jackdmp use a lock-free way to access (read/write) the client graph, thus allowing connections/disconnection to be done without interrupting the audio stream. The result is that connections/disconnections are glitch-free. -- jackdmp can work in 2 different mode at the server level : +- jackdmp can work in 2 different modes at the server level : - synchronous activation : in a given cycle, the server waits for all clients to be finished (similar to normal jackd) @@ -20,7 +20,7 @@ The audible result of this mode is that if a client is not activated during one Linux version -------------- -The published version still uses fifos for server/client synchronization. The use of POSIX named semaphore is implemented but still a bit unstable. Sockets are used for server/client communications. The ALSA backend derived from jackd implementation is used. To build jackdmp, a "waf" (http://code.google.com/p/waf/) based compilation system is available. The code has to be compiled on a machine where ALSA and possibly frebob (FFADO) headers and libraries are corrected installed. +The published version still uses fifos for server/client synchronization. The use of POSIX named semaphore is implemented but still a bit unstable. Sockets are used for server/client communications. The ALSA backend derived from jackd implementation is used. To build jackdmp, a "waf" (http://code.google.com/p/waf/) based compilation system is available. The code has to be compiled on a machine where ALSA and possibly freeboot (FFADO) headers and libraries are corrected installed. In the top folder do : @@ -54,7 +54,7 @@ In the top folder do : ./waf build sudo ./waf install -(Note : you may have to use "pfexec" instead of "sudo" on systems where sudo is not there.) +(Note : you may have to use "pfexec" instead of "sudo" on systems where sudo is not there). Various compilation options can be seen using ./waf --help. @@ -68,43 +68,37 @@ Starting the server : - for best performances, the server has to be started with privileges that allows to use "real-time" threads, for example using the "pfexec" command (or configurating the system with "priocntl" first), for instance : pfexec jackd -R -S -P59 -d oss -- audio cards info can be retrieved using "ossinfo" tool (for instance ossinfo -v3). Some card needs to be configurated first using "ossxmix" then the correct buffer size has to be used, for instance : pfexec jackd -R -S -P59 -d oss -p 512 +- audio cards info can be retrieved using "ossinfo" tool (for instance ossinfo -v3). Some card needs to be configured first using "ossxmix" then the correct buffer size has to be used, for instance : pfexec jackd -R -S -P59 -d oss -p 512 ------------ OSX version ------------ -The published version uses Mach semaphores for server/client synchronization. MIG generated Remote Procedure Calls (RPC) are used for server/client communications. The CoreAudio backend derived from jackd implementation is used. - -The package contains : - - - the compiled binaries with "install" and "remove" scripts located in bin/osx - - the source code with an XCode project - - the component needed to use CoreAudio applications with JACK (the JackRouter JACK/CoreAudio bridge) +The published version uses Mach semaphores for server/client synchronization. Sockets are used for server/client communications. The CoreAudio backend derived from JACK1 implementation is used. Starting with 0.70 version, the OSX project can compile 32/64 bits binaries for PPC and Intel machines. On a 64 bits machine, using the "jackdmp" in a terminal will start the 64 bits version. Using the "arch" command possibly allows to force starting in 32 bits (see man arch). The JackPilot and JackRouter binaries are now also released as 32/64 bits versions for PPC and Intel machines. By default the JackPilot application will start in 32 bits mode (even on a 64 bits machine) and launch the 32 bits jackdmp. Unchecking the "Launch in 32 bits mode" box in the JackPilot info (GetInfo = %I in the Finder...) allows to start JackPilot in 64 bits then launch the 64 bits jackdmp version. Very few audio applications are already 64 bits aware: Apple AU Lab (included in Developer tools) can be launched in 64 bit, here again by unchecking the "Launch in 32 bits mode" box in the AU Lab info. -WARNING !! WARNING !! - -Users of the "official" JackOSX package (found at www.jackosx.com) MUST uninstall JackOSX (using the script located in /Applications/Jack) before installing and testing jackdmp. The "official" JackOSX package can then be re-installed by using the JackOSX installer again. +JackOSX package (found at www.jackosx.com) is the preferred way to Jackdmp on OSX. --------------------------------- Mac Intel special considerations --------------------------------- -- New Mac Intel use 2 different coreaudio device for input/output. Jackdmp cannot directly handle 2 devices to do duplex processing. An "aggregate" device has to be built in this case. +- New Mac Intel use 2 different CoreAudio device for input/output. Jackdmp cannot directly handle 2 devices to do duplex processing. An "aggregate" device has to be built in this case. Use the "/Applications/Utilities/Audio MIDI Setup" tool to build and aggregate device that combine both input and output in a single duplex device, then select it when launching jackdmp, with something like : jackdmp -R -d coreaudio -n "~:Aggregate:0" -or directly with the JackPilot tool. +or directly with the JackPilot tool. + +Starting from 1.9.6 version, the CoreAudio diver can now dynamically aggregate devices. So using "Audio MIDI Setup" tool is not mandatory anymore. - CoreAudio applications running under Rosetta emulator cannot access an Intel version of Jackdmp. -Using Jackdmp with Qjackctl : +Using jackdmp with QjackCtl : -To start jackdmp server in Qjackctl, the complete server path has to be added, like /usr/local/bin/jackdmp in Setup/Server Path. +To start jackdmp server in QjackCtl, the complete server path has to be added, like /usr/local/bin/jackdmp in Setup/Server Path. ---------------- Windows version @@ -124,7 +118,9 @@ The binary elements are : - jack_dummy.dll : the "dummy" driver. -- jack_net.dll : the NetJack driver. +- jack_net.dll : the NetJack2 driver. + +- jack_netone.dll : the NetJack1 driver. - netmanager.dll : the "in server" client NetJack Manager. @@ -132,13 +128,13 @@ The binary elements are : - netadapter.dll : the network to audio card adapter (to be used on a slave machine started with an audio driver). -- jack_connect.exe, jack_disconnect.exe, jack_lsp.exe, jack_metro.exe, jack_load.exe, jack_unload.exe tools. +- jack_connect.exe, jack_disconnect.exe, jack_lsp.exe, jack_metro.exe, jack_load.exe, jack_unload.exe, jack_netsource.exe tools. -- JackRouter.dll : an ASIO/JACK driver that allows ASIO compatible applications to become JACK clients and access the JACK server. ASIO "jackified" applications appear with their names. Ableton Live, Samplitude, Reason, Arturia applications have been successfully tested. To install it, use "regsvr32 JackRouter.dll" in a terminal (use regsvr32 /u JackRouter.dll to uninstall). [VISTA special note: regsvr32 has to be used with "administrator" priviledges to properly register JackRouter.dll (Start Menu -> All Programs -> Accessories -> Right Click on Command Prompt -> Run As Administrator)]. A JackRouter.ini file is used by the driver to read parameters : an [IO] section allows to setup the number of input/output jack ports for the application and a [AUTO_CONNECT] section allows to setup jack ports autoconnection mode to machine input/output. +- JackRouter.dll : an ASIO/JACK driver that allows ASIO compatible applications to become JACK clients and access the JACK server. ASIO "jackified" applications appear with their names. Ableton Live, Samplitude, Reason, Arturia applications have been successfully tested. To install it, use "regsvr32 JackRouter.dll" in a terminal (use regsvr32 /u JackRouter.dll to uninstall). [VISTA special note: regsvr32 has to be used with "administrator" rights to properly register JackRouter.dll (Start Menu -> All Programs -> Accessories -> Right Click on Command Prompt -> Run As Administrator)]. A JackRouter.ini file is used by the driver to read parameters : an [IO] section allows to setup the number of input/output jack ports for the application and a [AUTO_CONNECT] section allows to setup jack ports auto connection mode to machine input/output. WARNING !! WARNING !! -Depending of the used interface and driver settings, the PortAudio layer may add additionnal buffering between the real card interrupt and the jack server callback. This usually result in *unregular* calls of the jack server callback (for example if jack server used a 256 frames buffer and the card used a 512 frames, the jack server callback will be called twice every card interrupt). For proper functionning of jack server and clients in this case, the jack server has to be started in "synchronous" mode, using the "-S" parameter. +Depending of the used interface and driver settings, the PortAudio layer may add additional buffering between the real card interrupt and the jack server callback. This usually result in *unregular* calls of the jack server callback (for example if jack server used a 256 frames buffer and the card used a 512 frames, the jack server callback will be called twice every card interrupt). For proper functioning of jack server and clients in this case, the jack server has to be started in "synchronous" mode, using the "-S" parameter. ---------------------------- Known problems, limitations @@ -150,7 +146,7 @@ Known problems, limitations Automatic server launch ---------------------------- -Starting from the 0.64 version, automatic server launch from client is implemented : when the server is not yet running, and if the client uses the "jack_client_open" API, the server will be started automatically. The server configuration is saved in a ".jackdrc" file located in the user home folder. The Qjackctl tool allows to save its configuration in this . jackdrc (setting can be done in Qjackctl Setup/Misc). If no configuration file is found, a default setup will be used. +Starting from the 0.64 version, automatic server launch from client is implemented : when the server is not yet running, QjackCtl if the client uses the "jack_client_open" API, the server will be started automatically. The server configuration is saved in a ".jackdrc" file located in the user home folder. The QjackCtl tool allows to save its configuration in this .jackdrc (setting can be done in QjackCtl Setup/Misc). If no configuration file is found, a default setup will be used. WARNING : automatic server launch is not implemented on Windows @@ -158,7 +154,7 @@ WARNING : automatic server launch is not implemented on Windows Validations tools ------------------ -jackdmp can possibly validate client applications by checking they are using the API in a correct manner (calling functions in the right order, correctly desallocating ressources....) and produce a log file. A JACK_CLIENT_DEBUG environment variable must be used to activate client validation : use "export JACK_CLIENT_DEBUG=on". +jackdmp can possibly validate client applications by checking they are using the API in a correct manner (calling functions in the right order, correctly deallocating resources....) and produce a log file. A JACK_CLIENT_DEBUG environment variable must be used to activate client validation : use "export JACK_CLIENT_DEBUG=on". -------------- Documentation @@ -182,7 +178,7 @@ Note : To experiment with the -S option, jackdmp must be launched in a console. 0.42 : Patch from Nick Mainsbridge. Correct default mode for ALSA driver. Correct XCode project. 0.43 : Correct freewheel mode. Optimize ALSA and coreaudio drivers. Correct OSX installation script. 0.44 : Patch from Dmitry Daikov : use clock_gettime by default for timing. Correct dirty buffer issue in CoreAudio driver. Updated doc. -0.45 : Script to remove the OSX binary stuff. Correct an export symbol issue that was preventing Qjacktcl to work on OSX. Fix the consequences of the asynchronous semantic of connections/disconnections. +0.45 : Script to remove the OSX binary stuff. Correct an export symbol issue that was preventing QjackCtl to work on OSX. Fix the consequences of the asynchronous semantic of connections/disconnections. 0.46 : Fix a bug in loop management. Fix a bug in driver loading/unloading code. Internal code cleanup for better 64 bits architecture support. Compilation on OSX/Intel. Add the -d option for coreaudio driver (display CoreAudio devices internal name). 0.47 : More fix for 64 bits compilation. Correct ALSA driver. Create a specific folder for jackdmp drivers. Use /dev/shm as default for fifo and sockets. "Install" and "Remove" script for smoother use with regular jack. 0.48 : Finish software monitoring implementation for ALSA and CoreAudio drivers. Simpler shared library management on OSX. @@ -199,25 +195,26 @@ Note : To experiment with the -S option, jackdmp must be launched in a console. 0.59 : Various fixes in Windows version. Signal handling in the Windows server. Improved JackRouter ASIO/Jack bridge on Windows. Rename global "verbose" in "jack_verbose" to avoid symbol clash with PureData. Add a new cpu testing/loading client. Correct server SetBufferSize in case of failure. Correct PortAudio driver help. Use -D to setup ADDON_DIR on OSX and Linux. Synchronize ALSA backend with jack one. 0.60 : Improve audio driver synchronous code to better handle possible time-out cases. Correct JackWinEnvent::Allocate (handle the ERROR_ALREADY_EXISTS case). Correct JackEngine::ClientExternalNew. 0.61 : Tom Szilagyi memory leak fix in ringbuffer.c. Move client refnum management in JackEngine. Shared_ports renamed to shared_graph. Add call to the init callback (set up using the jack_set_thread_init_callback API) in Real-Time and Notification threads. Define a new 'kActivateClient' notification. New server/client data transfer model to fix a 64 bits system bug. Fix a device name reversal bug in ALSA driver. Implement thread.h API. -0.62 : More client debug code : check if the client is still valid in every JackDebugClient method, check if the library context is still valid in every API call. Uses a time out value of 10 sec in freewheel mode (like jack). More robust activation/deactivation code, especially in case of client crash. New LockAllMemory and UnlockAllMemory functions. Use pthread_attr_setstacksize in JackPosixThread class. Add Pieter Palmers FreeBob driver. Thibault LeMeur ALSA driver patch. Thom Johansen fix for port buffer alignment issues. Better error checking in PortAudio driver. +0.62 : More client debug code : check if the client is still valid in every JackDebugClient method, check if the library context is still valid in every API call. Uses a time out value of 10 sec in freewheel mode (like jack). More robust activation/deactivation code, especially in case of client crash. New LockAllMemory and UnlockAllMemory functions. Use pthread_attr_setstacksize in JackPosixThread class. Add Pieter Palmers FreeBob driver. Thibault LeMeur ALSA driver patch. Thom Johansen fix for port buffer alignment issues. Better error checking in PortAudio driver. 0.63 : Correct back JackAlsaDriver::Read method. Dmitry Baikov patch for JackGraphManager.cpp. Merge JackGraphManager Remove and Release method in a unique Release method. Dmitry Baikov jackmp-time patch : add jack_get_time, jack_time_to_frames, jack_frames_to_time. Add missing -D__SMP__in OSX project. Add new jack_port_set_alias, jack_port_unset_alias and jack_port_get_aliases API. Steven Chamberlain patch to fix jack_port_by_id export. Steven Chamberlain patch to fix jack_port_type. Test for jack_port_type behaviour in jack_test.cpp tool. Add jack_set_client_registration_callback API. Add "callback exiting" and "jack_frame_time" tests in jack_test. 0.64 : Checking in the server to avoid calling the clients if no callback are registered. Correct deprecated jack_set_sample_rate_callback to return 0 instead of -1. Dmitry Baikov buffer size patch. Correct notification for kActivateClient event. Correct JackEngine::ClientCloseAux (when called from JackEngine::ClientExternalOpen). Correct JackWinEvent::Allocate. Automatic client renaming. Add "systemic" latencies management in CoreAudio driver. Automatic server launch. Removes unneeded 'volatile' for JackTransportEngine::fWriteCounter. 0.65 : Fix backend port alias management (renaming in system:xxx). Fix a bug in JackLibClient::Open introduced when adding automatic client renaming. Fix a bug in jack_test. Correct JackShmMem destructor. Correct end case in JackClient::Execute. Correct JackMachSemaphore::Disconnect. Implement server temporary (-T) mode. Make "Rename" a method of JackPort class, call it from driver Attach method. Server/library protocol checking implementation. 0.66 : Internal cleanup. Windows JackRouter.dll version 0.16 : use of "jack_client_open" API to allow automatic client renaming, better Windows VISTA support, new JackRouter.ini file. 0.67 : Correct jack_client_open "status" management. Rename server_name from "default" to "jackdmp_default" to avoid conflict with regular jackd server. Fix a resource leak issue in JackCoreAudioDriver::Close(). Better implement "jack_client_open" when linking a client with the server library. Correct "jack_register_server" in shm.c. Add missing timestamps.c and timestamps.h files. Correctly export public headers in OSX frameworks. Suppress JackEngine::ClientInternalCloseIm method. Use .jackdrc file (instead of .jackdmprc). Install script now creates a link "jackd ==> jackdmp" so that automatic launch can work correctly. Paul Davis patch for -r (--replace-registry) feature. Internal loadable client implementation. Fix JackEngine::Close() method. Windows JackRouter.dll version 0.17: 32 integer sample format. -0.68 : Internal loadable client implementation, winpipe version added. Reorganize jack headers. Improve Linux install/remove scripts. Use LIB_DIR variable for 64 bits related compilation (drivers location). More generic Linux script. Correct jack_acquire_real_time_scheduling on OSX. Merge of Dmitry Baikov MIDI branch. Correct JackGraphManager::GetPortsAux to use port type. Remove JackEngineTiming class: code moved in JackEngineControl. Add midiseq and midisine examples. Cleanup old zombification code. Linux Makefile now install jack headers. Use of JACK_CLIENT_DEBUG environment variable to activate debug client mode. Definition of JACK_LOCATION variable using -D in the Makefile. Restore jack 0.103.0 MIDI API version. Fix a bug in freewheel management in async mode: drivers now receive the kStartFreewheelCallback and kStopFreewheelCallback notifications. Server and user directory related code moved in a JackTools file. Client name rewritting to remove path characters (used in fifo naming). Correct ALSA driver Attach method: internal driver may have changed the buffer_size and sample_rate values. Add JackWinSemaphore class. Add an implementation for obsolete jack_internal_client_new and jack_internal_client_close. Add missing jack_port_type_size. Use of JackWinSemaphore instead of JackWinEvent for inter-process synchronization. Correct types.h for use with MINGW on Windows. Move OSX start/stop notification mechanism in Jackdmp.cpp. Correct CheckPort in JackAPI.cpp. +0.68 : Internal loadable client implementation, winpipe version added. Reorganize jack headers. Improve Linux install/remove scripts. Use LIB_DIR variable for 64 bits related compilation (drivers location). More generic Linux script. Correct jack_acquire_real_time_scheduling on OSX. Merge of Dmitry Baikov MIDI branch. Correct JackGraphManager::GetPortsAux to use port type. Remove JackEngineTiming class: code moved in JackEngineControl. Add midiseq and midisine examples. Cleanup old zombification code. Linux Makefile now install jack headers. Use of JACK_CLIENT_DEBUG environment variable to activate debug client mode. Definition of JACK_LOCATION variable using -D in the Makefile. Restore jack 0.103.0 MIDI API version. Fix a bug in freewheel management in async mode: drivers now receive the kStartFreewheelCallback and kStopFreewheelCallback notifications. Server and user directory related code moved in a JackTools file. Client name rewriting to remove path characters (used in fifo naming). Correct ALSA driver Attach method: internal driver may have changed the buffer_size and sample_rate values. Add JackWinSemaphore class. Add an implementation for obsolete jack_internal_client_new and jack_internal_client_close. Add missing jack_port_type_size. Use of JackWinSemaphore instead of JackWinEvent for inter-process synchronization. Correct types.h for use with MINGW on Windows. Move OSX start/stop notification mechanism in Jackdmp.cpp. Correct CheckPort in JackAPI.cpp. 0.69 : On OSX, use CFNotificationCenterPostNotificationWithOptions with kCFNotificationDeliverImmediately | kCFNotificationPostToAllSessions for server ==> JackRouter plugin notification. On OSX, use jack server name in notification system. Correct fPeriodUsecs computation in JackAudioDriver::SetBufferSize and JackAudioDriver::SetSampleRate. Correct JackMachNotifyChannel::ClientNotify. Correct bug in CoreAudio driver sample rate management. Add a sample_rate change listener in CoreAudio driver. Correct sample_rate management in JackCoreAudioDriver::Open. Better handling in sample_rate change listener. Pieter Palmers FFADO driver and scons based build. Pieter Palmers second new build system: scons and Makefile based build. Tim Blechmann scons patch. Change string management for proper compilation with gcc 4.2.2. JackLog cleanup. Cleanup in CoreAudio driver. Tim Blechmann patch for JackGraphManager::GetPortsAux memory leak, Tim Blechmann patch for scons install. Dmitry Baikov MIDI patch : alsa_seqmidi and alsa_rammidi drivers. CoreAudio driver improvement : detect and notify abnormal situations (stopped driver in case of SR change...). 0.70 : Updated API to match jack 0.109.0 version. Update in usx2y.c and JackPort.cpp to match jackd 0.109.2. Latest jack_lsp code from jack SVN. Add jack_mp_thread_wait client example. Add jack_thread_wait client example. Remove checking thread in CoreAudio driver, better device state change recovery strategy: the driver is stopped and restarted. Move transport related methods from JackEngine to JackServer. Tim Blechmann sse optimization patch for JackaudioPort::MixAudioBuffer, use of Apple Accelerate framework on OSX. Remove use of assert in JackFifo, JackMachSemaphore, and JackPosixSemaphore: print an error instead. Correct "server_connect": close the communication channel. More robust external API. Use SetAlias for port naming. Use jackd midi port naming scheme. Notify ports unregistration in JackEngine::ClientCloseAux. Fix in JackClient::Error(): when RT thread is failing and calling Shutdown, Shutdown was not desactivating the client correctly. 0.71 : Add port register/unregister notification in JackAlsaDriver. Correct JACK_port_unregister in MIDI backend. Add TimeCallback in JackDebugClient class. Correct jack_get_time propotype. Correct JackSocketClientChannel::ClientClose to use ServerSyncCall instead of ServerAsyncCall. Better documentation in jack.h. libjackdmp.so renamed to libjackservermp.so and same for OSX framework. Define an internal jack_client_open_aux needed for library wrapper feature. Remove unneeded jack_port_connect API. Correct jack_port_get_connections function (should return NULL when no connections). In thread model, execute a dummy cycle to be sure thread has the correct properties (ensure thread creation is finished). Fix engine real-time notification (was broken since ??). Implements wrapper layer. Correct jack_port_get_total_latency. Correct all backend playback port latency in case of "asynchronous" mode (1 buffer more). Add test for jack_cycle_wait, jack_cycle_wait and jack_set_process_thread API. RT scheduling for OSX thread (when used in dummy driver). Add -L (extra output latency in aynchronous mode) in CoreAudio driver. New JackLockedEngine decorator class to serialize access from ALSA Midi thread, command thread and in-server clients. Use engine in JackAlsaDriver::port_register and JackAlsaDriver::port_unregister. Fix connect notification to deliver *one* notification only. Correct JackClient::Activate so that first kGraphOrderCallback can be received by the client notification thread. New jack_server_control client to test notifications when linked to the server library. Synchronise transport.h with latest jackd version (Video handling). Transport timebase fix. Dmitry Baikov patch for alsa_rawmidi driver. Pieter Palmers patch for FFADO driver. Add an Init method for blocking drivers to be decorated using JackThreadedDriver class. Correct PortRegister, port name checking must be done on server side. Correct a missing parameter in the usage message of jack_midiseq. New SetNonBlocking method for JackSocket. Correct a dirty port array issue in JackGraphManager::GetPortsAux. 1.9.0 : Waf based build system : Nedko Arnaudov, Grame for preliminary OSX support. Control API, dbus based server control access : Nedko Arnaudov, Grame. NetJack2 components (in progress) : jack_net backend, netmanager, audioadapter, netadapter : Romain Moret, Grame. Code restructuring to help port on other architectures : Michael Voigt. Code cleanup/optimization : Tim Blechmann. Improve handling of server internal clients that can now be loaded/unloaded using the new server control API : Grame. A lot of bug fix and improvements. -1.9.1 : Fix jackctl_server_unload_internal. Filter SIGPIPE to avoid having client get a SIGPIPE when trying to access a died server. Libjack shutdown handler does not "deactivate" (fActive = false) the client anymore, so that jack_deactivate correctly does the job later on. Better isolation of server and clients system resources to allow starting the server in several user account at the same time. Report ringbuffer.c fixes from jack1. Client and library global context cleanup in case of incorrect shutdown handling (that is applications not correctly closing client after server has shutdown). Use JACK_DRIVER_DIR variable in internal clients loader. For ALSA driver, synchronize with latest jack1 memops functions. Synchronize jack2 public headers with jack1 ones. Implement jack_client_real_time_priority and jack_client_max_real_time_priority API. Use up to BUFFER_SIZE_MAX frames in midi ports, fix for ticket #117. Cleanup server starting code for clients directly linked with libjackserver.so. JackMessageBuffer was using thread "Stop" scheme in destructor, now use the safer thread "Kill" way. Synchronize ALSA backend code with JACK1 one. Set default mode to 'slow' in JackNetDriver and JackNetAdapter. Simplify audio packet order verification. Fix JackNetInterface::SetNetBufferSize for socket buffer size computation and JackNetMasterInterface::DataRecv if synch packet is received, various cleanup. Better recovery of network overload situations, now "resynchronize" by skipping cycles.". Support for BIG_ENDIAN machines in NetJack2. Support for BIG_ENDIAN machines in NetJack2 for MIDI ports. Support for "-h" option in internal clients to print the parameters. In NetJack2, fix a bug when capture or playback only channels are used. Add a JACK_INTERNAL_DIR environment variable to be used for internal clients. Add a resample quality parameter in audioadapter. Now correctly return an error if JackServer::SetBufferSize could not change the buffer size (and was just restoring the current one). Use PRIu32 kind of macro in JackAlsaDriver again. Add a resample quality parameter in netadapter. +1.9.1 : Fix jackctl_server_unload_internal. Filter SIGPIPE to avoid having client get a SIGPIPE when trying to access a died server. Libjack shutdown handler does not "deactivate" (fActive = false) the client anymore, so that jack_deactivate correctly does the job later on. Better isolation of server and clients system resources to allow starting the server in several user account at the same time. Report ringbuffer.c fixes from JACK1. Client and library global context cleanup in case of incorrect shutdown handling (that is applications not correctly closing client after server has shutdown). Use JACK_DRIVER_DIR variable in internal clients loader. For ALSA driver, synchronize with latest JACK1 memops functions. Synchronize JACK2 public headers with JACK1 ones. Implement jack_client_real_time_priority and jack_client_max_real_time_priority API. Use up to BUFFER_SIZE_MAX frames in midi ports, fix for ticket #117. Cleanup server starting code for clients directly linked with libjackserver.so. JackMessageBuffer was using thread "Stop" scheme in destructor, now use the safer thread "Kill" way. Synchronize ALSA backend code with JACK1 one. Set default mode to 'slow' in JackNetDriver and JackNetAdapter. Simplify audio packet order verification. Fix JackNetInterface::SetNetBufferSize for socket buffer size computation and JackNetMasterInterface::DataRecv if synch packet is received, various cleanup. Better recovery of network overload situations, now "resynchronize" by skipping cycles.". Support for BIG_ENDIAN machines in NetJack2. Support for BIG_ENDIAN machines in NetJack2 for MIDI ports. Support for "-h" option in internal clients to print the parameters. In NetJack2, fix a bug when capture or playback only channels are used. Add a JACK_INTERNAL_DIR environment variable to be used for internal clients. Add a resample quality parameter in audioadapter. Now correctly return an error if JackServer::SetBufferSize could not change the buffer size (and was just restoring the current one). Use PRIu32 kind of macro in JackAlsaDriver again. Add a resample quality parameter in netadapter. 1.9.2 : Solaris version. New "profiling" tools. Rework the mutex/signal classes. Support for BIG_ENDIAN machines in NetJack2. D-BUS based device reservation to better coexist with PulseAudio on Linux. Add auto_connect parameter in netmanager and netadapter. Use Torben Hohn PI controler code for adapters. Client incorrect re-naming fixed : now done at socket and fifo level. Virtualize and allow overriding of thread creation function, to allow Wine support (from JACK1). 1.9.3 : New JackBoomerDriver class for Boomer driver on Solaris. Add mixed 32/64 bits mode (off by default). Native MIDI backend (JackCoreMidiDriver, JackWinMMEDriver). In ALSA audio card reservation code, tries to open the card even if reservation fails. Clock source setting on Linux. Add jackctl_server_switch_master API. Fix transport callback (timebase master, sync) issue when used after jack_activate (RT thread was not running). D-Bus access for jackctl_server_add_slave/jackctl_server_remove_slave API. Cleanup "loopback" stuff in server. Torben Hohn fix for InitTime and GetMicroSeconds in JackWinTime.c. New jack_free function added in jack.h. Reworked Torben Hohn fix for server restart issue on Windows. Correct jack_set_error_function, jack_set_info_function and jack_set_thread_creator functions. Correct JackFifo::TimedWait for EINTR handling. Move DBus based audio device reservation code in ALSA backend compilation. Correct JackTransportEngine::MakeAllLocating, sync callback has to be called in this case also. NetJack2 code : better error checkout, method renaming. Tim Bechmann patch : hammerfall, only release monitor thread, if it has been created. Tim Bechmann memops.c optimization patches. In combined --dbus and --classic compilation code, use PulseAudio acquire/release code. Big rewrite of Solaris boomer driver, seems to work in duplex mode at least. Loopback backend reborn as a dynamically loadable separated backend. 1.9.4 : Solaris boomer backend now working in capture or playback only mode. Add a -G parameter in CoreAudio backend (the computation value in RT thread expressed as percent of period). Use SNDCTL_DSP_SYNCGROUP/SNDCTL_DSP_SYNCSTART API to synchronize input and output in Solaris boomer backend. Big endian bug fix in memops.c. Fix issues in JackNetDriver::DecodeTransportData and JackNetDriver::Initialize. Correct CPU timing in JackNetDriver, now take cycle begin time after Read. Simplify transport in NetJack2: master only can control transport. Change CoreAudio notification thread setup for OSX Snow Leopard. Correct server temporary mode : now set a global and quit after server/client message handling is finished. Add a string parameter to server ==> client notification, add a new JackInfoShutdownCallback type. CoreAudio backend now issue a JackInfoShutdownCallback when an unrecoverable error is detected (sampling rate change, stream configuration changeÉ). Correct jackdmp.cpp (failures case were not correct..). Improve JackCoreAudioDriver code. Raise default port number to 2048. Correct JackProcessSync::LockedTimedWait. Correct JACK_MESSAGE_SIZE value, particularly in OSX RPC code. Now start server channel thread only when backend has been started (so in JackServer::Start). Should solve race conditions at start time. jack_verbose moved to JackGlobals class. Improve aggregate device management in JackCoreAudioDriver : now a "private" device only and cleanup properly. Aggregate device code added to JackCoreAudioAdapter. Implement "hog mode" (exclusive access of the audio device) in JackCoreAudioDriver. Fix jack_set_sample_rate_callback to have he same behavior as in JACK1. Dynamic system version detection in JackCoreAudioDriver to either create public or private aggregate device. In JackCoreAudioDriver, force the SR value to the wanted one *before* creating aggregate device (otherwise creation will fail). In JackCoreAudioDriver, better cleanup of AD when intermediate open failure. In JackCoreAudioDriver::Start, wait for the audio driver to effectively start (use the MeasureCallback). In JackCoreAudioDriver, improve management of input/output channels: -1 is now used internally to indicate a wanted max value. In JackCoreAudioDriver::OpenAUHAL, correct stream format setup and cleanup. Correct crash bug in JackAudioAdapterInterface when not input is used in adapter (temporary fixÉ). Sync JackCoreAudioAdapter code on JackCoreAudioDriver one. JACK_SCHED_POLICY switched to SCHED_FIFO. Now can aggregate device that are themselves AD. No reason to make jack_on_shutdown deprecated, so revert the incorrect change. Thread AcquireRealTime and DropRealTime were (incorrectly) using fThread field. Use pthread_self()) (or GetCurrentThread() on Windows) to get the calling thread. Correctly save and restore RT mode state in freewheel mode. Correct freewheel code on client side. Fix AcquireRealTime and DropRealTime: now distinguish when called from another thread (AcquireRealTime/DropRealTime) and from the thread itself (AcquireSelfRealTime/DropSelfRealTime). Correct JackPosixThread::StartImp : thread priority setting now done in the RT case only. Correct JackGraphManager::GetBuffer for the "client loop with one connection" case : buffer must be copied. Correct JackInfoShutdownCallback prototype, two new JackClientProcessFailure and JackClientZombie JackStatus code. Correct JackCoreAudio driver when empty strings are given as -C, -P or -d parameter. Better memory allocation error checking on client (library) side. Better memory allocation error checking in ringbuffer.c, weak import improvements. Memory allocation error checking for jack_client_new and jack_client_open (server and client side). Memory allocation error checking in server for RPC. Simplify server temporary mode : now use a JackTemporaryException. Lock/Unlock shared memory segments (to test...). Sync with JACK1 : -r parameter now used for no-realtime, realtime (-R) is now default, usable backend given vie platform. In JackCoreAudio driver, (possibly) clock drift compensation when needed in aggregated devices. In JackCoreAudio driver, clock drift compensation in aggregated devices working. In JackCoreAudio driver, clock drift compensation semantic changed a bit : when on, does not activate if not needed (same clock domain). Sync JackCoreAudioAdapter code with JackCoreAudioDriver. 1.9.5 : Dynamic choice of maximum port number. More robust sample rate change handling code in JackCoreAudioDriver. Devin Anderson patch for Jack FFADO driver issues with lost MIDI bytes between periods (and more). Fix port_rename callback : now both old name and new name are given as parameters. Special code in JackCoreAudio driver to handle completely buggy Digidesign CoreAudio user-land driver. Ensure that client-side message buffer thread calls thread_init callback if/when it is set by the client (backport of JACK1 rev 3838). Check dynamic port-max value. Fix JackCoreMidiDriver::ReadProcAux when ring buffer is full (thanks Devin Anderson). Josh Green ALSA driver capture only patch. When threads are cancelled, the exception has to be rethrown. Use a QUIT notification to properly quit the server channel, the server channel thread can then be 'stopped' instead of 'canceled'. Mario Lang alsa_io time calculation overflow patch. Shared memory manager was calling abort in case of fatal error, now return an error in caller. Change JackEngineProfiling and JackAudioAdapterInterface gnuplot scripts to output SVG instead of PDF. 1.9.6 : Improve JackCoreAudioDriver and JackCoreAudioAdapter : when no devices are described, takes default input and output and aggregate them.Correct JackGraphManager::DeactivatePort. Correct JackMachServerChannel::Execute : keep running even in error cases. Raise JACK_PROTOCOL_VERSION number. Arnold Krille firewire patch. Raise JACK_DRIVER_PARAM_STRING_MAX and JACK_PARAM_STRING_MAX to 127 otherwise some audio drivers cannot be loaded on OSX. Fix some file header to have library side code use LGPL. On Windows, now use TRE library for regexp (BSD license instead of GPL license). ffado-portname-sync.patch from ticket #163 applied. Remove call to exit in library code. Make jack_connect/jack_disconnect wait for effective port connection/disconnection. Add tests to validate intclient.h API. On Linux, inter-process synchronization primitive switched to POSIX semaphore. In JackCoreAudioDriver, move code called in MeasureCallback to be called once in IO thread. David Garcia Garzon netone patch. Fix from Fernando Lopez-Lezcano for compilation on fc13. Fix JackPosixSemaphore::TimedWait : same behavior as JackPosixSemaphore::Wait regarding EINTR. David Garcia Garzon unused_pkt_buf_field_jack2 netone patch. Arnold Krille firewire snooping patch. Jan Engelhardt patch for get_cycles on SPARC. Adrian Knoth hurd.patch, kfreebsd-fix.patch and alpha_ia64-sigsegv.patch from ticket 177. Adrian Knoth fix for linux cycle.h (ticket 188). In JackCoreAudioDriver, fix an issue when no value is given for input. +1.9.7 : Sync JackAlsaDriver::alsa_driver_check_card_type with JACK1 backend. Correct JackServer::Open to avoid a race when control API is used on OSX. Improve backend error handling: fatal error returned by Read/Write now cause a Process failure (so a thread exit for blocking backends). Recoverable ones (XRuns..) are now treated internally in ALSA, FreeBob and FFADO backends. In jackdmp.cpp, jackctl_setup_signals moved before jackctl_server_start. Correct symbols export in backends on OSX. ALSA backend : suspend/resume handling. Correct dummy driver. Adrian Knoth jack_lsp patch. Remove JackPortIsActive flag. New latency API implementation. ComputeTotalLatencies now a client/server call. Add latent test client for latency API. Also print playback and capture latency in jack_lsp. jack_client_has_session_callback implementation. Check requested buffer size and limit to 1..8192 - avoids weird behaviour caused by jack_bufsize foobar. jack_port_type_get_buffer_size implementation. Stop using alloca and allocate buffer on the heap for alsa_io. Rename jdelay to jack_iodelay as per Fons' request. Call buffer size callback in activate (actually this is done on client side in the RT thread Init method). Add jack_midi_dump client. Synchronize net JACK1 with JACK1 version. Synchronize jack_connect/jack_disconnect with JACK1 version. Correct JackNetMaster::SetBufferSize. Use jack_default_audio_sample_t instead of float consistently, fix ticket #201. -X now allows to add several slave backends, add -I to load several internal clients. Rework internal slave driver management, JackServerGlobals now handle same parameters as jackdmp. Correct JackEngine::NotifyGraphReorder, update JackDebugClient with latest API. Devin Anderson server-ctl-proposal branch merged on trunk: improved control API, slave backend reworked. Implement renaming in JackDriver::Open to avoid name collision (thanks Devin Anderson). Correct alsa_driver_restart (thanks Devin Anderson). Correction of jack_connect/jack_disconnect: use of jack_activate and volatile keyword for thread shared variable. Correction of JackNetOneDriver for latest CELT API. Synchronize JackWeakAPI.cpp with new APIs. -This is a work in progress but the implementation is now stable enough to be tested. jackdmp has been used successfully with the following applications : Ardour, Hydrogen, Jamin, Qjackctl, Jack-Rack, SooperLooper, AlsaPlayer... +This is a work in progress but the implementation is now stable enough to be tested. jackdmp has been used successfully with the following applications : Ardour, Hydrogen, Jamin, QjackCtl, Jack-Rack, SooperLooper, AlsaPlayer... ------------------------------------ General known problems, limitations @@ -225,9 +222,7 @@ General known problems, limitations - zombification of clients is not implemented -- the number of server audio ports is fixed - -- memory locking is not implemented +- memory locking is implemented for shared data only The package is available at http://www.grame.fr/~letz/jackdmp.html diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index 550133cb..5c0d4cb1 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -116,7 +116,7 @@ extern "C" EXPORT int jack_set_xrun_callback(jack_client_t *, JackXRunCallback xrun_callback, void *arg); EXPORT int jack_set_latency_callback(jack_client_t *client, - JackLatencyCallback callback, void *arg); + JackLatencyCallback latency_callback, void *arg); EXPORT int jack_activate(jack_client_t *client); EXPORT int jack_deactivate(jack_client_t *client); diff --git a/common/JackAudioAdapter.cpp b/common/JackAudioAdapter.cpp index 03f4605f..9319b0f7 100644 --- a/common/JackAudioAdapter.cpp +++ b/common/JackAudioAdapter.cpp @@ -36,17 +36,17 @@ namespace Jack int JackAudioAdapter::Process (jack_nframes_t frames, void* arg) { JackAudioAdapter* adapter = static_cast(arg); - float* inputBuffer[adapter->fAudioAdapter->GetInputs()]; - float* outputBuffer[adapter->fAudioAdapter->GetOutputs()]; + jack_default_audio_sample_t* inputBuffer[adapter->fAudioAdapter->GetInputs()]; + jack_default_audio_sample_t* outputBuffer[adapter->fAudioAdapter->GetOutputs()]; // Always clear output for (int i = 0; i < adapter->fAudioAdapter->GetInputs(); i++) { - inputBuffer[i] = (float*)jack_port_get_buffer(adapter->fCapturePortList[i], frames); - memset(inputBuffer[i], 0, frames * sizeof(float)); + inputBuffer[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(adapter->fCapturePortList[i], frames); + memset(inputBuffer[i], 0, frames * sizeof(jack_default_audio_sample_t)); } for (int i = 0; i < adapter->fAudioAdapter->GetOutputs(); i++) { - outputBuffer[i] = (float*)jack_port_get_buffer(adapter->fPlaybackPortList[i], frames); + outputBuffer[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(adapter->fPlaybackPortList[i], frames); } adapter->fAudioAdapter->PullAndPush(inputBuffer, outputBuffer, frames); diff --git a/common/JackAudioAdapterInterface.h b/common/JackAudioAdapterInterface.h index a661598f..9573a68d 100644 --- a/common/JackAudioAdapterInterface.h +++ b/common/JackAudioAdapterInterface.h @@ -88,18 +88,18 @@ namespace Jack JackResampler** fCaptureRingBuffer; JackResampler** fPlaybackRingBuffer; - + unsigned int fQuality; unsigned int fRingbufferCurSize; jack_time_t fPullAndPushTime; - + bool fRunning; bool fAdaptative; - + void ResetRingBuffers(); void AdaptRingBufferSize(); void GrowRingBufferSize(); - + public: JackAudioAdapterInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate, jack_nframes_t ring_buffer_size = DEFAULT_ADAPTATIVE_SIZE): @@ -140,15 +140,15 @@ namespace Jack {} virtual void Reset(); - + virtual void Create(); virtual void Destroy(); - + virtual int Open() { return 0; } - + virtual int Close() { return 0; @@ -157,7 +157,7 @@ namespace Jack virtual int SetHostBufferSize ( jack_nframes_t buffer_size ) { fHostBufferSize = buffer_size; - if (fAdaptative) + if (fAdaptative) AdaptRingBufferSize(); return 0; } @@ -165,7 +165,7 @@ namespace Jack virtual int SetAdaptedBufferSize ( jack_nframes_t buffer_size ) { fAdaptedBufferSize = buffer_size; - if (fAdaptative) + if (fAdaptative) AdaptRingBufferSize(); return 0; } @@ -197,7 +197,7 @@ namespace Jack SetAdaptedSampleRate ( sample_rate ); return 0; } - + void SetInputs ( int inputs ) { jack_log ( "JackAudioAdapterInterface::SetInputs %d", inputs ); @@ -222,8 +222,8 @@ namespace Jack return fPlaybackChannels; } - int PushAndPull(float** inputBuffer, float** outputBuffer, unsigned int frames); - int PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int frames); + int PushAndPull(jack_default_audio_sample_t** inputBuffer, jack_default_audio_sample_t** outputBuffer, unsigned int frames); + int PullAndPush(jack_default_audio_sample_t** inputBuffer, jack_default_audio_sample_t** outputBuffer, unsigned int frames); }; diff --git a/common/JackAudioDriver.cpp b/common/JackAudioDriver.cpp index 1e02f213..272c1e66 100644 --- a/common/JackAudioDriver.cpp +++ b/common/JackAudioDriver.cpp @@ -138,14 +138,13 @@ int JackAudioDriver::Attach() // Monitor ports if (fWithMonitorPorts) { - jack_log("Create monitor port "); + jack_log("Create monitor port"); snprintf(name, sizeof(name) - 1, "%s:monitor_%u", fClientControl.fName, i + 1); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("Cannot register monitor port for %s", name); return -1; } else { port = fGraphManager->GetPort(port_index); - port->SetAlias(alias); range.min = range.max = fEngineControl->fBufferSize; port->SetLatencyRange(JackCaptureLatency, &range); fMonitorPortList[i] = port_index; @@ -178,8 +177,8 @@ int JackAudioDriver::Write() { for (int i = 0; i < fPlaybackChannels; i++) { if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) { - float* buffer = GetOutputBuffer(i); - int size = sizeof(float) * fEngineControl->fBufferSize; + jack_default_audio_sample_t* buffer = GetOutputBuffer(i); + int size = sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize; // Monitor ports if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[i]) > 0) memcpy(GetMonitorBuffer(i), buffer, size); @@ -313,6 +312,26 @@ int JackAudioDriver::ProcessGraphSync() return res; } +int JackAudioDriver::Start() +{ + int res = JackDriver::Start(); + if ((res >= 0) && fIsMaster) { + res = StartSlaves(); + } + return res; +} + +int JackAudioDriver::Stop() +{ + int res = JackDriver::Stop(); + if (fIsMaster) { + if (StopSlaves() < 0) { + res = -1; + } + } + return res; +} + void JackAudioDriver::WaitUntilNextCycle() { int wait_time_usec = (int((float(fEngineControl->fBufferSize) / (float(fEngineControl->fSampleRate))) * 1000000.0f)); diff --git a/common/JackAudioDriver.h b/common/JackAudioDriver.h index 3127f4c1..8eaca692 100644 --- a/common/JackAudioDriver.h +++ b/common/JackAudioDriver.h @@ -92,6 +92,9 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver virtual int Attach(); virtual int Detach(); + virtual int Start(); + virtual int Stop(); + virtual int Write(); virtual int SetBufferSize(jack_nframes_t buffer_size); diff --git a/common/JackAudioPort.cpp b/common/JackAudioPort.cpp index c006b1cf..25483181 100644 --- a/common/JackAudioPort.cpp +++ b/common/JackAudioPort.cpp @@ -38,11 +38,11 @@ static void AudioBufferInit(void* buffer, size_t buffer_size, jack_nframes_t) memset(buffer, 0, buffer_size); } -static inline void MixAudioBuffer(float* mixbuffer, float* buffer, jack_nframes_t frames) +static inline void MixAudioBuffer(jack_default_audio_sample_t* mixbuffer, jack_default_audio_sample_t* buffer, jack_nframes_t frames) { #ifdef __APPLE__ // It seems that a vector mult only operation does not exist... - float gain = 1.0f; + jack_default_audio_sample_t gain = jack_default_audio_sample_t(1.0); vDSP_vsma(buffer, 1, &gain, mixbuffer, 1, mixbuffer, 1, frames); #else jack_nframes_t frames_group = frames / 4; @@ -57,14 +57,14 @@ static inline void MixAudioBuffer(float* mixbuffer, float* buffer, jack_nframes_ buffer += 4; frames_group--; #else - register float mixFloat1 = *mixbuffer; - register float sourceFloat1 = *buffer; - register float mixFloat2 = *(mixbuffer + 1); - register float sourceFloat2 = *(buffer + 1); - register float mixFloat3 = *(mixbuffer + 2); - register float sourceFloat3 = *(buffer + 2); - register float mixFloat4 = *(mixbuffer + 3); - register float sourceFloat4 = *(buffer + 3); + register jack_default_audio_sample_t mixFloat1 = *mixbuffer; + register jack_default_audio_sample_t sourceFloat1 = *buffer; + register jack_default_audio_sample_t mixFloat2 = *(mixbuffer + 1); + register jack_default_audio_sample_t sourceFloat2 = *(buffer + 1); + register jack_default_audio_sample_t mixFloat3 = *(mixbuffer + 2); + register jack_default_audio_sample_t sourceFloat3 = *(buffer + 2); + register jack_default_audio_sample_t mixFloat4 = *(mixbuffer + 3); + register jack_default_audio_sample_t sourceFloat4 = *(buffer + 3); buffer += 4; frames_group--; @@ -84,8 +84,8 @@ static inline void MixAudioBuffer(float* mixbuffer, float* buffer, jack_nframes_ } while (frames > 0) { - register float mixFloat1 = *mixbuffer; - register float sourceFloat1 = *buffer; + register jack_default_audio_sample_t mixFloat1 = *mixbuffer; + register jack_default_audio_sample_t sourceFloat1 = *buffer; buffer++; frames--; mixFloat1 += sourceFloat1; @@ -104,8 +104,8 @@ static void AudioBufferMixdown(void* mixbuffer, void** src_buffers, int src_coun jack_nframes_t frames_group = nframes / 4; jack_nframes_t remaining_frames = nframes % 4; - float * source = static_cast(src_buffers[0]); - float * target = static_cast(mixbuffer); + jack_default_audio_sample_t * source = static_cast(src_buffers[0]); + jack_default_audio_sample_t * target = static_cast(mixbuffer); while (frames_group > 0) { @@ -120,19 +120,19 @@ static void AudioBufferMixdown(void* mixbuffer, void** src_buffers, int src_coun target[i] = source[i]; #else - memcpy(mixbuffer, src_buffers[0], nframes * sizeof(float)); + memcpy(mixbuffer, src_buffers[0], nframes * sizeof(jack_default_audio_sample_t)); #endif // Mix remaining buffers for (int i = 1; i < src_count; ++i) { buffer = src_buffers[i]; - MixAudioBuffer(static_cast(mixbuffer), static_cast(buffer), nframes); + MixAudioBuffer(static_cast(mixbuffer), static_cast(buffer), nframes); } } static size_t AudioBufferSize() { - return GetEngineControl()->fBufferSize * sizeof(float); + return GetEngineControl()->fBufferSize * sizeof(jack_default_audio_sample_t); } const JackPortType gAudioPortType = diff --git a/common/JackClient.cpp b/common/JackClient.cpp index ae244688..8c3c6de5 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -496,8 +496,8 @@ bool JackClient::Init() // Setup RT if (GetEngineControl()->fRealTime) { - if (fThread.AcquireRealTime(GetEngineControl()->fClientPriority) < 0) { - jack_error("JackClient::AcquireRealTime error"); + if (fThread.AcquireSelfRealTime(GetEngineControl()->fClientPriority) < 0) { + jack_error("JackClient::AcquireSelfRealTime error"); } } diff --git a/common/JackClient.h b/common/JackClient.h index 230edf53..a03e17d2 100644 --- a/common/JackClient.h +++ b/common/JackClient.h @@ -44,7 +44,7 @@ struct JackEngineControl; \brief The base class for clients: share part of the implementation for JackInternalClient and JackLibClient. */ -class JackClient : public JackClientInterface, public JackRunnableInterface +class SERVER_EXPORT JackClient : public JackClientInterface, public JackRunnableInterface { friend class JackDebugClient; @@ -195,15 +195,15 @@ class JackClient : public JackClientInterface, public JackRunnableInterface // RT Thread jack_nframes_t CycleWait(); void CycleSignal(int status); - int SetProcessThread(JackThreadCallback fun, void *arg); + virtual int SetProcessThread(JackThreadCallback fun, void *arg); // Session API virtual jack_session_command_t* SessionNotify(const char* target, jack_session_event_type_t type, const char* path); virtual int SessionReply(jack_session_event_t* ev); - char* GetUUIDForClientName(const char* client_name); - char* GetClientNameByUUID(const char* uuid); - int ReserveClientName(const char* client_name, const char* uuid); - int ClientHasSessionCallback(const char* client_name); + virtual char* GetUUIDForClientName(const char* client_name); + virtual char* GetClientNameByUUID(const char* uuid); + virtual int ReserveClientName(const char* client_name, const char* uuid); + virtual int ClientHasSessionCallback(const char* client_name); // JackRunnableInterface interface bool Init(); diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index cd0ec2bf..4ff69adc 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -78,15 +78,15 @@ struct jackctl_server /* int32_t, msecs; if zero, use period size. */ union jackctl_parameter_value client_timeout; union jackctl_parameter_value default_client_timeout; - + /* uint32_t, clock source type */ union jackctl_parameter_value clock_source; union jackctl_parameter_value default_clock_source; - + /* uint32_t, max port number */ union jackctl_parameter_value port_max; union jackctl_parameter_value default_port_max; - + /* bool */ union jackctl_parameter_value replace_registry; union jackctl_parameter_value default_replace_registry; @@ -366,7 +366,7 @@ jackctl_internals_load( } while (descriptor_node_ptr != NULL) - { + { internal_ptr = (struct jackctl_internal *)malloc(sizeof(struct jackctl_internal)); if (internal_ptr == NULL) { @@ -450,21 +450,21 @@ sigset_t jackctl_setup_signals( unsigned int flags) { - if ((waitEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) { + if ((waitEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) { jack_error("CreateEvent fails err = %ld", GetLastError()); return 0; } - (void) signal(SIGINT, do_nothing_handler); + (void) signal(SIGINT, do_nothing_handler); (void) signal(SIGABRT, do_nothing_handler); (void) signal(SIGTERM, do_nothing_handler); - return (sigset_t)waitEvent; + return (sigset_t)waitEvent; } void jackctl_wait_signals(sigset_t signals) { - if (WaitForSingleObject(waitEvent, INFINITE) != WAIT_OBJECT_0) { + if (WaitForSingleObject(waitEvent, INFINITE) != WAIT_OBJECT_0) { jack_error("WaitForSingleObject fails err = %ld", GetLastError()); } } @@ -539,7 +539,7 @@ jackctl_setup_signals( * explicitly reset it */ - pthread_sigmask(SIG_BLOCK, &signals, 0); + pthread_sigmask(SIG_BLOCK, &signals, 0); /* install a do-nothing handler because otherwise pthreads behaviour is undefined when we enter sigwait. @@ -745,7 +745,7 @@ EXPORT jackctl_server_t * jackctl_server_create( { goto fail_free_parameters; } - + value.ui = PORT_NUM; if (jackctl_add_parameter( &server_ptr->parameters, @@ -795,7 +795,7 @@ EXPORT jackctl_server_t * jackctl_server_create( { goto fail_free_parameters; } - + /* Allowed to fail */ jackctl_internals_load(server_ptr); @@ -826,6 +826,11 @@ EXPORT const JSList * jackctl_server_get_drivers_list(jackctl_server *server_ptr EXPORT bool jackctl_server_stop(jackctl_server *server_ptr) { server_ptr->engine->Stop(); + return true; +} + +EXPORT bool jackctl_server_close(jackctl_server *server_ptr) +{ server_ptr->engine->Close(); delete server_ptr->engine; @@ -853,7 +858,7 @@ EXPORT const JSList * jackctl_server_get_parameters(jackctl_server *server_ptr) } EXPORT bool -jackctl_server_start( +jackctl_server_open( jackctl_server *server_ptr, jackctl_driver *driver_ptr) { @@ -882,7 +887,7 @@ jackctl_server_start( if (!server_ptr->realtime.b && server_ptr->client_timeout.i == 0) server_ptr->client_timeout.i = 500; /* 0.5 sec; usable when non realtime. */ - + /* check port max value before allocating server */ if (server_ptr->port_max.ui > PORT_NUM_MAX) { jack_error("JACK server started with too much ports %d (when port max can be %d)", server_ptr->port_max.ui, PORT_NUM_MAX); @@ -896,7 +901,7 @@ jackctl_server_start( server_ptr->client_timeout.i, server_ptr->realtime.b, server_ptr->realtime_priority.i, - server_ptr->port_max.ui, + server_ptr->port_max.ui, server_ptr->verbose.b, (jack_timer_type_t)server_ptr->clock_source.ui, server_ptr->name.str); @@ -913,18 +918,8 @@ jackctl_server_start( goto fail_delete; } - rc = server_ptr->engine->Start(); - if (rc < 0) - { - jack_error("JackServer::Start() failed with %d", rc); - goto fail_close; - } - return true; -fail_close: - server_ptr->engine->Close(); - fail_delete: delete server_ptr->engine; server_ptr->engine = NULL; @@ -946,6 +941,19 @@ fail: return false; } +EXPORT bool +jackctl_server_start( + jackctl_server *server_ptr) +{ + int rc = server_ptr->engine->Start(); + bool result = rc >= 0; + if (! result) + { + jack_error("JackServer::Start() failed with %d", rc); + } + return result; +} + EXPORT const char * jackctl_driver_get_name(jackctl_driver *driver_ptr) { return driver_ptr->desc_ptr->name; @@ -1179,7 +1187,7 @@ EXPORT bool jackctl_server_load_internal( { int status; if (server_ptr->engine != NULL) { - server_ptr->engine->InternalClientLoad(internal->desc_ptr->name, internal->desc_ptr->name, internal->set_parameters, JackNullOption, &internal->refnum, -1, &status); + server_ptr->engine->InternalClientLoad2(internal->desc_ptr->name, internal->desc_ptr->name, internal->set_parameters, JackNullOption, &internal->refnum, -1, &status); return (internal->refnum > 0); } else { return false; @@ -1192,6 +1200,7 @@ EXPORT bool jackctl_server_unload_internal( { int status; if (server_ptr->engine != NULL && internal->refnum > 0) { + // Client object is internally kept in JackEngine, and will be desallocated in InternalClientUnload return ((server_ptr->engine->GetEngine()->InternalClientUnload(internal->refnum, &status)) == 0); } else { return false; @@ -1201,8 +1210,13 @@ EXPORT bool jackctl_server_unload_internal( EXPORT bool jackctl_server_add_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr) { if (server_ptr->engine != NULL) { - driver_ptr->info = server_ptr->engine->AddSlave(driver_ptr->desc_ptr, driver_ptr->set_parameters); - return (driver_ptr->info != 0); + if (server_ptr->engine->IsRunning()) { + jack_error("cannot add a slave in a running server"); + return false; + } else { + driver_ptr->info = server_ptr->engine->AddSlave(driver_ptr->desc_ptr, driver_ptr->set_parameters); + return (driver_ptr->info != 0); + } } else { return false; } @@ -1211,9 +1225,14 @@ EXPORT bool jackctl_server_add_slave(jackctl_server * server_ptr, jackctl_driver EXPORT bool jackctl_server_remove_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr) { if (server_ptr->engine != NULL) { - server_ptr->engine->RemoveSlave(driver_ptr->info); - delete driver_ptr->info; - return true; + if (server_ptr->engine->IsRunning()) { + jack_error("cannot remove a slave from a running server"); + return false; + } else { + server_ptr->engine->RemoveSlave(driver_ptr->info); + delete driver_ptr->info; + return true; + } } else { return false; } diff --git a/common/JackControlAPI.h b/common/JackControlAPI.h index d0b0cbc1..8e87d513 100644 --- a/common/JackControlAPI.h +++ b/common/JackControlAPI.h @@ -101,13 +101,21 @@ jackctl_server_get_drivers_list( jackctl_server_t * server); EXPORT bool -jackctl_server_start( +jackctl_server_open( jackctl_server_t * server, jackctl_driver_t * driver); +EXPORT bool +jackctl_server_start( + jackctl_server_t * server); + EXPORT bool jackctl_server_stop( - jackctl_server_t * server); + jackctl_server_t * server); + +EXPORT bool +jackctl_server_close( + jackctl_server_t * server); EXPORT const JSList * jackctl_server_get_parameters( diff --git a/common/JackDebugClient.cpp b/common/JackDebugClient.cpp index 3c389abc..a1a2fe69 100644 --- a/common/JackDebugClient.cpp +++ b/common/JackDebugClient.cpp @@ -505,6 +505,54 @@ int JackDebugClient::SetPortRenameCallback(JackPortRenameCallback callback, void return fClient->SetPortRenameCallback(callback, arg); } +int JackDebugClient::SetSessionCallback(JackSessionCallback callback, void *arg) +{ + CheckClient("SetSessionCallback"); + return fClient->SetSessionCallback(callback, arg); +} + +int JackDebugClient::SetLatencyCallback(JackLatencyCallback callback, void *arg) +{ + CheckClient("SetLatencyCallback"); + return fClient->SetLatencyCallback(callback, arg); +} + +jack_session_command_t* JackDebugClient::SessionNotify(const char* target, jack_session_event_type_t type, const char* path) +{ + CheckClient("SessionNotify"); + return fClient->SessionNotify(target, type, path); +} + +int JackDebugClient::SessionReply(jack_session_event_t* ev) +{ + CheckClient("SessionReply"); + return fClient->SessionReply(ev); +} + +char* JackDebugClient::GetUUIDForClientName(const char* client_name) +{ + CheckClient("GetUUIDForClientName"); + return fClient->GetUUIDForClientName(client_name); +} + +char* JackDebugClient::GetClientNameByUUID(const char* uuid) +{ + CheckClient("GetClientNameByUUID"); + return fClient->GetClientNameByUUID(uuid); +} + +int JackDebugClient::ReserveClientName(const char* client_name, const char* uuid) +{ + CheckClient("ReserveClientName"); + return fClient->ReserveClientName(client_name, uuid); +} + +int JackDebugClient::ClientHasSessionCallback(const char* client_name) +{ + CheckClient("ClientHasSessionCallback"); + return fClient->ClientHasSessionCallback(client_name); +} + JackClientControl* JackDebugClient::GetClientControl() const { CheckClient("GetClientControl"); diff --git a/common/JackDebugClient.h b/common/JackDebugClient.h index 6a19deca..465d9465 100644 --- a/common/JackDebugClient.h +++ b/common/JackDebugClient.h @@ -46,7 +46,7 @@ PortFollower; \brief A "decorator" debug client to validate API use. */ -class JackDebugClient : public JackClient +class SERVER_EXPORT JackDebugClient : public JackClient { protected: @@ -121,6 +121,8 @@ class JackDebugClient : public JackClient int SetPortRegistrationCallback(JackPortRegistrationCallback callback, void* arg); int SetPortConnectCallback(JackPortConnectCallback callback, void *arg); int SetPortRenameCallback(JackPortRenameCallback callback, void *arg); + int SetSessionCallback(JackSessionCallback callback, void *arg); + int SetLatencyCallback(JackLatencyCallback callback, void *arg); // Internal clients char* GetInternalClientName(int ref); @@ -128,6 +130,14 @@ class JackDebugClient : public JackClient int InternalClientLoad(const char* client_name, jack_options_t options, jack_status_t* status, jack_varargs_t* va); void InternalClientUnload(int ref, jack_status_t* status); + // Session API + jack_session_command_t* SessionNotify(const char* target, jack_session_event_type_t type, const char* path); + int SessionReply(jack_session_event_t* ev); + char* GetUUIDForClientName(const char* client_name); + char* GetClientNameByUUID(const char* uuid); + int ReserveClientName(const char* client_name, const char* uuid); + int ClientHasSessionCallback(const char* client_name); + JackClientControl* GetClientControl() const; void CheckClient(const char* function_name) const; diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index a2c6ccd6..ce860468 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -47,6 +47,7 @@ JackDriver::JackDriver(const char* name, const char* alias, JackLockedEngine* en fBeginDateUst = 0; fDelayedUsecs = 0.f; fIsMaster = true; + fIsRunning = false; } JackDriver::JackDriver() @@ -56,6 +57,7 @@ JackDriver::JackDriver() fGraphManager = NULL; fBeginDateUst = 0; fIsMaster = true; + fIsRunning = false; } JackDriver::~JackDriver() @@ -80,7 +82,7 @@ int JackDriver::Open() return 0; } -int JackDriver::Open (bool capturing, +int JackDriver::Open(bool capturing, bool playing, int inchannels, int outchannels, @@ -93,6 +95,15 @@ int JackDriver::Open (bool capturing, jack_log("JackDriver::Open capture_driver_name = %s", capture_driver_name); jack_log("JackDriver::Open playback_driver_name = %s", playback_driver_name); int refnum = -1; + char name_res[JACK_CLIENT_NAME_SIZE + 1]; + int status; + + // Check name and possibly rename + if (fEngine->ClientCheck(fClientControl.fName, -1, name_res, JACK_PROTOCOL_VERSION, (int)JackNullOption, (int*)&status) < 0) { + jack_error("Client name = %s conflits with another running client", fClientControl.fName); + return -1; + } + strcpy(fClientControl.fName, name_res); if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) { jack_error("Cannot allocate internal client for driver"); @@ -135,6 +146,15 @@ int JackDriver::Open(jack_nframes_t buffer_size, jack_log("JackDriver::Open capture_driver_name = %s", capture_driver_name); jack_log("JackDriver::Open playback_driver_name = %s", playback_driver_name); int refnum = -1; + char name_res[JACK_CLIENT_NAME_SIZE + 1]; + int status; + + // Check name and possibly rename + if (fEngine->ClientCheck(fClientControl.fName, -1, name_res, JACK_PROTOCOL_VERSION, (int)JackNullOption, (int*)&status) < 0) { + jack_error("Client name = %s conflits with another running client", fClientControl.fName); + return -1; + } + strcpy(fClientControl.fName, name_res); if (fEngine->ClientInternalOpen(fClientControl.fName, &refnum, &fEngineControl, &fGraphManager, this, false) != 0) { jack_error("Cannot allocate internal client for driver"); @@ -288,6 +308,7 @@ int JackDriver::ProcessSlaves() JackDriverInterface* slave = *it; if (slave->Process() < 0) res = -1; + } return res; } @@ -324,15 +345,49 @@ int JackDriver::Write() int JackDriver::Start() { - fEngineControl->InitFrameTime(); + if (fIsMaster) { + fEngineControl->InitFrameTime(); + } + fIsRunning = true; return 0; } +int JackDriver::StartSlaves() +{ + int res = 0; + list::const_iterator it; + for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { + JackDriverInterface* slave = *it; + if (slave->Start() < 0) { + res = -1; + + // XXX: We should attempt to stop all of the slaves that we've + // started here. + + break; + } + } + return res; +} + int JackDriver::Stop() { + fIsRunning = false; return 0; } +int JackDriver::StopSlaves() +{ + int res = 0; + list::const_iterator it; + for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { + JackDriverInterface* slave = *it; + if (slave->Stop() < 0) + res = -1; + } + return res; +} + bool JackDriver::IsFixedBufferSize() { return true; diff --git a/common/JackDriver.h b/common/JackDriver.h index 6f230831..68f937c2 100644 --- a/common/JackDriver.h +++ b/common/JackDriver.h @@ -97,6 +97,7 @@ class SERVER_EXPORT JackDriverInterface virtual int ProcessSlaves() = 0; virtual bool IsRealTime() const = 0; + virtual bool IsRunning() const = 0; }; /*! @@ -134,6 +135,7 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface JackClientControl fClientControl; std::list fSlaveList; bool fIsMaster; + bool fIsRunning; void CycleIncTime(); void CycleTakeBeginTime(); @@ -198,7 +200,9 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface virtual int Write(); virtual int Start(); + virtual int StartSlaves(); virtual int Stop(); + virtual int StopSlaves(); virtual bool IsFixedBufferSize(); virtual int SetBufferSize(jack_nframes_t buffer_size); @@ -208,6 +212,7 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface virtual JackClientControl* GetClientControl() const; virtual bool IsRealTime() const; + virtual bool IsRunning() const { return fIsRunning; } virtual bool Initialize(); // To be called by the wrapping thread Init method when the driver is a "blocking" one }; diff --git a/common/JackDriverLoader.cpp b/common/JackDriverLoader.cpp index 80ea3318..2d270656 100644 --- a/common/JackDriverLoader.cpp +++ b/common/JackDriverLoader.cpp @@ -119,7 +119,7 @@ jack_parse_driver_params (jack_driver_desc_t * desc, int argc, char* argv[], JSL desc->name); } - printf ("Parameters for driver '%s' (all parameters are optional):\n", desc->name); + jack_log("Parameters for driver '%s' (all parameters are optional):", desc->name); jack_print_driver_options (desc, stdout); return 1; } @@ -263,7 +263,7 @@ jackctl_parse_driver_params (jackctl_driver *driver_ptr, int argc, char* argv[]) desc->name); } - printf ("Parameters for driver '%s' (all parameters are optional):\n", desc->name); + jack_log("Parameters for driver '%s' (all parameters are optional):", desc->name); jack_print_driver_options (desc, stdout); return 1; } @@ -446,7 +446,7 @@ jack_get_descriptor (JSList * drivers, const char * sofile, const char * symbol) free(filename); return NULL; } - + if ((descriptor = so_get_descriptor ()) == NULL) { jack_error("driver from '%s' returned NULL descriptor", filename); UnloadDriverModule(dlhandle); @@ -467,7 +467,7 @@ jack_get_descriptor (JSList * drivers, const char * sofile, const char * symbol) /* check it doesn't exist already */ for (node = drivers; node; node = jack_slist_next (node)) { other_descriptor = (jack_driver_desc_t *) node->data; - + if (strcmp(descriptor->name, other_descriptor->name) == 0) { jack_error("the drivers in '%s' and '%s' both have the name '%s'; using the first", other_descriptor->file, filename, other_descriptor->name); @@ -603,7 +603,7 @@ jack_drivers_load (JSList * drivers) { } while ((dir_entry = readdir(dir_stream))) { - + /* check the filename is of the right format */ if (strncmp ("jack_", dir_entry->d_name, 5) != 0) { continue; @@ -619,7 +619,7 @@ jack_drivers_load (JSList * drivers) { } desc = jack_get_descriptor (drivers, dir_entry->d_name, "driver_get_descriptor"); - + if (desc) { driver_list = jack_slist_append (driver_list, desc); } else { @@ -771,9 +771,9 @@ jack_internals_load (JSList * internals) { #endif -Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver_desc, - Jack::JackLockedEngine* engine, - Jack::JackSynchro* synchro, +Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver_desc, + Jack::JackLockedEngine* engine, + Jack::JackSynchro* synchro, const JSList* params) { #ifdef WIN32 @@ -783,7 +783,7 @@ Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver #endif fHandle = LoadDriverModule (driver_desc->file); - + if (fHandle == NULL) { #ifdef WIN32 if ((errstr = GetLastError ()) != 0) { @@ -809,8 +809,14 @@ Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver jack_error("no initialize function in shared object %s\n", driver_desc->file); return NULL; } - + fBackend = fInitialize(engine, synchro, params); return fBackend; } +JackDriverInfo::~JackDriverInfo() +{ + delete fBackend; + if (fHandle) + UnloadDriverModule(fHandle); +} diff --git a/common/JackDriverLoader.h b/common/JackDriverLoader.h index 17777e54..c194304d 100644 --- a/common/JackDriverLoader.h +++ b/common/JackDriverLoader.h @@ -24,14 +24,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "driver_interface.h" #include "JackControlAPI.h" #include "JackPlatformPlug.h" +#include "JackDriver.h" #include "JackSystemDeps.h" -namespace Jack -{ - class JackDriverClientInterface; - class JackLockedEngine; -}; - typedef jack_driver_desc_t * (*JackDriverDescFunction) (); typedef Jack::JackDriverClientInterface* (*driverInitialize) (Jack::JackLockedEngine*, Jack::JackSynchro*, const JSList*); @@ -39,34 +34,30 @@ class JackDriverInfo { private: - + driverInitialize fInitialize; DRIVER_HANDLE fHandle; Jack::JackDriverClientInterface* fBackend; - + public: - - JackDriverInfo():fInitialize(NULL),fHandle(NULL) + + JackDriverInfo():fInitialize(NULL),fHandle(NULL),fBackend(NULL) {} - ~JackDriverInfo() - { - if (fHandle) - UnloadDriverModule(fHandle); - } - + ~JackDriverInfo(); + Jack::JackDriverClientInterface* Open(jack_driver_desc_t* driver_desc, Jack::JackLockedEngine*, Jack::JackSynchro*, const JSList*); - + Jack::JackDriverClientInterface* GetBackend() { return fBackend; } - + }; -jack_driver_desc_t * jack_find_driver_descriptor (JSList * drivers, const char * name); +jack_driver_desc_t * jack_find_driver_descriptor(JSList * drivers, const char * name); -JSList * jack_drivers_load (JSList * drivers); -JSList * jack_internals_load (JSList * internals); +JSList * jack_drivers_load(JSList * drivers); +JSList * jack_internals_load(JSList * internals); EXPORT int jackctl_parse_driver_params (jackctl_driver * driver_ptr, int argc, char* argv[]); EXPORT void jack_free_driver_params(JSList * param_ptr); diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index 338e5a42..2c7db9e3 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -223,7 +223,6 @@ int JackEngine::ComputeTotalLatencies() */ for (it = sorted.begin(); it != sorted.end(); it++) { - jack_log("Sorted %d", *it); NotifyClient(*it, kLatencyCallback, true, "", 0, 0); } @@ -322,8 +321,8 @@ void JackEngine::NotifyXRun(int refnum) void JackEngine::NotifyGraphReorder() { - ComputeTotalLatencies(); NotifyClients(kGraphOrderCallback, false, "", 0, 0); + ComputeTotalLatencies(); } void JackEngine::NotifyBufferSize(jack_nframes_t buffer_size) @@ -520,7 +519,7 @@ void JackEngine::EnsureUUID(int uuid) for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* client = fClientTable[i]; - if (client && (client->GetClientControl()->fSessionID==uuid)) { + if (client && (client->GetClientControl()->fSessionID == uuid)) { client->GetClientControl()->fSessionID = GetNewUUID(); } } @@ -551,13 +550,13 @@ int JackEngine::GetClientRefNum(const char* name) // Used for external clients int JackEngine::ClientExternalOpen(const char* name, int pid, int uuid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager) { - char real_name[JACK_CLIENT_NAME_SIZE+1]; + char real_name[JACK_CLIENT_NAME_SIZE + 1]; if (uuid < 0) { uuid = GetNewUUID(); strncpy(real_name, name, JACK_CLIENT_NAME_SIZE); } else { - std::map::iterator res = fReservationMap.find(uuid); + std::map::iterator res = fReservationMap.find(uuid); if (res != fReservationMap.end()) { strncpy(real_name, res->second.c_str(), JACK_CLIENT_NAME_SIZE); fReservationMap.erase(uuid); @@ -568,7 +567,7 @@ int JackEngine::ClientExternalOpen(const char* name, int pid, int uuid, int* ref EnsureUUID(uuid); } - jack_log("JackEngine::ClientExternalOpen: uuid=%d, name = %s ", uuid, real_name); + jack_log("JackEngine::ClientExternalOpen: uuid = %d, name = %s ", uuid, real_name); int refnum = AllocateRefnum(); if (refnum < 0) { @@ -762,7 +761,7 @@ int JackEngine::ClientDeactivate(int refnum) fGraphManager->GetInputPorts(refnum, input_ports); fGraphManager->GetOutputPorts(refnum, output_ports); - // First disconnect all ports and remove their JackPortIsActive state + // First disconnect all ports for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { PortDisconnect(refnum, input_ports[i], ALL_PORTS); } @@ -959,7 +958,7 @@ void JackEngine::SessionNotify(int refnum, const char *target, jack_session_even if (client && client->GetClientControl()->fCallback[kSessionCallback]) { // check if this is a notification to a specific client. - if (target!=NULL && strlen(target)!=0) { + if (target != NULL && strlen(target) != 0) { if (strcmp(target, client->GetClientControl()->fName)) { continue; } @@ -1019,7 +1018,7 @@ void JackEngine::GetUUIDForClientName(const char *client_name, char *uuid_res, i for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* client = fClientTable[i]; - if (client && (strcmp(client_name, client->GetClientControl()->fName)==0)) { + if (client && (strcmp(client_name, client->GetClientControl()->fName) == 0)) { snprintf(uuid_res, JACK_UUID_SIZE, "%d", client->GetClientControl()->fSessionID); *result = 0; return; diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index 451d8cce..1366316a 100644 --- a/common/JackGraphManager.cpp +++ b/common/JackGraphManager.cpp @@ -77,7 +77,7 @@ JackPort* JackGraphManager::GetPort(jack_port_id_t port_index) return &fPortArray[port_index]; } -float* JackGraphManager::GetBuffer(jack_port_id_t port_index) +jack_default_audio_sample_t* JackGraphManager::GetBuffer(jack_port_id_t port_index) { return fPortArray[port_index].GetBuffer(); } diff --git a/common/JackGraphManager.h b/common/JackGraphManager.h index 5db84209..df6237e5 100644 --- a/common/JackGraphManager.h +++ b/common/JackGraphManager.h @@ -49,7 +49,7 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState jack_port_id_t AllocatePortAux(int refnum, const char* port_name, const char* port_type, JackPortFlags flags); void GetConnectionsAux(JackConnectionManager* manager, const char** res, jack_port_id_t port_index); void GetPortsAux(const char** matching_ports, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags); - float* GetBuffer(jack_port_id_t port_index); + jack_default_audio_sample_t* GetBuffer(jack_port_id_t port_index); void* GetBufferAux(JackConnectionManager* manager, jack_port_id_t port_index, jack_nframes_t frames); jack_nframes_t ComputeTotalLatencyAux(jack_port_id_t port_index, jack_port_id_t src_port_index, JackConnectionManager* manager, int hop_count); void RecalculateLatencyAux(jack_port_id_t port_index, jack_latency_callback_mode_t mode); diff --git a/common/JackInternalClient.cpp b/common/JackInternalClient.cpp index 0f0e3e2a..550db2ef 100644 --- a/common/JackInternalClient.cpp +++ b/common/JackInternalClient.cpp @@ -123,7 +123,7 @@ int JackLoadableInternalClient::Init(const char* so_name) { char path_to_so[JACK_PATH_MAX + 1]; BuildClientPath(path_to_so, sizeof(path_to_so), so_name); - + fHandle = LoadJackModule(path_to_so); jack_log("JackLoadableInternalClient::JackLoadableInternalClient path_to_so = %s", path_to_so); @@ -151,7 +151,7 @@ int JackLoadableInternalClient1::Init(const char* so_name) if (JackLoadableInternalClient::Init(so_name) < 0) { return -1; } - + fInitialize = (InitializeCallback)GetJackProc(fHandle, "jack_initialize"); if (fInitialize == NULL) { UnloadJackModule(fHandle); @@ -167,7 +167,7 @@ int JackLoadableInternalClient2::Init(const char* so_name) if (JackLoadableInternalClient::Init(so_name) < 0) { return -1; } - + fInitialize = (InternalInitializeCallback)GetJackProc(fHandle, "jack_internal_initialize"); if (fInitialize == NULL) { UnloadJackModule(fHandle); @@ -181,7 +181,7 @@ int JackLoadableInternalClient2::Init(const char* so_name) JackLoadableInternalClient1::JackLoadableInternalClient1(JackServer* server, JackSynchro* table, const char* object_data) : JackLoadableInternalClient(server, table) { - strncpy(fObjectData, object_data, JACK_LOAD_INIT_LIMIT); + strncpy(fObjectData, object_data, JACK_LOAD_INIT_LIMIT); } JackLoadableInternalClient2::JackLoadableInternalClient2(JackServer* server, JackSynchro* table, const JSList* parameters) @@ -201,7 +201,7 @@ JackLoadableInternalClient::~JackLoadableInternalClient() int JackLoadableInternalClient1::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) { int res = -1; - + if (JackInternalClient::Open(server_name, name, uuid, options, status) == 0) { if (fInitialize((jack_client_t*)this, fObjectData) == 0) { res = 0; @@ -210,14 +210,14 @@ int JackLoadableInternalClient1::Open(const char* server_name, const char* name, fFinish = NULL; } } - + return res; } int JackLoadableInternalClient2::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) { int res = -1; - + if (JackInternalClient::Open(server_name, name, uuid, options, status) == 0) { if (fInitialize((jack_client_t*)this, fParameters) == 0) { res = 0; @@ -226,7 +226,7 @@ int JackLoadableInternalClient2::Open(const char* server_name, const char* name, fFinish = NULL; } } - + return res; } diff --git a/common/JackInternalClientChannel.h b/common/JackInternalClientChannel.h index 6b0772ce..dc81ac8c 100644 --- a/common/JackInternalClientChannel.h +++ b/common/JackInternalClientChannel.h @@ -136,7 +136,7 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result) { - *result = fServer->InternalClientLoad(client_name, so_name, objet_data, options, int_ref, uuid, status); + *result = fServer->InternalClientLoad1(client_name, so_name, objet_data, options, int_ref, uuid, status); } void InternalClientUnload(int refnum, int int_ref, int* status, int* result) diff --git a/common/JackLibClient.h b/common/JackLibClient.h index f2820601..ef07581c 100644 --- a/common/JackLibClient.h +++ b/common/JackLibClient.h @@ -12,7 +12,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. */ @@ -32,7 +32,7 @@ namespace Jack \brief Client on the library side. */ -class JackLibClient : public JackClient +class SERVER_EXPORT JackLibClient : public JackClient { private: diff --git a/common/JackLibGlobals.h b/common/JackLibGlobals.h index 5ef8b9e9..8d312295 100644 --- a/common/JackLibGlobals.h +++ b/common/JackLibGlobals.h @@ -12,7 +12,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. */ @@ -31,7 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackError.h" #include #include - + namespace Jack { @@ -42,13 +42,13 @@ class JackClient; \brief Global library static structure: singleton kind of pattern. */ -struct JackLibGlobals +struct SERVER_EXPORT JackLibGlobals { JackShmReadWritePtr fGraphManager; /*! Shared memory Port manager */ JackShmReadWritePtr fEngineControl; /*! Shared engine control */ // transport engine has to be writable JackSynchro fSynchroTable[CLIENT_NUM]; /*! Shared synchro table */ sigset_t fProcessSignals; - + static int fClientCount; static JackLibGlobals* fGlobals; @@ -67,7 +67,7 @@ struct JackLibGlobals sigemptyset(&signals); sigaddset(&signals, SIGPIPE); sigprocmask(SIG_BLOCK, &signals, &fProcessSignals); - #endif + #endif } ~JackLibGlobals() @@ -83,13 +83,13 @@ struct JackLibGlobals // TODO #else sigprocmask(SIG_BLOCK, &fProcessSignals, 0); - #endif + #endif } static void Init() { if (!JackGlobals::fServerRunning && fClientCount > 0) { - + // Cleanup remaining clients jack_error("Jack server was closed but clients are still allocated, cleanup..."); for (int i = 0; i < CLIENT_NUM; i++) { @@ -101,13 +101,13 @@ struct JackLibGlobals JackGlobals::fClientTable[CLIENT_NUM] = NULL; } } - + // Cleanup global context fClientCount = 0; delete fGlobals; fGlobals = NULL; } - + if (fClientCount++ == 0 && !fGlobals) { jack_log("JackLibGlobals Init %x", fGlobals); InitTime(); diff --git a/common/JackLibSampleRateResampler.cpp b/common/JackLibSampleRateResampler.cpp index 7475282a..ea70438d 100644 --- a/common/JackLibSampleRateResampler.cpp +++ b/common/JackLibSampleRateResampler.cpp @@ -27,7 +27,7 @@ JackLibSampleRateResampler::JackLibSampleRateResampler() { int error; fResampler = src_new(SRC_LINEAR, 1, &error); - if (error != 0) + if (error != 0) jack_error("JackLibSampleRateResampler::JackLibSampleRateResampler err = %s", src_strerror(error)); } @@ -50,7 +50,7 @@ JackLibSampleRateResampler::JackLibSampleRateResampler(unsigned int quality) case 4: quality = SRC_SINC_BEST_QUALITY; break; - default: + default: quality = SRC_LINEAR; jack_error("Out of range resample quality"); break; @@ -58,7 +58,7 @@ JackLibSampleRateResampler::JackLibSampleRateResampler(unsigned int quality) int error; fResampler = src_new(quality, 1, &error); - if (error != 0) + if (error != 0) jack_error("JackLibSampleRateResampler::JackLibSampleRateResampler err = %s", src_strerror(error)); } @@ -73,103 +73,103 @@ void JackLibSampleRateResampler::Reset(unsigned int new_size) src_reset(fResampler); } -unsigned int JackLibSampleRateResampler::ReadResample(float* buffer, unsigned int frames) +unsigned int JackLibSampleRateResampler::ReadResample(jack_default_audio_sample_t* buffer, unsigned int frames) { jack_ringbuffer_data_t ring_buffer_data[2]; SRC_DATA src_data; unsigned int frames_to_write = frames; unsigned int written_frames = 0; int res; - + jack_ringbuffer_get_read_vector(fRingBuffer, ring_buffer_data); - unsigned int available_frames = (ring_buffer_data[0].len + ring_buffer_data[1].len) / sizeof(float); + unsigned int available_frames = (ring_buffer_data[0].len + ring_buffer_data[1].len) / sizeof(jack_default_audio_sample_t); jack_log("Output available = %ld", available_frames); - + for (int j = 0; j < 2; j++) { - + if (ring_buffer_data[j].len > 0) { - - src_data.data_in = (float*)ring_buffer_data[j].buf; + + src_data.data_in = (jack_default_audio_sample_t*)ring_buffer_data[j].buf; src_data.data_out = &buffer[written_frames]; - src_data.input_frames = ring_buffer_data[j].len / sizeof(float); + src_data.input_frames = ring_buffer_data[j].len / sizeof(jack_default_audio_sample_t); src_data.output_frames = frames_to_write; src_data.end_of_input = 0; src_data.src_ratio = fRatio; - + res = src_process(fResampler, &src_data); if (res != 0) { jack_error("JackLibSampleRateResampler::ReadResample ratio = %f err = %s", fRatio, src_strerror(res)); return 0; } - + frames_to_write -= src_data.output_frames_gen; written_frames += src_data.output_frames_gen; - + if ((src_data.input_frames_used == 0 || src_data.output_frames_gen == 0) && j == 0) { jack_log("Output : j = %d input_frames_used = %ld output_frames_gen = %ld frames1 = %lu frames2 = %lu" , j, src_data.input_frames_used, src_data.output_frames_gen, ring_buffer_data[0].len, ring_buffer_data[1].len); } - + jack_log("Output : j = %d input_frames_used = %ld output_frames_gen = %ld", j, src_data.input_frames_used, src_data.output_frames_gen); - jack_ringbuffer_read_advance(fRingBuffer, src_data.input_frames_used * sizeof(float)); + jack_ringbuffer_read_advance(fRingBuffer, src_data.input_frames_used * sizeof(jack_default_audio_sample_t)); } } - + if (written_frames < frames) { jack_error("Output available = %ld", available_frames); jack_error("JackLibSampleRateResampler::ReadResample error written_frames = %ld", written_frames); } - + return written_frames; } -unsigned int JackLibSampleRateResampler::WriteResample(float* buffer, unsigned int frames) +unsigned int JackLibSampleRateResampler::WriteResample(jack_default_audio_sample_t* buffer, unsigned int frames) { jack_ringbuffer_data_t ring_buffer_data[2]; SRC_DATA src_data; unsigned int frames_to_read = frames; unsigned int read_frames = 0; int res; - + jack_ringbuffer_get_write_vector(fRingBuffer, ring_buffer_data); - unsigned int available_frames = (ring_buffer_data[0].len + ring_buffer_data[1].len) / sizeof(float); + unsigned int available_frames = (ring_buffer_data[0].len + ring_buffer_data[1].len) / sizeof(jack_default_audio_sample_t); jack_log("Input available = %ld", available_frames); - + for (int j = 0; j < 2; j++) { - + if (ring_buffer_data[j].len > 0) { - + src_data.data_in = &buffer[read_frames]; - src_data.data_out = (float*)ring_buffer_data[j].buf; + src_data.data_out = (jack_default_audio_sample_t*)ring_buffer_data[j].buf; src_data.input_frames = frames_to_read; - src_data.output_frames = (ring_buffer_data[j].len / sizeof(float)); + src_data.output_frames = (ring_buffer_data[j].len / sizeof(jack_default_audio_sample_t)); src_data.end_of_input = 0; src_data.src_ratio = fRatio; - + res = src_process(fResampler, &src_data); if (res != 0) { jack_error("JackLibSampleRateResampler::ReadResample ratio = %f err = %s", fRatio, src_strerror(res)); return 0; } - + frames_to_read -= src_data.input_frames_used; read_frames += src_data.input_frames_used; - + if ((src_data.input_frames_used == 0 || src_data.output_frames_gen == 0) && j == 0) { jack_log("Input : j = %d input_frames_used = %ld output_frames_gen = %ld frames1 = %lu frames2 = %lu" , j, src_data.input_frames_used, src_data.output_frames_gen, ring_buffer_data[0].len, ring_buffer_data[1].len); } - + jack_log("Input : j = %d input_frames_used = %ld output_frames_gen = %ld", j, src_data.input_frames_used, src_data.output_frames_gen); - jack_ringbuffer_write_advance(fRingBuffer, src_data.output_frames_gen * sizeof(float)); + jack_ringbuffer_write_advance(fRingBuffer, src_data.output_frames_gen * sizeof(jack_default_audio_sample_t)); } } - + if (read_frames < frames) { jack_error("Input available = %ld", available_frames); jack_error("JackLibSampleRateResampler::ReadResample error read_frames = %ld", read_frames); } - + return read_frames; } diff --git a/common/JackLibSampleRateResampler.h b/common/JackLibSampleRateResampler.h index e51a7442..4d6821d8 100644 --- a/common/JackLibSampleRateResampler.h +++ b/common/JackLibSampleRateResampler.h @@ -21,6 +21,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #define __JackLibSampleRateResampler__ #include "JackResampler.h" +#include "types.h" + #include namespace Jack @@ -34,20 +36,20 @@ class JackLibSampleRateResampler : public JackResampler { private: - + SRC_STATE* fResampler; - + public: - + JackLibSampleRateResampler(); JackLibSampleRateResampler(unsigned int quality); virtual ~JackLibSampleRateResampler(); - - unsigned int ReadResample(float* buffer, unsigned int frames); - unsigned int WriteResample(float* buffer, unsigned int frames); - + + unsigned int ReadResample(jack_default_audio_sample_t* buffer, unsigned int frames); + unsigned int WriteResample(jack_default_audio_sample_t* buffer, unsigned int frames); + void Reset(unsigned int new_size); - + }; } diff --git a/common/JackLoopbackDriver.cpp b/common/JackLoopbackDriver.cpp index 48a9d253..e91cce1e 100644 --- a/common/JackLoopbackDriver.cpp +++ b/common/JackLoopbackDriver.cpp @@ -34,7 +34,7 @@ int JackLoopbackDriver::Process() { // Loopback copy for (int i = 0; i < fCaptureChannels; i++) { - memcpy(GetInputBuffer(i), GetOutputBuffer(i), sizeof(float) * fEngineControl->fBufferSize); + memcpy(GetInputBuffer(i), GetOutputBuffer(i), sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); } fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); // Signal all clients @@ -54,7 +54,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; @@ -65,7 +65,7 @@ extern "C" desc->nparams = 1; desc->params = (jack_driver_param_desc_t*)calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); - + i = 0; strcpy(desc->params[i].name, "channels"); desc->params[i].character = 'c'; @@ -77,12 +77,12 @@ 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) { const JSList * node; const jack_driver_param_t * param; int channels = 2; - + for (node = params; node; node = jack_slist_next (node)) { param = (const jack_driver_param_t *) node->data; @@ -93,7 +93,7 @@ extern "C" break; } } - + Jack::JackDriverClientInterface* driver = new Jack::JackLoopbackDriver(engine, table); if (driver->Open(1, 1, channels, channels, false, "loopback", "loopback", 0, 0) == 0) { return driver; diff --git a/common/JackMidiDriver.cpp b/common/JackMidiDriver.cpp index 4ddf417c..15d507b1 100644 --- a/common/JackMidiDriver.cpp +++ b/common/JackMidiDriver.cpp @@ -60,11 +60,11 @@ int JackMidiDriver::Open(bool capturing, { fCaptureChannels = inchannels; fPlaybackChannels = outchannels; - + for (int i = 0; i < fCaptureChannels; i++) { - fRingBuffer[i] = jack_ringbuffer_create(sizeof(float) * BUFFER_SIZE_MAX); + fRingBuffer[i] = jack_ringbuffer_create(sizeof(jack_default_audio_sample_t) * BUFFER_SIZE_MAX); } - + return JackDriver::Open(capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); } @@ -141,11 +141,11 @@ int JackMidiDriver::ProcessNull() int JackMidiDriver::Process() { // Read input buffers for the current cycle - if (Read() < 0) { + if (Read() < 0) { jack_error("JackMidiDriver::Process: read error, skip cycle"); return 0; // Skip cycle, but continue processing... } - + fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); if (fEngineControl->fSyncMode) { if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, fEngineControl->fTimeOutUsecs) < 0) { @@ -153,13 +153,13 @@ int JackMidiDriver::Process() return -1; } } - + // Write output buffers for the current cycle - if (Write() < 0) { + if (Write() < 0) { jack_error("JackMidiDriver::Process: write error, skip cycle"); return 0; // Skip cycle, but continue processing... } - + return 0; } diff --git a/common/JackMidiPort.cpp b/common/JackMidiPort.cpp index 117b7a70..42ee245c 100644 --- a/common/JackMidiPort.cpp +++ b/common/JackMidiPort.cpp @@ -72,7 +72,7 @@ static void MidiBufferInit(void* buffer, size_t buffer_size, jack_nframes_t nfra JackMidiBuffer* midi = (JackMidiBuffer*)buffer; midi->magic = JackMidiBuffer::MAGIC; /* Since port buffer has actually always BUFFER_SIZE_MAX frames, we can safely use all the size */ - midi->buffer_size = BUFFER_SIZE_MAX * sizeof(float); + midi->buffer_size = BUFFER_SIZE_MAX * sizeof(jack_default_audio_sample_t); midi->Reset(nframes); } @@ -135,7 +135,7 @@ static void MidiBufferMixdown(void* mixbuffer, void** src_buffers, int src_count static size_t MidiBufferSize() { - return BUFFER_SIZE_MAX * sizeof(float); + return BUFFER_SIZE_MAX * sizeof(jack_default_audio_sample_t); } const JackPortType gMidiPortType = diff --git a/common/JackMidiPort.h b/common/JackMidiPort.h index 0dbfcb9a..3c24542b 100644 --- a/common/JackMidiPort.h +++ b/common/JackMidiPort.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. */ @@ -71,7 +71,7 @@ struct SERVER_EXPORT JackMidiEvent * but their data (if not inlined) is stored from the end of the same buffer. */ -struct JackMidiBuffer +struct SERVER_EXPORT JackMidiBuffer { enum { MAGIC = 0x900df00d }; diff --git a/common/JackNetOneDriver.cpp b/common/JackNetOneDriver.cpp index 5b1b8cdd..93adecdd 100644 --- a/common/JackNetOneDriver.cpp +++ b/common/JackNetOneDriver.cpp @@ -36,7 +36,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #endif #if HAVE_CELT -#include "celt/celt.h" +#include #endif #define MIN(x,y) ((x)<(y) ? (x) : (y)) @@ -153,12 +153,15 @@ namespace Jack } //port = fGraphManager->GetPort ( port_id ); - netj.capture_ports = - jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); + netj.capture_ports = jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); if( netj.bitdepth == CELT_MODE ) { #if HAVE_CELT - #if HAVE_CELT_API_0_7 + #if HAVE_CELT_API_0_11 + celt_int32 lookahead; + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); + netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) ); + #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 celt_int32 lookahead; CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); @@ -202,12 +205,13 @@ namespace Jack } //port = fGraphManager->GetPort ( port_id ); - netj.playback_ports = - jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); - + netj.playback_ports = jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); if( netj.bitdepth == CELT_MODE ) { #if HAVE_CELT - #if HAVE_CELT_API_0_7 + #if HAVE_CELT_API_0_11 + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); + netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create_custom( celt_mode, 1, NULL ) ); + #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); #else @@ -697,10 +701,18 @@ namespace Jack { // audio port, decode celt data. CELTDecoder *decoder = (CELTDecoder *)src_node->data; + + #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 + if( !packet_payload ) + celt_decode_float( decoder, NULL, net_period_down, buf, nframes ); + else + celt_decode_float( decoder, packet_bufX, net_period_down, buf, nframes ); + #else if( !packet_payload ) - celt_decode_float( decoder, NULL, net_period_down, buf ); + celt_decode_float( decoder, NULL, net_period_down, buf ); else - celt_decode_float( decoder, packet_bufX, net_period_down, buf ); + celt_decode_float( decoder, packet_bufX, net_period_down, buf ); + #endif src_node = jack_slist_next (src_node); } @@ -743,11 +755,15 @@ namespace Jack // audio port, encode celt data. int encoded_bytes; - float *floatbuf = (float *)alloca (sizeof(float) * nframes ); - memcpy( floatbuf, buf, nframes*sizeof(float) ); + jack_default_audio_sample_t *floatbuf = (jack_default_audio_sample_t *)alloca (sizeof(jack_default_audio_sample_t) * nframes ); + memcpy( floatbuf, buf, nframes * sizeof(jack_default_audio_sample_t) ); CELTEncoder *encoder = (CELTEncoder *)src_node->data; + #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 + encoded_bytes = celt_encode_float( encoder, floatbuf, nframes, packet_bufX, net_period_up ); +#else encoded_bytes = celt_encode_float( encoder, floatbuf, NULL, packet_bufX, net_period_up ); - if( encoded_bytes != (int)net_period_up ) +#endif + if( encoded_bytes != (int)net_period_up ) jack_error( "something in celt changed. netjack needs to be changed to handle this." ); src_node = jack_slist_next( src_node ); } diff --git a/common/JackPort.cpp b/common/JackPort.cpp index e3dd12f6..870d6ee8 100644 --- a/common/JackPort.cpp +++ b/common/JackPort.cpp @@ -286,7 +286,7 @@ int JackPort::UnsetAlias(const char* alias) void JackPort::ClearBuffer(jack_nframes_t frames) { const JackPortType* type = GetPortType(fTypeId); - (type->init)(GetBuffer(), frames * sizeof(float), frames); + (type->init)(GetBuffer(), frames * sizeof(jack_default_audio_sample_t), frames); } void JackPort::MixBuffers(void** src_buffers, int src_count, jack_nframes_t buffer_size) diff --git a/common/JackPort.h b/common/JackPort.h index 758e402b..8e8c1667 100644 --- a/common/JackPort.h +++ b/common/JackPort.h @@ -57,7 +57,7 @@ class SERVER_EXPORT JackPort bool fInUse; jack_port_id_t fTied; // Locally tied source port - float fBuffer[BUFFER_SIZE_MAX + 4]; + jack_default_audio_sample_t fBuffer[BUFFER_SIZE_MAX + 4]; bool IsUsed() const { @@ -105,9 +105,9 @@ class SERVER_EXPORT JackPort } // Since we are in shared memory, the resulting pointer cannot be cached, so align it here... - float* GetBuffer() + jack_default_audio_sample_t* GetBuffer() { - return (float*)((long)fBuffer & ~15L) + 4; + return (jack_default_audio_sample_t*)((long)fBuffer & ~15L) + 4; } int GetRefNum() const; diff --git a/common/JackResampler.cpp b/common/JackResampler.cpp index b9a26f44..e2d32520 100644 --- a/common/JackResampler.cpp +++ b/common/JackResampler.cpp @@ -26,8 +26,8 @@ namespace Jack JackResampler::JackResampler() :fRatio(1),fRingBufferSize(DEFAULT_RB_SIZE) { - fRingBuffer = jack_ringbuffer_create(sizeof(float) * fRingBufferSize); - jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize) / 2); + fRingBuffer = jack_ringbuffer_create(sizeof(jack_default_audio_sample_t) * fRingBufferSize); + jack_ringbuffer_read_advance(fRingBuffer, (sizeof(jack_default_audio_sample_t) * fRingBufferSize) / 2); } JackResampler::~JackResampler() @@ -40,44 +40,44 @@ void JackResampler::Reset(unsigned int new_size) { fRingBufferSize = new_size; jack_ringbuffer_reset(fRingBuffer); - jack_ringbuffer_reset_size(fRingBuffer, sizeof(float) * fRingBufferSize); - jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize / 2)); + jack_ringbuffer_reset_size(fRingBuffer, sizeof(jack_default_audio_sample_t) * fRingBufferSize); + jack_ringbuffer_read_advance(fRingBuffer, (sizeof(jack_default_audio_sample_t) * fRingBufferSize / 2)); } unsigned int JackResampler::ReadSpace() { - return (jack_ringbuffer_read_space(fRingBuffer) / sizeof(float)); + return (jack_ringbuffer_read_space(fRingBuffer) / sizeof(jack_default_audio_sample_t)); } unsigned int JackResampler::WriteSpace() { - return (jack_ringbuffer_write_space(fRingBuffer) / sizeof(float)); + return (jack_ringbuffer_write_space(fRingBuffer) / sizeof(jack_default_audio_sample_t)); } -unsigned int JackResampler::Read(float* buffer, unsigned int frames) +unsigned int JackResampler::Read(jack_default_audio_sample_t* buffer, unsigned int frames) { size_t len = jack_ringbuffer_read_space(fRingBuffer); - jack_log("JackResampler::Read input available = %ld", len / sizeof(float)); - - if (len < frames * sizeof(float)) { + jack_log("JackResampler::Read input available = %ld", len / sizeof(jack_default_audio_sample_t)); + + if (len < frames * sizeof(jack_default_audio_sample_t)) { jack_error("JackResampler::Read : producer too slow, missing frames = %d", frames); return 0; } else { - jack_ringbuffer_read(fRingBuffer, (char*)buffer, frames * sizeof(float)); + jack_ringbuffer_read(fRingBuffer, (char*)buffer, frames * sizeof(jack_default_audio_sample_t)); return frames; } } -unsigned int JackResampler::Write(float* buffer, unsigned int frames) +unsigned int JackResampler::Write(jack_default_audio_sample_t* buffer, unsigned int frames) { size_t len = jack_ringbuffer_write_space(fRingBuffer); - jack_log("JackResampler::Write output available = %ld", len / sizeof(float)); - - if (len < frames * sizeof(float)) { + jack_log("JackResampler::Write output available = %ld", len / sizeof(jack_default_audio_sample_t)); + + if (len < frames * sizeof(jack_default_audio_sample_t)) { jack_error("JackResampler::Write : consumer too slow, skip frames = %d", frames); return 0; } else { - jack_ringbuffer_write(fRingBuffer, (char*)buffer, frames * sizeof(float)); + jack_ringbuffer_write(fRingBuffer, (char*)buffer, frames * sizeof(jack_default_audio_sample_t)); return frames; } } @@ -110,12 +110,12 @@ unsigned int JackResampler::Write(void* buffer, unsigned int bytes) } } -unsigned int JackResampler::ReadResample(float* buffer, unsigned int frames) +unsigned int JackResampler::ReadResample(jack_default_audio_sample_t* buffer, unsigned int frames) { return Read(buffer, frames); } -unsigned int JackResampler::WriteResample(float* buffer, unsigned int frames) +unsigned int JackResampler::WriteResample(jack_default_audio_sample_t* buffer, unsigned int frames) { return Write(buffer, frames); } diff --git a/common/JackResampler.h b/common/JackResampler.h index bfb93f04..3b9877a5 100644 --- a/common/JackResampler.h +++ b/common/JackResampler.h @@ -21,19 +21,20 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #define __JackResampler__ #include "ringbuffer.h" +#include "types.h" #include "JackError.h" namespace Jack { #define DEFAULT_RB_SIZE 32768 -#define DEFAULT_ADAPTATIVE_SIZE 2048 +#define DEFAULT_ADAPTATIVE_SIZE 2048 inline float Range(float min, float max, float val) { return (val < min) ? min : ((val > max) ? max : val); } - + /*! \brief Base class for Resampler. */ @@ -42,30 +43,30 @@ class JackResampler { protected: - + jack_ringbuffer_t* fRingBuffer; double fRatio; unsigned int fRingBufferSize; - + public: - + JackResampler(); virtual ~JackResampler(); - + virtual void Reset(unsigned int new_size); - - virtual unsigned int ReadResample(float* buffer, unsigned int frames); - virtual unsigned int WriteResample(float* buffer, unsigned int frames); - - virtual unsigned int Read(float* buffer, unsigned int frames); - virtual unsigned int Write(float* buffer, unsigned int frames); - + + virtual unsigned int ReadResample(jack_default_audio_sample_t* buffer, unsigned int frames); + virtual unsigned int WriteResample(jack_default_audio_sample_t* buffer, unsigned int frames); + + virtual unsigned int Read(jack_default_audio_sample_t* buffer, unsigned int frames); + virtual unsigned int Write(jack_default_audio_sample_t* buffer, unsigned int frames); + virtual unsigned int Read(void* buffer, unsigned int bytes); virtual unsigned int Write(void* buffer, unsigned int bytes); virtual unsigned int ReadSpace(); virtual unsigned int WriteSpace(); - + unsigned int GetError() { return (jack_ringbuffer_read_space(fRingBuffer) / sizeof(float)) - (fRingBufferSize / 2); @@ -75,12 +76,12 @@ class JackResampler { fRatio = Range(0.25, 4.0, ratio); } - + double GetRatio() { return fRatio; } - + }; } diff --git a/common/JackServer.cpp b/common/JackServer.cpp index 50894529..cd1915fb 100644 --- a/common/JackServer.cpp +++ b/common/JackServer.cpp @@ -49,7 +49,16 @@ JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int prio fGraphManager = JackGraphManager::Allocate(port_max); fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, clock, server_name); fEngine = new JackLockedEngine(fGraphManager, GetSynchroTable(), fEngineControl); - fFreewheelDriver = new JackThreadedDriver(new JackFreewheelDriver(fEngine, GetSynchroTable())); + + // A distinction is made between the threaded freewheel driver and the + // regular freewheel driver because the freewheel driver needs to run in + // threaded mode when freewheel mode is active and needs to run as a slave + // when freewheel mode isn't active. + JackFreewheelDriver *freewheelDriver = + new JackFreewheelDriver(fEngine, GetSynchroTable()); + fThreadedFreewheelDriver = new JackThreadedDriver(freewheelDriver); + + fFreewheelDriver = freewheelDriver; fDriverInfo = new JackDriverInfo(); fAudioDriver = NULL; fFreewheel = false; @@ -61,9 +70,8 @@ JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int prio JackServer::~JackServer() { JackGraphManager::Destroy(fGraphManager); - delete fAudioDriver; delete fDriverInfo; - delete fFreewheelDriver; + delete fThreadedFreewheelDriver; delete fEngine; delete fEngineControl; } @@ -88,8 +96,8 @@ int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params) goto fail_close3; } - if (fFreewheelDriver->Open() < 0) { // before engine open - jack_error("Cannot open driver"); + if (fFreewheelDriver->Open() < 0) { + jack_error("Cannot open freewheel driver"); goto fail_close4; } @@ -100,7 +108,7 @@ int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params) fFreewheelDriver->SetMaster(false); fAudioDriver->SetMaster(true); - fAudioDriver->AddSlave(fFreewheelDriver); // After ??? + fAudioDriver->AddSlave(fFreewheelDriver); InitTime(); SetClockSource(fEngineControl->fClockSource); return 0; @@ -136,14 +144,14 @@ int JackServer::Close() return 0; } -int JackServer::InternalClientLoad(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int uuid, int* status) +int JackServer::InternalClientLoad1(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int uuid, int* status) { JackLoadableInternalClient* client = new JackLoadableInternalClient1(JackServerGlobals::fInstance, GetSynchroTable(), objet_data); assert(client); return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status); } -int JackServer::InternalClientLoad(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int uuid, int* status) +int JackServer::InternalClientLoad2(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int uuid, int* status) { JackLoadableInternalClient* client = new JackLoadableInternalClient2(JackServerGlobals::fInstance, GetSynchroTable(), parameters); assert(client); @@ -154,6 +162,8 @@ int JackServer::InternalClientLoadAux(JackLoadableInternalClient* client, const { // Clear status *status = 0; + + // Client object is internally kept in JackEngine if ((client->Init(so_name) < 0) || (client->Open(JACK_DEFAULT_SERVER_NAME, client_name, uuid, (jack_options_t)options, (jack_status_t*)status) < 0)) { delete client; int my_status1 = *status | JackFailure; @@ -178,7 +188,18 @@ int JackServer::Start() int JackServer::Stop() { jack_log("JackServer::Stop"); - return fAudioDriver->Stop(); + if (fFreewheel) { + return fThreadedFreewheelDriver->Stop(); + } else { + return fAudioDriver->Stop(); + } +} + +bool JackServer::IsRunning() +{ + jack_log("JackServer::IsRunning"); + assert(fAudioDriver); + return fAudioDriver->IsRunning(); } int JackServer::SetBufferSize(jack_nframes_t buffer_size) @@ -236,10 +257,11 @@ int JackServer::SetFreewheel(bool onoff) return -1; } else { fFreewheel = false; - fFreewheelDriver->Stop(); + fThreadedFreewheelDriver->Stop(); fGraphManager->Restore(&fConnectionState); // Restore previous connection state fEngine->NotifyFreewheel(onoff); fFreewheelDriver->SetMaster(false); + fAudioDriver->SetMaster(true); return fAudioDriver->Start(); } } else { @@ -249,8 +271,9 @@ int JackServer::SetFreewheel(bool onoff) fGraphManager->Save(&fConnectionState); // Save connection state fGraphManager->DisconnectAllPorts(fAudioDriver->GetClientControl()->fRefNum); fEngine->NotifyFreewheel(onoff); + fAudioDriver->SetMaster(false); fFreewheelDriver->SetMaster(true); - return fFreewheelDriver->Start(); + return fThreadedFreewheelDriver->Start(); } else { return -1; } @@ -269,7 +292,6 @@ void JackServer::Notify(int refnum, int notify, int value) case kXRunCallback: fEngine->NotifyXRun(refnum); break; - } } @@ -295,11 +317,11 @@ JackDriverInfo* JackServer::AddSlave(jack_driver_desc_t* driver_desc, JSList* dr if (slave == NULL) { delete info; return NULL; - } else { - slave->Attach(); - fAudioDriver->AddSlave(slave); - return info; } + slave->Attach(); + slave->SetMaster(false); + fAudioDriver->AddSlave(slave); + return info; } void JackServer::RemoveSlave(JackDriverInfo* info) @@ -321,33 +343,30 @@ int JackServer::SwitchMaster(jack_driver_desc_t* driver_desc, JSList* driver_par JackDriverInfo* info = new JackDriverInfo(); JackDriverClientInterface* master = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params); - if (master == NULL || info == NULL) { + if (master == NULL) { delete info; - delete master; return -1; - } else { + } - // Get slaves list - std::list slave_list = fAudioDriver->GetSlaves(); - std::list::const_iterator it; + // Get slaves list + std::list slave_list = fAudioDriver->GetSlaves(); + std::list::const_iterator it; - // Move slaves in new master - for (it = slave_list.begin(); it != slave_list.end(); it++) { - JackDriverInterface* slave = *it; - master->AddSlave(slave); - } + // Move slaves in new master + for (it = slave_list.begin(); it != slave_list.end(); it++) { + JackDriverInterface* slave = *it; + master->AddSlave(slave); + } - // Delete old master - delete fAudioDriver; - delete fDriverInfo; + // Delete old master + delete fDriverInfo; - // Activate master - fAudioDriver = master; - fDriverInfo = info; - fAudioDriver->Attach(); - fAudioDriver->SetMaster(true); - return fAudioDriver->Start(); - } + // Activate master + fAudioDriver = master; + fDriverInfo = info; + fAudioDriver->Attach(); + fAudioDriver->SetMaster(true); + return fAudioDriver->Start(); } //---------------------- diff --git a/common/JackServer.h b/common/JackServer.h index 9b07d60f..bdbd8ea8 100644 --- a/common/JackServer.h +++ b/common/JackServer.h @@ -50,6 +50,7 @@ class SERVER_EXPORT JackServer JackDriverInfo* fDriverInfo; JackDriverClientInterface* fAudioDriver; JackDriverClientInterface* fFreewheelDriver; + JackDriverClientInterface* fThreadedFreewheelDriver; JackLockedEngine* fEngine; JackEngineControl* fEngineControl; JackGraphManager* fGraphManager; @@ -57,7 +58,7 @@ class SERVER_EXPORT JackServer JackConnectionManager fConnectionState; JackSynchro fSynchroTable[CLIENT_NUM]; bool fFreewheel; - + int InternalClientLoadAux(JackLoadableInternalClient* client, const char* so_name, const char* client_name, int options, int* int_ref, int uuid, int* status); public: @@ -70,6 +71,7 @@ class SERVER_EXPORT JackServer int Start(); int Stop(); + bool IsRunning(); // RT thread void Notify(int refnum, int notify, int value); @@ -77,19 +79,19 @@ class SERVER_EXPORT JackServer // Command thread : API int SetBufferSize(jack_nframes_t buffer_size); int SetFreewheel(bool onoff); - int InternalClientLoad(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int uuid, int* status); - int InternalClientLoad(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int uuid, int* status); + int InternalClientLoad1(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int uuid, int* status); + int InternalClientLoad2(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int uuid, int* status); void ClientKill(int refnum); // Transport management int ReleaseTimebase(int refnum); int SetTimebaseCallback(int refnum, int conditional); - + // Backend management JackDriverInfo* AddSlave(jack_driver_desc_t* driver_desc, JSList* driver_params); void RemoveSlave(JackDriverInfo* info); int SwitchMaster(jack_driver_desc_t* driver_desc, JSList* driver_params); - + // Object access JackLockedEngine* GetEngine(); JackEngineControl* GetEngineControl(); diff --git a/common/JackServerAPI.cpp b/common/JackServerAPI.cpp index 5561f154..49cc4a58 100644 --- a/common/JackServerAPI.cpp +++ b/common/JackServerAPI.cpp @@ -63,7 +63,7 @@ jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t optio } jack_log("jack_client_new %s", client_name); - + if (status == NULL) /* no status from caller? */ status = &my_status; /* use local status word */ *status = (jack_status_t)0; @@ -77,13 +77,13 @@ jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t optio /* parse variable arguments */ jack_varargs_init(&va); - + if (!JackServerGlobals::Init()) { // jack server initialisation int my_status1 = (JackFailure | JackServerError); *status = (jack_status_t)my_status1; return NULL; } - + if (JACK_DEBUG) { client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode } else { @@ -114,7 +114,7 @@ jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t opti } jack_log("jack_client_open %s", client_name); - + if (status == NULL) /* no status from caller? */ status = &my_status; /* use local status word */ *status = (jack_status_t)0; @@ -128,13 +128,13 @@ jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t opti /* parse variable arguments */ jack_varargs_parse(options, ap, &va); - + if (!JackServerGlobals::Init()) { // jack server initialisation int my_status1 = (JackFailure | JackServerError); *status = (jack_status_t)my_status1; return NULL; } - + if (JACK_DEBUG) { client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode } else { @@ -180,7 +180,7 @@ EXPORT int jack_client_close(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ JackGlobals::CheckContext("jack_client_close"); -#endif +#endif assert(JackGlobals::fOpenMutex); JackGlobals::fOpenMutex->Lock(); int res = -1; @@ -200,7 +200,7 @@ EXPORT int jack_client_close(jack_client_t* ext_client) EXPORT int jack_get_client_pid(const char *name) { - return (JackServerGlobals::fInstance != NULL) + return (JackServerGlobals::fInstance != NULL) ? JackServerGlobals::fInstance->GetEngine()->GetClientPID(name) : 0; } diff --git a/common/JackServerGlobals.cpp b/common/JackServerGlobals.cpp index 04489190..00127fa6 100644 --- a/common/JackServerGlobals.cpp +++ b/common/JackServerGlobals.cpp @@ -18,6 +18,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackServerGlobals.h" +#include "JackLockedEngine.h" #include "JackTools.h" #include "shm.h" #include @@ -31,6 +32,8 @@ namespace Jack JackServer* JackServerGlobals::fInstance; unsigned int JackServerGlobals::fUserCount; int JackServerGlobals::fRTNotificationSocket; +std::map JackServerGlobals::fSlavesList; +std::map JackServerGlobals::fInternalsList; bool (* JackServerGlobals::on_device_acquire)(const char * device_name) = NULL; void (* JackServerGlobals::on_device_release)(const char * device_name) = NULL; @@ -63,6 +66,30 @@ void JackServerGlobals::Stop() void JackServerGlobals::Delete() { jack_log("Jackdmp: delete server"); + + // Slave drivers + std::map::iterator it1; + for (it1 = fSlavesList.begin(); it1 != fSlavesList.end(); it1++) { + JackDriverInfo* info = (*it1).second; + if (info) { + fInstance->RemoveSlave((info)); + delete (info); + } + } + fSlavesList.clear(); + + // Internal clients + std::map ::iterator it2; + for (it2 = fInternalsList.begin(); it2 != fInternalsList.end(); it2++) { + int status; + int refnum = (*it2).second; + if (refnum > 0) { + // Client object is internally kept in JackEngine, and will be desallocated in InternalClientUnload + fInstance->GetEngine()->InternalClientUnload(refnum, &status); + } + } + fInternalsList.clear(); + delete fInstance; fInstance = NULL; } @@ -80,49 +107,62 @@ bool JackServerGlobals::Init() int opt = 0; int option_index = 0; - int seen_driver = 0; - char *driver_name = NULL; - char **driver_args = NULL; - JSList* driver_params = NULL; + char *master_driver_name = NULL; + char **master_driver_args = NULL; + JSList* master_driver_params = NULL; + jack_driver_desc_t* driver_desc; + jack_timer_type_t clock_source = JACK_TIMER_SYSTEM_CLOCK; int driver_nargs = 1; JSList* drivers = NULL; - int show_version = 0; + int loopback = 0; int sync = 0; int rc, i; int ret; + int replace_registry = 0; FILE* fp = 0; char filename[255]; char buffer[255]; int argc = 0; char* argv[32]; - jack_timer_type_t clock_source = JACK_TIMER_SYSTEM_CLOCK; // First user starts the server if (fUserCount++ == 0) { jack_log("JackServerGlobals Init"); - jack_driver_desc_t* driver_desc; - const char *options = "-ad:P:uvshVRL:STFl:t:mn:p:c:"; - static struct option long_options[] = { - { "clock-source", 1, 0, 'c' }, - { "driver", 1, 0, 'd' }, - { "verbose", 0, 0, 'v' }, - { "help", 0, 0, 'h' }, - { "port-max", 1, 0, 'p' }, - { "no-mlock", 0, 0, 'm' }, - { "name", 0, 0, 'n' }, - { "unlock", 0, 0, 'u' }, - { "realtime", 0, 0, 'R' }, - { "realtime-priority", 1, 0, 'P' }, - { "timeout", 1, 0, 't' }, - { "temporary", 0, 0, 'T' }, - { "version", 0, 0, 'V' }, - { "silent", 0, 0, 's' }, - { "sync", 0, 0, 'S' }, - { 0, 0, 0, 0 } - }; + const char *options = "-d:X:I:P:uvshVrRL:STFl:t:mn:p:" + #ifdef __linux__ + "c:" + #endif + ; + + struct option long_options[] = { + #ifdef __linux__ + { "clock-source", 1, 0, 'c' }, + #endif + { "loopback-driver", 1, 0, 'L' }, + { "audio-driver", 1, 0, 'd' }, + { "midi-driver", 1, 0, 'X' }, + { "internal-client", 1, 0, 'I' }, + { "verbose", 0, 0, 'v' }, + { "help", 0, 0, 'h' }, + { "port-max", 1, 0, 'p' }, + { "no-mlock", 0, 0, 'm' }, + { "name", 1, 0, 'n' }, + { "unlock", 0, 0, 'u' }, + { "realtime", 0, 0, 'R' }, + { "no-realtime", 0, 0, 'r' }, + { "replace-registry", 0, &replace_registry, 0 }, + { "loopback", 0, 0, 'L' }, + { "realtime-priority", 1, 0, 'P' }, + { "timeout", 1, 0, 't' }, + { "temporary", 0, 0, 'T' }, + { "version", 0, 0, 'V' }, + { "silent", 0, 0, 's' }, + { "sync", 0, 0, 'S' }, + { 0, 0, 0, 0 } + }; snprintf(filename, 255, "%s/.jackdrc", getenv("HOME")); fp = fopen(filename, "r"); @@ -156,7 +196,7 @@ bool JackServerGlobals::Init() opterr = 0; optind = 1; // Important : to reset argv parsing - while (!seen_driver && + while (!master_driver_name && (opt = getopt_long(argc, argv, options, long_options, &option_index)) != EOF) { switch (opt) { @@ -174,34 +214,53 @@ bool JackServerGlobals::Init() break; case 'd': - seen_driver = 1; - driver_name = optarg; + master_driver_name = optarg; break; - case 'v': - verbose_aux = 1; + case 'L': + loopback = atoi(optarg); break; - case 'S': - sync = 1; + case 'X': + fSlavesList[optarg] = NULL; break; - case 'n': - server_name = optarg; + case 'I': + fInternalsList[optarg] = -1; + break; + + case 'p': + port_max = (unsigned int)atol(optarg); break; case 'm': do_mlock = 0; break; - case 'p': - port_max = (unsigned int)atol(optarg); + case 'u': + do_unlock = 1; + break; + + case 'v': + verbose_aux = 1; + break; + + case 'S': + sync = 1; + break; + + case 'n': + server_name = optarg; break; case 'P': realtime_priority = atoi(optarg); break; + case 'r': + realtime = 0; + break; + case 'R': realtime = 1; break; @@ -214,14 +273,6 @@ bool JackServerGlobals::Init() client_timeout = atoi(optarg); break; - case 'u': - do_unlock = 1; - break; - - case 'V': - show_version = 1; - break; - default: jack_error("unknown option character %c", optopt); break; @@ -234,9 +285,9 @@ bool JackServerGlobals::Init() goto error; } - driver_desc = jack_find_driver_descriptor(drivers, driver_name); + driver_desc = jack_find_driver_descriptor(drivers, master_driver_name); if (!driver_desc) { - jack_error("jackdmp: unknown driver '%s'", driver_name); + jack_error("jackdmp: unknown master driver '%s'", master_driver_name); goto error; } @@ -252,14 +303,14 @@ bool JackServerGlobals::Init() goto error; } - driver_args = (char**)malloc(sizeof(char*) * driver_nargs); - driver_args[0] = driver_name; + master_driver_args = (char**)malloc(sizeof(char*) * driver_nargs); + master_driver_args[0] = master_driver_name; for (i = 1; i < driver_nargs; i++) { - driver_args[i] = argv[optind++]; + master_driver_args[i] = argv[optind++]; } - if (jack_parse_driver_params(driver_desc, driver_nargs, driver_args, &driver_params)) { + if (jack_parse_driver_params(driver_desc, driver_nargs, master_driver_args, &master_driver_params)) { goto error; } @@ -294,7 +345,7 @@ bool JackServerGlobals::Init() free(argv[i]); } - int res = Start(server_name, driver_desc, driver_params, sync, temporary, client_timeout, realtime, realtime_priority, port_max, verbose_aux, clock_source); + int res = Start(server_name, driver_desc, master_driver_params, sync, temporary, client_timeout, realtime, realtime_priority, port_max, verbose_aux, clock_source); if (res < 0) { jack_error("Cannot start server... exit"); Delete(); @@ -303,16 +354,48 @@ bool JackServerGlobals::Init() jack_unregister_server(server_name); goto error; } + + // Slave drivers + std::map::iterator it1; + for (it1 = fSlavesList.begin(); it1 != fSlavesList.end(); it1++) { + const char* name = ((*it1).first).c_str(); + driver_desc = jack_find_driver_descriptor(drivers, name); + if (!driver_desc) { + jack_error("jackdmp: unknown slave driver '%s'", name); + } else { + (*it1).second = fInstance->AddSlave(driver_desc, NULL); + } + } + + // Loopback driver + if (loopback > 0) { + driver_desc = jack_find_driver_descriptor(drivers, "loopback"); + if (!driver_desc) { + jack_error("jackdmp: unknown driver '%s'", "loopback"); + } else { + fSlavesList["loopback"] = fInstance->AddSlave(driver_desc, NULL); + } + } + + // Internal clients + std::map::iterator it2; + for (it2 = fInternalsList.begin(); it2 != fInternalsList.end(); it2++) { + int status, refnum; + const char* name = ((*it2).first).c_str(); + fInstance->InternalClientLoad2(name, name, NULL, JackNullOption, &refnum, -1, &status); + (*it2).second = refnum; + } } - if (driver_params) - jack_free_driver_params(driver_params); + if (master_driver_params) + jack_free_driver_params(master_driver_params); return true; error: - if (driver_params) - jack_free_driver_params(driver_params); - fUserCount--; + jack_log("JackServerGlobals Init error"); + if (master_driver_params) + jack_free_driver_params(master_driver_params); + Destroy(); return false; } diff --git a/common/JackServerGlobals.h b/common/JackServerGlobals.h index f7d6e439..69b8979e 100644 --- a/common/JackServerGlobals.h +++ b/common/JackServerGlobals.h @@ -24,6 +24,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackDriverLoader.h" #include "JackCompilerDeps.h" #include "JackServer.h" +#include namespace Jack { @@ -39,6 +40,9 @@ struct SERVER_EXPORT JackServerGlobals static JackServer* fInstance; static unsigned int fUserCount; static int fRTNotificationSocket; // For debugging purpose + static std::map fSlavesList; + static std::map fInternalsList; + static bool (* on_device_acquire)(const char* device_name); static void (* on_device_release)(const char* device_name); diff --git a/common/JackThreadedDriver.cpp b/common/JackThreadedDriver.cpp index 52e49197..88323fe5 100644 --- a/common/JackThreadedDriver.cpp +++ b/common/JackThreadedDriver.cpp @@ -152,6 +152,11 @@ bool JackThreadedDriver::IsRealTime() const return fDriver->IsRealTime(); } +bool JackThreadedDriver::IsRunning() const +{ + return fDriver->IsRunning(); +} + int JackThreadedDriver::Start() { jack_log("JackThreadedDriver::Start"); @@ -171,9 +176,9 @@ int JackThreadedDriver::Start() int JackThreadedDriver::Stop() { jack_log("JackThreadedDriver::Stop"); - + switch (fThread.GetStatus()) { - + // Kill the thread in Init phase case JackThread::kStarting: case JackThread::kIniting: @@ -182,15 +187,15 @@ int JackThreadedDriver::Stop() return -1; } break; - + // Stop when the thread cycle is finished case JackThread::kRunning: if (fThread.Stop() < 0) { - jack_error("Cannot stop thread"); + jack_error("Cannot stop thread"); return -1; } break; - + default: break; } @@ -218,7 +223,7 @@ bool JackThreadedDriver::Init() if (fThread.AcquireSelfRealTime(GetEngineControl()->fServerPriority) < 0) { jack_error("AcquireSelfRealTime error"); } else { - set_threaded_log_function(); + set_threaded_log_function(); } } return true; diff --git a/common/JackThreadedDriver.h b/common/JackThreadedDriver.h index f7bbf2d0..92ec1d26 100644 --- a/common/JackThreadedDriver.h +++ b/common/JackThreadedDriver.h @@ -38,14 +38,14 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi JackThread fThread; JackDriver* fDriver; - + public: JackThreadedDriver(JackDriver* driver); virtual ~JackThreadedDriver(); virtual int Open(); - + virtual int Open (bool capturing, bool playing, int inchannels, @@ -54,7 +54,7 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, - jack_nframes_t playback_latency) + jack_nframes_t playback_latency) { return -1; } @@ -70,34 +70,35 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi 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 void SetMaster(bool onoff); virtual bool GetMaster(); virtual void AddSlave(JackDriverInterface* slave); virtual void RemoveSlave(JackDriverInterface* slave); virtual std::list GetSlaves(); virtual int ProcessSlaves(); - + 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 IsRunning() const; + // JackRunnableInterface interface virtual bool Execute(); virtual bool Init(); diff --git a/common/JackWeakAPI.cpp b/common/JackWeakAPI.cpp index d516be76..6ff5af85 100644 --- a/common/JackWeakAPI.cpp +++ b/common/JackWeakAPI.cpp @@ -33,7 +33,7 @@ #include #include -/* dynamically load libjack and forward all registered calls to libjack +/* dynamically load libjack and forward all registered calls to libjack (similar to what relaytool is trying to do, but more portably..) */ @@ -61,15 +61,15 @@ static void __attribute__((constructor)) tryload_libjack() #else libjack_handle = dlopen("libjack.so.0", RTLD_LAZY); #endif - + } libjack_is_present = (libjack_handle != 0); } -void *load_jack_function(const char *fn_name) +void *load_jack_function(const char *fn_name) { void *fn = 0; - if (!libjack_handle) { + if (!libjack_handle) { fprintf (stderr, "libjack not found, so do not try to load %s ffs !\n", fn_name); return 0; } @@ -78,13 +78,13 @@ void *load_jack_function(const char *fn_name) #else fn = dlsym(libjack_handle, fn_name); #endif - if (!fn) { + if (!fn) { #ifdef WIN32 char* lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR) &lpMsgBuf,0,NULL ); fprintf (stderr, "could not GetProcAddress( %s ), %s \n", fn_name, lpMsgBuf) ; -#else - fprintf (stderr, "could not dlsym( %s ), %s \n", fn_name, dlerror()) ; +#else + fprintf (stderr, "could not dlsym( %s ), %s \n", fn_name, dlerror()) ; #endif } return fn; @@ -107,7 +107,7 @@ void *load_jack_function(const char *fn_name) if (fn) return (*fn)arguments; \ else return (return_type)0; \ } - + #define DECL_VOID_FUNCTION(fn_name, arguments_types, arguments) \ typedef void (*fn_name##_ptr_t)arguments_types; \ void fn_name arguments_types { \ @@ -118,8 +118,8 @@ void *load_jack_function(const char *fn_name) DECL_VOID_FUNCTION(jack_get_version, (int *major_ptr, int *minor_ptr, int *micro_ptr, int *proto_ptr), (major_ptr, minor_ptr, micro_ptr, proto_ptr)); -DECL_FUNCTION_NULL(const char *, jack_get_version_string, (), ()); -DECL_FUNCTION_NULL(jack_client_t *, jack_client_open, (const char *client_name, jack_options_t options, jack_status_t *status, ...), +DECL_FUNCTION_NULL(const char *, jack_get_version_string, (), ()); +DECL_FUNCTION_NULL(jack_client_t *, jack_client_open, (const char *client_name, jack_options_t options, jack_status_t *status, ...), (client_name, options, status)); DECL_FUNCTION(int, jack_client_close, (jack_client_t *client), (client)); DECL_FUNCTION_NULL(jack_client_t *, jack_client_new, (const char *client_name), (client_name)); @@ -135,11 +135,11 @@ DECL_VOID_FUNCTION(jack_on_info_shutdown, (jack_client_t* client, JackInfoShutdo DECL_FUNCTION(int, jack_set_process_callback, (jack_client_t *client, JackProcessCallback process_callback, void *arg), (client, process_callback, arg)); -DECL_FUNCTION(jack_nframes_t, jack_thread_wait, (jack_client_t *client, int status), (client, status)); - +DECL_FUNCTION(jack_nframes_t, jack_thread_wait, (jack_client_t *client, int status), (client, status)); + // -DECL_FUNCTION(jack_nframes_t, jack_cycle_wait, (jack_client_t *client), (client)); -DECL_VOID_FUNCTION(jack_cycle_signal, (jack_client_t *client, int status), (client, status)); +DECL_FUNCTION(jack_nframes_t, jack_cycle_wait, (jack_client_t *client), (client)); +DECL_VOID_FUNCTION(jack_cycle_signal, (jack_client_t *client, int status), (client, status)); DECL_FUNCTION(int, jack_set_process_thread, (jack_client_t *client, JackThreadCallback fun, void *arg), (client, fun, arg)); @@ -149,8 +149,8 @@ DECL_FUNCTION(int, jack_set_thread_init_callback, (jack_client_t *client, DECL_FUNCTION(int, jack_set_freewheel_callback, (jack_client_t *client, JackFreewheelCallback freewheel_callback, void *arg), (client, freewheel_callback, arg)); -DECL_FUNCTION(int, jack_set_freewheel, (jack_client_t *client, int onoff), (client, onoff)); -DECL_FUNCTION(int, jack_set_buffer_size, (jack_client_t *client, jack_nframes_t nframes), (client, nframes)); +DECL_FUNCTION(int, jack_set_freewheel, (jack_client_t *client, int onoff), (client, onoff)); +DECL_FUNCTION(int, jack_set_buffer_size, (jack_client_t *client, jack_nframes_t nframes), (client, nframes)); DECL_FUNCTION(int, jack_set_buffer_size_callback, (jack_client_t *client, JackBufferSizeCallback bufsize_callback, void *arg), (client, bufsize_callback, arg)); @@ -175,6 +175,9 @@ DECL_FUNCTION(int, jack_set_graph_order_callback, (jack_client_t *client, DECL_FUNCTION(int, jack_set_xrun_callback, (jack_client_t *client, JackXRunCallback xrun_callback, void *arg), (client, xrun_callback, arg)); +DECL_FUNCTION(int, jack_set_latency_callback, (jack_client_t *client, + JackLatencyCallback latency_callback, + void *arg), (client, latency_callback, arg)); DECL_FUNCTION(int, jack_activate, (jack_client_t *client), (client)); DECL_FUNCTION(int, jack_deactivate, (jack_client_t *client), (client)); DECL_FUNCTION_NULL(jack_port_t *, jack_port_register, (jack_client_t *client, const char *port_name, const char *port_type, @@ -198,6 +201,8 @@ DECL_FUNCTION(jack_nframes_t, jack_port_get_latency, (jack_port_t *port), (port) DECL_FUNCTION(jack_nframes_t, jack_port_get_total_latency ,(jack_client_t * client, jack_port_t *port), (client, port)); DECL_VOID_FUNCTION(jack_port_set_latency, (jack_port_t * port, jack_nframes_t frames), (port, frames)); DECL_FUNCTION(int, jack_recompute_total_latency, (jack_client_t* client, jack_port_t* port), (client, port)); +DECL_VOID_FUNCTION(jack_port_get_latency_range, (jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range), (port, mode, range)); +DECL_VOID_FUNCTION(jack_port_set_latency_range, (jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range), (port, mode, range)); DECL_FUNCTION(int, jack_recompute_total_latencies, (jack_client_t* client),(client)); DECL_FUNCTION(int, jack_port_set_name, (jack_port_t *port, const char *port_name), (port, port_name)); @@ -213,10 +218,11 @@ DECL_FUNCTION(int, jack_disconnect, (jack_client_t * client, const char *source_ DECL_FUNCTION(int, jack_port_disconnect, (jack_client_t * client, jack_port_t * port), (client, port)); DECL_FUNCTION(int, jack_port_name_size,(),()); DECL_FUNCTION(int, jack_port_type_size,(),()); - +DECL_FUNCTION(size_t, jack_port_type_get_buffer_size, (jack_client_t *client, const char* port_type), (client, port_type)); + DECL_FUNCTION(jack_nframes_t, jack_get_sample_rate, (jack_client_t *client), (client)); DECL_FUNCTION(jack_nframes_t, jack_get_buffer_size, (jack_client_t *client), (client)); -DECL_FUNCTION_NULL(const char**, jack_get_ports, (jack_client_t *client, const char *port_name_pattern, const char * type_name_pattern, +DECL_FUNCTION_NULL(const char**, jack_get_ports, (jack_client_t *client, const char *port_name_pattern, const char * type_name_pattern, unsigned long flags), (client, port_name_pattern, type_name_pattern, flags)); DECL_FUNCTION_NULL(jack_port_t *, jack_port_by_name, (jack_client_t * client, const char *port_name), (client, port_name)); DECL_FUNCTION_NULL(jack_port_t *, jack_port_by_id, (jack_client_t *client, jack_port_id_t port_id), (client, port_id)); @@ -240,7 +246,7 @@ DECL_VOID_FUNCTION(jack_reset_max_delayed_usecs, (jack_client_t *client), (clien DECL_FUNCTION(int, jack_release_timebase, (jack_client_t *client), (client)); DECL_FUNCTION(int, jack_set_sync_callback, (jack_client_t *client, JackSyncCallback sync_callback, void *arg), (client, sync_callback, arg)); DECL_FUNCTION(int, jack_set_sync_timeout, (jack_client_t *client, jack_time_t timeout), (client, timeout)); -DECL_FUNCTION(int, jack_set_timebase_callback, (jack_client_t *client, +DECL_FUNCTION(int, jack_set_timebase_callback, (jack_client_t *client, int conditional, JackTimebaseCallback timebase_callback, void *arg), (client, conditional, timebase_callback, arg)); @@ -272,17 +278,27 @@ DECL_VOID_FUNCTION(jack_set_thread_creator, (jack_thread_creator_t jtc), (jtc)); DECL_FUNCTION(char *, jack_get_internal_client_name, (jack_client_t *client, jack_intclient_t intclient), (client, intclient)); DECL_FUNCTION(jack_intclient_t, jack_internal_client_handle, (jack_client_t *client, const char *client_name, jack_status_t *status), (client, client_name, status)); /* -DECL_FUNCTION(jack_intclient_t, jack_internal_client_load, (jack_client_t *client, - const char *client_name, - jack_options_t options, +DECL_FUNCTION(jack_intclient_t, jack_internal_client_load, (jack_client_t *client, + const char *client_name, + jack_options_t options, jack_status_t *status , ...), (client, client_name, options, status, ...)); */ DECL_FUNCTION(jack_status_t, jack_internal_client_unload, (jack_client_t *client, jack_intclient_t intclient), (client, intclient)); DECL_VOID_FUNCTION(jack_free, (void* ptr), (ptr)); -// MIDI +// session +DECL_FUNCTION(int, jack_set_session_callback, (jack_client_t* ext_client, JackSessionCallback session_callback, void* arg), (ext_client, session_callback, arg)); +DECL_FUNCTION(jack_session_command_t*, jack_session_notify, (jack_client_t* ext_client, const char* target, jack_session_event_type_t ev_type, const char* path), (ext_client, target, ev_type, path)à); +DECL_FUNCTION(int jack_session_reply, (jack_client_t* ext_client, jack_session_event_t *event), (ext_client, event)); +DECL_VOID_FUNCTION(jack_session_event_free, (jack_session_event_t* ev), (ev)); +DECL_FUNCTION(char*, jack_get_uuid_for_client_name, (jack_client_t* ext_client, const char* client_name),(ext_client, client_name)); +DECL_FUNCTION(char*, jack_get_client_name_by_uuid, (jack_client_t* ext_client, const char* client_uuid),(ext_client, client_uuid)); +DECL_FUNCTION(int, jack_reserve_client_name, (jack_client_t* ext_client, const char* name, const char* uuid),(ext_client, name, uuid)); +DECL_VOID_FUNCTION(jack_session_commands_free, (jack_session_command_t *cmds),(cmds)); +DECL_FUNCTION(int, jack_client_has_session_callback, (jack_client_t *client, const char* client_name),(client, client_name)); +// MIDI DECL_FUNCTION(jack_nframes_t, jack_midi_get_event_count, (void* port_buffer), (port_buffer)); DECL_FUNCTION(int, jack_midi_event_get, (jack_midi_event_t* event, void* port_buffer, jack_nframes_t event_index), (event, port_buffer, event_index)) ; DECL_VOID_FUNCTION(jack_midi_clear_buffer, (void* port_buffer), (port_buffer)); diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index 1d05eeb8..602aca31 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -26,6 +26,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include #include +#include #include "types.h" #include "jack.h" @@ -101,7 +102,8 @@ static void usage(FILE* file) " [ --timeout OR -t client-timeout-in-msecs ]\n" " [ --loopback OR -L loopback-port-number ]\n" " [ --port-max OR -p maximum-number-of-ports]\n" - " [ --midi OR -X midi-driver ]\n" + " [ --slave-backend OR -X slave-backend-name ]\n" + " [ --internal-client OR -I internal-client-name ]\n" " [ --verbose OR -v ]\n" #ifdef __linux__ " [ --clocksource OR -c [ c(ycle) | h(pet) | s(ystem) ]\n" @@ -111,21 +113,21 @@ static void usage(FILE* file) " [ --sync OR -S ]\n" " [ --temporary OR -T ]\n" " [ --version OR -V ]\n" - " -d backend [ ... backend args ... ]\n" + " -d master-backend-name [ ... master-backend args ... ]\n" #ifdef __APPLE__ - " Available backends may include: coreaudio, dummy or net.\n\n" + " Available master backends may include: coreaudio, dummy or net.\n\n" #endif #ifdef WIN32 - " Available backends may include: portaudio, dummy or net.\n\n" + " Available master backends may include: portaudio, dummy or net.\n\n" #endif #ifdef __linux__ - " Available backends may include: alsa, dummy, freebob, firewire or net\n\n" + " Available master backends may include: alsa, dummy, freebob, firewire or net\n\n" #endif #if defined(__sun__) || defined(sun) - " Available backends may include: boomer, oss, dummy or net.\n\n" + " Available master backends may include: boomer, oss, dummy or net.\n\n" #endif - " jackdmp -d backend --help\n" - " to display options for each backend\n\n"); + " jackdmp -d master-backend-name --help\n" + " to display options for each master backend\n\n"); } // To put in the control.h interface?? @@ -151,6 +153,20 @@ jackctl_server_get_driver( return NULL; } +static jackctl_internal_t * jackctl_server_get_internal(jackctl_server_t *server, const char *internal_name) +{ + const JSList * node_ptr = jackctl_server_get_internals_list(server); + + while (node_ptr) { + if (strcmp(jackctl_internal_get_name((jackctl_internal_t *)node_ptr->data), internal_name) == 0) { + return (jackctl_internal_t *)node_ptr->data; + } + node_ptr = jack_slist_next(node_ptr); + } + + return NULL; +} + static jackctl_parameter_t * jackctl_get_parameter( const JSList * parameters_list, @@ -174,12 +190,11 @@ int main(int argc, char* argv[]) jackctl_server_t * server_ctl; const JSList * server_parameters; const char* server_name = "default"; - jackctl_driver_t * audio_driver_ctl; - jackctl_driver_t * midi_driver_ctl; + jackctl_driver_t * master_driver_ctl; jackctl_driver_t * loopback_driver_ctl; int replace_registry = 0; - const char *options = "-d:X:P:uvshVrRL:STFl:t:mn:p:" + const char *options = "-d:X:I:P:uvshVrRL:STFl:t:mn:p:" #ifdef __linux__ "c:" #endif @@ -192,6 +207,7 @@ int main(int argc, char* argv[]) { "loopback-driver", 1, 0, 'L' }, { "audio-driver", 1, 0, 'd' }, { "midi-driver", 1, 0, 'X' }, + { "internal-client", 1, 0, 'I' }, { "verbose", 0, 0, 'v' }, { "help", 0, 0, 'h' }, { "port-max", 1, 0, 'p' }, @@ -213,14 +229,9 @@ int main(int argc, char* argv[]) int i,opt = 0; int option_index = 0; - bool seen_audio_driver = false; - bool seen_midi_driver = false; - char *audio_driver_name = NULL; - char **audio_driver_args = NULL; - int audio_driver_nargs = 1; - char *midi_driver_name = NULL; - char **midi_driver_args = NULL; - int midi_driver_nargs = 1; + char* master_driver_name = NULL; + char** master_driver_args = NULL; + int master_driver_nargs = 1; int do_mlock = 1; int do_unlock = 0; int loopback = 0; @@ -229,6 +240,14 @@ int main(int argc, char* argv[]) jackctl_parameter_t* param; union jackctl_parameter_value value; + std::list internals_list; + std::list slaves_list; + std::list::iterator it; + + // Assume that we fail. + int return_value = -1; + bool notify_sent = false; + copyright(stdout); #if defined(JACK_DBUS) && defined(__linux__) server_ctl = jackctl_server_create(audio_acquire, audio_release); @@ -250,7 +269,7 @@ int main(int argc, char* argv[]) } opterr = 0; - while (!seen_audio_driver && + while (!master_driver_name && (opt = getopt_long(argc, argv, options, long_options, &option_index)) != EOF) { switch (opt) { @@ -270,15 +289,14 @@ int main(int argc, char* argv[]) jackctl_parameter_set_value(param, &value); } else { usage(stdout); - goto fail_free1; + goto destroy_server; } } break; #endif case 'd': - seen_audio_driver = true; - audio_driver_name = optarg; + master_driver_name = optarg; break; case 'L': @@ -286,8 +304,11 @@ int main(int argc, char* argv[]) break; case 'X': - seen_midi_driver = true; - midi_driver_name = optarg; + slaves_list.push_back(optarg); + break; + + case 'I': + internals_list.push_back(optarg); break; case 'p': @@ -385,7 +406,7 @@ int main(int argc, char* argv[]) case 'h': usage(stdout); - goto fail_free1; + goto destroy_server; } } @@ -404,64 +425,65 @@ int main(int argc, char* argv[]) return -1; } - if (!seen_audio_driver) { + if (!master_driver_name) { usage(stderr); - goto fail_free1; + goto destroy_server; } - // Audio driver - audio_driver_ctl = jackctl_server_get_driver(server_ctl, audio_driver_name); - if (audio_driver_ctl == NULL) { - fprintf(stderr, "Unknown driver \"%s\"\n", audio_driver_name); - goto fail_free1; + // Master driver + master_driver_ctl = jackctl_server_get_driver(server_ctl, master_driver_name); + if (master_driver_ctl == NULL) { + fprintf(stderr, "Unknown driver \"%s\"\n", master_driver_name); + goto destroy_server; } if (optind < argc) { - audio_driver_nargs = 1 + argc - optind; + master_driver_nargs = 1 + argc - optind; } else { - audio_driver_nargs = 1; + master_driver_nargs = 1; } - if (audio_driver_nargs == 0) { + if (master_driver_nargs == 0) { fprintf(stderr, "No driver specified ... hmm. JACK won't do" " anything when run like this.\n"); - goto fail_free1; + goto destroy_server; } - audio_driver_args = (char **) malloc(sizeof(char *) * audio_driver_nargs); - audio_driver_args[0] = audio_driver_name; + master_driver_args = (char **) malloc(sizeof(char *) * master_driver_nargs); + master_driver_args[0] = master_driver_name; - for (i = 1; i < audio_driver_nargs; i++) { - audio_driver_args[i] = argv[optind++]; + for (i = 1; i < master_driver_nargs; i++) { + master_driver_args[i] = argv[optind++]; } - if (jackctl_parse_driver_params(audio_driver_ctl, audio_driver_nargs, audio_driver_args)) { - goto fail_free1; + if (jackctl_parse_driver_params(master_driver_ctl, master_driver_nargs, master_driver_args)) { + goto destroy_server; } - // Setup signals then start server + // Setup signals signals = jackctl_setup_signals(0); - if (!jackctl_server_start(server_ctl, audio_driver_ctl)) { - fprintf(stderr, "Failed to start server\n"); - goto fail_free1; + // Open server + if (! jackctl_server_open(server_ctl, master_driver_ctl)) { + fprintf(stderr, "Failed to open server\n"); + goto destroy_server; } - // MIDI driver - if (seen_midi_driver) { - - midi_driver_ctl = jackctl_server_get_driver(server_ctl, midi_driver_name); - if (midi_driver_ctl == NULL) { - fprintf(stderr, "Unknown driver \"%s\"\n", midi_driver_name); - goto fail_free2; + // Slave drivers + for (it = slaves_list.begin(); it != slaves_list.end(); it++) { + jackctl_driver_t * slave_driver_ctl = jackctl_server_get_driver(server_ctl, *it); + if (slave_driver_ctl == NULL) { + fprintf(stderr, "Unknown driver \"%s\"\n", *it); + goto close_server; } - - jackctl_server_add_slave(server_ctl, midi_driver_ctl); + jackctl_server_add_slave(server_ctl, slave_driver_ctl); } // Loopback driver if (loopback > 0) { loopback_driver_ctl = jackctl_server_get_driver(server_ctl, "loopback"); + + // XX: What if this fails? if (loopback_driver_ctl != NULL) { const JSList * loopback_parameters = jackctl_driver_get_parameters(loopback_driver_ctl); param = jackctl_get_parameter(loopback_parameters, "channels"); @@ -471,27 +493,42 @@ int main(int argc, char* argv[]) } jackctl_server_add_slave(server_ctl, loopback_driver_ctl); } + + } + + // Start the server + if (!jackctl_server_start(server_ctl)) { + fprintf(stderr, "Failed to start server\n"); + goto close_server; + } + + // Internal clients + for (it = internals_list.begin(); it != internals_list.end(); it++) { + jackctl_internal_t * internal_driver_ctl = jackctl_server_get_internal(server_ctl, *it); + if (internal_driver_ctl == NULL) { + fprintf(stderr, "Unknown internal \"%s\"\n", *it); + goto stop_server; + } + jackctl_server_load_internal(server_ctl, internal_driver_ctl); } notify_server_start(server_name); + notify_sent = true; + return_value = 0; // Waits for signal jackctl_wait_signals(signals); - if (!jackctl_server_stop(server_ctl)) + stop_server: + if (! jackctl_server_stop(server_ctl)) { fprintf(stderr, "Cannot stop server...\n"); - - jackctl_server_destroy(server_ctl); - notify_server_stop(server_name); - return 0; - -fail_free1: - jackctl_server_destroy(server_ctl); - return -1; - -fail_free2: - jackctl_server_stop(server_ctl); + } + if (notify_sent) { + notify_server_stop(server_name); + } + close_server: + jackctl_server_close(server_ctl); + destroy_server: jackctl_server_destroy(server_ctl); - notify_server_stop(server_name); - return -1; + return return_value; } diff --git a/common/jack/control.h b/common/jack/control.h index caeb931d..b2c53ab0 100644 --- a/common/jack/control.h +++ b/common/jack/control.h @@ -4,7 +4,7 @@ Copyright (C) 2008 Nedko Arnaudov Copyright (C) 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; version 2 of the License. @@ -86,10 +86,10 @@ extern "C" { * @{ */ -/** +/** * Call this function to setup process signal handling. As a general * rule, it is required for proper operation for the server object. - * + * * @param flags signals setup flags, use 0 for none. Currently no * flags are defined * @@ -99,9 +99,9 @@ sigset_t jackctl_setup_signals( unsigned int flags); -/** +/** * Call this function to wait on a signal set. - * + * * @param signals signals set to wait on */ void @@ -123,43 +123,65 @@ jackctl_server_create( bool (* on_device_acquire)(const char * device_name), void (* on_device_release)(const char * device_name)); -/** +/** * Call this function to destroy server object. - * + * * @param server server object handle to destroy */ void jackctl_server_destroy( jackctl_server_t * server); -/** - * Call this function to start JACK server - * +/** + * Call this function to open JACK server + * * @param server server object handle * @param driver driver to use - * + * * @return success status: true - success, false - fail */ bool -jackctl_server_start( +jackctl_server_open( jackctl_server_t * server, jackctl_driver_t * driver); -/** +/** + * Call this function to start JACK server + * + * @param server server object handle + * + * @return success status: true - success, false - fail + */ +bool +jackctl_server_start( + jackctl_server_t * server); + +/** * Call this function to stop JACK server - * + * * @param server server object handle - * + * * @return success status: true - success, false - fail */ bool jackctl_server_stop( jackctl_server_t * server); -/** +/** + * Call this function to close JACK server + * + * @param server server object handle + * + * @return success status: true - success, false - fail + */ +bool +jackctl_server_close( + jackctl_server_t * server); + +/** * Call this function to get list of available drivers. List node data * pointers is a driver object handle (::jackctl_driver_t). - * + * * @param server server object handle to get drivers for * * @return Single linked list of driver object handles. Must not be @@ -169,10 +191,10 @@ const JSList * jackctl_server_get_drivers_list( jackctl_server_t * server); -/** +/** * Call this function to get list of server parameters. List node data * pointers is a parameter object handle (::jackctl_parameter_t). - * + * * @param server server object handle to get parameters for * * @return Single linked list of parameter object handles. Must not be @@ -182,10 +204,10 @@ const JSList * jackctl_server_get_parameters( jackctl_server_t * server); -/** +/** * Call this function to get list of available internal clients. List node data * pointers is a internal client object handle (::jackctl_internal_t). - * + * * @param server server object handle to get internal clients for * * @return Single linked list of internal client object handles. Must not be @@ -195,12 +217,13 @@ const JSList * jackctl_server_get_internals_list( jackctl_server_t * server); -/** +/** * Call this function to load one internal client. - * + * (can be used when the server is running) + * * @param server server object handle * @param internal internal to use - * + * * @return success status: true - success, false - fail */ bool @@ -208,12 +231,13 @@ jackctl_server_load_internal( jackctl_server_t * server, jackctl_internal_t * internal); -/** +/** * Call this function to unload one internal client. - * + * (can be used when the server is running) + * * @param server server object handle * @param internal internal to unload - * + * * @return success status: true - success, false - fail */ bool @@ -221,46 +245,50 @@ jackctl_server_unload_internal( jackctl_server_t * server, jackctl_internal_t * internal); -/** +/** * Call this function to add a slave in the driver slave list. - * + * (cannot be used when the server is running that is between + * jackctl_server_start and jackctl_server_stop) + * * @param server server object handle * @param driver driver to add in the driver slave list. - * + * * @return success status: true - success, false - fail - */ -bool + */ +bool jackctl_server_add_slave(jackctl_server_t * server, jackctl_driver_t * driver); -/** +/** * Call this function to remove a slave from the driver slave list. - * + * (cannot be used when the server is running that is between + * jackctl_server_start and jackctl_server_stop) + * * @param server server object handle * @param driver driver to remove from the driver slave list. - * + * * @return success status: true - success, false - fail - */ -bool + */ +bool jackctl_server_remove_slave(jackctl_server_t * server, jackctl_driver_t * driver); -/** +/** * Call this function to switch master driver. - * + * * @param server server object handle * @param driver driver to switch to - * + * * @return success status: true - success, false - fail - */ -bool + */ +bool jackctl_server_switch_master(jackctl_server_t * server, jackctl_driver_t * driver); - -/** + +/** * Call this function to get name of driver. - * + * * @param driver driver object handle to get name of * * @return driver name. Must not be modified. Always same for same @@ -270,10 +298,10 @@ const char * jackctl_driver_get_name( jackctl_driver_t * driver); -/** +/** * Call this function to get list of driver parameters. List node data * pointers is a parameter object handle (::jackctl_parameter_t). - * + * * @param driver driver object handle to get parameters for * * @return Single linked list of parameter object handles. Must not be @@ -283,9 +311,9 @@ const JSList * jackctl_driver_get_parameters( jackctl_driver_t * driver); -/** +/** * Call this function to get name of internal client. - * + * * @param internal internal object handle to get name of * * @return internal name. Must not be modified. Always same for same @@ -295,10 +323,10 @@ const char * jackctl_internal_get_name( jackctl_internal_t * internal); -/** +/** * Call this function to get list of internal parameters. List node data * pointers is a parameter object handle (::jackctl_parameter_t). - * + * * @param internal internal object handle to get parameters for * * @return Single linked list of parameter object handles. Must not be @@ -308,9 +336,9 @@ const JSList * jackctl_internal_get_parameters( jackctl_internal_t * internal); -/** +/** * Call this function to get parameter name. - * + * * @param parameter parameter object handle to get name of * * @return parameter name. Must not be modified. Always same for same @@ -320,9 +348,9 @@ const char * jackctl_parameter_get_name( jackctl_parameter_t * parameter); -/** +/** * Call this function to get parameter short description. - * + * * @param parameter parameter object handle to get short description of * * @return parameter short description. Must not be modified. Always @@ -332,9 +360,9 @@ const char * jackctl_parameter_get_short_description( jackctl_parameter_t * parameter); -/** +/** * Call this function to get parameter long description. - * + * * @param parameter parameter object handle to get long description of * * @return parameter long description. Must not be modified. Always @@ -344,9 +372,9 @@ const char * jackctl_parameter_get_long_description( jackctl_parameter_t * parameter); -/** +/** * Call this function to get parameter type. - * + * * @param parameter parameter object handle to get type of * * @return parameter type. Always same for same parameter object. @@ -355,21 +383,21 @@ jackctl_param_type_t jackctl_parameter_get_type( jackctl_parameter_t * parameter); -/** +/** * Call this function to get parameter character. - * + * * @param parameter parameter object handle to get character of * - * @return character. + * @return character. */ char jackctl_parameter_get_id( jackctl_parameter_t * parameter); -/** +/** * Call this function to check whether parameter has been set, or its * default value is being used. - * + * * @param parameter parameter object handle to check * * @return true - parameter is set, false - parameter is using default @@ -379,9 +407,9 @@ bool jackctl_parameter_is_set( jackctl_parameter_t * parameter); -/** +/** * Call this function to reset parameter to its default value. - * + * * @param parameter parameter object handle to reset value of * * @return success status: true - success, false - fail @@ -390,9 +418,9 @@ bool jackctl_parameter_reset( jackctl_parameter_t * parameter); -/** +/** * Call this function to get parameter value. - * + * * @param parameter parameter object handle to get value of * * @return parameter value. @@ -401,9 +429,9 @@ union jackctl_parameter_value jackctl_parameter_get_value( jackctl_parameter_t * parameter); -/** +/** * Call this function to set parameter value. - * + * * @param parameter parameter object handle to get value of * @param value_ptr pointer to variable containing parameter value * @@ -414,9 +442,9 @@ jackctl_parameter_set_value( jackctl_parameter_t * parameter, const union jackctl_parameter_value * value_ptr); -/** +/** * Call this function to get parameter default value. - * + * * @param parameter parameter object handle to get default value of * * @return parameter default value. @@ -424,10 +452,10 @@ jackctl_parameter_set_value( union jackctl_parameter_value jackctl_parameter_get_default_value( jackctl_parameter_t * parameter); - -/** + +/** * Call this function check whether parameter has range constraint. - * + * * @param parameter object handle of parameter to check * * @return whether parameter has range constraint. @@ -436,9 +464,9 @@ bool jackctl_parameter_has_range_constraint( jackctl_parameter_t * parameter); -/** +/** * Call this function check whether parameter has enumeration constraint. - * + * * @param parameter object handle of parameter to check * * @return whether parameter has enumeration constraint. @@ -447,9 +475,9 @@ bool jackctl_parameter_has_enum_constraint( jackctl_parameter_t * parameter); -/** +/** * Call this function get how many enumeration values parameter has. - * + * * @param parameter object handle of parameter * * @return number of enumeration values @@ -458,9 +486,9 @@ uint32_t jackctl_parameter_get_enum_constraints_count( jackctl_parameter_t * parameter); -/** +/** * Call this function to get parameter enumeration value. - * + * * @param parameter object handle of parameter * @param index index of parameter enumeration value * @@ -471,9 +499,9 @@ jackctl_parameter_get_enum_constraint_value( jackctl_parameter_t * parameter, uint32_t index); -/** +/** * Call this function to get parameter enumeration value description. - * + * * @param parameter object handle of parameter * @param index index of parameter enumeration value * @@ -484,9 +512,9 @@ jackctl_parameter_get_enum_constraint_description( jackctl_parameter_t * parameter, uint32_t index); -/** +/** * Call this function to get parameter range. - * + * * @param parameter object handle of parameter * @param min_ptr pointer to variable receiving parameter minimum value * @param max_ptr pointer to variable receiving parameter maximum value @@ -497,10 +525,10 @@ jackctl_parameter_get_range_constraint( union jackctl_parameter_value * min_ptr, union jackctl_parameter_value * max_ptr); -/** +/** * Call this function to check whether parameter constraint is strict, * i.e. whether supplying non-matching value will not work for sure. - * + * * @param parameter parameter object handle to check * * @return whether parameter constraint is strict. @@ -509,11 +537,11 @@ bool jackctl_parameter_constraint_is_strict( jackctl_parameter_t * parameter); -/** +/** * Call this function to check whether parameter has fake values, * i.e. values have no user meaningful meaning and only value * description is meaningful to user. - * + * * @param parameter parameter object handle to check * * @return whether parameter constraint is strict. @@ -522,9 +550,9 @@ bool jackctl_parameter_constraint_is_fake_value( jackctl_parameter_t * parameter); -/** +/** * Call this function to log an error message. - * + * * @param format string */ void @@ -532,9 +560,9 @@ jack_error( const char *format, ...); -/** +/** * Call this function to log an information message. - * + * * @param format string */ void @@ -542,10 +570,10 @@ jack_info( const char *format, ...); -/** +/** * Call this function to log an information message but only when * verbose mode is enabled. - * + * * @param format string */ void diff --git a/common/netjack.c b/common/netjack.c index ce97da5c..e3ec0c33 100644 --- a/common/netjack.c +++ b/common/netjack.c @@ -365,7 +365,7 @@ void netjack_attach( netjack_driver_state_t *netj ) if( netj->bitdepth == CELT_MODE ) { #if HAVE_CELT -#if HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 +#if HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 celt_int32 lookahead; netj->celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); #else @@ -398,7 +398,9 @@ void netjack_attach( netjack_driver_state_t *netj ) if( netj->bitdepth == CELT_MODE ) { #if HAVE_CELT -#if HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 +#if HAVE_CELT_API_0_11 + netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create_custom( netj->celt_mode, 1, NULL ) ); +#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode, 1, NULL ) ); #else netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode ) ); @@ -444,7 +446,10 @@ void netjack_attach( netjack_driver_state_t *netj ) jack_slist_append (netj->playback_ports, port); if( netj->bitdepth == CELT_MODE ) { #if HAVE_CELT -#if HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 +#if HAVE_CELT_API_0_11 + CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); + netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) ); +#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); #else @@ -545,18 +550,18 @@ void netjack_detach( netjack_driver_state_t *netj ) netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj, jack_client_t * client, - const char *name, - unsigned int capture_ports, - unsigned int playback_ports, - unsigned int capture_ports_midi, - unsigned int playback_ports_midi, - jack_nframes_t sample_rate, - jack_nframes_t period_size, - unsigned int listen_port, - unsigned int transport_sync, - unsigned int resample_factor, - unsigned int resample_factor_up, - unsigned int bitdepth, + const char *name, + unsigned int capture_ports, + unsigned int playback_ports, + unsigned int capture_ports_midi, + unsigned int playback_ports_midi, + jack_nframes_t sample_rate, + jack_nframes_t period_size, + unsigned int listen_port, + unsigned int transport_sync, + unsigned int resample_factor, + unsigned int resample_factor_up, + unsigned int bitdepth, unsigned int use_autoconfig, unsigned int latency, unsigned int redundancy, @@ -663,74 +668,74 @@ netjack_startup( netjack_driver_state_t *netj ) netj->srcaddress_valid = 0; if (netj->use_autoconfig) { - jacknet_packet_header *first_packet = alloca (sizeof (jacknet_packet_header)); -#ifdef WIN32 - int address_size = sizeof( struct sockaddr_in ); -#else - socklen_t address_size = sizeof (struct sockaddr_in); -#endif - //jack_info ("Waiting for an incoming packet !!!"); - //jack_info ("*** IMPORTANT *** Dont connect a client to jackd until the driver is attached to a clock source !!!"); - - while(1) { - if( ! netjack_poll( netj->sockfd, 1000 ) ) { - jack_info ("Waiting aborted"); - return -1; - } - first_pack_len = recvfrom (netj->sockfd, (char *)first_packet, sizeof (jacknet_packet_header), 0, (struct sockaddr*) & netj->syncsource_address, &address_size); -#ifdef WIN32 - if( first_pack_len == -1 ) { - first_pack_len = sizeof(jacknet_packet_header); - break; + jacknet_packet_header *first_packet = alloca (sizeof (jacknet_packet_header)); + #ifdef WIN32 + int address_size = sizeof( struct sockaddr_in ); + #else + socklen_t address_size = sizeof (struct sockaddr_in); + #endif + //jack_info ("Waiting for an incoming packet !!!"); + //jack_info ("*** IMPORTANT *** Dont connect a client to jackd until the driver is attached to a clock source !!!"); + + while(1) { + if( ! netjack_poll( netj->sockfd, 1000 ) ) { + jack_info ("Waiting aborted"); + return -1; + } + first_pack_len = recvfrom (netj->sockfd, (char *)first_packet, sizeof (jacknet_packet_header), 0, (struct sockaddr*) & netj->syncsource_address, &address_size); + #ifdef WIN32 + if( first_pack_len == -1 ) { + first_pack_len = sizeof(jacknet_packet_header); + break; + } + #else + if (first_pack_len == sizeof (jacknet_packet_header)) + break; + #endif } -#else - if (first_pack_len == sizeof (jacknet_packet_header)) - break; -#endif - } - netj->srcaddress_valid = 1; + netj->srcaddress_valid = 1; - if (first_pack_len == sizeof (jacknet_packet_header)) - { - packet_header_ntoh (first_packet); - - jack_info ("AutoConfig Override !!!"); - if (netj->sample_rate != first_packet->sample_rate) - { - jack_info ("AutoConfig Override: Master JACK sample rate = %d", first_packet->sample_rate); - netj->sample_rate = first_packet->sample_rate; - } - - if (netj->period_size != first_packet->period_size) - { - jack_info ("AutoConfig Override: Master JACK period size is %d", first_packet->period_size); - netj->period_size = first_packet->period_size; - } - if (netj->capture_channels_audio != first_packet->capture_channels_audio) - { - jack_info ("AutoConfig Override: capture_channels_audio = %d", first_packet->capture_channels_audio); - netj->capture_channels_audio = first_packet->capture_channels_audio; - } - if (netj->capture_channels_midi != first_packet->capture_channels_midi) - { - jack_info ("AutoConfig Override: capture_channels_midi = %d", first_packet->capture_channels_midi); - netj->capture_channels_midi = first_packet->capture_channels_midi; - } - if (netj->playback_channels_audio != first_packet->playback_channels_audio) - { - jack_info ("AutoConfig Override: playback_channels_audio = %d", first_packet->playback_channels_audio); - netj->playback_channels_audio = first_packet->playback_channels_audio; - } - if (netj->playback_channels_midi != first_packet->playback_channels_midi) - { - jack_info ("AutoConfig Override: playback_channels_midi = %d", first_packet->playback_channels_midi); - netj->playback_channels_midi = first_packet->playback_channels_midi; - } - - netj->mtu = first_packet->mtu; - jack_info ("MTU is set to %d bytes", first_packet->mtu); - netj->latency = first_packet->latency; - } + if (first_pack_len == sizeof (jacknet_packet_header)) + { + packet_header_ntoh (first_packet); + + jack_info ("AutoConfig Override !!!"); + if (netj->sample_rate != first_packet->sample_rate) + { + jack_info ("AutoConfig Override: Master JACK sample rate = %d", first_packet->sample_rate); + netj->sample_rate = first_packet->sample_rate; + } + + if (netj->period_size != first_packet->period_size) + { + jack_info ("AutoConfig Override: Master JACK period size is %d", first_packet->period_size); + netj->period_size = first_packet->period_size; + } + if (netj->capture_channels_audio != first_packet->capture_channels_audio) + { + jack_info ("AutoConfig Override: capture_channels_audio = %d", first_packet->capture_channels_audio); + netj->capture_channels_audio = first_packet->capture_channels_audio; + } + if (netj->capture_channels_midi != first_packet->capture_channels_midi) + { + jack_info ("AutoConfig Override: capture_channels_midi = %d", first_packet->capture_channels_midi); + netj->capture_channels_midi = first_packet->capture_channels_midi; + } + if (netj->playback_channels_audio != first_packet->playback_channels_audio) + { + jack_info ("AutoConfig Override: playback_channels_audio = %d", first_packet->playback_channels_audio); + netj->playback_channels_audio = first_packet->playback_channels_audio; + } + if (netj->playback_channels_midi != first_packet->playback_channels_midi) + { + jack_info ("AutoConfig Override: playback_channels_midi = %d", first_packet->playback_channels_midi); + netj->playback_channels_midi = first_packet->playback_channels_midi; + } + + netj->mtu = first_packet->mtu; + jack_info ("MTU is set to %d bytes", first_packet->mtu); + netj->latency = first_packet->latency; + } } netj->capture_channels = netj->capture_channels_audio + netj->capture_channels_midi; netj->playback_channels = netj->playback_channels_audio + netj->playback_channels_midi; @@ -762,21 +767,21 @@ netjack_startup( netjack_driver_state_t *netj ) * 1000000.0f); if( netj->latency == 0 ) - netj->deadline_offset = 50*netj->period_usecs; + netj->deadline_offset = 50*netj->period_usecs; else - netj->deadline_offset = netj->period_usecs + 10*netj->latency*netj->period_usecs/100; + netj->deadline_offset = netj->period_usecs + 10*netj->latency*netj->period_usecs/100; if( netj->bitdepth == CELT_MODE ) { - // celt mode. - // TODO: this is a hack. But i dont want to change the packet header. - netj->resample_factor = (netj->resample_factor * netj->period_size * 1024 / netj->sample_rate / 8)&(~1); - netj->resample_factor_up = (netj->resample_factor_up * netj->period_size * 1024 / netj->sample_rate / 8)&(~1); + // celt mode. + // TODO: this is a hack. But i dont want to change the packet header. + netj->resample_factor = (netj->resample_factor * netj->period_size * 1024 / netj->sample_rate / 8)&(~1); + netj->resample_factor_up = (netj->resample_factor_up * netj->period_size * 1024 / netj->sample_rate / 8)&(~1); - netj->net_period_down = netj->resample_factor; - netj->net_period_up = netj->resample_factor_up; + netj->net_period_down = netj->resample_factor; + netj->net_period_up = netj->resample_factor_up; } else { - netj->net_period_down = (float) netj->period_size / (float) netj->resample_factor; - netj->net_period_up = (float) netj->period_size / (float) netj->resample_factor_up; + netj->net_period_down = (float) netj->period_size / (float) netj->resample_factor; + netj->net_period_up = (float) netj->period_size / (float) netj->resample_factor_up; } netj->rx_bufsize = sizeof (jacknet_packet_header) + netj->net_period_down * netj->capture_channels * get_sample_size (netj->bitdepth); @@ -790,9 +795,9 @@ netjack_startup( netjack_driver_state_t *netj ) // Special handling for latency=0 if( netj->latency == 0 ) - netj->resync_threshold = 0; + netj->resync_threshold = 0; else - netj->resync_threshold = MIN( 15, netj->latency-1 ); + netj->resync_threshold = MIN( 15, netj->latency-1 ); netj->running_free = 0; diff --git a/common/netjack.h b/common/netjack.h index 2bdd092c..bb745829 100644 --- a/common/netjack.h +++ b/common/netjack.h @@ -127,19 +127,19 @@ void netjack_detach( netjack_driver_state_t *netj ); netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj, jack_client_t * client, - const char *name, - unsigned int capture_ports, - unsigned int playback_ports, - unsigned int capture_ports_midi, - unsigned int playback_ports_midi, - jack_nframes_t sample_rate, - jack_nframes_t period_size, - unsigned int listen_port, - unsigned int transport_sync, - unsigned int resample_factor, - unsigned int resample_factor_up, - unsigned int bitdepth, - unsigned int use_autoconfig, + const char *name, + unsigned int capture_ports, + unsigned int playback_ports, + unsigned int capture_ports_midi, + unsigned int playback_ports_midi, + jack_nframes_t sample_rate, + jack_nframes_t period_size, + unsigned int listen_port, + unsigned int transport_sync, + unsigned int resample_factor, + unsigned int resample_factor_up, + unsigned int bitdepth, + unsigned int use_autoconfig, unsigned int latency, unsigned int redundancy, int dont_htonl_floats, diff --git a/common/netjack_packet.c b/common/netjack_packet.c index d03d49f0..638e3d82 100644 --- a/common/netjack_packet.c +++ b/common/netjack_packet.c @@ -130,7 +130,7 @@ int get_sample_size (int bitdepth) //JN: why? is this for buffer sizes before or after encoding? //JN: if the former, why not int16_t, if the latter, shouldn't it depend on -c N? if( bitdepth == CELT_MODE ) - return sizeof( unsigned char ); + return sizeof( unsigned char ); return sizeof (int32_t); } @@ -328,7 +328,6 @@ cache_packet_add_fragment (cache_packet *pack, char *packet_buf, int rcv_len) return; } - if (fragment_nr == 0) { memcpy (pack->packet_buf, packet_buf, rcv_len); @@ -374,7 +373,6 @@ netjack_poll_deadline (int sockfd, jack_time_t deadline) int timeout; #endif - jack_time_t now = jack_get_time(); if( now >= deadline ) return 0; @@ -389,7 +387,6 @@ netjack_poll_deadline (int sockfd, jack_time_t deadline) timeout = lrintf( (float)(deadline - now) / 1000.0 ); #endif - fds.fd = sockfd; fds.events = POLLIN; @@ -600,24 +597,24 @@ packet_cache_retreive_packet_pointer( packet_cache *pcache, jack_nframes_t frame for (i = 0; i < pcache->size; i++) { if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt)) { - cpack = &(pcache->packets[i]); + cpack = &(pcache->packets[i]); break; - } + } } if( cpack == NULL ) { - //printf( "retreive packet: %d....not found\n", framecnt ); - return -1; + //printf( "retreive packet: %d....not found\n", framecnt ); + return -1; } if( !cache_packet_is_complete( cpack ) ) { - return -1; + return -1; } // ok. cpack is the one we want and its complete. *packet_buf = cpack->packet_buf; if( timestamp ) - *timestamp = cpack->recv_timestamp; + *timestamp = cpack->recv_timestamp; pcache->last_framecnt_retreived_valid = 1; pcache->last_framecnt_retreived = framecnt; @@ -634,18 +631,18 @@ packet_cache_release_packet( packet_cache *pcache, jack_nframes_t framecnt ) for (i = 0; i < pcache->size; i++) { if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt)) { - cpack = &(pcache->packets[i]); + cpack = &(pcache->packets[i]); break; - } + } } if( cpack == NULL ) { - //printf( "retreive packet: %d....not found\n", framecnt ); - return -1; + //printf( "retreive packet: %d....not found\n", framecnt ); + return -1; } if( !cache_packet_is_complete( cpack ) ) { - return -1; + return -1; } cache_packet_reset (cpack); @@ -661,13 +658,13 @@ packet_cache_get_fill( packet_cache *pcache, jack_nframes_t expected_framecnt ) for (i = 0; i < pcache->size; i++) { - cache_packet *cpack = &(pcache->packets[i]); + cache_packet *cpack = &(pcache->packets[i]); if (cpack->valid && cache_packet_is_complete( cpack )) - if( cpack->framecnt >= expected_framecnt ) - num_packets_before_us += 1; + if( cpack->framecnt >= expected_framecnt ) + num_packets_before_us += 1; } - return 100.0 * (float)num_packets_before_us / (float)( pcache->size ) ; + return 100.0 * (float)num_packets_before_us / (float)( pcache->size ); } // Returns 0 when no valid packet is inside the cache. @@ -680,29 +677,29 @@ packet_cache_get_next_available_framecnt( packet_cache *pcache, jack_nframes_t e for (i = 0; i < pcache->size; i++) { - cache_packet *cpack = &(pcache->packets[i]); - //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); + cache_packet *cpack = &(pcache->packets[i]); + //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); if (!cpack->valid || !cache_packet_is_complete( cpack )) { - //printf( "invalid\n" ); - continue; - } + //printf( "invalid\n" ); + continue; + } - if( cpack->framecnt < expected_framecnt ) - continue; + if( cpack->framecnt < expected_framecnt ) + continue; - if( (cpack->framecnt - expected_framecnt) > best_offset ) { - continue; + if( (cpack->framecnt - expected_framecnt) > best_offset ) { + continue; } best_offset = cpack->framecnt - expected_framecnt; retval = 1; - if( best_offset == 0 ) + if (best_offset == 0) break; } - if( retval && framecnt ) - *framecnt = expected_framecnt + best_offset; + if (retval && framecnt) + *framecnt = expected_framecnt + best_offset; return retval; } @@ -716,12 +713,12 @@ packet_cache_get_highest_available_framecnt( packet_cache *pcache, jack_nframes_ for (i = 0; i < pcache->size; i++) { - cache_packet *cpack = &(pcache->packets[i]); - //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); + cache_packet *cpack = &(pcache->packets[i]); + //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); if (!cpack->valid || !cache_packet_is_complete( cpack )) { - //printf( "invalid\n" ); - continue; + //printf( "invalid\n" ); + continue; } if (cpack->framecnt < best_value) { @@ -732,8 +729,8 @@ packet_cache_get_highest_available_framecnt( packet_cache *pcache, jack_nframes_ retval = 1; } - if( retval && framecnt ) - *framecnt = best_value; + if (retval && framecnt) + *framecnt = best_value; return retval; } @@ -748,15 +745,15 @@ packet_cache_find_latency( packet_cache *pcache, jack_nframes_t expected_framecn for (i = 0; i < pcache->size; i++) { - cache_packet *cpack = &(pcache->packets[i]); - //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); + cache_packet *cpack = &(pcache->packets[i]); + //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); if (!cpack->valid || !cache_packet_is_complete( cpack )) { - //printf( "invalid\n" ); - continue; + //printf( "invalid\n" ); + continue; } - if( (cpack->framecnt - expected_framecnt) < best_offset ) { + if ((cpack->framecnt - expected_framecnt) < best_offset) { continue; } @@ -766,8 +763,8 @@ packet_cache_find_latency( packet_cache *pcache, jack_nframes_t expected_framecn if( best_offset == 0 ) break; } - if( retval && framecnt ) - *framecnt = JACK_MAX_FRAMES - best_offset; + if (retval && framecnt) + *framecnt = JACK_MAX_FRAMES - best_offset; return retval; } @@ -786,18 +783,18 @@ netjack_sendto (int sockfd, char *packet_buf, int pkt_size, int flags, struct so int fragment_payload_size = mtu - sizeof (jacknet_packet_header); if (pkt_size <= mtu) { - int err; - pkthdr = (jacknet_packet_header *) packet_buf; + int err; + pkthdr = (jacknet_packet_header *) packet_buf; pkthdr->fragment_nr = htonl (0); err = sendto(sockfd, packet_buf, pkt_size, flags, addr, addr_size); - if( err<0 ) { - //printf( "error in send\n" ); - perror( "send" ); - } + if( err<0 ) { + //printf( "error in send\n" ); + perror( "send" ); + } } else { - int err; + int err; // Copy the packet header to the tx pack first. memcpy(tx_packet, packet_buf, sizeof (jacknet_packet_header)); @@ -819,14 +816,13 @@ netjack_sendto (int sockfd, char *packet_buf, int pkt_size, int flags, struct so // sendto(last_pack_size); err = sendto(sockfd, tx_packet, last_payload_size + sizeof(jacknet_packet_header), flags, addr, addr_size); - if( err<0 ) { - //printf( "error in send\n" ); - perror( "send" ); - } + if( err<0 ) { + //printf( "error in send\n" ); + perror( "send" ); + } } } - void decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf) { @@ -907,8 +903,8 @@ render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_pe uint32_t *packet_bufX = (uint32_t *)packet_payload; - if( !packet_payload ) - return; + if (!packet_payload) + return; while (node != NULL) { @@ -951,19 +947,19 @@ render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_pe else #endif { - if( dont_htonl_floats ) - { - memcpy( buf, packet_bufX, net_period_down*sizeof(jack_default_audio_sample_t)); - } - else - { - for (i = 0; i < net_period_down; i++) - { - val.i = packet_bufX[i]; - val.i = ntohl (val.i); - buf[i] = val.f; - } - } + if( dont_htonl_floats ) + { + memcpy( buf, packet_bufX, net_period_down*sizeof(jack_default_audio_sample_t)); + } + else + { + for (i = 0; i < net_period_down; i++) + { + val.i = packet_bufX[i]; + val.i = ntohl (val.i); + buf[i] = val.f; + } + } } } else if (jack_port_is_midi (porttype)) @@ -1031,19 +1027,19 @@ render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_src else #endif { - if( dont_htonl_floats ) - { - memcpy( packet_bufX, buf, net_period_up*sizeof(jack_default_audio_sample_t) ); - } - else - { - for (i = 0; i < net_period_up; i++) - { - val.f = buf[i]; - val.i = htonl (val.i); - packet_bufX[i] = val.i; - } - } + if( dont_htonl_floats ) + { + memcpy( packet_bufX, buf, net_period_up*sizeof(jack_default_audio_sample_t) ); + } + else + { + for (i = 0; i < net_period_up; i++) + { + val.f = buf[i]; + val.i = htonl (val.i); + packet_bufX[i] = val.i; + } + } } } else if (jack_port_is_midi (porttype)) @@ -1218,8 +1214,8 @@ render_payload_to_jack_ports_8bit (void *packet_payload, jack_nframes_t net_peri int8_t *packet_bufX = (int8_t *)packet_payload; - if( !packet_payload ) - return; + if (!packet_payload) + return; while (node != NULL) { @@ -1368,21 +1364,20 @@ render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_peri if (jack_port_is_audio (porttype)) { // audio port, decode celt data. + CELTDecoder *decoder = src_node->data; + #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 + if( !packet_payload ) + celt_decode_float( decoder, NULL, net_period_down, buf, nframes ); + else + celt_decode_float( decoder, packet_bufX, net_period_down, buf, nframes ); + #else + if( !packet_payload ) + celt_decode_float( decoder, NULL, net_period_down, buf ); + else + celt_decode_float( decoder, packet_bufX, net_period_down, buf ); + #endif - CELTDecoder *decoder = src_node->data; -#if HAVE_CELT_API_0_8 - if( !packet_payload ) - celt_decode_float( decoder, NULL, net_period_down, buf, nframes ); - else - celt_decode_float( decoder, packet_bufX, net_period_down, buf, nframes ); -#else - if( !packet_payload ) - celt_decode_float( decoder, NULL, net_period_down, buf ); - else - celt_decode_float( decoder, packet_bufX, net_period_down, buf ); -#endif - - src_node = jack_slist_next (src_node); + src_node = jack_slist_next (src_node); } else if (jack_port_is_midi (porttype)) { @@ -1390,8 +1385,8 @@ render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_peri // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_down / 2; uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; - if( packet_payload ) - decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + if( packet_payload ) + decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } packet_bufX = (packet_bufX + net_period_down); node = jack_slist_next (node); @@ -1422,7 +1417,7 @@ render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs float *floatbuf = alloca (sizeof(float) * nframes ); memcpy( floatbuf, buf, nframes*sizeof(float) ); CELTEncoder *encoder = src_node->data; -#if HAVE_CELT_API_0_8 +#if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 encoded_bytes = celt_encode_float( encoder, floatbuf, nframes, packet_bufX, net_period_up ); #else encoded_bytes = celt_encode_float( encoder, floatbuf, NULL, packet_bufX, net_period_up ); diff --git a/common/varargs.h b/common/varargs.h index b7df00f6..f4a50948 100644 --- a/common/varargs.h +++ b/common/varargs.h @@ -39,23 +39,23 @@ extern "C" } jack_varargs_t; - static const char* jack_default_server_name (void) - { + static const char* jack_default_server_name (void) + { const char *server_name; if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL) server_name = "default"; return server_name; } - static inline void jack_varargs_init (jack_varargs_t *va) - { + static inline void jack_varargs_init (jack_varargs_t *va) + { memset (va, 0, sizeof(jack_varargs_t)); va->server_name = (char*)jack_default_server_name(); va->session_id = -1; } - static inline void jack_varargs_parse (jack_options_t options, va_list ap, jack_varargs_t *va) - { + static inline void jack_varargs_parse (jack_options_t options, va_list ap, jack_varargs_t *va) + { // initialize default settings jack_varargs_init (va); diff --git a/dbus/controller.c b/dbus/controller.c index 9c2bf3a5..77acef39 100644 --- a/dbus/controller.c +++ b/dbus/controller.c @@ -153,14 +153,21 @@ jack_controller_start_server( controller_ptr->xruns = 0; - if (!jackctl_server_start( + if (!jackctl_server_open( controller_ptr->server, controller_ptr->driver)) { - jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to start server"); + jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to open server"); goto fail; } + if (!jackctl_server_start( + controller_ptr->server)) + { + jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to start server"); + goto fail_close_server; + } + controller_ptr->client = jack_client_open( "dbusapi", JackNoStartServer, @@ -213,6 +220,12 @@ fail_stop_server: jack_error("failed to stop jack server"); } +fail_close_server: + if (!jackctl_server_close(controller_ptr->server)) + { + jack_error("failed to close jack server"); + } + fail: return FALSE; } @@ -250,6 +263,12 @@ jack_controller_stop_server( return FALSE; } + if (!jackctl_server_close(controller_ptr->server)) + { + jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to close server"); + return FALSE; + } + controller_ptr->started = false; return TRUE; diff --git a/doxyfile b/doxyfile index 8f1342a4..45b36fda 100644 --- a/doxyfile +++ b/doxyfile @@ -1,4 +1,4 @@ -# Doxyfile 1.2.8.1 +# Doxyfile 1.6.2 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project @@ -11,592 +11,1158 @@ # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- -# General configuration options +# Project related configuration options #--------------------------------------------------------------------------- -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = "Jack2" -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = 1.9.7 -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. -OUTPUT_DIRECTORY = build/default/ +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Brazilian, Chinese, Croatian, Czech, Danish, Dutch, Finnish, French, -# German, Hungarian, Italian, Japanese, Korean, Norwegian, Polish, -# Portuguese, Romanian, Russian, Slovak, Slovene, Spanish and Swedish. +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. -EXTRACT_ALL = NO +BRIEF_MEMBER_DESC = YES -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. -EXTRACT_PRIVATE = NO +REPEAT_BRIEF = YES -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" -EXTRACT_STATIC = NO +ABBREVIATE_BRIEF = -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. -HIDE_UNDOC_MEMBERS = NO +ALWAYS_DETAILED_SEC = NO -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these class will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. -HIDE_UNDOC_CLASSES = NO +INLINE_INHERITED_MEMB = NO -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. -BRIEF_MEMBER_DESC = YES +FULL_PATH_NAMES = NO -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. -REPEAT_BRIEF = YES +STRIP_FROM_PATH = -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. -ALWAYS_DETAILED_SEC = NO +STRIP_FROM_INC_PATH = -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. -FULL_PATH_NAMES = NO +SHORT_NAMES = NO -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. It is allowed to use relative paths in the argument list. +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) -STRIP_FROM_PATH = +JAVADOC_AUTOBRIEF = NO -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) -INTERNAL_DOCS = NO +QT_AUTOBRIEF = NO -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a class diagram (in Html and LaTeX) for classes with base or -# super classes. Setting the tag to NO turns the diagrams off. +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. -CLASS_DIAGRAMS = YES +MULTILINE_CPP_IS_BRIEF = NO -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. -SOURCE_BROWSER = YES +INHERIT_DOCS = YES -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. -INLINE_SOURCES = NO +SEPARATE_MEMBER_PAGES = NO -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. -STRIP_CODE_COMMENTS = YES +TAB_SIZE = 8 -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower case letters. If set to YES upper case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# users are adviced to set this option to NO. +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. -CASE_SENSE_NAMES = YES +ALIASES = -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. -SHORT_NAMES = NO +OPTIMIZE_OUTPUT_FOR_C = NO -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. -HIDE_SCOPE_NAMES = NO +OPTIMIZE_OUTPUT_JAVA = NO -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. -VERBATIM_HEADERS = YES +OPTIMIZE_FOR_FORTRAN = NO -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put list of the files that are included by a file in the documentation -# of that file. +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. -SHOW_INCLUDE_FILES = YES +OPTIMIZE_OUTPUT_VHDL = NO -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like the Qt-style comments (thus requiring an -# explict @brief command for a brief description. +# Doxygen selects the parser to use depending on the extension of the files it parses. +# With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this tag. +# The format is ext=language, where ext is a file extension, and language is one of +# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, +# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. -JAVADOC_AUTOBRIEF = NO +EXTENSION_MAPPING = -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# reimplements. +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. -INHERIT_DOCS = YES +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = NO -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. -DISTRIBUTE_GROUP_DOC = NO +SORT_BRIEF_DOCS = NO -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. -TAB_SIZE = 8 +SORT_MEMBERS_CTORS_1ST = NO -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO -ENABLED_SECTIONS = +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. -ALIASES = +GENERATE_DEPRECATEDLIST= YES -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consist of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. -MAX_INITIALIZER_LINES = 30 +ENABLED_SECTIONS = -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. -# For instance some of the names that are used will be different. The list -# of all members will be omitted, etc. +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. -OPTIMIZE_OUTPUT_FOR_C = NO +MAX_INITIALIZER_LINES = 30 -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by +# doxygen. The layout file controls the global structure of the generated output files +# in an output format independent way. The create the layout file that represents +# doxygen's defaults, run doxygen with the -l option. You can optionally specify a +# file name after the option, if omitted DoxygenLayout.xml will be used as the name +# of the layout file. + +LAYOUT_FILE = + #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- -# The QUIET tag can be used to turn on/off the messages that are generated +# The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO -WARN_FORMAT = +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written +WARN_FORMAT = + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written # to stderr. -WARN_LOGFILE = +WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = common posix macosx macosx/coreaudio/ linux linux/alsa windows windows/portaudio common/jack/ - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -FILE_PATTERNS = *.cpp *.h - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. +INPUT = common \ + posix \ + macosx \ + macosx/coreaudio/ \ + linux \ + linux/alsa \ + windows \ + windows/portaudio \ + common/jack/ + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = *.cpp \ + *.h + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = RPC -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test -EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see # the \include command). -EXAMPLE_PATH = +EXAMPLE_PATH = -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left # blank all files are included. -EXAMPLE_PATTERNS = +EXAMPLE_PATTERNS = -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see # the \image command). -IMAGE_PATH = +IMAGE_PATH = -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes # to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = -INPUT_FILTER = +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse. +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. -IGNORE_PREFIX = +IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. -HTML_OUTPUT = +HTML_OUTPUT = + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a # standard header. -HTML_HEADER = +HTML_HEADER = -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a # standard footer. -HTML_FOOTER = +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = -# The HTML_STYLESHEET tag can be used to specify a user defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. -HTML_STYLESHEET = +HTML_TIMESTAMP = NO -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the Html help documentation and to the tree view. +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER +# are set, an additional index file will be generated that can be used as input for +# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated +# HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. +# For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see +#
Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's +# filter section matches. +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO -# This tag can be used to set the number of enum values (range [1..20]) +# This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript and frames is required (for instance Netscape 4.0+ -# or Internet explorer 4.0+). +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NO -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = NO + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be implemented using a PHP enabled web server instead of at the web client using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server based approach is that it scales better to large projects and allows full text search. The disadvances is that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. -LATEX_OUTPUT = +LATEX_OUTPUT = + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. -EXTRA_PACKAGES = +EXTRA_PACKAGES = -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! -LATEX_HEADER = +LATEX_HEADER = -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimised for Word 97 and may not look very pretty with +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. -RTF_OUTPUT = +RTF_OUTPUT = -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assigments. You only have to provide +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. -RTF_STYLESHEET_FILE = +RTF_STYLESHEET_FILE = -# Set optional variables used in the generation of an rtf document. +# Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. -RTF_EXTENSIONS_FILE = +RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. -MAN_OUTPUT = +MAN_OUTPUT = -# The MAN_EXTENSION tag determines the extension that is added to +# The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) -MAN_EXTENSION = +MAN_EXTENSION = # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity @@ -607,202 +1173,388 @@ MAN_EXTENSION = MAN_LINKS = NO #--------------------------------------------------------------------------- -# Configuration options related to the preprocessor +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_PREDEFINED tags. +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by # the preprocessor. -INCLUDE_PATH = +INCLUDE_PATH = -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. -INCLUDE_FILE_PATTERNS = +INCLUDE_FILE_PATTERNS = -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. -PREDEFINED = +PREDEFINED = -# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. -EXPAND_AS_DEFINED = +EXPAND_AS_DEFINED = -#--------------------------------------------------------------------------- -# Configuration::addtions related to external references -#--------------------------------------------------------------------------- +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. -# The TAGFILES tag can be used to specify one or more tagfiles. +SKIP_FUNCTION_MACROS = YES -TAGFILES = +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- -# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. -GENERATE_TAGFILE = +GENERATE_TAGFILE = -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO -# The PERL_PATH should be the absolute path and name of the perl script +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). -PERL_PATH = +PERL_PATH = #--------------------------------------------------------------------------- -# Configuration options related to the dot tool +# Configuration options related to the dot tool #--------------------------------------------------------------------------- -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. -GRAPHICAL_HIERARCHY = YES +CALL_GRAPH = NO -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found on the path. +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. -DOT_PATH = +CALLER_GRAPH = NO -# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. -MAX_DOT_GRAPH_WIDTH = 1024 +GRAPHICAL_HIERARCHY = YES -# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. -MAX_DOT_GRAPH_HEIGHT = 1024 +DIRECTORY_GRAPH = YES -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. -GENERATE_LEGEND = YES +DOT_IMAGE_FORMAT = png -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermedate dot files that are used to generate -# the various graphs. +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. -DOT_CLEANUP = YES +DOT_PATH = -#--------------------------------------------------------------------------- -# Configuration::addtions related to the search engine -#--------------------------------------------------------------------------- +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO +DOTFILE_DIRS = -# The CGI_NAME tag should be the name of the CGI script that -# starts the search engine (doxysearch) with the correct parameters. -# A script with this name will be generated by doxygen. +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. -CGI_NAME = +DOT_GRAPH_MAX_NODES = 50 -# The CGI_URL tag should be the absolute URL to the directory where the -# cgi binaries are located. See the documentation of your http daemon for -# details. +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. -CGI_URL = +MAX_DOT_GRAPH_DEPTH = 0 -# The DOC_URL tag should be the absolute URL to the directory where the -# documentation is located. If left blank the absolute path to the -# documentation, with file:// prepended to it, will be used. +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). -DOC_URL = +DOT_TRANSPARENT = NO -# The DOC_ABSPATH tag should be the absolute path to the directory where the -# documentation is located. If left blank the directory on the local machine -# will be used. +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. -DOC_ABSPATH = +DOT_MULTI_TARGETS = NO -# The BIN_ABSPATH tag must point to the directory where the doxysearch binary -# is installed. +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. -BIN_ABSPATH = +GENERATE_LEGEND = YES -# The EXT_DOC_PATHS tag can be used to specify one or more paths to -# documentation generated for other projects. This allows doxysearch to search -# the documentation for these projects as well. +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. -EXT_DOC_PATHS = +DOT_CLEANUP = YES diff --git a/example-clients/alsa_in.c b/example-clients/alsa_in.c index 7007fffd..43a030ef 100644 --- a/example-clients/alsa_in.c +++ b/example-clients/alsa_in.c @@ -15,7 +15,7 @@ #include #include -#include +#include "memops.h" #include "alsa/asoundlib.h" diff --git a/example-clients/alsa_out.c b/example-clients/alsa_out.c index 0dfb839f..be25e403 100644 --- a/example-clients/alsa_out.c +++ b/example-clients/alsa_out.c @@ -15,7 +15,7 @@ #include #include -#include +#include "memops.h" #include "alsa/asoundlib.h" diff --git a/example-clients/connect.c b/example-clients/connect.c index a4132cea..3c6de6b9 100644 --- a/example-clients/connect.c +++ b/example-clients/connect.c @@ -31,7 +31,7 @@ jack_port_t *input_port; jack_port_t *output_port; int connecting, disconnecting; -int done = 0; +volatile int done = 0; #define TRUE 1 #define FALSE 0 @@ -58,7 +58,6 @@ show_usage (char *my_name) fprintf (stderr, "For more information see http://jackaudio.org/\n"); } - int main (int argc, char *argv[]) { @@ -181,11 +180,11 @@ main (int argc, char *argv[]) if ((port1 = jack_port_by_name(client, portA)) == 0) { fprintf (stderr, "ERROR %s not a valid port\n", portA); goto exit; - } + } if ((port2 = jack_port_by_name(client, portB)) == 0) { fprintf (stderr, "ERROR %s not a valid port\n", portB); goto exit; - } + } port1_flags = jack_port_flags (port1); port2_flags = jack_port_flags (port2); @@ -207,17 +206,25 @@ main (int argc, char *argv[]) goto exit; } + /* tell the JACK server that we are ready to roll */ + if (jack_activate (client)) { + fprintf (stderr, "cannot activate client"); + goto exit; + } + /* connect the ports. Note: you can't do this before the client is activated (this may change in the future). */ if (connecting) { if (jack_connect(client, jack_port_name(src_port), jack_port_name(dst_port))) { + fprintf (stderr, "cannot connect client, already connected?\n"); goto exit; } } if (disconnecting) { if (jack_disconnect(client, jack_port_name(src_port), jack_port_name(dst_port))) { + fprintf (stderr, "cannot disconnect client, already disconnected?\n"); goto exit; } } diff --git a/example-clients/control.c b/example-clients/control.c index 363b6b21..f22307b6 100644 --- a/example-clients/control.c +++ b/example-clients/control.c @@ -1,4 +1,4 @@ -/** @file simple_client.c +/** @file control.c * * @brief This simple client demonstrates the basic features of JACK * as they would be used by many applications. @@ -14,14 +14,14 @@ jack_client_t *client; static int reorder = 0; - + static int Jack_Graph_Order_Callback(void *arg) { const char **ports; int i; - + printf("Jack_Graph_Order_Callback count = %d\n", reorder++); - + ports = jack_get_ports(client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput); if (ports) { for (i = 0; ports[i]; ++i) { @@ -29,15 +29,15 @@ static int Jack_Graph_Order_Callback(void *arg) } free(ports); } - + ports = jack_get_ports(client, NULL, NULL, JackPortIsPhysical|JackPortIsInput); - if (ports) { + if (ports) { for (i = 0; ports[i]; ++i) { printf("name: %s\n", ports[i]); } free(ports); } - + return 0; } @@ -46,7 +46,7 @@ main (int argc, char *argv[]) { jack_options_t options = JackNullOption; jack_status_t status; - + /* open a client connection to the JACK server */ client = jack_client_open("control_client", options, &status); @@ -54,7 +54,7 @@ main (int argc, char *argv[]) printf("jack_client_open() failed \n"); exit(1); } - + if (jack_set_graph_order_callback(client, Jack_Graph_Order_Callback, 0) != 0) { printf("Error when calling jack_set_graph_order_callback() !\n"); } @@ -66,10 +66,10 @@ main (int argc, char *argv[]) printf("cannot activate client"); exit(1); } - - printf("Type 'q' to quit\n"); + + printf("Type 'q' to quit\n"); while ((getchar() != 'q')) {} - + jack_client_close(client); exit (0); } diff --git a/example-clients/netsource.c b/example-clients/netsource.c index f3cd8274..5dd36265 100644 --- a/example-clients/netsource.c +++ b/example-clients/netsource.c @@ -139,21 +139,24 @@ alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int printf( "jack_netsource: cannot register %s port\n", buf); break; } - if( bitdepth == 1000 ) { -#if HAVE_CELT -#if HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 - CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL ); - capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); -#else - CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), 1, jack_get_buffer_size(client), NULL ); - capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode ) ); -#endif -#endif - } else { -#if HAVE_SAMPLERATE - capture_srcs = jack_slist_append (capture_srcs, src_new (SRC_LINEAR, 1, NULL)); -#endif - } + if (bitdepth == 1000) { + #if HAVE_CELT + #if HAVE_CELT_API_0_11 + CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL ); + capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) ); + #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 + CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL ); + capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); + #else + CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), 1, jack_get_buffer_size(client), NULL ); + capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode ) ); + #endif + #endif + } else { + #if HAVE_SAMPLERATE + capture_srcs = jack_slist_append (capture_srcs, src_new (SRC_LINEAR, 1, NULL)); + #endif + } capture_ports = jack_slist_append (capture_ports, port); } @@ -182,22 +185,25 @@ alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int printf ("jack_netsource: cannot register %s port\n", buf); break; } - if( bitdepth == 1000 ) { -#if HAVE_CELT -#if HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 - CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL ); - playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); -#else - CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), 1, jack_get_buffer_size(client), NULL ); - playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode ) ); -#endif -#endif - } else { -#if HAVE_SAMPLERATE - playback_srcs = jack_slist_append (playback_srcs, src_new (SRC_LINEAR, 1, NULL)); -#endif - } - playback_ports = jack_slist_append (playback_ports, port); + if( bitdepth == 1000 ) { + #if HAVE_CELT + #if HAVE_CELT_API_0_11 + CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL ); + playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create_custom( celt_mode, 1, NULL ) ); + #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 + CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL ); + playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); + #else + CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), 1, jack_get_buffer_size(client), NULL ); + playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode ) ); + #endif + #endif + } else { + #if HAVE_SAMPLERATE + playback_srcs = jack_slist_append (playback_srcs, src_new (SRC_LINEAR, 1, NULL)); + #endif + } + playback_ports = jack_slist_append (playback_ports, port); } /* Allocate midi playback channels */ @@ -226,7 +232,7 @@ sync_cb (jack_transport_state_t state, jack_position_t *pos, void *arg) int retval = sync_state; if (! state_connected) { - return 1; + return 1; } if (latency_count) { latency_count--; @@ -275,14 +281,13 @@ process (jack_nframes_t nframes, void *arg) jack_time_t packet_recv_timestamp; if( bitdepth == 1000 ) - net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8)&(~1) ; + net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8)&(~1) ; else - net_period = (float) nframes / (float) factor; + net_period = (float) nframes / (float) factor; rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header); tx_bufsize = get_sample_size (bitdepth) * playback_channels * net_period + sizeof (jacknet_packet_header); - /* Allocate a buffer where both In and Out Buffer will fit */ packet_buf_tx = alloca (tx_bufsize); @@ -346,29 +351,29 @@ process (jack_nframes_t nframes, void *arg) if( reply_port ) - input_fd = insockfd; + input_fd = insockfd; else - input_fd = outsockfd; + input_fd = outsockfd; // for latency == 0 we can poll. if( (latency == 0) || (freewheeling!=0) ) { - jack_time_t deadline = jack_get_time() + 1000000 * jack_get_buffer_size(client)/jack_get_sample_rate(client); - // Now loop until we get the right packet. - while(1) { - jack_nframes_t got_frame; - if ( ! netjack_poll_deadline( input_fd, deadline ) ) - break; - - packet_cache_drain_socket(packcache, input_fd); - - if (packet_cache_get_next_available_framecnt( packcache, framecnt - latency, &got_frame )) - if( got_frame == (framecnt - latency) ) - break; - } + jack_time_t deadline = jack_get_time() + 1000000 * jack_get_buffer_size(client)/jack_get_sample_rate(client); + // Now loop until we get the right packet. + while(1) { + jack_nframes_t got_frame; + if ( ! netjack_poll_deadline( input_fd, deadline ) ) + break; + + packet_cache_drain_socket(packcache, input_fd); + + if (packet_cache_get_next_available_framecnt( packcache, framecnt - latency, &got_frame )) + if( got_frame == (framecnt - latency) ) + break; + } } else { - // normally: - // only drain socket. - packet_cache_drain_socket(packcache, input_fd); + // normally: + // only drain socket. + packet_cache_drain_socket(packcache, input_fd); } size = packet_cache_retreive_packet_pointer( packcache, framecnt - latency, (char**)&rx_packet_ptr, rx_bufsize, &packet_recv_timestamp ); @@ -376,15 +381,15 @@ process (jack_nframes_t nframes, void *arg) * to the JACK ports so it can be played. */ if (size == rx_bufsize) { - uint32_t *packet_buf_rx = rx_packet_ptr; - jacknet_packet_header *pkthdr_rx = (jacknet_packet_header *) packet_buf_rx; - packet_bufX = packet_buf_rx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); - // calculate how much time there would have been, if this packet was sent at the deadline. + uint32_t *packet_buf_rx = rx_packet_ptr; + jacknet_packet_header *pkthdr_rx = (jacknet_packet_header *) packet_buf_rx; + packet_bufX = packet_buf_rx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); + // calculate how much time there would have been, if this packet was sent at the deadline. - int recv_time_offset = (int) (jack_get_time() - packet_recv_timestamp); - packet_header_ntoh (pkthdr_rx); - deadline_goodness = recv_time_offset - (int)pkthdr_rx->latency; - //printf( "deadline goodness = %d ---> off: %d\n", deadline_goodness, recv_time_offset ); + int recv_time_offset = (int) (jack_get_time() - packet_recv_timestamp); + packet_header_ntoh (pkthdr_rx); + deadline_goodness = recv_time_offset - (int)pkthdr_rx->latency; + //printf( "deadline goodness = %d ---> off: %d\n", deadline_goodness, recv_time_offset ); if (cont_miss) { @@ -394,26 +399,26 @@ process (jack_nframes_t nframes, void *arg) render_payload_to_jack_ports (bitdepth, packet_bufX, net_period, capture_ports, capture_srcs, nframes, dont_htonl_floats); - state_currentframe = framecnt; - state_recv_packet_queue_time = recv_time_offset; - state_connected = 1; + state_currentframe = framecnt; + state_recv_packet_queue_time = recv_time_offset; + state_connected = 1; sync_state = pkthdr_rx->sync_state; - packet_cache_release_packet( packcache, framecnt - latency ); + packet_cache_release_packet( packcache, framecnt - latency ); } /* Second alternative : we've received something that's not * as big as expected or we missed a packet. We render silence * to the ouput ports */ else { - jack_nframes_t latency_estimate; - if( packet_cache_find_latency( packcache, framecnt, &latency_estimate ) ) - //if( (state_latency == 0) || (latency_estimate < state_latency) ) - state_latency = latency_estimate; + jack_nframes_t latency_estimate; + if( packet_cache_find_latency( packcache, framecnt, &latency_estimate ) ) + //if( (state_latency == 0) || (latency_estimate < state_latency) ) + state_latency = latency_estimate; - // Set the counters up. - state_currentframe = framecnt; - //state_latency = framecnt - pkthdr->framecnt; - state_netxruns += 1; + // Set the counters up. + state_currentframe = framecnt; + //state_latency = framecnt - pkthdr->framecnt; + state_netxruns += 1; //printf ("Frame %d \tPacket missed or incomplete (expected: %d bytes, got: %d bytes)\n", framecnt, rx_bufsize, size); //printf ("Frame %d \tPacket missed or incomplete\n", framecnt); @@ -434,7 +439,7 @@ process (jack_nframes_t nframes, void *arg) chn++; } } - if( latency != 0 ) { + if (latency != 0) { /* reset packet_bufX... */ packet_bufX = packet_buf_tx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); @@ -624,15 +629,15 @@ main (int argc, char *argv[]) case 'b': bitdepth = atoi (optarg); break; - case 'c': + case 'c': #if HAVE_CELT - bitdepth = 1000; + bitdepth = 1000; factor = atoi (optarg); #else - printf( "not built with celt supprt\n" ); + printf( "not built with celt support\n" ); exit(10); #endif - break; + break; case 'm': mtu = atoi (optarg); break; @@ -673,24 +678,24 @@ main (int argc, char *argv[]) outsockfd = socket (AF_INET, SOCK_DGRAM, 0); insockfd = socket (AF_INET, SOCK_DGRAM, 0); - if( (outsockfd == -1) || (insockfd == -1) ) { + if ((outsockfd == -1) || (insockfd == -1)) { fprintf (stderr, "cant open sockets\n" ); return 1; } init_sockaddr_in ((struct sockaddr_in *) &destaddr, peer_ip, peer_port); - if(bind_port) { + if (bind_port) { init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, bind_port); if( bind (outsockfd, &bindaddr, sizeof (bindaddr)) ) { - fprintf (stderr, "bind failure\n" ); - } + fprintf (stderr, "bind failure\n" ); + } } - if(reply_port) + if (reply_port) { init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port); if( bind (insockfd, &bindaddr, sizeof (bindaddr)) ) { - fprintf (stderr, "bind failure\n" ); - } + fprintf (stderr, "bind failure\n" ); + } } /* try to become a client of the JACK server */ @@ -711,9 +716,9 @@ main (int argc, char *argv[]) alloc_ports (capture_channels_audio, playback_channels_audio, capture_channels_midi, playback_channels_midi); if( bitdepth == 1000 ) - net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8)&(~1) ; + net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8)&(~1) ; else - net_period = ceilf((float) jack_get_buffer_size (client) / (float) factor); + net_period = ceilf((float) jack_get_buffer_size (client) / (float) factor); int rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header); packcache = packet_cache_new (latency + 50, rx_bufsize, mtu); @@ -757,26 +762,26 @@ main (int argc, char *argv[]) if (statecopy_connected) { - if (statecopy_netxruns != state_netxruns) { - statecopy_netxruns = state_netxruns; - printf ("%s: at frame %06d -> total netxruns %d (%d%%) queue time= %d\n", + if (statecopy_netxruns != state_netxruns) { + statecopy_netxruns = state_netxruns; + printf ("%s: at frame %06d -> total netxruns %d (%d%%) queue time= %d\n", client_name, state_currentframe, statecopy_netxruns, 100*statecopy_netxruns/state_currentframe, state_recv_packet_queue_time); - fflush(stdout); + fflush(stdout); } - } - else + } + else + { + if (statecopy_latency != state_latency) { - if (statecopy_latency != state_latency) - { - statecopy_latency = state_latency; - if (statecopy_latency > 1) - printf ("current latency %d\n", statecopy_latency); - fflush(stdout); + statecopy_latency = state_latency; + if (statecopy_latency > 1) + printf ("current latency %d\n", statecopy_latency); + fflush(stdout); } } } diff --git a/example-clients/server_control.cpp b/example-clients/server_control.cpp index 64ec977c..46efa1bc 100644 --- a/example-clients/server_control.cpp +++ b/example-clients/server_control.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 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 @@ -74,23 +74,23 @@ jackctl_get_parameter( static void print_value(union jackctl_parameter_value value, jackctl_param_type_t type) { switch (type) { - + case JackParamInt: printf("parameter value = %d\n", value.i); break; - + case JackParamUInt: printf("parameter value = %u\n", value.ui); break; - + case JackParamChar: printf("parameter value = %c\n", value.c); break; - + case JackParamString: printf("parameter value = %s\n", value.str); break; - + case JackParamBool: printf("parameter value = %d\n", value.b); break; @@ -115,7 +115,7 @@ static void print_driver(jackctl_driver_t * driver) printf("\n--------------------------\n"); printf("driver = %s\n", jackctl_driver_get_name(driver)); printf("-------------------------- \n"); - print_parameters(jackctl_driver_get_parameters(driver)); + print_parameters(jackctl_driver_get_parameters(driver)); } static void print_internal(jackctl_internal_t * internal) @@ -152,7 +152,7 @@ int main(int argc, char *argv[]) {"driver", 1, 0, 'd'}, {"client", 1, 0, 'c'}, }; - + while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) { switch (opt) { case 'd': @@ -166,10 +166,10 @@ int main(int argc, char *argv[]) exit(0); } } - + server = jackctl_server_create(NULL, NULL); parameters = jackctl_server_get_parameters(server); - + /* jackctl_parameter_t* param; union jackctl_parameter_value value; @@ -179,58 +179,63 @@ int main(int argc, char *argv[]) jackctl_parameter_set_value(param, &value); } */ - + printf("\n========================== \n"); printf("List of server parameters \n"); printf("========================== \n"); - + print_parameters(parameters); - + printf("\n========================== \n"); printf("List of drivers \n"); printf("========================== \n"); - + drivers = jackctl_server_get_drivers_list(server); node_ptr = drivers; while (node_ptr != NULL) { print_driver((jackctl_driver_t *)node_ptr->data); node_ptr = jack_slist_next(node_ptr); } - + printf("\n========================== \n"); printf("List of internal clients \n"); printf("========================== \n"); - + internals = jackctl_server_get_internals_list(server); node_ptr = internals; while (node_ptr != NULL) { print_internal((jackctl_internal_t *)node_ptr->data); node_ptr = jack_slist_next(node_ptr); } - - jackctl_server_start(server, jackctl_server_get_driver(server, driver_name)); + + // No error checking in this simple example... + + jackctl_server_open(server, jackctl_server_get_driver(server, driver_name)); + jackctl_server_start(server); + jackctl_server_load_internal(server, jackctl_server_get_internal(server, client_name)); - + /* // Switch master test - + jackctl_driver_t* master; - + usleep(5000000); printf("jackctl_server_load_master\n"); master = jackctl_server_get_driver(server, "coreaudio"); jackctl_server_switch_master(server, master); - + usleep(5000000); printf("jackctl_server_load_master\n"); master = jackctl_server_get_driver(server, "dummy"); jackctl_server_switch_master(server, master); - + */ - + signals = jackctl_setup_signals(0); jackctl_wait_signals(signals); - + jackctl_server_stop(server); + jackctl_server_close(server); jackctl_server_destroy(server); return 0; } diff --git a/example-clients/wscript b/example-clients/wscript index 54a6a599..d32c1f75 100644 --- a/example-clients/wscript +++ b/example-clients/wscript @@ -63,7 +63,7 @@ def configure(conf): conf.env['BUILD_EXAMPLE_CLIENT_REC'] = conf.is_defined('HAVE_SNDFILE') - conf.env['BUILD_EXAMPLE_ALSA_IO'] = conf.is_defined('HAVE_SAMPLERATE') and conf.is_defined('HAVE_ALSA') + conf.env['BUILD_EXAMPLE_ALSA_IO'] = conf.is_defined('HAVE_SAMPLERATE') and conf.env['BUILD_DRIVER_ALSA'] def build(bld): if bld.env['IS_LINUX']: @@ -137,21 +137,21 @@ def build(bld): prog.target = 'jack_netsource' if bld.env['IS_LINUX'] and bld.env['BUILD_EXAMPLE_ALSA_IO']: - prog = bld.new_task_gen('cc', 'program') - prog.includes = os_incdir + ['../common/jack', '../common'] - prog.source = ['alsa_in.c', '../common/memops.c'] - prog.env.append_value("CCFLAGS", "-DNO_JACK_ERROR") - prog.uselib = 'ALSA SAMPLERATE' - prog.uselib_local = 'clientlib' - prog.target = 'alsa_in' - - prog = bld.new_task_gen('cc', 'program') - prog.includes = os_incdir + ['../common/jack', '../common'] - prog.source = ['alsa_out.c', '../common/memops.c'] - prog.env.append_value("CCFLAGS", "-DNO_JACK_ERROR") - prog.uselib = 'ALSA SAMPLERATE' - prog.uselib_local = 'clientlib' - prog.target = 'alsa_out' + prog = bld.new_task_gen('cc', 'program') + prog.includes = os_incdir + ['../common/jack', '../common'] + prog.source = ['alsa_in.c', '../common/memops.c'] + prog.env.append_value("CCFLAGS", "-DNO_JACK_ERROR") + prog.uselib = 'ALSA SAMPLERATE' + prog.uselib_local = 'clientlib' + prog.target = 'alsa_in' + + prog = bld.new_task_gen('cc', 'program') + prog.includes = os_incdir + ['../common/jack', '../common'] + prog.source = ['alsa_out.c', '../common/memops.c'] + prog.env.append_value("CCFLAGS", "-DNO_JACK_ERROR") + prog.uselib = 'ALSA SAMPLERATE' + prog.uselib_local = 'clientlib' + prog.target = 'alsa_out' for example_lib, example_lib_source in example_libs.items(): lib = bld.new_task_gen('cc', 'shlib') diff --git a/linux/JackLinuxTime.c b/linux/JackLinuxTime.c index d8b474eb..93f7f03f 100644 --- a/linux/JackLinuxTime.c +++ b/linux/JackLinuxTime.c @@ -14,7 +14,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. */ @@ -82,7 +82,7 @@ static int jack_hpet_init () } /* this assumes period to be constant. if needed, - it can be moved to the clock access function + it can be moved to the clock access function */ hpet_period = *((uint32_t *) (hpet_ptr + HPET_PERIOD)); hpet_caps = *((uint32_t *) (hpet_ptr + HPET_CAPS)); @@ -93,7 +93,7 @@ static int jack_hpet_init () return 0; } -static jack_time_t jack_get_microseconds_from_hpet (void) +static jack_time_t jack_get_microseconds_from_hpet (void) { hpet_counter_t hpet_counter; long double hpet_time; @@ -116,7 +116,7 @@ static int jack_hpet_init () return -1; } -static jack_time_t jack_get_microseconds_from_hpet (void) +static jack_time_t jack_get_microseconds_from_hpet (void) { /* never called */ return 0; @@ -168,7 +168,7 @@ static jack_time_t jack_get_mhz (void) ret = sscanf(buf, "bogomips per cpu: %" SCNu64, &mhz); #else /* MIPS, ARM, alpha */ ret = sscanf(buf, "BogoMIPS : %" SCNu64, &mhz); -#endif +#endif if (ret == 1) { @@ -182,7 +182,7 @@ static jack_time_t jack_get_mhz (void) #ifndef HAVE_CLOCK_GETTIME -static jack_time_t jack_get_microseconds_from_system (void) +static jack_time_t jack_get_microseconds_from_system (void) { jack_time_t jackTime; struct timeval tv; @@ -194,7 +194,7 @@ static jack_time_t jack_get_microseconds_from_system (void) #else -static jack_time_t jack_get_microseconds_from_system (void) +static jack_time_t jack_get_microseconds_from_system (void) { jack_time_t jackTime; struct timespec time; @@ -208,7 +208,7 @@ static jack_time_t jack_get_microseconds_from_system (void) #endif /* HAVE_CLOCK_GETTIME */ -SERVER_EXPORT void JackSleep(long usec) +SERVER_EXPORT void JackSleep(long usec) { usleep(usec); } @@ -266,3 +266,9 @@ SERVER_EXPORT jack_time_t GetMicroSeconds() { return _jack_get_microseconds(); } + +SERVER_EXPORT jack_time_t jack_get_microseconds() +{ + return _jack_get_microseconds(); +} + diff --git a/linux/alsa/JackAlsaAdapter.cpp b/linux/alsa/JackAlsaAdapter.cpp index a046e1f2..ba847851 100644 --- a/linux/alsa/JackAlsaAdapter.cpp +++ b/linux/alsa/JackAlsaAdapter.cpp @@ -22,7 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #endif #include "JackAlsaAdapter.h" -#include "JackServerGlobals.h" +#include "JackGlobals.h" #include "JackEngineControl.h" namespace Jack @@ -104,7 +104,7 @@ namespace Jack fAudioInterface.longinfo(); //turn the thread realtime - fThread.AcquireRealTime ( JackServerGlobals::fInstance->GetEngineControl()->fClientPriority ); + fThread.AcquireRealTime(GetEngineControl()->fClientPriority); return 0; } @@ -154,7 +154,7 @@ namespace Jack //read data from audio interface if (fAudioInterface.read() < 0) return false; - + PushAndPull(fAudioInterface.fInputSoftChannels, fAudioInterface.fOutputSoftChannels, fAdaptedBufferSize); //write data to audio interface @@ -273,7 +273,7 @@ extern "C" strcpy ( desc->params[i].short_desc, "Number of playback channels (defaults to hardware max)" ); strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); - + i++; strcpy(desc->params[i].name, "quality"); desc->params[i].character = 'q'; @@ -281,7 +281,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'; diff --git a/linux/alsa/JackAlsaAdapter.h b/linux/alsa/JackAlsaAdapter.h index 8cdde0ee..e4fbad26 100644 --- a/linux/alsa/JackAlsaAdapter.h +++ b/linux/alsa/JackAlsaAdapter.h @@ -145,8 +145,8 @@ namespace Jack void* fOutputCardChannels[256]; //non-interleaved mod, floating point software buffers - float* fInputSoftChannels[256]; - float* fOutputSoftChannels[256]; + jack_default_audio_sample_t* fInputSoftChannels[256]; + jack_default_audio_sample_t* fOutputSoftChannels[256]; //public methods --------------------------------------------------------- @@ -165,12 +165,12 @@ namespace Jack return fBuffering; } - float** inputSoftChannels() + jack_default_audio_sample_t** inputSoftChannels() { return fInputSoftChannels; } - float** outputSoftChannels() + jack_default_audio_sample_t** outputSoftChannels() { return fOutputSoftChannels; } @@ -182,10 +182,10 @@ namespace Jack fInputParams = 0; fOutputParams = 0; fPeriod = 2; - + fInputCardBuffer = 0; fOutputCardBuffer = 0; - + for ( int i = 0; i < 256; i++ ) { fInputCardChannels[i] = 0; @@ -222,18 +222,18 @@ namespace Jack //get hardware input parameters check_error ( snd_pcm_hw_params_malloc ( &fInputParams ) ); setAudioParams ( fInputDevice, fInputParams ); - + //get hardware output parameters check_error ( snd_pcm_hw_params_malloc ( &fOutputParams ) ) setAudioParams ( fOutputDevice, fOutputParams ); - + // set the number of physical input and output channels close to what we need fCardInputs = fSoftInputs; fCardOutputs = fSoftOutputs; - + snd_pcm_hw_params_set_channels_near(fInputDevice, fInputParams, &fCardInputs); snd_pcm_hw_params_set_channels_near(fOutputDevice, fOutputParams, &fCardOutputs); - + //set input/output param check_error ( snd_pcm_hw_params ( fInputDevice, fInputParams ) ); check_error ( snd_pcm_hw_params ( fOutputDevice, fOutputParams ) ); @@ -260,14 +260,14 @@ namespace Jack for ( unsigned int i = 0; i < fSoftInputs; i++ ) { - fInputSoftChannels[i] = ( float* ) aligned_calloc ( fBuffering, sizeof ( float ) ); + fInputSoftChannels[i] = ( jack_default_audio_sample_t* ) aligned_calloc ( fBuffering, sizeof ( jack_default_audio_sample_t ) ); for ( int j = 0; j < fBuffering; j++ ) fInputSoftChannels[i][j] = 0.0; } for ( unsigned int i = 0; i < fSoftOutputs; i++ ) { - fOutputSoftChannels[i] = ( float* ) aligned_calloc ( fBuffering, sizeof ( float ) ); + fOutputSoftChannels[i] = ( jack_default_audio_sample_t* ) aligned_calloc ( fBuffering, sizeof ( jack_default_audio_sample_t ) ); for ( int j = 0; j < fBuffering; j++ ) fOutputSoftChannels[i][j] = 0.0; } @@ -376,14 +376,14 @@ namespace Jack short* buffer16b = ( short* ) fInputCardBuffer; for ( s = 0; s < fBuffering; s++ ) for ( c = 0; c < fCardInputs; c++ ) - fInputSoftChannels[c][s] = float ( buffer16b[c + s*fCardInputs] ) * ( 1.0/float ( SHRT_MAX ) ); + fInputSoftChannels[c][s] = jack_default_audio_sample_t(buffer16b[c + s*fCardInputs]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(SHRT_MAX)); } else // SND_PCM_FORMAT_S32 { int32_t* buffer32b = ( int32_t* ) fInputCardBuffer; for ( s = 0; s < fBuffering; s++ ) for ( c = 0; c < fCardInputs; c++ ) - fInputSoftChannels[c][s] = float ( buffer32b[c + s*fCardInputs] ) * ( 1.0/float ( INT_MAX ) ); + fInputSoftChannels[c][s] = jack_default_audio_sample_t(buffer32b[c + s*fCardInputs]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(INT_MAX)); } break; case SND_PCM_ACCESS_RW_NONINTERLEAVED : @@ -400,7 +400,7 @@ namespace Jack { chan16b = ( short* ) fInputCardChannels[c]; for ( s = 0; s < fBuffering; s++ ) - fInputSoftChannels[c][s] = float ( chan16b[s] ) * ( 1.0/float ( SHRT_MAX ) ); + fInputSoftChannels[c][s] = jack_default_audio_sample_t(chan16b[s]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(SHRT_MAX)); } } else // SND_PCM_FORMAT_S32 @@ -410,7 +410,7 @@ namespace Jack { chan32b = ( int32_t* ) fInputCardChannels[c]; for ( s = 0; s < fBuffering; s++ ) - fInputSoftChannels[c][s] = float ( chan32b[s] ) * ( 1.0/float ( INT_MAX ) ); + fInputSoftChannels[c][s] = jack_default_audio_sample_t(chan32b[s]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(INT_MAX)); } } break; @@ -440,8 +440,8 @@ namespace Jack { for ( unsigned int c = 0; c < fCardOutputs; c++ ) { - float x = fOutputSoftChannels[c][f]; - buffer16b[c + f * fCardOutputs] = short ( max ( min ( x, 1.0 ), -1.0 ) * float ( SHRT_MAX ) ); + jack_default_audio_sample_t x = fOutputSoftChannels[c][f]; + buffer16b[c + f * fCardOutputs] = short(max(min (x, jack_default_audio_sample_t(1.0)), jack_default_audio_sample_t(-1.0)) * jack_default_audio_sample_t(SHRT_MAX)); } } } @@ -452,8 +452,8 @@ namespace Jack { for ( unsigned int c = 0; c < fCardOutputs; c++ ) { - float x = fOutputSoftChannels[c][f]; - buffer32b[c + f * fCardOutputs] = int32_t ( max ( min ( x, 1.0 ), -1.0 ) * float ( INT_MAX ) ); + jack_default_audio_sample_t x = fOutputSoftChannels[c][f]; + buffer32b[c + f * fCardOutputs] = int32_t(max(min(x, jack_default_audio_sample_t(1.0)), jack_default_audio_sample_t(-1.0)) * jack_default_audio_sample_t(INT_MAX)); } } } @@ -474,8 +474,8 @@ namespace Jack short* chan16b = ( short* ) fOutputCardChannels[c]; for ( f = 0; f < fBuffering; f++ ) { - float x = fOutputSoftChannels[c][f]; - chan16b[f] = short ( max ( min ( x,1.0 ), -1.0 ) * float ( SHRT_MAX ) ) ; + jack_default_audio_sample_t x = fOutputSoftChannels[c][f]; + chan16b[f] = short(max(min (x, jack_default_audio_sample_t(1.0)), jack_default_audio_sample_t(-1.0)) * jack_default_audio_sample_t(SHRT_MAX)); } } } @@ -486,8 +486,8 @@ namespace Jack int32_t* chan32b = ( int32_t* ) fOutputCardChannels[c]; for ( f = 0; f < fBuffering; f++ ) { - float x = fOutputSoftChannels[c][f]; - chan32b[f] = int32_t ( max ( min ( x,1.0 ),-1.0 ) * float ( INT_MAX ) ) ; + jack_default_audio_sample_t x = fOutputSoftChannels[c][f]; + chan32b[f] = int32_t(max(min(x, jack_default_audio_sample_t(1.0)), jack_default_audio_sample_t(-1.0)) * jack_default_audio_sample_t(INT_MAX)); } } } diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index fdf5a0cb..b42e9693 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -42,1459 +42,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackLockedEngine.h" #include "JackPosixThread.h" #include "JackCompilerDeps.h" -#include "hammerfall.h" -#include "hdsp.h" -#include "ice1712.h" -#include "usx2y.h" -#include "generic.h" -#include "memops.h" #include "JackServerGlobals.h" - -//#define DEBUG_WAKEUP 1 - -namespace Jack -{ - -#define jack_get_microseconds GetMicroSeconds - -/* Delay (in process calls) before jackd will report an xrun */ -#define XRUN_REPORT_DELAY 0 - -void -JackAlsaDriver::alsa_driver_release_channel_dependent_memory (alsa_driver_t *driver) -{ - bitset_destroy (&driver->channels_done); - bitset_destroy (&driver->channels_not_done); - - if (driver->playback_addr) { - free (driver->playback_addr); - driver->playback_addr = 0; - } - - if (driver->capture_addr) { - free (driver->capture_addr); - driver->capture_addr = 0; - } - - if (driver->playback_interleave_skip) { - free (driver->playback_interleave_skip); - driver->playback_interleave_skip = NULL; - } - - if (driver->capture_interleave_skip) { - free (driver->capture_interleave_skip); - driver->capture_interleave_skip = NULL; - } - - if (driver->silent) { - free (driver->silent); - driver->silent = 0; - } - - if (driver->dither_state) { - free (driver->dither_state); - driver->dither_state = 0; - } -} - -int -JackAlsaDriver::alsa_driver_check_capabilities (alsa_driver_t *driver) -{ - return 0; -} - -static -char * -get_control_device_name (const char * device_name) -{ - char * ctl_name; - regex_t expression; - - regcomp(&expression, "(plug)?hw:[0-9](,[0-9])?", REG_ICASE | REG_EXTENDED); - - if (!regexec(&expression, device_name, 0, NULL, 0)) { - /* the user wants a hw or plughw device, the ctl name - * should be hw:x where x is the card number */ - - char tmp[5]; - strncpy(tmp, strstr(device_name, "hw"), 4); - tmp[4] = '\0'; - jack_info("control device %s",tmp); - ctl_name = strdup(tmp); - } else { - ctl_name = strdup(device_name); - } - - regfree(&expression); - - if (ctl_name == NULL) { - jack_error("strdup(\"%s\") failed.", ctl_name); - } - - return ctl_name; -} - -int -JackAlsaDriver::alsa_driver_check_card_type (alsa_driver_t *driver) -{ - int err; - snd_ctl_card_info_t *card_info; - char * ctl_name; - - snd_ctl_card_info_alloca (&card_info); - - ctl_name = get_control_device_name(driver->alsa_name_playback); - - // XXX: I don't know the "right" way to do this. Which to use - // driver->alsa_name_playback or driver->alsa_name_capture. - if ((err = snd_ctl_open (&driver->ctl_handle, ctl_name, 0)) < 0) { - jack_error ("control open \"%s\" (%s)", ctl_name, - snd_strerror(err)); - } else if ((err = snd_ctl_card_info(driver->ctl_handle, card_info)) < 0) { - jack_error ("control hardware info \"%s\" (%s)", - driver->alsa_name_playback, snd_strerror (err)); - snd_ctl_close (driver->ctl_handle); - } - - driver->alsa_driver = strdup(snd_ctl_card_info_get_driver (card_info)); - jack_info("Using ALSA driver %s running on card %i - %s", driver->alsa_driver, snd_ctl_card_info_get_card(card_info), snd_ctl_card_info_get_longname(card_info)); - - free(ctl_name); - return alsa_driver_check_capabilities (driver); -} - -int -JackAlsaDriver::alsa_driver_hammerfall_hardware (alsa_driver_t *driver) -{ - driver->hw = jack_alsa_hammerfall_hw_new (driver); - return 0; -} - -int -JackAlsaDriver::alsa_driver_hdsp_hardware (alsa_driver_t *driver) -{ - driver->hw = jack_alsa_hdsp_hw_new (driver); - return 0; -} - -int -JackAlsaDriver::alsa_driver_ice1712_hardware (alsa_driver_t *driver) -{ - driver->hw = jack_alsa_ice1712_hw_new (driver); - return 0; -} - -int -JackAlsaDriver::alsa_driver_usx2y_hardware (alsa_driver_t *driver) -{ - // TODO : will need so deeped redesign - // driver->hw = jack_alsa_usx2y_hw_new (driver); - return 0; -} - -int -JackAlsaDriver::alsa_driver_generic_hardware (alsa_driver_t *driver) -{ - driver->hw = jack_alsa_generic_hw_new (driver); - return 0; -} - -int -JackAlsaDriver::alsa_driver_hw_specific (alsa_driver_t *driver, int hw_monitoring, - int hw_metering) -{ - int err; - - if (!strcmp(driver->alsa_driver, "RME9652")) { - if ((err = alsa_driver_hammerfall_hardware (driver)) != 0) { - return err; - } - } else if (!strcmp(driver->alsa_driver, "H-DSP")) { - if ((err = alsa_driver_hdsp_hardware (driver)) != 0) { - return err; - } - } else if (!strcmp(driver->alsa_driver, "ICE1712")) { - if ((err = alsa_driver_ice1712_hardware (driver)) != 0) { - return err; - } - } /*else if (!strcmp(driver->alsa_driver, "USB US-X2Y")) { - if ((err = alsa_driver_usx2y_hardware (driver)) != 0) { - return err; - } - } */else { - if ((err = alsa_driver_generic_hardware (driver)) != 0) { - return err; - } - } - - if (driver->hw->capabilities & Cap_HardwareMonitoring) { - driver->has_hw_monitoring = TRUE; - /* XXX need to ensure that this is really FALSE or - * TRUE or whatever*/ - driver->hw_monitoring = hw_monitoring; - } else { - driver->has_hw_monitoring = FALSE; - driver->hw_monitoring = FALSE; - } - - if (driver->hw->capabilities & Cap_ClockLockReporting) { - driver->has_clock_sync_reporting = TRUE; - } else { - driver->has_clock_sync_reporting = FALSE; - } - - if (driver->hw->capabilities & Cap_HardwareMetering) { - driver->has_hw_metering = TRUE; - driver->hw_metering = hw_metering; - } else { - driver->has_hw_metering = FALSE; - driver->hw_metering = FALSE; - } - - return 0; -} - -int -JackAlsaDriver::alsa_driver_setup_io_function_pointers (alsa_driver_t *driver) -{ - if (driver->playback_handle) { - if (SND_PCM_FORMAT_FLOAT_LE == driver->playback_sample_format) { - if (driver->playback_interleaved) { - driver->channel_copy = memcpy_interleave_d32_s32; - } else { - driver->channel_copy = memcpy_fake; - } - driver->read_via_copy = sample_move_floatLE_sSs; - driver->write_via_copy = sample_move_dS_floatLE; - } else { - - switch (driver->playback_sample_bytes) { - case 2: - if (driver->playback_interleaved) { - driver->channel_copy = memcpy_interleave_d16_s16; - } else { - driver->channel_copy = memcpy_fake; - } - - switch (driver->dither) { - case Rectangular: - jack_info("Rectangular dithering at 16 bits"); - driver->write_via_copy = driver->quirk_bswap? - sample_move_dither_rect_d16_sSs: - sample_move_dither_rect_d16_sS; - break; - - case Triangular: - jack_info("Triangular dithering at 16 bits"); - driver->write_via_copy = driver->quirk_bswap? - sample_move_dither_tri_d16_sSs: - sample_move_dither_tri_d16_sS; - break; - - case Shaped: - jack_info("Noise-shaped dithering at 16 bits"); - driver->write_via_copy = driver->quirk_bswap? - sample_move_dither_shaped_d16_sSs: - sample_move_dither_shaped_d16_sS; - break; - - default: - driver->write_via_copy = driver->quirk_bswap? - sample_move_d16_sSs : - sample_move_d16_sS; - break; - } - break; - - case 3: /* NO DITHER */ - if (driver->playback_interleaved) { - driver->channel_copy = memcpy_interleave_d24_s24; - } else { - driver->channel_copy = memcpy_fake; - } - - driver->write_via_copy = driver->quirk_bswap? - sample_move_d24_sSs: - sample_move_d24_sS; - - break; - - case 4: /* NO DITHER */ - if (driver->playback_interleaved) { - driver->channel_copy = memcpy_interleave_d32_s32; - } else { - driver->channel_copy = memcpy_fake; - } - - driver->write_via_copy = driver->quirk_bswap? - sample_move_d32u24_sSs: - sample_move_d32u24_sS; - break; - - default: - jack_error ("impossible sample width (%d) discovered!", - driver->playback_sample_bytes); - return -1; - } - } - } - - if (driver->capture_handle) { - switch (driver->capture_sample_bytes) { - case 2: - driver->read_via_copy = driver->quirk_bswap? - sample_move_dS_s16s: - sample_move_dS_s16; - break; - case 3: - driver->read_via_copy = driver->quirk_bswap? - sample_move_dS_s24s: - sample_move_dS_s24; - break; - case 4: - driver->read_via_copy = driver->quirk_bswap? - sample_move_dS_s32u24s: - sample_move_dS_s32u24; - break; - } - } - - return 0; -} - -int -JackAlsaDriver::alsa_driver_configure_stream (alsa_driver_t *driver, char *device_name, - const char *stream_name, - snd_pcm_t *handle, - snd_pcm_hw_params_t *hw_params, - snd_pcm_sw_params_t *sw_params, - unsigned int *nperiodsp, - unsigned long *nchns, - unsigned long sample_width) -{ - int err, format; - unsigned int frame_rate; - snd_pcm_uframes_t stop_th; - static struct { - char Name[32]; - snd_pcm_format_t format; - int swapped; - } formats[] = { - {"32bit float little-endian", SND_PCM_FORMAT_FLOAT_LE}, - {"32bit integer little-endian", SND_PCM_FORMAT_S32_LE, IS_LE}, - {"32bit integer big-endian", SND_PCM_FORMAT_S32_BE, IS_BE}, - {"24bit little-endian", SND_PCM_FORMAT_S24_3LE, IS_LE}, - {"24bit big-endian", SND_PCM_FORMAT_S24_3BE, IS_BE}, - {"16bit little-endian", SND_PCM_FORMAT_S16_LE, IS_LE}, - {"16bit big-endian", SND_PCM_FORMAT_S16_BE, IS_BE}, - }; -#define NUMFORMATS (sizeof(formats)/sizeof(formats[0])) -#define FIRST_16BIT_FORMAT 5 - - if ((err = snd_pcm_hw_params_any (handle, hw_params)) < 0) { - jack_error ("ALSA: no playback configurations available (%s)", - snd_strerror (err)); - return -1; - } - - if ((err = snd_pcm_hw_params_set_periods_integer (handle, hw_params)) - < 0) { - jack_error ("ALSA: cannot restrict period size to integral" - " value."); - return -1; - } - - if ((err = snd_pcm_hw_params_set_access (handle, hw_params, SND_PCM_ACCESS_MMAP_NONINTERLEAVED)) < 0) { - if ((err = snd_pcm_hw_params_set_access (handle, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0) { - if ((err = snd_pcm_hw_params_set_access ( - handle, hw_params, - SND_PCM_ACCESS_MMAP_COMPLEX)) < 0) { - jack_error ("ALSA: mmap-based access is not possible" - " for the %s " - "stream of this audio interface", - stream_name); - return -1; - } - } - } - - format = (sample_width == 4) ? 0 : NUMFORMATS - 1; - - while (1) { - if ((err = snd_pcm_hw_params_set_format ( - handle, hw_params, formats[format].format)) < 0) { - - if ((sample_width == 4 - ? format++ >= NUMFORMATS - 1 - : format-- <= 0)) { - jack_error ("Sorry. The audio interface \"%s\"" - " doesn't support any of the" - " hardware sample formats that" - " JACK's alsa-driver can use.", - device_name); - return -1; - } - } else { - if (formats[format].swapped) { - driver->quirk_bswap = 1; - } else { - driver->quirk_bswap = 0; - } - jack_info ("ALSA: final selected sample format for %s: %s", stream_name, formats[format].Name); - break; - } - } - - frame_rate = driver->frame_rate ; - err = snd_pcm_hw_params_set_rate_near (handle, hw_params, - &frame_rate, NULL) ; - driver->frame_rate = frame_rate ; - if (err < 0) { - jack_error ("ALSA: cannot set sample/frame rate to %" - PRIu32 " for %s", driver->frame_rate, - stream_name); - return -1; - } - if (!*nchns) { - /*if not user-specified, try to find the maximum - * number of channels */ - unsigned int channels_max ; - err = snd_pcm_hw_params_get_channels_max (hw_params, - &channels_max); - *nchns = channels_max ; - - if (*nchns > 1024) { - - /* the hapless user is an unwitting victim of - the "default" ALSA PCM device, which can - support up to 16 million channels. since - they can't be bothered to set up a proper - default device, limit the number of - channels for them to a sane default. - */ - - jack_error ( -"You appear to be using the ALSA software \"plug\" layer, probably\n" -"a result of using the \"default\" ALSA device. This is less\n" -"efficient than it could be. Consider using a hardware device\n" -"instead rather than using the plug layer. Usually the name of the\n" -"hardware device that corresponds to the first sound card is hw:0\n" - ); - *nchns = 2; - } - } - - if ((err = snd_pcm_hw_params_set_channels (handle, hw_params, - *nchns)) < 0) { - jack_error ("ALSA: cannot set channel count to %u for %s", - *nchns, stream_name); - return -1; - } - - if ((err = snd_pcm_hw_params_set_period_size (handle, hw_params, - driver->frames_per_cycle, - 0)) - < 0) { - jack_error ("ALSA: cannot set period size to %" PRIu32 - " frames for %s", driver->frames_per_cycle, - stream_name); - return -1; - } - - *nperiodsp = driver->user_nperiods; - snd_pcm_hw_params_set_periods_min (handle, hw_params, nperiodsp, NULL); - if (*nperiodsp < driver->user_nperiods) - *nperiodsp = driver->user_nperiods; - if (snd_pcm_hw_params_set_periods_near (handle, hw_params, - nperiodsp, NULL) < 0) { - jack_error ("ALSA: cannot set number of periods to %u for %s", - *nperiodsp, stream_name); - return -1; - } - - if (*nperiodsp < driver->user_nperiods) { - jack_error ("ALSA: got smaller periods %u than %u for %s", - *nperiodsp, (unsigned int) driver->user_nperiods, - stream_name); - return -1; - } - jack_info ("ALSA: use %d periods for %s", *nperiodsp, stream_name); -#if 0 - if (!jack_power_of_two(driver->frames_per_cycle)) { - jack_error("JACK: frames must be a power of two " - "(64, 512, 1024, ...)\n"); - return -1; - } -#endif - - if ((err = snd_pcm_hw_params_set_buffer_size (handle, hw_params, - *nperiodsp * - driver->frames_per_cycle)) - < 0) { - jack_error ("ALSA: cannot set buffer length to %" PRIu32 - " for %s", - *nperiodsp * driver->frames_per_cycle, - stream_name); - return -1; - } - - if ((err = snd_pcm_hw_params (handle, hw_params)) < 0) { - jack_error ("ALSA: cannot set hardware parameters for %s", - stream_name); - return -1; - } - - snd_pcm_sw_params_current (handle, sw_params); - - if ((err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, - 0U)) < 0) { - jack_error ("ALSA: cannot set start mode for %s", stream_name); - return -1; - } - - stop_th = *nperiodsp * driver->frames_per_cycle; - if (driver->soft_mode) { - stop_th = (snd_pcm_uframes_t)-1; - } - - if ((err = snd_pcm_sw_params_set_stop_threshold ( - handle, sw_params, stop_th)) < 0) { - jack_error ("ALSA: cannot set stop mode for %s", - stream_name); - return -1; - } - - if ((err = snd_pcm_sw_params_set_silence_threshold ( - handle, sw_params, 0)) < 0) { - jack_error ("ALSA: cannot set silence threshold for %s", - stream_name); - return -1; - } - -#if 0 - jack_info ("set silence size to %lu * %lu = %lu", - driver->frames_per_cycle, *nperiodsp, - driver->frames_per_cycle * *nperiodsp); - - if ((err = snd_pcm_sw_params_set_silence_size ( - handle, sw_params, - driver->frames_per_cycle * *nperiodsp)) < 0) { - jack_error ("ALSA: cannot set silence size for %s", - stream_name); - return -1; - } -#endif - - if (handle == driver->playback_handle) - err = snd_pcm_sw_params_set_avail_min ( - handle, sw_params, - driver->frames_per_cycle - * (*nperiodsp - driver->user_nperiods + 1)); - else - err = snd_pcm_sw_params_set_avail_min ( - handle, sw_params, driver->frames_per_cycle); - - if (err < 0) { - jack_error ("ALSA: cannot set avail min for %s", stream_name); - return -1; - } - - if ((err = snd_pcm_sw_params (handle, sw_params)) < 0) { - jack_error ("ALSA: cannot set software parameters for %s\n", - stream_name); - return -1; - } - - return 0; -} - -int -JackAlsaDriver::alsa_driver_set_parameters (alsa_driver_t *driver, - jack_nframes_t frames_per_cycle, - jack_nframes_t user_nperiods, - jack_nframes_t rate) -{ - int dir; - snd_pcm_uframes_t p_period_size = 0; - snd_pcm_uframes_t c_period_size = 0; - channel_t chn; - unsigned int pr = 0; - unsigned int cr = 0; - int err; - - driver->frame_rate = rate; - driver->frames_per_cycle = frames_per_cycle; - driver->user_nperiods = user_nperiods; - - jack_info ("configuring for %" PRIu32 "Hz, period = %" - PRIu32 " frames (%.1f ms), buffer = %" PRIu32 " periods", - rate, frames_per_cycle, (((float)frames_per_cycle / (float) rate) * 1000.0f), user_nperiods); - - if (driver->capture_handle) { - if (alsa_driver_configure_stream ( - driver, - driver->alsa_name_capture, - "capture", - driver->capture_handle, - driver->capture_hw_params, - driver->capture_sw_params, - &driver->capture_nperiods, - (long unsigned int*)&driver->capture_nchannels, - driver->capture_sample_bytes)) { - jack_error ("ALSA: cannot configure capture channel"); - return -1; - } - } - - if (driver->playback_handle) { - if (alsa_driver_configure_stream ( - driver, - driver->alsa_name_playback, - "playback", - driver->playback_handle, - driver->playback_hw_params, - driver->playback_sw_params, - &driver->playback_nperiods, - (long unsigned int*)&driver->playback_nchannels, - driver->playback_sample_bytes)) { - jack_error ("ALSA: cannot configure playback channel"); - return -1; - } - } - - /* check the rate, since thats rather important */ - - if (driver->playback_handle) { - snd_pcm_hw_params_get_rate (driver->playback_hw_params, - &pr, &dir); - } - - if (driver->capture_handle) { - snd_pcm_hw_params_get_rate (driver->capture_hw_params, - &cr, &dir); - } - - if (driver->capture_handle && driver->playback_handle) { - if (cr != pr) { - jack_error ("playback and capture sample rates do " - "not match (%d vs. %d)", pr, cr); - } - - /* only change if *both* capture and playback rates - * don't match requested certain hardware actually - * still works properly in full-duplex with slightly - * different rate values between adc and dac - */ - if (cr != driver->frame_rate && pr != driver->frame_rate) { - jack_error ("sample rate in use (%d Hz) does not " - "match requested rate (%d Hz)", - cr, driver->frame_rate); - driver->frame_rate = cr; - } - - } else if (driver->capture_handle && cr != driver->frame_rate) { - jack_error ("capture sample rate in use (%d Hz) does not " - "match requested rate (%d Hz)", - cr, driver->frame_rate); - driver->frame_rate = cr; - } else if (driver->playback_handle && pr != driver->frame_rate) { - jack_error ("playback sample rate in use (%d Hz) does not " - "match requested rate (%d Hz)", - pr, driver->frame_rate); - driver->frame_rate = pr; - } - - - /* check the fragment size, since thats non-negotiable */ - - if (driver->playback_handle) { - snd_pcm_access_t access; - - err = snd_pcm_hw_params_get_period_size ( - driver->playback_hw_params, &p_period_size, &dir); - err = snd_pcm_hw_params_get_format ( - driver->playback_hw_params, - &(driver->playback_sample_format)); - err = snd_pcm_hw_params_get_access (driver->playback_hw_params, - &access); - driver->playback_interleaved = - (access == SND_PCM_ACCESS_MMAP_INTERLEAVED) - || (access == SND_PCM_ACCESS_MMAP_COMPLEX); - - if (p_period_size != driver->frames_per_cycle) { - jack_error ("alsa_pcm: requested an interrupt every %" - PRIu32 - " frames but got %u frames for playback", - driver->frames_per_cycle, p_period_size); - return -1; - } - } - - if (driver->capture_handle) { - snd_pcm_access_t access; - - err = snd_pcm_hw_params_get_period_size ( - driver->capture_hw_params, &c_period_size, &dir); - err = snd_pcm_hw_params_get_format ( - driver->capture_hw_params, - &(driver->capture_sample_format)); - err = snd_pcm_hw_params_get_access (driver->capture_hw_params, - &access); - driver->capture_interleaved = - (access == SND_PCM_ACCESS_MMAP_INTERLEAVED) - || (access == SND_PCM_ACCESS_MMAP_COMPLEX); - - - if (c_period_size != driver->frames_per_cycle) { - jack_error ("alsa_pcm: requested an interrupt every %" - PRIu32 - " frames but got %uc frames for capture", - driver->frames_per_cycle, p_period_size); - return -1; - } - } - - driver->playback_sample_bytes = - snd_pcm_format_physical_width (driver->playback_sample_format) - / 8; - driver->capture_sample_bytes = - snd_pcm_format_physical_width (driver->capture_sample_format) - / 8; - - if (driver->playback_handle) { - switch (driver->playback_sample_format) { - case SND_PCM_FORMAT_FLOAT_LE: - case SND_PCM_FORMAT_S32_LE: - case SND_PCM_FORMAT_S24_3LE: - case SND_PCM_FORMAT_S24_3BE: - case SND_PCM_FORMAT_S16_LE: - case SND_PCM_FORMAT_S32_BE: - case SND_PCM_FORMAT_S16_BE: - break; - - default: - jack_error ("programming error: unhandled format " - "type for playback"); - return -1; - } - } - - if (driver->capture_handle) { - switch (driver->capture_sample_format) { - case SND_PCM_FORMAT_FLOAT_LE: - case SND_PCM_FORMAT_S32_LE: - case SND_PCM_FORMAT_S24_3LE: - case SND_PCM_FORMAT_S24_3BE: - case SND_PCM_FORMAT_S16_LE: - case SND_PCM_FORMAT_S32_BE: - case SND_PCM_FORMAT_S16_BE: - break; - - default: - jack_error ("programming error: unhandled format " - "type for capture"); - return -1; - } - } - - if (driver->playback_interleaved) { - const snd_pcm_channel_area_t *my_areas; - snd_pcm_uframes_t offset, frames; - if (snd_pcm_mmap_begin(driver->playback_handle, - &my_areas, &offset, &frames) < 0) { - jack_error ("ALSA: %s: mmap areas info error", - driver->alsa_name_playback); - return -1; - } - driver->interleave_unit = - snd_pcm_format_physical_width ( - driver->playback_sample_format) / 8; - } else { - driver->interleave_unit = 0; /* NOT USED */ - } - - if (driver->capture_interleaved) { - const snd_pcm_channel_area_t *my_areas; - snd_pcm_uframes_t offset, frames; - if (snd_pcm_mmap_begin(driver->capture_handle, - &my_areas, &offset, &frames) < 0) { - jack_error ("ALSA: %s: mmap areas info error", - driver->alsa_name_capture); - return -1; - } - } - - if (driver->playback_nchannels > driver->capture_nchannels) { - driver->max_nchannels = driver->playback_nchannels; - driver->user_nchannels = driver->capture_nchannels; - } else { - driver->max_nchannels = driver->capture_nchannels; - driver->user_nchannels = driver->playback_nchannels; - } - - if (alsa_driver_setup_io_function_pointers (driver) != 0) - return -1; - - /* Allocate and initialize structures that rely on the - channels counts. - - Set up the bit pattern that is used to record which - channels require action on every cycle. any bits that are - not set after the engine's process() call indicate channels - that potentially need to be silenced. - */ - - bitset_create (&driver->channels_done, driver->max_nchannels); - bitset_create (&driver->channels_not_done, driver->max_nchannels); - - if (driver->playback_handle) { - driver->playback_addr = (char **) - malloc (sizeof (char *) * driver->playback_nchannels); - memset (driver->playback_addr, 0, - sizeof (char *) * driver->playback_nchannels); - driver->playback_interleave_skip = (unsigned long *) - malloc (sizeof (unsigned long *) * driver->playback_nchannels); - memset (driver->playback_interleave_skip, 0, - sizeof (unsigned long *) * driver->playback_nchannels); - driver->silent = (unsigned long *) - malloc (sizeof (unsigned long) - * driver->playback_nchannels); - - for (chn = 0; chn < driver->playback_nchannels; chn++) { - driver->silent[chn] = 0; - } - - for (chn = 0; chn < driver->playback_nchannels; chn++) { - bitset_add (driver->channels_done, chn); - } - - driver->dither_state = (dither_state_t *) - calloc ( driver->playback_nchannels, - sizeof (dither_state_t)); - } - - if (driver->capture_handle) { - driver->capture_addr = (char **) - malloc (sizeof (char *) * driver->capture_nchannels); - memset (driver->capture_addr, 0, - sizeof (char *) * driver->capture_nchannels); - driver->capture_interleave_skip = (unsigned long *) - malloc (sizeof (unsigned long *) * driver->capture_nchannels); - memset (driver->capture_interleave_skip, 0, - sizeof (unsigned long *) * driver->capture_nchannels); - } - - driver->clock_sync_data = (ClockSyncStatus *) - malloc (sizeof (ClockSyncStatus) * driver->max_nchannels); - - driver->period_usecs = - (jack_time_t) floor ((((float) driver->frames_per_cycle) / - driver->frame_rate) * 1000000.0f); - driver->poll_timeout = (int) floor (1.5f * driver->period_usecs); - - // steph - /* - if (driver->engine) { - driver->engine->set_buffer_size (driver->engine, - driver->frames_per_cycle); - } - */ - return 0; -} - -int -JackAlsaDriver::alsa_driver_reset_parameters (alsa_driver_t *driver, - jack_nframes_t frames_per_cycle, - jack_nframes_t user_nperiods, - jack_nframes_t rate) -{ - /* XXX unregister old ports ? */ - alsa_driver_release_channel_dependent_memory (driver); - return alsa_driver_set_parameters (driver, - frames_per_cycle, - user_nperiods, rate); -} - -int -JackAlsaDriver::alsa_driver_get_channel_addresses (alsa_driver_t *driver, - snd_pcm_uframes_t *capture_avail, - snd_pcm_uframes_t *playback_avail, - snd_pcm_uframes_t *capture_offset, - snd_pcm_uframes_t *playback_offset) -{ - unsigned long err; - channel_t chn; - - if (capture_avail) { - if ((err = snd_pcm_mmap_begin ( - driver->capture_handle, &driver->capture_areas, - (snd_pcm_uframes_t *) capture_offset, - (snd_pcm_uframes_t *) capture_avail)) < 0) { - jack_error ("ALSA: %s: mmap areas info error", - driver->alsa_name_capture); - return -1; - } - - for (chn = 0; chn < driver->capture_nchannels; chn++) { - const snd_pcm_channel_area_t *a = - &driver->capture_areas[chn]; - driver->capture_addr[chn] = (char *) a->addr - + ((a->first + a->step * *capture_offset) / 8); - driver->capture_interleave_skip[chn] = (unsigned long ) (a->step / 8); - } - } - - if (playback_avail) { - if ((err = snd_pcm_mmap_begin ( - driver->playback_handle, &driver->playback_areas, - (snd_pcm_uframes_t *) playback_offset, - (snd_pcm_uframes_t *) playback_avail)) < 0) { - jack_error ("ALSA: %s: mmap areas info error ", - driver->alsa_name_playback); - return -1; - } - - for (chn = 0; chn < driver->playback_nchannels; chn++) { - const snd_pcm_channel_area_t *a = - &driver->playback_areas[chn]; - driver->playback_addr[chn] = (char *) a->addr - + ((a->first + a->step * *playback_offset) / 8); - driver->playback_interleave_skip[chn] = (unsigned long ) (a->step / 8); - } - } - - return 0; -} - -int -JackAlsaDriver::alsa_driver_start (alsa_driver_t *driver) -{ - int err; - snd_pcm_uframes_t poffset, pavail; - channel_t chn; - - driver->poll_last = 0; - driver->poll_next = 0; - - if (driver->playback_handle) { - if ((err = snd_pcm_prepare (driver->playback_handle)) < 0) { - jack_error ("ALSA: prepare error for playback on " - "\"%s\" (%s)", driver->alsa_name_playback, - snd_strerror(err)); - return -1; - } - } - - if ((driver->capture_handle && driver->capture_and_playback_not_synced) - || !driver->playback_handle) { - if ((err = snd_pcm_prepare (driver->capture_handle)) < 0) { - jack_error ("ALSA: prepare error for capture on \"%s\"" - " (%s)", driver->alsa_name_capture, - snd_strerror(err)); - return -1; - } - } - - if (driver->hw_monitoring) { - if (driver->input_monitor_mask || driver->all_monitor_in) { - if (driver->all_monitor_in) { - driver->hw->set_input_monitor_mask (driver->hw, ~0U); - } else { - driver->hw->set_input_monitor_mask ( - driver->hw, driver->input_monitor_mask); - } - } else { - driver->hw->set_input_monitor_mask (driver->hw, - driver->input_monitor_mask); - } - } - - if (driver->playback_handle) { - driver->playback_nfds = - snd_pcm_poll_descriptors_count (driver->playback_handle); - } else { - driver->playback_nfds = 0; - } - - if (driver->capture_handle) { - driver->capture_nfds = - snd_pcm_poll_descriptors_count (driver->capture_handle); - } else { - driver->capture_nfds = 0; - } - - if (driver->pfd) { - free (driver->pfd); - } - - driver->pfd = (struct pollfd *) - malloc (sizeof (struct pollfd) * - (driver->playback_nfds + driver->capture_nfds + 2)); - - if (driver->midi && !driver->xrun_recovery) - (driver->midi->start)(driver->midi); - - if (driver->playback_handle) { - /* fill playback buffer with zeroes, and mark - all fragments as having data. - */ - - pavail = snd_pcm_avail_update (driver->playback_handle); - - if (pavail != - driver->frames_per_cycle * driver->playback_nperiods) { - jack_error ("ALSA: full buffer not available at start"); - return -1; - } - - if (alsa_driver_get_channel_addresses (driver, - 0, &pavail, 0, &poffset)) { - return -1; - } - - /* XXX this is cheating. ALSA offers no guarantee that - we can access the entire buffer at any one time. It - works on most hardware tested so far, however, buts - its a liability in the long run. I think that - alsa-lib may have a better function for doing this - here, where the goal is to silence the entire - buffer. - */ - - for (chn = 0; chn < driver->playback_nchannels; chn++) { - alsa_driver_silence_on_channel ( - driver, chn, - driver->user_nperiods - * driver->frames_per_cycle); - } - - snd_pcm_mmap_commit (driver->playback_handle, poffset, - driver->user_nperiods - * driver->frames_per_cycle); - - if ((err = snd_pcm_start (driver->playback_handle)) < 0) { - jack_error ("ALSA: could not start playback (%s)", - snd_strerror (err)); - return -1; - } - } - - if ((driver->capture_handle && driver->capture_and_playback_not_synced) - || !driver->playback_handle) { - if ((err = snd_pcm_start (driver->capture_handle)) < 0) { - jack_error ("ALSA: could not start capture (%s)", - snd_strerror (err)); - return -1; - } - } - - return 0; -} - -int -JackAlsaDriver::alsa_driver_stop (alsa_driver_t *driver) -{ - int err; - //JSList* node; - //int chn; - - /* silence all capture port buffers, because we might - be entering offline mode. - */ - - // steph - /* - for (chn = 0, node = driver->capture_ports; node; - node = jack_slist_next (node), chn++) { - - jack_port_t* port; - char* buf; - jack_nframes_t nframes = driver->engine->control->buffer_size; - - port = (jack_port_t *) node->data; - buf = jack_port_get_buffer (port, nframes); - memset (buf, 0, sizeof (jack_default_audio_sample_t) * nframes); - } - */ - - for (int i = 0; i < fPlaybackChannels; i++) { - jack_default_audio_sample_t* buf = - (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[i], fEngineControl->fBufferSize); - memset (buf, 0, sizeof (jack_default_audio_sample_t) * fEngineControl->fBufferSize); - } - - if (driver->playback_handle) { - if ((err = snd_pcm_drop (driver->playback_handle)) < 0) { - jack_error ("ALSA: channel flush for playback " - "failed (%s)", snd_strerror (err)); - return -1; - } - } - - if (!driver->playback_handle - || driver->capture_and_playback_not_synced) { - if (driver->capture_handle) { - if ((err = snd_pcm_drop (driver->capture_handle)) < 0) { - jack_error ("ALSA: channel flush for " - "capture failed (%s)", - snd_strerror (err)); - return -1; - } - } - } - - if (driver->hw_monitoring) { - driver->hw->set_input_monitor_mask (driver->hw, 0); - } - - if (driver->midi && !driver->xrun_recovery) - (driver->midi->stop)(driver->midi); - - return 0; -} - -int -JackAlsaDriver::alsa_driver_restart (alsa_driver_t *driver) -{ - int res; - - driver->xrun_recovery = 1; - if ((res = Stop()) == 0) - res = Start(); - driver->xrun_recovery = 0; - - if (res && driver->midi) - (driver->midi->stop)(driver->midi); - return res; -} - -int -JackAlsaDriver::alsa_driver_xrun_recovery (alsa_driver_t *driver, float *delayed_usecs) -{ - snd_pcm_status_t *status; - int res; - - snd_pcm_status_alloca(&status); - - if (driver->capture_handle) { - if ((res = snd_pcm_status(driver->capture_handle, status)) - < 0) { - jack_error("status error: %s", snd_strerror(res)); - } - } else { - if ((res = snd_pcm_status(driver->playback_handle, status)) - < 0) { - jack_error("status error: %s", snd_strerror(res)); - } - } - - if (snd_pcm_status_get_state(status) == SND_PCM_STATE_SUSPENDED) { - jack_error("**** alsa_pcm: pcm in suspended state, resuming it" ); - if (driver->capture_handle) { - if ((res = snd_pcm_prepare(driver->capture_handle)) < 0) { - jack_error("error preparing after suspend: %s", snd_strerror(res)); - } - } else { - if ((res = snd_pcm_prepare(driver->playback_handle)) < 0) { - jack_error("error preparing after suspend: %s", snd_strerror(res)); - } - } - } - - if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN - && driver->process_count > XRUN_REPORT_DELAY) { - struct timeval now, diff, tstamp; - driver->xrun_count++; - snd_pcm_status_get_tstamp(status,&now); - snd_pcm_status_get_trigger_tstamp(status, &tstamp); - timersub(&now, &tstamp, &diff); - *delayed_usecs = diff.tv_sec * 1000000.0 + diff.tv_usec; - jack_error("**** alsa_pcm: xrun of at least %.3f msecs", *delayed_usecs / 1000.0); - } - - if (alsa_driver_restart (driver)) { - return -1; - } - return 0; -} - -void -JackAlsaDriver::alsa_driver_silence_untouched_channels (alsa_driver_t *driver, - jack_nframes_t nframes) -{ - channel_t chn; - jack_nframes_t buffer_frames = - driver->frames_per_cycle * driver->playback_nperiods; - - for (chn = 0; chn < driver->playback_nchannels; chn++) { - if (bitset_contains (driver->channels_not_done, chn)) { - if (driver->silent[chn] < buffer_frames) { - alsa_driver_silence_on_channel_no_mark ( - driver, chn, nframes); - driver->silent[chn] += nframes; - } - } - } -} - -static int under_gdb = FALSE; - -jack_nframes_t -JackAlsaDriver::alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *status, float - *delayed_usecs) -{ - snd_pcm_sframes_t avail = 0; - snd_pcm_sframes_t capture_avail = 0; - snd_pcm_sframes_t playback_avail = 0; - int xrun_detected = FALSE; - int need_capture; - int need_playback; - unsigned int i; - jack_time_t poll_enter; - jack_time_t poll_ret = 0; - - *status = -1; - *delayed_usecs = 0; - - need_capture = driver->capture_handle ? 1 : 0; - - if (extra_fd >= 0) { - need_playback = 0; - } else { - need_playback = driver->playback_handle ? 1 : 0; - } - - again: - - while (need_playback || need_capture) { - - int poll_result; - unsigned int ci = 0; - unsigned int nfds; - unsigned short revents; - - nfds = 0; - - if (need_playback) { - snd_pcm_poll_descriptors (driver->playback_handle, - &driver->pfd[0], - driver->playback_nfds); - nfds += driver->playback_nfds; - } - - if (need_capture) { - snd_pcm_poll_descriptors (driver->capture_handle, - &driver->pfd[nfds], - driver->capture_nfds); - ci = nfds; - nfds += driver->capture_nfds; - } - - /* ALSA doesn't set POLLERR in some versions of 0.9.X */ - - for (i = 0; i < nfds; i++) { - driver->pfd[i].events |= POLLERR; - } - - if (extra_fd >= 0) { - driver->pfd[nfds].fd = extra_fd; - driver->pfd[nfds].events = - POLLIN|POLLERR|POLLHUP|POLLNVAL; - nfds++; - } - - poll_enter = jack_get_microseconds (); - - if (poll_enter > driver->poll_next) { - /* - * This processing cycle was delayed past the - * next due interrupt! Do not account this as - * a wakeup delay: - */ - driver->poll_next = 0; - driver->poll_late++; - } - - poll_result = poll (driver->pfd, nfds, driver->poll_timeout); - if (poll_result < 0) { - - if (errno == EINTR) { - jack_info ("poll interrupt"); - // this happens mostly when run - // under gdb, or when exiting due to a signal - if (under_gdb) { - goto again; - } - *status = -2; - return 0; - } - - jack_error ("ALSA: poll call failed (%s)", - strerror (errno)); - *status = -3; - return 0; - - } - - poll_ret = jack_get_microseconds (); - - // steph - fBeginDateUst = poll_ret; - - if (extra_fd < 0) { - if (driver->poll_next && poll_ret > driver->poll_next) { - *delayed_usecs = poll_ret - driver->poll_next; - } - driver->poll_last = poll_ret; - driver->poll_next = poll_ret + driver->period_usecs; - // steph - /* - driver->engine->transport_cycle_start (driver->engine, - poll_ret); - */ - } - -#ifdef DEBUG_WAKEUP - jack_info ("%" PRIu64 ": checked %d fds, %" PRIu64 - " usecs since poll entered", poll_ret, nfds, - poll_ret - poll_enter); -#endif - - /* check to see if it was the extra FD that caused us - * to return from poll */ - - if (extra_fd >= 0) { - - if (driver->pfd[nfds-1].revents == 0) { - /* we timed out on the extra fd */ - - *status = -4; - return -1; - } - - /* if POLLIN was the only bit set, we're OK */ - - *status = 0; - if (driver->pfd[nfds-1].revents != POLLIN) { - jack_error("driver->pfd[nfds-1].revents == POLLIN"); - } - return (driver->pfd[nfds-1].revents == POLLIN) ? 0 : -1; - } - - if (need_playback) { - if (snd_pcm_poll_descriptors_revents - (driver->playback_handle, &driver->pfd[0], - driver->playback_nfds, &revents) < 0) { - jack_error ("ALSA: playback revents failed"); - *status = -6; - return 0; - } - - if (revents & POLLERR) { - xrun_detected = TRUE; - } - - if (revents & POLLOUT) { - need_playback = 0; -#ifdef DEBUG_WAKEUP - jack_info ("%" PRIu64 - " playback stream ready", - poll_ret); -#endif - } - } - - if (need_capture) { - if (snd_pcm_poll_descriptors_revents - (driver->capture_handle, &driver->pfd[ci], - driver->capture_nfds, &revents) < 0) { - jack_error ("ALSA: capture revents failed"); - *status = -6; - return 0; - } - - if (revents & POLLERR) { - xrun_detected = TRUE; - } - - if (revents & POLLIN) { - need_capture = 0; -#ifdef DEBUG_WAKEUP - jack_info ("%" PRIu64 - " capture stream ready", - poll_ret); -#endif - } - } - - if (poll_result == 0) { - jack_error ("ALSA: poll time out, polled for %" PRIu64 - " usecs", - poll_ret - poll_enter); - *status = -5; - return 0; - } - - } - - if (driver->capture_handle) { - if ((capture_avail = snd_pcm_avail_update ( - driver->capture_handle)) < 0) { - if (capture_avail == -EPIPE) { - xrun_detected = TRUE; - } else { - jack_error ("unknown ALSA avail_update return" - " value (%u)", capture_avail); - } - } - } else { - /* odd, but see min() computation below */ - capture_avail = INT_MAX; - } - - if (driver->playback_handle) { - if ((playback_avail = snd_pcm_avail_update ( - driver->playback_handle)) < 0) { - if (playback_avail == -EPIPE) { - xrun_detected = TRUE; - } else { - jack_error ("unknown ALSA avail_update return" - " value (%u)", playback_avail); - } - } - } else { - /* odd, but see min() computation below */ - playback_avail = INT_MAX; - } - - if (xrun_detected) { - *status = alsa_driver_xrun_recovery (driver, delayed_usecs); - return 0; - } - - *status = 0; - driver->last_wait_ust = poll_ret; - - avail = capture_avail < playback_avail ? capture_avail : playback_avail; - -#ifdef DEBUG_WAKEUP - jack_info ("wakeup complete, avail = %lu, pavail = %lu " - "cavail = %lu", - avail, playback_avail, capture_avail); -#endif - - /* mark all channels not done for now. read/write will change this */ - - bitset_copy (driver->channels_not_done, driver->channels_done); - - /* constrain the available count to the nearest (round down) number of - periods. - */ - - return avail - (avail % driver->frames_per_cycle); -} - +namespace Jack +{ int JackAlsaDriver::SetBufferSize(jack_nframes_t buffer_size) { @@ -1514,574 +65,11 @@ int JackAlsaDriver::SetBufferSize(jack_nframes_t buffer_size) return res; } -int -JackAlsaDriver::alsa_driver_read (alsa_driver_t *driver, jack_nframes_t nframes) -{ - snd_pcm_sframes_t contiguous; - snd_pcm_sframes_t nread; - snd_pcm_sframes_t offset; - jack_nframes_t orig_nframes; - jack_default_audio_sample_t* buf; - //channel_t chn; - //JSList *node; - //jack_port_t* port; - int err; - - // steph - /* - if (!driver->capture_handle || driver->engine->freewheeling) { - return 0; - } - */ - - if (nframes > driver->frames_per_cycle) { - return -1; - } - - if (driver->midi) - (driver->midi->read)(driver->midi, nframes); - - if (!driver->capture_handle) { - return 0; - } - - nread = 0; - contiguous = 0; - orig_nframes = nframes; - - while (nframes) { - - contiguous = nframes; - - if (alsa_driver_get_channel_addresses ( - driver, - (snd_pcm_uframes_t *) &contiguous, - (snd_pcm_uframes_t *) 0, - (snd_pcm_uframes_t *)&offset, 0) < 0) { - return -1; - } - - // steph - for (int chn = 0; chn < fCaptureChannels; chn++) { - if (fGraphManager->GetConnectionsNum(fCapturePortList[chn]) > 0) { - buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[chn], orig_nframes); - alsa_driver_read_from_channel (driver, chn, buf + nread, contiguous); - } - } - - /* // steph - for (chn = 0, node = driver->capture_ports; node; - node = jack_slist_next (node), chn++) { - - port = (jack_port_t *) node->data; - - if (!jack_port_connected (port)) { - // no-copy optimization - continue; - } - buf = jack_port_get_buffer (port, orig_nframes); - alsa_driver_read_from_channel (driver, chn, - buf + nread, contiguous); - } - */ - - if ((err = snd_pcm_mmap_commit (driver->capture_handle, - offset, contiguous)) < 0) { - - jack_error ("ALSA: could not complete read of %" - PRIu32 " frames: error = %d\n", contiguous, err); - return -1; - } - - nframes -= contiguous; - nread += contiguous; - } - - return 0; -} - -int -JackAlsaDriver::alsa_driver_write (alsa_driver_t* driver, jack_nframes_t nframes) -{ - //channel_t chn; - //JSList *node; - //JSList *mon_node; - jack_default_audio_sample_t* buf; - jack_default_audio_sample_t* monbuf; - jack_nframes_t orig_nframes; - snd_pcm_sframes_t nwritten; - snd_pcm_sframes_t contiguous; - snd_pcm_sframes_t offset; - JackPort* port; - //jack_port_t *port; - int err; - - driver->process_count++; - - // steph - /* - if (!driver->playback_handle || driver->engine->freewheeling) { - return 0; - } - */ - if (!driver->playback_handle) { - return 0; - } - - if (nframes > driver->frames_per_cycle) { - return -1; - } - - if (driver->midi) - (driver->midi->write)(driver->midi, nframes); - - nwritten = 0; - contiguous = 0; - orig_nframes = nframes; - - /* check current input monitor request status */ - - driver->input_monitor_mask = 0; - - // steph - /* - for (chn = 0, node = driver->capture_ports; node; - node = jack_slist_next (node), chn++) { - if (((jack_port_t *) node->data)->shared->monitor_requests) { - driver->input_monitor_mask |= (1<GetPort(fCapturePortList[chn]); - if (port->MonitoringInput()) { - driver->input_monitor_mask |= (1 << chn); - } - } - - if (driver->hw_monitoring) { - if ((driver->hw->input_monitor_mask - != driver->input_monitor_mask) - && !driver->all_monitor_in) { - driver->hw->set_input_monitor_mask ( - driver->hw, driver->input_monitor_mask); - } - } - - while (nframes) { - - contiguous = nframes; - - if (alsa_driver_get_channel_addresses ( - driver, - (snd_pcm_uframes_t *) 0, - (snd_pcm_uframes_t *) &contiguous, - 0, (snd_pcm_uframes_t *)&offset) < 0) { - return -1; - } - - // steph - for (int chn = 0; chn < fPlaybackChannels; chn++) { - // Ouput ports - if (fGraphManager->GetConnectionsNum(fPlaybackPortList[chn]) > 0) { - buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[chn], orig_nframes); - alsa_driver_write_to_channel (driver, chn, buf + nwritten, contiguous); - // Monitor ports - if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[chn]) > 0) { - monbuf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[chn], orig_nframes); - memcpy(monbuf + nwritten, buf + nwritten, contiguous * sizeof(jack_default_audio_sample_t)); - } - } - } - - /* - for (chn = 0, node = driver->playback_ports, mon_node=driver->monitor_ports; - node; - node = jack_slist_next (node), chn++) { - - port = (jack_port_t *) node->data; - - if (!jack_port_connected (port)) { - continue; - } - buf = jack_port_get_buffer (port, orig_nframes); - alsa_driver_write_to_channel (driver, chn, - buf + nwritten, contiguous); - - if (mon_node) { - port = (jack_port_t *) mon_node->data; - if (!jack_port_connected (port)) { - continue; - } - monbuf = jack_port_get_buffer (port, orig_nframes); - memcpy (monbuf + nwritten, buf + nwritten, contiguous * sizeof(jack_default_audio_sample_t)); - mon_node = jack_slist_next (mon_node); - } - } - */ - - if (!bitset_empty (driver->channels_not_done)) { - alsa_driver_silence_untouched_channels (driver, - contiguous); - } - - if ((err = snd_pcm_mmap_commit (driver->playback_handle, - offset, contiguous)) < 0) { - jack_error ("ALSA: could not complete playback of %" - PRIu32 " frames: error = %d", contiguous, err); - if (err != -EPIPE && err != -ESTRPIPE) - return -1; - } - - nframes -= contiguous; - nwritten += contiguous; - } - return 0; -} - -void -JackAlsaDriver::alsa_driver_delete (alsa_driver_t *driver) -{ - JSList *node; - - if (driver->midi) - (driver->midi->destroy)(driver->midi); - - for (node = driver->clock_sync_listeners; node; - node = jack_slist_next (node)) { - free (node->data); - } - jack_slist_free (driver->clock_sync_listeners); - - if (driver->ctl_handle) { - snd_ctl_close (driver->ctl_handle); - driver->ctl_handle = 0; - } - - if (driver->capture_handle) { - snd_pcm_close (driver->capture_handle); - driver->capture_handle = 0; - } - - if (driver->playback_handle) { - snd_pcm_close (driver->playback_handle); - driver->capture_handle = 0; - } - - if (driver->capture_hw_params) { - snd_pcm_hw_params_free (driver->capture_hw_params); - driver->capture_hw_params = 0; - } - - if (driver->playback_hw_params) { - snd_pcm_hw_params_free (driver->playback_hw_params); - driver->playback_hw_params = 0; - } - - if (driver->capture_sw_params) { - snd_pcm_sw_params_free (driver->capture_sw_params); - driver->capture_sw_params = 0; - } - - if (driver->playback_sw_params) { - snd_pcm_sw_params_free (driver->playback_sw_params); - driver->playback_sw_params = 0; - } - - if (driver->pfd) { - free (driver->pfd); - } - - if (driver->hw) { - driver->hw->release (driver->hw); - driver->hw = 0; - } - free(driver->alsa_name_playback); - free(driver->alsa_name_capture); - free(driver->alsa_driver); - - alsa_driver_release_channel_dependent_memory (driver); - // steph - //jack_driver_nt_finish ((jack_driver_nt_t *) driver); - free (driver); -} - -jack_driver_t * -JackAlsaDriver::alsa_driver_new (const char *name, char *playback_alsa_device, - char *capture_alsa_device, - jack_client_t *client, - jack_nframes_t frames_per_cycle, - jack_nframes_t user_nperiods, - jack_nframes_t rate, - int hw_monitoring, - int hw_metering, - int capturing, - int playing, - DitherAlgorithm dither, - int soft_mode, - int monitor, - int user_capture_nchnls, - int user_playback_nchnls, - int shorts_first, - jack_nframes_t capture_latency, - jack_nframes_t playback_latency, - alsa_midi_t *midi) -{ - int err; - - alsa_driver_t *driver; - - jack_info ("creating alsa driver ... %s|%s|%" PRIu32 "|%" PRIu32 - "|%" PRIu32"|%" PRIu32"|%" PRIu32 "|%s|%s|%s|%s", - playing ? playback_alsa_device : "-", - capturing ? capture_alsa_device : "-", - frames_per_cycle, user_nperiods, rate, - user_capture_nchnls,user_playback_nchnls, - hw_monitoring ? "hwmon": "nomon", - hw_metering ? "hwmeter":"swmeter", - soft_mode ? "soft-mode":"-", - shorts_first ? "16bit":"32bit"); - - driver = (alsa_driver_t *) calloc (1, sizeof (alsa_driver_t)); - - jack_driver_nt_init ((jack_driver_nt_t *) driver); - - driver->midi = midi; - driver->xrun_recovery = 0; - - //driver->nt_attach = (JackDriverNTAttachFunction) alsa_driver_attach; - //driver->nt_detach = (JackDriverNTDetachFunction) alsa_driver_detach; - //driver->read = (JackDriverReadFunction) alsa_driver_read; - //driver->write = (JackDriverReadFunction) alsa_driver_write; - //driver->null_cycle = (JackDriverNullCycleFunction) alsa_driver_null_cycle; - //driver->nt_bufsize = (JackDriverNTBufSizeFunction) alsa_driver_bufsize; - //driver->nt_start = (JackDriverNTStartFunction) alsa_driver_start; - //driver->nt_stop = (JackDriverNTStopFunction) alsa_driver_stop; - //driver->nt_run_cycle = (JackDriverNTRunCycleFunction) alsa_driver_run_cycle; - - driver->playback_handle = NULL; - driver->capture_handle = NULL; - driver->ctl_handle = 0; - driver->hw = 0; - driver->capture_and_playback_not_synced = FALSE; - driver->max_nchannels = 0; - driver->user_nchannels = 0; - driver->playback_nchannels = user_playback_nchnls; - driver->capture_nchannels = user_capture_nchnls; - driver->playback_sample_bytes = (shorts_first ? 2 : 4); - driver->capture_sample_bytes = (shorts_first ? 2 : 4); - driver->capture_frame_latency = capture_latency; - driver->playback_frame_latency = playback_latency; - - driver->playback_addr = 0; - driver->capture_addr = 0; - driver->playback_interleave_skip = NULL; - driver->capture_interleave_skip = NULL; - - driver->silent = 0; - driver->all_monitor_in = FALSE; - driver->with_monitor_ports = monitor; - - driver->clock_mode = ClockMaster; /* XXX is it? */ - driver->input_monitor_mask = 0; /* XXX is it? */ - - driver->capture_ports = 0; - driver->playback_ports = 0; - driver->monitor_ports = 0; - - driver->pfd = 0; - driver->playback_nfds = 0; - driver->capture_nfds = 0; - - driver->dither = dither; - driver->soft_mode = soft_mode; - - pthread_mutex_init (&driver->clock_sync_lock, 0); - driver->clock_sync_listeners = 0; - - driver->poll_late = 0; - driver->xrun_count = 0; - driver->process_count = 0; - - driver->alsa_name_playback = strdup (playback_alsa_device); - driver->alsa_name_capture = strdup (capture_alsa_device); - - if (alsa_driver_check_card_type (driver)) { - alsa_driver_delete (driver); - return NULL; - } - - alsa_driver_hw_specific (driver, hw_monitoring, hw_metering); - - if (playing) { - if (snd_pcm_open (&driver->playback_handle, - playback_alsa_device, - SND_PCM_STREAM_PLAYBACK, - SND_PCM_NONBLOCK) < 0) { - switch (errno) { - case EBUSY: - jack_error ("the playback device \"%s\" is " - "already in use. Please stop the" - " application using it and " - "run JACK again", - playback_alsa_device); - alsa_driver_delete (driver); - return NULL; - break; - - case EPERM: - jack_error ("you do not have permission to open " - "the audio device \"%s\" for playback", - playback_alsa_device); - alsa_driver_delete (driver); - return NULL; - break; - } - - driver->playback_handle = NULL; - } - - if (driver->playback_handle) { - snd_pcm_nonblock (driver->playback_handle, 0); - } - } - - if (capturing) { - if (snd_pcm_open (&driver->capture_handle, - capture_alsa_device, - SND_PCM_STREAM_CAPTURE, - SND_PCM_NONBLOCK) < 0) { - switch (errno) { - case EBUSY: - jack_error ("the capture device \"%s\" is " - "already in use. Please stop the" - " application using it and " - "run JACK again", - capture_alsa_device); - alsa_driver_delete (driver); - return NULL; - break; - - case EPERM: - jack_error ("you do not have permission to open " - "the audio device \"%s\" for capture", - capture_alsa_device); - alsa_driver_delete (driver); - return NULL; - break; - } - - driver->capture_handle = NULL; - } - - if (driver->capture_handle) { - snd_pcm_nonblock (driver->capture_handle, 0); - } - } - - if (driver->playback_handle == NULL) { - if (playing) { - - /* they asked for playback, but we can't do it */ - - jack_error ("ALSA: Cannot open PCM device %s for " - "playback. Falling back to capture-only" - " mode", name); - - if (driver->capture_handle == NULL) { - /* can't do anything */ - alsa_driver_delete (driver); - return NULL; - } - - playing = FALSE; - } - } - - if (driver->capture_handle == NULL) { - if (capturing) { - - /* they asked for capture, but we can't do it */ - - jack_error ("ALSA: Cannot open PCM device %s for " - "capture. Falling back to playback-only" - " mode", name); - - if (driver->playback_handle == NULL) { - /* can't do anything */ - alsa_driver_delete (driver); - return NULL; - } - - capturing = FALSE; - } - } - - driver->playback_hw_params = 0; - driver->capture_hw_params = 0; - driver->playback_sw_params = 0; - driver->capture_sw_params = 0; - - if (driver->playback_handle) { - if ((err = snd_pcm_hw_params_malloc ( - &driver->playback_hw_params)) < 0) { - jack_error ("ALSA: could not allocate playback hw" - " params structure"); - alsa_driver_delete (driver); - return NULL; - } - - if ((err = snd_pcm_sw_params_malloc ( - &driver->playback_sw_params)) < 0) { - jack_error ("ALSA: could not allocate playback sw" - " params structure"); - alsa_driver_delete (driver); - return NULL; - } - } - - if (driver->capture_handle) { - if ((err = snd_pcm_hw_params_malloc ( - &driver->capture_hw_params)) < 0) { - jack_error ("ALSA: could not allocate capture hw" - " params structure"); - alsa_driver_delete (driver); - return NULL; - } - - if ((err = snd_pcm_sw_params_malloc ( - &driver->capture_sw_params)) < 0) { - jack_error ("ALSA: could not allocate capture sw" - " params structure"); - alsa_driver_delete (driver); - return NULL; - } - } - - if (alsa_driver_set_parameters (driver, frames_per_cycle, - user_nperiods, rate)) { - alsa_driver_delete (driver); - return NULL; - } - - driver->capture_and_playback_not_synced = FALSE; - - if (driver->capture_handle && driver->playback_handle) { - if (snd_pcm_link (driver->capture_handle, - driver->playback_handle) != 0) { - driver->capture_and_playback_not_synced = TRUE; - } - } - - driver->client = client; - return (jack_driver_t *) driver; -} - int JackAlsaDriver::Attach() { JackPort* port; int port_index; - unsigned long port_flags; + unsigned long port_flags = (unsigned long)CaptureDriverFlags; char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; jack_latency_range_t range; @@ -2089,8 +77,6 @@ int JackAlsaDriver::Attach() assert(fCaptureChannels < DRIVER_PORT_NUM); assert(fPlaybackChannels < DRIVER_PORT_NUM); - port_flags = (unsigned long)CaptureDriverFlags; - alsa_driver_t* alsa_driver = (alsa_driver_t*)fDriver; if (alsa_driver->has_hw_monitoring) @@ -2100,10 +86,10 @@ int JackAlsaDriver::Attach() JackAudioDriver::SetBufferSize(alsa_driver->frames_per_cycle); JackAudioDriver::SetSampleRate(alsa_driver->frame_rate); - jack_log("JackAudioDriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); + jack_log("JackAlsaDriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); for (int i = 0; i < fCaptureChannels; i++) { - snprintf(alias, sizeof(alias) - 1, "%s:capture_%u", fAliasName, i + 1); + snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", name); @@ -2114,13 +100,13 @@ int JackAlsaDriver::Attach() range.min = range.max = alsa_driver->frames_per_cycle + alsa_driver->capture_frame_latency; port->SetLatencyRange(JackCaptureLatency, &range); fCapturePortList[i] = port_index; - jack_log("JackAudioDriver::Attach fCapturePortList[i] %ld ", port_index); + jack_log("JackAlsaDriver::Attach fCapturePortList[i] %ld ", port_index); } port_flags = (unsigned long)PlaybackDriverFlags; for (int i = 0; i < fPlaybackChannels; i++) { - snprintf(alias, sizeof(alias) - 1, "%s:playback_%u", fAliasName, i + 1); + snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", name); @@ -2134,11 +120,11 @@ int JackAlsaDriver::Attach() port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[i] = port_index; - jack_log("JackAudioDriver::Attach fPlaybackPortList[i] %ld ", port_index); + jack_log("JackAlsaDriver::Attach fPlaybackPortList[i] %ld ", port_index); // Monitor ports if (fWithMonitorPorts) { - jack_log("Create monitor port "); + jack_log("Create monitor port"); snprintf(name, sizeof(name) - 1, "%s:monitor_%d", fClientControl.fName, i + 1); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, MonitorDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error ("ALSA: cannot register monitor port for %s", name); @@ -2169,6 +155,35 @@ int JackAlsaDriver::Detach() return JackAudioDriver::Detach(); } +static char* get_control_device_name(const char * device_name) +{ + char * ctl_name; + regex_t expression; + + regcomp(&expression, "(plug)?hw:[0-9](,[0-9])?", REG_ICASE | REG_EXTENDED); + + if (!regexec(&expression, device_name, 0, NULL, 0)) { + /* the user wants a hw or plughw device, the ctl name + * should be hw:x where x is the card number */ + + char tmp[5]; + strncpy(tmp, strstr(device_name, "hw"), 4); + tmp[4] = '\0'; + jack_info("control device %s",tmp); + ctl_name = strdup(tmp); + } else { + ctl_name = strdup(device_name); + } + + regfree(&expression); + + if (ctl_name == NULL) { + jack_error("strdup(\"%s\") failed.", ctl_name); + } + + return ctl_name; +} + static int card_to_num(const char* device) { int err; @@ -2291,7 +306,9 @@ int JackAlsaDriver::Open(jack_nframes_t nframes, int JackAlsaDriver::Close() { - JackAudioDriver::Close(); + // Generic audio driver close + int res = JackAudioDriver::Close(); + alsa_driver_delete((alsa_driver_t*)fDriver); if (JackServerGlobals::on_device_release != NULL) @@ -2310,18 +327,28 @@ int JackAlsaDriver::Close() } } - return 0; + return res; } int JackAlsaDriver::Start() { - JackAudioDriver::Start(); - return alsa_driver_start((alsa_driver_t *)fDriver); + int res = JackAudioDriver::Start(); + if (res >= 0) { + res = alsa_driver_start((alsa_driver_t *)fDriver); + if (res < 0) { + JackAudioDriver::Stop(); + } + } + return res; } int JackAlsaDriver::Stop() { - return alsa_driver_stop((alsa_driver_t *)fDriver); + int res = alsa_driver_stop((alsa_driver_t *)fDriver); + if (JackAudioDriver::Stop() < 0) { + res = -1; + } + return res; } int JackAlsaDriver::Read() @@ -2348,7 +375,7 @@ retry: } if (nframes != fEngineControl->fBufferSize) - jack_log("JackAlsaDriver::Read warning nframes = %ld", nframes); + jack_log("JackAlsaDriver::Read warning fBufferSize = %ld nframes = %ld", fEngineControl->fBufferSize, nframes); // Has to be done before read JackDriver::CycleIncTime(); @@ -2361,40 +388,54 @@ int JackAlsaDriver::Write() return alsa_driver_write((alsa_driver_t *)fDriver, fEngineControl->fBufferSize); } -void -JackAlsaDriver::jack_driver_init (jack_driver_t *driver) +void JackAlsaDriver::ReadInputAux(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nread) { - memset (driver, 0, sizeof (*driver)); - - driver->attach = 0; - driver->detach = 0; - driver->write = 0; - driver->read = 0; - driver->null_cycle = 0; - driver->bufsize = 0; - driver->start = 0; - driver->stop = 0; + for (int chn = 0; chn < fCaptureChannels; chn++) { + if (fGraphManager->GetConnectionsNum(fCapturePortList[chn]) > 0) { + jack_default_audio_sample_t* buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[chn], orig_nframes); + alsa_driver_read_from_channel((alsa_driver_t *)fDriver, chn, buf + nread, contiguous); + } + } } -void -JackAlsaDriver::jack_driver_nt_init (jack_driver_nt_t * driver) +void JackAlsaDriver::MonitorInputAux() +{ + for (int chn = 0; chn < fCaptureChannels; chn++) { + JackPort* port = fGraphManager->GetPort(fCapturePortList[chn]); + if (port->MonitoringInput()) { + ((alsa_driver_t *)fDriver)->input_monitor_mask |= (1 << chn); + } + } +} + +void JackAlsaDriver::ClearOutputAux() +{ + for (int chn = 0; chn < fPlaybackChannels; chn++) { + jack_default_audio_sample_t* buf = + (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[chn], fEngineControl->fBufferSize); + memset(buf, 0, sizeof (jack_default_audio_sample_t) * fEngineControl->fBufferSize); + } +} + +void JackAlsaDriver::SetTimetAux(jack_time_t time) { - memset (driver, 0, sizeof (*driver)); - - jack_driver_init ((jack_driver_t *) driver); - - driver->attach = 0; - driver->detach = 0; - driver->bufsize = 0; - driver->stop = 0; - driver->start = 0; - - driver->nt_bufsize = 0; - driver->nt_start = 0; - driver->nt_stop = 0; - driver->nt_attach = 0; - driver->nt_detach = 0; - driver->nt_run_cycle = 0; + fBeginDateUst = time; +} + +void JackAlsaDriver::WriteOutputAux(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nwritten) +{ + for (int chn = 0; chn < fPlaybackChannels; chn++) { + // Output ports + if (fGraphManager->GetConnectionsNum(fPlaybackPortList[chn]) > 0) { + jack_default_audio_sample_t* buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[chn], orig_nframes); + alsa_driver_write_to_channel(((alsa_driver_t *)fDriver), chn, buf + nwritten, contiguous); + // Monitor ports + if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[chn]) > 0) { + jack_default_audio_sample_t* monbuf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[chn], orig_nframes); + memcpy(monbuf + nwritten, buf + nwritten, contiguous * sizeof(jack_default_audio_sample_t)); + } + } + } } int JackAlsaDriver::is_realtime() const @@ -2843,6 +884,8 @@ SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor () return desc; } +static Jack::JackAlsaDriver* g_alsa_driver; + SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { jack_nframes_t srate = 48000; @@ -2969,10 +1012,10 @@ SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLocke playback = TRUE; } - Jack::JackAlsaDriver* alsa_driver = new Jack::JackAlsaDriver("system", "alsa_pcm", engine, table); - Jack::JackDriverClientInterface* threaded_driver = new Jack::JackThreadedDriver(alsa_driver); + g_alsa_driver = new Jack::JackAlsaDriver("system", "alsa_pcm", engine, table); + Jack::JackDriverClientInterface* threaded_driver = new Jack::JackThreadedDriver(g_alsa_driver); // Special open for ALSA driver... - if (alsa_driver->Open(frames_per_interrupt, user_nperiods, srate, hw_monitoring, hw_metering, capture, playback, dither, soft_mode, monitor, + if (g_alsa_driver->Open(frames_per_interrupt, user_nperiods, srate, hw_monitoring, hw_metering, capture, playback, dither, soft_mode, monitor, user_capture_nchnls, user_playback_nchnls, shorts_first, capture_pcm_name, playback_pcm_name, systemic_input_latency, systemic_output_latency, midi_driver) == 0) { return threaded_driver; @@ -2982,6 +1025,37 @@ SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLocke } } +// Code to be used in alsa_driver.c + +void ReadInput(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nread) +{ + g_alsa_driver->ReadInputAux(orig_nframes, contiguous, nread); +} +void MonitorInput() +{ + g_alsa_driver->MonitorInputAux(); +} +void ClearOutput() +{ + g_alsa_driver->ClearOutputAux(); +} +void WriteOutput(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nwritten) +{ + g_alsa_driver->WriteOutputAux(orig_nframes, contiguous, nwritten); +} +void SetTime(jack_time_t time) +{ + g_alsa_driver->SetTimetAux(time); +} + +int Restart() +{ + int res; + if ((res = g_alsa_driver->Stop()) == 0) + res = g_alsa_driver->Start(); + return res; +} + #ifdef __cplusplus } #endif diff --git a/linux/alsa/JackAlsaDriver.h b/linux/alsa/JackAlsaDriver.h index 8bab0e69..6d42b91a 100644 --- a/linux/alsa/JackAlsaDriver.h +++ b/linux/alsa/JackAlsaDriver.h @@ -24,7 +24,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackAudioDriver.h" #include "JackThreadedDriver.h" #include "JackTime.h" - #include "alsa_driver.h" namespace Jack @@ -42,87 +41,11 @@ class JackAlsaDriver : public JackAudioDriver jack_driver_t* fDriver; int fReservedCaptureDevice; int fReservedPlaybackDevice; - - void alsa_driver_release_channel_dependent_memory(alsa_driver_t *driver); - int alsa_driver_check_capabilities(alsa_driver_t *driver); - int alsa_driver_check_card_type(alsa_driver_t *driver); - int alsa_driver_hammerfall_hardware(alsa_driver_t *driver); - int alsa_driver_hdsp_hardware(alsa_driver_t *driver); - int alsa_driver_ice1712_hardware(alsa_driver_t *driver); - int alsa_driver_usx2y_hardware(alsa_driver_t *driver); - int alsa_driver_generic_hardware(alsa_driver_t *driver); - int alsa_driver_hw_specific(alsa_driver_t *driver, int hw_monitoring, - int hw_metering); - int alsa_driver_setup_io_function_pointers (alsa_driver_t *driver); - int alsa_driver_configure_stream(alsa_driver_t *driver, char *device_name, - const char *stream_name, - snd_pcm_t *handle, - snd_pcm_hw_params_t *hw_params, - snd_pcm_sw_params_t *sw_params, - unsigned int *nperiodsp, - unsigned long *nchns, - unsigned long sample_width); - - int alsa_driver_set_parameters(alsa_driver_t *driver, - jack_nframes_t frames_per_cycle, - jack_nframes_t user_nperiods, - jack_nframes_t rate); - - int alsa_driver_reset_parameters(alsa_driver_t *driver, - jack_nframes_t frames_per_cycle, - jack_nframes_t user_nperiods, - jack_nframes_t rate); - - int alsa_driver_get_channel_addresses(alsa_driver_t *driver, - snd_pcm_uframes_t *capture_avail, - snd_pcm_uframes_t *playback_avail, - snd_pcm_uframes_t *capture_offset, - snd_pcm_uframes_t *playback_offset); - - jack_driver_t * alsa_driver_new(const char *name, char *playback_alsa_device, - char *capture_alsa_device, - jack_client_t *client, - jack_nframes_t frames_per_cycle, - jack_nframes_t user_nperiods, - jack_nframes_t rate, - int hw_monitoring, - int hw_metering, - int capturing, - int playing, - DitherAlgorithm dither, - int soft_mode, - int monitor, - int user_capture_nchnls, - int user_playback_nchnls, - int shorts_first, - jack_nframes_t capture_latency, - jack_nframes_t playback_latency, - alsa_midi_t *midi); - - void alsa_driver_delete(alsa_driver_t *driver); - int alsa_driver_start(alsa_driver_t *driver); - int alsa_driver_stop(alsa_driver_t *driver); - int alsa_driver_read(alsa_driver_t *driver, jack_nframes_t nframes); - int alsa_driver_write(alsa_driver_t *driver, jack_nframes_t nframes); - - jack_nframes_t alsa_driver_wait(alsa_driver_t *driver, int extra_fd, int *status, float - *delayed_usecs); - - void alsa_driver_silence_untouched_channels(alsa_driver_t *driver, - jack_nframes_t nframes); - - int alsa_driver_restart(alsa_driver_t *driver); - int alsa_driver_xrun_recovery(alsa_driver_t *driver, float *delayed_usecs); - void jack_driver_init(jack_driver_t *driver); - void jack_driver_nt_init(jack_driver_nt_t * driver); public: JackAlsaDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) - : JackAudioDriver(name, alias, engine, table) - ,fDriver(NULL) - ,fReservedCaptureDevice(-1) - ,fReservedPlaybackDevice(-1) + : JackAudioDriver(name, alias, engine, table),fDriver(NULL),fReservedCaptureDevice(-1),fReservedPlaybackDevice(-1) {} virtual ~JackAlsaDriver() {} @@ -164,7 +87,13 @@ class JackAlsaDriver : public JackAudioDriver int SetBufferSize(jack_nframes_t buffer_size); - // jack api emulation for the midi driver + void ReadInputAux(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nread); + void MonitorInputAux(); + void ClearOutputAux(); + void WriteOutputAux(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nwritten); + void SetTimetAux(jack_time_t time); + + // JACK API emulation for the midi driver int is_realtime() const; int create_thread(pthread_t *thread, int prio, int rt, void *(*start_func)(void*), void *arg); diff --git a/linux/alsa/alsa_driver.c b/linux/alsa/alsa_driver.c new file mode 100644 index 00000000..536cfb6c --- /dev/null +++ b/linux/alsa/alsa_driver.c @@ -0,0 +1,2172 @@ +/* -*- mode: c; c-file-style: "linux"; -*- */ +/* + Copyright (C) 2001 Paul Davis + + 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. + +*/ + + +#define __STDC_FORMAT_MACROS // For inttypes.h to work in C++ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "alsa_driver.h" +#include "hammerfall.h" +#include "hdsp.h" +#include "ice1712.h" +#include "usx2y.h" +#include "generic.h" +#include "memops.h" +#include "JackError.h" + +#include "alsa_midi_impl.h" + +extern void store_work_time (int); +extern void store_wait_time (int); +extern void show_wait_times (); +extern void show_work_times (); + +#undef DEBUG_WAKEUP + +/* Delay (in process calls) before jackd will report an xrun */ +#define XRUN_REPORT_DELAY 0 + +void +jack_driver_init (jack_driver_t *driver) +{ + memset (driver, 0, sizeof (*driver)); + + driver->attach = 0; + driver->detach = 0; + driver->write = 0; + driver->read = 0; + driver->null_cycle = 0; + driver->bufsize = 0; + driver->start = 0; + driver->stop = 0; +} + +void +jack_driver_nt_init (jack_driver_nt_t * driver) +{ + memset (driver, 0, sizeof (*driver)); + + jack_driver_init ((jack_driver_t *) driver); + + driver->attach = 0; + driver->detach = 0; + driver->bufsize = 0; + driver->stop = 0; + driver->start = 0; + + driver->nt_bufsize = 0; + driver->nt_start = 0; + driver->nt_stop = 0; + driver->nt_attach = 0; + driver->nt_detach = 0; + driver->nt_run_cycle = 0; +} + +static void +alsa_driver_release_channel_dependent_memory (alsa_driver_t *driver) +{ + bitset_destroy (&driver->channels_done); + bitset_destroy (&driver->channels_not_done); + + if (driver->playback_addr) { + free (driver->playback_addr); + driver->playback_addr = 0; + } + + if (driver->capture_addr) { + free (driver->capture_addr); + driver->capture_addr = 0; + } + + if (driver->playback_interleave_skip) { + free (driver->playback_interleave_skip); + driver->playback_interleave_skip = NULL; + } + + if (driver->capture_interleave_skip) { + free (driver->capture_interleave_skip); + driver->capture_interleave_skip = NULL; + } + + if (driver->silent) { + free (driver->silent); + driver->silent = 0; + } + + if (driver->dither_state) { + free (driver->dither_state); + driver->dither_state = 0; + } +} + +static int +alsa_driver_check_capabilities (alsa_driver_t *driver) +{ + return 0; +} + +static int +alsa_driver_check_card_type (alsa_driver_t *driver) +{ + int err; + snd_ctl_card_info_t *card_info; + char * ctl_name; + regex_t expression; + + snd_ctl_card_info_alloca (&card_info); + + regcomp(&expression,"(plug)?hw:[0-9](,[0-9])?",REG_ICASE|REG_EXTENDED); + + if (!regexec(&expression,driver->alsa_name_playback,0,NULL,0)) { + /* the user wants a hw or plughw device, the ctl name + * should be hw:x where x is the card number */ + + char tmp[5]; + strncpy(tmp,strstr(driver->alsa_name_playback,"hw"),4); + tmp[4]='\0'; + jack_info("control device %s",tmp); + ctl_name = strdup(tmp); + } else { + ctl_name = strdup(driver->alsa_name_playback); + } + + // XXX: I don't know the "right" way to do this. Which to use + // driver->alsa_name_playback or driver->alsa_name_capture. + if ((err = snd_ctl_open (&driver->ctl_handle, ctl_name, 0)) < 0) { + jack_error ("control open \"%s\" (%s)", ctl_name, + snd_strerror(err)); + } else if ((err = snd_ctl_card_info(driver->ctl_handle, card_info)) < 0) { + jack_error ("control hardware info \"%s\" (%s)", + driver->alsa_name_playback, snd_strerror (err)); + snd_ctl_close (driver->ctl_handle); + } + + driver->alsa_driver = strdup(snd_ctl_card_info_get_driver (card_info)); + + regfree(&expression); + free(ctl_name); + + return alsa_driver_check_capabilities (driver); +} + +static int +alsa_driver_hammerfall_hardware (alsa_driver_t *driver) +{ + driver->hw = jack_alsa_hammerfall_hw_new (driver); + return 0; +} + +static int +alsa_driver_hdsp_hardware (alsa_driver_t *driver) +{ + driver->hw = jack_alsa_hdsp_hw_new (driver); + return 0; +} + +static int +alsa_driver_ice1712_hardware (alsa_driver_t *driver) +{ + driver->hw = jack_alsa_ice1712_hw_new (driver); + return 0; +} + +// JACK2 +/* +static int +alsa_driver_usx2y_hardware (alsa_driver_t *driver) +{ + driver->hw = jack_alsa_usx2y_hw_new (driver); + return 0; +} +*/ + +static int +alsa_driver_generic_hardware (alsa_driver_t *driver) +{ + driver->hw = jack_alsa_generic_hw_new (driver); + return 0; +} + +static int +alsa_driver_hw_specific (alsa_driver_t *driver, int hw_monitoring, + int hw_metering) +{ + int err; + + if (!strcmp(driver->alsa_driver, "RME9652")) { + if ((err = alsa_driver_hammerfall_hardware (driver)) != 0) { + return err; + } + } else if (!strcmp(driver->alsa_driver, "H-DSP")) { + if ((err = alsa_driver_hdsp_hardware (driver)) !=0) { + return err; + } + } else if (!strcmp(driver->alsa_driver, "ICE1712")) { + if ((err = alsa_driver_ice1712_hardware (driver)) !=0) { + return err; + } + } + // JACK2 + /* + else if (!strcmp(driver->alsa_driver, "USB US-X2Y")) { + if ((err = alsa_driver_usx2y_hardware (driver)) !=0) { + return err; + } + } + */ + else { + if ((err = alsa_driver_generic_hardware (driver)) != 0) { + return err; + } + } + + if (driver->hw->capabilities & Cap_HardwareMonitoring) { + driver->has_hw_monitoring = TRUE; + /* XXX need to ensure that this is really FALSE or + * TRUE or whatever*/ + driver->hw_monitoring = hw_monitoring; + } else { + driver->has_hw_monitoring = FALSE; + driver->hw_monitoring = FALSE; + } + + if (driver->hw->capabilities & Cap_ClockLockReporting) { + driver->has_clock_sync_reporting = TRUE; + } else { + driver->has_clock_sync_reporting = FALSE; + } + + if (driver->hw->capabilities & Cap_HardwareMetering) { + driver->has_hw_metering = TRUE; + driver->hw_metering = hw_metering; + } else { + driver->has_hw_metering = FALSE; + driver->hw_metering = FALSE; + } + + return 0; +} + +static void +alsa_driver_setup_io_function_pointers (alsa_driver_t *driver) +{ + if (driver->playback_handle) { + if (SND_PCM_FORMAT_FLOAT_LE == driver->playback_sample_format) { + driver->write_via_copy = sample_move_dS_floatLE; + } else { + switch (driver->playback_sample_bytes) { + case 2: + switch (driver->dither) { + case Rectangular: + jack_info("Rectangular dithering at 16 bits"); + driver->write_via_copy = driver->quirk_bswap? + sample_move_dither_rect_d16_sSs: + sample_move_dither_rect_d16_sS; + break; + + case Triangular: + jack_info("Triangular dithering at 16 bits"); + driver->write_via_copy = driver->quirk_bswap? + sample_move_dither_tri_d16_sSs: + sample_move_dither_tri_d16_sS; + break; + + case Shaped: + jack_info("Noise-shaped dithering at 16 bits"); + driver->write_via_copy = driver->quirk_bswap? + sample_move_dither_shaped_d16_sSs: + sample_move_dither_shaped_d16_sS; + break; + + default: + driver->write_via_copy = driver->quirk_bswap? + sample_move_d16_sSs : + sample_move_d16_sS; + break; + } + break; + + case 3: /* NO DITHER */ + driver->write_via_copy = driver->quirk_bswap? + sample_move_d24_sSs: + sample_move_d24_sS; + + break; + + case 4: /* NO DITHER */ + driver->write_via_copy = driver->quirk_bswap? + sample_move_d32u24_sSs: + sample_move_d32u24_sS; + break; + + default: + jack_error ("impossible sample width (%d) discovered!", + driver->playback_sample_bytes); + exit (1); + } + } + } + + if (driver->capture_handle) { + if (SND_PCM_FORMAT_FLOAT_LE == driver->capture_sample_format) { + driver->read_via_copy = sample_move_floatLE_sSs; + } else { + switch (driver->capture_sample_bytes) { + case 2: + driver->read_via_copy = driver->quirk_bswap? + sample_move_dS_s16s: + sample_move_dS_s16; + break; + case 3: + driver->read_via_copy = driver->quirk_bswap? + sample_move_dS_s24s: + sample_move_dS_s24; + break; + case 4: + driver->read_via_copy = driver->quirk_bswap? + sample_move_dS_s32u24s: + sample_move_dS_s32u24; + break; + } + } + } +} + +static int +alsa_driver_configure_stream (alsa_driver_t *driver, char *device_name, + const char *stream_name, + snd_pcm_t *handle, + snd_pcm_hw_params_t *hw_params, + snd_pcm_sw_params_t *sw_params, + unsigned int *nperiodsp, + channel_t *nchns, + unsigned long sample_width) +{ + int err, format; + unsigned int frame_rate; + snd_pcm_uframes_t stop_th; + static struct { + char Name[32]; + snd_pcm_format_t format; + int swapped; + } formats[] = { + {"32bit float little-endian", SND_PCM_FORMAT_FLOAT_LE}, + {"32bit integer little-endian", SND_PCM_FORMAT_S32_LE, IS_LE}, + {"32bit integer big-endian", SND_PCM_FORMAT_S32_BE, IS_BE}, + {"24bit little-endian", SND_PCM_FORMAT_S24_3LE, IS_LE}, + {"24bit big-endian", SND_PCM_FORMAT_S24_3BE, IS_BE}, + {"16bit little-endian", SND_PCM_FORMAT_S16_LE, IS_LE}, + {"16bit big-endian", SND_PCM_FORMAT_S16_BE, IS_BE}, + }; +#define NUMFORMATS (sizeof(formats)/sizeof(formats[0])) +#define FIRST_16BIT_FORMAT 5 + + if ((err = snd_pcm_hw_params_any (handle, hw_params)) < 0) { + jack_error ("ALSA: no playback configurations available (%s)", + snd_strerror (err)); + return -1; + } + + if ((err = snd_pcm_hw_params_set_periods_integer (handle, hw_params)) + < 0) { + jack_error ("ALSA: cannot restrict period size to integral" + " value."); + return -1; + } + + if ((err = snd_pcm_hw_params_set_access (handle, hw_params, SND_PCM_ACCESS_MMAP_NONINTERLEAVED)) < 0) { + if ((err = snd_pcm_hw_params_set_access (handle, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0) { + if ((err = snd_pcm_hw_params_set_access ( + handle, hw_params, + SND_PCM_ACCESS_MMAP_COMPLEX)) < 0) { + jack_error ("ALSA: mmap-based access is not possible" + " for the %s " + "stream of this audio interface", + stream_name); + return -1; + } + } + } + + format = (sample_width == 4) ? 0 : NUMFORMATS - 1; + + while (1) { + if ((err = snd_pcm_hw_params_set_format ( + handle, hw_params, formats[format].format)) < 0) { + + if ((sample_width == 4 + ? format++ >= NUMFORMATS - 1 + : format-- <= 0)) { + jack_error ("Sorry. The audio interface \"%s\"" + " doesn't support any of the" + " hardware sample formats that" + " JACK's alsa-driver can use.", + device_name); + return -1; + } + } else { + if (formats[format].swapped) { + driver->quirk_bswap = 1; + } else { + driver->quirk_bswap = 0; + } + jack_info ("ALSA: final selected sample format for %s: %s", stream_name, formats[format].Name); + break; + } + } + + frame_rate = driver->frame_rate ; + err = snd_pcm_hw_params_set_rate_near (handle, hw_params, + &frame_rate, NULL) ; + driver->frame_rate = frame_rate ; + if (err < 0) { + jack_error ("ALSA: cannot set sample/frame rate to %" + PRIu32 " for %s", driver->frame_rate, + stream_name); + return -1; + } + if (!*nchns) { + /*if not user-specified, try to find the maximum + * number of channels */ + unsigned int channels_max ; + err = snd_pcm_hw_params_get_channels_max (hw_params, + &channels_max); + *nchns = channels_max ; + + if (*nchns > 1024) { + + /* the hapless user is an unwitting victim of + the "default" ALSA PCM device, which can + support up to 16 million channels. since + they can't be bothered to set up a proper + default device, limit the number of + channels for them to a sane default. + */ + + jack_error ( +"You appear to be using the ALSA software \"plug\" layer, probably\n" +"a result of using the \"default\" ALSA device. This is less\n" +"efficient than it could be. Consider using a hardware device\n" +"instead rather than using the plug layer. Usually the name of the\n" +"hardware device that corresponds to the first sound card is hw:0\n" + ); + *nchns = 2; + } + } + + if ((err = snd_pcm_hw_params_set_channels (handle, hw_params, + *nchns)) < 0) { + jack_error ("ALSA: cannot set channel count to %u for %s", + *nchns, stream_name); + return -1; + } + + if ((err = snd_pcm_hw_params_set_period_size (handle, hw_params, + driver->frames_per_cycle, + 0)) + < 0) { + jack_error ("ALSA: cannot set period size to %" PRIu32 + " frames for %s", driver->frames_per_cycle, + stream_name); + return -1; + } + + *nperiodsp = driver->user_nperiods; + snd_pcm_hw_params_set_periods_min (handle, hw_params, nperiodsp, NULL); + if (*nperiodsp < driver->user_nperiods) + *nperiodsp = driver->user_nperiods; + if (snd_pcm_hw_params_set_periods_near (handle, hw_params, + nperiodsp, NULL) < 0) { + jack_error ("ALSA: cannot set number of periods to %u for %s", + *nperiodsp, stream_name); + return -1; + } + + if (*nperiodsp < driver->user_nperiods) { + jack_error ("ALSA: got smaller periods %u than %u for %s", + *nperiodsp, (unsigned int) driver->user_nperiods, + stream_name); + return -1; + } + jack_info ("ALSA: use %d periods for %s", *nperiodsp, stream_name); +#if 0 + if (!jack_power_of_two(driver->frames_per_cycle)) { + jack_error("JACK: frames must be a power of two " + "(64, 512, 1024, ...)\n"); + return -1; + } +#endif + + if ((err = snd_pcm_hw_params_set_buffer_size (handle, hw_params, + *nperiodsp * + driver->frames_per_cycle)) + < 0) { + jack_error ("ALSA: cannot set buffer length to %" PRIu32 + " for %s", + *nperiodsp * driver->frames_per_cycle, + stream_name); + return -1; + } + + if ((err = snd_pcm_hw_params (handle, hw_params)) < 0) { + jack_error ("ALSA: cannot set hardware parameters for %s", + stream_name); + return -1; + } + + snd_pcm_sw_params_current (handle, sw_params); + + if ((err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, + 0U)) < 0) { + jack_error ("ALSA: cannot set start mode for %s", stream_name); + return -1; + } + + stop_th = *nperiodsp * driver->frames_per_cycle; + if (driver->soft_mode) { + stop_th = (snd_pcm_uframes_t)-1; + } + + if ((err = snd_pcm_sw_params_set_stop_threshold ( + handle, sw_params, stop_th)) < 0) { + jack_error ("ALSA: cannot set stop mode for %s", + stream_name); + return -1; + } + + if ((err = snd_pcm_sw_params_set_silence_threshold ( + handle, sw_params, 0)) < 0) { + jack_error ("ALSA: cannot set silence threshold for %s", + stream_name); + return -1; + } + +#if 0 + jack_info ("set silence size to %lu * %lu = %lu", + driver->frames_per_cycle, *nperiodsp, + driver->frames_per_cycle * *nperiodsp); + + if ((err = snd_pcm_sw_params_set_silence_size ( + handle, sw_params, + driver->frames_per_cycle * *nperiodsp)) < 0) { + jack_error ("ALSA: cannot set silence size for %s", + stream_name); + return -1; + } +#endif + + if (handle == driver->playback_handle) + err = snd_pcm_sw_params_set_avail_min ( + handle, sw_params, + driver->frames_per_cycle + * (*nperiodsp - driver->user_nperiods + 1)); + else + err = snd_pcm_sw_params_set_avail_min ( + handle, sw_params, driver->frames_per_cycle); + + if (err < 0) { + jack_error ("ALSA: cannot set avail min for %s", stream_name); + return -1; + } + + if ((err = snd_pcm_sw_params (handle, sw_params)) < 0) { + jack_error ("ALSA: cannot set software parameters for %s\n", + stream_name); + return -1; + } + + return 0; +} + +static int +alsa_driver_set_parameters (alsa_driver_t *driver, + jack_nframes_t frames_per_cycle, + jack_nframes_t user_nperiods, + jack_nframes_t rate) +{ + int dir; + snd_pcm_uframes_t p_period_size = 0; + snd_pcm_uframes_t c_period_size = 0; + channel_t chn; + unsigned int pr = 0; + unsigned int cr = 0; + int err; + + driver->frame_rate = rate; + driver->frames_per_cycle = frames_per_cycle; + driver->user_nperiods = user_nperiods; + + jack_info ("configuring for %" PRIu32 "Hz, period = %" + PRIu32 " frames (%.1f ms), buffer = %" PRIu32 " periods", + rate, frames_per_cycle, (((float)frames_per_cycle / (float) rate) * 1000.0f), user_nperiods); + + if (driver->capture_handle) { + if (alsa_driver_configure_stream ( + driver, + driver->alsa_name_capture, + "capture", + driver->capture_handle, + driver->capture_hw_params, + driver->capture_sw_params, + &driver->capture_nperiods, + &driver->capture_nchannels, + driver->capture_sample_bytes)) { + jack_error ("ALSA: cannot configure capture channel"); + return -1; + } + } + + if (driver->playback_handle) { + if (alsa_driver_configure_stream ( + driver, + driver->alsa_name_playback, + "playback", + driver->playback_handle, + driver->playback_hw_params, + driver->playback_sw_params, + &driver->playback_nperiods, + &driver->playback_nchannels, + driver->playback_sample_bytes)) { + jack_error ("ALSA: cannot configure playback channel"); + return -1; + } + } + + /* check the rate, since thats rather important */ + + if (driver->playback_handle) { + snd_pcm_hw_params_get_rate (driver->playback_hw_params, + &pr, &dir); + } + + if (driver->capture_handle) { + snd_pcm_hw_params_get_rate (driver->capture_hw_params, + &cr, &dir); + } + + if (driver->capture_handle && driver->playback_handle) { + if (cr != pr) { + jack_error ("playback and capture sample rates do " + "not match (%d vs. %d)", pr, cr); + } + + /* only change if *both* capture and playback rates + * don't match requested certain hardware actually + * still works properly in full-duplex with slightly + * different rate values between adc and dac + */ + if (cr != driver->frame_rate && pr != driver->frame_rate) { + jack_error ("sample rate in use (%d Hz) does not " + "match requested rate (%d Hz)", + cr, driver->frame_rate); + driver->frame_rate = cr; + } + + } + else if (driver->capture_handle && cr != driver->frame_rate) { + jack_error ("capture sample rate in use (%d Hz) does not " + "match requested rate (%d Hz)", + cr, driver->frame_rate); + driver->frame_rate = cr; + } + else if (driver->playback_handle && pr != driver->frame_rate) { + jack_error ("playback sample rate in use (%d Hz) does not " + "match requested rate (%d Hz)", + pr, driver->frame_rate); + driver->frame_rate = pr; + } + + + /* check the fragment size, since thats non-negotiable */ + + if (driver->playback_handle) { + snd_pcm_access_t access; + + err = snd_pcm_hw_params_get_period_size ( + driver->playback_hw_params, &p_period_size, &dir); + err = snd_pcm_hw_params_get_format ( + driver->playback_hw_params, + &(driver->playback_sample_format)); + err = snd_pcm_hw_params_get_access (driver->playback_hw_params, + &access); + driver->playback_interleaved = + (access == SND_PCM_ACCESS_MMAP_INTERLEAVED) + || (access == SND_PCM_ACCESS_MMAP_COMPLEX); + + if (p_period_size != driver->frames_per_cycle) { + jack_error ("alsa_pcm: requested an interrupt every %" + PRIu32 + " frames but got %u frames for playback", + driver->frames_per_cycle, p_period_size); + return -1; + } + } + + if (driver->capture_handle) { + snd_pcm_access_t access; + + err = snd_pcm_hw_params_get_period_size ( + driver->capture_hw_params, &c_period_size, &dir); + err = snd_pcm_hw_params_get_format ( + driver->capture_hw_params, + &(driver->capture_sample_format)); + err = snd_pcm_hw_params_get_access (driver->capture_hw_params, + &access); + driver->capture_interleaved = + (access == SND_PCM_ACCESS_MMAP_INTERLEAVED) + || (access == SND_PCM_ACCESS_MMAP_COMPLEX); + + if (c_period_size != driver->frames_per_cycle) { + jack_error ("alsa_pcm: requested an interrupt every %" + PRIu32 + " frames but got %uc frames for capture", + driver->frames_per_cycle, p_period_size); + return -1; + } + } + + driver->playback_sample_bytes = + snd_pcm_format_physical_width (driver->playback_sample_format) + / 8; + driver->capture_sample_bytes = + snd_pcm_format_physical_width (driver->capture_sample_format) + / 8; + + if (driver->playback_handle) { + switch (driver->playback_sample_format) { + case SND_PCM_FORMAT_FLOAT_LE: + case SND_PCM_FORMAT_S32_LE: + case SND_PCM_FORMAT_S24_3LE: + case SND_PCM_FORMAT_S24_3BE: + case SND_PCM_FORMAT_S16_LE: + case SND_PCM_FORMAT_S32_BE: + case SND_PCM_FORMAT_S16_BE: + break; + + default: + jack_error ("programming error: unhandled format " + "type for playback"); + exit (1); + } + } + + if (driver->capture_handle) { + switch (driver->capture_sample_format) { + case SND_PCM_FORMAT_FLOAT_LE: + case SND_PCM_FORMAT_S32_LE: + case SND_PCM_FORMAT_S24_3LE: + case SND_PCM_FORMAT_S24_3BE: + case SND_PCM_FORMAT_S16_LE: + case SND_PCM_FORMAT_S32_BE: + case SND_PCM_FORMAT_S16_BE: + break; + + default: + jack_error ("programming error: unhandled format " + "type for capture"); + exit (1); + } + } + + if (driver->playback_interleaved) { + const snd_pcm_channel_area_t *my_areas; + snd_pcm_uframes_t offset, frames; + if (snd_pcm_mmap_begin(driver->playback_handle, + &my_areas, &offset, &frames) < 0) { + jack_error ("ALSA: %s: mmap areas info error", + driver->alsa_name_playback); + return -1; + } + driver->interleave_unit = + snd_pcm_format_physical_width ( + driver->playback_sample_format) / 8; + } else { + driver->interleave_unit = 0; /* NOT USED */ + } + + if (driver->capture_interleaved) { + const snd_pcm_channel_area_t *my_areas; + snd_pcm_uframes_t offset, frames; + if (snd_pcm_mmap_begin(driver->capture_handle, + &my_areas, &offset, &frames) < 0) { + jack_error ("ALSA: %s: mmap areas info error", + driver->alsa_name_capture); + return -1; + } + } + + if (driver->playback_nchannels > driver->capture_nchannels) { + driver->max_nchannels = driver->playback_nchannels; + driver->user_nchannels = driver->capture_nchannels; + } else { + driver->max_nchannels = driver->capture_nchannels; + driver->user_nchannels = driver->playback_nchannels; + } + + alsa_driver_setup_io_function_pointers (driver); + + /* Allocate and initialize structures that rely on the + channels counts. + + Set up the bit pattern that is used to record which + channels require action on every cycle. any bits that are + not set after the engine's process() call indicate channels + that potentially need to be silenced. + */ + + bitset_create (&driver->channels_done, driver->max_nchannels); + bitset_create (&driver->channels_not_done, driver->max_nchannels); + + if (driver->playback_handle) { + driver->playback_addr = (char **) + malloc (sizeof (char *) * driver->playback_nchannels); + memset (driver->playback_addr, 0, + sizeof (char *) * driver->playback_nchannels); + driver->playback_interleave_skip = (unsigned long *) + malloc (sizeof (unsigned long *) * driver->playback_nchannels); + memset (driver->playback_interleave_skip, 0, + sizeof (unsigned long *) * driver->playback_nchannels); + driver->silent = (unsigned long *) + malloc (sizeof (unsigned long) + * driver->playback_nchannels); + + for (chn = 0; chn < driver->playback_nchannels; chn++) { + driver->silent[chn] = 0; + } + + for (chn = 0; chn < driver->playback_nchannels; chn++) { + bitset_add (driver->channels_done, chn); + } + + driver->dither_state = (dither_state_t *) + calloc ( driver->playback_nchannels, + sizeof (dither_state_t)); + } + + if (driver->capture_handle) { + driver->capture_addr = (char **) + malloc (sizeof (char *) * driver->capture_nchannels); + memset (driver->capture_addr, 0, + sizeof (char *) * driver->capture_nchannels); + driver->capture_interleave_skip = (unsigned long *) + malloc (sizeof (unsigned long *) * driver->capture_nchannels); + memset (driver->capture_interleave_skip, 0, + sizeof (unsigned long *) * driver->capture_nchannels); + } + + driver->clock_sync_data = (ClockSyncStatus *) + malloc (sizeof (ClockSyncStatus) * driver->max_nchannels); + + driver->period_usecs = + (jack_time_t) floor ((((float) driver->frames_per_cycle) / + driver->frame_rate) * 1000000.0f); + driver->poll_timeout = (int) floor (1.5f * driver->period_usecs); + +// JACK2 +/* + if (driver->engine) { + if (driver->engine->set_buffer_size (driver->engine, + driver->frames_per_cycle)) { + jack_error ("ALSA: Cannot set engine buffer size to %d (check MIDI)", driver->frames_per_cycle); + return -1; + } + } +*/ + + return 0; +} + +int +alsa_driver_reset_parameters (alsa_driver_t *driver, + jack_nframes_t frames_per_cycle, + jack_nframes_t user_nperiods, + jack_nframes_t rate) +{ + /* XXX unregister old ports ? */ + alsa_driver_release_channel_dependent_memory (driver); + return alsa_driver_set_parameters (driver, + frames_per_cycle, + user_nperiods, rate); +} + +static int +alsa_driver_get_channel_addresses (alsa_driver_t *driver, + snd_pcm_uframes_t *capture_avail, + snd_pcm_uframes_t *playback_avail, + snd_pcm_uframes_t *capture_offset, + snd_pcm_uframes_t *playback_offset) +{ + unsigned long err; + channel_t chn; + + if (capture_avail) { + if ((err = snd_pcm_mmap_begin ( + driver->capture_handle, &driver->capture_areas, + (snd_pcm_uframes_t *) capture_offset, + (snd_pcm_uframes_t *) capture_avail)) < 0) { + jack_error ("ALSA: %s: mmap areas info error", + driver->alsa_name_capture); + return -1; + } + + for (chn = 0; chn < driver->capture_nchannels; chn++) { + const snd_pcm_channel_area_t *a = + &driver->capture_areas[chn]; + driver->capture_addr[chn] = (char *) a->addr + + ((a->first + a->step * *capture_offset) / 8); + driver->capture_interleave_skip[chn] = (unsigned long ) (a->step / 8); + } + } + + if (playback_avail) { + if ((err = snd_pcm_mmap_begin ( + driver->playback_handle, &driver->playback_areas, + (snd_pcm_uframes_t *) playback_offset, + (snd_pcm_uframes_t *) playback_avail)) < 0) { + jack_error ("ALSA: %s: mmap areas info error ", + driver->alsa_name_playback); + return -1; + } + + for (chn = 0; chn < driver->playback_nchannels; chn++) { + const snd_pcm_channel_area_t *a = + &driver->playback_areas[chn]; + driver->playback_addr[chn] = (char *) a->addr + + ((a->first + a->step * *playback_offset) / 8); + driver->playback_interleave_skip[chn] = (unsigned long ) (a->step / 8); + } + } + + return 0; +} + +int +alsa_driver_start (alsa_driver_t *driver) +{ + int err; + snd_pcm_uframes_t poffset, pavail; + channel_t chn; + + driver->poll_last = 0; + driver->poll_next = 0; + + if (driver->playback_handle) { + if ((err = snd_pcm_prepare (driver->playback_handle)) < 0) { + jack_error ("ALSA: prepare error for playback on " + "\"%s\" (%s)", driver->alsa_name_playback, + snd_strerror(err)); + return -1; + } + } + + if ((driver->capture_handle && driver->capture_and_playback_not_synced) + || !driver->playback_handle) { + if ((err = snd_pcm_prepare (driver->capture_handle)) < 0) { + jack_error ("ALSA: prepare error for capture on \"%s\"" + " (%s)", driver->alsa_name_capture, + snd_strerror(err)); + return -1; + } + } + + if (driver->hw_monitoring) { + if (driver->input_monitor_mask || driver->all_monitor_in) { + if (driver->all_monitor_in) { + driver->hw->set_input_monitor_mask (driver->hw, ~0U); + } else { + driver->hw->set_input_monitor_mask ( + driver->hw, driver->input_monitor_mask); + } + } else { + driver->hw->set_input_monitor_mask (driver->hw, + driver->input_monitor_mask); + } + } + + if (driver->playback_handle) { + driver->playback_nfds = + snd_pcm_poll_descriptors_count (driver->playback_handle); + } else { + driver->playback_nfds = 0; + } + + if (driver->capture_handle) { + driver->capture_nfds = + snd_pcm_poll_descriptors_count (driver->capture_handle); + } else { + driver->capture_nfds = 0; + } + + if (driver->pfd) { + free (driver->pfd); + } + + driver->pfd = (struct pollfd *) + malloc (sizeof (struct pollfd) * + (driver->playback_nfds + driver->capture_nfds + 2)); + + if (driver->midi && !driver->xrun_recovery) + (driver->midi->start)(driver->midi); + + if (driver->playback_handle) { + /* fill playback buffer with zeroes, and mark + all fragments as having data. + */ + + pavail = snd_pcm_avail_update (driver->playback_handle); + + if (pavail != + driver->frames_per_cycle * driver->playback_nperiods) { + jack_error ("ALSA: full buffer not available at start"); + return -1; + } + + if (alsa_driver_get_channel_addresses (driver, + 0, &pavail, 0, &poffset)) { + return -1; + } + + /* XXX this is cheating. ALSA offers no guarantee that + we can access the entire buffer at any one time. It + works on most hardware tested so far, however, buts + its a liability in the long run. I think that + alsa-lib may have a better function for doing this + here, where the goal is to silence the entire + buffer. + */ + + for (chn = 0; chn < driver->playback_nchannels; chn++) { + alsa_driver_silence_on_channel ( + driver, chn, + driver->user_nperiods + * driver->frames_per_cycle); + } + + snd_pcm_mmap_commit (driver->playback_handle, poffset, + driver->user_nperiods + * driver->frames_per_cycle); + + if ((err = snd_pcm_start (driver->playback_handle)) < 0) { + jack_error ("ALSA: could not start playback (%s)", + snd_strerror (err)); + return -1; + } + } + + if ((driver->capture_handle && driver->capture_and_playback_not_synced) + || !driver->playback_handle) { + if ((err = snd_pcm_start (driver->capture_handle)) < 0) { + jack_error ("ALSA: could not start capture (%s)", + snd_strerror (err)); + return -1; + } + } + + return 0; +} + +int +alsa_driver_stop (alsa_driver_t *driver) +{ + int err; +// JSList* node; +// int chn; + + /* silence all capture port buffers, because we might + be entering offline mode. + */ + +// JACK2 +/* + for (chn = 0, node = driver->capture_ports; node; + node = jack_slist_next (node), chn++) { + + jack_port_t* port; + char* buf; + jack_nframes_t nframes = driver->engine->control->buffer_size; + + port = (jack_port_t *) node->data; + buf = jack_port_get_buffer (port, nframes); + memset (buf, 0, sizeof (jack_default_audio_sample_t) * nframes); + } +*/ + +// JACK2 + ClearOutput(); + + if (driver->playback_handle) { + if ((err = snd_pcm_drop (driver->playback_handle)) < 0) { + jack_error ("ALSA: channel flush for playback " + "failed (%s)", snd_strerror (err)); + return -1; + } + } + + if (!driver->playback_handle + || driver->capture_and_playback_not_synced) { + if (driver->capture_handle) { + if ((err = snd_pcm_drop (driver->capture_handle)) < 0) { + jack_error ("ALSA: channel flush for " + "capture failed (%s)", + snd_strerror (err)); + return -1; + } + } + } + + if (driver->hw_monitoring) { + driver->hw->set_input_monitor_mask (driver->hw, 0); + } + + if (driver->midi && !driver->xrun_recovery) + (driver->midi->stop)(driver->midi); + + return 0; +} + +static int +alsa_driver_restart (alsa_driver_t *driver) +{ + int res; + + driver->xrun_recovery = 1; + // JACK2 + /* + if ((res = driver->nt_stop((struct _jack_driver_nt *) driver))==0) + res = driver->nt_start((struct _jack_driver_nt *) driver); + */ + res = Restart(); + driver->xrun_recovery = 0; + + if (res && driver->midi) + (driver->midi->stop)(driver->midi); + + return res; +} + +static int +alsa_driver_xrun_recovery (alsa_driver_t *driver, float *delayed_usecs) +{ + snd_pcm_status_t *status; + int res; + + snd_pcm_status_alloca(&status); + + if (driver->capture_handle) { + if ((res = snd_pcm_status(driver->capture_handle, status)) + < 0) { + jack_error("status error: %s", snd_strerror(res)); + } + } else { + if ((res = snd_pcm_status(driver->playback_handle, status)) + < 0) { + jack_error("status error: %s", snd_strerror(res)); + } + } + + if (snd_pcm_status_get_state(status) == SND_PCM_STATE_SUSPENDED) + { + jack_log("**** alsa_pcm: pcm in suspended state, resuming it" ); + if (driver->capture_handle) { + if ((res = snd_pcm_prepare(driver->capture_handle)) + < 0) { + jack_error("error preparing after suspend: %s", snd_strerror(res)); + } + } else { + if ((res = snd_pcm_prepare(driver->playback_handle)) + < 0) { + jack_error("error preparing after suspend: %s", snd_strerror(res)); + } + } + } + + if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN + && driver->process_count > XRUN_REPORT_DELAY) { + struct timeval now, diff, tstamp; + driver->xrun_count++; + snd_pcm_status_get_tstamp(status,&now); + snd_pcm_status_get_trigger_tstamp(status, &tstamp); + timersub(&now, &tstamp, &diff); + *delayed_usecs = diff.tv_sec * 1000000.0 + diff.tv_usec; + jack_log("**** alsa_pcm: xrun of at least %.3f msecs",*delayed_usecs / 1000.0); + } + + if (alsa_driver_restart (driver)) { + return -1; + } + return 0; +} + +void +alsa_driver_silence_untouched_channels (alsa_driver_t *driver, + jack_nframes_t nframes) +{ + channel_t chn; + jack_nframes_t buffer_frames = + driver->frames_per_cycle * driver->playback_nperiods; + + for (chn = 0; chn < driver->playback_nchannels; chn++) { + if (bitset_contains (driver->channels_not_done, chn)) { + if (driver->silent[chn] < buffer_frames) { + alsa_driver_silence_on_channel_no_mark ( + driver, chn, nframes); + driver->silent[chn] += nframes; + } + } + } +} + +void +alsa_driver_set_clock_sync_status (alsa_driver_t *driver, channel_t chn, + ClockSyncStatus status) +{ + driver->clock_sync_data[chn] = status; + alsa_driver_clock_sync_notify (driver, chn, status); +} + +static int under_gdb = FALSE; + +jack_nframes_t +alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *status, float + *delayed_usecs) +{ + snd_pcm_sframes_t avail = 0; + snd_pcm_sframes_t capture_avail = 0; + snd_pcm_sframes_t playback_avail = 0; + int xrun_detected = FALSE; + int need_capture; + int need_playback; + unsigned int i; + jack_time_t poll_enter; + jack_time_t poll_ret = 0; + + *status = -1; + *delayed_usecs = 0; + + need_capture = driver->capture_handle ? 1 : 0; + + if (extra_fd >= 0) { + need_playback = 0; + } else { + need_playback = driver->playback_handle ? 1 : 0; + } + + again: + + while (need_playback || need_capture) { + + int poll_result; + unsigned int ci = 0; + unsigned int nfds; + unsigned short revents; + + nfds = 0; + + if (need_playback) { + snd_pcm_poll_descriptors (driver->playback_handle, + &driver->pfd[0], + driver->playback_nfds); + nfds += driver->playback_nfds; + } + + if (need_capture) { + snd_pcm_poll_descriptors (driver->capture_handle, + &driver->pfd[nfds], + driver->capture_nfds); + ci = nfds; + nfds += driver->capture_nfds; + } + + /* ALSA doesn't set POLLERR in some versions of 0.9.X */ + + for (i = 0; i < nfds; i++) { + driver->pfd[i].events |= POLLERR; + } + + if (extra_fd >= 0) { + driver->pfd[nfds].fd = extra_fd; + driver->pfd[nfds].events = + POLLIN|POLLERR|POLLHUP|POLLNVAL; + nfds++; + } + + poll_enter = jack_get_microseconds (); + + if (poll_enter > driver->poll_next) { + /* + * This processing cycle was delayed past the + * next due interrupt! Do not account this as + * a wakeup delay: + */ + driver->poll_next = 0; + driver->poll_late++; + } + + poll_result = poll (driver->pfd, nfds, driver->poll_timeout); + if (poll_result < 0) { + + if (errno == EINTR) { + jack_info ("poll interrupt"); + // this happens mostly when run + // under gdb, or when exiting due to a signal + if (under_gdb) { + goto again; + } + *status = -2; + return 0; + } + + jack_error ("ALSA: poll call failed (%s)", + strerror (errno)); + *status = -3; + return 0; + + } + + poll_ret = jack_get_microseconds (); + + // JACK2 + SetTime(poll_ret); + + if (extra_fd < 0) { + if (driver->poll_next && poll_ret > driver->poll_next) { + *delayed_usecs = poll_ret - driver->poll_next; + } + driver->poll_last = poll_ret; + driver->poll_next = poll_ret + driver->period_usecs; +// JACK2 +/* + driver->engine->transport_cycle_start (driver->engine, + poll_ret); +*/ + } + +#ifdef DEBUG_WAKEUP + fprintf (stderr, "%" PRIu64 ": checked %d fds, started at %" PRIu64 " %" PRIu64 " usecs since poll entered\n", + poll_ret, nfds, poll_enter, poll_ret - poll_enter); +#endif + + /* check to see if it was the extra FD that caused us + * to return from poll */ + + if (extra_fd >= 0) { + + if (driver->pfd[nfds-1].revents == 0) { + /* we timed out on the extra fd */ + + *status = -4; + return -1; + } + + /* if POLLIN was the only bit set, we're OK */ + + *status = 0; + return (driver->pfd[nfds-1].revents == POLLIN) ? 0 : -1; + } + + if (need_playback) { + if (snd_pcm_poll_descriptors_revents + (driver->playback_handle, &driver->pfd[0], + driver->playback_nfds, &revents) < 0) { + jack_error ("ALSA: playback revents failed"); + *status = -6; + return 0; + } + + if (revents & POLLERR) { + xrun_detected = TRUE; + } + + if (revents & POLLOUT) { + need_playback = 0; +#ifdef DEBUG_WAKEUP + fprintf (stderr, "%" PRIu64 + " playback stream ready\n", + poll_ret); +#endif + } + } + + if (need_capture) { + if (snd_pcm_poll_descriptors_revents + (driver->capture_handle, &driver->pfd[ci], + driver->capture_nfds, &revents) < 0) { + jack_error ("ALSA: capture revents failed"); + *status = -6; + return 0; + } + + if (revents & POLLERR) { + xrun_detected = TRUE; + } + + if (revents & POLLIN) { + need_capture = 0; +#ifdef DEBUG_WAKEUP + fprintf (stderr, "%" PRIu64 + " capture stream ready\n", + poll_ret); +#endif + } + } + + if (poll_result == 0) { + jack_error ("ALSA: poll time out, polled for %" PRIu64 + " usecs", + poll_ret - poll_enter); + *status = -5; + return 0; + } + + } + + if (driver->capture_handle) { + if ((capture_avail = snd_pcm_avail_update ( + driver->capture_handle)) < 0) { + if (capture_avail == -EPIPE) { + xrun_detected = TRUE; + } else { + jack_error ("unknown ALSA avail_update return" + " value (%u)", capture_avail); + } + } + } else { + /* odd, but see min() computation below */ + capture_avail = INT_MAX; + } + + if (driver->playback_handle) { + if ((playback_avail = snd_pcm_avail_update ( + driver->playback_handle)) < 0) { + if (playback_avail == -EPIPE) { + xrun_detected = TRUE; + } else { + jack_error ("unknown ALSA avail_update return" + " value (%u)", playback_avail); + } + } + } else { + /* odd, but see min() computation below */ + playback_avail = INT_MAX; + } + + if (xrun_detected) { + *status = alsa_driver_xrun_recovery (driver, delayed_usecs); + return 0; + } + + *status = 0; + driver->last_wait_ust = poll_ret; + + avail = capture_avail < playback_avail ? capture_avail : playback_avail; + +#ifdef DEBUG_WAKEUP + fprintf (stderr, "wakeup complete, avail = %lu, pavail = %lu " + "cavail = %lu\n", + avail, playback_avail, capture_avail); +#endif + + /* mark all channels not done for now. read/write will change this */ + + bitset_copy (driver->channels_not_done, driver->channels_done); + + /* constrain the available count to the nearest (round down) number of + periods. + */ + + return avail - (avail % driver->frames_per_cycle); +} + + +int +alsa_driver_read (alsa_driver_t *driver, jack_nframes_t nframes) +{ + snd_pcm_sframes_t contiguous; + snd_pcm_sframes_t nread; + snd_pcm_uframes_t offset; + jack_nframes_t orig_nframes; +// jack_default_audio_sample_t* buf; +// channel_t chn; +// JSList *node; +// jack_port_t* port; + int err; + + if (nframes > driver->frames_per_cycle) { + return -1; + } + +// JACK2 +/* + if (driver->engine->freewheeling) { + return 0; + } +*/ + if (driver->midi) + (driver->midi->read)(driver->midi, nframes); + + if (!driver->capture_handle) { + return 0; + } + + nread = 0; + contiguous = 0; + orig_nframes = nframes; + + while (nframes) { + + contiguous = nframes; + + if (alsa_driver_get_channel_addresses ( + driver, + (snd_pcm_uframes_t *) &contiguous, + (snd_pcm_uframes_t *) 0, + &offset, 0) < 0) { + return -1; + } +// JACK2 +/* + for (chn = 0, node = driver->capture_ports; node; + node = jack_slist_next (node), chn++) { + + port = (jack_port_t *) node->data; + + if (!jack_port_connected (port)) { + // no-copy optimization + continue; + } + buf = jack_port_get_buffer (port, orig_nframes); + alsa_driver_read_from_channel (driver, chn, + buf + nread, contiguous); + } +*/ + ReadInput(orig_nframes, contiguous, nread); + + if ((err = snd_pcm_mmap_commit (driver->capture_handle, + offset, contiguous)) < 0) { + jack_error ("ALSA: could not complete read of %" + PRIu32 " frames: error = %d", contiguous, err); + return -1; + } + + nframes -= contiguous; + nread += contiguous; + } + + return 0; +} + +int +alsa_driver_write (alsa_driver_t* driver, jack_nframes_t nframes) +{ +// channel_t chn; +// JSList *node; +// JSList *mon_node; +// jack_default_audio_sample_t* buf; +// jack_default_audio_sample_t* monbuf; + jack_nframes_t orig_nframes; + snd_pcm_sframes_t nwritten; + snd_pcm_sframes_t contiguous; + snd_pcm_uframes_t offset; +// jack_port_t *port; + int err; + + driver->process_count++; + +// JACK2 +/* + if (!driver->playback_handle || driver->engine->freewheeling) { + return 0; + } +*/ + if (!driver->playback_handle) { + return 0; + } + + if (nframes > driver->frames_per_cycle) { + return -1; + } + + if (driver->midi) + (driver->midi->write)(driver->midi, nframes); + + nwritten = 0; + contiguous = 0; + orig_nframes = nframes; + + /* check current input monitor request status */ + + driver->input_monitor_mask = 0; + +// JACK2 +/* + for (chn = 0, node = driver->capture_ports; node; + node = jack_slist_next (node), chn++) { + if (((jack_port_t *) node->data)->shared->monitor_requests) { + driver->input_monitor_mask |= (1<hw_monitoring) { + if ((driver->hw->input_monitor_mask + != driver->input_monitor_mask) + && !driver->all_monitor_in) { + driver->hw->set_input_monitor_mask ( + driver->hw, driver->input_monitor_mask); + } + } + + while (nframes) { + + contiguous = nframes; + + if (alsa_driver_get_channel_addresses ( + driver, + (snd_pcm_uframes_t *) 0, + (snd_pcm_uframes_t *) &contiguous, + 0, &offset) < 0) { + return -1; + } + +// JACK2 +/* + for (chn = 0, node = driver->playback_ports, mon_node=driver->monitor_ports; + node; + node = jack_slist_next (node), chn++) { + + port = (jack_port_t *) node->data; + + if (!jack_port_connected (port)) { + continue; + } + buf = jack_port_get_buffer (port, orig_nframes); + alsa_driver_write_to_channel (driver, chn, + buf + nwritten, contiguous); + + if (mon_node) { + port = (jack_port_t *) mon_node->data; + if (!jack_port_connected (port)) { + continue; + } + monbuf = jack_port_get_buffer (port, orig_nframes); + memcpy (monbuf + nwritten, buf + nwritten, contiguous * sizeof(jack_default_audio_sample_t)); + mon_node = jack_slist_next (mon_node); + } + } +*/ + + // JACK2 + WriteOutput(orig_nframes, contiguous, nwritten); + + if (!bitset_empty (driver->channels_not_done)) { + alsa_driver_silence_untouched_channels (driver, + contiguous); + } + + if ((err = snd_pcm_mmap_commit (driver->playback_handle, + offset, contiguous)) < 0) { + jack_error ("ALSA: could not complete playback of %" + PRIu32 " frames: error = %d", contiguous, err); + if (err != -EPIPE && err != -ESTRPIPE) + return -1; + } + + nframes -= contiguous; + nwritten += contiguous; + } + + return 0; +} + +#if 0 +static int /* UNUSED */ +alsa_driver_change_sample_clock (alsa_driver_t *driver, SampleClockMode mode) +{ + return driver->hw->change_sample_clock (driver->hw, mode); +} + +static void /* UNUSED */ +alsa_driver_request_all_monitor_input (alsa_driver_t *driver, int yn) + +{ + if (driver->hw_monitoring) { + if (yn) { + driver->hw->set_input_monitor_mask (driver->hw, ~0U); + } else { + driver->hw->set_input_monitor_mask ( + driver->hw, driver->input_monitor_mask); + } + } + + driver->all_monitor_in = yn; +} + +static void /* UNUSED */ +alsa_driver_set_hw_monitoring (alsa_driver_t *driver, int yn) +{ + if (yn) { + driver->hw_monitoring = TRUE; + + if (driver->all_monitor_in) { + driver->hw->set_input_monitor_mask (driver->hw, ~0U); + } else { + driver->hw->set_input_monitor_mask ( + driver->hw, driver->input_monitor_mask); + } + } else { + driver->hw_monitoring = FALSE; + driver->hw->set_input_monitor_mask (driver->hw, 0); + } +} + +static ClockSyncStatus /* UNUSED */ +alsa_driver_clock_sync_status (channel_t chn) +{ + return Lock; +} +#endif + +void +alsa_driver_delete (alsa_driver_t *driver) +{ + JSList *node; + + if (driver->midi) + (driver->midi->destroy)(driver->midi); + + for (node = driver->clock_sync_listeners; node; + node = jack_slist_next (node)) { + free (node->data); + } + jack_slist_free (driver->clock_sync_listeners); + + if (driver->ctl_handle) { + snd_ctl_close (driver->ctl_handle); + driver->ctl_handle = 0; + } + + if (driver->capture_handle) { + snd_pcm_close (driver->capture_handle); + driver->capture_handle = 0; + } + + if (driver->playback_handle) { + snd_pcm_close (driver->playback_handle); + driver->capture_handle = 0; + } + + if (driver->capture_hw_params) { + snd_pcm_hw_params_free (driver->capture_hw_params); + driver->capture_hw_params = 0; + } + + if (driver->playback_hw_params) { + snd_pcm_hw_params_free (driver->playback_hw_params); + driver->playback_hw_params = 0; + } + + if (driver->capture_sw_params) { + snd_pcm_sw_params_free (driver->capture_sw_params); + driver->capture_sw_params = 0; + } + + if (driver->playback_sw_params) { + snd_pcm_sw_params_free (driver->playback_sw_params); + driver->playback_sw_params = 0; + } + + if (driver->pfd) { + free (driver->pfd); + } + + if (driver->hw) { + driver->hw->release (driver->hw); + driver->hw = 0; + } + free(driver->alsa_name_playback); + free(driver->alsa_name_capture); + free(driver->alsa_driver); + + alsa_driver_release_channel_dependent_memory (driver); + //JACK2 + //jack_driver_nt_finish ((jack_driver_nt_t *) driver); + free (driver); +} + +jack_driver_t * +alsa_driver_new (char *name, char *playback_alsa_device, + char *capture_alsa_device, + jack_client_t *client, + jack_nframes_t frames_per_cycle, + jack_nframes_t user_nperiods, + jack_nframes_t rate, + int hw_monitoring, + int hw_metering, + int capturing, + int playing, + DitherAlgorithm dither, + int soft_mode, + int monitor, + int user_capture_nchnls, + int user_playback_nchnls, + int shorts_first, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency, + alsa_midi_t *midi_driver + ) +{ + int err; + + alsa_driver_t *driver; + + jack_info ("creating alsa driver ... %s|%s|%" PRIu32 "|%" PRIu32 + "|%" PRIu32"|%" PRIu32"|%" PRIu32 "|%s|%s|%s|%s", + playing ? playback_alsa_device : "-", + capturing ? capture_alsa_device : "-", + frames_per_cycle, user_nperiods, rate, + user_capture_nchnls,user_playback_nchnls, + hw_monitoring ? "hwmon": "nomon", + hw_metering ? "hwmeter":"swmeter", + soft_mode ? "soft-mode":"-", + shorts_first ? "16bit":"32bit"); + + driver = (alsa_driver_t *) calloc (1, sizeof (alsa_driver_t)); + + jack_driver_nt_init ((jack_driver_nt_t *) driver); + + // JACK2 + /* + driver->nt_attach = (JackDriverNTAttachFunction) alsa_driver_attach; + driver->nt_detach = (JackDriverNTDetachFunction) alsa_driver_detach; + driver->read = (JackDriverReadFunction) alsa_driver_read; + driver->write = (JackDriverReadFunction) alsa_driver_write; + driver->null_cycle = (JackDriverNullCycleFunction) alsa_driver_null_cycle; + driver->nt_bufsize = (JackDriverNTBufSizeFunction) alsa_driver_bufsize; + driver->nt_start = (JackDriverNTStartFunction) alsa_driver_start; + driver->nt_stop = (JackDriverNTStopFunction) alsa_driver_stop; + driver->nt_run_cycle = (JackDriverNTRunCycleFunction) alsa_driver_run_cycle; + */ + + driver->playback_handle = NULL; + driver->capture_handle = NULL; + driver->ctl_handle = 0; + driver->hw = 0; + driver->capture_and_playback_not_synced = FALSE; + driver->max_nchannels = 0; + driver->user_nchannels = 0; + driver->playback_nchannels = user_playback_nchnls; + driver->capture_nchannels = user_capture_nchnls; + driver->playback_sample_bytes = (shorts_first ? 2:4); + driver->capture_sample_bytes = (shorts_first ? 2:4); + driver->capture_frame_latency = capture_latency; + driver->playback_frame_latency = playback_latency; + + driver->playback_addr = 0; + driver->capture_addr = 0; + driver->playback_interleave_skip = NULL; + driver->capture_interleave_skip = NULL; + + + driver->silent = 0; + driver->all_monitor_in = FALSE; + driver->with_monitor_ports = monitor; + + driver->clock_mode = ClockMaster; /* XXX is it? */ + driver->input_monitor_mask = 0; /* XXX is it? */ + + driver->capture_ports = 0; + driver->playback_ports = 0; + driver->monitor_ports = 0; + + driver->pfd = 0; + driver->playback_nfds = 0; + driver->capture_nfds = 0; + + driver->dither = dither; + driver->soft_mode = soft_mode; + + driver->quirk_bswap = 0; + + pthread_mutex_init (&driver->clock_sync_lock, 0); + driver->clock_sync_listeners = 0; + + driver->poll_late = 0; + driver->xrun_count = 0; + driver->process_count = 0; + + driver->alsa_name_playback = strdup (playback_alsa_device); + driver->alsa_name_capture = strdup (capture_alsa_device); + + driver->midi = midi_driver; + driver->xrun_recovery = 0; + + if (alsa_driver_check_card_type (driver)) { + alsa_driver_delete (driver); + return NULL; + } + + alsa_driver_hw_specific (driver, hw_monitoring, hw_metering); + + if (playing) { + if (snd_pcm_open (&driver->playback_handle, + playback_alsa_device, + SND_PCM_STREAM_PLAYBACK, + SND_PCM_NONBLOCK) < 0) { + switch (errno) { + case EBUSY: + jack_error ("the playback device \"%s\" is " + "already in use. Please stop the" + " application using it and " + "run JACK again", + playback_alsa_device); + alsa_driver_delete (driver); + return NULL; + break; + + case EPERM: + jack_error ("you do not have permission to open " + "the audio device \"%s\" for playback", + playback_alsa_device); + alsa_driver_delete (driver); + return NULL; + break; + } + + driver->playback_handle = NULL; + } + + if (driver->playback_handle) { + snd_pcm_nonblock (driver->playback_handle, 0); + } + } + + if (capturing) { + if (snd_pcm_open (&driver->capture_handle, + capture_alsa_device, + SND_PCM_STREAM_CAPTURE, + SND_PCM_NONBLOCK) < 0) { + switch (errno) { + case EBUSY: + jack_error ("the capture device \"%s\" is " + "already in use. Please stop the" + " application using it and " + "run JACK again", + capture_alsa_device); + alsa_driver_delete (driver); + return NULL; + break; + + case EPERM: + jack_error ("you do not have permission to open " + "the audio device \"%s\" for capture", + capture_alsa_device); + alsa_driver_delete (driver); + return NULL; + break; + } + + driver->capture_handle = NULL; + } + + if (driver->capture_handle) { + snd_pcm_nonblock (driver->capture_handle, 0); + } + } + + if (driver->playback_handle == NULL) { + if (playing) { + + /* they asked for playback, but we can't do it */ + + jack_error ("ALSA: Cannot open PCM device %s for " + "playback. Falling back to capture-only" + " mode", name); + + if (driver->capture_handle == NULL) { + /* can't do anything */ + alsa_driver_delete (driver); + return NULL; + } + + playing = FALSE; + } + } + + if (driver->capture_handle == NULL) { + if (capturing) { + + /* they asked for capture, but we can't do it */ + + jack_error ("ALSA: Cannot open PCM device %s for " + "capture. Falling back to playback-only" + " mode", name); + + if (driver->playback_handle == NULL) { + /* can't do anything */ + alsa_driver_delete (driver); + return NULL; + } + + capturing = FALSE; + } + } + + driver->playback_hw_params = 0; + driver->capture_hw_params = 0; + driver->playback_sw_params = 0; + driver->capture_sw_params = 0; + + if (driver->playback_handle) { + if ((err = snd_pcm_hw_params_malloc ( + &driver->playback_hw_params)) < 0) { + jack_error ("ALSA: could not allocate playback hw" + " params structure"); + alsa_driver_delete (driver); + return NULL; + } + + if ((err = snd_pcm_sw_params_malloc ( + &driver->playback_sw_params)) < 0) { + jack_error ("ALSA: could not allocate playback sw" + " params structure"); + alsa_driver_delete (driver); + return NULL; + } + } + + if (driver->capture_handle) { + if ((err = snd_pcm_hw_params_malloc ( + &driver->capture_hw_params)) < 0) { + jack_error ("ALSA: could not allocate capture hw" + " params structure"); + alsa_driver_delete (driver); + return NULL; + } + + if ((err = snd_pcm_sw_params_malloc ( + &driver->capture_sw_params)) < 0) { + jack_error ("ALSA: could not allocate capture sw" + " params structure"); + alsa_driver_delete (driver); + return NULL; + } + } + + if (alsa_driver_set_parameters (driver, frames_per_cycle, + user_nperiods, rate)) { + alsa_driver_delete (driver); + return NULL; + } + + driver->capture_and_playback_not_synced = FALSE; + + if (driver->capture_handle && driver->playback_handle) { + if (snd_pcm_link (driver->playback_handle, + driver->capture_handle) != 0) { + driver->capture_and_playback_not_synced = TRUE; + } + } + + driver->client = client; + + return (jack_driver_t *) driver; +} + +int +alsa_driver_listen_for_clock_sync_status (alsa_driver_t *driver, + ClockSyncListenerFunction func, + void *arg) +{ + ClockSyncListener *csl; + + csl = (ClockSyncListener *) malloc (sizeof (ClockSyncListener)); + csl->function = func; + csl->arg = arg; + csl->id = driver->next_clock_sync_listener_id++; + + pthread_mutex_lock (&driver->clock_sync_lock); + driver->clock_sync_listeners = + jack_slist_prepend (driver->clock_sync_listeners, csl); + pthread_mutex_unlock (&driver->clock_sync_lock); + return csl->id; +} + +int +alsa_driver_stop_listening_to_clock_sync_status (alsa_driver_t *driver, + unsigned int which) + +{ + JSList *node; + int ret = -1; + pthread_mutex_lock (&driver->clock_sync_lock); + for (node = driver->clock_sync_listeners; node; + node = jack_slist_next (node)) { + if (((ClockSyncListener *) node->data)->id == which) { + driver->clock_sync_listeners = + jack_slist_remove_link ( + driver->clock_sync_listeners, node); + free (node->data); + jack_slist_free_1 (node); + ret = 0; + break; + } + } + pthread_mutex_unlock (&driver->clock_sync_lock); + return ret; +} + +void +alsa_driver_clock_sync_notify (alsa_driver_t *driver, channel_t chn, + ClockSyncStatus status) +{ + JSList *node; + + pthread_mutex_lock (&driver->clock_sync_lock); + for (node = driver->clock_sync_listeners; node; + node = jack_slist_next (node)) { + ClockSyncListener *csl = (ClockSyncListener *) node->data; + csl->function (chn, status, csl->arg); + } + pthread_mutex_unlock (&driver->clock_sync_lock); + +} + +/* DRIVER "PLUGIN" INTERFACE */ + +const char driver_client_name[] = "alsa_pcm"; + +void +driver_finish (jack_driver_t *driver) +{ + alsa_driver_delete ((alsa_driver_t *) driver); +} diff --git a/linux/alsa/alsa_driver.h b/linux/alsa/alsa_driver.h index 13a78073..efe93de5 100644 --- a/linux/alsa/alsa_driver.h +++ b/linux/alsa/alsa_driver.h @@ -32,12 +32,20 @@ #define IS_BE 0 #endif +#define TRUE 1 +#define FALSE 0 + #include "types.h" #include "hardware.h" #include "driver.h" #include "memops.h" #include "alsa_midi.h" +#ifdef __cplusplus +extern "C" +{ +#endif + typedef void (*ReadCopyFunction) (jack_default_audio_sample_t *dst, char *src, unsigned long src_bytes, unsigned long src_skip_bytes); @@ -45,13 +53,8 @@ typedef void (*WriteCopyFunction) (char *dst, jack_default_audio_sample_t *src, unsigned long src_bytes, unsigned long dst_skip_bytes, dither_state_t *state); -typedef void (*CopyCopyFunction) (char *dst, char *src, - unsigned long src_bytes, - unsigned long dst_skip_bytes, - unsigned long src_skip_byte); -typedef struct _alsa_driver -{ +typedef struct _alsa_driver { JACK_DRIVER_NT_DECL @@ -124,7 +127,6 @@ typedef struct _alsa_driver ReadCopyFunction read_via_copy; WriteCopyFunction write_via_copy; - CopyCopyFunction channel_copy; int dither; dither_state_t *dither_state; @@ -144,100 +146,143 @@ typedef struct _alsa_driver alsa_midi_t *midi; int xrun_recovery; -} -alsa_driver_t; +} alsa_driver_t; static inline void -alsa_driver_mark_channel_done (alsa_driver_t *driver, channel_t chn) -{ - bitset_remove (driver->channels_not_done, chn); - driver->silent[chn] = 0; +alsa_driver_mark_channel_done (alsa_driver_t *driver, channel_t chn) { + bitset_remove (driver->channels_not_done, chn); + driver->silent[chn] = 0; } static inline void alsa_driver_silence_on_channel (alsa_driver_t *driver, channel_t chn, - jack_nframes_t nframes) -{ - if (driver->playback_interleaved) { - memset_interleave - (driver->playback_addr[chn], - 0, nframes * driver->playback_sample_bytes, - driver->interleave_unit, - driver->playback_interleave_skip[chn]); - } else { - memset (driver->playback_addr[chn], 0, - nframes * driver->playback_sample_bytes); - } - alsa_driver_mark_channel_done (driver, chn); + jack_nframes_t nframes) { + if (driver->playback_interleaved) { + memset_interleave + (driver->playback_addr[chn], + 0, nframes * driver->playback_sample_bytes, + driver->interleave_unit, + driver->playback_interleave_skip[chn]); + } else { + memset (driver->playback_addr[chn], 0, + nframes * driver->playback_sample_bytes); + } + alsa_driver_mark_channel_done (driver,chn); } static inline void alsa_driver_silence_on_channel_no_mark (alsa_driver_t *driver, channel_t chn, - jack_nframes_t nframes) -{ - if (driver->playback_interleaved) { - memset_interleave - (driver->playback_addr[chn], - 0, nframes * driver->playback_sample_bytes, - driver->interleave_unit, - driver->playback_interleave_skip[chn]); - } else { - memset (driver->playback_addr[chn], 0, - nframes * driver->playback_sample_bytes); - } + jack_nframes_t nframes) { + if (driver->playback_interleaved) { + memset_interleave + (driver->playback_addr[chn], + 0, nframes * driver->playback_sample_bytes, + driver->interleave_unit, + driver->playback_interleave_skip[chn]); + } else { + memset (driver->playback_addr[chn], 0, + nframes * driver->playback_sample_bytes); + } } static inline void alsa_driver_read_from_channel (alsa_driver_t *driver, - channel_t channel, - jack_default_audio_sample_t *buf, - jack_nframes_t nsamples) + channel_t channel, + jack_default_audio_sample_t *buf, + jack_nframes_t nsamples) { - driver->read_via_copy (buf, - driver->capture_addr[channel], - nsamples, - driver->capture_interleave_skip[channel]); + driver->read_via_copy (buf, + driver->capture_addr[channel], + nsamples, + driver->capture_interleave_skip[channel]); } static inline void alsa_driver_write_to_channel (alsa_driver_t *driver, - channel_t channel, - jack_default_audio_sample_t *buf, - jack_nframes_t nsamples) + channel_t channel, + jack_default_audio_sample_t *buf, + jack_nframes_t nsamples) { - driver->write_via_copy (driver->playback_addr[channel], - buf, - nsamples, - driver->playback_interleave_skip[channel], - driver->dither_state + channel); - alsa_driver_mark_channel_done (driver, channel); -} - -static inline void -alsa_driver_copy_channel (alsa_driver_t *driver, - channel_t input_channel, - channel_t output_channel, - jack_nframes_t nsamples) -{ - - driver->channel_copy (driver->playback_addr[output_channel], - driver->capture_addr[input_channel], - nsamples * driver->playback_sample_bytes, - driver->playback_interleave_skip[output_channel], - driver->capture_interleave_skip[input_channel]); - alsa_driver_mark_channel_done (driver, output_channel); + driver->write_via_copy (driver->playback_addr[channel], + buf, + nsamples, + driver->playback_interleave_skip[channel], + driver->dither_state+channel); + alsa_driver_mark_channel_done (driver, channel); } void alsa_driver_silence_untouched_channels (alsa_driver_t *driver, - jack_nframes_t nframes); + jack_nframes_t nframes); void alsa_driver_set_clock_sync_status (alsa_driver_t *driver, channel_t chn, - ClockSyncStatus status); + ClockSyncStatus status); int alsa_driver_listen_for_clock_sync_status (alsa_driver_t *, - ClockSyncListenerFunction, - void *arg); + ClockSyncListenerFunction, + void *arg); int alsa_driver_stop_listen_for_clock_sync_status (alsa_driver_t *, - unsigned int); + unsigned int); void alsa_driver_clock_sync_notify (alsa_driver_t *, channel_t chn, - ClockSyncStatus); + ClockSyncStatus); + +int +alsa_driver_reset_parameters (alsa_driver_t *driver, + jack_nframes_t frames_per_cycle, + jack_nframes_t user_nperiods, + jack_nframes_t rate); + +jack_driver_t * +alsa_driver_new (char *name, char *playback_alsa_device, + char *capture_alsa_device, + jack_client_t *client, + jack_nframes_t frames_per_cycle, + jack_nframes_t user_nperiods, + jack_nframes_t rate, + int hw_monitoring, + int hw_metering, + int capturing, + int playing, + DitherAlgorithm dither, + int soft_mode, + int monitor, + int user_capture_nchnls, + int user_playback_nchnls, + int shorts_first, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency, + alsa_midi_t *midi_driver + ); +void +alsa_driver_delete (alsa_driver_t *driver); + +int +alsa_driver_start (alsa_driver_t *driver); + +int +alsa_driver_stop (alsa_driver_t *driver); + +jack_nframes_t +alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *status, float + *delayed_usecs); + +int +alsa_driver_read (alsa_driver_t *driver, jack_nframes_t nframes); + +int +alsa_driver_write (alsa_driver_t* driver, jack_nframes_t nframes); + +jack_time_t jack_get_microseconds(void); + +// Code implemented in JackAlsaDriver.cpp + +void ReadInput(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nread); +void MonitorInput(); +void ClearOutput(); +void WriteOutput(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nwritten); +void SetTime(jack_time_t time); +int Restart(); + +#ifdef __cplusplus +} +#endif + #endif /* __jack_alsa_driver_h__ */ diff --git a/linux/firewire/JackFFADODriver.cpp b/linux/firewire/JackFFADODriver.cpp index 486c3794..2f855f37 100644 --- a/linux/firewire/JackFFADODriver.cpp +++ b/linux/firewire/JackFFADODriver.cpp @@ -526,7 +526,7 @@ int JackFFADODriver::Attach() port = fGraphManager->GetPort(port_index); // Add one buffer more latency if "async" mode is used... - range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency + range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency; port->SetLatencyRange(JackPlaybackLatency, &range); // playback port aliases (jackd1 style port names) snprintf(buf, sizeof(buf) - 1, "%s:playback_%i", fClientControl.fName, (int) chn + 1); @@ -644,20 +644,32 @@ int JackFFADODriver::Open(ffado_jack_settings_t *params) int JackFFADODriver::Close() { - JackAudioDriver::Close(); + // Generic audio driver close + int res = JackAudioDriver::Close(); + ffado_driver_delete((ffado_driver_t*)fDriver); - return 0; + return res; } int JackFFADODriver::Start() { - JackAudioDriver::Start(); - return ffado_driver_start((ffado_driver_t *)fDriver); + int res = JackAudioDriver::Start(); + if (res >= 0) { + res = ffado_driver_start((ffado_driver_t *)fDriver); + if (res < 0) { + JackAudioDriver::Stop(); + } + } + return res; } int JackFFADODriver::Stop() { - return ffado_driver_stop((ffado_driver_t *)fDriver); + int res = ffado_driver_stop((ffado_driver_t *)fDriver); + if (JackAudioDriver::Stop() < 0) { + res = -1; + } + return res; } int JackFFADODriver::Read() diff --git a/linux/freebob/JackFreebobDriver.cpp b/linux/freebob/JackFreebobDriver.cpp index 552e9927..03a26893 100644 --- a/linux/freebob/JackFreebobDriver.cpp +++ b/linux/freebob/JackFreebobDriver.cpp @@ -832,20 +832,32 @@ int JackFreebobDriver::Open(freebob_jack_settings_t *params) int JackFreebobDriver::Close() { - JackAudioDriver::Close(); + // Generic audio driver close + int res = JackAudioDriver::Close(); + freebob_driver_delete((freebob_driver_t*)fDriver); - return 0; + return res; } int JackFreebobDriver::Start() { - JackAudioDriver::Start(); - return freebob_driver_start((freebob_driver_t *)fDriver); + int res = JackAudioDriver::Start(); + if (res >= 0) { + res = freebob_driver_start((freebob_driver_t *)fDriver); + if (res < 0) { + JackAudioDriver::Stop(); + } + } + return res; } int JackFreebobDriver::Stop() { - return freebob_driver_stop((freebob_driver_t *)fDriver); + int res = freebob_driver_stop((freebob_driver_t *)fDriver); + if (JackAudioDriver::Stop() < 0) { + res = -1; + } + return res; } int JackFreebobDriver::Read() diff --git a/linux/wscript b/linux/wscript index 869985d4..5675c3dc 100644 --- a/linux/wscript +++ b/linux/wscript @@ -44,13 +44,15 @@ def build(bld): create_jack_driver_obj(bld, 'dummy', '../common/JackDummyDriver.cpp') - alsa_driver_src = ['alsa/JackAlsaDriver.cpp', + alsa_driver_src = [ + 'alsa/JackAlsaDriver.cpp', 'alsa/alsa_rawmidi.c', 'alsa/alsa_seqmidi.c', 'alsa/alsa_midi_jackmp.cpp', '../common/memops.c', 'alsa/generic_hw.c', 'alsa/hdsp.c', + 'alsa/alsa_driver.c', 'alsa/hammerfall.c', 'alsa/ice1712.c' ] diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index 1c3370aa..dbcdbe05 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -1598,6 +1598,7 @@ 4B98AE010931D30C0091932A /* JackDebugClient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackDebugClient.h; path = ../common/JackDebugClient.h; sourceTree = SOURCE_ROOT; }; 4B9A25B30DBF8330006E9FBC /* JackError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackError.cpp; path = ../common/JackError.cpp; sourceTree = SOURCE_ROOT; }; 4B9A26000DBF8584006E9FBC /* jslist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jslist.h; path = ../common/jack/jslist.h; sourceTree = SOURCE_ROOT; }; + 4BA2574C132FB49B009F2D3F /* alsa_driver.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = alsa_driver.c; path = ../linux/alsa/alsa_driver.c; sourceTree = SOURCE_ROOT; }; 4BA339AC10B2E36800190E3B /* Jackservermp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackservermp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4BA577BC08BF8BE200F82DE1 /* testSynchroClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSynchroClient.cpp; path = ../tests/testSynchroClient.cpp; sourceTree = SOURCE_ROOT; }; 4BA577FB08BF8E4600F82DE1 /* testSynchroServer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSynchroServer.cpp; path = ../tests/testSynchroServer.cpp; sourceTree = SOURCE_ROOT; }; @@ -2683,6 +2684,7 @@ 4B05A09D0DF72C6000840F4C /* Additional */ = { isa = PBXGroup; children = ( + 4BA2574C132FB49B009F2D3F /* alsa_driver.c */, 4B05A08A0DF72BF600840F4C /* Windows */, 4B05A0420DF72B8500840F4C /* Linux */, ); diff --git a/macosx/coreaudio/JackCoreAudioAdapter.cpp b/macosx/coreaudio/JackCoreAudioAdapter.cpp index d7e5edea..c1e9dc5e 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.cpp +++ b/macosx/coreaudio/JackCoreAudioAdapter.cpp @@ -276,17 +276,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]; + jack_default_audio_sample_t* inputBuffer[adapter->fCaptureChannels]; + jack_default_audio_sample_t* outputBuffer[adapter->fPlaybackChannels]; for (int i = 0; i < adapter->fCaptureChannels; i++) { - inputBuffer[i] = (float*)adapter->fInputData->mBuffers[i].mData; + inputBuffer[i] = (jack_default_audio_sample_t*)adapter->fInputData->mBuffers[i].mData; } for (int i = 0; i < adapter->fPlaybackChannels; i++) { - outputBuffer[i] = (float*)ioData->mBuffers[i].mData; + outputBuffer[i] = (jack_default_audio_sample_t*)ioData->mBuffers[i].mData; } - adapter->PushAndPull((float**)inputBuffer, (float**)outputBuffer, inNumberFrames); + adapter->PushAndPull((jack_default_audio_sample_t**)inputBuffer, (jack_default_audio_sample_t**)outputBuffer, inNumberFrames); return noErr; } @@ -769,8 +769,8 @@ int JackCoreAudioAdapter::SetupBuffers(int inchannels) fInputData->mNumberBuffers = inchannels; for (int i = 0; i < fCaptureChannels; i++) { fInputData->mBuffers[i].mNumberChannels = 1; - fInputData->mBuffers[i].mDataByteSize = fAdaptedBufferSize * sizeof(float); - fInputData->mBuffers[i].mData = malloc(fAdaptedBufferSize * sizeof(float)); + fInputData->mBuffers[i].mDataByteSize = fAdaptedBufferSize * sizeof(jack_default_audio_sample_t); + fInputData->mBuffers[i].mData = malloc(fAdaptedBufferSize * sizeof(jack_default_audio_sample_t)); } return 0; } @@ -942,9 +942,9 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, srcFormat.mSampleRate = samplerate; srcFormat.mFormatID = kAudioFormatLinearPCM; srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; - srcFormat.mBytesPerPacket = sizeof(float); + srcFormat.mBytesPerPacket = sizeof(jack_default_audio_sample_t); srcFormat.mFramesPerPacket = 1; - srcFormat.mBytesPerFrame = sizeof(float); + srcFormat.mBytesPerFrame = sizeof(jack_default_audio_sample_t); srcFormat.mChannelsPerFrame = inchannels; srcFormat.mBitsPerChannel = 32; PrintStreamDesc(&srcFormat); @@ -973,9 +973,9 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, dstFormat.mSampleRate = samplerate; dstFormat.mFormatID = kAudioFormatLinearPCM; dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; - dstFormat.mBytesPerPacket = sizeof(float); + dstFormat.mBytesPerPacket = sizeof(jack_default_audio_sample_t); dstFormat.mFramesPerPacket = 1; - dstFormat.mBytesPerFrame = sizeof(float); + dstFormat.mBytesPerFrame = sizeof(jack_default_audio_sample_t); dstFormat.mChannelsPerFrame = outchannels; dstFormat.mBitsPerChannel = 32; PrintStreamDesc(&dstFormat); diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 03e22adf..83806646 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -55,7 +55,7 @@ static void PrintStreamDesc(AudioStreamBasicDescription *inDesc) jack_log(" Bytes per Frame:%ld", inDesc->mBytesPerFrame); jack_log(" Channels per Frame:%ld", inDesc->mChannelsPerFrame); jack_log(" Bits per Channel:%ld", inDesc->mBitsPerChannel); - jack_log("- - - - - - - - - - - - - - - - - - - -\n"); + jack_log("- - - - - - - - - - - - - - - - - - - -"); } static void printError(OSStatus err) @@ -224,20 +224,19 @@ int JackCoreAudioDriver::Write() { for (int i = 0; i < fPlaybackChannels; i++) { if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) { - float* buffer = GetOutputBuffer(i); - int size = sizeof(float) * fEngineControl->fBufferSize; - memcpy((float*)fDriverOutputData->mBuffers[i].mData, buffer, size); + jack_default_audio_sample_t* buffer = GetOutputBuffer(i); + int size = sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize; + memcpy((jack_default_audio_sample_t*)fDriverOutputData->mBuffers[i].mData, buffer, size); // Monitor ports if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[i]) > 0) memcpy(GetMonitorBuffer(i), buffer, size); } else { - memset((float*)fDriverOutputData->mBuffers[i].mData, 0, sizeof(float) * fEngineControl->fBufferSize); + memset((jack_default_audio_sample_t*)fDriverOutputData->mBuffers[i].mData, 0, sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); } } return 0; } - OSStatus JackCoreAudioDriver::SRNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, @@ -1294,9 +1293,9 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, srcFormat.mSampleRate = samplerate; srcFormat.mFormatID = kAudioFormatLinearPCM; srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; - srcFormat.mBytesPerPacket = sizeof(float); + srcFormat.mBytesPerPacket = sizeof(jack_default_audio_sample_t); srcFormat.mFramesPerPacket = 1; - srcFormat.mBytesPerFrame = sizeof(float); + srcFormat.mBytesPerFrame = sizeof(jack_default_audio_sample_t); srcFormat.mChannelsPerFrame = inchannels; srcFormat.mBitsPerChannel = 32; PrintStreamDesc(&srcFormat); @@ -1324,9 +1323,9 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, dstFormat.mSampleRate = samplerate; dstFormat.mFormatID = kAudioFormatLinearPCM; dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; - dstFormat.mBytesPerPacket = sizeof(float); + dstFormat.mBytesPerPacket = sizeof(jack_default_audio_sample_t); dstFormat.mFramesPerPacket = 1; - dstFormat.mBytesPerFrame = sizeof(float); + dstFormat.mBytesPerFrame = sizeof(jack_default_audio_sample_t); dstFormat.mChannelsPerFrame = outchannels; dstFormat.mBitsPerChannel = 32; PrintStreamDesc(&dstFormat); @@ -1376,7 +1375,7 @@ int JackCoreAudioDriver::SetupBuffers(int inchannels) fJackInputData->mNumberBuffers = inchannels; for (int i = 0; i < inchannels; i++) { fJackInputData->mBuffers[i].mNumberChannels = 1; - fJackInputData->mBuffers[i].mDataByteSize = fEngineControl->fBufferSize * sizeof(float); + fJackInputData->mBuffers[i].mDataByteSize = fEngineControl->fBufferSize * sizeof(jack_default_audio_sample_t); } return 0; } @@ -1551,12 +1550,15 @@ int JackCoreAudioDriver::Close() { jack_log("JackCoreAudioDriver::Close"); Stop(); - JackAudioDriver::Close(); + + // Generic audio driver close + int res = JackAudioDriver::Close(); + RemoveListeners(); DisposeBuffers(); CloseAUHAL(); DestroyAggregateDevice(); - return 0; + return res; } int JackCoreAudioDriver::Attach() @@ -1577,11 +1579,11 @@ int JackCoreAudioDriver::Attach() err = AudioDeviceGetPropertyInfo(fDeviceID, i + 1, true, kAudioDevicePropertyChannelName, &size, &isWritable); if (err != noErr) - jack_log("AudioDeviceGetPropertyInfo kAudioDevicePropertyChannelName error "); + jack_log("AudioDeviceGetPropertyInfo kAudioDevicePropertyChannelName error"); if (err == noErr && size > 0) { err = AudioDeviceGetProperty(fDeviceID, i + 1, true, kAudioDevicePropertyChannelName, &size, channel_name); if (err != noErr) - jack_log("AudioDeviceGetProperty kAudioDevicePropertyChannelName error "); + jack_log("AudioDeviceGetProperty kAudioDevicePropertyChannelName error"); snprintf(alias, sizeof(alias) - 1, "%s:%s:out_%s%u", fAliasName, fCaptureDriverName, channel_name, i + 1); } else { snprintf(alias, sizeof(alias) - 1, "%s:%s:out%u", fAliasName, fCaptureDriverName, i + 1); @@ -1599,10 +1601,10 @@ int JackCoreAudioDriver::Attach() UInt32 value2 = 0; err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertyLatency, &size, &value1); if (err != noErr) - jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error "); + jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error"); err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertySafetyOffset, &size, &value2); if (err != noErr) - jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error "); + jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error"); port = fGraphManager->GetPort(port_index); port->SetAlias(alias); @@ -1615,11 +1617,11 @@ int JackCoreAudioDriver::Attach() err = AudioDeviceGetPropertyInfo(fDeviceID, i + 1, false, kAudioDevicePropertyChannelName, &size, &isWritable); if (err != noErr) - jack_log("AudioDeviceGetPropertyInfo kAudioDevicePropertyChannelName error "); + jack_log("AudioDeviceGetPropertyInfo kAudioDevicePropertyChannelName error"); if (err == noErr && size > 0) { err = AudioDeviceGetProperty(fDeviceID, i + 1, false, kAudioDevicePropertyChannelName, &size, channel_name); if (err != noErr) - jack_log("AudioDeviceGetProperty kAudioDevicePropertyChannelName error "); + jack_log("AudioDeviceGetProperty kAudioDevicePropertyChannelName error"); snprintf(alias, sizeof(alias) - 1, "%s:%s:in_%s%u", fAliasName, fPlaybackDriverName, channel_name, i + 1); } else { snprintf(alias, sizeof(alias) - 1, "%s:%s:in%u", fAliasName, fPlaybackDriverName, i + 1); @@ -1637,10 +1639,10 @@ int JackCoreAudioDriver::Attach() UInt32 value2 = 0; err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertyLatency, &size, &value1); if (err != noErr) - jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error "); + jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error"); err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertySafetyOffset, &size, &value2); if (err != noErr) - jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error "); + jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error"); port = fGraphManager->GetPort(port_index); port->SetAlias(alias); @@ -1651,14 +1653,13 @@ int JackCoreAudioDriver::Attach() // Monitor ports if (fWithMonitorPorts) { - jack_log("Create monitor port "); + jack_log("Create monitor port"); snprintf(name, sizeof(name) - 1, "%s:monitor_%u", fClientControl.fName, i + 1); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, MonitorDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("Cannot register monitor port for %s", name); return -1; } else { port = fGraphManager->GetPort(port_index); - port->SetAlias(alias); range.min = range.max = fEngineControl->fBufferSize; port->SetLatencyRange(JackCaptureLatency, &range); fMonitorPortList[i] = port_index; @@ -1677,33 +1678,38 @@ int JackCoreAudioDriver::Attach() int JackCoreAudioDriver::Start() { jack_log("JackCoreAudioDriver::Start"); - JackAudioDriver::Start(); + if (JackAudioDriver::Start() >= 0) { + OSStatus err = AudioOutputUnitStart(fAUHAL); + if (err == noErr) { - OSStatus err = AudioOutputUnitStart(fAUHAL); - if (err != noErr) - return -1; + // Waiting for Measure callback to be called (= driver has started) + fState = false; + int count = 0; + while (!fState && count++ < WAIT_COUNTER) { + usleep(100000); + jack_log("JackCoreAudioDriver::Start wait count = %d", count); + } - // Waiting for Measure callback to be called (= driver has started) - fState = false; - int count = 0; - while (!fState && count++ < WAIT_COUNTER) { - usleep(100000); - jack_log("JackCoreAudioDriver::Start wait count = %d", count); - } + if (count < WAIT_COUNTER) { + jack_info("CoreAudio driver is running..."); + return 0; + } - if (count < WAIT_COUNTER) { - jack_info("CoreAudio driver is running..."); - return 0; - } else { - jack_error("CoreAudio driver cannot start..."); - return -1; + jack_error("CoreAudio driver cannot start..."); + } + JackAudioDriver::Stop(); } + return -1; } int JackCoreAudioDriver::Stop() { jack_log("JackCoreAudioDriver::Stop"); - return (AudioOutputUnitStop(fAUHAL) == noErr) ? 0 : -1; + int res = (AudioOutputUnitStop(fAUHAL) == noErr) ? 0 : -1; + if (JackAudioDriver::Stop() < 0) { + res = -1; + } + return res; } int JackCoreAudioDriver::SetBufferSize(jack_nframes_t buffer_size) @@ -1723,7 +1729,7 @@ int JackCoreAudioDriver::SetBufferSize(jack_nframes_t buffer_size) // Input buffers do no change : prepare them only once for (int i = 0; i < fCaptureChannels; i++) { fJackInputData->mBuffers[i].mNumberChannels = 1; - fJackInputData->mBuffers[i].mDataByteSize = fEngineControl->fBufferSize * sizeof(float); + fJackInputData->mBuffers[i].mDataByteSize = fEngineControl->fBufferSize * sizeof(jack_default_audio_sample_t); fJackInputData->mBuffers[i].mData = GetInputBuffer(i); } diff --git a/macosx/coremidi/JackCoreMidiDriver.cpp b/macosx/coremidi/JackCoreMidiDriver.cpp index 55ffeae6..1cb7176b 100644 --- a/macosx/coremidi/JackCoreMidiDriver.cpp +++ b/macosx/coremidi/JackCoreMidiDriver.cpp @@ -45,15 +45,15 @@ void JackCoreMidiDriver::ReadProcAux(const MIDIPacketList *pktlist, jack_ringbuf jack_error("ReadProc : ring buffer is full, skip events..."); return; } - + jack_ringbuffer_write(ringbuffer, (char*)&pktlist->numPackets, sizeof(UInt32)); - + for (unsigned int i = 0; i < pktlist->numPackets; ++i) { - + MIDIPacket *packet = (MIDIPacket *)pktlist->packet; - + // TODO : use timestamp - + // Check available size first.. size = jack_ringbuffer_write_space(ringbuffer); if (size < (sizeof(UInt16) + packet->length)) { @@ -64,7 +64,7 @@ void JackCoreMidiDriver::ReadProcAux(const MIDIPacketList *pktlist, jack_ringbuf jack_ringbuffer_write(ringbuffer, (char*)&packet->length, sizeof(UInt16)); // Write event actual data jack_ringbuffer_write(ringbuffer, (char*)packet->data, packet->length); - + packet = MIDIPacketNext(packet); } } @@ -83,7 +83,7 @@ void JackCoreMidiDriver::ReadVirtualProc(const MIDIPacketList *pktlist, void *re void JackCoreMidiDriver::NotifyProc(const MIDINotification *message, void *refCon) { - jack_info("NotifyProc %d", message->messageID); + jack_log("NotifyProc %d", message->messageID); } JackCoreMidiDriver::JackCoreMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) @@ -106,15 +106,15 @@ int JackCoreMidiDriver::Open(bool capturing, OSStatus err; CFStringRef coutputStr; std::string str; - + // Get real input/output number fRealCaptureChannels = MIDIGetNumberOfSources(); fRealPlaybackChannels = MIDIGetNumberOfDestinations(); - + // Generic JackMidiDriver Open if (JackMidiDriver::Open(capturing, playing, inchannels + fRealCaptureChannels, outchannels + fRealPlaybackChannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0) return -1; - + coutputStr = CFStringCreateWithCString(0, "JackMidi", CFStringGetSystemEncoding()); err = MIDIClientCreate(coutputStr, NotifyProc, this, &fMidiClient); CFRelease(coutputStr); @@ -122,7 +122,7 @@ int JackCoreMidiDriver::Open(bool capturing, jack_error("Cannot create CoreMidi client"); goto error; } - + err = MIDIInputPortCreate(fMidiClient, CFSTR("Input port"), ReadProc, this, &fInputPort); if (!fInputPort) { jack_error("Cannot open CoreMidi in port\n"); @@ -134,10 +134,10 @@ int JackCoreMidiDriver::Open(bool capturing, jack_error("Cannot open CoreMidi out port\n"); goto error; } - + fMidiDestination = new MIDIEndpointRef[inchannels + fRealCaptureChannels]; assert(fMidiDestination); - + // Virtual input for (int i = 0; i < inchannels; i++) { std::stringstream num; @@ -151,13 +151,13 @@ int JackCoreMidiDriver::Open(bool capturing, goto error; } } - + // Real input for (int i = 0; i < fRealCaptureChannels; i++) { fMidiDestination[i + inchannels] = MIDIGetSource(i); MIDIPortConnectSource(fInputPort, fMidiDestination[i + inchannels], fRingBuffer[i + inchannels]); } - + fMidiSource = new MIDIEndpointRef[outchannels + fRealPlaybackChannels]; assert(fMidiSource); @@ -172,47 +172,50 @@ int JackCoreMidiDriver::Open(bool capturing, if (!fMidiSource[i]) { jack_error("Cannot create CoreMidi source"); goto error; - } + } } - + // Real output for (int i = 0; i < fRealPlaybackChannels; i++) { fMidiSource[i + outchannels] = MIDIGetDestination(i); } - + return 0; - + error: Close(); return -1; } - + int JackCoreMidiDriver::Close() { + // Generic midi driver close + int res = JackMidiDriver::Close(); + if (fInputPort) MIDIPortDispose(fInputPort); - - if (fOutputPort) + + if (fOutputPort) MIDIPortDispose(fOutputPort); - + // Only dispose "virtual" endpoints for (int i = 0; i < fCaptureChannels - fRealCaptureChannels; i++) { - if (fMidiDestination) + if (fMidiDestination) MIDIEndpointDispose(fMidiDestination[i]); } delete[] fMidiDestination; - + // Only dispose "virtual" endpoints for (int i = 0; i < fPlaybackChannels - fRealPlaybackChannels; i++) { - if (fMidiSource[i]) + if (fMidiSource[i]) MIDIEndpointDispose(fMidiSource[i]); } delete[] fMidiSource; - - if (fMidiClient) + + if (fMidiClient) MIDIClientDispose(fMidiClient); - - return 0; + + return res; } int JackCoreMidiDriver::Attach() @@ -229,7 +232,7 @@ int JackCoreMidiDriver::Attach() jack_log("JackCoreMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); for (i = 0; i < fCaptureChannels; i++) { - + err = MIDIObjectGetStringProperty(fMidiDestination[i], kMIDIPropertyName, &pname); if (err == noErr) { CFStringGetCString(pname, endpoint_name, sizeof(endpoint_name), 0); @@ -238,7 +241,7 @@ int JackCoreMidiDriver::Attach() } else { snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); } - + snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", name); @@ -251,7 +254,7 @@ int JackCoreMidiDriver::Attach() } for (i = 0; i < fPlaybackChannels; i++) { - + err = MIDIObjectGetStringProperty(fMidiSource[i], kMIDIPropertyName, &pname); if (err == noErr) { CFStringGetCString(pname, endpoint_name, sizeof(endpoint_name), 0); @@ -260,7 +263,7 @@ int JackCoreMidiDriver::Attach() } else { snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); } - + snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("driver: cannot register port for %s", name); @@ -277,23 +280,23 @@ int JackCoreMidiDriver::Attach() int JackCoreMidiDriver::Read() { for (int chan = 0; chan < fCaptureChannels; chan++) { - + if (fGraphManager->GetConnectionsNum(fCapturePortList[chan]) > 0) { - + // Get JACK port JackMidiBuffer* midi_buffer = GetInputBuffer(chan); - + if (jack_ringbuffer_read_space(fRingBuffer[chan]) == 0) { // Reset buffer midi_buffer->Reset(midi_buffer->nframes); } else { - + while (jack_ringbuffer_read_space(fRingBuffer[chan]) > 0) { - + // Read event number int ev_count = 0; jack_ringbuffer_read(fRingBuffer[chan], (char*)&ev_count, sizeof(int)); - + for (int j = 0; j < ev_count; j++) { // Read event length UInt16 event_len; @@ -304,7 +307,7 @@ int JackCoreMidiDriver::Read() } } } - + } else { // Consume ring buffer jack_ringbuffer_read_advance(fRingBuffer[chan], jack_ringbuffer_read_space(fRingBuffer[chan])); @@ -316,35 +319,35 @@ int JackCoreMidiDriver::Read() int JackCoreMidiDriver::Write() { MIDIPacketList* pktlist = (MIDIPacketList*)fMIDIBuffer; - + for (int chan = 0; chan < fPlaybackChannels; chan++) { - + if (fGraphManager->GetConnectionsNum(fPlaybackPortList[chan]) > 0) { - + MIDIPacket* packet = MIDIPacketListInit(pktlist); JackMidiBuffer* midi_buffer = GetOutputBuffer(chan); - + // TODO : use timestamp - + for (unsigned int j = 0; j < midi_buffer->event_count; j++) { JackMidiEvent* ev = &midi_buffer->events[j]; packet = MIDIPacketListAdd(pktlist, sizeof(fMIDIBuffer), packet, MIDIGetCurrentHostTime(), ev->size, ev->GetData(midi_buffer)); } - + if (packet) { if (chan < fPlaybackChannels - fRealPlaybackChannels) { OSStatus err = MIDIReceived(fMidiSource[chan], pktlist); - if (err != noErr) + if (err != noErr) jack_error("MIDIReceived error"); } else { OSStatus err = MIDISend(fOutputPort, fMidiSource[chan], pktlist); - if (err != noErr) + if (err != noErr) jack_error("MIDISend error"); } } } } - + return 0; } @@ -355,7 +358,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; @@ -366,7 +369,7 @@ extern "C" desc->nparams = 2; desc->params = (jack_driver_param_desc_t*)calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); - + i = 0; strcpy(desc->params[i].name, "inchannels"); desc->params[i].character = 'i'; @@ -386,7 +389,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) { const JSList * node; const jack_driver_param_t * param; @@ -407,7 +410,7 @@ extern "C" break; } } - + Jack::JackDriverClientInterface* driver = new Jack::JackCoreMidiDriver("system_midi", "coremidi", engine, table); if (driver->Open(1, 1, virtual_in, virtual_out, false, "in", "out", 0, 0) == 0) { return driver; diff --git a/macosx/coremidi/JackCoreMidiDriver.h b/macosx/coremidi/JackCoreMidiDriver.h index 190e9cd2..a99b35a0 100644 --- a/macosx/coremidi/JackCoreMidiDriver.h +++ b/macosx/coremidi/JackCoreMidiDriver.h @@ -41,17 +41,17 @@ class JackCoreMidiDriver : public JackMidiDriver MIDIPortRef fOutputPort; MIDIEndpointRef* fMidiDestination; MIDIEndpointRef* fMidiSource; - - char fMIDIBuffer[BUFFER_SIZE_MAX * sizeof(float)]; - + + char fMIDIBuffer[BUFFER_SIZE_MAX * sizeof(jack_default_audio_sample_t)]; + int fRealCaptureChannels; int fRealPlaybackChannels; - + static void ReadProcAux(const MIDIPacketList *pktlist, jack_ringbuffer_t* ringbuffer); static void ReadProc(const MIDIPacketList *pktlist, void *refCon, void *connRefCon); static void ReadVirtualProc(const MIDIPacketList *pktlist, void *refCon, void *connRefCon); static void NotifyProc(const MIDINotification *message, void *refCon); - + public: JackCoreMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); @@ -67,7 +67,7 @@ class JackCoreMidiDriver : public JackMidiDriver jack_nframes_t capture_latency, jack_nframes_t playback_latency); int Close(); - + int Attach(); int Read(); diff --git a/posix/JackSocketServerChannel.cpp b/posix/JackSocketServerChannel.cpp index ac857de2..3008e307 100644 --- a/posix/JackSocketServerChannel.cpp +++ b/posix/JackSocketServerChannel.cpp @@ -392,7 +392,7 @@ bool JackSocketServerChannel::HandleRequest(int fd) JackInternalClientLoadRequest req; JackInternalClientLoadResult res; if (req.Read(socket) == 0) - res.fResult = fServer->InternalClientLoad(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, req.fUUID, &res.fStatus); + res.fResult = fServer->InternalClientLoad1(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, req.fUUID, &res.fStatus); if (res.Write(socket) < 0) jack_error("JackRequest::InternalClientLoad write error name = %s", req.fName); break; diff --git a/posix/JackSystemDeps_os.h b/posix/JackSystemDeps_os.h index 41ee9528..516b805b 100644 --- a/posix/JackSystemDeps_os.h +++ b/posix/JackSystemDeps_os.h @@ -25,7 +25,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include +#ifndef UINT32_MAX #define UINT32_MAX 4294967295U +#endif #define DRIVER_HANDLE void* #define LoadDriverModule(name) dlopen((name), RTLD_NOW | RTLD_GLOBAL) diff --git a/windows/JackRouter/JackRouter.cpp b/windows/JackRouter/JackRouter.cpp index 47727af7..e5086f8d 100644 --- a/windows/JackRouter/JackRouter.cpp +++ b/windows/JackRouter/JackRouter.cpp @@ -1,5 +1,5 @@ /* -Copyright (C) 2006 Grame +Copyright (C) 2006 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 @@ -58,13 +58,13 @@ static const double twoRaisedTo32Reciprocal = 1. / twoRaisedTo32; using namespace std; -// class id. +// class id. // {838FE50A-C1AB-4b77-B9B6-0A40788B53F3} CLSID IID_ASIO_DRIVER = { 0x838fe50a, 0xc1ab, 0x4b77, { 0xb9, 0xb6, 0xa, 0x40, 0x78, 0x8b, 0x53, 0xf3 } }; CFactoryTemplate g_Templates[1] = { - {L"ASIOJACK", &IID_ASIO_DRIVER, JackRouter::CreateInstance} + {L"ASIOJACK", &IID_ASIO_DRIVER, JackRouter::CreateInstance} }; int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]); @@ -183,7 +183,7 @@ JackRouter::JackRouter() : AsioDriver() char dllName[512]; string confPath; DWORD res = GetModuleFileName(handle, dllName, 512); - + // Compute .ini file path string fullPath = dllName; int lastPos = fullPath.find_last_of(PATH_SEP); @@ -223,7 +223,7 @@ static bool GetEXEName(DWORD dwProcessID, char* name) { DWORD aProcesses [1024], cbNeeded, cProcesses; unsigned int i; - + // Enumerate all processes if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) return false; @@ -240,33 +240,33 @@ static bool GetEXEName(DWORD dwProcessID, char* name) // Get a handle to the process HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessID); - + // Get the process name if (NULL != hProcess) { HMODULE hMod; DWORD cbNeeded; - - if(EnumProcessModules(hProcess, &hMod, + + if(EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) { //Get the name of the exe file - GetModuleBaseName(hProcess, hMod, szEXEName, + GetModuleBaseName(hProcess, hMod, szEXEName, sizeof(szEXEName)/sizeof(TCHAR)); int len = strlen((char*)szEXEName) - 4; // remove ".exe" - strncpy(name, (char*)szEXEName, len); + strncpy(name, (char*)szEXEName, len); name[len] = '\0'; return true; } } - } + } } return false; } //------------------------------------------------------------------------------------------ -static inline float ClipFloat(float sample) +static inline jack_default_audio_sample_t ClipFloat(jack_default_audio_sample_t sample) { - return (sample < -1.0f) ? -1.0f : (sample > 1.0f) ? 1.0f : sample; + return (sample < jack_default_audio_sample_t(-1.0)) ? jack_default_audio_sample_t(-1.0) : (sample > jack_default_audio_sample_t(1.0)) ? jack_default_audio_sample_t(1.0) : sample; } //------------------------------------------------------------------------------------------ @@ -288,42 +288,42 @@ int JackRouter::process(jack_nframes_t nframes, void* arg) { JackRouter* driver = (JackRouter*)arg; int i,j; - int pos = (driver->fToggle) ? 0 : driver->fBufferSize ; - - for (i = 0; i < driver->fActiveInputs; i++) { - -#ifdef LONG_SAMPLE - float* buffer = (float*)jack_port_get_buffer(driver->fInputPorts[i], nframes); + int pos = (driver->fToggle) ? 0 : driver->fBufferSize ; + + for (i = 0; i < driver->fActiveInputs; i++) { + +#ifdef LONG_SAMPLE + jack_default_audio_sample_t* buffer = (jack_default_audio_sample_t*)jack_port_get_buffer(driver->fInputPorts[i], nframes); long* in = driver->fInputBuffers[i] + pos; for (j = 0; j < nframes; j++) { - in[j] = buffer[j] * float(0x7fffffff); + in[j] = buffer[j] * jack_default_audio_sample_t(0x7fffffff); } #else memcpy(driver->fInputBuffers[i] + pos, jack_port_get_buffer(driver->fInputPorts[i], nframes), - nframes * sizeof(float)); + nframes * sizeof(jack_default_audio_sample_t)); #endif - } + } driver->bufferSwitch(); for (i = 0; i < driver->fActiveOutputs; i++) { #ifdef LONG_SAMPLE - float* buffer = (float*)jack_port_get_buffer(driver->fOutputPorts[i], nframes); + jack_default_audio_sample_t* buffer = (jack_default_audio_sample_t*)jack_port_get_buffer(driver->fOutputPorts[i], nframes); long* out = driver->fOutputBuffers[i] + pos; - float gain = 1.f/float(0x7fffffff); + jack_default_audio_sample_t gain = jack_default_audio_sample_t(1)/jack_default_audio_sample_t(0x7fffffff); for (j = 0; j < nframes; j++) { buffer[j] = out[j] * gain; } #else memcpy(jack_port_get_buffer(driver->fOutputPorts[i], nframes), driver->fOutputBuffers[i] + pos, - nframes * sizeof(float)); + nframes * sizeof(jack_default_audio_sample_t)); #endif } - + return 0; } @@ -356,7 +356,7 @@ ASIOBool JackRouter::init(void* sysRef) HANDLE win = (HANDLE)sysRef; int my_pid = _getpid(); - + if (!GetEXEName(my_pid, name)) { // If getting the .exe name fails, takes a generic one. _snprintf(name, sizeof(name) - 1, "JackRouter_%d", my_pid); } @@ -365,19 +365,19 @@ ASIOBool JackRouter::init(void* sysRef) printf("Error: jack client still present...\n"); return true; } - + fClient = jack_client_open(name, JackNullOption, NULL); if (fClient == NULL) { strcpy (fErrorMessage, "Open error: is jack server running?"); printf("Open error: is jack server running?\n"); return false; } - + fBufferSize = jack_get_buffer_size(fClient); fSampleRate = jack_get_sample_rate(fClient); jack_set_process_callback(fClient, process, this); jack_on_shutdown(fClient, shutdown, this); - + fInputLatency = fBufferSize; // typically fOutputLatency = fBufferSize * 2; fMilliSeconds = (long)((double)(fBufferSize * 1000) / fSampleRate); @@ -399,7 +399,7 @@ ASIOError JackRouter::start() fToggle = 0; fStarted = true; printf("Start ASIO Jack\n"); - + if (jack_activate(fClient) == 0) { if (fFirstActivate) { @@ -413,9 +413,9 @@ ASIOError JackRouter::start() } else { return ASE_NotPresent; - } + } } - + return ASE_NotPresent; } @@ -533,8 +533,8 @@ ASIOError JackRouter::getChannelInfo(ASIOChannelInfo *info) char buf[32]; if (info->isInput) { - for (i = 0; i < fActiveInputs; i++) { - if (fInMap[i] == info->channel) { + for (i = 0; i < fActiveInputs; i++) { + if (fInMap[i] == info->channel) { info->isActive = ASIOTrue; //_snprintf(buf, sizeof(buf) - 1, "Jack::In%d ", info->channel); //strcpy(info->name, buf); @@ -545,7 +545,7 @@ ASIOError JackRouter::getChannelInfo(ASIOChannelInfo *info) _snprintf(buf, sizeof(buf) - 1, "In%d ", info->channel); strcpy(info->name, buf); } else { - for (i = 0; i < fActiveOutputs; i++) { + for (i = 0; i < fActiveOutputs; i++) { if (fOutMap[i] == info->channel) { //NOT USED !! info->isActive = ASIOTrue; //_snprintf(buf, sizeof(buf) - 1, "Jack::Out%d ", info->channel); @@ -579,7 +579,7 @@ ASIOError JackRouter::createBuffers(ASIOBufferInfo *bufferInfos, long numChannel #ifdef LONG_SAMPLE fInputBuffers[fActiveInputs] = new long[fBufferSize * 2]; // double buffer #else - fInputBuffers[fActiveInputs] = new float[fBufferSize * 2]; // double buffer + fInputBuffers[fActiveInputs] = new jack_default_audio_sample_t[fBufferSize * 2]; // double buffer #endif if (fInputBuffers[fActiveInputs]) { info->buffers[0] = fInputBuffers[fActiveInputs]; @@ -588,9 +588,9 @@ ASIOError JackRouter::createBuffers(ASIOBufferInfo *bufferInfos, long numChannel info->buffers[0] = info->buffers[1] = 0; notEnoughMem = true; } - + _snprintf(buf, sizeof(buf) - 1, "in%d", fActiveInputs + 1); - fInputPorts[fActiveInputs] + fInputPorts[fActiveInputs] = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput,0); if (fInputPorts[fActiveInputs] == NULL) goto error; @@ -601,17 +601,17 @@ error: disposeBuffers(); return ASE_InvalidParameter; } - } else { // output + } else { // output if (info->channelNum < 0 || info->channelNum >= kNumOutputs) goto error; fOutMap[fActiveOutputs] = info->channelNum; - + #ifdef LONG_SAMPLE fOutputBuffers[fActiveOutputs] = new long[fBufferSize * 2]; // double buffer #else - fOutputBuffers[fActiveOutputs] = new float[fBufferSize * 2]; // double buffer + fOutputBuffers[fActiveOutputs] = new jack_default_audio_sample_t[fBufferSize * 2]; // double buffer #endif - + if (fOutputBuffers[fActiveOutputs]) { info->buffers[0] = fOutputBuffers[fActiveOutputs]; info->buffers[1] = fOutputBuffers[fActiveOutputs] + fBufferSize; @@ -619,9 +619,9 @@ error: info->buffers[0] = info->buffers[1] = 0; notEnoughMem = true; } - + _snprintf(buf, sizeof(buf) - 1, "out%d", fActiveOutputs + 1); - fOutputPorts[fActiveOutputs] + fOutputPorts[fActiveOutputs] = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput,0); if (fOutputPorts[fActiveOutputs] == NULL) goto error; @@ -633,7 +633,7 @@ error: return ASE_InvalidParameter; } } - } + } if (notEnoughMem) { disposeBuffers(); @@ -653,9 +653,9 @@ error: fAsioTime.timeCode.timeCodeSamples.lo = fAsioTime.timeCode.timeCodeSamples.hi = 0; fAsioTime.timeCode.flags = kTcValid | kTcRunning ; } else { - fTimeInfoMode = false; + fTimeInfoMode = false; } - + return ASE_OK; } @@ -663,14 +663,14 @@ error: ASIOError JackRouter::disposeBuffers() { long i; - + fCallbacks = 0; stop(); for (i = 0; i < fActiveInputs; i++) { delete[] fInputBuffers[i]; jack_port_unregister(fClient, fInputPorts[i]); - } + } fActiveInputs = 0; for (i = 0; i < fActiveOutputs; i++) { @@ -689,7 +689,7 @@ ASIOError JackRouter::controlPanel() } //--------------------------------------------------------------------------------------------- -ASIOError JackRouter::future(long selector, void* opt) // !!! check properties +ASIOError JackRouter::future(long selector, void* opt) // !!! check properties { ASIOTransportParameters* tp = (ASIOTransportParameters*)opt; switch (selector) @@ -804,7 +804,7 @@ void JackRouter::RestoreConnections() void JackRouter::AutoConnect() { const char** ports; - + if ((ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput)) == NULL) { printf("Cannot find any physical capture ports\n"); } else { @@ -818,9 +818,9 @@ void JackRouter::AutoConnect() } } } - jack_free(ports); + jack_free(ports); } - + if ((ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput)) == NULL) { printf("Cannot find any physical playback ports"); } else { @@ -834,7 +834,7 @@ void JackRouter::AutoConnect() } } } - jack_free(ports); + jack_free(ports); } } diff --git a/windows/JackWinNamedPipeServerChannel.cpp b/windows/JackWinNamedPipeServerChannel.cpp index b4d4d622..3723af5e 100644 --- a/windows/JackWinNamedPipeServerChannel.cpp +++ b/windows/JackWinNamedPipeServerChannel.cpp @@ -307,7 +307,7 @@ bool JackClientPipeThread::HandleRequest() JackInternalClientLoadRequest req; JackInternalClientLoadResult res; if (req.Read(fPipe) == 0) - res.fResult = fServer->InternalClientLoad(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, req.fUUID, &res.fStatus); + res.fResult = fServer->InternalClientLoad1(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, req.fUUID, &res.fStatus); res.Write(fPipe); break; } diff --git a/windows/JackWinProcessSync.cpp b/windows/JackWinProcessSync.cpp index 12dbcdcf..5f3fa2fd 100644 --- a/windows/JackWinProcessSync.cpp +++ b/windows/JackWinProcessSync.cpp @@ -1,20 +1,20 @@ /* Copyright (C) 2004-2008 Grame - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 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 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - + */ @@ -74,7 +74,7 @@ bool JackWinProcessSync::LockedTimedWait(long usec) } /* -Code from CAGuard.cpp : does ot sees to work as expected.. +Code from APPLE CAGuard.cpp : does not seem to work as expected... void JackWinProcessSync::Wait() { diff --git a/windows/Setup/JackRouter.dll b/windows/Setup/JackRouter.dll index 829f6e106b5f03290f60129a70e137c2726dcd74..860fcc39daf68896951326eac0d21b1eccfc6f78 100644 GIT binary patch delta 161 zcmZo@U}|V!n(%>nvC!m=pMToh=`b=hBmuDs5Ss$A9S~;&u`Ccr0C6S|Cj+qt5YGeR h3Lv%xVlyC?Vce|c7{o%U8M|D6v4PyPdApCNF#z(userData); - adapter->PushAndPull((float**)inputBuffer, (float**)outputBuffer, framesPerBuffer); + adapter->PushAndPull((jack_default_audio_sample_t**)inputBuffer, (jack_default_audio_sample_t**)outputBuffer, framesPerBuffer); return paContinue; } diff --git a/windows/portaudio/JackPortAudioDriver.cpp b/windows/portaudio/JackPortAudioDriver.cpp index d910bb9d..41a3deb2 100644 --- a/windows/portaudio/JackPortAudioDriver.cpp +++ b/windows/portaudio/JackPortAudioDriver.cpp @@ -38,8 +38,8 @@ namespace Jack void* userData) { JackPortAudioDriver* driver = (JackPortAudioDriver*)userData; - driver->fInputBuffer = (float**)inputBuffer; - driver->fOutputBuffer = (float**)outputBuffer; + driver->fInputBuffer = (jack_default_audio_sample_t**)inputBuffer; + driver->fOutputBuffer = (jack_default_audio_sample_t**)outputBuffer; // Setup threadded based log function set_threaded_log_function(); driver->CycleTakeBeginTime(); @@ -49,14 +49,14 @@ namespace Jack int JackPortAudioDriver::Read() { for (int i = 0; i < fCaptureChannels; i++) - memcpy(GetInputBuffer(i), fInputBuffer[i], sizeof(float) * fEngineControl->fBufferSize); + memcpy(GetInputBuffer(i), fInputBuffer[i], sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); return 0; } int JackPortAudioDriver::Write() { for (int i = 0; i < fPlaybackChannels; i++) - memcpy(fOutputBuffer[i], GetOutputBuffer(i), sizeof(float) * fEngineControl->fBufferSize); + memcpy(fOutputBuffer[i], GetOutputBuffer(i), sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); return 0; } @@ -180,7 +180,9 @@ error: int JackPortAudioDriver::Close() { + // Generic audio driver close int res = JackAudioDriver::Close(); + jack_log("JackPortAudioDriver::Close"); Pa_CloseStream(fStream); return res; @@ -189,16 +191,25 @@ error: int JackPortAudioDriver::Start() { jack_log("JackPortAudioDriver::Start"); - JackAudioDriver::Start(); - PaError err = Pa_StartStream(fStream); - return (err == paNoError) ? 0 : -1; + if (JackAudioDriver::Start() >= 0) { + PaError err = Pa_StartStream(fStream); + if (err == paNoError) { + return 0; + } + JackAudioDriver::Stop(); + } + return -1; } int JackPortAudioDriver::Stop() { jack_log("JackPortAudioDriver::Stop"); PaError err = Pa_StopStream(fStream); - return (err == paNoError) ? 0 : -1; + int res = (err == paNoError) ? 0 : -1; + if (JackAudioDriver::Stop() < 0) { + res = -1; + } + return res; } int JackPortAudioDriver::SetBufferSize(jack_nframes_t buffer_size) diff --git a/windows/portaudio/JackPortAudioDriver.h b/windows/portaudio/JackPortAudioDriver.h index d18da9b8..c4945f44 100644 --- a/windows/portaudio/JackPortAudioDriver.h +++ b/windows/portaudio/JackPortAudioDriver.h @@ -37,8 +37,8 @@ class JackPortAudioDriver : public JackAudioDriver PortAudioDevices* fPaDevices; PaStream* fStream; - float** fInputBuffer; - float** fOutputBuffer; + jack_default_audio_sample_t** fInputBuffer; + jack_default_audio_sample_t** fOutputBuffer; PaDeviceIndex fInputDevice; PaDeviceIndex fOutputDevice; diff --git a/windows/winmme/JackWinMMEDriver.cpp b/windows/winmme/JackWinMMEDriver.cpp index b76a8299..d3635c64 100644 --- a/windows/winmme/JackWinMMEDriver.cpp +++ b/windows/winmme/JackWinMMEDriver.cpp @@ -264,6 +264,9 @@ int JackWinMMEDriver::Close() { jack_log("JackWinMMEDriver::Close"); + // Generic midi driver close + int res = JackMidiDriver::Close(); + // Close input if (fMidiDestination) { for (int i = 0; i < fRealCaptureChannels; i++) { @@ -280,7 +283,7 @@ int JackWinMMEDriver::Close() delete[] fMidiSource; } - return 0; + return res; } int JackWinMMEDriver::Attach() diff --git a/wscript b/wscript index 43ab73a2..dedd86eb 100644 --- a/wscript +++ b/wscript @@ -129,23 +129,33 @@ def configure(conf): conf.fatal('jackdbus was explicitly requested but cannot be built') conf.sub_config('example-clients') - if conf.check_cfg(package='celt', atleast_version='0.8.0', args='--cflags --libs'): + if conf.check_cfg(package='celt', atleast_version='0.11.0', args='--cflags --libs'): conf.define('HAVE_CELT', 1) + conf.define('HAVE_CELT_API_0_11', 1) + conf.define('HAVE_CELT_API_0_8', 0) + conf.define('HAVE_CELT_API_0_7', 0) + conf.define('HAVE_CELT_API_0_5', 0) + elif conf.check_cfg(package='celt', atleast_version='0.8.0', args='--cflags --libs'): + conf.define('HAVE_CELT', 1) + conf.define('HAVE_CELT_API_0_11', 0) conf.define('HAVE_CELT_API_0_8', 1) conf.define('HAVE_CELT_API_0_7', 0) conf.define('HAVE_CELT_API_0_5', 0) elif conf.check_cfg(package='celt', atleast_version='0.7.0', args='--cflags --libs'): conf.define('HAVE_CELT', 1) + conf.define('HAVE_CELT_API_0_11', 0) conf.define('HAVE_CELT_API_0_8', 0) conf.define('HAVE_CELT_API_0_7', 1) conf.define('HAVE_CELT_API_0_5', 0) elif conf.check_cfg(package='celt', atleast_version='0.5.0', args='--cflags --libs', required=True): conf.define('HAVE_CELT', 1) + conf.define('HAVE_CELT_API_0_11', 0) conf.define('HAVE_CELT_API_0_8', 0) conf.define('HAVE_CELT_API_0_7', 0) conf.define('HAVE_CELT_API_0_5', 1) else: conf.define('HAVE_CELT', 0) + conf.define('HAVE_CELT_API_0_11', 0) conf.define('HAVE_CELT_API_0_8', 0) conf.define('HAVE_CELT_API_0_7', 0) conf.define('HAVE_CELT_API_0_5', 0) From 53111aac1bac1b9c50d68a27428b452661a1170e Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 30 Mar 2011 16:45:28 +0000 Subject: [PATCH 105/472] Version 1.9.8 started. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4240 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 4 ++++ README | 2 +- common/JackConstants.h | 4 ++-- doxyfile | 2 +- macosx/Jack-Info.plist | 4 ++-- windows/Setup/jack.ci | 4 ++-- windows/jackaudioadapter.rc | 8 ++++---- windows/jackd.rc | 8 ++++---- windows/jackdummydriver.rc | 8 ++++---- windows/jackloopbackdriver.rc | 8 ++++---- windows/jacknetadapter.rc | 8 ++++---- windows/jacknetdriver.rc | 8 ++++---- windows/jacknetmanager.rc | 10 +++++----- windows/jacknetonedriver.rc | 10 +++++----- windows/jackportaudio.rc | 10 +++++----- windows/jackwinmme.rc | 10 +++++----- windows/libjack.rc | 10 +++++----- windows/libjackserver.rc | 10 +++++----- windows/resource.rc | 10 +++++----- wscript | 2 +- 20 files changed, 72 insertions(+), 68 deletions(-) diff --git a/ChangeLog b/ChangeLog index e40d91ab..906a557e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -34,6 +34,10 @@ Valerio Pilo Jackdmp changes log --------------------------- +2011-03-30 Stephane Letz + + * Version 1.9.8 started. + 2011-03-29 Stephane Letz * Synchronize JackWeakAPI.cpp with new APIs. diff --git a/README b/README index b9a0a533..beaa700b 100644 --- a/README +++ b/README @@ -20,7 +20,7 @@ The audible result of this mode is that if a client is not activated during one Linux version -------------- -The published version still uses fifos for server/client synchronization. The use of POSIX named semaphore is implemented but still a bit unstable. Sockets are used for server/client communications. The ALSA backend derived from jackd implementation is used. To build jackdmp, a "waf" (http://code.google.com/p/waf/) based compilation system is available. The code has to be compiled on a machine where ALSA and possibly freeboot (FFADO) headers and libraries are corrected installed. +The published version still uses fifos for server/client synchronization. The use of POSIX named semaphore is implemented but still a bit unstable. Sockets are used for server/client communications. The ALSA backend derived from jackd implementation is used. To build jackdmp, a "waf" (http://code.google.com/p/waf/) based compilation system is available. The code has to be compiled on a machine where ALSA and possibly freebob (FFADO) headers and libraries are corrected installed. In the top folder do : diff --git a/common/JackConstants.h b/common/JackConstants.h index 33d52cbd..c4c816da 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -24,7 +24,7 @@ #include "config.h" #endif -#define VERSION "1.9.7" +#define VERSION "1.9.8" #define BUFFER_SIZE_MAX 8192 @@ -71,7 +71,7 @@ #define SOCKET_TIME_OUT 5 // in sec #define DRIVER_OPEN_TIMEOUT 5 // in sec #define FREEWHEEL_DRIVER_TIMEOUT 10 // in sec -#define DRIVER_TIMEOUT_FACTOR 10 +#define DRIVER_TIMEOUT_FACTOR 10 #define NO_PORT 0xFFFE diff --git a/doxyfile b/doxyfile index 45b36fda..084836cd 100644 --- a/doxyfile +++ b/doxyfile @@ -31,7 +31,7 @@ PROJECT_NAME = "Jack2" # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 1.9.7 +PROJECT_NUMBER = 1.9.8 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/macosx/Jack-Info.plist b/macosx/Jack-Info.plist index 0d714313..ef6c3bfa 100644 --- a/macosx/Jack-Info.plist +++ b/macosx/Jack-Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable Jackservermp CFBundleGetInfoString - Jackdmp 1.9.7, @03-11 Paul Davis, Grame + Jackdmp 1.9.8, @03-11 Paul Davis, Grame CFBundleIdentifier com.grame.Jackmp CFBundleInfoDictionaryVersion @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.9.7 + 1.9.8 diff --git a/windows/Setup/jack.ci b/windows/Setup/jack.ci index 7ad82cb3..703e3354 100644 --- a/windows/Setup/jack.ci +++ b/windows/Setup/jack.ci @@ -1,9 +1,9 @@ <*project version = 4 civer = "Free v4.14.5" winver = "2.6/5.1.2600" > . - Jack_v1.9.7_setup.exe + Jack_v1.9.8_setup.exe - Jack v1.9.7 + Jack v1.9.8 Default - 2 diff --git a/windows/jackaudioadapter.rc b/windows/jackaudioadapter.rc index f9c115f3..2c29dee7 100644 --- a/windows/jackaudioadapter.rc +++ b/windows/jackaudioadapter.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,7,0 - PRODUCTVERSION 1,9,7,0 + FILEVERSION 1,9,8,0 + PRODUCTVERSION 1,9,8,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Audio Adapter for Windows\0" - VALUE "FileVersion", "1, 9, 7, 0\0" + VALUE "FileVersion", "1, 9, 8, 0\0" VALUE "InternalName", "audioadapter\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "audioadapter.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "audioadapter\0" - VALUE "ProductVersion", "1, 9, 7, 0\0" + VALUE "ProductVersion", "1, 9, 8, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackd.rc b/windows/jackd.rc index f61abc0e..0af38293 100644 --- a/windows/jackd.rc +++ b/windows/jackd.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,7,0 - PRODUCTVERSION 1,9,7,0 + FILEVERSION 1,9,8,0 + PRODUCTVERSION 1,9,8,0 FILEOS VOS_UNKNOWN FILETYPE VFT_APP BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack server for Windows\0" - VALUE "FileVersion", "1, 9, 7, 0\0" + VALUE "FileVersion", "1, 9, 8, 0\0" VALUE "InternalName", "jackd\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jackd.exe\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jackd\0" - VALUE "ProductVersion", "1, 9, 7, 0\0" + VALUE "ProductVersion", "1, 9, 8, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackdummydriver.rc b/windows/jackdummydriver.rc index da787e2e..881a3811 100644 --- a/windows/jackdummydriver.rc +++ b/windows/jackdummydriver.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,7,0 - PRODUCTVERSION 1,9,7,0 + FILEVERSION 1,9,8,0 + PRODUCTVERSION 1,9,8,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Dummy Driver for Windows\0" - VALUE "FileVersion", "1, 9, 7, 0\0" + VALUE "FileVersion", "1, 9, 8, 0\0" VALUE "InternalName", "jack_dummy\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_dummy.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_dummy\0" - VALUE "ProductVersion", "1, 9, 7, 0\0" + VALUE "ProductVersion", "1, 9, 8, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackloopbackdriver.rc b/windows/jackloopbackdriver.rc index b4d32b0e..878605cc 100644 --- a/windows/jackloopbackdriver.rc +++ b/windows/jackloopbackdriver.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,7,0 - PRODUCTVERSION 1,9,7,0 + FILEVERSION 1,9,8,0 + PRODUCTVERSION 1,9,8,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Loopback Driver for Windows\0" - VALUE "FileVersion", "1, 9, 7, 0\0" + VALUE "FileVersion", "1, 9, 8, 0\0" VALUE "InternalName", "jack_loopback\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_loopback.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_loopback\0" - VALUE "ProductVersion", "1, 9, 7, 0\0" + VALUE "ProductVersion", "1, 9, 8, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetadapter.rc b/windows/jacknetadapter.rc index 8142ce61..ba5c2ae8 100644 --- a/windows/jacknetadapter.rc +++ b/windows/jacknetadapter.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,7,0 - PRODUCTVERSION 1,9,7,0 + FILEVERSION 1,9,8,0 + PRODUCTVERSION 1,9,8,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Adapter for Windows\0" - VALUE "FileVersion", "1, 9, 7, 0\0" + VALUE "FileVersion", "1, 9, 8, 0\0" VALUE "InternalName", "netadapter\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "netadapter.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "netadapter\0" - VALUE "ProductVersion", "1, 9, 7, 0\0" + VALUE "ProductVersion", "1, 9, 8, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetdriver.rc b/windows/jacknetdriver.rc index edac06c3..9df605a3 100644 --- a/windows/jacknetdriver.rc +++ b/windows/jacknetdriver.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,7,0 - PRODUCTVERSION 1,9,7,0 + FILEVERSION 1,9,8,0 + PRODUCTVERSION 1,9,8,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Driver for Windows\0" - VALUE "FileVersion", "1, 9, 7, 0\0" + VALUE "FileVersion", "1, 9, 8, 0\0" VALUE "InternalName", "jack_netdriver\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_netdriver.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_netdriver\0" - VALUE "ProductVersion", "1, 9, 7, 0\0" + VALUE "ProductVersion", "1, 9, 8, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetmanager.rc b/windows/jacknetmanager.rc index f30dc040..cc0b6d82 100644 --- a/windows/jacknetmanager.rc +++ b/windows/jacknetmanager.rc @@ -1,4 +1,4 @@ -// Generated by ResEdit 1.4.3 +8// Generated by ResEdit 1.4.3 // Copyright (C) 2006-2008 // http://www.resedit.net @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,7,0 - PRODUCTVERSION 1,9,7,0 + FILEVERSION 1,9,8,0 + PRODUCTVERSION 1,9,8,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Manager for Windows\0" - VALUE "FileVersion", "1, 9, 7, 0\0" + VALUE "FileVersion", "1, 9, 8, 0\0" VALUE "InternalName", "netmanager\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "netmanager.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "netmanager\0" - VALUE "ProductVersion", "1, 9, 7, 0\0" + VALUE "ProductVersion", "1, 9, 8, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetonedriver.rc b/windows/jacknetonedriver.rc index 57518a2d..f08f9420 100644 --- a/windows/jacknetonedriver.rc +++ b/windows/jacknetonedriver.rc @@ -1,4 +1,4 @@ -// Generated by ResEdit 1.4.3 +8// Generated by ResEdit 1.4.3 // Copyright (C) 2006-2008 // http://www.resedit.net @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,7,0 - PRODUCTVERSION 1,9,7,0 + FILEVERSION 1,9,8,0 + PRODUCTVERSION 1,9,8,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp NetOne Driver for Windows\0" - VALUE "FileVersion", "1, 9, 7, 0\0" + VALUE "FileVersion", "1, 9, 8, 0\0" VALUE "InternalName", "jack_netonedriver\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_netonedriver.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_netonedriver\0" - VALUE "ProductVersion", "1, 9, 7, 0\0" + VALUE "ProductVersion", "1, 9, 8, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackportaudio.rc b/windows/jackportaudio.rc index d953dbd9..d228f39c 100644 --- a/windows/jackportaudio.rc +++ b/windows/jackportaudio.rc @@ -1,4 +1,4 @@ -// Generated by ResEdit 1.4.3 +8// Generated by ResEdit 1.4.3 // Copyright (C) 2006-2008 // http://www.resedit.net @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,7,0 - PRODUCTVERSION 1,9,7,0 + FILEVERSION 1,9,8,0 + PRODUCTVERSION 1,9,8,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp PortAudio Driver for Windows\0" - VALUE "FileVersion", "1, 9, 7, 0\0" + VALUE "FileVersion", "1, 9, 8, 0\0" VALUE "InternalName", "jack_portaudio\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_portaudio.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_portaudio\0" - VALUE "ProductVersion", "1, 9, 7, 0\0" + VALUE "ProductVersion", "1, 9, 8, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackwinmme.rc b/windows/jackwinmme.rc index dfe7bfe2..17c02de1 100644 --- a/windows/jackwinmme.rc +++ b/windows/jackwinmme.rc @@ -1,4 +1,4 @@ -// Generated by ResEdit 1.4.3 +8// Generated by ResEdit 1.4.3 // Copyright (C) 2006-2008 // http://www.resedit.net @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,7,0 - PRODUCTVERSION 1,9,7,0 + FILEVERSION 1,9,8,0 + PRODUCTVERSION 1,9,8,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp WinMME Driver for Windows\0" - VALUE "FileVersion", "1, 9, 7, 0\0" + VALUE "FileVersion", "1, 9, 8, 0\0" VALUE "InternalName", "jack_portaudio\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_winmme.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_winmme\0" - VALUE "ProductVersion", "1, 9, 7, 0\0" + VALUE "ProductVersion", "1, 9, 8, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/libjack.rc b/windows/libjack.rc index d1aaae1e..39631e34 100644 --- a/windows/libjack.rc +++ b/windows/libjack.rc @@ -1,4 +1,4 @@ -// Generated by ResEdit 1.4.3 +8// Generated by ResEdit 1.4.3 // Copyright (C) 2006-2008 // http://www.resedit.net @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,7,0 - PRODUCTVERSION 1,9,7,0 + FILEVERSION 1,9,8,0 + PRODUCTVERSION 1,9,8,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack client library for Windows\0" - VALUE "FileVersion", "1, 9, 7, 0\0" + VALUE "FileVersion", "1, 9, 8, 0\0" VALUE "InternalName", "libjack\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjack.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjack\0" - VALUE "ProductVersion", "1, 9, 7, 0\0" + VALUE "ProductVersion", "1, 9, 8, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/libjackserver.rc b/windows/libjackserver.rc index d0c02280..460e7db0 100644 --- a/windows/libjackserver.rc +++ b/windows/libjackserver.rc @@ -1,4 +1,4 @@ -// Generated by ResEdit 1.4.3 +8// Generated by ResEdit 1.4.3 // Copyright (C) 2006-2008 // http://www.resedit.net @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,7,0 - PRODUCTVERSION 1,9,7,0 + FILEVERSION 1,9,8,0 + PRODUCTVERSION 1,9,8,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack server library for Windows\0" - VALUE "FileVersion", "1, 9, 7, 0\0" + VALUE "FileVersion", "1, 9, 8, 0\0" VALUE "InternalName", "libjackserver\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjackserver.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjackserver\0" - VALUE "ProductVersion", "1, 9, 7, 0\0" + VALUE "ProductVersion", "1, 9, 8, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/resource.rc b/windows/resource.rc index 65851b24..902ea5ee 100644 --- a/windows/resource.rc +++ b/windows/resource.rc @@ -1,4 +1,4 @@ - +8 #include "resource_vc.h" #define APSTUDIO_READONLY_SYMBOLS @@ -14,8 +14,8 @@ LANGUAGE LANG_FRENCH, SUBLANG_FRENCH #ifndef _MAC VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,9,7,0 - PRODUCTVERSION 1,9,7,0 + FILEVERSION 1,9,8,0 + PRODUCTVERSION 1,9,8,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -33,14 +33,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp for Windows\0" - VALUE "FileVersion", "1, 9, 7, 0\0" + VALUE "FileVersion", "1, 9, 8, 0\0" VALUE "InternalName", "libjackmp\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjackmp.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjackmp\0" - VALUE "ProductVersion", "1, 9, 7, 0\0" + VALUE "ProductVersion", "1, 9, 8, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/wscript b/wscript index dedd86eb..b0a1ef0d 100644 --- a/wscript +++ b/wscript @@ -11,7 +11,7 @@ import Task import re import Logs -VERSION='1.9.7' +VERSION='1.9.8' APPNAME='jack' JACK_API_VERSION = '0.1.0' From ff7978b4a07503bd4f97a5fb4320030f6b2764c8 Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 30 Mar 2011 20:05:53 +0000 Subject: [PATCH 106/472] Cleanup. git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@4241 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetAPI.cpp | 311 +++++++++--------- common/JackNetInterface.cpp | 14 +- common/jack/net.h | 2 +- example-clients/netmaster.c | 10 +- example-clients/netslave.c | 28 +- .../iPhoneNet.xcodeproj/project.pbxproj | 4 - 6 files changed, 182 insertions(+), 187 deletions(-) diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index f83cab53..3f130771 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -29,9 +29,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. extern "C" { #endif - + // NetJack common API - + #define MASTER_NAME_SIZE 256 enum JackNetMode { @@ -40,7 +40,7 @@ extern "C" JackNormalMode = 'n', JackSlowMode = 's', }; - + enum JackNetEncoder { JackFloatEncoder = 0, @@ -49,11 +49,11 @@ extern "C" }; typedef struct { - + int audio_input; int audio_output; int midi_input; - int midi_output; + int midi_output; int mtu; int time_out; // in millisecond, -1 means in infinite int encoder; @@ -63,59 +63,59 @@ extern "C" } jack_slave_t; typedef struct { - + jack_nframes_t buffer_size; jack_nframes_t sample_rate; char master_name[MASTER_NAME_SIZE]; } jack_master_t; - + // NetJack slave API - + typedef struct _jack_net_slave jack_net_slave_t; - + typedef int (* JackNetSlaveProcessCallback) (jack_nframes_t buffer_size, - int audio_input, - float** audio_input_buffer, + int audio_input, + float** audio_input_buffer, int midi_input, void** midi_input_buffer, int audio_output, - float** audio_output_buffer, - int midi_output, - void** midi_output_buffer, + float** audio_output_buffer, + int midi_output, + void** midi_output_buffer, void* data); - + typedef int (*JackNetSlaveBufferSizeCallback) (jack_nframes_t nframes, void *arg); typedef int (*JackNetSlaveSampleRateCallback) (jack_nframes_t nframes, void *arg); typedef void (*JackNetSlaveShutdownCallback) (void* data); SERVER_EXPORT jack_net_slave_t* jack_net_slave_open(const char* ip, int port, const char* name, jack_slave_t* request, jack_master_t* result); SERVER_EXPORT int jack_net_slave_close(jack_net_slave_t* net); - + SERVER_EXPORT int jack_net_slave_activate(jack_net_slave_t* net); SERVER_EXPORT int jack_net_slave_deactivate(jack_net_slave_t* net); - + SERVER_EXPORT int jack_set_net_slave_process_callback(jack_net_slave_t * net, JackNetSlaveProcessCallback net_callback, void *arg); SERVER_EXPORT int jack_set_net_slave_buffer_size_callback(jack_net_slave_t *net, JackNetSlaveBufferSizeCallback bufsize_callback, void *arg); SERVER_EXPORT int jack_set_net_slave_sample_rate_callback(jack_net_slave_t *net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg); SERVER_EXPORT int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, JackNetSlaveShutdownCallback shutdown_callback, void *arg); - + // NetJack master API - + typedef struct _jack_net_master jack_net_master_t; - + SERVER_EXPORT jack_net_master_t* jack_net_master_open(const char* ip, int port, const char* name, jack_master_t* request, jack_slave_t* result); SERVER_EXPORT int jack_net_master_close(jack_net_master_t* net); - + SERVER_EXPORT int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer); SERVER_EXPORT int jack_net_master_send(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer); - + // NetJack adapter API - + typedef struct _jack_adapter jack_adapter_t; - + SERVER_EXPORT jack_adapter_t* jack_create_adapter(int input, int output, - jack_nframes_t host_buffer_size, + jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_sample_rate); @@ -124,7 +124,7 @@ extern "C" SERVER_EXPORT int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); SERVER_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); - + #ifdef __cplusplus } #endif @@ -133,19 +133,19 @@ namespace Jack { struct JackNetExtMaster : public JackNetMasterInterface { - + // Data buffers float** fAudioCaptureBuffer; float** fAudioPlaybackBuffer; - + JackMidiBuffer** fMidiCaptureBuffer; JackMidiBuffer** fMidiPlaybackBuffer; - + jack_master_t fRequest; - - JackNetExtMaster(const char* ip, - int port, - const char* name, + + JackNetExtMaster(const char* ip, + int port, + const char* name, jack_master_t* request) { fRunning = true; @@ -159,10 +159,10 @@ struct JackNetExtMaster : public JackNetMasterInterface { fMidiCaptureBuffer = NULL; fMidiPlaybackBuffer = NULL; } - + virtual ~JackNetExtMaster() {} - + int Open(jack_slave_t* result) { // Init socket API (win32) @@ -195,18 +195,18 @@ struct JackNetExtMaster : public JackNetMasterInterface { // Set a timeout on the multicast receive (the thread can now be cancelled) if (fSocket.SetTimeOut(2000000) == SOCKET_ERROR) fprintf(stderr, "Can't set timeout : %s\n", StrError(NET_ERROR_CODE)); - + //main loop, wait for data, deal with it and wait again //utility variables int attempt = 0; int rx_bytes = 0; - + do { session_params_t net_params; rx_bytes = fSocket.CatchHost(&net_params, sizeof(session_params_t), 0); SessionParamsNToH(&net_params, &fParams); - + if ((rx_bytes == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) { fprintf(stderr, "Error in receive : %s\n", StrError(NET_ERROR_CODE)); if (++attempt == 10) { @@ -214,11 +214,11 @@ struct JackNetExtMaster : public JackNetMasterInterface { goto error; } } - + if (rx_bytes == sizeof(session_params_t )) { - + switch (GetPacketType(&fParams)) { - + case SLAVE_AVAILABLE: if (MasterInit() == 0) { SessionParamsDisplay(&fParams); @@ -229,17 +229,17 @@ struct JackNetExtMaster : public JackNetMasterInterface { } jack_info ( "Waiting for a slave..." ); break; - + case KILL_MASTER: break; - + default: break; } } } while (fRunning); - + // Set result paramaters result->audio_input = fParams.fSendAudioChannels; result->audio_output = fParams.fReturnAudioChannels; @@ -248,12 +248,12 @@ struct JackNetExtMaster : public JackNetMasterInterface { result->mtu = fParams.fMtu; result->mode = fParams.fNetworkMode; return 0; - + error: fSocket.Close(); return -1; } - + int MasterInit() { // Check MASTER <==> SLAVE network protocol coherency @@ -268,10 +268,10 @@ struct JackNetExtMaster : public JackNetMasterInterface { fParams.fSampleEncoder = JackFloatEncoder; fParams.fPeriodSize = fRequest.buffer_size; fParams.fSampleRate = fRequest.sample_rate; - + // Close request socket fSocket.Close(); - + // Network slave init if (!JackNetMasterInterface::Init()) return -1; @@ -279,22 +279,22 @@ struct JackNetExtMaster : public JackNetMasterInterface { // Set global parameters if (!SetParams()) return -1; - + AllocPorts(); return 0; } - + int Close() { fSocket.Close(); FreePorts(); return 0; } - + void AllocPorts() { unsigned int port_index; - + // Set buffers if (fParams.fSendAudioChannels > 0) { fAudioCaptureBuffer = new float*[fParams.fSendAudioChannels]; @@ -303,7 +303,7 @@ struct JackNetExtMaster : public JackNetMasterInterface { fNetAudioCaptureBuffer->SetBuffer(port_index, fAudioCaptureBuffer[port_index]); } } - + if (fParams.fSendMidiChannels > 0) { fMidiCaptureBuffer = new JackMidiBuffer*[fParams.fSendMidiChannels]; for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) { @@ -311,15 +311,15 @@ struct JackNetExtMaster : public JackNetMasterInterface { fNetMidiCaptureBuffer->SetBuffer(port_index, fMidiCaptureBuffer[port_index]); } } - + if (fParams.fReturnAudioChannels > 0) { fAudioPlaybackBuffer = new float*[fParams.fReturnAudioChannels]; for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) { fAudioPlaybackBuffer[port_index] = new float[fParams.fPeriodSize]; fNetAudioPlaybackBuffer->SetBuffer(port_index, fAudioPlaybackBuffer[port_index]); - } + } } - + if (fParams.fReturnMidiChannels > 0) { fMidiPlaybackBuffer = new JackMidiBuffer*[fParams.fReturnMidiChannels]; for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) { @@ -328,18 +328,18 @@ struct JackNetExtMaster : public JackNetMasterInterface { } } } - + void FreePorts() { unsigned int port_index; - + if (fAudioPlaybackBuffer) { for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) delete[] fAudioPlaybackBuffer[port_index]; delete[] fAudioPlaybackBuffer; fAudioPlaybackBuffer = NULL; } - + if (fMidiPlaybackBuffer) { for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) delete[] (fMidiPlaybackBuffer[port_index]); @@ -353,7 +353,7 @@ struct JackNetExtMaster : public JackNetMasterInterface { delete[] fAudioCaptureBuffer; fAudioCaptureBuffer = NULL; } - + if (fMidiCaptureBuffer) { for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) delete[] fMidiCaptureBuffer[port_index]; @@ -361,98 +361,98 @@ struct JackNetExtMaster : public JackNetMasterInterface { fMidiCaptureBuffer = NULL; } } - + int Read(int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer) { try { assert((unsigned int)audio_input == fParams.fReturnAudioChannels); - + for (int port_index = 0; port_index < audio_input; port_index++) { fNetAudioPlaybackBuffer->SetBuffer(port_index, audio_input_buffer[port_index]); } - + for (int port_index = 0; port_index < midi_input; port_index++) { fNetMidiPlaybackBuffer->SetBuffer(port_index, ((JackMidiBuffer**)midi_input_buffer)[port_index]); } - + if (SyncRecv() == SOCKET_ERROR) return 0; DecodeSyncPacket(); return DataRecv(); - + } catch (JackNetException& e) { jack_error("Connection lost."); return -1; - } + } } int Write(int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer) { try { assert((unsigned int)audio_output == fParams.fSendAudioChannels); - + for (int port_index = 0; port_index < audio_output; port_index++) { fNetAudioCaptureBuffer->SetBuffer(port_index, audio_output_buffer[port_index]); } - + for (int port_index = 0; port_index < midi_output; port_index++) { fNetMidiCaptureBuffer->SetBuffer(port_index, ((JackMidiBuffer**)midi_output_buffer)[port_index]); } - + EncodeSyncPacket(); - + if (SyncSend() == SOCKET_ERROR) return SOCKET_ERROR; return DataSend(); - + } catch (JackNetException& e) { jack_error("Connection lost."); return -1; - } + } } - + // Transport void EncodeTransportData() {} - + void DecodeTransportData() {} - + }; struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterface { - + JackThread fThread; - + JackNetSlaveProcessCallback fProcessCallback; void* fProcessArg; - + JackNetSlaveShutdownCallback fShutdownCallback; void* fShutdownArg; - + JackNetSlaveBufferSizeCallback fBufferSizeCallback; void* fBufferSizeArg; - + JackNetSlaveSampleRateCallback fSampleRateCallback; void* fSampleRateArg; - + //sample buffers float** fAudioCaptureBuffer; float** fAudioPlaybackBuffer; - + JackMidiBuffer** fMidiCaptureBuffer; JackMidiBuffer** fMidiPlaybackBuffer; - + int fConnectTimeOut; - - JackNetExtSlave(const char* ip, - int port, - const char* name, + + JackNetExtSlave(const char* ip, + int port, + const char* name, jack_slave_t* request) :fThread(this), - fProcessCallback(NULL),fProcessArg(NULL), + fProcessCallback(NULL),fProcessArg(NULL), fShutdownCallback(NULL), fShutdownArg(NULL), fBufferSizeCallback(NULL), fBufferSizeArg(NULL), fSampleRateCallback(NULL), fSampleRateArg(NULL), @@ -460,11 +460,11 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf fMidiCaptureBuffer(NULL), fMidiPlaybackBuffer(NULL) { char host_name[JACK_CLIENT_NAME_SIZE]; - + // Request parameters assert(strlen(ip) < 32); strcpy(fMulticastIP, ip); - + fParams.fMtu = request->mtu; fParams.fTransportSync = 0; fParams.fSendAudioChannels = request->audio_input; @@ -475,66 +475,66 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf fParams.fSampleEncoder = request->encoder; fParams.fKBps = request->kbps; fConnectTimeOut = request->time_out; - + // Create name with hostname and client name GetHostName(host_name, JACK_CLIENT_NAME_SIZE); snprintf(fParams.fName, JACK_CLIENT_NAME_SIZE, "%s_%s", host_name, name); fSocket.GetName(fParams.fSlaveNetName); - + // Set the socket parameters fSocket.SetPort(port); fSocket.SetAddress(fMulticastIP, port); } - + virtual ~JackNetExtSlave() {} - + int Open(jack_master_t* result) { // Init network connection - if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) + if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) return -1; - + // Then set global parameters if (!SetParams()) return -1; - + // Set result if (result != NULL) { result->buffer_size = fParams.fPeriodSize; result->sample_rate = fParams.fSampleRate; strcpy(result->master_name, fParams.fMasterNetName); } - + AllocPorts(); return 0; } - + int Restart() { // If shutdown cb is set, then call it if (fShutdownCallback) fShutdownCallback(fShutdownArg); - + // Init complete network connection if (!JackNetSlaveInterface::Init()) return -1; - + // Then set global parameters if (!SetParams()) return -1; - + // We need to notify possibly new buffer size and sample rate (see Execute) - if (fBufferSizeCallback) + if (fBufferSizeCallback) fBufferSizeCallback(fParams.fPeriodSize, fBufferSizeArg); - - if (fSampleRateCallback) + + if (fSampleRateCallback) fSampleRateCallback(fParams.fSampleRate, fSampleRateArg); - + AllocPorts(); return 0; } - + int Close() { fSocket.Close(); @@ -545,44 +545,44 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf void AllocPorts() { unsigned int port_index; - + // Set buffers fAudioCaptureBuffer = new float*[fParams.fSendAudioChannels]; for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) { fAudioCaptureBuffer[port_index] = new float[fParams.fPeriodSize]; fNetAudioCaptureBuffer->SetBuffer(port_index, fAudioCaptureBuffer[port_index]); } - + fMidiCaptureBuffer = new JackMidiBuffer*[fParams.fSendMidiChannels]; for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) { fMidiCaptureBuffer[port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize]; fNetMidiCaptureBuffer->SetBuffer(port_index, fMidiCaptureBuffer[port_index]); } - + fAudioPlaybackBuffer = new float*[fParams.fReturnAudioChannels]; for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) { fAudioPlaybackBuffer[port_index] = new float[fParams.fPeriodSize]; fNetAudioPlaybackBuffer->SetBuffer(port_index, fAudioPlaybackBuffer[port_index]); - } - + } + fMidiPlaybackBuffer = new JackMidiBuffer*[fParams.fReturnMidiChannels]; for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) { fMidiPlaybackBuffer[port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize]; fNetMidiPlaybackBuffer->SetBuffer(port_index, fMidiPlaybackBuffer[port_index]); } } - + void FreePorts() { unsigned int port_index; - + if (fAudioCaptureBuffer) { for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) delete[] fAudioCaptureBuffer[port_index]; delete[] fAudioCaptureBuffer; fAudioCaptureBuffer = NULL; } - + if (fMidiCaptureBuffer) { for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) delete[] (fMidiCaptureBuffer[port_index]); @@ -596,7 +596,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf delete[] fAudioPlaybackBuffer; fAudioPlaybackBuffer = NULL; } - + if (fMidiPlaybackBuffer) { for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) delete[] fMidiPlaybackBuffer[port_index]; @@ -604,21 +604,21 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf fMidiPlaybackBuffer = NULL; } } - + // Transport void EncodeTransportData() {} - + void DecodeTransportData() {} - - bool Init() + + bool Init() { // Will do "something" on OSX only... - fThread.SetParams(float(fParams.fPeriodSize) / float(fParams.fSampleRate) * 1000000, 100 * 1000, 500 * 1000); + fThread.SetParams(float(fParams.fPeriodSize) / float(fParams.fSampleRate) * 1000000, 100 * 1000, 500 * 1000); return (fThread.AcquireRealTime(80) == 0); // TODO: get a value from the server } - + bool Execute() { try { @@ -629,7 +629,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf } return false; } catch (JackNetException& e) { - + // Otherwise just restart... e.PrintMessage(); fThread.DropRealTime(); @@ -644,7 +644,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf } } } - + int Read() { // Don't return -1 in case of sync recv failure @@ -659,31 +659,31 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf int Write() { EncodeSyncPacket(); - + if (SyncSend() == SOCKET_ERROR) return SOCKET_ERROR; return DataSend(); } - - int Process() + + int Process() { // Read data from the network // in case of fatal network error, stop the process if (Read() == SOCKET_ERROR) return SOCKET_ERROR; - - fProcessCallback(fParams.fPeriodSize, - fParams.fSendAudioChannels, - fAudioCaptureBuffer, + + fProcessCallback(fParams.fPeriodSize, + fParams.fSendAudioChannels, + fAudioCaptureBuffer, fParams.fSendMidiChannels, - (void**)fMidiCaptureBuffer, + (void**)fMidiCaptureBuffer, fParams.fReturnAudioChannels, - fAudioPlaybackBuffer, + fAudioPlaybackBuffer, fParams.fReturnMidiChannels, - (void**)fMidiPlaybackBuffer, - fProcessArg); - + (void**)fMidiPlaybackBuffer, + fProcessArg); + // Then write data to network // in case of failure, stop process if (Write() == SOCKET_ERROR) @@ -691,14 +691,14 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf return 0; } - + int Start() { - // Finish connection.. + // Finish connection.. if (!JackNetSlaveInterface::InitRendering()) { return -1; } - + return (fProcessCallback == 0) ? -1 : fThread.StartSync(); } @@ -706,7 +706,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf { return (fProcessCallback == 0) ? -1 : fThread.Kill(); } - + // Callback int SetProcessCallback(JackNetSlaveProcessCallback net_callback, void *arg) { @@ -729,7 +729,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf return 0; } } - + int SetBufferSizeCallback(JackNetSlaveBufferSizeCallback bufsize_callback, void *arg) { if (fThread.GetStatus() == JackThread::kRunning) { @@ -740,7 +740,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf return 0; } } - + int SetSampleRateCallback(JackNetSlaveSampleRateCallback samplerate_callback, void *arg) { if (fThread.GetStatus() == JackThread::kRunning) { @@ -756,9 +756,8 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf struct JackNetAdapter : public JackAudioAdapterInterface { - JackNetAdapter(int input, int output, - jack_nframes_t host_buffer_size, + jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_sample_rate) @@ -768,21 +767,21 @@ struct JackNetAdapter : public JackAudioAdapterInterface { fPlaybackChannels = output; Create(); } - + void Create() { //ringbuffers - + if (fCaptureChannels > 0) fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; if (fPlaybackChannels > 0) fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; - + if (fAdaptative) { AdaptRingBufferSize(); jack_info("Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize); } else { - if (fRingbufferCurSize > DEFAULT_RB_SIZE) + if (fRingbufferCurSize > DEFAULT_RB_SIZE) fRingbufferCurSize = DEFAULT_RB_SIZE; jack_info("Fixed ringbuffer size = %d frames", fRingbufferCurSize); } @@ -806,7 +805,7 @@ struct JackNetAdapter : public JackAudioAdapterInterface { { Destroy(); } - + void Flush() { for (int i = 0; i < fCaptureChannels; i++ ) { @@ -816,7 +815,7 @@ struct JackNetAdapter : public JackAudioAdapterInterface { fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize); } } - + }; @@ -826,7 +825,7 @@ using namespace Jack; SERVER_EXPORT jack_net_slave_t* jack_net_slave_open(const char* ip, int port, const char* name, jack_slave_t* request, jack_master_t* result) { - JackNetExtSlave* slave = new JackNetExtSlave(ip, port, name, request); + JackNetExtSlave* slave = new JackNetExtSlave(ip, port, name, request); if (slave->Open(result) == 0) { return (jack_net_slave_t*)slave; } else { @@ -842,7 +841,7 @@ SERVER_EXPORT int jack_net_slave_close(jack_net_slave_t* net) delete slave; return 0; } - + SERVER_EXPORT int jack_set_net_slave_process_callback(jack_net_slave_t* net, JackNetSlaveProcessCallback net_callback, void *arg) { JackNetExtSlave* slave = (JackNetExtSlave*)net; @@ -883,7 +882,7 @@ SERVER_EXPORT int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, Ja SERVER_EXPORT jack_net_master_t* jack_net_master_open(const char* ip, int port, const char* name, jack_master_t* request, jack_slave_t* result) { - JackNetExtMaster* master = new JackNetExtMaster(ip, port, name, request); + JackNetExtMaster* master = new JackNetExtMaster(ip, port, name, request); if (master->Open(result) == 0) { return (jack_net_master_t*)master; } else { @@ -914,7 +913,7 @@ SERVER_EXPORT int jack_net_master_send(jack_net_master_t* net, int audio_output, // Adapter API SERVER_EXPORT jack_adapter_t* jack_create_adapter(int input, int output, - jack_nframes_t host_buffer_size, + jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_sample_rate) @@ -953,14 +952,14 @@ static void jack_format_and_log(int level, const char *prefix, const char *fmt, { char buffer[300]; size_t len; - + if (prefix != NULL) { len = strlen(prefix); memcpy(buffer, prefix, len); } else { len = 0; } - + vsnprintf(buffer + len, sizeof(buffer) - len, fmt, ap); printf(buffer); printf("\n"); diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 1eb66ca1..65562ceb 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -250,16 +250,16 @@ namespace Jack switch (fParams.fSampleEncoder) { case JackFloatEncoder: - fNetAudioCaptureBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); + fNetAudioCaptureBuffer = new NetFloatAudioBuffer(&fParams, fParams.fSendAudioChannels, fTxData); break; case JackIntEncoder: - fNetAudioCaptureBuffer = new NetIntAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData ); + fNetAudioCaptureBuffer = new NetIntAudioBuffer(&fParams, fParams.fSendAudioChannels, fTxData); break; case JackCeltEncoder: #ifdef CELT - fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData, fParams.fKBps ); + fNetAudioCaptureBuffer = new NetCeltAudioBuffer(&fParams, fParams.fSendAudioChannels, fTxData, fParams.fKBps); #endif break; } @@ -270,16 +270,16 @@ namespace Jack switch (fParams.fSampleEncoder) { case JackFloatEncoder: - fNetAudioPlaybackBuffer = new NetFloatAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); + fNetAudioPlaybackBuffer = new NetFloatAudioBuffer(&fParams, fParams.fReturnAudioChannels, fRxData); break; case JackIntEncoder: - fNetAudioPlaybackBuffer = new NetIntAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData ); + fNetAudioPlaybackBuffer = new NetIntAudioBuffer(&fParams, fParams.fReturnAudioChannels, fRxData); break; case JackCeltEncoder: #ifdef CELT - fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData, fParams.fKBps ); + fNetAudioPlaybackBuffer = new NetCeltAudioBuffer(&fParams, fParams.fReturnAudioChannels, fRxData, fParams.fKBps); #endif break; } @@ -552,7 +552,7 @@ namespace Jack fRxHeader.fCycle = rx_head->fCycle; fRxHeader.fSubCycle = rx_head->fSubCycle; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; - fNetAudioPlaybackBuffer->RenderFromNetwork (rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE); + fNetAudioPlaybackBuffer->RenderFromNetwork(rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE); // Last audio packet is received, so finish rendering... if (fRxHeader.fIsLastPckt) fNetAudioPlaybackBuffer->RenderToJackPorts(); diff --git a/common/jack/net.h b/common/jack/net.h index 8a5894c7..54de2412 100644 --- a/common/jack/net.h +++ b/common/jack/net.h @@ -55,7 +55,7 @@ typedef struct { int audio_output; // to master or from slave int midi_input; // from master or to slave int midi_output; // to master or from slave - int mtu; // Network Maximum Transmission Unit + int mtu; // network Maximum Transmission Unit int time_out; // in second, -1 means in infinite int encoder; // Encoder type (one of JackNetEncoder) int kbps; // KB per second for CELT encoder diff --git a/example-clients/netmaster.c b/example-clients/netmaster.c index 3ca00900..c00fbb35 100644 --- a/example-clients/netmaster.c +++ b/example-clients/netmaster.c @@ -45,11 +45,11 @@ static void usage () { fprintf (stderr, "\n" -"usage: jack_net_master \n" -" [ -b buffer size (default = %d) ]\n" -" [ -r sample rate (default = %d) ]\n" -" [ -a hostname (default = %s) ]\n" -" [ -p port (default = %d) ]\n", BUFFER_SIZE, SAMPLE_RATE, DEFAULT_MULTICAST_IP, DEFAULT_PORT); + "usage: jack_net_master \n" + " [ -b buffer size (default = %d) ]\n" + " [ -r sample rate (default = %d) ]\n" + " [ -a hostname (default = %s) ]\n" + " [ -p port (default = %d) ]\n", BUFFER_SIZE, SAMPLE_RATE, DEFAULT_MULTICAST_IP, DEFAULT_PORT); } int diff --git a/example-clients/netslave.c b/example-clients/netslave.c index 6390743d..446d1561 100644 --- a/example-clients/netslave.c +++ b/example-clients/netslave.c @@ -42,11 +42,11 @@ static void usage () { fprintf (stderr, "\n" -"usage: jack_net_slave \n" -" [ -C capture channels (default = 2)]\n" -" [ -P playback channels (default = 2) ]\n" -" [ -a hostname (default = %s) ]\n" -" [ -p port (default = %d)]\n", DEFAULT_MULTICAST_IP, DEFAULT_PORT); + "usage: jack_net_slave \n" + " [ -C capture channels (default = 2)]\n" + " [ -P playback channels (default = 2) ]\n" + " [ -a hostname (default = %s) ]\n" + " [ -p port (default = %d)]\n", DEFAULT_MULTICAST_IP, DEFAULT_PORT); } static void net_shutdown(void* data) @@ -55,15 +55,15 @@ static void net_shutdown(void* data) } static int net_process(jack_nframes_t buffer_size, - int audio_input, - float** audio_input_buffer, - int midi_input, - void** midi_input_buffer, - int audio_output, - float** audio_output_buffer, - int midi_output, - void** midi_output_buffer, - void* data) + int audio_input, + float** audio_input_buffer, + int midi_input, + void** midi_input_buffer, + int audio_output, + float** audio_output_buffer, + int midi_output, + void** midi_output_buffer, + void* data) { int i; diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj index 4b976838..eff06935 100755 --- a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -85,7 +85,6 @@ 4BCB37C8112D647C008C7BC1 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 4BCB37C9112D647C008C7BC1 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 4BCB37CA112D647C008C7BC1 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; - 4BCB37D6112D64B4008C7BC1 /* HardwareClock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCB37D5112D64B4008C7BC1 /* HardwareClock.cpp */; }; 4BCB37D9112D64D8008C7BC1 /* iphone-faust.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */; }; 4BCF75DA10BC2FD90082C526 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 4BCF75DC10BC2FD90082C526 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; }; @@ -181,7 +180,6 @@ 4BBDC8F90F5420C000465F9C /* freeverb.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = freeverb.mm; sourceTree = SOURCE_ROOT; }; 4BC9C1D31135AA1800D22670 /* iPhoneNetMasterAppl-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "iPhoneNetMasterAppl-Info.plist"; sourceTree = ""; }; 4BCB37CE112D647C008C7BC1 /* iPhoneFaust.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaust.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 4BCB37D5112D64B4008C7BC1 /* HardwareClock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HardwareClock.cpp; sourceTree = SOURCE_ROOT; }; 4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "iphone-faust.mm"; sourceTree = SOURCE_ROOT; }; 4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneThruNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BCF75F610BC30140082C526 /* audio_thru.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = audio_thru.mm; sourceTree = SOURCE_ROOT; }; @@ -305,7 +303,6 @@ isa = PBXGroup; children = ( 4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */, - 4BCB37D5112D64B4008C7BC1 /* HardwareClock.cpp */, 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */, 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */, 29B97315FDCFA39411CA2CEA /* Other Sources */, @@ -703,7 +700,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4BCB37D6112D64B4008C7BC1 /* HardwareClock.cpp in Sources */, 4BCB37D9112D64D8008C7BC1 /* iphone-faust.mm in Sources */, 4BF15E2A11356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, 4BF15F7D11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */, From ceb7c50ec4240ba1bbb333b4c3e1656a8dcd2a81 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Wed, 30 Mar 2011 23:40:47 +0200 Subject: [PATCH 107/472] Correct virtual sources/destinations handling. --- macosx/coremidi/JackCoreMidiDriver.cpp | 101 +++++++++--------- .../coremidi/JackCoreMidiVirtualInputPort.cpp | 2 +- .../JackCoreMidiVirtualOutputPort.cpp | 2 +- 3 files changed, 53 insertions(+), 52 deletions(-) diff --git a/macosx/coremidi/JackCoreMidiDriver.cpp b/macosx/coremidi/JackCoreMidiDriver.cpp index acdd5136..234f2afe 100644 --- a/macosx/coremidi/JackCoreMidiDriver.cpp +++ b/macosx/coremidi/JackCoreMidiDriver.cpp @@ -279,56 +279,6 @@ JackCoreMidiDriver::Open(bool capturing, bool playing, int in_channels, } char *client_name = fClientControl.fName; - // Allocate and connect virtual inputs - if (in_channels) { - try { - virtual_input_ports = - new JackCoreMidiVirtualInputPort*[in_channels]; - } catch (std::exception e) { - jack_error("JackCoreMidiDriver::Open - while creating virtual " - "input port array: %s", e.what()); - goto destroy_client; - } - for (vi_count = 0; vi_count < in_channels; vi_count++) { - try { - virtual_input_ports[vi_count] = - new JackCoreMidiVirtualInputPort(fAliasName, client_name, - capture_driver_name, - vi_count, client, - time_ratio); - } catch (std::exception e) { - jack_error("JackCoreMidiDriver::Open - while creating virtual " - "input port: %s", e.what()); - goto destroy_virtual_input_ports; - } - } - } - - // Allocate and connect virtual outputs - if (out_channels) { - try { - virtual_output_ports = - new JackCoreMidiVirtualOutputPort*[out_channels]; - } catch (std::exception e) { - jack_error("JackCoreMidiDriver::Open - while creating virtual " - "output port array: %s", e.what()); - goto destroy_virtual_input_ports; - } - for (vo_count = 0; vo_count < out_channels; vo_count++) { - try { - virtual_output_ports[vo_count] = - new JackCoreMidiVirtualOutputPort(fAliasName, client_name, - playback_driver_name, - vo_count, client, - time_ratio); - } catch (std::exception e) { - jack_error("JackCoreMidiDriver::Open - while creating virtual " - "output port: %s", e.what()); - goto destroy_virtual_output_ports; - } - } - } - // Allocate and connect physical inputs potential_pi_count = MIDIGetNumberOfSources(); if (potential_pi_count) { @@ -397,6 +347,57 @@ JackCoreMidiDriver::Open(bool capturing, bool playing, int in_channels, } } + // Allocate and connect virtual inputs + if (in_channels) { + try { + virtual_input_ports = + new JackCoreMidiVirtualInputPort*[in_channels]; + } catch (std::exception e) { + jack_error("JackCoreMidiDriver::Open - while creating virtual " + "input port array: %s", e.what()); + goto destroy_client; + } + for (vi_count = 0; vi_count < in_channels; vi_count++) { + try { + virtual_input_ports[vi_count] = + new JackCoreMidiVirtualInputPort(fAliasName, client_name, + capture_driver_name, + vi_count + pi_count, client, + time_ratio); + } catch (std::exception e) { + jack_error("JackCoreMidiDriver::Open - while creating virtual " + "input port: %s", e.what()); + goto destroy_virtual_input_ports; + } + } + } + + // Allocate and connect virtual outputs + if (out_channels) { + try { + virtual_output_ports = + new JackCoreMidiVirtualOutputPort*[out_channels]; + } catch (std::exception e) { + jack_error("JackCoreMidiDriver::Open - while creating virtual " + "output port array: %s", e.what()); + goto destroy_virtual_input_ports; + } + for (vo_count = 0; vo_count < out_channels; vo_count++) { + try { + virtual_output_ports[vo_count] = + new JackCoreMidiVirtualOutputPort(fAliasName, client_name, + playback_driver_name, + vo_count + po_count, client, + time_ratio); + } catch (std::exception e) { + jack_error("JackCoreMidiDriver::Open - while creating virtual " + "output port: %s", e.what()); + goto destroy_virtual_output_ports; + } + } + } + + if (! (pi_count || po_count || in_channels || out_channels)) { jack_error("JackCoreMidiDriver::Open - no CoreMIDI inputs or outputs " "found, and no virtual ports allocated."); diff --git a/macosx/coremidi/JackCoreMidiVirtualInputPort.cpp b/macosx/coremidi/JackCoreMidiVirtualInputPort.cpp index 42d9b52f..874a644d 100644 --- a/macosx/coremidi/JackCoreMidiVirtualInputPort.cpp +++ b/macosx/coremidi/JackCoreMidiVirtualInputPort.cpp @@ -49,7 +49,7 @@ JackCoreMidiVirtualInputPort(const char *alias_name, const char *client_name, JackCoreMidiInputPort(time_ratio, max_bytes, max_messages) { std::stringstream stream; - stream << "JackMidi" << (index + 1); + stream << "virtual" << (index + 1); CFStringRef name = CFStringCreateWithCString(0, stream.str().c_str(), CFStringGetSystemEncoding()); if (! name) { diff --git a/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp b/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp index 88b46d06..0d8bc173 100644 --- a/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp @@ -35,7 +35,7 @@ JackCoreMidiVirtualOutputPort(const char *alias_name, const char *client_name, max_messages) { std::stringstream stream; - stream << "JackMidi" << (index + 1); + stream << "virtual" << (index + 1); CFStringRef name = CFStringCreateWithCString(0, stream.str().c_str(), CFStringGetSystemEncoding()); if (! name) { From 9280aa834e29d38d53ed6d6638de4ba20b42639d Mon Sep 17 00:00:00 2001 From: sletz Date: Thu, 31 Mar 2011 08:49:31 +0000 Subject: [PATCH 108/472] Typos on Windows. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4242 0c269be4-1314-0410-8aa9-9f06e86f4224 --- windows/jacknetmanager.rc | 2 +- windows/jacknetonedriver.rc | 2 +- windows/jackportaudio.rc | 2 +- windows/jackwinmme.rc | 2 +- windows/libjack.rc | 2 +- windows/libjackserver.rc | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/windows/jacknetmanager.rc b/windows/jacknetmanager.rc index cc0b6d82..2691e8fe 100644 --- a/windows/jacknetmanager.rc +++ b/windows/jacknetmanager.rc @@ -1,4 +1,4 @@ -8// Generated by ResEdit 1.4.3 +// Generated by ResEdit 1.4.3 // Copyright (C) 2006-2008 // http://www.resedit.net diff --git a/windows/jacknetonedriver.rc b/windows/jacknetonedriver.rc index f08f9420..6c57a212 100644 --- a/windows/jacknetonedriver.rc +++ b/windows/jacknetonedriver.rc @@ -1,4 +1,4 @@ -8// Generated by ResEdit 1.4.3 +// Generated by ResEdit 1.4.3 // Copyright (C) 2006-2008 // http://www.resedit.net diff --git a/windows/jackportaudio.rc b/windows/jackportaudio.rc index d228f39c..991c4bd8 100644 --- a/windows/jackportaudio.rc +++ b/windows/jackportaudio.rc @@ -1,4 +1,4 @@ -8// Generated by ResEdit 1.4.3 +// Generated by ResEdit 1.4.3 // Copyright (C) 2006-2008 // http://www.resedit.net diff --git a/windows/jackwinmme.rc b/windows/jackwinmme.rc index 17c02de1..8ee884b7 100644 --- a/windows/jackwinmme.rc +++ b/windows/jackwinmme.rc @@ -1,4 +1,4 @@ -8// Generated by ResEdit 1.4.3 +// Generated by ResEdit 1.4.3 // Copyright (C) 2006-2008 // http://www.resedit.net diff --git a/windows/libjack.rc b/windows/libjack.rc index 39631e34..753aeb8e 100644 --- a/windows/libjack.rc +++ b/windows/libjack.rc @@ -1,4 +1,4 @@ -8// Generated by ResEdit 1.4.3 +// Generated by ResEdit 1.4.3 // Copyright (C) 2006-2008 // http://www.resedit.net diff --git a/windows/libjackserver.rc b/windows/libjackserver.rc index 460e7db0..b930ccc7 100644 --- a/windows/libjackserver.rc +++ b/windows/libjackserver.rc @@ -1,4 +1,4 @@ -8// Generated by ResEdit 1.4.3 +// Generated by ResEdit 1.4.3 // Copyright (C) 2006-2008 // http://www.resedit.net From 69c59f4423ce79f41444479f5dde8dbc8ba977db Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Thu, 31 Mar 2011 11:34:58 +0200 Subject: [PATCH 109/472] Renaming for Windows compatibility. --- common/JackMidiWriteQueue.h | 4 ++-- linux/alsarawmidi/JackALSARawMidiSendQueue.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/common/JackMidiWriteQueue.h b/common/JackMidiWriteQueue.h index a39776c9..f21a58ff 100644 --- a/common/JackMidiWriteQueue.h +++ b/common/JackMidiWriteQueue.h @@ -37,7 +37,7 @@ namespace Jack { BUFFER_FULL, BUFFER_TOO_SMALL, EVENT_EARLY, - ERROR, + EN_ERROR, OK }; @@ -54,7 +54,7 @@ namespace Jack { * if the write queue isn't able to accept the event right now, * `BUFFER_TOO_SMALL` if this write queue will never be able to accept * the event because the event is too large, `EVENT_EARLY` if this - * queue cannot schedule events ahead of time, and `ERROR` if an error + * queue cannot schedule events ahead of time, and `EN_ERROR` if an error * occurs that cannot be specified by another return code. */ diff --git a/linux/alsarawmidi/JackALSARawMidiSendQueue.cpp b/linux/alsarawmidi/JackALSARawMidiSendQueue.cpp index 5f314263..80a11b56 100755 --- a/linux/alsarawmidi/JackALSARawMidiSendQueue.cpp +++ b/linux/alsarawmidi/JackALSARawMidiSendQueue.cpp @@ -30,7 +30,7 @@ JackALSARawMidiSendQueue::EnqueueEvent(jack_nframes_t time, size_t size, } jack_error("JackALSARawMidiSendQueue::EnqueueEvent - snd_rawmidi_write: " "%s", snd_strerror(result)); - return ERROR; + return EN_ERROR; } bool From 07f7895991345ac8a0b66d271052d9c145e8cb6f Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Thu, 31 Mar 2011 13:16:19 +0200 Subject: [PATCH 110/472] New driver compiles. --- windows/jack_winmme.cbp | 11 +++++ windows/jackd.workspace | 4 +- windows/libjackserver.cbp | 2 - windows/portaudio/JackPortAudioDriver.cpp | 2 +- windows/winmme/JackWinMMEInputPort.cpp | 33 +++++++------- windows/winmme/JackWinMMEInputPort.h | 4 +- windows/winmme/JackWinMMEOutputPort.cpp | 52 +++++++++++++++++------ windows/winmme/JackWinMMEOutputPort.h | 16 +++++-- 8 files changed, 85 insertions(+), 39 deletions(-) diff --git a/windows/jack_winmme.cbp b/windows/jack_winmme.cbp index 2c6d8bbe..7de61fa8 100644 --- a/windows/jack_winmme.cbp +++ b/windows/jack_winmme.cbp @@ -102,10 +102,21 @@
+ + + + + + + + + + + diff --git a/windows/jackd.workspace b/windows/jackd.workspace index 05f5b3d1..4384140e 100644 --- a/windows/jackd.workspace +++ b/windows/jackd.workspace @@ -5,7 +5,7 @@ - + @@ -57,6 +57,6 @@ - + diff --git a/windows/libjackserver.cbp b/windows/libjackserver.cbp index e4db2136..89cd2dd3 100644 --- a/windows/libjackserver.cbp +++ b/windows/libjackserver.cbp @@ -154,8 +154,6 @@ - - diff --git a/windows/portaudio/JackPortAudioDriver.cpp b/windows/portaudio/JackPortAudioDriver.cpp index 790bcda1..f7611add 100644 --- a/windows/portaudio/JackPortAudioDriver.cpp +++ b/windows/portaudio/JackPortAudioDriver.cpp @@ -248,7 +248,7 @@ error: } else { JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails // PortAudio specific - UpdateLatencies(); + JackAudioDriver::UpdateLatencies(); return 0; } } diff --git a/windows/winmme/JackWinMMEInputPort.cpp b/windows/winmme/JackWinMMEInputPort.cpp index c9b9cbb1..0adf3bec 100644 --- a/windows/winmme/JackWinMMEInputPort.cpp +++ b/windows/winmme/JackWinMMEInputPort.cpp @@ -24,6 +24,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackError.h" #include "JackMidiUtil.h" #include "JackWinMMEInputPort.h" +#include "JackMidiWriteQueue.h" using Jack::JackWinMMEInputPort; @@ -54,7 +55,7 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, std::auto_ptr write_queue_ptr(write_queue); sysex_buffer = new jack_midi_data_t[max_bytes]; char error_message[MAXERRORLENGTH]; - MMRESULT result = midiInOpen(&handle, index, HandleMidiInputEvent, this, + MMRESULT result = midiInOpen(&handle, index, (DWORD)HandleMidiInputEvent, (DWORD)this, CALLBACK_FUNCTION | MIDI_IO_STATUS); if (result != MMSYSERR_NOERROR) { GetErrorString(result, error_message); @@ -64,7 +65,7 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, sysex_header.dwBytesRecorded = 0; sysex_header.dwFlags = 0; sysex_header.dwUser = 0; - sysex_header.lpData = (((LPBYTE) sysex_header) + sizeof(MIDIHDR)); + sysex_header.lpData = (LPSTR)(((LPBYTE) &sysex_header) + sizeof(MIDIHDR)); sysex_header.lpNext = 0; result = midiInPrepareHeader(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { @@ -84,7 +85,7 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, return; unprepare_header: - result = midiInUnprepareHeader(handle, sysex_header, sizeof(MIDIHDR)); + result = midiInUnprepareHeader(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { WriteError("JackWinMMEInputPort [constructor]", "midiInUnprepareHeader", result); @@ -106,7 +107,7 @@ JackWinMMEInputPort::~JackWinMMEInputPort() if (result != MMSYSERR_NOERROR) { WriteError("JackWinMMEInputPort [destructor]", "midiInReset", result); } - result = midiInUnprepareHeader(handle, sysex_header, sizeof(MIDIHDR)); + result = midiInUnprepareHeader(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { WriteError("JackWinMMEInputPort [destructor]", "midiInUnprepareHeader", result); @@ -128,12 +129,12 @@ JackWinMMEInputPort::EnqueueMessage(jack_nframes_t time, size_t length, case JackMidiWriteQueue::BUFFER_FULL: jack_error("JackWinMMEInputPort::EnqueueMessage - The thread queue " "cannot currently accept a %d-byte event. Dropping event.", - size); + length); break; case JackMidiWriteQueue::BUFFER_TOO_SMALL: jack_error("JackWinMMEInputPort::EnqueueMessage - The thread queue " "buffer is too small to enqueue a %d-byte event. Dropping " - "event.", size); + "event.", length); break; default: ; @@ -162,20 +163,20 @@ JackWinMMEInputPort::GetName() } void -JackWinMMEInputPort::ProcessJack() +JackWinMMEInputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames) { write_queue->ResetMidiBuffer(port_buffer, frames); if (! jack_event) { jack_event = thread_queue->DequeueEvent(); } for (; jack_event; jack_event = thread_queue->DequeueEvent()) { - switch (write_queue->EnqueueEvent(event)) { - case BUFFER_TOO_SMALL: + switch (write_queue->EnqueueEvent(jack_event)) { + case JackMidiWriteQueue::BUFFER_TOO_SMALL: jack_error("JackWinMMEMidiInputPort::Process - The buffer write " "queue couldn't enqueue a %d-byte event. Dropping " - "event.", event->size); + "event.", jack_event->size); // Fallthrough on purpose - case OK: + case JackMidiWriteQueue::OK: continue; } break; @@ -224,14 +225,14 @@ JackWinMMEInputPort::ProcessWinMME(UINT message, DWORD param1, DWORD param2) EnqueueMessage(current_frame, (size_t) length, message_buffer); break; case MIM_LONGDATA: - LPMIDIHDR header = (LPMIDIHDR) dwParam1; + LPMIDIHDR header = (LPMIDIHDR) param1; jack_midi_data_t *data = (jack_midi_data_t *) header->lpData; - size_t length = header->dwBytesRecorded; - if ((data[0] != 0xf0) || (data[length - 1] != 0xf7)) { + size_t length1 = header->dwBytesRecorded; + if ((data[0] != 0xf0) || (data[length1 - 1] != 0xf7)) { jack_error("JackWinMMEInputPort::ProcessWinMME - Discarding " "%d-byte sysex chunk.", length); } else { - EnqueueMessage(current_frame, length, data); + EnqueueMessage(current_frame, length1, data); } // Is this realtime-safe? This function isn't run in the JACK thread, // but we still want it to perform as quickly as possible. Even if @@ -282,7 +283,7 @@ void JackWinMMEInputPort::WriteError(const char *jack_func, const char *mm_func, MMRESULT result) { - const char error_message[MAXERRORLENGTH]; + char error_message[MAXERRORLENGTH]; GetErrorString(result, error_message); jack_error("%s - %s: %s", jack_func, mm_func, error_message); } diff --git a/windows/winmme/JackWinMMEInputPort.h b/windows/winmme/JackWinMMEInputPort.h index 5ce042b9..dd4c53f1 100644 --- a/windows/winmme/JackWinMMEInputPort.h +++ b/windows/winmme/JackWinMMEInputPort.h @@ -55,7 +55,7 @@ namespace Jack { char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; bool started; jack_midi_data_t *sysex_buffer; - MIDIHDR sysex_header + MIDIHDR sysex_header; JackMidiAsyncQueue *thread_queue; JackMidiBufferWriteQueue *write_queue; @@ -74,7 +74,7 @@ namespace Jack { GetName(); void - ProcessJack(); + ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames); bool Start(); diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index aa87de0f..eb9ba49e 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -55,7 +55,7 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, thread = new JackThread(this); std::auto_ptr thread_ptr(thread); char error_message[MAXERRORLENGTH]; - MMRESULT result = midiOutOpen(&handle, index, HandleMessageEvent, this, + MMRESULT result = midiOutOpen(&handle, index, (DWORD)HandleMessageEvent, (DWORD)this, CALLBACK_FUNCTION); if (result != MMSYSERR_NOERROR) { GetErrorString(result, error_message); @@ -71,22 +71,24 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, GetOSErrorString(error_message); goto destroy_thread_queue_semaphore; } - MIDIINCAPS capabilities; - char *name; + MIDIOUTCAPS capabilities; + char *name_tmp; result = midiOutGetDevCaps(index, &capabilities, sizeof(capabilities)); + /* + Devin : FIXME if (result != MMSYSERR_NOERROR) { WriteMMError("JackWinMMEOutputPort [constructor]", "midiOutGetDevCaps", result); - name = driver_name; + name_tmp = driver_name; } else { - name = capabilities.szPname; + name_tmp = capabilities.szPname; } + */ snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", alias_name, driver_name, index + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", client_name, index + 1); thread_ptr.release(); - write_queue_ptr.release(); - thread_queue_ptr.release(); + thread_queue_ptr.release(); return; destroy_thread_queue_semaphore: @@ -185,7 +187,7 @@ JackWinMMEOutputPort::Execute() header.dwFlags = 0; header.dwOffset = 0; header.dwUser = 0; - header.lpData = data; + header.lpData = (LPSTR)data; result = midiOutPrepareHeader(handle, &header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { WriteMMError("JackWinMMEOutputPort::Execute", @@ -230,11 +232,14 @@ void JackWinMMEOutputPort::GetOSErrorString(LPTSTR text) { DWORD error = GetLastError(); + /* + Devin: FIXME if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &text, MAXERRORLENGTH, NULL)) { snprintf(text, MAXERRORLENGTH, "Unknown OS error code '%d'", error); } + */ } void @@ -297,7 +302,7 @@ JackWinMMEOutputPort::ProcessJack(JackMidiBuffer *port_buffer, } bool -JackWinMMEOutputPort::Signal(Handle semaphore) +JackWinMMEOutputPort::Signal(HANDLE semaphore) { bool result = (bool) ReleaseSemaphore(semaphore, 1, NULL); if (! result) { @@ -351,7 +356,7 @@ JackWinMMEOutputPort::Stop() } bool -JackWinMMEOutputPort::Wait(Handle semaphore) +JackWinMMEOutputPort::Wait(HANDLE semaphore) { DWORD result = WaitForSingleObject(semaphore, INFINITE); switch (result) { @@ -371,7 +376,7 @@ void JackWinMMEOutputPort::WriteMMError(const char *jack_func, const char *mm_func, MMRESULT result) { - const char error_message[MAXERRORLENGTH]; + char error_message[MAXERRORLENGTH]; GetMMErrorString(result, error_message); jack_error("%s - %s: %s", jack_func, mm_func, error_message); } @@ -379,7 +384,28 @@ JackWinMMEOutputPort::WriteMMError(const char *jack_func, const char *mm_func, void JackWinMMEOutputPort::WriteOSError(const char *jack_func, const char *os_func) { - const char error_message[MAXERRORLENGTH]; - GetOSErrorString(result, error_message); + char error_message[MAXERRORLENGTH]; + // Devin : FIXME + //GetOSErrorString(result, error_message); jack_error("%s - %s: %s", jack_func, os_func, error_message); } + +const char * +JackWinMMEOutputPort::GetAlias() +{ + return alias; +} +const char * +JackWinMMEOutputPort::GetName() +{ + return name; +} + +void +JackWinMMEOutputPort::GetErrorString(MMRESULT error, LPTSTR text) +{ + MMRESULT result = midiInGetErrorText(error, text, MAXERRORLENGTH); + if (result != MMSYSERR_NOERROR) { + snprintf(text, MAXERRORLENGTH, "Unknown error code '%d'", error); + } +} diff --git a/windows/winmme/JackWinMMEOutputPort.h b/windows/winmme/JackWinMMEOutputPort.h index 1033ec3e..c343ff55 100644 --- a/windows/winmme/JackWinMMEOutputPort.h +++ b/windows/winmme/JackWinMMEOutputPort.h @@ -47,10 +47,10 @@ namespace Jack { HandleMessage(UINT message, DWORD_PTR param1, DWORD_PTR param2); bool - Signal(Handle semaphore); + Signal(HANDLE semaphore); bool - Wait(Handle semaphore); + Wait(HANDLE semaphore); void WriteMMError(const char *jack_func, const char *mm_func, @@ -60,14 +60,18 @@ namespace Jack { WriteOSError(const char *jack_func, const char *os_func); char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - HMIDIOUT handle; char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + + HMIDIOUT handle; JackMidiBufferReadQueue *read_queue; HANDLE sysex_semaphore; JackThread *thread; JackMidiAsyncQueue *thread_queue; HANDLE thread_queue_semaphore; + void + GetErrorString(MMRESULT error, LPTSTR text); + public: JackWinMMEOutputPort(const char *alias_name, const char *client_name, @@ -91,6 +95,12 @@ namespace Jack { bool Stop(); + const char * + GetAlias(); + + const char * + GetName(); + }; } From 2997da1f23403a84501d229d951e8808026aea79 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Thu, 31 Mar 2011 15:53:55 +0200 Subject: [PATCH 111/472] Move MIDI common files in server library on OSX. --- macosx/Jackdmp.xcodeproj/project.pbxproj | 144 +++++++++++------------ 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index 195dd976..eb5eb758 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -108,42 +108,6 @@ /* Begin PBXBuildFile section */ 4B0A28ED0D520852002EFF74 /* tw.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B0A28EC0D520852002EFF74 /* tw.c */; }; 4B0A29260D52108E002EFF74 /* tw.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B0A28EC0D520852002EFF74 /* tw.c */; }; - 4B193933133F311400547810 /* JackMidiAsyncQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193931133F311400547810 /* JackMidiAsyncQueue.cpp */; }; - 4B193934133F311400547810 /* JackMidiAsyncQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193932133F311400547810 /* JackMidiAsyncQueue.h */; }; - 4B193935133F311400547810 /* JackMidiAsyncQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193931133F311400547810 /* JackMidiAsyncQueue.cpp */; }; - 4B193936133F311400547810 /* JackMidiAsyncQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193932133F311400547810 /* JackMidiAsyncQueue.h */; }; - 4B19393D133F313000547810 /* JackMidiAsyncWaitQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19393B133F313000547810 /* JackMidiAsyncWaitQueue.cpp */; }; - 4B19393E133F313000547810 /* JackMidiAsyncWaitQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19393C133F313000547810 /* JackMidiAsyncWaitQueue.h */; }; - 4B19393F133F313000547810 /* JackMidiAsyncWaitQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19393B133F313000547810 /* JackMidiAsyncWaitQueue.cpp */; }; - 4B193940133F313000547810 /* JackMidiAsyncWaitQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19393C133F313000547810 /* JackMidiAsyncWaitQueue.h */; }; - 4B193947133F315300547810 /* JackMidiReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193945133F315200547810 /* JackMidiReadQueue.cpp */; }; - 4B193948133F315300547810 /* JackMidiReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193946133F315200547810 /* JackMidiReadQueue.h */; }; - 4B193949133F315300547810 /* JackMidiReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193945133F315200547810 /* JackMidiReadQueue.cpp */; }; - 4B19394A133F315300547810 /* JackMidiReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193946133F315200547810 /* JackMidiReadQueue.h */; }; - 4B19395F133F317300547810 /* JackMidiBufferReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19395D133F317300547810 /* JackMidiBufferReadQueue.cpp */; }; - 4B193960133F317300547810 /* JackMidiBufferReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19395E133F317300547810 /* JackMidiBufferReadQueue.h */; }; - 4B193961133F317300547810 /* JackMidiBufferReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19395D133F317300547810 /* JackMidiBufferReadQueue.cpp */; }; - 4B193962133F317300547810 /* JackMidiBufferReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19395E133F317300547810 /* JackMidiBufferReadQueue.h */; }; - 4B19396A133F319000547810 /* JackMidiBufferWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193968133F319000547810 /* JackMidiBufferWriteQueue.cpp */; }; - 4B19396B133F319000547810 /* JackMidiBufferWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193969133F319000547810 /* JackMidiBufferWriteQueue.h */; }; - 4B19396C133F319000547810 /* JackMidiBufferWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193968133F319000547810 /* JackMidiBufferWriteQueue.cpp */; }; - 4B19396D133F319000547810 /* JackMidiBufferWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193969133F319000547810 /* JackMidiBufferWriteQueue.h */; }; - 4B19397B133F31CB00547810 /* JackMidiReceiveQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193973133F31CB00547810 /* JackMidiReceiveQueue.cpp */; }; - 4B19397C133F31CB00547810 /* JackMidiReceiveQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193974133F31CB00547810 /* JackMidiReceiveQueue.h */; }; - 4B19397D133F31CB00547810 /* JackMidiSendQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193975133F31CB00547810 /* JackMidiSendQueue.cpp */; }; - 4B19397E133F31CB00547810 /* JackMidiSendQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193976133F31CB00547810 /* JackMidiSendQueue.h */; }; - 4B19397F133F31CB00547810 /* JackMidiUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193977133F31CB00547810 /* JackMidiUtil.cpp */; }; - 4B193980133F31CB00547810 /* JackMidiUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193978133F31CB00547810 /* JackMidiUtil.h */; }; - 4B193981133F31CB00547810 /* JackMidiWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193979133F31CB00547810 /* JackMidiWriteQueue.cpp */; }; - 4B193982133F31CB00547810 /* JackMidiWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19397A133F31CB00547810 /* JackMidiWriteQueue.h */; }; - 4B193983133F31CB00547810 /* JackMidiReceiveQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193973133F31CB00547810 /* JackMidiReceiveQueue.cpp */; }; - 4B193984133F31CB00547810 /* JackMidiReceiveQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193974133F31CB00547810 /* JackMidiReceiveQueue.h */; }; - 4B193985133F31CB00547810 /* JackMidiSendQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193975133F31CB00547810 /* JackMidiSendQueue.cpp */; }; - 4B193986133F31CB00547810 /* JackMidiSendQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193976133F31CB00547810 /* JackMidiSendQueue.h */; }; - 4B193987133F31CB00547810 /* JackMidiUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193977133F31CB00547810 /* JackMidiUtil.cpp */; }; - 4B193988133F31CB00547810 /* JackMidiUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193978133F31CB00547810 /* JackMidiUtil.h */; }; - 4B193989133F31CB00547810 /* JackMidiWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193979133F31CB00547810 /* JackMidiWriteQueue.cpp */; }; - 4B19398A133F31CB00547810 /* JackMidiWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19397A133F31CB00547810 /* JackMidiWriteQueue.h */; }; 4B193991133F321500547810 /* JackFilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193990133F321500547810 /* JackFilters.h */; }; 4B193992133F321500547810 /* JackFilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193990133F321500547810 /* JackFilters.h */; }; 4B193993133F321500547810 /* JackFilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193990133F321500547810 /* JackFilters.h */; }; @@ -671,6 +635,42 @@ 4B94334A10A5E666002A187F /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B94334B10A5E666002A187F /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B95BCAE0D913073000F7695 /* control.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B95BCAD0D913073000F7695 /* control.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B97B6381344B3C100794F57 /* JackMidiAsyncQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193931133F311400547810 /* JackMidiAsyncQueue.cpp */; }; + 4B97B6391344B3C300794F57 /* JackMidiAsyncQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193932133F311400547810 /* JackMidiAsyncQueue.h */; }; + 4B97B63A1344B3C700794F57 /* JackMidiAsyncWaitQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19393B133F313000547810 /* JackMidiAsyncWaitQueue.cpp */; }; + 4B97B63D1344B3EC00794F57 /* JackMidiAsyncWaitQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19393C133F313000547810 /* JackMidiAsyncWaitQueue.h */; }; + 4B97B63E1344B3F100794F57 /* JackMidiBufferReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19395D133F317300547810 /* JackMidiBufferReadQueue.cpp */; }; + 4B97B6411344B40C00794F57 /* JackMidiBufferReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19395E133F317300547810 /* JackMidiBufferReadQueue.h */; }; + 4B97B6531344B41E00794F57 /* JackMidiBufferWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193968133F319000547810 /* JackMidiBufferWriteQueue.cpp */; }; + 4B97B6541344B42400794F57 /* JackMidiBufferWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193969133F319000547810 /* JackMidiBufferWriteQueue.h */; }; + 4B97B6561344B43600794F57 /* JackMidiReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193946133F315200547810 /* JackMidiReadQueue.h */; }; + 4B97B6571344B43A00794F57 /* JackMidiReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193945133F315200547810 /* JackMidiReadQueue.cpp */; }; + 4B97B6581344B43F00794F57 /* JackMidiReceiveQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193973133F31CB00547810 /* JackMidiReceiveQueue.cpp */; }; + 4B97B6591344B44800794F57 /* JackMidiReceiveQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193974133F31CB00547810 /* JackMidiReceiveQueue.h */; }; + 4B97B65A1344B44F00794F57 /* JackMidiSendQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193975133F31CB00547810 /* JackMidiSendQueue.cpp */; }; + 4B97B65B1344B45600794F57 /* JackMidiSendQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193976133F31CB00547810 /* JackMidiSendQueue.h */; }; + 4B97B65C1344B45D00794F57 /* JackMidiUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193977133F31CB00547810 /* JackMidiUtil.cpp */; }; + 4B97B65D1344B46400794F57 /* JackMidiUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193978133F31CB00547810 /* JackMidiUtil.h */; }; + 4B97B65E1344B46B00794F57 /* JackMidiWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193979133F31CB00547810 /* JackMidiWriteQueue.cpp */; }; + 4B97B65F1344B47100794F57 /* JackMidiWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19397A133F31CB00547810 /* JackMidiWriteQueue.h */; }; + 4B97B6601344B48F00794F57 /* JackMidiAsyncQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193931133F311400547810 /* JackMidiAsyncQueue.cpp */; }; + 4B97B6611344B49500794F57 /* JackMidiAsyncQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193932133F311400547810 /* JackMidiAsyncQueue.h */; }; + 4B97B6621344B49C00794F57 /* JackMidiAsyncWaitQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19393B133F313000547810 /* JackMidiAsyncWaitQueue.cpp */; }; + 4B97B6631344B4A800794F57 /* JackMidiAsyncWaitQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19393C133F313000547810 /* JackMidiAsyncWaitQueue.h */; }; + 4B97B6641344B4AE00794F57 /* JackMidiBufferReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19395D133F317300547810 /* JackMidiBufferReadQueue.cpp */; }; + 4B97B6651344B4B500794F57 /* JackMidiBufferReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19395E133F317300547810 /* JackMidiBufferReadQueue.h */; }; + 4B97B6671344B4C700794F57 /* JackMidiBufferWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193969133F319000547810 /* JackMidiBufferWriteQueue.h */; }; + 4B97B6691344B4CE00794F57 /* JackMidiBufferWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193968133F319000547810 /* JackMidiBufferWriteQueue.cpp */; }; + 4B97B66E1344B4D500794F57 /* JackMidiReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193945133F315200547810 /* JackMidiReadQueue.cpp */; }; + 4B97B66F1344B4DC00794F57 /* JackMidiReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193946133F315200547810 /* JackMidiReadQueue.h */; }; + 4B97B6701344B4E300794F57 /* JackMidiReceiveQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193973133F31CB00547810 /* JackMidiReceiveQueue.cpp */; }; + 4B97B6711344B4EA00794F57 /* JackMidiReceiveQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193974133F31CB00547810 /* JackMidiReceiveQueue.h */; }; + 4B97B6721344B4F000794F57 /* JackMidiSendQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193975133F31CB00547810 /* JackMidiSendQueue.cpp */; }; + 4B97B6781344B50800794F57 /* JackMidiSendQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193976133F31CB00547810 /* JackMidiSendQueue.h */; }; + 4B97B6791344B50F00794F57 /* JackMidiUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193977133F31CB00547810 /* JackMidiUtil.cpp */; }; + 4B97B67A1344B51600794F57 /* JackMidiUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193978133F31CB00547810 /* JackMidiUtil.h */; }; + 4B97B67B1344B51D00794F57 /* JackMidiWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193979133F31CB00547810 /* JackMidiWriteQueue.cpp */; }; + 4B97B67C1344B52800794F57 /* JackMidiWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19397A133F31CB00547810 /* JackMidiWriteQueue.h */; }; 4B9A25B50DBF8330006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; 4B9A25B60DBF8330006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; 4B9A26010DBF8584006E9FBC /* jslist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B9A26000DBF8584006E9FBC /* jslist.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -3454,6 +3454,15 @@ 4B8A38C4117B814000664E07 /* JackSocketServerNotifyChannel.h in Headers */, 4B5160AA13215ED900BB7DCB /* systemdeps.h in Headers */, 4B193995133F321500547810 /* JackFilters.h in Headers */, + 4B97B6611344B49500794F57 /* JackMidiAsyncQueue.h in Headers */, + 4B97B6631344B4A800794F57 /* JackMidiAsyncWaitQueue.h in Headers */, + 4B97B6651344B4B500794F57 /* JackMidiBufferReadQueue.h in Headers */, + 4B97B6671344B4C700794F57 /* JackMidiBufferWriteQueue.h in Headers */, + 4B97B66F1344B4DC00794F57 /* JackMidiReadQueue.h in Headers */, + 4B97B6711344B4EA00794F57 /* JackMidiReceiveQueue.h in Headers */, + 4B97B6781344B50800794F57 /* JackMidiSendQueue.h in Headers */, + 4B97B67A1344B51600794F57 /* JackMidiUtil.h in Headers */, + 4B97B67C1344B52800794F57 /* JackMidiWriteQueue.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3917,6 +3926,15 @@ 4B2209E712F6BC0300E5DC26 /* JackSocket.h in Headers */, 4B2209EA12F6BC1600E5DC26 /* JackSocketNotifyChannel.h in Headers */, 4B193992133F321500547810 /* JackFilters.h in Headers */, + 4B97B6391344B3C300794F57 /* JackMidiAsyncQueue.h in Headers */, + 4B97B63D1344B3EC00794F57 /* JackMidiAsyncWaitQueue.h in Headers */, + 4B97B6411344B40C00794F57 /* JackMidiBufferReadQueue.h in Headers */, + 4B97B6541344B42400794F57 /* JackMidiBufferWriteQueue.h in Headers */, + 4B97B6561344B43600794F57 /* JackMidiReadQueue.h in Headers */, + 4B97B6591344B44800794F57 /* JackMidiReceiveQueue.h in Headers */, + 4B97B65B1344B45600794F57 /* JackMidiSendQueue.h in Headers */, + 4B97B65D1344B46400794F57 /* JackMidiUtil.h in Headers */, + 4B97B65F1344B47100794F57 /* JackMidiWriteQueue.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4152,15 +4170,6 @@ 4B370A3F133DD7E300237B68 /* JackCoreMidiUtil.h in Headers */, 4B370A41133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h in Headers */, 4B370A43133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h in Headers */, - 4B193936133F311400547810 /* JackMidiAsyncQueue.h in Headers */, - 4B193940133F313000547810 /* JackMidiAsyncWaitQueue.h in Headers */, - 4B19394A133F315300547810 /* JackMidiReadQueue.h in Headers */, - 4B193962133F317300547810 /* JackMidiBufferReadQueue.h in Headers */, - 4B19396D133F319000547810 /* JackMidiBufferWriteQueue.h in Headers */, - 4B193984133F31CB00547810 /* JackMidiReceiveQueue.h in Headers */, - 4B193986133F31CB00547810 /* JackMidiSendQueue.h in Headers */, - 4B193988133F31CB00547810 /* JackMidiUtil.h in Headers */, - 4B19398A133F31CB00547810 /* JackMidiWriteQueue.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4229,15 +4238,6 @@ 4B370A2F133DD7E300237B68 /* JackCoreMidiUtil.h in Headers */, 4B370A31133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h in Headers */, 4B370A33133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h in Headers */, - 4B193934133F311400547810 /* JackMidiAsyncQueue.h in Headers */, - 4B19393E133F313000547810 /* JackMidiAsyncWaitQueue.h in Headers */, - 4B193948133F315300547810 /* JackMidiReadQueue.h in Headers */, - 4B193960133F317300547810 /* JackMidiBufferReadQueue.h in Headers */, - 4B19396B133F319000547810 /* JackMidiBufferWriteQueue.h in Headers */, - 4B19397C133F31CB00547810 /* JackMidiReceiveQueue.h in Headers */, - 4B19397E133F31CB00547810 /* JackMidiSendQueue.h in Headers */, - 4B193980133F31CB00547810 /* JackMidiUtil.h in Headers */, - 4B193982133F31CB00547810 /* JackMidiWriteQueue.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6885,6 +6885,15 @@ 4B8A38AE117B811100664E07 /* JackSocketNotifyChannel.cpp in Sources */, 4B8A38B1117B812D00664E07 /* JackSocketServerChannel.cpp in Sources */, 4B8A38B2117B813400664E07 /* JackSocketServerNotifyChannel.cpp in Sources */, + 4B97B6601344B48F00794F57 /* JackMidiAsyncQueue.cpp in Sources */, + 4B97B6621344B49C00794F57 /* JackMidiAsyncWaitQueue.cpp in Sources */, + 4B97B6641344B4AE00794F57 /* JackMidiBufferReadQueue.cpp in Sources */, + 4B97B6691344B4CE00794F57 /* JackMidiBufferWriteQueue.cpp in Sources */, + 4B97B66E1344B4D500794F57 /* JackMidiReadQueue.cpp in Sources */, + 4B97B6701344B4E300794F57 /* JackMidiReceiveQueue.cpp in Sources */, + 4B97B6721344B4F000794F57 /* JackMidiSendQueue.cpp in Sources */, + 4B97B6791344B50F00794F57 /* JackMidiUtil.cpp in Sources */, + 4B97B67B1344B51D00794F57 /* JackMidiWriteQueue.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7337,6 +7346,15 @@ 4B2209E312F6BBF500E5DC26 /* JackSocketServerNotifyChannel.cpp in Sources */, 4B2209E612F6BC0200E5DC26 /* JackSocket.cpp in Sources */, 4B2209E912F6BC1500E5DC26 /* JackSocketNotifyChannel.cpp in Sources */, + 4B97B6381344B3C100794F57 /* JackMidiAsyncQueue.cpp in Sources */, + 4B97B63A1344B3C700794F57 /* JackMidiAsyncWaitQueue.cpp in Sources */, + 4B97B63E1344B3F100794F57 /* JackMidiBufferReadQueue.cpp in Sources */, + 4B97B6531344B41E00794F57 /* JackMidiBufferWriteQueue.cpp in Sources */, + 4B97B6571344B43A00794F57 /* JackMidiReadQueue.cpp in Sources */, + 4B97B6581344B43F00794F57 /* JackMidiReceiveQueue.cpp in Sources */, + 4B97B65A1344B44F00794F57 /* JackMidiSendQueue.cpp in Sources */, + 4B97B65C1344B45D00794F57 /* JackMidiUtil.cpp in Sources */, + 4B97B65E1344B46B00794F57 /* JackMidiWriteQueue.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7575,15 +7593,6 @@ 4B370A3E133DD7E300237B68 /* JackCoreMidiUtil.cpp in Sources */, 4B370A40133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp in Sources */, 4B370A42133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp in Sources */, - 4B193935133F311400547810 /* JackMidiAsyncQueue.cpp in Sources */, - 4B19393F133F313000547810 /* JackMidiAsyncWaitQueue.cpp in Sources */, - 4B193949133F315300547810 /* JackMidiReadQueue.cpp in Sources */, - 4B193961133F317300547810 /* JackMidiBufferReadQueue.cpp in Sources */, - 4B19396C133F319000547810 /* JackMidiBufferWriteQueue.cpp in Sources */, - 4B193983133F31CB00547810 /* JackMidiReceiveQueue.cpp in Sources */, - 4B193985133F31CB00547810 /* JackMidiSendQueue.cpp in Sources */, - 4B193987133F31CB00547810 /* JackMidiUtil.cpp in Sources */, - 4B193989133F31CB00547810 /* JackMidiWriteQueue.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7657,15 +7666,6 @@ 4B370A2E133DD7E300237B68 /* JackCoreMidiUtil.cpp in Sources */, 4B370A30133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp in Sources */, 4B370A32133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp in Sources */, - 4B193933133F311400547810 /* JackMidiAsyncQueue.cpp in Sources */, - 4B19393D133F313000547810 /* JackMidiAsyncWaitQueue.cpp in Sources */, - 4B193947133F315300547810 /* JackMidiReadQueue.cpp in Sources */, - 4B19395F133F317300547810 /* JackMidiBufferReadQueue.cpp in Sources */, - 4B19396A133F319000547810 /* JackMidiBufferWriteQueue.cpp in Sources */, - 4B19397B133F31CB00547810 /* JackMidiReceiveQueue.cpp in Sources */, - 4B19397D133F31CB00547810 /* JackMidiSendQueue.cpp in Sources */, - 4B19397F133F31CB00547810 /* JackMidiUtil.cpp in Sources */, - 4B193981133F31CB00547810 /* JackMidiWriteQueue.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; From a871bb2496c14c125c3c7007441874a1dd60101e Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Thu, 31 Mar 2011 18:22:52 +0200 Subject: [PATCH 112/472] Correct JackWinMMEInputPort.cpp. --- common/shm.h | 2 +- windows/jackd.workspace | 4 +-- windows/winmme/JackWinMMEDriver.cpp | 39 ++++++++++++++++++------- windows/winmme/JackWinMMEInputPort.cpp | 29 ++++++++++++++---- windows/winmme/JackWinMMEInputPort.h | 6 ++-- windows/winmme/JackWinMMEOutputPort.cpp | 11 ++++++- 6 files changed, 68 insertions(+), 23 deletions(-) diff --git a/common/shm.h b/common/shm.h index ed5a953f..f1edc8ed 100644 --- a/common/shm.h +++ b/common/shm.h @@ -14,7 +14,7 @@ extern "C" { #endif -#define MAX_SERVERS 8 /* maximum concurrent servers */ +#define MAX_SERVERS 64 /* maximum concurrent servers */ #define MAX_SHM_ID 256 /* generally about 16 per server */ #define JACK_SERVER_NAME_SIZE 256 /* maximum length of server name */ #define JACK_SHM_MAGIC 0x4a41434b /* shm magic number: "JACK" */ diff --git a/windows/jackd.workspace b/windows/jackd.workspace index 4384140e..c424a7b4 100644 --- a/windows/jackd.workspace +++ b/windows/jackd.workspace @@ -5,7 +5,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/windows/winmme/JackWinMMEDriver.cpp b/windows/winmme/JackWinMMEDriver.cpp index 455118a2..96bebda1 100644 --- a/windows/winmme/JackWinMMEDriver.cpp +++ b/windows/winmme/JackWinMMEDriver.cpp @@ -52,6 +52,9 @@ JackWinMMEDriver::Attach() latency_range.max = latency; latency_range.min = latency; + jack_info("JackWinMMEDriver::Attach - fCaptureChannels %d", fCaptureChannels); + jack_info("JackWinMMEDriver::Attach - fPlaybackChannels %d", fPlaybackChannels); + // Inputs for (int i = 0; i < fCaptureChannels; i++) { JackWinMMEInputPort *input_port = input_ports[i]; @@ -130,9 +133,13 @@ JackWinMMEDriver::Open(bool capturing, bool playing, int in_channels, { const char *client_name = fClientControl.fName; int input_count = 0; + int output_count = 0; int num_potential_inputs = midiInGetNumDevs(); int num_potential_outputs = midiOutGetNumDevs(); - int output_count = 0; + + jack_info("JackWinMMEDriver::Open - num_potential_inputs %d", num_potential_inputs); + jack_info("JackWinMMEDriver::Open - num_potential_outputs %d", num_potential_outputs); + if (num_potential_inputs) { try { input_ports = new JackWinMMEInputPort *[num_potential_inputs]; @@ -175,6 +182,11 @@ JackWinMMEDriver::Open(bool capturing, bool playing, int in_channels, output_count++; } } + + jack_info("JackWinMMEDriver::Open - input_count %d", input_count); + jack_info("JackWinMMEDriver::Open - output_count %d", output_count); + + if (! (input_count || output_count)) { jack_error("JackWinMMEDriver::Open - no WinMME inputs or outputs " "allocated."); @@ -200,10 +212,25 @@ JackWinMMEDriver::Open(bool capturing, bool playing, int in_channels, int JackWinMMEDriver::Read() { + jack_nframes_t buffer_size = fEngineControl->fBufferSize; for (int i = 0; i < fCaptureChannels; i++) { input_ports[i]->ProcessJack(GetInputBuffer(i), buffer_size); } + + return 0; +} + + +int +JackWinMMEDriver::Write() +{ + /* + jack_nframes_t buffer_size = fEngineControl->fBufferSize; + for (int i = 0; i < fPlaybackChannels; i++) { + output_ports[i]->ProcessJack(GetOutputBuffer(i), buffer_size); + } + */ return 0; } @@ -287,16 +314,6 @@ JackWinMMEDriver::Stop() return result; } -int -JackWinMMEDriver::Write() -{ - jack_nframes_t buffer_size = fEngineControl->fBufferSize; - for (int i = 0; i < fPlaybackChannels; i++) { - output_ports[i]->ProcessJack(GetOutputBuffer(i), buffer_size); - } - return 0; -} - #ifdef __cplusplus extern "C" { diff --git a/windows/winmme/JackWinMMEInputPort.cpp b/windows/winmme/JackWinMMEInputPort.cpp index 0adf3bec..6c573cf0 100644 --- a/windows/winmme/JackWinMMEInputPort.cpp +++ b/windows/winmme/JackWinMMEInputPort.cpp @@ -78,6 +78,23 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, goto unprepare_header; } + MIDIINCAPS capabilities; + char *name_tmp; + result = midiInGetDevCaps(index, &capabilities, sizeof(capabilities)); + /* + Devin : FIXME + if (result != MMSYSERR_NOERROR) { + WriteMMError("JackWinMMEOutputPort [constructor]", "midiOutGetDevCaps", + result); + name_tmp = driver_name; + } else { + name_tmp = capabilities.szPname; + } + */ + snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", alias_name, driver_name, + index + 1); + snprintf(name, sizeof(name) - 1, "%s:capture_%d", client_name, index + 1); + jack_event = 0; started = false; write_queue_ptr.release(); @@ -147,6 +164,12 @@ JackWinMMEInputPort::GetAlias() return alias; } +const char * +JackWinMMEInputPort::GetName() +{ + return name; +} + void JackWinMMEInputPort::GetErrorString(MMRESULT error, LPTSTR text) { @@ -156,12 +179,6 @@ JackWinMMEInputPort::GetErrorString(MMRESULT error, LPTSTR text) } } -const char * -JackWinMMEInputPort::GetName() -{ - return name; -} - void JackWinMMEInputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames) { diff --git a/windows/winmme/JackWinMMEInputPort.h b/windows/winmme/JackWinMMEInputPort.h index dd4c53f1..568bd9f5 100644 --- a/windows/winmme/JackWinMMEInputPort.h +++ b/windows/winmme/JackWinMMEInputPort.h @@ -50,15 +50,17 @@ namespace Jack { MMRESULT result); char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + HMIDIIN handle; jack_midi_event_t *jack_event; - char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - bool started; jack_midi_data_t *sysex_buffer; MIDIHDR sysex_header; JackMidiAsyncQueue *thread_queue; JackMidiBufferWriteQueue *write_queue; + bool started; + public: JackWinMMEInputPort(const char *alias_name, const char *client_name, diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index eb9ba49e..0b05cb2c 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -88,7 +88,7 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, index + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", client_name, index + 1); thread_ptr.release(); - thread_queue_ptr.release(); + thread_queue_ptr.release(); return; destroy_thread_queue_semaphore: @@ -132,9 +132,15 @@ bool JackWinMMEOutputPort::Execute() { for (;;) { + jack_log("JackWinMMEOutputPort::Execute TOTO"); + JackSleep(100000); + if (! Wait(thread_queue_semaphore)) { + jack_log("JackWinMMEOutputPort::Execute BREAK"); + break; } + /* jack_midi_event_t *event = thread_queue->DequeueEvent(); if (! event) { break; @@ -214,6 +220,7 @@ JackWinMMEOutputPort::Execute() "midiOutUnprepareHeader", result); break; } + */ } stop_execution: return false; @@ -358,6 +365,8 @@ JackWinMMEOutputPort::Stop() bool JackWinMMEOutputPort::Wait(HANDLE semaphore) { + jack_log("JackWinMMEOutputPort::Wait %d", semaphore); + DWORD result = WaitForSingleObject(semaphore, INFINITE); switch (result) { case WAIT_FAILED: From 173f1629a95298dfb0692044dd9b932245685d3d Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Thu, 31 Mar 2011 10:37:17 -0700 Subject: [PATCH 113/472] Fix problems sent by Stephane. --- windows/winmme/JackWinMMEInputPort.cpp | 20 ++++++++-- windows/winmme/JackWinMMEOutputPort.cpp | 53 +++++++++---------------- 2 files changed, 36 insertions(+), 37 deletions(-) diff --git a/windows/winmme/JackWinMMEInputPort.cpp b/windows/winmme/JackWinMMEInputPort.cpp index 0adf3bec..79d1c8af 100644 --- a/windows/winmme/JackWinMMEInputPort.cpp +++ b/windows/winmme/JackWinMMEInputPort.cpp @@ -55,7 +55,8 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, std::auto_ptr write_queue_ptr(write_queue); sysex_buffer = new jack_midi_data_t[max_bytes]; char error_message[MAXERRORLENGTH]; - MMRESULT result = midiInOpen(&handle, index, (DWORD)HandleMidiInputEvent, (DWORD)this, + MMRESULT result = midiInOpen(&handle, index, (DWORD)HandleMidiInputEvent, + (DWORD)this, CALLBACK_FUNCTION | MIDI_IO_STATUS); if (result != MMSYSERR_NOERROR) { GetErrorString(result, error_message); @@ -77,7 +78,19 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, GetErrorString(result, error_message); goto unprepare_header; } - + MIDIINCAPS capabilities; + char *name_tmp; + result = midiInGetDevCaps(index, &capabilities, sizeof(capabilities)); + if (result != MMSYSERR_NOERROR) { + WriteError("JackWinMMEInputPort [constructor]", "midiInGetDevCaps", + result); + name_tmp = driver_name; + } else { + name_tmp = capabilities.szPname; + } + snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", alias_name, name_tmp, + index + 1); + snprintf(name, sizeof(name) - 1, "%s:capture_%d", client_name, index + 1); jack_event = 0; started = false; write_queue_ptr.release(); @@ -163,7 +176,8 @@ JackWinMMEInputPort::GetName() } void -JackWinMMEInputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames) +JackWinMMEInputPort::ProcessJack(JackMidiBuffer *port_buffer, + jack_nframes_t frames) { write_queue->ResetMidiBuffer(port_buffer, frames); if (! jack_event) { diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index eb9ba49e..ff001d96 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -55,10 +55,10 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, thread = new JackThread(this); std::auto_ptr thread_ptr(thread); char error_message[MAXERRORLENGTH]; - MMRESULT result = midiOutOpen(&handle, index, (DWORD)HandleMessageEvent, (DWORD)this, - CALLBACK_FUNCTION); + MMRESULT result = midiOutOpen(&handle, index, (DWORD)HandleMessageEvent, + (DWORD)this, CALLBACK_FUNCTION); if (result != MMSYSERR_NOERROR) { - GetErrorString(result, error_message); + GetMMErrorString(result, error_message); goto raise_exception; } thread_queue_semaphore = CreateSemaphore(NULL, 0, max_messages, NULL); @@ -74,8 +74,6 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, MIDIOUTCAPS capabilities; char *name_tmp; result = midiOutGetDevCaps(index, &capabilities, sizeof(capabilities)); - /* - Devin : FIXME if (result != MMSYSERR_NOERROR) { WriteMMError("JackWinMMEOutputPort [constructor]", "midiOutGetDevCaps", result); @@ -83,12 +81,11 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, } else { name_tmp = capabilities.szPname; } - */ - snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", alias_name, driver_name, + snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", alias_name, name_tmp, index + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", client_name, index + 1); thread_ptr.release(); - thread_queue_ptr.release(); + thread_queue_ptr.release(); return; destroy_thread_queue_semaphore: @@ -219,6 +216,12 @@ JackWinMMEOutputPort::Execute() return false; } +const char * +JackWinMMEOutputPort::GetAlias() +{ + return alias; +} + void JackWinMMEOutputPort::GetMMErrorString(MMRESULT error, LPTSTR text) { @@ -228,18 +231,21 @@ JackWinMMEOutputPort::GetMMErrorString(MMRESULT error, LPTSTR text) } } +const char * +JackWinMMEOutputPort::GetName() +{ + return name; +} + void JackWinMMEOutputPort::GetOSErrorString(LPTSTR text) { DWORD error = GetLastError(); - /* - Devin: FIXME if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &text, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), text, MAXERRORLENGTH, NULL)) { snprintf(text, MAXERRORLENGTH, "Unknown OS error code '%d'", error); } - */ } void @@ -385,27 +391,6 @@ void JackWinMMEOutputPort::WriteOSError(const char *jack_func, const char *os_func) { char error_message[MAXERRORLENGTH]; - // Devin : FIXME - //GetOSErrorString(result, error_message); + GetOSErrorString(error_message); jack_error("%s - %s: %s", jack_func, os_func, error_message); } - -const char * -JackWinMMEOutputPort::GetAlias() -{ - return alias; -} -const char * -JackWinMMEOutputPort::GetName() -{ - return name; -} - -void -JackWinMMEOutputPort::GetErrorString(MMRESULT error, LPTSTR text) -{ - MMRESULT result = midiInGetErrorText(error, text, MAXERRORLENGTH); - if (result != MMSYSERR_NOERROR) { - snprintf(text, MAXERRORLENGTH, "Unknown error code '%d'", error); - } -} From a3318119b3df546061b6960d7d6a4a8752265383 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Thu, 31 Mar 2011 19:52:14 +0200 Subject: [PATCH 114/472] Correct MIDI ports memory management in JackNetDriver. --- common/JackNetDriver.cpp | 52 +++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index d2327eb1..66e4f7dd 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -151,8 +151,16 @@ namespace Jack //allocate midi ports lists fMidiCapturePortList = new jack_port_id_t [fParams.fSendMidiChannels]; fMidiPlaybackPortList = new jack_port_id_t [fParams.fReturnMidiChannels]; - assert ( fMidiCapturePortList ); - assert ( fMidiPlaybackPortList ); + + assert(fMidiCapturePortList); + assert(fMidiPlaybackPortList); + + for (uint midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { + fMidiCapturePortList[midi_port_index] = NULL; + } + for (uint midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { + fMidiPlaybackPortList[midi_port_index] = NULL; + } //register jack ports if ( AllocPorts() != 0 ) @@ -362,20 +370,32 @@ namespace Jack { jack_log ( "JackNetDriver::FreePorts" ); - int audio_port_index; - uint midi_port_index; - for ( audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++ ) - if (fCapturePortList[audio_port_index] > 0) - fGraphManager->ReleasePort ( fClientControl.fRefNum, fCapturePortList[audio_port_index] ); - for ( audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++ ) - if (fPlaybackPortList[audio_port_index] > 0) - fGraphManager->ReleasePort ( fClientControl.fRefNum, fPlaybackPortList[audio_port_index] ); - for ( midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++ ) - if (fMidiCapturePortList[midi_port_index] > 0) - fGraphManager->ReleasePort ( fClientControl.fRefNum, fMidiCapturePortList[midi_port_index] ); - for ( midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++ ) - if (fMidiPlaybackPortList[midi_port_index] > 0) - fGraphManager->ReleasePort ( fClientControl.fRefNum, fMidiPlaybackPortList[midi_port_index] ); + for (int audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++) { + if (fCapturePortList[audio_port_index] > 0) { + fGraphManager->ReleasePort ( fClientControl.fRefNum, fCapturePortList[audio_port_index]); + } + } + + for (int audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) { + if (fPlaybackPortList[audio_port_index] > 0) { + fGraphManager->ReleasePort ( fClientControl.fRefNum, fPlaybackPortList[audio_port_index]); + } + } + + for (uint midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { + if (fMidiCapturePortList && fMidiCapturePortList[midi_port_index] > 0) { + fGraphManager->ReleasePort ( fClientControl.fRefNum, fMidiCapturePortList[midi_port_index]); + } + } + + for (uint midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { + if (fMidiPlaybackPortList && fMidiPlaybackPortList[midi_port_index] > 0) { + fGraphManager->ReleasePort ( fClientControl.fRefNum, fMidiPlaybackPortList[midi_port_index]); + } + } + // Clear MIDI channels + fParams.fSendMidiChannels = 0; + fParams.fReturnMidiChannels = 0; return 0; } From 9ce3e4fc5224eda16c677497e070150f9af8b918 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Thu, 31 Mar 2011 21:15:42 +0200 Subject: [PATCH 115/472] Correct test.cpp. --- tests/test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test.cpp b/tests/test.cpp index 1a6e4a05..7c3f5b5e 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -972,14 +972,14 @@ int main (int argc, char *argv[]) float factor = 0.5f; old_buffer_size = jack_get_buffer_size(client1); - Log("Testing BufferSize change & Callback...\n--> Current buffer size : %i.\n", old_buffer_size); + Log("Testing BufferSize change & Callback...\n--> Current buffer size : %d.\n", old_buffer_size); linebuf = linecount; if (jack_set_buffer_size(client1, (jack_nframes_t)(old_buffer_size * factor)) < 0) { printf("!!! ERROR !!! jack_set_buffer_size fails !\n"); } jack_sleep(1 * 1000); cur_buffer_size = jack_get_buffer_size(client1); - if ((old_buffer_size * factor) != cur_buffer_size) { + if (abs((old_buffer_size * factor) - cur_buffer_size) > 5) { // Tolerance needed for dummy driver... printf("!!! ERROR !!! Buffer size has not been changed !\n"); printf("!!! Maybe jack was compiled without the '--enable-resize' flag...\n"); } else { From eb24bdac93a1871785ca4db191f5817267f0cc46 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Thu, 31 Mar 2011 22:03:34 +0200 Subject: [PATCH 116/472] New JackWinMMEPort class to factorize some code. --- windows/winmme/JackWinMMEInputPort.cpp | 59 +++++++++------------ windows/winmme/JackWinMMEInputPort.h | 25 ++++----- windows/winmme/JackWinMMEOutputPort.cpp | 67 +++++++----------------- windows/winmme/JackWinMMEOutputPort.h | 31 +++-------- windows/winmme/JackWinMMEPort.cpp | 69 +++++++++++++++++++++++++ windows/winmme/JackWinMMEPort.h | 58 +++++++++++++++++++++ 6 files changed, 185 insertions(+), 124 deletions(-) create mode 100644 windows/winmme/JackWinMMEPort.cpp create mode 100644 windows/winmme/JackWinMMEPort.h diff --git a/windows/winmme/JackWinMMEInputPort.cpp b/windows/winmme/JackWinMMEInputPort.cpp index ae526cbc..9d72cc42 100644 --- a/windows/winmme/JackWinMMEInputPort.cpp +++ b/windows/winmme/JackWinMMEInputPort.cpp @@ -59,7 +59,7 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, (DWORD)this, CALLBACK_FUNCTION | MIDI_IO_STATUS); if (result != MMSYSERR_NOERROR) { - GetErrorString(result, error_message); + GetInErrorString(result, error_message); goto delete_sysex_buffer; } sysex_header.dwBufferLength = max_bytes; @@ -70,19 +70,19 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, sysex_header.lpNext = 0; result = midiInPrepareHeader(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { - GetErrorString(result, error_message); + GetInErrorString(result, error_message); goto close_handle; } result = midiInAddBuffer(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { - GetErrorString(result, error_message); + GetInErrorString(result, error_message); goto unprepare_header; } MIDIINCAPS capabilities; char *name_tmp; result = midiInGetDevCaps(index, &capabilities, sizeof(capabilities)); if (result != MMSYSERR_NOERROR) { - WriteError("JackWinMMEInputPort [constructor]", "midiInGetDevCaps", + WriteInError("JackWinMMEInputPort [constructor]", "midiInGetDevCaps", result); name_tmp = driver_name; } else { @@ -100,13 +100,13 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, unprepare_header: result = midiInUnprepareHeader(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { - WriteError("JackWinMMEInputPort [constructor]", + WriteInError("JackWinMMEInputPort [constructor]", "midiInUnprepareHeader", result); } close_handle: result = midiInClose(handle); if (result != MMSYSERR_NOERROR) { - WriteError("JackWinMMEInputPort [constructor]", "midiInClose", result); + WriteInError("JackWinMMEInputPort [constructor]", "midiInClose", result); } delete_sysex_buffer: delete[] sysex_buffer; @@ -118,16 +118,16 @@ JackWinMMEInputPort::~JackWinMMEInputPort() Stop(); MMRESULT result = midiInReset(handle); if (result != MMSYSERR_NOERROR) { - WriteError("JackWinMMEInputPort [destructor]", "midiInReset", result); + WriteInError("JackWinMMEInputPort [destructor]", "midiInReset", result); } result = midiInUnprepareHeader(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { - WriteError("JackWinMMEInputPort [destructor]", "midiInUnprepareHeader", + WriteInError("JackWinMMEInputPort [destructor]", "midiInUnprepareHeader", result); } result = midiInClose(handle); if (result != MMSYSERR_NOERROR) { - WriteError("JackWinMMEInputPort [destructor]", "midiInClose", result); + WriteInError("JackWinMMEInputPort [destructor]", "midiInClose", result); } delete[] sysex_buffer; delete thread_queue; @@ -154,27 +154,6 @@ JackWinMMEInputPort::EnqueueMessage(jack_nframes_t time, size_t length, } } -const char * -JackWinMMEInputPort::GetAlias() -{ - return alias; -} - -const char * -JackWinMMEInputPort::GetName() -{ - return name; -} - -void -JackWinMMEInputPort::GetErrorString(MMRESULT error, LPTSTR text) -{ - MMRESULT result = midiInGetErrorText(error, text, MAXERRORLENGTH); - if (result != MMSYSERR_NOERROR) { - snprintf(text, MAXERRORLENGTH, "Unknown error code '%d'", error); - } -} - void JackWinMMEInputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames) @@ -254,7 +233,7 @@ JackWinMMEInputPort::ProcessWinMME(UINT message, DWORD param1, DWORD param2) MMRESULT result = midiInAddBuffer(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { - WriteError("JackWinMMEInputPort::ProcessWinMME", "midiInAddBuffer", + WriteInError("JackWinMMEInputPort::ProcessWinMME", "midiInAddBuffer", result); } break; @@ -274,7 +253,7 @@ JackWinMMEInputPort::Start() MMRESULT result = midiInStart(handle); started = result == MMSYSERR_NOERROR; if (! started) { - WriteError("JackWinMMEInputPort::Start", "midiInStart", result); + WriteInError("JackWinMMEInputPort::Start", "midiInStart", result); } } return started; @@ -287,17 +266,27 @@ JackWinMMEInputPort::Stop() MMRESULT result = midiInStop(handle); started = result != MMSYSERR_NOERROR; if (started) { - WriteError("JackWinMMEInputPort::Stop", "midiInStop", result); + WriteInError("JackWinMMEInputPort::Stop", "midiInStop", result); } } return ! started; } void -JackWinMMEInputPort::WriteError(const char *jack_func, const char *mm_func, +JackWinMMEInputPort::GetInErrorString(MMRESULT error, LPTSTR text) +{ + MMRESULT result = midiInGetErrorText(error, text, MAXERRORLENGTH); + if (result != MMSYSERR_NOERROR) { + snprintf(text, MAXERRORLENGTH, "Unknown error code '%d'", error); + } +} + +void +JackWinMMEInputPort::WriteInError(const char *jack_func, const char *mm_func, MMRESULT result) { char error_message[MAXERRORLENGTH]; - GetErrorString(result, error_message); + GetInErrorString(result, error_message); jack_error("%s - %s: %s", jack_func, mm_func, error_message); } + diff --git a/windows/winmme/JackWinMMEInputPort.h b/windows/winmme/JackWinMMEInputPort.h index 568bd9f5..a7305340 100644 --- a/windows/winmme/JackWinMMEInputPort.h +++ b/windows/winmme/JackWinMMEInputPort.h @@ -24,10 +24,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackMidiAsyncQueue.h" #include "JackMidiBufferWriteQueue.h" +#include "JackWinMMEPort.h" namespace Jack { - class JackWinMMEInputPort { + class JackWinMMEInputPort : public JackRunnableInterface { private: @@ -39,19 +40,10 @@ namespace Jack { EnqueueMessage(jack_nframes_t time, size_t length, jack_midi_data_t *data); - void - GetErrorString(MMRESULT error, LPTSTR text); void ProcessWinMME(UINT message, DWORD param1, DWORD param2); - void - WriteError(const char *jack_func, const char *mm_func, - MMRESULT result); - - char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - HMIDIIN handle; jack_midi_event_t *jack_event; jack_midi_data_t *sysex_buffer; @@ -61,6 +53,13 @@ namespace Jack { bool started; + void + WriteOSError(const char *jack_func, const char *os_func); + + void + WriteInError(const char *jack_func, const char *mm_func, + MMRESULT result); + public: JackWinMMEInputPort(const char *alias_name, const char *client_name, @@ -69,12 +68,6 @@ namespace Jack { ~JackWinMMEInputPort(); - const char * - GetAlias(); - - const char * - GetName(); - void ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames); diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index 7af41ca7..dcc1dd79 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -58,7 +58,7 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, MMRESULT result = midiOutOpen(&handle, index, (DWORD)HandleMessageEvent, (DWORD)this, CALLBACK_FUNCTION); if (result != MMSYSERR_NOERROR) { - GetMMErrorString(result, error_message); + GetOutErrorString(result, error_message); goto raise_exception; } thread_queue_semaphore = CreateSemaphore(NULL, 0, max_messages, NULL); @@ -75,7 +75,7 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, char *name_tmp; result = midiOutGetDevCaps(index, &capabilities, sizeof(capabilities)); if (result != MMSYSERR_NOERROR) { - WriteMMError("JackWinMMEOutputPort [constructor]", "midiOutGetDevCaps", + WriteOutError("JackWinMMEOutputPort [constructor]", "midiOutGetDevCaps", result); name_tmp = driver_name; } else { @@ -95,7 +95,7 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, close_handle: result = midiOutClose(handle); if (result != MMSYSERR_NOERROR) { - WriteMMError("JackWinMMEOutputPort [constructor]", "midiOutClose", + WriteOutError("JackWinMMEOutputPort [constructor]", "midiOutClose", result); } raise_exception: @@ -107,12 +107,12 @@ JackWinMMEOutputPort::~JackWinMMEOutputPort() Stop(); MMRESULT result = midiOutReset(handle); if (result != MMSYSERR_NOERROR) { - WriteMMError("JackWinMMEOutputPort [destructor]", "midiOutReset", + WriteOutError("JackWinMMEOutputPort [destructor]", "midiOutReset", result); } result = midiOutClose(handle); if (result != MMSYSERR_NOERROR) { - WriteMMError("JackWinMMEOutputPort [destructor]", "midiOutClose", + WriteOutError("JackWinMMEOutputPort [destructor]", "midiOutClose", result); } if (! CloseHandle(sysex_semaphore)) { @@ -179,7 +179,7 @@ JackWinMMEOutputPort::Execute() message |= (DWORD) data[0]; result = midiOutShortMsg(handle, message); if (result != MMSYSERR_NOERROR) { - WriteMMError("JackWinMMEOutputPort::Execute", + WriteOutError("JackWinMMEOutputPort::Execute", "midiOutShortMsg", result); } continue; @@ -193,13 +193,13 @@ JackWinMMEOutputPort::Execute() header.lpData = (LPSTR)data; result = midiOutPrepareHeader(handle, &header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { - WriteMMError("JackWinMMEOutputPort::Execute", + WriteOutError("JackWinMMEOutputPort::Execute", "midiOutPrepareHeader", result); continue; } result = midiOutLongMsg(handle, &header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { - WriteMMError("JackWinMMEOutputPort::Execute", "midiOutLongMsg", + WriteOutError("JackWinMMEOutputPort::Execute", "midiOutLongMsg", result); continue; } @@ -213,7 +213,7 @@ JackWinMMEOutputPort::Execute() result = midiOutUnprepareHeader(handle, &header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { - WriteMMError("JackWinMMEOutputPort::Execute", + WriteOutError("JackWinMMEOutputPort::Execute", "midiOutUnprepareHeader", result); break; } @@ -223,38 +223,6 @@ JackWinMMEOutputPort::Execute() return false; } -const char * -JackWinMMEOutputPort::GetAlias() -{ - return alias; -} - -void -JackWinMMEOutputPort::GetMMErrorString(MMRESULT error, LPTSTR text) -{ - MMRESULT result = midiOutGetErrorText(error, text, MAXERRORLENGTH); - if (result != MMSYSERR_NOERROR) { - snprintf(text, MAXERRORLENGTH, "Unknown MM error code '%d'", error); - } -} - -const char * -JackWinMMEOutputPort::GetName() -{ - return name; -} - -void -JackWinMMEOutputPort::GetOSErrorString(LPTSTR text) -{ - DWORD error = GetLastError(); - if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), text, - MAXERRORLENGTH, NULL)) { - snprintf(text, MAXERRORLENGTH, "Unknown OS error code '%d'", error); - } -} - void JackWinMMEOutputPort::HandleMessage(UINT message, DWORD_PTR param1, DWORD_PTR param2) @@ -388,18 +356,19 @@ JackWinMMEOutputPort::Wait(HANDLE semaphore) } void -JackWinMMEOutputPort::WriteMMError(const char *jack_func, const char *mm_func, - MMRESULT result) +JackWinMMEOutputPort::GetOutErrorString(MMRESULT error, LPTSTR text) { - char error_message[MAXERRORLENGTH]; - GetMMErrorString(result, error_message); - jack_error("%s - %s: %s", jack_func, mm_func, error_message); + MMRESULT result = midiOutGetErrorText(error, text, MAXERRORLENGTH); + if (result != MMSYSERR_NOERROR) { + snprintf(text, MAXERRORLENGTH, "Unknown MM error code '%d'", error); + } } void -JackWinMMEOutputPort::WriteOSError(const char *jack_func, const char *os_func) +JackWinMMEOutputPort::WriteOutError(const char *jack_func, const char *mm_func, + MMRESULT result) { char error_message[MAXERRORLENGTH]; - GetOSErrorString(error_message); - jack_error("%s - %s: %s", jack_func, os_func, error_message); + GetMMErrorString(result, error_message); + jack_error("%s - %s: %s", jack_func, mm_func, error_message); } diff --git a/windows/winmme/JackWinMMEOutputPort.h b/windows/winmme/JackWinMMEOutputPort.h index c343ff55..36fa28b1 100644 --- a/windows/winmme/JackWinMMEOutputPort.h +++ b/windows/winmme/JackWinMMEOutputPort.h @@ -29,7 +29,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { - class JackWinMMEOutputPort: public JackRunnableInterface { + class JackWinMMEOutputPort : + public JackWinMMEPort, public JackRunnableInterface { private: @@ -37,12 +38,6 @@ namespace Jack { HandleMessageEvent(HMIDIOUT handle, UINT message, DWORD_PTR port, DWORD_PTR param1, DWORD_PTR param2); - void - GetMMErrorString(MMRESULT error, LPTSTR text); - - void - GetOSErrorString(LPTSTR text); - void HandleMessage(UINT message, DWORD_PTR param1, DWORD_PTR param2); @@ -52,16 +47,6 @@ namespace Jack { bool Wait(HANDLE semaphore); - void - WriteMMError(const char *jack_func, const char *mm_func, - MMRESULT result); - - void - WriteOSError(const char *jack_func, const char *os_func); - - char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - HMIDIOUT handle; JackMidiBufferReadQueue *read_queue; HANDLE sysex_semaphore; @@ -70,7 +55,11 @@ namespace Jack { HANDLE thread_queue_semaphore; void - GetErrorString(MMRESULT error, LPTSTR text); + GetOutErrorString(MMRESULT error, LPTSTR text); + + void + WriteOutError(const char *jack_func, const char *mm_func, + MMRESULT result); public: @@ -95,12 +84,6 @@ namespace Jack { bool Stop(); - const char * - GetAlias(); - - const char * - GetName(); - }; } diff --git a/windows/winmme/JackWinMMEPort.cpp b/windows/winmme/JackWinMMEPort.cpp new file mode 100644 index 00000000..577cfbeb --- /dev/null +++ b/windows/winmme/JackWinMMEPort.cpp @@ -0,0 +1,69 @@ +/* +Copyright (C) 2011 Devin Anderson + +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. + +*/ + +#include +#include + +#include "JackWinMMEPort.h" + +using Jack::JackWinMMEPort; + +/////////////////////////////////////////////////////////////////////////////// +// Class +/////////////////////////////////////////////////////////////////////////////// + +JackWinMMEPort::JackWinMMEPort(const char *alias_name, + const char *client_name, + const char *driver_name) +{} + +JackWinMMEPort::~JackWinMMEPort() +{} + +const JackWinMMEPort * +JackWinMMEOutputPort::GetAlias() +{ + return alias; +} + +const char * +JackWinMMEPort::GetName() +{ + return name; +} + +void +JackWinMMEPort::GetOSErrorString(LPTSTR text) +{ + DWORD error = GetLastError(); + if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), text, + MAXERRORLENGTH, NULL)) { + snprintf(text, MAXERRORLENGTH, "Unknown OS error code '%d'", error); + } +} + +void +JackWinMMEPort::WriteOSError(const char *jack_func, const char *os_func) +{ + char error_message[MAXERRORLENGTH]; + GetOSErrorString(error_message); + jack_error("%s - %s: %s", jack_func, os_func, error_message); +} + diff --git a/windows/winmme/JackWinMMEPort.h b/windows/winmme/JackWinMMEPort.h new file mode 100644 index 00000000..3b53fd5f --- /dev/null +++ b/windows/winmme/JackWinMMEPort.h @@ -0,0 +1,58 @@ +/* +Copyright (C) 2011 Devin Anderson + +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 __JackWinMMEPort__ +#define __JackWinMMEPort__ + +#include +#include + +namespace Jack { + + class JackWinMMEPort { + + protected: + + char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + + public: + + JackWinMMEPort(const char *alias_name, const char *client_name, + const char *driver_name); + + ~JackWinMMEPort(); + + const char * + GetAlias(); + + const char * + GetName(); + + void + GetOSErrorString(LPTSTR text); + + void + GetInErrorString(MMRESULT error, LPTSTR text); + + }; + +} + +#endif From 8e55718c3834d458690315c4dba55c93ef6e6145 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Fri, 1 Apr 2011 10:45:55 +0200 Subject: [PATCH 117/472] Winmme driver compiles again. --- windows/jack_winmme.cbp | 7 +------ windows/libjackserver.cbp | 6 ++++++ windows/winmme/JackWinMMEInputPort.cpp | 4 +++- windows/winmme/JackWinMMEInputPort.h | 7 ++++--- windows/winmme/JackWinMMEOutputPort.cpp | 4 ++-- windows/winmme/JackWinMMEOutputPort.h | 4 +--- windows/winmme/JackWinMMEPort.cpp | 9 ++++----- windows/winmme/JackWinMMEPort.h | 9 +++++---- 8 files changed, 26 insertions(+), 24 deletions(-) diff --git a/windows/jack_winmme.cbp b/windows/jack_winmme.cbp index 7de61fa8..7fe93703 100644 --- a/windows/jack_winmme.cbp +++ b/windows/jack_winmme.cbp @@ -102,12 +102,6 @@
- - - - - - @@ -117,6 +111,7 @@ + diff --git a/windows/libjackserver.cbp b/windows/libjackserver.cbp index 89cd2dd3..84b8985d 100644 --- a/windows/libjackserver.cbp +++ b/windows/libjackserver.cbp @@ -150,8 +150,14 @@ + + + + + + diff --git a/windows/winmme/JackWinMMEInputPort.cpp b/windows/winmme/JackWinMMEInputPort.cpp index 9d72cc42..c3b04453 100644 --- a/windows/winmme/JackWinMMEInputPort.cpp +++ b/windows/winmme/JackWinMMEInputPort.cpp @@ -78,16 +78,18 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, GetInErrorString(result, error_message); goto unprepare_header; } + MIDIINCAPS capabilities; char *name_tmp; result = midiInGetDevCaps(index, &capabilities, sizeof(capabilities)); if (result != MMSYSERR_NOERROR) { WriteInError("JackWinMMEInputPort [constructor]", "midiInGetDevCaps", result); - name_tmp = driver_name; + name_tmp = (char*) driver_name; } else { name_tmp = capabilities.szPname; } + snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", alias_name, name_tmp, index + 1); snprintf(name, sizeof(name) - 1, "%s:capture_%d", client_name, index + 1); diff --git a/windows/winmme/JackWinMMEInputPort.h b/windows/winmme/JackWinMMEInputPort.h index a7305340..13eb32a6 100644 --- a/windows/winmme/JackWinMMEInputPort.h +++ b/windows/winmme/JackWinMMEInputPort.h @@ -28,7 +28,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { - class JackWinMMEInputPort : public JackRunnableInterface { + class JackWinMMEInputPort : public JackWinMMEPort { private: @@ -53,13 +53,14 @@ namespace Jack { bool started; - void - WriteOSError(const char *jack_func, const char *os_func); void WriteInError(const char *jack_func, const char *mm_func, MMRESULT result); + void + GetInErrorString(MMRESULT error, LPTSTR text); + public: JackWinMMEInputPort(const char *alias_name, const char *client_name, diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index dcc1dd79..51a9ddbd 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -77,7 +77,7 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, if (result != MMSYSERR_NOERROR) { WriteOutError("JackWinMMEOutputPort [constructor]", "midiOutGetDevCaps", result); - name_tmp = driver_name; + name_tmp = (char*)driver_name; } else { name_tmp = capabilities.szPname; } @@ -369,6 +369,6 @@ JackWinMMEOutputPort::WriteOutError(const char *jack_func, const char *mm_func, MMRESULT result) { char error_message[MAXERRORLENGTH]; - GetMMErrorString(result, error_message); + GetOutErrorString(result, error_message); jack_error("%s - %s: %s", jack_func, mm_func, error_message); } diff --git a/windows/winmme/JackWinMMEOutputPort.h b/windows/winmme/JackWinMMEOutputPort.h index 36fa28b1..d43eae35 100644 --- a/windows/winmme/JackWinMMEOutputPort.h +++ b/windows/winmme/JackWinMMEOutputPort.h @@ -20,12 +20,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifndef __JackWinMMEOutputPort__ #define __JackWinMMEOutputPort__ -#include -#include - #include "JackMidiAsyncQueue.h" #include "JackMidiBufferReadQueue.h" #include "JackThread.h" +#include "JackWinMMEPort.h" namespace Jack { diff --git a/windows/winmme/JackWinMMEPort.cpp b/windows/winmme/JackWinMMEPort.cpp index 577cfbeb..46c4546b 100644 --- a/windows/winmme/JackWinMMEPort.cpp +++ b/windows/winmme/JackWinMMEPort.cpp @@ -21,6 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include "JackWinMMEPort.h" +#include "JackError.h" using Jack::JackWinMMEPort; @@ -28,16 +29,14 @@ using Jack::JackWinMMEPort; // Class /////////////////////////////////////////////////////////////////////////////// -JackWinMMEPort::JackWinMMEPort(const char *alias_name, - const char *client_name, - const char *driver_name) +JackWinMMEPort::JackWinMMEPort() {} JackWinMMEPort::~JackWinMMEPort() {} -const JackWinMMEPort * -JackWinMMEOutputPort::GetAlias() +const char * +JackWinMMEPort::GetAlias() { return alias; } diff --git a/windows/winmme/JackWinMMEPort.h b/windows/winmme/JackWinMMEPort.h index 3b53fd5f..a544c4a6 100644 --- a/windows/winmme/JackWinMMEPort.h +++ b/windows/winmme/JackWinMMEPort.h @@ -20,8 +20,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifndef __JackWinMMEPort__ #define __JackWinMMEPort__ -#include #include +#include + +#include "JackConstants.h" namespace Jack { @@ -34,8 +36,7 @@ namespace Jack { public: - JackWinMMEPort(const char *alias_name, const char *client_name, - const char *driver_name); + JackWinMMEPort(); ~JackWinMMEPort(); @@ -49,7 +50,7 @@ namespace Jack { GetOSErrorString(LPTSTR text); void - GetInErrorString(MMRESULT error, LPTSTR text); + WriteOSError(const char *jack_func, const char *os_func); }; From 4bfaf8822ad3aad6d957f30e95646d2d7937384b Mon Sep 17 00:00:00 2001 From: sletz Date: Fri, 1 Apr 2011 09:45:27 +0000 Subject: [PATCH 118/472] Cleanup JackThreadedDriver::Stop. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4244 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 5 +++++ common/JackNetAdapter.cpp | 41 ++++++++++++++++++----------------- common/JackThreadedDriver.cpp | 2 -- linux/alsa/alsa_driver.c | 4 ++-- 4 files changed, 28 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index 906a557e..e4038ab3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -34,6 +34,11 @@ Valerio Pilo Jackdmp changes log --------------------------- +2011-04-01 Stephane Letz + + * Merge newer-midi branch (Devin Anderson redesign of the MIDI drivers: alsarawmidi, ffado, coremidi and winmme). + * Cleanup JackThreadedDriver::Stop. + 2011-03-30 Stephane Letz * Version 1.9.8 started. diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index 5532f01e..6538b9ed 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -158,6 +158,7 @@ namespace Jack #ifdef JACK_MONITOR fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize); #endif + fSocket.Close(); switch ( fThread.GetStatus() ) { @@ -171,7 +172,7 @@ namespace Jack } break; // Stop when the thread cycle is finished - + case JackThread::kRunning: if ( fThread.Stop() < 0 ) { @@ -179,11 +180,11 @@ namespace Jack return -1; } break; - + default: break; } - fSocket.Close(); + return 0; } @@ -224,16 +225,16 @@ namespace Jack //set audio adapter parameters SetAdaptedBufferSize ( fParams.fPeriodSize ); SetAdaptedSampleRate ( fParams.fSampleRate ); - + // Will do "something" on OSX only... fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); - + if (fThread.AcquireSelfRealTime(GetEngineControl()->fClientPriority) < 0) { jack_error("AcquireSelfRealTime error"); } else { set_threaded_log_function(); } - + //init done, display parameters SessionParamsDisplay ( &fParams ); return true; @@ -276,13 +277,13 @@ namespace Jack jack_transport_stop ( fJackClient ); jack_info ( "NetMaster : transport stops." ); break; - + case JackTransportStarting : jack_transport_reposition ( fJackClient, &fSendTransportData.fPosition ); jack_transport_start ( fJackClient ); jack_info ( "NetMaster : transport starts." ); break; - + case JackTransportRolling : //TODO , we need to : // - find a way to call TransportEngine->SetNetworkSync() @@ -344,7 +345,7 @@ namespace Jack int JackNetAdapter::Write() { EncodeSyncPacket(); - + if ( SyncSend() == SOCKET_ERROR ) return SOCKET_ERROR; @@ -358,7 +359,7 @@ namespace Jack //in case of fatal network error, stop the process if (Read() == SOCKET_ERROR) return SOCKET_ERROR; - + PushAndPull(fSoftCaptureBuffer, fSoftPlaybackBuffer, fAdaptedBufferSize); //then write data to network @@ -368,7 +369,7 @@ namespace Jack return 0; } - + } // namespace Jack //loader------------------------------------------------------------------------------ @@ -385,10 +386,10 @@ extern "C" SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor() { jack_driver_desc_t* desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) ); - + strcpy(desc->name, "netadapter"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->desc, "netjack net <==> audio backend adapter"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - + desc->nparams = 11; desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) ); @@ -455,7 +456,7 @@ extern "C" strcpy ( desc->params[i].value.str, "slow" ); strcpy ( desc->params[i].short_desc, "Slow, Normal or Fast mode." ); strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); - + i++; strcpy(desc->params[i].name, "quality"); desc->params[i].character = 'q'; @@ -463,7 +464,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'; @@ -471,7 +472,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, "auto-connect" ); desc->params[i].character = 'c'; @@ -479,7 +480,7 @@ extern "C" desc->params[i].value.i = false; strcpy ( desc->params[i].short_desc, "Auto connect netmaster to system ports" ); strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); - + return desc; } @@ -490,9 +491,9 @@ extern "C" Jack::JackAudioAdapter* adapter; jack_nframes_t buffer_size = jack_get_buffer_size ( jack_client ); jack_nframes_t sample_rate = jack_get_sample_rate ( jack_client ); - + try { - + adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackNetAdapter(jack_client, buffer_size, sample_rate, params), params, false); assert ( adapter ); @@ -503,7 +504,7 @@ extern "C" delete adapter; return 1; } - + } catch (...) { return 1; } diff --git a/common/JackThreadedDriver.cpp b/common/JackThreadedDriver.cpp index 62260e59..d11eb13e 100644 --- a/common/JackThreadedDriver.cpp +++ b/common/JackThreadedDriver.cpp @@ -199,7 +199,6 @@ int JackThreadedDriver::Stop() case JackThread::kIniting: if (fThread.Kill() < 0) { jack_error("Cannot kill thread"); - return -1; } break; @@ -207,7 +206,6 @@ int JackThreadedDriver::Stop() case JackThread::kRunning: if (fThread.Stop() < 0) { jack_error("Cannot stop thread"); - return -1; } break; diff --git a/linux/alsa/alsa_driver.c b/linux/alsa/alsa_driver.c index 536cfb6c..5fe3635c 100644 --- a/linux/alsa/alsa_driver.c +++ b/linux/alsa/alsa_driver.c @@ -204,8 +204,8 @@ alsa_driver_ice1712_hardware (alsa_driver_t *driver) static int alsa_driver_usx2y_hardware (alsa_driver_t *driver) { - driver->hw = jack_alsa_usx2y_hw_new (driver); - return 0; + driver->hw = jack_alsa_usx2y_hw_new (driver); + return 0; } */ From c261cca84b702a83ded9a06017804aef019322fe Mon Sep 17 00:00:00 2001 From: sletz Date: Fri, 1 Apr 2011 12:10:12 +0000 Subject: [PATCH 119/472] Correct JackNetOneDriver::Close. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4245 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 1 + common/JackNetOneDriver.cpp | 7 +++++-- common/JackServer.cpp | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index e4038ab3..7dc08efa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -38,6 +38,7 @@ Valerio Pilo * Merge newer-midi branch (Devin Anderson redesign of the MIDI drivers: alsarawmidi, ffado, coremidi and winmme). * Cleanup JackThreadedDriver::Stop. + * Correct JackNetOneDriver::Close. 2011-03-30 Stephane Letz diff --git a/common/JackNetOneDriver.cpp b/common/JackNetOneDriver.cpp index 93adecdd..9d3b59ee 100644 --- a/common/JackNetOneDriver.cpp +++ b/common/JackNetOneDriver.cpp @@ -118,9 +118,12 @@ namespace Jack int JackNetOneDriver::Close() { + // Generic audio driver close + int res = JackAudioDriver::Close(); + FreePorts(); - netjack_release( &netj ); - return JackDriver::Close(); + netjack_release(&netj); + return res; } int JackNetOneDriver::Attach() diff --git a/common/JackServer.cpp b/common/JackServer.cpp index e1bcbb8a..22027c9c 100644 --- a/common/JackServer.cpp +++ b/common/JackServer.cpp @@ -58,7 +58,7 @@ JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int prio new JackFreewheelDriver(fEngine, GetSynchroTable()); fThreadedFreewheelDriver = new JackThreadedDriver(freewheelDriver); - fFreewheelDriver = freewheelDriver; + fFreewheelDriver = freewheelDriver; fDriverInfo = new JackDriverInfo(); fAudioDriver = NULL; fFreewheel = false; From a49f53c5bffe23a08952cae93d55980f14821492 Mon Sep 17 00:00:00 2001 From: sletz Date: Fri, 1 Apr 2011 12:26:37 +0000 Subject: [PATCH 120/472] More messages in verbose mode. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4246 0c269be4-1314-0410-8aa9-9f06e86f4224 --- macosx/JackMachThread.cpp | 2 +- posix/JackPosixThread.cpp | 2 ++ windows/JackWinThread.cpp | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/macosx/JackMachThread.cpp b/macosx/JackMachThread.cpp index dc102a4e..d17d0497 100644 --- a/macosx/JackMachThread.cpp +++ b/macosx/JackMachThread.cpp @@ -164,7 +164,7 @@ int JackMachThread::AcquireRealTime() int JackMachThread::AcquireSelfRealTime() { - jack_log("JackMachThread::AcquireRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld", + jack_log("JackMachThread::AcquireSelfRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld", long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000)); return AcquireRealTimeImp(pthread_self(), fPeriod, fComputation, fConstraint); } diff --git a/posix/JackPosixThread.cpp b/posix/JackPosixThread.cpp index aed3796b..cae2c493 100644 --- a/posix/JackPosixThread.cpp +++ b/posix/JackPosixThread.cpp @@ -232,6 +232,8 @@ int JackPosixThread::AcquireRealTimeImp(jack_native_thread_t thread, int priorit memset(&rtparam, 0, sizeof(rtparam)); rtparam.sched_priority = priority; + jack_log("JackPosixThread::AcquireRealTimeImp priority = %d", priority); + if ((res = pthread_setschedparam(thread, JACK_SCHED_POLICY, &rtparam)) != 0) { jack_error("Cannot use real-time scheduling (RR/%d)" "(%d: %s)", rtparam.sched_priority, res, diff --git a/windows/JackWinThread.cpp b/windows/JackWinThread.cpp index e3f2cdd9..042279ca 100644 --- a/windows/JackWinThread.cpp +++ b/windows/JackWinThread.cpp @@ -200,7 +200,7 @@ int JackWinThread::AcquireSelfRealTime(int priority) int JackWinThread::AcquireRealTimeImp(jack_native_thread_t thread, int priority) { - jack_log("JackWinThread::AcquireRealTime"); + jack_log("JackWinThread::AcquireRealTimeImp priority = %d", THREAD_PRIORITY_TIME_CRITICAL); if (SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL)) { return 0; From d351df4e06d45ec472113bd587cff2d2e9ef0ef7 Mon Sep 17 00:00:00 2001 From: sletz Date: Fri, 1 Apr 2011 12:47:37 +0000 Subject: [PATCH 121/472] Beautiful JackNetOneDriver code. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4247 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetOneDriver.cpp | 1602 +++++++++++++++++------------------ common/JackNetOneDriver.h | 129 ++- 2 files changed, 841 insertions(+), 890 deletions(-) diff --git a/common/JackNetOneDriver.cpp b/common/JackNetOneDriver.cpp index 9d3b59ee..b235b1c5 100644 --- a/common/JackNetOneDriver.cpp +++ b/common/JackNetOneDriver.cpp @@ -45,424 +45,415 @@ using namespace std; namespace Jack { - JackNetOneDriver::JackNetOneDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, - int port, int mtu, int capture_ports, int playback_ports, int midi_input_ports, int midi_output_ports, - int sample_rate, int period_size, int resample_factor, - const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig, - int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val ) - : JackAudioDriver ( name, alias, engine, table ) - { - jack_log ( "JackNetOneDriver::JackNetOneDriver port %d", port ); - - #ifdef WIN32 - WSADATA wsa; - int rc = WSAStartup(MAKEWORD(2,0),&wsa); - #endif - - netjack_init( & (this->netj), - NULL, // client - name, - capture_ports, - playback_ports, - midi_input_ports, - midi_output_ports, - sample_rate, - period_size, - port, - transport_sync, - resample_factor, - 0, - bitdepth, - use_autoconfig, - latency, - redundancy, - dont_htonl_floats, - always_deadline, - jitter_val); - } - - JackNetOneDriver::~JackNetOneDriver() - { - // No destructor yet. - } +JackNetOneDriver::JackNetOneDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, + int port, int mtu, int capture_ports, int playback_ports, int midi_input_ports, int midi_output_ports, + int sample_rate, int period_size, int resample_factor, + const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig, + int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val ) + : JackAudioDriver ( name, alias, engine, table ) +{ + jack_log ( "JackNetOneDriver::JackNetOneDriver port %d", port ); -//open, close, attach and detach------------------------------------------------------ - int JackNetOneDriver::Open ( jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing, - int inchannels, int outchannels, bool monitor, - const char* capture_driver_name, const char* playback_driver_name, - jack_nframes_t capture_latency, jack_nframes_t playback_latency ) - { - if ( JackAudioDriver::Open ( buffer_size, - samplerate, - capturing, - playing, - inchannels, - outchannels, - monitor, - capture_driver_name, - playback_driver_name, - capture_latency, - playback_latency ) == 0 ) - { - fEngineControl->fPeriod = 0; - fEngineControl->fComputation = 500 * 1000; - fEngineControl->fConstraint = 500 * 1000; - return 0; - } - else - { - jack_error( "open fail" ); - return -1; - } - } +#ifdef WIN32 + WSADATA wsa; + int rc = WSAStartup(MAKEWORD(2, 0), &wsa); +#endif - int JackNetOneDriver::Close() - { - // Generic audio driver close - int res = JackAudioDriver::Close(); + netjack_init( & (this->netj), + NULL, // client + name, + capture_ports, + playback_ports, + midi_input_ports, + midi_output_ports, + sample_rate, + period_size, + port, + transport_sync, + resample_factor, + 0, + bitdepth, + use_autoconfig, + latency, + redundancy, + dont_htonl_floats, + always_deadline, + jitter_val); +} - FreePorts(); - netjack_release(&netj); - return res; - } +JackNetOneDriver::~JackNetOneDriver() +{ + // No destructor yet. +} - int JackNetOneDriver::Attach() - { +//open, close, attach and detach------------------------------------------------------ +int JackNetOneDriver::Open ( jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing, + int inchannels, int outchannels, bool monitor, + const char* capture_driver_name, const char* playback_driver_name, + jack_nframes_t capture_latency, jack_nframes_t playback_latency ) +{ + if ( JackAudioDriver::Open ( buffer_size, + samplerate, + capturing, + playing, + inchannels, + outchannels, + monitor, + capture_driver_name, + playback_driver_name, + capture_latency, + playback_latency ) == 0 ) { + fEngineControl->fPeriod = 0; + fEngineControl->fComputation = 500 * 1000; + fEngineControl->fConstraint = 500 * 1000; return 0; + } else { + jack_error( "open fail" ); + return -1; } +} - int JackNetOneDriver::Detach() - { - return 0; - } +int JackNetOneDriver::Close() +{ + // Generic audio driver close + int res = JackAudioDriver::Close(); - int JackNetOneDriver::AllocPorts() - { - jack_port_id_t port_id; - char buf[64]; - unsigned int chn; + FreePorts(); + netjack_release(&netj); + return res; +} + +int JackNetOneDriver::Attach() +{ + return 0; +} - //if (netj.handle_transport_sync) - // jack_set_sync_callback(netj.client, (JackSyncCallback) net_driver_sync_cb, NULL); +int JackNetOneDriver::Detach() +{ + return 0; +} - for (chn = 0; chn < netj.capture_channels_audio; chn++) { - snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); +int JackNetOneDriver::AllocPorts() +{ + jack_port_id_t port_id; + char buf[64]; + unsigned int chn; - if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, - CaptureDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) - { - jack_error ( "driver: cannot register port for %s", buf ); - return -1; - } - //port = fGraphManager->GetPort ( port_id ); - - netj.capture_ports = jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); - - if( netj.bitdepth == CELT_MODE ) { - #if HAVE_CELT - #if HAVE_CELT_API_0_11 - celt_int32 lookahead; - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); - netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) ); - #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 - celt_int32 lookahead; - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); - netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); - #else - celt_int32_t lookahead; - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); - netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode ) ); - #endif - celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); - netj.codec_latency = 2*lookahead; - #endif - } else { - #if HAVE_SAMPLERATE - netj.capture_srcs = jack_slist_append(netj.capture_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); - #endif - } - } - for (chn = netj.capture_channels_audio; chn < netj.capture_channels; chn++) { - snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); + //if (netj.handle_transport_sync) + // jack_set_sync_callback(netj.client, (JackSyncCallback) net_driver_sync_cb, NULL); - if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, - CaptureDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) - { - jack_error ( "driver: cannot register port for %s", buf ); - return -1; - } - //port = fGraphManager->GetPort ( port_id ); + for (chn = 0; chn < netj.capture_channels_audio; chn++) { + snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); - netj.capture_ports = - jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); + if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, + CaptureDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) { + jack_error ( "driver: cannot register port for %s", buf ); + return -1; } + //port = fGraphManager->GetPort ( port_id ); - for (chn = 0; chn < netj.playback_channels_audio; chn++) { - snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); + netj.capture_ports = jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); - if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, - PlaybackDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) - { - jack_error ( "driver: cannot register port for %s", buf ); - return -1; - } - //port = fGraphManager->GetPort ( port_id ); - - netj.playback_ports = jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); - if( netj.bitdepth == CELT_MODE ) { - #if HAVE_CELT - #if HAVE_CELT_API_0_11 - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); - netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create_custom( celt_mode, 1, NULL ) ); - #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); - netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); - #else - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); - netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode ) ); - #endif - #endif - } else { - #if HAVE_SAMPLERATE - netj.playback_srcs = jack_slist_append(netj.playback_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); - #endif - } + if( netj.bitdepth == CELT_MODE ) { +#if HAVE_CELT +#if HAVE_CELT_API_0_11 + celt_int32 lookahead; + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); + netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) ); +#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 + celt_int32 lookahead; + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); + netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); +#else + celt_int32_t lookahead; + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); + netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode ) ); +#endif + celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); + netj.codec_latency = 2 * lookahead; +#endif + } else { +#if HAVE_SAMPLERATE + netj.capture_srcs = jack_slist_append(netj.capture_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); +#endif } - for (chn = netj.playback_channels_audio; chn < netj.playback_channels; chn++) { - snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); - - if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, - PlaybackDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) - { - jack_error ( "driver: cannot register port for %s", buf ); - return -1; - } - //port = fGraphManager->GetPort ( port_id ); + } + for (chn = netj.capture_channels_audio; chn < netj.capture_channels; chn++) { + snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); - netj.playback_ports = - jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); + if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, + CaptureDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) { + jack_error ( "driver: cannot register port for %s", buf ); + return -1; } - return 0; + //port = fGraphManager->GetPort ( port_id ); + + netj.capture_ports = + jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); } -//init and restart-------------------------------------------------------------------- - bool JackNetOneDriver::Initialize() - { - jack_log ( "JackNetOneDriver::Init()" ); + for (chn = 0; chn < netj.playback_channels_audio; chn++) { + snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); - FreePorts(); - netjack_release( &netj ); + if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, + PlaybackDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) { + jack_error ( "driver: cannot register port for %s", buf ); + return -1; + } + //port = fGraphManager->GetPort ( port_id ); - //display some additional infos - jack_info ( "NetOne driver started" ); - if( netjack_startup( &netj ) ) { - return false; + netj.playback_ports = jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); + if( netj.bitdepth == CELT_MODE ) { +#if HAVE_CELT +#if HAVE_CELT_API_0_11 + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); + netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create_custom( celt_mode, 1, NULL ) ); +#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); + netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); +#else + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); + netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode ) ); +#endif +#endif + } else { +#if HAVE_SAMPLERATE + netj.playback_srcs = jack_slist_append(netj.playback_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); +#endif } + } + for (chn = netj.playback_channels_audio; chn < netj.playback_channels; chn++) { + snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); - //register jack ports - if ( AllocPorts() != 0 ) - { - jack_error ( "Can't allocate ports." ); - return false; + if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, + PlaybackDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) { + jack_error ( "driver: cannot register port for %s", buf ); + return -1; } + //port = fGraphManager->GetPort ( port_id ); + + netj.playback_ports = + jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); + } + return 0; +} - //monitor - //driver parametering - JackAudioDriver::SetBufferSize ( netj.period_size ); - JackAudioDriver::SetSampleRate ( netj.sample_rate ); +//init and restart-------------------------------------------------------------------- +bool JackNetOneDriver::Initialize() +{ + jack_log ( "JackNetOneDriver::Init()" ); - JackDriver::NotifyBufferSize ( netj.period_size ); - JackDriver::NotifySampleRate ( netj.sample_rate ); + FreePorts(); + netjack_release( &netj ); - //transport engine parametering - fEngineControl->fTransport.SetNetworkSync ( true ); - return true; + //display some additional infos + jack_info ( "NetOne driver started" ); + if( netjack_startup( &netj ) ) { + return false; } + //register jack ports + if ( AllocPorts() != 0 ) { + jack_error ( "Can't allocate ports." ); + return false; + } -//jack ports and buffers-------------------------------------------------------------- + //monitor + //driver parametering + JackAudioDriver::SetBufferSize ( netj.period_size ); + JackAudioDriver::SetSampleRate ( netj.sample_rate ); -//driver processes-------------------------------------------------------------------- - int JackNetOneDriver::Read() - { - int delay; - delay = netjack_wait( &netj ); - if( delay ) { - NotifyXRun(fBeginDateUst, (float) delay); - jack_error( "netxruns... duration: %dms", delay/1000 ); - } + JackDriver::NotifyBufferSize ( netj.period_size ); + JackDriver::NotifySampleRate ( netj.sample_rate ); - if( (netj.num_lost_packets * netj.period_size / netj.sample_rate) > 2 ) - JackTools::ThrowJackNetException(); + //transport engine parametering + fEngineControl->fTransport.SetNetworkSync ( true ); + return true; +} - //netjack_read( &netj, netj.period_size ); - JackDriver::CycleTakeBeginTime(); - jack_position_t local_trans_pos; - jack_transport_state_t local_trans_state; +//jack ports and buffers-------------------------------------------------------------- - unsigned int *packet_buf, *packet_bufX; +//driver processes-------------------------------------------------------------------- +int JackNetOneDriver::Read() +{ + int delay; + delay = netjack_wait( &netj ); + if( delay ) { + NotifyXRun(fBeginDateUst, (float) delay); + jack_error( "netxruns... duration: %dms", delay / 1000 ); + } - if( ! netj.packet_data_valid ) { - jack_log( "data not valid" ); - render_payload_to_jack_ports (netj.bitdepth, NULL, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats ); - return 0; - } - packet_buf = netj.rx_buf; + if( (netj.num_lost_packets * netj.period_size / netj.sample_rate) > 2 ) + JackTools::ThrowJackNetException(); - jacknet_packet_header *pkthdr = (jacknet_packet_header *)packet_buf; + //netjack_read( &netj, netj.period_size ); + JackDriver::CycleTakeBeginTime(); - packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); + jack_position_t local_trans_pos; + jack_transport_state_t local_trans_state; - netj.reply_port = pkthdr->reply_port; - netj.latency = pkthdr->latency; + unsigned int *packet_buf, *packet_bufX; - // Special handling for latency=0 - if( netj.latency == 0 ) - netj.resync_threshold = 0; - else - netj.resync_threshold = MIN( 15, pkthdr->latency-1 ); + if( ! netj.packet_data_valid ) { + jack_log( "data not valid" ); + render_payload_to_jack_ports (netj.bitdepth, NULL, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats ); + return 0; + } + packet_buf = netj.rx_buf; - // check whether, we should handle the transport sync stuff, or leave trnasports untouched. - if (netj.handle_transport_sync) { - #if 1 - unsigned int compensated_tranport_pos = (pkthdr->transport_frame + (pkthdr->latency * netj.period_size) + netj.codec_latency); + jacknet_packet_header *pkthdr = (jacknet_packet_header *)packet_buf; - // read local transport info.... - //local_trans_state = jack_transport_query(netj.client, &local_trans_pos); + packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); - local_trans_state = fEngineControl->fTransport.Query ( &local_trans_pos ); + netj.reply_port = pkthdr->reply_port; + netj.latency = pkthdr->latency; - // Now check if we have to start or stop local transport to sync to remote... - switch (pkthdr->transport_state) { + // Special handling for latency=0 + if( netj.latency == 0 ) + netj.resync_threshold = 0; + else + netj.resync_threshold = MIN( 15, pkthdr->latency - 1 ); - case JackTransportStarting: - // the master transport is starting... so we set our reply to the sync_callback; - if (local_trans_state == JackTransportStopped) { - fEngineControl->fTransport.SetCommand ( TransportCommandStart ); - //jack_transport_start(netj.client); - //last_transport_state = JackTransportStopped; - netj.sync_state = 0; - jack_info("locally stopped... starting..."); - } + // check whether, we should handle the transport sync stuff, or leave trnasports untouched. + if (netj.handle_transport_sync) { +#if 1 + unsigned int compensated_tranport_pos = (pkthdr->transport_frame + (pkthdr->latency * netj.period_size) + netj.codec_latency); - if (local_trans_pos.frame != compensated_tranport_pos) { - jack_position_t new_pos = local_trans_pos; - new_pos.frame = compensated_tranport_pos + 2*netj.period_size; - new_pos.valid = (jack_position_bits_t) 0; + // read local transport info.... + //local_trans_state = jack_transport_query(netj.client, &local_trans_pos); + local_trans_state = fEngineControl->fTransport.Query ( &local_trans_pos ); - fEngineControl->fTransport.RequestNewPos ( &new_pos ); - //jack_transport_locate(netj.client, compensated_tranport_pos); - //last_transport_state = JackTransportRolling; - netj.sync_state = 0; - jack_info("starting locate to %d", compensated_tranport_pos ); - } - break; + // Now check if we have to start or stop local transport to sync to remote... + switch (pkthdr->transport_state) { - case JackTransportStopped: - netj.sync_state = 1; - if (local_trans_pos.frame != (pkthdr->transport_frame)) { - jack_position_t new_pos = local_trans_pos; - new_pos.frame = pkthdr->transport_frame; - new_pos.valid = (jack_position_bits_t)0; - fEngineControl->fTransport.RequestNewPos ( &new_pos ); - //jack_transport_locate(netj.client, (pkthdr->transport_frame)); - jack_info("transport is stopped locate to %d", pkthdr->transport_frame); - } - if (local_trans_state != JackTransportStopped) - //jack_transport_stop(netj.client); - fEngineControl->fTransport.SetCommand ( TransportCommandStop ); - break; + case JackTransportStarting: + // the master transport is starting... so we set our reply to the sync_callback; + if (local_trans_state == JackTransportStopped) { + fEngineControl->fTransport.SetCommand ( TransportCommandStart ); + //jack_transport_start(netj.client); + //last_transport_state = JackTransportStopped; + netj.sync_state = 0; + jack_info("locally stopped... starting..."); + } - case JackTransportRolling: - netj.sync_state = 1; - // if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * netj.period_size)) { - // jack_transport_locate(netj.client, (pkthdr->transport_frame + (pkthdr->latency + 2) * netj.period_size)); - // jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*netj.period_size); - // } - if (local_trans_state != JackTransportRolling) - fEngineControl->fTransport.SetState ( JackTransportRolling ); - break; + if (local_trans_pos.frame != compensated_tranport_pos) { + jack_position_t new_pos = local_trans_pos; + new_pos.frame = compensated_tranport_pos + 2 * netj.period_size; + new_pos.valid = (jack_position_bits_t) 0; - case JackTransportLooping: - break; - } -#endif - } - render_payload_to_jack_ports (netj.bitdepth, packet_bufX, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats ); - packet_cache_release_packet(netj.packcache, netj.expected_framecnt ); - return 0; + fEngineControl->fTransport.RequestNewPos ( &new_pos ); + //jack_transport_locate(netj.client, compensated_tranport_pos); + //last_transport_state = JackTransportRolling; + netj.sync_state = 0; + jack_info("starting locate to %d", compensated_tranport_pos ); + } + break; + + case JackTransportStopped: + netj.sync_state = 1; + if (local_trans_pos.frame != (pkthdr->transport_frame)) { + jack_position_t new_pos = local_trans_pos; + new_pos.frame = pkthdr->transport_frame; + new_pos.valid = (jack_position_bits_t)0; + fEngineControl->fTransport.RequestNewPos ( &new_pos ); + //jack_transport_locate(netj.client, (pkthdr->transport_frame)); + jack_info("transport is stopped locate to %d", pkthdr->transport_frame); + } + if (local_trans_state != JackTransportStopped) + //jack_transport_stop(netj.client); + fEngineControl->fTransport.SetCommand ( TransportCommandStop ); + break; + + case JackTransportRolling: + netj.sync_state = 1; + // if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * netj.period_size)) { + // jack_transport_locate(netj.client, (pkthdr->transport_frame + (pkthdr->latency + 2) * netj.period_size)); + // jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*netj.period_size); + // } + if (local_trans_state != JackTransportRolling) + fEngineControl->fTransport.SetState ( JackTransportRolling ); + break; + + case JackTransportLooping: + break; + } +#endif } - int JackNetOneDriver::Write() - { - int syncstate = netj.sync_state | ((fEngineControl->fTransport.GetState() == JackTransportNetStarting) ? 1 : 0 ); - uint32_t *packet_buf, *packet_bufX; + render_payload_to_jack_ports (netj.bitdepth, packet_bufX, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats ); + packet_cache_release_packet(netj.packcache, netj.expected_framecnt ); + return 0; +} + +int JackNetOneDriver::Write() +{ + int syncstate = netj.sync_state | ((fEngineControl->fTransport.GetState() == JackTransportNetStarting) ? 1 : 0 ); + uint32_t *packet_buf, *packet_bufX; - int packet_size = get_sample_size(netj.bitdepth) * netj.playback_channels * netj.net_period_up + sizeof(jacknet_packet_header); - jacknet_packet_header *pkthdr; + int packet_size = get_sample_size(netj.bitdepth) * netj.playback_channels * netj.net_period_up + sizeof(jacknet_packet_header); + jacknet_packet_header *pkthdr; - packet_buf = (uint32_t *) alloca(packet_size); - pkthdr = (jacknet_packet_header *)packet_buf; + packet_buf = (uint32_t *) alloca(packet_size); + pkthdr = (jacknet_packet_header *)packet_buf; - if( netj.running_free ) { - return 0; - } + if( netj.running_free ) { + return 0; + } - // offset packet_bufX by the packetheader. - packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); + // offset packet_bufX by the packetheader. + packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); - pkthdr->sync_state = syncstate;; - pkthdr->latency = netj.time_to_deadline; - //printf( "time to deadline = %d goodness=%d\n", (int)netj.time_to_deadline, netj.deadline_goodness ); - pkthdr->framecnt = netj.expected_framecnt; + pkthdr->sync_state = syncstate;; + pkthdr->latency = netj.time_to_deadline; + //printf( "time to deadline = %d goodness=%d\n", (int)netj.time_to_deadline, netj.deadline_goodness ); + pkthdr->framecnt = netj.expected_framecnt; - render_jack_ports_to_payload(netj.bitdepth, netj.playback_ports, netj.playback_srcs, netj.period_size, packet_bufX, netj.net_period_up, netj.dont_htonl_floats ); + render_jack_ports_to_payload(netj.bitdepth, netj.playback_ports, netj.playback_srcs, netj.period_size, packet_bufX, netj.net_period_up, netj.dont_htonl_floats ); - packet_header_hton(pkthdr); - if (netj.srcaddress_valid) - { - unsigned int r; - static const int flag = 0; + packet_header_hton(pkthdr); + if (netj.srcaddress_valid) { + unsigned int r; + static const int flag = 0; - if (netj.reply_port) + if (netj.reply_port) netj.syncsource_address.sin_port = htons(netj.reply_port); - for( r=0; rdata; - node = jack_slist_remove_link( node, this_node ); - jack_slist_free_1( this_node ); - fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); - } - netj.capture_ports = NULL; - - node = netj.playback_ports; - while( node != NULL ) { - JSList *this_node = node; - jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; - node = jack_slist_remove_link( node, this_node ); - jack_slist_free_1( this_node ); - fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); - } - netj.playback_ports = NULL; +void +JackNetOneDriver::FreePorts () +{ + JSList *node = netj.capture_ports; + + while( node != NULL ) { + JSList *this_node = node; + jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); + } + netj.capture_ports = NULL; + + node = netj.playback_ports; + while( node != NULL ) { + JSList *this_node = node; + jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); + } + netj.playback_ports = NULL; - if( netj.bitdepth == CELT_MODE ) { - #if HAVE_CELT + if( netj.bitdepth == CELT_MODE ) { +#if HAVE_CELT node = netj.playback_srcs; while( node != NULL ) { JSList *this_node = node; @@ -482,9 +473,9 @@ namespace Jack celt_decoder_destroy( dec ); } netj.capture_srcs = NULL; - #endif - } else { - #if HAVE_SAMPLERATE +#endif + } else { +#if HAVE_SAMPLERATE node = netj.playback_srcs; while( node != NULL ) { JSList *this_node = node; @@ -504,518 +495,487 @@ namespace Jack src_delete( state ); } netj.capture_srcs = NULL; - #endif - } +#endif } +} //Render functions-------------------------------------------------------------------- // render functions for float - void - JackNetOneDriver::render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) - { - uint32_t chn = 0; - JSList *node = capture_ports; - #if HAVE_SAMPLERATE - JSList *src_node = capture_srcs; - #endif +void +JackNetOneDriver::render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) +{ + uint32_t chn = 0; + JSList *node = capture_ports; +#if HAVE_SAMPLERATE + JSList *src_node = capture_srcs; +#endif - uint32_t *packet_bufX = (uint32_t *)packet_payload; + uint32_t *packet_bufX = (uint32_t *)packet_payload; - if( !packet_payload ) - return; + if( !packet_payload ) + return; - while (node != NULL) - { - unsigned int i; - int_float_t val; - #if HAVE_SAMPLERATE - SRC_DATA src; - #endif - jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; - JackPort *port = fGraphManager->GetPort( port_id ); + while (node != NULL) { + unsigned int i; + int_float_t val; +#if HAVE_SAMPLERATE + SRC_DATA src; +#endif + jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; + JackPort *port = fGraphManager->GetPort( port_id ); - jack_default_audio_sample_t* buf = - (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); + jack_default_audio_sample_t* buf = + (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); - const char *porttype = port->GetType(); + const char *porttype = port->GetType(); - if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) - { - #if HAVE_SAMPLERATE - // audio port, resample if necessary - if (net_period_down != nframes) - { - SRC_STATE *src_state = (SRC_STATE *)src_node->data; - for (i = 0; i < net_period_down; i++) - { - packet_bufX[i] = ntohl (packet_bufX[i]); - } + if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) { +#if HAVE_SAMPLERATE + // audio port, resample if necessary + if (net_period_down != nframes) { + SRC_STATE *src_state = (SRC_STATE *)src_node->data; + for (i = 0; i < net_period_down; i++) { + packet_bufX[i] = ntohl (packet_bufX[i]); + } - src.data_in = (float *) packet_bufX; - src.input_frames = net_period_down; + src.data_in = (float *) packet_bufX; + src.input_frames = net_period_down; - src.data_out = buf; - src.output_frames = nframes; + src.data_out = buf; + src.output_frames = nframes; - src.src_ratio = (float) nframes / (float) net_period_down; - src.end_of_input = 0; + src.src_ratio = (float) nframes / (float) net_period_down; + src.end_of_input = 0; - src_set_ratio (src_state, src.src_ratio); - src_process (src_state, &src); - src_node = jack_slist_next (src_node); - } - else - #endif - { - if( dont_htonl_floats ) - { - memcpy( buf, packet_bufX, net_period_down*sizeof(jack_default_audio_sample_t)); - } - else - { - for (i = 0; i < net_period_down; i++) - { - val.i = packet_bufX[i]; - val.i = ntohl (val.i); - buf[i] = val.f; - } + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); + src_node = jack_slist_next (src_node); + } else +#endif + { + if( dont_htonl_floats ) { + memcpy( buf, packet_bufX, net_period_down * sizeof(jack_default_audio_sample_t)); + } else { + for (i = 0; i < net_period_down; i++) { + val.i = packet_bufX[i]; + val.i = ntohl (val.i); + buf[i] = val.f; } } } - else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) - { - // midi port, decode midi events - // convert the data buffer to a standard format (uint32_t based) - unsigned int buffer_size_uint32 = net_period_down; - uint32_t * buffer_uint32 = (uint32_t*)packet_bufX; - decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); - } - packet_bufX = (packet_bufX + net_period_down); - node = jack_slist_next (node); - chn++; + } else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) { + // midi port, decode midi events + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_down; + uint32_t * buffer_uint32 = (uint32_t*)packet_bufX; + decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } + packet_bufX = (packet_bufX + net_period_down); + node = jack_slist_next (node); + chn++; + } } - void - JackNetOneDriver::render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ) - { - uint32_t chn = 0; - JSList *node = playback_ports; - #if HAVE_SAMPLERATE - JSList *src_node = playback_srcs; - #endif - - uint32_t *packet_bufX = (uint32_t *) packet_payload; - - while (node != NULL) - { - #if HAVE_SAMPLERATE - SRC_DATA src; - #endif - unsigned int i; - int_float_t val; - jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; - JackPort *port = fGraphManager->GetPort( port_id ); - - jack_default_audio_sample_t* buf = - (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); - - const char *porttype = port->GetType(); - - if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) - { - // audio port, resample if necessary +void +JackNetOneDriver::render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ) +{ + uint32_t chn = 0; + JSList *node = playback_ports; +#if HAVE_SAMPLERATE + JSList *src_node = playback_srcs; +#endif + + uint32_t *packet_bufX = (uint32_t *) packet_payload; - #if HAVE_SAMPLERATE - if (net_period_up != nframes) { - SRC_STATE *src_state = (SRC_STATE *) src_node->data; - src.data_in = buf; - src.input_frames = nframes; + while (node != NULL) { +#if HAVE_SAMPLERATE + SRC_DATA src; +#endif + unsigned int i; + int_float_t val; + jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; + JackPort *port = fGraphManager->GetPort( port_id ); - src.data_out = (float *) packet_bufX; - src.output_frames = net_period_up; + jack_default_audio_sample_t* buf = + (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); - src.src_ratio = (float) net_period_up / (float) nframes; - src.end_of_input = 0; + const char *porttype = port->GetType(); - src_set_ratio (src_state, src.src_ratio); - src_process (src_state, &src); + if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) { + // audio port, resample if necessary - for (i = 0; i < net_period_up; i++) - { - packet_bufX[i] = htonl (packet_bufX[i]); - } - src_node = jack_slist_next (src_node); +#if HAVE_SAMPLERATE + if (net_period_up != nframes) { + SRC_STATE *src_state = (SRC_STATE *) src_node->data; + src.data_in = buf; + src.input_frames = nframes; + + src.data_out = (float *) packet_bufX; + src.output_frames = net_period_up; + + src.src_ratio = (float) net_period_up / (float) nframes; + src.end_of_input = 0; + + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); + + for (i = 0; i < net_period_up; i++) { + packet_bufX[i] = htonl (packet_bufX[i]); } - else - #endif - { - if( dont_htonl_floats ) - { - memcpy( packet_bufX, buf, net_period_up*sizeof(jack_default_audio_sample_t) ); - } - else - { - for (i = 0; i < net_period_up; i++) - { - val.f = buf[i]; - val.i = htonl (val.i); - packet_bufX[i] = val.i; - } + src_node = jack_slist_next (src_node); + } else +#endif + { + if( dont_htonl_floats ) { + memcpy( packet_bufX, buf, net_period_up * sizeof(jack_default_audio_sample_t) ); + } else { + for (i = 0; i < net_period_up; i++) { + val.f = buf[i]; + val.i = htonl (val.i); + packet_bufX[i] = val.i; } } } - else if (strncmp(porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) - { - // encode midi events from port to packet - // convert the data buffer to a standard format (uint32_t based) - unsigned int buffer_size_uint32 = net_period_up; - uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; - encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); - } - packet_bufX = (packet_bufX + net_period_up); - node = jack_slist_next (node); - chn++; + } else if (strncmp(porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) { + // encode midi events from port to packet + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_up; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } + packet_bufX = (packet_bufX + net_period_up); + node = jack_slist_next (node); + chn++; } +} - #if HAVE_CELT - // render functions for celt. - void - JackNetOneDriver::render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes) - { - uint32_t chn = 0; - JSList *node = capture_ports; - JSList *src_node = capture_srcs; - unsigned char *packet_bufX = (unsigned char *)packet_payload; +#if HAVE_CELT +// render functions for celt. +void +JackNetOneDriver::render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes) +{ + uint32_t chn = 0; + JSList *node = capture_ports; + JSList *src_node = capture_srcs; + unsigned char *packet_bufX = (unsigned char *)packet_payload; - while (node != NULL) - { - jack_port_id_t port_id = (jack_port_id_t) (intptr_t)node->data; - JackPort *port = fGraphManager->GetPort( port_id ); + while (node != NULL) { + jack_port_id_t port_id = (jack_port_id_t) (intptr_t)node->data; + JackPort *port = fGraphManager->GetPort( port_id ); - jack_default_audio_sample_t* buf = - (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); + jack_default_audio_sample_t* buf = + (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); - const char *portname = port->GetType(); + const char *portname = port->GetType(); - if (strncmp(portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) - { - // audio port, decode celt data. - CELTDecoder *decoder = (CELTDecoder *)src_node->data; - - #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 - if( !packet_payload ) - celt_decode_float( decoder, NULL, net_period_down, buf, nframes ); - else - celt_decode_float( decoder, packet_bufX, net_period_down, buf, nframes ); - #else - if( !packet_payload ) - celt_decode_float( decoder, NULL, net_period_down, buf ); - else - celt_decode_float( decoder, packet_bufX, net_period_down, buf ); - #endif + if (strncmp(portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) { + // audio port, decode celt data. + CELTDecoder *decoder = (CELTDecoder *)src_node->data; - src_node = jack_slist_next (src_node); - } - else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) - { - // midi port, decode midi events - // convert the data buffer to a standard format (uint32_t based) - unsigned int buffer_size_uint32 = net_period_down / 2; - uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; +#if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 + if( !packet_payload ) + celt_decode_float( decoder, NULL, net_period_down, buf, nframes ); + else + celt_decode_float( decoder, packet_bufX, net_period_down, buf, nframes ); +#else + if( !packet_payload ) + celt_decode_float( decoder, NULL, net_period_down, buf ); + else + celt_decode_float( decoder, packet_bufX, net_period_down, buf ); +#endif + + src_node = jack_slist_next (src_node); + } else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) { + // midi port, decode midi events + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_down / 2; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; if( packet_payload ) decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); - } - packet_bufX = (packet_bufX + net_period_down); - node = jack_slist_next (node); - chn++; } + packet_bufX = (packet_bufX + net_period_down); + node = jack_slist_next (node); + chn++; } +} - void - JackNetOneDriver::render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up) - { - uint32_t chn = 0; - JSList *node = playback_ports; - JSList *src_node = playback_srcs; +void +JackNetOneDriver::render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up) +{ + uint32_t chn = 0; + JSList *node = playback_ports; + JSList *src_node = playback_srcs; - unsigned char *packet_bufX = (unsigned char *)packet_payload; + unsigned char *packet_bufX = (unsigned char *)packet_payload; - while (node != NULL) - { - jack_port_id_t port_id = (jack_port_id_t) (intptr_t) node->data; - JackPort *port = fGraphManager->GetPort( port_id ); + while (node != NULL) { + jack_port_id_t port_id = (jack_port_id_t) (intptr_t) node->data; + JackPort *port = fGraphManager->GetPort( port_id ); - jack_default_audio_sample_t* buf = - (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); + jack_default_audio_sample_t* buf = + (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); - const char *portname = port->GetType(); + const char *portname = port->GetType(); - if (strncmp (portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) - { - // audio port, encode celt data. + if (strncmp (portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) { + // audio port, encode celt data. int encoded_bytes; jack_default_audio_sample_t *floatbuf = (jack_default_audio_sample_t *)alloca (sizeof(jack_default_audio_sample_t) * nframes ); memcpy( floatbuf, buf, nframes * sizeof(jack_default_audio_sample_t) ); CELTEncoder *encoder = (CELTEncoder *)src_node->data; - #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 +#if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 encoded_bytes = celt_encode_float( encoder, floatbuf, nframes, packet_bufX, net_period_up ); #else encoded_bytes = celt_encode_float( encoder, floatbuf, NULL, packet_bufX, net_period_up ); #endif - if( encoded_bytes != (int)net_period_up ) - jack_error( "something in celt changed. netjack needs to be changed to handle this." ); + if( encoded_bytes != (int)net_period_up ) + jack_error( "something in celt changed. netjack needs to be changed to handle this." ); src_node = jack_slist_next( src_node ); - } - else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) - { - // encode midi events from port to packet - // convert the data buffer to a standard format (uint32_t based) - unsigned int buffer_size_uint32 = net_period_up / 2; - uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; - encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); - } - packet_bufX = (packet_bufX + net_period_up); - node = jack_slist_next (node); - chn++; + } else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) { + // encode midi events from port to packet + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_up / 2; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } + packet_bufX = (packet_bufX + net_period_up); + node = jack_slist_next (node); + chn++; } +} - #endif - /* Wrapper functions with bitdepth argument... */ - void - JackNetOneDriver::render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) - { - #if HAVE_CELT - if (bitdepth == CELT_MODE) - render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); - else - #endif - render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats); - } +#endif +/* Wrapper functions with bitdepth argument... */ +void +JackNetOneDriver::render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) +{ +#if HAVE_CELT + if (bitdepth == CELT_MODE) + render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); + else +#endif + render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats); +} - void - JackNetOneDriver::render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats) - { - #if HAVE_CELT - if (bitdepth == CELT_MODE) - render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); - else - #endif - render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats); - } +void +JackNetOneDriver::render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats) +{ +#if HAVE_CELT + if (bitdepth == CELT_MODE) + render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); + else +#endif + render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats); +} + +//driver loader----------------------------------------------------------------------- - //driver loader----------------------------------------------------------------------- - - #ifdef __cplusplus - extern "C" - { - #endif - SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor () - { - jack_driver_desc_t* desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) ); - jack_driver_param_desc_t * params; - - strcpy ( desc->name, "netone" ); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 - strcpy ( desc->desc, "netjack one slave backend component" ); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - - desc->nparams = 18; - params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) ); - - int i = 0; - strcpy (params[i].name, "audio-ins"); - params[i].character = 'i'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 2U; - strcpy (params[i].short_desc, "Number of capture channels (defaults to 2)"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "audio-outs"); - params[i].character = 'o'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 2U; - strcpy (params[i].short_desc, "Number of playback channels (defaults to 2)"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "midi-ins"); - params[i].character = 'I'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 1U; - strcpy (params[i].short_desc, "Number of midi capture channels (defaults to 1)"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "midi-outs"); - params[i].character = 'O'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 1U; - strcpy (params[i].short_desc, "Number of midi playback channels (defaults to 1)"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "rate"); - params[i].character = 'r'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 48000U; - strcpy (params[i].short_desc, "Sample rate"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "period"); - params[i].character = 'p'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 1024U; - strcpy (params[i].short_desc, "Frames per period"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "num-periods"); - params[i].character = 'n'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 5U; - strcpy (params[i].short_desc, +#ifdef __cplusplus +extern "C" +{ +#endif + SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor () + { + jack_driver_desc_t* desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) ); + jack_driver_param_desc_t * params; + + strcpy ( desc->name, "netone" ); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 + strcpy ( desc->desc, "netjack one slave backend component" ); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 + + desc->nparams = 18; + params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) ); + + int i = 0; + strcpy (params[i].name, "audio-ins"); + params[i].character = 'i'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 2U; + strcpy (params[i].short_desc, "Number of capture channels (defaults to 2)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "audio-outs"); + params[i].character = 'o'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 2U; + strcpy (params[i].short_desc, "Number of playback channels (defaults to 2)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "midi-ins"); + params[i].character = 'I'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, "Number of midi capture channels (defaults to 1)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "midi-outs"); + params[i].character = 'O'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, "Number of midi playback channels (defaults to 1)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "rate"); + params[i].character = 'r'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 48000U; + strcpy (params[i].short_desc, "Sample rate"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "period"); + params[i].character = 'p'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1024U; + strcpy (params[i].short_desc, "Frames per period"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "num-periods"); + params[i].character = 'n'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 5U; + strcpy (params[i].short_desc, "Network latency setting in no. of periods"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "listen-port"); - params[i].character = 'l'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 3000U; - strcpy (params[i].short_desc, + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "listen-port"); + params[i].character = 'l'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 3000U; + strcpy (params[i].short_desc, "The socket port we are listening on for sync packets"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "factor"); - params[i].character = 'f'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 1U; - strcpy (params[i].short_desc, + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "factor"); + params[i].character = 'f'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, "Factor for sample rate reduction"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "upstream-factor"); - params[i].character = 'u'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 0U; - strcpy (params[i].short_desc, + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "upstream-factor"); + params[i].character = 'u'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, "Factor for sample rate reduction on the upstream"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "celt"); - params[i].character = 'c'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 0U; - strcpy (params[i].short_desc, + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "celt"); + params[i].character = 'c'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, "sets celt encoding and number of kbits per channel"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "bit-depth"); - params[i].character = 'b'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 0U; - strcpy (params[i].short_desc, + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "bit-depth"); + params[i].character = 'b'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, "Sample bit-depth (0 for float, 8 for 8bit and 16 for 16bit)"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "transport-sync"); - params[i].character = 't'; - params[i].type = JackDriverParamBool; - params[i].value.ui = 1U; - strcpy (params[i].short_desc, + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "transport-sync"); + params[i].character = 't'; + params[i].type = JackDriverParamBool; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, "Whether to slave the transport to the master transport"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "autoconf"); - params[i].character = 'a'; - params[i].type = JackDriverParamBool; - params[i].value.ui = 1U; - strcpy (params[i].short_desc, + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "autoconf"); + params[i].character = 'a'; + params[i].type = JackDriverParamBool; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, "Whether to use Autoconfig, or just start."); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "redundancy"); - params[i].character = 'R'; - params[i].type = JackDriverParamUInt; - params[i].value.ui = 1U; - strcpy (params[i].short_desc, + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "redundancy"); + params[i].character = 'R'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, "Send packets N times"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "native-endian"); - params[i].character = 'e'; - params[i].type = JackDriverParamBool; - params[i].value.ui = 0U; - strcpy (params[i].short_desc, + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "native-endian"); + params[i].character = 'e'; + params[i].type = JackDriverParamBool; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, "Dont convert samples to network byte order."); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "jitterval"); - params[i].character = 'J'; - params[i].type = JackDriverParamInt; - params[i].value.i = 0; - strcpy (params[i].short_desc, + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "jitterval"); + params[i].character = 'J'; + params[i].type = JackDriverParamInt; + params[i].value.i = 0; + strcpy (params[i].short_desc, "attempted jitterbuffer microseconds on master"); - strcpy (params[i].long_desc, params[i].short_desc); - - i++; - strcpy (params[i].name, "always-deadline"); - params[i].character = 'D'; - params[i].type = JackDriverParamBool; - params[i].value.ui = 0U; - strcpy (params[i].short_desc, + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "always-deadline"); + params[i].character = 'D'; + params[i].type = JackDriverParamBool; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, "always use deadline"); - strcpy (params[i].long_desc, params[i].short_desc); + strcpy (params[i].long_desc, params[i].short_desc); - desc->params = params; + desc->params = params; - return desc; - } + return desc; + } - SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize ( Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params ) - { - jack_nframes_t sample_rate = 48000; - jack_nframes_t resample_factor = 1; - jack_nframes_t period_size = 1024; - unsigned int capture_ports = 2; - unsigned int playback_ports = 2; - unsigned int capture_ports_midi = 1; - unsigned int playback_ports_midi = 1; - unsigned int listen_port = 3000; - unsigned int bitdepth = 0; - unsigned int handle_transport_sync = 1; - unsigned int use_autoconfig = 1; - unsigned int latency = 5; - unsigned int redundancy = 1; - unsigned int mtu = 1400; - #if HAVE_SAMPLERATE - unsigned int resample_factor_up = 1; - #endif - int dont_htonl_floats = 0; - int always_deadline = 0; - int jitter_val = 0; - const JSList * node; - const jack_driver_param_t * param; - - for ( node = params; node; node = jack_slist_next ( node ) ) - { - param = ( const jack_driver_param_t* ) node->data; - switch ( param->character ) - { + SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize ( Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params ) + { + jack_nframes_t sample_rate = 48000; + jack_nframes_t resample_factor = 1; + jack_nframes_t period_size = 1024; + unsigned int capture_ports = 2; + unsigned int playback_ports = 2; + unsigned int capture_ports_midi = 1; + unsigned int playback_ports_midi = 1; + unsigned int listen_port = 3000; + unsigned int bitdepth = 0; + unsigned int handle_transport_sync = 1; + unsigned int use_autoconfig = 1; + unsigned int latency = 5; + unsigned int redundancy = 1; + unsigned int mtu = 1400; +#if HAVE_SAMPLERATE + unsigned int resample_factor_up = 1; +#endif + int dont_htonl_floats = 0; + int always_deadline = 0; + int jitter_val = 0; + const JSList * node; + const jack_driver_param_t * param; + + for ( node = params; node; node = jack_slist_next ( node ) ) { + param = ( const jack_driver_param_t* ) node->data; + switch ( param->character ) { case 'i': capture_ports = param->value.ui; break; @@ -1045,21 +1005,21 @@ namespace Jack break; case 'f': - #if HAVE_SAMPLERATE +#if HAVE_SAMPLERATE resample_factor = param->value.ui; - #else +#else jack_error( "not built with libsamplerate support" ); return NULL; - #endif +#endif break; case 'u': - #if HAVE_SAMPLERATE +#if HAVE_SAMPLERATE resample_factor_up = param->value.ui; - #else +#else jack_error( "not built with libsamplerate support" ); return NULL; - #endif +#endif break; case 'b': @@ -1067,13 +1027,13 @@ namespace Jack break; case 'c': - #if HAVE_CELT +#if HAVE_CELT bitdepth = CELT_MODE; resample_factor = param->value.ui; - #else +#else jack_error( "not built with celt support" ); return NULL; - #endif +#endif break; case 't': @@ -1103,38 +1063,32 @@ namespace Jack case 'D': always_deadline = param->value.ui; break; - } - } - - try - { - Jack::JackDriverClientInterface* driver = - new Jack::JackWaitThreadedDriver ( - new Jack::JackNetOneDriver ( "system", "net_pcm", engine, table, listen_port, mtu, - capture_ports_midi, playback_ports_midi, capture_ports, playback_ports, - sample_rate, period_size, resample_factor, - "net_pcm", handle_transport_sync, bitdepth, use_autoconfig, latency, redundancy, - dont_htonl_floats, always_deadline, jitter_val ) ); - - if ( driver->Open ( period_size, sample_rate, 1, 1, capture_ports, playback_ports, - 0, "from_master_", "to_master_", 0, 0 ) == 0 ) - { - return driver; - } - else - { - delete driver; - return NULL; - } + } + } - } - catch ( ... ) - { - return NULL; - } + try { + Jack::JackDriverClientInterface* driver = + new Jack::JackWaitThreadedDriver ( + new Jack::JackNetOneDriver ( "system", "net_pcm", engine, table, listen_port, mtu, + capture_ports_midi, playback_ports_midi, capture_ports, playback_ports, + sample_rate, period_size, resample_factor, + "net_pcm", handle_transport_sync, bitdepth, use_autoconfig, latency, redundancy, + dont_htonl_floats, always_deadline, jitter_val ) ); + + if ( driver->Open ( period_size, sample_rate, 1, 1, capture_ports, playback_ports, + 0, "from_master_", "to_master_", 0, 0 ) == 0 ) { + return driver; + } else { + delete driver; + return NULL; } - #ifdef __cplusplus + } catch ( ... ) { + return NULL; } - #endif + } + +#ifdef __cplusplus +} +#endif } diff --git a/common/JackNetOneDriver.h b/common/JackNetOneDriver.h index 348b4628..577c2f6f 100644 --- a/common/JackNetOneDriver.h +++ b/common/JackNetOneDriver.h @@ -27,72 +27,69 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { - /** - \Brief This class describes the Net Backend - */ - - class JackNetOneDriver : public JackAudioDriver - { - private: - - netjack_driver_state_t netj; - - void - render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats); - void - render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ); - #ifdef HAVE_CELT - void - render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes); - void - render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up); - #endif - void - render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats); - void - render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats); - - public: - - JackNetOneDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, - int port, int mtu, int capture_ports, int playback_ports, int midi_input_ports, int midi_output_ports, - int sample_rate, int period_size, int resample_factor, - const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig, - int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val ); - ~JackNetOneDriver(); - - int Open ( jack_nframes_t frames_per_cycle, jack_nframes_t rate, bool capturing, bool playing, - int inchannels, int outchannels, bool monitor, const char* capture_driver_name, - const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency ); - - int Close(); - int Attach(); - int Detach(); - - int Read(); - int Write(); - - bool Initialize(); - int AllocPorts(); - void FreePorts(); - - // BufferSize can't be changed - bool IsFixedBufferSize() - { - return true; - } - - int SetBufferSize ( jack_nframes_t buffer_size ) - { - return -1; - } - - int SetSampleRate ( jack_nframes_t sample_rate ) - { - return -1; - } - - }; +/** +\Brief This class describes the Net Backend +*/ + +class JackNetOneDriver : public JackAudioDriver +{ + private: + + netjack_driver_state_t netj; + + void + render_payload_to_jack_ports_float(void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats); + void + render_jack_ports_to_payload_float(JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ); +#ifdef HAVE_CELT + void + render_payload_to_jack_ports_celt(void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes); + void + render_jack_ports_to_payload_celt(JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up); +#endif + void + render_payload_to_jack_ports(int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats); + void + render_jack_ports_to_payload(int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats); + + public: + + JackNetOneDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, + int port, int mtu, int capture_ports, int playback_ports, int midi_input_ports, int midi_output_ports, + int sample_rate, int period_size, int resample_factor, + const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig, + int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val); + ~JackNetOneDriver(); + + int Open(jack_nframes_t frames_per_cycle, jack_nframes_t rate, bool capturing, bool playing, + int inchannels, int outchannels, bool monitor, const char* capture_driver_name, + const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency); + + int Close(); + int Attach(); + int Detach(); + + int Read(); + int Write(); + + bool Initialize(); + int AllocPorts(); + void FreePorts(); + + // BufferSize can't be changed + bool IsFixedBufferSize() { + return true; + } + + int SetBufferSize(jack_nframes_t buffer_size) { + return -1; + } + + int SetSampleRate(jack_nframes_t sample_rate) { + return -1; + } + +}; } #endif From fdcb49c06345643eefd6fa32eb954e1d118fc1eb Mon Sep 17 00:00:00 2001 From: sletz Date: Fri, 1 Apr 2011 14:30:21 +0000 Subject: [PATCH 122/472] Correction in jackdmp.cpp: notify_server_stop should be done after server destruction. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4248 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 1 + README | 2 +- common/JackExternalClient.cpp | 1 + common/JackWaitThreadedDriver.h | 2 +- common/Jackdmp.cpp | 6 +++--- posix/JackSocketServerChannel.cpp | 2 +- windows/JackWinNamedPipeServerChannel.cpp | 2 +- 7 files changed, 9 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7dc08efa..10bae97c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -39,6 +39,7 @@ Valerio Pilo * Merge newer-midi branch (Devin Anderson redesign of the MIDI drivers: alsarawmidi, ffado, coremidi and winmme). * Cleanup JackThreadedDriver::Stop. * Correct JackNetOneDriver::Close. + * Correction in jackdmp.cpp: notify_server_stop should be done after server destruction. 2011-03-30 Stephane Letz diff --git a/README b/README index beaa700b..1b35ab15 100644 --- a/README +++ b/README @@ -212,7 +212,7 @@ Note : To experiment with the -S option, jackdmp must be launched in a console. 1.9.4 : Solaris boomer backend now working in capture or playback only mode. Add a -G parameter in CoreAudio backend (the computation value in RT thread expressed as percent of period). Use SNDCTL_DSP_SYNCGROUP/SNDCTL_DSP_SYNCSTART API to synchronize input and output in Solaris boomer backend. Big endian bug fix in memops.c. Fix issues in JackNetDriver::DecodeTransportData and JackNetDriver::Initialize. Correct CPU timing in JackNetDriver, now take cycle begin time after Read. Simplify transport in NetJack2: master only can control transport. Change CoreAudio notification thread setup for OSX Snow Leopard. Correct server temporary mode : now set a global and quit after server/client message handling is finished. Add a string parameter to server ==> client notification, add a new JackInfoShutdownCallback type. CoreAudio backend now issue a JackInfoShutdownCallback when an unrecoverable error is detected (sampling rate change, stream configuration changeÉ). Correct jackdmp.cpp (failures case were not correct..). Improve JackCoreAudioDriver code. Raise default port number to 2048. Correct JackProcessSync::LockedTimedWait. Correct JACK_MESSAGE_SIZE value, particularly in OSX RPC code. Now start server channel thread only when backend has been started (so in JackServer::Start). Should solve race conditions at start time. jack_verbose moved to JackGlobals class. Improve aggregate device management in JackCoreAudioDriver : now a "private" device only and cleanup properly. Aggregate device code added to JackCoreAudioAdapter. Implement "hog mode" (exclusive access of the audio device) in JackCoreAudioDriver. Fix jack_set_sample_rate_callback to have he same behavior as in JACK1. Dynamic system version detection in JackCoreAudioDriver to either create public or private aggregate device. In JackCoreAudioDriver, force the SR value to the wanted one *before* creating aggregate device (otherwise creation will fail). In JackCoreAudioDriver, better cleanup of AD when intermediate open failure. In JackCoreAudioDriver::Start, wait for the audio driver to effectively start (use the MeasureCallback). In JackCoreAudioDriver, improve management of input/output channels: -1 is now used internally to indicate a wanted max value. In JackCoreAudioDriver::OpenAUHAL, correct stream format setup and cleanup. Correct crash bug in JackAudioAdapterInterface when not input is used in adapter (temporary fixÉ). Sync JackCoreAudioAdapter code on JackCoreAudioDriver one. JACK_SCHED_POLICY switched to SCHED_FIFO. Now can aggregate device that are themselves AD. No reason to make jack_on_shutdown deprecated, so revert the incorrect change. Thread AcquireRealTime and DropRealTime were (incorrectly) using fThread field. Use pthread_self()) (or GetCurrentThread() on Windows) to get the calling thread. Correctly save and restore RT mode state in freewheel mode. Correct freewheel code on client side. Fix AcquireRealTime and DropRealTime: now distinguish when called from another thread (AcquireRealTime/DropRealTime) and from the thread itself (AcquireSelfRealTime/DropSelfRealTime). Correct JackPosixThread::StartImp : thread priority setting now done in the RT case only. Correct JackGraphManager::GetBuffer for the "client loop with one connection" case : buffer must be copied. Correct JackInfoShutdownCallback prototype, two new JackClientProcessFailure and JackClientZombie JackStatus code. Correct JackCoreAudio driver when empty strings are given as -C, -P or -d parameter. Better memory allocation error checking on client (library) side. Better memory allocation error checking in ringbuffer.c, weak import improvements. Memory allocation error checking for jack_client_new and jack_client_open (server and client side). Memory allocation error checking in server for RPC. Simplify server temporary mode : now use a JackTemporaryException. Lock/Unlock shared memory segments (to test...). Sync with JACK1 : -r parameter now used for no-realtime, realtime (-R) is now default, usable backend given vie platform. In JackCoreAudio driver, (possibly) clock drift compensation when needed in aggregated devices. In JackCoreAudio driver, clock drift compensation in aggregated devices working. In JackCoreAudio driver, clock drift compensation semantic changed a bit : when on, does not activate if not needed (same clock domain). Sync JackCoreAudioAdapter code with JackCoreAudioDriver. 1.9.5 : Dynamic choice of maximum port number. More robust sample rate change handling code in JackCoreAudioDriver. Devin Anderson patch for Jack FFADO driver issues with lost MIDI bytes between periods (and more). Fix port_rename callback : now both old name and new name are given as parameters. Special code in JackCoreAudio driver to handle completely buggy Digidesign CoreAudio user-land driver. Ensure that client-side message buffer thread calls thread_init callback if/when it is set by the client (backport of JACK1 rev 3838). Check dynamic port-max value. Fix JackCoreMidiDriver::ReadProcAux when ring buffer is full (thanks Devin Anderson). Josh Green ALSA driver capture only patch. When threads are cancelled, the exception has to be rethrown. Use a QUIT notification to properly quit the server channel, the server channel thread can then be 'stopped' instead of 'canceled'. Mario Lang alsa_io time calculation overflow patch. Shared memory manager was calling abort in case of fatal error, now return an error in caller. Change JackEngineProfiling and JackAudioAdapterInterface gnuplot scripts to output SVG instead of PDF. 1.9.6 : Improve JackCoreAudioDriver and JackCoreAudioAdapter : when no devices are described, takes default input and output and aggregate them.Correct JackGraphManager::DeactivatePort. Correct JackMachServerChannel::Execute : keep running even in error cases. Raise JACK_PROTOCOL_VERSION number. Arnold Krille firewire patch. Raise JACK_DRIVER_PARAM_STRING_MAX and JACK_PARAM_STRING_MAX to 127 otherwise some audio drivers cannot be loaded on OSX. Fix some file header to have library side code use LGPL. On Windows, now use TRE library for regexp (BSD license instead of GPL license). ffado-portname-sync.patch from ticket #163 applied. Remove call to exit in library code. Make jack_connect/jack_disconnect wait for effective port connection/disconnection. Add tests to validate intclient.h API. On Linux, inter-process synchronization primitive switched to POSIX semaphore. In JackCoreAudioDriver, move code called in MeasureCallback to be called once in IO thread. David Garcia Garzon netone patch. Fix from Fernando Lopez-Lezcano for compilation on fc13. Fix JackPosixSemaphore::TimedWait : same behavior as JackPosixSemaphore::Wait regarding EINTR. David Garcia Garzon unused_pkt_buf_field_jack2 netone patch. Arnold Krille firewire snooping patch. Jan Engelhardt patch for get_cycles on SPARC. Adrian Knoth hurd.patch, kfreebsd-fix.patch and alpha_ia64-sigsegv.patch from ticket 177. Adrian Knoth fix for linux cycle.h (ticket 188). In JackCoreAudioDriver, fix an issue when no value is given for input. -1.9.7 : Sync JackAlsaDriver::alsa_driver_check_card_type with JACK1 backend. Correct JackServer::Open to avoid a race when control API is used on OSX. Improve backend error handling: fatal error returned by Read/Write now cause a Process failure (so a thread exit for blocking backends). Recoverable ones (XRuns..) are now treated internally in ALSA, FreeBob and FFADO backends. In jackdmp.cpp, jackctl_setup_signals moved before jackctl_server_start. Correct symbols export in backends on OSX. ALSA backend : suspend/resume handling. Correct dummy driver. Adrian Knoth jack_lsp patch. Remove JackPortIsActive flag. New latency API implementation. ComputeTotalLatencies now a client/server call. Add latent test client for latency API. Also print playback and capture latency in jack_lsp. jack_client_has_session_callback implementation. Check requested buffer size and limit to 1..8192 - avoids weird behaviour caused by jack_bufsize foobar. jack_port_type_get_buffer_size implementation. Stop using alloca and allocate buffer on the heap for alsa_io. Rename jdelay to jack_iodelay as per Fons' request. Call buffer size callback in activate (actually this is done on client side in the RT thread Init method). Add jack_midi_dump client. Synchronize net JACK1 with JACK1 version. Synchronize jack_connect/jack_disconnect with JACK1 version. Correct JackNetMaster::SetBufferSize. Use jack_default_audio_sample_t instead of float consistently, fix ticket #201. -X now allows to add several slave backends, add -I to load several internal clients. Rework internal slave driver management, JackServerGlobals now handle same parameters as jackdmp. Correct JackEngine::NotifyGraphReorder, update JackDebugClient with latest API. Devin Anderson server-ctl-proposal branch merged on trunk: improved control API, slave backend reworked. Implement renaming in JackDriver::Open to avoid name collision (thanks Devin Anderson). Correct alsa_driver_restart (thanks Devin Anderson). Correction of jack_connect/jack_disconnect: use of jack_activate and volatile keyword for thread shared variable. Correction of JackNetOneDriver for latest CELT API. Synchronize JackWeakAPI.cpp with new APIs. +1.9.7 : Sync JackAlsaDriver::alsa_driver_check_card_type with JACK1 backend. Correct JackServer::Open to avoid a race when control API is used on OSX. Improve backend error handling: fatal error returned by Read/Write now cause a Process failure (so a thread exit for blocking backends). Recoverable ones (XRuns..) are now treated internally in ALSA, FreeBob and FFADO backends. In jackdmp.cpp, jackctl_setup_signals moved before jackctl_server_start. Correct symbols export in backends on OSX. ALSA backend : suspend/resume handling. Correct dummy driver. Adrian Knoth jack_lsp patch. Remove JackPortIsActive flag. New latency API implementation. ComputeTotalLatencies now a client/server call. Add latent test client for latency API. Also print playback and capture latency in jack_lsp. jack_client_has_session_callback implementation. Check requested buffer size and limit to 1..8192 - avoids weird behaviour caused by jack_bufsize foobar. jack_port_type_get_buffer_size implementation. Stop using alloca and allocate buffer on the heap for alsa_io. Rename jdelay to jack_iodelay as per Fons' request. Call buffer size callback in activate (actually this is done on client side in the RT thread Init method). Add jack_midi_dump client. Synchronize net JACK1 with JACK1 version. Synchronize jack_connect/jack_disconnect with JACK1 version. Correct JackNetMaster::SetBufferSize. Use jack_default_audio_sample_t instead of float consistently, fix ticket #201. -X now allows to add several slave backends, add -I to load several internal clients. Rework internal slave driver management, JackServerGlobals now handle same parameters as jackdmp. Correct JackEngine::NotifyGraphReorder, update JackDebugClient with latest API. Devin Anderson server-ctl-proposal branch merged on trunk: improved control API, slave backend reworked. Implement renaming in JackDriver::Open to avoid name collision (thanks Devin Anderson). Correct alsa_driver_restart (thanks Devin Anderson). Correction of jack_connect/jack_disconnect: use of jack_activate and volatile keyword for thread shared variable. Correction of JackNetOneDriver for latest CELT API. Synchronize JackWeakAPI.cpp with new APIs. This is a work in progress but the implementation is now stable enough to be tested. jackdmp has been used successfully with the following applications : Ardour, Hydrogen, Jamin, QjackCtl, Jack-Rack, SooperLooper, AlsaPlayer... diff --git a/common/JackExternalClient.cpp b/common/JackExternalClient.cpp index 1dca599a..54342f97 100644 --- a/common/JackExternalClient.cpp +++ b/common/JackExternalClient.cpp @@ -71,6 +71,7 @@ int JackExternalClient::Open(const char* name, int pid, int refnum, int uuid, in int JackExternalClient::Close() { + jack_log("JackExternalClient::Close"); fChannel.Close(); if (fClientControl) { fClientControl->~JackClientControl(); diff --git a/common/JackWaitThreadedDriver.h b/common/JackWaitThreadedDriver.h index f81db20c..0ef3d070 100644 --- a/common/JackWaitThreadedDriver.h +++ b/common/JackWaitThreadedDriver.h @@ -44,7 +44,7 @@ class SERVER_EXPORT JackWaitThreadedDriver : public JackThreadedDriver JackDriver* fDriver; JackThread fThread; - bool fRunning; + volatile bool fRunning; JackDriverStarter(JackDriver* driver) :fDriver(driver),fThread(this),fRunning(false) diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index 9123b3c7..f0651ab9 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -532,12 +532,12 @@ int main(int argc, char* argv[]) if (! jackctl_server_stop(server_ctl)) { fprintf(stderr, "Cannot stop server...\n"); } - if (notify_sent) { - notify_server_stop(server_name); - } close_server: jackctl_server_close(server_ctl); destroy_server: jackctl_server_destroy(server_ctl); + if (notify_sent) { + notify_server_stop(server_name); + } return return_value; } diff --git a/posix/JackSocketServerChannel.cpp b/posix/JackSocketServerChannel.cpp index 3008e307..2c5f267e 100644 --- a/posix/JackSocketServerChannel.cpp +++ b/posix/JackSocketServerChannel.cpp @@ -571,7 +571,7 @@ bool JackSocketServerChannel::Execute() return true; } catch (JackQuitException& e) { - jack_log("JackMachServerChannel::Execute JackQuitException"); + jack_log("JackSocketServerChannel::Execute JackQuitException"); return false; } } diff --git a/windows/JackWinNamedPipeServerChannel.cpp b/windows/JackWinNamedPipeServerChannel.cpp index 3723af5e..fd5a8eda 100644 --- a/windows/JackWinNamedPipeServerChannel.cpp +++ b/windows/JackWinNamedPipeServerChannel.cpp @@ -85,7 +85,7 @@ bool JackClientPipeThread::Execute() jack_log("JackClientPipeThread::Execute"); return (HandleRequest()); } catch (JackQuitException& e) { - jack_log("JackMachServerChannel::Execute JackQuitException"); + jack_log("JackClientPipeThread::Execute JackQuitException"); return false; } } From e03d1ddd44085572d6072e38606a98576b70772d Mon Sep 17 00:00:00 2001 From: sletz Date: Fri, 1 Apr 2011 16:08:48 +0000 Subject: [PATCH 123/472] Improve error management in JackNetDriver. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4249 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 1 + common/JackAudioDriver.cpp | 21 ++++++--- common/JackNetDriver.cpp | 11 ++--- common/JackNetInterface.cpp | 80 ++++++++++++++++----------------- common/JackNetTool.cpp | 2 + common/JackWaitThreadedDriver.h | 41 +++++++++-------- 6 files changed, 86 insertions(+), 70 deletions(-) diff --git a/ChangeLog b/ChangeLog index 10bae97c..ba91b540 100644 --- a/ChangeLog +++ b/ChangeLog @@ -40,6 +40,7 @@ Valerio Pilo * Cleanup JackThreadedDriver::Stop. * Correct JackNetOneDriver::Close. * Correction in jackdmp.cpp: notify_server_stop should be done after server destruction. + * Improve error management in JackNetDriver. 2011-03-30 Stephane Letz diff --git a/common/JackAudioDriver.cpp b/common/JackAudioDriver.cpp index f284a8cf..31b8a51b 100644 --- a/common/JackAudioDriver.cpp +++ b/common/JackAudioDriver.cpp @@ -82,6 +82,9 @@ int JackAudioDriver::Open(jack_nframes_t buffer_size, fCaptureChannels = inchannels; fPlaybackChannels = outchannels; fWithMonitorPorts = monitor; + memset(fCapturePortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); + memset(fPlaybackPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); + memset(fMonitorPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); return JackDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); } @@ -98,6 +101,9 @@ int JackAudioDriver::Open(bool capturing, fCaptureChannels = inchannels; fPlaybackChannels = outchannels; fWithMonitorPorts = monitor; + memset(fCapturePortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); + memset(fPlaybackPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); + memset(fMonitorPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); return JackDriver::Open(capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); } @@ -389,20 +395,23 @@ void JackAudioDriver::WaitUntilNextCycle() jack_default_audio_sample_t* JackAudioDriver::GetInputBuffer(int port_index) { - assert(fCapturePortList[port_index]); - return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[port_index], fEngineControl->fBufferSize); + return fCapturePortList[port_index] + ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[port_index], fEngineControl->fBufferSize) + : NULL; } jack_default_audio_sample_t* JackAudioDriver::GetOutputBuffer(int port_index) { - assert(fPlaybackPortList[port_index]); - return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[port_index], fEngineControl->fBufferSize); + return fPlaybackPortList[port_index] + ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[port_index], fEngineControl->fBufferSize) + : NULL; } jack_default_audio_sample_t* JackAudioDriver::GetMonitorBuffer(int port_index) { - assert(fPlaybackPortList[port_index]); - return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[port_index], fEngineControl->fBufferSize); + return fPlaybackPortList[port_index] + ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[port_index], fEngineControl->fBufferSize) + : NULL; } int JackAudioDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index 66e4f7dd..b52a8a07 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -142,8 +142,10 @@ namespace Jack ( fParams.fSlaveSyncMode ) ? "sync" : "async", ( fParams.fTransportSync ) ? "with" : "without" ); //init network - if ( !JackNetSlaveInterface::Init() ) + if (!JackNetSlaveInterface::Init()) { + jack_error("Starting network fails..."); return false; + } //set global parameters SetParams(); @@ -163,14 +165,13 @@ namespace Jack } //register jack ports - if ( AllocPorts() != 0 ) - { - jack_error ( "Can't allocate ports." ); + if (AllocPorts() != 0) { + jack_error("Can't allocate ports."); return false; } //init done, display parameters - SessionParamsDisplay ( &fParams ); + SessionParamsDisplay(&fParams); //monitor #ifdef JACK_MONITOR diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index b794e8bf..f8e5dd5f 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -24,9 +24,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. using namespace std; -/* - TODO : since midi buffers now uses up to BUFFER_SIZE_MAX frames, - probably also use BUFFER_SIZE_MAX in everything related to MIDI events +/* + TODO : since midi buffers now uses up to BUFFER_SIZE_MAX frames, + probably also use BUFFER_SIZE_MAX in everything related to MIDI events handling (see MidiBufferInit in JackMidiPort.cpp) */ @@ -212,7 +212,7 @@ namespace Jack //timeout on receive (for init) if ( fSocket.SetTimeOut ( MASTER_INIT_TIMEOUT ) < 0 ) jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) ); - + //connect if ( fSocket.Connect() == SOCKET_ERROR ) { jack_error ( "Can't connect : %s", StrError ( NET_ERROR_CODE ) ); @@ -230,17 +230,17 @@ namespace Jack memset(&net_params, 0, sizeof ( session_params_t )); SetPacketType ( &fParams, SLAVE_SETUP ); SessionParamsHToN(&fParams, &net_params); - + if ( fSocket.Send ( &net_params, sizeof ( session_params_t ), 0 ) == SOCKET_ERROR ) jack_error ( "Error in send : ", StrError ( NET_ERROR_CODE ) ); - + memset(&net_params, 0, sizeof ( session_params_t )); if ( ( ( rx_bytes = fSocket.Recv ( &net_params, sizeof ( session_params_t ), 0 ) ) == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) ) { jack_error ( "Problem with network." ); return false; } - + SessionParamsNToH(&net_params, &host_params); } while ( ( GetPacketType ( &host_params ) != START_MASTER ) && ( ++attempt < SLAVE_SETUP_RETRY ) ); @@ -315,7 +315,7 @@ namespace Jack jack_info ( "Exiting '%s'", fParams.fName ); SetPacketType ( &fParams, KILL_MASTER ); JackNetSocket mcast_socket ( fMulticastIP, fSocket.GetPort() ); - + session_params_t net_params; memset(&net_params, 0, sizeof ( session_params_t )); SessionParamsHToN(&fParams, &net_params); @@ -324,7 +324,7 @@ namespace Jack jack_error ( "Can't create socket : %s", StrError ( NET_ERROR_CODE ) ); if ( mcast_socket.SendTo ( &net_params, sizeof ( session_params_t ), 0, fMulticastIP ) == SOCKET_ERROR ) jack_error ( "Can't send suicide request : %s", StrError ( NET_ERROR_CODE ) ); - + mcast_socket.Close(); } @@ -343,25 +343,25 @@ namespace Jack jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) ); //ask to the manager to properly remove the master Exit(); - + // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine. ThreadExit(); } else jack_error ( "Error in master receive : %s", StrError ( NET_ERROR_CODE ) ); } - + packet_header_t* header = reinterpret_cast(fRxBuffer); PacketHeaderNToH(header, header); return rx_bytes; } - + int JackNetMasterInterface::Send ( size_t size, int flags ) { int tx_bytes; packet_header_t* header = reinterpret_cast(fTxBuffer); PacketHeaderHToN(header, header); - + if ( ( ( tx_bytes = fSocket.Send ( fTxBuffer, size, flags ) ) == SOCKET_ERROR ) && fRunning ) { net_error_t error = fSocket.GetError(); @@ -370,7 +370,7 @@ namespace Jack //fatal connection issue, exit jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) ); Exit(); - + // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine. ThreadExit(); } @@ -379,7 +379,7 @@ namespace Jack } return tx_bytes; } - + bool JackNetMasterInterface::IsSynched() { if (fParams.fNetworkMode == 's') { @@ -388,7 +388,7 @@ namespace Jack return true; } } - + int JackNetMasterInterface::SyncSend() { fTxHeader.fCycle++; @@ -446,12 +446,12 @@ namespace Jack { packet_header_t* rx_head = reinterpret_cast ( fRxBuffer ); int rx_bytes = Recv ( fParams.fMtu, MSG_PEEK ); - + if ( ( rx_bytes == 0 ) || ( rx_bytes == SOCKET_ERROR ) ) return rx_bytes; fCycleOffset = fTxHeader.fCycle - rx_head->fCycle; - + switch ( fParams.fNetworkMode ) { case 's' : @@ -464,7 +464,7 @@ namespace Jack return 0; else rx_bytes = Recv ( rx_head->fPacketSize, 0 ); - + if (fCycleOffset > 2) { jack_info("Warning : '%s' runs in slow network mode, but data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); } @@ -479,8 +479,8 @@ namespace Jack return 0; else rx_bytes = Recv ( rx_head->fPacketSize, 0 ); - - if (fCycleOffset != 1) + + if (fCycleOffset != 1) jack_info("'%s' can't run in normal network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); break; @@ -490,7 +490,7 @@ namespace Jack // - here, receive data, we can't keep it queued on the rx buffer, // - but if there is a cycle offset, tell the user, that means we're not in fast mode anymore, network is too slow rx_bytes = Recv ( rx_head->fPacketSize, 0 ); - + if (fCycleOffset != 0) jack_info("'%s' can't run in fast network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); break; @@ -499,7 +499,7 @@ namespace Jack fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; return rx_bytes; } - + int JackNetMasterInterface::DataRecv() { int rx_bytes = 0; @@ -507,12 +507,12 @@ namespace Jack uint recvd_midi_pckt = 0; uint recvd_audio_pckt = 0; packet_header_t* rx_head = reinterpret_cast ( fRxBuffer ); - + while ( !fRxHeader.fIsLastPckt ) { //how much data is queued on the rx buffer ? rx_bytes = Recv ( fParams.fMtu, MSG_PEEK ); - + if ( rx_bytes == SOCKET_ERROR ) return rx_bytes; //if no data @@ -564,7 +564,7 @@ namespace Jack } return rx_bytes; } - + void JackNetMasterInterface::EncodeSyncPacket() { //this method contains every step of sync packet informations coding @@ -632,9 +632,9 @@ namespace Jack return true; } - + // Separate the connection protocol into two separated step - + bool JackNetSlaveInterface::InitConnection() { jack_log ( "JackNetSlaveInterface::InitConnection()" ); @@ -653,10 +653,10 @@ namespace Jack return false; } while (status != NET_CONNECTED); - + return true; } - + bool JackNetSlaveInterface::InitRendering() { jack_log("JackNetSlaveInterface::InitRendering()"); @@ -670,8 +670,8 @@ namespace Jack if (status == NET_ERROR) return false; } - while (status != NET_ROLLING); - + while (status != NET_ROLLING); + return true; } @@ -695,7 +695,7 @@ namespace Jack } //timeout on receive - if ( fSocket.SetTimeOut ( SLAVE_INIT_TIMEOUT ) == SOCKET_ERROR ) + if ( fSocket.SetTimeOut ( SLAVE_INIT_TIMEOUT ) == SOCKET_ERROR ) jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) ); //disable local loop @@ -712,7 +712,7 @@ namespace Jack SessionParamsHToN(&fParams, &net_params); if ( fSocket.SendTo ( &net_params, sizeof ( session_params_t ), 0, fMulticastIP ) == SOCKET_ERROR ) jack_error ( "Error in data send : %s", StrError ( NET_ERROR_CODE ) ); - + //filter incoming packets : don't exit while no error is detected memset(&net_params, 0, sizeof ( session_params_t )); rx_bytes = fSocket.CatchHost ( &net_params, sizeof ( session_params_t ), 0 ); @@ -762,7 +762,7 @@ namespace Jack void JackNetSlaveInterface::SetParams() { - jack_log ( "JackNetSlaveInterface::SetParams" ); + jack_log("JackNetSlaveInterface::SetParams"); JackNetInterface::SetParams(); @@ -801,7 +801,7 @@ namespace Jack else jack_error ( "Fatal error in slave receive : %s", StrError ( NET_ERROR_CODE ) ); } - + packet_header_t* header = reinterpret_cast(fRxBuffer); PacketHeaderNToH(header, header); return rx_bytes; @@ -812,7 +812,7 @@ namespace Jack packet_header_t* header = reinterpret_cast(fTxBuffer); PacketHeaderHToN(header, header); int tx_bytes = fSocket.Send ( fTxBuffer, size, flags ); - + //handle errors if ( tx_bytes == SOCKET_ERROR ) { @@ -842,7 +842,7 @@ namespace Jack return rx_bytes; } while ((strcmp(rx_head->fPacketType, "header") != 0) && (rx_head->fDataType != 's')); - + fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; return rx_bytes; } @@ -953,7 +953,7 @@ namespace Jack } return 0; } - + //network sync------------------------------------------------------------------------ void JackNetSlaveInterface::EncodeSyncPacket() { @@ -970,7 +970,7 @@ namespace Jack //then others //... } - + void JackNetSlaveInterface::DecodeSyncPacket() { //this method contains every step of sync packet informations decoding process diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index 6adbd471..82aa01ad 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -151,11 +151,13 @@ namespace Jack void NetAudioBuffer::SetBuffer ( int index, sample_t* buffer ) { + assert(fPortBuffer); fPortBuffer[index] = buffer; } sample_t* NetAudioBuffer::GetBuffer ( int index ) { + assert(fPortBuffer); return fPortBuffer[index]; } diff --git a/common/JackWaitThreadedDriver.h b/common/JackWaitThreadedDriver.h index 0ef3d070..990065f4 100644 --- a/common/JackWaitThreadedDriver.h +++ b/common/JackWaitThreadedDriver.h @@ -26,11 +26,11 @@ namespace Jack { - + /*! -\brief To be used as a wrapper of JackNetDriver. +\brief To be used as a wrapper of JackNetDriver. -The idea is to behave as the "dummy" driver, until the network connection is really started and processing starts. +The idea is to behave as the "dummy" driver, until the network connection is really started and processing starts. The Execute method will call the ProcessNull method until the decorated driver Init method returns. A helper JackDriverStarter thread is used for that purpose. */ @@ -38,54 +38,57 @@ A helper JackDriverStarter thread is used for that purpose. class SERVER_EXPORT JackWaitThreadedDriver : public JackThreadedDriver { private: - - struct SERVER_EXPORT JackDriverStarter : public JackRunnableInterface + + struct SERVER_EXPORT JackDriverStarter : public JackRunnableInterface { - + JackDriver* fDriver; JackThread fThread; volatile bool fRunning; - + JackDriverStarter(JackDriver* driver) :fDriver(driver),fThread(this),fRunning(false) {} - + ~JackDriverStarter() { fThread.Kill(); } - + int Start() { fRunning = false; return fThread.Start(); } - + // JackRunnableInterface interface bool Execute() { // Blocks until decorated driver is started (that is when it's Init method returns). - fDriver->Initialize(); - fRunning = true; + if (fDriver->Initialize()) { + fRunning = true; + } else { + jack_error("Initing net driver fails..."); + } return false; } - + }; - + JackDriverStarter fStarter; - + public: - JackWaitThreadedDriver(JackDriver* netdriver) - :JackThreadedDriver(netdriver),fStarter(netdriver) + JackWaitThreadedDriver(JackDriver* net_driver) + :JackThreadedDriver(net_driver), fStarter(net_driver) {} virtual ~JackWaitThreadedDriver() {} - + // JackRunnableInterface interface bool Init(); bool Execute(); -}; +}; } // end of namespace From df7e4df27462222757b650308e3f3aaa9cc45053 Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Fri, 1 Apr 2011 11:34:03 -0700 Subject: [PATCH 124/472] Add license headers to 'alsarawmidi' driver files. --- linux/alsarawmidi/JackALSARawMidiDriver.cpp | 19 +++++++++++++++++++ linux/alsarawmidi/JackALSARawMidiDriver.h | 19 +++++++++++++++++++ .../alsarawmidi/JackALSARawMidiInputPort.cpp | 19 +++++++++++++++++++ linux/alsarawmidi/JackALSARawMidiInputPort.h | 19 +++++++++++++++++++ .../alsarawmidi/JackALSARawMidiOutputPort.cpp | 19 +++++++++++++++++++ linux/alsarawmidi/JackALSARawMidiOutputPort.h | 19 +++++++++++++++++++ linux/alsarawmidi/JackALSARawMidiPort.cpp | 19 +++++++++++++++++++ linux/alsarawmidi/JackALSARawMidiPort.h | 19 +++++++++++++++++++ .../JackALSARawMidiReceiveQueue.cpp | 19 +++++++++++++++++++ .../alsarawmidi/JackALSARawMidiReceiveQueue.h | 19 +++++++++++++++++++ .../alsarawmidi/JackALSARawMidiSendQueue.cpp | 19 +++++++++++++++++++ linux/alsarawmidi/JackALSARawMidiSendQueue.h | 19 +++++++++++++++++++ 12 files changed, 228 insertions(+) diff --git a/linux/alsarawmidi/JackALSARawMidiDriver.cpp b/linux/alsarawmidi/JackALSARawMidiDriver.cpp index 3f4761e0..7bbd5276 100755 --- a/linux/alsarawmidi/JackALSARawMidiDriver.cpp +++ b/linux/alsarawmidi/JackALSARawMidiDriver.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2011 Devin Anderson + +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. + +*/ + #include #include #include diff --git a/linux/alsarawmidi/JackALSARawMidiDriver.h b/linux/alsarawmidi/JackALSARawMidiDriver.h index 0ffc4e52..1b0afd7e 100755 --- a/linux/alsarawmidi/JackALSARawMidiDriver.h +++ b/linux/alsarawmidi/JackALSARawMidiDriver.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2011 Devin Anderson + +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 __JackALSARawMidiDriver__ #define __JackALSARawMidiDriver__ diff --git a/linux/alsarawmidi/JackALSARawMidiInputPort.cpp b/linux/alsarawmidi/JackALSARawMidiInputPort.cpp index 5ed14882..b81c5783 100755 --- a/linux/alsarawmidi/JackALSARawMidiInputPort.cpp +++ b/linux/alsarawmidi/JackALSARawMidiInputPort.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2011 Devin Anderson + +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. + +*/ + #include #include "JackALSARawMidiInputPort.h" diff --git a/linux/alsarawmidi/JackALSARawMidiInputPort.h b/linux/alsarawmidi/JackALSARawMidiInputPort.h index 38b8985b..55ad2278 100755 --- a/linux/alsarawmidi/JackALSARawMidiInputPort.h +++ b/linux/alsarawmidi/JackALSARawMidiInputPort.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2011 Devin Anderson + +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 __JackALSARawMidiInputPort__ #define __JackALSARawMidiInputPort__ diff --git a/linux/alsarawmidi/JackALSARawMidiOutputPort.cpp b/linux/alsarawmidi/JackALSARawMidiOutputPort.cpp index c1a2bfb8..1b9a19bb 100755 --- a/linux/alsarawmidi/JackALSARawMidiOutputPort.cpp +++ b/linux/alsarawmidi/JackALSARawMidiOutputPort.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2011 Devin Anderson + +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. + +*/ + #include #include "JackALSARawMidiOutputPort.h" diff --git a/linux/alsarawmidi/JackALSARawMidiOutputPort.h b/linux/alsarawmidi/JackALSARawMidiOutputPort.h index 816ab6a2..6707e381 100755 --- a/linux/alsarawmidi/JackALSARawMidiOutputPort.h +++ b/linux/alsarawmidi/JackALSARawMidiOutputPort.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2011 Devin Anderson + +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 __JackALSARawMidiOutputPort__ #define __JackALSARawMidiOutputPort__ diff --git a/linux/alsarawmidi/JackALSARawMidiPort.cpp b/linux/alsarawmidi/JackALSARawMidiPort.cpp index a37f9d93..4e25cb1a 100755 --- a/linux/alsarawmidi/JackALSARawMidiPort.cpp +++ b/linux/alsarawmidi/JackALSARawMidiPort.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2011 Devin Anderson + +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. + +*/ + #include #include diff --git a/linux/alsarawmidi/JackALSARawMidiPort.h b/linux/alsarawmidi/JackALSARawMidiPort.h index 07fb4c0f..16d1a006 100755 --- a/linux/alsarawmidi/JackALSARawMidiPort.h +++ b/linux/alsarawmidi/JackALSARawMidiPort.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2011 Devin Anderson + +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 __JackALSARawMidiPort__ #define __JackALSARawMidiPort__ diff --git a/linux/alsarawmidi/JackALSARawMidiReceiveQueue.cpp b/linux/alsarawmidi/JackALSARawMidiReceiveQueue.cpp index a4b24bef..61af8e91 100755 --- a/linux/alsarawmidi/JackALSARawMidiReceiveQueue.cpp +++ b/linux/alsarawmidi/JackALSARawMidiReceiveQueue.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2011 Devin Anderson + +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. + +*/ + #include "JackALSARawMidiReceiveQueue.h" #include "JackError.h" #include "JackMidiUtil.h" diff --git a/linux/alsarawmidi/JackALSARawMidiReceiveQueue.h b/linux/alsarawmidi/JackALSARawMidiReceiveQueue.h index a76c1e54..ffe4ea5f 100755 --- a/linux/alsarawmidi/JackALSARawMidiReceiveQueue.h +++ b/linux/alsarawmidi/JackALSARawMidiReceiveQueue.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2011 Devin Anderson + +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 __JackALSARawMidiReceiveQueue__ #define __JackALSARawMidiReceiveQueue__ diff --git a/linux/alsarawmidi/JackALSARawMidiSendQueue.cpp b/linux/alsarawmidi/JackALSARawMidiSendQueue.cpp index 80a11b56..156986a7 100755 --- a/linux/alsarawmidi/JackALSARawMidiSendQueue.cpp +++ b/linux/alsarawmidi/JackALSARawMidiSendQueue.cpp @@ -1,3 +1,22 @@ +/* +Copyright (C) 2011 Devin Anderson + +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. + +*/ + #include #include "JackALSARawMidiSendQueue.h" diff --git a/linux/alsarawmidi/JackALSARawMidiSendQueue.h b/linux/alsarawmidi/JackALSARawMidiSendQueue.h index f3f6542c..2d904b3a 100755 --- a/linux/alsarawmidi/JackALSARawMidiSendQueue.h +++ b/linux/alsarawmidi/JackALSARawMidiSendQueue.h @@ -1,3 +1,22 @@ +/* +Copyright (C) 2011 Devin Anderson + +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 __JackALSARawMidiSendQueue__ #define __JackALSARawMidiSendQueue__ From 38fbcf2de4723fec4d1e11a2339bc6aeb717f028 Mon Sep 17 00:00:00 2001 From: sletz Date: Sat, 2 Apr 2011 07:39:18 +0000 Subject: [PATCH 125/472] Code factorization on JackPortAudioDriver. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4251 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackWaitThreadedDriver.h | 2 +- windows/portaudio/JackPortAudioDevices.cpp | 11 +-- windows/portaudio/JackPortAudioDriver.cpp | 107 ++++++++------------- windows/portaudio/JackPortAudioDriver.h | 1 + 4 files changed, 49 insertions(+), 72 deletions(-) diff --git a/common/JackWaitThreadedDriver.h b/common/JackWaitThreadedDriver.h index 990065f4..32263123 100644 --- a/common/JackWaitThreadedDriver.h +++ b/common/JackWaitThreadedDriver.h @@ -22,7 +22,7 @@ #define __JackWaitThreadedDriver__ #include "JackThreadedDriver.h" -#include "JackAudioDriver.h" +#include "JackDriver.h" namespace Jack { diff --git a/windows/portaudio/JackPortAudioDevices.cpp b/windows/portaudio/JackPortAudioDevices.cpp index d12cfca3..786fb939 100644 --- a/windows/portaudio/JackPortAudioDevices.cpp +++ b/windows/portaudio/JackPortAudioDevices.cpp @@ -27,19 +27,18 @@ PortAudioDevices::PortAudioDevices() PaError err; PaDeviceIndex id; jack_log("Initializing PortAudio..."); - if ( ( err = Pa_Initialize() ) == paNoError ) - { + if ((err = Pa_Initialize() ) == paNoError) { fNumHostApi = Pa_GetHostApiCount(); fNumDevice = Pa_GetDeviceCount(); fDeviceInfo = new PaDeviceInfo*[fNumDevice]; - for ( id = 0; id < fNumDevice; id++ ) + for (id = 0; id < fNumDevice; id++) fDeviceInfo[id] = const_cast(Pa_GetDeviceInfo(id)); fHostName = new string[fNumHostApi]; - for ( id = 0; id < fNumHostApi; id++ ) + for (id = 0; id < fNumHostApi; id++) fHostName[id] = string ( Pa_GetHostApiInfo(id)->name ); - } - else + } else { jack_error("JackPortAudioDriver::Pa_Initialize error = %s", Pa_GetErrorText(err)); + } } PortAudioDevices::~PortAudioDevices() diff --git a/windows/portaudio/JackPortAudioDriver.cpp b/windows/portaudio/JackPortAudioDriver.cpp index f7611add..d0b23a02 100644 --- a/windows/portaudio/JackPortAudioDriver.cpp +++ b/windows/portaudio/JackPortAudioDriver.cpp @@ -60,6 +60,40 @@ namespace Jack return 0; } + int JackPortAudioDriver::OpenStream() + { + PaStreamParameters inputParameters; + PaStreamParameters outputParameters; + + // Update parameters + inputParameters.device = fInputDevice; + inputParameters.channelCount = fCaptureChannels; + inputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output + inputParameters.suggestedLatency = (fInputDevice != paNoDevice) // TODO: check how to setup this on ASIO + ? Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency + : 0; + inputParameters.hostApiSpecificStreamInfo = NULL; + + outputParameters.device = fOutputDevice; + outputParameters.channelCount = fPlaybackChannels; + outputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output + outputParameters.suggestedLatency = (fOutputDevice != paNoDevice) // TODO: check how to setup this on ASIO + ? Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency + : 0; + outputParameters.hostApiSpecificStreamInfo = NULL; + + PaError err = Pa_OpenStream(&fStream, + (fInputDevice == paNoDevice) ? 0 : &inputParameters, + (fOutputDevice == paNoDevice) ? 0 : &outputParameters, + fEngineControl->fSampleRate, + buffer_size, + paNoFlag, // Clipping is on... + Render, + this); + + return (err == paNoError) ? 0: -1; + } + int JackPortAudioDriver::Open(jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, @@ -72,9 +106,6 @@ namespace Jack jack_nframes_t capture_latency, jack_nframes_t playback_latency) { - PaError err = paNoError; - PaStreamParameters inputParameters; - PaStreamParameters outputParameters; int in_max = 0; int out_max = 0; @@ -117,32 +148,7 @@ namespace Jack outchannels = out_max; } - //in/out streams parametering - inputParameters.device = fInputDevice; - inputParameters.channelCount = inchannels; - inputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output - inputParameters.suggestedLatency = (fInputDevice != paNoDevice) // TODO: check how to setup this on ASIO - ? fPaDevices->GetDeviceInfo(fInputDevice)->defaultLowInputLatency - : 0; - inputParameters.hostApiSpecificStreamInfo = NULL; - - outputParameters.device = fOutputDevice; - outputParameters.channelCount = outchannels; - outputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output - outputParameters.suggestedLatency = (fOutputDevice != paNoDevice) // TODO: check how to setup this on ASIO - ? fPaDevices->GetDeviceInfo(fOutputDevice)->defaultLowOutputLatency - : 0; - outputParameters.hostApiSpecificStreamInfo = NULL; - - err = Pa_OpenStream(&fStream, - (fInputDevice == paNoDevice) ? 0 : &inputParameters, - (fOutputDevice == paNoDevice) ? 0 : &outputParameters, - samplerate, - buffer_size, - paNoFlag, // Clipping is on... - Render, - this); - if (err != paNoError) { + if (OpenStream() < 0) { jack_error("Pa_OpenStream error = %s", Pa_GetErrorText(err)); goto error; } @@ -208,41 +214,13 @@ error: int JackPortAudioDriver::SetBufferSize(jack_nframes_t buffer_size) { PaError err; - PaStreamParameters inputParameters; - PaStreamParameters outputParameters; if ((err = Pa_CloseStream(fStream)) != paNoError) { jack_error("Pa_CloseStream error = %s", Pa_GetErrorText(err)); return -1; } - // Update parameters - inputParameters.device = fInputDevice; - inputParameters.channelCount = fCaptureChannels; - inputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output - inputParameters.suggestedLatency = (fInputDevice != paNoDevice) // TODO: check how to setup this on ASIO - ? Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency - : 0; - inputParameters.hostApiSpecificStreamInfo = NULL; - - outputParameters.device = fOutputDevice; - outputParameters.channelCount = fPlaybackChannels; - outputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output - outputParameters.suggestedLatency = (fOutputDevice != paNoDevice) // TODO: check how to setup this on ASIO - ? Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency - : 0; - outputParameters.hostApiSpecificStreamInfo = NULL; - - err = Pa_OpenStream(&fStream, - (fInputDevice == paNoDevice) ? 0 : &inputParameters, - (fOutputDevice == paNoDevice) ? 0 : &outputParameters, - fEngineControl->fSampleRate, - buffer_size, - paNoFlag, // Clipping is on... - Render, - this); - - if (err != paNoError) { + if (OpenStream() < 0) { jack_error("Pa_OpenStream error = %s", Pa_GetErrorText(err)); return -1; } else { @@ -402,8 +380,7 @@ extern "C" { param = (const jack_driver_param_t *) node->data; - switch (param->character) - { + switch (param->character) { case 'd': capture_pcm_name = param->value.str; @@ -474,12 +451,12 @@ extern "C" } Jack::JackDriverClientInterface* driver = new Jack::JackPortAudioDriver("system", "portaudio", engine, table, pa_devices); - if (driver->Open(frames_per_interrupt, srate, capture, playback, chan_in, chan_out, monitor, capture_pcm_name, playback_pcm_name, systemic_input_latency, systemic_output_latency) == 0) - { + if (driver->Open(frames_per_interrupt, srate, capture, playback, + chan_in, chan_out, monitor, capture_pcm_name, + playback_pcm_name, systemic_input_latency, + systemic_output_latency) == 0) { return driver; - } - else - { + } else { delete driver; return NULL; } diff --git a/windows/portaudio/JackPortAudioDriver.h b/windows/portaudio/JackPortAudioDriver.h index 564d5a4e..c49d391d 100644 --- a/windows/portaudio/JackPortAudioDriver.h +++ b/windows/portaudio/JackPortAudioDriver.h @@ -49,6 +49,7 @@ class JackPortAudioDriver : public JackAudioDriver void* userData); void UpdateLatencies(); + int OpenStream(); public: From 4789c74f37565db81c19f4e89308961dc38e8cd8 Mon Sep 17 00:00:00 2001 From: sletz Date: Sat, 2 Apr 2011 07:57:02 +0000 Subject: [PATCH 126/472] Update Solaris drivers. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4252 0c269be4-1314-0410-8aa9-9f06e86f4224 --- example-clients/latent_client.c | 17 +- example-clients/thru_client.c | 2 +- example-clients/tw.c | 46 ++-- example-clients/wait.c | 2 +- example-clients/zombie.c | 18 +- solaris/oss/JackBoomerDriver.cpp | 270 +++++++++++----------- solaris/oss/JackOSSDriver.cpp | 174 +++++++------- windows/portaudio/JackPortAudioDriver.cpp | 2 - 8 files changed, 265 insertions(+), 266 deletions(-) diff --git a/example-clients/latent_client.c b/example-clients/latent_client.c index 67217832..9384d98a 100644 --- a/example-clients/latent_client.c +++ b/example-clients/latent_client.c @@ -1,4 +1,4 @@ -/** @file simple_client.c +/** @file latent_client.c * * @brief This simple client demonstrates the most basic features of JACK * as they would be used by many applications. @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include @@ -19,12 +19,12 @@ jack_client_t *client; jack_default_audio_sample_t *delay_line; jack_nframes_t delay_index; -jack_nframes_t latency = 1024; - -#ifdef WIN32 -#define jack_sleep(val) Sleep((val)) -#else -#define jack_sleep(val) usleep((val) * 1000) +jack_nframes_t latency = 1024; + +#ifdef WIN32 +#define jack_sleep(val) Sleep((val)) +#else +#define jack_sleep(val) usleep((val) * 1000) #endif /** @@ -213,3 +213,4 @@ main (int argc, char *argv[]) jack_client_close (client); exit (0); } + diff --git a/example-clients/thru_client.c b/example-clients/thru_client.c index 426fa6bc..d47fbe15 100644 --- a/example-clients/thru_client.c +++ b/example-clients/thru_client.c @@ -1,4 +1,4 @@ -/** @file simple_client.c +/** @file thru_client.c * * @brief This simple through client demonstrates the basic features of JACK * as they would be used by many applications. diff --git a/example-clients/tw.c b/example-clients/tw.c index b583720e..339f1c37 100644 --- a/example-clients/tw.c +++ b/example-clients/tw.c @@ -1,4 +1,4 @@ -/** @file simple_client.c +/** @file tw.c * * @brief This simple client demonstrates the basic features of JACK * as they would be used by many applications. @@ -42,56 +42,56 @@ _process (jack_nframes_t nframes) { jack_default_audio_sample_t *in, *out; jack_transport_state_t ts = jack_transport_query(client, NULL); - + if (ts == JackTransportRolling) { - + if (client_state == Init) client_state = Run; - + in = jack_port_get_buffer (input_port, nframes); out = jack_port_get_buffer (output_port, nframes); memcpy (out, in, sizeof (jack_default_audio_sample_t) * nframes); - + } else if (ts == JackTransportStopped) { - + if (client_state == Run) { client_state = Exit; return -1; // to stop the thread } } - return 0; + return 0; } -static void* jack_thread(void *arg) +static void* jack_thread(void *arg) { jack_client_t* client = (jack_client_t*) arg; - + while (1) { - + jack_nframes_t frames = jack_cycle_wait (client); int status = _process(frames); jack_cycle_signal (client, status); - + /* Possibly do something else after signaling next clients in the graph */ - + /* End condition */ if (status != 0) - return 0; + return 0; } - + /* not reached*/ return 0; } /* -static void* jack_thread(void *arg) +static void* jack_thread(void *arg) { jack_client_t* client = (jack_client_t*) arg; - + while (1) { jack_nframes_t frames; int status; @@ -103,7 +103,7 @@ static void* jack_thread(void *arg) frames = jack_cycle_wait (client); status = _process(frames); jack_cycle_signal (client, status); - // cycle 3 + // cycle 3 frames = jack_cycle_wait (client); status = _process(frames); jack_cycle_signal (client, status); @@ -112,7 +112,7 @@ static void* jack_thread(void *arg) status = _process(frames); jack_cycle_signal (client, status); } - + return 0; } */ @@ -172,8 +172,8 @@ main (int argc, char *argv[]) /* tell the JACK server to call `process()' whenever there is work to be done. - */ - if (jack_set_process_thread(client, jack_thread, client) < 0) + */ + if (jack_set_process_thread(client, jack_thread, client) < 0) exit(1); /* tell the JACK server to call `jack_shutdown()' if @@ -183,7 +183,7 @@ main (int argc, char *argv[]) jack_on_shutdown (client, jack_shutdown, 0); - /* display the current sample rate. + /* display the current sample rate. */ printf ("engine sample rate: %" PRIu32 "\n", @@ -231,7 +231,7 @@ main (int argc, char *argv[]) } free (ports); - + ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsInput); if (ports == NULL) { @@ -244,7 +244,7 @@ main (int argc, char *argv[]) } free (ports); - + /* install a signal handler to properly quits jack client */ signal(SIGQUIT, signal_handler); signal(SIGTERM, signal_handler); diff --git a/example-clients/wait.c b/example-clients/wait.c index 81870321..9150bb63 100644 --- a/example-clients/wait.c +++ b/example-clients/wait.c @@ -40,7 +40,7 @@ main (int argc, char *argv[]) int wait_timeout = 0; time_t start_timestamp; - + struct option long_options[] = { { "server", 1, 0, 's' }, { "wait", 0, 0, 'w' }, diff --git a/example-clients/zombie.c b/example-clients/zombie.c index a3a2dadd..fb3cd24e 100644 --- a/example-clients/zombie.c +++ b/example-clients/zombie.c @@ -1,6 +1,6 @@ /* Copyright (C) 2002 Jeremy Hall - + 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 @@ -30,18 +30,18 @@ int count = 0; jack_port_t* output_port; static int -process(jack_nframes_t nframes, void* arg) +process(jack_nframes_t nframes, void* arg) { if (count++ == 1000) { printf("process block\n"); //while (1) {} sleep(1); } - + return 0; } -static void +static void shutdown (void *arg) { printf("shutdown \n"); @@ -57,7 +57,7 @@ main (int argc, char *argv[]) fprintf (stderr, "jack server not running?\n"); goto error; } - + jack_set_process_callback (client, process, NULL); jack_on_shutdown(client, shutdown, NULL); output_port = jack_port_register (client, "port1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); @@ -67,9 +67,9 @@ main (int argc, char *argv[]) fprintf (stderr, "cannot activate client"); goto error; } - + jack_connect(client, jack_port_name(output_port), "coreaudio:Built-in Audio:in2"); - + while (running) { sleep(1); printf ("run\n"); @@ -78,9 +78,9 @@ main (int argc, char *argv[]) jack_deactivate (client); jack_client_close (client); return 0; - + error: - if (client) + if (client) jack_client_close (client); return 1; } diff --git a/solaris/oss/JackBoomerDriver.cpp b/solaris/oss/JackBoomerDriver.cpp index fc054541..bbf1c67c 100644 --- a/solaris/oss/JackBoomerDriver.cpp +++ b/solaris/oss/JackBoomerDriver.cpp @@ -106,14 +106,14 @@ static inline void CopyAndConvertOut(void *dst, jack_sample_t *src, size_t nfram case 24: { signed int *s32dst = (signed int*)dst; s32dst += channel; - sample_move_d24_sS((char*)s32dst, src, nframes, byte_skip, NULL); + sample_move_d24_sS((char*)s32dst, src, nframes, byte_skip, NULL); break; - } + } case 32: { signed int *s32dst = (signed int*)dst; s32dst += channel; sample_move_d32u24_sS((char*)s32dst, src, nframes, byte_skip, NULL); - break; + break; } } } @@ -127,7 +127,7 @@ void JackBoomerDriver::SetSampleFormat() fSampleSize = 4; break; case 32: /* native-endian 32-bit integer */ - fSampleFormat = AFMT_S32_NE; + fSampleFormat = AFMT_S32_NE; fSampleSize = 4; break; case 16: /* native-endian 16-bit integer */ @@ -144,13 +144,13 @@ void JackBoomerDriver::DisplayDeviceInfo() oss_audioinfo ai_in, ai_out; memset(&info, 0, sizeof(audio_buf_info)); int cap = 0; - + // Duplex cards : http://manuals.opensound.com/developer/full_duplex.html jack_info("Audio Interface Description :"); jack_info("Sampling Frequency : %d, Sample Format : %d, Mode : %d", fEngineControl->fSampleRate, fSampleFormat, fRWMode); - + if (fRWMode & kWrite) { - + oss_sysinfo si; if (ioctl(fOutFD, OSS_SYSINFO, &si) == -1) { jack_error("JackBoomerDriver::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); @@ -162,18 +162,18 @@ void JackBoomerDriver::DisplayDeviceInfo() jack_info("OSS numaudioengines %d", si.numaudioengines); jack_info("OSS numcards %d", si.numcards); } - + jack_info("Output capabilities - %d channels : ", fPlaybackChannels); jack_info("Output block size = %d", fOutputBufferSize); - + if (ioctl(fOutFD, SNDCTL_DSP_GETOSPACE, &info) == -1) { jack_error("JackBoomerDriver::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { - jack_info("output space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", + jack_info("output space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", info.fragments, info.fragstotal, info.fragsize, info.bytes); fFragmentSize = info.fragsize; } - + if (ioctl(fOutFD, SNDCTL_DSP_GETCAPS, &cap) == -1) { jack_error("JackBoomerDriver::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { @@ -186,10 +186,10 @@ void JackBoomerDriver::DisplayDeviceInfo() if (cap & DSP_CAP_MULTI) jack_info(" DSP_CAP_MULTI"); if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); } - } - + } + if (fRWMode & kRead) { - + oss_sysinfo si; if (ioctl(fInFD, OSS_SYSINFO, &si) == -1) { jack_error("JackBoomerDriver::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); @@ -201,14 +201,14 @@ void JackBoomerDriver::DisplayDeviceInfo() jack_info("OSS numaudioengines %d", si.numaudioengines); jack_info("OSS numcards %d", si.numcards); } - + jack_info("Input capabilities - %d channels : ", fCaptureChannels); jack_info("Input block size = %d", fInputBufferSize); - - if (ioctl(fInFD, SNDCTL_DSP_GETISPACE, &info) == -1) { + + if (ioctl(fInFD, SNDCTL_DSP_GETISPACE, &info) == -1) { jack_error("JackBoomerDriver::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { - jack_info("input space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", + jack_info("input space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", info.fragments, info.fragstotal, info.fragsize, info.bytes); } @@ -225,31 +225,30 @@ void JackBoomerDriver::DisplayDeviceInfo() if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); } } - + if (ai_in.rate_source != ai_out.rate_source) { jack_info("Warning : input and output are not necessarily driven by the same clock!"); } } JackBoomerDriver::JackBoomerDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) - : JackAudioDriver(name, alias, engine, table), - fInFD(-1), fOutFD(-1), fBits(0), - fSampleFormat(0), fNperiods(0), fSampleSize(0), fFragmentSize(0), - fRWMode(0), fExcl(false), fSyncIO(false), - fInputBufferSize(0), fOutputBufferSize(0), - fInputBuffer(NULL), fOutputBuffer(NULL), - fInputThread(&fInputHandler), fOutputThread(&fOutputHandler), - fInputHandler(this), fOutputHandler(this) - + : JackAudioDriver(name, alias, engine, table), + fInFD(-1), fOutFD(-1), fBits(0), + fSampleFormat(0), fNperiods(0), fSampleSize(0), fFragmentSize(0), + fRWMode(0), fExcl(false), fSyncIO(false), + fInputBufferSize(0), fOutputBufferSize(0), + fInputBuffer(NULL), fOutputBuffer(NULL), + fInputThread(&fInputHandler), fOutputThread(&fOutputHandler), + fInputHandler(this), fOutputHandler(this) { - sem_init(&fReadSema, 0, 0); - sem_init(&fWriteSema, 0, 0); + sem_init(&fReadSema, 0, 0); + sem_init(&fWriteSema, 0, 0); } JackBoomerDriver::~JackBoomerDriver() { - sem_destroy(&fReadSema); - sem_destroy(&fWriteSema); + sem_destroy(&fReadSema); + sem_destroy(&fWriteSema); } int JackBoomerDriver::OpenInput() @@ -260,8 +259,9 @@ int JackBoomerDriver::OpenInput() int cur_sample_format; jack_nframes_t cur_sample_rate; - if (fCaptureChannels == 0) fCaptureChannels = 2; - + if (fCaptureChannels == 0) + fCaptureChannels = 2; + if ((fInFD = open(fCaptureDriverName, O_RDONLY | ((fExcl) ? O_EXCL : 0))) < 0) { jack_error("JackBoomerDriver::OpenInput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); return -1; @@ -276,7 +276,7 @@ int JackBoomerDriver::OpenInput() } } - gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fCaptureChannels); + gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fCaptureChannels); if (ioctl(fInFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { jack_error("JackBoomerDriver::OpenInput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; @@ -290,7 +290,7 @@ int JackBoomerDriver::OpenInput() if (cur_sample_format != fSampleFormat) { jack_info("JackBoomerDriver::OpenInput driver forced the sample format %ld", fSampleFormat); } - + cur_capture_channels = fCaptureChannels; if (ioctl(fInFD, SNDCTL_DSP_CHANNELS, &fCaptureChannels) == -1) { jack_error("JackBoomerDriver::OpenInput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); @@ -299,7 +299,7 @@ int JackBoomerDriver::OpenInput() if (cur_capture_channels != fCaptureChannels) { jack_info("JackBoomerDriver::OpenInput driver forced the number of capture channels %ld", fCaptureChannels); } - + cur_sample_rate = fEngineControl->fSampleRate; if (ioctl(fInFD, SNDCTL_DSP_SPEED, &fEngineControl->fSampleRate) == -1) { jack_error("JackBoomerDriver::OpenInput failed to set sample rate : %s@%i, errno = %d", __FILE__, __LINE__, errno); @@ -315,7 +315,7 @@ int JackBoomerDriver::OpenInput() fInputBuffer = (void*)calloc(fInputBufferSize, 1); assert(fInputBuffer); return 0; - + error: ::close(fInFD); return -1; @@ -329,28 +329,29 @@ int JackBoomerDriver::OpenOutput() int cur_playback_channels; jack_nframes_t cur_sample_rate; - if (fPlaybackChannels == 0) fPlaybackChannels = 2; - + if (fPlaybackChannels == 0) + fPlaybackChannels = 2; + if ((fOutFD = open(fPlaybackDriverName, O_WRONLY | ((fExcl) ? O_EXCL : 0))) < 0) { jack_error("JackBoomerDriver::OpenOutput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); return -1; } jack_log("JackBoomerDriver::OpenOutput output fOutFD = %d", fOutFD); - + if (fExcl) { if (ioctl(fOutFD, SNDCTL_DSP_COOKEDMODE, &flags) == -1) { jack_error("JackBoomerDriver::OpenOutput failed to set cooked mode : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; - } - } + } + } - gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels); + gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels); if (ioctl(fOutFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { jack_error("JackBoomerDriver::OpenOutput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } - + cur_sample_format = fSampleFormat; if (ioctl(fOutFD, SNDCTL_DSP_SETFMT, &fSampleFormat) == -1) { jack_error("JackBoomerDriver::OpenOutput failed to set format : %s@%i, errno = %d", __FILE__, __LINE__, errno); @@ -359,7 +360,7 @@ int JackBoomerDriver::OpenOutput() if (cur_sample_format != fSampleFormat) { jack_info("JackBoomerDriver::OpenOutput driver forced the sample format %ld", fSampleFormat); } - + cur_playback_channels = fPlaybackChannels; if (ioctl(fOutFD, SNDCTL_DSP_CHANNELS, &fPlaybackChannels) == -1) { jack_error("JackBoomerDriver::OpenOutput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); @@ -380,33 +381,33 @@ int JackBoomerDriver::OpenOutput() // Just set the write size to the value we want... fOutputBufferSize = fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels; - + fOutputBuffer = (void*)calloc(fOutputBufferSize, 1); assert(fOutputBuffer); return 0; - + error: ::close(fOutFD); return -1; } int JackBoomerDriver::Open(jack_nframes_t nframes, - int user_nperiods, - jack_nframes_t samplerate, - bool capturing, - bool playing, - int inchannels, - int outchannels, - bool excl, - bool monitor, - const char* capture_driver_uid, - const char* playback_driver_uid, - jack_nframes_t capture_latency, - jack_nframes_t playback_latency, - int bits, bool syncio) + int user_nperiods, + jack_nframes_t samplerate, + bool capturing, + bool playing, + int inchannels, + int outchannels, + bool excl, + bool monitor, + const char* capture_driver_uid, + const char* playback_driver_uid, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency, + int bits, bool syncio) { // Generic JackAudioDriver Open - if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, + if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) { return -1; } else { @@ -422,12 +423,12 @@ int JackBoomerDriver::Open(jack_nframes_t nframes, fExcl = excl; fNperiods = (user_nperiods == 0) ? 1 : user_nperiods ; fSyncIO = syncio; - + #ifdef JACK_MONITOR // Force memory page in memset(&gCycleTable, 0, sizeof(gCycleTable)); #endif - + if (OpenAux() < 0) { Close(); return -1; @@ -441,14 +442,14 @@ int JackBoomerDriver::Close() { #ifdef JACK_MONITOR FILE* file = fopen("OSSProfiling.log", "w"); - + if (file) { jack_info("Writing OSS driver timing data...."); for (int i = 1; i < std::min(gCycleReadCount, gCycleWriteCount); i++) { int d1 = gCycleTable.fTable[i].fAfterRead - gCycleTable.fTable[i].fBeforeRead; int d2 = gCycleTable.fTable[i].fAfterReadConvert - gCycleTable.fTable[i].fAfterRead; int d3 = gCycleTable.fTable[i].fAfterWrite - gCycleTable.fTable[i].fBeforeWrite; - int d4 = gCycleTable.fTable[i].fBeforeWrite - gCycleTable.fTable[i].fBeforeWriteConvert; + int d4 = gCycleTable.fTable[i].fBeforeWrite - gCycleTable.fTable[i].fBeforeWriteConvert; fprintf(file, "%d \t %d \t %d \t %d \t \n", d1, d2, d3, d4); } fclose(file); @@ -461,7 +462,7 @@ int JackBoomerDriver::Close() if (file == NULL) { jack_error("JackBoomerDriver::Close cannot open TimingOSS.plot file"); } else { - + fprintf(file, "set grid\n"); fprintf(file, "set title \"OSS audio driver timing\"\n"); fprintf(file, "set xlabel \"audio cycles\"\n"); @@ -470,10 +471,10 @@ int JackBoomerDriver::Close() \"OSSProfiling.log\" using 2 title \"Driver read convert duration\" with lines, \ \"OSSProfiling.log\" using 3 title \"Driver write wait\" with lines, \ \"OSSProfiling.log\" using 4 title \"Driver write convert duration\" with lines\n"); - + fprintf(file, "set output 'TimingOSS.pdf\n"); fprintf(file, "set terminal pdf\n"); - + fprintf(file, "set grid\n"); fprintf(file, "set title \"OSS audio driver timing\"\n"); fprintf(file, "set xlabel \"audio cycles\"\n"); @@ -482,12 +483,12 @@ int JackBoomerDriver::Close() \"OSSProfiling.log\" using 2 title \"Driver read convert duration\" with lines, \ \"OSSProfiling.log\" using 3 title \"Driver write wait\" with lines, \ \"OSSProfiling.log\" using 4 title \"Driver write convert duration\" with lines\n"); - + fclose(file); } #endif int res = JackAudioDriver::Close(); - CloseAux(); + CloseAux(); return res; } @@ -498,12 +499,12 @@ int JackBoomerDriver::OpenAux() if ((fRWMode & kRead) && (OpenInput() < 0)) { return -1; } - - if ((fRWMode & kWrite) && (OpenOutput() < 0)) { + + if ((fRWMode & kWrite) && (OpenOutput() < 0)) { return -1; } - - DisplayDeviceInfo(); + + DisplayDeviceInfo(); return 0; } @@ -513,16 +514,16 @@ void JackBoomerDriver::CloseAux() close(fInFD); fInFD = -1; } - + if (fRWMode & kWrite && fOutFD >= 0) { close(fOutFD); fOutFD = -1; } - + if (fInputBuffer) free(fInputBuffer); fInputBuffer = NULL; - + if (fOutputBuffer) free(fOutputBuffer); fOutputBuffer = NULL; @@ -533,29 +534,29 @@ int JackBoomerDriver::Start() jack_log("JackBoomerDriver::Start"); JackAudioDriver::Start(); - // Input/output synchronisation + // Input/output synchronisation if (fInFD >= 0 && fOutFD >= 0 && fSyncIO) { - jack_log("JackBoomerDriver::Start sync input/output"); + jack_log("JackBoomerDriver::Start sync input/output"); // Create and fill synch group int id; oss_syncgroup group; group.id = 0; - + group.mode = PCM_ENABLE_INPUT; - if (ioctl(fInFD, SNDCTL_DSP_SYNCGROUP, &group) == -1) + if (ioctl(fInFD, SNDCTL_DSP_SYNCGROUP, &group) == -1) jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCGROUP : %s@%i, errno = %d", __FILE__, __LINE__, errno); - + group.mode = PCM_ENABLE_OUTPUT; - if (ioctl(fOutFD, SNDCTL_DSP_SYNCGROUP, &group) == -1) + if (ioctl(fOutFD, SNDCTL_DSP_SYNCGROUP, &group) == -1) jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCGROUP : %s@%i, errno = %d", __FILE__, __LINE__, errno); // Prefill output buffer : 2 fragments of silence as described in http://manuals.opensound.com/developer/synctest.c.html#LOC6 char* silence_buf = (char*)malloc(fFragmentSize); memset(silence_buf, 0, fFragmentSize); - jack_log ("JackBoomerDriver::Start prefill size = %d", fFragmentSize); + jack_log ("JackBoomerDriver::Start prefill size = %d", fFragmentSize); for (int i = 0; i < 2; i++) { ssize_t count = ::write(fOutFD, silence_buf, fFragmentSize); @@ -569,12 +570,12 @@ int JackBoomerDriver::Start() // Start input/output in sync id = group.id; - if (ioctl(fInFD, SNDCTL_DSP_SYNCSTART, &id) == -1) + if (ioctl(fInFD, SNDCTL_DSP_SYNCSTART, &id) == -1) jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCSTART : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else if (fOutFD >= 0) { - - // Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html + + // Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html memset(fOutputBuffer, 0, fOutputBufferSize); // Prefill ouput buffer @@ -584,8 +585,8 @@ int JackBoomerDriver::Start() jack_error("JackBoomerDriver::Start error bytes written = %ld", count); } } - } - + } + // Start input thread only when needed if (fInFD >= 0) { if (fInputThread.StartSync() < 0) { @@ -627,44 +628,44 @@ bool JackBoomerDriver::JackBoomerDriverInput::Init() if (fDriver->fInputThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { jack_error("AcquireRealTime error"); } else { - set_threaded_log_function(); + set_threaded_log_function(); } } - + return true; } // TODO : better error handling bool JackBoomerDriver::JackBoomerDriverInput::Execute() { - + #ifdef JACK_MONITOR gCycleTable.fTable[gCycleReadCount].fBeforeRead = GetMicroSeconds(); #endif audio_errinfo ei_in; - ssize_t count = ::read(fDriver->fInFD, fDriver->fInputBuffer, fDriver->fInputBufferSize); - + ssize_t count = ::read(fDriver->fInFD, fDriver->fInputBuffer, fDriver->fInputBufferSize); + #ifdef JACK_MONITOR if (count > 0 && count != (int)fDriver->fInputBufferSize) jack_log("JackBoomerDriverInput::Execute count = %ld", count / (fDriver->fSampleSize * fDriver->fCaptureChannels)); gCycleTable.fTable[gCycleReadCount].fAfterRead = GetMicroSeconds(); #endif - + // XRun detection if (ioctl(fDriver->fInFD, SNDCTL_DSP_GETERROR, &ei_in) == 0) { if (ei_in.rec_overruns > 0 ) { jack_error("JackBoomerDriverInput::Execute overruns"); jack_time_t cur_time = GetMicroSeconds(); - fDriver->NotifyXRun(cur_time, float(cur_time - fDriver->fBeginDateUst)); // Better this value than nothing... + fDriver->NotifyXRun(cur_time, float(cur_time - fDriver->fBeginDateUst)); // Better this value than nothing... } if (ei_in.rec_errorcount > 0 && ei_in.rec_lasterror != 0) { jack_error("%d OSS rec event(s), last=%05d:%d", ei_in.rec_errorcount, ei_in.rec_lasterror, ei_in.rec_errorparm); } - } - + } + if (count < 0) { jack_log("JackBoomerDriverInput::Execute error = %s", strerror(errno)); } else if (count < (int)fDriver->fInputBufferSize) { @@ -675,11 +676,11 @@ bool JackBoomerDriver::JackBoomerDriverInput::Execute() fDriver->CycleTakeBeginTime(); for (int i = 0; i < fDriver->fCaptureChannels; i++) { if (fDriver->fGraphManager->GetConnectionsNum(fDriver->fCapturePortList[i]) > 0) { - CopyAndConvertIn(fDriver->GetInputBuffer(i), - fDriver->fInputBuffer, - fDriver->fEngineControl->fBufferSize, - i, - fDriver->fCaptureChannels * fDriver->fSampleSize, + CopyAndConvertIn(fDriver->GetInputBuffer(i), + fDriver->fInputBuffer, + fDriver->fEngineControl->fBufferSize, + i, + fDriver->fCaptureChannels * fDriver->fSampleSize, fDriver->fBits); } } @@ -707,18 +708,18 @@ bool JackBoomerDriver::JackBoomerDriverOutput::Init() if (fDriver->fOutputThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { jack_error("AcquireRealTime error"); } else { - set_threaded_log_function(); + set_threaded_log_function(); } } - + int delay; if (ioctl(fDriver->fOutFD, SNDCTL_DSP_GETODELAY, &delay) == -1) { jack_error("JackBoomerDriverOutput::Init error get out delay : %s@%i, errno = %d", __FILE__, __LINE__, errno); } - + delay /= fDriver->fSampleSize * fDriver->fPlaybackChannels; jack_info("JackBoomerDriverOutput::Init output latency frames = %ld", delay); - + return true; } @@ -730,21 +731,21 @@ bool JackBoomerDriver::JackBoomerDriverOutput::Execute() #ifdef JACK_MONITOR gCycleTable.fTable[gCycleWriteCount].fBeforeWriteConvert = GetMicroSeconds(); #endif - + for (int i = 0; i < fDriver->fPlaybackChannels; i++) { if (fDriver->fGraphManager->GetConnectionsNum(fDriver->fPlaybackPortList[i]) > 0) { - CopyAndConvertOut(fDriver->fOutputBuffer, - fDriver->GetOutputBuffer(i), - fDriver->fEngineControl->fBufferSize, - i, - fDriver->fPlaybackChannels * fDriver->fSampleSize, + CopyAndConvertOut(fDriver->fOutputBuffer, + fDriver->GetOutputBuffer(i), + fDriver->fEngineControl->fBufferSize, + i, + fDriver->fPlaybackChannels * fDriver->fSampleSize, fDriver->fBits); } } - + #ifdef JACK_MONITOR gCycleTable.fTable[gCycleWriteCount].fBeforeWrite = GetMicroSeconds(); -#endif +#endif ssize_t count = ::write(fDriver->fOutFD, fDriver->fOutputBuffer, fDriver->fOutputBufferSize); @@ -762,20 +763,20 @@ bool JackBoomerDriver::JackBoomerDriverOutput::Execute() if (ei_out.play_underruns > 0) { jack_error("JackBoomerDriverOutput::Execute underruns"); jack_time_t cur_time = GetMicroSeconds(); - fDriver->NotifyXRun(cur_time, float(cur_time - fDriver->fBeginDateUst)); // Better this value than nothing... + fDriver->NotifyXRun(cur_time, float(cur_time - fDriver->fBeginDateUst)); // Better this value than nothing... } if (ei_out.play_errorcount > 0 && ei_out.play_lasterror != 0) { jack_error("%d OSS play event(s), last=%05d:%d",ei_out.play_errorcount, ei_out.play_lasterror, ei_out.play_errorparm); } } - + if (count < 0) { jack_log("JackBoomerDriverOutput::Execute error = %s", strerror(errno)); } else if (count < (int)fDriver->fOutputBufferSize) { jack_error("JackBoomerDriverOutput::Execute error bytes written = %ld", count); } - + // Duplex : sync with read thread if (fDriver->fInFD >= 0 && fDriver->fOutFD >= 0) { fDriver->SynchronizeWrite(); @@ -802,12 +803,11 @@ void JackBoomerDriver::SynchronizeWrite() int JackBoomerDriver::SetBufferSize(jack_nframes_t buffer_size) { - CloseAux(); - JackAudioDriver::SetBufferSize(buffer_size); // never fails + CloseAux(); + JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails return OpenAux(); } - } // end of namespace #ifdef __cplusplus @@ -823,7 +823,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() strcpy(desc->name, "boomer"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->desc, "Boomer/OSS API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - + desc->nparams = OSS_DRIVER_N_PARAMS; desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); @@ -866,7 +866,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() desc->params[i].value.ui = OSS_DRIVER_DEF_INS; strcpy(desc->params[i].short_desc, "Capture channels"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); - + i++; strcpy(desc->params[i].name, "outchannels"); desc->params[i].character = 'o'; @@ -874,7 +874,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() desc->params[i].value.ui = OSS_DRIVER_DEF_OUTS; strcpy(desc->params[i].short_desc, "Playback channels"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); - + i++; strcpy(desc->params[i].name, "excl"); desc->params[i].character = 'e'; @@ -890,7 +890,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() strcpy(desc->params[i].value.str, OSS_DRIVER_DEF_DEV); strcpy(desc->params[i].short_desc, "Input device"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); - + i++; strcpy(desc->params[i].name, "playback"); desc->params[i].character = 'P'; @@ -906,7 +906,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() strcpy(desc->params[i].value.str, OSS_DRIVER_DEF_DEV); strcpy(desc->params[i].short_desc, "OSS device name"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); - + i++; strcpy(desc->params[i].name, "input-latency"); desc->params[i].character = 'I'; @@ -953,13 +953,13 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine const jack_driver_param_t *param; jack_nframes_t systemic_input_latency = 0; jack_nframes_t systemic_output_latency = 0; - + for (node = params; node; node = jack_slist_next(node)) { - + param = (const jack_driver_param_t *)node->data; switch (param->character) { - + case 'r': srate = param->value.ui; break; @@ -983,7 +983,7 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine case 'o': chan_out = (int)param->value.ui; break; - + case 'C': capture = true; if (strcmp(param->value.str, "none") != 0) { @@ -1002,11 +1002,11 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine playback_pcm_name = param->value.str; capture_pcm_name = param->value.str; break; - + case 'e': excl = true; break; - + case 'I': systemic_input_latency = param->value.ui; break; @@ -1028,9 +1028,9 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine } Jack::JackBoomerDriver* boomer_driver = new Jack::JackBoomerDriver("system", "boomer", engine, table); - + // Special open for Boomer driver... - if (boomer_driver->Open(frames_per_interrupt, nperiods, srate, capture, playback, chan_in, chan_out, excl, + if (boomer_driver->Open(frames_per_interrupt, nperiods, srate, capture, playback, chan_in, chan_out, excl, monitor, capture_pcm_name, playback_pcm_name, systemic_input_latency, systemic_output_latency, bits, syncio) == 0) { return boomer_driver; } else { diff --git a/solaris/oss/JackOSSDriver.cpp b/solaris/oss/JackOSSDriver.cpp index 3b66740a..be62f37d 100644 --- a/solaris/oss/JackOSSDriver.cpp +++ b/solaris/oss/JackOSSDriver.cpp @@ -107,12 +107,12 @@ static inline void CopyAndConvertOut(void *dst, jack_sample_t *src, size_t nfram s32dst += channel; sample_move_d24_sS((char*)s32dst, src, nframes, chcount<<2, NULL); // No dithering for now... break; - } + } case 32: { signed int *s32dst = (signed int*)dst; s32dst += channel; sample_move_d32u24_sS((char*)s32dst, src, nframes, chcount<<2, NULL); - break; + break; } } } @@ -126,7 +126,7 @@ void JackOSSDriver::SetSampleFormat() fSampleSize = sizeof(int); break; case 32: /* native-endian 32-bit integer */ - fSampleFormat = AFMT_S32_NE; + fSampleFormat = AFMT_S32_NE; fSampleSize = sizeof(int); break; case 16: /* native-endian 16-bit integer */ @@ -143,13 +143,13 @@ void JackOSSDriver::DisplayDeviceInfo() oss_audioinfo ai_in, ai_out; memset(&info, 0, sizeof(audio_buf_info)); int cap = 0; - + // Duplex cards : http://manuals.opensound.com/developer/full_duplex.html jack_info("Audio Interface Description :"); jack_info("Sampling Frequency : %d, Sample Format : %d, Mode : %d", fEngineControl->fSampleRate, fSampleFormat, fRWMode); - + if (fRWMode & kWrite) { - + oss_sysinfo si; if (ioctl(fOutFD, OSS_SYSINFO, &si) == -1) { jack_error("JackOSSDriver::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); @@ -161,17 +161,17 @@ void JackOSSDriver::DisplayDeviceInfo() jack_info("OSS numaudioengines %d", si.numaudioengines); jack_info("OSS numcards %d", si.numcards); } - + jack_info("Output capabilities - %d channels : ", fPlaybackChannels); jack_info("Output block size = %d", fOutputBufferSize); - + if (ioctl(fOutFD, SNDCTL_DSP_GETOSPACE, &info) == -1) { jack_error("JackOSSDriver::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { - jack_info("output space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", + jack_info("output space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", info.fragments, info.fragstotal, info.fragsize, info.bytes); } - + if (ioctl(fOutFD, SNDCTL_DSP_GETCAPS, &cap) == -1) { jack_error("JackOSSDriver::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { @@ -184,10 +184,10 @@ void JackOSSDriver::DisplayDeviceInfo() if (cap & DSP_CAP_MULTI) jack_info(" DSP_CAP_MULTI"); if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); } - } - + } + if (fRWMode & kRead) { - + oss_sysinfo si; if (ioctl(fInFD, OSS_SYSINFO, &si) == -1) { jack_error("JackOSSDriver::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); @@ -199,14 +199,14 @@ void JackOSSDriver::DisplayDeviceInfo() jack_info("OSS numaudioengines %d", si.numaudioengines); jack_info("OSS numcards %d", si.numcards); } - + jack_info("Input capabilities - %d channels : ", fCaptureChannels); jack_info("Input block size = %d", fInputBufferSize); - - if (ioctl(fInFD, SNDCTL_DSP_GETISPACE, &info) == -1) { + + if (ioctl(fInFD, SNDCTL_DSP_GETISPACE, &info) == -1) { jack_error("JackOSSDriver::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); } else { - jack_info("input space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", + jack_info("input space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", info.fragments, info.fragstotal, info.fragsize, info.bytes); } @@ -223,7 +223,7 @@ void JackOSSDriver::DisplayDeviceInfo() if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); } } - + if (ai_in.rate_source != ai_out.rate_source) { jack_info("Warning : input and output are not necessarily driven by the same clock!"); } @@ -238,7 +238,7 @@ int JackOSSDriver::OpenInput() jack_nframes_t cur_sample_rate; if (fCaptureChannels == 0) fCaptureChannels = 2; - + if ((fInFD = open(fCaptureDriverName, O_RDONLY | ((fExcl) ? O_EXCL : 0))) < 0) { jack_error("JackOSSDriver::OpenInput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); return -1; @@ -253,7 +253,7 @@ int JackOSSDriver::OpenInput() } } - gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fCaptureChannels); + gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fCaptureChannels); if (ioctl(fInFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { jack_error("JackOSSDriver::OpenInput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; @@ -267,7 +267,7 @@ int JackOSSDriver::OpenInput() if (cur_sample_format != fSampleFormat) { jack_info("JackOSSDriver::OpenInput driver forced the sample format %ld", fSampleFormat); } - + cur_capture_channels = fCaptureChannels; if (ioctl(fInFD, SNDCTL_DSP_CHANNELS, &fCaptureChannels) == -1) { jack_error("JackOSSDriver::OpenInput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); @@ -276,7 +276,7 @@ int JackOSSDriver::OpenInput() if (cur_capture_channels != fCaptureChannels) { jack_info("JackOSSDriver::OpenInput driver forced the number of capture channels %ld", fCaptureChannels); } - + cur_sample_rate = fEngineControl->fSampleRate; if (ioctl(fInFD, SNDCTL_DSP_SPEED, &fEngineControl->fSampleRate) == -1) { jack_error("JackOSSDriver::OpenInput failed to set sample rate : %s@%i, errno = %d", __FILE__, __LINE__, errno); @@ -291,7 +291,7 @@ int JackOSSDriver::OpenInput() jack_error("JackOSSDriver::OpenInput failed to get fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } - + if (fInputBufferSize != fEngineControl->fBufferSize * fSampleSize * fCaptureChannels) { if (fIgnoreHW) { int new_buffer_size = fInputBufferSize / (fSampleSize * fCaptureChannels); @@ -306,7 +306,7 @@ int JackOSSDriver::OpenInput() fInputBuffer = (void*)calloc(fInputBufferSize, 1); assert(fInputBuffer); return 0; - + error: ::close(fInFD); return -1; @@ -321,27 +321,27 @@ int JackOSSDriver::OpenOutput() jack_nframes_t cur_sample_rate; if (fPlaybackChannels == 0) fPlaybackChannels = 2; - + if ((fOutFD = open(fPlaybackDriverName, O_WRONLY | ((fExcl) ? O_EXCL : 0))) < 0) { jack_error("JackOSSDriver::OpenOutput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); return -1; } jack_log("JackOSSDriver::OpenOutput output fOutFD = %d", fOutFD); - + if (fExcl) { if (ioctl(fOutFD, SNDCTL_DSP_COOKEDMODE, &flags) == -1) { jack_error("JackOSSDriver::OpenOutput failed to set cooked mode : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; - } - } + } + } - gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels); + gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels); if (ioctl(fOutFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { jack_error("JackOSSDriver::OpenOutput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } - + cur_sample_format = fSampleFormat; if (ioctl(fOutFD, SNDCTL_DSP_SETFMT, &fSampleFormat) == -1) { jack_error("JackOSSDriver::OpenOutput failed to set format : %s@%i, errno = %d", __FILE__, __LINE__, errno); @@ -350,7 +350,7 @@ int JackOSSDriver::OpenOutput() if (cur_sample_format != fSampleFormat) { jack_info("JackOSSDriver::OpenOutput driver forced the sample format %ld", fSampleFormat); } - + cur_playback_channels = fPlaybackChannels; if (ioctl(fOutFD, SNDCTL_DSP_CHANNELS, &fPlaybackChannels) == -1) { jack_error("JackOSSDriver::OpenOutput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); @@ -374,7 +374,7 @@ int JackOSSDriver::OpenOutput() jack_error("JackOSSDriver::OpenOutput failed to get fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); goto error; } - + if (fOutputBufferSize != fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels) { if (fIgnoreHW) { int new_buffer_size = fOutputBufferSize / (fSampleSize * fPlaybackChannels); @@ -385,19 +385,19 @@ int JackOSSDriver::OpenOutput() goto error; } } - + fOutputBuffer = (void*)calloc(fOutputBufferSize, 1); fFirstCycle = true; assert(fOutputBuffer); return 0; - + error: ::close(fOutFD); return -1; } int JackOSSDriver::Open(jack_nframes_t nframes, - int user_nperiods, + int user_nperiods, jack_nframes_t samplerate, bool capturing, bool playing, @@ -413,7 +413,7 @@ int JackOSSDriver::Open(jack_nframes_t nframes, bool ignorehwbuf) { // Generic JackAudioDriver Open - if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, + if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) { return -1; } else { @@ -422,7 +422,7 @@ int JackOSSDriver::Open(jack_nframes_t nframes, jack_error("Cannot run in asynchronous mode, use the -S parameter for jackd"); return -1; } - + fRWMode |= ((capturing) ? kRead : 0); fRWMode |= ((playing) ? kWrite : 0); fBits = bits; @@ -434,7 +434,7 @@ int JackOSSDriver::Open(jack_nframes_t nframes, // Force memory page in memset(&gCycleTable, 0, sizeof(gCycleTable)); #endif - + if (OpenAux() < 0) { Close(); return -1; @@ -448,14 +448,14 @@ int JackOSSDriver::Close() { #ifdef JACK_MONITOR FILE* file = fopen("OSSProfiling.log", "w"); - + if (file) { jack_info("Writing OSS driver timing data...."); for (int i = 1; i < gCycleCount; i++) { int d1 = gCycleTable.fTable[i].fAfterRead - gCycleTable.fTable[i].fBeforeRead; int d2 = gCycleTable.fTable[i].fAfterReadConvert - gCycleTable.fTable[i].fAfterRead; int d3 = gCycleTable.fTable[i].fAfterWrite - gCycleTable.fTable[i].fBeforeWrite; - int d4 = gCycleTable.fTable[i].fBeforeWrite - gCycleTable.fTable[i].fBeforeWriteConvert; + int d4 = gCycleTable.fTable[i].fBeforeWrite - gCycleTable.fTable[i].fBeforeWriteConvert; fprintf(file, "%d \t %d \t %d \t %d \t \n", d1, d2, d3, d4); } fclose(file); @@ -468,7 +468,7 @@ int JackOSSDriver::Close() if (file == NULL) { jack_error("JackOSSDriver::Close cannot open TimingOSS.plot file"); } else { - + fprintf(file, "set grid\n"); fprintf(file, "set title \"OSS audio driver timing\"\n"); fprintf(file, "set xlabel \"audio cycles\"\n"); @@ -477,10 +477,10 @@ int JackOSSDriver::Close() \"OSSProfiling.log\" using 2 title \"Driver read convert duration\" with lines, \ \"OSSProfiling.log\" using 3 title \"Driver write wait\" with lines, \ \"OSSProfiling.log\" using 4 title \"Driver write convert duration\" with lines\n"); - + fprintf(file, "set output 'TimingOSS.pdf\n"); fprintf(file, "set terminal pdf\n"); - + fprintf(file, "set grid\n"); fprintf(file, "set title \"OSS audio driver timing\"\n"); fprintf(file, "set xlabel \"audio cycles\"\n"); @@ -489,12 +489,12 @@ int JackOSSDriver::Close() \"OSSProfiling.log\" using 2 title \"Driver read convert duration\" with lines, \ \"OSSProfiling.log\" using 3 title \"Driver write wait\" with lines, \ \"OSSProfiling.log\" using 4 title \"Driver write convert duration\" with lines\n"); - + fclose(file); } #endif int res = JackAudioDriver::Close(); - CloseAux(); + CloseAux(); return res; } @@ -506,8 +506,8 @@ int JackOSSDriver::OpenAux() if ((fRWMode & kRead) && (OpenInput() < 0)) { return -1; } - - if ((fRWMode & kWrite) && (OpenOutput() < 0)) { + + if ((fRWMode & kWrite) && (OpenOutput() < 0)) { return -1; } @@ -522,7 +522,7 @@ int JackOSSDriver::OpenAux() } */ - DisplayDeviceInfo(); + DisplayDeviceInfo(); return 0; } @@ -532,16 +532,16 @@ void JackOSSDriver::CloseAux() close(fInFD); fInFD = -1; } - + if (fRWMode & kWrite && fOutFD > 0) { close(fOutFD); fOutFD = -1; } - + if (fInputBuffer) free(fInputBuffer); fInputBuffer = NULL; - + if (fOutputBuffer) free(fOutputBuffer); fOutputBuffer = NULL; @@ -554,7 +554,7 @@ int JackOSSDriver::Read() JackDriver::CycleTakeBeginTime(); return 0; } - + ssize_t count; #ifdef JACK_MONITOR @@ -562,28 +562,28 @@ int JackOSSDriver::Read() #endif audio_errinfo ei_in; - count = ::read(fInFD, fInputBuffer, fInputBufferSize); - + count = ::read(fInFD, fInputBuffer, fInputBufferSize); + #ifdef JACK_MONITOR if (count > 0 && count != (int)fInputBufferSize) jack_log("JackOSSDriver::Read count = %ld", count / (fSampleSize * fCaptureChannels)); gCycleTable.fTable[gCycleCount].fAfterRead = GetMicroSeconds(); #endif - + // XRun detection if (ioctl(fInFD, SNDCTL_DSP_GETERROR, &ei_in) == 0) { if (ei_in.rec_overruns > 0 ) { jack_error("JackOSSDriver::Read overruns"); jack_time_t cur_time = GetMicroSeconds(); - NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... + NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... } if (ei_in.rec_errorcount > 0 && ei_in.rec_lasterror != 0) { jack_error("%d OSS rec event(s), last=%05d:%d", ei_in.rec_errorcount, ei_in.rec_lasterror, ei_in.rec_errorparm); } - } - + } + if (count < 0) { jack_log("JackOSSDriver::Read error = %s", strerror(errno)); return -1; @@ -603,7 +603,7 @@ int JackOSSDriver::Read() #ifdef JACK_MONITOR gCycleTable.fTable[gCycleCount].fAfterReadConvert = GetMicroSeconds(); #endif - + return 0; } } @@ -618,10 +618,10 @@ int JackOSSDriver::Write() ssize_t count; audio_errinfo ei_out; - - // Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html + + // Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html if (fFirstCycle) { - + fFirstCycle = false; memset(fOutputBuffer, 0, fOutputBufferSize); @@ -633,17 +633,17 @@ int JackOSSDriver::Write() return -1; } } - + int delay; if (ioctl(fOutFD, SNDCTL_DSP_GETODELAY, &delay) == -1) { jack_error("JackOSSDriver::Write error get out delay : %s@%i, errno = %d", __FILE__, __LINE__, errno); return -1; } - + delay /= fSampleSize * fPlaybackChannels; jack_info("JackOSSDriver::Write output latency frames = %ld", delay); } - + #ifdef JACK_MONITOR gCycleTable.fTable[gCycleCount].fBeforeWriteConvert = GetMicroSeconds(); #endif @@ -657,7 +657,7 @@ int JackOSSDriver::Write() #ifdef JACK_MONITOR gCycleTable.fTable[gCycleCount].fBeforeWrite = GetMicroSeconds(); - #endif + #endif // Keep end cycle time JackDriver::CycleTakeEndTime(); @@ -676,14 +676,14 @@ int JackOSSDriver::Write() if (ei_out.play_underruns > 0) { jack_error("JackOSSDriver::Write underruns"); jack_time_t cur_time = GetMicroSeconds(); - NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... + NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... } if (ei_out.play_errorcount > 0 && ei_out.play_lasterror != 0) { jack_error("%d OSS play event(s), last=%05d:%d",ei_out.play_errorcount, ei_out.play_lasterror, ei_out.play_errorparm); } } - + if (count < 0) { jack_log("JackOSSDriver::Write error = %s", strerror(errno)); return -1; @@ -697,15 +697,15 @@ int JackOSSDriver::Write() int JackOSSDriver::SetBufferSize(jack_nframes_t buffer_size) { - CloseAux(); - JackAudioDriver::SetBufferSize(buffer_size); // never fails + CloseAux(); + JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails return OpenAux(); } int JackOSSDriver::ProcessSync() { // Read input buffers for the current cycle - if (Read() < 0) { + if (Read() < 0) { jack_error("ProcessSync: read error, skip cycle"); return 0; // Non fatal error here, skip cycle, but continue processing... } @@ -715,13 +715,13 @@ int JackOSSDriver::ProcessSync() } else { fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); } - + // Write output buffers for the current cycle - if (Write() < 0) { + if (Write() < 0) { jack_error("JackAudioDriver::ProcessSync: write error, skip cycle"); return 0; // Non fatal error here, skip cycle, but continue processing... } - + return 0; } @@ -740,7 +740,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() strcpy(desc->name, "oss"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->desc, "OSS API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - + desc->nparams = OSS_DRIVER_N_PARAMS; desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); @@ -783,7 +783,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() desc->params[i].value.ui = OSS_DRIVER_DEF_INS; strcpy(desc->params[i].short_desc, "Capture channels"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); - + i++; strcpy(desc->params[i].name, "outchannels"); desc->params[i].character = 'o'; @@ -807,7 +807,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() strcpy(desc->params[i].value.str, OSS_DRIVER_DEF_DEV); strcpy(desc->params[i].short_desc, "Input device"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); - + i++; strcpy(desc->params[i].name, "playback"); desc->params[i].character = 'P'; @@ -823,7 +823,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() strcpy(desc->params[i].value.str, OSS_DRIVER_DEF_DEV); strcpy(desc->params[i].short_desc, "OSS device name"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); - + i++; strcpy(desc->params[i].name, "ignorehwbuf"); desc->params[i].character = 'b'; @@ -831,7 +831,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() desc->params[i].value.i = false; strcpy(desc->params[i].short_desc, "Ignore hardware period size"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); - + i++; strcpy(desc->params[i].name, "input-latency"); desc->params[i].character = 'I'; @@ -870,13 +870,13 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine bool ignorehwbuf = false; jack_nframes_t systemic_input_latency = 0; jack_nframes_t systemic_output_latency = 0; - + for (node = params; node; node = jack_slist_next(node)) { - + param = (const jack_driver_param_t *)node->data; switch (param->character) { - + case 'r': srate = param->value.ui; break; @@ -900,7 +900,7 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine case 'o': chan_out = (int)param->value.ui; break; - + case 'C': capture = true; if (strcmp(param->value.str, "none") != 0) { @@ -919,7 +919,7 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine playback_pcm_name = param->value.str; capture_pcm_name = param->value.str; break; - + case 'b': ignorehwbuf = true; break; @@ -927,7 +927,7 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine case 'e': excl = true; break; - + case 'I': systemic_input_latency = param->value.ui; break; @@ -946,9 +946,9 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine Jack::JackOSSDriver* oss_driver = new Jack::JackOSSDriver("system", "oss", engine, table); Jack::JackDriverClientInterface* threaded_driver = new Jack::JackThreadedDriver(oss_driver); - + // Special open for OSS driver... - if (oss_driver->Open(frames_per_interrupt, nperiods, srate, capture, playback, chan_in, chan_out, + if (oss_driver->Open(frames_per_interrupt, nperiods, srate, capture, playback, chan_in, chan_out, excl, monitor, capture_pcm_name, playback_pcm_name, systemic_input_latency, systemic_output_latency, bits, ignorehwbuf) == 0) { return threaded_driver; } else { diff --git a/windows/portaudio/JackPortAudioDriver.cpp b/windows/portaudio/JackPortAudioDriver.cpp index d0b23a02..c0dadbc6 100644 --- a/windows/portaudio/JackPortAudioDriver.cpp +++ b/windows/portaudio/JackPortAudioDriver.cpp @@ -225,8 +225,6 @@ error: return -1; } else { JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails - // PortAudio specific - JackAudioDriver::UpdateLatencies(); return 0; } } From 3ea1d70b0c0f83071b91acf79054600cdd40055e Mon Sep 17 00:00:00 2001 From: sletz Date: Sat, 2 Apr 2011 10:21:31 +0000 Subject: [PATCH 127/472] Netdriver can now ask for in/out values from the master (in progress). git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4253 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 5 +++ common/JackNetDriver.cpp | 34 ++++++++++-------- common/JackNetManager.cpp | 44 ++++++++++++++++++++--- common/JackNetManager.h | 10 ++++++ common/JackNetTool.h | 8 ++--- linux/alsa/JackAlsaAdapter.cpp | 8 ++--- linux/alsa/JackAlsaDriver.cpp | 8 ++--- macosx/coreaudio/JackCoreAudioAdapter.cpp | 6 ++-- macosx/coreaudio/JackCoreAudioDriver.cpp | 14 ++++---- solaris/oss/JackBoomerDriver.cpp | 4 +-- solaris/oss/JackOSSDriver.cpp | 4 +-- windows/portaudio/JackPortAudioDriver.cpp | 10 +++--- 12 files changed, 105 insertions(+), 50 deletions(-) diff --git a/ChangeLog b/ChangeLog index ba91b540..6f0ffb6e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -34,6 +34,11 @@ Valerio Pilo Jackdmp changes log --------------------------- +2011-04-02 Stephane Letz + + * Netdriver can now ask for in/out values from the master (in progress). + * Correct drivers parameter settings. + 2011-04-01 Stephane Letz * Merge newer-midi branch (Devin Anderson redesign of the MIDI drivers: alsarawmidi, ffado, coremidi and winmme). diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index b52a8a07..9a1a8f0a 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -150,6 +150,10 @@ namespace Jack //set global parameters SetParams(); + // If -1 at conection time, in/out channels count is sent by the master + fCaptureChannels = fParams.fSendAudioChannels; + fPlaybackChannels = fParams.fReturnAudioChannels; + //allocate midi ports lists fMidiCapturePortList = new jack_port_id_t [fParams.fSendMidiChannels]; fMidiPlaybackPortList = new jack_port_id_t [fParams.fReturnMidiChannels]; @@ -157,10 +161,10 @@ namespace Jack assert(fMidiCapturePortList); assert(fMidiPlaybackPortList); - for (uint midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { + for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { fMidiCapturePortList[midi_port_index] = NULL; } - for (uint midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { + for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { fMidiPlaybackPortList[midi_port_index] = NULL; } @@ -261,7 +265,7 @@ namespace Jack char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; unsigned long port_flags; int audio_port_index; - uint midi_port_index; + int midi_port_index; jack_latency_range_t range; //audio @@ -383,13 +387,13 @@ namespace Jack } } - for (uint midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { + for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { if (fMidiCapturePortList && fMidiCapturePortList[midi_port_index] > 0) { fGraphManager->ReleasePort ( fClientControl.fRefNum, fMidiCapturePortList[midi_port_index]); } } - for (uint midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { + for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { if (fMidiPlaybackPortList && fMidiPlaybackPortList[midi_port_index] > 0) { fGraphManager->ReleasePort ( fClientControl.fRefNum, fMidiPlaybackPortList[midi_port_index]); } @@ -495,8 +499,8 @@ namespace Jack //driver processes-------------------------------------------------------------------- int JackNetDriver::Read() { - uint midi_port_index; - uint audio_port_index; + int midi_port_index; + int audio_port_index; //buffers for ( midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++ ) @@ -540,7 +544,7 @@ namespace Jack int JackNetDriver::Write() { - uint midi_port_index; + int midi_port_index; int audio_port_index; //buffers @@ -618,24 +622,24 @@ namespace Jack i++; strcpy ( desc->params[i].name, "input_ports" ); desc->params[i].character = 'C'; - desc->params[i].type = JackDriverParamInt; - desc->params[i].value.i = 2; + desc->params[i].type = JackDriverParamUInt; + desc->params[i].value.ui = 2; strcpy ( desc->params[i].short_desc, "Number of audio input ports" ); strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); i++; strcpy ( desc->params[i].name, "output_ports" ); desc->params[i].character = 'P'; - desc->params[i].type = JackDriverParamInt; - desc->params[i].value.i = 2; + desc->params[i].type = JackDriverParamUInt; + desc->params[i].value.ui = 2; strcpy ( desc->params[i].short_desc, "Number of audio output ports" ); strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); i++; strcpy ( desc->params[i].name, "midi_in_ports" ); desc->params[i].character = 'i'; - desc->params[i].type = JackDriverParamInt; - desc->params[i].value.i = 0; + desc->params[i].type = JackDriverParamUInt; + desc->params[i].value.ui = 0; strcpy ( desc->params[i].short_desc, "Number of midi input ports" ); strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); @@ -643,7 +647,7 @@ namespace Jack strcpy ( desc->params[i].name, "midi_out_ports" ); desc->params[i].character = 'o'; desc->params[i].type = JackDriverParamUInt; - desc->params[i].value.i = 0; + desc->params[i].value.ui = 0; strcpy ( desc->params[i].short_desc, "Number of midi output ports" ); strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index ab97637b..7fa2456a 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -542,6 +542,32 @@ namespace Jack SocketAPIEnd(); } + int JackNetMasterManager::CountPhysicalInputs() + { + const char **ports; + int count = 0; + + ports = jack_get_ports(fManagerClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); + if (ports != NULL) { + while(ports[count]) count++; + free(ports); + } + return count; + } + + int JackNetMasterManager::CountPhysicalOutputs() + { + const char **ports; + int count = 0; + + ports = jack_get_ports(fManagerClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput); + if (ports != NULL) { + while(ports[count]) count++; + free(ports); + } + return count; + } + int JackNetMasterManager::SetSyncCallback ( jack_transport_state_t state, jack_position_t* pos, void* arg ) { return static_cast ( arg )->SyncCallback ( state, pos ); @@ -669,13 +695,23 @@ namespace Jack params.fSampleRate = jack_get_sample_rate ( fManagerClient ); params.fPeriodSize = jack_get_buffer_size ( fManagerClient ); params.fBitdepth = 0; - SetSlaveName ( params ); + + if (params.fSendAudioChannels == -1) { + params.fSendAudioChannels = CountPhysicalInputs(); + jack_info( "Takes physical %d inputs for client", params.fSendAudioChannels); + } + + if (params.fReturnAudioChannels == -1) { + params.fReturnAudioChannels = CountPhysicalOutputs(); + jack_info("Takes physical %d outputs for client", params.fReturnAudioChannels); + } + + SetSlaveName (params); //create a new master and add it to the list JackNetMaster* master = new JackNetMaster(fSocket, params, fMulticastIP); - if ( master->Init(fAutoConnect) ) - { - fMasterList.push_back ( master ); + if (master->Init(fAutoConnect)) { + fMasterList.push_back(master); return master; } delete master; diff --git a/common/JackNetManager.h b/common/JackNetManager.h index cbeaee9e..09fd640f 100644 --- a/common/JackNetManager.h +++ b/common/JackNetManager.h @@ -37,6 +37,9 @@ namespace Jack class JackNetMaster : public JackNetMasterInterface { friend class JackNetMasterManager; + + private: + private: static int SetProcess ( jack_nframes_t nframes, void* arg ); static int SetBufferSize (jack_nframes_t nframes, void* arg); @@ -90,7 +93,9 @@ namespace Jack class JackNetMasterManager { friend class JackNetMaster; + private: + static int SetSyncCallback ( jack_transport_state_t state, jack_position_t* pos, void* arg ); static void* NetManagerThread ( void* arg ); @@ -111,7 +116,12 @@ namespace Jack void SetSlaveName ( session_params_t& params ); int SyncCallback ( jack_transport_state_t state, jack_position_t* pos ); + + int CountPhysicalInputs(); + int CountPhysicalOutputs(); + public: + JackNetMasterManager ( jack_client_t* jack_client, const JSList* params); ~JackNetMasterManager(); }; diff --git a/common/JackNetTool.h b/common/JackNetTool.h index cb6f494f..725d100c 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -81,10 +81,10 @@ namespace Jack uint32_t fMtu; //connection mtu uint32_t fID; //slave's ID uint32_t fTransportSync; //is the transport synced ? - uint32_t fSendAudioChannels; //number of master->slave channels - uint32_t fReturnAudioChannels; //number of slave->master channels - uint32_t fSendMidiChannels; //number of master->slave midi channels - uint32_t fReturnMidiChannels; //number of slave->master midi channels + int32_t fSendAudioChannels; //number of master->slave channels + int32_t fReturnAudioChannels; //number of slave->master channels + int32_t fSendMidiChannels; //number of master->slave midi channels + int32_t fReturnMidiChannels; //number of slave->master midi channels uint32_t fSampleRate; //session sample rate uint32_t fPeriodSize; //period size uint32_t fFramesPerPacket; //complete frames per packet diff --git a/linux/alsa/JackAlsaAdapter.cpp b/linux/alsa/JackAlsaAdapter.cpp index ba847851..070dacd4 100644 --- a/linux/alsa/JackAlsaAdapter.cpp +++ b/linux/alsa/JackAlsaAdapter.cpp @@ -259,7 +259,7 @@ extern "C" i++; strcpy ( desc->params[i].name, "inchannels" ); desc->params[i].character = 'i'; - desc->params[i].type = JackDriverParamUInt; + desc->params[i].type = JackDriverParamInt; desc->params[i].value.i = 0; strcpy ( desc->params[i].short_desc, "Number of capture channels (defaults to hardware max)" ); @@ -268,7 +268,7 @@ extern "C" i++; strcpy ( desc->params[i].name, "outchannels" ); desc->params[i].character = 'o'; - desc->params[i].type = JackDriverParamUInt; + desc->params[i].type = JackDriverParamInt; desc->params[i].value.i = 0; strcpy ( desc->params[i].short_desc, "Number of playback channels (defaults to hardware max)" ); @@ -277,7 +277,7 @@ extern "C" i++; strcpy(desc->params[i].name, "quality"); desc->params[i].character = 'q'; - desc->params[i].type = JackDriverParamInt; + desc->params[i].type = JackDriverParamUInt; 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); @@ -285,7 +285,7 @@ extern "C" i++; strcpy(desc->params[i].name, "ring-buffer"); desc->params[i].character = 'g'; - desc->params[i].type = JackDriverParamInt; + desc->params[i].type = JackDriverParamUInt; 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)"); diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index fb816453..f0da6578 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -845,7 +845,7 @@ SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor () i++; strcpy (params[i].name, "inchannels"); params[i].character = 'i'; - params[i].type = JackDriverParamUInt; + params[i].type = JackDriverParamInt; params[i].value.i = 0; strcpy (params[i].short_desc, "Number of capture channels (defaults to hardware max)"); @@ -854,7 +854,7 @@ SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor () i++; strcpy (params[i].name, "outchannels"); params[i].character = 'o'; - params[i].type = JackDriverParamUInt; + params[i].type = JackDriverParamInt; params[i].value.i = 0; strcpy (params[i].short_desc, "Number of playback channels (defaults to hardware max)"); @@ -872,7 +872,7 @@ SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor () strcpy (params[i].name, "input-latency"); params[i].character = 'I'; params[i].type = JackDriverParamUInt; - params[i].value.i = 0; + params[i].value.ui = 0; strcpy (params[i].short_desc, "Extra input latency (frames)"); strcpy (params[i].long_desc, params[i].short_desc); @@ -880,7 +880,7 @@ SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor () strcpy (params[i].name, "output-latency"); params[i].character = 'O'; params[i].type = JackDriverParamUInt; - params[i].value.i = 0; + params[i].value.ui = 0; strcpy (params[i].short_desc, "Extra output latency (frames)"); strcpy (params[i].long_desc, params[i].short_desc); diff --git a/macosx/coreaudio/JackCoreAudioAdapter.cpp b/macosx/coreaudio/JackCoreAudioAdapter.cpp index d086a877..f77a5e3a 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.cpp +++ b/macosx/coreaudio/JackCoreAudioAdapter.cpp @@ -1511,7 +1511,7 @@ extern "C" strcpy(desc->params[i].name, "channels"); desc->params[i].character = 'c'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = -1; + desc->params[i].value.i = -1; strcpy(desc->params[i].short_desc, "Maximum number of channels"); strcpy(desc->params[i].long_desc, "Maximum number of channels. If -1, max possible number of channels will be used"); @@ -1519,7 +1519,7 @@ extern "C" strcpy(desc->params[i].name, "inchannels"); desc->params[i].character = 'i'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = -1; + desc->params[i].value.i = -1; strcpy(desc->params[i].short_desc, "Maximum number of input channels"); strcpy(desc->params[i].long_desc, "Maximum number of input channels. If -1, max possible number of input channels will be used"); @@ -1527,7 +1527,7 @@ extern "C" strcpy(desc->params[i].name, "outchannels"); desc->params[i].character = 'o'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = -1; + desc->params[i].value.i = -1; strcpy(desc->params[i].short_desc, "Maximum number of output channels"); strcpy(desc->params[i].long_desc, "Maximum number of output channels. If -1, max possible number of output channels will be used"); diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 97352bca..adbb5805 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -1844,7 +1844,7 @@ extern "C" strcpy(desc->params[i].name, "channels"); desc->params[i].character = 'c'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = -1; + desc->params[i].value.i = -1; strcpy(desc->params[i].short_desc, "Maximum number of channels"); strcpy(desc->params[i].long_desc, "Maximum number of channels. If -1, max possible number of channels will be used"); @@ -1852,7 +1852,7 @@ extern "C" strcpy(desc->params[i].name, "inchannels"); desc->params[i].character = 'i'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = -1; + desc->params[i].value.i = -1; strcpy(desc->params[i].short_desc, "Maximum number of input channels"); strcpy(desc->params[i].long_desc, "Maximum number of input channels. If -1, max possible number of input channels will be used"); @@ -1860,7 +1860,7 @@ extern "C" strcpy(desc->params[i].name, "outchannels"); desc->params[i].character = 'o'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = -1; + desc->params[i].value.i = -1; strcpy(desc->params[i].short_desc, "Maximum number of output channels"); strcpy(desc->params[i].long_desc, "Maximum number of output channels. If -1, max possible number of output channels will be used"); @@ -1921,7 +1921,7 @@ extern "C" strcpy(desc->params[i].name, "input-latency"); desc->params[i].character = 'I'; desc->params[i].type = JackDriverParamUInt; - desc->params[i].value.i = 0; + desc->params[i].value.ui = 0; strcpy(desc->params[i].short_desc, "Extra input latency (frames)"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); @@ -1929,7 +1929,7 @@ extern "C" strcpy(desc->params[i].name, "output-latency"); desc->params[i].character = 'O'; desc->params[i].type = JackDriverParamUInt; - desc->params[i].value.i = 0; + desc->params[i].value.ui = 0; strcpy(desc->params[i].short_desc, "Extra output latency (frames)"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); @@ -1953,7 +1953,7 @@ extern "C" strcpy(desc->params[i].name, "async-latency"); desc->params[i].character = 'L'; desc->params[i].type = JackDriverParamUInt; - desc->params[i].value.i = 100; + desc->params[i].value.ui = 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); @@ -1961,7 +1961,7 @@ extern "C" strcpy(desc->params[i].name, "grain"); desc->params[i].character = 'G'; desc->params[i].type = JackDriverParamUInt; - desc->params[i].value.i = 100; + desc->params[i].value.ui = 100; strcpy(desc->params[i].short_desc, "Computation grain in RT thread (percent)"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); diff --git a/solaris/oss/JackBoomerDriver.cpp b/solaris/oss/JackBoomerDriver.cpp index bbf1c67c..63446f14 100644 --- a/solaris/oss/JackBoomerDriver.cpp +++ b/solaris/oss/JackBoomerDriver.cpp @@ -911,7 +911,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() strcpy(desc->params[i].name, "input-latency"); desc->params[i].character = 'I'; desc->params[i].type = JackDriverParamUInt; - desc->params[i].value.i = 0; + desc->params[i].value.ui = 0; strcpy(desc->params[i].short_desc, "Extra input latency"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); @@ -919,7 +919,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() strcpy(desc->params[i].name, "output-latency"); desc->params[i].character = 'O'; desc->params[i].type = JackDriverParamUInt; - desc->params[i].value.i = 0; + desc->params[i].value.ui = 0; strcpy(desc->params[i].short_desc, "Extra output latency"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); diff --git a/solaris/oss/JackOSSDriver.cpp b/solaris/oss/JackOSSDriver.cpp index be62f37d..444fce44 100644 --- a/solaris/oss/JackOSSDriver.cpp +++ b/solaris/oss/JackOSSDriver.cpp @@ -836,7 +836,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() strcpy(desc->params[i].name, "input-latency"); desc->params[i].character = 'I'; desc->params[i].type = JackDriverParamUInt; - desc->params[i].value.i = 0; + desc->params[i].value.ui = 0; strcpy(desc->params[i].short_desc, "Extra input latency"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); @@ -844,7 +844,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() strcpy(desc->params[i].name, "output-latency"); desc->params[i].character = 'O'; desc->params[i].type = JackDriverParamUInt; - desc->params[i].value.i = 0; + desc->params[i].value.ui = 0; strcpy(desc->params[i].short_desc, "Extra output latency"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); diff --git a/windows/portaudio/JackPortAudioDriver.cpp b/windows/portaudio/JackPortAudioDriver.cpp index c0dadbc6..aff1dbdb 100644 --- a/windows/portaudio/JackPortAudioDriver.cpp +++ b/windows/portaudio/JackPortAudioDriver.cpp @@ -253,7 +253,7 @@ extern "C" i = 0; strcpy(desc->params[i].name, "channels"); desc->params[i].character = 'c'; - desc->params[i].type = JackDriverParamInt; + desc->params[i].type = JackDriverParamUInt; desc->params[i].value.ui = 0; strcpy(desc->params[i].short_desc, "Maximum number of channels"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); @@ -261,7 +261,7 @@ extern "C" i++; strcpy(desc->params[i].name, "inchannels"); desc->params[i].character = 'i'; - desc->params[i].type = JackDriverParamInt; + desc->params[i].type = JackDriverParamUInt; desc->params[i].value.ui = 0; strcpy(desc->params[i].short_desc, "Maximum number of input channels"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); @@ -269,7 +269,7 @@ extern "C" i++; strcpy(desc->params[i].name, "outchannels"); desc->params[i].character = 'o'; - desc->params[i].type = JackDriverParamInt; + desc->params[i].type = JackDriverParamUInt; desc->params[i].value.ui = 0; strcpy(desc->params[i].short_desc, "Maximum number of output channels"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); @@ -334,7 +334,7 @@ extern "C" strcpy(desc->params[i].name, "input-latency"); desc->params[i].character = 'I'; desc->params[i].type = JackDriverParamUInt; - desc->params[i].value.i = 0; + desc->params[i].value.ui = 0; strcpy(desc->params[i].short_desc, "Extra input latency"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); @@ -342,7 +342,7 @@ extern "C" strcpy(desc->params[i].name, "output-latency"); desc->params[i].character = 'O'; desc->params[i].type = JackDriverParamUInt; - desc->params[i].value.i = 0; + desc->params[i].value.ui = 0; strcpy(desc->params[i].short_desc, "Extra output latency"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); From 010947119f42f9815123e4634240c6c8de3ecfec Mon Sep 17 00:00:00 2001 From: sletz Date: Sat, 2 Apr 2011 10:34:17 +0000 Subject: [PATCH 128/472] Now default in/out to -1 in Netdriver. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4254 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetDriver.cpp | 10 +++++----- common/JackNetManager.cpp | 23 +++++------------------ common/JackNetManager.h | 3 +-- 3 files changed, 11 insertions(+), 25 deletions(-) diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index 9a1a8f0a..49416de6 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -124,7 +124,7 @@ namespace Jack bool JackNetDriver::Initialize() { - jack_log("JackNetDriver::Initialize()"); + jack_log("JackNetDriver::Initialize() "); //new loading, but existing socket, restart the driver if (fSocket.IsSocket()) { @@ -625,7 +625,7 @@ namespace Jack desc->params[i].type = JackDriverParamUInt; desc->params[i].value.ui = 2; strcpy ( desc->params[i].short_desc, "Number of audio input ports" ); - strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); + strcpy ( desc->params[i].long_desc, "Number of audio input ports. If -1, audio physical input from the master"); i++; strcpy ( desc->params[i].name, "output_ports" ); @@ -633,7 +633,7 @@ namespace Jack desc->params[i].type = JackDriverParamUInt; desc->params[i].value.ui = 2; strcpy ( desc->params[i].short_desc, "Number of audio output ports" ); - strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); + strcpy ( desc->params[i].long_desc, "Number of audio output ports. If -1, audio physical output from the master"); i++; strcpy ( desc->params[i].name, "midi_in_ports" ); @@ -688,8 +688,8 @@ namespace Jack uint transport_sync = 1; jack_nframes_t period_size = 128; jack_nframes_t sample_rate = 48000; - int audio_capture_ports = 2; - int audio_playback_ports = 2; + int audio_capture_ports = -1; + int audio_playback_ports = -1; int midi_input_ports = 0; int midi_output_ports = 0; bool monitor = false; diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index 7fa2456a..87b09391 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -542,25 +542,12 @@ namespace Jack SocketAPIEnd(); } - int JackNetMasterManager::CountPhysicalInputs() + int JackNetMasterManager::CountIO(int flags) { const char **ports; int count = 0; - ports = jack_get_ports(fManagerClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); - if (ports != NULL) { - while(ports[count]) count++; - free(ports); - } - return count; - } - - int JackNetMasterManager::CountPhysicalOutputs() - { - const char **ports; - int count = 0; - - ports = jack_get_ports(fManagerClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput); + ports = jack_get_ports(fManagerClient, NULL, NULL, flags); if (ports != NULL) { while(ports[count]) count++; free(ports); @@ -697,12 +684,12 @@ namespace Jack params.fBitdepth = 0; if (params.fSendAudioChannels == -1) { - params.fSendAudioChannels = CountPhysicalInputs(); - jack_info( "Takes physical %d inputs for client", params.fSendAudioChannels); + params.fSendAudioChannels = CountIO(JackPortIsPhysical | JackPortIsOutput); + jack_info("Takes physical %d inputs for client", params.fSendAudioChannels); } if (params.fReturnAudioChannels == -1) { - params.fReturnAudioChannels = CountPhysicalOutputs(); + params.fReturnAudioChannels = CountIO(JackPortIsPhysical | JackPortIsInput); jack_info("Takes physical %d outputs for client", params.fReturnAudioChannels); } diff --git a/common/JackNetManager.h b/common/JackNetManager.h index 09fd640f..5429c360 100644 --- a/common/JackNetManager.h +++ b/common/JackNetManager.h @@ -117,8 +117,7 @@ namespace Jack int SyncCallback ( jack_transport_state_t state, jack_position_t* pos ); - int CountPhysicalInputs(); - int CountPhysicalOutputs(); + int CountIO(int flags); public: From 47cc588e41bc7f4b0b5e57cb0f27606d88d51433 Mon Sep 17 00:00:00 2001 From: sletz Date: Sat, 2 Apr 2011 11:10:07 +0000 Subject: [PATCH 129/472] Cleanup. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4255 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetAdapter.h | 58 +++++++++++++++++++++------------------ common/JackNetDriver.cpp | 16 +++++------ common/JackNetDriver.h | 9 ++++-- common/JackNetInterface.h | 37 ++++++++++++++++--------- common/JackNetManager.h | 2 +- posix/JackNetUnixSocket.h | 3 ++ 6 files changed, 73 insertions(+), 52 deletions(-) diff --git a/common/JackNetAdapter.h b/common/JackNetAdapter.h index f6b7675b..d90a1d97 100644 --- a/common/JackNetAdapter.h +++ b/common/JackNetAdapter.h @@ -30,44 +30,48 @@ namespace Jack \brief Net adapter. */ - class JackNetAdapter : public JackAudioAdapterInterface, public JackNetSlaveInterface, public JackRunnableInterface + class JackNetAdapter : public JackAudioAdapterInterface, + public JackNetSlaveInterface, + public JackRunnableInterface { - private: - //jack data - jack_client_t* fJackClient; - //transport data - int fLastTransportState; - int fLastTimebaseMaster; - - //sample buffers - sample_t** fSoftCaptureBuffer; - sample_t** fSoftPlaybackBuffer; + private: - //adapter thread - JackThread fThread; + //jack data + jack_client_t* fJackClient; - //transport - void EncodeTransportData(); - void DecodeTransportData(); + //transport data + int fLastTransportState; + int fLastTimebaseMaster; - public: + //sample buffers + sample_t** fSoftCaptureBuffer; + sample_t** fSoftPlaybackBuffer; - JackNetAdapter ( jack_client_t* jack_client, jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params ); - ~JackNetAdapter(); + //adapter thread + JackThread fThread; - int Open(); - int Close(); + //transport + void EncodeTransportData(); + void DecodeTransportData(); - int SetBufferSize ( jack_nframes_t buffer_size ); + public: - bool Init(); - bool Execute(); + JackNetAdapter(jack_client_t* jack_client, jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params); + ~JackNetAdapter(); - int Read(); - int Write(); + int Open(); + int Close(); - int Process(); + int SetBufferSize(jack_nframes_t buffer_size); + + bool Init(); + bool Execute(); + + int Read(); + int Write(); + + int Process(); }; } diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index 49416de6..f46ca4ae 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -622,32 +622,32 @@ namespace Jack i++; strcpy ( desc->params[i].name, "input_ports" ); desc->params[i].character = 'C'; - desc->params[i].type = JackDriverParamUInt; - desc->params[i].value.ui = 2; + desc->params[i].type = JackDriverParamInt; + desc->params[i].value.i = -1; strcpy ( desc->params[i].short_desc, "Number of audio input ports" ); strcpy ( desc->params[i].long_desc, "Number of audio input ports. If -1, audio physical input from the master"); i++; strcpy ( desc->params[i].name, "output_ports" ); desc->params[i].character = 'P'; - desc->params[i].type = JackDriverParamUInt; - desc->params[i].value.ui = 2; + desc->params[i].type = JackDriverParamInt; + desc->params[i].value.i = -1; strcpy ( desc->params[i].short_desc, "Number of audio output ports" ); strcpy ( desc->params[i].long_desc, "Number of audio output ports. If -1, audio physical output from the master"); i++; strcpy ( desc->params[i].name, "midi_in_ports" ); desc->params[i].character = 'i'; - desc->params[i].type = JackDriverParamUInt; - desc->params[i].value.ui = 0; + desc->params[i].type = JackDriverParamInt; + desc->params[i].value.i = 0; strcpy ( desc->params[i].short_desc, "Number of midi input ports" ); strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); i++; strcpy ( desc->params[i].name, "midi_out_ports" ); desc->params[i].character = 'o'; - desc->params[i].type = JackDriverParamUInt; - desc->params[i].value.ui = 0; + desc->params[i].type = JackDriverParamInt; + desc->params[i].value.i = 0; strcpy ( desc->params[i].short_desc, "Number of midi output ports" ); strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); diff --git a/common/JackNetDriver.h b/common/JackNetDriver.h index af137b43..7c4635ae 100644 --- a/common/JackNetDriver.h +++ b/common/JackNetDriver.h @@ -36,15 +36,17 @@ namespace Jack class JackNetDriver : public JackAudioDriver, public JackNetSlaveInterface { + private: + //jack data jack_port_id_t* fMidiCapturePortList; jack_port_id_t* fMidiPlaybackPortList; - + //transport int fLastTransportState; int fLastTimebaseMaster; - + //monitoring #ifdef JACK_MONITOR JackGnuPlotMonitor* fNetTimeMon; @@ -53,7 +55,7 @@ namespace Jack bool Initialize(); void FreeAll(); - + int AllocPorts(); int FreePorts(); @@ -65,6 +67,7 @@ namespace Jack JackMidiBuffer* GetMidiOutputBuffer ( int port_index ); public: + JackNetDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, const char* ip, int port, int mtu, int midi_input_ports, int midi_output_ports, char* net_name, uint transport_sync, char network_master_mode ); diff --git a/common/JackNetInterface.h b/common/JackNetInterface.h index ca90875f..64e8f40e 100644 --- a/common/JackNetInterface.h +++ b/common/JackNetInterface.h @@ -31,7 +31,9 @@ namespace Jack class SERVER_EXPORT JackNetInterface { + protected: + session_params_t fParams; JackNetSocket fSocket; char fMulticastIP[32]; @@ -40,7 +42,7 @@ namespace Jack //headers packet_header_t fTxHeader; packet_header_t fRxHeader; - + // transport net_transport_data_t fSendTransportData; net_transport_data_t fReturnTransportData; @@ -93,7 +95,9 @@ namespace Jack JackNetInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip ); public: + virtual ~JackNetInterface(); + }; /** @@ -102,32 +106,35 @@ namespace Jack class SERVER_EXPORT JackNetMasterInterface : public JackNetInterface { + protected: + bool fRunning; int fCycleOffset; bool Init(); int SetRxTimeout(); void SetParams(); - + void Exit(); - + int SyncRecv(); int SyncSend(); - + int DataRecv(); int DataSend(); - + //sync packet void EncodeSyncPacket(); void DecodeSyncPacket(); int Send ( size_t size, int flags ); int Recv ( size_t size, int flags ); - + bool IsSynched(); public: + JackNetMasterInterface() : JackNetInterface(), fRunning(false), fCycleOffset(0) {} JackNetMasterInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip ) @@ -143,25 +150,26 @@ namespace Jack class SERVER_EXPORT JackNetSlaveInterface : public JackNetInterface { + protected: - + static uint fSlaveCounter; - + bool Init(); bool InitConnection(); bool InitRendering(); - + net_status_t SendAvailableToMaster(); net_status_t SendStartToMaster(); - + void SetParams(); - + int SyncRecv(); int SyncSend(); - + int DataRecv(); int DataSend(); - + //sync packet void EncodeSyncPacket(); void DecodeSyncPacket(); @@ -170,6 +178,7 @@ namespace Jack int Send ( size_t size, int flags ); public: + JackNetSlaveInterface() : JackNetInterface() { //open Socket API with the first slave @@ -182,6 +191,7 @@ namespace Jack } } } + JackNetSlaveInterface ( const char* ip, int port ) : JackNetInterface ( ip, port ) { //open Socket API with the first slave @@ -194,6 +204,7 @@ namespace Jack } } } + ~JackNetSlaveInterface() { //close Socket API with the last slave diff --git a/common/JackNetManager.h b/common/JackNetManager.h index 5429c360..48b6c25c 100644 --- a/common/JackNetManager.h +++ b/common/JackNetManager.h @@ -40,7 +40,6 @@ namespace Jack private: - private: static int SetProcess ( jack_nframes_t nframes, void* arg ); static int SetBufferSize (jack_nframes_t nframes, void* arg); static void SetTimebaseCallback ( jack_transport_state_t state, jack_nframes_t nframes, jack_position_t* pos, int new_pos, void* arg ); @@ -77,6 +76,7 @@ namespace Jack void ConnectPorts(); public: + JackNetMaster ( JackNetSocket& socket, session_params_t& params, const char* multicast_ip); ~JackNetMaster (); diff --git a/posix/JackNetUnixSocket.h b/posix/JackNetUnixSocket.h index 34e69b05..10fc2331 100644 --- a/posix/JackNetUnixSocket.h +++ b/posix/JackNetUnixSocket.h @@ -40,6 +40,7 @@ namespace Jack class SERVER_EXPORT JackNetUnixSocket { private: + int fSockfd; int fPort; int fTimeOut; @@ -50,7 +51,9 @@ namespace Jack int WaitRead(); int WaitWrite(); #endif + public: + JackNetUnixSocket(); JackNetUnixSocket ( const char* ip, int port ); JackNetUnixSocket ( const JackNetUnixSocket& ); From 3b80fc105c1f42562e65cc36d5f5ea1ba30613f8 Mon Sep 17 00:00:00 2001 From: sletz Date: Sat, 2 Apr 2011 15:03:01 +0000 Subject: [PATCH 130/472] Cleanup. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4256 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackDriver.cpp | 1 + common/JackNetAdapter.cpp | 5 ++--- common/JackNetManager.cpp | 12 ++++++------ macosx/coremidi/JackCoreMidiDriver.cpp | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index 5fab3f4f..b09eb812 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -56,6 +56,7 @@ JackDriver::JackDriver() fEngine = NULL; fGraphManager = NULL; fBeginDateUst = 0; + fDelayedUsecs = 0.f; fIsMaster = true; fIsRunning = false; } diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index 6538b9ed..b538e833 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -497,10 +497,9 @@ extern "C" adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackNetAdapter(jack_client, buffer_size, sample_rate, params), params, false); assert ( adapter ); - if ( adapter->Open() == 0 ) + if (adapter->Open() == 0) { return 0; - else - { + } else { delete adapter; return 1; } diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index 87b09391..25619d07 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -37,7 +37,7 @@ namespace Jack fSendTransportData.fState = -1; fReturnTransportData.fState = -1; fLastTransportState = -1; - uint port_index; + int port_index; //jack audio ports fAudioCapturePorts = new jack_port_t* [fParams.fSendAudioChannels]; @@ -164,7 +164,7 @@ namespace Jack //jack ports-------------------------------------------------------------------------- int JackNetMaster::AllocPorts() { - uint i; + int i; char name[24]; jack_nframes_t port_latency = jack_get_buffer_size ( fJackClient ); jack_latency_range_t range; @@ -247,7 +247,7 @@ namespace Jack ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); if (ports != NULL) { - for (unsigned int i = 0; i < fParams.fSendAudioChannels && ports[i]; i++) { + for (int i = 0; i < fParams.fSendAudioChannels && ports[i]; i++) { jack_connect(fJackClient, ports[i], jack_port_name(fAudioCapturePorts[i])); } free(ports); @@ -255,7 +255,7 @@ namespace Jack ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput); if (ports != NULL) { - for (unsigned int i = 0; i < fParams.fReturnAudioChannels && ports[i]; i++) { + for (int i = 0; i < fParams.fReturnAudioChannels && ports[i]; i++) { jack_connect(fJackClient, jack_port_name(fAudioPlaybackPorts[i]), ports[i]); } free(ports); @@ -266,7 +266,7 @@ namespace Jack { jack_log ( "JackNetMaster::FreePorts, ID %u", fParams.fID ); - uint port_index; + int port_index; for ( port_index = 0; port_index < fParams.fSendAudioChannels; port_index++ ) if ( fAudioCapturePorts[port_index] ) jack_port_unregister ( fJackClient, fAudioCapturePorts[port_index] ); @@ -409,7 +409,7 @@ namespace Jack if ( !fRunning ) return 0; - uint port_index; + int port_index; int res = 0; #ifdef JACK_MONITOR diff --git a/macosx/coremidi/JackCoreMidiDriver.cpp b/macosx/coremidi/JackCoreMidiDriver.cpp index 234f2afe..cc9b67c5 100644 --- a/macosx/coremidi/JackCoreMidiDriver.cpp +++ b/macosx/coremidi/JackCoreMidiDriver.cpp @@ -650,7 +650,7 @@ extern "C" { i = 0; strcpy(desc->params[i].name, "inchannels"); desc->params[i].character = 'i'; - desc->params[i].type = JackDriverParamInt; + desc->params[i].type = JackDriverParamUInt; desc->params[i].value.ui = 0; strcpy(desc->params[i].short_desc, "CoreMIDI virtual bus"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); @@ -658,7 +658,7 @@ extern "C" { i++; strcpy(desc->params[i].name, "outchannels"); desc->params[i].character = 'o'; - desc->params[i].type = JackDriverParamInt; + desc->params[i].type = JackDriverParamUInt; desc->params[i].value.ui = 0; strcpy(desc->params[i].short_desc, "CoreMIDI virtual bus"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); From 37a971473b490d2618cdaf4c8399624bd1b987a5 Mon Sep 17 00:00:00 2001 From: sletz Date: Sun, 3 Apr 2011 13:00:30 +0000 Subject: [PATCH 131/472] Fix in JackCoreAudioDriver::Read when there is no inputs. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4257 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 4 ++++ macosx/coreaudio/JackCoreAudioDriver.cpp | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6f0ffb6e..586bbfc7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -34,6 +34,10 @@ Valerio Pilo Jackdmp changes log --------------------------- +2011-04-03 Stephane Letz + + * Fix in JackCoreAudioDriver::Read when there is no inputs. + 2011-04-02 Stephane Letz * Netdriver can now ask for in/out values from the master (in progress). diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index adbb5805..1c26ce65 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -216,8 +216,11 @@ OSStatus JackCoreAudioDriver::Render(void *inRefCon, int JackCoreAudioDriver::Read() { - OSStatus err = AudioUnitRender(fAUHAL, fActionFags, fCurrentTime, 1, fEngineControl->fBufferSize, fJackInputData); - return (err == noErr) ? 0 : -1; + if (fCaptureChannels > 0) { // Calling AudioUnitRender with no input returns a '????' error (callback setting issue ??), so hack to avoid it here... + return (AudioUnitRender(fAUHAL, fActionFags, fCurrentTime, 1, fEngineControl->fBufferSize, fJackInputData) == noErr) ? 0 : -1; + } else { + return 0; + } } int JackCoreAudioDriver::Write() From 59ccc8d648cbfeeee3407dd666533128069ca1ba Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 4 Apr 2011 10:14:25 +0000 Subject: [PATCH 132/472] Correct warning. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4258 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetDriver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index f46ca4ae..9551aac0 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -162,10 +162,10 @@ namespace Jack assert(fMidiPlaybackPortList); for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { - fMidiCapturePortList[midi_port_index] = NULL; + fMidiCapturePortList[midi_port_index] = 0; } for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { - fMidiPlaybackPortList[midi_port_index] = NULL; + fMidiPlaybackPortList[midi_port_index] = 0; } //register jack ports From d617cef4da10f2f5ea40df0d49ebb64a7b8bbdc4 Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 4 Apr 2011 12:03:01 +0000 Subject: [PATCH 133/472] Correct JackPortAudioDriver. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4259 0c269be4-1314-0410-8aa9-9f06e86f4224 --- windows/portaudio/JackPortAudioDriver.cpp | 17 +++++++++-------- windows/portaudio/JackPortAudioDriver.h | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/windows/portaudio/JackPortAudioDriver.cpp b/windows/portaudio/JackPortAudioDriver.cpp index aff1dbdb..603c1fff 100644 --- a/windows/portaudio/JackPortAudioDriver.cpp +++ b/windows/portaudio/JackPortAudioDriver.cpp @@ -60,7 +60,7 @@ namespace Jack return 0; } - int JackPortAudioDriver::OpenStream() + PaError JackPortAudioDriver::OpenStream(jack_nframes_t buffer_size) { PaStreamParameters inputParameters; PaStreamParameters outputParameters; @@ -91,7 +91,7 @@ namespace Jack Render, this); - return (err == paNoError) ? 0: -1; + return err; } int JackPortAudioDriver::Open(jack_nframes_t buffer_size, @@ -108,6 +108,7 @@ namespace Jack { int in_max = 0; int out_max = 0; + PaError err = paNoError; jack_log("JackPortAudioDriver::Open nframes = %ld in = %ld out = %ld capture name = %s playback name = %s samplerate = %ld", buffer_size, inchannels, outchannels, capture_driver_uid, playback_driver_uid, samplerate); @@ -148,7 +149,11 @@ namespace Jack outchannels = out_max; } - if (OpenStream() < 0) { + // Core driver may have changed the in/out values + fCaptureChannels = inchannels; + fPlaybackChannels = outchannels; + + if ((err = OpenStream(buffer_size)) != paNoError) { jack_error("Pa_OpenStream error = %s", Pa_GetErrorText(err)); goto error; } @@ -159,10 +164,6 @@ namespace Jack fEngineControl->fConstraint = fEngineControl->fPeriodUsecs * 1000; #endif - // Core driver may have changed the in/out values - fCaptureChannels = inchannels; - fPlaybackChannels = outchannels; - assert(strlen(capture_driver_uid) < JACK_CLIENT_NAME_SIZE); assert(strlen(playback_driver_uid) < JACK_CLIENT_NAME_SIZE); @@ -220,7 +221,7 @@ error: return -1; } - if (OpenStream() < 0) { + if ((err = OpenStream(buffer_size)) != paNoError) { jack_error("Pa_OpenStream error = %s", Pa_GetErrorText(err)); return -1; } else { diff --git a/windows/portaudio/JackPortAudioDriver.h b/windows/portaudio/JackPortAudioDriver.h index c49d391d..d4e15a55 100644 --- a/windows/portaudio/JackPortAudioDriver.h +++ b/windows/portaudio/JackPortAudioDriver.h @@ -49,7 +49,7 @@ class JackPortAudioDriver : public JackAudioDriver void* userData); void UpdateLatencies(); - int OpenStream(); + PaError OpenStream(jack_nframes_t buffer_size); public: From 09cedc138f6633dc7de80fd5d4320ebb0448899c Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 4 Apr 2011 14:59:36 +0000 Subject: [PATCH 134/472] Winmme driver working again. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4260 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/shm.h | 2 +- windows/winmme/JackWinMMEDriver.cpp | 5 +--- windows/winmme/JackWinMMEInputPort.cpp | 24 ++++++++++--------- windows/winmme/JackWinMMEOutputPort.cpp | 31 +++++++++++-------------- 4 files changed, 29 insertions(+), 33 deletions(-) diff --git a/common/shm.h b/common/shm.h index f1edc8ed..ed5a953f 100644 --- a/common/shm.h +++ b/common/shm.h @@ -14,7 +14,7 @@ extern "C" { #endif -#define MAX_SERVERS 64 /* maximum concurrent servers */ +#define MAX_SERVERS 8 /* maximum concurrent servers */ #define MAX_SHM_ID 256 /* generally about 16 per server */ #define JACK_SERVER_NAME_SIZE 256 /* maximum length of server name */ #define JACK_SHM_MAGIC 0x4a41434b /* shm magic number: "JACK" */ diff --git a/windows/winmme/JackWinMMEDriver.cpp b/windows/winmme/JackWinMMEDriver.cpp index 96bebda1..fa3e1f7f 100644 --- a/windows/winmme/JackWinMMEDriver.cpp +++ b/windows/winmme/JackWinMMEDriver.cpp @@ -212,7 +212,6 @@ JackWinMMEDriver::Open(bool capturing, bool playing, int in_channels, int JackWinMMEDriver::Read() { - jack_nframes_t buffer_size = fEngineControl->fBufferSize; for (int i = 0; i < fCaptureChannels; i++) { input_ports[i]->ProcessJack(GetInputBuffer(i), buffer_size); @@ -221,16 +220,14 @@ JackWinMMEDriver::Read() return 0; } - int JackWinMMEDriver::Write() { - /* jack_nframes_t buffer_size = fEngineControl->fBufferSize; for (int i = 0; i < fPlaybackChannels; i++) { output_ports[i]->ProcessJack(GetOutputBuffer(i), buffer_size); } - */ + return 0; } diff --git a/windows/winmme/JackWinMMEInputPort.cpp b/windows/winmme/JackWinMMEInputPort.cpp index c3b04453..6bb2d2a5 100644 --- a/windows/winmme/JackWinMMEInputPort.cpp +++ b/windows/winmme/JackWinMMEInputPort.cpp @@ -50,9 +50,9 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, size_t max_bytes, size_t max_messages) { thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); - std::auto_ptr thread_queue_ptr(thread_queue); + //std::auto_ptr thread_queue_ptr(thread_queue); write_queue = new JackMidiBufferWriteQueue(); - std::auto_ptr write_queue_ptr(write_queue); + //std::auto_ptr write_queue_ptr(write_queue); sysex_buffer = new jack_midi_data_t[max_bytes]; char error_message[MAXERRORLENGTH]; MMRESULT result = midiInOpen(&handle, index, (DWORD)HandleMidiInputEvent, @@ -95,8 +95,8 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, snprintf(name, sizeof(name) - 1, "%s:capture_%d", client_name, index + 1); jack_event = 0; started = false; - write_queue_ptr.release(); - thread_queue_ptr.release(); + //write_queue_ptr.release(); + //thread_queue_ptr.release(); return; unprepare_header: @@ -164,14 +164,14 @@ JackWinMMEInputPort::ProcessJack(JackMidiBuffer *port_buffer, if (! jack_event) { jack_event = thread_queue->DequeueEvent(); } - for (; jack_event; jack_event = thread_queue->DequeueEvent()) { + for (; jack_event; jack_event = thread_queue->DequeueEvent()) { switch (write_queue->EnqueueEvent(jack_event)) { case JackMidiWriteQueue::BUFFER_TOO_SMALL: jack_error("JackWinMMEMidiInputPort::Process - The buffer write " "queue couldn't enqueue a %d-byte event. Dropping " "event.", jack_event->size); // Fallthrough on purpose - case JackMidiWriteQueue::OK: + case JackMidiWriteQueue::OK: continue; } break; @@ -182,7 +182,8 @@ void JackWinMMEInputPort::ProcessWinMME(UINT message, DWORD param1, DWORD param2) { set_threaded_log_function(); - jack_nframes_t current_frame = GetCurrentFrame(); + jack_nframes_t current_frame = GetCurrentFrame(); + switch (message) { case MIM_CLOSE: jack_info("JackWinMMEInputPort::ProcessWinMME - MIDI device closed."); @@ -195,13 +196,14 @@ JackWinMMEInputPort::ProcessWinMME(UINT message, DWORD param1, DWORD param2) case MIM_DATA: jack_midi_data_t message_buffer[3]; jack_midi_data_t status = param1 & 0xff; - int length = GetMessageLength(status); + int length = GetMessageLength(status); + switch (length) { case 3: - message_buffer[2] = param1 & 0xff0000; + message_buffer[2] = (param1 >> 16) & 0xff; // Fallthrough on purpose. case 2: - message_buffer[1] = param1 & 0xff00; + message_buffer[1] = (param1 >> 8) & 0xff; // Fallthrough on purpose. case 1: message_buffer[0] = status; @@ -216,7 +218,7 @@ JackWinMMEInputPort::ProcessWinMME(UINT message, DWORD param1, DWORD param2) "input driver sent an MIM_DATA message with an invalid " "status byte."); return; - } + } EnqueueMessage(current_frame, (size_t) length, message_buffer); break; case MIM_LONGDATA: diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index 51a9ddbd..060e525b 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -49,11 +49,11 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, size_t max_messages) { read_queue = new JackMidiBufferReadQueue(); - std::auto_ptr read_queue_ptr(read_queue); + //std::auto_ptr read_queue_ptr(read_queue); thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); - std::auto_ptr thread_queue_ptr(thread_queue); + //std::auto_ptr thread_queue_ptr(thread_queue); thread = new JackThread(this); - std::auto_ptr thread_ptr(thread); + //std::auto_ptr thread_ptr(thread); char error_message[MAXERRORLENGTH]; MMRESULT result = midiOutOpen(&handle, index, (DWORD)HandleMessageEvent, (DWORD)this, CALLBACK_FUNCTION); @@ -84,8 +84,8 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", alias_name, name_tmp, index + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", client_name, index + 1); - thread_ptr.release(); - thread_queue_ptr.release(); + //thread_ptr.release(); + //thread_queue_ptr.release(); return; destroy_thread_queue_semaphore: @@ -129,15 +129,12 @@ bool JackWinMMEOutputPort::Execute() { for (;;) { - jack_log("JackWinMMEOutputPort::Execute TOTO"); - JackSleep(100000); - - if (! Wait(thread_queue_semaphore)) { + if (! Wait(thread_queue_semaphore)) { jack_log("JackWinMMEOutputPort::Execute BREAK"); break; - } - /* + } + jack_midi_event_t *event = thread_queue->DequeueEvent(); if (! event) { break; @@ -217,7 +214,7 @@ JackWinMMEOutputPort::Execute() "midiOutUnprepareHeader", result); break; } - */ + } stop_execution: return false; @@ -262,10 +259,12 @@ JackWinMMEOutputPort::Init() void JackWinMMEOutputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames) -{ - read_queue->ResetMidiBuffer(port_buffer); +{ + read_queue->ResetMidiBuffer(port_buffer); + for (jack_midi_event_t *event = read_queue->DequeueEvent(); event; - event = read_queue->DequeueEvent()) { + event = read_queue->DequeueEvent()) { + switch (thread_queue->EnqueueEvent(event, frames)) { case JackMidiWriteQueue::BUFFER_FULL: jack_error("JackWinMMEOutputPort::ProcessJack - The thread queue " @@ -339,8 +338,6 @@ JackWinMMEOutputPort::Stop() bool JackWinMMEOutputPort::Wait(HANDLE semaphore) { - jack_log("JackWinMMEOutputPort::Wait %d", semaphore); - DWORD result = WaitForSingleObject(semaphore, INFINITE); switch (result) { case WAIT_FAILED: From 083de8e163af8e6a092c265ae1883f3908e7a8fc Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 4 Apr 2011 15:21:00 +0000 Subject: [PATCH 135/472] Cleanup now unused code in JackMidiDriver. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4261 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackMidiDriver.cpp | 18 ++---------------- common/JackMidiDriver.h | 2 -- windows/portaudio/JackPortAudioDriver.cpp | 4 +--- 3 files changed, 3 insertions(+), 21 deletions(-) diff --git a/common/JackMidiDriver.cpp b/common/JackMidiDriver.cpp index b98b8daa..1fbd1e38 100644 --- a/common/JackMidiDriver.cpp +++ b/common/JackMidiDriver.cpp @@ -34,19 +34,10 @@ JackMidiDriver::JackMidiDriver(const char* name, const char* alias, JackLockedEn : JackDriver(name, alias, engine, table), fCaptureChannels(0), fPlaybackChannels(0) -{ - for (int i = 0; i < DRIVER_PORT_NUM; i++) { - fRingBuffer[i] = NULL; - } -} +{} JackMidiDriver::~JackMidiDriver() -{ - for (int i = 0; i < fCaptureChannels; i++) { - if (fRingBuffer[i]) - jack_ringbuffer_free(fRingBuffer[i]); - } -} +{} int JackMidiDriver::Open(bool capturing, bool playing, @@ -60,11 +51,6 @@ int JackMidiDriver::Open(bool capturing, { fCaptureChannels = inchannels; fPlaybackChannels = outchannels; - - for (int i = 0; i < fCaptureChannels; i++) { - fRingBuffer[i] = jack_ringbuffer_create(sizeof(jack_default_audio_sample_t) * BUFFER_SIZE_MAX); - } - return JackDriver::Open(capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); } diff --git a/common/JackMidiDriver.h b/common/JackMidiDriver.h index fa471627..b7584bbe 100644 --- a/common/JackMidiDriver.h +++ b/common/JackMidiDriver.h @@ -40,8 +40,6 @@ class SERVER_EXPORT JackMidiDriver : public JackDriver int fCaptureChannels; int fPlaybackChannels; - jack_ringbuffer_t* fRingBuffer[DRIVER_PORT_NUM]; - jack_port_id_t fCapturePortList[DRIVER_PORT_NUM]; jack_port_id_t fPlaybackPortList[DRIVER_PORT_NUM]; diff --git a/windows/portaudio/JackPortAudioDriver.cpp b/windows/portaudio/JackPortAudioDriver.cpp index 603c1fff..a314e30c 100644 --- a/windows/portaudio/JackPortAudioDriver.cpp +++ b/windows/portaudio/JackPortAudioDriver.cpp @@ -82,7 +82,7 @@ namespace Jack : 0; outputParameters.hostApiSpecificStreamInfo = NULL; - PaError err = Pa_OpenStream(&fStream, + return Pa_OpenStream(&fStream, (fInputDevice == paNoDevice) ? 0 : &inputParameters, (fOutputDevice == paNoDevice) ? 0 : &outputParameters, fEngineControl->fSampleRate, @@ -90,8 +90,6 @@ namespace Jack paNoFlag, // Clipping is on... Render, this); - - return err; } int JackPortAudioDriver::Open(jack_nframes_t buffer_size, From a6bd0be7f86d0edc8f64806ec6d959ef633b3932 Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 4 Apr 2011 15:22:49 +0000 Subject: [PATCH 136/472] Cleanup. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4262 0c269be4-1314-0410-8aa9-9f06e86f4224 --- windows/winmme/JackWinMMEOutputPort.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index 060e525b..a3a478e1 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -85,7 +85,8 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, index + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", client_name, index + 1); //thread_ptr.release(); - //thread_queue_ptr.release(); + //thread_queue_ptr.release(); + //thread_ptr.release(); return; destroy_thread_queue_semaphore: @@ -122,7 +123,8 @@ JackWinMMEOutputPort::~JackWinMMEOutputPort() WriteOSError("JackWinMMEOutputPort [destructor]", "CloseHandle"); } delete read_queue; - delete thread_queue; + delete thread_queue; + delete thread; } bool From c9343ff2900738aec32878353adb6079bf853125 Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 4 Apr 2011 15:29:29 +0000 Subject: [PATCH 137/472] "Fix" auto_ptr issues on Windows. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4263 0c269be4-1314-0410-8aa9-9f06e86f4224 --- windows/winmme/JackWinMMEDriver.cpp | 1 - windows/winmme/JackWinMMEInputPort.cpp | 5 ++++- windows/winmme/JackWinMMEOutputPort.cpp | 6 +++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/windows/winmme/JackWinMMEDriver.cpp b/windows/winmme/JackWinMMEDriver.cpp index fa3e1f7f..2a9085ec 100644 --- a/windows/winmme/JackWinMMEDriver.cpp +++ b/windows/winmme/JackWinMMEDriver.cpp @@ -186,7 +186,6 @@ JackWinMMEDriver::Open(bool capturing, bool playing, int in_channels, jack_info("JackWinMMEDriver::Open - input_count %d", input_count); jack_info("JackWinMMEDriver::Open - output_count %d", output_count); - if (! (input_count || output_count)) { jack_error("JackWinMMEDriver::Open - no WinMME inputs or outputs " "allocated."); diff --git a/windows/winmme/JackWinMMEInputPort.cpp b/windows/winmme/JackWinMMEInputPort.cpp index 6bb2d2a5..871934c4 100644 --- a/windows/winmme/JackWinMMEInputPort.cpp +++ b/windows/winmme/JackWinMMEInputPort.cpp @@ -111,7 +111,10 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, WriteInError("JackWinMMEInputPort [constructor]", "midiInClose", result); } delete_sysex_buffer: - delete[] sysex_buffer; + delete[] sysex_buffer; + // auto_ptr causing crash so explicitly deleting here... + delete thread_queue; + delete write_queue; throw std::runtime_error(error_message); } diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index a3a478e1..05e97362 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -99,7 +99,11 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, WriteOutError("JackWinMMEOutputPort [constructor]", "midiOutClose", result); } - raise_exception: + raise_exception: + // auto_ptr causing crash so explicitly deleting here... + delete read_queue; + delete thread_queue; + delete thread; throw std::runtime_error(error_message); } From a722a218dbb54b88b8f5d798bb37e7d21f5d5159 Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 4 Apr 2011 15:42:18 +0000 Subject: [PATCH 138/472] Really fix auto_ptr issues on Windows. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4264 0c269be4-1314-0410-8aa9-9f06e86f4224 --- windows/winmme/JackWinMMEInputPort.cpp | 11 ++++------- windows/winmme/JackWinMMEOutputPort.cpp | 16 ++++++---------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/windows/winmme/JackWinMMEInputPort.cpp b/windows/winmme/JackWinMMEInputPort.cpp index 871934c4..7371cbf4 100644 --- a/windows/winmme/JackWinMMEInputPort.cpp +++ b/windows/winmme/JackWinMMEInputPort.cpp @@ -50,9 +50,9 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, size_t max_bytes, size_t max_messages) { thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); - //std::auto_ptr thread_queue_ptr(thread_queue); + std::auto_ptr thread_queue_ptr(thread_queue); write_queue = new JackMidiBufferWriteQueue(); - //std::auto_ptr write_queue_ptr(write_queue); + std::auto_ptr write_queue_ptr(write_queue); sysex_buffer = new jack_midi_data_t[max_bytes]; char error_message[MAXERRORLENGTH]; MMRESULT result = midiInOpen(&handle, index, (DWORD)HandleMidiInputEvent, @@ -95,8 +95,8 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, snprintf(name, sizeof(name) - 1, "%s:capture_%d", client_name, index + 1); jack_event = 0; started = false; - //write_queue_ptr.release(); - //thread_queue_ptr.release(); + write_queue_ptr.release(); + thread_queue_ptr.release(); return; unprepare_header: @@ -112,9 +112,6 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, } delete_sysex_buffer: delete[] sysex_buffer; - // auto_ptr causing crash so explicitly deleting here... - delete thread_queue; - delete write_queue; throw std::runtime_error(error_message); } diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index 05e97362..01ac2f02 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -49,11 +49,11 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, size_t max_messages) { read_queue = new JackMidiBufferReadQueue(); - //std::auto_ptr read_queue_ptr(read_queue); + std::auto_ptr read_queue_ptr(read_queue); thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); - //std::auto_ptr thread_queue_ptr(thread_queue); + std::auto_ptr thread_queue_ptr(thread_queue); thread = new JackThread(this); - //std::auto_ptr thread_ptr(thread); + std::auto_ptr thread_ptr(thread); char error_message[MAXERRORLENGTH]; MMRESULT result = midiOutOpen(&handle, index, (DWORD)HandleMessageEvent, (DWORD)this, CALLBACK_FUNCTION); @@ -84,9 +84,9 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", alias_name, name_tmp, index + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", client_name, index + 1); - //thread_ptr.release(); - //thread_queue_ptr.release(); - //thread_ptr.release(); + read_queue_ptr.release(); + thread_queue_ptr.release(); + thread_ptr.release(); return; destroy_thread_queue_semaphore: @@ -100,10 +100,6 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, result); } raise_exception: - // auto_ptr causing crash so explicitly deleting here... - delete read_queue; - delete thread_queue; - delete thread; throw std::runtime_error(error_message); } From 169d3ef8691a54175cc47092392c3c35b9e34aa0 Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 4 Apr 2011 18:26:30 +0000 Subject: [PATCH 139/472] Attempt to port midi_latency_test.c to Windows. Can't test, as I don't have a Windows development environment. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4265 0c269be4-1314-0410-8aa9-9f06e86f4224 --- example-clients/midi_latency_test.c | 272 ++++++++++++++++++---------- 1 file changed, 177 insertions(+), 95 deletions(-) diff --git a/example-clients/midi_latency_test.c b/example-clients/midi_latency_test.c index 42e7f1ed..156e6667 100644 --- a/example-clients/midi_latency_test.c +++ b/example-clients/midi_latency_test.c @@ -53,22 +53,31 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include -#include -#include #include #include +#ifdef WIN32 +#include +#else +#include +#endif + #define ABS(x) (((x) >= 0) ? (x) : (-(x))) -const char *ERROR_UNEXPECTED = "in port received unexpected MIDI message"; -const char *ERROR_UNEXPECTED_EXTRA = "received more than one MIDI message"; +#ifdef WIN32 +typedef HANDLE semaphore_t; +#else +typedef sem_t *semaphore_t; +#endif + const char *ERROR_RESERVE = "could not reserve MIDI event on port buffer"; const char *ERROR_TIMEOUT = "timed out while waiting for MIDI message"; + const char *SOURCE_EVENT_RESERVE = "jack_midi_event_reserve"; const char *SOURCE_PROCESS = "handle_process"; -const char *SOURCE_TRYLOCK = "pthread_mutex_trylock"; -const char *SOURCE_UNLOCK = "pthread_mutex_unlock"; +const char *SOURCE_SIGNAL_SEMAPHORE = "signal_semaphore"; +const char *SOURCE_WAIT_SEMAPHORE = "wait_semaphore"; jack_client_t *client; const char *error_message; @@ -77,6 +86,7 @@ jack_nframes_t highest_latency; jack_time_t highest_latency_time; jack_latency_range_t in_latency_range; jack_port_t *in_port; +semaphore_t init_semaphore; jack_nframes_t last_activity; jack_time_t last_activity_time; jack_time_t *latency_time_values; @@ -90,25 +100,22 @@ size_t messages_sent; size_t message_size; jack_latency_range_t out_latency_range; jack_port_t *out_port; +semaphore_t process_semaphore; int process_state; char *program_name; jack_port_t *remote_in_port; jack_port_t *remote_out_port; size_t samples; - -#ifdef __APPLE__ -sem_t* semaphore; -#else -sem_t semaphore; -#endif - -pthread_mutex_t start_mutex; int timeout; jack_nframes_t total_latency; jack_time_t total_latency_time; size_t unexpected_messages; size_t xrun_count; +#ifdef WIN32 +char *semaphore_error_msg; +#endif + static void output_error(const char *source, const char *message); @@ -118,6 +125,58 @@ output_usage(); static void set_process_error(const char *source, const char *message); +static int +signal_semaphore(semaphore_t semaphore); + +static int +wait_semaphore(semaphore_t semaphore, int block); + +static semaphore_t +create_semaphore(int id) +{ + semaphore_t semaphore; + +#ifdef WIN32 + semaphore = CreateSemaphore(NULL, 0, 1, NULL); +#elif defined (__APPLE__) + char name[128]; + sprintf(name, "midi_sem_%d", id); + semaphore = sem_open(name, O_CREAT, 0777, 0); + if (semaphore == (sem_t *) SEM_FAILED) { + semaphore = NULL; + } +#else + semaphore = malloc(sizeof(semaphore_t)); + if (semaphore != NULL) { + if (sem_init(semaphore, 0, 0)) { + free(semaphore); + semaphore = NULL; + } + } +#endif + + return semaphore; +} + +static void +destroy_semaphore(semaphore_t semaphore, int id) +{ + +#ifdef WIN32 + CloseHandle(semaphore); +#else + sem_destroy(semaphore); +#ifdef __APPLE__ + { + char name[128]; + sprintf(name, "midi_sem_%d", id); + sem_unlink(name); + } +#endif +#endif + +} + static void die(char *source, char *error_message) { @@ -126,6 +185,25 @@ die(char *source, char *error_message) exit(EXIT_FAILURE); } +static const char * +get_semaphore_error() +{ + +#ifdef WIN32 + DWORD error = GetLastError(); + if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + semaphore_error_msg, 1024, NULL)) { + sprintf(semaphore_error_msg, 1024, "Unknown OS error code '%d'", + error); + } + return semaphore_error_msg; +#else + return strerror(errno); +#endif + +} + static void handle_info(const char *message) { @@ -136,7 +214,6 @@ static int handle_process(jack_nframes_t frames, void *arg) { jack_midi_data_t *buffer; - int code; jack_midi_event_t event; jack_nframes_t event_count; jack_nframes_t event_time; @@ -144,23 +221,20 @@ handle_process(jack_nframes_t frames, void *arg) size_t i; jack_nframes_t last_frame_time; jack_midi_data_t *message; + jack_time_t microseconds; void *port_buffer; jack_time_t time; + jack_midi_clear_buffer(jack_port_get_buffer(out_port, frames)); switch (process_state) { case 0: /* State: initializing */ - code = pthread_mutex_trylock(&start_mutex); - if (code) { - if (code != EBUSY) { - set_process_error(SOURCE_TRYLOCK, strerror(code)); - } - break; - } - code = pthread_mutex_unlock(&start_mutex); - if (code) { - set_process_error(SOURCE_UNLOCK, strerror(code)); - break; + switch (wait_semaphore(init_semaphore, 0)) { + case -1: + set_process_error(SOURCE_WAIT_SEMAPHORE, get_semaphore_error()); + // Fallthrough on purpose + case 0: + return 0; } highest_latency = 0; lowest_latency = 0; @@ -179,7 +253,6 @@ handle_process(jack_nframes_t frames, void *arg) case 1: /* State: processing */ - jack_midi_clear_buffer(jack_port_get_buffer(out_port, frames)); port_buffer = jack_port_get_buffer(in_port, frames); event_count = jack_midi_get_event_count(port_buffer); last_frame_time = jack_last_frame_time(client); @@ -193,8 +266,8 @@ handle_process(jack_nframes_t frames, void *arg) } unexpected_messages++; } - jack_time_t microseconds = - jack_frames_to_time(client, last_frame_time) - last_activity_time; + microseconds = jack_frames_to_time(client, last_frame_time) - + last_activity_time; if ((microseconds / 1000000) >= timeout) { set_process_error(SOURCE_PROCESS, ERROR_TIMEOUT); } @@ -218,13 +291,10 @@ handle_process(jack_nframes_t frames, void *arg) messages_received++; if (messages_received == samples) { process_state = 2; - -#ifdef __APPLE__ - sem_post(semaphore); -#else - sem_post(&semaphore); -#endif - + if (! signal_semaphore(process_semaphore)) { + // Sigh ... + die(SOURCE_SIGNAL_SEMAPHORE, get_semaphore_error()); + } break; } send_message: @@ -314,11 +384,58 @@ set_process_error(const char *source, const char *message) error_source = source; error_message = message; process_state = -1; + if (! signal_semaphore(process_semaphore)) { + // Sigh + output_error(source, message); + die(SOURCE_SIGNAL_SEMAPHORE, get_semaphore_error()); + } +} -#ifdef __APPLE__ - sem_post(semaphore); +static int +signal_semaphore(semaphore_t semaphore) +{ + +#ifdef WIN32 + return ReleaseSemaphore(semaphore, 1, NULL); #else - sem_post(&semaphore); + return ! sem_post(semaphore); +#endif + +} + +static int +wait_semaphore(semaphore_t semaphore, int block) +{ + +#ifdef WIN32 + DWORD result = WaitForSingleObject(semaphore, block ? INFINITE : 0); + switch (result) { + case WAIT_OBJECT_0: + return 1; + case WAIT_TIMEOUT: + return 0; + } + return -1; +#else + if (block) { + while (sem_wait(semaphore)) { + if (errno != EINTR) { + return -1; + } + } + } else { + while (sem_trywait(semaphore)) { + switch (errno) { + case EAGAIN: + return 0; + case EINTR: + continue; + default: + return -1; + } + } + } + return 1; #endif } @@ -326,7 +443,6 @@ set_process_error(const char *source, const char *message) int main(int argc, char **argv) { - int code; size_t jitter_plot[101]; int long_index = 0; struct option long_options[] = { @@ -478,40 +594,22 @@ main(int argc, char **argv) jack_on_shutdown(client, handle_shutdown, NULL); jack_set_info_function(handle_info); process_state = 0; - -#ifdef __APPLE__ - // sem_init is not implemented on OSX - char name[128]; - sprintf(name, "midi_sem_%p", client); - if ((semaphore = sem_open(name, O_CREAT, 0777, 0)) == (sem_t*)SEM_FAILED) { - error_message = strerror(errno); - error_source = "sem_open"; + init_semaphore = create_semaphore(0); + if (init_semaphore == NULL) { + error_message = get_semaphore_error(); + error_source = "create_semaphore"; goto unregister_out_port; } -#else - if (sem_init(&semaphore, 0, 0)) { - error_message = strerror(errno); - error_source = "sem_init"; - goto unregister_out_port; - } -#endif - - code = pthread_mutex_init(&start_mutex, NULL); - if (code) { - error_message = strerror(errno); - error_source = "pthread_mutex_init"; - goto destroy_semaphore; - } - code = pthread_mutex_trylock(&start_mutex); - if (code) { - error_message = strerror(code); - error_source = "pthread_mutex_trylock"; - goto destroy_mutex; + process_semaphore = create_semaphore(1); + if (process_semaphore == NULL) { + error_message = get_semaphore_error(); + error_source = "create_semaphore"; + goto destroy_init_semaphore; } if (jack_activate(client)) { error_message = "could not activate client"; error_source = "jack_activate"; - goto destroy_mutex; + goto destroy_process_semaphore; } if (jack_connect(client, jack_port_name(out_port), jack_port_name(remote_out_port))) { @@ -525,24 +623,15 @@ main(int argc, char **argv) error_source = "jack_connect"; goto deactivate_client; } - code = pthread_mutex_unlock(&start_mutex); - if (code) { - error_message = strerror(code); - error_source = "pthread_mutex_unlock"; + if (! signal_semaphore(init_semaphore)) { + error_message = get_semaphore_error(); + error_source = "post_semaphore"; goto deactivate_client; } - -#ifdef __APPLE__ - while (sem_wait(semaphore) != 0) { -#else - while (sem_wait(&semaphore) != 0) { -#endif - - if (errno != EINTR) { - error_message = strerror(errno); - error_source = "sem_wait"; - goto deactivate_client; - } + if (wait_semaphore(process_semaphore, 1)) { + error_message = get_semaphore_error(); + error_source = "wait_semaphore"; + goto deactivate_client; } if (process_state == 2) { double average_latency = ((double) total_latency) / samples; @@ -608,17 +697,10 @@ main(int argc, char **argv) } deactivate_client: jack_deactivate(client); - destroy_mutex: - pthread_mutex_destroy(&start_mutex); - destroy_semaphore: - -#ifdef __APPLE__ - sem_destroy(semaphore); - sem_unlink(name); -#else - sem_destroy(&semaphore); -#endif - + destroy_process_semaphore: + destroy_semaphore(process_semaphore, 1); + destroy_init_semaphore: + destroy_semaphore(init_semaphore, 0); unregister_out_port: jack_port_unregister(client, out_port); unregister_in_port: From 4f5e3ecd37cacea88340a05b1903214a3edea282 Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 4 Apr 2011 20:58:20 +0000 Subject: [PATCH 140/472] Correct driver lifetime management. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4266 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 4 ++++ common/JackControlAPI.cpp | 20 +++++++++++++++----- common/JackDriver.cpp | 12 ++++++------ common/JackServer.cpp | 1 - common/Jackdmp.cpp | 13 +++++++++++++ linux/alsarawmidi/JackALSARawMidiDriver.cpp | 8 ++++---- macosx/coremidi/JackCoreMidiDriver.cpp | 9 ++++----- macosx/coremidi/JackCoreMidiOutputPort.cpp | 1 - windows/winmme/JackWinMMEDriver.cpp | 7 +++---- windows/winmme/JackWinMMEInputPort.cpp | 14 +++++++------- windows/winmme/JackWinMMEOutputPort.cpp | 17 ++++++++--------- 11 files changed, 64 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index 586bbfc7..f0b6694c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -34,6 +34,10 @@ Valerio Pilo Jackdmp changes log --------------------------- +2011-04-04 Stephane Letz + + * Correct driver lifetime management. + 2011-04-03 Stephane Letz * Fix in JackCoreAudioDriver::Read when there is no inputs. diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index 4ff69adc..2c612961 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -101,7 +101,8 @@ struct jackctl_driver jack_driver_desc_t * desc_ptr; JSList * parameters; JSList * set_parameters; - JackDriverInfo* info; + //JackDriverInfo* info; + JSList * infos; }; struct jackctl_internal @@ -308,6 +309,7 @@ jackctl_drivers_load( driver_ptr->desc_ptr = (jack_driver_desc_t *)descriptor_node_ptr->data; driver_ptr->parameters = NULL; driver_ptr->set_parameters = NULL; + driver_ptr->infos = NULL; if (!jackctl_add_driver_parameters(driver_ptr)) { @@ -377,6 +379,7 @@ jackctl_internals_load( internal_ptr->desc_ptr = (jack_driver_desc_t *)descriptor_node_ptr->data; internal_ptr->parameters = NULL; internal_ptr->set_parameters = NULL; + internal_ptr->refnum = -1; if (!jackctl_add_driver_parameters((struct jackctl_driver *)internal_ptr)) { @@ -1214,8 +1217,13 @@ EXPORT bool jackctl_server_add_slave(jackctl_server * server_ptr, jackctl_driver jack_error("cannot add a slave in a running server"); return false; } else { - driver_ptr->info = server_ptr->engine->AddSlave(driver_ptr->desc_ptr, driver_ptr->set_parameters); - return (driver_ptr->info != 0); + JackDriverInfo* info = server_ptr->engine->AddSlave(driver_ptr->desc_ptr, driver_ptr->set_parameters); + if (info) { + driver_ptr->infos = jack_slist_append(driver_ptr->infos, info); + return true; + } else { + return false; + } } } else { return false; @@ -1229,8 +1237,10 @@ EXPORT bool jackctl_server_remove_slave(jackctl_server * server_ptr, jackctl_dri jack_error("cannot remove a slave from a running server"); return false; } else { - server_ptr->engine->RemoveSlave(driver_ptr->info); - delete driver_ptr->info; + JackDriverInfo* info = (JackDriverInfo*)driver_ptr->infos->data; + driver_ptr->infos = jack_slist_remove(driver_ptr->infos, info); + server_ptr->engine->RemoveSlave(info); + delete info; return true; } } else { diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index b09eb812..e424ce28 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -376,6 +376,12 @@ int JackDriver::Start() return 0; } +int JackDriver::Stop() +{ + fIsRunning = false; + return 0; +} + int JackDriver::StartSlaves() { int res = 0; @@ -394,12 +400,6 @@ int JackDriver::StartSlaves() return res; } -int JackDriver::Stop() -{ - fIsRunning = false; - return 0; -} - int JackDriver::StopSlaves() { int res = 0; diff --git a/common/JackServer.cpp b/common/JackServer.cpp index 22027c9c..3b060ee5 100644 --- a/common/JackServer.cpp +++ b/common/JackServer.cpp @@ -137,7 +137,6 @@ int JackServer::Close() fChannel.Close(); fAudioDriver->Detach(); fAudioDriver->Close(); - fFreewheelDriver->Close(); fEngine->Close(); // TODO: move that in reworked JackServerGlobals::Destroy() JackMessageBuffer::Destroy(); diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index f0651ab9..d72243e6 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -533,6 +533,19 @@ int main(int argc, char* argv[]) fprintf(stderr, "Cannot stop server...\n"); } close_server: + if (loopback > 0) { + jackctl_server_remove_slave(server_ctl, loopback_driver_ctl); + } + // Slave drivers + for (it = slaves_list.begin(); it != slaves_list.end(); it++) { + jackctl_driver_t * slave_driver_ctl = jackctl_server_get_driver(server_ctl, *it); + jackctl_server_remove_slave(server_ctl, slave_driver_ctl); + } + // Internal clients + for (it = internals_list.begin(); it != internals_list.end(); it++) { + jackctl_internal_t * internal_driver_ctl = jackctl_server_get_internal(server_ctl, *it); + jackctl_server_unload_internal(server_ctl, internal_driver_ctl); + } jackctl_server_close(server_ctl); destroy_server: jackctl_server_destroy(server_ctl); diff --git a/linux/alsarawmidi/JackALSARawMidiDriver.cpp b/linux/alsarawmidi/JackALSARawMidiDriver.cpp index 7bbd5276..d2220707 100755 --- a/linux/alsarawmidi/JackALSARawMidiDriver.cpp +++ b/linux/alsarawmidi/JackALSARawMidiDriver.cpp @@ -48,9 +48,7 @@ JackALSARawMidiDriver::JackALSARawMidiDriver(const char *name, JackALSARawMidiDriver::~JackALSARawMidiDriver() { - Stop(); delete thread; - Close(); } int @@ -109,6 +107,9 @@ JackALSARawMidiDriver::Attach() int JackALSARawMidiDriver::Close() { + // Generic MIDI driver close + int result = JackMidiDriver::Close(); + if (input_ports) { for (int i = 0; i < fCaptureChannels; i++) { delete input_ports[i]; @@ -123,7 +124,7 @@ JackALSARawMidiDriver::Close() delete[] output_ports; output_ports = 0; } - return 0; + return result; } bool @@ -528,7 +529,6 @@ JackALSARawMidiDriver::Start() int JackALSARawMidiDriver::Stop() { - jack_info("JackALSARawMidiDriver::Stop - stopping 'alsarawmidi' driver."); if (fds[1] != -1) { diff --git a/macosx/coremidi/JackCoreMidiDriver.cpp b/macosx/coremidi/JackCoreMidiDriver.cpp index cc9b67c5..292e771f 100644 --- a/macosx/coremidi/JackCoreMidiDriver.cpp +++ b/macosx/coremidi/JackCoreMidiDriver.cpp @@ -75,10 +75,7 @@ JackCoreMidiDriver::JackCoreMidiDriver(const char *name, const char *alias, } JackCoreMidiDriver::~JackCoreMidiDriver() -{ - Stop(); - Close(); -} +{} int JackCoreMidiDriver::Attach() @@ -181,7 +178,9 @@ JackCoreMidiDriver::Attach() int JackCoreMidiDriver::Close() { - int result = 0; + // Generic MIDI driver close + int result = JackMidiDriver::Close(); + OSStatus status; if (physical_input_ports) { for (int i = 0; i < num_physical_inputs; i++) { diff --git a/macosx/coremidi/JackCoreMidiOutputPort.cpp b/macosx/coremidi/JackCoreMidiOutputPort.cpp index f014d478..9a66b88d 100644 --- a/macosx/coremidi/JackCoreMidiOutputPort.cpp +++ b/macosx/coremidi/JackCoreMidiOutputPort.cpp @@ -53,7 +53,6 @@ JackCoreMidiOutputPort::JackCoreMidiOutputPort(double time_ratio, JackCoreMidiOutputPort::~JackCoreMidiOutputPort() { - Stop(); delete thread; sem_destroy(thread_queue_semaphore); sem_unlink(semaphore_name); diff --git a/windows/winmme/JackWinMMEDriver.cpp b/windows/winmme/JackWinMMEDriver.cpp index 2a9085ec..f7793363 100644 --- a/windows/winmme/JackWinMMEDriver.cpp +++ b/windows/winmme/JackWinMMEDriver.cpp @@ -35,10 +35,7 @@ JackWinMMEDriver::JackWinMMEDriver(const char *name, const char *alias, } JackWinMMEDriver::~JackWinMMEDriver() -{ - Stop(); - Close(); -} +{} int JackWinMMEDriver::Attach() @@ -105,7 +102,9 @@ JackWinMMEDriver::Attach() int JackWinMMEDriver::Close() { + // Generic MIDI driver close int result = JackMidiDriver::Close(); + if (input_ports) { for (int i = 0; i < fCaptureChannels; i++) { delete input_ports[i]; diff --git a/windows/winmme/JackWinMMEInputPort.cpp b/windows/winmme/JackWinMMEInputPort.cpp index 7371cbf4..acafe158 100644 --- a/windows/winmme/JackWinMMEInputPort.cpp +++ b/windows/winmme/JackWinMMEInputPort.cpp @@ -111,13 +111,12 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, WriteInError("JackWinMMEInputPort [constructor]", "midiInClose", result); } delete_sysex_buffer: - delete[] sysex_buffer; + delete[] sysex_buffer; throw std::runtime_error(error_message); } JackWinMMEInputPort::~JackWinMMEInputPort() { - Stop(); MMRESULT result = midiInReset(handle); if (result != MMSYSERR_NOERROR) { WriteInError("JackWinMMEInputPort [destructor]", "midiInReset", result); @@ -164,14 +163,14 @@ JackWinMMEInputPort::ProcessJack(JackMidiBuffer *port_buffer, if (! jack_event) { jack_event = thread_queue->DequeueEvent(); } - for (; jack_event; jack_event = thread_queue->DequeueEvent()) { + for (; jack_event; jack_event = thread_queue->DequeueEvent()) { switch (write_queue->EnqueueEvent(jack_event)) { case JackMidiWriteQueue::BUFFER_TOO_SMALL: jack_error("JackWinMMEMidiInputPort::Process - The buffer write " "queue couldn't enqueue a %d-byte event. Dropping " "event.", jack_event->size); // Fallthrough on purpose - case JackMidiWriteQueue::OK: + case JackMidiWriteQueue::OK: continue; } break; @@ -182,7 +181,7 @@ void JackWinMMEInputPort::ProcessWinMME(UINT message, DWORD param1, DWORD param2) { set_threaded_log_function(); - jack_nframes_t current_frame = GetCurrentFrame(); + jack_nframes_t current_frame = GetCurrentFrame(); switch (message) { case MIM_CLOSE: @@ -196,7 +195,7 @@ JackWinMMEInputPort::ProcessWinMME(UINT message, DWORD param1, DWORD param2) case MIM_DATA: jack_midi_data_t message_buffer[3]; jack_midi_data_t status = param1 & 0xff; - int length = GetMessageLength(status); + int length = GetMessageLength(status); switch (length) { case 3: @@ -218,7 +217,7 @@ JackWinMMEInputPort::ProcessWinMME(UINT message, DWORD param1, DWORD param2) "input driver sent an MIM_DATA message with an invalid " "status byte."); return; - } + } EnqueueMessage(current_frame, (size_t) length, message_buffer); break; case MIM_LONGDATA: @@ -294,3 +293,4 @@ JackWinMMEInputPort::WriteInError(const char *jack_func, const char *mm_func, jack_error("%s - %s: %s", jack_func, mm_func, error_message); } + diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index 01ac2f02..fea0aa53 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -85,7 +85,7 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, index + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", client_name, index + 1); read_queue_ptr.release(); - thread_queue_ptr.release(); + thread_queue_ptr.release(); thread_ptr.release(); return; @@ -99,13 +99,12 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, WriteOutError("JackWinMMEOutputPort [constructor]", "midiOutClose", result); } - raise_exception: + raise_exception: throw std::runtime_error(error_message); } JackWinMMEOutputPort::~JackWinMMEOutputPort() { - Stop(); MMRESULT result = midiOutReset(handle); if (result != MMSYSERR_NOERROR) { WriteOutError("JackWinMMEOutputPort [destructor]", "midiOutReset", @@ -123,7 +122,7 @@ JackWinMMEOutputPort::~JackWinMMEOutputPort() WriteOSError("JackWinMMEOutputPort [destructor]", "CloseHandle"); } delete read_queue; - delete thread_queue; + delete thread_queue; delete thread; } @@ -135,7 +134,7 @@ JackWinMMEOutputPort::Execute() jack_log("JackWinMMEOutputPort::Execute BREAK"); break; - } + } jack_midi_event_t *event = thread_queue->DequeueEvent(); if (! event) { @@ -261,11 +260,11 @@ JackWinMMEOutputPort::Init() void JackWinMMEOutputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames) -{ - read_queue->ResetMidiBuffer(port_buffer); +{ + read_queue->ResetMidiBuffer(port_buffer); for (jack_midi_event_t *event = read_queue->DequeueEvent(); event; - event = read_queue->DequeueEvent()) { + event = read_queue->DequeueEvent()) { switch (thread_queue->EnqueueEvent(event, frames)) { case JackMidiWriteQueue::BUFFER_FULL: @@ -310,7 +309,6 @@ JackWinMMEOutputPort::Start() bool JackWinMMEOutputPort::Stop() { - jack_info("JackWinMMEOutputPort::Stop - stopping MIDI output port " "processing thread."); @@ -371,3 +369,4 @@ JackWinMMEOutputPort::WriteOutError(const char *jack_func, const char *mm_func, GetOutErrorString(result, error_message); jack_error("%s - %s: %s", jack_func, mm_func, error_message); } + From cf7c43c270cd5e15b8b95d89cc4679ae1cfad9df Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 4 Apr 2011 21:03:01 +0000 Subject: [PATCH 141/472] Free semaphore memory on Linux. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4267 0c269be4-1314-0410-8aa9-9f06e86f4224 --- example-clients/midi_latency_test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/example-clients/midi_latency_test.c b/example-clients/midi_latency_test.c index 156e6667..ae850a48 100644 --- a/example-clients/midi_latency_test.c +++ b/example-clients/midi_latency_test.c @@ -172,6 +172,8 @@ destroy_semaphore(semaphore_t semaphore, int id) sprintf(name, "midi_sem_%d", id); sem_unlink(name); } +#else + free(semaphore); #endif #endif From 44d46d34cdb77588054c919f5c5bfe227a6c37f5 Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 4 Apr 2011 21:03:10 +0000 Subject: [PATCH 142/472] Oops! Check proper error return code from 'wait_semaphore'. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4268 0c269be4-1314-0410-8aa9-9f06e86f4224 --- example-clients/midi_latency_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example-clients/midi_latency_test.c b/example-clients/midi_latency_test.c index ae850a48..1f671f7c 100644 --- a/example-clients/midi_latency_test.c +++ b/example-clients/midi_latency_test.c @@ -630,7 +630,7 @@ main(int argc, char **argv) error_source = "post_semaphore"; goto deactivate_client; } - if (wait_semaphore(process_semaphore, 1)) { + if (wait_semaphore(process_semaphore, 1) == -1) { error_message = get_semaphore_error(); error_source = "wait_semaphore"; goto deactivate_client; From d904746b42411382280ade9f0e10b5c089c6cb15 Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 4 Apr 2011 21:03:19 +0000 Subject: [PATCH 143/472] Oops! Fix error messages on WIN32. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4269 0c269be4-1314-0410-8aa9-9f06e86f4224 --- example-clients/midi_latency_test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example-clients/midi_latency_test.c b/example-clients/midi_latency_test.c index 1f671f7c..b38c07d4 100644 --- a/example-clients/midi_latency_test.c +++ b/example-clients/midi_latency_test.c @@ -113,7 +113,7 @@ size_t unexpected_messages; size_t xrun_count; #ifdef WIN32 -char *semaphore_error_msg; +char semaphore_error_msg[1024]; #endif static void @@ -196,7 +196,7 @@ get_semaphore_error() if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), semaphore_error_msg, 1024, NULL)) { - sprintf(semaphore_error_msg, 1024, "Unknown OS error code '%d'", + sprintf(semaphore_error_msg, 1023, "Unknown OS error code '%d'", error); } return semaphore_error_msg; From 59b39cad0e45c99b0b0ebeef58de5fbe3d82ddb7 Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 4 Apr 2011 21:08:11 +0000 Subject: [PATCH 144/472] Improve jackctl_server_remove_slave. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4270 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackControlAPI.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index 2c612961..c3ddec54 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -101,7 +101,6 @@ struct jackctl_driver jack_driver_desc_t * desc_ptr; JSList * parameters; JSList * set_parameters; - //JackDriverInfo* info; JSList * infos; }; @@ -1238,10 +1237,14 @@ EXPORT bool jackctl_server_remove_slave(jackctl_server * server_ptr, jackctl_dri return false; } else { JackDriverInfo* info = (JackDriverInfo*)driver_ptr->infos->data; - driver_ptr->infos = jack_slist_remove(driver_ptr->infos, info); - server_ptr->engine->RemoveSlave(info); - delete info; - return true; + if (info) { + driver_ptr->infos = jack_slist_remove(driver_ptr->infos, info); + server_ptr->engine->RemoveSlave(info); + delete info; + return true; + } else { + return false; + } } } else { return false; From 621db9bf55ff3435a33f60d34b7f2efea44b5b43 Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 4 Apr 2011 21:29:43 +0000 Subject: [PATCH 145/472] FW driver has to be explicitly closed. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4271 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackServer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/common/JackServer.cpp b/common/JackServer.cpp index 3b060ee5..22027c9c 100644 --- a/common/JackServer.cpp +++ b/common/JackServer.cpp @@ -137,6 +137,7 @@ int JackServer::Close() fChannel.Close(); fAudioDriver->Detach(); fAudioDriver->Close(); + fFreewheelDriver->Close(); fEngine->Close(); // TODO: move that in reworked JackServerGlobals::Destroy() JackMessageBuffer::Destroy(); From 0269b3deb228e87d82566deb9d53b71913dbf1c2 Mon Sep 17 00:00:00 2001 From: sletz Date: Mon, 4 Apr 2011 21:35:45 +0000 Subject: [PATCH 146/472] Improve handling of loopback driver. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4272 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/Jackdmp.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index d72243e6..f2edfe5b 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -191,7 +191,7 @@ int main(int argc, char* argv[]) const JSList * server_parameters; const char* server_name = "default"; jackctl_driver_t * master_driver_ctl; - jackctl_driver_t * loopback_driver_ctl; + jackctl_driver_t * loopback_driver_ctl = NULL; int replace_registry = 0; const char *options = "-d:X:I:P:uvshVrRL:STFl:t:mn:p:" @@ -486,7 +486,6 @@ int main(int argc, char* argv[]) if (loopback > 0) { loopback_driver_ctl = jackctl_server_get_driver(server_ctl, "loopback"); - // XX: What if this fails? if (loopback_driver_ctl != NULL) { const JSList * loopback_parameters = jackctl_driver_get_parameters(loopback_driver_ctl); param = jackctl_get_parameter(loopback_parameters, "channels"); @@ -498,8 +497,10 @@ int main(int argc, char* argv[]) fprintf(stderr, "Driver \"loopback\" cannot be loaded\n"); goto close_server; } + } else { + fprintf(stderr, "Driver \"loopback\" not found\n"); + goto close_server; } - } // Start the server @@ -533,7 +534,7 @@ int main(int argc, char* argv[]) fprintf(stderr, "Cannot stop server...\n"); } close_server: - if (loopback > 0) { + if (loopback > 0 && loopback_driver_ctl) { jackctl_server_remove_slave(server_ctl, loopback_driver_ctl); } // Slave drivers From 92bb6df2142cf54d5fc952f5820fa3c68b83cbde Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 5 Apr 2011 11:38:20 +0000 Subject: [PATCH 147/472] Remove warnings. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4273 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackDriverLoader.h | 2 +- linux/alsa/JackAlsaDriver.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/JackDriverLoader.h b/common/JackDriverLoader.h index c194304d..719881e8 100644 --- a/common/JackDriverLoader.h +++ b/common/JackDriverLoader.h @@ -30,7 +30,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. typedef jack_driver_desc_t * (*JackDriverDescFunction) (); typedef Jack::JackDriverClientInterface* (*driverInitialize) (Jack::JackLockedEngine*, Jack::JackSynchro*, const JSList*); -class JackDriverInfo +class SERVER_EXPORT JackDriverInfo { private: diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index f0da6578..470d46df 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -292,7 +292,7 @@ int JackAlsaDriver::Open(jack_nframes_t nframes, } } - fDriver = alsa_driver_new ("alsa_pcm", (char*)playback_driver_name, (char*)capture_driver_name, + fDriver = alsa_driver_new ((char*)"alsa_pcm", (char*)playback_driver_name, (char*)capture_driver_name, NULL, nframes, user_nperiods, From acb9fe26b959434b3f68ff56d4ecb4afe3a957e6 Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 5 Apr 2011 15:35:16 +0000 Subject: [PATCH 148/472] New internal JackSession.h file (for 64 bits compilation on Windows). git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4274 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackChannel.h | 4 ++- common/JackClient.h | 2 +- common/JackClientControl.h | 3 +- common/JackSession.h | 69 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 common/JackSession.h diff --git a/common/JackChannel.h b/common/JackChannel.h index c9ee89e5..a0bcfe63 100644 --- a/common/JackChannel.h +++ b/common/JackChannel.h @@ -20,7 +20,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __JackChannel__ #define __JackChannel__ -#include "session.h" +#include "types.h" +#include "JackSession.h" +//#include "session.h" namespace Jack { diff --git a/common/JackClient.h b/common/JackClient.h index a03e17d2..8a7a9249 100644 --- a/common/JackClient.h +++ b/common/JackClient.h @@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackSynchro.h" #include "JackPlatformPlug.h" #include "JackChannel.h" -#include "session.h" +//#include "session.h" #include "varargs.h" #include diff --git a/common/JackClientControl.h b/common/JackClientControl.h index 29e4a5b7..281d6b62 100644 --- a/common/JackClientControl.h +++ b/common/JackClientControl.h @@ -25,7 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackPort.h" #include "JackSynchro.h" #include "JackNotification.h" -#include "session.h" +#include "JackSession.h" +//#include "session.h" namespace Jack { diff --git a/common/JackSession.h b/common/JackSession.h new file mode 100644 index 00000000..af78978a --- /dev/null +++ b/common/JackSession.h @@ -0,0 +1,69 @@ +/* + Copyright (C) 2001 Paul Davis + Copyright (C) 2004 Jack O'Quin + Copyright (C) 2010 Torben Hohn + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __jack_session_int_h__ +#define __jack_session_int_h__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum JackSessionEventType { + JackSessionSave = 1, + JackSessionSaveAndQuit = 2, + JackSessionSaveTemplate = 3 +}; + +typedef enum JackSessionEventType jack_session_event_type_t; + +enum JackSessionFlags { + JackSessionSaveError = 0x01, + JackSessionNeedTerminal = 0x02 +}; + +typedef enum JackSessionFlags jack_session_flags_t; + +struct _jack_session_event { + jack_session_event_type_t type; + const char *session_dir; + const char *client_uuid; + char *command_line; + jack_session_flags_t flags; + uint32_t future; +}; + +typedef struct _jack_session_event jack_session_event_t; + +typedef void (*JackSessionCallback)(jack_session_event_t *event, + void *arg); + +typedef struct { + const char *uuid; + const char *client_name; + const char *command; + jack_session_flags_t flags; +} jack_session_command_t; + +#ifdef __cplusplus +} +#endif +#endif From ccbf581d19e1784bcb0becd470bb9b0b140e41f1 Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Tue, 5 Apr 2011 11:05:42 -0700 Subject: [PATCH 149/472] Optimize timing of 'alsarawmiidi' driver. Set parameters on 'rawmidi' ports. Minor fixes to 'jack_midi_latency_test'. Add latency plot to 'jack_midi_latency_test'. --- example-clients/midi_latency_test.c | 41 ++++++++++++++--- linux/alsarawmidi/JackALSARawMidiDriver.cpp | 50 +++++++-------------- linux/alsarawmidi/JackALSARawMidiDriver.h | 2 +- linux/alsarawmidi/JackALSARawMidiPort.cpp | 6 +++ 4 files changed, 57 insertions(+), 42 deletions(-) diff --git a/example-clients/midi_latency_test.c b/example-clients/midi_latency_test.c index b38c07d4..a5bb3edc 100644 --- a/example-clients/midi_latency_test.c +++ b/example-clients/midi_latency_test.c @@ -44,10 +44,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * suite. * * To port this program to non-POSIX platforms, you'll have to include - * implementations for mutexes, semaphores, and command-line argument handling. + * implementations for semaphores and command-line argument handling. */ #include +#include #include #include #include @@ -72,10 +73,12 @@ typedef sem_t *semaphore_t; #endif const char *ERROR_RESERVE = "could not reserve MIDI event on port buffer"; +const char *ERROR_SHUTDOWN = "the JACK server has been shutdown"; const char *ERROR_TIMEOUT = "timed out while waiting for MIDI message"; const char *SOURCE_EVENT_RESERVE = "jack_midi_event_reserve"; const char *SOURCE_PROCESS = "handle_process"; +const char *SOURCE_SHUTDOWN = "handle_shutdown"; const char *SOURCE_SIGNAL_SEMAPHORE = "signal_semaphore"; const char *SOURCE_WAIT_SEMAPHORE = "wait_semaphore"; @@ -180,7 +183,7 @@ destroy_semaphore(semaphore_t semaphore, int id) } static void -die(char *source, char *error_message) +die(const char *source, const char *error_message) { output_error(source, error_message); output_usage(); @@ -305,7 +308,6 @@ handle_process(jack_nframes_t frames, void *arg) frame = frames - 1; } port_buffer = jack_port_get_buffer(out_port, frames); - jack_midi_clear_buffer(port_buffer); buffer = jack_midi_event_reserve(port_buffer, frame, message_size); if (buffer == NULL) { set_process_error(SOURCE_EVENT_RESERVE, ERROR_RESERVE); @@ -331,7 +333,7 @@ handle_process(jack_nframes_t frames, void *arg) static void handle_shutdown(void *arg) { - set_process_error("handle_shutdown", "The JACK server has been shutdown"); + set_process_error(SOURCE_SHUTDOWN, ERROR_SHUTDOWN); } static int @@ -446,6 +448,7 @@ int main(int argc, char **argv) { size_t jitter_plot[101]; + size_t latency_plot[101]; int long_index = 0; struct option long_options[] = { {"help", 0, NULL, 'h'}, @@ -639,15 +642,26 @@ main(int argc, char **argv) double average_latency = ((double) total_latency) / samples; double average_latency_time = total_latency_time / samples; size_t i; + double latency_plot_offset = + floor(((double) lowest_latency_time) / 100.0) / 10.0; double sample_rate = (double) jack_get_sample_rate(client); jack_nframes_t total_jitter = 0; jack_time_t total_jitter_time = 0; for (i = 0; i <= 100; i++) { jitter_plot[i] = 0; + latency_plot[i] = 0; } for (i = 0; i < samples; i++) { + double latency_time_value = (double) latency_time_values[i]; + double relational_latency_time = + latency_time_value - lowest_latency_time; double jitter_time = ABS(average_latency_time - - ((double) latency_time_values[i])); + latency_time_value); + if (relational_latency_time >= 10000.0) { + (latency_plot[100])++; + } else { + (latency_plot[(int) (relational_latency_time / 100.0)])++; + } if (jitter_time >= 10000.0) { (jitter_plot[100])++; } else { @@ -660,8 +674,8 @@ main(int argc, char **argv) printf("Reported out-port latency: %.2f-%.2f ms (%u-%u frames)\n" "Reported in-port latency: %.2f-%.2f ms (%u-%u frames)\n" "Average latency: %.2f ms (%.2f frames)\n" - "Best latency: %.2f ms (%u frames)\n" - "Worst latency: %.2f ms (%u frames)\n" + "Lowest latency: %.2f ms (%u frames)\n" + "Highest latency: %.2f ms (%u frames)\n" "Peak MIDI jitter: %.2f ms (%u frames)\n" "Average MIDI jitter: %.2f ms (%.2f frames)\n", (out_latency_range.min / sample_rate) * 1000.0, @@ -687,6 +701,19 @@ main(int argc, char **argv) if (jitter_plot[100]) { printf(" > 10 ms: %u\n", jitter_plot[100]); } + printf("\nLatency Plot:\n"); + for (i = 0; i < 100; i++) { + if (latency_plot[i]) { + printf("%.1f - %.1f ms: %u\n", + latency_plot_offset + (((float) i) / 10.0), + latency_plot_offset + (((float) (i + 1)) / 10.0), + latency_plot[i]); + } + } + if (latency_plot[100]) { + printf(" > %.1f ms: %u\n", latency_plot_offset + 10.0, + latency_plot[100]); + } } printf("\nMessages sent: %d\n" "Messages received: %d\n", diff --git a/linux/alsarawmidi/JackALSARawMidiDriver.cpp b/linux/alsarawmidi/JackALSARawMidiDriver.cpp index d2220707..00b35c50 100755 --- a/linux/alsarawmidi/JackALSARawMidiDriver.cpp +++ b/linux/alsarawmidi/JackALSARawMidiDriver.cpp @@ -133,18 +133,14 @@ JackALSARawMidiDriver::Execute() jack_nframes_t timeout_frame = 0; for (;;) { jack_nframes_t process_frame; - jack_time_t wait_time; - jack_time_t *wait_time_ptr; unsigned short revents; + jack_nframes_t *timeout_frame_ptr; if (! timeout_frame) { - wait_time_ptr = 0; + timeout_frame_ptr = 0; } else { - jack_time_t next_time = GetTimeFromFrames(timeout_frame); - jack_time_t now = GetMicroSeconds(); - wait_time = next_time <= now ? 0 : next_time - now; - wait_time_ptr = &wait_time; + timeout_frame_ptr = &timeout_frame; } - if (Poll(wait_time_ptr) == -1) { + if (Poll(timeout_frame_ptr) == -1) { if (errno == EINTR) { continue; } @@ -392,43 +388,29 @@ JackALSARawMidiDriver::Open(bool capturing, bool playing, int in_channels, return -1; } -#ifdef HAVE_PPOLL - int -JackALSARawMidiDriver::Poll(const jack_time_t *wait_time) +JackALSARawMidiDriver::Poll(const jack_nframes_t *wakeup_frame) { struct timespec timeout; struct timespec *timeout_ptr; - if (! wait_time) { + if (! wakeup_frame) { timeout_ptr = 0; } else { - timeout.tv_sec = (*wait_time) / 1000000; - timeout.tv_nsec = ((*wait_time) % 1000000) * 1000; timeout_ptr = &timeout; - } - return ppoll(poll_fds, poll_fd_count, timeout_ptr, 0); -} - -#else - -int -JackALSARawMidiDriver::Poll(const jack_time_t *wait_time) -{ - int result = poll(poll_fds, poll_fd_count, - ! wait_time ? -1 : (int) ((*wait_time) / 1000)); - if ((! result) && wait_time) { - jack_time_t time_left = (*wait_time) % 1000; - if (time_left) { - // Cheap hack. - usleep(time_left); - result = poll(poll_fds, poll_fd_count, 0); + jack_time_t next_time = GetTimeFromFrames(*wakeup_frame); + jack_time_t now = GetMicroSeconds(); + if (next_time <= now) { + timeout.tv_sec = 0; + timeout.tv_nsec = 0; + } else { + jack_time_t wait_time = next_time - now; + timeout.tv_sec = wait_time / 1000000; + timeout.tv_nsec = (wait_time % 1000000) * 1000; } } - return result; + return ppoll(poll_fds, poll_fd_count, timeout_ptr, 0); } -#endif - int JackALSARawMidiDriver::Read() { diff --git a/linux/alsarawmidi/JackALSARawMidiDriver.h b/linux/alsarawmidi/JackALSARawMidiDriver.h index 1b0afd7e..4dfa05bc 100755 --- a/linux/alsarawmidi/JackALSARawMidiDriver.h +++ b/linux/alsarawmidi/JackALSARawMidiDriver.h @@ -53,7 +53,7 @@ namespace Jack { int code); int - Poll(const jack_time_t *wait_time); + Poll(const jack_nframes_t *wakeup_frame); public: diff --git a/linux/alsarawmidi/JackALSARawMidiPort.cpp b/linux/alsarawmidi/JackALSARawMidiPort.cpp index 4e25cb1a..04fec375 100755 --- a/linux/alsarawmidi/JackALSARawMidiPort.cpp +++ b/linux/alsarawmidi/JackALSARawMidiPort.cpp @@ -82,6 +82,12 @@ JackALSARawMidiPort::JackALSARawMidiPort(snd_rawmidi_info_t *info, func = "snd_rawmidi_params_set_no_active_sensing"; goto free_params; } + code = snd_rawmidi_params(rawmidi, params); + if (code) { + error_message = snd_strerror(code); + func = "snd_rawmidi_params"; + goto free_params; + } snd_rawmidi_params_free(params); num_fds = snd_rawmidi_poll_descriptors_count(rawmidi); if (! num_fds) { From d1d25bea79aaad91d0eb67da0a26e1a8d70e3acb Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Tue, 5 Apr 2011 17:56:26 -0700 Subject: [PATCH 150/472] Fix latency plot error. --- example-clients/midi_latency_test.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/example-clients/midi_latency_test.c b/example-clients/midi_latency_test.c index a5bb3edc..df0af439 100644 --- a/example-clients/midi_latency_test.c +++ b/example-clients/midi_latency_test.c @@ -653,14 +653,14 @@ main(int argc, char **argv) } for (i = 0; i < samples; i++) { double latency_time_value = (double) latency_time_values[i]; - double relational_latency_time = - latency_time_value - lowest_latency_time; + double latency_plot_time = + (latency_time_value / 1000.0) - latency_plot_offset; double jitter_time = ABS(average_latency_time - latency_time_value); - if (relational_latency_time >= 10000.0) { + if (latency_plot_time >= 10.0) { (latency_plot[100])++; } else { - (latency_plot[(int) (relational_latency_time / 100.0)])++; + (latency_plot[(int) (latency_plot_time * 10.0)])++; } if (jitter_time >= 10000.0) { (jitter_plot[100])++; From 87067633323fb0d8c127258057619caabf2b9910 Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 6 Apr 2011 08:22:57 +0000 Subject: [PATCH 151/472] 64 bits compilation on Windows. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4276 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackChannel.h | 1 - common/JackClient.h | 1 - common/JackClientControl.h | 1 - common/JackControlAPI.cpp | 3 ++- common/JackControlAPI.h | 27 ++++++++++++++------------- common/JackLibGlobals.h | 6 ++++++ common/JackPort.h | 2 +- windows/JackNetWinSocket.h | 15 ++++++++------- 8 files changed, 31 insertions(+), 25 deletions(-) diff --git a/common/JackChannel.h b/common/JackChannel.h index a0bcfe63..69d25e00 100644 --- a/common/JackChannel.h +++ b/common/JackChannel.h @@ -22,7 +22,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "types.h" #include "JackSession.h" -//#include "session.h" namespace Jack { diff --git a/common/JackClient.h b/common/JackClient.h index 8a7a9249..7d8e0864 100644 --- a/common/JackClient.h +++ b/common/JackClient.h @@ -27,7 +27,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackSynchro.h" #include "JackPlatformPlug.h" #include "JackChannel.h" -//#include "session.h" #include "varargs.h" #include diff --git a/common/JackClientControl.h b/common/JackClientControl.h index 281d6b62..d035ccd0 100644 --- a/common/JackClientControl.h +++ b/common/JackClientControl.h @@ -26,7 +26,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackSynchro.h" #include "JackNotification.h" #include "JackSession.h" -//#include "session.h" namespace Jack { diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index c3ddec54..555a8599 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -215,7 +215,8 @@ bool jackctl_add_driver_parameters( struct jackctl_driver * driver_ptr) { - uint32_t i; + int i; + union jackctl_parameter_value jackctl_value; jackctl_param_type_t jackctl_type; struct jackctl_parameter * parameter_ptr; diff --git a/common/JackControlAPI.h b/common/JackControlAPI.h index 8e87d513..65b8528e 100644 --- a/common/JackControlAPI.h +++ b/common/JackControlAPI.h @@ -27,7 +27,8 @@ #ifdef WIN32 #ifdef __MINGW32__ -#include +#include +typedef _sigset_t sigset_t; #else typedef HANDLE sigset_t; #endif @@ -169,11 +170,11 @@ jackctl_parameter_set_value( EXPORT union jackctl_parameter_value jackctl_parameter_get_default_value( jackctl_parameter_t * parameter); - -EXPORT union jackctl_parameter_value + +EXPORT union jackctl_parameter_value jackctl_parameter_get_default_value( jackctl_parameter *parameter_ptr); - + EXPORT bool jackctl_parameter_has_range_constraint( jackctl_parameter_t * parameter_ptr); @@ -210,33 +211,33 @@ EXPORT bool jackctl_parameter_constraint_is_fake_value( jackctl_parameter_t * parameter_ptr); -EXPORT const JSList * +EXPORT const JSList * jackctl_server_get_internals_list( jackctl_server *server_ptr); - -EXPORT const char * + +EXPORT const char * jackctl_internal_get_name( jackctl_internal *internal_ptr); - -EXPORT const JSList * + +EXPORT const JSList * jackctl_internal_get_parameters( jackctl_internal *internal_ptr); - + EXPORT bool jackctl_server_load_internal( jackctl_server * server, jackctl_internal * internal); - + EXPORT bool jackctl_server_unload_internal( jackctl_server * server, jackctl_internal * internal); - + EXPORT bool jackctl_server_add_slave(jackctl_server_t * server, jackctl_driver_t * driver); EXPORT bool jackctl_server_remove_slave(jackctl_server_t * server, jackctl_driver_t * driver); -EXPORT bool +EXPORT bool jackctl_server_switch_master(jackctl_server_t * server, jackctl_driver_t * driver); diff --git a/common/JackLibGlobals.h b/common/JackLibGlobals.h index 8d312295..f95739d6 100644 --- a/common/JackLibGlobals.h +++ b/common/JackLibGlobals.h @@ -32,6 +32,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include +#ifdef __MINGW32__ +#include +typedef _sigset_t sigset_t; +#else +typedef HANDLE sigset_t; +#endif namespace Jack { diff --git a/common/JackPort.h b/common/JackPort.h index 8e8c1667..88edf1ba 100644 --- a/common/JackPort.h +++ b/common/JackPort.h @@ -107,7 +107,7 @@ class SERVER_EXPORT JackPort // Since we are in shared memory, the resulting pointer cannot be cached, so align it here... jack_default_audio_sample_t* GetBuffer() { - return (jack_default_audio_sample_t*)((long)fBuffer & ~15L) + 4; + return (jack_default_audio_sample_t*)((uintptr_t)fBuffer & ~15L) + 4; } int GetRefNum() const; diff --git a/windows/JackNetWinSocket.h b/windows/JackNetWinSocket.h index bd303eff..1041fab8 100644 --- a/windows/JackNetWinSocket.h +++ b/windows/JackNetWinSocket.h @@ -1,20 +1,20 @@ /* Copyright (C) 2004-2008 Grame - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 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 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - + */ #ifndef __JackNetWinSocket__ @@ -23,7 +23,8 @@ #include "JackNetSocket.h" #ifdef __MINGW32__ #include -#include +#include +#include #endif @@ -31,9 +32,9 @@ namespace Jack { #define E(code, s) { code, s } #define NET_ERROR_CODE WSAGetLastError() -#define StrError PrintError +#define StrError PrintError - typedef uint32_t uint; + typedef uint32_t uint; typedef int SOCKLEN; typedef struct _win_net_error win_net_error_t; From 44db4f1c6cf001fdb3214ac4d4e7d0e03dda82ef Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 6 Apr 2011 08:59:43 +0000 Subject: [PATCH 152/472] Compiles again on OSX. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4277 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackLibGlobals.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/JackLibGlobals.h b/common/JackLibGlobals.h index f95739d6..a2f87ed1 100644 --- a/common/JackLibGlobals.h +++ b/common/JackLibGlobals.h @@ -32,12 +32,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include +#ifdef WIN32 #ifdef __MINGW32__ #include typedef _sigset_t sigset_t; #else typedef HANDLE sigset_t; #endif +#endif namespace Jack { From 18644baf797715eb38facab64307289ac8bf66ce Mon Sep 17 00:00:00 2001 From: sletz Date: Wed, 6 Apr 2011 09:10:42 +0000 Subject: [PATCH 153/472] libjackserver.cbp for 64/32 bits compilation. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4278 0c269be4-1314-0410-8aa9-9f06e86f4224 --- windows/libjackserver.cbp | 81 +++++++++++++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 7 deletions(-) diff --git a/windows/libjackserver.cbp b/windows/libjackserver.cbp index 84b8985d..82628a70 100644 --- a/windows/libjackserver.cbp +++ b/windows/libjackserver.cbp @@ -4,16 +4,81 @@
- +
- +
- +
- + + + + + + + diff --git a/windows/jack_netsource.cbp b/windows/jack_netsource.cbp index ddfe02e8..b4b4542d 100644 --- a/windows/jack_netsource.cbp +++ b/windows/jack_netsource.cbp @@ -4,16 +4,69 @@ - + + + + + @@ -141,7 +174,7 @@ - + diff --git a/windows/multiple_metro.cbp b/windows/multiple_metro.cbp index dde3ac7d..5502ab87 100644 --- a/windows/multiple_metro.cbp +++ b/windows/multiple_metro.cbp @@ -4,16 +4,68 @@ @@ -44,6 +47,9 @@ + + + @@ -65,6 +71,9 @@ + + + @@ -87,6 +96,9 @@ + + + @@ -112,6 +124,9 @@ + + + @@ -138,6 +153,9 @@ + + + @@ -160,9 +178,6 @@ - - - diff --git a/windows/jack_connect.cbp b/windows/jack_connect.cbp index 68556aff..1af53ac1 100644 --- a/windows/jack_connect.cbp +++ b/windows/jack_connect.cbp @@ -21,6 +21,7 @@ + @@ -38,6 +39,7 @@ + @@ -56,6 +58,7 @@ + @@ -75,6 +78,7 @@ + @@ -94,6 +98,7 @@ + @@ -114,6 +119,7 @@ + @@ -133,7 +139,6 @@ -