AU/VST plugin does not recognize changed sample rate of the host

I have a plugin which depends on knowing the current sample rate to get correct calculations.

When changing the sample rate in any host (Logic Pro X, AudioPluginHost, Audacity), the plugin gets duefully reset (evidenced by PreparetoPlay being called), however, when I check the sample rate with getSampleRate(), it only ever reports 44100. Same if I start the plugin in a 48k host. Blocksize gets reported immediately and correctly, by the way.

Calculation results based on sample rate are in fact wrong, so it’s not just me looking in the wrong spot, the plugin actually doesn’t know.

How can I solve this ?

Thanks

Is the sample rate passed into prepareToPlay correct?

I would hope so. I ask PrepareToPlay() to getSampelRate() upon which I’m told it is 44.1 when I know it’s 48. That’s what I could find as far as Sample Rate goes. Is there a correct way ?

The documentation says getSampleRate returns a valid value only during processBlock. But in prepareToPlay you get the samplerate from the method’s argument…(It is of course possible there are hosts that update the sample rate only during the audio processing call and you have to get it in processBlock with getSampleRate.)

Just tried to use it in processBlock and it also just reports 44.1 after the host is switched or even launched in 48

Do I remember right your plugin is MIDI-only? Maybe the hosts you’ve tested don’t bother reporting the current audio sample rate for such plugins. Or it could be a bug in the Juce plugin client code.

https://docs.juce.com/master/classAudioSource.html#a653279dbd167f70e318fd280681dbddf

prepareToPlay’s second parameter is the sample rate… what’s it reporting?

It should match the host’s sample rate setting.

If your audio device is being shared by more than one app or is locked to an external clock the sample rate may not match the actual device’s rate.

Rail

Could be. I’ll have to add some bogus audio functionality to test this.

Contrary to the documentation, it is the first parameter. Ps2P is a void function returning nothing but I put in a DBG() command to print to the debug console. 44100 it is.

Right – the docs are wrong… Build a simple gain audio plugin and check the samplerate in prepareToPlay in Logic vs. a MIDI plugin… I know that Logic does send the correct value for an audio plugin.

Rail

I don’t know why this happens but this reminded me of this thread that came up a few weeks ago:

Okay – take a look at the JUCE AU wrapper… getSampleRate():

double getSampleRate() { return AudioUnitHelpers::getBusCount (juceFilter.get(), false) > 0 ? GetOutput (0)->GetStreamFormat().mSampleRate : 44100.0; }

What’s your BusCount? If it’s zero you’ll always get 44100.0

That’s what’s called by the wrapper to get the samplerate to send to the (juceFilter) AudioProcessor::prepareToPlay()

    //==============================================================================
    void prepareToPlay()
    {
        if (juceFilter != nullptr)
        {
            juceFilter->setRateAndBufferSizeDetails (getSampleRate(), (int) GetMaxFramesPerSlice());

            audioBuffer.prepare (totalInChannels, totalOutChannels, (int) GetMaxFramesPerSlice() + 32);
            juceFilter->prepareToPlay (getSampleRate(), (int) GetMaxFramesPerSlice());

            midiEvents.ensureSize (2048);
            midiEvents.clear();
            incomingEvents.ensureSize (2048);
            incomingEvents.clear();

            prepared = true;
        }
    }

Rail

Bus Count is 0 and stays 0 as long as the plugin is a MIDI-FX.

Exactly. That’s obviously the issue.

Rail

So to recap and to consolidate information, sampleRate is not reported to a MIDI-FX plugin. I solved this by allowing text input into an already existing label originally designed to get numerical input only. “44.1k” and “48k” make the plugin adapt to different sample rates.

I also implemented AudioPlayhead to optionally allow automatic sync to the host tempo.

Then I tried to implement parameter recall with get- / setSateInformation, but since the plugin was pretty much finished by then, that’s too much of a change apparently, it pretty much exploded in my face with small clouds of smoke going up everywhere.

So I took one step back and now consider it done. No point in rewriting it from the ground up just to get back the window the size it was. For the first plugin I ever did it’s pretty functional and does what it should and then some.

tm2

This plugin, aptly named Tempomat, captures a live drummer’s (MIDI) snare hits and calculates and displays the tempo from that. That’s the upper number.

The lower number is the target tempo, this can be synced to the host, set manually or via a MIDI CC message and thus can be saved per song or section. The target tempo serves several purposes:

  • it’s a direct visual guide in comparison to the actual tempo
  • it sets up a corridor in which precise snare hits are rewarded with the number in green
  • it sets up several other corridors in which half time, double time, dotted eights etc are detected correctly and all displayed as the source tempo, in blue

Also, the lower label accepts text input of sample rates and “auto” to re-engage automatic sync to the host tempo.

Thanks everyone for helping me get there.

2 Likes