| 67 | } |
| 68 | |
| 69 | void process(const ProcessArgs& args) override { |
| 70 | tides::GeneratorMode mode = generator.mode(); |
| 71 | if (modeTrigger.process(params[MODE_PARAM].getValue())) { |
| 72 | mode = (tides::GeneratorMode)(((int)mode - 1 + 3) % 3); |
| 73 | generator.set_mode(mode); |
| 74 | } |
| 75 | lights[MODE_GREEN_LIGHT].value = (mode == 2) ? 1.0 : 0.0; |
| 76 | lights[MODE_RED_LIGHT].value = (mode == 0) ? 1.0 : 0.0; |
| 77 | |
| 78 | tides::GeneratorRange range = generator.range(); |
| 79 | if (rangeTrigger.process(params[RANGE_PARAM].getValue())) { |
| 80 | range = (tides::GeneratorRange)(((int)range - 1 + 3) % 3); |
| 81 | generator.set_range(range); |
| 82 | } |
| 83 | lights[RANGE_GREEN_LIGHT].value = (range == 2) ? 1.0 : 0.0; |
| 84 | lights[RANGE_RED_LIGHT].value = (range == 0) ? 1.0 : 0.0; |
| 85 | |
| 86 | // Buffer loop |
| 87 | if (++frame >= 16) { |
| 88 | frame = 0; |
| 89 | |
| 90 | // Pitch |
| 91 | float pitch = params[FREQUENCY_PARAM].getValue(); |
| 92 | pitch += 12.0 * inputs[PITCH_INPUT].getVoltage(); |
| 93 | pitch += params[FM_PARAM].getValue() * inputs[FM_INPUT].getNormalVoltage(0.1) / 5.0; |
| 94 | pitch += 60.0; |
| 95 | // Scale to the global sample rate |
| 96 | pitch += log2f(48000.0 / args.sampleRate) * 12.0; |
| 97 | generator.set_pitch((int) clamp(pitch * 0x80, (float) -0x8000, (float) 0x7fff)); |
| 98 | |
| 99 | // Slope, smoothness, pitch |
| 100 | int16_t shape = clamp(params[SHAPE_PARAM].getValue() + inputs[SHAPE_INPUT].getVoltage() / 5.0f, -1.0f, 1.0f) * 0x7fff; |
| 101 | int16_t slope = clamp(params[SLOPE_PARAM].getValue() + inputs[SLOPE_INPUT].getVoltage() / 5.0f, -1.0f, 1.0f) * 0x7fff; |
| 102 | int16_t smoothness = clamp(params[SMOOTHNESS_PARAM].getValue() + inputs[SMOOTHNESS_INPUT].getVoltage() / 5.0f, -1.0f, 1.0f) * 0x7fff; |
| 103 | generator.set_shape(shape); |
| 104 | generator.set_slope(slope); |
| 105 | generator.set_smoothness(smoothness); |
| 106 | |
| 107 | // Sync |
| 108 | // Slight deviation from spec here. |
| 109 | // Instead of toggling sync by holding the range button, just enable it if the clock port is plugged in. |
| 110 | generator.set_sync(inputs[CLOCK_INPUT].isConnected() && !sheep); |
| 111 | |
| 112 | // Generator |
| 113 | generator.Process(sheep); |
| 114 | } |
| 115 | |
| 116 | // Level |
| 117 | uint16_t level = clamp(inputs[LEVEL_INPUT].getNormalVoltage(8.0) / 8.0f, 0.0f, 1.0f) * 0xffff; |
| 118 | if (level < 32) |
| 119 | level = 0; |
| 120 | |
| 121 | uint8_t gate = 0; |
| 122 | if (inputs[FREEZE_INPUT].getVoltage() >= 0.7) |
| 123 | gate |= tides::CONTROL_FREEZE; |
| 124 | if (inputs[TRIG_INPUT].getVoltage() >= 0.7) |
| 125 | gate |= tides::CONTROL_GATE; |
| 126 | if (inputs[CLOCK_INPUT].getVoltage() >= 0.7) |