from scamp import *
s = Session()
s.tempo = 65
# user input instrument and its information format dict
instrument_and_infor_dict = {"guitar": [[45, 52, 59, 57, 60], [0.9, 0.6, 0.8, 0.5, 0.8], 0.5],
"piano": [[45, 52, 59, 57, 60], [0.9, 0.6, 0.8, 0.5, 0.8], 0.5]}
instrument_objects = [] # list to collect instrument_object that created by creat_instrument_object_from_dict for fork function
play = [] # collect soundtrack to fork
# the next step
def creat_instrument_object_from_dict(instrument_and_infor_dict):
for instruments, instruments_info in instrument_and_infor_dict.items():
instrument_name = []
instrument_name.append(instruments)
# get the name of the instrument and use it to create a instrument object
for i in range(len(instrument_name)):
instru = instrument_name[i]
print(instru)
instru = s.new_part(instru)
instrument_objects.append(instru)
def play_instruments(instrument_and_infor_dict):
# get the information of the instrument and use the play method to play it
for instruments, instruments_info in instrument_and_infor_dict.items():
pitchs = instruments_info[0]
volumes = instruments_info[1]
note_length = instruments_info[2]
for i in range(len(instrument_objects)):
for p, v in zip(pitchs, volumes):
# I define a instrument play notes as a soundtrack and collect it into play for the next :fork
soundtrack = instrument_objects[i].play_note(p, v, note_length)
play.append(soundtrack)
creat_instrument_object_from_dict(instrument_and_infor_dict)
play_instruments(instrument_and_infor_dict)
# to here everything is fine, but if I intend to fork the soundtracks in play it goes wrong,what should I do to fork the
# soundtrack in the play to make them sound at the same time.
for i in range(len(play)):
s.fork(play[i])
I stuck here for hours ,I got no clue, can you help me?
Hi @yison ,
I reworked your code a bit. I hope this is what you were after.
If I understand correctly, s.fork()
is for forking functions so you need to build a function that will take scamp instruments and note information as arguments.
So, typically I make some type of play_notes
function that takes an_instrument_list
and note_data_list
as arguments and then does the playing within the function.
So it would look like
s.fork(play_notes, (an_instrument_list, note_data_list))
When using forks, important to add s.wait_for_children_to_finish()
at the end so that the script waits until all of the forks end before finishing.
Neil
from scamp import *
s = Session()
s.tempo = 65
# user input instrument and its information format dict
info = [[[45, 52, 59, 57, 60], [0.9, 0.6, 0.8, 0.5, 0.8], 0.5],
[[45, 52, 59, 57, 60], [0.9, 0.6, 0.8, 0.5, 0.8], 0.5]]
instrument_names = ['guitar', 'piano']
instruments = []
for inst in instrument_names:
x = s.new_part(inst)
instruments.append(x)
print('instruments:', instruments)
def instrument_player(instrument, info):
print('instrument:', instrument)
pitches = info[0]
volumes = info[1]
note_length = info[2]
iter_list = list(zip(pitches, volumes))
print('iter_list:', iter_list)
for p, v in iter_list:
print('p, v', p, v)
instrument.play_note(p, v, note_length)
for instrument, inf in zip(instruments, info):
print(inf)
print(instrument)
s.fork(instrument_player, (instrument, inf))
s.wait_for_children_to_finish()
Thanks for chiming in, Neil! Nice explanation of how to approach fork in these kinds of situations
that’s really helpful, Thank you. you make things easier.
I got confused here, the result seemd to be [[45, 52, 59, 57, 60], [0.9, 0.6, 0.8, 0.5, 0.8], 0.5], but when you print the result is [45, 52, 59, 57, 60], why was that?
There’s a little confusion there, since the variable name info is being used in multiple places for different things, and sometimes the local name masks the global name. If you change a few variable names, it’s maybe a little clearer:
from scamp import *
s = Session()
s.tempo = 65
# user input instrument and its information format dict
all_parts_info = [
[[45, 52, 59, 57, 60], [0.9, 0.6, 0.8, 0.5, 0.8], 0.5],
[[49, 52, 59, 57, 62], [0.9, 0.6, 0.8, 0.5, 0.8], 0.5]
]
instrument_names = ['guitar', 'piano']
instruments = []
for inst in instrument_names:
x = s.new_part(inst)
instruments.append(x)
print('instruments:', instruments)
def instrument_player(instrument, part_info):
print('instrument:', instrument)
pitches = part_info[0]
volumes = part_info[1]
note_length = part_info[2]
iter_list = list(zip(pitches, volumes))
print('iter_list:', iter_list)
for p, v in iter_list:
print('p, v', p, v)
instrument.play_note(p, v, note_length)
for instrument, this_part_info in zip(instruments, all_parts_info):
print(this_part_info)
print(instrument)
s.fork(instrument_player, (instrument, this_part_info))
s.wait_for_children_to_finish()
Thank you for your explaination. That’s helpful.
good fix - a bad habit I still have to break
Very easy habit to fall into! Coming up with names is hard.