Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions Fledge.jucer
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>

<JUCERPROJECT id="hEWOgg" name="Fledge" projectType="audioplug" useAppConfig="0"
addUsingNamespaceToJuceHeader="0" jucerFormatVersion="1" companyName="Rainbow Circuit"
version="1.0.0" pluginCharacteristicsValue="pluginIsSynth,pluginWantsMidiIn">
<JUCERPROJECT id="hEWOgg" name="Fledge" projectType="audioplug" addUsingNamespaceToJuceHeader="0"
jucerFormatVersion="1" companyName="Rainbow Circuit" version="1.0.0"
pluginCharacteristicsValue="pluginIsSynth,pluginWantsMidiIn"
pluginFormats="buildAU,buildStandalone,buildUnity,buildVST3"
pluginVSTNumMidiInputs="16" pluginAUIsSandboxSafe="1">
<MAINGROUP id="HjcJ18" name="Fledge">
<GROUP id="{E95012C8-BA53-E04B-38D3-3734F17061CD}" name="Utility">
<FILE id="pAkmnd" name="GraphicsUtility.h" compile="0" resource="0"
Expand Down Expand Up @@ -120,8 +122,8 @@
<EXPORTFORMATS>
<XCODE_MAC targetFolder="Builds/MacOSX">
<CONFIGURATIONS>
<CONFIGURATION isDebug="1" name="Debug" targetName="Fledge"/>
<CONFIGURATION isDebug="0" name="Release" targetName="Fledge"/>
<CONFIGURATION isDebug="1" name="Debug" targetName="Fledge" optimisation="3"/>
<CONFIGURATION isDebug="0" name="Release" targetName="Fledge" recommendedWarnings="LLVM"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_audio_basics" path="../../../JUCE/modules"/>
Expand Down
55 changes: 55 additions & 0 deletions Presets/Taco Hell.preset
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>

<Parameters op0XPos="74.25" op0YPos="219.2124938964844" op1XPos="74.25" op1YPos="101.1750030517578"
op2XPos="195.75" op2YPos="219.2124938964844" op3XPos="195.75"
op3YPos="101.1750030517578" presetName="Taco Hell">
<PARAM id="amplitude0" value="98.0"/>
<PARAM id="amplitude1" value="16.5"/>
<PARAM id="amplitude2" value="22.10000038146973"/>
<PARAM id="amplitude3" value="3.700000047683716"/>
<PARAM id="attack0" value="0.5"/>
<PARAM id="attack1" value="0.5"/>
<PARAM id="attack2" value="60.5"/>
<PARAM id="attack3" value="144.5"/>
<PARAM id="decay0" value="1040.719970703125"/>
<PARAM id="decay1" value="1058.0"/>
<PARAM id="decay2" value="908.3599853515625"/>
<PARAM id="decay3" value="1040.719970703125"/>
<PARAM id="fixed0" value="20.0"/>
<PARAM id="fixed1" value="20.0"/>
<PARAM id="fixed2" value="20.0"/>
<PARAM id="fixed3" value="20.0"/>
<PARAM id="gain" value="1.072883605957031e-6"/>
<PARAM id="globalAttack" value="100.0"/>
<PARAM id="globalDecay" value="100.0"/>
<PARAM id="globalModIndex" value="100.0"/>
<PARAM id="globalRelease" value="100.0"/>
<PARAM id="globalSustain" value="100.0"/>
<PARAM id="opMode0" value="0.0"/>
<PARAM id="opMode1" value="0.0"/>
<PARAM id="opMode2" value="0.0"/>
<PARAM id="opMode3" value="0.0"/>
<PARAM id="operator0Routing" value="2.0"/>
<PARAM id="operator1Routing" value="0.0"/>
<PARAM id="operator2Routing" value="8.0"/>
<PARAM id="operator3Routing" value="0.0"/>
<PARAM id="outputRouting" value="5.0"/>
<PARAM id="phase0" value="9.609999656677246"/>
<PARAM id="phase1" value="29.15999984741211"/>
<PARAM id="phase2" value="72.25"/>
<PARAM id="phase3" value="39.04000091552734"/>
<PARAM id="ratio0" value="1.0"/>
<PARAM id="ratio1" value="3.5"/>
<PARAM id="ratio2" value="3.5"/>
<PARAM id="ratio3" value="5.0"/>
<PARAM id="release0" value="829.1199951171875"/>
<PARAM id="release1" value="1568.0"/>
<PARAM id="release2" value="722.0"/>
<PARAM id="release3" value="2178.0"/>
<PARAM id="sustain0" value="0.0"/>
<PARAM id="sustain1" value="0.0"/>
<PARAM id="sustain2" value="0.0"/>
<PARAM id="sustain3" value="0.0"/>
<PARAM id="voiceCount" value="1.0"/>
<PARAM id="voiceSlew" value="0.0"/>
</Parameters>
60 changes: 60 additions & 0 deletions Presets/pan_drum keys.preset
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>

