Hi everyone! I’m new to JUCE and am trying to build a simple Audio Sample Playback plugin to learn the ropes a little bit. In my PluginProcessor.h I store a unique_ptr to an AudioSampleBuffer, set that pointer once I read the contents of a file in the PluginProcessor ctor, and then copy the contents (sample by sample) to the buffer passed into processBlock().
When I run the plugin, things seem to be working properly except that the audio playback is extremely glitchy and sounds terrible compared to how the sample should sound. Any help on this would be much appreciated!
Please show your code so we can better understand the issue. Playing the contents of an AudioBuffer should be pretty trivial to get right, but there are of course some details that can be wrong. (There’s also no need to use an AudioBuffer via a unique_ptr, it works fine as a value type. That however likely isn’t causing your playback issue.)
You are probably advancing the file buffer read position twice or more because your outer loop iterates over the plugin channels. Try inverting the looping order so that the outer loop iterates the samples and the inner loop iterates over the channels and only advance the read position when you advance the sample loop.
Something like :
for (int i = 0; i < buffer.getNumSamples(); ++i)
{
for (int j = 0; j < buffer.getNumChannels(); ++j)
{
int chantoread = j % m_fileBuffer.getNumChannels();
buffer.setSample(j, i, 0.1*m_fileBuffer.getSample(chantoread,m_filePos));
}
++m_filePos;
if (m_filePos >= m_fileBuffer.getNumSamples())
m_filePos = 0;
}
The first problem I see in the code is that you declare the wavBuffer as a local variable in prepareToPlay. So, it won’t be the same wavBuffer your processBlock is going to use.
@Xenakios sorry for more nooby questions, but when I remove the
AudioBuffer<float>
class declaration from inside ::prepareToPlay I get thrown the error
Type 'AudioBuffer <float>' does not provide a call operator'
I assume this is because wavBuffer is not a callable function here, I am trying to figure out a way to call the AudioBuffer function without having to redeclare the variable but for the life of me I can’t figure it out. Thank you for the help by the way, it’s really appreciated.
@daniel and @Xenakios thank you again, unfortunately I’m still not getting any audio out
I have also declared this variable and pointer privately in the header, but I’m thinking that I didn’t need to as they are only needed in the scope of ::prepareToPlay?
I’m stepping through breakpoints in ::prepareToPlay and all the variables and pointers to memory seem to be assigned just fine. Inside ::processBlock, the wavBuffer’s allocated data is now present (thank you both again!), however the juce::AudioBuffer is allocated 0 bytes, could this be the problem?
It is an indicator, that your audio file has the length of 0.
Did you actually verify, that mFormatReader is not nullptr?
next thing is, if createReaderFor() succeeds, it will take ownership of the inputStream. That’s a bad thing here, because it is on the stack, so you will have a double delete.
It all looks pretty hairy.
May I ask, what you actually want to build?
It seems there are easier solutions than what you are trying right now, or that this approach won’t suit your goal…
I’m planning to build binaural audio plugin that convolves impulse responses with incoming audio. At the moment I’m trying to load a .wav file into AudioSampleBuffer (and play it to check it’s stored ok), with the intention to eventually build an array of AudioSampleBuffers filled with very short impulse responses.
@daniel Thank you so so much for such an in depth response at this kind of time! All working perfectly. I see what you mean about the importance of taking ownership of streams
Hello Rishdosh,
I have done same as you like load file when any button pressed, then modify ProcessBlock function as above, but what should we have to keep in PrepareToPlay function?.
I tried without keeping anyting, its not worked.