bool CCoreAudioStream::SetPhysicalFormat(AudioStreamBasicDescription* pDesc) { if (!pDesc || !m_StreamId) return false; std::string formatString; if (!m_OriginalPhysicalFormat.mFormatID) { // Store the original format (as we found it) so that it can be restored later if (!GetPhysicalFormat(&m_OriginalPhysicalFormat)) { CLog::Log(LOGERROR, "CCoreAudioStream::SetPhysicalFormat: " "Unable to retrieve current physical format for stream 0x%04x.", (uint)m_StreamId); return false; } } m_physical_format_event.Reset(); OSStatus ret = AudioStreamSetProperty(m_StreamId, NULL, 0, kAudioStreamPropertyPhysicalFormat, sizeof(AudioStreamBasicDescription), pDesc); if (ret) { CLog::Log(LOGERROR, "CCoreAudioStream::SetPhysicalFormat: " "Unable to set physical format for stream 0x%04x. Error = %s", (uint)m_StreamId, GetError(ret).c_str()); return false; } // The AudioStreamSetProperty is not only asynchronious, // it is also not Atomic, in its behaviour. // Therefore we check 5 times before we really give up. // FIXME: failing isn't actually implemented yet. for(int i = 0; i < 10; ++i) { AudioStreamBasicDescription checkPhysicalFormat; if (!GetPhysicalFormat(&checkPhysicalFormat)) { CLog::Log(LOGERROR, "CCoreAudioStream::SetPhysicalFormat: " "Unable to retrieve current physical format for stream 0x%04x.", (uint)m_StreamId); return false; } if (checkPhysicalFormat.mSampleRate == pDesc->mSampleRate && checkPhysicalFormat.mFormatID == pDesc->mFormatID && checkPhysicalFormat.mFramesPerPacket == pDesc->mFramesPerPacket) { // The right format is now active. CLog::Log(LOGDEBUG, "CCoreAudioStream::SetPhysicalFormat: " "Physical format for stream 0x%04x. now active (%s)", (uint)m_StreamId, StreamDescriptionToString(checkPhysicalFormat, formatString)); break; } m_physical_format_event.WaitMSec(100); } return true; }
bool CCoreAudioStream::SetPhysicalFormat(AudioStreamBasicDescription* pDesc) { if (!pDesc || !m_StreamId) return false; if (!m_OriginalPhysicalFormat.mFormatID) { if (!GetPhysicalFormat(m_StreamId, &m_OriginalPhysicalFormat)) // Store the original format (as we found it) so that it can be restored later { CLog::Log(LOGERROR, "CCoreAudioStream::SetPhysicalFormat: Unable to retrieve current physical format for stream 0x%04x.", m_StreamId); return false; } } OSStatus ret = AudioStreamSetProperty(m_StreamId, NULL, 0, kAudioStreamPropertyPhysicalFormat, sizeof(AudioStreamBasicDescription), pDesc); if (ret) { CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: Unable to set physical format for stream 0x%04x. Error = 0x%08x (%4.4s)", m_StreamId, ret, CONVERT_OSSTATUS(ret)); return false; } return true; }
bool CCoreAudioStream::SetPhysicalFormat(AudioStreamBasicDescription* pDesc) { if (!pDesc || !m_StreamId) return false; std::string formatString; // suppress callbacks for the default output device change // for the next 2 seconds because setting format // might trigger a change (when setting/unsetting an encoded // passthrough format) CCoreAudioDevice::SuppressDefaultOutputDeviceCB(2000); if (!m_OriginalPhysicalFormat.mFormatID) { // Store the original format (as we found it) so that it can be restored later if (!GetPhysicalFormat(&m_OriginalPhysicalFormat)) { CLog::Log(LOGERROR, "CCoreAudioStream::SetPhysicalFormat: " "Unable to retrieve current physical format for stream 0x%04x.", (uint)m_StreamId); return false; } } m_physical_format_event.Reset(); AudioObjectPropertyAddress propertyAddress; propertyAddress.mScope = kAudioObjectPropertyScopeGlobal; propertyAddress.mElement = kAudioObjectPropertyElementMaster; propertyAddress.mSelector = kAudioStreamPropertyPhysicalFormat; UInt32 propertySize = sizeof(AudioStreamBasicDescription); OSStatus ret = AudioObjectSetPropertyData(m_StreamId, &propertyAddress, 0, NULL, propertySize, pDesc); if (ret) { CLog::Log(LOGERROR, "CCoreAudioStream::SetPhysicalFormat: " "Unable to set physical format for stream 0x%04x. Error = %s", (uint)m_StreamId, GetError(ret).c_str()); return false; } // The AudioStreamSetProperty is not only asynchronious, // it is also not Atomic, in its behaviour. // Therefore we check 5 times before we really give up. // FIXME: failing isn't actually implemented yet. for(int i = 0; i < 10; ++i) { AudioStreamBasicDescription checkPhysicalFormat; if (!GetPhysicalFormat(&checkPhysicalFormat)) { CLog::Log(LOGERROR, "CCoreAudioStream::SetPhysicalFormat: " "Unable to retrieve current physical format for stream 0x%04x.", (uint)m_StreamId); return false; } if (checkPhysicalFormat.mSampleRate == pDesc->mSampleRate && checkPhysicalFormat.mFormatID == pDesc->mFormatID && checkPhysicalFormat.mFramesPerPacket == pDesc->mFramesPerPacket && checkPhysicalFormat.mChannelsPerFrame == pDesc->mChannelsPerFrame) { // The right format is now active. CLog::Log(LOGDEBUG, "CCoreAudioStream::SetPhysicalFormat: " "Physical format for stream 0x%04x. now active (%s)", (uint)m_StreamId, StreamDescriptionToString(checkPhysicalFormat, formatString)); break; } m_physical_format_event.WaitMSec(100); } return true; }