<Parameters op0XPos="74.25" op0YPos="219.2124938964844" op1XPos="74.25" op1YPos="101.1750030517578"
op2XPos="195.75" op2YPos="219.2124938964844" op3XPos="195.75"
op3YPos="101.1750030517578" presetName="pan_drum keys">
<PARAM id="amplitude0" value="100.0"/>
<PARAM id="amplitude1" value="2.0"/>
<PARAM id="amplitude2" value="100.0"/>
<PARAM id="amplitude3" value="24.60000038146973"/>
<PARAM id="attack0" value="12.5"/>
<PARAM id="attack1" value="37.18000030517578"/>
<PARAM id="attack2" value="84.5"/>
<PARAM id="attack3" value="0.0"/>
<PARAM id="decay0" value="1104.5"/>
<PARAM id="decay1" value="3169.89990234375"/>
<PARAM id="decay2" value="578.0"/>
<PARAM id="decay3" value="1040.7099609375"/>
<PARAM id="fixed0" value="20.0"/>
<PARAM id="fixed1" value="20.0"/>
<PARAM id="fixed2" value="20.0"/>
<PARAM id="fixed3" value="20.0"/>
<PARAM id="globalAttack" value="100.0"/>
<PARAM id="globalDecay" value="100.0"/>
<PARAM id="globalModIndex" value="100.0"/>
<PARAM id="globalRelease" value="100.0"/>
<PARAM id="globalSustain" value="100.0"/>
<PARAM id="opMode0" value="0.0"/>
<PARAM id="opMode1" value="0.0"/>
<PARAM id="opMode2" value="0.0"/>
<PARAM id="opMode3" value="0.0"/>
<PARAM id="operator0Routing" value="2.0"/>
<PARAM id="operator1Routing" value="0.0"/>
<PARAM id="operator2Routing" value="8.0"/>
<PARAM id="operator3Routing" value="0.0"/>
<PARAM id="outputRouting" value="5.0"/>
<PARAM id="phase0" value="0.0"/>
<PARAM id="phase1" value="45.55999755859375"/>
<PARAM id="phase2" value="0.0"/>
<PARAM id="phase3" value="0.0"/>
<PARAM id="ratio0" value="1.0"/>
<PARAM id="ratio1" value="12.0"/>
<PARAM id="ratio2" value="1.0"/>
<PARAM id="ratio3" value="0.9999999403953552"/>
<PARAM id="release0" value="788.8999633789062"/>
<PARAM id="release1" value="1724.099975585938"/>
<PARAM id="release2" value="1442.989990234375"/>
<PARAM id="release3" value="1186.890014648438"/>
<PARAM id="sustain0" value="12.0"/>
<PARAM id="sustain1" value="22.99999809265137"/>
<PARAM id="sustain2" value="9.999999046325684"/>
<PARAM id="sustain3" value="32.00000381469727"/>
<PARAM id="voiceCount" value="1.0"/>
<PARAM id="voiceSlew" value="0.0"/>
<PARAM id="gain"/>
<PARAM id="globalVelocity" value="0.7977030873298645"/>
<PARAM id="velocity0"/>
<PARAM id="velocity1"/>
<PARAM id="velocity2"/>
<PARAM id="velocity3"/>
</Parameters>
60 changes: 60 additions & 0 deletions Presets/simple_sine.preset
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>

