Merge pull request #4955 from Memphiz/osxfixoptical2
[vuplus_xbmc] / xbmc / cores / AudioEngine / Sinks / AESinkDARWINOSX.cpp
index a6006c6..d390368 100644 (file)
@@ -438,6 +438,10 @@ static void EnumerateDevices(CADeviceList &list)
       }
       else// treat all other digital passthrough devices as optical
         device.m_deviceType = AE_DEVTYPE_IEC958;
+
+      //treat all other digital devices as HDMI to let options open to the user
+      if (device.m_deviceType == AE_DEVTYPE_PCM)
+        device.m_deviceType = AE_DEVTYPE_HDMI;
     }
 
     // devicename based overwrites from former code - maybe FIXME at some point when we
@@ -589,6 +593,19 @@ CAESinkDARWINOSX::~CAESinkDARWINOSX()
   RegisterDeviceChangedCB(false, this);
 }
 
+float scoreSampleRate(Float64 destinationRate, unsigned int sourceRate)
+{
+  float score = 0;
+  double intPortion;
+  double fracPortion = modf(destinationRate / sourceRate, &intPortion);
+
+  score += (1 - fracPortion) * 1000;      // prefer sample rates that are multiples of the source sample rate
+  score += (intPortion == 1.0) ? 500 : 0;   // prefer exact matches over other multiples
+  score += (intPortion > 1 && intPortion < 100) ? (100 - intPortion) / 100 * 100 : 0; // prefer smaller multiples otherwise
+
+  return score;
+}
+
 float ScoreStream(const AudioStreamBasicDescription &desc, const AEAudioFormat &format)
 {
   float score = 0;
@@ -624,10 +641,8 @@ float ScoreStream(const AudioStreamBasicDescription &desc, const AEAudioFormat &
   { // non-passthrough, whatever works is fine
     if (desc.mFormatID == kAudioFormatLinearPCM)
     {
-      if (desc.mSampleRate == format.m_sampleRate)
-        score += 10;
-      else if (desc.mSampleRate > format.m_sampleRate)
-        score += 1;
+      score += scoreSampleRate(desc.mSampleRate, format.m_sampleRate);
+
       if (desc.mChannelsPerFrame == format.m_channelLayout.Count())
         score += 5;
       else if (desc.mChannelsPerFrame > format.m_channelLayout.Count())
@@ -687,6 +702,7 @@ bool CAESinkDARWINOSX::Initialize(AEAudioFormat &format, std::string &device)
 
   bool                        passthrough  = false;
   UInt32                      outputIndex  = 0;
+  UInt32                      numOutputChannels = 0;
   float                       outputScore  = 0;
   AudioStreamBasicDescription outputFormat = {0};
   AudioStreamID               outputStream = 0;
@@ -721,7 +737,7 @@ bool CAESinkDARWINOSX::Initialize(AEAudioFormat &format, std::string &device)
 
       if (score > outputScore)
       {
-        passthrough  = score > 1000;
+        passthrough  = score > 10000;
         outputScore  = score;
         outputFormat = desc;
         outputStream = *i;
@@ -732,11 +748,12 @@ bool CAESinkDARWINOSX::Initialize(AEAudioFormat &format, std::string &device)
   }
 
   m_planar = false;
+  numOutputChannels = outputFormat.mChannelsPerFrame;
   if (streams.size() > 1 && outputFormat.mChannelsPerFrame == 1)
   {
-    CLog::Log(LOGDEBUG, "%s Found planar audio with %u channels?", __FUNCTION__, streams.size());
-    outputFormat.mChannelsPerFrame = std::min((size_t)format.m_channelLayout.Count(), streams.size());
+    numOutputChannels = std::min((size_t)format.m_channelLayout.Count(), streams.size());
     m_planar = true;
+    CLog::Log(LOGDEBUG, "%s Found planar audio with %u channels using %u of them.", __FUNCTION__, (unsigned int)streams.size(), (unsigned int)numOutputChannels);
   }
 
   if (!outputFormat.mFormatID)
@@ -770,7 +787,7 @@ bool CAESinkDARWINOSX::Initialize(AEAudioFormat &format, std::string &device)
   CLog::Log(LOGDEBUG, "%s: New Physical Format: %s", __FUNCTION__, StreamDescriptionToString(outputFormat, formatString));
 
   // update the channel map based on the new stream format
-  GetAEChannelMap(m_device, format.m_channelLayout, outputFormat.mChannelsPerFrame);
+  GetAEChannelMap(m_device, format.m_channelLayout, numOutputChannels);
 
 
   m_latentFrames = m_device.GetNumLatencyFrames();