|
|
|
@@ -50,7 +50,7 @@ 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 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); |
|
|
|
@@ -124,7 +124,7 @@ static void printError(OSStatus err) |
|
|
|
jack_log("error code : kAudioHardwareUnsupportedOperationError"); |
|
|
|
break; |
|
|
|
default: |
|
|
|
Print4CharCode("error code : unknown", err); |
|
|
|
Print4CharCode("error code : unknown ", err); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
@@ -648,12 +648,13 @@ OSStatus JackCoreAudioDriver::GetTotalChannels(AudioDeviceID device, int& channe |
|
|
|
err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, &outWritable); |
|
|
|
if (err == noErr) { |
|
|
|
int stream_count = outSize / sizeof(AudioBufferList); |
|
|
|
jack_log(" JackCoreAudioDriver::GetTotalChannels stream_count = %d", stream_count); |
|
|
|
AudioBufferList bufferList[stream_count]; |
|
|
|
err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, bufferList); |
|
|
|
if (err == noErr) { |
|
|
|
for (uint i = 0; i < bufferList->mNumberBuffers; i++) { |
|
|
|
channelCount += bufferList->mBuffers[i].mNumberChannels; |
|
|
|
//jack_info("GetTotalChannels stream = %d channels = %d", i, bufferList->mBuffers[i].mNumberChannels); |
|
|
|
jack_log(" JackCoreAudioDriver::GetTotalChannels stream = %d channels = %d", i, bufferList->mBuffers[i].mNumberChannels); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@@ -731,12 +732,12 @@ bool JackCoreAudioDriver::IsDigitalDevice(AudioDeviceID device) |
|
|
|
} |
|
|
|
|
|
|
|
AudioObjectPropertyAddress physicalFormatsAddress = { kAudioStreamPropertyAvailablePhysicalFormats, kAudioObjectPropertyScopeGlobal, 0 }; |
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < stream_count ; i++) { |
|
|
|
|
|
|
|
|
|
|
|
/* Find a stream with a cac3 stream */ |
|
|
|
int format_num = 0; |
|
|
|
|
|
|
|
|
|
|
|
/* Retrieve all the stream formats supported by each output stream */ |
|
|
|
err = AudioObjectGetPropertyDataSize(streamIDs[i], &physicalFormatsAddress, 0, NULL, &outSize1); |
|
|
|
|
|
|
|
@@ -754,13 +755,16 @@ bool JackCoreAudioDriver::IsDigitalDevice(AudioDeviceID device) |
|
|
|
jack_error("IsDigitalDevice could not get the list of streamformats err = %d", err); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Check if one of the supported formats is a digital format */ |
|
|
|
for (int j = 0; j < format_num; j++) { |
|
|
|
|
|
|
|
PrintStreamDesc(&format_list[j].mFormat); |
|
|
|
|
|
|
|
if (format_list[j].mFormat.mFormatID == 'IAC3' || |
|
|
|
format_list[j].mFormat.mFormatID == 'iac3' || |
|
|
|
format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 || |
|
|
|
format_list[j].mFormat.mFormatID == kAudioFormatAC3 ) |
|
|
|
format_list[j].mFormat.mFormatID == kAudioFormatAC3) |
|
|
|
{ |
|
|
|
is_digital = true; |
|
|
|
break; |
|
|
|
@@ -781,7 +785,8 @@ JackCoreAudioDriver::JackCoreAudioDriver(const char* name, const char* alias, Ja |
|
|
|
fHogged(false), |
|
|
|
fIOUsage(1.f), |
|
|
|
fComputationGrain(-1.f), |
|
|
|
fClockDriftCompensate(false) |
|
|
|
fClockDriftCompensate(false), |
|
|
|
fDigitalPlayback(false) |
|
|
|
{} |
|
|
|
|
|
|
|
JackCoreAudioDriver::~JackCoreAudioDriver() |
|
|
|
@@ -1207,7 +1212,8 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, |
|
|
|
const char* playback_driver_uid, |
|
|
|
char* capture_driver_name, |
|
|
|
char* playback_driver_name, |
|
|
|
jack_nframes_t samplerate) |
|
|
|
jack_nframes_t samplerate, |
|
|
|
bool ac3_encoding) |
|
|
|
{ |
|
|
|
capture_driver_name[0] = 0; |
|
|
|
playback_driver_name[0] = 0; |
|
|
|
@@ -1230,12 +1236,22 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, |
|
|
|
jack_error("Cannot get device name from device ID"); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
if (fHogged) { |
|
|
|
if (!TakeHogAux(fDeviceID, false)) { |
|
|
|
jack_error("Cannot take hog mode"); |
|
|
|
} |
|
|
|
if (ac3_encoding) { |
|
|
|
fDigitalPlayback = IsDigitalDevice(fDeviceID); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
// Creates aggregate device |
|
|
|
AudioDeviceID captureID, playbackID; |
|
|
|
|
|
|
|
AudioDeviceID captureID = -1; |
|
|
|
AudioDeviceID playbackID = -1; |
|
|
|
|
|
|
|
if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { |
|
|
|
jack_log("JackCoreAudioDriver::SetupDevices : will take default input"); |
|
|
|
if (GetDefaultInputDevice(&captureID) != noErr) { |
|
|
|
@@ -1258,7 +1274,20 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, |
|
|
|
|
|
|
|
GetDeviceNameFromID(captureID, fCaptureUID); |
|
|
|
GetDeviceNameFromID(playbackID, fPlaybackUID); |
|
|
|
} |
|
|
|
|
|
|
|
if (fHogged) { |
|
|
|
if (!TakeHogAux(captureID, true)) { |
|
|
|
jack_error("Cannot take hog mode for capture device"); |
|
|
|
} |
|
|
|
if (!TakeHogAux(playbackID, false)) { |
|
|
|
jack_error("Cannot take hog mode for playback device"); |
|
|
|
} |
|
|
|
if (ac3_encoding) { |
|
|
|
fDigitalPlayback = IsDigitalDevice(playbackID); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// Capture only |
|
|
|
} else if (strcmp(capture_driver_uid, "") != 0) { |
|
|
|
@@ -1274,6 +1303,12 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, |
|
|
|
jack_error("Cannot get device name from device ID"); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
if (fHogged) { |
|
|
|
if (!TakeHogAux(fDeviceID, true)) { |
|
|
|
jack_error("Cannot take hog mode for capture device"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Playback only |
|
|
|
} else if (strcmp(playback_driver_uid, "") != 0) { |
|
|
|
@@ -1289,6 +1324,15 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, |
|
|
|
jack_error("Cannot get device name from device ID"); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
if (fHogged) { |
|
|
|
if (!TakeHogAux(fDeviceID, false)) { |
|
|
|
jack_error("Cannot take hog mode for playback device"); |
|
|
|
} |
|
|
|
if (ac3_encoding) { |
|
|
|
fDigitalPlayback = IsDigitalDevice(fDeviceID); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Use default driver in duplex mode |
|
|
|
} else { |
|
|
|
@@ -1297,8 +1341,9 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, |
|
|
|
jack_error("Cannot open default device in duplex mode, so aggregate default input and default output"); |
|
|
|
|
|
|
|
// Creates aggregate device |
|
|
|
AudioDeviceID captureID, playbackID; |
|
|
|
|
|
|
|
AudioDeviceID captureID = -1; |
|
|
|
AudioDeviceID playbackID = -1; |
|
|
|
|
|
|
|
if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { |
|
|
|
jack_log("JackCoreAudioDriver::SetupDevices : will take default input"); |
|
|
|
if (GetDefaultInputDevice(&captureID) != noErr) { |
|
|
|
@@ -1321,15 +1366,29 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, |
|
|
|
|
|
|
|
GetDeviceNameFromID(captureID, fCaptureUID); |
|
|
|
GetDeviceNameFromID(playbackID, fPlaybackUID); |
|
|
|
|
|
|
|
if (fHogged) { |
|
|
|
if (!TakeHogAux(captureID, true)) { |
|
|
|
jack_error("Cannot take hog mode for capture device"); |
|
|
|
} |
|
|
|
if (!TakeHogAux(playbackID, false)) { |
|
|
|
jack_error("Cannot take hog mode for playback device"); |
|
|
|
} |
|
|
|
if (ac3_encoding) { |
|
|
|
fDigitalPlayback = IsDigitalDevice(playbackID); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
if (fHogged) { |
|
|
|
if (TakeHog()) { |
|
|
|
jack_info("Device = %ld has been hogged", fDeviceID); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
@@ -1582,7 +1641,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, |
|
|
|
printError(err1); |
|
|
|
goto error; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Start I/O |
|
|
|
if (capturing && inchannels > 0) { |
|
|
|
enableIO = 1; |
|
|
|
@@ -1986,7 +2045,7 @@ 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, ac3_encoding) < 0) { |
|
|
|
goto error; |
|
|
|
} |
|
|
|
|
|
|
|
@@ -2016,15 +2075,24 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, |
|
|
|
|
|
|
|
if (ac3_encoding) { |
|
|
|
|
|
|
|
/* |
|
|
|
// Force hogged mode |
|
|
|
fHogged = true; |
|
|
|
if (TakeHog()) { |
|
|
|
jack_info("Device = %ld has been hogged", fDeviceID); |
|
|
|
} |
|
|
|
*/ |
|
|
|
|
|
|
|
/* |
|
|
|
if (!IsDigitalDevice(fDeviceID)) { |
|
|
|
jack_error("AC3 encoding can only be used with a digital device"); |
|
|
|
goto error; |
|
|
|
} |
|
|
|
*/ |
|
|
|
|
|
|
|
// Force hogged mode |
|
|
|
fHogged = true; |
|
|
|
if (TakeHog()) { |
|
|
|
jack_info("Device = %ld has been hogged", fDeviceID); |
|
|
|
if (!fDigitalPlayback) { |
|
|
|
jack_error("AC3 encoding can only be used with a digital device"); |
|
|
|
goto error; |
|
|
|
} |
|
|
|
|
|
|
|
JackAC3EncoderParams params; |
|
|
|
@@ -2036,7 +2104,7 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, |
|
|
|
fAC3Encoder = new JackAC3Encoder(params); |
|
|
|
|
|
|
|
if (!fAC3Encoder || !fAC3Encoder->Init(sample_rate)) { |
|
|
|
jack_error("Cannot allocate of init AC3 encoder"); |
|
|
|
jack_error("Cannot allocate or init AC3 encoder"); |
|
|
|
goto error; |
|
|
|
} |
|
|
|
|
|
|
|
@@ -2338,6 +2406,8 @@ bool JackCoreAudioDriver::TakeHogAux(AudioDeviceID deviceID, bool isInput) |
|
|
|
jack_error("Cannot read hog state..."); |
|
|
|
printError(err); |
|
|
|
} |
|
|
|
|
|
|
|
jack_log("JackCoreAudioDriver::TakeHogAux : deviceID = %d", deviceID); |
|
|
|
|
|
|
|
if (hog_pid != getpid()) { |
|
|
|
hog_pid = getpid(); |
|
|
|
|