<Parameters op0XPos="135.0" op0YPos="269.8000183105469" op1XPos="135.0" op1YPos="193.9187469482422"
op2XPos="135.0" op2YPos="118.0374984741211" op3XPos="135.0" op3YPos="42.15625"
presetName="simple_sine">
<PARAM id="amplitude0" value="100.0"/>
<PARAM id="amplitude1" value="0.0"/>
<PARAM id="amplitude2" value="0.0"/>
<PARAM id="amplitude3" value="0.0"/>
<PARAM id="attack0" value="24.5"/>
<PARAM id="attack1" value="499.9999694824219"/>
<PARAM id="attack2" value="499.9999694824219"/>
<PARAM id="attack3" value="499.9999694824219"/>
<PARAM id="decay0" value="0.0"/>
<PARAM id="decay1" value="499.9999694824219"/>
<PARAM id="decay2" value="499.9999694824219"/>
<PARAM id="decay3" value="499.9999694824219"/>
<PARAM id="fixed0" value="20.0"/>
<PARAM id="fixed1" value="20.0"/>
<PARAM id="fixed2" value="20.0"/>
<PARAM id="fixed3" value="20.0"/>
<PARAM id="globalAttack" value="100.0"/>
<PARAM id="globalDecay" value="100.0"/>
<PARAM id="globalModIndex" value="100.0"/>
<PARAM id="globalRelease" value="100.0"/>
<PARAM id="globalSustain" value="100.0"/>
<PARAM id="opMode0" value="0.0"/>
<PARAM id="opMode1" value="0.0"/>
<PARAM id="opMode2" value="0.0"/>
<PARAM id="opMode3" value="0.0"/>
<PARAM id="operator0Routing" value="2.0"/>
<PARAM id="operator1Routing" value="4.0"/>
<PARAM id="operator2Routing" value="8.0"/>
<PARAM id="operator3Routing" value="0.0"/>
<PARAM id="outputRouting" value="1.0"/>
<PARAM id="phase0" value="0.0"/>
<PARAM id="phase1" value="0.0"/>
<PARAM id="phase2" value="0.0"/>
<PARAM id="phase3" value="0.0"/>
<PARAM id="ratio0" value="1.0"/>
<PARAM id="ratio1" value="0.75"/>
<PARAM id="ratio2" value="0.9999999403953552"/>
<PARAM id="ratio3" value="0.9999999403953552"/>
<PARAM id="release0" value="22.59000015258789"/>
<PARAM id="release1" value="999.9999389648438"/>
<PARAM id="release2" value="999.9999389648438"/>
<PARAM id="release3" value="999.9999389648438"/>
<PARAM id="sustain0" value="100.0"/>
<PARAM id="sustain1" value="80.0"/>
<PARAM id="sustain2" value="80.0"/>
<PARAM id="sustain3" value="80.0"/>
<PARAM id="voiceCount" value="1.0"/>
<PARAM id="voiceSlew" value="0.0"/>
<PARAM id="gain"/>
<PARAM id="globalVelocity" value="0.7977030873298645"/>
<PARAM id="velocity0"/>
<PARAM id="velocity1"/>
<PARAM id="velocity2"/>
<PARAM id="velocity3"/>
</Parameters>
43 changes: 33 additions & 10 deletions Source/Operator.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

#include "Operator.h"
#include "VoiceProcessor.h"

