Exemple #1
0
/* sets the input format, and returns the requested channel layout */
enum PCMChannels *CPCMRemap::SetInputFormat(unsigned int channels, enum PCMChannels *channelMap, unsigned int sampleSize, unsigned int sampleRate)
{
  m_inChannels   = channels;
  m_inSampleSize = sampleSize;
  m_sampleRate   = (float)sampleRate;
  m_inSet        = channelMap != NULL;
  if (channelMap)
    memcpy(m_inMap, channelMap, sizeof(enum PCMChannels) * channels);

  /* fix me later */
  assert(sampleSize == 2);

  /* get the audio layout, and count the channels in it */
  if (!m_bAudio2)
    m_channelLayout  = (enum PCMLayout)g_guiSettings.GetInt("audiooutput.channellayout");
  else
    m_channelLayout  = (enum PCMLayout)g_guiSettings.GetInt("audiooutput2.channellayout");
  if (m_channelLayout >= PCM_MAX_LAYOUT) m_channelLayout = PCM_LAYOUT_2_0;

  //spdif only has 2 pcm channels, so don't try to use more
  if (g_guiSettings.GetInt("audiooutput.mode") == AUDIO_IEC958)
  {
    CLog::Log(LOGINFO, "CPCMRemap: Configured speaker layout: %s (iec958)\n", PCMLayoutStr(m_channelLayout).c_str());
    m_channelLayout = PCM_LAYOUT_2_0;
  }
  else
    CLog::Log(LOGINFO, "CPCMRemap: Configured speaker layout: %s\n", PCMLayoutStr(m_channelLayout).c_str());

  
  DumpMap("I", channels, channelMap);
  BuildMap();

  /* now remove the empty channels from PCMLayoutMap;
   * we don't perform upmixing so we want the minimum amount of those */
  if (channelMap) {
    if (!m_outSet)
      ResolveChannels(); /* Do basic channel resolving to find out the empty channels;
                          * If m_outSet == true, this was done already by BuildMap() above */
    int i = 0;
    for (enum PCMChannels *chan = PCMLayoutMap[m_channelLayout]; *chan != PCM_INVALID; ++chan)
      if (m_lookupMap[*chan][0].channel != PCM_INVALID) {
        /* something is mapped here, so add the channel */
        m_layoutMap[i++] = *chan;
      }
    m_layoutMap[i] = PCM_INVALID;
  } else
    memcpy(m_layoutMap, PCMLayoutMap[m_channelLayout], sizeof(PCMLayoutMap[m_channelLayout]));

  m_attenuation = 1.0;
  m_attenuationInc = 1.0;
  m_holdCounter = 0;

  return m_layoutMap;
}
Exemple #2
0
void KickPrefetchChannels(const struct NaClApp *nap)
{
  int i;

  /* quietly return if no name service specified */
  if(!NameServiceSet()) return;

  assert(nap != NULL);
  assert(nap->system_manifest != NULL);

  /* exchange channel information with the name server */
  ResolveChannels(nap, binds, connects);

  /* make connections */
  for(i = 0; i < nap->system_manifest->channels_count; ++i)
  {
    int result;
    struct ChannelDesc *channel = &nap->system_manifest->channels[i];
    struct ChannelConnection *record;

    assert(channel != NULL);

    /* skip all channels except the network "connect" ones */
    if(channel->source != ChannelTCP) continue;

    /* get the channel connection information */
    record = GetChannelConnectionInfo(channel);
    assert(record != NULL);

    /* only the "connect" channels need to be processed */
    if(record->mark != CONNECT_MARK) continue;

    /* bind or connect the channel and look at result */
    result = DoConnect(channel);
    ZLOGFAIL(result != 0, EFAULT, "cannot connect socket to %s", channel->alias);
  }

  /*
   * temporary fix (the lost 1st messsage) to allow 0mq to complete
   * the connection procedure. 1 millisecond should be enough
   * todo(d'b): replace it with the channels readiness check
   */
  usleep(PREPOLL_WAIT);
}
Exemple #3
0
/* sets the input format, and returns the requested channel layout */
enum PCMChannels *CPCMRemap::SetInputFormat(unsigned int channels, enum PCMChannels *channelMap, unsigned int sampleSize, unsigned int sampleRate, PCMLayout layout)
{
  m_inChannels   = channels;
  m_inSampleSize = sampleSize;
  m_sampleRate   = sampleRate;
  m_inSet        = channelMap != NULL;
  if (channelMap)
    memcpy(m_inMap, channelMap, sizeof(enum PCMChannels) * channels);

