How To Clear Audio Buffer & Synthesiser Sounds To Load New Sample

Hey I’m building a simple rompler/sampler and for some reason when I try to clear the buffer and load a new sample/preset im unable to, its playing the same sound that was first added to the synhtesiser. Im using the Synthesiser Class, and ive added it as a member to my Processor Class. Is there a way to clear the AudioFormatManager, AudioBuffer, or Synthesiser to load a new sample when selecting a new preset? It seems that I can only load a sample one time in the constructor initSynth(0), then after it initializes, im unable to load a new sample. I cant Below is the snippet

         //PreserComponent.cpp
       void PresetComponent::listBoxItemClicked(int row, const MouseEvent &)
        {
     
              if (currentCategory == 0)
              {

	              *presetNameArrayPtr = presetCategory0NameArray[row];
	               presetLabel.setText(*presetNameArrayPtr, juce::dontSendNotification);
	               presetNum = row;
	               processor.initSynth(row);		
          }

              if (currentCategory == 1)
              {

	              *presetNameArrayPtr = presetCategory0NameArray[row];
	               presetLabel.setText(*presetNameArrayPtr, juce::dontSendNotification);
	               presetNum = row;
	               processor.initSynth(row);		
          }
       }



         //PluginProcessor.h

  CustomAudioProcessor::CustomAudioProcesso()
       #ifndef JucePlugin_PreferredChannelConfigurations
      :audioBuffer(new AudioBuffer<float>()), AudioProcessor(BusesProperties()
       #if ! JucePlugin_IsMidiEffect
       #if ! JucePlugin_IsSynth
	.withInput("Input", juce::AudioChannelSet::stereo(), true)
           #endif
	.withOutput("Output", juce::AudioChannelSet::stereo(), true)
       #endif
     	)
          #endif
        {

     	auto numVoices = 8;
        formatManager.registerFormat(wavAudioFormat = new WavAudioFormat(), true);
         for (auto i = 0; i < numVoices; ++i)
         	synth.addVoice(new SamplerVoice());
             initSynth(0);
            keyboardState.addListener(this);
        }


       void CustomAudioProcessor::processBlock(juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
       {

         auto numSamples = buffer.getNumSamples();
         for (auto i = getTotalNumInputChannels(); i < getTotalNumOutputChannels(); ++i)
	     buffer.clear(i, 0, numSamples);

         *audioBuffer = buffer;

         keyboardState.processNextMidiBuffer(midiMessages, 0, numSamples, true);
         synth.renderNextBlock(buffer, midiMessages, 0, numSamples);

       }



       void CustomAudioProcessor::initSynth(int presetName)
    {

         if (presetName == 0)
         {

	        synth.clearSounds();
	        BigInteger highNotes;
	        formatManager.clearFormats();
	        audioBuffer->clear();
	        formatManager.registerFormat(wavAudioFormat = new WavAudioFormat(), true);
	        highNotes.clear();
	        reader = formatManager.createReaderFor(File("C:/Users/../Music/Sounds/cello.wav"));
	   //highNotes.clear();
	      highNotes.setRange(0, 126, true);
	       synth.addSound(new SamplerSound("cello", *reader, highNotes, 0, 0, 0, 1.0));

}

       if (presetName == 1)
       {
	          synth.removeSound(0);
	           synth.clearSounds();
	          BigInteger highNotes;
	          formatManager.clearFormats();
	
	           audioBuffer->clear();
	          formatManager.registerFormat(wavAudioFormat = new WavAudioFormat(), true);
	           highNotes.clear();
	          reader = formatManager.createReaderFor(File("C:/Users/.../Music/Sounds/guitar.wav"));
	     //highNotes.clear();
	          highNotes.setRange(0, 126, true);
	synth.addSound(new SamplerSound("guitar", *reader, highNotes, 0, 0, 0, 1.0));

     }

To do that just load a file that you choose once you press a button. Then pass a pointer to the file to the processBlock to read it there. I wouldn’t manage the files inside the synth class but on a separate one, and definitely don’t do it in the audio thread as memory management is really slow and will create artifacts. Do it in a background thread.

I think you can get most of what you need from this tutorial

1 Like

Yes, thanks John for that tutorial. I was able to subclass ReferenceCountedObject, and dynamically change samples/wav files on the fly in the background thread.

1 Like