Skip to content
This repository
Browse code

Merge pull request #2081 from popcornmix/mixer_volume

[rbp] Apply volume control at audio_mixer when possible
  • Loading branch information...
commit 99a536c4670690758da512e2434a88abc3259ed8 2 parents ae2fcc6 + 453e2b2
huceke authored January 16, 2013

Showing 1 changed file with 78 additions and 27 deletions. Show diff stats Hide diff stats

  1. 105  xbmc/cores/omxplayer/OMXAudio.cpp
105  xbmc/cores/omxplayer/OMXAudio.cpp
@@ -37,10 +37,6 @@
37 37
 #include "guilib/LocalizeStrings.h"
38 38
 #include "cores/AudioEngine/Utils/AEConvert.h"
39 39
 
40  
-#ifndef VOLUME_MINIMUM
41  
-#define VOLUME_MINIMUM -6000  // -60dB
42  
-#endif
43  
-
44 40
 using namespace std;
45 41
 
46 42
 #define OMX_MAX_CHANNELS 10
@@ -77,6 +73,19 @@ static const uint16_t AC3FSCod   [] = {48000, 44100, 32000, 0};
77 73
 
78 74
 static const uint16_t DTSFSCod   [] = {0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0, 12000, 24000, 48000, 0, 0};
79 75
 
  76
+// 7.1 downmixing coefficients
  77
+const float downmixing_coefficients_8[OMX_AUDIO_MAXCHANNELS] = {
  78
+  //        L       R
  79
+  /* L */   1,      0,
  80
+  /* R */   0,      1,
  81
+  /* C */   0.7071, 0.7071,
  82
+  /* LFE */ 0.7071, 0.7071,
  83
+  /* Ls */  0.7071, 0,
  84
+  /* Rs */  0,      0.7071,
  85
+  /* Lr */  0.7071, 0,
  86
+  /* Rr */  0,      0.7071
  87
+};
  88
+
80 89
 //////////////////////////////////////////////////////////////////////
81 90
 // Construction/Destruction
82 91
 //////////////////////////////////////////////////////////////////////
