Esempio n. 1
0
bool CAudioDecoder::Init(const CFileItem& file, unsigned int filecache)
{
  if (!Initialized())
    return false;

  // for replaygain
  CTagLoaderTagLib tag;
  tag.Load(file.GetPath(), XFILE::CMusicFileDirectory::m_tag, NULL);

  int channels;
  int sampleRate;

  m_context = m_struct.toAddon.Init(file.GetPath().c_str(), filecache,
                              &channels, &sampleRate,
                              &m_bitsPerSample, &m_TotalTime,
                              &m_bitRate, &m_format.m_dataFormat, &m_channel);

  m_format.m_sampleRate = sampleRate;
  if (m_channel)
    m_format.m_channelLayout = CAEChannelInfo(m_channel);
  else
    m_format.m_channelLayout = CAEUtil::GuessChLayout(channels);

  return (m_context != NULL);
}
Esempio n. 2
0
CAEChannelInfo CDVDAudioCodecLibMad::GetChannelMap()
{
    assert(m_iSourceChannels > 0 && m_iSourceChannels < 3);

    static enum AEChannel map[2][3] = {
        {AE_CH_FC, AE_CH_NULL},
        {AE_CH_FL, AE_CH_FR, AE_CH_NULL}
    };

    return CAEChannelInfo(map[m_iSourceChannels -1]);
}
Esempio n. 3
0
CAEChannelInfo SIDCodec::GetChannelInfo()
{
  static enum AEChannel map[1][2] = {
    {AE_CH_FC, AE_CH_NULL}
  };

  if (m_Channels > 1)
    return CAEUtil::GuessChLayout(m_Channels);

  return CAEChannelInfo(map[m_Channels - 1]);
}
Esempio n. 4
0
CAEChannelInfo CDDACodec::GetChannelInfo()
{
    static enum AEChannel map[2][3] = {
        {AE_CH_FC, AE_CH_NULL},
        {AE_CH_FL, AE_CH_FR  , AE_CH_NULL}
    };

    if (m_Channels > 2)
        return CAEUtil::GuessChLayout(m_Channels);

    return CAEChannelInfo(map[m_Channels - 1]);
}
Esempio n. 5
0
  CAEChannelInfo Codec::GetChannelInfo()
  {
    static enum AEChannel map[2][3] = {
      {AE_CH_FC, AE_CH_NULL},
      {AE_CH_FL, AE_CH_FR  , AE_CH_NULL}
    };

    if (m_Channels > 2) {
	  Logger::printOut("m_Channels is bigger than 2, please fix code, I can´t return a valid AEChannel map");
//    return CAEUtil::GuessChLayout(m_Channels);
    }

  return CAEChannelInfo(map[m_Channels - 1]);
  }
Esempio n. 6
0
CAEChannelInfo OGGCodec::GetChannelInfo()
{
  static enum AEChannel map[8][9] = {
    {AE_CH_FC, AE_CH_NULL},
    {AE_CH_FL, AE_CH_FR, AE_CH_NULL},
    {AE_CH_FL, AE_CH_FC, AE_CH_FR, AE_CH_NULL},
    {AE_CH_FL, AE_CH_FR, AE_CH_BL, AE_CH_BR, AE_CH_NULL},
    {AE_CH_FL, AE_CH_FC, AE_CH_FR, AE_CH_BL, AE_CH_BR, AE_CH_NULL},
    {AE_CH_FL, AE_CH_FC, AE_CH_FR, AE_CH_BL, AE_CH_BR, AE_CH_LFE, AE_CH_NULL},
    {AE_CH_FL, AE_CH_FC, AE_CH_FR, AE_CH_SL, AE_CH_SR, AE_CH_BL, AE_CH_BR, AE_CH_NULL},
    {AE_CH_FL, AE_CH_FC, AE_CH_FR, AE_CH_SL, AE_CH_SR, AE_CH_BL, AE_CH_BR, AE_CH_LFE, AE_CH_NULL}
  };

  if (m_Channels > 8)
    return CAEUtil::GuessChLayout(m_Channels);

  return CAEChannelInfo(map[m_Channels - 1]);
}
Esempio n. 7
0
bool CCoreAudioAE::OpenCoreAudio(unsigned int sampleRate, bool forceRaw,
  enum AEDataFormat rawDataFormat)
{

  // remove any deleted streams
  CSingleLock streamLock(m_streamLock);
  for (StreamList::iterator itt = m_streams.begin(); itt != m_streams.end();)
  {
    CCoreAudioAEStream *stream = *itt;
    if (stream->IsDestroyed())
    {
      itt = m_streams.erase(itt);
      delete stream;
      continue;
    }
    else
    {
      // close all converter
      stream->CloseConverter();
    }
    ++itt;
  }

