Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Performance

This page reports how much memory a sampled organ needs, how long it takes to open, and what each of Masterpiece’s engine settings gains. Every figure is measured on a real sample set, and the method is at the end.

Summary

BaselineMasterpieceGain
Sample memory, full organ21.6 GB2.3 GB9.3x less
Sample memory, stereo kept21.6 GB4.7 GB4.6x less
Sample memory, bit-exact 24-bit21.6 GB16.2 GB1.3x less
Time to open the organ77.1 s25.9 s3.0x faster
Sample loading, from the cache13.0 s2.6 s5.0x faster
Memory added by drawing all 44 stopsnoneflat

The baseline is the conventional approach: every sample decoded to 32-bit floating point and held in memory.

Test bed

InstrumentFriesach: 44 stops, three manuals and pedal
Sample set17.0 GB, 12,148 WAV files, 24-bit / 48 kHz / stereo
Machine15.9 GB RAM, Windows
BuildMasterpiece 0.3.3, Release

The figures are the project’s own measurements, made with Masterpiece 0.3.3.

Techniques

The settings are on the Loading tab of Organ settings.

TechniqueSettingWhat it does
Release streamingStream release tails from diskA release tail is several seconds of room sound, played once from its start and never looped. Masterpiece keeps only its first frames in memory and streams the rest from disk into a per-voice ring buffer while it sounds. Attacks and sustain loops stay in memory.
24-bit storageResident format: 24-bit - what the samples areThe source files are 24-bit. Samples are held as 24-bit integers, so the audio in memory is bit-for-bit identical to the file. The 32-bit float baseline widens every sample.
16-bit storageResident format: 16-bit - two thirds of that, inaudibleSamples are requantised to 16 bits against each file’s own peak, so a quiet stop still uses every bit.
Mono foldingLoad in mono (halves memory, gives up the stereo image)A stereo sample set is folded to mono as it loads.
Sample cacheSample cacheThe decoded, converted samples are written to one file, so the next load of the same organ with the same settings is one sequential read in place of 12,148 decodes.
Load-time rate conversionSample rateSamples are converted to the chosen rate as they load (As recorded, 48 kHz or 44.1 kHz), so playback needs no per-voice rate conversion.

The Memory profile list sets several of these at once: Best quality - 24-bit, hold everything, Recommended - 16-bit, stream releases and Smallest - 16-bit mono, stream releases.

Memory

ConfigurationHeld in memoryLeft on diskMemory savedReduction
32-bit float, resident (baseline)21,606.5 MB
24-bit, resident16,204.9 MB5,401.6 MB1.3x
24-bit, streamed6,976.0 MB8,891.9 MB14,630.5 MB3.1x
16-bit, streamed4,650.7 MB5,927.9 MB16,955.8 MB4.6x
16-bit mono, streamed2,325.3 MB2,964.0 MB19,281.2 MB9.3x

Release streaming is the largest single saving: it leaves 56% of the sample data on disk. The settings multiply, and each step is an exact ratio of the one before:

StepBeforeAfterRatio
32-bit float to 24-bit21,606.5 MB16,204.9 MB0.750
24-bit to 16-bit (streamed)6,976.0 MB4,650.7 MB0.667
Stereo to mono4,650.7 MB2,325.3 MB0.500

The exact ratios confirm that the accounting measures the sample data itself.

Memory while loading and playing

Each run opens the organ, then walks the registration from a single Principal 8′ to full organ in eight steps. At each step it plays the same 15-second passage: notes build up to sixteen held voices, then all are released together, so every voice is in its release tail at once.

Memory rises only while the organ loads. After that it stays level through every registration step and every chord, including sixteen simultaneous release tails streaming from disk.

Memory against registration

Every rank is loaded whether its stop is drawn or not, so full organ costs the same memory as a single stop. Peak process memory at each step:

Configuration1 stop44 stopsChange
24-bit, streamed8,270 MB8,268 MB−2 MB
16-bit, streamed5,939 MB5,927 MB−12 MB

Drawing a stop waits for no samples, and a registration change allocates nothing.

Load time

ConfigurationTime to openSpeed-up
32-bit float, resident (baseline)77.1 s
24-bit, resident55.8 s1.4x
24-bit, streamed28.9 s2.7x
16-bit, streamed28.0 s2.8x
16-bit mono, streamed25.9 s3.0x

Holding less also opens faster: a streaming load reads no release tails, and they are more than half the data on disk.

Sample cache

16-bit mono, streamedDecoded from WAVRead from cacheSpeed-up
Sample loading13.0 s2.6 s5.0x
Whole organ25.9 s18.9 s1.4x

The cache file is 2,439 MB and stands in for about 7 GB of source files.

The cache is keyed to a fingerprint of everything that changes the bytes in memory: the organ definition’s size and modification time, storage width, mono folding, load rate, preload head, loop selection, release streaming and the ranks requested. Any change is a cache miss that rebuilds the cache, so a stale cache is never read. This was verified on a five-rank load: a 16-bit cache is reused at 16-bit, and rebuilt at 24-bit and at 16-bit mono to exactly the expected sizes (291.8, 437.7 and 146.0 MB).

By default Masterpiece keeps a single cache file and replaces it when the organ or settings change, so the cache stays the size of one organ. The Sample cache list offers One cache, replaced as organs change, One cache per organ (uses more disk) and Off.

Sample-rate conversion

Memory falls in exact proportion to the load rate: a 96 kHz sample set played through a 48 kHz device takes half the memory. Verified on Friesach (five ranks) by converting from its native 48 kHz:

Load rateHeld in memory
48 kHz, as recorded1,599.7 MB
44.1 kHz1,469.8 MB
24 kHz799.9 MB

Pitch and level are unchanged at every rate. A converted attack joined to a converted streamed release tail matches a fully resident render to 0.0 dB across the whole release.

The Sample rate list offers As recorded, 48 kHz and 44.1 kHz.

Audio fidelity

Measured on the sample data directly, applying exactly what the loader applies, to 60 files chosen at random from the 12,148:

StorageCompared with the source file
24-bitBit-for-bit identical
16-bit78.1 dB signal to quantisation noise (median), 75.2 dB lowest

Method

  • Held / left on disk. The sample library’s own accounting, logged at the end of each load: residentBytes() sums the sample buffers actually held, streamedBytesSaved() sums what streaming left on disk.
  • Process memory. The process’s private bytes, sampled from outside it every 250 ms.
  • Load time. From the start of the load to the organ being ready to play, as logged by the application.

Friesach is a freely published sample set by Piotr Grabowski and is not part of this repository. See ATTRIBUTION.md in the repository root.