@@ -4,18 +4,6 @@ | |||
using namespace rack; | |||
struct TripleModeLight : ValueLight { | |||
void step() { | |||
int mode = (int)roundf(getf(value)); | |||
if (mode == 0) | |||
color = nvgRGB(0x22, 0xe6, 0xef); | |||
else if (mode == 1) | |||
color = nvgRGB(0xf2, 0xb1, 0x20); | |||
else | |||
color = nvgRGB(0xed, 0x2c, 0x24); | |||
} | |||
}; | |||
//////////////////// | |||
// module widgets | |||
//////////////////// | |||
@@ -53,10 +53,34 @@ struct Rings : Module { | |||
rings::Strummer strummer; | |||
bool strum = false; | |||
bool lastStrum = false; | |||
float lights[2] = {}; | |||
Trigger polyphonyTrigger; | |||
Trigger modelTrigger; | |||
int polyphonyMode = 0; | |||
int model = 0; | |||
Rings(); | |||
~Rings(); | |||
void step(); | |||
json_t *toJsonData() { | |||
json_t *root = json_object(); | |||
json_object_set_new(root, "polyphony", json_integer(polyphonyMode)); | |||
json_object_set_new(root, "model", json_integer(model)); | |||
return root; | |||
} | |||
void fromJsonData(json_t *root) { | |||
json_t *polyphonyJ = json_object_get(root, "polyphony"); | |||
if (polyphonyJ) { | |||
polyphonyMode = json_integer_value(polyphonyJ); | |||
} | |||
json_t *modelJ = json_object_get(root, "model"); | |||
if (modelJ) { | |||
model = json_integer_value(modelJ); | |||
} | |||
} | |||
}; | |||
@@ -74,9 +98,6 @@ Rings::Rings() { | |||
string_synth.Init(reverb_buffer); | |||
} | |||
Rings::~Rings() { | |||
} | |||
void Rings::step() { | |||
// TODO | |||
// "Normalized to a pulse/burst generator that reacts to note changes on the V/OCT input." | |||
@@ -91,6 +112,17 @@ void Rings::step() { | |||
strum = getf(inputs[STRUM_INPUT]) >= 1.0; | |||
} | |||
// Polyphony / model | |||
if (polyphonyTrigger.process(params[POLYPHONY_PARAM])) { | |||
polyphonyMode = (polyphonyMode + 1) % 3; | |||
} | |||
lights[0] = (float)polyphonyMode; | |||
if (modelTrigger.process(params[RESONATOR_PARAM])) { | |||
model = (model + 1) % 3; | |||
} | |||
lights[1] = (float)model; | |||
// Render frames | |||
if (outputBuffer.empty()) { | |||
float in[24] = {}; | |||
@@ -103,21 +135,11 @@ void Rings::step() { | |||
inputBuffer.startIncr(inLen); | |||
} | |||
// modes | |||
int polyphony; | |||
switch ((int) roundf(params[POLYPHONY_PARAM])) { | |||
case 1: polyphony = 2; break; | |||
case 2: polyphony = 4; break; | |||
default: polyphony = 1; | |||
} | |||
if (polyphony != part.polyphony()) { | |||
// Polyphony / model | |||
int polyphony = 1<<polyphonyMode; | |||
if (part.polyphony() != polyphony) | |||
part.set_polyphony(polyphony); | |||
} | |||
int model = (int) roundf(params[RESONATOR_PARAM]); | |||
if (0 <= model && model < rings::RESONATOR_MODEL_LAST) { | |||
part.set_model((rings::ResonatorModel) model); | |||
} | |||
part.set_model((rings::ResonatorModel)model); | |||
// Patch | |||
rings::Patch patch; | |||
@@ -192,10 +214,18 @@ void Rings::step() { | |||
setf(outputs[EVEN_OUTPUT], v); | |||
} | |||
} | |||
} | |||
struct RingsModeLight : ModeValueLight { | |||
RingsModeLight() { | |||
addColor(COLOR_CYAN); | |||
addColor(COLOR_ORANGE); | |||
addColor(COLOR_RED); | |||
} | |||
}; | |||
RingsWidget::RingsWidget() { | |||
Rings *module = new Rings(); | |||
setModule(module); | |||
@@ -213,8 +243,8 @@ RingsWidget::RingsWidget() { | |||
addChild(createScrew<ScrewSilver>(Vec(15, 365))); | |||
addChild(createScrew<ScrewSilver>(Vec(180, 365))); | |||
addParam(createParam<TL1105>(Vec(14, 40), module, Rings::POLYPHONY_PARAM, 0.0, 2.0, 0.0)); | |||
addParam(createParam<TL1105>(Vec(179, 40), module, Rings::RESONATOR_PARAM, 0.0, 2.0, 0.0)); | |||
addParam(createParam<TL1105>(Vec(14, 40), module, Rings::POLYPHONY_PARAM, 0.0, 1.0, 0.0)); | |||
addParam(createParam<TL1105>(Vec(179, 40), module, Rings::RESONATOR_PARAM, 0.0, 1.0, 0.0)); | |||
addParam(createParam<Rogan3PSWhite>(Vec(30, 73), module, Rings::FREQUENCY_PARAM, 0.0, 60.0, 30.0)); | |||
addParam(createParam<Rogan3PSWhite>(Vec(127, 73), module, Rings::STRUCTURE_PARAM, 0.0, 1.0, 0.5)); | |||
@@ -225,9 +255,9 @@ RingsWidget::RingsWidget() { | |||
addParam(createParam<Trimpot>(Vec(19, 229), module, Rings::BRIGHTNESS_MOD_PARAM, -1.0, 1.0, 0.0)); | |||
addParam(createParam<Trimpot>(Vec(57, 229), module, Rings::FREQUENCY_MOD_PARAM, -1.0, 1.0, 0.0)); | |||
addParam(createParam<Trimpot>(Vec(95, 229), module, Rings::DAMPING_MOD_PARAM, -1.0, 1.0, 0.0)); | |||
addParam(createParam<Trimpot>(Vec(96, 229), module, Rings::DAMPING_MOD_PARAM, -1.0, 1.0, 0.0)); | |||
addParam(createParam<Trimpot>(Vec(134, 229), module, Rings::STRUCTURE_MOD_PARAM, -1.0, 1.0, 0.0)); | |||
addParam(createParam<Trimpot>(Vec(172, 229), module, Rings::POSITION_MOD_PARAM, -1.0, 1.0, 0.0)); | |||
addParam(createParam<Trimpot>(Vec(173, 229), module, Rings::POSITION_MOD_PARAM, -1.0, 1.0, 0.0)); | |||
addInput(createInput<PJ3410Port>(Vec(12, 270), module, Rings::BRIGHTNESS_MOD_INPUT)); | |||
addInput(createInput<PJ3410Port>(Vec(51, 270), module, Rings::FREQUENCY_MOD_INPUT)); | |||
@@ -241,6 +271,6 @@ RingsWidget::RingsWidget() { | |||
addOutput(createOutput<PJ3410Port>(Vec(128, 313), module, Rings::ODD_OUTPUT)); | |||
addOutput(createOutput<PJ3410Port>(Vec(166, 313), module, Rings::EVEN_OUTPUT)); | |||
addChild(createValueLight<SmallLight<TripleModeLight>>(Vec(38, 43.8), &module->params[Rings::POLYPHONY_PARAM])); | |||
addChild(createValueLight<SmallLight<TripleModeLight>>(Vec(163, 43.8), &module->params[Rings::RESONATOR_PARAM])); | |||
addChild(createValueLight<SmallLight<RingsModeLight>>(Vec(38, 43.8), &module->lights[0])); | |||
addChild(createValueLight<SmallLight<RingsModeLight>>(Vec(163, 43.8), &module->lights[1])); | |||
} |
@@ -90,13 +90,13 @@ ShadesWidget::ShadesWidget() { | |||
addChild(createScrew<ScrewSilver>(Vec(15, 0))); | |||
addChild(createScrew<ScrewSilver>(Vec(15, 365))); | |||
addParam(createParam<Rogan1PSRed>(Vec(40, 41), module, Shades::GAIN1_PARAM, 0.0, 1.0, 0.5)); | |||
addParam(createParam<Rogan1PSWhite>(Vec(40, 107), module, Shades::GAIN2_PARAM, 0.0, 1.0, 0.5)); | |||
addParam(createParam<Rogan1PSGreen>(Vec(40, 173), module, Shades::GAIN3_PARAM, 0.0, 1.0, 0.5)); | |||
addParam(createParam<Rogan1PSRed>(Vec(40, 41), module, Shades::GAIN1_PARAM, 0.0, 1.0, 0.0)); | |||
addParam(createParam<Rogan1PSWhite>(Vec(40, 107), module, Shades::GAIN2_PARAM, 0.0, 1.0, 0.0)); | |||
addParam(createParam<Rogan1PSGreen>(Vec(40, 173), module, Shades::GAIN3_PARAM, 0.0, 1.0, 0.0)); | |||
addParam(createParam<CKSS>(Vec(10, 52), module, Shades::MODE1_PARAM, 0.0, 1.0, 1.0)); | |||
addParam(createParam<CKSS>(Vec(10, 118), module, Shades::MODE2_PARAM, 0.0, 1.0, 1.0)); | |||
addParam(createParam<CKSS>(Vec(10, 184), module, Shades::MODE3_PARAM, 0.0, 1.0, 1.0)); | |||
addParam(createParam<CKSS>(Vec(10, 52), module, Shades::MODE1_PARAM, 0.0, 1.0, 0.0)); | |||
addParam(createParam<CKSS>(Vec(10, 118), module, Shades::MODE2_PARAM, 0.0, 1.0, 0.0)); | |||
addParam(createParam<CKSS>(Vec(10, 184), module, Shades::MODE3_PARAM, 0.0, 1.0, 0.0)); | |||
addInput(createInput<PJ3410Port>(Vec(5, 242), module, Shades::IN1_INPUT)); | |||
addInput(createInput<PJ3410Port>(Vec(5, 278), module, Shades::IN2_INPUT)); | |||
@@ -42,9 +42,31 @@ struct Tides : Module { | |||
float lights[3] = {}; | |||
int frame = 0; | |||
uint8_t lastGate; | |||
Trigger modeTrigger; | |||
Trigger rangeTrigger; | |||
Tides(); | |||
void step(); | |||
json_t *toJsonData() { | |||
json_t *root = json_object(); | |||
json_object_set_new(root, "mode", json_integer((int)generator.mode())); | |||
json_object_set_new(root, "range", json_integer((int)generator.range())); | |||
return root; | |||
} | |||
void fromJsonData(json_t *root) { | |||
json_t *modeJ = json_object_get(root, "mode"); | |||
if (modeJ) { | |||
generator.set_mode((tides::GeneratorMode)json_integer_value(modeJ)); | |||
} | |||
json_t *rangeJ = json_object_get(root, "range"); | |||
if (rangeJ) { | |||
generator.set_range((tides::GeneratorRange)json_integer_value(rangeJ)); | |||
} | |||
} | |||
}; | |||
@@ -55,27 +77,30 @@ Tides::Tides() { | |||
memset(&generator, 0, sizeof(generator)); | |||
generator.Init(); | |||
generator.set_range(tides::GENERATOR_RANGE_LOW); | |||
generator.set_mode(tides::GENERATOR_MODE_AD); | |||
generator.set_range(tides::GENERATOR_RANGE_MEDIUM); | |||
generator.set_mode(tides::GENERATOR_MODE_LOOPING); | |||
generator.set_sync(false); | |||
} | |||
void Tides::step() { | |||
if (++frame >= 16) { | |||
frame = 0; | |||
// TODO Save / load the state of MODE and RANGE to JSON | |||
tides::GeneratorMode mode = generator.mode(); | |||
if (modeTrigger.process(params[MODE_PARAM])) { | |||
mode = (tides::GeneratorMode) (((int)mode + 2) % 3); | |||
generator.set_mode(mode); | |||
} | |||
lights[0] = (float)mode; | |||
// Mode and range | |||
tides::GeneratorMode mode = (tides::GeneratorMode) roundf(1.0 - params[MODE_PARAM]); | |||
if (mode != generator.mode()) { | |||
generator.set_mode(mode); | |||
} | |||
lights[0] = -params[MODE_PARAM]; | |||
tides::GeneratorRange range = generator.range(); | |||
if (rangeTrigger.process(params[RANGE_PARAM])) { | |||
range = (tides::GeneratorRange) (((int)range + 2) % 3); | |||
generator.set_range(range); | |||
} | |||
lights[2] = (float)range; | |||
tides::GeneratorRange range = (tides::GeneratorRange) roundf(1.0 - params[RANGE_PARAM]); | |||
if (range != generator.range()) { | |||
generator.set_range(range); | |||
} | |||
lights[2] = -params[RANGE_PARAM]; | |||
// Buffer loop | |||
if (++frame >= 16) { | |||
frame = 0; | |||
// Pitch | |||
float pitch = params[FREQUENCY_PARAM]; | |||
@@ -141,6 +166,15 @@ void Tides::step() { | |||
} | |||
struct TidesModeLight : ModeValueLight { | |||
TidesModeLight() { | |||
addColor(COLOR_RED); | |||
addColor(COLOR_BLACK_TRANSPARENT); | |||
addColor(COLOR_CYAN); | |||
} | |||
}; | |||
TidesWidget::TidesWidget() { | |||
Tides *module = new Tides(); | |||
setModule(module); | |||
@@ -158,8 +192,8 @@ TidesWidget::TidesWidget() { | |||
addChild(createScrew<ScrewSilver>(Vec(15, 365))); | |||
addChild(createScrew<ScrewSilver>(Vec(180, 365))); | |||
addParam(createParam<CKD6>(Vec(19, 52), module, Tides::MODE_PARAM, -1.0, 1.0, 0.0)); | |||
addParam(createParam<CKD6>(Vec(19, 93), module, Tides::RANGE_PARAM, -1.0, 1.0, 0.0)); | |||
addParam(createParam<CKD6>(Vec(19, 52), module, Tides::MODE_PARAM, 0.0, 1.0, 0.0)); | |||
addParam(createParam<CKD6>(Vec(19, 93), module, Tides::RANGE_PARAM, 0.0, 1.0, 0.0)); | |||
addParam(createParam<Rogan3PSGreen>(Vec(79, 60), module, Tides::FREQUENCY_PARAM, -48.0, 48.0, 0.0)); | |||
addParam(createParam<Rogan1PSGreen>(Vec(156, 66), module, Tides::FM_PARAM, -12.0, 12.0, 0.0)); | |||
@@ -184,7 +218,7 @@ TidesWidget::TidesWidget() { | |||
addOutput(createOutput<PJ3410Port>(Vec(125, 313), module, Tides::UNI_OUTPUT)); | |||
addOutput(createOutput<PJ3410Port>(Vec(161, 313), module, Tides::BI_OUTPUT)); | |||
addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(57, 62), &module->lights[0])); | |||
addChild(createValueLight<SmallLight<TidesModeLight>>(Vec(57, 62), &module->lights[0])); | |||
addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(57, 83), &module->lights[1])); | |||
addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(57, 103), &module->lights[2])); | |||
addChild(createValueLight<SmallLight<TidesModeLight>>(Vec(57, 103), &module->lights[2])); | |||
} |
@@ -32,9 +32,24 @@ struct Warps : Module { | |||
warps::ShortFrame inputFrames[60] = {}; | |||
warps::ShortFrame outputFrames[60] = {}; | |||
float lights[1] = {}; | |||
Trigger stateTrigger; | |||
Warps(); | |||
void step(); | |||
json_t *toJsonData() { | |||
json_t *root = json_object(); | |||
warps::Parameters *p = modulator.mutable_parameters(); | |||
json_object_set_new(root, "shape", json_integer(p->carrier_shape)); | |||
return root; | |||
} | |||
void fromJsonData(json_t *root) { | |||
json_t *shapeJ = json_object_get(root, "shape"); | |||
warps::Parameters *p = modulator.mutable_parameters(); | |||
if (shapeJ) { | |||
p->carrier_shape = json_integer_value(shapeJ); | |||
} | |||
} | |||
}; | |||
@@ -48,10 +63,17 @@ Warps::Warps() { | |||
} | |||
void Warps::step() { | |||
// State trigger | |||
warps::Parameters *p = modulator.mutable_parameters(); | |||
if (stateTrigger.process(params[STATE_PARAM])) { | |||
p->carrier_shape = (p->carrier_shape + 1) % 4; | |||
} | |||
lights[0] = p->carrier_shape; | |||
// Buffer loop | |||
if (++frame >= 60) { | |||
frame = 0; | |||
warps::Parameters *p = modulator.mutable_parameters(); | |||
p->channel_drive[0] = clampf(params[LEVEL1_PARAM] + getf(inputs[LEVEL1_INPUT]) / 5.0, 0.0, 1.0); | |||
p->channel_drive[1] = clampf(params[LEVEL2_PARAM] + getf(inputs[LEVEL2_INPUT]) / 5.0, 0.0, 1.0); | |||
p->modulation_algorithm = clampf(params[ALGORITHM_PARAM] / 8.0 + getf(inputs[ALGORITHM_PARAM]) / 5.0, 0.0, 1.0); | |||
@@ -62,9 +84,6 @@ void Warps::step() { | |||
p->phase_shift = p->modulation_algorithm; | |||
p->note = 60.0 * params[LEVEL1_PARAM] + 12.0 * getf(inputs[LEVEL1_INPUT], 2.0) + 12.0; | |||
p->note += log2f(96000.0 / gSampleRate) * 12.0; | |||
float state = roundf(params[STATE_PARAM]); | |||
p->carrier_shape = (int32_t)state; | |||
lights[0] = state; | |||
modulator.Process(inputFrames, outputFrames, 60); | |||
} | |||
@@ -76,6 +95,15 @@ void Warps::step() { | |||
} | |||
struct WarpsModeLight : ModeValueLight { | |||
WarpsModeLight() { | |||
addColor(COLOR_BLACK_TRANSPARENT); | |||
addColor(COLOR_GREEN); | |||
addColor(COLOR_YELLOW); | |||
addColor(COLOR_RED); | |||
} | |||
}; | |||
WarpsWidget::WarpsWidget() { | |||
Warps *module = new Warps(); | |||
setModule(module); | |||
@@ -96,7 +124,7 @@ WarpsWidget::WarpsWidget() { | |||
addParam(createParam<Rogan6PSWhite>(Vec(30, 53), module, Warps::ALGORITHM_PARAM, 0.0, 8.0, 0.0)); | |||
addParam(createParam<Rogan1PSWhite>(Vec(95, 173), module, Warps::TIMBRE_PARAM, 0.0, 1.0, 0.5)); | |||
addParam(createParam<TL1105>(Vec(16, 182), module, Warps::STATE_PARAM, 0.0, 3.0, 0.0)); | |||
addParam(createParam<TL1105>(Vec(16, 182), module, Warps::STATE_PARAM, 0.0, 1.0, 0.0)); | |||
addParam(createParam<Trimpot>(Vec(15, 214), module, Warps::LEVEL1_PARAM, 0.0, 1.0, 1.0)); | |||
addParam(createParam<Trimpot>(Vec(54, 214), module, Warps::LEVEL2_PARAM, 0.0, 1.0, 1.0)); | |||
@@ -110,5 +138,5 @@ WarpsWidget::WarpsWidget() { | |||
addOutput(createOutput<PJ3410Port>(Vec(77, 313), module, Warps::MODULATOR_OUTPUT)); | |||
addOutput(createOutput<PJ3410Port>(Vec(113, 313), module, Warps::AUX_OUTPUT)); | |||
addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(20, 167), &module->lights[0])); | |||
addChild(createValueLight<SmallLight<WarpsModeLight>>(Vec(20, 167), &module->lights[0])); | |||
} |