  /* override the sample rate based on the oldest stream if there is one */
  if (!m_streams.empty())
    sampleRate = m_streams.front()->GetSampleRate();

  if (forceRaw)
    m_rawPassthrough = true;
  else
    m_rawPassthrough = !m_streams.empty() && m_streams.front()->IsRaw();
  streamLock.Leave();
    
  if (m_rawPassthrough)
    CLog::Log(LOGINFO, "CCoreAudioAE::OpenCoreAudio - RAW passthrough enabled");

  std::string m_outputDevice =  g_guiSettings.GetString("audiooutput.audiodevice");

  // on iOS devices we set fixed to two channels.
  m_stdChLayout = AE_CH_LAYOUT_2_0;
#if defined(TARGET_DARWIN_OSX)
  switch (g_guiSettings.GetInt("audiooutput.channels"))
  {
    default:
    case  0: m_stdChLayout = AE_CH_LAYOUT_2_0; break; /* do not allow 1_0 output */
    case  1: m_stdChLayout = AE_CH_LAYOUT_2_0; break;
    case  2: m_stdChLayout = AE_CH_LAYOUT_2_1; break;
    case  3: m_stdChLayout = AE_CH_LAYOUT_3_0; break;
    case  4: m_stdChLayout = AE_CH_LAYOUT_3_1; break;
    case  5: m_stdChLayout = AE_CH_LAYOUT_4_0; break;
    case  6: m_stdChLayout = AE_CH_LAYOUT_4_1; break;
    case  7: m_stdChLayout = AE_CH_LAYOUT_5_0; break;
    case  8: m_stdChLayout = AE_CH_LAYOUT_5_1; break;
    case  9: m_stdChLayout = AE_CH_LAYOUT_7_0; break;
    case 10: m_stdChLayout = AE_CH_LAYOUT_7_1; break;
  }
#endif
  // force optical/coax to 2.0 output channels
  if (!m_rawPassthrough && g_guiSettings.GetInt("audiooutput.mode") == AUDIO_IEC958)
    m_stdChLayout = AE_CH_LAYOUT_2_0;

  // setup the desired format
  m_format.m_channelLayout = CAEChannelInfo(m_stdChLayout);

  // if there is an audio resample rate set, use it.
  if (g_advancedSettings.m_audioResample && !m_rawPassthrough)
  {
    sampleRate = g_advancedSettings.m_audioResample;
    CLog::Log(LOGINFO, "CCoreAudioAE::passthrough - Forcing samplerate to %d", sampleRate);
  }

  if (m_rawPassthrough)
  {
    switch (rawDataFormat)
    {
      case AE_FMT_AC3:
      case AE_FMT_DTS:
        m_format.m_channelLayout = CAEChannelInfo(AE_CH_LAYOUT_2_0);
        m_format.m_sampleRate   = 48000;
        m_format.m_dataFormat   = AE_FMT_S16NE;
        break;
      case AE_FMT_EAC3:
        m_format.m_channelLayout = CAEChannelInfo(AE_CH_LAYOUT_2_0);
        m_format.m_sampleRate   = 192000;
        m_format.m_dataFormat   = AE_FMT_S16NE;
        break;
      case AE_FMT_DTSHD:
      case AE_FMT_TRUEHD:
        m_format.m_channelLayout = CAEChannelInfo(AE_CH_LAYOUT_7_1);
        m_format.m_sampleRate   = 192000;
        m_format.m_dataFormat   = AE_FMT_S16NE;
        break;
      case AE_FMT_LPCM:
        m_format.m_channelLayout = CAEChannelInfo(AE_CH_LAYOUT_7_1);
        m_format.m_sampleRate   = sampleRate;
        m_format.m_dataFormat   = AE_FMT_FLOAT;
        break;
      default:
        break;
    }
  }
  else
  {
    m_format.m_sampleRate       = sampleRate;
    m_format.m_channelLayout    = CAEChannelInfo(m_stdChLayout);
    m_format.m_dataFormat       = AE_FMT_FLOAT;
  }

  m_format.m_encodedRate = 0;

  if (m_outputDevice.empty())
    m_outputDevice = "default";

  AEAudioFormat initformat = m_format;

  // initialize audio hardware
  m_Initialized = HAL->Initialize(this, m_rawPassthrough, initformat, rawDataFormat, m_outputDevice, m_volume);

  unsigned int bps         = CAEUtil::DataFormatToBits(m_format.m_dataFormat);
  m_chLayoutCount          = m_format.m_channelLayout.Count();
  m_format.m_frameSize     = (bps>>3) * m_chLayoutCount; //initformat.m_frameSize;
  //m_format.m_frames        = (unsigned int)(((float)m_format.m_sampleRate / 1000.0f) * (float)DELAY_FRAME_TIME);
  //m_format.m_frameSamples  = m_format.m_frames * m_format.m_channelLayout.Count();

