Virtual Mappings– a lot like loopbacks, but slightly different?

Many users who’ve used loopbacks before 1.14.0 are excited by the idea of being able to get Midihub to map to itself all inside the box. But are Virtual Mappings exactly the same?

This topic is to gather ideas as users discover similarities and –maybe more important– differences

Ok, wow. My thinking was way to narrow. @resonotter had mentioned earlier about rescaling through the same pipeline but I didn’t get the full implications of this at first. I’ve been putting the dispatcher through its paces to see all the ways it can be utilized creatively so I only gave virtual loops a quick look… But working through this patch, I have a much better understanding of how powerful this can be.

Being able to map to arguments in the same pipeline means I have to change some of my thinking processes. I am wondering though what extra component makes this work vs 1.13 and a physical loopback. In my early experiments with physical loopbacks, changing parameters in the same pipeline, the results were inadequate and I can’t think of why at the moment.

Right off the back I can imagine that in one pipeline, I can turn on and off different pipe combos with itself, making one pipeline capable of doing radically different transformations depending on a certain input or value. Although it’ll likely need one passthrough first.

1 Like

I having a sneaking suspicion that I don’t fully yet either.

I’ve stopped using the word “loopback” in context of v-m partly just to stop myself thinking that the two are the same.

1 Like

Difference 1 : Virtual Mappings are “safe”

Loopbacks are potentially dangerous, cos you can get into infinite loops if you’re not careful with filters.
Midihub Virtual pipes were always designed so that any chain could not branch back to itself…
…so loops are impossible.


(only Virtual pipes not in the chain are allowed)

“safe?”…

...yet to be decided:

It might be just possible for a mapping event to create an event feedback cascade.
I’ve tried and failed but not yet convinced myself that this is impossible.

Hopefully another user can settle this issue.
TBD


\

Difference 2 : The number of Virtual Mappings “stages” is limited

Sometimes, an event passing through one pipeline needs to map to a Virtual I/O and go on a new pipeline for further manipulation and then to a new mapping…
…and so on.

Each time you do this, a Virtual I/O is “used up”.

With Loopback, as long as you could keep track of the filters there is (was?) no such limit.

My hunch, however, is that

  1. Most virtual mapping scenarios won’t push this envelope, and

  2. Some old loopback patches may well be simplified in translation to virtual mapping presets

1 Like

I’m trying to improve some of my past patches with the new capabilities. This patch scrolls through pipelines by turning them on or off. With targeted mapping, you can bypass 1 or any combination of pipelines by mapping 1 or more notes to each bypass. This was way more complicated with a physical loopback so I was hesitant to share. But now I’ve managed to make it more user friendly and streamline it a bit from the original but I still feel like I’m not completely utilizing the new virtual mapping to its fullest.

In this patch I use CC #20 for multiple purposes. The base incoming value is mapped to the argument 1 in the first transform pipe in the second pipeline. This is to set the note that will disable the bypass. It is also mapped to the low and high work with values to constrict output to the specific note. I’ve found that I had to have this in a separate higher pipeline to change the argument before the midi message goes through the second pipeline.

In the first pipeline I multiply CC 20 into CC 20, 21 and 22. Then I rescale the values of CC 21 to start at value 1 and rescale the value of CC 22 to start at 11. I use these rescaled values to map to the high and low range in the 2nd transform pipe in the 2nd pipeline.

The 1st transform pipe will turn off the bypass inside of the value ranges by sending a note with value 63.
The 2nd transform pipe will turn on the bypass outside of the value ranges by sending a note value 65.

There are 128 notes available to map so this can scale as large as desired. It can also scroll through pipes in the same pipeline if needed. Any input would be helpful.
11-30-2023 (13-31-01)

edited New version
PipeLine Scroll Method 1 amended.mhp (1.0 KB)

I still feel like there’s a way to reduce it further by a few pipes. it works great as is but for us that like to make 255 pipe presets, every pipe is a premium.


@Giedrius Would this be expected behaviour?

@JoeyButters I see all your Transforms are Insert After, did you find the same “line-order-dependent” behaviour when you tried Insert Before in the Transform Rescale line?


@JoeyButters What’s the planned outcome of this patch:

  • To “scroll” up from the bottom “Clock” → “Final” pipeline with Disable as CC#20 is swept down,
  • then “scroll” down re-enabling when CC#20 is swept up again?

