def on_zyncoder(self, encoder, value):
        if encoder == ENC_BACK:
            if self.edit_mode:
                self.velocity = self.velocity + value
                if self.velocity > 127:
                    self.velocity = 127
                    return
                if self.velocity < 1:
                    self.velocity = 1
                    return
                self.velocity_canvas.coords(
                    "velocityIndicator", 0, 0,
                    self.piano_roll_width * self.velocity / 127,
                    PLAYHEAD_HEIGHT)
                note = self.keymap[self.selected_cell[1]]["note"]
                if libseq.getNoteDuration(self.selected_cell[0], note):
                    libseq.setNoteVelocity(self.selected_cell[0], note,
                                           self.velocity)
                    self.draw_cell(self.selected_cell[0],
                                   self.selected_cell[1])
                self.parent.set_title("Velocity: %d" % (self.velocity), None,
                                      None, 2)
            else:
                self.select_cell(None, self.selected_cell[1] - value)

        elif encoder == ENC_SELECT:
            if self.edit_mode:
                if value > 0:
                    self.duration = self.duration + 1
                if value < 0:
                    self.duration = self.duration - 1
                if self.duration > libseq.getSteps():
                    self.duration = libseq.getSteps()
                    return
                if self.duration < 1:
                    self.duration = 1
                    return
                if libseq.getNoteDuration(self.selected_cell[0],
                                          self.selected_cell[1]):
                    self.add_event(self.selected_cell[0],
                                   self.selected_cell[1])
                else:
                    self.select_cell()
                self.parent.set_title("Duration: %d steps" % (self.duration),
                                      None, None, 2)
            else:
                self.select_cell(self.selected_cell[0] + value, None)

        elif encoder == ENC_LAYER and not self.parent.lst_menu.winfo_viewable(
        ):
            # Show menu
            self.parent.toggle_menu()
            return
 def load_pattern(self, index):
     libseq.clearSequence(self.bank, self.sequence)
     libseq.setChannel(self.bank, self.sequence, 0, self.channel)
     self.pattern = index
     libseq.selectPattern(index)
     libseq.addPattern(self.bank, self.sequence, 0, 0, index)
     if self.selected_cell[0] >= libseq.getSteps():
         self.selected_cell[0] = libseq.getSteps() - 1
     self.keymap_offset = libseq.getRefNote()
     self.load_keymap()
     self.redraw_pending = 2
     self.select_cell(0, int(self.keymap_offset + self.zoom / 2))
     self.play_canvas.coords("playCursor", 1, 0, 1 + self.step_width,
                             PLAYHEAD_HEIGHT)
 def draw_cell(self, step, row):
     libseq.isPatternModified()  # Avoid refresh redrawing whole grid
     cellIndex = row * libseq.getSteps(
     ) + step  # Cells are stored in array sequentially: 1st row, 2nd row...
     if cellIndex >= len(self.cells):
         return
     note = self.keymap[row + self.keymap_offset]["note"]
     velocity_colour = libseq.getNoteVelocity(step, note)
     if velocity_colour:
         velocity_colour = 70 + velocity_colour
     elif libseq.getScale() == 1:
         # Draw tramlines for white notes in chromatic scale
         key = note % 12
         if key in (0, 2, 4, 5, 7, 9, 11):  # White notes
             #			if key in (1,3,6,8,10): # Black notes
             velocity_colour += 30
     else:
         # Draw tramlines for odd rows in other scales and maps
         if (row + self.keymap_offset) % 2:
             velocity_colour += 30
     duration = libseq.getNoteDuration(step, note)
     if not duration:
         duration = 1
     fill_colour = "#%02x%02x%02x" % (velocity_colour, velocity_colour,
                                      velocity_colour)
     cell = self.cells[cellIndex]
     coord = self.get_cell(step, row, duration)
     if cell:
         # Update existing cell
         self.grid_canvas.itemconfig(cell, fill=fill_colour)
         self.grid_canvas.coords(cell, coord)
     else:
         # Create new cell
         cell = self.grid_canvas.create_rectangle(
             coord,
             fill=fill_colour,
             width=0,
             tags=("%d,%d" % (step, row), "gridcell", "step%d" % step))
         self.grid_canvas.tag_bind(cell, '<ButtonPress-1>',
                                   self.on_grid_press)
         self.grid_canvas.tag_bind(cell, '<ButtonRelease-1>',
                                   self.on_grid_release)
         self.grid_canvas.tag_bind(cell, '<B1-Motion>', self.on_grid_drag)
         self.cells[cellIndex] = cell
     if step + duration > libseq.getSteps():
         self.grid_canvas.itemconfig("lastnotetext%d" % row,
                                     text="+%d" %
                                     (duration - libseq.getSteps() + step),
                                     state="normal")
 def toggle_event(self, step, index):
     if step < 0 or step >= libseq.getSteps() or index >= len(self.keymap):
         return
     note = self.keymap[index]['note']
     if libseq.getNoteVelocity(step, note):
         self.remove_event(step, index)
     else:
         self.add_event(step, index)
         return note
