Hi SCAMPsters! Just a quick question about the MIDI flow within this script I’m using. Ive recently been building on my collection of compositional tools when I came across the isorhythm script built by Marc Evanstein using SCAMP…
To summarise, I have midi messages being sent from my DAW (Reaper) into the script, the script then takes these messages and makes a list of 6 midi notes which then get sent to the “do_isorhythm” function that is being forked later on in the script. The problem is, despite defining the list and inputting it into the “args=” of the “do_isorhythm” fork it just isn’t being registered.
Im assume it could be a few things but my main guess is the timing of the script and that the midi information isn’t being passed to the function in time/sync, here’s the code:
from scamp import *
from collections import namedtuple
import datetime
from itertools import cycle
import random
from random import randint
USE_PLAY_NOTE=False
s = Session()
t = Session(tempo=140)
inst_1 = s.new_midi_part("melo-1", 0)
class Manipulator:
def __init__(self):
self.session = Session()
self.session.print_available_midi_output_devices()
self.session.print_available_midi_input_devices()
try:
self.piano = self.session.new_midi_part("piano", midi_output_device=0, num_channels=8) # Scamp to QSynth
except:
print("Failed to open MidiLoop Port for output")
self.midi_messages = [] # List to store MIDI pitch values
self.message_count = 0 # Counter for MIDI messages
self.count_started = False # Flag to track if the count has started
def midi_callback(self, midi_message):
code, pitch, volume = midi_message
if pitch == 0 and volume > 0: # Start the count when MIDI message "0" is received
self.count_started = True
if self.count_started:
if volume > 0: # Only append the pitch value if it's an "on" message
self.midi_messages.append(pitch) # Append the pitch value to the list
self.message_count += 1
if self.message_count == 4:
# Insert "None" randomly into the list at two random positions
for _ in range(2):
index = random.randint(0, len(self.midi_messages))
self.midi_messages.insert(index, None)
# Print the captured MIDI messages in the desired format
print("Captured MIDI messages:")
print(self.midi_messages)
# Reset counter and clear the list
self.message_count = 0
self.midi_messages.clear()
if volume > 0: # This is an on-event
self.onTime = datetime.datetime.now()
self.note = Note(pitch, volume, self.onTime.timestamp())
else:
self.offTime = datetime.datetime.now()
delta = self.offTime - self.onTime
self.note.duration = float(delta.total_seconds())
# Eventually do something with the note here
if USE_PLAY_NOTE:
self.piano.play_note(self.note.pitch, .8, self.note.duration)
else:
noteReference = self.piano.start_note(self.note.pitch, .8)
wait(self.note.duration)
noteReference.end()
def Run(self):
def do_isorhythm(inst_1, color, talea, voluminor=(1.0,)):
for pitch, volume, dur in zip(cycle(color), cycle(voluminor), cycle(talea)):
inst_1.play_note(pitch, volume, dur)
try:
self.session.register_midi_listener(1, self.midi_callback) #[Port 4]: Input from Virtual Keyboard
except:
print("Failed to open MidiLoop Port for input")
#self.session.wait_forever()
s = Session()
t = Session(tempo=140)
global_midi = self.midi_messages
# Call do_isorhythm within Run
fork(do_isorhythm, args=(inst_1, [64, 62, None, 65, 67, None, 62],
[1.0, 0.5, 0.75, 0.25, 1.0], [0.5, 0.7, 0.3]))
fork(do_isorhythm, args=(inst_1, [None, 64, 67, 69, None],
[2.0, 0.5, 1.0], [0.3, 0.5, 0.4, 0.6, 0.9, 0.6, 0.4]))
m = Manipulator()
m.Run()
wait_forever()
Currently, the fork function looks like this:
fork(do_isorhythm, args=(inst_1, [64, 62, None, 65, 67, None, 62],
[1.0, 0.5, 0.75, 0.25, 1.0], [0.5, 0.7, 0.3]))
fork(do_isorhythm, args=(inst_1, [None, 64, 67, 69, None],
[2.0, 0.5, 1.0], [0.3, 0.5, 0.4, 0.6, 0.9, 0.6, 0.4]))
I’m trying to make it work like this, but having problems:
fork(do_isorhythm, args=(inst_1, global_midi,
[1.0, 0.5, 0.75, 0.25, 1.0], [0.5, 0.7, 0.3]))
fork(do_isorhythm, args=(inst_1, global_midi,
[2.0, 0.5, 1.0], [0.3, 0.5, 0.4, 0.6, 0.9, 0.6, 0.4]))
This way my live midi input gets sent into the isorhythm function and then outputs it back into my DAW for later processing, any insight into how I can achieve this??
Im new here so please do forgive me if my query hasn’t been formatted to this forum’s standards… any help/guidance is much appreciated!!
Thanks in advance <3