# How to detune voices

#1

Hello everyone,

lets say I have a Synthesiser with 8 Voices, how am I supposed to detune them all?

#2

Are you / your plugin / app synthesising the voices?

If so then it’s quite trivial. Just change the frequency of each of your oscillators by some degree. If you want to detune by say +5cent.

double root = std::exp (std::log(2) / 1200); // cent root
double cent = pow(root, 5); // raise to the number of cent

double detunedFreq = originalFreq * cent;

Where std::exp (std::log(2) / 1200) is the 12th hundred root of an octave or 100th root of a note.

#3

Where did that equation for pitch come from?

#4

I worked it out.
I have changed to be clearer as it looked a little dirty…
The math is just an given octave is double its base frequency and on a logarithmic scale we use log(2) and that a cent is just 100th root of a note and a note is just the 12th root of an octave then we just need the exponent of log(2) / 1200
The exponent is a number when in this case is multiplied by itself 1200 times = 2
Then take the cent root and raise it to the power of the number of scent

This should also work if you want to work in semi-tones

double root = std::exp (std::log(2) / 12); // semi-tone root
double tones = pow(root, 0.05); // raise to the number of semi tones

#5

It’s maybe simpler to just detune the note in the linear MIDI Note scale before calculating the frequency.

#6
double midiNoteToFrequency(double midiNote)
{
return std::exp ((midiNote-69) * std::log(2) / 12) * 440;
}

And while we are on that subject you can do that like this…
You can supply a midi note of say 44.05

#7

FYI we also provide MidiMessage::getMidiNoteInHertz()

#8

First, thank you all for your participation

Are you / your plugin / app synthesising the voices?
I currently have a regular Synthesiser set up like this

mySynth.clearVoices();

for (int i = 0; i < 16; i++)
{
}

mySynth.clearSounds();

And this is my SynthVoice Class

#pragma once

#include "SynthSound.h"
#include "maximilian.h"

class SynthVoice : public SynthesiserVoice
{
public:
bool canPlaySound(SynthesiserSound* sound) {
return dynamic_cast<SynthSound*>(sound) != nullptr;
}

void startNote(int midiNoteNumber, float velocity, SynthesiserSound* sound, int currentPitchWheelPosition) {

env1.trigger = 1;
level = velocity;
frequency = MidiMessage::getMidiNoteInHertz(midiNoteNumber);
}

void stopNote(float velocity, bool allowTailOff) {
env1.trigger = 0;
allowTailOff = true;

if (velocity == 0)
clearCurrentNote();
}

void pitchWheelMoved(int newPitchWheelValue) {

}

void controllerMoved(int controllerNumber, int newControllerValue) {

}

void renderNextBlock(AudioBuffer<float> &outputBuffer, int startSample, int numSamples) {
env1.setAttack(2000);
env1.setDecay(500);
env1.setSustain(0.8);
env1.setRelease(2000);

for (int sample = 0; sample < numSamples; sample++) {

double theWave = osc1.saw(frequency + (rand() % 5)); //DETUNING
double theSound = env1.adsr(theWave, env1.trigger) * level;
double filteredSound = filter1.lores(theSound, 100, 0.1);

for (int channel = 0; channel < outputBuffer.getNumChannels(); channel++) {
}
++startSample;
}
}

private:
double level, frequency;

maxiOsc osc1;
maxiEnv env1;
maxiFilter filter1;

};

So how do I set up multiple voices so I can detune them all? Do I add multiple Oscillators, add all the detuned signals together and divide them with the number of Osc’s?
(I’m using the Oscillator from Maximilian)

#9

First of all it may make more sense to have a little restructuring, either put your filters,envs and oscillators, detune amount into arrays or have a voice structure with them as members you can then do something like this

for (int sample = 0; sample < numSamples; sample++) {

float sum = 0.0;

for(int v=0; v< numVoice; c++)
{
float theWave = osc[v].saw(frequency + detune[v]); //DETUNING
float theSound = env[v].adsr(theWave, env[v].trigger) * level;
float filteredSound = filter[v].lores(theSound, 100, 0.1);
sum += theSound;
}

for (int channel = 0; channel < outputBuffer.getNumChannels(); channel++) {