Ejemplo n.º 5
0
 def check_pattern(self, beat_type, steps_per_beat, beats_in_pattern):
     steps_in_pattern = beats_in_pattern * steps_per_beat
     clocks_per_step = 24 / steps_per_beat
     self.assertEqual(libseq.getSteps(), steps_in_pattern)
     self.assertEqual(libseq.getBeatType(), beat_type)
     self.assertEqual(libseq.getStepsPerBeat(), steps_per_beat)
     self.assertEqual(libseq.getBeatsInPattern(), beats_in_pattern)
     self.assertEqual(libseq.getClocksPerStep(), clocks_per_step)
     self.assertEqual(libseq.getPatternLength(libseq.getPatternIndex()),
                      clocks_per_step * steps_in_pattern)
 def export_smf(self, params):
     smf = libsmf.addSmf()
     tempo = libseq.getTempo()
     libsmf.addTempo(smf, 0, tempo)
     ticks_per_step = libsmf.getTicksPerQuarterNote(
         smf) / libseq.getStepsPerBeat()
     for step in range(libseq.getSteps()):
         time = int(step * ticks_per_step)
         for note in range(128):
             duration = libseq.getNoteDuration(step, note)
             if duration == 0:
                 continue
             duration = int(duration * ticks_per_step)
             velocity = libseq.getNoteVelocity(step, note)
             libsmf.addNote(smf, 0, time, duration, self.channel, note,
                            velocity)
     libsmf.setEndOfTrack(smf, 0, int(libseq.getSteps() * ticks_per_step))
     zynsmf.save(
         smf, "/zynthian/zynthian-my-data/capture/pattern%d_%s.mid" %
         (self.pattern, datetime.now()))
 def on_grid_press(self, event):
     if self.parent.lst_menu.winfo_viewable():
         self.parent.hide_menu()
         return
     if self.parent.param_editor_item != None:
         self.parent.hide_param_editor()
         return
     self.grid_drag_start = event
     try:
         col, row = self.grid_canvas.gettags(
             self.grid_canvas.find_withtag(tkinter.CURRENT))[0].split(',')
     except:
         return
     note = self.keymap[self.keymap_offset + int(row)]["note"]
     step = int(col)
     if step < 0 or step >= libseq.getSteps():
         return
     self.drag_start_velocity = libseq.getNoteVelocity(step, note)
     self.drag_start_duration = libseq.getNoteDuration(step, note)
     self.drag_start_step = int(event.x / self.step_width)
     if not self.drag_start_velocity:
         self.play_note(note)
     self.select_cell(int(col), self.keymap_offset + int(row))
 def select_cell(self, step=None, index=None):
     if len(self.keymap) == 0:
         return
     redraw = False
     if step == None:
         step = self.selected_cell[0]
     if index == None:
         index = self.selected_cell[1]
     if step < 0:
         step = 0
     if step >= libseq.getSteps():
         step = libseq.getSteps() - 1
     if index >= len(self.keymap):
         index = len(self.keymap) - 1
     if index >= self.keymap_offset + self.zoom:
         # Note is off top of display
         self.keymap_offset = index - self.zoom + 1
         redraw = True
     if index < 0:
         index = 0
     if index < self.keymap_offset:
         # Note is off bottom of display
         self.keymap_offset = index
         redraw = True
     if redraw:
         self.redraw_pending = 1
     row = index - self.keymap_offset
     note = self.keymap[index]['note']
     # Skip hidden (overlapping) cells
     for previous in range(step - 1, -1, -1):
         prev_duration = libseq.getNoteDuration(previous, note)
         if not prev_duration:
             continue
         if prev_duration > step - previous:
             if step > self.selected_cell[0]:
                 step = previous + prev_duration
             else:
                 step = previous
             break
     if step < 0:
         step = 0
     if step >= libseq.getSteps():
         step = libseq.getSteps() - 1
     self.selected_cell = [step, index]
     cell = self.grid_canvas.find_withtag("selection")
     duration = libseq.getNoteDuration(step, row)
     if not duration:
         duration = self.duration
     coord = self.get_cell(step, row, duration)
     coord[0] = coord[0] - 1
     coord[1] = coord[1] - 1
     coord[2] = coord[2]
     coord[3] = coord[3]
     if not cell:
         cell = self.grid_canvas.create_rectangle(
             coord,
             fill="",
             outline=SELECT_BORDER,
             width=self.select_thickness,
             tags="selection")
     else:
         self.grid_canvas.coords(cell, coord)
     self.grid_canvas.tag_raise(cell)
 def draw_grid(self):
     clear_grid = (self.redraw_pending == 2)
     self.redraw_pending = 0
     if libseq.getSteps() == 0:
         return  #TODO: Should we clear grid?
     if self.keymap_offset > len(self.keymap) - self.zoom:
         self.keymap_offset = len(self.keymap) - self.zoom
     if self.keymap_offset < 0:
         self.keymap_offset = 0
     font = tkFont.Font(family=zynthian_gui_config.font_topbar[0],
                        size=self.fontsize)
     if clear_grid:
         self.grid_canvas.delete(tkinter.ALL)
         self.step_width = (self.grid_width - 2) / libseq.getSteps()
         self.draw_pianoroll()
         self.cells = [None] * self.zoom * libseq.getSteps()
         self.play_canvas.coords(
             "playCursor", 1 + self.playhead * self.step_width, 0,
             1 + self.playhead * self.step_width + self.step_width,
             PLAYHEAD_HEIGHT)
     # Draw cells of grid
     self.grid_canvas.itemconfig("gridcell", fill="black")
     # Redraw gridlines
     self.grid_canvas.delete("gridline")
     if libseq.getStepsPerBeat():
         for step in range(0,
                           libseq.getSteps() + 1, libseq.getStepsPerBeat()):
             self.grid_canvas.create_line(step * self.step_width,
                                          0,
                                          step * self.step_width,
                                          self.zoom * self.row_height - 1,
                                          fill=GRID_LINE,
                                          tags=("gridline"))
     # Delete existing note names
     self.piano_roll.delete("notename")
     for row in range(0, self.zoom):
         index = row + self.keymap_offset
         if (index >= len(self.keymap)):
             break
         if clear_grid:
             # Create last note labels in grid
             self.grid_canvas.create_text(
                 self.grid_width - self.select_thickness,
                 int(self.row_height * (self.zoom - row - 0.5)),
                 state="hidden",
                 tags=("lastnotetext%d" % (row), "lastnotetext"),
                 font=font,
                 anchor="e")
         self.draw_row(index)
         # Update pianoroll keys
         id = "row%d" % (row)
         try:
             name = self.keymap[index]["name"]
         except:
             name = None
         try:
             colour = self.keymap[index]["colour"]
         except:
             colour = "white"
         self.piano_roll.itemconfig(id, fill=colour)
         if name:
             self.piano_roll.create_text(
                 (2, self.row_height * (self.zoom - row - 0.5)),
                 text=name,
                 font=font,
                 anchor="w",
                 fill=CANVAS_BACKGROUND,
                 tags="notename")
         if self.keymap[index]['note'] % 12 == libseq.getTonic():
             self.grid_canvas.create_line(
                 0, (self.zoom - row) * self.row_height,
                 self.grid_width, (self.zoom - row) * self.row_height,
                 fill=GRID_LINE,
                 tags=("gridline"))
     # Set z-order to allow duration to show
     if clear_grid:
         for step in range(libseq.getSteps()):
             self.grid_canvas.tag_lower("step%d" % step)
     self.select_cell()
 def draw_row(self, index):
     row = index - self.keymap_offset
     self.grid_canvas.itemconfig("lastnotetext%d" % (row), state="hidden")
     for step in range(libseq.getSteps()):
         self.draw_cell(step, row)