It works fine if I include the GUI.
It requires midi notes as taps.
Any suggestions would be most welcome.
Thanks.
Code: Select all
/** \file
* Tap Tempo
* For Cantabile
*/
#include "./Resources/dsp-scripts/library/Midi.hxx"
string name="Tap Tempo";
string author="Cousin Itt";
string description="Bind to Cantabile's tempo";
// parameters definition
array<string> inputParametersNames={"Min", "Max", "Start Tempo"};
array<double> inputParameters(inputParametersNames.length);
array<double> inputParametersMin={5,5,5};
array<double> inputParametersMax={300,300,300};
array<double> inputParametersDefault={115,130,125};
array<int> inputParametersSteps={296,296,296};
array<string> outputParametersNames={"Tempo"};
array<double> outputParameters(outputParametersNames.length);
array<double> outputParametersMin={5};
array<double> outputParametersMax={300};
MidiEvent midiEvent;
uint8 maxNumTaps = 8;
uint8 minNumTapsForTempo = 3;
uint16 minTempo;
uint16 maxTempo;
float maxTempoTapDuration;
float minTempoTapDuration;
float lastTapTime;
float tapTime;
float tapDuration;
uint16 startTempo = 125;
uint16 lastStartTempo;
float tempo;
float lastTempo;
uint blockCount; // number of blocks since initialisation
float blockSeconds; // seconds in a block
array<float> tapArray;
void initialise() {
}
void processBlock(BlockData& data)
{
blockSeconds = maxBlockSize / sampleRate;
blockCount++;
for(uint i=0;i<data.inputMidiEvents.length;i++)
{
midiEvent = data.inputMidiEvents[i];
// Check for Note On
MidiEventType type = MidiEventUtils::getType(midiEvent);
if(type==kMidiNoteOn) {
addTap(getSeconds(midiEvent.timeStamp));
}
}
}
void updateInputParametersForBlock(const TransportInfo@ )
{
minTempo = uint16(inputParameters[0]+.5);
maxTempo = uint16(inputParameters[1]+.5);
maxTempoTapDuration = 60/float(minTempo);
minTempoTapDuration = 60/float(maxTempo);
uint16 curStartTempo = uint16(inputParameters[2]+.5);
if(curStartTempo != lastStartTempo) {
tempo = float(curStartTempo);
lastStartTempo = curStartTempo;
}
}
float getSeconds(float timeStamp) {
float seconds = blockCount * blockSeconds + timeStamp/sampleRate;
return seconds;
}
void addTap(float tapTime) {
float tapDuration = tapTime - lastTapTime;
if(tapDuration < minTempoTapDuration || tapDuration > maxTempoTapDuration) {
//treat as start of new tap tempo
lastTapTime = tapTime;
tapArray = {tapTime};
}
else {
lastTapTime = tapTime;
tapArray.sortDesc();
if(tapArray.length ==maxNumTaps) tapArray.removeLast();
tapArray.insertAt(0, tapTime);
if(tapArray.length >= minNumTapsForTempo) {
tempo = 60 / ((tapArray[0] - tapArray[tapArray.length -1]) / (tapArray.length - 1));
}
}
}
void computeOutputData() {
if(tempo != lastTempo) {
outputParameters[0] = tempo;
lastTempo = tempo;
}
}