For the sole purpose of learning some basic skills I’m trying to swap the Polysub engine used in the Earthsea script with Passersby.
I’ve already done it with fugu without any problem, just by changing the engine references. Did the same with earthsea, but the script doesn’t start

#16 local passersby = include 'passersby/lib/passersby_engine'
#34 engine.name = 'Passersby'
#62 passersby:params()

seem to be the only three times the engine is recalled and i just swapped the engine name and included the right directory.
Is there something else that needs to be done?

Here’s the earthsea script for reference
https://raw.githubusercontent.com/tehn/ash/master/earthsea.lua

:slight_smile:

Check the error output in Maiden - it looks like passersby_engine doesn’t have a function called params, but if you try passersby:add_params() instead it might work.

Not sure this will help your script not starting, but if you haven’t already you might want to swap the syntax for note generation… something like this:

Polysub:
engine.start(e.id, getHzET(note))

Passersby:
engine.noteOn(e.id, getHzET(note), vel)

Thank you! It was easier than I thought! The noteOn and noteOff params were different from the polysub start and stop! Now it works!

Thanks also to @nattog !!
:slight_smile:

2 Likes

I’ve done the basic Norns tutorials and I feel I am ready to try and tackle some sound processing, as opposed to just playing samples.

Is there an example file somewhere that just adds a single effect to incoming audio, like adds distortion to whatever is coming via Input A.

Thanks a lot :slight_smile:

here’s one that just applies gain:

1 Like

Perfect!
Thanks a lot, I will give it a shot.

Let’s say I didn’t ask here, would I have been able to find that somewhere?

I’m looking for the levels.lua example, if anyone has it I would love to see how I can grab incoming audio signal.

Edit: Found it.

After the basic earthsea-passersby, the next exercise I’m doing is adding the earthsea keyboard and pattern to the whole passersby-tunnel script. Everything works fine except for the pattern record (I can record, but I can’t play the pattern).
Here’s the maiden error output that is displayed after pressing the pattern rec button to play it and which I’m not skilled enough to understand.
I think it has something to do with the recall of this pattern.time.lua file, but I don’t understand what to do
lua: /home/we/norns/lua/lib/pattern_time.lua:78: attempt to call a nil value (field ‘process’)

stack traceback:

/home/we/norns/lua/lib/pattern_time.lua:78: in function 'pattern_time.start'

/home/we/dust/code/ash/passtunnearth.lua:649: in field 'key'

/home/we/norns/lua/core/grid.lua:183: in function </home/we/norns/lua/core/grid.lua:174>

lua: /home/we/norns/lua/lib/pattern_time.lua:78: attempt to call a nil value (field 'process')

stack traceback:

/home/we/norns/lua/lib/pattern_time.lua:78: in function 'pattern_time.start'

/home/we/dust/code/ash/passtunnearth.lua:649: in field 'key'

/home/we/norns/lua/core/grid.lua:183: in function </home/we/norns/lua/core/grid.lua:174>

thank you for your time :smiley:

Is pattern time in scope?

Yes, I think i put it in the global scope,

local MusicUtil = require "musicutil"
local UI = require "ui"
local Graph = require "graph"
local EnvGraph = require "envgraph"
local Passersby = require "passersby/lib/passersby_engine"

local tab = require 'tabutil'
local pattern_time = require 'pattern_time'
local g = grid.connect()
local mode_transpose = 0
local root = { x=5, y=5 }
local trans = { x=5, y=5 }
local lit = {}
local screen_framerate = 15
local screen_refresh_metro

local ripple_repeat_rate = 1 / 0.3 / screen_framerate
local ripple_decay_rate = 1 / 0.5 / screen_framerate
local ripple_growth_rate = 1 / 0.02 / screen_framerate
local screen_notes = {}



local tn = include('tunnels/lib/tunnel')

local SCREEN_FRAMERATE = 15
local screen_refresh_metro
local screen_dirty = true

local midi_in_device
local active_notes = {}

local pages
local tabs
local tab_titles = {{"Wave", "FM"}, {"Env", "Reverb"}, {"LFO", "Targets"}, {"Fate"}, {"Tunnels"}}

local input_indicator_active = false
local wave_table = {}
local wave = {}
local wave_graph
local SUB_SAMPLING = 4
local fm1_dial
local fm2_dial
local env_graph
local env_status = {}
local env_status_metro
local spring_path = {}
local reverb_slider
local lfo_graph
local dice_throw_vel = 0
local dice_throw_progress = 0
local dice_thrown = false
local dice_need_update = false
local dice = {}
local drift_dial

local timbre = 0
local wave_shape = {actual = 0, modu = 0, dirty = true}
local wave_folds = {actual = 0, modu = 0, dirty = true}
local fm1_amount = {actual = 0, modu = 0, dirty = true}
local fm2_amount = {actual = 0, modu = 0, dirty = true}
local attack = {actual = 0, modu = 0, dirty = true}
local peak = {actual = 0, modu = 1, dirty = true}
local decay = {actual = 0, modu = 0, dirty = true}
local reverb_mix = {actual = 0, modu = 0, dirty = true}
local lfo_shape = {dirty = true}
local lfo_freq = {dirty = true}
local lfo_destinations = {dirty = true}
local drift = {actual = 0, dirty = true}

engine.name = "Passersby"

here’s the section that controls grid input and pattern
– GRID input

pat = pattern_time.new()
  pat.process = grid_note_trans
local MAX_NUM_VOICES = 16


