What a basic explanation of how I'd start creating a plugin that played a sample every ⅛ th note, triggered by a midi note?

I am thinking of creating a plugin that outputs a pre-loaded sample every ⅛ th (eighth) note.
Like a “pulse” sample, playing every eighth note for 3 bars.

The sample would be triggered by a midi note, and then be output every eighth note for three bars thereafter. Like this, but for three bars (in the image below its 1/4 notes though!):
image

Whas the approach (in basic terms) to create this plugin?

E.g.

If midi note detected:
Wait until playhead is on next eighth note boundary and then start sequence by outputting 1st sample
Wait until playhead is on next boundary to output the next sample
Do for 3 bars
Repeat

Is looking at the playhead position all the time the best way to output on 1/8th note boundaries? I think some DAWs won’t even tell Juce where the playhead is.
And in the Juce settings, isMidiPlugin [/] or not?

Hi Ian,

I am no expert and am only just learning myself, but can hopefully point you in the right direction regarding a few things:

Detecting a MIDI note - in the ProcessBlock function inside the basic Juce plugin template there is a MidiBuffer which stores any Midi messages passed in from the DAW during that processBlock. To detect the Midi note you would iterate through the Midimessages buffer and use a conditional statement if there is an onNote message in the buffer.

outputting in 8th notes - The playhead position is not a reliable source for accurately coutning samples or time passed. The most relaiable timer you have is the ProcessBlock function. Theoretically, this should be called every number of samples the bufferSize is set to in the DAW.

so ideally, you would create a running timer that is added to every processBlock function call until it is equal an 8th note in samples (i.e. sample rate = 44100, bpm = 120 then an 8th note can be calculated as ((60.0 / 120.) * 44100) / 8.

in terms of actually playing loading and playing the sample, The Audio Programmer is an excellent resource for beginning to understand how to sample using Juce.

Build a Sampler VST Plug-in with JUCE Part 1 - Loading and Playing - YouTube

Hope this helps

1 Like

Thanks, some good tips in there. I’ve watched a dozen of Josh’s tutorials and they are very helpful, but the Sampler one I’ve not watched yet.
I wonder if I need to check the settings box isMidiPlugin or does a regular audio VST3 take in midi as well by default?

I believe you will need to select the options ‘plugin is a synth’, and ‘has MIDI input’. I don’t think there is a default operation for dealing with MIDI in the VST3 standard. That is all the good stuff that Juce deals with so we don’t have too!

Like always, I could be wrong though haha

An alternative approach you should consider is using the Tracktion library, which takes care of most of the under-the-hood audio thread stuff and gives you a much higher level API to work with. Starting out with Tracktion can be a bit of a pain, because it’s one more thing to learn and not as well documented as JUCE. But it will pay off in the long run, as the library is well developed and will prevent you from making a lot of mistakes.

Take a look at the Tracktion tutorials–one of them is a basic sampler, which should be of interest. They also have a ClickTrack object, which might do exactly what you’re looking for.

Be careful because you cannot rely on the buffersize to be static! prepareToPlay will give you a buffer size which is a maximum, but you’ll want to check the buffer you get in every call to ProcessBlock!

2 Likes

good tip, didn’t know that.

I guess I’ll have to rely on the user putting the midi note on where he wants the sample pulse triggered and assume that is right on the boundary. Then find out the number of samples in a 1/8th note, then just do a countdown to the next sample output.
Just have to remember the L & R channels and be aware of how I count samples.

@Ian-SAfc I have a series of 3 open source plugins that generate midi events (not samples) along the lines of what you want to do. The code listens for MMC events (start/stop of transport) and keeps track of beats, measures etc - and then quantizes the output of midi events (to 1/8, 1/4 or whatever). The plugins can override the host transport - so you can make them run even if the host transport is not (e.g. triggered by first note in for example - useful for live situations). All code is on github; feel free to DM me if you want info.

https://github.com/tomto66/Topiary-Beatz
https://github.com/tomto66/Topiary-Presetz
https://github.com/tomto66/Topiary-Riffz

If you want to understand what the plugins do you’ll find manuals here: https://topiaryplugins.wordpress.com/

2 Likes

Thanks. I had a look at that a little. Is TopiaryBeatsMasterComponent.cpp where you listen for MMC events and keep track of beats/measures?
I’ll have to look deeper into it. I’m in the newb stage so baby steps.
Your coding style is very neat and tidy though, which will make it easier. :+1:

sorry, @TWelby94 , just to clarify, do you mean (120 / 60) as opposed to ( 60 / 120)?

I think to find out how long a bar(measure) is, what about this formula:
If N is the number of beats per bar, one bar lasts 60*N/BPM seconds. In 4/4 time, N=4.

MasterComponent.cpp is the code for the “Master” tab in the GUI.

Calcs of measures and beats is done at various locations in TopiaryModel.cpp.h - look for calcMeasureBeat() :slight_smile: - that one is defined in TopiaryModel.h .

Listening to MCC commands is done in PluginProcessor.cpp.h - in the processBlock() method inthere.

1 Like