Preloading all samples into memory

I want to make a sampler plugin from about 6000 .wav files with a total size of about 2500 MB. It is necessary to completely preload them into memory in order to have quick access to any of them at any time without delay, instantly. I am using AudioTransportSource and it has been tested perfectly with 2 samples, but is it suitable for large volumes? Does it load an object into memory completely once upon initialization, or does it read from disk while in use? Could using it cause delays when playing / switching between samples? Example:

void NewProjectAudioProcessor::Init()
{
    formatManager.registerBasicFormats();
    transportSource.addChangeListener(this);
	
    audioReader = formatManager.createReaderFor(File(String("Samples/test1.wav"))); //in DAW .exe folder or plugin .vst3 folder

    if (audioReader != nullptr)
    {
        AudioFormatReaderSource* newSource = new AudioFormatReaderSource(audioReader, true);
        transportSource.setSource(newSource, 0, nullptr, audioReader->sampleRate);
    }
}

Loading it all into memory would work on most machines, but 2.5 GB is a bunch, and especially plugins aren’t usually alone on a machine.

You’ll probably want to do some disk streaming, which is quite involved to implement if you want to prevent hiccups. What you basically do is load the beginning of each samples into ring buffers that you read from when playing the samples. As soon as a voice starts consuming from these ring buffers, you need to have a background streaming thread that reads more audio from disk and stores it in the ring buffers. That way you keep the memory usage low and efficient, but you’ll have to take care of all the thread synchronization. Reading from disk is a blocking operation and there are basically no guarantees on timing, especially when you’re dealing with spinning discs!

Does anyone still care about keeping memory usage low? My browser with a bunch of open tabs takes up even more RAM space. Memory isn’t a problem because it’s not 1990. I want to avoid disk streaming. Is there a way to not bother with streaming and load everything into memory at once? Does the AudioTransportSource do this? I have met conflicting opinions and do not understand if this class is suitable for massive sample sets.

The combination of AudioFormatReader, AudioFormatReaderSource and AudioTransportSource will stream the samples from disk on the fly and would almost certainly not work properly for your desired use case.

Is there any other combination that will cache the entire volume of samples completely?

You should have a look at MemoryMappedAudioFormatReader

That also technically streams the data from disk, but it’s just well hidden. (Since the streaming is delegated for the operating system.)

So is there any way to really preload everything into memory?

I don’t have answers for you, sorry. However, just to be clear in some cases you’ll be using 2.5GB per instance of your plugin. You could use statics which will prevent this for most DAWs. Unfortunately some DAWs will load each plugin instance in a unique process which will prevent the optimisation achieved by the statics. You may already be aware of this but thought I would point it out rather than you heading down a path that you later find isn’t suitable for you in the end.

I think you can write your own AudioFormatReader thats reads from an AudioBuffer that is already in memory. This way you can continue to use the AudioTransportSource. I don’t recall having an implementation ready from JUCE to use the AudioFormatReader for In-Memory operations.