Pattern Synthesis

I don’t have a lot of idea what I’m doing, but after reading Mark Fell’s PhD Works in Sound and Pattern Synthesis ~ Folio of Works (2013, University of Surrey) chapter 4 Microtemporal works, and setting a single OP-Z drum track note style to gate and animating some OP-Z reverb:

pattern-synthesis-studies/study-0002.lua
-- Pattern synthesis study 0002.
--
-- E1-3 control note on times
-- K2 increase speed.
-- K3 decrease speed.
--
-- Inspired by Mark Fell's PhD
-- thesis "Works in Sound and
-- Pattern Synthesis ~ Folio of
-- Works" (2013)
-- https://openresearch.surrey.ac.uk/esploro/outputs/doctoral/Works-in-Sound-and-Pattern-Synthesis--Folio-of-Works/99516858802346

-- Using sequins and the lattice library.

DEBUG = true
SCREEN_HEIGHT = 64
SCREEN_WIDTH  = 128
MIN = 0.001
MAX = 1

-- Library imports
l = require("lattice")
s = require("sequins")

-- Sequins for values, divisions and velocities
-- From Fell 2013 figure 15, page 100.
seq_len = s{1, 0.371257, 0.323353, 0.239521, 0.197605, 0.137725, 0.08982, 0.05988, 0.047904, 0.02994}
seq_vel = s{100/127}

-- Graph for drawing
graph = {}

function init()
  init_params()

  midi_out = midi.connect(params:get("midi_dev"))
  lat = l:new()
  pat_a = lat:new_pattern{
    division=1/32,
    action=fell
  }
  lat:start()
end

function init_params()
  params:add_option("midi_dev", "MIDI device", {1, 2, 3, 4}, 1)
  params:set_action("midi_dev",
    function(value)
      midi_out = midi.connect(value)
    end
  )
  params:add_number("midi_ch", "MIDI channel", 1, 16, 1)
  params:add_taper("bias", "bias", -0.5, 0.5, 0, 0.1)
end

function fell()
  val = 0.5
  noteon_len = seq_len()
  vel = seq_vel()
  
  midi_note = util.round(127*(val+params:get("bias")))
  midi_vel = util.round(util.linlin(0, 1, 0, 127, vel))
  -- if DEBUG then print("♪ "..midi_note) end
  midi_out:note_on(midi_note, midi_vel, params:get("midi_ch"))
  c = clock.run(delayed_noteoff, midi_note, noteon_len)
  
  update_graph(noteon_len)
  -- pat_a:set_division(div)
  redraw()
end

function delayed_noteoff(midi_note, noteon_len)
  clock.sleep(noteon_len)
  midi_out:note_off(midi_note, 0, params:get("midi_ch"))
end

-- Interactions
-- Encoders set timings in pairs
function enc(n, d)
  seq_len[n] = util.clamp(seq_len[n] + d/10, MIN, MAX)
  seq_len[n+6] = util.clamp(seq_len[n] - d/10, MIN, MAX)
  if DEBUG then print("⏲ New seq_lens is") end
  if DEBUG then tab.print(seq_len.data) end
end

-- K2 slows down, K3 speeds up
function key(n, z)
  if n == 2 and z == 1 then
    pat_a:set_division(pat_a.division*1.02)
    if DEBUG then print("⏲new div is "..pat_a.division) end
  end
  if n == 3 and z == 1 then
    pat_a:set_division(pat_a.division*0.98)
    if DEBUG then print("⏲new div is "..pat_a.division) end
  end
end

-- Screen stuff
function redraw()
  screen.clear()
  draw_graph()
  screen.update()
end

function update_graph(val)
  table.insert(graph, val)
  if #graph > SCREEN_WIDTH then
    table.remove(graph, 1)
  end
end

function draw_graph()
  for i,v in pairs(graph) do
    screen.pixel(i, util.linlin(0, 1, SCREEN_HEIGHT, 0, v))
    screen.fill()
  end
end
17 Likes

ahhhhhh

crazy! i love it
you and @angel are really inspiring with these demos and shared scripts

1 Like

Still don’t have an idea but having fun. Pd driving OP-Z.

OP-Z MIDI implementation is just so amazingly comprehensive. Above all I’m doing is messing with per-track step count at cc 60.

12 Likes

this album is gold. How do they program those drums im not so sure if im understanding how its done.

A lot of super collider i believe. And Max.

Some useful info about their methods also available in this PhD thesis:

5 Likes

thanks for this! 20chars

1 Like

Or defaced their CD’s w Sharpie. (Presumably friends’ CD’s, too.) :yum:


I miss Ottobar :frowning:

1 Like