  if ((initformat.m_channelLayout.Count() != m_chLayoutCount) && !m_rawPassthrough)
  {
    /* readjust parameters. hardware didn't accept channel count*/
    CLog::Log(LOGINFO, "CCoreAudioAE::Initialize: Setup channels (%d) greater than possible hardware channels (%d).",
              m_chLayoutCount, initformat.m_channelLayout.Count());

    m_format.m_channelLayout = CAEChannelInfo(initformat.m_channelLayout);
    m_chLayoutCount          = m_format.m_channelLayout.Count();
    m_format.m_frameSize     = (bps>>3) * m_chLayoutCount; //initformat.m_frameSize;
    //m_format.m_frameSamples  = m_format.m_frames * m_format.m_channelLayout.Count();
  }
Esempio n. 8
0
static void SinkInfoRequestCallback(pa_context *c, const pa_sink_info *i, int eol, void *userdata)
{

  SinkInfoStruct *sinkStruct = (SinkInfoStruct *)userdata;
  if (!sinkStruct)
    return;

  if(sinkStruct->list->empty())
  {
    //add a default device first
    CAEDeviceInfo defaultDevice;
    defaultDevice.m_deviceName = std::string("Default");
    defaultDevice.m_displayName = std::string("Default");
    defaultDevice.m_displayNameExtra = std::string("Default Output Device (PULSEAUDIO)");
    defaultDevice.m_dataFormats.insert(defaultDevice.m_dataFormats.end(), defaultDataFormats, defaultDataFormats + ARRAY_SIZE(defaultDataFormats));
    defaultDevice.m_channels = CAEChannelInfo(AE_CH_LAYOUT_2_0);
    defaultDevice.m_sampleRates.assign(defaultSampleRates, defaultSampleRates + ARRAY_SIZE(defaultSampleRates));
    defaultDevice.m_deviceType = AE_DEVTYPE_PCM;
    sinkStruct->list->push_back(defaultDevice);
  }
  if (i && i->name)
  {
    CAEDeviceInfo device;
    bool valid = true;
    device.m_deviceName = std::string(i->name);
    device.m_displayName = std::string(i->description);
    if (i->active_port && i->active_port->description)
      device.m_displayNameExtra = std::string((i->active_port->description)).append(" (PULSEAUDIO)");
    else
      device.m_displayNameExtra = std::string((i->description)).append(" (PULSEAUDIO)");
    unsigned int device_type = AE_DEVTYPE_PCM; //0

    device.m_channels = PAChannelToAEChannelMap(i->channel_map);

    // Don't add devices that would not have a channel map
    if(device.m_channels.Count() == 0)
      valid = false;

    device.m_sampleRates.assign(defaultSampleRates, defaultSampleRates + ARRAY_SIZE(defaultSampleRates));

    for (unsigned int j = 0; j < i->n_formats; j++)
    {
      switch(i->formats[j]->encoding)
      {
        case PA_ENCODING_AC3_IEC61937:
          device.m_dataFormats.push_back(AE_FMT_AC3);
          device_type = AE_DEVTYPE_IEC958;
          break;
        case PA_ENCODING_DTS_IEC61937:
          device.m_dataFormats.push_back(AE_FMT_DTS);
          device_type = AE_DEVTYPE_IEC958;
          break;
        case PA_ENCODING_EAC3_IEC61937:
          device.m_dataFormats.push_back(AE_FMT_EAC3);
          device_type = AE_DEVTYPE_IEC958;
          break;
        case PA_ENCODING_PCM:
          device.m_dataFormats.insert(device.m_dataFormats.end(), defaultDataFormats, defaultDataFormats + ARRAY_SIZE(defaultDataFormats));
          break;
        default:
          break;
      }
    }
    // passthrough is only working when device has Stereo channel config
    if (device_type > AE_DEVTYPE_PCM && device.m_channels.Count() == 2)
      device.m_deviceType = AE_DEVTYPE_IEC958;
    else
      device.m_deviceType = AE_DEVTYPE_PCM;
    if(valid)
    {
      CLog::Log(LOGDEBUG, "PulseAudio: Found %s with devicestring %s", device.m_displayName.c_str(), device.m_deviceName.c_str());
      sinkStruct->list->push_back(device);
    }
    else
    {
      CLog::Log(LOGDEBUG, "PulseAudio: Skipped %s with devicestring %s", device.m_displayName.c_str(), device.m_deviceName.c_str());
    }
  }
  pa_threaded_mainloop_signal(sinkStruct->mainloop, 0);
}