Executive summary:
When I converted 24-bit and 16-bit WAV files to 64-bit floating-point in a Python script, MC playback sounds more accurate. I propose MC uses the ldexp() function from the standard C++ library to convert PCM/integer to 64-bit floating-point in a bit-perfect way.
Details:
I found the same problem and confirmed the same fix in both MC v21.0.83 and MC v22.0.13. I run 64-bit Windows 8.1.
For a 24-bit WAV file, I used the Maria 24/192 sample (Windows version) at
http://www.soundkeeperrecordings.com/format.htmFor a 16-bit WAV file, I used the Maria 16/44 sample from the same link.
I use a Lynx Hilo external 24-bit DAC for audio playback, which has an analog volume control after the DAC. Therefore, I disable the volume control in MC to minimize distortion. I observe that the Lynx Hilo sounds better with WASAPI exclusive than ASIO in MC and other applications, so I used WASAPI exclusive. The Lynx ASIO driver has a mixer for sharing audio from multiple apps, so this could be why WASAPI exclusive sounds better. Here are the options I used in an attempt to make MC bit-perfect for 24-bit and 16-bit WAV playback:
Tools > Options > Audio:
- Audio Device = Lynx Hilo [WASAPI]
- Audio Device ... Device settings... check "Open device for exclusive access", Bitdepth = 24-bit integer, Buffering = 100 msec
- Settings ... DSP & output format... uncheck all checkboxes at left (no changes made by DSP Studio)
- Settings > Bitstreaming = none
- Track Change > Switch tracks = Gapless
- Track Change > check "Do not play silence (leading and trailing)"
- Track Change > check "Use gapless for sequential album tracks"
- Track Change > check "Use gapless for manual track changes"
- Stop, Seek & Skip > Seek = Gapless
- Stop, Seek & Skip > Stop = Immediate
- Stop, Seek & Skip > Pause = Immediate
- Volume > Volume mode = Disabled Volume
- Advanced > Dither Mode (not zone-specific) = No Dithering
- Advanced > Live playback latency = 50 msec (recommended)
As a side note, disabling dithering in MC turned out to be important to get the best sound quality.
Here is a Python script named wav_to_64b.py that I used to convert the 24-bit and 16-bit WAV files to 64-bit floating-point:
# -*- coding: utf-8 -*-
"""WAV file reformat to 64b
Supports mono and stereo.
Usage:
Install NumPy and SciPy packages in Python. See www.scipy.org/install.html
Download wavio.py from https://gist.github.com/WarrenWeckesser/7461781
Put wavio.py in the same folder as this script.
In a Python console:
>>> os.chdir(r'path of folder containing this script')
>>> from wav_to_64b import wav_reformat
>>> in_file = r'D:\Music\input file.wav'
>>> out_file = r'D:\Music\output file.wav'
>>> wav_reformat(in_file, out_file)
"""
import numpy
import scipy.io.wavfile
import wavio
def wav_reformat(in_file, out_file):
# wavio supports only PCM/integer WAV files, with 8, 16, 24 or 32 bits.
# in_array has one column per channel.
sample_rate, bytes_per_mono_sample, in_array = wavio.readwav(in_file)
# Convert integer to float64 dtype
out_array = numpy.float64(in_array)
# Scale to fractional format.
if bytes_per_mono_sample == 2:
out_array = numpy.ldexp(out_array, -15)
elif bytes_per_mono_sample == 3:
out_array = numpy.ldexp(out_array, -23)
elif bytes_per_mono_sample == 4:
out_array = numpy.ldexp(out_array, -31)
else:
raise ValueError('8-bit WAV files are not supported.')
# Write to floating-point WAV file
scipy.io.wavfile.write(out_file, sample_rate, out_array)
My listening tests showed that the 64-bit floating-point versions:
- Had deeper bass
- Had better clarity
- Had better 3D imaging
- Had more impact
- Were more emotionally involving and fun to listen to
If MC was bit-perfect, the original 24-bit and 16-bit WAV files would sound identical or better.
To summarize, all I did in Python was recast the PCM/integer values to floating-point (double type in C++) and use NumPy's ldexp() function to scale the data to the standard [-1, 1] fractional range for floating-point audio. The same improvement in sound quality and realization of bit-perfect playback is achievable in MC by using the ldexp() standard library function in C++:
http://en.cppreference.com/w/cpp/numeric/math/ldexpEnjoy!