You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

344 lines
16KB

  1. #include "Plateau.hpp"
  2. Plateau::Plateau() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
  3. reverb.setSampleRate(engineGetSampleRate());
  4. size = 1.f;
  5. diffusion;
  6. decay = 0.f;
  7. inputDampLow = 0.f;
  8. inputDampHigh = 10.f;
  9. reverbDampLow = 0.f;
  10. reverbDampHigh = 10.f;
  11. modSpeed = 0.1f;
  12. modShape = 0.5f;
  13. modDepth = 0.0f;
  14. freezeButtonState = false;
  15. freezeToggle = false;
  16. freezeToggleButtonState = false;
  17. freeze = false;
  18. frozen = false;
  19. tunedButtonState = false;
  20. diffuseButtonState = false;
  21. clear = 0;
  22. cleared = false;
  23. tuned = 0;
  24. diffuseInput = 1;
  25. }
  26. void Plateau::step() {
  27. //Freeze
  28. if(params[FREEZE_TOGGLE_PARAM].value > 0.5f && !freezeToggleButtonState) {
  29. freezeToggleButtonState = true;
  30. freezeToggle = !freezeToggle;
  31. }
  32. else if(params[FREEZE_TOGGLE_PARAM].value < 0.5f && freezeToggleButtonState) {
  33. freezeToggleButtonState = false;
  34. }
  35. lights[FREEZE_TOGGLE_LIGHT].value = freezeToggle ? 10.f : 0.f;
  36. if((params[FREEZE_PARAM].value > 0.5f || inputs[FREEZE_CV_INPUT].value > 0.5f)
  37. && !freezeButtonState) {
  38. freeze = freezeToggle ? !freeze : true;
  39. freezeButtonState = true;
  40. }
  41. if(params[FREEZE_PARAM].value <= 0.5f && inputs[FREEZE_CV_INPUT].value <= 0.5f
  42. && freezeButtonState) {
  43. freeze = freezeToggle ? freeze : false;
  44. freezeButtonState = false;
  45. }
  46. if(freeze && !frozen) {
  47. frozen = true;
  48. reverb.freeze();
  49. }
  50. else if(!freeze && frozen){
  51. frozen = false;
  52. reverb.unFreeze();
  53. }
  54. lights[FREEZE_LIGHT].value = freeze ? 10.f : 0.f;
  55. // Clear
  56. if(params[CLEAR_PARAM].value > 0.5f || inputs[CLEAR_CV_INPUT].value > 0.5f) {
  57. clear = 1;
  58. }
  59. else if(params[CLEAR_PARAM].value < 0.5f && inputs[CLEAR_CV_INPUT].value < 0.5f) {
  60. clear = 0;
  61. }
  62. if(params[TUNED_MODE_PARAM].value > 0.5f && tunedButtonState == false) {
  63. tuned = 1 - tuned;
  64. tunedButtonState = true;
  65. }
  66. else if(params[TUNED_MODE_PARAM].value < 0.5f && tunedButtonState) {
  67. tunedButtonState = false;
  68. }
  69. lights[TUNED_MODE_LIGHT].value = tuned ? 10.f : 0.f;
  70. if(params[DIFFUSE_INPUT_PARAM].value > 0.5f && diffuseButtonState == false) {
  71. diffuseInput = 1 - diffuseInput;
  72. diffuseButtonState = true;
  73. }
  74. else if(params[DIFFUSE_INPUT_PARAM].value < 0.5f && diffuseButtonState) {
  75. diffuseButtonState = false;
  76. }
  77. lights[DIFFUSE_INPUT_LIGHT].value = diffuseInput ? 10.f : 0.f;
  78. if(clear && !cleared) {
  79. cleared = true;
  80. reverb.clear();
  81. lights[CLEAR_LIGHT].value = 10.f;
  82. }
  83. else if(!clear && cleared){
  84. cleared = false;
  85. lights[CLEAR_LIGHT].value = 0.f;
  86. }
  87. // CV
  88. reverb.setPreDelay(params[PRE_DELAY_PARAM].value);
  89. size = inputs[SIZE_CV_INPUT].value * params[SIZE_CV_PARAM].value * 0.1f;
  90. size += params[SIZE_PARAM].value;
  91. if(tuned) {
  92. size = sizeMin * powf(2.f, size * 5.f);
  93. size = clamp(size, sizeMin, 2.5f);
  94. }
  95. else {
  96. size *= size;
  97. size = rescale(size, 0.f, 1.f, 0.01f, sizeMax);
  98. size = clamp(size, 0.01f, sizeMax);
  99. }
  100. reverb.setTimeScale(size);
  101. diffusion = inputs[DIFFUSION_CV_INPUT].value * params[DIFFUSION_CV_PARAM].value;
  102. diffusion += params[DIFFUSION_PARAM].value;
  103. diffusion = clamp(diffusion, 0.f, 10.f);
  104. reverb.plateDiffusion1 = rescale(diffusion, 0.f, 10.f, 0.f, 0.7f);
  105. reverb.plateDiffusion2 = rescale(diffusion, 0.f, 10.f, 0.f, 0.5f);
  106. decay = rescale(inputs[DECAY_CV_INPUT].value * params[DECAY_CV_PARAM].value, 0.f, 10.f, 0.1f, 0.999f);
  107. decay += params[DECAY_PARAM].value;
  108. decay = clamp(decay, 0.1f, decayMax);
  109. decay = 1.f - decay;
  110. decay = 1.f - decay * decay;
  111. inputDampLow = inputs[INPUT_LOW_DAMP_CV_INPUT].value * params[INPUT_LOW_DAMP_CV_PARAM].value;
  112. inputDampLow += params[INPUT_LOW_DAMP_PARAM].value;
  113. inputDampLow = clamp(inputDampLow, 0.f, 10.f);
  114. inputDampLow = 10.f - inputDampLow;
  115. inputDampHigh = inputs[INPUT_HIGH_DAMP_CV_INPUT].value * params[INPUT_HIGH_DAMP_CV_PARAM].value;
  116. inputDampHigh += params[INPUT_HIGH_DAMP_PARAM].value;
  117. inputDampHigh = clamp(inputDampHigh, 0.f, 10.f);
  118. reverbDampLow = inputs[REVERB_LOW_DAMP_CV_INPUT].value * params[REVERB_LOW_DAMP_CV_PARAM].value;
  119. reverbDampLow += params[REVERB_LOW_DAMP_PARAM].value;
  120. reverbDampLow = clamp(reverbDampLow, 0.f, 10.f);
  121. reverbDampLow = 10.f - reverbDampLow;
  122. reverbDampHigh = inputs[REVERB_HIGH_DAMP_CV_INPUT].value * params[REVERB_HIGH_DAMP_CV_PARAM].value;
  123. reverbDampHigh += params[REVERB_HIGH_DAMP_PARAM].value;
  124. reverbDampHigh = clamp(reverbDampHigh, 0.f, 10.f);
  125. reverb.diffuseInput = (double)diffuseInput;
  126. reverb.decay = decay;
  127. reverb.inputLowCut = 440.f * powf(2.f, inputDampLow - 5.f);
  128. reverb.inputHighCut = 440.f * powf(2.f, inputDampHigh - 5.f);
  129. reverb.reverbLowCut = 440.f * powf(2.f, reverbDampLow - 5.f);
  130. reverb.reverbHighCut = 440.f * powf(2.f, reverbDampHigh - 5.f);
  131. modSpeed = inputs[MOD_SPEED_CV_INPUT].value * params[MOD_SPEED_CV_PARAM].value * 0.1f;
  132. modSpeed += params[MOD_SPEED_PARAM].value;
  133. modSpeed = clamp(modSpeed, modSpeedMin, modSpeedMax);
  134. modSpeed *= modSpeed;
  135. modSpeed = modSpeed * 99.f + 1.f;
  136. modShape = inputs[MOD_SHAPE_CV_INPUT].value * params[MOD_DEPTH_CV_PARAM].value * 0.1f;
  137. modShape += params[MOD_SHAPE_PARAM].value;
  138. modShape = rescale(modShape, 0.f, 1.f, modShapeMin, modShapeMax);
  139. modShape = clamp(modShape, modShapeMin, modShapeMax);
  140. modDepth = inputs[MOD_DEPTH_CV_INPUT].value * params[MOD_DEPTH_CV_PARAM].value;
  141. modDepth = rescale(modDepth, 0.f, 10.f, modDepthMin, modDepthMax);
  142. modDepth += params[MOD_DEPTH_PARAM].value;
  143. modDepth = clamp(modDepth, modDepthMin, modDepthMax);
  144. reverb.modSpeed = modSpeed;
  145. reverb.modDepth = modDepth;
  146. reverb.setModShape(modShape);
  147. reverb.process(inputs[LEFT_INPUT].value / 10.f, inputs[RIGHT_INPUT].value / 10.f);
  148. dry = inputs[DRY_CV_INPUT].value * params[DRY_CV_PARAM].value;
  149. dry += params[DRY_PARAM].value;
  150. dry = clamp(dry, 0.f, 1.f);
  151. wet = inputs[WET_CV_INPUT].value * params[WET_CV_PARAM].value;
  152. wet += params[WET_PARAM].value;
  153. wet = clamp(wet, 0.f, 1.f) * 10.f;
  154. outputs[LEFT_OUTPUT].value = inputs[LEFT_INPUT].value * dry;
  155. outputs[RIGHT_OUTPUT].value = inputs[LEFT_INPUT].value * dry;
  156. outputs[LEFT_OUTPUT].value += reverb.leftOut * wet;
  157. outputs[RIGHT_OUTPUT].value += reverb.rightOut * wet;
  158. }
  159. void Plateau::onSampleRateChange() {
  160. reverb.setSampleRate(engineGetSampleRate());
  161. }
  162. void Plateau::reset() {
  163. diffuseInput = 1;
  164. }
  165. json_t* Plateau::toJson() {
  166. json_t *rootJ = json_object();
  167. json_object_set_new(rootJ, "frozen", json_boolean(freeze));
  168. json_object_set_new(rootJ, "freezeToggle", json_boolean(freezeToggle));
  169. json_object_set_new(rootJ, "panelStyle", json_integer(panelStyle));
  170. json_object_set_new(rootJ, "tuned", json_integer((int)tuned));
  171. json_object_set_new(rootJ, "diffuseInput", json_integer((int)diffuseInput));
  172. return rootJ;
  173. }
  174. void Plateau::fromJson(json_t *rootJ) {
  175. json_t *frozenJ = json_object_get(rootJ, "frozen");
  176. freeze = json_boolean_value(frozenJ);
  177. json_t *freezeToggleJ = json_object_get(rootJ, "freezeToggle");
  178. freezeToggle = json_boolean_value(freezeToggleJ);
  179. json_t *panelStyleJ = json_object_get(rootJ, "panelStyle");
  180. panelStyle = json_integer_value(panelStyleJ);
  181. json_t *tunedJ = json_object_get(rootJ, "tuned");
  182. tuned = json_integer_value(tunedJ);
  183. json_t *diffuseInputJ = json_object_get(rootJ, "diffuseInput");
  184. diffuseInput = json_integer_value(diffuseInputJ);
  185. }
  186. ////////////////////////////////////////////////////////////////////////////////////////////////////
  187. void PlateauPanelStyleItem::onAction(EventAction &e) {
  188. module->panelStyle = panelStyle;
  189. }
  190. void PlateauPanelStyleItem::step() {
  191. rightText = (module->panelStyle == panelStyle) ? "✔" : "";
  192. MenuItem::step();
  193. }
  194. ////////////////////////////////////////////////////////////////////////////////////////////////////
  195. PlateauWidget::PlateauWidget(Plateau* module) : ModuleWidget(module) {
  196. {
  197. DynamicPanelWidget *panel = new DynamicPanelWidget();
  198. panel->addPanel(SVG::load(assetPlugin(plugin, "res/PlateauPanelDark.svg")));
  199. panel->addPanel(SVG::load(assetPlugin(plugin, "res/PlateauPanelLight.svg")));
  200. box.size = panel->box.size;
  201. panel->mode = &module->panelStyle;
  202. addChild(panel);
  203. }
  204. addChild(Widget::create<ScrewBlack>(Vec(RACK_GRID_WIDTH, 0)));
  205. addChild(Widget::create<ScrewBlack>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
  206. addChild(Widget::create<ScrewBlack>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  207. addChild(Widget::create<ScrewBlack>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  208. // Make jacks
  209. addInput(Port::create<PJ301MDarkSmall>(module->leftInputPos, Port::INPUT, module, Plateau::LEFT_INPUT));
  210. addInput(Port::create<PJ301MDarkSmall>(module->rightInputPos, Port::INPUT, module, Plateau::RIGHT_INPUT));
  211. addInput(Port::create<PJ301MDarkSmall>(module->dryCVPos, Port::INPUT, module, Plateau::DRY_CV_INPUT));
  212. addInput(Port::create<PJ301MDarkSmall>(module->wetCVPos, Port::INPUT, module, Plateau::WET_CV_INPUT));
  213. addInput(Port::create<PJ301MDarkSmall>(module->inputLowDampCVPos, Port::INPUT, module, Plateau::INPUT_LOW_DAMP_CV_INPUT));
  214. addInput(Port::create<PJ301MDarkSmall>(module->inputHighDampCVPos, Port::INPUT, module, Plateau::INPUT_HIGH_DAMP_CV_INPUT));
  215. addInput(Port::create<PJ301MDarkSmall>(module->sizeCVPos, Port::INPUT, module, Plateau::SIZE_CV_INPUT));
  216. addInput(Port::create<PJ301MDarkSmall>(module->diffCVPos, Port::INPUT, module, Plateau::DIFFUSION_CV_INPUT));
  217. addInput(Port::create<PJ301MDarkSmall>(module->decayCVPos, Port::INPUT, module, Plateau::DECAY_CV_INPUT));
  218. addInput(Port::create<PJ301MDarkSmall>(module->reverbLowDampCVPos, Port::INPUT, module, Plateau::REVERB_LOW_DAMP_CV_INPUT));
  219. addInput(Port::create<PJ301MDarkSmall>(module->reverbHighDampCVPos, Port::INPUT, module, Plateau::REVERB_HIGH_DAMP_CV_INPUT));
  220. addInput(Port::create<PJ301MDarkSmall>(module->modRateCVPos, Port::INPUT, module, Plateau::MOD_SPEED_CV_INPUT));
  221. addInput(Port::create<PJ301MDarkSmall>(module->modShapeCVPos, Port::INPUT, module, Plateau::MOD_SHAPE_CV_INPUT));
  222. addInput(Port::create<PJ301MDarkSmall>(module->modDepthCVPos, Port::INPUT, module, Plateau::MOD_DEPTH_CV_INPUT));
  223. addInput(Port::create<PJ301MDarkSmall>(module->holdCVPos, Port::INPUT, module, Plateau::FREEZE_CV_INPUT));
  224. addInput(Port::create<PJ301MDarkSmall>(module->clearCVPos, Port::INPUT, module, Plateau::CLEAR_CV_INPUT));
  225. addOutput(Port::create<PJ301MDarkSmallOut>(module->leftOutputPos, Port::OUTPUT, module, Plateau::LEFT_OUTPUT));
  226. addOutput(Port::create<PJ301MDarkSmallOut>(module->rightOutputPos, Port::OUTPUT, module, Plateau::RIGHT_OUTPUT));
  227. // Make knobs
  228. float minAngle = -0.77f * M_PI;
  229. float maxAngle = 0.77f * M_PI;
  230. addParam(createValleyKnob<RoganMedWhite>(module->dryPos, module, Plateau::DRY_PARAM, 0.0f, 1.f, 1.f, minAngle, maxAngle));
  231. addParam(createValleyKnob<RoganMedWhite>(module->wetPos, module, Plateau::WET_PARAM, 0.0f, 1.f, 0.5f, minAngle, maxAngle));
  232. addParam(createValleyKnob<RoganSmallWhite>(module->preDelayPos, module, Plateau::PRE_DELAY_PARAM, 0.f, 0.500f, 0.f, minAngle, maxAngle));
  233. addParam(createValleyKnob<RoganMedGreen>(module->inputLowDampPos, module, Plateau::INPUT_LOW_DAMP_PARAM, 0.f, 10.f, 10.f, minAngle, maxAngle));
  234. addParam(createValleyKnob<RoganMedGreen>(module->inputHighDampPos, module, Plateau::INPUT_HIGH_DAMP_PARAM, 0.f, 10.f, 10.f, minAngle, maxAngle));
  235. addParam(createValleyKnob<RoganMedBlue>(module->sizePos, module, Plateau::SIZE_PARAM, 0.f, 1.f, 0.5f, minAngle, maxAngle));
  236. addParam(createValleyKnob<RoganMedBlue>(module->diffPos, module, Plateau::DIFFUSION_PARAM, 0.f, 10.f, 10.f, minAngle, maxAngle));
  237. addParam(createValleyKnob<RoganMedBlue>(module->decayPos, module, Plateau::DECAY_PARAM, 0.1f, 0.9999f, 0.54995f, minAngle, maxAngle));
  238. addParam(createValleyKnob<RoganMedGreen>(module->reverbLowDampPos, module, Plateau::REVERB_LOW_DAMP_PARAM, 0.0f, 10.f, 10.f, minAngle, maxAngle));
  239. addParam(createValleyKnob<RoganMedGreen>(module->reverbHighDampPos, module, Plateau::REVERB_HIGH_DAMP_PARAM, 0.0f, 10.f, 10.f, minAngle, maxAngle));
  240. addParam(createValleyKnob<RoganMedRed>(module->modRatePos, module, Plateau::MOD_SPEED_PARAM, 0.f, 1.f, 0.f, minAngle, maxAngle));
  241. addParam(createValleyKnob<RoganMedRed>(module->modDepthPos, module, Plateau::MOD_DEPTH_PARAM, 0.f, 16.f, 0.5f, minAngle, maxAngle));
  242. addParam(createValleyKnob<RoganMedRed>(module->modShapePos, module, Plateau::MOD_SHAPE_PARAM, 0.f, 1.f, 0.5f, minAngle, maxAngle));
  243. // Make Attenuverters
  244. addParam(ParamWidget::create<RoganSmallWhite>(module->dryAttenPos, module, Plateau::DRY_CV_PARAM, -1.f, 1.f, 1.f));
  245. addParam(ParamWidget::create<RoganSmallWhite>(module->wetAttenPos, module, Plateau::WET_CV_PARAM, -1.f, 1.f, 1.f));
  246. addParam(ParamWidget::create<RoganSmallGreen>(module->inputLowDampAttenPos, module, Plateau::INPUT_LOW_DAMP_CV_PARAM, -1.f, 1.f, 1.f));
  247. addParam(ParamWidget::create<RoganSmallGreen>(module->inputHighDampAttenPos, module, Plateau::INPUT_HIGH_DAMP_CV_PARAM, -1.f, 1.f, 1.f));
  248. addParam(ParamWidget::create<RoganSmallBlue>(module->sizeAttenPos, module, Plateau::SIZE_CV_PARAM, -1.f, 1.f, 1.f));
  249. addParam(ParamWidget::create<RoganSmallBlue>(module->diffAttenPos, module, Plateau::DIFFUSION_CV_PARAM, -1.f, 1.f, 1.f));
  250. addParam(ParamWidget::create<RoganSmallBlue>(module->decayAttenPos, module, Plateau::DECAY_CV_PARAM, -1.f, 1.f, 1.f));
  251. addParam(ParamWidget::create<RoganSmallGreen>(module->reverbLowDampAttenPos, module, Plateau::REVERB_LOW_DAMP_CV_PARAM, -1.f, 1.f, 1.f));
  252. addParam(ParamWidget::create<RoganSmallGreen>(module->reverbHighDampAttenPos, module, Plateau::REVERB_HIGH_DAMP_CV_PARAM, -1.f, 1.f, 1.f));
  253. addParam(ParamWidget::create<RoganSmallRed>(module->modRateAttenPos, module, Plateau::MOD_SPEED_CV_PARAM, -1.f, 1.f, 1.f));
  254. addParam(ParamWidget::create<RoganSmallRed>(module->modShapeAttenPos, module, Plateau::MOD_DEPTH_CV_PARAM, -1.f, 1.f, 1.f));
  255. addParam(ParamWidget::create<RoganSmallRed>(module->modDepthAttenPos, module, Plateau::MOD_SHAPE_CV_PARAM, -1.f, 1.f, 1.f));
  256. // Make buttons
  257. addParam(ParamWidget::create<LightLEDButton>(Vec(7.875, 244.85), module, Plateau::FREEZE_PARAM, 0.f, 10.f, 0.f));
  258. addChild(ModuleLightWidget::create<MediumLight<RedLight>>(Vec(10.375, 247.35), module, Plateau::FREEZE_LIGHT));
  259. addParam(ParamWidget::create<LightLEDButton>(Vec(31.375, 256.35), module, Plateau::FREEZE_TOGGLE_PARAM, 0.f, 10.f, 0.f));
  260. addChild(ModuleLightWidget::create<MediumLight<RedLight>>(Vec(33.875, 258.85), module, Plateau::FREEZE_TOGGLE_LIGHT));
  261. addParam(ParamWidget::create<LightLEDButton>(Vec(157.875, 244.85), module, Plateau::CLEAR_PARAM, 0.f, 10.f, 0.f));
  262. addChild(ModuleLightWidget::create<MediumLight<RedLight>>(Vec(160.375, 247.35), module, Plateau::CLEAR_LIGHT));
  263. addParam(ParamWidget::create<LightLEDButton>(Vec(13.875, 123.35), module, Plateau::TUNED_MODE_PARAM, 0.f, 10.f, 0.f));
  264. addChild(ModuleLightWidget::create<MediumLight<RedLight>>(Vec(16.375, 125.85), module, Plateau::TUNED_MODE_LIGHT));
  265. addParam(ParamWidget::create<LightLEDButton>(Vec(151.875, 123.35), module, Plateau::DIFFUSE_INPUT_PARAM, 0.f, 10.f, 0.f));
  266. addChild(ModuleLightWidget::create<MediumLight<RedLight>>(Vec(154.375, 125.85), module, Plateau::DIFFUSE_INPUT_LIGHT));
  267. }
  268. void PlateauWidget::appendContextMenu(Menu *menu) {
  269. Plateau *module = dynamic_cast<Plateau*>(this->module);
  270. assert(module);
  271. menu->addChild(construct<MenuLabel>());
  272. menu->addChild(construct<MenuLabel>(&MenuLabel::text, "Panel style"));
  273. menu->addChild(construct<PlateauPanelStyleItem>(&MenuItem::text, "Dark", &PlateauPanelStyleItem::module,
  274. module, &PlateauPanelStyleItem::panelStyle, 0));
  275. menu->addChild(construct<PlateauPanelStyleItem>(&MenuItem::text, "Light", &PlateauPanelStyleItem::module,
  276. module, &PlateauPanelStyleItem::panelStyle, 1));
  277. }
  278. RACK_PLUGIN_MODEL_INIT(Valley, Plateau) {
  279. Model *modelPlateau = Model::create<Plateau, PlateauWidget>(TOSTRING(SLUG), "Plateau", "Plateau",
  280. REVERB_TAG);
  281. return modelPlateau;
  282. }