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;
}
Пример #2
0
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;   
}
Пример #3
0
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;
}