コード例 #1
0
ファイル: CoreAudioHardware.cpp プロジェクト: HofiOne/xbmc
void CCoreAudioHardware::ResetStream(AudioStreamID streamId)
{
  CCoreAudioStream stream;
  stream.Open(streamId);
  
  AudioStreamBasicDescription desc;
  if (stream.GetPhysicalFormat(&desc))
  {
    if (desc.mFormatID == 'IAC3' || desc.mFormatID == kAudioFormat60958AC3)
    {
      CLog::Log(LOGDEBUG, "CCoreAudioHardware::ResetStream stream 0x%x is in encoded format.. setting to LPCM", (unsigned int)streamId);

      StreamFormatList availableFormats;
      if (stream.GetAvailablePhysicalFormats(&availableFormats))
      {
        for (StreamFormatList::iterator fmtIt = availableFormats.begin(); fmtIt != availableFormats.end() ; ++fmtIt)
        {
          AudioStreamRangedDescription fmtDesc = *fmtIt;
          if (fmtDesc.mFormat.mFormatID == kAudioFormatLinearPCM)
          {
            AudioStreamBasicDescription newFmt = fmtDesc.mFormat;

            if (stream.SetPhysicalFormat(&newFmt))
              break;
          }
        }
      }
    }
  }

  stream.Close(false);
}
コード例 #2
0
ファイル: CoreAudioAEHALOSX.cpp プロジェクト: A600/xbmc
bool CCoreAudioAEHALOSX::InitializeEncoded(AudioDeviceID outputDevice, AEAudioFormat &format)
{
  std::string formatString;
  AudioStreamID outputStream = 0;
  AudioStreamBasicDescription outputFormat = {0};

  // Fetch a list of the streams defined by the output device
  UInt32 streamIndex = 0;
  AudioStreamIdList streams;
  m_AudioDevice->GetStreams(&streams);

  m_OutputBufferIndex = 0;

  while (!streams.empty())
  {
    // Get the next stream
    CCoreAudioStream stream;
    stream.Open(streams.front());
    streams.pop_front(); // We copied it, now we are done with it

    // Probe physical formats
    StreamFormatList physicalFormats;
    stream.GetAvailablePhysicalFormats(&physicalFormats);
    while (!physicalFormats.empty())
    {
      AudioStreamRangedDescription& desc = physicalFormats.front();
      CLog::Log(LOGDEBUG, "CCoreAudioAEHALOSX::InitializeEncoded:    "
        "Considering Physical Format: %s", StreamDescriptionToString(desc.mFormat, formatString));

      if (m_rawDataFormat == AE_FMT_LPCM   || m_rawDataFormat == AE_FMT_DTSHD ||
          m_rawDataFormat == AE_FMT_TRUEHD || m_rawDataFormat == AE_FMT_EAC3)
      {
        // check pcm output formats
        unsigned int bps = CAEUtil::DataFormatToBits(AE_FMT_S16NE);
        if (desc.mFormat.mChannelsPerFrame == m_initformat.m_channelLayout.Count() &&
            desc.mFormat.mBitsPerChannel == bps &&
            desc.mFormat.mSampleRate == m_initformat.m_sampleRate )
        {
          outputFormat = desc.mFormat; // Select this format
          m_OutputBufferIndex = streamIndex;
          outputStream = stream.GetId();
          break;
        }
      }
      else
      {
        // check encoded formats
        if (desc.mFormat.mFormatID == kAudioFormat60958AC3 || desc.mFormat.mFormatID == 'IAC3')
        {
          if (desc.mFormat.mChannelsPerFrame == m_initformat.m_channelLayout.Count() &&
              desc.mFormat.mSampleRate == m_initformat.m_sampleRate )
          {
            outputFormat = desc.mFormat; // Select this format
            m_OutputBufferIndex = streamIndex;
            outputStream = stream.GetId();
            break;
          }
        }
      }
      physicalFormats.pop_front();
    }

    // TODO: How do we determine if this is the right stream (not just the right format) to use?
    if (outputFormat.mFormatID)
      break; // We found a suitable format. No need to continue.
    streamIndex++;
  }

  if (!outputFormat.mFormatID) // No match found
  {
    CLog::Log(LOGDEBUG, "CCoreAudioAEHALOSX::InitializeEncoded: "
      "Unable to identify suitable output format.");
    return false;
  }

  CLog::Log(LOGDEBUG, "CCoreAudioAEHALOSX::InitializeEncoded: "
    "Selected stream[%u] - id: 0x%04X, Physical Format: %s",
    m_OutputBufferIndex, (uint)outputStream, StreamDescriptionToString(outputFormat, formatString));

  // TODO: Auto hogging sets this for us. Figure out how/when to turn it off or use it
  // It appears that leaving this set will aslo restore the previous stream format when the
  // Application exits. If auto hogging is set and we try to set hog mode, we will deadlock
  // From the SDK docs: "If the AudioDevice is in a non-mixable mode, the HAL will automatically take hog mode on behalf of the first process to start an IOProc."

  // Lock down the device.  This MUST be done PRIOR to switching to a non-mixable format, if it is done at all
  // If it is attempted after the format change, there is a high likelihood of a deadlock
  // We may need to do this sooner to enable mix-disable (i.e. before setting the stream format)

  // Auto-Hog does not always un-hog the device when changing back to a mixable mode.
  // Handle this on our own until it is fixed.
  CCoreAudioHardware::SetAutoHogMode(false);
  bool autoHog = CCoreAudioHardware::GetAutoHogMode();
  CLog::Log(LOGDEBUG, " CoreAudioRenderer::InitializeEncoded: "
    "Auto 'hog' mode is set to '%s'.", autoHog ? "On" : "Off");
  if (!autoHog) // Try to handle this ourselves
  {
    // Hog the device if it is not set to be done automatically
    m_AudioDevice->SetHogStatus(true);
    // Try to disable mixing. If we cannot, it may not be a problem
    m_AudioDevice->SetMixingSupport(false);
  }

  m_NumLatencyFrames = m_AudioDevice->GetNumLatencyFrames();

  // Configure the output stream object, this is the one we will keep
  m_OutputStream->Open(outputStream);

  AudioStreamBasicDescription virtualFormat;
  m_OutputStream->GetVirtualFormat(&virtualFormat);
  CLog::Log(LOGDEBUG, "CCoreAudioAEHALOSX::InitializeEncoded: "
    "Previous Virtual Format: %s", StreamDescriptionToString(virtualFormat, formatString));

  AudioStreamBasicDescription previousPhysicalFormat;
  m_OutputStream->GetPhysicalFormat(&previousPhysicalFormat);
  CLog::Log(LOGDEBUG, "CCoreAudioAEHALOSX::InitializeEncoded: "
    "Previous Physical Format: %s", StreamDescriptionToString(previousPhysicalFormat, formatString));

  // Set the active format (the old one will be reverted when we close)
  m_OutputStream->SetPhysicalFormat(&outputFormat);
  m_NumLatencyFrames += m_OutputStream->GetNumLatencyFrames();

  m_OutputStream->GetVirtualFormat(&virtualFormat);
  CLog::Log(LOGDEBUG, "CCoreAudioAEHALOSX::InitializeEncoded: "
    "New Virtual Format: %s", StreamDescriptionToString(virtualFormat, formatString));
  CLog::Log(LOGDEBUG, "CCoreAudioAEHALOSX::InitializeEncoded: "
    "New Physical Format: %s", StreamDescriptionToString(outputFormat, formatString));

  m_allowMixing = false;

  return true;
}