organize voice profile + tweaks
This commit is contained in:
@@ -107,5 +107,14 @@ target_link_libraries(metabolus
|
||||
RtMidi::rtmidi
|
||||
yaml-cpp
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
# needed some different calls here
|
||||
if (WIN32)
|
||||
|
||||
else()
|
||||
target_link_libraries(metabolus
|
||||
PRIVATE
|
||||
atomic
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -14,3 +14,15 @@ stereoMode: 2
|
||||
|
||||
# number of samples per audio buffer
|
||||
bufferSize: 512
|
||||
|
||||
|
||||
# synth settings
|
||||
|
||||
#define SYNTH_PITCH_STANDARD 440.0f // frequency of home pitch
|
||||
#define SYNTH_MIDI_HOME 69 // midi note index of home pitch
|
||||
#define SYNTH_NOTES_PER_OCTAVE 12
|
||||
|
||||
# midi home note (usually A4=69) = pitchStandard hz (usually 440 or 432 hz)
|
||||
pitchStandard: 440.0
|
||||
midi_home: 69
|
||||
notesPerOctave: 12 # changes to this give some interesting non-western harmonics
|
||||
|
||||
@@ -4,51 +4,46 @@
|
||||
|
||||
# sequences in the form [x, x, x] denote [setValue, sliderMinimum, sliderMaximum]
|
||||
|
||||
version: 0x0003
|
||||
|
||||
# deprecated, useless
|
||||
Osc1Freq: [100, 20, 600]
|
||||
version: 0x04
|
||||
|
||||
# wavetable selections
|
||||
OscWaveSelector1: 2
|
||||
OscWaveSelector2: 3
|
||||
|
||||
# Frequency parameters
|
||||
MasterOctaveOffset: [0, -5, 5]
|
||||
MasterSemitoneOffset: [0, -12, 12]
|
||||
MasterPitchOffset: [0, -100, 100]
|
||||
Osc1OctaveOffset: [0, -5, 5]
|
||||
Osc1SemitoneOffset: [0, -12, 12]
|
||||
Osc1PitchOffset: [1.34, -100, 100]
|
||||
Osc2OctaveOffset: [1, -5, 5]
|
||||
Osc2SemitoneOffset: [0, -12, 12]
|
||||
Osc2PitchOffset: [12.86, -100, 100]
|
||||
Osc3OctaveOffset: [1, -5, 5]
|
||||
Osc3SemitoneOffset: [7, -12, 12]
|
||||
Osc3PitchOffset: [-8.79, -100, 100]
|
||||
|
||||
# gonna have something like this:
|
||||
#MasterPitchOffset:
|
||||
# - [0, -5, 5] # Octave
|
||||
# - [0, -12, -12] # Semitone
|
||||
# - [0, -100, 100] # Pitch
|
||||
MasterPitchOffset:
|
||||
Octave: [0, -5, 5]
|
||||
Semitone: [0, -12, 12]
|
||||
Pitch: [0, -100, 100]
|
||||
Osc1PitchOffset:
|
||||
Octave: [0, -5, 5]
|
||||
Semitone: [0, -12, 12]
|
||||
Pitch: [1.34, -100, 100]
|
||||
Osc2PitchOffset:
|
||||
Octave: [1, -5, 5]
|
||||
Semitone: [0, -12, 12]
|
||||
Pitch: [12.86, -100, 100]
|
||||
Osc3PitchOffset:
|
||||
Octave: [1, -5, 5]
|
||||
Semitone: [7, -12, 12]
|
||||
Pitch: [-8.79, -100, 100]
|
||||
|
||||
# Envelope generator parameters
|
||||
Osc1Volume:
|
||||
- [1, 0, 10] # Depth
|
||||
- [0.05, 0, 2] # Attack
|
||||
- [0.2, 0, 2] # Decay
|
||||
- [0.7, 0, 1] # Sustain
|
||||
- [0.2, 0, 2] # Release
|
||||
Depth: [1, 0, 10]
|
||||
Attack: [0.05, 0, 2]
|
||||
Decay: [0.2, 0, 2]
|
||||
Sustain: [0.7, 0, 1]
|
||||
Release: [0.2, 0, 2]
|
||||
FilterCutoff:
|
||||
- [4, 0, 8] # Depth
|
||||
- [0.05, 0, 2] # Attack
|
||||
- [0.2, 0, 2] # Decay
|
||||
- [0.2, 0, 1] # Sustain
|
||||
- [0.25, 0, 2] # Release
|
||||
Depth: [4, 0, 8]
|
||||
Attack: [0.05, 0, 2]
|
||||
Decay: [0.2, 0, 2]
|
||||
Sustain: [0.2, 0, 1]
|
||||
Release: [0.25, 0, 2]
|
||||
FilterResonance:
|
||||
- [3, 0, 8] # Depth
|
||||
- [0.05, 0, 2] # Attack
|
||||
- [0.2, 0, 2] # Decay
|
||||
- [0.5, 0, 1] # Sustain
|
||||
- [0.3, 0, 2] # Release
|
||||
Depth: [3, 0, 8]
|
||||
Attack: [0.05, 0, 2]
|
||||
Decay: [0.2, 0, 2]
|
||||
Sustain: [0.5, 0, 1]
|
||||
Release: [0.3, 0, 2]
|
||||
|
||||
BIN
config/wavetables/sigmoid.wt
Normal file
BIN
config/wavetables/sigmoid.wt
Normal file
Binary file not shown.
@@ -3,7 +3,7 @@ import math
|
||||
|
||||
from generate_wavetable import generateWavetable
|
||||
|
||||
WAVETABLE_FILE_NAME = "sharkFin"
|
||||
WAVETABLE_FILE_NAME = "sigmoid"
|
||||
|
||||
# process expects a waveform from x=[0, 2pi) centered around f(x)=0
|
||||
# normalization is handled by the wavetableGenerator
|
||||
@@ -38,12 +38,15 @@ def sharkFin(phase):
|
||||
sample = -2 * (phase/math.pi - 1.0) ** k + 1.0
|
||||
return sample
|
||||
|
||||
def sphere(phase):
|
||||
return 1
|
||||
def sigmoid(phase):
|
||||
k = 4
|
||||
a = -k * (phase - math.pi)
|
||||
sample = 2 / (1 + math.exp(a)) - 1
|
||||
return sample
|
||||
|
||||
# pass in the name of your wavtable file and the process function
|
||||
def main():
|
||||
generateWavetable(WAVETABLE_FILE_NAME, process)
|
||||
generateWavetable(WAVETABLE_FILE_NAME, sigmoid)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -74,25 +74,29 @@ YAML::Node ConfigInterface::loadProfile(std::string filename) {
|
||||
std::array<Param, 5> fCutoffProfile = loadEnvProfile(&config, "FilterCutoff");
|
||||
std::array<Param, 5> fResonanceProfile = loadEnvProfile(&config, "FilterResonance");
|
||||
|
||||
YAML::Node masterNode = config["MasterPitchOffset"];
|
||||
YAML::Node osc1Node = config["Osc1PitchOffset"];
|
||||
YAML::Node osc2Node = config["Osc2PitchOffset"];
|
||||
YAML::Node osc3Node = config["Osc3PitchOffset"];
|
||||
std::array<Param, 3> masterPitchOffsets = {{
|
||||
{ config["MasterOctaveOffset"][0].as<float>(), config["MasterOctaveOffset"][1].as<float>(), config["MasterOctaveOffset"][2].as<float>() },
|
||||
{ config["MasterSemitoneOffset"][0].as<float>(), config["MasterSemitoneOffset"][1].as<float>(), config["MasterSemitoneOffset"][2].as<float>() },
|
||||
{ config["MasterPitchOffset"][0].as<float>(), config["MasterPitchOffset"][1].as<float>(), config["MasterPitchOffset"][2].as<float>() },
|
||||
{ masterNode["Octave"][0].as<float>(), masterNode["Octave"][1].as<float>(), masterNode["Octave"][2].as<float>() },
|
||||
{ masterNode["Semitone"][0].as<float>(), masterNode["Semitone"][1].as<float>(), masterNode["Semitone"][2].as<float>() },
|
||||
{ masterNode["Pitch"][0].as<float>(), masterNode["Pitch"][1].as<float>(), masterNode["Pitch"][2].as<float>() },
|
||||
}};
|
||||
std::array<Param, 3> osc1PitchOffsets = {{
|
||||
{ config["Osc1OctaveOffset"][0].as<float>(), config["Osc1OctaveOffset"][1].as<float>(), config["Osc1OctaveOffset"][2].as<float>() },
|
||||
{ config["Osc1SemitoneOffset"][0].as<float>(), config["Osc1SemitoneOffset"][1].as<float>(), config["Osc1SemitoneOffset"][2].as<float>() },
|
||||
{ config["Osc1PitchOffset"][0].as<float>(), config["Osc1PitchOffset"][1].as<float>(), config["Osc1PitchOffset"][2].as<float>() },
|
||||
{ osc1Node["Octave"][0].as<float>(), osc1Node["Octave"][1].as<float>(), osc1Node["Octave"][2].as<float>() },
|
||||
{ osc1Node["Semitone"][0].as<float>(), osc1Node["Semitone"][1].as<float>(), osc1Node["Semitone"][2].as<float>() },
|
||||
{ osc1Node["Pitch"][0].as<float>(),osc1Node["Pitch"][1].as<float>(), osc1Node["Pitch"][2].as<float>() },
|
||||
}};
|
||||
std::array<Param, 3> osc2PitchOffsets = {{
|
||||
{ config["Osc2OctaveOffset"][0].as<float>(), config["Osc2OctaveOffset"][1].as<float>(), config["Osc2OctaveOffset"][2].as<float>() },
|
||||
{ config["Osc2SemitoneOffset"][0].as<float>(), config["Osc2SemitoneOffset"][1].as<float>(), config["Osc2SemitoneOffset"][2].as<float>() },
|
||||
{ config["Osc2PitchOffset"][0].as<float>(), config["Osc2PitchOffset"][1].as<float>(), config["Osc2PitchOffset"][2].as<float>() },
|
||||
{ osc2Node["Octave"][0].as<float>(), osc2Node["Octave"][1].as<float>(), osc2Node["Octave"][2].as<float>() },
|
||||
{ osc2Node["Semitone"][0].as<float>(), osc2Node["Semitone"][1].as<float>(), osc2Node["Semitone"][2].as<float>() },
|
||||
{ osc2Node["Pitch"][0].as<float>(), osc2Node["Pitch"][1].as<float>(), osc2Node["Pitch"][2].as<float>() },
|
||||
}};
|
||||
std::array<Param, 3> osc3PitchOffsets = {{
|
||||
{ config["Osc3OctaveOffset"][0].as<float>(), config["Osc3OctaveOffset"][1].as<float>(), config["Osc3OctaveOffset"][2].as<float>() },
|
||||
{ config["Osc3SemitoneOffset"][0].as<float>(), config["Osc3SemitoneOffset"][1].as<float>(), config["Osc3SemitoneOffset"][2].as<float>() },
|
||||
{ config["Osc3PitchOffset"][0].as<float>(), config["Osc3PitchOffset"][1].as<float>(), config["Osc3PitchOffset"][2].as<float>() },
|
||||
{ osc3Node["Octave"][0].as<float>(), osc3Node["Octave"][1].as<float>(), osc3Node["Octave"][2].as<float>() },
|
||||
{ osc3Node["Semitone"][0].as<float>(), osc3Node["Semitone"][1].as<float>(), osc3Node["Semitone"][2].as<float>() },
|
||||
{ osc3Node["Pitch"][0].as<float>(), osc3Node["Pitch"][1].as<float>(), osc3Node["Pitch"][2].as<float>() },
|
||||
}};
|
||||
|
||||
// set the values in the paramstore
|
||||
@@ -126,9 +130,11 @@ std::array<Param, 5> ConfigInterface::loadEnvProfile(YAML::Node* node, std::stri
|
||||
|
||||
std::array<Param, 5> paramProfile;
|
||||
|
||||
for(int i = 0; i < paramProfile.size(); i++) {
|
||||
paramProfile[i] = { envelopeNode[i][0].as<float>(), envelopeNode[i][1].as<float>(), envelopeNode[i][2].as<float>() };
|
||||
}
|
||||
paramProfile[0] = { envelopeNode["Depth"][0].as<float>(), envelopeNode["Depth"][1].as<float>(), envelopeNode["Depth"][2].as<float>() };
|
||||
paramProfile[1] = { envelopeNode["Attack"][0].as<float>(), envelopeNode["Attack"][1].as<float>(), envelopeNode["Attack"][2].as<float>() };
|
||||
paramProfile[2] = { envelopeNode["Decay"][0].as<float>(), envelopeNode["Decay"][1].as<float>(), envelopeNode["Decay"][2].as<float>() };
|
||||
paramProfile[3] = { envelopeNode["Sustain"][0].as<float>(), envelopeNode["Sustain"][1].as<float>(), envelopeNode["Sustain"][2].as<float>() };
|
||||
paramProfile[4] = { envelopeNode["Release"][0].as<float>(), envelopeNode["Release"][1].as<float>(), envelopeNode["Release"][2].as<float>() };
|
||||
|
||||
return paramProfile;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include "ParameterStore.h"
|
||||
|
||||
#define CONFIG_VERSION 0x0002
|
||||
#define CONFIG_VERSION 0x04
|
||||
|
||||
enum class ConfigFile {
|
||||
Audio = 0
|
||||
|
||||
@@ -157,49 +157,53 @@ void MainWindow::onResetClicked() {
|
||||
|
||||
// TODO: clean these up, maybe put them in a package like the envelope generators (it'll help encapsulate the int-snapping business)
|
||||
// what I might do is make a variable-length slider-package object
|
||||
ui_->sliderMasterOctave->setResolution(configRoot["MasterOctaveOffset"][2].as<int>() - configRoot["MasterOctaveOffset"][1].as<int>());
|
||||
ui_->sliderMasterOctave->setRange(configRoot["MasterOctaveOffset"][1].as<int>(), configRoot["MasterOctaveOffset"][2].as<int>());
|
||||
ui_->sliderMasterOctave->setValue(configRoot["MasterOctaveOffset"][0].as<int>());
|
||||
YAML::Node masterNode = configRoot["MasterPitchOffset"];
|
||||
YAML::Node osc1Node = configRoot["Osc1PitchOffset"];
|
||||
YAML::Node osc2Node = configRoot["Osc2PitchOffset"];
|
||||
YAML::Node osc3Node = configRoot["Osc3PitchOffset"];
|
||||
ui_->sliderMasterOctave->setResolution(masterNode["Octave"][2].as<int>() - masterNode["Octave"][1].as<int>());
|
||||
ui_->sliderMasterOctave->setRange(masterNode["Octave"][1].as<int>(), masterNode["Octave"][2].as<int>());
|
||||
ui_->sliderMasterOctave->setValue(masterNode["Octave"][0].as<int>());
|
||||
|
||||
ui_->sliderMasterSemitone->setResolution(configRoot["MasterSemitoneOffset"][2].as<int>() - configRoot["MasterSemitoneOffset"][1].as<int>());
|
||||
ui_->sliderMasterSemitone->setRange(configRoot["MasterSemitoneOffset"][1].as<int>(), configRoot["MasterSemitoneOffset"][2].as<int>());
|
||||
ui_->sliderMasterSemitone->setValue(configRoot["MasterSemitoneOffset"][0].as<int>());
|
||||
ui_->sliderMasterSemitone->setResolution(masterNode["Semitone"][2].as<int>() - masterNode["Semitone"][1].as<int>());
|
||||
ui_->sliderMasterSemitone->setRange(masterNode["Semitone"][1].as<int>(), masterNode["Semitone"][2].as<int>());
|
||||
ui_->sliderMasterSemitone->setValue(masterNode["Semitone"][0].as<int>());
|
||||
|
||||
ui_->sliderMasterPitch->setRange(configRoot["MasterPitchOffset"][1].as<float>(), configRoot["MasterPitchOffset"][2].as<float>());
|
||||
ui_->sliderMasterPitch->setValue(configRoot["MasterPitchOffset"][0].as<float>());
|
||||
ui_->sliderMasterPitch->setRange(masterNode["Pitch"][1].as<float>(), masterNode["Pitch"][2].as<float>());
|
||||
ui_->sliderMasterPitch->setValue(masterNode["Pitch"][0].as<float>());
|
||||
|
||||
ui_->sliderOsc1Octave->setResolution(configRoot["Osc1OctaveOffset"][2].as<int>() - configRoot["Osc1OctaveOffset"][1].as<int>());
|
||||
ui_->sliderOsc1Octave->setRange(configRoot["Osc1OctaveOffset"][1].as<int>(), configRoot["Osc1OctaveOffset"][2].as<int>());
|
||||
ui_->sliderOsc1Octave->setValue(configRoot["Osc1OctaveOffset"][0].as<int>());
|
||||
ui_->sliderOsc1Octave->setResolution(osc1Node["Octave"][2].as<int>() - osc1Node["Octave"][1].as<int>());
|
||||
ui_->sliderOsc1Octave->setRange(osc1Node["Octave"][1].as<int>(), osc1Node["Octave"][2].as<int>());
|
||||
ui_->sliderOsc1Octave->setValue(osc1Node["Octave"][0].as<int>());
|
||||
|
||||
ui_->sliderOsc1Semitone->setResolution(configRoot["Osc1SemitoneOffset"][2].as<int>() - configRoot["Osc1SemitoneOffset"][1].as<int>());
|
||||
ui_->sliderOsc1Semitone->setRange(configRoot["Osc1SemitoneOffset"][1].as<int>(), configRoot["Osc1SemitoneOffset"][2].as<int>());
|
||||
ui_->sliderOsc1Semitone->setValue(configRoot["Osc1SemitoneOffset"][0].as<int>());
|
||||
ui_->sliderOsc1Semitone->setResolution(osc1Node["Semitone"][2].as<int>() - osc1Node["Semitone"][1].as<int>());
|
||||
ui_->sliderOsc1Semitone->setRange(osc1Node["Semitone"][1].as<int>(), osc1Node["Semitone"][2].as<int>());
|
||||
ui_->sliderOsc1Semitone->setValue(osc1Node["Semitone"][0].as<int>());
|
||||
|
||||
ui_->sliderOsc1Pitch->setRange(configRoot["Osc1PitchOffset"][1].as<float>(), configRoot["Osc1PitchOffset"][2].as<float>());
|
||||
ui_->sliderOsc1Pitch->setValue(configRoot["Osc1PitchOffset"][0].as<float>());
|
||||
ui_->sliderOsc1Pitch->setRange(osc1Node["Pitch"][1].as<float>(), osc1Node["Pitch"][2].as<float>());
|
||||
ui_->sliderOsc1Pitch->setValue(osc1Node["Pitch"][0].as<float>());
|
||||
|
||||
ui_->sliderOsc2Octave->setResolution(configRoot["Osc2OctaveOffset"][2].as<int>() - configRoot["Osc2OctaveOffset"][1].as<int>());
|
||||
ui_->sliderOsc2Octave->setRange(configRoot["Osc2OctaveOffset"][1].as<int>(), configRoot["Osc2OctaveOffset"][2].as<int>());
|
||||
ui_->sliderOsc2Octave->setValue(configRoot["Osc2OctaveOffset"][0].as<int>());
|
||||
ui_->sliderOsc2Octave->setResolution(osc2Node["Octave"][2].as<int>() - osc2Node["Octave"][1].as<int>());
|
||||
ui_->sliderOsc2Octave->setRange(osc2Node["Octave"][1].as<int>(), osc2Node["Octave"][2].as<int>());
|
||||
ui_->sliderOsc2Octave->setValue(osc2Node["Octave"][0].as<int>());
|
||||
|
||||
ui_->sliderOsc2Semitone->setResolution(configRoot["Osc2SemitoneOffset"][2].as<int>() - configRoot["Osc2SemitoneOffset"][1].as<int>());
|
||||
ui_->sliderOsc2Semitone->setRange(configRoot["Osc2SemitoneOffset"][1].as<int>(), configRoot["Osc2SemitoneOffset"][2].as<int>());
|
||||
ui_->sliderOsc2Semitone->setValue(configRoot["Osc2SemitoneOffset"][0].as<int>());
|
||||
ui_->sliderOsc2Semitone->setResolution(osc2Node["Semitone"][2].as<int>() - osc2Node["Semitone"][1].as<int>());
|
||||
ui_->sliderOsc2Semitone->setRange(osc2Node["Semitone"][1].as<int>(), osc2Node["Semitone"][2].as<int>());
|
||||
ui_->sliderOsc2Semitone->setValue(osc2Node["Semitone"][0].as<int>());
|
||||
|
||||
ui_->sliderOsc2Pitch->setRange(configRoot["Osc2PitchOffset"][1].as<float>(), configRoot["Osc2PitchOffset"][2].as<float>());
|
||||
ui_->sliderOsc2Pitch->setValue(configRoot["Osc2PitchOffset"][0].as<float>());
|
||||
ui_->sliderOsc2Pitch->setRange(osc2Node["Pitch"][1].as<float>(), osc2Node["Pitch"][2].as<float>());
|
||||
ui_->sliderOsc2Pitch->setValue(osc2Node["Pitch"][0].as<float>());
|
||||
|
||||
ui_->sliderOsc3Octave->setResolution(configRoot["Osc3OctaveOffset"][2].as<int>() - configRoot["Osc3OctaveOffset"][1].as<int>());
|
||||
ui_->sliderOsc3Octave->setRange(configRoot["Osc3OctaveOffset"][1].as<int>(), configRoot["Osc3OctaveOffset"][2].as<int>());
|
||||
ui_->sliderOsc3Octave->setValue(configRoot["Osc3OctaveOffset"][0].as<int>());
|
||||
ui_->sliderOsc3Octave->setResolution(osc3Node["Octave"][2].as<int>() - osc3Node["Octave"][1].as<int>());
|
||||
ui_->sliderOsc3Octave->setRange(osc3Node["Octave"][1].as<int>(), osc3Node["Octave"][2].as<int>());
|
||||
ui_->sliderOsc3Octave->setValue(osc3Node["Octave"][0].as<int>());
|
||||
|
||||
ui_->sliderOsc3Semitone->setResolution(configRoot["Osc3SemitoneOffset"][2].as<int>() - configRoot["Osc3SemitoneOffset"][1].as<int>());
|
||||
ui_->sliderOsc3Semitone->setRange(configRoot["Osc3SemitoneOffset"][1].as<int>(), configRoot["Osc3SemitoneOffset"][2].as<int>());
|
||||
ui_->sliderOsc3Semitone->setValue(configRoot["Osc3SemitoneOffset"][0].as<int>());
|
||||
ui_->sliderOsc3Semitone->setResolution(osc3Node["Semitone"][2].as<int>() - osc3Node["Semitone"][1].as<int>());
|
||||
ui_->sliderOsc3Semitone->setRange(osc3Node["Semitone"][1].as<int>(), osc3Node["Semitone"][2].as<int>());
|
||||
ui_->sliderOsc3Semitone->setValue(osc3Node["Semitone"][0].as<int>());
|
||||
|
||||
ui_->sliderOsc3Pitch->setRange(configRoot["Osc3PitchOffset"][1].as<float>(), configRoot["Osc3PitchOffset"][2].as<float>());
|
||||
ui_->sliderOsc3Pitch->setValue(configRoot["Osc3PitchOffset"][0].as<float>());
|
||||
ui_->sliderOsc3Pitch->setRange(osc3Node["Pitch"][1].as<float>(), osc3Node["Pitch"][2].as<float>());
|
||||
ui_->sliderOsc3Pitch->setValue(osc3Node["Pitch"][0].as<float>());
|
||||
|
||||
ui_->comboOsc1WaveSelector1->setCurrentIndex(configRoot["OscWaveSelector1"].as<int>());
|
||||
ui_->comboOsc1WaveSelector2->setCurrentIndex(configRoot["OscWaveSelector2"].as<int>());
|
||||
|
||||
Reference in New Issue
Block a user