bool CCoreAudioDevice::SetHogStatus(bool hog) { if (!m_DeviceId) return false; pid_t holder = GetHogStatus(); pid_t me = getpid(); if (hog) { if (holder != me) { CLog::Log(LOGDEBUG, "CCoreAudioDevice::SetHogStatus: Setting 'hog' status on device 0x%04x", m_DeviceId); OSStatus ret = AudioDeviceSetProperty(m_DeviceId, NULL, 0, false, kAudioDevicePropertyHogMode, sizeof(me), &me); if (ret) { CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: Unable to set 'hog' status. Error = 0x%08x (%4.4s)", ret, CONVERT_OSSTATUS(ret)); return false; } pid_t holder = GetHogStatus(); if (holder != getpid()) { CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: Unable to set 'hog' status. another process (%x) has it.", holder); return false; } CLog::Log(LOGDEBUG, "CCoreAudioDevice::SetHogStatus: Successfully set 'hog' status on device 0x%04x", m_DeviceId); } } else { if (holder == me) // Currently Set { CLog::Log(LOGDEBUG, "CCoreAudioDevice::SetHogStatus: Releasing 'hog' status on device 0x%04x", m_DeviceId); pid_t hogPid = -1; OSStatus ret = AudioDeviceSetProperty(m_DeviceId, NULL, 0, false, kAudioDevicePropertyHogMode, sizeof(hogPid), &hogPid); if (ret) { CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: Unable to release 'hog' status. Error = 0x%08x (%4.4s)", ret, CONVERT_OSSTATUS(ret)); return false; } pid_t holder = GetHogStatus(); if (holder == getpid()) { CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: failed to release. still hogging!"); return false; } } } 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) { 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; }