/**************************************************************************
Copyright (C) 2019 Arnaud Champenois arthelion@free.fr
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/
#pragma once
#include "../JuceLibraryCode/JuceHeader.h"
/*!
* Here are all constants for parameters definition
*
*/
#define MOLOSS_VERSION "24.01.04"
constexpr float NoiseMaxGain = 3.0f;
constexpr float LFORamp = 0.2f; // In s
constexpr float LFOMaxSpeed = 10.0f; // In Hz
constexpr float LFOMaxDelay = 5.0f; // In s
constexpr float TVFLowestCutoffFrequency = 10.0f; // In Hz
constexpr float TVFHighestCutoffFrequency = 20000.0f; // In Hz
constexpr float TVFMaxCutoffPower = 3.0f; // same in log10(Hz/20)
constexpr float TVFMaxLowCutPower = 2.5f; // in log10(Hz/20)
constexpr float TVFDefaultResonance = (1.0f / MathConstants<float>::sqrt2);
constexpr float TVFKeyFollowMaxDepth = 0.04f; // in log10(Hz/20) per note
constexpr float TVFMaxResonance = 10.0f;
constexpr float TVFKeyFollowMaxResonance = 0.5f;
constexpr float TVAKeyFollowMaxDepth = 0.014f; // In level unity per note
constexpr float ADSRMinAttackRelease = 0.001f; // in s, to avoid plops
constexpr float ADSRAttackKFMaxDepth = 0.05f; // In s per note
constexpr float ADSRMaxVeloDepth = 1.5f; // We allow to saturate
constexpr float ADSRMaxRelease = 10.0f; // in seconds
constexpr float PitchMaxLFODepth = 5.0f; // In semitones
constexpr float PitchMaxADSRDepth = 12.0f; // In semitones
constexpr float ChorusMinDepth = 0.001f;
constexpr float ChorusMaxDepth = 0.075f;
constexpr float ChorusMinFreq = 0.1f; // in Hz
constexpr float ChorusMaxFreq = 10.0f; // in Hz
constexpr float ChorusFreqFactor = 1.001f; // between left & right LFO
constexpr float ChorusDefaultDelay = 0.01f; // in s
constexpr float MaxDelayTime = 1.0f; // s
constexpr float MaxGain = 1.5f;
// Adjust polyhony here
constexpr int POLYPHONY = 16;
// Number of voices.
// Careful : changing this doesn't automatically add tabs to the GUI !
// The automated gui is not coded...
constexpr int VCO_NUMBER = 4;
// Fake midi values to identify those as controllers, in order to simplify code
constexpr int AftrTouchCtrl = 254;
constexpr int PitchWheelCtrl = 255;
constexpr int ModWheelCtrl = 1;
// Random phase instability
// Sine component
constexpr double RndPhaseShiftPeriodMin = 13.0; // s for one sine drift period
constexpr double RndPhaseShiftPeriodMax = 30.0; // s for one sine drift period
constexpr double RndPhaseSinCoef = 0.001; // max modulation coefficient
// White noise component
constexpr double RndPhaseNoiseCoef = 0.005; // max modulation coefficient
constexpr double KFNoteSplit = 56.0;
/*!
* Appends a counter to a given name
*
* \param name The name
* \param count The counter
* \return <name><counter>
*/
inline std::string countedName(std::string name, int count) {
std::ostringstream sstream;
sstream << name << count;
return sstream.str();
}
class MolossLogger {
#ifdef LOG_FILE
public:
MolossLogger() :
fl(File("D:/Temp/MOLOSS.log"), "Welcome to MOLOSS", 1000)
{}
void log(const String& str) {
fl.logMessage(str);
}
private:
FileLogger fl;
#else
public:
MolossLogger() {}
void log(const String&) {
}
#endif
};
namespace Moloss {
constexpr std::array<const char*, 15> syncStringValues = { "1/32T", "1/32", "1/32D", "1/16T","1/16","1/16D", "1/8T","1/8","1/8D", "1/4T", "1/4","1/4D", "1/2T", "1/2","1/2D" };
constexpr std::array<float, 15> conversionFactor = { 12.0, 8.0, 16.0/3.0, 6.0, 4.0, 8.0/3.0, 3.0, 2.0, 4.0/3.0, 1.5, 1.0, 2.0/3.0, 0.75, 0.5, 1.0/3.0 };
inline float getSyncFreq(float tempo, float normalizedValue, bool inverted) {
if (inverted) normalizedValue = 1.0f - normalizedValue;
int index;
if (normalizedValue == 1.0f)
index = 14;
else
index = (int)floor(conversionFactor.size()*normalizedValue);
return inverted? tempo / 60.0f*conversionFactor[index]: 60.0f / (tempo*conversionFactor[index]);
}
inline double clip(double a, double min, double max) {
if (a > max) return max;
if (a < min) return min;
return a;
}
inline bool setIfChanged(double& valueToSet, double newValue,bool&hasChangedFlag) {
if (valueToSet != newValue) {
valueToSet = newValue;
hasChangedFlag = true;
return true;
}
return false;
}
}