The easiest way I know of to update parameters in a function that’s already been forked is to use a global variable. Something like this, maybe?
import random
import scamp
# global variables
RHYTHM = [0.125, 0.25, 0.33, 0.5, 0.66, 1, 2, 0.75, 0.8]
NUMBER_LOOP_REPEATS = 2
NUMBER_ARTICULATIONS = 1
SEQ = [[60, 64, 67], [59, 62, 67]]
def loop_part_one(treble):
while True:
env = [0.25, 0.5, 0.75, 1]
for i in range(NUMBER_LOOP_REPEATS):
for s in SEQ:
for i in range(NUMBER_ARTICULATIONS):
treble.play_chord(s, random.choice(env), random.choice(RHYTHM))
scamp.wait(2)
s = scamp.Session()
treble = s.new_part("piano")
s.fork(loop_part_one, args = [treble])
s.wait(10)
NUMBER_ARTICULATIONS = 3
s.wait_forever()
If you want to be able to modify a global variable from the command line while the script is running, I might fork another function using the very handy fork_unsynchronized()
method which Marc recently mentioned on the forum—this new function will be responsible for checking for command line input and updating the variable accordingly:
import random
import scamp
# global variables
RHYTHM = [0.125, 0.25, 0.33, 0.5, 0.66, 1, 2, 0.75, 0.8]
NUMBER_LOOP_REPEATS = 1
NUMBER_ARTICULATIONS = 1
SEQ = [[60, 64, 67], [59, 62, 67]]
def loop_part_one(treble):
while True:
env = [0.25, 0.5, 0.75, 1]
for i in range(NUMBER_LOOP_REPEATS):
for s in SEQ:
for i in range(NUMBER_ARTICULATIONS):
treble.play_chord(s, random.choice(env), random.choice(RHYTHM))
scamp.wait(2)
def update_variable():
global NUMBER_ARTICULATIONS
while True:
print("Enter a new value for NUMBER_ARTICULATIONS when desired:")
val = input()
NUMBER_ARTICULATIONS = int(val)
s = scamp.Session()
treble = s.new_part("piano")
s.fork(loop_part_one, args = [treble])
s.fork_unsynchronized(update_variable)
s.wait_forever()
Sometimes you can run into some unexpected scenarios when multiple threads are either updating or reading from a global variable at the same time. For instance, maybe you only want an update to NUMBER_ARTICULATIONS
to take effect once a new loop starts. To do that you could use a lock:
import random
import scamp
import threading
# global variables
RHYTHM = [0.125, 0.25, 0.33, 0.5, 0.66, 1, 2, 0.75, 0.8]
NUMBER_LOOP_REPEATS = 1
NUMBER_ARTICULATIONS = 1
SEQ = [[60, 64, 67], [59, 62, 67]]
MY_LOCK = threading.Lock()
def loop_part_one(treble):
while True:
env = [0.25, 0.5, 0.75, 1]
with MY_LOCK:
for i in range(NUMBER_LOOP_REPEATS):
for s in SEQ:
for i in range(NUMBER_ARTICULATIONS):
treble.play_chord(s, random.choice(env), random.choice(RHYTHM))
scamp.wait(2)
def update_variable():
global NUMBER_ARTICULATIONS
while True:
print("Enter a new value for NUMBER_ARTICULATIONS when desired:")
val = input()
with MY_LOCK:
NUMBER_ARTICULATIONS = int(val)
s = scamp.Session()
treble = s.new_part("piano")
s.fork(loop_part_one, args = [treble])
s.fork_unsynchronized(update_variable)
s.wait_forever()
Does that help?