First JUCE plugin, compiling right but no sound - where did I make a mistake?


#1

Hi all, I’m back to VST and C++ programming after years and I’m trying JUCE this time.

I’m making a simple VST instrument that should generate random noise in the [-1.0, 1.0] float range (using stdlib’s rand for simplicity), just to test how it works. JUCE generates the Visual Studio 2017 project well and I can build the DLL without any problem, after including the right files.

VST Host 64 and JUCE’s Plugin Host load the plugin all right, but I can’t hear no sound at all coming out of it (not even glitching, just pure silence). I guess there’s something wrong in my code, but I can’t say what. If someone could take a look and say where I’m making a mistake, that would be very helpful.

Below is my processBlock function. Most of it is generated by JUCE, and my modifications are between the // This is my stuff and // stuff ends comments.

Thanks in advance!

void BeeswaxAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
{
    const int totalNumInputChannels  = getTotalNumInputChannels();
    const int totalNumOutputChannels = getTotalNumOutputChannels();

    // In case we have more outputs than inputs, this code clears any output
    // channels that didn't contain input data, (because these aren't
    // guaranteed to be empty - they may contain garbage).
    // This is here to avoid people getting screaming feedback
    // when they first compile a plugin, but obviously you don't need to keep
    // this code if your algorithm always overwrites all the output channels.
    for (int i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
        buffer.clear (i, 0, buffer.getNumSamples());

    // This is the place where you'd normally do the guts of your plugin's
    // audio processing...
    for (int channel = 0; channel < totalNumInputChannels; ++channel)
    {
        float* channelData = buffer.getWritePointer (channel);

        // ..do something to the data...

        // This is my stuff
		long numSamples = buffer.getNumSamples();

		for (long sample = 0; sample < numSamples; sample++) {
			float nextSample = ((float)rand() / (float)RAND_MAX) * 2.0 - 1.0;
			channelData[sample] = nextSample;
		}
        // stuff ends
    }
}

#2

*(channelData[sample]) = nextSample;

I think this will work.


#3

Did you add a breakpoint or a DBG (String(nextSample))?

Also, you are iterating over the number of totalNumInputChannels, but you want to create output signal. Did you maybe specify it to have no input channels, as it is generating noise? In that case the loop is never executed.

@SUBARU, I don’t think your suggestion will work. What @hya wrote is the correct way to set a value in the array.


#4

@daniel - debugging in JUCE is something I didn’t look at. I suppose there are debugging macros, but where should I see the debug logs if I’m, like in this case, developing a VST plugin? Same for breakpoints - Maybe I can attach a debugger to the host? Would that be possible?

However, I think you’re right about the input channels. I think my code, which is directly taken from the plugin boilerplate, is never called. I guess I’m clearing the output channels instead and relying on the presence of input channels in a plugin that has (and can’t have) none. I’ll look into how to directly write on the output channels - unfortunately I couldn’t find any example regarding that.


#5

Yes, that’s the way to do it. It should work, even if the host has no debug symbols. If not, you have always the chance to test in the Juce Host example for exactly that purpose.

The other way with the DBG (which is a shorthand to write to std out or the Logger), that is removed in a release build. To see the output the easiest way is to start the host from a console. The advantage is, that you don’t stop the processing instead of stepping through.

It is the same samples block, so it works destructive, i.e. overwriting the incoming samples. You just need to check, which channels are expected. Your code should work, if you simply change totalNumInputChannels to totalNumOutputChannels, so that the code is actually called.


#6

That’s the best for day-to-day debug, thanks, that was very helpful.

Ahah - now I understand. I was looping from 0 to 0, never really entering into the loop body, and I didn’t know because I wasn’t debugging it. LOL. Thanks!