|
|
@@ -2,11 +2,15 @@ |
|
|
|
#include "AudibleInstruments.hpp" |
|
|
|
#include "dsp/samplerate.hpp" |
|
|
|
#include "dsp/ringbuffer.hpp" |
|
|
|
#include "dsp/digital.hpp" |
|
|
|
#include "clouds/dsp/granular_processor.h" |
|
|
|
|
|
|
|
|
|
|
|
struct Clouds : Module { |
|
|
|
enum ParamIds { |
|
|
|
FREEZE_PARAM, |
|
|
|
MODE_PARAM, |
|
|
|
LOAD_PARAM, |
|
|
|
POSITION_PARAM, |
|
|
|
SIZE_PARAM, |
|
|
|
PITCH_PARAM, |
|
|
@@ -14,6 +18,9 @@ struct Clouds : Module { |
|
|
|
DENSITY_PARAM, |
|
|
|
TEXTURE_PARAM, |
|
|
|
BLEND_PARAM, |
|
|
|
SPREAD_PARAM, |
|
|
|
FEEDBACK_PARAM, |
|
|
|
REVERB_PARAM, |
|
|
|
NUM_PARAMS |
|
|
|
}; |
|
|
|
enum InputIds { |
|
|
@@ -34,6 +41,14 @@ struct Clouds : Module { |
|
|
|
OUT_R_OUTPUT, |
|
|
|
NUM_OUTPUTS |
|
|
|
}; |
|
|
|
enum LightIds { |
|
|
|
FREEZE_LIGHT, |
|
|
|
MIX_GREEN_LIGHT, MIX_RED_LIGHT, |
|
|
|
PAN_GREEN_LIGHT, PAN_RED_LIGHT, |
|
|
|
FEEDBACK_GREEN_LIGHT, FEEDBACK_RED_LIGHT, |
|
|
|
REVERB_GREEN_LIGHT, REVERB_RED_LIGHT, |
|
|
|
NUM_LIGHTS |
|
|
|
}; |
|
|
|
|
|
|
|
SampleRateConverter<2> inputSrc; |
|
|
|
SampleRateConverter<2> outputSrc; |
|
|
@@ -46,13 +61,23 @@ struct Clouds : Module { |
|
|
|
|
|
|
|
bool triggered = false; |
|
|
|
|
|
|
|
SchmittTrigger freezeTrigger; |
|
|
|
bool freeze = false; |
|
|
|
SchmittTrigger modeTrigger; |
|
|
|
int modeIndex = 0; |
|
|
|
|
|
|
|
Clouds(); |
|
|
|
~Clouds(); |
|
|
|
void step() override; |
|
|
|
|
|
|
|
void reset() override { |
|
|
|
freeze = false; |
|
|
|
modeIndex = 0; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
Clouds::Clouds() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { |
|
|
|
Clouds::Clouds() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { |
|
|
|
const int memLen = 118784; |
|
|
|
const int ccmLen = 65536 - 128; |
|
|
|
block_mem = new uint8_t[memLen](); |
|
|
@@ -78,6 +103,13 @@ void Clouds::step() { |
|
|
|
inputBuffer.push(inputFrame); |
|
|
|
} |
|
|
|
|
|
|
|
if (freezeTrigger.process(params[FREEZE_PARAM].value)) { |
|
|
|
freeze ^= true; |
|
|
|
} |
|
|
|
if (modeTrigger.process(params[MODE_PARAM].value)) { |
|
|
|
modeIndex = (modeIndex + 1) % 4; |
|
|
|
} |
|
|
|
|
|
|
|
// Trigger |
|
|
|
if (inputs[TRIG_INPUT].value >= 1.0) { |
|
|
|
triggered = true; |
|
|
@@ -112,17 +144,16 @@ void Clouds::step() { |
|
|
|
clouds::Parameters* p = processor->mutable_parameters(); |
|
|
|
p->trigger = triggered; |
|
|
|
p->gate = triggered; |
|
|
|
p->freeze = (inputs[FREEZE_INPUT].value >= 1.0); |
|
|
|
p->freeze = freeze; |
|
|
|
p->position = clampf(params[POSITION_PARAM].value + inputs[POSITION_INPUT].value / 5.0, 0.0, 1.0); |
|
|
|
p->size = clampf(params[SIZE_PARAM].value + inputs[SIZE_INPUT].value / 5.0, 0.0, 1.0); |
|
|
|
p->pitch = clampf((params[PITCH_PARAM].value + inputs[PITCH_INPUT].value) * 12.0, -48.0, 48.0); |
|
|
|
p->density = clampf(params[DENSITY_PARAM].value + inputs[DENSITY_INPUT].value / 5.0, 0.0, 1.0); |
|
|
|
p->texture = clampf(params[TEXTURE_PARAM].value + inputs[TEXTURE_INPUT].value / 5.0, 0.0, 1.0); |
|
|
|
float blend = clampf(params[BLEND_PARAM].value + inputs[BLEND_INPUT].value / 5.0, 0.0, 1.0); |
|
|
|
p->dry_wet = blend; |
|
|
|
p->stereo_spread = 0.0; |
|
|
|
p->feedback = 0.0; |
|
|
|
p->reverb = 0.0; |
|
|
|
p->dry_wet = clampf(params[BLEND_PARAM].value + inputs[BLEND_INPUT].value / 5.0, 0.0, 1.0); |
|
|
|
p->stereo_spread = params[SPREAD_PARAM].value; |
|
|
|
p->feedback = params[FEEDBACK_PARAM].value; |
|
|
|
p->reverb = params[REVERB_PARAM].value; |
|
|
|
|
|
|
|
clouds::ShortFrame output[32]; |
|
|
|
processor->Process(input, output, 32); |
|
|
@@ -143,6 +174,14 @@ void Clouds::step() { |
|
|
|
} |
|
|
|
|
|
|
|
triggered = false; |
|
|
|
|
|
|
|
// Lights |
|
|
|
lights[FREEZE_LIGHT].value = freeze ? 1.0 : 0.0; |
|
|
|
// TODO |
|
|
|
lights[MIX_GREEN_LIGHT].value = 1.0; |
|
|
|
lights[PAN_GREEN_LIGHT].value = 1.0; |
|
|
|
lights[FEEDBACK_GREEN_LIGHT].value = 1.0; |
|
|
|
lights[REVERB_GREEN_LIGHT].value = 1.0; |
|
|
|
} |
|
|
|
|
|
|
|
// Set output |
|
|
@@ -171,10 +210,6 @@ CloudsWidget::CloudsWidget() { |
|
|
|
addChild(createScrew<ScrewSilver>(Vec(15, 365))); |
|
|
|
addChild(createScrew<ScrewSilver>(Vec(240, 365))); |
|
|
|
|
|
|
|
// TODO |
|
|
|
// addParam(createParam<MediumMomentarySwitch>(Vec(211, 51), module, Clouds::POSITION_PARAM, 0.0, 1.0, 0.5)); |
|
|
|
// addParam(createParam<MediumMomentarySwitch>(Vec(239, 51), module, Clouds::POSITION_PARAM, 0.0, 1.0, 0.5)); |
|
|
|
|
|
|
|
addParam(createParam<Rogan3PSRed>(Vec(27, 93), module, Clouds::POSITION_PARAM, 0.0, 1.0, 0.5)); |
|
|
|
addParam(createParam<Rogan3PSGreen>(Vec(108, 93), module, Clouds::SIZE_PARAM, 0.0, 1.0, 0.5)); |
|
|
|
addParam(createParam<Rogan3PSWhite>(Vec(190, 93), module, Clouds::PITCH_PARAM, -2.0, 2.0, 0.0)); |
|
|
@@ -182,7 +217,18 @@ CloudsWidget::CloudsWidget() { |
|
|
|
addParam(createParam<Rogan1PSRed>(Vec(14, 180), module, Clouds::IN_GAIN_PARAM, 0.0, 1.0, 0.5)); |
|
|
|
addParam(createParam<Rogan1PSRed>(Vec(81, 180), module, Clouds::DENSITY_PARAM, 0.0, 1.0, 0.5)); |
|
|
|
addParam(createParam<Rogan1PSGreen>(Vec(146, 180), module, Clouds::TEXTURE_PARAM, 0.0, 1.0, 0.5)); |
|
|
|
addParam(createParam<Rogan1PSWhite>(Vec(213, 180), module, Clouds::BLEND_PARAM, 0.0, 1.0, 0.5)); |
|
|
|
blendParam = createParam<Rogan1PSWhite>(Vec(213, 180), module, Clouds::BLEND_PARAM, 0.0, 1.0, 0.5); |
|
|
|
addParam(blendParam); |
|
|
|
spreadParam = createParam<Rogan1PSRed>(Vec(213, 180), module, Clouds::SPREAD_PARAM, 0.0, 1.0, 0.0); |
|
|
|
addParam(spreadParam); |
|
|
|
feedbackParam = createParam<Rogan1PSGreen>(Vec(213, 180), module, Clouds::FEEDBACK_PARAM, 0.0, 1.0, 0.0); |
|
|
|
addParam(feedbackParam); |
|
|
|
reverbParam = createParam<Rogan1PSBlue>(Vec(213, 180), module, Clouds::REVERB_PARAM, 0.0, 1.0, 0.0); |
|
|
|
addParam(reverbParam); |
|
|
|
|
|
|
|
addParam(createParam<CKD6>(Vec(12, 43), module, Clouds::FREEZE_PARAM, 0.0, 1.0, 0.0)); |
|
|
|
addParam(createParam<TL1105>(Vec(211, 50), module, Clouds::MODE_PARAM, 0.0, 1.0, 0.0)); |
|
|
|
addParam(createParam<TL1105>(Vec(239, 50), module, Clouds::LOAD_PARAM, 0.0, 1.0, 0.0)); |
|
|
|
|
|
|
|
addInput(createInput<PJ301MPort>(Vec(15, 274), module, Clouds::FREEZE_INPUT)); |
|
|
|
addInput(createInput<PJ301MPort>(Vec(58, 274), module, Clouds::TRIG_INPUT)); |
|
|
@@ -197,4 +243,54 @@ CloudsWidget::CloudsWidget() { |
|
|
|
addInput(createInput<PJ301MPort>(Vec(144, 317), module, Clouds::TEXTURE_INPUT)); |
|
|
|
addOutput(createOutput<PJ301MPort>(Vec(188, 317), module, Clouds::OUT_L_OUTPUT)); |
|
|
|
addOutput(createOutput<PJ301MPort>(Vec(230, 317), module, Clouds::OUT_R_OUTPUT)); |
|
|
|
|
|
|
|
struct FreezeLight : YellowLight { |
|
|
|
FreezeLight() { |
|
|
|
box.size = Vec(28-6, 28-6); |
|
|
|
bgColor = COLOR_BLACK_TRANSPARENT; |
|
|
|
} |
|
|
|
}; |
|
|
|
addChild(createLight<FreezeLight>(Vec(12+3, 43+3), module, Clouds::FREEZE_LIGHT)); |
|
|
|
addChild(createLight<MediumLight<GreenRedLight>>(Vec(82.5, 53), module, Clouds::MIX_GREEN_LIGHT)); |
|
|
|
addChild(createLight<MediumLight<GreenRedLight>>(Vec(114.5, 53), module, Clouds::PAN_GREEN_LIGHT)); |
|
|
|
addChild(createLight<MediumLight<GreenRedLight>>(Vec(145.5, 53), module, Clouds::FEEDBACK_GREEN_LIGHT)); |
|
|
|
addChild(createLight<MediumLight<GreenRedLight>>(Vec(177.5, 53), module, Clouds::REVERB_GREEN_LIGHT)); |
|
|
|
} |
|
|
|
|
|
|
|
void CloudsWidget::step() { |
|
|
|
Clouds *module = dynamic_cast<Clouds*>(this->module); |
|
|
|
|
|
|
|
blendParam->visible = (module->modeIndex == 0); |
|
|
|
spreadParam->visible = (module->modeIndex == 1); |
|
|
|
feedbackParam->visible = (module->modeIndex == 2); |
|
|
|
reverbParam->visible = (module->modeIndex == 3); |
|
|
|
|
|
|
|
ModuleWidget::step(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
struct CloudsModeItem : MenuItem { |
|
|
|
Clouds *module; |
|
|
|
int modeIndex; |
|
|
|
void onAction(EventAction &e) override { |
|
|
|
module->modeIndex = modeIndex; |
|
|
|
} |
|
|
|
void step() override { |
|
|
|
rightText = (module->modeIndex == modeIndex) ? "✔" : ""; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
Menu *CloudsWidget::createContextMenu() { |
|
|
|
Menu *menu = ModuleWidget::createContextMenu(); |
|
|
|
|
|
|
|
Clouds *module = dynamic_cast<Clouds*>(this->module); |
|
|
|
|
|
|
|
menu->pushChild(construct<MenuLabel>()); |
|
|
|
menu->pushChild(construct<MenuLabel>(&MenuEntry::text, "Blend knob")); |
|
|
|
menu->pushChild(construct<CloudsModeItem>(&MenuEntry::text, "Wet/dry", &CloudsModeItem::module, module, &CloudsModeItem::modeIndex, 0)); |
|
|
|
menu->pushChild(construct<CloudsModeItem>(&MenuEntry::text, "Spread", &CloudsModeItem::module, module, &CloudsModeItem::modeIndex, 1)); |
|
|
|
menu->pushChild(construct<CloudsModeItem>(&MenuEntry::text, "Feedback", &CloudsModeItem::module, module, &CloudsModeItem::modeIndex, 2)); |
|
|
|
menu->pushChild(construct<CloudsModeItem>(&MenuEntry::text, "Reverb", &CloudsModeItem::module, module, &CloudsModeItem::modeIndex, 3)); |
|
|
|
|
|
|
|
return menu; |
|
|
|
} |