Trouble generating arc.array in lua

Official support for: loomer.co.uk
Post Reply New Topic
RELATED
PRODUCTS

Post

Howdy - wondering if anyone could help with this code? I've been able to output as a string, but getting a bad argument type error when trying to send an arc.array. I'm sure that I am doing something wrong, just looking for a few pointers. Thanks in advance!!


-- Define constants
local TOTAL_LENGTH = 512
local ROOT_NOTE = 60
local REST_NOTE = -1 -- or any other value you want to use for rest notes
local NOTE_RANGE_LOW = 36
local NOTE_RANGE_HIGH = 86
local OCTAVE = 12
local BAR_LENGTH = 16
local NUM_BARS = 16
local MAX_RUNS = 8
local MAX_MOTIFS = 4
local MOTIF_OCCURRENCE = 0.2 -- 20% chance of a motif occurring in a bar
local ARC_STEPS_PER_BEAT = 4 -- or whatever value you want to use

-- Define functions
local function random_interval()
return math.random(NOTE_RANGE_LOW, NOTE_RANGE_HIGH) - ROOT_NOTE
end

local function random_step_length()
return math.random(3, 8)
end

local function random_motif_step_length()
return math.random(3, 8)
end

local function random_motif_interval()
return math.random(-6, 6) * OCTAVE
end

local function transpose(note, interval, direction)
return note + interval * direction
end

function arc.new_array(size)
local t = {}
for i = 1, size do
t = 0
end
return t
end


-- Define valid note lookup table
local valid_notes = {}
for i = NOTE_RANGE_LOW, NOTE_RANGE_HIGH do
valid_notes = true
end

-- Register module
print("Registering module...")
if arc.module then
arc.module.name = "Sequence Generator"
arc.module.author = "Loomer"
arc.module.description = "Generates a random sequence of notes"
arc.module.version = "1.0"
arc.module.init = function()
-- Define outlets
print("Initializing outlets...")
arc.module.outlets = {
arc.Control("sequence")
}
end

arc.module.receive = function(inlet, object)
if type(object) == "boolean" and object == true then
print("Generating sequence...")
-- Initialize variables
local sequence = {}
local current_note = ROOT_NOTE
local current_bar = 1
local current_step = 1
local num_runs = 0
local num_motifs = 0
local arc_sequence = {}
local arc_sequence = {}

-- Loop to generate sequence
while #sequence < TOTAL_LENGTH do
-- Check if current step is the first step of a new bar
if (current_step - 1) % BAR_LENGTH == 0 then
current_bar = current_bar + 1
current_note = ROOT_NOTE
end

-- Decide whether to generate a run or motif
local generate_run = true
if num_runs >= MAX_RUNS then
generate_run = false
elseif num_motifs >= MAX_MOTIFS then
generate_run = true
else
generate_run = math.random() > MOTIF_OCCURRENCE
end

local direction = math.random(0, 1) == 0 and -1 or 1

-- Generate run or motif
local step_length = generate_run and random_step_length() or random_motif_step_length()
local interval = generate_run and random_interval() or random_motif_interval()

for i = 1, step_length do
local note = transpose(current_note, interval, direction)
note = note % 128 -- Ensure note is within range of 0 to 127
if valid_notes[note] and note ~= REST_NOTE then
table.insert(sequence, note)
end
current_note = current_note + OCTAVE
end

-- Increment step counter
current_step = current_step + 1

-- Check if we've exceeded the maximum number of runs/motifs
if current_bar > NUM_BARS then
break
end
end

-- Truncate sequence to 64 steps if it's longer
if #sequence > TOTAL_LENGTH then
for i = #sequence, TOTAL_LENGTH + 1, -1 do
sequence = nil
end
end

-- Set arc_sequence to the generated sequence
arc_sequence = sequence

-- Define reversed sequence as an empty table
local reversed_sequence = {}

-- If sequence is shorter than 64 steps, fill with the inverse sequence
if #arc_sequence < 64 then
local inverse_sequence = {}
for i = 1, #arc_sequence do
inverse_sequence = -1 * arc_sequence
end
for i = #arc_sequence + 1, 64 do
inverse_sequence = -1 * (arc_sequence[i - #arc_sequence] or 0) -- check if arc_sequence[i - #arc_sequence] exists before using it
end
arc_sequence = inverse_sequence
end

-- Create a new sequence by concatenating arc_sequence with its reverse
for i = 1, #arc_sequence do
reversed_sequence = arc_sequence
end
for i = #arc_sequence - 1, 1, -1 do
reversed_sequence[#reversed_sequence + 1] = arc_sequence
end

-- Send the sequence to the arc module
print("Sending the sequence to the arc module...")

local arc_sequence = arc.array()
for i = 1, #sequence do
sequence_array:insert(sequence)
end
arc.module.outlets[1]:send(sequence_array)

print("Sequence sent!")
end
end
end

Post

If anyone's got just a general couple of lines of script on how to send an arc array that's all I'd need and I can change it. Would be appreciated 😸

Post

Yes, no worries: I'll paste a minimal example reply shortly...
Architect, the modular MIDI toolkit, beta now available for macOS, Windows, and Linux.

Post

So this will output an array of the first few prime numbers when any event is received:

Code: Select all

function arc.module.receive(inlet, object) 
  local arr = arc.array.new()
  arr:insert(2)
  arr:insert(3)
  arr:insert(5)
  arc.module.outlets[1]:send(arr)
end
Architect, the modular MIDI toolkit, beta now available for macOS, Windows, and Linux.

Post

(If you are having trouble applying this to your script, let me know, and if you talk me through what you want the script to do, I'm happy to debug it for you.)
Architect, the modular MIDI toolkit, beta now available for macOS, Windows, and Linux.

Post

Thanks for your response! Working now :)

Post Reply

Return to “Loomer”