function g.key(x, y, z)
  if x == 1 then
    if z == 1 then
      if y == 1 and pat.rec == 0 then
        mode_transpose = 0
        trans.x = 5
        trans.y = 5
        pat:stop()
        engine.noteOffAll()
        pat:clear()
        pat:rec_start()
      elseif y == 1 and pat.rec == 1 then
        pat:rec_stop()
        if pat.count > 0 then
          root.x = pat.event[1].x
          root.y = pat.event[1].y
          trans.x = root.x
          trans.y = root.y
          pat:start()
        end
      elseif y == 2 and pat.play == 0 and pat.count > 0 then
        if pat.rec == 1 then
          pat:rec_stop()
        end
        pat:start()
      elseif y == 2 and pat.play == 1 then
        pat:stop()
        engine.noteOffAll()
        stop_all_screen_notes()
        nvoices = 0
        lit = {}
      elseif y == 8 then
        mode_transpose = 1 - mode_transpose
      end
    end
  else
    if mode_transpose == 0 then
      local e = {}
      e.id = x*8 + y
      e.x = x
      e.y = y
      e.state = z
      pat:watch(e)
      grid_note(e)
    else
      trans.x = x
      trans.y = y
    end
  end
  gridredraw()
end


function grid_note(e)
  local note = ((7-e.y)*5) + e.x
  if e.state > 0 then
    if nvoices < MAX_NUM_VOICES then
      --engine.start(id, getHz(x, y-1))
      --print("grid > "..id.." "..note)
      engine.noteOn(e.id, getHzET(note), vel)
     
      lit[e.id] = {}
      lit[e.id].x = e.x
      lit[e.id].y = e.y
      nvoices = nvoices + 1
    end
  else
    if lit[e.id] ~= nil then
      engine.noteOff(e.id)
     
      lit[e.id] = nil
      nvoices = nvoices - 1
    end
  end
  gridredraw()
end

function grid_note_trans(e)
  local note = ((7-e.y+(root.y-trans.y))*5) + e.x + (trans.x-root.x)
  if e.state > 0 then
    if nvoices < MAX_NUM_VOICES then
      --engine.start(id, getHz(x, y-1))
      --print("grid > "..id.." "..note)
      engine.noteOn(e.id, getHzET(note))
      start_screen_note(note)
      lit[e.id] = {}
      lit[e.id].x = e.x + trans.x - root.x
      lit[e.id].y = e.y + trans.y - root.y
      nvoices = nvoices + 1
    end
  else
    engine.noteOff(e.id)
    stop_screen_note(note)
    lit[e.id] = nil
    nvoices = nvoices - 1
  end
  gridredraw()
end

function gridredraw()
  g:all(0)
  g:led(1,1,2 + pat.rec * 10)
  g:led(1,2,2 + pat.play * 10)
  g:led(1,8,2 + mode_transpose * 10)

  if mode_transpose == 1 then g:led(trans.x, trans.y, 4) end
  for i,e in pairs(lit) do
    g:led(e.x, e.y,15)
  end

  g:refresh()
end

function note_on(note, vel)
  if nvoices < MAX_NUM_VOICES then
    --engine.start(id, getHz(x, y-1))
    engine.start(note, getHzET(note))
    start_screen_note(note)
    nvoices = nvoices + 1
  end
end

function note_off(note, vel)
  engine.stop(note)
  stop_screen_note(note)
  nvoices = nvoices - 1
end


function midi_event(data)
  if #data == 0 then return end
  local msg = midi.to_msg(data)

  -- Note off
  if msg.type == "note_off" then
    note_off(msg.note)

    -- Note on
  elseif msg.type == "note_on" then
    note_on(msg.note, msg.vel / 127)
end
end
function cleanup()
  stop_all_screen_notes()
  pat:stop()
  pat = nil
end

I would focus on this - I’m not sure where grid_note_trans is defined, but your instance of pattern_time thinks it’s nil.

Update: I see grid_note_trans is defined in the earthsea script. You would have to copy that entire function from earthsea, but then that function also references other things that are scoped to earthsea, so you’re going to run into more errors with that and would have to figure out how to copy those things also.

I think I copied the entire grid_note_trans function from earthsea, which is defined later in my script and I think all the variables scoped in the earthsea script should be in my global scope too.
Not sure I did all the right things though, it’s the first time I face so many variables

My guess is that at the time this is evaluated: pat.process = grid_note_trans

grid_note_trans is nil because it is defined further down in your script. Try moving the grid_note_trans function above that line, or moving the code that sets pat and pat.process into the init method

I tried it, but the same error displays.
Interestingly, the pattern command that the script is unable to understand is pat:start, while it understands perfectly pat:rec

pattern rec start

count 6

start pattern

lua: /home/we/norns/lua/lib/pattern_time.lua:78: attempt to call a nil value (field 'process')

stack traceback:

/home/we/norns/lua/lib/pattern_time.lua:78: in function 'pattern_time.start'

/home/we/dust/code/ash/passtunnearth.lua:674: in field 'key'

/home/we/norns/lua/core/grid.lua:183: in function </home/we/norns/lua/core/grid.lua:174>

If it helps I did some various combinations of earthsea with some other engines like passerby before norns 2.0. I haven’t made changes to make them compatible with the current version, but if you want to check things out for your reference:

https://gist.github.com/j-flee

1 Like

Thank you, I’ll check them out!

i actually forgot where i put it and googles “norns passthru” :slight_smile:

but the real answer is - not really, and that’s definitely a hole with the documentation. (getting people started with the SC side of things.)

1 Like

Is it possible to take a screencapture on the norns?

and here’s my image magick trick:

magick convert $1.png -gamma 1.25 -filter point -resize 400% -gravity center -background black -extent 120% $1-m.png
6 Likes

Perfect thanks :slight_smile: I started a series of basic tutorials and I want to augment it with screenshots.

7 Likes