bool CCoreAudioStream::SetVirtualFormat(AudioStreamBasicDescription* pDesc)
{
    if (!pDesc || !m_StreamId)
        return false;

    std::string formatString;

    if (!m_OriginalVirtualFormat.mFormatID)
    {
        // Store the original format (as we found it) so that it can be restored later
        if (!GetVirtualFormat(&m_OriginalVirtualFormat))
        {
            CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: "
                      "Unable to retrieve current virtual format for stream 0x%04x.", (uint)m_StreamId);
            return false;
        }
    }
    m_virtual_format_event.Reset();
    OSStatus ret = AudioStreamSetProperty(m_StreamId,
                                          NULL, 0, kAudioStreamPropertyVirtualFormat, sizeof(AudioStreamBasicDescription), pDesc);
    if (ret)
    {
        CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: "
                  "Unable to set virtual 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 checkVirtualFormat;
        if (!GetVirtualFormat(&checkVirtualFormat))
        {
            CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: "
                      "Unable to retrieve current physical format for stream 0x%04x.", (uint)m_StreamId);
            return false;
        }
        if (checkVirtualFormat.mSampleRate == pDesc->mSampleRate &&
                checkVirtualFormat.mFormatID == pDesc->mFormatID &&
                checkVirtualFormat.mFramesPerPacket == pDesc->mFramesPerPacket)
        {
            // The right format is now active.
            CLog::Log(LOGDEBUG, "CCoreAudioStream::SetVirtualFormat: "
                      "Virtual format for stream 0x%04x. now active (%s)",
                      (uint)m_StreamId, StreamDescriptionToString(checkVirtualFormat, formatString));
            break;
        }
        m_virtual_format_event.WaitMSec(100);
    }
    return true;
}
示例#2
0
bool CCoreAudioStream::SetVirtualFormat(AudioStreamBasicDescription* pDesc)
{
  if (!pDesc || !m_StreamId)
    return false;
  if (!m_OriginalVirtualFormat.mFormatID)
  {
    if (!GetVirtualFormat(m_StreamId, &m_OriginalVirtualFormat)) // Store the original format (as we found it) so that it can be restored later
    {
      CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: Unable to retrieve current virtual format for stream 0x%04x.", m_StreamId);
      return false;
    }
  }
  OSStatus ret = AudioStreamSetProperty(m_StreamId, NULL, 0, kAudioStreamPropertyVirtualFormat, sizeof(AudioStreamBasicDescription), pDesc);
  if (ret)
  {
    CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: Unable to set virtual format for stream 0x%04x. Error = 0x%08x (%4.4s)", m_StreamId, ret, CONVERT_OSSTATUS(ret));
    return false;
  }
  return true;   
}
示例#3
0
bool CCoreAudioStream::SetVirtualFormat(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_OriginalVirtualFormat.mFormatID)
  {
    // Store the original format (as we found it) so that it can be restored later
    if (!GetVirtualFormat(&m_OriginalVirtualFormat))
    {
      CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: "
        "Unable to retrieve current virtual format for stream 0x%04x.", (uint)m_StreamId);
      return false;
    }
  }
  m_virtual_format_event.Reset();

  AudioObjectPropertyAddress propertyAddress; 
  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
  propertyAddress.mSelector = kAudioStreamPropertyVirtualFormat; 

  UInt32 propertySize = sizeof(AudioStreamBasicDescription);
  OSStatus ret = AudioObjectSetPropertyData(m_StreamId, &propertyAddress, 0, NULL, propertySize, pDesc); 
  if (ret)
  {
    CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: "
      "Unable to set virtual 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 checkVirtualFormat;
    if (!GetVirtualFormat(&checkVirtualFormat))
    {
      CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: "
        "Unable to retrieve current physical format for stream 0x%04x.", (uint)m_StreamId);
      return false;
    }
    if (checkVirtualFormat.mSampleRate == pDesc->mSampleRate &&
        checkVirtualFormat.mFormatID == pDesc->mFormatID &&
        checkVirtualFormat.mFramesPerPacket == pDesc->mFramesPerPacket)
    {
      // The right format is now active.
      CLog::Log(LOGDEBUG, "CCoreAudioStream::SetVirtualFormat: "
        "Virtual format for stream 0x%04x. now active (%s)",
        (uint)m_StreamId, StreamDescriptionToString(checkVirtualFormat, formatString));
      break;
    }
    m_virtual_format_event.WaitMSec(100);
  }
  return true;
}