the story continues:

sharing code (and ideas) is a form of potential preservation. after yesterday’s post @ioflow (who holds this forum together!) had recalled that i shared the code during the marathon set in the twitch stream (it was that kind of show).

the code
s = require 'sequins'

m = midi.connect(1)

function init()
  params:add_number("filter","filter",0,127,64)
  params:set_action("filter", function(x) jp("vcf_f",x) end)
end

jmap = {
  lfo_rate = 0,
  lfo_delay = 1,
  dco_lfo = 2,
  dco_pwn = 3,
  dco_noise = 4,
  vcf_f = 5,
  vcf_r = 6,
  vcf_env = 7,
  vcf_lfo = 8,
  vcf_kbd = 9,
  vca = 0xA,
  a = 0xB,
  d = 0xC,
  s = 0xD,
  r = 0xD,
  sub = 0xF
}
  

function no(n,t)
  m:note_on(n,127)
  clock.run(noff,n,t) 
end

function noff(n,t)
  clock.sleep(t)
  m:note_off(n)
end



--m.event = function(data) tab.print(data) end

function jp(p,x)
  m:send{0xf0}
  m:send{0x41}
  m:send{0x32}
  m:send{0x0}
  m:send{jmap[p]}
  m:send{x}
  m:send{0xf7}
end

function panic() for i=0,127 do m:note_off(i) end end



a = s{0,5,3,8,s{15,19},12,s{24,29,8}}
a = s{0,3,8,5,12,15,s{19,24,31}}
a = s{0,3,8,5,12,24,s{19,24,31}:every(2)}

b = s{0,0,0,12,0,7,0,0,s{7,12,24}}

e = s{45,50,55,60,65,70}

c = s{false,false,false, true, false, s{false,true}, true, s{false}:every(2)}

tra = 60
tra2 = 48
ti = 0.1


n = function()
  while true do
    jp("s",5)
    jp("vcf_f",e())
    no(tra+a()+b(),ti)
    if c() then
      no(tra2+a()+b(),ti)
      jp("s",50)
      jp("vcf_f",60)
      clock.sync(2)
    else
      clock.sync(1/8)
    end
  end
end
  
ca = clock.run(n)

a few details jumped out after i saw this. i knew i started with the pedal-to-juno already worked out before the set. but at some point i clearly started editing it live— some sequins emerged so i could, well, hang out with visitors. the giveaway is this:

a = s{0,5,3,8,s{15,19},12,s{24,29,8}}
a = s{0,3,8,5,12,15,s{19,24,31}}
a = s{0,3,8,5,12,24,s{19,24,31}:every(2)}

the first two definitions just get overwritten by the third, so i was line-executing via maiden, testing things out without restarting the script. the likelihood then that this code is “not the final product” is assured by definition: changing the code was part of the process of the performance unfolding.

you’ll also see that despite my previous resistance to use parameters, i did use them this earlier time:

  params:add_number("filter","filter",0,127,64)
  params:set_action("filter", function(x) jp("vcf_f",x) end)

which suggests i just added these two lines then used the param system to map the pedal via the midi mapping system (perhaps with the ranges adjusted, that makes sense… but note, as easy to do with a few more numbers typed for some math scaling.)

and also, some “infrastructure” in the form of a lookup table for the various other sysex params:

jmap = {
  lfo_rate = 0,
  lfo_delay = 1,
  dco_lfo = 2,
  dco_pwn = 3,
  dco_noise = 4,
  vcf_f = 5,
  vcf_r = 6,
...

i don’t remember if i did this on the fly or not, but it is later used in the sequins to make more variation.

the variable names are terrible, but this is normal for thing-in-the-moment, when these obtuse strings are close to your brain.

none of what’s happening is complex: it’s just putting together a few existing musical facilities that the system provides— in a way that allows for a level of control much beyond stringing plugins together with some automation. it’s starting from a lower level. (and again, this example i think works well because it’s nothing genius or original— the point is that it illustrates a different approach to thinking about technological capability.)


what a serious nostalgia trip you just provided. (i recall reading so much about mode x and having it feel just beyond my grasp with assembly/etc. these were the golden demoscene years…)

though i’d say my quintessential general-purpose-computer experience was using basic on the apple 2. having the computer boot to a repl, expectantly. having that be the low level.

teletype and crow have a more narrow focus given their limited capabilities. the nature of these machines ask for a small scope and provide a direct-to-the-point command set. it takes dedication to not just keep going deeper with a more powerful/feature-full machine.

i couldn’t agree more. and am constantly seeking ways to defeat this pattern. i’m hoping this thread can be about that journey.

(not that engineering should be avoided. it’s a necessary task, when called for.)

21 Likes