Hello!
Is there an engine or attempts for one, that deals with Spectral/FFT/Phase Vocoder processing? Maybe a freeze effect as a starting point, or more creative uses with treating the real and imaginary components differently for glitch-like mayhem?

And something related to convolution? Maybe not the stereotypical convolution reverb, but more creative uses, I tried to layer sounds on itself via convolution in Ableton live, with hard to manage but sometimes interesting results in the past.

These are just ideas, I’m currently in the process of getting the parts for a Raspberry shield, so am not experienced with norns at all but willing to learn all the stuff.
I tried some FFT-stuff on the Bela/Beaglebon Black with SC but quickly reached it’s limits in terms of processing power, hopefully the Rpi 4 will provide some better results!?

here is an example of one. it does many things including a phase vocoder freeze effect (which is the tip of the iceberg of the PV_ChainUGens really)

you can get a lot of PV done on norns. optimization tips would include:

  • use PV_Copy and friends when possible/appropriate for parallel processing, avoiding multiple FFTs
  • prefer dedicated PV_* ugens (well-optimized) to rolling your own with pvcalc and pvcollect (not optimized)
3 Likes

Norns + grid seems to have a lot of potential as a platform for interesting “intelligent” midi controllers. I’d love to have a chord-based MIDI controller to quickly build progressions in ableton or just play around intuitively with hardware polysynths. I made this quick mockup sort of inspired by the Omnichord, Kordbot, and accordion bass buttons. I have almost zero coding experience and have no idea how feasible this is to implement, so I’m mostly just putting this out there because it’s fun to think about. None of this is precious or refined.

The right half is a play surface with buttons that trigger chords (top right quadrant) or individual notes of a chord (bottom right quadrant). Each column is a different scale degree plus an octave repeat. Each row in the top right quadrant represents diatonic triads or 7th chords built on the major or minor scale, so everything sounds in key (i.e. the row that says “major” aren’t all major chords, they’re triads built from the major scale). Bottom right quadrant lets you play individual notes of each chord (whether it’s octave/7ths or major/minor depends on the last played row in the top right quadrant).

The left half sets parameters. All are latching unless held for momentary selection.

“Base” columns set the center point of a parameter (bottom button = minimum, top button = maximum). “Spread” columns set the variance/distribution width of the values for the parameter for all the notes in a chord (i.e. it determines the average offset from the base value for a cluster of notes). E.g. MIDI note velocity base is column 7 and spread is column 8, so if velocity base is maximum and velocity spread is minimum, all the notes in a chord will have a velocity of 127. If velocity base is medium and velocity spread is medium then you’ll get a distribution of note velocities clustered around 64.

Note density leaves all notes in at maximum value and thins notes from of large multi-octave chords at medium or low values.

Different strike types are for different timing offsets of the notes and might include block chord, strum up, strum down, strum in, strum out, zig zag down, zig zag up, etc. Spread range in the timing offsets could be large to accommodate both naturalistic strums (low spread) and pseudo sequences (high spread).

Bottom half of column 1 sets chord inversions.

Top half of column 1 is for miscellaneous functions including a separate key select page, all notes off button, note-on latch or sustain (midi cc 64) button, and a secondary dominant modifier.

The secondary dominant button is a little wacky but seems like a good way to generate less “in key” sounding chords and quickly create tension and release without being totally random. When this button is pressed and a chord is selected in the top right quadrant, instead of playing the chord itself it will play the dominant chord of that chord. That means if you press the 5th scale degree chord in the major scale triads row (column 13, row 1) while the secondary dominant button is pressed, then it will play the dominant (fifth) chord relative to the chord you selected. In that case it’s the fifth of the fifth but you can select other scale degrees to play the fifth of the second chord or the fifth of the fourth chord, etc. I hope that makes sense as I know just enough music theory to say dumb things that might sound smart.

It’s sorta complex but everything is layed out on one page besides key select. One variant might be that instead of having major (ionian) and minor (aeolian) as the only two modes, you could select two modes from a larger list, but I’m not sure if that’s necessary (probably fine going my whole life without hearing locrian 7th chords).

9 Likes

So, I recently assembled my DIY Norns Shield. I’m still going through all the scripts available, which is great fun, and I have found a couple of uses to incorporate it in my music. But I’m looking for two apps/scripts which could be of great use to me. Does anyone know whether any of the following is out there?

  • I’m looking to use the Norns as a sample playing device. I would like to have a quick access menu to select a sample uploaded to the Norns. One button would act as a play button, another button as a stop button. No further audio processing necessary.

  • I’m also looking for a script similar to the looper function in the Line6 DL4 guitar pedal. One button acts as a record and overdub button (first press starts recording the input, second press puts the device in overdubbing mode, meaning that the loop starts playing but immediately records the input on top of the loop). A second button functions as both a play and stop button. A third button retriggers the loop with every press and plays it only once. If there could be a half speed/double speed function, as well as reverse mode, that’d be great. As this requires somewhat more controls, I’ve no idea yet how this would work with the limited controls on the Norns.

