4ms / metamodule

MetaModule virtual patch module firmware
Other
9 stars 0 forks source link

Feature: Handle Normalization of jacks #40

Open danngreen opened 1 year ago

danngreen commented 1 year ago

Would be great to be able to indicate a Hub jack is normalized to a virtual jack. For example, you might want to make a patch where you can physically patch a trigger into Gate In 1, and it triggers a Djembe. But if you unpatch the Gate In 1 jack, an internal LFO square wave output triggers the Djembe.

How to do this?

mhetrick commented 1 year ago

Wait, the hardware can detect if a cable is connected? That's great!

One thought would be to add eight jacks to the right of the Hub, either always there or maybe as a VCV expander to the Hub (since it would be a less frequently used feature). These would be labeled something like "INPUT CONNECTED GATES". Those eight jacks would output +5V if a cable is connected. With that, the user could use the +5V signal to toggle a switch to choose between the input signal or the "normalized" signal. It also opens up a fun performance feature where you could plug in dummy cables to trigger gestures.

danngreen commented 1 year ago

Yes, actually all 16 physical jacks (inputs and outputs) have a detection pin, so the processor knows if they're plugged or not. The patch player passes this information to the virtual modules (here, which ends up calling this for VCV ported modules)

An expander with gate outs for plugged/unplugged status could be generally useful thing, I imagine people would come up with some interesting uses for that. It could handle the case where you have stereo outputs of a virtual module patched to panel Outs 1 + 2, but you want to hear the mono mix if you patch only into Out 1 (and leave Out 2 unpatched). The normalization gate from Out 2 could go into a 2:1 switch that selects Out 1's signal: Left channel output, or the output of a mixer which is summing the Left and Right outs. Of course, this could be done on the virtual module itself, so there would only be a need for this use case if the virtual module doesn't have that feature or if you want to combine signals from two different modules.

Taking this idea a bit farther, since the most common use case would be for switching between two signals, maybe the expander itself has 2:1 switches built into it. The associated panel jack's signal could be normalized to one of the jacks, so at minimum you would just need to patch to an expander input jack labeled "Gate In 1 Normalization", "Audio In 1 Normalization", etc. It might save some processing overhead and patch complexity to not have extra modules and cables.

In any case I'd have to figure out how to cleanly handle Hub-expanders in firmware...

Re: playability: The latency is high for the jack detection, since I didn't design it to be able to respond rapidly to changes. That probably would make it hard to use for performance triggers, but still useful for enabling/disabling a connection.

mhetrick commented 11 months ago

So here's another design consideration: sending "0 channels" to inputs when nothing is connected to the physical module.

For a module like Rings, for instance, when nothing is connected to the input jacks, an internal noise generator is normalled there for its traditional sound as an instrument. When anything else is connected, it defeats the noise generator and Rings becomes an effect resonator for whatever is plugged in.

Don Cross made a module called "Moots" that is able to send a signal with 0 active channels, which Rack interprets the same as isConnected == false. https://github.com/cosinekitty/sapphire/blob/main/Moots.md

If there were a way to do something similar with the hardware, you could have a Rings patch on the MM instead of saving separate "Rings Instrument" and "Rings Effect" patches.

danngreen commented 11 months ago

Interesting.... The way Moots does it is similar to how the MetaModule VCV_Adaptor works internally. That is, in MetaModule the cable is still "connected", it's just that a call to inputs[JACK].isConnected() will return false (same as in VCV where that function returns false if channels == 0). Also in the MetaModule the patch player will stop sending the physical jack's values to the module, so even if a module doesn't call isConnected(), it still won't see any signal. Internally, the MetaModule just stores a boolean value (connected or not), but if we migrate to polyphony then I imagine it would need to store # of channels as well (or just # of channels, with 0 meaning unconnected, like VCV does).

I just tested the Rings module test patch (shared/patch/module_tests/AudibleInstruments/Rings1.yml) and it seems to work the same as in VCV. I can send a signal into the V/oct jack, for instance, with no other jacks patched and it'll automatically trigger notes when the voltage changes. Same thing if I patch any of the outputs-- the unpatched jacks act like there's an internal exciter patched to them. So we shouldn't need separate Rings FX and Rings Instrument patches.

danngreen commented 2 months ago

Requested in this thread: https://forum.4ms.info/t/various-quality-of-life-issues/140/8

I often want to normal the inputs on the Meta, e.g. create a patch where a signal patched to input 3 is automatically normaled to input 4 unless there’s a physical cable inserted into input 4. It would be great to add that feature down the road if the hardware allows.