summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYue Wang <Wang-Yue@users.noreply.github.com>2018-08-07 01:55:06 -0700
committerGitHub <noreply@github.com>2018-08-07 01:55:06 -0700
commit2127a482da8531980bb7e931a507505532f92c65 (patch)
tree7becb2384009e24707efbe04d031d5f64c1798ef
parent7df0d3b7fc581ee63102a70baa19d3919a28a624 (diff)
Fix various bugs in OS X DSD playback
the most notable bugs are 1. osx_output_set_device_format should use the target asbd rather than AudioFormat. This is because asbd's sample rate calculation reflects the real dop target rate of the DAC, white AudioFormat's sample rate is the original DSD format rate. 2. the original code value the highest rate that's the multiple of the target rate. This cause DOP always have the wrong rate chosen. This is also not necessary for PCM playback --- MPD's goal is bit perfect, and it's meaningless to raise to two or four times the PCM sample rate. 3. if sample_rate cannot be synchronized, the test for falling back to PCM is wrong. If the file format is in DSD format such fallback is necessary, whatever the params.dop setting is.
-rw-r--r--src/output/plugins/OSXOutputPlugin.cxx26
1 files changed, 14 insertions, 12 deletions
diff --git a/src/output/plugins/OSXOutputPlugin.cxx b/src/output/plugins/OSXOutputPlugin.cxx
index 3ae760671..7e39959b6 100644
--- a/src/output/plugins/OSXOutputPlugin.cxx
+++ b/src/output/plugins/OSXOutputPlugin.cxx
@@ -339,8 +339,9 @@ osx_output_score_sample_rate(Float64 destination_rate, unsigned int source_rate)
score += (1 - frac_portion) * 1000;
// prefer exact matches over other multiples
score += (int_portion == 1.0) ? 500 : 0;
- // prefer higher multiples if source rate higher than dest rate
- if(source_rate >= destination_rate)
+ if (source_rate == destination_rate)
+ score += 1000;
+ else if(source_rate > destination_rate)
score += (int_portion > 1 && int_portion < 100) ? (100 - int_portion) / 100 * 100 : 0;
else
score += (int_portion > 1 && int_portion < 100) ? (100 + int_portion) / 100 * 100 : 0;
@@ -349,23 +350,23 @@ osx_output_score_sample_rate(Float64 destination_rate, unsigned int source_rate)
}
static float
-osx_output_score_format(const AudioStreamBasicDescription &format_desc, const AudioFormat &format) {
+osx_output_score_format(const AudioStreamBasicDescription &format_desc, const AudioStreamBasicDescription &target_format) {
float score = 0;
// Score only linear PCM formats (everything else MPD cannot use)
if (format_desc.mFormatID == kAudioFormatLinearPCM) {
- score += osx_output_score_sample_rate(format_desc.mSampleRate, format.sample_rate);
+ score += osx_output_score_sample_rate(format_desc.mSampleRate, target_format.mSampleRate);
// Just choose the stream / format with the highest number of output channels
score += format_desc.mChannelsPerFrame * 5;
- if (format.format == SampleFormat::FLOAT) {
+ if (target_format.mFormatFlags == kLinearPCMFormatFlagIsFloat) {
// for float, prefer the highest bitdepth we have
if (format_desc.mBitsPerChannel >= 16)
score += (format_desc.mBitsPerChannel / 8);
} else {
- if (format_desc.mBitsPerChannel == ((format.format == SampleFormat::S24_P32) ? 24 : format.GetSampleSize() * 8))
+ if (format_desc.mBitsPerChannel == target_format.mBitsPerChannel)
score += 5;
- else if (format_desc.mBitsPerChannel > format.GetSampleSize() * 8)
+ else if (format_desc.mBitsPerChannel > target_format.mBitsPerChannel)
score += 1;
}
@@ -374,7 +375,7 @@ osx_output_score_format(const AudioStreamBasicDescription &format_desc, const Au
}
static Float64
-osx_output_set_device_format(AudioDeviceID dev_id, const AudioFormat &audio_format)
+osx_output_set_device_format(AudioDeviceID dev_id, const AudioStreamBasicDescription &target_format)
{
AudioObjectPropertyAddress aopa = {
kAudioDevicePropertyStreams,
@@ -436,8 +437,8 @@ osx_output_set_device_format(AudioDeviceID dev_id, const AudioFormat &audio_form
// for devices with kAudioStreamAnyRate
// we use the requested samplerate here
if (format_desc.mSampleRate == kAudioStreamAnyRate)
- format_desc.mSampleRate = audio_format.sample_rate;
- float score = osx_output_score_format(format_desc, audio_format);
+ format_desc.mSampleRate = target_format.mSampleRate;
+ float score = osx_output_score_format(format_desc, target_format);
// print all (linear pcm) formats and their rating
if(score > 0.0)
@@ -785,6 +786,7 @@ OSXOutput::Open(AudioFormat &audio_format)
params.dop = true;
asbd.mSampleRate = params.CalcOutputSampleRate(audio_format.sample_rate);
asbd.mBytesPerPacket = 4 * audio_format.channels;
+
}
#endif
@@ -792,10 +794,10 @@ OSXOutput::Open(AudioFormat &audio_format)
asbd.mBytesPerFrame = asbd.mBytesPerPacket;
asbd.mChannelsPerFrame = audio_format.channels;
- Float64 sample_rate = osx_output_set_device_format(dev_id, audio_format);
+ Float64 sample_rate = osx_output_set_device_format(dev_id, asbd);
#ifdef ENABLE_DSD
- if(params.dop && sample_rate != asbd.mSampleRate) { // fall back to PCM in case sample_rate cannot be synchronized
+ if(audio_format.format == SampleFormat::DSD && sample_rate != asbd.mSampleRate) { // fall back to PCM in case sample_rate cannot be synchronized
params.dop = false;
audio_format.format = SampleFormat::S32;
asbd.mBitsPerChannel = 32;