  /* get the audio layout, and count the channels in it */
  m_channelLayout  = layout;
  if (m_channelLayout >= PCM_MAX_LAYOUT) m_channelLayout = PCM_LAYOUT_2_0;


  DumpMap("I", channels, channelMap);
  BuildMap();

  /* now remove the empty channels from PCMLayoutMap;
   * we don't perform upmixing so we want the minimum amount of those */
  if (channelMap) {
    if (!m_outSet)
      ResolveChannels(); /* Do basic channel resolving to find out the empty channels;
                          * If m_outSet == true, this was done already by BuildMap() above */
    int i = 0;
    for (enum PCMChannels *chan = PCMLayoutMap[m_channelLayout]; *chan != PCM_INVALID; ++chan)
      if (m_lookupMap[*chan][0].channel != PCM_INVALID) {
        /* something is mapped here, so add the channel */
        m_layoutMap[i++] = *chan;
      }
    m_layoutMap[i] = PCM_INVALID;
  } else
    memcpy(m_layoutMap, PCMLayoutMap[m_channelLayout], sizeof(PCMLayoutMap[m_channelLayout]));

  m_attenuation = 1.0;
  m_attenuationInc = 1.0;
  m_holdCounter = 0;

  return m_layoutMap;
}
Exemple #4
0
/*
  builds a lookup table to convert from the input mapping to the output
  mapping, this decreases the amount of work per sample to remap it.
*/
void CPCMRemap::BuildMap()
{
  struct PCMMapInfo *dst;
  unsigned int out_ch;

  if (!m_inSet || !m_outSet) return;

  m_inStride  = m_inSampleSize * m_inChannels ;
  m_outStride = m_inSampleSize * m_outChannels;

  /* see if we need to normalize the levels */
  bool dontnormalize = g_guiSettings.GetBool("audiooutput.dontnormalizelevels");
  CLog::Log(LOGDEBUG, "CPCMRemap: Downmix normalization is %s", (dontnormalize ? "disabled" : "enabled"));

  ResolveChannels();

  /* convert the levels into RMS values */
  float loudest    = 0.0;
  bool  hasLoudest = false;

  for(out_ch = 0; out_ch < m_outChannels; ++out_ch)
  {
    float scale = 0;
    int count = 0;
    for(dst = m_lookupMap[m_outMap[out_ch]]; dst->channel != PCM_INVALID; ++dst)
    {
      dst->copy  = false;
      dst->level = dst->level / sqrt((float)m_counts[dst->channel]);
      scale     += dst->level;
      ++count;
    }

    /* if there is only 1 channel to mix, and the level is 1.0, then just copy the channel */
    dst = m_lookupMap[m_outMap[out_ch]];
    if (count == 1 && dst->level > 0.99 && dst->level < 1.01)
      dst->copy = true;
    
    /* normalize the levels if it is turned on */
    if (!dontnormalize)
      for(dst = m_lookupMap[m_outMap[out_ch]]; dst->channel != PCM_INVALID; ++dst)
      {
        dst->level /= scale;
        /* find the loudest output level we have that is not 1-1 */
        if (dst->level < 1.0 && loudest < dst->level)
        {
          loudest    = dst->level;
          hasLoudest = true;
        }
      }
  }
  
  /* adjust the channels that are too loud */
  for(out_ch = 0; out_ch < m_outChannels; ++out_ch)
  {
    CStdString s = "", f;
    for(dst = m_lookupMap[m_outMap[out_ch]]; dst->channel != PCM_INVALID; ++dst)
    {
      if (hasLoudest && dst->copy)
      {
        dst->level = loudest;
        dst->copy  = false;
      }

      f.Format("%s(%f%s) ",  PCMChannelStr(dst->channel).c_str(), dst->level, dst->copy ? "*" : "");
      s += f;
    }
    CLog::Log(LOGDEBUG, "CPCMRemap: %s = %s\n", PCMChannelStr(m_outMap[out_ch]).c_str(), s.c_str());
  }
}