I’m still really new to this platform, so I have no idea how the coding would work. If someone could point me in the right direction (either an existing script or pointers on how to write the code for this), that would be great!

Thanks in advance, guys!

You could use TAPE.

I don’t have experience with that particular looper, but there are tons of great looper scripts. If none fit the bill, i’m sure you could work something up with softcut.

Check out the norns studies :slight_smile:

2 Likes

wrms + cranes !

2 Likes

I think a Norns roguelike would be super fun and a cool opportunity at a novel control surface. Anyone interested in getting libtcod wrapped for Lua 5.3? The last working wrapper I found was for Lua 5.1 and I have a few too many things rn to figure that one out… yet!

3 Likes

Now that I think about it, this thread might be a nice inspiration for screen interface designs for norns instruments/devices:

2643c1294a7249ff

23 Likes

interesting, I was just looking at that Earle Brown in terms of norns screen.

also, these:

and for my “Albers” script that I want to pick back up:

20 Likes

Oh yeah! That Albers piece already looks like a Norns screen! :joy:

2 Likes

now to figure out what to do with it…

the crazy thing is I didn’t plan it out as far as pixels/sizing and it ended up fitting perfectly

37 Likes

It’d be fun to do this as golf… how many strokes to recreate this!

Ha!
Totally awesome.
It can be a sequencer, that reads pixel columns or rows. Each shade of gray being a sample or note value. If notes, then the 3 or 4 notes could be chords. So maybe it’s an arpegiator of sorts…

1 Like

I keep drooling over the possibility to add a fixed filter bank to my eurorack system but thought that this might make for a very interesting and straight forward Norns script. I’m particularly fond of the sounds from the Verbos Bark Filter, which is inspired by the Buchla 296 Programmable Spectral Processor and makes use a bank of 12 fixed filters on the Bark scale (proposed by Eberhard Zwicker in 1961). Considering the possibility to integrate Crow to allow for some creative CV control, i’d love to see what people could come up with.

7 Likes

This is a great idea. (And I love having a fixed filter in my Eurorack. For many years it was the ADDAC601, though eventually I needed the room for other modules, so I switched to the Make Noise FXDf, which apparently is no longer in production but can be found used, of course. Both are highly recommended.)

3 Likes

mind sharing the code?

i’d love to build around this

sure. I am working on something with it but def use the graphics however you want. (you would want to clean up the darkmode here - either delete anything where darkmode == 1 and delete just the if statements around == 0 or create a toggle like I did)

