bool CCoreAudioDevice::SetHogStatus(bool hog) { // According to Jeff Moore (Core Audio, Apple), Setting kAudioDevicePropertyHogMode // is a toggle and the only way to tell if you do get hog mode is to compare // the returned pid against getpid, if the match, you have hog mode, if not you don't. if (!m_DeviceId) return false; AudioObjectPropertyAddress propertyAddress; propertyAddress.mScope = kAudioDevicePropertyScopeOutput; propertyAddress.mElement = 0; propertyAddress.mSelector = kAudioDevicePropertyHogMode; if (hog) { // Not already set if (m_HogPid == -1) { CLog::Log(LOGDEBUG, "CCoreAudioDevice::SetHogStatus: " "Setting 'hog' status on device 0x%04x", (unsigned int)m_DeviceId); OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(m_HogPid), &m_HogPid); // even if setting hogmode was successfull our PID might not get written // into m_HogPid (so it stays -1). Readback hogstatus for judging if we // had success on getting hog status m_HogPid = GetHogStatus(); if (ret || m_HogPid != getpid()) { CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: " "Unable to set 'hog' status. Error = %s", GetError(ret).c_str()); return false; } CLog::Log(LOGDEBUG, "CCoreAudioDevice::SetHogStatus: " "Successfully set 'hog' status on device 0x%04x", (unsigned int)m_DeviceId); } } else { // Currently Set if (m_HogPid > -1) { CLog::Log(LOGDEBUG, "CCoreAudioDevice::SetHogStatus: " "Releasing 'hog' status on device 0x%04x", (unsigned int)m_DeviceId); pid_t hogPid = -1; OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(hogPid), &hogPid); if (ret || hogPid == getpid()) { CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: " "Unable to release 'hog' status. Error = %s", GetError(ret).c_str()); return false; } // Reset internal state m_HogPid = hogPid; } } return true; }
bool CCoreAudioDevice::SetHogStatus(bool hog) { // According to Jeff Moore (Core Audio, Apple), Setting kAudioDevicePropertyHogMode // is a toggle and the only way to tell if you do get hog mode is to compare // the returned pid against getpid, if the match, you have hog mode, if not you don't. if (!m_DeviceId) return false; AudioObjectPropertyAddress propertyAddress; propertyAddress.mScope = kAudioDevicePropertyScopeOutput; propertyAddress.mElement = 0; propertyAddress.mSelector = kAudioDevicePropertyHogMode; if (hog) { // Not already set if (m_HogPid == -1) { OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(m_HogPid), &m_HogPid); // even if setting hogmode was successfull our PID might not get written // into m_HogPid (so it stays -1). Readback hogstatus for judging if we // had success on getting hog status // We do this only when AudioObjectSetPropertyData didn't set m_HogPid because // it seems that in the other cases the GetHogStatus could return -1 // which would overwrite our valid m_HogPid again // Man we should never touch this shit again ;) if (m_HogPid == -1) m_HogPid = GetHogStatus(); if (ret || m_HogPid != getpid()) { CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: " "Unable to set 'hog' status. Error = %s", GetError(ret).c_str()); return false; } } } else { // Currently Set if (m_HogPid > -1) { pid_t hogPid = -1; OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(hogPid), &hogPid); if (ret || hogPid == getpid()) { CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: " "Unable to release 'hog' status. Error = %s", GetError(ret).c_str()); return false; } // Reset internal state m_HogPid = hogPid; } } return true; }
void AudioSession::setPreferredBufferSize(size_t bufferSize) { AudioValueRange bufferSizeRange = {0, 0}; UInt32 bufferSizeRangeSize = sizeof(AudioValueRange); AudioObjectPropertyAddress bufferSizeRangeAddress = { kAudioDevicePropertyBufferFrameSizeRange, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; OSStatus result = AudioObjectGetPropertyData(defaultDevice(), &bufferSizeRangeAddress, 0, 0, &bufferSizeRangeSize, &bufferSizeRange); if (result) return; size_t minBufferSize = static_cast<size_t>(bufferSizeRange.mMinimum); size_t maxBufferSize = static_cast<size_t>(bufferSizeRange.mMaximum); UInt32 bufferSizeOut = std::min(maxBufferSize, std::max(minBufferSize, bufferSize)); AudioObjectPropertyAddress preferredBufferSizeAddress = { kAudioDevicePropertyBufferFrameSize, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; result = AudioObjectSetPropertyData(defaultDevice(), &preferredBufferSizeAddress, 0, 0, sizeof(bufferSizeOut), (void*)&bufferSizeOut); #if LOG_DISABLED UNUSED_PARAM(result); #else if (result) LOG(Media, "AudioSession::setPreferredBufferSize(%zu) - failed with error %d", bufferSize, static_cast<int>(result)); else LOG(Media, "AudioSession::setPreferredBufferSize(%zu)", bufferSize); #endif }
bool CCoreAudioDevice::SetBufferSize(UInt32 size) { if (!m_DeviceId) return false; AudioObjectPropertyAddress propertyAddress; propertyAddress.mScope = kAudioDevicePropertyScopeOutput; propertyAddress.mElement = 0; propertyAddress.mSelector = kAudioDevicePropertyBufferFrameSize; UInt32 propertySize = sizeof(size); OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, propertySize, &size); if (ret != noErr) { CLog::Log(LOGERROR, "CCoreAudioDevice::SetBufferSize: " "Unable to set buffer size. Error = %s", GetError(ret).c_str()); } if (GetBufferSize() != size) CLog::Log(LOGERROR, "CCoreAudioDevice::SetBufferSize: Buffer size change not applied."); else CLog::Log(LOGDEBUG, "CCoreAudioDevice::SetBufferSize: Set buffer size to %d", (int)size); return (ret == noErr); }
bool CCoreAudioDevice::SetNominalSampleRate(Float64 sampleRate) { if (!m_DeviceId || sampleRate == 0.0f) return false; Float64 currentRate = GetNominalSampleRate(); if (currentRate == sampleRate) return true; //No need to change AudioObjectPropertyAddress propertyAddress; propertyAddress.mScope = kAudioDevicePropertyScopeOutput; propertyAddress.mElement = 0; propertyAddress.mSelector = kAudioDevicePropertyNominalSampleRate; OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(Float64), &sampleRate); if (ret != noErr) { CLog::Log(LOGERROR, "CCoreAudioDevice::SetNominalSampleRate: " "Unable to set current device sample rate to %0.0f. Error = %s", (float)sampleRate, GetError(ret).c_str()); return false; } if (m_SampleRateRestore == 0.0f) m_SampleRateRestore = currentRate; return true; }
void add_audio_status_listener(audio_status_callback_t function, ptr_t data) { OSStatus result; CFRunLoopRef theRunLoop; closure_t closure; AudioObjectPropertyAddress runLoop = { .mSelector = kAudioHardwarePropertyRunLoop, .mScope = kAudioObjectPropertyScopeGlobal, .mElement = kAudioObjectPropertyElementMaster }; AudioObjectPropertyAddress devices = { .mSelector = kAudioHardwarePropertyDevices, .mScope = kAudioObjectPropertyScopeGlobal, .mElement = kAudioObjectPropertyElementMaster }; theRunLoop = NULL; // necessary? result = AudioObjectSetPropertyData(kAudioObjectSystemObject, &runLoop, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop); assert(result == noErr); closure = new_closure(function, data); result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &devices, audio_listener, closure); assert(result == noErr); }
void mozilla_set_coreaudio_notification_runloop_if_needed() { mozilla::StaticMutexAutoLock lock(gMutex); if (gRunLoopSet) { return; } /* This is needed so that AudioUnit listeners get called on this thread, and * not the main thread. If we don't do that, they are not called, or a crash * occur, depending on the OSX version. */ AudioObjectPropertyAddress runloop_address = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; CFRunLoopRef run_loop = nullptr; OSStatus r; r = AudioObjectSetPropertyData(kAudioObjectSystemObject, &runloop_address, 0, NULL, sizeof(CFRunLoopRef), &run_loop); if (r != noErr) { NS_WARNING("Could not make global CoreAudio notifications use their own thread."); } gRunLoopSet = true; }
bool CCoreAudioDevice::SetMixingSupport(UInt32 mix) { if (!m_DeviceId) return false; if (!GetMixingSupport()) return false; int restore = -1; if (m_MixerRestore == -1) { // This is our first change to this setting. Store the original setting for restore restore = (GetMixingSupport() ? 1 : 0); } AudioObjectPropertyAddress propertyAddress; propertyAddress.mScope = kAudioDevicePropertyScopeOutput; propertyAddress.mElement = 0; propertyAddress.mSelector = kAudioDevicePropertySupportsMixing; UInt32 mixEnable = mix ? 1 : 0; OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(mixEnable), &mixEnable); if (ret != noErr) { CLog::Log(LOGERROR, "CCoreAudioDevice::SetMixingSupport: " "Unable to set MixingSupport to %s. Error = %s", mix ? "'On'" : "'Off'", GetError(ret).c_str()); return false; } if (m_MixerRestore == -1) m_MixerRestore = restore; return true; }
OSStatus AudioDevice::SetBufferSize(UInt32 buffersize) { OSStatus err = noErr; UInt32 size = sizeof(UInt32); AudioObjectPropertyAddress addr = { kAudioDevicePropertyBufferFrameSize, (mIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput), 0 }; err = AudioObjectSetPropertyData(mID, &addr, 0, NULL, size, &buffersize); AudioObjectGetPropertyData(mID, &addr, 0, NULL, &size, &mBufferSizeFrames); if(mBufferSizeFrames != buffersize) printf("buffer size mismatch!"); return err; }
OSStatus AudioDevice::SetSampleRate(Float64 sr) { OSStatus err = noErr; mFormat.mSampleRate = sr; UInt32 size = sizeof(mFormat); AudioObjectPropertyAddress addr = { kAudioDevicePropertyStreamFormat, (mIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput), 0 }; err = AudioObjectSetPropertyData(mID, &addr, 0, NULL, size, &mFormat); if(mFormat.mSampleRate != sr) printf("Error in AudioDevice::SetSampleRate - sample rate mismatch!"); return err; }
OSStatus AudioOutputSetVolume(AudioDeviceID device, Float32 left, Float32 right) { OSStatus err = AudioObjectSetPropertyData(device, &kAudioOutputVolumeProperty, 0, NULL, (UInt32)sizeof(left), &left); if (kAudioHardwareUnknownPropertyError == err) { UInt32 channels[2]; err = AudioOutputGetStereoChannels(device, &channels[0], &channels[1]); if (noErr == err) err = AudioDeviceSetProperty(device, NULL, channels[0], FALSE, kAudioDevicePropertyVolumeScalar, (UInt32)sizeof(Float32), &left); if (noErr == err) err = AudioDeviceSetProperty(device, NULL, channels[1], FALSE, kAudioDevicePropertyVolumeScalar, (UInt32)sizeof(Float32), &right); } return err; }
static OSStatus SetAudioProperty(AudioObjectID id, AudioObjectPropertySelector selector, UInt32 inDataSize, void *inData) { AudioObjectPropertyAddress property_address; property_address.mSelector = selector; property_address.mScope = kAudioObjectPropertyScopeGlobal; property_address.mElement = kAudioObjectPropertyElementMaster; return AudioObjectSetPropertyData(id, &property_address, 0, NULL, inDataSize, inData); }
static BOOL MIX_LineSetMute(DWORD lineID, BOOL mute) { MixerLine *line = &mixer.lines[lineID]; UInt32 val = mute; UInt32 size = sizeof(UInt32); AudioObjectPropertyAddress address; OSStatus err = noErr; address.mSelector = kAudioDevicePropertyMute; address.mScope = IsInput(line->direction) ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; address.mElement = 0; err = AudioObjectSetPropertyData(line->deviceID, &address, 0, 0, size, &val); return (err == noErr); }
void CCoreAudioHardware::SetAutoHogMode(bool enable) { AudioObjectPropertyAddress propertyAddress; propertyAddress.mScope = kAudioObjectPropertyScopeGlobal; propertyAddress.mElement = kAudioObjectPropertyElementMaster; propertyAddress.mSelector = kAudioHardwarePropertyHogModeIsAllowed; UInt32 val = enable ? 1 : 0; UInt32 size = sizeof(val); OSStatus ret = AudioObjectSetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, size, &val); if (ret != noErr) CLog::Log(LOGERROR, "CCoreAudioHardware::SetAutoHogMode: " "Unable to set auto 'hog' mode. Error = %s", GetError(ret).c_str()); }
/* * Setters */ static BOOL MIX_LineSetVolume(DWORD lineID, DWORD channels, Float32 left, Float32 right) { MixerLine *line = &mixer.lines[lineID]; UInt32 size = sizeof(Float32); AudioObjectPropertyAddress address; OSStatus err = noErr; TRACE("lineID %d channels %d left %f right %f\n", lineID, channels, left, right); address.mSelector = kAudioDevicePropertyVolumeScalar; address.mScope = IsInput(line->direction) ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; if (channels == 2) { address.mElement = 1; err = AudioObjectSetPropertyData(line->deviceID, &address, 0, NULL, size, &left); if (err != noErr) return FALSE; address.mElement = 2; err = AudioObjectSetPropertyData(line->deviceID, &address, 0, NULL, size, &right); } else { /* FIXME Using master channel failed ?? return kAudioHardwareUnknownPropertyError address.mElement = 0; err = AudioObjectSetPropertyData(line->deviceID, &address, 0, NULL, size, &left); */ right = left; address.mElement = 1; err = AudioObjectSetPropertyData(line->deviceID, &address, 0, NULL, size, &left); if (err != noErr) return FALSE; address.mElement = 2; err = AudioObjectSetPropertyData(line->deviceID, &address, 0, NULL, size, &right); } return (err == noErr); }
void AudioDevice::SetBufferSize(UInt32 size) { UInt32 propsize = sizeof(UInt32); AudioObjectPropertyScope theScope = mIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; AudioObjectPropertyAddress theAddress = { kAudioDevicePropertyBufferFrameSize, theScope, 0 }; // channel verify_noerr(AudioObjectSetPropertyData(mID, &theAddress, 0, NULL, propsize, &size)); verify_noerr(AudioObjectGetPropertyData(mID, &theAddress, 0, NULL, &propsize, &mBufferSizeFrames)); }
static inline gboolean _audio_device_set_mixing (AudioDeviceID device_id, gboolean enable_mix) { OSStatus status = noErr; UInt32 propertySize = 0, can_mix = enable_mix; Boolean writable = FALSE; gboolean res = FALSE; AudioObjectPropertyAddress audioDeviceSupportsMixingAddress = { kAudioDevicePropertySupportsMixing, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; if (AudioObjectHasProperty (device_id, &audioDeviceSupportsMixingAddress)) { /* Set mixable to false if we are allowed to */ status = AudioObjectIsPropertySettable (device_id, &audioDeviceSupportsMixingAddress, &writable); if (status) { GST_DEBUG ("AudioObjectIsPropertySettable: %d", (int) status); } status = AudioObjectGetPropertyDataSize (device_id, &audioDeviceSupportsMixingAddress, 0, NULL, &propertySize); if (status) { GST_DEBUG ("AudioObjectGetPropertyDataSize: %d", (int) status); } status = AudioObjectGetPropertyData (device_id, &audioDeviceSupportsMixingAddress, 0, NULL, &propertySize, &can_mix); if (status) { GST_DEBUG ("AudioObjectGetPropertyData: %d", (int) status); } if (status == noErr && writable) { can_mix = enable_mix; status = AudioObjectSetPropertyData (device_id, &audioDeviceSupportsMixingAddress, 0, NULL, propertySize, &can_mix); res = TRUE; } if (status != noErr) { GST_ERROR ("failed to set mixmode: %d", (int) status); } } else { GST_DEBUG ("property not found, mixing coudln't be changed"); } return res; }
static OSStatus coreaudio_set_framesize(AudioDeviceID id, UInt32 *framesize) { UInt32 size = sizeof(*framesize); AudioObjectPropertyAddress addr = { kAudioDevicePropertyBufferFrameSize, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; return AudioObjectSetPropertyData(id, &addr, 0, NULL, size, framesize); }
static int coreaudio_plugin_start (void) { // This is a largely undocumented but absolutely necessary // requirement starting with OS-X 10.6. If not called, queries and // updates to various audio device properties are not handled // correctly. // Many thanks to the rtaudio project for documenting this. CFRunLoopRef theRunLoop = NULL; AudioObjectPropertyAddress property = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; OSStatus err = AudioObjectSetPropertyData( kAudioObjectSystemObject, &property, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop); if (err) { trace ("AudioObjectSetPropertyData-plugin_start= %s\n", GetMacOSStatusErrorString(err) ); return -1; } au_state = 0; return 0; }
static OSStatus coreaudio_set_streamformat(AudioDeviceID id, AudioStreamBasicDescription *d) { UInt32 size = sizeof(*d); AudioObjectPropertyAddress addr = { kAudioDevicePropertyStreamFormat, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; return AudioObjectSetPropertyData(id, &addr, 0, NULL, size, d); }
void CCoreAudioHardware::ResetStream(AudioStreamID stream) { // Find the streams current physical format AudioObjectPropertyAddress propertyAddress; propertyAddress.mScope = kAudioObjectPropertyScopeGlobal; propertyAddress.mElement = kAudioObjectPropertyElementMaster; propertyAddress.mSelector = kAudioStreamPropertyPhysicalFormat; AudioStreamBasicDescription currentFormat; UInt32 paramSize = sizeof(currentFormat); OSStatus ret = AudioObjectGetPropertyData(stream, &propertyAddress, 0, NULL, ¶mSize, ¤tFormat); if (ret != noErr) return; // If it's currently AC-3/SPDIF then reset it to some mixable format if (currentFormat.mFormatID == 'IAC3' || currentFormat.mFormatID == kAudioFormat60958AC3) { AudioStreamBasicDescription *formats = CCoreAudioHardware::FormatsList(stream); bool streamReset = false; if (!formats) return; for (int i = 0; !streamReset && formats[i].mFormatID != 0; i++) { if (formats[i].mFormatID == kAudioFormatLinearPCM) { ret = AudioObjectSetPropertyData(stream, &propertyAddress, 0, NULL, sizeof(formats[i]), &(formats[i])); if (ret != noErr) { CLog::Log(LOGDEBUG, "CCoreAudioHardware::ResetStream: " "Unable to retrieve the list of available devices. Error = %s", GetError(ret).c_str()); continue; } else { streamReset = true; Sleep(10); } } } free(formats); } }
bool CCoreAudioDevice::SetDataSource(UInt32 &dataSourceId) { bool ret = false; if (!m_DeviceId) return false; AudioObjectPropertyAddress propertyAddress; propertyAddress.mScope = kAudioDevicePropertyScopeOutput; propertyAddress.mElement = 0; propertyAddress.mSelector = kAudioDevicePropertyDataSource; UInt32 size = sizeof(dataSourceId); OSStatus status = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, size, &dataSourceId); if(status == noErr) ret = true; return ret; }
bool CCoreAudioDevice::SetCurrentVolume(Float32 vol) { if (!m_DeviceId) return false; AudioObjectPropertyAddress propertyAddress; propertyAddress.mScope = kAudioDevicePropertyScopeOutput; propertyAddress.mElement = 0; propertyAddress.mSelector = kHALOutputParam_Volume; OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(Float32), &vol); if (ret != noErr) { CLog::Log(LOGERROR, "CCoreAudioDevice::SetCurrentVolume: " "Unable to set AudioUnit volume. Error = %s", GetError(ret).c_str()); return false; } return true; }
void setCurrentSourceIndex (int index, bool input) { if (deviceID != 0) { HeapBlock <OSType> types; const int num = getAllDataSourcesForDevice (deviceID, types); if (isPositiveAndBelow (index, num)) { AudioObjectPropertyAddress pa; pa.mSelector = kAudioDevicePropertyDataSource; pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; pa.mElement = kAudioObjectPropertyElementMaster; OSType typeId = types[index]; OK (AudioObjectSetPropertyData (deviceID, &pa, 0, 0, sizeof (typeId), &typeId)); } } }
static void coreaudio_set_channel_position(AudioDeviceID dev_id, int channels, const channel_position_t *map) { AudioObjectPropertyAddress aopa = { kAudioDevicePropertyPreferredChannelLayout, kAudioObjectPropertyScopeOutput, kAudioObjectPropertyElementMaster }; AudioChannelLayout *layout = NULL; size_t layout_size = (size_t) &layout->mChannelDescriptions[channels]; layout = (AudioChannelLayout*)malloc(layout_size); layout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions ; layout->mChannelBitmap = 0; layout->mNumberChannelDescriptions = channels; AudioChannelDescription *descriptions = layout->mChannelDescriptions; for (int i = 0; i < channels; i++) { const channel_position_t pos = map[i]; AudioChannelLabel label = kAudioChannelLabel_Mono; for (int j = 0; j < N_ELEMENTS(coreaudio_channel_mapping); j++) { if (pos == coreaudio_channel_mapping[j].pos) { label = coreaudio_channel_mapping[j].label; break; } } descriptions[channels - 1 - i].mChannelLabel = label; descriptions[i].mChannelFlags = kAudioChannelFlags_AllOff; descriptions[i].mCoordinates[0] = 0; descriptions[i].mCoordinates[1] = 0; descriptions[i].mCoordinates[2] = 0; } OSStatus err = AudioObjectSetPropertyData(dev_id, &aopa, 0, NULL, layout_size, layout); if (err != noErr) d_print("Cannot set the channel layout successfully.\n"); free(layout); }
static inline gboolean _audio_stream_set_current_format (AudioStreamID stream_id, AudioStreamBasicDescription format) { OSStatus status = noErr; UInt32 propertySize = sizeof (AudioStreamBasicDescription); AudioObjectPropertyAddress formatAddress = { kAudioStreamPropertyPhysicalFormat, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; status = AudioObjectSetPropertyData (stream_id, &formatAddress, 0, NULL, propertySize, &format); if (status != noErr) { GST_ERROR ("failed to set current format: %d", (int) status); return FALSE; } return TRUE; }
CCoreAudioAEHALOSX::CCoreAudioAEHALOSX() : m_audioGraph (NULL ), m_Initialized (false ), m_Passthrough (false ), m_allowMixing (false ), m_encoded (false ), m_initVolume (1.0f ), m_NumLatencyFrames (0 ), m_OutputBufferIndex (0 ), m_ae (NULL ) { m_AudioDevice = new CCoreAudioDevice(); m_OutputStream = new CCoreAudioStream(); SInt32 major, minor; Gestalt(gestaltSystemVersionMajor, &major); Gestalt(gestaltSystemVersionMinor, &minor); // By default, kAudioHardwarePropertyRunLoop points at the process's main thread on SnowLeopard, // If your process lacks such a run loop, you can set kAudioHardwarePropertyRunLoop to NULL which // tells the HAL to run it's own thread for notifications (which was the default prior to SnowLeopard). // So tell the HAL to use its own thread for similar behavior under all supported versions of OSX. 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) { CLog::Log(LOGERROR, "CCoreAudioAE::constructor: kAudioHardwarePropertyRunLoop error."); } } }
static inline gboolean _audio_system_set_runloop (CFRunLoopRef runLoop) { OSStatus status = noErr; gboolean res = FALSE; AudioObjectPropertyAddress runloopAddress = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; status = AudioObjectSetPropertyData (kAudioObjectSystemObject, &runloopAddress, 0, NULL, sizeof (CFRunLoopRef), &runLoop); if (status == noErr) { res = TRUE; } else { GST_ERROR ("failed to set runloop to %p: %d", runLoop, (int) status); } return res; }
audio::orchestra::api::Core::Core() : m_private(new audio::orchestra::api::CorePrivate()) { #if defined(AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER) // This is a largely undocumented but absolutely necessary // requirement starting with OS-X 10.6. If not called, queries and // updates to various audio device properties are not handled // correctly. CFRunLoopRef theRunLoop = nullptr; AudioObjectPropertyAddress property = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; OSStatus result = AudioObjectSetPropertyData(kAudioObjectSystemObject, &property, 0, nullptr, sizeof(CFRunLoopRef), &theRunLoop); if (result != noErr) { ATA_ERROR("error setting run loop property!"); } #endif }
static inline gboolean _audio_device_set_hog (AudioDeviceID device_id, pid_t hog_pid) { OSStatus status = noErr; UInt32 propertySize = sizeof (hog_pid); gboolean res = FALSE; AudioObjectPropertyAddress audioDeviceHogModeAddress = { kAudioDevicePropertyHogMode, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; status = AudioObjectSetPropertyData (device_id, &audioDeviceHogModeAddress, 0, NULL, propertySize, &hog_pid); if (status == noErr) { res = TRUE; } else { GST_ERROR ("failed to set hog: %d", (int) status); } return res; }