BogaudioModules

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

mixer.cpp (5761B)


      1 
      2 #include "mixer.hpp"
      3 
      4 const float MixerChannel::maxDecibels = 6.0f;
      5 const float MixerChannel::minDecibels = Amplifier::minDecibels;
      6 const float MixerChannel::levelSlewTimeMS = 5.0f;
      7 
      8 void MixerChannel::setSampleRate(float sampleRate) {
      9 	_levelSL.setParams(sampleRate, levelSlewTimeMS, maxDecibels - minDecibels);
     10 	_levelCVSL.setParams(sampleRate, levelSlewTimeMS, 1.0f);
     11 	_rms.setSampleRate(sampleRate);
     12 }
     13 
     14 void MixerChannel::reset() {
     15 	out = rms = 0.0f;
     16 }
     17 
     18 void MixerChannel::next(float sample, bool solo, int c, bool linearCV) {
     19 	float cv = 1.0f;
     20 	if (_levelInput.isConnected()) {
     21 		cv = clamp(_levelInput.getPolyVoltage(c) / 10.0f, 0.0f, 1.0f);
     22 	}
     23 
     24 	float mute = _muteParam.getValue();
     25 	if (_muteInput) {
     26 		mute += clamp(_muteInput->getPolyVoltage(c), 0.0f, 10.0f);
     27 	}
     28 	bool muted = solo ? mute < 2.0f : mute > 0.5f;
     29 	if (muted) {
     30 		_amplifier.setLevel(_levelSL.next(minDecibels));
     31 	}
     32 	else {
     33 		float level = clamp(_levelParam.getValue(), 0.0f, 1.0f);
     34 		if (!linearCV) {
     35 			level *= cv;
     36 		}
     37 		level *= maxDecibels - minDecibels;
     38 		level += minDecibels;
     39 		_amplifier.setLevel(_levelSL.next(level));
     40 	}
     41 
     42 	out = _amplifier.next(sample);
     43 	if (linearCV) {
     44 		out *= _levelCVSL.next(cv);
     45 	}
     46 	rms = _rms.next(out / 5.0f);
     47 }
     48 
     49 
     50 #define LINEAR_CV "linear_cv"
     51 
     52 json_t* LinearCVMixerModule::saveToJson(json_t* root) {
     53 	json_object_set_new(root, LINEAR_CV, json_boolean(_linearCV));
     54 	return root;
     55 }
     56 
     57 void LinearCVMixerModule::loadFromJson(json_t* root) {
     58 	json_t* l = json_object_get(root, LINEAR_CV);
     59 	if (l) {
     60 		_linearCV = json_boolean_value(l);
     61 	}
     62 }
     63 
     64 
     65 void LinearCVMixerWidget::contextMenu(Menu* menu) {
     66 	auto m = dynamic_cast<LinearCVMixerModule*>(module);
     67 	assert(m);
     68 	menu->addChild(new BoolOptionMenuItem("Linear level CV response", [m]() { return &m->_linearCV; }));
     69 }
     70 
     71 
     72 #define DIM_DB "dim_decibels"
     73 
     74 json_t* DimmableMixerModule::saveToJson(json_t* root) {
     75 	root = LinearCVMixerModule::saveToJson(root);
     76 	json_object_set_new(root, DIM_DB, json_real(_dimDb));
     77 	return root;
     78 }
     79 
     80 void DimmableMixerModule::loadFromJson(json_t* root) {
     81 	LinearCVMixerModule::loadFromJson(root);
     82 	json_t* o = json_object_get(root, DIM_DB);
     83 	if (o) {
     84 		_dimDb = json_real_value(o);
     85 	}
     86 }
     87 
     88 
     89 void DimmableMixerWidget::contextMenu(Menu* menu) {
     90 	LinearCVMixerWidget::contextMenu(menu);
     91 	auto m = dynamic_cast<DimmableMixerModule*>(module);
     92 	assert(m);
     93 	OptionsMenuItem* da = new OptionsMenuItem("Dim amount");
     94 	da->addItem(OptionMenuItem("-6 dB", [m]() { return m->_dimDb == 6.0f; }, [m]() { m->_dimDb = 6.0f; }));
     95 	da->addItem(OptionMenuItem("-12 dB", [m]() { return m->_dimDb == 12.0f; }, [m]() { m->_dimDb = 12.0f; }));
     96 	da->addItem(OptionMenuItem("-18 dB", [m]() { return m->_dimDb == 18.0f; }, [m]() { m->_dimDb = 18.0f; }));
     97 	da->addItem(OptionMenuItem("-24 dB", [m]() { return m->_dimDb == 24.0f; }, [m]() { m->_dimDb = 24.0f; }));
     98 	OptionsMenuItem::addToMenu(da, menu);
     99 }
    100 
    101 
    102 void MuteButton::onButton(const event::Button& e) {
    103 	if (!(e.action == GLFW_PRESS && (e.mods & RACK_MOD_MASK) == 0)) {
    104 		return;
    105 	}
    106 
    107 	if (e.button == GLFW_MOUSE_BUTTON_RIGHT) {
    108 		e.consume(this);
    109 	}
    110 	else {
    111 		ToggleButton::onButton(e);
    112 	}
    113 }
    114 
    115 bool MuteButton::isLit() {
    116 	return module && !module->isBypassed() && getParamQuantity() && getParamQuantity()->getValue() > 0.0f;
    117 }
    118 
    119 void MuteButton::draw(const DrawArgs& args) {
    120 	if (!isLit()) {
    121 		ToggleButton::draw(args);
    122 	}
    123 }
    124 
    125 void MuteButton::drawLit(const DrawArgs& args) {
    126 	ToggleButton::draw(args);
    127 }
    128 
    129 
    130 SoloMuteButton::SoloMuteButton() {
    131 	shadow = new CircularShadow();
    132 	addChild(shadow);
    133 
    134 	_svgWidget = new SvgWidget();
    135 	addChild(_svgWidget);
    136 
    137 	auto svg = APP->window->loadSvg(asset::plugin(pluginInstance, "res/button_18px_0.svg"));
    138 	_frames.push_back(svg);
    139 	_frames.push_back(APP->window->loadSvg(asset::plugin(pluginInstance, "res/button_18px_1_orange.svg")));
    140 	_frames.push_back(APP->window->loadSvg(asset::plugin(pluginInstance, "res/button_18px_1_green.svg")));
    141 	_frames.push_back(APP->window->loadSvg(asset::plugin(pluginInstance, "res/button_18px_1_green.svg")));
    142 
    143 	_svgWidget->setSvg(svg);
    144 	box.size = _svgWidget->box.size;
    145 	shadow->box.size = _svgWidget->box.size;
    146 	shadow->blurRadius = 1.0;
    147 	shadow->box.pos = Vec(0.0, 1.0);
    148 }
    149 
    150 void SoloMuteButton::onButton(const event::Button& e) {
    151 	if (!getParamQuantity() || !(e.action == GLFW_PRESS && (e.mods & RACK_MOD_MASK) == 0)) {
    152 		ParamWidget::onButton(e);
    153 		return;
    154 	}
    155 
    156 	float value = getParamQuantity()->getValue();
    157 	if (value >= 2.0f) {
    158 		getParamQuantity()->setValue(value - 2.0f);
    159 	}
    160 	else if (e.button == GLFW_MOUSE_BUTTON_RIGHT) {
    161 		getParamQuantity()->setValue(value + 2.0f);
    162 	}
    163 	else {
    164 		getParamQuantity()->setValue(value > 0.5f ? 0.0f : 1.0f);
    165 	}
    166 
    167 	if (e.button == GLFW_MOUSE_BUTTON_RIGHT) {
    168 		e.consume(this);
    169 	} else {
    170 		ParamWidget::onButton(e);
    171 	}
    172 }
    173 
    174 void SoloMuteButton::onChange(const event::Change& e) {
    175 	assert(_frames.size() == 4);
    176 	if (getParamQuantity()) {
    177 		float value = getParamQuantity()->getValue();
    178 		assert(value >= 0.0f && value <= 3.0f);
    179 		_svgWidget->setSvg(_frames[(int)value]);
    180 	}
    181 	ParamWidget::onChange(e);
    182 }
    183 
    184 bool SoloMuteButton::isLit() {
    185 	return module && !module->isBypassed() && getParamQuantity() && getParamQuantity()->getValue() > 0.0f;
    186 }
    187 
    188 void SoloMuteButton::draw(const DrawArgs& args) {
    189 	if (!isLit() || !getParamQuantity() || getParamQuantity()->getValue() < 1.0f) {
    190 		ParamWidget::draw(args);
    191 	}
    192 }
    193 
    194 void SoloMuteButton::drawLit(const DrawArgs& args) {
    195 	if (getParamQuantity() && getParamQuantity()->getValue() >= 1.0f) {
    196 		ParamWidget::draw(args);
    197 	}
    198 }
    199 
    200 
    201 std::string DimSwitchQuantity::getDisplayValueString() {
    202 	if (!module || getValue() < 1.0f) {
    203 		return SwitchQuantity::getDisplayValueString();
    204 	}
    205 	auto* m = static_cast<DimmableMixerModule*>(module);
    206 	assert(labels.size() == 2);
    207 	return format("%s (-%ddB)", labels[1].c_str(), (int)m->_dimDb);
    208 }