One of the techniques BitPerfect uses to maximize playback sound
quality is to play from RAM memory. Most music players will play
directly from the music file. The advantage of that method is that you
only read the music data from the file as you need it, and stream it to
the audio output device. If you change your mind and decide to play
something else, or move playback to a different
part of the track, that is easy to accomplish - at least from a
programming simplicity perspective - using that method.
BitPerfect instead takes advantage of the phenomenal processing power of
a modern computer and pre-loads the music into a RAM buffer. When you
want to play the music, you simply pass the “address” of the RAM buffer
to the audio output device, and it automatically handles the rest. In
order for this to be practical, you must be able to not only read the
file, decode it, and load the music data into the buffer, but also
perform any manipulation that might be necessary, such as sample rate
conversion, all in double-quick time.
So how practical is this?
Surprisingly so, it turns out. Here is a peg in the ground taken from
the totally basic 2013 Mac Mini I use in our reference system. It has a
2.5GHz Core i5 processor, and 4GB of system RAM. I allocate 512MB of
RAM for the audio buffers. For this test I have BitPerfect set to
upsample from 44.1kHz to 176.4kHz and (for purposes of full disclosure) I
am using the as-yet unreleased version 1.1 of BitPerfect which has a
new and improved 64-bit audio engine. Using this system, a piece of
music of 1 minute 35 seconds duration, is read from an Apple Lossless
file, decoded, upsampled to 176.4kHz, and loaded into its RAM buffer in
only 1.9 seconds.
There are many advantages to doing it this
way, and one of those is the ability to minimize CPU time during
playback. In the early days of BitPerfect we discovered that reducing
the CPU time tended to have an improving effect on sound quality. More
recently we have established that it is only certain kinds of CPU
activity that have this effect, but nonetheless, minimizing
“undesirable” CPU load is one BitPerfect’s key goals in improving
playback quality.
BitPerfect is able to start playing the track
as soon as you start loading it into the buffer, so playback commences
pretty much instantly, and the loading of the track continues during the
first 1.9 seconds of playback. Beyond that, BitPerfect requires CPU
cycles only for the direct management of playback. In principle, then,
there exists the possibility that the sound quality of playback is
degraded slightly by the additional CPU load during those first 1.9
seconds, but frankly, we know of nobody who has been able to detect this
audibly. Certainly, we can’t. However, for the remaining 1 minute 33
seconds, playback will be at BitPerfect’s highest caliber.
What
happens if the track is too big to fit into the buffer? No problem.
The RAM that you allocate in BitPerfect’s Preferences menu is actually
equally divided into two buffers. If the whole track does not fit into
the first buffer, the remainder is put into the second buffer. As soon
as the contents of the first buffer finishes playing, playback is
instantaneously switched to the second buffer. The switching occupies
only a tiny fraction of the time interval between consecutive samples,
so the audio output device does not even know it is happening. And if
the track still does not fit into two buffers, then as soon as the first
buffer finishes playing and playback switches to the second buffer, the
remaining unplayed content is loaded into the first buffer. BitPerfect
can do this ad infinitum, in effect maintaining the two buffers as a
“wash and wear” pair, with one in use and the other containing whatever
is up next.
This has important ramifications for those who like
to claim that lossless music encoded in different formats, such as WAV,
AIFF, FLAC, and Apple Lossless, all sound different. Of those three formats,
the third and fourth are losslessly compressed. Like unzipping a ZIP
file, they need to be decoded after opening before they can be played.
But after decoding, their contents are absolutely identical (“bit
perfect”, if you like) to the contents of the uncompressed WAV or AIFF file. I
suppose there is room for playback of a losslessly compressed file to
sound different to a WAV/AIFF file if you make the assumption that the
additional processing involved in decoding the file results in some kind
of audible degradation. But either way, if you are playing those files
using BitPerfect, then once the 1.9 second buffer load is over, then
there is nothing left that would be in any way different depending on
whether the music data had originally been extracted from a WAV, AIFF, FLAC, or Apple
Lossless file. Absolutely none whatsoever.
The other take-away
from this is that it is not really necessary to allocate a particularly
large amount of system RAM to the audio buffer. We used to think that
by pre-loading the whole track into memory it would sound better than if
it was loaded chunk by chunk into a pair of wash-and-wear buffers. The
additional CPU cycles involved in loading and switching ought to be
degrading the sound. Over time, though, it has not turned out that way.
We find that setting a larger audio buffer size seems to imbue the
system with no audible improvements that we can reliably observe. I
have for some time now left the audio buffer size on my reference system
set to either 256MB or 512MB, and it seems to sound just fine to me.
Tim does the same - and he listens on Stax SR009s.
All this is good news, because OS/X Mavericks seems to appreciate having lots of system RAM to play with.