Mark on Darwin Grosse’s Art + Music + Technology podcast episode 365 from September 2021. 50 minutes.

Blurb is the following:

Mark Fell is one of my favorite artists – his work is the right mix of comfortable and challenging, and his music is truly as good as his ideas about music! As a result, I end up listening to a lot of his work, from the SND material released by Mille Plateaux to his recent experiments with live musicians. I’ve also had the chance to speak with – and interview – him in the past (for Cycling ’74), so there was already a comfort level there between us. So that should have made for a good conversation…

… and it did.

We ranged around the idea-space, talking about his history, his latest work, how he gets along with collaboration and how he thinks about time and complexity. We also get some insights into his overall aesthetic (something that is very important to him), and how that affects his composing/arranging practice. Very interesting, and wonderfully insightful.

Enjoy the podcast, and learn more about Mark’s work on his personal website: mark fell | HomePage .

Transcription available at Transcription: Podcast 0365 - Mark Fell

Exclusive extra content on the Patron page: Patreon

What a lovely North of England chap!

I always kind of hated listening to interviews with musicians, but I’m trying to get into it (is not).


Unrelated but the OPd-Z thing (a few posts up) on MobMuPlat on Android


Update later: while i still don’t even know what “pattern synthesis” means, could means or should mean, after studying Fell’s PhD thesis, his music and others like Automatisme and Alex McLean, and messing around with MIDI, sequencer and looping envelope parameters on my OP-Z, I think I am completely addicted to pattern synthesis. I blame this thread!

7 Likes

Getting really positive results with the acid rain constellation. Highly recommended for Fell/ Gabor Lazar/ Church Andrews/ Matt Davies vibes.

1 Like

For those who want to try this approach in software, I recommend Dot by Fors.fm (included in the Kit bundle)

1 Like

I had a look on the Surrey website, and it seems like the thesis is available there once again:

https://openresearch.surrey.ac.uk/esploro/outputs/doctoral/Works-in-sound-and-pattern-synthesis/99511354802346

i just finished a patch which works but i’m certain there are better ways to accomplish what i did and improve

once i tighten things up i’ll share but wanna draw from the collective wisdom here which might surpass what i found while teaching myself to build the thing (through a million youtube and google searches plus heavy scrutiny of two friends patches)

my main goal? to create a sequencer in which amplitude of waveforms are scanned to determine probability of a trig…i hoped to make small modules for the synthesis of the waves, morphing/interpolation between em, and multiple independent trig patterns to control discrete sounds like the sections of a drum kit

here are those parts and my current solutions:

  • to “generate” waves at the heart of the seq i used two multislider objects w/ 32 faders each…pretty low resolution but when I tried using 64 or more I ran into some problems.
  • each wavemap functions differently, the 1st is propelled by a common metro & counter setup and allows direct input on the faders to change the range of trigs in the cycle coming from that map . zlscramble refreshes the order of values in the seq but the values themselves…the pool of values remains the same without human input
  • wavemap 2 is based around automated interpolation of 16 crude shapes i saved as presets within the multislider (cycle~ into pattrstorage) the purple upfader controls a param i call trig skew…a redundant fader fed into the same inlet for glitchy preset jumping that effectively overrides the cycle
  • a crossfader that really only toggles from one map to another because i could not find my ideal object (a slider with two inlets that xfades between the data values it’s fed) . one is a bit more scattered than the other so switching between maps like this offers crude control of global trig density
  • the last param is one i call pattern size (instead of pattern length) . it’s the way i parse probability of trig output using windows to catch the numbers raining down . each window has a default range it’s “listening” for so you can alter and affect the sequence with the other params mentioned above (esp trig range) OR use the crude toggles i rigged to bloat & squeeze window/pattern size for each section (via slider>preset>rslider>split linked together)

I’m most curious to find a better method for making complex waves to feed the sequencer, understanding how interpolation between data is handled in max, and finding out which of my ideas are more suited to gen (if any)

6 Likes

I did not really get how it works, but it seems interesting. I would like to check it out once you decide to share the patch!

1 Like

Thanks! Revealing everything today…you’ll be able to download the patch in a minute

current v1 UI is buried in patch cords

12 Likes

I came across a close reading of Mark Fell’s Multistability patch which he published in The Wire in 2013 in Joe Snape’s and Georgina Born’s chapter Max, music software and the mutual mediation of aesthetics and digital technologies. The reading on pages 227-233 serves as a point of departure for a wider ethnography and argument they make. The chapter appears in book Music and Digital Media. A Planetary Anthropology (2022, UCL Press :unlock: openly accessible) edited and cowritten by Born.

Might be of interest to peeps in this thread.

8 Likes