Getting host's bpm from VST plugin


#1

Hi,
I’m new to juce so maybe this is a stupid question, but… is there a way to get the bpm setting of the host at a given moment (or something equivalent to bpm for timing)? VST 2.4 docs gives a couple of functions to do that, but I haven’t looked at them too much because if it’s possible I would like to do this using juce-only code.

What am I missing?
Thank you very much :wink:


#2

Check out the AudioPlayHead class.


#3

Thank you very much :slight_smile:


#4

I have a problem…
I do getPlayHead()->getCurrentPosition(currentPositionInfo) inside my AudioProcessor class (is it normale that if I call it from the constructor Plugin Host crashes?). But then currentPositionInfo.bpm is always 0. It seems like Plugin Host doesn’t define a default BPM. Can this happen in mainstream hosts?
In this case it should be better for me to include a check and if it is 0 I set it to something.


[SOLVED] Synchronizing VST with DAW MIDI Clock
#5

Oh yes, the plugin host’s just a simple demo, it doesn’t provide much of the info you’d get from a real host.


#6

[quote=“3mpty”]
I do getPlayHead()->getCurrentPosition(currentPositionInfo) inside my AudioProcessor class (is it normale that if I call it from the constructor Plugin Host crashes?). [/quote]
Did you check whether getPlayHead() returns a valid pointer (e.g. not 0)?

Chris


#7

[quote=“ckk”][quote=“3mpty”]
I do getPlayHead()->getCurrentPosition(currentPositionInfo) inside my AudioProcessor class (is it normale that if I call it from the constructor Plugin Host crashes?). [/quote]
Did you check whether getPlayHead() returns a valid pointer (e.g. not 0)?

Chris[/quote]

Did not check. Thank you for the tip :wink:


#8

Hi,

What do I have to modify to give the audio plugin host demo a tempo, and have that propogated to the vst plugins? I gather that I have to subclass AudioPlayHead but I still don’t understand all the interactions involved when using a filter graph in the context of the plugin host demo. I spent about 6 hours digging the forum, the juce source, and the plugin host source but am still having trouble understanding what might actually have to be done, and the implications of the changes.

Thanks,
Kurt


#9

Hey Kurt,

Make whatever class you want into an AudioPlayHead subclass and implement getCurrentPosition something like the following: (you could just make the FilterGraph inherit from AudioPlayHead if you wanted)

bool WhateverClass::getCurrentPosition(AudioPlayHead::CurrentPositionInfo& result) {
    
    //Fill these in as you please
    result.timeInSeconds = ...
    result.isPlaying = ...
    result.isRecording = ...
    result.timeSigDenominator = ...
    result.timeSigNumerator = ...
    result.bpm = ...
    
    return true; //not sure when it should be false
}

Then when the plugins are loaded just set their playhead to that object. If you used the FilterGraph you could do this in addFilter like this:

        if (node != nullptr)
        {
            node->getProcessor()->setPlayHead(this);
            node->properties.set ("x", x);
            node->properties.set ("y", y);
            changed();
        }

That should be it! :slight_smile:


#10

Shootz,

I get it now. I made the assumption that the AudioProcesesors that I added to a filter graph would HAVE a playhead. But they don’t. I assumed that since I could ‘play’ my softsynths in the plugin host demo that it was ‘playing’ - wrong.

So, I guess I have to subclass AudioPlayHead, override its getCurrentPosition method and fill in the CurrentPositionInfo structure, which is where I set the bpm among other things. Then modify FilterGraph.h/cpp and teach it to call setPlayHead on each AudioProcessor when they’re added to the graph.

I’ll go do that and report back…


#11

Thanks Graeme, I got it working. I did what you suggested and it works quite well. The only glitch I have is that since I’m not changing the time in the structure one of my drum machines freaks out. It probably wants to know where in time it is which I’m not providing but the softsynth sequencers are picking up the tempo at last.

So, I’ll now go investigate obtaining time info from the sample position etc.

Thanks,
Kurt


#12

You’re very welcome Kurt. Glad to hear you got it working. I’m not really sure what the best practice is for keeping track of time, but if you want to derive the seconds from a sample count you can make the FilterGraph also inherit from AudioIODeviceCallback and implement audioDeviceIOCallback, audioDeviceAboutToStart and audioDeviceStopped. You have to implement all 3 but you’re only really interested in audioDeviceIOCallback for this. Once you’ve done that then you add the FilterGraph as a callback for the deviceManager. (I’m not sure where it should be done in the demo but look for where the graph player is added as a callback)

Then each time audioDeviceIOCallback is called you just accumulate the number of samples in a member variable on the FilterGraph. Then it’s easy access in getCurrentPosition where you can divide by your current sample rate (you can get that from the deviceManager, not sure if the FilterGraph has a reference to the deviceManager so you may want to add a pointer to it on the class)

to get the seconds. You might find a better or easier way to do it, but this has worked for me.

Or if you don’t really care about sample accuracy or a specific timeline I imagine you could just get the current time using the Time class. But I’m not sure about this or any problems there might be in doing so.


#13

Thanks, I will try this as soon as I can. Your comments will make it MUCH easier!