Browse Source

Enable explicit channel mapping in CoreAudio driver.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4515 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/1.9.8
sletz 14 years ago
parent
commit
4e0a70b5d2
6 changed files with 242 additions and 114 deletions
  1. +4
    -0
      ChangeLog
  2. +15
    -32
      common/JackDriverLoader.cpp
  3. +17
    -19
      common/jack/net.h
  4. +1
    -1
      example-clients/netslave.c
  5. +197
    -60
      macosx/coreaudio/JackCoreAudioDriver.cpp
  6. +8
    -2
      macosx/coreaudio/JackCoreAudioDriver.h

+ 4
- 0
ChangeLog View File

@@ -35,6 +35,10 @@ Chris Caudle
Jackdmp changes log Jackdmp changes log
--------------------------- ---------------------------


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

* Enable explicit channel mapping in CoreAudio driver.

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


* NetJack2: no more timeout, correct JackWaitThreadedDriver::Execute. * NetJack2: no more timeout, correct JackWaitThreadedDriver::Execute.


+ 15
- 32
common/JackDriverLoader.cpp View File

@@ -173,10 +173,10 @@ jack_parse_driver_params(jack_driver_desc_t * desc, int argc, char* argv[], JSLi
if (optarg) { if (optarg) {
switch (desc->params[param_index].type) { switch (desc->params[param_index].type) {
case JackDriverParamInt: case JackDriverParamInt:
driver_param->value.i = atoi (optarg);
driver_param->value.i = atoi(optarg);
break; break;
case JackDriverParamUInt: case JackDriverParamUInt:
driver_param->value.ui = strtoul (optarg, NULL, 10);
driver_param->value.ui = strtoul(optarg, NULL, 10);
break; break;
case JackDriverParamChar: case JackDriverParamChar:
driver_param->value.c = optarg[0]; driver_param->value.c = optarg[0];
@@ -185,20 +185,11 @@ jack_parse_driver_params(jack_driver_desc_t * desc, int argc, char* argv[], JSLi
strncpy (driver_param->value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX); strncpy (driver_param->value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX);
break; break;
case JackDriverParamBool: case JackDriverParamBool:

/*
if (strcasecmp ("false", optarg) == 0 ||
strcasecmp ("off", optarg) == 0 ||
strcasecmp ("no", optarg) == 0 ||
strcasecmp ("0", optarg) == 0 ||
strcasecmp ("(null)", optarg) == 0 ) {
*/
// steph
if (strcmp ("false", optarg) == 0 ||
strcmp ("off", optarg) == 0 ||
strcmp ("no", optarg) == 0 ||
strcmp ("0", optarg) == 0 ||
strcmp ("(null)", optarg) == 0 ) {
if (strcasecmp("false", optarg) == 0 ||
strcasecmp("off", optarg) == 0 ||
strcasecmp("no", optarg) == 0 ||
strcasecmp("0", optarg) == 0 ||
strcasecmp("(null)", optarg) == 0 ) {
driver_param->value.i = false; driver_param->value.i = false;


} else { } else {
@@ -317,11 +308,11 @@ jackctl_parse_driver_params(jackctl_driver *driver_ptr, int argc, char* argv[])
if (optarg) { if (optarg) {
switch (jackctl_parameter_get_type(param)) { switch (jackctl_parameter_get_type(param)) {
case JackDriverParamInt: case JackDriverParamInt:
value.i = atoi (optarg);
value.i = atoi(optarg);
jackctl_parameter_set_value(param, &value); jackctl_parameter_set_value(param, &value);
break; break;
case JackDriverParamUInt: case JackDriverParamUInt:
value.ui = strtoul (optarg, NULL, 10);
value.ui = strtoul(optarg, NULL, 10);
jackctl_parameter_set_value(param, &value); jackctl_parameter_set_value(param, &value);
break; break;
case JackDriverParamChar: case JackDriverParamChar:
@@ -329,23 +320,15 @@ jackctl_parse_driver_params(jackctl_driver *driver_ptr, int argc, char* argv[])
jackctl_parameter_set_value(param, &value); jackctl_parameter_set_value(param, &value);
break; break;
case JackDriverParamString: case JackDriverParamString:
strncpy (value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX);
strncpy(value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX);
jackctl_parameter_set_value(param, &value); jackctl_parameter_set_value(param, &value);
break; break;
case JackDriverParamBool: case JackDriverParamBool:
/*
if (strcasecmp ("false", optarg) == 0 ||
strcasecmp ("off", optarg) == 0 ||
strcasecmp ("no", optarg) == 0 ||
strcasecmp ("0", optarg) == 0 ||
strcasecmp ("(null)", optarg) == 0 ) {
*/
// steph
if (strcmp ("false", optarg) == 0 ||
strcmp ("off", optarg) == 0 ||
strcmp ("no", optarg) == 0 ||
strcmp ("0", optarg) == 0 ||
strcmp ("(null)", optarg) == 0 ) {
if (strcasecmp("false", optarg) == 0 ||
strcasecmp("off", optarg) == 0 ||
strcasecmp("no", optarg) == 0 ||
strcasecmp("0", optarg) == 0 ||
strcasecmp("(null)", optarg) == 0 ) {
value.i = false; value.i = false;
} else { } else {
value.i = true; value.i = true;


+ 17
- 19
common/jack/net.h View File

@@ -28,18 +28,18 @@ extern "C"
#include <jack/systemdeps.h> #include <jack/systemdeps.h>
#include <jack/types.h> #include <jack/types.h>


#define DEFAULT_MULTICAST_IP "225.3.19.154"
#define DEFAULT_PORT 19000
#define DEFAULT_MTU 1500
#define MASTER_NAME_SIZE 256
#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 #define SOCKET_ERROR -1


enum JackNetEncoder { enum JackNetEncoder {


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/)
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 { typedef struct {
@@ -50,7 +50,7 @@ typedef struct {
int midi_output; // to master or from slave (-1 for get master MIDI physical inputs) int midi_output; // to master or from slave (-1 for get master MIDI physical inputs)
int mtu; // network Maximum Transmission Unit int mtu; // network Maximum Transmission Unit
int time_out; // in second, -1 means in infinite int time_out; // in second, -1 means in infinite
int encoder; // Encoder type (one of JackNetEncoder)
int encoder; // encoder type (one of JackNetEncoder)
int kbps; // KB per second for CELT encoder int kbps; // KB per second for CELT encoder
int latency; // network latency int latency; // network latency


@@ -104,7 +104,7 @@ int jack_net_slave_close(jack_net_slave_t* net);
* @param audio_output_buffer an array of audio output buffers (to master) * @param audio_output_buffer an array of audio output buffers (to master)
* @param midi_output number of MIDI outputs * @param midi_output number of MIDI outputs
* @param midi_output_buffer an array of MIDI output buffers (to master) * @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().
* @param arg pointer to a client supplied structure supplied by jack_set_net_process_callback()
* *
* @return zero on success, non-zero on error * @return zero on success, non-zero on error
*/ */
@@ -148,7 +148,7 @@ int jack_net_slave_deactivate(jack_net_slave_t* net);
/** /**
* Prototype for BufferSize callback. * Prototype for BufferSize callback.
* @param nframes buffer size * @param nframes buffer size
* @param arg pointer to a client supplied structure supplied by jack_set_net_buffer_size_callback().
* @param arg pointer to a client supplied structure supplied by jack_set_net_buffer_size_callback()
* *
* @return zero on success, non-zero on error * @return zero on success, non-zero on error
*/ */
@@ -157,7 +157,7 @@ typedef int (*JackNetSlaveBufferSizeCallback)(jack_nframes_t nframes, void *arg)
/** /**
* Prototype for SampleRate callback. * Prototype for SampleRate callback.
* @param nframes sample rate * @param nframes sample rate
* @param arg pointer to a client supplied structure supplied by jack_set_net_sample_rate_callback().
* @param arg pointer to a client supplied structure supplied by jack_set_net_sample_rate_callback()
* *
* @return zero on success, non-zero on error * @return zero on success, non-zero on error
*/ */
@@ -185,7 +185,7 @@ int jack_set_net_slave_sample_rate_callback(jack_net_slave_t *net, JackNetSlaveS


/** /**
* Prototype for server Shutdown callback (if not set, the client will just restart, waiting for an available master again). * 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().
* @param arg pointer to a client supplied structure supplied by jack_set_net_shutdown_callback()
*/ */
typedef void (*JackNetSlaveShutdownCallback)(void* data); typedef void (*JackNetSlaveShutdownCallback)(void* data);


@@ -200,8 +200,7 @@ typedef void (*JackNetSlaveShutdownCallback)(void* data);
int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, JackNetSlaveShutdownCallback shutdown_callback, void *arg); int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, JackNetSlaveShutdownCallback shutdown_callback, void *arg);


/** /**
* jack_net_master_t is an opaque type.
* You may only access it using the API provided.
* jack_net_master_t is an opaque type, you may only access it using the API provided.
*/ */
typedef struct _jack_net_master jack_net_master_t; typedef struct _jack_net_master jack_net_master_t;


@@ -237,7 +236,7 @@ int jack_net_master_close(jack_net_master_t* net);
int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer); 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
* Send sync and data to the network.
* @param net the network connection * @param net the network connection
* @param audio_output number of audio outputs * @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
@@ -251,8 +250,7 @@ int jack_net_master_send(jack_net_master_t* net, int audio_output, float** audio
// Experimental Adapter API // Experimental Adapter API


/** /**
* jack_adapter_t is an opaque type. You may only access it using the
* API provided.
* jack_adapter_t is an opaque type, you may only access it using the API provided.
*/ */
typedef struct _jack_adapter jack_adapter_t; typedef struct _jack_adapter jack_adapter_t;


@@ -290,7 +288,7 @@ int jack_destroy_adapter(jack_adapter_t* adapter);
void jack_flush_adapter(jack_adapter_t* adapter); void jack_flush_adapter(jack_adapter_t* adapter);


/** /**
* Push input to and pull output from adapter ringbuffer
* Push input to and pull output from adapter ringbuffer.
* @param adapter the adapter * @param adapter the adapter
* @param input an array of audio input buffers * @param input an array of audio input buffers
* @param output an array of audio ouput buffers * @param output an array of audio ouput buffers
@@ -301,7 +299,7 @@ void jack_flush_adapter(jack_adapter_t* adapter);
int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames);


/** /**
* Pull input to and push output from adapter ringbuffer
* Pull input to and push output from adapter ringbuffer.
* @param adapter the adapter * @param adapter the adapter
* @param input an array of audio input buffers * @param input an array of audio input buffers
* @param output an array of audio ouput buffers * @param output an array of audio ouput buffers


+ 1
- 1
example-clients/netslave.c View File

@@ -130,7 +130,7 @@ main (int argc, char *argv[])
return 1; return 1;
} }


printf("Slave is found and running...\n");
printf("Master is found and running...\n");


jack_set_net_slave_process_callback(net, net_process, NULL); jack_set_net_slave_process_callback(net, net_process, NULL);
jack_set_net_slave_shutdown_callback(net, net_shutdown, NULL); jack_set_net_slave_shutdown_callback(net, net_shutdown, NULL);


+ 197
- 60
macosx/coreaudio/JackCoreAudioDriver.cpp View File

@@ -29,6 +29,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "JackCompilerDeps.h" #include "JackCompilerDeps.h"
#include "JackLockedEngine.h" #include "JackLockedEngine.h"


#include <sstream>
#include <iostream> #include <iostream>
#include <CoreServices/CoreServices.h> #include <CoreServices/CoreServices.h>
#include <CoreFoundation/CFNumber.h> #include <CoreFoundation/CFNumber.h>
@@ -137,15 +138,17 @@ static OSStatus DisplayDeviceNames()
CFStringRef UIname; CFStringRef UIname;


err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, &isWritable); err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, &isWritable);
if (err != noErr)
if (err != noErr) {
return err; return err;
}


deviceNum = size / sizeof(AudioDeviceID); deviceNum = size / sizeof(AudioDeviceID);
AudioDeviceID devices[deviceNum]; AudioDeviceID devices[deviceNum];


err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, devices); err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, devices);
if (err != noErr)
if (err != noErr) {
return err; return err;
}


for (i = 0; i < deviceNum; i++) { for (i = 0; i < deviceNum; i++) {
char device_name[256]; char device_name[256];
@@ -162,8 +165,9 @@ static OSStatus DisplayDeviceNames()


size = 256; size = 256;
err = AudioDeviceGetProperty(devices[i], 0, false, kAudioDevicePropertyDeviceName, &size, device_name); err = AudioDeviceGetProperty(devices[i], 0, false, kAudioDevicePropertyDeviceName, &size, device_name);
if (err != noErr)
if (err != noErr) {
return err; return err;
}


jack_info("Device name = \'%s\', internal name = \'%s\' (to be used as -C, -P, or -d parameter)", device_name, internal_name); jack_info("Device name = \'%s\', internal name = \'%s\' (to be used as -C, -P, or -d parameter)", device_name, internal_name);
} }
@@ -171,8 +175,9 @@ static OSStatus DisplayDeviceNames()
return noErr; return noErr;


error: error:
if (UIname != NULL)
if (UIname != NULL) {
CFRelease(UIname); CFRelease(UIname);
}
return err; return err;
} }


@@ -184,6 +189,20 @@ static CFStringRef GetDeviceName(AudioDeviceID id)
return (err == noErr) ? UIname : NULL; return (err == noErr) ? UIname : NULL;
} }


void JackCoreAudioDriver::ParseChannelList(const string& list, vector<int>& result)
{
stringstream ss(list);
string token;
int chan;

while (ss >> token) {
istringstream ins;
ins.str(token);
ins >> chan;
result.push_back(chan);
}
}

OSStatus JackCoreAudioDriver::Render(void *inRefCon, OSStatus JackCoreAudioDriver::Render(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags, AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp, const AudioTimeStamp *inTimeStamp,
@@ -241,8 +260,9 @@ int JackCoreAudioDriver::Write()
int size = sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize; int size = sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize;
memcpy((jack_default_audio_sample_t*)fDriverOutputData->mBuffers[i].mData, buffer, size); memcpy((jack_default_audio_sample_t*)fDriverOutputData->mBuffers[i].mData, buffer, size);
// Monitor ports // Monitor ports
if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[i]) > 0)
if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[i]) > 0) {
memcpy(GetMonitorBuffer(i), buffer, size); memcpy(GetMonitorBuffer(i), buffer, size);
}
} else { } else {
memset((jack_default_audio_sample_t*)fDriverOutputData->mBuffers[i].mData, 0, sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); memset((jack_default_audio_sample_t*)fDriverOutputData->mBuffers[i].mData, 0, sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize);
} }
@@ -349,8 +369,9 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice,
Float64 sample_rate = 0; Float64 sample_rate = 0;
UInt32 outsize = sizeof(Float64); UInt32 outsize = sizeof(Float64);
OSStatus err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sample_rate); OSStatus err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sample_rate);
if (err != noErr)
if (err != noErr) {
return kAudioHardwareUnsupportedOperationError; return kAudioHardwareUnsupportedOperationError;
}


char device_name[256]; char device_name[256];
const char* digidesign_name = "Digidesign"; const char* digidesign_name = "Digidesign";
@@ -420,11 +441,13 @@ OSStatus JackCoreAudioDriver::GetDefaultDevice(AudioDeviceID* id)
AudioDeviceID inDefault; AudioDeviceID inDefault;
AudioDeviceID outDefault; AudioDeviceID outDefault;


if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr)
if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) {
return res; return res;
}


if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr)
if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) {
return res; return res;
}


jack_log("GetDefaultDevice: input = %ld output = %ld", inDefault, outDefault); jack_log("GetDefaultDevice: input = %ld output = %ld", inDefault, outDefault);


@@ -447,8 +470,9 @@ OSStatus JackCoreAudioDriver::GetDefaultInputDevice(AudioDeviceID* id)
UInt32 theSize = sizeof(UInt32); UInt32 theSize = sizeof(UInt32);
AudioDeviceID inDefault; AudioDeviceID inDefault;


if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr)
if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) {
return res; return res;
}


if (inDefault == 0) { if (inDefault == 0) {
jack_error("Error : input device is 0, please select a correct one !!"); jack_error("Error : input device is 0, please select a correct one !!");
@@ -465,8 +489,9 @@ OSStatus JackCoreAudioDriver::GetDefaultOutputDevice(AudioDeviceID* id)
UInt32 theSize = sizeof(UInt32); UInt32 theSize = sizeof(UInt32);
AudioDeviceID outDefault; AudioDeviceID outDefault;


if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr)
if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) {
return res; return res;
}


if (outDefault == 0) { if (outDefault == 0) {
jack_error("Error : output device is 0, please select a correct one !!"); jack_error("Error : output device is 0, please select a correct one !!");
@@ -495,8 +520,9 @@ OSStatus JackCoreAudioDriver::GetTotalChannels(AudioDeviceID device, int& channe
AudioBufferList bufferList[outSize]; AudioBufferList bufferList[outSize];
err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, bufferList); err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, bufferList);
if (err == noErr) { if (err == noErr) {
for (unsigned int i = 0; i < bufferList->mNumberBuffers; i++)
for (unsigned int i = 0; i < bufferList->mNumberBuffers; i++) {
channelCount += bufferList->mBuffers[i].mNumberChannels; channelCount += bufferList->mBuffers[i].mNumberChannels;
}
} }
} }
return err; return err;
@@ -526,7 +552,7 @@ OSStatus JackCoreAudioDriver::DestroyAggregateDevice()
pluginAOPA.mElement = kAudioObjectPropertyElementMaster; pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
UInt32 outDataSize; UInt32 outDataSize;


if (fPluginID > 0) {
if (fPluginID > 0) {


osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize);
if (osErr != noErr) { if (osErr != noErr) {
@@ -771,8 +797,9 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
vector<CFStringRef> captureDeviceUID; vector<CFStringRef> captureDeviceUID;
for (UInt32 i = 0; i < captureDeviceID.size(); i++) { for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
CFStringRef ref = GetDeviceName(captureDeviceID[i]); CFStringRef ref = GetDeviceName(captureDeviceID[i]);
if (ref == NULL)
if (ref == NULL) {
return -1; return -1;
}
captureDeviceUID.push_back(ref); captureDeviceUID.push_back(ref);
// input sub-devices in this example, so append the sub-device's UID to the CFArray // input sub-devices in this example, so append the sub-device's UID to the CFArray
CFArrayAppendValue(subDevicesArray, ref); CFArrayAppendValue(subDevicesArray, ref);
@@ -781,8 +808,9 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
vector<CFStringRef> playbackDeviceUID; vector<CFStringRef> playbackDeviceUID;
for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
CFStringRef ref = GetDeviceName(playbackDeviceID[i]); CFStringRef ref = GetDeviceName(playbackDeviceID[i]);
if (ref == NULL)
if (ref == NULL) {
return -1; return -1;
}
playbackDeviceUID.push_back(ref); playbackDeviceUID.push_back(ref);
// output sub-devices in this example, so append the sub-device's UID to the CFArray // output sub-devices in this example, so append the sub-device's UID to the CFArray
CFArrayAppendValue(subDevicesArray, ref); CFArrayAppendValue(subDevicesArray, ref);
@@ -908,8 +936,9 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
CFRelease(aggDeviceDict); CFRelease(aggDeviceDict);
CFRelease(subDevicesArray); CFRelease(subDevicesArray);


if (subDevicesArrayClock)
if (subDevicesArrayClock) {
CFRelease(subDevicesArrayClock); CFRelease(subDevicesArrayClock);
}


// release the device UID // release the device UID
for (UInt32 i = 0; i < captureDeviceUID.size(); i++) { for (UInt32 i = 0; i < captureDeviceUID.size(); i++) {
@@ -977,8 +1006,9 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid,
} }
} }


if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr)
if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) {
return -1; return -1;
}
} }


// Capture only // Capture only
@@ -1036,8 +1066,9 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid,
} }
} }


if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr)
if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) {
return -1; return -1;
}
} }
} }


@@ -1081,14 +1112,16 @@ int JackCoreAudioDriver::SetupChannels(bool capturing, bool playing, int& inchan


if (inchannels > in_nChannels) { if (inchannels > in_nChannels) {
jack_error("This device hasn't required input channels inchannels = %d in_nChannels = %d", inchannels, in_nChannels); jack_error("This device hasn't required input channels inchannels = %d in_nChannels = %d", inchannels, in_nChannels);
if (strict)
if (strict) {
return -1; return -1;
}
} }


if (outchannels > out_nChannels) { if (outchannels > out_nChannels) {
jack_error("This device hasn't required output channels outchannels = %d out_nChannels = %d", outchannels, out_nChannels); jack_error("This device hasn't required output channels outchannels = %d out_nChannels = %d", outchannels, out_nChannels);
if (strict)
if (strict) {
return -1; return -1;
}
} }


if (inchannels == -1) { if (inchannels == -1) {
@@ -1261,6 +1294,8 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
int outchannels, int outchannels,
int in_nChannels, int in_nChannels,
int out_nChannels, int out_nChannels,
const vector<int>& chan_in_list,
const vector<int>& chan_out_list,
jack_nframes_t buffer_size, jack_nframes_t buffer_size,
jack_nframes_t sample_rate) jack_nframes_t sample_rate)
{ {
@@ -1270,7 +1305,8 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
AudioDeviceID currAudioDeviceID; AudioDeviceID currAudioDeviceID;
UInt32 size; UInt32 size;


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);
jack_log("OpenAUHAL capturing = %d playing = %d inchannels = %d outchannels = %d in_nChannels = %d out_nChannels = %d chan_in_list = %d chan_out_list = %d",
capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, chan_in_list.size(), chan_out_list.size());


if (inchannels == 0 && outchannels == 0) { if (inchannels == 0 && outchannels == 0) {
jack_error("No input and output channels..."); jack_error("No input and output channels...");
@@ -1363,34 +1399,61 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
} }
} }


// Setup channel map
if (capturing && inchannels > 0 && inchannels < in_nChannels) {
SInt32 chanArr[in_nChannels];
// Setup input channel map
if (capturing && inchannels > 0 && inchannels <= in_nChannels) {
UInt32 chanArr[in_nChannels];
for (int i = 0; i < in_nChannels; i++) { for (int i = 0; i < in_nChannels; i++) {
chanArr[i] = -1; chanArr[i] = -1;
} }
for (int i = 0; i < inchannels; i++) {
chanArr[i] = i;
// Explicit mapping
if (chan_in_list.size() > 0) {
for (uint i = 0; i < chan_in_list.size(); i++) {
int chan = chan_in_list[i];
if (chan < out_nChannels) {
chanArr[i] = chan;
} else {
jack_info("Error input channel number is incorrect : %d", chan);
goto error;
}
}
} else {
for (int i = 0; i < inchannels; i++) {
chanArr[i] = i;
}
} }
AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap , kAudioUnitScope_Input, 1, chanArr, sizeof(SInt32) * in_nChannels);
AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap , kAudioUnitScope_Input, 1, chanArr, sizeof(UInt32) * in_nChannels);
if (err1 != noErr) { if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 1");
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap for input");
printError(err1); printError(err1);
goto error; goto error;
} }
} }


if (playing && outchannels > 0 && outchannels < out_nChannels) {
SInt32 chanArr[out_nChannels];
// Setup output channel map
if (playing && outchannels > 0 && outchannels <= out_nChannels) {
UInt32 chanArr[out_nChannels];
for (int i = 0; i < out_nChannels; i++) { for (int i = 0; i < out_nChannels; i++) {
chanArr[i] = -1; chanArr[i] = -1;
} }
for (int i = 0; i < outchannels; i++) {
chanArr[i] = i;
// Explicit mapping
if (chan_out_list.size() > 0) {
for (uint i = 0; i < chan_out_list.size(); i++) {
int chan = chan_out_list[i];
if (chan < out_nChannels) {
chanArr[i] = chan;
} else {
jack_info("Error output channel number is incorrect : %d", chan);
goto error;
}
}
} else {
for (int i = 0; i < outchannels; i++) {
chanArr[i] = i;
}
} }
err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, chanArr, sizeof(SInt32) * out_nChannels);
err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, chanArr, sizeof(UInt32) * out_nChannels);
if (err1 != noErr) { if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 0");
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap for output");
printError(err1); printError(err1);
goto error; goto error;
} }
@@ -1588,6 +1651,8 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,
bool playing, bool playing,
int inchannels, int inchannels,
int outchannels, int outchannels,
const char* chan_in_list,
const char* chan_out_list,
bool monitor, bool monitor,
const char* capture_driver_uid, const char* capture_driver_uid,
const char* playback_driver_uid, const char* playback_driver_uid,
@@ -1618,6 +1683,21 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,
Gestalt(gestaltSystemVersionMajor, &major); Gestalt(gestaltSystemVersionMajor, &major);
Gestalt(gestaltSystemVersionMinor, &minor); Gestalt(gestaltSystemVersionMinor, &minor);


vector<int> parsed_chan_in_list;
vector<int> parsed_chan_out_list;

ParseChannelList(chan_in_list, parsed_chan_in_list);
if (parsed_chan_in_list.size() > 0) {
jack_info("Explicit input channel list size = %d", parsed_chan_in_list.size());
inchannels = parsed_chan_in_list.size();
}

ParseChannelList(chan_out_list, parsed_chan_out_list);
if (parsed_chan_out_list.size() > 0) {
jack_info("Explicit output channel list size = %d", parsed_chan_out_list.size());
outchannels = parsed_chan_out_list.size();
}

// Starting with 10.6 systems, the HAL notification thread is created internally // Starting with 10.6 systems, the HAL notification thread is created internally
if (major == 10 && minor >= 6) { if (major == 10 && minor >= 6) {
CFRunLoopRef theRunLoop = NULL; CFRunLoopRef theRunLoop = NULL;
@@ -1629,31 +1709,47 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,
} }
} }


if (SetupDevices(capture_driver_uid, playback_driver_uid, capture_driver_name, playback_driver_name, sample_rate) < 0)
if (SetupDevices(capture_driver_uid, playback_driver_uid, capture_driver_name, playback_driver_name, sample_rate) < 0) {
goto error; goto error;
}


// Generic JackAudioDriver Open // Generic JackAudioDriver Open
if (JackAudioDriver::Open(buffer_size, sample_rate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0)
if (JackAudioDriver::Open(buffer_size, sample_rate,
capturing, playing,
inchannels, outchannels,
monitor,
capture_driver_name,
playback_driver_name,
capture_latency,
playback_latency) != 0) {
goto error; goto error;
}


if (SetupChannels(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, true) < 0)
if (SetupChannels(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, true) < 0) {
goto error; goto error;
}


if (SetupBufferSize(buffer_size) < 0)
if (SetupBufferSize(buffer_size) < 0) {
goto error; goto error;
}


if (SetupSampleRate(sample_rate) < 0)
if (SetupSampleRate(sample_rate) < 0) {
goto error; goto error;
}


if (OpenAUHAL(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, buffer_size, sample_rate) < 0)
if (OpenAUHAL(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, parsed_chan_in_list, parsed_chan_out_list, buffer_size, sample_rate) < 0) {
goto error; goto error;
}


if (capturing && inchannels > 0)
if (SetupBuffers(inchannels) < 0)
if (capturing && inchannels > 0) {
if (SetupBuffers(inchannels) < 0) {
goto error; goto error;
}
}


if (AddListeners() < 0)
if (AddListeners() < 0) {
goto error; goto error;
}


// Core driver may have changed the in/out values // Core driver may have changed the in/out values
fCaptureChannels = inchannels; fCaptureChannels = inchannels;
@@ -1692,11 +1788,13 @@ void JackCoreAudioDriver::UpdateLatencies()
UInt32 value1 = 0; UInt32 value1 = 0;
UInt32 value2 = 0; UInt32 value2 = 0;
err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertyLatency, &size, &value1); err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertyLatency, &size, &value1);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error"); jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error");
}
err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertySafetyOffset, &size, &value2); err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertySafetyOffset, &size, &value2);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error"); jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error");
}


range.min = range.max = fEngineControl->fBufferSize + value1 + value2 + fCaptureLatency; range.min = range.max = fEngineControl->fBufferSize + value1 + value2 + fCaptureLatency;
fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &range); fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &range);
@@ -1707,11 +1805,13 @@ void JackCoreAudioDriver::UpdateLatencies()
UInt32 value1 = 0; UInt32 value1 = 0;
UInt32 value2 = 0; UInt32 value2 = 0;
err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertyLatency, &size, &value1); err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertyLatency, &size, &value1);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error"); jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error");
}
err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertySafetyOffset, &size, &value2); err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertySafetyOffset, &size, &value2);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error"); jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error");
}


// Add more latency if "async" mode is used... // Add more latency if "async" mode is used...
range.min = range.max range.min = range.max
@@ -1742,12 +1842,14 @@ int JackCoreAudioDriver::Attach()
for (int i = 0; i < fCaptureChannels; i++) { for (int i = 0; i < fCaptureChannels; i++) {


err = AudioDeviceGetPropertyInfo(fDeviceID, i + 1, true, kAudioDevicePropertyChannelName, &size, &isWritable); err = AudioDeviceGetPropertyInfo(fDeviceID, i + 1, true, kAudioDevicePropertyChannelName, &size, &isWritable);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetPropertyInfo kAudioDevicePropertyChannelName error"); jack_log("AudioDeviceGetPropertyInfo kAudioDevicePropertyChannelName error");
}
if (err == noErr && size > 0) { if (err == noErr && size > 0) {
err = AudioDeviceGetProperty(fDeviceID, i + 1, true, kAudioDevicePropertyChannelName, &size, channel_name); err = AudioDeviceGetProperty(fDeviceID, i + 1, true, kAudioDevicePropertyChannelName, &size, channel_name);
if (err != noErr)
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); snprintf(alias, sizeof(alias) - 1, "%s:%s:out_%s%u", fAliasName, fCaptureDriverName, channel_name, i + 1);
} else { } else {
snprintf(alias, sizeof(alias) - 1, "%s:%s:out%u", fAliasName, fCaptureDriverName, i + 1); snprintf(alias, sizeof(alias) - 1, "%s:%s:out%u", fAliasName, fCaptureDriverName, i + 1);
@@ -1768,12 +1870,14 @@ int JackCoreAudioDriver::Attach()
for (int i = 0; i < fPlaybackChannels; i++) { for (int i = 0; i < fPlaybackChannels; i++) {


err = AudioDeviceGetPropertyInfo(fDeviceID, i + 1, false, kAudioDevicePropertyChannelName, &size, &isWritable); err = AudioDeviceGetPropertyInfo(fDeviceID, i + 1, false, kAudioDevicePropertyChannelName, &size, &isWritable);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetPropertyInfo kAudioDevicePropertyChannelName error"); jack_log("AudioDeviceGetPropertyInfo kAudioDevicePropertyChannelName error");
}
if (err == noErr && size > 0) { if (err == noErr && size > 0) {
err = AudioDeviceGetProperty(fDeviceID, i + 1, false, kAudioDevicePropertyChannelName, &size, channel_name); err = AudioDeviceGetProperty(fDeviceID, i + 1, false, kAudioDevicePropertyChannelName, &size, channel_name);
if (err != noErr)
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); snprintf(alias, sizeof(alias) - 1, "%s:%s:in_%s%u", fAliasName, fPlaybackDriverName, channel_name, i + 1);
} else { } else {
snprintf(alias, sizeof(alias) - 1, "%s:%s:in%u", fAliasName, fPlaybackDriverName, i + 1); snprintf(alias, sizeof(alias) - 1, "%s:%s:in%u", fAliasName, fPlaybackDriverName, i + 1);
@@ -1854,8 +1958,9 @@ int JackCoreAudioDriver::Stop()


int JackCoreAudioDriver::SetBufferSize(jack_nframes_t buffer_size) int JackCoreAudioDriver::SetBufferSize(jack_nframes_t buffer_size)
{ {
if (SetupBufferSize(buffer_size) < 0)
if (SetupBufferSize(buffer_size) < 0) {
return -1; return -1;
}


JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails


@@ -1950,8 +2055,12 @@ extern "C"


value.i = -1; value.i = -1;
jack_driver_descriptor_add_parameter(desc, &filler, "channels", 'c', JackDriverParamInt, &value, NULL, "Maximum number of channels", "Maximum number of channels. If -1, max possible number of channels will be used"); jack_driver_descriptor_add_parameter(desc, &filler, "channels", 'c', JackDriverParamInt, &value, NULL, "Maximum number of channels", "Maximum number of channels. If -1, max possible number of channels will be used");
jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamInt, &value, NULL, "Maximum number of input channels", "Maximum number of input channels. If -1, max possible number of input channels will be used");
jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamInt, &value, NULL, "Maximum number of output channels", "Maximum number of output channels. If -1, max possible number of output channels will be used");
jack_driver_descriptor_add_parameter(desc, &filler, "in-channels", 'i', JackDriverParamInt, &value, NULL, "Maximum number of input channels", "Maximum number of input channels. If -1, max possible number of input channels will be used");
jack_driver_descriptor_add_parameter(desc, &filler, "out-channels", 'o', JackDriverParamInt, &value, NULL, "Maximum number of output channels", "Maximum number of output channels. If -1, max possible number of output channels will be used");

value.str[0] = 0;
jack_driver_descriptor_add_parameter(desc, &filler, "input-list", 'n', JackDriverParamString, &value, NULL, "Input channel list", "List of input channel number to be opened");
jack_driver_descriptor_add_parameter(desc, &filler, "output-list", 'N', JackDriverParamString, &value, NULL, "Output channel list", "List of output channel number to be opened");


value.str[0] = 0; value.str[0] = 0;
jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Input CoreAudio device name", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Input CoreAudio device name", NULL);
@@ -1966,7 +2075,7 @@ extern "C"
value.ui = 44100U; value.ui = 44100U;
jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL);


value.ui = 128U;
value.ui = 256U;
jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL);


value.str[0] = 0; value.str[0] = 0;
@@ -1997,11 +2106,13 @@ extern "C"
SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params)
{ {
jack_nframes_t srate = 44100; jack_nframes_t srate = 44100;
jack_nframes_t frames_per_interrupt = 128;
jack_nframes_t frames_per_interrupt = 256;
bool capture = false; bool capture = false;
bool playback = false; bool playback = false;
int chan_in = -1; // Default: if not explicitely set, then max possible will be used... 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...
const char* chan_in_list = "";
const char* chan_out_list = "";
bool monitor = false; bool monitor = false;
const char* capture_driver_uid = ""; const char* capture_driver_uid = "";
const char* playback_driver_uid = ""; const char* playback_driver_uid = "";
@@ -2030,15 +2141,23 @@ extern "C"
break; break;


case 'c': case 'c':
chan_in = chan_out = (int)param->value.ui;
chan_in = chan_out = param->value.i;
break; break;


case 'i': case 'i':
chan_in = (int)param->value.ui;
chan_in = param->value.i;
break; break;


case 'o': case 'o':
chan_out = (int)param->value.ui;
chan_out = param->value.i;
break;

case 'n':
chan_in_list = param->value.str;
break;

case 'N':
chan_out_list = param->value.str;
break; break;


case 'C': case 'C':
@@ -2103,9 +2222,27 @@ extern "C"
playback = true; playback = true;
} }


if (strcmp(chan_in_list, "") != 0 && chan_in >= 0) {
printf("Input channel list and in channels are both specified, input channel list will take over...\n");
}

if (strcmp(chan_out_list, "") != 0 && chan_out >= 0) {
printf("Output channel list and out channels are both specified, output channel list will take over...\n");
}

Jack::JackCoreAudioDriver* driver = new Jack::JackCoreAudioDriver("system", "coreaudio", engine, table); Jack::JackCoreAudioDriver* driver = new Jack::JackCoreAudioDriver("system", "coreaudio", engine, table);
if (driver->Open(frames_per_interrupt, srate, capture, playback, chan_in, chan_out, monitor, capture_driver_uid,
playback_driver_uid, systemic_input_latency, systemic_output_latency, async_output_latency, computation_grain, hogged, clock_drift) == 0) {
if (driver->Open(frames_per_interrupt,
srate, capture,
playback, chan_in,
chan_out, chan_in_list,
chan_out_list, monitor,
capture_driver_uid,
playback_driver_uid,
systemic_input_latency,
systemic_output_latency,
async_output_latency,
computation_grain,
hogged, clock_drift) == 0) {
return driver; return driver;
} else { } else {
delete driver; delete driver;


+ 8
- 2
macosx/coreaudio/JackCoreAudioDriver.h View File

@@ -141,6 +141,8 @@ class JackCoreAudioDriver : public JackAudioDriver
int outchannels, int outchannels,
int in_nChannels, int in_nChannels,
int out_nChannels, int out_nChannels,
const vector<int>& chan_in_list,
const vector<int>& chan_out_list,
jack_nframes_t nframes, jack_nframes_t nframes,
jack_nframes_t samplerate); jack_nframes_t samplerate);
void CloseAUHAL(); void CloseAUHAL();
@@ -153,6 +155,8 @@ class JackCoreAudioDriver : public JackAudioDriver


void UpdateLatencies(); void UpdateLatencies();


void ParseChannelList(const string& list, vector<int>& result);

public: public:


JackCoreAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); JackCoreAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table);
@@ -162,8 +166,10 @@ class JackCoreAudioDriver : public JackAudioDriver
jack_nframes_t samplerate, jack_nframes_t samplerate,
bool capturing, bool capturing,
bool playing, bool playing,
int chan_in,
int chan_out,
int inchannels,
int outchannels,
const char* chan_in_list,
const char* chan_out_list,
bool monitor, bool monitor,
const char* capture_driver_name, const char* capture_driver_name,
const char* playback_driver_name, const char* playback_driver_name,


Loading…
Cancel
Save