mirror of
https://codeberg.org/armin/chromaflock.git
synced 2026-09-01 04:10:47 +02:00
feat: add octave and halftone transpose menus
This commit is contained in:
parent
5cc704c1d1
commit
6432ab060d
4 changed files with 43 additions and 2 deletions
|
|
@ -543,6 +543,27 @@ MainContentComponent::MainContentComponent(ChromaFlockProcessor& p)
|
||||||
scaleLabel.setJustificationType(juce::Justification::centredRight);
|
scaleLabel.setJustificationType(juce::Justification::centredRight);
|
||||||
addAndMakeVisible(scaleLabel);
|
addAndMakeVisible(scaleLabel);
|
||||||
|
|
||||||
|
auto setupTransposeLabel = [&](juce::Label& label, const juce::String& text) {
|
||||||
|
label.setText(text, juce::dontSendNotification);
|
||||||
|
label.setFont(juce::Font(9.0f));
|
||||||
|
label.setColour(juce::Label::textColourId, juce::Colour(0xff888888));
|
||||||
|
label.setJustificationType(juce::Justification::centredLeft);
|
||||||
|
addAndMakeVisible(label);
|
||||||
|
};
|
||||||
|
setupTransposeLabel(octaveTransposeLabel, "OCT");
|
||||||
|
setupTransposeLabel(semitoneTransposeLabel, "SEMI");
|
||||||
|
|
||||||
|
setupCombo(octaveTransposeBox);
|
||||||
|
octaveTransposeBox.addItemList(juce::StringArray{"-3", "-2", "-1", "0", "+1", "+2", "+3"}, 1);
|
||||||
|
octaveTransposeAttach = std::make_unique<ComboBoxAttachment>(
|
||||||
|
processorRef.apvts, "octaveTranspose", octaveTransposeBox);
|
||||||
|
|
||||||
|
setupCombo(semitoneTransposeBox);
|
||||||
|
semitoneTransposeBox.addItemList(
|
||||||
|
juce::StringArray{getSemitoneChoices()}, 1);
|
||||||
|
semitoneTransposeAttach = std::make_unique<ComboBoxAttachment>(
|
||||||
|
processorRef.apvts, "semitoneTranspose", semitoneTransposeBox);
|
||||||
|
|
||||||
addAndMakeVisible(vuMeter);
|
addAndMakeVisible(vuMeter);
|
||||||
addAndMakeVisible(waveformDisplay);
|
addAndMakeVisible(waveformDisplay);
|
||||||
addAndMakeVisible(spectrumAnalyzer);
|
addAndMakeVisible(spectrumAnalyzer);
|
||||||
|
|
@ -886,6 +907,11 @@ void MainContentComponent::resized() {
|
||||||
patchLCD.setBounds(118, 8, 360, 28);
|
patchLCD.setBounds(118, 8, 360, 28);
|
||||||
prevPresetButton.setBounds(486, 8, 28, 28);
|
prevPresetButton.setBounds(486, 8, 28, 28);
|
||||||
nextPresetButton.setBounds(518, 8, 28, 28);
|
nextPresetButton.setBounds(518, 8, 28, 28);
|
||||||
|
octaveTransposeLabel.setBounds(1112, 10, 30, 20);
|
||||||
|
octaveTransposeBox.setBounds(1142, 8, 64, 24);
|
||||||
|
semitoneTransposeLabel.setBounds(1214, 10, 32, 20);
|
||||||
|
semitoneTransposeBox.setBounds(1246, 8, 74, 24);
|
||||||
|
|
||||||
scaleLabel.setBounds(1520, 10, 42, 20);
|
scaleLabel.setBounds(1520, 10, 42, 20);
|
||||||
uiScaleBox.setBounds(1566, 8, 80, 24);
|
uiScaleBox.setBounds(1566, 8, 80, 24);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,9 @@ private:
|
||||||
juce::Label osc1Label, osc2Label, filterLabel, envLabel, fEnvLabel, globalLabel;
|
juce::Label osc1Label, osc2Label, filterLabel, envLabel, fEnvLabel, globalLabel;
|
||||||
juce::Label fxLabel, lfoLabel, fx2Label;
|
juce::Label fxLabel, lfoLabel, fx2Label;
|
||||||
juce::Label scaleLabel;
|
juce::Label scaleLabel;
|
||||||
|
juce::Label octaveTransposeLabel, semitoneTransposeLabel;
|
||||||
|
|
||||||
|
juce::ComboBox octaveTransposeBox, semitoneTransposeBox;
|
||||||
juce::ComboBox osc1WaveBox;
|
juce::ComboBox osc1WaveBox;
|
||||||
juce::Slider osc1OctKnob, osc1SemiKnob, osc1FineKnob, osc1LevelKnob;
|
juce::Slider osc1OctKnob, osc1SemiKnob, osc1FineKnob, osc1LevelKnob;
|
||||||
|
|
||||||
|
|
@ -164,6 +166,7 @@ private:
|
||||||
std::unique_ptr<SliderAttachment> osc1OctAttach, osc1SemiAttach, osc1FineAttach, osc1LevelAttach;
|
std::unique_ptr<SliderAttachment> osc1OctAttach, osc1SemiAttach, osc1FineAttach, osc1LevelAttach;
|
||||||
std::unique_ptr<SliderAttachment> osc2OctAttach, osc2SemiAttach, osc2FineAttach, osc2LevelAttach, phaseOffsetAttach;
|
std::unique_ptr<SliderAttachment> osc2OctAttach, osc2SemiAttach, osc2FineAttach, osc2LevelAttach, phaseOffsetAttach;
|
||||||
std::unique_ptr<ComboBoxAttachment> osc1WaveAttach, osc2WaveAttach, filterTypeAttach;
|
std::unique_ptr<ComboBoxAttachment> osc1WaveAttach, osc2WaveAttach, filterTypeAttach;
|
||||||
|
std::unique_ptr<ComboBoxAttachment> octaveTransposeAttach, semitoneTransposeAttach;
|
||||||
std::unique_ptr<SliderAttachment> filterCutoffAttach, filterResAttach, filterEnvAmtAttach, keyTrackAttach;
|
std::unique_ptr<SliderAttachment> filterCutoffAttach, filterResAttach, filterEnvAmtAttach, keyTrackAttach;
|
||||||
std::unique_ptr<SliderAttachment> envAttackAttach, envDecayAttach, envSustainAttach, envReleaseAttach;
|
std::unique_ptr<SliderAttachment> envAttackAttach, envDecayAttach, envSustainAttach, envReleaseAttach;
|
||||||
std::unique_ptr<SliderAttachment> fEnvAttackAttach, fEnvDecayAttach, fEnvSustainAttach, fEnvReleaseAttach;
|
std::unique_ptr<SliderAttachment> fEnvAttackAttach, fEnvDecayAttach, fEnvSustainAttach, fEnvReleaseAttach;
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,14 @@ juce::AudioProcessorValueTreeState::ParameterLayout ChromaFlockProcessor::create
|
||||||
juce::ParameterID{"pitchBendRange", 1}, "Pitch Bend Range",
|
juce::ParameterID{"pitchBendRange", 1}, "Pitch Bend Range",
|
||||||
juce::NormalisableRange<float>(1.0f, 12.0f, 1.0f), 2.0f));
|
juce::NormalisableRange<float>(1.0f, 12.0f, 1.0f), 2.0f));
|
||||||
|
|
||||||
|
// TRANSPOSE
|
||||||
|
layout.add(std::make_unique<juce::AudioParameterChoice>(
|
||||||
|
juce::ParameterID{"octaveTranspose", 1}, "Octave Transpose",
|
||||||
|
juce::StringArray{"-3", "-2", "-1", "0", "+1", "+2", "+3"}, 3));
|
||||||
|
layout.add(std::make_unique<juce::AudioParameterChoice>(
|
||||||
|
juce::ParameterID{"semitoneTranspose", 1}, "Halftone Transpose",
|
||||||
|
getSemitoneChoices(), 0));
|
||||||
|
|
||||||
// DISTORTION
|
// DISTORTION
|
||||||
layout.add(std::make_unique<juce::AudioParameterChoice>(
|
layout.add(std::make_unique<juce::AudioParameterChoice>(
|
||||||
juce::ParameterID{"distType", 1}, "Dist Type",
|
juce::ParameterID{"distType", 1}, "Dist Type",
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
|
const juce::StringArray& getSemitoneChoices();
|
||||||
|
|
||||||
class ChromaFlockProcessor : public juce::AudioProcessor {
|
class ChromaFlockProcessor : public juce::AudioProcessor {
|
||||||
public:
|
public:
|
||||||
ChromaFlockProcessor();
|
ChromaFlockProcessor();
|
||||||
|
|
@ -55,18 +57,20 @@ public:
|
||||||
void noteOn(int midiNote, float velocity) {
|
void noteOn(int midiNote, float velocity) {
|
||||||
if (midiNote >= 0 && midiNote < 128)
|
if (midiNote >= 0 && midiNote < 128)
|
||||||
activeNotes[midiNote].store(true, std::memory_order_relaxed);
|
activeNotes[midiNote].store(true, std::memory_order_relaxed);
|
||||||
synth.noteOn(1, midiNote, velocity);
|
synth.noteOn(1, juce::jlimit(0, 127, midiNote + getTransposeSemitones()), velocity);
|
||||||
}
|
}
|
||||||
void noteOff(int midiNote) {
|
void noteOff(int midiNote) {
|
||||||
if (midiNote >= 0 && midiNote < 128)
|
if (midiNote >= 0 && midiNote < 128)
|
||||||
activeNotes[midiNote].store(false, std::memory_order_relaxed);
|
activeNotes[midiNote].store(false, std::memory_order_relaxed);
|
||||||
synth.noteOff(1, midiNote, 0.0f, true);
|
synth.noteOff(1, juce::jlimit(0, 127, midiNote + getTransposeSemitones()), 0.0f, true);
|
||||||
}
|
}
|
||||||
bool isNoteActive(int midiNote) const {
|
bool isNoteActive(int midiNote) const {
|
||||||
return midiNote >= 0 && midiNote < 128
|
return midiNote >= 0 && midiNote < 128
|
||||||
&& activeNotes[midiNote].load(std::memory_order_relaxed);
|
&& activeNotes[midiNote].load(std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getTransposeSemitones() const;
|
||||||
|
|
||||||
std::atomic<float> pitchBendValue{0.0f};
|
std::atomic<float> pitchBendValue{0.0f};
|
||||||
float getPitchBend() const { return pitchBendValue.load(std::memory_order_relaxed); }
|
float getPitchBend() const { return pitchBendValue.load(std::memory_order_relaxed); }
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue