Hey all,
I’m having a hard time understanding how to get access to the pitchwheel position in the SynthesiserVoice::renderNextBlock()
.
In my inherited class i have the pitchbend working in the startNote() method. That’s simple enough becuase currentPitchWheelPosition
is an argument:
void MySynthVoice::startNote (int midiNoteNumber, float velocity, SynthesiserSound*, int currentPitchWheelPosition)
So i can play a pitch shifted note, but can’t shift pitch during playback.
Is void MySynthVoice::pitchWheelMoved(int newPitchWheelValue)
a callback to be called during the renderNextBlock()? API says
This will be called during the rendering callback, so must be fast and thread-safe.
but, then where do i get the value for the argument newPitchWheelValue
?
I fear i’m overlooking something incredibly straightforward.
// Pitch Wheel methods:
void MySynthVoice::pitchWheelMoved(int newPitchWheelValue)
{
setPitchBend(newPitchWheelValue);
shiftHz = calcShiftHz( pitchBendCents() );
}
/// Pitch wheel position to pitchBend up or down
void MySynthVoice::setPitchBend(int pitchWheelPos)
{
if (pitchWheelPos > 8192)
{
// shifting up
pitchBend = float(pitchWheelPos - 8192) / (16383 - 8192);
}
else
{
// shifting down
pitchBend = float(8192 - pitchWheelPos) / -8192; // negative number
}
}
/// calculates pitch wheel's shift in hz
float MySynthVoice::calcShiftHz(float centsOffset)
{
return std::powf(2.0f, centsOffset / 1200.0f);
}
/// maps pitchwheel min/max positions to bend in cents
float MySynthVoice::pitchBendCents()
{
if (pitchBend >= 0.0f)
{
// shifting up
return pitchBend * pitchBendUpSemitones * 100;
}
else
{
// shifting down
return pitchBend * pitchBendDownSemitones * 100;
}
}
void MySynthVoice::startNote (int midiNoteNumber, float velocity, SynthesiserSound*, int currentPitchWheelPosition)
{
playing = true;
ending = false;
setPortamentoTime(sampleRate, *portamentoAmount);
// Sets Amp ADSR for each note
setAmpADSRValues();
setFilterADSRValues();
// Set Sub Octave
incrementDenominator = subOscParamControl.subOctaveSelector(subOctave);
// Converts incoming MIDI note and pitch bend to frequency
setPitchBend( currentPitchWheelPosition );
freq = MidiMessage::getMidiNoteInHertz(midiNoteNumber) * calcShiftHz( pitchBendCents() );
portamento.setTargetValue(freq);
// Envelopes
// Amp envelope
env.noteOn(); // Start envelope
//Filter Envelope
filtEnv.noteOn();
filtLFOClickingEnv.noteOn();
// Velocity
vel = velocity;
}
renderNextBlock, minus all the code not relevant to pitchwheel/bending:
void MySynthVoice::renderNextBlock(AudioSampleBuffer& outputBuffer, int startSample, int numSamples)
{
if (playing) // check to see if this voice should be playing
{
for (int sampleIndex = startSample; sampleIndex < (startSample+numSamples); sampleIndex++)
{
// Portamento processing
float portaFreq = portamento.getNextValue();
// ***
// *** HERE IS WHERE I WANT TO do something like: ***
// setPitchBend( currentPitchWheelPosition ); // How do i get the pitchWheelPos here?
// portaFreq *= calcShiftHz( pitchBendCents() )
// ***
// ***
// Main Oscillators
wtSine.setIncrement (portaFreq);
wtSaw.setIncrement (portaFreq);
wtSpike.setIncrement (portaFreq);
subOsc.setIncrement (portaFreq, incrementDenominator);
// Mod Oscs
ringMod.modFreq (portaFreq, ringModPitch);
freqShift.modFreq (portaFreq, freqShiftPitch);
sAndH.modFreq (portaFreq, sAndHPitch);
// more post-pitch-bend code here
} // END DSP!!
} // END if (playing)
} // END ProcessBlock
Thanks in advance. If you want to see the full code it’s available here.
Cheers!