void FMOperator::prepareToPlay(double sampleRate, float samplesPerBlock, int numChannels)
{
Expand All @@ -15,6 +16,8 @@ void FMOperator::prepareToPlay(double sampleRate, float samplesPerBlock, int num
globalModIndexSmoothed.reset(sampleRate, 0.001);
}

MidiProcessor midi;

void FMOperator::startNote()
{
ampEnvelope.noteOn();
Expand All @@ -25,17 +28,37 @@ void FMOperator::stopNote()
ampEnvelope.noteOff();
}


void FMOperator::setEnvelope(float attackInMs, float decayInMs, float sustainInFloat, float releaseInMs, bool isLooping)
{
ampEnvelope.setEnvelopeParameters(attackInMs, decayInMs, sustainInFloat, releaseInMs);
}

void FMOperator::setNoteNumber(float noteNumber)
{
noteFrequency = juce::MidiMessage::getMidiNoteInHertz(noteNumber);
noteNumberCents = noteNumber * 100.0f;
setPlayedFrequency();
}
void FMOperator::setPitchbend(int pitchWheelPosition)
{
float pitchWheelFloat = pitchWheelPosition * 1.0f;
pitchWheelCents = juce::jmap(pitchWheelFloat, 0.0f, 16383.0f, -4800.0f, 4800.0f);
setPlayedFrequency();
}
void FMOperator::setPlayedFrequency()
{
playedFrequency = midi.getMidiFrequencyCents(noteNumberCents + pitchWheelCents);
noteFrequencySmoothed.setTargetValue(playedFrequency);
}
void FMOperator::setVelocity(float velocity)
{
noteVelocity = std::pow(velocity, 2);
noteVelocitySmoothed.setTargetValue(noteVelocity);
}
void FMOperator::setPressure(float pressure)
{
channelPressure = (std::tanh(pressure * juce::MathConstants<float>::pi) * 0.25f) + 0.75f;//this still produces some truncation distortion, needs reworking, 7 bits just isnt alot of resolution
channelPressureSmoothed.setTargetValue(channelPressure);
}

void FMOperator::setOperator(float ratio, float fixed, bool isFixed, float amplitude, float phase, float globalModIndex)
{
ratioSmoothed.setTargetValue(ratio);
Expand All @@ -51,16 +74,16 @@ float FMOperator::processOperator(float phase1, float phase2, float phase3, floa
envParameters.sustain = sustainSmoothed.getNextValue();
// ampEnvelope.setParameters(envParameters);

frequency = noteFrequency * ratioSmoothed.getNextValue();
frequency = noteFrequencySmoothed.getNextValue() * ratioSmoothed.getNextValue();
if (isFixed) frequency = fixedSmoothed.getNextValue();
operatorAngle = frequency/sampleRate;

float modulatorPhase = phase1 + phase2 + phase3 + phase4;
float twopi = juce::MathConstants<float>::twoPi;
float envelope = ampEnvelope.getNextSample();
float phaseOffset = phaseSmoothed.getNextValue();
float modIndex = std::pow(2.0f, globalModIndexSmoothed.getNextValue() / 100.0f) * 8.0f;
float waveform = std::sin((operatorPhase + phaseOffset) * twopi + (modulatorPhase * modIndex)) * envelope; // 8 is the mod index
modulatorPhase = phase1 + phase2 + phase3 + phase4;
twopi = juce::MathConstants<float>::twoPi;
envelope = ampEnvelope.getNextSample() * noteVelocitySmoothed.getNextValue() * channelPressureSmoothed.getNextValue();//multiple amp envelope by velocity
phaseOffset = phaseSmoothed.getNextValue();
modIndex = std::pow(2.0f, globalModIndexSmoothed.getNextValue() / 100.0f) * 8.0f;
waveform = std::sin((operatorPhase + phaseOffset) * twopi + (modulatorPhase * modIndex)) * envelope; // 8 is the mod index

// accumulate and wrap
operatorPhase += operatorAngle;
Expand Down
18 changes: 15 additions & 3 deletions Source/Operator.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ class FMOperator

void setEnvelope(float attack, float decay, float sustain, float release, bool isLooping);
void setNoteNumber(float noteNumber);
void setPitchbend(int PitchWheelPostion);
void setPlayedFrequency();
void setVelocity(float velocity);
void setPressure(float pressure);
void setOperator(float ratio, float fixed, bool isFixed, float amplitude, float phase, float globalModIndex);
float processOperator(float phase1, float phase2, float phase3, float phase4);

Expand All @@ -23,14 +27,22 @@ class FMOperator
double operatorPhase = 0.0, operatorAngle = 0.0;
double prevInputSum = 0.0;
float modulationIndex = 1.0f;
float noteFrequency, frequency, ratio, fixed;
float playedFrequency, noteNumberCents, frequency, ratio, fixed, noteVelocity;
float channelPressure = 1.0f;
float pitchWheelCents = 0.0f;
bool isFixed = false;

float targetFrequency = 0.0f;
float currentFrequency = 0.0f;
float frequencySmoothingTimeMs = 100.0f;
float frequencySmoothingCoeff = 0.0f;


juce::SmoothedValue<float> ratioSmoothed, fixedSmoothed, amplitudeSmoothed, phaseSmoothed, sustainSmoothed, globalModIndexSmoothed;
float modulatorPhase;
float twopi;
float envelope;//multiple amp envelope by velocity
float phaseOffset;
float modIndex;
float waveform; // 8 is the mod index

juce::SmoothedValue<float> ratioSmoothed, fixedSmoothed, noteFrequencySmoothed, amplitudeSmoothed, phaseSmoothed, sustainSmoothed, globalModIndexSmoothed, noteVelocitySmoothed, channelPressureSmoothed;
};
4 changes: 2 additions & 2 deletions Source/PluginProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ void FledgeAudioProcessor::changeProgramName (int index, const juce::String& new
void FledgeAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
{

for (int v = 0; v < 8; v++)
for (int v = 0; v < 16; v++)
synth.addVoice(new SynthVoice());

synth.addSound(new SynthSound());
Expand Down Expand Up @@ -142,7 +142,7 @@ bool FledgeAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) c
void FledgeAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{
juce::ScopedNoDenormals noDenormals;
synth.setVoiceCount(params->voiceCount->get());
synth.setVoiceCount(8);
for (int oper = 0; oper < 4; oper++){
for (int v = 0; v < synth.getNumVoices(); v++)
{
Expand Down
13 changes: 8 additions & 5 deletions Source/VoiceProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ void SynthVoice::startNote(int midiNoteNumber, float velocity, juce::Synthesiser
{
op[i].startNote();
op[i].setNoteNumber(midiNoteNumber);
op[i].setVelocity(velocity);
op[i].setPitchbend(currentPitchWheelPosition);//init pitchWheel position
op[i].setPressure(1.0f);//init pressure value for no channel pressure
}
}

Expand All @@ -45,11 +48,11 @@ void SynthVoice::stopNote(float velocity, bool allowTailOff)

void SynthVoice::setEnvelope(int index, float attack, float decay, float sustain, float release, float globalAttack, float globalDecay, float globalSustain, float globalRelease)
{
float attackScaled = std::pow(2.0f, globalAttack / 100.0f) * attack;
float decayScaled = std::pow(2.0f, globalDecay / 100.0f) * decay;
attackScaled = std::pow(2.0f, globalAttack / 100.0f) * attack;
decayScaled = std::pow(2.0f, globalDecay / 100.0f) * decay;

float sustainScaled = juce::jlimit(0.0f, 1.0f, (globalSustain / 100.0f) * (sustain/100.0f));
float releaseScaled = std::pow(2.0f, globalRelease / 100.0f) * release;
sustainScaled = juce::jlimit(0.0f, 1.0f, (globalSustain / 100.0f) * (sustain/100.0f));
releaseScaled = std::pow(2.0f, globalRelease / 100.0f) * release;

op[index].ampEnvelope.setEnvelopeParameters(attackScaled, decayScaled, sustainScaled, releaseScaled);
}
Expand Down Expand Up @@ -87,7 +90,7 @@ void SynthVoice::renderNextBlock(juce::AudioBuffer<float> &outputBuffer, int sta
op2 * op0Gain[2],
op3 * op0Gain[3]);

float output = op0 * outputGain[0] +
output = op0 * outputGain[0] +
op1 * outputGain[1] +
op2 * outputGain[2] +
op3 * outputGain[3];
Expand Down
Loading