Skip to content

Commit

Permalink
Don't just randomly sleep, wait for the format change to take hold.
Browse files Browse the repository at this point in the history
  • Loading branch information
elan committed Apr 18, 2012
1 parent 129ca52 commit 0d15a72
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 8 deletions.
6 changes: 0 additions & 6 deletions xbmc/cores/AudioRenderers/CoreAudioRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,8 +423,6 @@ bool CCoreAudioRenderer::Initialize(IAudioCallback* pCallback, const CStdString&
if(m_init_state.bPassthrough)
{
m_Passthrough = InitializeEncoded(outputDevice, m_init_state.uiSamplesPerSec);
// TODO: wait for audio device startup
Sleep(200);
}

// If this is a PCM stream, or we failed to handle a passthrough stream natively,
Expand All @@ -446,15 +444,11 @@ bool CCoreAudioRenderer::Initialize(IAudioCallback* pCallback, const CStdString&
{
CLog::Log(LOGDEBUG, "CoreAudioRenderer::Initialize: No suitable AC3 output format found. Attempting DD-Wav.");
configured = InitializePCMEncoded(m_init_state.uiSamplesPerSec);
// TODO: wait for audio device startup
Sleep(250);
}
else
{
// Standard PCM data
configured = InitializePCM(m_init_state.iChannels, m_init_state.uiSamplesPerSec, m_init_state.uiBitsPerSample, m_init_state.channelMap);
// TODO: wait for audio device startup
Sleep(250);
}

if (!configured) // No suitable output format was able to be configured
Expand Down
63 changes: 61 additions & 2 deletions xbmc/osx/CoreAudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <PlatformDefs.h>
#include <Log.h>
#include <math.h>
#include <boost/thread.hpp>

char* UInt32ToFourCC(UInt32* pVal) // NOT NULL TERMINATED! Modifies input value.
{
Expand Down Expand Up @@ -660,6 +661,7 @@ UInt32 CCoreAudioDevice::GetNumLatencyFrames()
CCoreAudioStream::CCoreAudioStream() :
m_StreamId(0)
{
m_formatChanged = false;
m_OriginalVirtualFormat.mFormatID = 0;
m_OriginalPhysicalFormat.mFormatID = 0;
}
Expand All @@ -669,10 +671,47 @@ CCoreAudioStream::~CCoreAudioStream()
Close();
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
OSStatus CCoreAudioStream::HardwareStreamListener(AudioObjectID inObjectID,
UInt32 inNumberAddresses,
const AudioObjectPropertyAddress inAddresses[],
void* inClientData)
{
CCoreAudioStream* stream = (CCoreAudioStream* )inClientData;
OSStatus err = noErr;

for (int i=0; i<inNumberAddresses; i++)
{
if (inAddresses[i].mSelector == kAudioStreamPropertyPhysicalFormat)
{
// Hardware physical format has changed.
CStdString formatString;
AudioStreamBasicDescription actualFormat;
UInt32 propertySize = sizeof(AudioStreamBasicDescription);
if (AudioObjectGetPropertyData(stream->m_StreamId, &inAddresses[i], 0, NULL, &propertySize, &actualFormat) == noErr)
{
CLog::Log(LOGINFO, "CCoreAudioStream::HardwareStreamListener: Hardware format changed to %s", StreamDescriptionToString(actualFormat, formatString));
stream->m_formatChanged = true;
}
}
}

return err;
}

bool CCoreAudioStream::Open(AudioStreamID streamId)
{
m_StreamId = streamId;
CLog::Log(LOGDEBUG, "CCoreAudioStream::Open: Opened stream 0x%04x.", m_StreamId);

// Watch for changes.
AudioObjectPropertyAddress propertyAOPA;
propertyAOPA.mElement = kAudioObjectPropertyElementMaster;
propertyAOPA.mScope = kAudioObjectPropertyScopeGlobal;
propertyAOPA.mSelector = kAudioStreamPropertyPhysicalFormat;
if (AudioObjectAddPropertyListener(m_StreamId, &propertyAOPA, HardwareStreamListener, (void* )this) != noErr)
CLog::Log(LOGERROR, "CCoreAudioStream::Open: couldn't set up a property listener.", m_StreamId);

return true;
}

Expand All @@ -694,6 +733,14 @@ void CCoreAudioStream::Close()
SetPhysicalFormat(&m_OriginalPhysicalFormat);
}

// Remove the listener.
AudioObjectPropertyAddress propertyAOPA;
propertyAOPA.mElement = kAudioObjectPropertyElementMaster;
propertyAOPA.mScope = kAudioObjectPropertyScopeGlobal;
propertyAOPA.mSelector = kAudioStreamPropertyPhysicalFormat;
if (AudioObjectRemovePropertyListener(m_StreamId, &propertyAOPA, HardwareStreamListener, this) != noErr)
CLog::Log(LOGDEBUG, "CCoreAudioStream::Close: Couldn't remove property listener.");

m_OriginalPhysicalFormat.mFormatID = 0;
m_OriginalVirtualFormat.mFormatID = 0;
CLog::Log(LOGDEBUG, "CCoreAudioStream::Close: Closed stream 0x%04x.", m_StreamId);
Expand Down Expand Up @@ -789,22 +836,34 @@ bool CCoreAudioStream::SetPhysicalFormat(AudioStreamBasicDescription* pDesc)
{
if (!pDesc || !m_StreamId)
return false;

// Save original format.
if (!m_OriginalPhysicalFormat.mFormatID)
{
if (!GetPhysicalFormat(&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;
}
}
}

// Set the new format.
m_formatChanged = 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;
}

sleep(1); // For the change to take effect
// Wait for the format to take effect.
int i = 0;
for (; i<50 && m_formatChanged == false; i++)
boost::this_thread::sleep(boost::posix_time::milliseconds(25));

if (m_formatChanged == true)
CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: Changed physical format in %dms", i*50);

return true;
}

Expand Down
7 changes: 7 additions & 0 deletions xbmc/osx/CoreAudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,13 @@ class CCoreAudioStream
bool GetAvailablePhysicalFormats(StreamFormatList* pList);

protected:

static OSStatus HardwareStreamListener(AudioObjectID inObjectID,
UInt32 inNumberAddresses,
const AudioObjectPropertyAddress inAddresses[],
void* inClientData);

bool m_formatChanged;
AudioStreamID m_StreamId;
AudioStreamBasicDescription m_OriginalVirtualFormat;
AudioStreamBasicDescription m_OriginalPhysicalFormat;
Expand Down

0 comments on commit 0d15a72

Please sign in to comment.