VST Piano plugin click problems

Hi!
I am kind of new to c++ and I wanted to implement my own VST piano. However, I have some issues with the real sound piano.

To generate real piano sound I use sampler. I’ve set it up to 16 channels. However when I play on keyboard only one sound is heared. When I play fast there is a lot of clipping. Could you help me find what is wrong with my code?

This is my whole cpp file of PianSound class that is responsible for generating real sound piano.

void PianoSound::prepareToPlay(double sampleRate, juce::MidiKeyboardState& keyboardState)
{

	this->sampleRate = sampleRate;
	keyboardState.reset();
	formatManager.registerBasicFormats();
	sampler.setCurrentPlaybackSampleRate(sampleRate);
	

	for (int i = 0; i < numVoices; i++)
	{
		sampler.addVoice(new juce::SamplerVoice());
	}
}


void PianoSound::getNote(juce::MidiMessage& midiEvent)
{
	juce::AudioFormatReader* reader{};
	
	if (midiEvent.isNoteOn())
	{
		noteID = midiEvent.getNoteNumber();
		auto noteName = juce::String(noteID);
		fileName.append(noteName, 100);
		fileName.append(juce::String(".wav"), 50);
		
		noteFile = juce::File(fileName);

		reader = formatManager.createReaderFor(noteFile);

		juce::BigInteger note;
		note.setBit(noteID);

		sampler.clearSounds();

		if (reader != nullptr)
		{
			sampler.addSound(new juce::SamplerSound("Sample", *reader, note, noteID, 0.01, 1.0, 10.0));
		}
		if (reader != nullptr) delete reader;
	}
	else if (midiEvent.isNoteOff())
	{
		fileName = "D:\\Studia\\naukaJuce\\PianoPlugin4\\notes\\";
		if (reader != nullptr) delete reader;
	}
	else if (midiEvent.isAllNotesOff())
	{
		fileName.clear();
		fileName = "D:\\Studia\\naukaJuce\\PianoPlugin4\\notes\\";
	}
}

void PianoSound::processBlock(juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{
	auto* firstChannel = buffer.getWritePointer(0);


	for (const auto midiMessage : midiMessages)
	{
		juce::MidiMessage midiEvent = midiMessage.getMessage();

		const auto midiEventSample = static_cast<int>(midiEvent.getTimeStamp());
		
		getNote(midiEvent);
		//openNoteFile();
		sampler.renderNextBlock(buffer, midiMessages, 0, buffer.getNumSamples());
	}
	
	sampler.renderNextBlock(buffer, midiMessages, 0, buffer.getNumSamples());

}

Or the main question is - where should I delete my reader?

Could it be that you are using code that is only for triggering individual samples? maybe you should use the Synthesiser class that manages its use as an instrument

https://vaporsoft.net/creating-a-very-simple-sampler-audio-plugin-in-juce-5/

But this is not what I am looking for. I actually use an object of Synthesiser class (sampler) and when I used 1 file it did not change the pitch to the pitch that notes were supposed to be. I also implemented different getNote method:

void PianoSound::getCelloSound(juce::MidiMessage& midiEvent)
{
	juce::String celloFileName = "D:\\Studia\\naukaJuce\\PianoPlugin4\\notes\\cello.wav";
	noteFile = juce::File(celloFileName);

	auto reader = formatManager.createReaderFor(celloFileName);

	juce::BigInteger allNotes;
	allNotes.setRange(21, 108, true);

	sampler.clearSounds();

	if (reader != nullptr)
	{
		sampler.addSound(new juce::SamplerSound("Sample", *reader, allNotes, 60, 0.01, 1.0, 10.0));
		delete reader;
	}
}

It can play 2 notes at the same time, but still some clipping issues occur.

The problem is I really want to play it my own samples, so it won’t sound so automatic.

I don’t know how it works exactly, but I find it strange that files are loaded in the audio thread, and that when a note is On, sampler.clearSounds() is called;