Event Highlighting

I'm playing around with a Tidal editor and trying to get feedforward-style context highlights working. Right now I'm running a Tidal boot file that contains the following editor target:

let editorTarget =
      Target {oName = "editor",
              oAddress = "127.0.0.1",
              oPort = editorPort, -- From an ENV variable
              oLatency = 0.02,
              oSchedule = Pre BundleStamp,
              oWindow = Nothing,
              oHandshake = False,
              oBusPort = Nothing
             }
             
    editorShape =
      OSCContext "/editor/highlights"

Then, I'm passing it into my config with:

tidal <- startStream (defaultConfig {cVerbose = True, cFrameTimespan = 1/20}) 
                       [(superdirtTarget, [superdirtShape]),
                        (editorTarget, [editorShape])]

Sure enough, this produces a stream of OSC messages with the pattern ID and the location of a highlighted range. However, it's not obvious to me how you go about matching highlights with individual mininotation strings. Any tips? Is there something else I should be doing?

Like, if I have the pattern d1 $ s "sn bd" # (rotR 0.5 $ n "15 16") and get a message to highlight the range [1, 3], how do I know which symbol to highlight?

My guess is relying on the order that events with the same timestamp come in, but that doesn't seem reliable since UDP makes no promises about dropped packets, etc.

Hey @archaic.tech

These numbers will tell you the column/row of the position within the mininotation. There should be four numbers to give you the start/stop. I think the row is always 1, because mininotation doesn't normally go over more than one row.

This is not so useful by itself, as you don't know which mininotation string it's referring to, and therefore whm00ere in the pattern should be highlighted. For example:
mat

d1 $ sound "bd sd"

The first event should give the numbers ((1,1),(3,1)), to highlight the 'bd ', from column 1 to 3.

To make this more useful you have to tell tidal where each mininotation string is in the original pattern. Here's my (not quite working) attempt at doing that with javascript.

var indexToColRow = function (index, string) {
  const sub = string.substr(0, index);
  const row = (sub.match(/\n/gs) || []).length;
  const col = ((sub.match(/[^\n]+$/gs) || [''])[0].length);
  return([col,row])
}
var mungePattern = function(pat) {
  return pat.replace(/"[^"]+"/sg, function(match, index) {const [col, row] = indexToColRow(index, match); return `(deltaContext ${col} ${row} ${match}})`});
}

With that

mungePattern('d1 $ sound "bd sn" \n  # speed "2 3"')

returns

d1 $ sound (deltaContext 7 0 "bd sn"}) 
  # speed (deltaContext 5 0 "2 3"})"

I.e. it tries to add the row and column to the source positions in the pattern, which should then be reflected in the highlights you get back.

However there's something wrong with my javascript as those aren't the right col / row values! Not sure what's going on as the 'indexToColRow' function seems to work on its own.

Anyway hope that makes some sense, I'm pretty tired atm.. But this is how feedforward does it. There's a big assumption that double quotes are only used to delimit mininotation. That's generally the case.. But it will create confusing errors if you don't match your double quotes. It's a big hack really!

2 Likes

Thinking about it a second more.. tidal-listener could take care of this munging on the haskell side, using the existing 'deltaMini' function.

That makes a lot of sense, thanks! I hadn't realized that there was an extra step of injecting new metadata code, but that makes sense. I'm happy to keep tweaking your Javascript example and figuring out how to get it working.

I found this interesting so I did some digging and opened Reimplementing event highlighting in tidal-listener · Issue #1047 · tidalcycles/Tidal · GitHub to share my thoughts and spark a new discussion.

4 Likes

As I mentioned here Visual feedback - #3 by mrreason I started to implement the event highlighting for TidalCycles in the Pulsar editor. I will continue the discussion in this thread - it feels more fitting.

I still have some work to do to make it easy accessible for everybody, but the implementaton itself is done :slight_smile: I expect that I will create a PR for this implementation next week.

Thanks to @archaic.tech and @Zalastax. The summary on Github and the implementation in text.management was really helpful. With this in mind I knew, that it is possible to implement event highlighting with the current data we receive from TidalCycles.

Here is a demo video I made. It show that it even works with a real special setup (in this case my setup :-D). I would really appreciate some early feedback:

3 Likes

Wow, your implementation already looks amazing!

1 Like

Looks absolutely perfect already, thank you for doing that!
This will be extremely valuable for teaching, or just in general to keep track of what's happening in longer patterns.

1 Like