Summary
function draw_city()
  screen.aa(0)
  if darkmode == 1 then
    screen.level(15)
    screen.rect(1,1,128,64)
    screen.fill()
  end
  -- column 1
  if darkmode == 0 then
    screen.level(15)
  elseif darkmode == 1 then
    screen.level(0)
  end
  for i=16,40,4 do
    screen.rect(0, i, 10, 2)
    screen.fill()
  end
  --column 2
  for i=0,12,4 do
    screen.level(2)
    screen.rect(10, i, 10, 2)
    screen.fill()
  end
  for i=2,34,4 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(10, i, 10, 2)
    screen.fill()
  end
  for i=38,42,4 do
    screen.level(2)
    screen.rect(10, i, 10, 2)
    screen.fill()
  end
  if darkmode == 0 then
    screen.level(15)
  elseif darkmode == 1 then
    screen.level(0)
  end
  screen.rect(10, 46, 10, 2)
  screen.fill()
  if darkmode == 0 then
    screen.level(15)
  elseif darkmode == 1 then
    screen.level(0)
  end
  screen.rect(10, 50, 10, 10)
  screen.fill()
  --column 3
  for i=14,42,4 do
    screen.level(2)
    screen.rect(20, i, 10, 2)
    screen.fill()
  end
  for i=16,40,4 do
    screen.level(2)
    screen.rect(26, i, 4, 2)
    screen.fill()
  end
  for i=44,48,4 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(26, i, 4, 2)
    screen.fill()
  end
  if darkmode == 0 then
    screen.level(15)
  elseif darkmode == 1 then
    screen.level(0)
  end
  screen.rect(20, 46, 10, 2)
  screen.fill()
  if darkmode == 0 then
    screen.level(15)
  elseif darkmode == 1 then
    screen.level(0)
  end
  screen.rect(20, 50, 10, 10)
  screen.fill()
  
  --column 4
  screen.level(2)
  screen.rect(32, 8, 8, 2)
  screen.fill()
  for i=12,56,4 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(30, i, 2, 2)
    screen.fill()
  end
  for i=12,56,4 do
    screen.level(2)
    screen.rect(32, i, 8, 2)
    screen.fill()
  end
  for i=14,42,4 do
    screen.level(2)
    screen.rect(30, i, 2, 2)
    screen.fill()
  end
  for i=14,42,4 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(32, i, 8, 2)
    screen.fill()
  end
  for i=46,54,4 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(30, i, 10, 2)
    screen.fill()
  end
  if darkmode == 0 then
    screen.level(15)
  elseif darkmode == 1 then
    screen.level(0)
  end
  screen.rect(30, 58, 10, 2)
  screen.fill()
  --column 5
  for i=0,44,4 do
    screen.level(15)
    screen.rect(40, i, 8, 2)
    screen.fill()
  end
  for i=42,48,4 do
    screen.level(2)
    screen.rect(40, i, 8, 2)
    screen.fill()
  end
  if darkmode == 0 then
    screen.level(15)
  elseif darkmode == 1 then
    screen.level(0)
  end
  screen.rect(40, 48, 8, 12)
  screen.fill()
  --column 6
  for i=12,44,4 do
    screen.level(2)
    screen.rect(48, i, 10, 2)
    screen.fill()
  end
  screen.level(2)
  screen.rect(48, 42, 10, 2)
  screen.fill()
  for i=46,58,2 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(48, i, 10, 2)
    screen.fill()
  end
  --column 7
  for i=10,34,4 do
    screen.level(15)
    screen.rect(58, i, 4, 2)
    screen.fill()
  end
  for i=12,36,4 do
    screen.level(2)
    screen.rect(58, i, 4, 2)
    screen.fill()
  end
  screen.level(2)
  screen.rect(58, 38, 4, 8)
  screen.fill()
  for i=46,58,2 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(58, i, 4, 2)
    screen.fill()
  end
  --column 8
  for i=2,54,4 do
    screen.level(2)
    screen.rect(62, i, 20, 2)
    screen.fill()
  end
  for i=12,36,4 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(72, i, 20, 2)
    screen.fill()
  end
  for i=40,52,4 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(62, i, 30, 2)
    screen.fill()
  end
  for i=56,58,2 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(62, i, 30, 2)
    screen.fill()
  end
  --column 9
  for i=8,40,4 do
    screen.level(2)
    screen.rect(92, i, 4, 2)
    screen.fill()
  end
  
  for i=16,42,4 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(100, i, 2, 2)
    screen.fill()
  end
  for i=44,52,4 do
    screen.level(15)
    screen.rect(92, i, 10, 2)
    screen.fill()
  end
  for i=56,58,2 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(92, i, 10, 2)
    screen.fill()
  end
  for i=16,46,2 do
    screen.level(2)
    screen.rect(96, i, 4, 2)
    screen.fill()
  end
  for i=48,54,2 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(96, i, 4, 2)
    screen.fill()
  end
  --column 10
  for i=2,58,4 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(102, i, 10, 2)
    screen.fill()
  end
  for i=16,56,4 do
    screen.level(2)
    screen.rect(102, i, 10, 2)
    screen.fill()
  end
  --column 11
  for i=0,12,2 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(112, i, 12, 2)
    screen.fill()
  end
  for i=16,56,4 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(112, i, 12, 2)
    screen.fill()
  end
  for i=50,58,4 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(114, i, 10, 2)
    screen.fill()
  end
  --column 12
  for i=0,40,4 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(126, i, 2, 2)
    screen.fill()
  end
  for i=2,58,4 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(124, i, 4, 2)
    screen.fill()
  end
  for i=44,56,4 do
    if darkmode == 0 then
      screen.level(15)
    elseif darkmode == 1 then
      screen.level(0)
    end
    screen.rect(124, i, 4, 2)
    screen.fill()
  end
end
2 Likes

just read this interesting article…and had an idea…so just throwing this out here
(maybe @Justmat or @dan_derks)
:stuck_out_tongue:

if there was script that could read the RNA letters of virus genomes.

  • norns graphics of virus

  • RNA could determine MIDI events or manipulations of samples.

  • user could change the amount of RNA read at a time.

  • user could create RNA or edit genome?

1 Like

Waldorf Blofeld Sample Player Engine with its Mod Matrix.

The special thing about this is, with all the limitations of the synth, you have a mod matrix mixer with several channels, you were able to assign a certain velocity input to a certain channel.

Now with the 60mb ram limitations one had to come up with ideas wich lead to some of the best sample handling i every found in the dozens of samplers i owned from asr 10 asr x mpc and so on.

You could have a 1 velocity layer simple sample of say a Epiano.
Now you could set it up into lets say 4 velocity layers (channels) and make variations to each, defining what velo triggers what channel, adding white noise and attack to a hard hit, adding mellow attack and dampening to a soft hit, mixing in the attack sound of another sample, adding slight lfo etc etc.

This would totaly fit the norns imo. For everyones consideration who can code this.
The idea isnt a new Kontakt player for realism but a way to create very individualized sample sets within norns. Grid velocity would of course be the absolute topping but probably not really an option

2 Likes

i posted a bark-scale filterbank in supercollider here, if anyone is interested in this


also shows attaching an envelope follower to each band.

the filters on 296/296e always seemed a little narrow to me. dunno about the verbos version.

also, maybe worth mentioning that 296 doesn’t use bark scale exactly, but something of don’s own devising.

7 Likes