tidalcycles / Tidal

Pattern language
http://tidalcycles.org/
GNU General Public License v3.0
2.27k stars 255 forks source link

bug with 'bite' and '@' in mininotation #1053

Open TylerMclaughlin opened 11 months ago

TylerMclaughlin commented 11 months ago

I'm on tidal_version 1.9.4. I'm having a bug when I use bite with @ symbol in mininotation.

Here's shorthand I use for midi:

let m = sound "midi" # midichan 0

Take the following melody:

d1 $ n "0 4 7" # m

For a negative control: I parameterize bite so it does nothing. The above code sounds exactly like

d1 $ bite 3 "0 1 2" $ n "0 4 7" # m

Good, this test passed.

(it's dividing the pattern into 3 and patterning those chunks in the normal order).

Modifying the beat in this kind of way works in bite:

d1 $ bite 3 "[0!5] [1!3] [2!9]" $ n "0 4 7" # m

But then this fails:

d1 $ bite 3 "0@5 1@6 2@5" $ n "0 4 7" # m

It adds extra onsets for some reason, instead of just shifting the three notes around. It doesn't sound like

d1 $ n "0@5 4@6 7@5" # m

as I'd expect it to.

jwaldmann commented 11 months ago

Hi. What "extra onsets"? These event sets look identical:

ghci> let m = sound "midi" # midichan 0

ghci> bite 3 "0@5 1@6 2@5" $ n "0 4 7" # m
    (0>5/16)|midichan: 0.0f, n: 0.0n (c5), s: "midi"
(5/16>11/16)|midichan: 0.0f, n: 4.0n (e5), s: "midi"
   (11/16>1)|midichan: 0.0f, n: 7.0n (g5), s: "midi"

ghci> n "0@5 4@6 7@5" # m
    (0>5/16)|midichan: 0.0f, n: 0.0n (c5), s: "midi"
(5/16>11/16)|midichan: 0.0f, n: 4.0n (e5), s: "midi"
   (11/16>1)|midichan: 0.0f, n: 7.0n (g5), s: "midi"

are you saying that the sound (on an externa MIDI device) is different?

TylerMclaughlin commented 11 months ago

Yes. I can reproduce your output examples, so things look good in the Haskell side.
Though MIDI monitor and external devices are definitely showing extra notes. Patterns that are identical after function application are producing different MIDI messages. Very strange.

yaxu commented 11 months ago

Are you able to create the simplest example that creates extra triggers, and share midi output for that? Are you monitoring midi straight out of superdirt?

jwaldmann commented 11 months ago

I confirm that extra events are audible, using the code (with bite) as shown, and sending to a virtual MIDI device (qsynth). It feels non-deterministic.

I am trying to attach here a short audio file, but github won't accept ogg, so I put it in the audio track of an empty video (?)

https://github.com/tidalcycles/Tidal/assets/1334345/ab4fd388-a60b-4ef7-afca-7453804566b6

jwaldmann commented 11 months ago

Perhaps I don't unterstand bite enough.

I wrote above that patterns agree, but that only holds for Arc 0 1, and they are different later:

ghci> flip queryArc (Arc 1 2)  ("0@5 4@6 7@5"  :: Pattern Int)
[(1>15/16)|0,(15/16>111/16)|4,(111/16>2)|7]

ghci> flip queryArc (Arc 1 2)  (bite 3 "0@5 1@6 2@5" $ "0 4 7" :: Pattern Int)
[(1>1¼)|0,(1¼>15/16)|0,(15/16>17/16)|4,(17/16>111/16)|4,(111/16>115/16)|7,(115/16>2)|7]

[EDIT] the version with bite has adjacent events that, when merged, give the events for the version without?

TylerMclaughlin commented 11 months ago

Smart to check later arcs @jwaldmann !

A closer look on the output-- it looks deterministic (thank heavens), but complex. Definitely not doing what I thought it would be doing with '@'.

@yaxu supercollider is sending MIDI through my IAC driver so @jwaldmann is reproducing this with a different virtual MIDI device.

Here's a minimal example that produces the behavior:

bite 2 "0@2 1" $ n "0 7"

I'd expect this to make n "0@2 7" but it makes n "[0@2 7 0 0 7]/2" instead.

yaxu commented 11 months ago

Yes this looks like a bug!

jwaldmann commented 11 months ago

the events are coming in a strange order here

flip queryArc (Arc 0 3) ("0 _ 1"  :: Pattern Int)

 [(0>⅔)|0,(1>1⅔)|0,(2>2⅔)|0,(⅔>1)|1,(1⅔>2)|1,(2⅔>3)|1]

and perhaps this confuses some combining functions (squeeze*). But that's just a guess. In reality, there is no order on events?

Anyway, where does that (non-)order come from? Mininotation AST is

TPat_Seq [TPat_Elongate (2 % 1) (TPat_Atom _ (0)),TPat_Atom _ (1)]

then (still in ParseBP) toPat calls resolveSeq calls timeCat, and there we have

flip queryArc (Arc 0 3) $ timeCat [(2, 0), (1, 1)]
[(0>⅔)|0,(1>1⅔)|0,(2>2⅔)|0,(⅔>1)|1,(1⅔>2)|1,(2⅔>3)|1]