class MainWidget2(BaseWidget): def __init__(self): super(MainWidget2, self).__init__() # create a clock and a tempo map self.clock = Clock() self.tempo_map = SimpleTempoMap(120) # and text to display our status self.label = topleft_label() self.add_widget(self.label) def on_key_down(self, keycode, modifiers): if keycode[1] == 'c': self.clock.toggle() def on_update(self): time = self.clock.get_time() tick = self.tempo_map.time_to_tick(time) bpm = self.tempo_map.get_tempo() self.label.text = 'time:{:.2f}\n'.format(time) self.label.text += tick_str(tick) + '\n' self.label.text += 'bpm:{}\n'.format(bpm) self.label.text += 'c: toggle clock\n'
def __init__(self): super(MainWidget, self).__init__() self.audio = Audio(2) self.synth = Synth('../data/FluidR3_GM.sf2') # create TempoMap, AudioScheduler self.tempo_map = SimpleTempoMap(120) self.sched = AudioScheduler(self.tempo_map) # connect scheduler into audio system self.audio.set_generator(self.sched) self.sched.set_generator(self.synth) # create the metronome: self.metro = Metronome(self.sched, self.synth) # Note Sequencers self.seq1 = NoteSequencer(self.sched, self.synth, 1, (0, 65), kYesterday, False) self.seq2 = NoteSequencer(self.sched, self.synth, 2, (0, 52), kSomewhere, True) # and text to display our status self.label = topleft_label() self.add_widget(self.label)
def __init__(self, norm, sandbox, mixer, client, client_id, block_handler, tempo=60): self.norm = norm self.module_name = 'TempoCursor' self.sandbox = sandbox self.mixer = mixer self.client = client self.cid = client_id self.block_handler = block_handler self.tempo = tempo self.clock = Clock() self.tempo_map = SimpleTempoMap(bpm=self.tempo) self.touch_points = {} self.cursors = AnimGroup() self.sandbox.add(self.cursors) self.gui = CursorGUI(norm, pos=self.norm.nt((20, 300)), beat_callback=self.update_touch_points) self.delete_mode = {}
def __init__(self): super(MainWidget2, self).__init__() # create a clock and a tempo map self.clock = Clock() self.tempo_map = SimpleTempoMap(120) # and text to display our status self.label = topleft_label() self.add_widget(self.label)
def __init__(self, other_members, tempo, bars, divs, inst_set): super(Session, self).__init__() self.tempo = tempo self.bars = bars self.divs = divs self.inst_set = inst_set spb = 60. / tempo beats = bars * 4 self.seconds = spb * beats self.clock = Clock() self.temp_map = SimpleTempoMap(bpm=tempo) self.sched = Scheduler(self.clock, self.temp_map) # self.players = players self.IM = InstrumentManager(self.sched) self.add(self.IM) ### NEW CODE ### self.pattern_list = PatternList(self.bars, self.tempo, self.inst_set) self.add(self.pattern_list) track = Track(num_lanes, self.bars, self.tempo) track.position.y = Window.height * 0.025 controller = InstrumentKeyboard(default_keycodes, lock_in_keycode) self.player = Player(controller, track, inst_set) self.player.position.x = Window.width - player_size[0] - 20 self.add(self.player) self.vplayers = [] self.add_band_members(other_members) self.IM.add(self.player.instrument) self.clock.offset = self.seconds - spb self.paused = True self.start()
def __init__(self, notes, bank=0, preset=0, loop=False, simon_says=False, bass_puzzle=False): super().__init__() self.audio = Audio(2) self.synth = Synth("./data/FluidR3_GM.sf2") self.tempo_map = SimpleTempoMap(120) self.sched = AudioScheduler(self.tempo_map) self.sched.set_generator(self.synth) self.audio.set_generator(self.sched) self.notes = notes self.bank = bank self.preset = preset self.loop = loop self.simon_says = simon_says self.bass_puzzle = bass_puzzle self.note_seq = NoteSequencer( sched=self.sched, synth=self.synth, channel=1, program=(self.bank, self.preset), notes=self.notes, loop=self.loop, )
class MainWidget(BaseWidget): def __init__(self): super(MainWidget, self).__init__() self.audio = Audio(2) self.synth = Synth('../data/FluidR3_GM.sf2') # create TempoMap, AudioScheduler self.tempo_map = SimpleTempoMap(120) self.sched = AudioScheduler(self.tempo_map) # connect scheduler into audio system self.audio.set_generator(self.sched) self.sched.set_generator(self.synth) # create the metronome: self.metro = Metronome(self.sched, self.synth) # Note Sequencers self.seq1 = NoteSequencer(self.sched, self.synth, 1, (0, 65), kYesterday, False) self.seq2 = NoteSequencer(self.sched, self.synth, 2, (0, 52), kSomewhere, True) # and text to display our status self.label = topleft_label() self.add_widget(self.label) def on_key_down(self, keycode, modifiers): obj = lookup(keycode[1], 'mas', (self.metro, self.seq1, self.seq2)) if obj is not None: obj.toggle() bpm_adj = lookup(keycode[1], ('up', 'down'), (10, -10)) if bpm_adj: new_tempo = self.tempo_map.get_tempo() + bpm_adj self.tempo_map.set_tempo(new_tempo, self.sched.get_time()) def on_update(self): self.audio.on_update() self.label.text = self.sched.now_str() + '\n' self.label.text += 'tempo:%d\n' % self.tempo_map.get_tempo() self.label.text += 'm: toggle Metronome\n' self.label.text += 'a: toggle Sequence 1\n' self.label.text += 's: toggle Sequence 2\n' self.label.text += 'up/down: change speed\n'
class MainWidget4(BaseWidget): def __init__(self): super(MainWidget4, self).__init__() self.audio = Audio(2) self.synth = Synth('../data/FluidR3_GM.sf2') self.audio.set_generator(self.synth) # create clock, tempo_map, scheduler self.clock = Clock() self.tempo_map = SimpleTempoMap(120) self.sched = Scheduler(self.clock, self.tempo_map) # create the metronome: self.metro = Metronome(self.sched, self.synth) # and text to display our status self.label = topleft_label() self.add_widget(self.label) def on_key_down(self, keycode, modifiers): if keycode[1] == 'c': self.clock.toggle() if keycode[1] == 'm': self.metro.toggle() bpm_adj = lookup(keycode[1], ('up', 'down'), (10, -10)) if bpm_adj: new_tempo = self.tempo_map.get_tempo() + bpm_adj self.tempo_map.set_tempo(new_tempo, self.sched.get_time()) def on_update(self): # scheduler and audio get poked every frame self.sched.on_update() self.audio.on_update() bpm = self.tempo_map.get_tempo() self.label.text = self.sched.now_str() + '\n' self.label.text += 'Metronome:' + ("ON" if self.metro.playing else "OFF") + '\n' self.label.text += 'tempo:{}\n'.format(bpm) self.label.text += 'm: toggle Metronome\n' self.label.text += 'up/down: change speed\n'
def __init__(self): super(MainWidget4, self).__init__() self.audio = Audio(2) self.synth = Synth('../data/FluidR3_GM.sf2') self.audio.set_generator(self.synth) # create clock, tempo_map, scheduler self.clock = Clock() self.tempo_map = SimpleTempoMap(120) self.sched = Scheduler(self.clock, self.tempo_map) # create the metronome: self.metro = Metronome(self.sched, self.synth) # and text to display our status self.label = topleft_label() self.add_widget(self.label)
class MainWidget1(BaseWidget) : def __init__(self): super(MainWidget1, self).__init__() self.audio = Audio(2) self.synth = Synth('../data/FluidR3_GM.sf2') # create TempoMap, AudioScheduler self.tempo_map = SimpleTempoMap(120) self.sched = AudioScheduler(self.tempo_map) # connect scheduler into audio system self.audio.set_generator(self.sched) self.sched.set_generator(self.synth) # create the metronome: self.metro = Metronome(self.sched, self.synth) # create the arpeggiator: self.arpeg = Arpeggiator(self.sched, self.synth, channel = 1, program = (0,0) ) # and text to display our status self.label = topleft_label() self.add_widget(self.label) def on_key_down(self, keycode, modifiers): if keycode[1] == 'm': self.metro.toggle() if keycode[1] == 'a': self.arpeg.start() pitches = lookup(keycode[1], 'qwe', ((60, 64, 67, 72), (55, 59, 62, 65, 67, 71), (60, 65, 69))) if pitches: self.arpeg.set_pitches(pitches) rhythm = lookup(keycode[1], 'uiop', ((120, 1), (160, 1), (240, 0.75), (480, 0.25))) if rhythm: self.arpeg.set_rhythm(*rhythm) direction = lookup(keycode[1], '123', ('up', 'down', 'updown')) if direction: self.arpeg.set_direction(direction) def on_key_up(self, keycode): if keycode[1] == 'a': self.arpeg.stop() def on_update(self) : self.audio.on_update() self.label.text = self.sched.now_str() + '\n' self.label.text += 'tempo:%d\n' % self.tempo_map.get_tempo() self.label.text += 'm: toggle Metronome\n' self.label.text += 'a: Enable Arpeggiator\n' self.label.text += 'q w e: Changes pitches\n' self.label.text += 'u i o p: Change Rhythm\n' self.label.text += '1 2 3: Change Direction\n'
def __init__(self): super(MainWidget5, self).__init__() self.audio = Audio(2) self.synth = Synth('../data/FluidR3_GM.sf2') # create TempoMap, AudioScheduler self.tempo_map = SimpleTempoMap(120) self.sched = AudioScheduler(self.tempo_map) # connect scheduler into audio system self.audio.set_generator(self.sched) self.sched.set_generator(self.synth) # create the metronome: self.metro = Metronome(self.sched, self.synth) # and text to display our status self.label = topleft_label() self.add_widget(self.label)
class MainWidget5(BaseWidget): def __init__(self): super(MainWidget5, self).__init__() self.audio = Audio(2) self.synth = Synth('../data/FluidR3_GM.sf2') # create TempoMap, AudioScheduler self.tempo_map = SimpleTempoMap(120) self.sched = AudioScheduler(self.tempo_map) # connect scheduler into audio system self.audio.set_generator(self.sched) self.sched.set_generator(self.synth) # create the metronome: self.metro = Metronome(self.sched, self.synth) # and text to display our status self.label = topleft_label() self.add_widget(self.label) def on_key_down(self, keycode, modifiers): if keycode[1] == 'm': self.metro.toggle() bpm_adj = lookup(keycode[1], ('up', 'down'), (10, -10)) if bpm_adj: new_tempo = self.tempo_map.get_tempo() + bpm_adj self.tempo_map.set_tempo(new_tempo, self.sched.get_time()) def on_update(self): self.audio.on_update() bpm = self.tempo_map.get_tempo() self.label.text = self.sched.now_str() + '\n' self.label.text += 'tempo:{}\n'.format(bpm) self.label.text += 'm: toggle Metronome\n' self.label.text += 'up/down: change speed\n'
def __init__(self): super(MainWidget3, self).__init__() # create a clock and TempoMap self.clock = Clock() self.tempo = SimpleTempoMap(120) # create a Scheduler self.sched = Scheduler(self.clock, self.tempo) # and text to display our status self.label = topleft_label() self.add_widget(self.label) # to see accumulated output: self.output_text = ''
def __init__(self): super(MainWidget2, self).__init__() self.audio = Audio(2) self.synth = Synth('../data/FluidR3_GM.sf2') # create TempoMap, AudioScheduler self.tempo_map = SimpleTempoMap(120) self.sched = AudioScheduler(self.tempo_map) # connect scheduler into audio system self.audio.set_generator(self.sched) self.sched.set_generator(self.synth) # create the metronome: self.metro = Metronome(self.sched, self.synth) # create the arpeggiator: self.arpeg = Arpeggiator(self.sched, self.synth, channel = 1, program = (0,0) ) self.arpeg.set_direction('updown') #size of the notes sent to the arpeggiator self.arpegSize = 3 #all of the notes this program can make. However, only self.arpegSize notes are sent to the arpegiator at a time self.allNotes = [50, 53, 55, 56, 57, 60, 62, 65, 67, 68, 69, 72, 74] self.lastPitchIndex = None self.lastPulseIndex = None self.noteLengths = [240, 210, 180, 150, 120, 90, 60] self.articulation = .75 # and text to display our status self.label = topleft_label() self.add_widget(self.label) # and text to display our status self.label = topleft_label() self.add_widget(self.label) self.objects = AnimGroup() self.canvas.add(self.objects) self.add_lines()
def __init__(self): super(MainWidget, self).__init__() self.writer = AudioWriter('song') self.audio = Audio(2, self.writer.add_audio) self.synth = Synth('../data/FluidR3_GM.sf2') # create TempoMap, AudioScheduler self.tempo_map = SimpleTempoMap(95*2) self.sched = AudioScheduler(self.tempo_map) # connect scheduler into audio system self.audio.set_generator(self.sched) self.sched.set_generator(self.synth) # create the metronome: self.metro = Metronome(self.sched, self.synth) # variables to store options self.transposition = 0 self.style = None self.melody = None self.chords = None self.chord_option = None self.perc = None self.perc_option = None # variables to store screen options self.style_selection = StyleSelection(self.update_style_screen) # screen index 0 self.key_selection = KeySelection(self.update_key_screen) # screen index 1 self.chord_selection = None # screen index 2 self.perc_selection = None # screen index 3 self.melody_selection = None # screen index 4 self.active_screen = self.style_selection self.screen_index = 0 self.add_widget(self.active_screen)
def __init__(self): super(MainWidget, self).__init__() self.audio = Audio(2, input_func=self.receive_audio, num_input_channels=1) self.mixer = Mixer() self.audio.set_generator(self.mixer) self.pitch = PitchDetector() self.recorder = VoiceAudioWriter('data') self.info = topleft_label() self.add_widget(self.info) self.anim_group = AnimGroup() self.mic_meter = MeterDisplay((50, 25), 150, (-96, 0), (.1, .9, .3)) self.mic_graph = GraphDisplay((110, 25), 150, 300, (-96, 0), (.1, .9, .3)) self.pitch_meter = MeterDisplay((50, 200), 150, (30, 90), (.9, .1, .3)) self.pitch_graph = GraphDisplay((110, 200), 150, 300, (30, 90), (.9, .1, .3)) self.canvas.add(self.mic_meter) self.canvas.add(self.mic_graph) self.canvas.add(self.pitch_meter) self.canvas.add(self.pitch_graph) # Record button self.record_button = InteractiveImage() self.record_button.source = "../data/mic.png" self.record_button.x = 400 self.record_button.y = 400 self.record_button.size = (100, 100) self.record_button.set_callback(self.init_recording) self.add_widget(self.record_button) # Play button self.play_button = InteractiveImage() self.play_button.source = "../data/play.png" self.play_button.x = 600 self.play_button.y = 400 self.play_button.size = (100, 100) self.play_button.set_callback(self.play_recording) self.add_widget(self.play_button) self.canvas.add(self.anim_group) self.onset_disp = None self.onset_x = 0 self.cur_pitch = 0 # Note Scheduler self.synth = Synth('../data/FluidR3_GM.sf2') # create TempoMap, AudioScheduler self.tempo_map = SimpleTempoMap(120) self.sched = AudioScheduler(self.tempo_map) # connect scheduler into audio system self.mixer.add(self.sched) self.sched.set_generator(self.synth) # Note Sequencers self.seq = [] # live Generator self.live_wave = None
def __init__(self, level, notes, goal_values, gear_values, **kwargs): super(LevelEasyMediumScreen, self).__init__(**kwargs) # set up notes for the level self.notes = notes # set up gear values for the levels self.goal_values = goal_values # set up gear values for the levels self.gear_values = gear_values self.level = level # only turn on tutorial for level 1 if self.level == 1: self.use_tutorial = True self.tutorial_screen = 'A' self.goal_play_status = None self.gear_play_status = None self.size_dim = min(Window.width / 6, Window.height / 6) self.tutorial_full_overlay = CRectangle(cpos=(Window.width / 2, Window.height / 2), csize=(Window.width, Window.height)) self.tutorial_options_overlay = Rectangle( pos=(0, 0), size=(Window.width, self.size_dim + Window.height / 25)) self.tutorial_musicbox_overlay = Rectangle( pos=(Window.width // 2, self.size_dim + Window.height / 25), size=(Window.width / 2, Window.height - (self.size_dim + Window.height / 25))) self.tutorial_gearbox_overlay = Rectangle( pos=(0, self.size_dim + Window.height / 25), size=(Window.width / 2, Window.height - (self.size_dim + Window.height / 25))) self.skip_image = CoreImage('images/skip_tutorial.png') self.tutorial_skip_button = Rectangle( pos=(0.98 * Window.width - (self.skip_image.width * self.size_dim / 300), 0.98 * Window.height - self.skip_image.height * self.size_dim / 300), size=(self.skip_image.width * self.size_dim / 300, self.skip_image.height * self.size_dim / 300), texture=self.skip_image.texture) else: self.use_tutorial = False ############################################ ### GOAL MUSIC ### ############################################ self.goal_audio = Audio(2) self.goal_synth = Synth('./data/FluidR3_GM.sf2') # create TempoMap, AudioScheduler self.goal_tempo_map = SimpleTempoMap(120) self.goal_sched = AudioScheduler(self.goal_tempo_map) # connect scheduler into audio system self.goal_audio.set_generator(self.goal_sched) self.goal_sched.set_generator(self.goal_synth) # generate goal music self.goal_music = MusicPlayer(notes=self.notes, sched=self.goal_sched, synth=self.goal_synth, channel=1, tempo_map=self.goal_tempo_map) self.goal_music.update_tempo(self.goal_values[0]) self.goal_music.update_instrument(self.goal_values[1]) self.goal_music.update_pitch(self.goal_values[2]) self.goal_music.update_volume(self.goal_values[3]) self.goal_music_seq = self.goal_music.generate() ############################################ ### GEAR MUSIC ### ############################################ self.gear_audio = Audio(2) self.gear_synth = Synth('./data/FluidR3_GM.sf2') # create TempoMap, AudioScheduler self.gear_tempo_map = SimpleTempoMap(120) self.gear_sched = AudioScheduler(self.gear_tempo_map) # connect scheduler into audio system self.gear_audio.set_generator(self.gear_sched) self.gear_sched.set_generator(self.gear_synth) # generate gear music self.gear_music = MusicPlayer(notes=self.notes, sched=self.gear_sched, synth=self.gear_synth, channel=1, tempo_map=self.gear_tempo_map) self.gear_music_seq = None ############################################ ### BACKGROUND UI COMPONENTS ### ############################################ self.gear_area = GearArea() self.canvas.add(self.gear_area) self.music_box_area = MusicBoxArea() self.canvas.add(self.music_box_area) self.options = LevelOptions( level=level, goal_music_seq=self.goal_music_seq, duration=self.goal_music.duration, edit_goal_play_status=self.edit_goal_play_status) self.canvas.add(self.options) self.label = Label(text=kwargs['name'], font_name='./fonts/PassionOne-Regular', color=(.165, .718, .792, 1)) self.add_widget(self.label) ########################################### ### GEAR LABELS ### ########################################### self.tempo_label = Label(text='Tempo (bpm)', font_name='./fonts/PassionOne-Regular', color=(0.7254901960784313, 0.5529411764705883, 0.8196078431372549, 1), center_x=(Window.width / 4), center_y=(Window.height / 5.25 * (0.5 + 0.5) + self.gear_area.position[1]), font_size=str(Window.width // 50) + 'sp') self.instrument_label = Label( text='Instrument', font_name='./fonts/PassionOne-Regular', color=(0.996078431372549, 0.8431372549019608, 0.4, 1), center_x=(Window.width / 4), center_y=(Window.height / 5.25 * (1.5 + 0.5) + self.gear_area.position[1]), font_size=str(Window.width // 50) + 'sp') self.pitch_label = Label(text='Pitch (semitones)', font_name='./fonts/PassionOne-Regular', color=(1.0, 0.6509803921568628, 0.09019607843137255, 1), center_x=(Window.width / 4), center_y=(Window.height / 5.25 * (2.5 + 0.5) + self.gear_area.position[1]), font_size=str(Window.width // 50) + 'sp') self.volume_label = Label( text='Volume', font_name='./fonts/PassionOne-Regular', color=(0.9254901960784314, 0.32941176470588235, 0.3176470588235294, 1), center_x=(Window.width / 4), center_y=(Window.height / 5.25 * (3.5 + 0.5) + self.gear_area.position[1]), font_size=str(Window.width // 50) + 'sp') self.add_widget(self.volume_label) self.add_widget(self.pitch_label) self.add_widget(self.instrument_label) self.add_widget(self.tempo_label) ########################################### ### GEAR CONSTRUCTION ### ########################################### self.gears = [] self.gear_centers = [] self.gears_group = AnimGroup() self.canvas.add(self.gears_group) ########################################### ### GEARS ### ########################################### self.gear_storage_locations = [] self.gear_music_locations = [] self.gear_labels = [] self.set_up_gears() ########################################### ### PARTICLE EFFECT ### ########################################### self.win_ps = ParticleSystem('particles/star_particle.pex') self.win_ps.emitter_x = Window.width / 2 self.win_ps.emitter_y = Window.height / 2 self.add_widget(self.win_ps) self.you_win_label = Label(text=' ', font_name='./fonts/PassionOne-Regular', color=(0.5843137254901961, 0.796078431372549, 0.37254901960784315, 1), center_x=Window.width / 2, center_y=Window.height / 2, font_size=str(Window.width // 10) + 'sp') self.add_widget(self.you_win_label) self.lose_ps = ParticleSystem('particles/lose_particle.pex') self.lose_ps.emitter_x = Window.width / 2 self.lose_ps.emitter_y = Window.height / 2 self.add_widget(self.lose_ps) self.you_lose_label = Label(text=' ', font_name='./fonts/PassionOne-Regular', color=(0.9254901960784314, 0.32941176470588235, 0.3176470588235294, 1), center_x=Window.width / 2, center_y=Window.height / 2, font_size=str(Window.width // 10) + 'sp') self.add_widget(self.you_lose_label) ########################################### ### ERROR MESSAGE ### ########################################### self.error_msg = Label(text=' ', font_name='./fonts/PassionOne-Regular', color=(0.9254901960784314, 0.32941176470588235, 0.3176470588235294, 1), center_x=Window.width / 2, center_y=Window.height / 2, font_size=str(Window.width // 20) + 'sp') self.add_widget(self.error_msg) # ########################################### # ### ADD TUTORIAL OVERLAYS ### # ########################################### if self.use_tutorial: self.canvas.add(Color(rgba=(0, 0, 0, 0.85))) self.canvas.add(self.tutorial_full_overlay) self.tutorial_label = Label( markup=True, text= "[font=./fonts/lato-bold]Welcome to the\n[/font] [font=./fonts/options-icons]|[/font] [font=./fonts/PassionOne-Regular]Play It By Gear Tutorial[/font] [font=./fonts/options-icons]|[/font] [font=./fonts/lato-bold]\n\nThe goal of this game is to make the \n goal song match the song you create by \nplacing the correct gears in a music box \n\n[/font] [font=./fonts/lato-light] (click to see the next \nstep of the tutorial)[/font]", color=(86 / 255, 189 / 255, 205 / 255, 1), center_x=Window.width / 2, center_y=Window.height / 2, font_size=str(Window.width // 40) + 'sp', halign='center') self.add_widget(self.tutorial_label) self.canvas.add(self.tutorial_skip_button) self.on_layout((Window.width, Window.height))
class IntroScreen(BaseWidget): image = "data/bedroom.jpg" def __init__(self): super(IntroScreen, self).__init__() self.genre_popup = CheckboxPopup(self.genre_callback, "GENRE", GENRE_CHECKBOXES) self.volume_popup = VolumePopup(self.slider_callback) self.record_popup = RecordPopup(self.init_recording, self.toggle_playing) self.instruments_popup = CheckboxPopup(self.instrument_callback, "INSTRUMENTS", INSTRUMENT_CHECKBOXES) self.storage_popup = StoragePopup(self.get_live_wave, self.set_live_wave) self.audio = Audio(2, input_func=self.receive_audio, num_input_channels=1) self.mixer = Mixer() self.audio.set_generator(self.mixer) self.pitch = PitchDetector() self.recorder = VoiceAudioWriter('data') self.playing = False self.recording = False self.cmd = None self.scene = Scene() self.add_widget(self.scene) self.scene.foreground.radio.set_callback(self.genre_popup.open) self.scene.foreground.amp.set_callback(self.volume_popup.open) self.scene.foreground.mic.set_callback(self.record_popup.open) self.scene.foreground.guitar.set_callback(self.instruments_popup.open) self.scene.foreground.storage.set_callback(self.storage_popup.open) self.cur_pitch = 0 self.midi_notes = None self.bass = [((40, 60), (0, 0)), ((43, 64), (0, 42)), ((28, 48), (0, 33))] self.tenor = [((52, 69), (0, 0)), ((52, 69), (0, 41)), ((45, 64), (0, 26))] self.alto = [((57, 77), (0, 0)), ((60, 79), (0, 40)), ((52, 72), (0, 29)), ((67, 86), (0, 73))] self.instruments = [self.bass, self.tenor, self.alto] self.genre = 'pop' self.indices = [0, 0, 0] # Note Scheduler self.synth = Synth('data/FluidR3_GM.sf2') # create TempoMap, AudioScheduler self.tempo_map = SimpleTempoMap(120) self.sched = AudioScheduler(self.tempo_map) self.metro = Metronome(self.sched, self.synth) self.start_tick = None # connect scheduler into audio system self.mixer.add(self.sched) self.sched.set_generator(self.synth) # Note Sequencers self.seq = [None, None, None] # live Generator self.live_wave = None # current .wav file self.current_wave_file = None def genre_callback(self, value, label): self.genre = value if value == 'classical': self.instruments_popup.set_checkboxes(ORCHESTRA) self.indices = [1, 1, 1] self.instrument_callback(None, None) if value == 'pop': self.instruments_popup.set_checkboxes(POP) self.indices = [2, 2, 0] self.instrument_callback(None, None) def instrument_callback(self, value, label): if label == 'high voice': self.indices[2] = ['piano', 'violin', 'guitar', 'flute'].index(value) if label == 'mid voice': self.indices[1] = ['piano', 'viola', 'guitar'].index(value) if label == 'low voice': self.indices[0] = ['piano', 'cello', 'bass'].index(value) if self.live_wave is not None: for i in self.seq: i.stop() self.live_wave.reset() #reharmonize and update NoteSequencers duration_midi = harmony.harmonize( self.midi_notes, self.genre, brange=self.bass[self.indices[0]][0], trange=self.tenor[self.indices[1]][0], arange=self.alto[self.indices[2]][0]) tempo = self.tempo_map.get_tempo() multiplier = 1 / 60 * tempo * 480 converted_midi_duration = [[(i * multiplier, j) for i, j in k] for k in duration_midi] for i in range(3): self.seq[i] = NoteSequencer( self.sched, self.synth, i + 1, self.instruments[i][self.indices[i]][1], converted_midi_duration[i + 1], self.scene.add_note_sprite, True) if self.playing: self.play_recording(1) def slider_callback(self, voice, value): val = int(value) idx = ["bass", "tenor", "alto", "melody"].index(voice) + 1 if idx < 4: self.synth.cc(idx, 7, val) else: if self.live_wave: self.live_wave.set_gain(val / 100) def on_update(self): self.audio.on_update() self.scene.on_update() def on_key_down(self, keycode, modifiers): if keycode[1] == 'm': self.metro.toggle() bpm_adj = lookup(keycode[1], ('up', 'down'), (10, -10)) if bpm_adj and not self.playing and not self.recording: new_tempo = max(self.tempo_map.get_tempo() + bpm_adj, 30) self.tempo_map.set_tempo(new_tempo, self.sched.get_time()) def receive_audio(self, frames, num_channels): assert (num_channels == 1) # Microphone volume level, take RMS, convert to dB. # display on meter and graph rms = np.sqrt(np.mean(frames**2)) rms = np.clip(rms, 1e-10, 1) # don't want log(0) db = 20 * np.log10(rms) # convert from amplitude to decibels self.record_popup.mic_meter.set(db) self.record_popup.mic_graph.add_point(db) # pitch detection: get pitch and display on meter and graph self.cur_pitch = self.pitch.write(frames) self.record_popup.pitch_meter.set(self.cur_pitch) self.record_popup.pitch_graph.add_point(self.cur_pitch) # record audio self.recorder.add_audio(frames, num_channels) def init_recording(self): if not self.recording: self.start_tick = self.sched.get_tick() data = self.recorder.toggle() if not data: self.recording = True if self.live_wave is not None: try: self.mixer.remove(self.live_wave) except: pass for i in self.seq: if i is not None: i.stop() self.playing = False else: self.recording = False stop_tick = self.sched.get_tick() wave_gen, filename, duration_midi = data self.current_wave_file = WaveFile(filename) #ignore short notes i = 0 while i < len(duration_midi): if duration_midi[i][0] < 0.1: duration_midi[i - 1] = (duration_midi[i][0] + duration_midi[i - 1][0], duration_midi[i - 1][1]) duration_midi.pop(i) else: i += 1 duration_midi[0] = (duration_midi[0][0] - .1, duration_midi[0][1]) ticks = [(int(note[0] * 480 * self.tempo_map.get_tempo() / 60), note[1]) for note in duration_midi] ticks[0] = (ticks[0]) duration_midi = [] tick_length = sum(i[0] for i in ticks) curr_beat = int(480 - self.start_tick % 480 + .22 * 8 * self.tempo_map.get_tempo()) % 480 ind = 0 ticks_passed = 0 while tick_length > 0: tot = 0 times = {} while tot < curr_beat and ind < len(ticks): left = ticks[ind][0] - ticks_passed if left > curr_beat - tot: ticks_passed += curr_beat - tot if ticks[ind][1] in times: times[ticks[ind][1]] += curr_beat - tot else: times[ticks[ind][1]] = curr_beat - tot tot = curr_beat else: tot += left ticks_passed = 0 if ticks[ind][1] in times: times[ticks[ind][1]] += left else: times[ticks[ind][1]] = left ind += 1 big = 80 note = 0 print(times) for guy in times: if times[guy] > big and guy != 0: note = guy big = times[guy] duration_midi.append( (60 * curr_beat / 480 / self.tempo_map.get_tempo(), note)) tick_length -= curr_beat curr_beat = min(480, tick_length) duration_midi = [(0.1, 0)] + duration_midi self.midi_notes = duration_midi #find harmonies self.live_wave = wave_gen good = False for i in duration_midi: if i[1] > 0: good = True break if good: duration_midi = harmony.harmonize( duration_midi, self.genre, brange=self.bass[self.indices[0]][0], trange=self.tenor[self.indices[1]][0], arange=self.alto[self.indices[2]][0]) #print([[i[1] for i in j] for j in duration_midi]) # cheat to use SimpleTempoMap tempo = self.tempo_map.get_tempo() multiplier = 1 / 60 * tempo * 480 converted_midi_duration = [[(i * multiplier, j) for i, j in k] for k in duration_midi] #make NoteSequencers for i in range(3): self.seq[i] = NoteSequencer( self.sched, self.synth, i + 1, self.instruments[i][self.indices[i]][1], converted_midi_duration[i + 1], self.scene.add_note_sprite, True) def play_recording(self, tick): for i in self.seq: if i is not None: i.start() if self.live_wave: self.live_wave.play() if self.live_wave not in self.mixer.generators: self.mixer.add(self.live_wave) def start_playing(self): if self.playing: return self.metro.stop() self.playing = True now = self.sched.get_tick() next_beat = quantize_tick_up(now, kTicksPerQuarter * 4) self.cmd = self.sched.post_at_tick(self.play_recording, next_beat) def stop_playing(self): if not self.playing: return self.playing = False for i in self.seq: i.stop() self.live_wave.reset() self.sched.cancel(self.cmd) self.cmd = None def toggle_playing(self): print(self.playing) if self.playing: self.stop_playing() else: self.start_playing() def get_live_wave(self): if self.live_wave: return WaveGenerator(self.current_wave_file, True), self.seq.copy() def set_live_wave(self, new_live_wave, note_sequencers): if self.live_wave: if self.live_wave is not None: try: self.mixer.remove(self.live_wave) except: pass for i in self.seq: if i is not None: i.stop() self.seq = note_sequencers for i in self.seq: if i is not None: i.start() self.live_wave = new_live_wave self.mixer.add(self.live_wave) self.start_playing()
def __init__(self, norm, sandbox, mixer, client, client_id): self.norm = norm self.module_name = 'SoundBlock' self.sandbox = sandbox self.mixer = mixer self.tempo_map = SimpleTempoMap(bpm=60) self.sched = AudioScheduler(self.tempo_map) self.synth = Synth("data/FluidR3_GM.sf2") self.sched.set_generator(self.synth) self.mixer.add(self.sched) self.cmd = {} self.client = client self.cid = client_id self.instruments = { 'piano': 1, 'violin': 41, 'trumpet': 57, 'ocarina': 80, 'choir': 53 } self.inst_list = ['piano', 'violin', 'trumpet', 'ocarina', 'choir'] self.drumkit = { 'snare': 38, 'crash': 49, 'bass': 35, 'hihat': 46, 'triangle': 81 } self.drum_list = ['snare', 'crash', 'bass', 'hihat', 'triangle'] self.channel = 0 self.drum_channel = len(self.inst_list) # set up the correct sound (program: bank and preset) # each instrument is on a different channel for index, inst in enumerate(self.inst_list): self.synth.program(index, 0, self.instruments[inst]) for index, drum in enumerate(self.drum_list): self.synth.program(index + len(self.instruments), 128, 0) # many variables here are dicts because a user's module handler needs to keep track of # not just its own variables, but other users' variables as well! so we use dictionaries # with client ids as the keys. self.hold_point = {} self.hold_shape = {} # this variable is needed for when a user clicks on a soundblock in a touch_down event, # so that the corresponding touch_up event is skipped self.skip = {} self.color_dict = { 'red': (201 / 255, 108 / 255, 130 / 255), 'orange': (214 / 255, 152 / 255, 142 / 255), 'yellow': (238 / 255, 234 / 255, 202 / 255), 'green': (170 / 255, 220 / 255, 206 / 255), 'teal': (159 / 255, 187 / 255, 208 / 255), 'blue': (44 / 255, 85 / 255, 123 / 255), 'turquoise': (50 / 255, 147 / 255, 140 / 255), 'indigo': (46 / 255, 40 / 255, 90 / 255), 'violet': (147 / 255, 127 / 255, 159 / 255), 'pink': (199 / 255, 150 / 255, 170 / 255), 'peach': (238 / 255, 142 / 255, 154 / 255), 'magenta': (172 / 255, 69 / 255, 133 / 255), 'grey': (140 / 255, 143 / 255, 148 / 255), 'white': (239 / 255, 226 / 255, 222 / 255) } self.default_color = self.color_dict['violet'] self.default_pitch = 60 self.default_timbre = 'sine' self.default_instrument = 'piano' self.default_drum = 'snare' self.color = {} self.pitch = {} self.timbre = {} self.instrument = {} self.drum = {} self.display = False self.blocks = AnimGroup() self.sandbox.add(self.blocks) self.gui = BlockGUI(self.norm, pos=self.norm.nt((50, 100)), is_drum=False, pitch_callback=self.update_pitch, instrument_callback=self.update_instrument, drum_callback=self.update_drum) self.delete_mode = {}
class TempoCursorHandler(object): """ Handles the TempoCursor GUI. Also stores and updates all currently active TempoCursors. """ def __init__(self, norm, sandbox, mixer, client, client_id, block_handler, tempo=60): self.norm = norm self.module_name = 'TempoCursor' self.sandbox = sandbox self.mixer = mixer self.client = client self.cid = client_id self.block_handler = block_handler self.tempo = tempo self.clock = Clock() self.tempo_map = SimpleTempoMap(bpm=self.tempo) self.touch_points = {} self.cursors = AnimGroup() self.sandbox.add(self.cursors) self.gui = CursorGUI(norm, pos=self.norm.nt((20, 300)), beat_callback=self.update_touch_points) self.delete_mode = {} def on_touch_down(self, cid, pos): if cid == self.cid: self.gui.on_touch_down(pos) if not self.sandbox.in_bounds(pos): return for cursor in self.cursors.objects: cursor_pos = (cursor.pos[0] - cursor.size[0] / 2, cursor.pos[1] - cursor.size[1] / 2) if in_bounds(pos, cursor_pos, cursor.size): if self.delete_mode[cid]: self.cursors.objects.remove(cursor) self.cursors.remove(cursor) return if self.delete_mode[cid]: return touch_points = self.touch_points[cid] if len(touch_points) == 0: return cursor = TempoCursor(self.norm, pos, self.tempo, self.clock, self.tempo_map, copy.deepcopy(touch_points), self.block_handler) self.cursors.add(cursor) def on_touch_move(self, cid, pos): pass def on_touch_up(self, cid, pos): pass def on_key_down(self, cid, key): if key == 'p': self.clock.toggle() if key == 'v' and cid == self.cid: self.delete_mode[cid] = not self.delete_mode[cid] self.update_server_state(post=True) if key == 'up': self.tempo += 4 self.tempo_map.set_tempo(self.tempo) self.update_server_state(post=True) if key == 'down': self.tempo -= 4 self.tempo_map.set_tempo(self.tempo) self.update_server_state(post=True) def on_update(self): self.cursors.on_update() def update_touch_points(self, touch_points): self.touch_points[self.cid] = touch_points self.update_server_state(post=True) def display_controls(self): cur_time = self.clock.get_time() cur_tick = self.tempo_map.time_to_tick(cur_time) info = 'delete mode: {}\n\n'.format(self.delete_mode[self.cid]) info += 'tempo: {}\n'.format(self.tempo) return info def update_server_state(self, post=False): """Update server state. If post is True, relay this updated state to all clients.""" state = { 'touch_points': self.touch_points, 'delete_mode': self.delete_mode, 'tempo': self.tempo } data = { 'module': self.module_name, 'cid': self.cid, 'state': state, 'post': post } self.client.emit('update_state', data) def update_client_state(self, cid, state): """Update this handler's state.""" if cid != self.cid: # this client already updated its own state self.touch_points = state['touch_points'] self.delete_mode = state['delete_mode'] self.tempo = state['tempo'] def sync_state(self, state): """ Initial sync with the server's copy of module state. """ self.touch_points = state['touch_points'] self.delete_mode = state['delete_mode'] self.tempo = state['tempo'] # after initial sync, add default values for this client self.touch_points[self.cid] = [] self.delete_mode[self.cid] = False # update server with these default values # post=True here because we want all other clients' states to update with this client's # default values. self.update_server_state(post=True)
def __init__(self): super(MainWidget3, self).__init__() self.audio = Audio(2) self.synth = Synth('../data/FluidR3_GM.sf2') # create TempoMap, AudioScheduler self.tempo_map = SimpleTempoMap(104) self.sched = AudioScheduler(self.tempo_map) # connect scheduler into audio system self.audio.set_generator(self.sched) self.sched.set_generator(self.synth) # create the metronome: self.metro = Metronome(self.sched, self.synth) percNotes = [(480,35), (360,42), (120,35), (480,35), (480,42)] self.base1Notes = [(240,43), (240,43), (240,43), (120,47), (240,41), (240,41), (360,41), (120,40), (360,41), (240,41), (240,41), (120,40), (120,36), (480,-1), (120,40), (240,41), (120,43)] self.base2Notes = [(120,-1), (120,45), (240,43), (120,-1), (240,43), (120,40), (480,43), (120,-1), (120,45), (120,45), (120,48), (240,-1), (240,41), (120,-1), (240,41), (120,40), (480,41), (120,-1), (120,45), (120,45), (120,48), (240,-1), (240,45), (120,-1), (240,45), (120,45), (480,45), (240,43), (120,-1), (120,45), (240,-1), (240,45), (120,-1), (240,45), (120,45), (480,45), (120,-1), (120,45), (120,45), (120,48)] self.baseNotes = self.base2Notes #[40, 41, 43, 45 48,] #changes / pitch sutff self.changes = [ (1920, [72, 74, 76, 79, 81, 84]), (1920, [69, 72, 74, 81]), (3840, [69, 72, 74, 76, 79, 81, 84])] self.changesIndex = 0 self.curChanges = [] self.selectSize = 2 self.lastPitchIndex = None self.lastTouch = None #Note length stuff self.noteLengths = [480, 240, 120] self.articulation = 1 self.lastPulseIndex = 0 #Declare the players self.perc = NoteSequencer(self.sched, self.synth, 1, (128,0), percNotes) self.base1 = NoteSequencer(self.sched, self.synth, 2, (0,33), self.base1Notes, callback = self.graphic_callback) self.base2 = NoteSequencer(self.sched, self.synth, 2, (0,33), self.base2Notes, callback = self.graphic_callback) self.lead = Arpeggiator(self.sched, self.synth, channel = 3, program = (0,65), callback = self.graphic_callback) self.lead.set_direction('updown') #Start the non-interactive stuff now = self.sched.get_tick() next_beat = quantize_tick_up(now, 480) self.perc.toggle() self.base2.toggle() self.sched.post_at_tick(self._updateChanges, next_beat) #Update changes as music starts self.sched.post_at_tick(self._spawnCrossBar, next_beat) # and text to display our status #self.label = topleft_label() #self.add_widget(self.label) #Graphics stuff self.objects = AnimGroup() self.canvas.add(self.objects) #self.allNotes = [40, 41, 43, 45, 48, 900, 69, 72, 74, 76, 79, 81, 84] self.allNotes = [36, 40, 41, 43, 45, 47, 48, 900, 69, 72, 74, 76, 79, 81, 84]
def __init__(self): super(IntroScreen, self).__init__() self.genre_popup = CheckboxPopup(self.genre_callback, "GENRE", GENRE_CHECKBOXES) self.volume_popup = VolumePopup(self.slider_callback) self.record_popup = RecordPopup(self.init_recording, self.toggle_playing) self.instruments_popup = CheckboxPopup(self.instrument_callback, "INSTRUMENTS", INSTRUMENT_CHECKBOXES) self.storage_popup = StoragePopup(self.get_live_wave, self.set_live_wave) self.audio = Audio(2, input_func=self.receive_audio, num_input_channels=1) self.mixer = Mixer() self.audio.set_generator(self.mixer) self.pitch = PitchDetector() self.recorder = VoiceAudioWriter('data') self.playing = False self.recording = False self.cmd = None self.scene = Scene() self.add_widget(self.scene) self.scene.foreground.radio.set_callback(self.genre_popup.open) self.scene.foreground.amp.set_callback(self.volume_popup.open) self.scene.foreground.mic.set_callback(self.record_popup.open) self.scene.foreground.guitar.set_callback(self.instruments_popup.open) self.scene.foreground.storage.set_callback(self.storage_popup.open) self.cur_pitch = 0 self.midi_notes = None self.bass = [((40, 60), (0, 0)), ((43, 64), (0, 42)), ((28, 48), (0, 33))] self.tenor = [((52, 69), (0, 0)), ((52, 69), (0, 41)), ((45, 64), (0, 26))] self.alto = [((57, 77), (0, 0)), ((60, 79), (0, 40)), ((52, 72), (0, 29)), ((67, 86), (0, 73))] self.instruments = [self.bass, self.tenor, self.alto] self.genre = 'pop' self.indices = [0, 0, 0] # Note Scheduler self.synth = Synth('data/FluidR3_GM.sf2') # create TempoMap, AudioScheduler self.tempo_map = SimpleTempoMap(120) self.sched = AudioScheduler(self.tempo_map) self.metro = Metronome(self.sched, self.synth) self.start_tick = None # connect scheduler into audio system self.mixer.add(self.sched) self.sched.set_generator(self.synth) # Note Sequencers self.seq = [None, None, None] # live Generator self.live_wave = None # current .wav file self.current_wave_file = None