@@ -198,8 +207,6 @@ bool COMXAudio::Initialize(AEAudioFormat format, std::string& device, OMXClock *
198 207
 
199 208
   m_drc         = 0;
200 209
 
201  
-  m_CurrentVolume = g_settings.m_fVolumeLevel; 
202  
-
203 210
   memset(m_input_channels, 0x0, sizeof(m_input_channels));
204 211
   memset(m_output_channels, 0x0, sizeof(m_output_channels));
205 212
   memset(&m_wave_header, 0x0, sizeof(m_wave_header));
@@ -545,8 +552,6 @@ bool COMXAudio::Initialize(AEAudioFormat format, std::string& device, OMXClock *
545 552
   m_first_frame   = true;
546 553
   m_last_pts      = DVD_NOPTS_VALUE;
547 554
 
548  
-  SetCurrentVolume(m_CurrentVolume);
549  
-
550 555
   CLog::Log(LOGDEBUG, "COMXAudio::Initialize Ouput bps %d samplerate %d channels %d buffer size %d bytes per second %d", 
551 556
       (int)m_pcm_output.nBitPerSample, (int)m_pcm_output.nSamplingRate, (int)m_pcm_output.nChannels, m_BufferLen, m_BytesPerSec);
552 557
   CLog::Log(LOGDEBUG, "COMXAudio::Initialize Input bps %d samplerate %d channels %d buffer size %d bytes per second %d", 
@@ -694,20 +699,76 @@ bool COMXAudio::SetCurrentVolume(float fVolume)
694 699
   CSingleLock lock (m_critSection);
695 700
 
696 701
   if(!m_Initialized || m_Passthrough)
697  
-    return -1;
698  
-
  702
+    return false;
  703
+  double gain = pow(10, (g_advancedSettings.m_ac3Gain - 12.0f) / 20.0);
699 704
   m_CurrentVolume = fVolume;
700 705
 
701  
-  OMX_AUDIO_CONFIG_VOLUMETYPE volume;
702  
-  OMX_INIT_STRUCTURE(volume);
703  
-  volume.nPortIndex = m_omx_render->GetInputPort();
  706
+  if (m_format.m_channelLayout.Count() > 2)
  707
+  {
  708
+    double r = fVolume;
  709
+    const float* coeff = downmixing_coefficients_8;
  710
+    int input_channels = 0;
  711
+
  712
+    // normally we normalalise the levels, can be skipped (boosted) at risk of distortion
  713
+    if(!g_guiSettings.GetBool("audiooutput.normalizelevels"))
  714
+    {
  715
+      double sum_L = 0;
  716
+      double sum_R = 0;
  717
+
  718
+      for(size_t i = 0; i < OMX_AUDIO_MAXCHANNELS; ++i)
  719
+      {
  720
+        if (m_input_channels[i] == OMX_AUDIO_ChannelMax)
  721
+          break;
  722
+        if(i & 1)
  723
+          sum_R += coeff[i];
  724
+        else
  725
+          sum_L += coeff[i];
  726
+      }
  727
+
  728
+      r /= max(sum_L, sum_R);
  729
+    }
  730
+
  731
+    // the analogue volume is too quiet for some. Allow use of an advancedsetting to boost this (at risk of distortion)
  732
+    r *= gain;
704 733
 
705  
-  volume.bLinear    = OMX_TRUE;
706  
-  float hardwareVolume = std::max(VOLUME_MINIMUM, std::min(VOLUME_MAXIMUM, fVolume)) * 100.0f;
707  
-  volume.sVolume.nValue = (int)hardwareVolume;
  734
+    OMX_CONFIG_BRCMAUDIODOWNMIXCOEFFICIENTS mix;
  735
+    OMX_INIT_STRUCTURE(mix);
  736
+    mix.nPortIndex = m_omx_mixer.GetInputPort();
708 737
 
709  
-  m_omx_render->SetConfig(OMX_IndexConfigAudioVolume, &volume);
  738
+    assert(sizeof(mix.coeff)/sizeof(mix.coeff[0]) == 16);
710 739
 
  740
+    for(size_t i = 0; i < 16; ++i)
  741
+      mix.coeff[i] = static_cast<unsigned int>(0x10000 * (coeff[i] * r));
  742
+
  743
+    OMX_ERRORTYPE omx_err =
  744
+      m_omx_mixer.SetConfig(OMX_IndexConfigBrcmAudioDownmixCoefficients, &mix);
  745
+
  746
+    if(omx_err != OMX_ErrorNone)
  747
+    {
  748
+      CLog::Log(LOGERROR, "%s::%s - error setting OMX_IndexConfigBrcmAudioDownmixCoefficients, error 0x%08x\n",
  749
+                CLASSNAME, __func__, omx_err);
  750
+      return false;
  751
+    }
  752
+  }
  753
+  else
  754
+  {
  755
+    OMX_AUDIO_CONFIG_VOLUMETYPE volume;
  756
+    OMX_INIT_STRUCTURE(volume);
  757
+    volume.nPortIndex = m_omx_render->GetInputPort();
  758
+
  759
+    volume.bLinear    = OMX_TRUE;
  760
+    float hardwareVolume = fVolume * gain * 100.0f;
  761
+    volume.sVolume.nValue = (int)(hardwareVolume + 0.5f);
  762
+
  763
+    OMX_ERRORTYPE omx_err =
  764
+      m_omx_render->SetConfig(OMX_IndexConfigAudioVolume, &volume);
  765
+    if(omx_err != OMX_ErrorNone)
  766
+    {
  767
+      CLog::Log(LOGERROR, "%s::%s - error setting OMX_IndexConfigAudioVolume, error 0x%08x\n",
  768
+                CLASSNAME, __func__, omx_err);
  769
+      return false;
  770
+    }
  771
+  }  
711 772
   return true;
712 773
 }
713 774
 
@@ -885,16 +946,6 @@ unsigned int COMXAudio::AddPackets(const void* data, unsigned int len, double dt
885 946
           }
886 947
         }
887 948
 
888  
-        if ((m_pcm_input.nChannels > m_pcm_output.nChannels) &&g_guiSettings.GetBool("audiooutput.normalizelevels"))
889  
-        {
890  
-          OMX_AUDIO_CONFIG_VOLUMETYPE volume;
891  
-          OMX_INIT_STRUCTURE(volume);
892  
-          volume.nPortIndex = m_omx_mixer.GetInputPort();
893  
-          volume.bLinear    = OMX_FALSE;
894  
-          volume.sVolume.nValue = (int)(g_advancedSettings.m_ac3Gain*100.0f+0.5f);
895  
-          m_omx_mixer.SetConfig(OMX_IndexConfigAudioVolume, &volume);
896  
-        }
897  
-
898 949
         memcpy(m_pcm_input.eChannelMapping, m_input_channels, sizeof(m_input_channels));
899 950
         m_pcm_input.nSamplingRate = m_format.m_sampleRate;
900 951
 

0 notes on commit 99a536c

Please sign in to comment.
Something went wrong with that request. Please try again.