The outcome is to trigger the bypass(or any mapped parameter) sequentially by turning a single knob(CC#20 or any knob desired). Turning CC20 sends out a note at value 63 or value 65 starting at note 0 for value 0 and so on up to note 127. The value argument can also be mapped if a user needs the values to be fluid or set to exact values for stepping.

Mappings can be sequentially 1 at a time as in this patch, or it can be multiple mapped parameter in any combination order the user desires by simply mapping the notes created by turning the knob to any parameters they see fit.

It could also be used for a bunch of other purposes like assigning multiple notes to the same parameter and changing those parameters at different rates through rescaling. So it essentially could be a knob that will spread or tighten a common group of parameters in different pipes.

In a more simple form it can be used as a glissando by just sending the notes to output ports instead of mapping. Or even more interestingly, in combination with a harmonizer, it could strum a chord with one knob. To take it a bit further, it may even be possible to create evolving chord strums(or any parameter) by using the spread technique and harmonizers in conjunction.

The spread + harmonizer technique could be used for many other things like adjusting the volume and/or effect sends rate of multiple tracks at the same time with one knob. Or it could adjust different timing parameters for multiple arps (internal or external). So for example if you wanted the kick drum arp or note repeat timing to be adjustable from a single knob but differently for the snares and hi hats.

I see this as the basis of opening up a tidal wave of possibilities. It works well now, but if this will be a foundation, I want to make sure it’s streamlined as it can possibly be. I feel like this could be done in one pipeline instead of 2, but the CC message at it’s incoming base value doesn’t seem to change the mapped argument values in time when using one pipeline.

The expected behavior is for this area to be a bit ‘not strictly defined’ - it does depend on the sequence you insert the pipes in, but the processing order of events coming in from the same input source on multiple lines might change after saving the preset into a .mhp and loading it again. So it’s best to not rely on this and have explicitly designed pipes to meet the expected ordering. The params mapped to a virtual output get updated as soon as a relevant event reaches the virtual output. The problem with having all Transforms in single line currently is that the event processing works by accumulating an avalanche of events, so when a Transform pipe produces 2 events from 1 event, the pipe on the right gets to process 2 events at the same time, and so on. That means all of the events move forward at the same pace. I’ll look into whether it’s possible to do a special ‘laser’ mode for Transform pipe where it would push the events one at a time, this way allowing virtual mapped param changes to happen before the remaining event gets processed, so it could affect the remaining pipes on the same line.

A sure way to get the ordering right would be to use 2 virtual buses - one level to get the initial preprocessing of CC20 done, which manipulate the parameters in a deeper virtual bus, but before CC20 starts to be processed there, as well as using “Insert Before” for producing CC21 and CC22 so they make the changes before CC20 is let through to the deeper bus, like so:

PipeLine Scroll Method 1 amended_deep_mappings.mhp (1.1 KB)

2 Likes

Useful insights :+1:

Just to clarify:

  • “produces 2 events from 1 event” = “creates an additional event from the incoming event”

  • “the pipe on the right” = “any subsequent pipe (at least in the same pipeline)”
    (even when Transform is Insert Before?)

  • “special ‘laser’ mode” not getting the metaphor here!


processing order of events coming in from the same input source on multiple lines might change after saving the preset into a .mhp and loading it again.

Whoa.
That’s something that needs to be built in to testing

Correct.

The events move in ordered batches pipe by pipe all the way to the right until the output when it gets split out again into single events.

Lasers are limited only by the speed of light. :slight_smile: So that means an event produced in laser mode would reach the end of the line faster than the remaining one.

1 Like

It’s unlikely to cause issues in practice, as long as you don’t explicitly rely on it (the circumstances where you would want to rely on that are the ones that call for explicit event ordering solutions)

1 Like

So for example

  1. CC1.33 @ t0, CC6.17 @ t1 enter line
    These are in 2 single event batches

  2. CC1.33 → Transform1, processed Before, creates CC16.33.
    CC6.17 → Transform1, processed Before, creates CC16.17.
    now have [CC16.33, CC1.33] @ t’0, [CC16.17, CC6.17] @ t’1,

    (where ‘’ = “batch of asynchronous events”)

  3. etc down the line until have at end of line, say
    [CC16.33, PC14.33, CC1.33] –pause– [CC16.17, CC6.17, Stop]

  4. at connected Virtual-IN these appear as…
    … micro-second separated single events from Batch0
    –pause–
    … micro-second separated single events from Batch1

It’s unlikely to cause issues in practice

Notwithstanding Difference 2

(Ooh my first time with a linked sub-heading :smile:)

1 Like

This example seems correct, except that the single batch gets processed entirely confined to the same ‘position of the clock’, all the way through, including virtual pipelines. The ‘clock position’ is updated once the t1 single-event batch starts to be processed. This happens naturally, as CC1.33 and CC6.17 enter Midihub at different times.

1 Like

Oh yea, this explains a lot. I kept building patches that worked perfectly or in one instance caused overflows but got totally different results after saving and loading. Aso noticing that throwing in random transform and adding a useless message tends to act as a buffer of sorts, so I am starting to get a better understanding of the message cascading and possibly how to exploit it with virtual mappings…

In laser mode, I’m guessing that the expedited priority message would shoot past the flow of messages, or would it stop messages until it reaches its destination? This sounds amazing for the transform pipe and the rescale pipe.

I wonder if it is possible to have the option for the laser mode to priority travel through the pipeline for processing or skip the rest of the pipeline and go straight to the virtual port.

1 Like

I’ve managed to successfully get the Pipeline Scroll patch down to 1 pipeline with virtual looping.
PipeLine Scroll Final.mhp (1004 Bytes)
12-04-2023 (19-43-18)
Now I’m trying to expand it so additional pipes can be scrolled separately but any use of the rescale pipe has some undesired behavior. I could of course just use a fresh separate pipeline for each control, but I’m trying to keep this economical with the possibility of adding even more scroll controls within just 2 pipelines.

The problem I am running into is when increasing the value 1-6 then decreasing back towards value 0, I expect to see notes 10-15 followed by notes 15-10 when turning back.

Instead of decreasing back to zero, it increases by one transformed message first even though value is decreasing.

Rescale test.mhp (650 Bytes)

1 Like

Use FROM VIRTUAL G on the 2nd line of the test:

image

And possibly rename it to SECONDARY LOOP too. :slight_smile:

Then the transforms will be 1:1.

There’s another possibility - duplicating the CC message with identical values, the second message will get transformed as expected, as the params will be updated by the time the 2nd message goes through. Of course it has the downside of requiring more messages which can have undesired side effects elsewhere.

1 Like

DOHHH! Thank you! For some reason I got locked into the mindset that a virtual mapping stopped the data stream at the mapped port. I’ve been stuck at that mental roadblock trying to build a bridge over it or dig a tunnel under it and never simply tried to walk through it. Now I can really step on the gas and blast down the road. Much appreciations @Giedrius.

1 Like