BogaudioModules

BogaudioModules for VCV Rack
Log | Files | Refs | README | LICENSE

module.cpp (6312B)


      1 
      2 #include "module.hpp"
      3 #include "bogaudio.hpp"
      4 
      5 using namespace bogaudio;
      6 
      7 #define SKIN "skin"
      8 
      9 void BGModule::onRemove() {
     10 	while (_channels >= 1) {
     11 		removeChannel(_channels - 1);
     12 		--_channels;
     13 	}
     14 }
     15 
     16 void BGModule::onReset() {
     17 	_steps = _modulationSteps;
     18 	reset();
     19 }
     20 
     21 void BGModule::onSampleRateChange() {
     22 	_modulationSteps = APP->engine->getSampleRate() * (2.5f / 1000.0f); // modulate every ~2.5ms regardless of sample rate.
     23 	_steps = _modulationSteps;
     24 	sampleRateChange();
     25 }
     26 
     27 json_t* BGModule::dataToJson() {
     28 	json_t* root = json_object();
     29 	if (_skinnable && _skin != "default") {
     30 		json_object_set_new(root, SKIN, json_string(_skin.c_str()));
     31 	}
     32 	return saveToJson(root);
     33 }
     34 
     35 void BGModule::dataFromJson(json_t* root) {
     36 	if (_skinnable) {
     37 		json_t* s = json_object_get(root, SKIN);
     38 		if (s) {
     39 			setSkin(json_string_value(s));
     40 		}
     41 		else {
     42 			setSkin(_skin);
     43 		}
     44 	}
     45 
     46 	loadFromJson(root);
     47 }
     48 
     49 void BGModule::process(const ProcessArgs& args) {
     50 	if (!_initialized) {
     51 		_initialized = true;
     52 		onReset();
     53 		onSampleRateChange();
     54 	}
     55 
     56 	bool modulateNow = false;
     57 	++_steps;
     58 	if (_steps >= _modulationSteps) {
     59 		_steps = 0;
     60 		modulateNow = true;
     61 		modulateAlways();
     62 	}
     63 
     64 	processAlways(args);
     65 	if (active()) {
     66 		if (modulateNow) {
     67 			int channelsBefore = _channels;
     68 			int channelsNow = std::max(1, channels());
     69 			if (channelsBefore != channelsNow) {
     70 				_channels = channelsNow;
     71 				_inverseChannels = 1.0f / (float)_channels;
     72 				channelsChanged(channelsBefore, channelsNow);
     73 				if (channelsBefore < channelsNow) {
     74 					while (channelsBefore < channelsNow) {
     75 						addChannel(channelsBefore);
     76 						++channelsBefore;
     77 					}
     78 				}
     79 				else {
     80 					while (channelsNow < channelsBefore) {
     81 						removeChannel(channelsBefore - 1);
     82 						--channelsBefore;
     83 					}
     84 				}
     85 			}
     86 
     87 			modulate();
     88 			for (int i = 0; i < _channels; ++i) {
     89 				modulateChannel(i);
     90 			}
     91 		}
     92 
     93 		processAll(args);
     94 		for (int i = 0; i < _channels; ++i) {
     95 			processChannel(args, i);
     96 		}
     97 		postProcess(args);
     98 	}
     99 	postProcessAlways(args);
    100 }
    101 
    102 void BGModule::setSkin(std::string skin) {
    103 	if (skin == "default" || Skins::skins().validKey(skin)) {
    104 		_skin = skin;
    105 		for (auto scl : _skinChangeListeners) {
    106 			scl->skinChanged(skin);
    107 		}
    108 	}
    109 }
    110 
    111 void BGModule::addSkinChangeListener(SkinChangeListener* listener) {
    112 	_skinChangeListeners.push_back(listener);
    113 	listener->skinChanged(_skin);
    114 }
    115 
    116 
    117 BGModuleWidget::BGModuleWidget() {
    118 	Skins::skins().registerDefaultSkinChangeListener(this);
    119 }
    120 
    121 BGModuleWidget::~BGModuleWidget() {
    122 	Skins::skins().deregisterDefaultSkinChangeListener(this);
    123 }
    124 
    125 void BGModuleWidget::addParam(ParamWidget* param) {
    126 	ModuleWidget::addParam(param);
    127 	if (module) {
    128 		auto l = dynamic_cast<SkinChangeListener*>(param);
    129 		if (l) {
    130 			auto m = dynamic_cast<BGModule*>(module);
    131 			assert(m);
    132 			m->addSkinChangeListener(l);
    133 		}
    134 	}
    135 }
    136 
    137 void BGModuleWidget::addInput(PortWidget* input) {
    138 	ModuleWidget::addInput(input);
    139 	if (module) {
    140 		auto l = dynamic_cast<SkinChangeListener*>(input);
    141 		if (l) {
    142 			auto m = dynamic_cast<BGModule*>(module);
    143 			assert(m);
    144 			m->addSkinChangeListener(l);
    145 		}
    146 	}
    147 }
    148 
    149 void BGModuleWidget::addOutput(PortWidget* output) {
    150 	ModuleWidget::addOutput(output);
    151 	if (module) {
    152 		auto l = dynamic_cast<SkinChangeListener*>(output);
    153 		if (l) {
    154 			auto m = dynamic_cast<BGModule*>(module);
    155 			assert(m);
    156 			m->addSkinChangeListener(l);
    157 		}
    158 	}
    159 }
    160 
    161 void BGModuleWidget::appendContextMenu(Menu* menu) {
    162 	auto m = dynamic_cast<BGModule*>(module);
    163 	assert(m);
    164 	if (m->_skinnable) {
    165 		Skins* skins = &Skins::skins();
    166 		if (skins->available().size() > 0) {
    167 			menu->addChild(new MenuLabel());
    168 			OptionsMenuItem* s = new OptionsMenuItem("Panel");
    169 
    170 			s->addItem(OptionMenuItem("Default", [m]() { return m->_skin == "default"; }, [m]() { m->setSkin("default"); }));
    171 			for (auto skin : skins->available()) {
    172 				std::string key = skin.key;
    173 				s->addItem(OptionMenuItem(
    174 					skin.display.c_str(),
    175 					[m, key]() { return m->_skin == key; },
    176 					[m, key]() { m->setSkin(key); }
    177 				));
    178 			}
    179 
    180 			s->addSpacer();
    181 			for (auto skin : skins->available()) {
    182 				std::string key = skin.key;
    183 				s->addItem(OptionMenuItem(
    184 					(std::string("Default to ") + skin.display).c_str(),
    185 					[key, skins]() { return skins->defaultKey() == key; },
    186 					[key, skins]() { skins->setDefaultSkin(key); }
    187 				));
    188 			}
    189 
    190 			OptionsMenuItem::addToMenu(s, menu);
    191 		}
    192 	}
    193 
    194 	contextMenu(menu);
    195 }
    196 
    197 void BGModuleWidget::skinChanged(const std::string& skin) {
    198 	updatePanel();
    199 }
    200 
    201 void BGModuleWidget::defaultSkinChanged(const std::string& skin) {
    202 	if (module) {
    203 		auto m = dynamic_cast<BGModule*>(module);
    204 		assert(m);
    205 		if (m->_skin == "default") {
    206 			m->setSkin("default");
    207 		}
    208 	}
    209 	else {
    210 		updatePanel();
    211 	}
    212 }
    213 
    214 void BGModuleWidget::setPanel(Vec size, std::string slug, bool skinnable) {
    215 	_size = size;
    216 	_slug = slug;
    217 	_skinnable = skinnable;
    218 	if (module && _skinnable) {
    219 		auto m = dynamic_cast<BGModule*>(module);
    220 		assert(m);
    221 		m->addSkinChangeListener(this);
    222 	}
    223 	updatePanel();
    224 }
    225 
    226 void BGModuleWidget::updatePanel() {
    227 	const Skins& skins = Skins::skins();
    228 	std::string skin = skins.defaultKey();
    229 	if (!_skinnable) {
    230 		skin = "light";
    231 	}
    232 	else if (module) {
    233 		auto m = dynamic_cast<BGModule*>(module);
    234 		assert(m);
    235 		skin = m->_skin;
    236 		if (skin == "default") {
    237 			skin = skins.defaultKey();
    238 		}
    239 	}
    240 
    241 	if (_loadedSkin == skin) {
    242 		return;
    243 	}
    244 	_loadedSkin = skin;
    245 	if (_panel) {
    246 		_panel->requestDelete();
    247 		_panel = NULL;
    248 	}
    249 
    250 	std::string svg = "res/" + _slug;
    251 	if (skin != "light") {
    252 		svg += "-";
    253 		svg += skin;
    254 	}
    255 	svg += ".svg";
    256 	_panel = new SvgPanel();
    257 	_panel->box.size = _size;
    258 	addChildBottom(_panel);
    259 	_panel->setBackground(APP->window->loadSvg(asset::plugin(pluginInstance, svg)));
    260 }
    261 
    262 void BGModuleWidget::createScrews() {
    263 	int hp = box.size.x / RACK_GRID_WIDTH;
    264 	BGModule* m = NULL;
    265 	if (_skinnable && module) {
    266 		m = dynamic_cast<BGModule*>(module);
    267 		assert(m);
    268 	}
    269 	auto screw = [m, this](Vec v) {
    270 		auto w = createWidget<Screw>(v);
    271 		if (m) {
    272 			m->addSkinChangeListener(w);
    273 		}
    274 		this->addChild(w);
    275 	};
    276 
    277 	if (hp > 13) {
    278 		screw(Vec(15, 0));
    279 		screw(Vec(box.size.x - 30, 0));
    280 		screw(Vec(15, 365));
    281 		screw(Vec(box.size.x - 30, 365));
    282 	}
    283 	else if (hp > 8) {
    284 		screw(Vec(0, 0));
    285 		screw(Vec(box.size.x - 15, 0));
    286 		screw(Vec(0, 365));
    287 		screw(Vec(box.size.x - 15, 365));
    288 	}
    289 	else {
    290 		screw(Vec(0, 0));
    291 		screw(Vec(box.size.x - 15, 365));
    292 	}
    293 }