mirror of
https://github.com/yokemura/Magical8bitPlug2.git
synced 2025-05-24 23:00:21 -04:00
Custom Waveform
This commit is contained in:
parent
47cefdd0e8
commit
915f9eb5bf
@ -33,6 +33,10 @@
|
||||
file="Source/SliderComponent.cpp"/>
|
||||
<FILE id="qIuf9N" name="SliderComponent.h" compile="0" resource="0"
|
||||
file="Source/SliderComponent.h"/>
|
||||
<FILE id="uajfNh" name="SliderVerticalComponent.cpp" compile="1" resource="0"
|
||||
file="Source/SliderVerticalComponent.cpp"/>
|
||||
<FILE id="p2nPNB" name="SliderVerticalComponent.h" compile="0" resource="0"
|
||||
file="Source/SliderVerticalComponent.h"/>
|
||||
</GROUP>
|
||||
<FILE id="SFqkUr" name="AdvancedParamsComponent.cpp" compile="1" resource="0"
|
||||
file="Source/AdvancedParamsComponent.cpp"/>
|
||||
@ -68,6 +72,13 @@
|
||||
file="Source/VibratoParamsComponent.h"/>
|
||||
</GROUP>
|
||||
<GROUP id="{630C27C7-03AA-CFC6-2FC4-4CE2DBE3640A}" name="Source">
|
||||
<FILE id="WS1wsR" name="WaveformParamsComponent.cpp" compile="1" resource="0"
|
||||
file="Source/WaveformParamsComponent.cpp"/>
|
||||
<FILE id="miNL07" name="WaveformParamsComponent.h" compile="0" resource="0"
|
||||
file="Source/WaveformParamsComponent.h"/>
|
||||
<FILE id="vVn1lo" name="WaveformVoice.cpp" compile="1" resource="0"
|
||||
file="Source/WaveformVoice.cpp"/>
|
||||
<FILE id="iZpU3j" name="WaveformVoice.h" compile="0" resource="0" file="Source/WaveformVoice.h"/>
|
||||
<FILE id="H2Vgbj" name="FrameSequenceParseErrors.cpp" compile="1" resource="0"
|
||||
file="Source/FrameSequenceParseErrors.cpp"/>
|
||||
<FILE id="Gwt2vB" name="FrameSequenceParseErrors.h" compile="0" resource="0"
|
||||
|
@ -154,6 +154,7 @@ void BasicParamsComponent::comboBoxChanged (ComboBox* comboBoxThatHasChanged)
|
||||
{
|
||||
processor.setupVoice();
|
||||
editor.resized();
|
||||
editor.resizeWholePanel();
|
||||
printf ("setup voice!!\n");
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,9 @@
|
||||
NoiseVoice::NoiseVoice(SettingRefs *sRefs) : TonalVoice(sRefs) {}
|
||||
|
||||
void NoiseVoice::startNote(int midiNoteNumber, float velocity, SynthesiserSound *, int currentPitchBendPosition) {
|
||||
TonalVoice::startNote(midiNoteNumber, velocity, 0, currentPitchBendPosition);
|
||||
//TonalVoice::startNote(midiNoteNumber, velocity, 0, currentPitchBendPosition);
|
||||
int midiNote = midiNoteNumber;
|
||||
int midiNoteRange[16] = { 5, 17, 29, 34, 41, 46, 53, 57, 61, 65, 70, 77, 89, 101, 113, 125 };
|
||||
switch (settingRefs->noiseAlgorithm()) {
|
||||
case kNoiseInfinite2:
|
||||
cycleLength = MathConstants<float>::pi / 25.0;
|
||||
@ -29,10 +31,19 @@ void NoiseVoice::startNote(int midiNoteNumber, float velocity, SynthesiserSound
|
||||
cycleLength = MathConstants<float>::pi / 8.0;
|
||||
break;
|
||||
|
||||
case kNoiseLongNes:
|
||||
case kNoiseShortNes:
|
||||
cycleLength = MathConstants<float>::pi / 20.175;
|
||||
//rgstr = 0x8000;
|
||||
//rgstr = rand();
|
||||
midiNote = midiNoteRange[(midiNote + 8) % 16];
|
||||
break;
|
||||
|
||||
default:
|
||||
cycleLength = MathConstants<float>::pi / 8.0;
|
||||
break;
|
||||
}
|
||||
TonalVoice::startNote(midiNote, velocity, 0, currentPitchBendPosition);
|
||||
}
|
||||
|
||||
float NoiseVoice::voltageForAngle (double angle)
|
||||
@ -58,9 +69,10 @@ float NoiseVoice::voltageForAngle (double angle)
|
||||
{
|
||||
if (settingRefs->noiseAlgorithm() == kNoiseInfinite2)
|
||||
{
|
||||
currentVoltage = float (rand() % 16 - 8) / 16.;
|
||||
currentVoltage = float (rand() % 16 - 8) / 16.0;
|
||||
//currentVoltage = float(rand() % 16 - 7.5) / 15.0;
|
||||
}
|
||||
else
|
||||
else if (settingRefs->noiseAlgorithm() == kNoiseLong || settingRefs->noiseAlgorithm() == kNoiseShort)
|
||||
{
|
||||
int compareBitPos = settingRefs->noiseAlgorithm() == kNoiseLong ? 1 : 6;
|
||||
|
||||
@ -76,6 +88,14 @@ float NoiseVoice::voltageForAngle (double angle)
|
||||
|
||||
currentVoltage = (float)bit0 - 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
int shortFreq = settingRefs->noiseAlgorithm() == kNoiseLongNes ? 1 : 6;
|
||||
|
||||
rgstr >>= 1;
|
||||
rgstr |= ((rgstr ^ (rgstr >> shortFreq)) & 1) << 15;
|
||||
currentVoltage = (float)(rgstr & 1) - 0.5;
|
||||
}
|
||||
|
||||
nextAngle = (double) ((int) (angle / cycleLength) + 1) * cycleLength;
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "BendParamsComponent.h"
|
||||
#include "SweepParamsComponent.h"
|
||||
#include "VibratoParamsComponent.h"
|
||||
#include "WaveformParamsComponent.h"
|
||||
|
||||
//==============================================================================
|
||||
Magical8bitPlug2AudioProcessorEditor::Magical8bitPlug2AudioProcessorEditor (Magical8bitPlug2AudioProcessor& p)
|
||||
@ -29,7 +30,7 @@ Magical8bitPlug2AudioProcessorEditor::Magical8bitPlug2AudioProcessorEditor (Magi
|
||||
|
||||
basicCompo.reset (new BasicParamsComponent (p, *this));
|
||||
addAndMakeVisible (basicCompo.get());
|
||||
|
||||
|
||||
envCompo.reset (new EnvelopeParamsComponent (p));
|
||||
addAndMakeVisible (envCompo.get());
|
||||
|
||||
@ -51,6 +52,10 @@ Magical8bitPlug2AudioProcessorEditor::Magical8bitPlug2AudioProcessorEditor (Magi
|
||||
vibCompo.reset (new VibratoParamsComponent (p));
|
||||
addAndMakeVisible (vibCompo.get());
|
||||
|
||||
// waveform
|
||||
waveformCompo.reset (new WaveformParamsComponent (p));
|
||||
addAndMakeVisible (waveformCompo.get());
|
||||
|
||||
(p.parameters.getParameter ("isVolumeSequenceEnabled_raw"))->addListener (this);
|
||||
(p.parameters.getParameter ("isDutySequenceEnabled_raw"))->addListener (this);
|
||||
|
||||
@ -141,7 +146,7 @@ struct
|
||||
+ genericControlHeight;
|
||||
const int sweepCompoHeight = componentMargin * 2
|
||||
+ indexHeight
|
||||
+ genericControlHeight * 2;
|
||||
+ genericControlHeight * 3;
|
||||
const int vibCompoHeight = componentMargin * 2
|
||||
+ indexHeight
|
||||
+ genericControlHeight * 4;
|
||||
@ -240,6 +245,11 @@ void Magical8bitPlug2AudioProcessorEditor::resized()
|
||||
y3 += sizes.sectionSeparatorHeight;
|
||||
advCompo->setBounds (x, y3, sizes.fullComponentWidth, sizes.advCompoHeight);
|
||||
|
||||
// Waveform
|
||||
int wrX = sizes.leftMargin + sizes.totalWidth;
|
||||
int wrY = sizes.topMargin;
|
||||
waveformCompo->setBounds(wrX, wrY, waveformCompo->getWidth(), waveformCompo->getHeight());
|
||||
|
||||
//
|
||||
// Visibility
|
||||
//
|
||||
@ -272,7 +282,12 @@ void Magical8bitPlug2AudioProcessorEditor::resized()
|
||||
|
||||
void Magical8bitPlug2AudioProcessorEditor::resizeWholePanel()
|
||||
{
|
||||
setSize (sizes.totalWidth, sizes.totalHeight (processor.settingRefs.isAdvancedPanelOpen()));
|
||||
int totalWidth = sizes.totalWidth;
|
||||
if (processor.settingRefs.oscillatorType() == kVoiceTypeWaveform)
|
||||
{
|
||||
totalWidth += sizes.leftMargin * 2 + waveformCompo->getWidth();
|
||||
}
|
||||
setSize (totalWidth, sizes.totalHeight (processor.settingRefs.isAdvancedPanelOpen()));
|
||||
}
|
||||
|
||||
void Magical8bitPlug2AudioProcessorEditor::parameterValueChanged (int parameterIndex, float newValue)
|
||||
@ -291,3 +306,13 @@ void Magical8bitPlug2AudioProcessorEditor::parameterValueChanged (int parameterI
|
||||
}
|
||||
}
|
||||
|
||||
// waveform
|
||||
//void Magical8bitPlug2AudioProcessorEditor::waveformInit()
|
||||
//{
|
||||
// waveformCompo->sliderInit();
|
||||
//}
|
||||
|
||||
void Magical8bitPlug2AudioProcessorEditor::waveformUpdate()
|
||||
{
|
||||
waveformCompo->sliderRepaint();
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ class NoiseParamsComponent;
|
||||
class BendParamsComponent;
|
||||
class SweepParamsComponent;
|
||||
class VibratoParamsComponent;
|
||||
class WaveformParamsComponent;
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
@ -40,6 +41,10 @@ public:
|
||||
void parameterValueChanged (int parameterIndex, float newValue) override;
|
||||
void parameterGestureChanged (int parameterIndex, bool gestureIsStarting) override {};
|
||||
|
||||
// waveform
|
||||
//void waveformInit();
|
||||
void waveformUpdate();
|
||||
|
||||
private:
|
||||
Magical8bitPlug2AudioProcessor& processor;
|
||||
|
||||
@ -51,6 +56,7 @@ private:
|
||||
std::unique_ptr<BendParamsComponent> bendCompo;
|
||||
std::unique_ptr<SweepParamsComponent> sweepCompo;
|
||||
std::unique_ptr<VibratoParamsComponent> vibCompo;
|
||||
std::unique_ptr<WaveformParamsComponent> waveformCompo;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Magical8bitPlug2AudioProcessorEditor)
|
||||
};
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "PulseVoice.h"
|
||||
#include "TriangleVoice.h"
|
||||
#include "NoiseVoice.h"
|
||||
#include "WaveformVoice.h"
|
||||
#include "FrameSequenceParseErrors.h"
|
||||
#include "EnvelopeParserTest.h"
|
||||
|
||||
@ -21,21 +22,21 @@ Magical8bitPlug2AudioProcessor::Magical8bitPlug2AudioProcessor()
|
||||
: parameters (
|
||||
*this, nullptr, Identifier ("Params"),
|
||||
{
|
||||
//
|
||||
// Meta
|
||||
//
|
||||
std::make_unique<AudioParameterBool> ("isAdvancedPanelOpen_raw", "Advanced", false),
|
||||
//
|
||||
// Meta
|
||||
//
|
||||
std::make_unique<AudioParameterBool> ("isAdvancedPanelOpen_raw", "Advanced", false),
|
||||
std::make_unique<AudioParameterChoice> ("colorScheme", "Color Scheme", StringArray ({"YMCK", "YMCK Dark", "Japan", "Worldwide", "Monotone", "Mono Dark"}), 0),
|
||||
//
|
||||
// Basic
|
||||
//
|
||||
std::make_unique<AudioParameterChoice> ("osc", "OSC Type", StringArray ({"Pulse/Square", "Triangle", "Noise"}), 0),
|
||||
std::make_unique<AudioParameterChoice> ("osc", "OSC Type", StringArray ({"Pulse/Square", "Triangle", "Noise", "Waveform"}), 0),
|
||||
std::make_unique<AudioParameterFloat> ("gain", "Gain", 0.0f, 1.0f, 0.5f),
|
||||
std::make_unique<AudioParameterFloat> ("maxPoly", "Max Poly", NormalisableRange<float> (1.0f, //min
|
||||
64.0f, //max
|
||||
1.0f, //step
|
||||
1.0f), //skew
|
||||
8),
|
||||
64.0f, //max
|
||||
1.0f, //step
|
||||
1.0f), //skew
|
||||
8),
|
||||
//
|
||||
// ADSR
|
||||
//
|
||||
@ -45,14 +46,14 @@ Magical8bitPlug2AudioProcessor::Magical8bitPlug2AudioProcessor()
|
||||
5.0f, //max
|
||||
0.001f, //step
|
||||
0.5f), //skew
|
||||
0.0f), //default
|
||||
0.0f), //default
|
||||
std::make_unique<AudioParameterFloat> ("decay", //ID
|
||||
"Decay", //name
|
||||
NormalisableRange<float> (0.0f, //min
|
||||
5.0f, //max
|
||||
0.001f, //step
|
||||
0.5f), //skew
|
||||
0.0f), //default
|
||||
0.0f), //default
|
||||
std::make_unique<AudioParameterFloat> ("suslevel", //ID
|
||||
"Sustain", //name
|
||||
0.0f, //min
|
||||
@ -64,7 +65,7 @@ Magical8bitPlug2AudioProcessor::Magical8bitPlug2AudioProcessor()
|
||||
5.0f, //max
|
||||
0.001f, //step
|
||||
0.5f), //skew
|
||||
0.0f), //default
|
||||
0.0f), //default
|
||||
//
|
||||
// Arpeggio
|
||||
//
|
||||
@ -84,7 +85,7 @@ Magical8bitPlug2AudioProcessor::Magical8bitPlug2AudioProcessor()
|
||||
1.0f, //max
|
||||
0.001f, //step
|
||||
0.5f), //skew
|
||||
0.15f), //default
|
||||
0.15f), //default
|
||||
std::make_unique<AudioParameterFloat> ("vibratoDepth", "Depth", 0.0f, 2.0f, 0.0f),
|
||||
std::make_unique<AudioParameterFloat> ("vibratoDelay", "Delay", 0.0f, 1.0f, 0.3f),
|
||||
std::make_unique<AudioParameterBool> ("vibratoIgnoresWheel_raw", "Ignores Wheel", true),
|
||||
@ -92,13 +93,14 @@ Magical8bitPlug2AudioProcessor::Magical8bitPlug2AudioProcessor()
|
||||
// Sweep
|
||||
//
|
||||
std::make_unique<AudioParameterInt> ("sweepInitialPitch", "Ini.Pitch", -24, 24, 0),
|
||||
std::make_unique<AudioParameterInt> ("sweepEndPitch", "End.Pitch", -24, 24, 0),
|
||||
std::make_unique<AudioParameterFloat> ("sweepTime", //ID
|
||||
"Time", //name
|
||||
NormalisableRange<float> (0.01f, //min
|
||||
5.0f, //max
|
||||
0.001f, //step
|
||||
0.5f), //skew
|
||||
0.1f), //default
|
||||
0.1f), //default
|
||||
//
|
||||
// For Pulse
|
||||
//
|
||||
@ -106,7 +108,7 @@ Magical8bitPlug2AudioProcessor::Magical8bitPlug2AudioProcessor()
|
||||
//
|
||||
// For Noise
|
||||
//
|
||||
std::make_unique<AudioParameterChoice> ("noiseAlgorithm_raw", "Algorithm", StringArray ({"4bit Pure Random", "1bit Long Cycle", "1bit Short Cycle"}), 0),
|
||||
std::make_unique<AudioParameterChoice> ("noiseAlgorithm_raw", "Algorithm", StringArray ({"4bit Pure Random", "1bit Long Cycle", "1bit Short Cycle", "Nes Long Cycle", "Nes Short Cycle"}), 0),
|
||||
std::make_unique<AudioParameterBool> ("restrictsToNESFrequency_raw", "Restricts to NES frequency", false),
|
||||
//
|
||||
// Sequence
|
||||
@ -114,8 +116,77 @@ Magical8bitPlug2AudioProcessor::Magical8bitPlug2AudioProcessor()
|
||||
std::make_unique<AudioParameterBool> ("isVolumeSequenceEnabled_raw", "Enabled", false),
|
||||
std::make_unique<AudioParameterBool> ("isPitchSequenceEnabled_raw", "Enabled", false),
|
||||
std::make_unique<AudioParameterBool> ("isDutySequenceEnabled_raw", "Enabled", false),
|
||||
std::make_unique<AudioParameterChoice> ("pitchSequenceMode_raw", "Mode", StringArray ({"Coarse", "Fine"}), 0)
|
||||
}
|
||||
std::make_unique<AudioParameterChoice> ("pitchSequenceMode_raw", "Mode", StringArray ({"Coarse", "Fine8", "Fine16"}), 0),
|
||||
// waveform
|
||||
std::make_unique<AudioParameterChoice>("waveformX", "X", StringArray({ "16", "32", "64" }), 2),
|
||||
std::make_unique<AudioParameterChoice>("waveformY", "Y", StringArray({ "16", "32", "64" }), 2),
|
||||
std::make_unique<AudioParameterChoice>("waveformTemplate", "Template", StringArray({ "Custom", "Sine", "Triangle", "Sawtooth", "Square 6.25%", "Square 18.75%", "Square 31.25%", "Square 37.5%", "Square 43.75%" }), 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave0", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave1", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave2", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave3", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave4", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave5", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave6", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave7", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave8", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave9", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave10", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave11", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave12", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave13", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave14", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave15", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave16", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave17", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave18", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave19", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave20", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave21", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave22", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave23", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave24", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave25", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave26", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave27", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave28", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave29", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave30", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave31", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave32", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave33", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave34", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave35", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave36", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave37", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave38", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave39", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave40", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave41", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave42", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave43", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave44", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave45", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave46", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave47", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave48", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave49", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave50", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave51", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave52", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave53", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave54", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave55", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave56", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave57", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave58", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave59", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave60", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave61", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave62", "wave", 0, 63, 0),
|
||||
std::make_unique<AudioParameterFloat>("waveformWave63", "wave", 0, 63, 0)
|
||||
|
||||
}
|
||||
)
|
||||
, settingRefs (¶meters)
|
||||
#ifndef JucePlugin_PreferredChannelConfigurations
|
||||
@ -129,6 +200,16 @@ Magical8bitPlug2AudioProcessor::Magical8bitPlug2AudioProcessor()
|
||||
)
|
||||
#endif
|
||||
{
|
||||
// waveform
|
||||
//parameters.createAndAddParameter(std::make_unique<AudioParameterChoice>("waveformX", "X", StringArray({ "16", "32", "64" }), 2));
|
||||
//parameters.createAndAddParameter(std::make_unique<AudioParameterChoice>("waveformY", "Y", StringArray({ "16", "32", "64" }), 2));
|
||||
//parameters.createAndAddParameter(std::make_unique<AudioParameterChoice>("waveformTemplate", "Template", StringArray({ "Custom", "Sine", "Triangle", "Sawtooth", "Square 6.25%", "Square 18.75%", "Square 31.25%", "Square 37.5%", "Square 43.75%" }), 0));
|
||||
//for (int i = 0; i < 64; i++)
|
||||
//{
|
||||
// parameters.createAndAddParameter(std::make_unique<AudioParameterInt>("waveformWave" + String(i), "wave" + String(i), 0, 63, 0));
|
||||
//}
|
||||
//settingRefs.setWaveform(¶meters);
|
||||
|
||||
synth.setCurrentPlaybackSampleRate (44100); // Temporary setup, just in case. The actual sample rate is set in prepareToPlay func.
|
||||
|
||||
setupVoice();
|
||||
@ -171,6 +252,10 @@ void Magical8bitPlug2AudioProcessor::setupVoice()
|
||||
case kVoiceTypeNoise:
|
||||
synth.addVoice (new NoiseVoice (&settingRefs));
|
||||
break;
|
||||
|
||||
case kVoiceTypeWaveform:
|
||||
synth.addVoice(new WaveformVoice(&settingRefs));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -375,8 +460,13 @@ void Magical8bitPlug2AudioProcessor::getStateInformation (MemoryBlock& destData)
|
||||
copyXmlToBinary (*xml, destData);
|
||||
}
|
||||
|
||||
void Magical8bitPlug2AudioProcessor::setStateInformation (const void* data, int sizeInBytes)
|
||||
void Magical8bitPlug2AudioProcessor::setStateInformation(const void* data, int sizeInBytes)
|
||||
{
|
||||
//if (Magical8bitPlug2AudioProcessorEditor* activeEditor = (Magical8bitPlug2AudioProcessorEditor*)getActiveEditor())
|
||||
//{
|
||||
// activeEditor->waveformInit();
|
||||
//}
|
||||
|
||||
std::unique_ptr<XmlElement> xmlState (getXmlFromBinary (data, sizeInBytes));
|
||||
|
||||
if (xmlState.get() != nullptr)
|
||||
@ -473,6 +563,13 @@ void Magical8bitPlug2AudioProcessor::setStateInformation (const void* data, int
|
||||
}
|
||||
|
||||
setupVoice();
|
||||
|
||||
if (Magical8bitPlug2AudioProcessorEditor* activeEditor = (Magical8bitPlug2AudioProcessorEditor*)getActiveEditor())
|
||||
{
|
||||
activeEditor->resized();
|
||||
activeEditor->resizeWholePanel();
|
||||
activeEditor->waveformUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
@ -56,7 +56,37 @@ void PulseVoice::advanceControlFrame()
|
||||
|
||||
if (settingRefs->isDutySequenceEnabled())
|
||||
{
|
||||
currentDutySequenceFrame = settingRefs->dutySequence.nextIndexOf (currentDutySequenceFrame);
|
||||
currentDuty = (PulseDuty)settingRefs->dutySequence.valueAt (currentDutySequenceFrame);
|
||||
//currentDutySequenceFrame = settingRefs->dutySequence.nextIndexOf(currentDutySequenceFrame);
|
||||
//currentDuty = (PulseDuty)settingRefs->dutySequence.valueAt(currentDutySequenceFrame);
|
||||
|
||||
int currentDutySequenceFrameTmp = settingRefs->dutySequence.nextIndexOf(currentDutySequenceFrame);
|
||||
if (currentDutySequenceFrameTmp != FrameSequence::SHOULD_RETIRE)
|
||||
{
|
||||
currentDutySequenceFrame = currentDutySequenceFrameTmp;
|
||||
currentDuty = (PulseDuty)settingRefs->dutySequence.valueAt(currentDutySequenceFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PulseVoice::stopNote(float velocity, bool allowTailOff)
|
||||
{
|
||||
TonalVoice::stopNote(velocity, allowTailOff);
|
||||
|
||||
if (!allowTailOff)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (settingRefs->isDutySequenceEnabled())
|
||||
{
|
||||
if (settingRefs->dutySequence.hasRelease)
|
||||
{
|
||||
if (settingRefs->dutySequence.isInRelease(currentDutySequenceFrame)) {
|
||||
// Already in release(Custom Env.)
|
||||
return;
|
||||
}
|
||||
currentDutySequenceFrame = settingRefs->dutySequence.releaseSequenceStartIndex;
|
||||
currentDuty = (PulseDuty)settingRefs->dutySequence.valueAt(currentDutySequenceFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,4 +25,5 @@ struct PulseVoice : public TonalVoice
|
||||
SynthesiserSound*, int currentPitchWheelPosition) override;
|
||||
float voltageForAngle (double angle) override;
|
||||
void advanceControlFrame() override;
|
||||
void stopNote(float velocity, bool allowTailOff) override;
|
||||
};
|
||||
|
@ -77,3 +77,29 @@ String& SettingRefs::getSequenceString (const String& type)
|
||||
printf ("*** parameter type invalid!\n");
|
||||
return volumeSequenceString;
|
||||
}
|
||||
|
||||
//void SettingRefs::setWaveform(AudioProcessorValueTreeState* parameters)
|
||||
//{
|
||||
// // waveform
|
||||
// for (int i = 0; i < 64; i++)
|
||||
// {
|
||||
// waveformWave[i] = (float*)parameters->getRawParameterValue("waveformWave" + String(i));
|
||||
// }
|
||||
// waveformX = (float*)parameters->getRawParameterValue("waveformX");
|
||||
// waveformY = (float*)parameters->getRawParameterValue("waveformY");
|
||||
// waveformTemplate = (float*)parameters->getRawParameterValue("waveformTemplate");
|
||||
//}
|
||||
|
||||
int SettingRefs::getWaveformX()
|
||||
{
|
||||
int range[3] = {16, 32, 64};
|
||||
|
||||
return range[(int)(*waveformX)];
|
||||
}
|
||||
|
||||
int SettingRefs::getWaveformY()
|
||||
{
|
||||
int range[3] = { 16, 32, 64 };
|
||||
|
||||
return range[(int)(*waveformY)] - 1;
|
||||
}
|
||||
|
@ -23,7 +23,8 @@ enum VoiceType
|
||||
{
|
||||
kVoiceTypePulse = 0,
|
||||
kVoiceTypeTriangle,
|
||||
kVoiceTypeNoise
|
||||
kVoiceTypeNoise,
|
||||
kVoiceTypeWaveform
|
||||
};
|
||||
|
||||
struct PluginSettings
|
||||
@ -52,12 +53,15 @@ enum NoiseAlgorithm
|
||||
kNoiseInfinite2 = 0,
|
||||
kNoiseLong,
|
||||
kNoiseShort,
|
||||
kNoiseLongNes,
|
||||
kNoiseShortNes,
|
||||
};
|
||||
|
||||
enum PitchSequenceMode
|
||||
{
|
||||
kPitchSequenceModeCoarse = 0,
|
||||
kPitchSequenceModeFine
|
||||
kPitchSequenceModeFine,
|
||||
kPitchSequenceModeFine16
|
||||
};
|
||||
|
||||
class FrameSequenceChangeListener
|
||||
@ -108,6 +112,7 @@ struct SettingRefs
|
||||
float* vibratoIgnoresWheel_raw = nullptr;
|
||||
// Sweep
|
||||
float* sweepInitialPitch = nullptr;
|
||||
float* sweepEndPitch = nullptr;
|
||||
float* sweepTime = nullptr;
|
||||
// For Pulse
|
||||
float* duty = nullptr;
|
||||
@ -123,9 +128,9 @@ struct SettingRefs
|
||||
FrameSequence volumeSequence;
|
||||
FrameSequence pitchSequence;
|
||||
FrameSequence dutySequence;
|
||||
String volumeSequenceString = "";
|
||||
String pitchSequenceString = "";
|
||||
String dutySequenceString = "";
|
||||
String volumeSequenceString; //= "15 x 5, 15 to 0 in 15 [5, 4, 3] | 2, 1, 0";
|
||||
String pitchSequenceString; //= "15 x 5, 15 to 0 in 15 [5, 4, 3] | 2, 1, 0";
|
||||
String dutySequenceString; //= "2 x 5, 2 to 0 in 15 [2, 1, 0] | 2, 1, 0";
|
||||
|
||||
bool setSequenceWithString (const String& type, const String& input, ParseError* error);
|
||||
String& getSequenceString (const String& type);
|
||||
@ -152,6 +157,14 @@ struct SettingRefs
|
||||
bool isDutySequenceEnabled() { return *isDutySequenceEnabled_raw > 0.5; }
|
||||
PitchSequenceMode pitchSequenceMode() { return (PitchSequenceMode) ((int) (*pitchSequenceMode_raw)); }
|
||||
|
||||
// waveform
|
||||
//void setWaveform(AudioProcessorValueTreeState* parameters);
|
||||
int getWaveformX();
|
||||
int getWaveformY();
|
||||
float* waveformWave[64];
|
||||
float* waveformX = nullptr;
|
||||
float* waveformY = nullptr;
|
||||
float* waveformTemplate = nullptr;
|
||||
|
||||
//
|
||||
// constructor
|
||||
@ -183,6 +196,7 @@ struct SettingRefs
|
||||
vibratoIgnoresWheel_raw = (float*) parameters->getRawParameterValue ("vibratoIgnoresWheel_raw");
|
||||
// Sweep
|
||||
sweepInitialPitch = (float*) parameters->getRawParameterValue ("sweepInitialPitch");
|
||||
sweepEndPitch = (float*)parameters->getRawParameterValue("sweepEndPitch");
|
||||
sweepTime = (float*) parameters->getRawParameterValue ("sweepTime");
|
||||
// For Pulse
|
||||
duty = (float*) parameters->getRawParameterValue ("duty");
|
||||
@ -194,6 +208,13 @@ struct SettingRefs
|
||||
isPitchSequenceEnabled_raw = (float*) parameters->getRawParameterValue ("isPitchSequenceEnabled_raw");
|
||||
isDutySequenceEnabled_raw = (float*) parameters->getRawParameterValue ("isDutySequenceEnabled_raw");
|
||||
pitchSequenceMode_raw = (float*) parameters->getRawParameterValue ("pitchSequenceMode_raw");
|
||||
|
||||
// waveform
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
waveformWave[i] = (float*)parameters->getRawParameterValue("waveformWave" + String(i));
|
||||
}
|
||||
waveformX = (float*)parameters->getRawParameterValue("waveformX");
|
||||
waveformY = (float*)parameters->getRawParameterValue("waveformY");
|
||||
waveformTemplate = (float*)parameters->getRawParameterValue("waveformTemplate");
|
||||
}
|
||||
};
|
||||
|
172
Source/SliderVerticalComponent.cpp
Normal file
172
Source/SliderVerticalComponent.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This is an automatically generated GUI class created by the Projucer!
|
||||
|
||||
Be careful when adding custom code to these files, as only the code within
|
||||
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
|
||||
and re-saved.
|
||||
|
||||
Created with Projucer version: 6.0.8
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The Projucer is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
//[Headers] You can add your own extra header files here...
|
||||
//[/Headers]
|
||||
|
||||
#include "SliderVerticalComponent.h"
|
||||
|
||||
|
||||
//[MiscUserDefs] You can add your own user definitions and misc code here...
|
||||
//[/MiscUserDefs]
|
||||
|
||||
//==============================================================================
|
||||
SliderVerticalComponent::SliderVerticalComponent (Magical8bitPlug2AudioProcessor& p, String paramId)
|
||||
: processor(p)
|
||||
{
|
||||
//[Constructor_pre] You can add your own custom stuff here..
|
||||
setInterceptsMouseClicks(true, false);
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
verticalSliders[i].reset(new juce::Slider("vertical slider"));
|
||||
addAndMakeVisible(verticalSliders[i].get());
|
||||
verticalSliders[i]->setRange(0, 63, 0);
|
||||
verticalSliders[i]->setSliderStyle(juce::Slider::LinearBarVertical);
|
||||
verticalSliders[i]->setTextBoxStyle(juce::Slider::NoTextBox, true, 30, 20);
|
||||
verticalSliders[i]->setBounds(0 + i * 8, 0, 9, 250);
|
||||
verticalSliders[i]->setInterceptsMouseClicks(false, false);
|
||||
attc[i].reset(new SliderAttachment(p.parameters, paramId + String(i), *verticalSliders[i]));
|
||||
}
|
||||
//[/Constructor_pre]
|
||||
|
||||
|
||||
//[UserPreSize]
|
||||
//[/UserPreSize]
|
||||
|
||||
setSize (513, 250);
|
||||
|
||||
|
||||
//[Constructor] You can add your own custom stuff here..
|
||||
baseMaxValue = 63;
|
||||
//[/Constructor]
|
||||
}
|
||||
|
||||
SliderVerticalComponent::~SliderVerticalComponent()
|
||||
{
|
||||
//[Destructor_pre]. You can add your own custom destruction code here..
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
attc[i].reset();
|
||||
verticalSliders[i] = nullptr;
|
||||
}
|
||||
//[/Destructor_pre]
|
||||
|
||||
|
||||
|
||||
//[Destructor]. You can add your own custom destruction code here..
|
||||
//[/Destructor]
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void SliderVerticalComponent::paint (juce::Graphics& g)
|
||||
{
|
||||
//[UserPrePaint] Add your own custom painting code here..
|
||||
//[/UserPrePaint]
|
||||
|
||||
//[UserPaint] Add your own custom painting code here..
|
||||
//[/UserPaint]
|
||||
}
|
||||
|
||||
void SliderVerticalComponent::resized()
|
||||
{
|
||||
//[UserPreResize] Add your own custom resize code here..
|
||||
//[/UserPreResize]
|
||||
|
||||
//[UserResized] Add your own custom resize handling here..
|
||||
//[/UserResized]
|
||||
}
|
||||
|
||||
void SliderVerticalComponent::mouseDown (const juce::MouseEvent& e)
|
||||
{
|
||||
//[UserCode_mouseDown] -- Add your code here...
|
||||
mouseDrag(e);
|
||||
//[/UserCode_mouseDown]
|
||||
}
|
||||
|
||||
void SliderVerticalComponent::mouseDrag (const juce::MouseEvent& e)
|
||||
{
|
||||
//[UserCode_mouseDrag] -- Add your code here...
|
||||
int rate = (baseMaxValue + 1) / (maxValue + 1);
|
||||
int sliderIndex = jlimit(0, numWidth - 1, (int)floor(e.position.x / (getWidth() / ((double)numWidth))));
|
||||
waveValue = jlimit(0, baseMaxValue, (int)(baseMaxValue * ((double)getHeight() - (double)e.position.y) / ((double)getHeight()) + 0.5));
|
||||
waveValue = (int)(waveValue / rate);
|
||||
verticalSliders[sliderIndex]->setValue(((double)waveValue / maxValue * baseMaxValue));
|
||||
getParentComponent()->mouseDrag(e.getEventRelativeTo(getParentComponent()));
|
||||
//[/UserCode_mouseDrag]
|
||||
}
|
||||
|
||||
|
||||
|
||||
//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
|
||||
void SliderVerticalComponent::setForm(int numWidth, int maxValue, int width, int height)
|
||||
{
|
||||
this->numWidth = jlimit(0, 64, numWidth);
|
||||
this->maxValue = maxValue;
|
||||
|
||||
int sliderWidth = width / this->numWidth;
|
||||
|
||||
setSize(sliderWidth * this->numWidth + 1, height);
|
||||
|
||||
int rate = (baseMaxValue + 1) / (maxValue + 1);
|
||||
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
verticalSliders[i]->setBounds(0 + i * sliderWidth, 0, sliderWidth + 1, height);
|
||||
int value = verticalSliders[i]->getValue();
|
||||
verticalSliders[i]->setValue(((double)(value / rate) / maxValue * baseMaxValue));
|
||||
verticalSliders[i]->repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void SliderVerticalComponent::setValue(int index, int value)
|
||||
{
|
||||
verticalSliders[index]->setValue(((double)value / maxValue * baseMaxValue));
|
||||
}
|
||||
//[/MiscUserCode]
|
||||
|
||||
|
||||
//==============================================================================
|
||||
#if 0
|
||||
/* -- Projucer information section --
|
||||
|
||||
This is where the Projucer stores the metadata that describe this GUI layout, so
|
||||
make changes in here at your peril!
|
||||
|
||||
BEGIN_JUCER_METADATA
|
||||
|
||||
<JUCER_COMPONENT documentType="Component" className="SliderVerticalComponent"
|
||||
componentName="" parentClasses="public juce::Component" constructorParams="Magical8bitPlug2AudioProcessor& p, String paramId"
|
||||
variableInitialisers="processor(p)" snapPixels="8" snapActive="1"
|
||||
snapShown="1" overlayOpacity="0.330" fixedSize="1" initialWidth="513"
|
||||
initialHeight="250">
|
||||
<METHODS>
|
||||
<METHOD name="mouseDrag (const juce::MouseEvent& e)"/>
|
||||
<METHOD name="mouseDown (const juce::MouseEvent& e)"/>
|
||||
</METHODS>
|
||||
<BACKGROUND backgroundColour="ffffff"/>
|
||||
</JUCER_COMPONENT>
|
||||
|
||||
END_JUCER_METADATA
|
||||
*/
|
||||
#endif
|
||||
|
||||
|
||||
//[EndFile] You can add extra defines here...
|
||||
//[/EndFile]
|
||||
|
78
Source/SliderVerticalComponent.h
Normal file
78
Source/SliderVerticalComponent.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This is an automatically generated GUI class created by the Projucer!
|
||||
|
||||
Be careful when adding custom code to these files, as only the code within
|
||||
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
|
||||
and re-saved.
|
||||
|
||||
Created with Projucer version: 6.0.8
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The Projucer is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
//[Headers] -- You can add your own extra header files here --
|
||||
#include <JuceHeader.h>
|
||||
#include "PluginProcessor.h"
|
||||
#include "Defs.h"
|
||||
//[/Headers]
|
||||
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
//[Comments]
|
||||
An auto-generated component, created by the Projucer.
|
||||
|
||||
Describe your class and how it works here!
|
||||
//[/Comments]
|
||||
*/
|
||||
class SliderVerticalComponent : public juce::Component
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
SliderVerticalComponent (Magical8bitPlug2AudioProcessor& p, String paramId);
|
||||
~SliderVerticalComponent() override;
|
||||
|
||||
//==============================================================================
|
||||
//[UserMethods] -- You can add your own custom methods in this section.
|
||||
void setForm(int numWidth, int maxValue, int width, int height);
|
||||
void setValue(int index, int value);
|
||||
int waveValue = -1;
|
||||
//[/UserMethods]
|
||||
|
||||
void paint (juce::Graphics& g) override;
|
||||
void resized() override;
|
||||
void mouseDown (const juce::MouseEvent& e) override;
|
||||
void mouseDrag (const juce::MouseEvent& e) override;
|
||||
|
||||
|
||||
|
||||
private:
|
||||
//[UserVariables] -- You can add your own custom variables in this section.
|
||||
std::unique_ptr<juce::Slider> verticalSliders[64];
|
||||
int numWidth;
|
||||
int maxValue;
|
||||
int baseMaxValue;
|
||||
Magical8bitPlug2AudioProcessor& processor;
|
||||
std::unique_ptr<SliderAttachment> attc[64];
|
||||
//[/UserVariables]
|
||||
|
||||
//==============================================================================
|
||||
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SliderVerticalComponent)
|
||||
};
|
||||
|
||||
//[EndFile] You can add extra defines here...
|
||||
//[/EndFile]
|
||||
|
@ -51,11 +51,15 @@ SweepParamsComponent::SweepParamsComponent (Magical8bitPlug2AudioProcessor& p)
|
||||
addAndMakeVisible (timeSlider.get());
|
||||
timeSlider->setName ("time slider");
|
||||
|
||||
endPitchSlider.reset (new SliderComponent (p, "sweepEndPitch", "End.Pitch"));
|
||||
addAndMakeVisible (endPitchSlider.get());
|
||||
endPitchSlider->setName ("end pitch slider");
|
||||
|
||||
|
||||
//[UserPreSize]
|
||||
//[/UserPreSize]
|
||||
|
||||
setSize (340, 86);
|
||||
setSize (340, 114);
|
||||
|
||||
|
||||
//[Constructor] You can add your own custom stuff here..
|
||||
@ -70,6 +74,7 @@ SweepParamsComponent::~SweepParamsComponent()
|
||||
label = nullptr;
|
||||
iniPitchSlider = nullptr;
|
||||
timeSlider = nullptr;
|
||||
endPitchSlider = nullptr;
|
||||
|
||||
|
||||
//[Destructor]. You can add your own custom destruction code here..
|
||||
@ -92,7 +97,8 @@ void SweepParamsComponent::resized()
|
||||
//[/UserPreResize]
|
||||
|
||||
iniPitchSlider->setBounds (0, 26, proportionOfWidth (1.0000f), 28);
|
||||
timeSlider->setBounds (0, 54, proportionOfWidth (1.0000f), 28);
|
||||
timeSlider->setBounds (0, 82, proportionOfWidth (1.0000f), 28);
|
||||
endPitchSlider->setBounds (0, 54, proportionOfWidth (1.0000f), 28);
|
||||
//[UserResized] Add your own custom resize handling here..
|
||||
//[/UserResized]
|
||||
}
|
||||
@ -115,7 +121,7 @@ BEGIN_JUCER_METADATA
|
||||
<JUCER_COMPONENT documentType="Component" className="SweepParamsComponent" componentName=""
|
||||
parentClasses="public Component" constructorParams="Magical8bitPlug2AudioProcessor& p"
|
||||
variableInitialisers="" snapPixels="8" snapActive="1" snapShown="1"
|
||||
overlayOpacity="0.330" fixedSize="1" initialWidth="340" initialHeight="86">
|
||||
overlayOpacity="0.330" fixedSize="1" initialWidth="340" initialHeight="114">
|
||||
<BACKGROUND backgroundColour="ffffff"/>
|
||||
<LABEL name="label" id="bae3132bcad681ce" memberName="label" virtualName=""
|
||||
explicitFocusOrder="0" pos="0 4 150 22" edTextCol="ff000000"
|
||||
@ -126,8 +132,11 @@ BEGIN_JUCER_METADATA
|
||||
virtualName="" explicitFocusOrder="0" pos="0 26 100% 28" class="SliderComponent"
|
||||
params="p, "sweepInitialPitch", "Ini.Pitch""/>
|
||||
<GENERICCOMPONENT name="time slider" id="1be45518932375fc" memberName="timeSlider"
|
||||
virtualName="" explicitFocusOrder="0" pos="0 54 100% 28" class="SliderComponent"
|
||||
virtualName="" explicitFocusOrder="0" pos="0 82 100% 28" class="SliderComponent"
|
||||
params="p, "sweepTime", "Time""/>
|
||||
<GENERICCOMPONENT name="end pitch slider" id="25cde38cec6274db" memberName="endPitchSlider"
|
||||
virtualName="" explicitFocusOrder="0" pos="0 54 100% 28" class="SliderComponent"
|
||||
params="p, "sweepEndPitch", "End.Pitch""/>
|
||||
</JUCER_COMPONENT>
|
||||
|
||||
END_JUCER_METADATA
|
||||
|
@ -58,6 +58,7 @@ private:
|
||||
std::unique_ptr<juce::Label> label;
|
||||
std::unique_ptr<SliderComponent> iniPitchSlider;
|
||||
std::unique_ptr<SliderComponent> timeSlider;
|
||||
std::unique_ptr<SliderComponent> endPitchSlider;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
|
@ -27,16 +27,28 @@ void TonalVoice::startNote (int midiNoteNumber, float velocity, SynthesiserSound
|
||||
vibratoCount = 0;
|
||||
|
||||
float iniPitch = * (settingRefs->sweepInitialPitch);
|
||||
float endPitch = *(settingRefs->sweepEndPitch);
|
||||
float time = * (settingRefs->sweepTime);
|
||||
currentAutoBendAmount = iniPitch;
|
||||
autoBendDelta = -1.0 * iniPitch / (time * getSampleRate());
|
||||
autoBendDelta = -1.0 * (iniPitch - endPitch) / (time * getSampleRate());
|
||||
|
||||
//if (*(settingRefs->osc) == kVoiceTypeTriangle)
|
||||
//{
|
||||
// nesPitchCorrection = -12;
|
||||
//}
|
||||
}
|
||||
|
||||
void TonalVoice::advanceControlFrame()
|
||||
{
|
||||
BaseVoice::advanceControlFrame();
|
||||
|
||||
currentPitchSequenceFrame = settingRefs->pitchSequence.nextIndexOf (currentPitchSequenceFrame);
|
||||
//currentPitchSequenceFrame = settingRefs->pitchSequence.nextIndexOf(currentPitchSequenceFrame);
|
||||
|
||||
int currentPitchSequenceFrameTmp = settingRefs->pitchSequence.nextIndexOf(currentPitchSequenceFrame);
|
||||
if (currentPitchSequenceFrameTmp != FrameSequence::SHOULD_RETIRE)
|
||||
{
|
||||
currentPitchSequenceFrame = currentPitchSequenceFrameTmp;
|
||||
}
|
||||
}
|
||||
|
||||
void TonalVoice::calculateAngleDelta()
|
||||
@ -49,6 +61,10 @@ void TonalVoice::calculateAngleDelta()
|
||||
{
|
||||
switch (settingRefs->pitchSequenceMode())
|
||||
{
|
||||
case kPitchSequenceModeFine16:
|
||||
finePitchInSeq = (double)settingRefs->pitchSequence.valueAt (currentPitchSequenceFrame) / 16.0;
|
||||
break;
|
||||
|
||||
case kPitchSequenceModeFine:
|
||||
finePitchInSeq = (double)settingRefs->pitchSequence.valueAt (currentPitchSequenceFrame) / 8.0;
|
||||
break;
|
||||
@ -69,7 +85,8 @@ void TonalVoice::calculateAngleDelta()
|
||||
+ currentBendAmount
|
||||
+ currentAutoBendAmount
|
||||
+ vibratoAmount
|
||||
+ finePitchInSeq;
|
||||
+ finePitchInSeq
|
||||
+ nesPitchCorrection;
|
||||
|
||||
auto cyclesPerSecond = noteNoToHeltzDouble (noteNoInDouble);
|
||||
auto cyclesPerSample = cyclesPerSecond / getSampleRate();
|
||||
@ -118,19 +135,41 @@ void TonalVoice::onFrameAdvanced()
|
||||
if (autoBendDelta > 0)
|
||||
{
|
||||
// positive slope
|
||||
if (currentAutoBendAmount > 0)
|
||||
if (currentAutoBendAmount > *(settingRefs->sweepEndPitch))
|
||||
{
|
||||
currentAutoBendAmount = 0;
|
||||
currentAutoBendAmount = *(settingRefs->sweepEndPitch);
|
||||
autoBendDelta = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// negative slope
|
||||
if (currentAutoBendAmount < 0)
|
||||
if (currentAutoBendAmount < *(settingRefs->sweepEndPitch))
|
||||
{
|
||||
currentAutoBendAmount = 0;
|
||||
currentAutoBendAmount = *(settingRefs->sweepEndPitch);
|
||||
autoBendDelta = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void TonalVoice::stopNote(float velocity, bool allowTailOff)
|
||||
{
|
||||
BaseVoice::stopNote(velocity, allowTailOff);
|
||||
|
||||
if (!allowTailOff)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (settingRefs->isPitchSequenceEnabled())
|
||||
{
|
||||
if (settingRefs->pitchSequence.hasRelease)
|
||||
{
|
||||
if (settingRefs->pitchSequence.isInRelease(currentPitchSequenceFrame)) {
|
||||
// Already in release(Custom Env.)
|
||||
return;
|
||||
}
|
||||
currentPitchSequenceFrame = settingRefs->pitchSequence.releaseSequenceStartIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ struct TonalVoice : public BaseVoice // The base for Pulse and Triangle
|
||||
// Custom Pitch/Note states
|
||||
int currentPitchSequenceFrame = 0;
|
||||
|
||||
double nesPitchCorrection = 0;
|
||||
|
||||
void startNote (int midiNoteNumber, float velocity,
|
||||
SynthesiserSound*, int currentPitchWheelPosition) override;
|
||||
void advanceControlFrame() override;
|
||||
@ -46,4 +48,5 @@ struct TonalVoice : public BaseVoice // The base for Pulse and Triangle
|
||||
double noteNoToHeltzDouble (double noteNoInDouble, const double frequencyOfA = 440);
|
||||
|
||||
void onFrameAdvanced() override;
|
||||
void stopNote(float velocity, bool allowTailOff) override;
|
||||
};
|
||||
|
374
Source/WaveformParamsComponent.cpp
Normal file
374
Source/WaveformParamsComponent.cpp
Normal file
@ -0,0 +1,374 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This is an automatically generated GUI class created by the Projucer!
|
||||
|
||||
Be careful when adding custom code to these files, as only the code within
|
||||
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
|
||||
and re-saved.
|
||||
|
||||
Created with Projucer version: 6.0.8
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The Projucer is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
//[Headers] You can add your own extra header files here...
|
||||
//[/Headers]
|
||||
|
||||
#include "WaveformParamsComponent.h"
|
||||
|
||||
|
||||
//[MiscUserDefs] You can add your own user definitions and misc code here...
|
||||
//[/MiscUserDefs]
|
||||
|
||||
//==============================================================================
|
||||
WaveformParamsComponent::WaveformParamsComponent (Magical8bitPlug2AudioProcessor& p)
|
||||
: processor(p)
|
||||
{
|
||||
//[Constructor_pre] You can add your own custom stuff here..
|
||||
//[/Constructor_pre]
|
||||
|
||||
sliderVerticalComponent.reset (new SliderVerticalComponent (p, "waveformWave"));
|
||||
addAndMakeVisible (sliderVerticalComponent.get());
|
||||
sliderVerticalComponent->setName ("slider vertical component");
|
||||
|
||||
sliderVerticalComponent->setBounds (10, 34, 513, 250);
|
||||
|
||||
label.reset (new juce::Label ("label",
|
||||
TRANS("Waveform")));
|
||||
addAndMakeVisible (label.get());
|
||||
label->setFont (juce::Font (17.00f, juce::Font::plain).withTypefaceStyle ("Regular"));
|
||||
label->setJustificationType (juce::Justification::centredLeft);
|
||||
label->setEditable (false, false, false);
|
||||
label->setColour (juce::TextEditor::textColourId, juce::Colours::black);
|
||||
label->setColour (juce::TextEditor::backgroundColourId, juce::Colour (0x00000000));
|
||||
|
||||
label->setBounds (0, 4, 150, 22);
|
||||
|
||||
waveformWaveText.reset (new juce::TextEditor ("waveform wave text"));
|
||||
addAndMakeVisible (waveformWaveText.get());
|
||||
waveformWaveText->setMultiLine (false);
|
||||
waveformWaveText->setReturnKeyStartsNewLine (false);
|
||||
waveformWaveText->setReadOnly (true);
|
||||
waveformWaveText->setScrollbarsShown (false);
|
||||
waveformWaveText->setCaretVisible (false);
|
||||
waveformWaveText->setPopupMenuEnabled (false);
|
||||
waveformWaveText->setText (juce::String());
|
||||
|
||||
waveformWaveText->setBounds (472, 8, 50, 20);
|
||||
|
||||
waveformComboX.reset (new juce::ComboBox ("waveform combo x"));
|
||||
addAndMakeVisible (waveformComboX.get());
|
||||
waveformComboX->setEditableText (false);
|
||||
waveformComboX->setJustificationType (juce::Justification::centredLeft);
|
||||
waveformComboX->setTextWhenNothingSelected (juce::String());
|
||||
waveformComboX->setTextWhenNoChoicesAvailable (TRANS("(no choices)"));
|
||||
waveformComboX->addListener (this);
|
||||
|
||||
waveformComboX->setBounds (40, 296, 80, 24);
|
||||
|
||||
waveformXLabel.reset (new juce::Label ("waveform x label",
|
||||
TRANS("X")));
|
||||
addAndMakeVisible (waveformXLabel.get());
|
||||
waveformXLabel->setFont (juce::Font (15.00f, juce::Font::plain).withTypefaceStyle ("Regular"));
|
||||
waveformXLabel->setJustificationType (juce::Justification::centredLeft);
|
||||
waveformXLabel->setEditable (false, false, false);
|
||||
waveformXLabel->setColour (juce::TextEditor::textColourId, juce::Colours::black);
|
||||
waveformXLabel->setColour (juce::TextEditor::backgroundColourId, juce::Colour (0x00000000));
|
||||
|
||||
waveformXLabel->setBounds (16, 296, 24, 24);
|
||||
|
||||
waveformYLabel.reset (new juce::Label ("waveform y label",
|
||||
TRANS("Y")));
|
||||
addAndMakeVisible (waveformYLabel.get());
|
||||
waveformYLabel->setFont (juce::Font (15.00f, juce::Font::plain).withTypefaceStyle ("Regular"));
|
||||
waveformYLabel->setJustificationType (juce::Justification::centredLeft);
|
||||
waveformYLabel->setEditable (false, false, false);
|
||||
waveformYLabel->setColour (juce::TextEditor::textColourId, juce::Colours::black);
|
||||
waveformYLabel->setColour (juce::TextEditor::backgroundColourId, juce::Colour (0x00000000));
|
||||
|
||||
waveformYLabel->setBounds (136, 296, 24, 24);
|
||||
|
||||
waveformComboY.reset (new juce::ComboBox ("waveform combo y"));
|
||||
addAndMakeVisible (waveformComboY.get());
|
||||
waveformComboY->setEditableText (false);
|
||||
waveformComboY->setJustificationType (juce::Justification::centredLeft);
|
||||
waveformComboY->setTextWhenNothingSelected (juce::String());
|
||||
waveformComboY->setTextWhenNoChoicesAvailable (TRANS("(no choices)"));
|
||||
waveformComboY->addListener (this);
|
||||
|
||||
waveformComboY->setBounds (160, 296, 80, 24);
|
||||
|
||||
waveformTemplateLabel.reset (new juce::Label ("waveform template label",
|
||||
TRANS("Template")));
|
||||
addAndMakeVisible (waveformTemplateLabel.get());
|
||||
waveformTemplateLabel->setFont (juce::Font (15.00f, juce::Font::plain).withTypefaceStyle ("Regular"));
|
||||
waveformTemplateLabel->setJustificationType (juce::Justification::centredLeft);
|
||||
waveformTemplateLabel->setEditable (false, false, false);
|
||||
waveformTemplateLabel->setColour (juce::TextEditor::textColourId, juce::Colours::black);
|
||||
waveformTemplateLabel->setColour (juce::TextEditor::backgroundColourId, juce::Colour (0x00000000));
|
||||
|
||||
waveformTemplateLabel->setBounds (280, 296, 72, 24);
|
||||
|
||||
waveformComboTemplate.reset (new juce::ComboBox ("waveform combo template"));
|
||||
addAndMakeVisible (waveformComboTemplate.get());
|
||||
waveformComboTemplate->setEditableText (false);
|
||||
waveformComboTemplate->setJustificationType (juce::Justification::centredLeft);
|
||||
waveformComboTemplate->setTextWhenNothingSelected (juce::String());
|
||||
waveformComboTemplate->setTextWhenNoChoicesAvailable (TRANS("(no choices)"));
|
||||
waveformComboTemplate->addListener (this);
|
||||
|
||||
waveformComboTemplate->setBounds (352, 296, 168, 24);
|
||||
|
||||
|
||||
//[UserPreSize]
|
||||
//[/UserPreSize]
|
||||
|
||||
setSize (536, 340);
|
||||
|
||||
|
||||
//[Constructor] You can add your own custom stuff here..
|
||||
AudioParameterChoice* cX = (AudioParameterChoice*)p.parameters.getParameter("waveformX");
|
||||
for (int i = 0; i < cX->choices.size(); i++)
|
||||
{
|
||||
String choice = cX->choices[i];
|
||||
waveformComboX->addItem(choice, i + 1);
|
||||
}
|
||||
waveformComboX->setSelectedItemIndex(cX->getIndex());
|
||||
attcX.reset(new ComboBoxAttachment(p.parameters, "waveformX", *waveformComboX));
|
||||
|
||||
AudioParameterChoice* cY = (AudioParameterChoice*)p.parameters.getParameter("waveformY");
|
||||
for (int i = 0; i < cY->choices.size(); i++)
|
||||
{
|
||||
String choice = cY->choices[i];
|
||||
waveformComboY->addItem(choice, i + 1);
|
||||
}
|
||||
waveformComboY->setSelectedItemIndex(cY->getIndex());
|
||||
attcY.reset(new ComboBoxAttachment(p.parameters, "waveformY", *waveformComboY));
|
||||
|
||||
AudioParameterChoice* cTemplate = (AudioParameterChoice*)p.parameters.getParameter("waveformTemplate");
|
||||
for (int i = 0; i < cTemplate->choices.size(); i++)
|
||||
{
|
||||
String choice = cTemplate->choices[i];
|
||||
waveformComboTemplate->addItem(choice, i + 1);
|
||||
}
|
||||
waveformComboTemplate->setSelectedItemIndex(cTemplate->getIndex());
|
||||
attcTemplate.reset(new ComboBoxAttachment(p.parameters, "waveformTemplate", *waveformComboTemplate));
|
||||
|
||||
int fontHeight = waveformWaveText->getFont().getHeight();
|
||||
int topIndent = (waveformWaveText->getHeight() - fontHeight) / 2;
|
||||
int fontWidth = fontHeight;
|
||||
int leftIndent = (waveformWaveText->getWidth() - fontWidth) / 2;
|
||||
waveformWaveText->setBorder(BorderSize<int>(0, 0, 0, 0));
|
||||
waveformWaveText->setIndents(leftIndent, topIndent);
|
||||
//[/Constructor]
|
||||
}
|
||||
|
||||
WaveformParamsComponent::~WaveformParamsComponent()
|
||||
{
|
||||
//[Destructor_pre]. You can add your own custom destruction code here..
|
||||
attcX.reset();
|
||||
attcY.reset();
|
||||
attcTemplate.reset();
|
||||
//[/Destructor_pre]
|
||||
|
||||
sliderVerticalComponent = nullptr;
|
||||
label = nullptr;
|
||||
waveformWaveText = nullptr;
|
||||
waveformComboX = nullptr;
|
||||
waveformXLabel = nullptr;
|
||||
waveformYLabel = nullptr;
|
||||
waveformComboY = nullptr;
|
||||
waveformTemplateLabel = nullptr;
|
||||
waveformComboTemplate = nullptr;
|
||||
|
||||
|
||||
//[Destructor]. You can add your own custom destruction code here..
|
||||
//[/Destructor]
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void WaveformParamsComponent::paint (juce::Graphics& g)
|
||||
{
|
||||
//[UserPrePaint] Add your own custom painting code here..
|
||||
//[/UserPrePaint]
|
||||
|
||||
//[UserPaint] Add your own custom painting code here..
|
||||
//[/UserPaint]
|
||||
}
|
||||
|
||||
void WaveformParamsComponent::resized()
|
||||
{
|
||||
//[UserPreResize] Add your own custom resize code here..
|
||||
//[/UserPreResize]
|
||||
|
||||
//[UserResized] Add your own custom resize handling here..
|
||||
//[/UserResized]
|
||||
}
|
||||
|
||||
void WaveformParamsComponent::comboBoxChanged (juce::ComboBox* comboBoxThatHasChanged)
|
||||
{
|
||||
//[UsercomboBoxChanged_Pre]
|
||||
//[/UsercomboBoxChanged_Pre]
|
||||
|
||||
if (comboBoxThatHasChanged == waveformComboX.get())
|
||||
{
|
||||
//[UserComboBoxCode_waveformComboX] -- add your combo box handling code here..
|
||||
sliderVerticalComponent->setForm(processor.settingRefs.getWaveformX(), processor.settingRefs.getWaveformY(), 513, 250);
|
||||
//[/UserComboBoxCode_waveformComboX]
|
||||
}
|
||||
else if (comboBoxThatHasChanged == waveformComboY.get())
|
||||
{
|
||||
//[UserComboBoxCode_waveformComboY] -- add your combo box handling code here..
|
||||
sliderVerticalComponent->setForm(processor.settingRefs.getWaveformX(), processor.settingRefs.getWaveformY(), 513, 250);
|
||||
//[/UserComboBoxCode_waveformComboY]
|
||||
}
|
||||
else if (comboBoxThatHasChanged == waveformComboTemplate.get())
|
||||
{
|
||||
//[UserComboBoxCode_waveformComboTemplate] -- add your combo box handling code here..
|
||||
//0:"Custom", 1:"Sine", 2:"Triangle", 3:"Sawtooth", 4:"Square 6.25%", 5:"Square 18.75%", 6:"Square 31.25%", 7:"Square 37.5%", 8:"Square 43.75%"
|
||||
int x = processor.settingRefs.getWaveformX();
|
||||
int y = processor.settingRefs.getWaveformY();
|
||||
if (waveformComboTemplate->getSelectedItemIndex() == 1)
|
||||
{
|
||||
double twopi = MathConstants<float>::pi * 2.0;
|
||||
for (int i = 0; i < x; i++)
|
||||
{
|
||||
sliderVerticalComponent->setValue(i, (int)((std::sin(twopi * i / x) + 1.0) * y / 2.0 + 0.5));
|
||||
}
|
||||
}
|
||||
else if (waveformComboTemplate->getSelectedItemIndex() == 2)
|
||||
{
|
||||
for (int i = 0; i < (x / 2); i++)
|
||||
{
|
||||
sliderVerticalComponent->setValue(i, (int)(i * (double)y / (x / 2 - 1) + 0.5));
|
||||
sliderVerticalComponent->setValue(i + (x / 2), (int)(y - i * (double)y / (x / 2 - 1) + 0.5));
|
||||
}
|
||||
}
|
||||
else if (waveformComboTemplate->getSelectedItemIndex() == 3)
|
||||
{
|
||||
for (int i = 0; i < x; i++)
|
||||
{
|
||||
sliderVerticalComponent->setValue(i, (int)(i * (double)y / (x - 1) + 0.5));
|
||||
}
|
||||
}
|
||||
else if (waveformComboTemplate->getSelectedItemIndex() >= 4 && waveformComboTemplate->getSelectedItemIndex() <= 8)
|
||||
{
|
||||
double duty[5] = { 0.0625, 0.1875, 0.3125, 0.375, 0.4375 };
|
||||
for (int i = 0; i < (int)(x * duty[waveformComboTemplate->getSelectedItemIndex() - 4]); i++)
|
||||
{
|
||||
sliderVerticalComponent->setValue(i, 0);
|
||||
}
|
||||
for (int i = (int)(x * duty[waveformComboTemplate->getSelectedItemIndex() - 4]); i < x; i++)
|
||||
{
|
||||
sliderVerticalComponent->setValue(i, y);
|
||||
}
|
||||
}
|
||||
waveformComboTemplate->setSelectedItemIndex(0);
|
||||
//[/UserComboBoxCode_waveformComboTemplate]
|
||||
}
|
||||
|
||||
//[UsercomboBoxChanged_Post]
|
||||
//[/UsercomboBoxChanged_Post]
|
||||
}
|
||||
|
||||
void WaveformParamsComponent::mouseDrag (const juce::MouseEvent& e)
|
||||
{
|
||||
//[UserCode_mouseDrag] -- Add your code here...
|
||||
int waveValue = sliderVerticalComponent->waveValue;
|
||||
if (waveValue >= 0)
|
||||
{
|
||||
waveformWaveText->setText(String(waveValue));
|
||||
}
|
||||
//[/UserCode_mouseDrag]
|
||||
}
|
||||
|
||||
|
||||
|
||||
//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
|
||||
void WaveformParamsComponent::sliderRepaint()
|
||||
{
|
||||
sliderVerticalComponent->setForm(processor.settingRefs.getWaveformX(), processor.settingRefs.getWaveformY(), 513, 250);
|
||||
}
|
||||
|
||||
//void WaveformParamsComponent::sliderInit()
|
||||
//{
|
||||
// for (int i = 0; i < 64; i++)
|
||||
// {
|
||||
// //sliderVerticalComponent->verticalSliders[i]->setValue(0);
|
||||
// sliderVerticalComponent->verticalSliders[i]->setRange(0, 63, 1);
|
||||
// //sliderVerticalComponent->verticalSliders[i]->repaint();
|
||||
// }
|
||||
//}
|
||||
//[/MiscUserCode]
|
||||
|
||||
|
||||
//==============================================================================
|
||||
#if 0
|
||||
/* -- Projucer information section --
|
||||
|
||||
This is where the Projucer stores the metadata that describe this GUI layout, so
|
||||
make changes in here at your peril!
|
||||
|
||||
BEGIN_JUCER_METADATA
|
||||
|
||||
<JUCER_COMPONENT documentType="Component" className="WaveformParamsComponent"
|
||||
componentName="" parentClasses="public Component" constructorParams="Magical8bitPlug2AudioProcessor& p"
|
||||
variableInitialisers="processor(p)" snapPixels="8" snapActive="1"
|
||||
snapShown="1" overlayOpacity="0.330" fixedSize="1" initialWidth="536"
|
||||
initialHeight="340">
|
||||
<METHODS>
|
||||
<METHOD name="mouseDrag (const juce::MouseEvent& e)"/>
|
||||
</METHODS>
|
||||
<BACKGROUND backgroundColour="ffffff"/>
|
||||
<GENERICCOMPONENT name="slider vertical component" id="d3c5ea1dec0891ea" memberName="sliderVerticalComponent"
|
||||
virtualName="" explicitFocusOrder="0" pos="10 34 513 250" class="SliderVerticalComponent"
|
||||
params="p, "waveformWave""/>
|
||||
<LABEL name="label" id="bae3132bcad681ce" memberName="label" virtualName=""
|
||||
explicitFocusOrder="0" pos="0 4 150 22" edTextCol="ff000000"
|
||||
edBkgCol="0" labelText="Waveform" editableSingleClick="0" editableDoubleClick="0"
|
||||
focusDiscardsChanges="0" fontname="Default font" fontsize="17.0"
|
||||
kerning="0.0" bold="0" italic="0" justification="33"/>
|
||||
<TEXTEDITOR name="waveform wave text" id="a0d4c4fff23ba9a7" memberName="waveformWaveText"
|
||||
virtualName="" explicitFocusOrder="0" pos="472 8 50 20" initialText=""
|
||||
multiline="0" retKeyStartsLine="0" readonly="1" scrollbars="0"
|
||||
caret="0" popupmenu="0"/>
|
||||
<COMBOBOX name="waveform combo x" id="47a8fb84e28a923b" memberName="waveformComboX"
|
||||
virtualName="" explicitFocusOrder="0" pos="40 296 80 24" editable="0"
|
||||
layout="33" items="" textWhenNonSelected="" textWhenNoItems="(no choices)"/>
|
||||
<LABEL name="waveform x label" id="80e4ef8bbf096c16" memberName="waveformXLabel"
|
||||
virtualName="" explicitFocusOrder="0" pos="16 296 24 24" edTextCol="ff000000"
|
||||
edBkgCol="0" labelText="X" editableSingleClick="0" editableDoubleClick="0"
|
||||
focusDiscardsChanges="0" fontname="Default font" fontsize="15.0"
|
||||
kerning="0.0" bold="0" italic="0" justification="33"/>
|
||||
<LABEL name="waveform y label" id="9d743f56f93330a9" memberName="waveformYLabel"
|
||||
virtualName="" explicitFocusOrder="0" pos="136 296 24 24" edTextCol="ff000000"
|
||||
edBkgCol="0" labelText="Y" editableSingleClick="0" editableDoubleClick="0"
|
||||
focusDiscardsChanges="0" fontname="Default font" fontsize="15.0"
|
||||
kerning="0.0" bold="0" italic="0" justification="33"/>
|
||||
<COMBOBOX name="waveform combo y" id="519e5c60d0487582" memberName="waveformComboY"
|
||||
virtualName="" explicitFocusOrder="0" pos="160 296 80 24" editable="0"
|
||||
layout="33" items="" textWhenNonSelected="" textWhenNoItems="(no choices)"/>
|
||||
<LABEL name="waveform template label" id="c0bf04a500a0f7b" memberName="waveformTemplateLabel"
|
||||
virtualName="" explicitFocusOrder="0" pos="280 296 72 24" edTextCol="ff000000"
|
||||
edBkgCol="0" labelText="Template" editableSingleClick="0" editableDoubleClick="0"
|
||||
focusDiscardsChanges="0" fontname="Default font" fontsize="15.0"
|
||||
kerning="0.0" bold="0" italic="0" justification="33"/>
|
||||
<COMBOBOX name="waveform combo template" id="a71bba02a0c84649" memberName="waveformComboTemplate"
|
||||
virtualName="" explicitFocusOrder="0" pos="352 296 168 24" editable="0"
|
||||
layout="33" items="" textWhenNonSelected="" textWhenNoItems="(no choices)"/>
|
||||
</JUCER_COMPONENT>
|
||||
|
||||
END_JUCER_METADATA
|
||||
*/
|
||||
#endif
|
||||
|
||||
|
||||
//[EndFile] You can add extra defines here...
|
||||
//[/EndFile]
|
||||
|
84
Source/WaveformParamsComponent.h
Normal file
84
Source/WaveformParamsComponent.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This is an automatically generated GUI class created by the Projucer!
|
||||
|
||||
Be careful when adding custom code to these files, as only the code within
|
||||
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
|
||||
and re-saved.
|
||||
|
||||
Created with Projucer version: 6.0.8
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The Projucer is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
//[Headers] -- You can add your own extra header files here --
|
||||
#include <JuceHeader.h>
|
||||
#include "SliderVerticalComponent.h"
|
||||
//[/Headers]
|
||||
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
//[Comments]
|
||||
An auto-generated component, created by the Projucer.
|
||||
|
||||
Describe your class and how it works here!
|
||||
//[/Comments]
|
||||
*/
|
||||
class WaveformParamsComponent : public Component,
|
||||
public juce::ComboBox::Listener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
WaveformParamsComponent (Magical8bitPlug2AudioProcessor& p);
|
||||
~WaveformParamsComponent() override;
|
||||
|
||||
//==============================================================================
|
||||
//[UserMethods] -- You can add your own custom methods in this section.
|
||||
void sliderRepaint();
|
||||
//void sliderInit();
|
||||
//[/UserMethods]
|
||||
|
||||
void paint (juce::Graphics& g) override;
|
||||
void resized() override;
|
||||
void comboBoxChanged (juce::ComboBox* comboBoxThatHasChanged) override;
|
||||
void mouseDrag (const juce::MouseEvent& e) override;
|
||||
|
||||
|
||||
|
||||
private:
|
||||
//[UserVariables] -- You can add your own custom variables in this section.
|
||||
Magical8bitPlug2AudioProcessor& processor;
|
||||
std::unique_ptr<ComboBoxAttachment> attcX;
|
||||
std::unique_ptr<ComboBoxAttachment> attcY;
|
||||
std::unique_ptr<ComboBoxAttachment> attcTemplate;
|
||||
//[/UserVariables]
|
||||
|
||||
//==============================================================================
|
||||
std::unique_ptr<SliderVerticalComponent> sliderVerticalComponent;
|
||||
std::unique_ptr<juce::Label> label;
|
||||
std::unique_ptr<juce::TextEditor> waveformWaveText;
|
||||
std::unique_ptr<juce::ComboBox> waveformComboX;
|
||||
std::unique_ptr<juce::Label> waveformXLabel;
|
||||
std::unique_ptr<juce::Label> waveformYLabel;
|
||||
std::unique_ptr<juce::ComboBox> waveformComboY;
|
||||
std::unique_ptr<juce::Label> waveformTemplateLabel;
|
||||
std::unique_ptr<juce::ComboBox> waveformComboTemplate;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WaveformParamsComponent)
|
||||
};
|
||||
|
||||
//[EndFile] You can add extra defines here...
|
||||
//[/EndFile]
|
||||
|
39
Source/WaveformVoice.cpp
Normal file
39
Source/WaveformVoice.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
WaveformVoice.cpp
|
||||
Created: 7 Jul 2021 5:57:30am
|
||||
Author: SHACHO
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "WaveformVoice.h"
|
||||
|
||||
//---------------------------------------------
|
||||
//
|
||||
// Waveform Voice
|
||||
//
|
||||
//---------------------------------------------
|
||||
WaveformVoice::WaveformVoice(SettingRefs* sRefs) : TonalVoice(sRefs) {}
|
||||
|
||||
float WaveformVoice::voltageForAngle(double angle)
|
||||
{
|
||||
int x = settingRefs->getWaveformX();
|
||||
int y = 63; // settingRefs->getWaveformY();
|
||||
|
||||
float sequence[64];
|
||||
|
||||
for (int i = 0; i < x; i++)
|
||||
{
|
||||
sequence[i] = *(settingRefs->waveformWave[i]);
|
||||
}
|
||||
|
||||
double twopi = MathConstants<float>::pi * 2.0;
|
||||
int step = (int)(x * angle / twopi);
|
||||
|
||||
float level = sequence[step];
|
||||
float output = (float)level / (y / 2.0f) - 1.0f;
|
||||
|
||||
return output;
|
||||
}
|
18
Source/WaveformVoice.h
Normal file
18
Source/WaveformVoice.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
WaveformVoice.h
|
||||
Created: 7 Jul 2021 5:57:30am
|
||||
Author: SHACHO
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "TonalVoice.h"
|
||||
|
||||
struct WaveformVoice : public TonalVoice
|
||||
{
|
||||
WaveformVoice(SettingRefs* sRefs);
|
||||
float voltageForAngle(double angle) override;
|
||||
};
|
Loading…
Reference in New Issue
Block a user