diff --git a/README.md b/README.md index 904b47e..7081076 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ LinnStrument Community Discord: https://discord.gg/h2BcrzmTXe ## Advantages -- Notes that sound good together are closer together. Notes that sound worse are furthest apart. Mistakes will be less likely and less obvious! +- Notes that sound good together are closer together. Notes that sound worse are furthest apart. Mistakes will be less likely and more obvious! - Like the LinnStrument's layout, it is also isomorphic (the same chord and scale shapes can be played anywhere) - The most common chords and scales are far easier to play and remember than other layouts. - Extended range compared to standard +5 tuning, making room for using a split. @@ -77,7 +77,7 @@ That being said, I hope you enjoy it and have fun! ### Windows -- [Download (Win)](https://github.com/flipcoder/midimech/releases) +- [Download (Win)](https://github.com/zass30/midimech/releases) After downloading, make sure to follow the instructions under `Setup`. @@ -87,7 +87,7 @@ After downloading, make sure to follow the instructions under `Setup`. - Download the project by typing the following commands in terminal: ``` -git clone https://github.com/flipcoder/midimech +git clone https://github.com/zass30/midimech ``` - Switch to the new project folder: diff --git a/src/constants.py b/src/constants.py index a8c4b66..9c50940 100644 --- a/src/constants.py +++ b/src/constants.py @@ -2,7 +2,10 @@ TITLE = "midimech" # FOCUS = False -NOTES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] +#U+1D12C flat +#1D130 sharp +NOTES_SHARPS = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] +NOTES_FLATS = ["C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B"] WHOLETONE = True FONT_SZ = 32 BRIGHTNESS = 0.4 diff --git a/src/core.py b/src/core.py index 930d754..eeaa1fb 100644 --- a/src/core.py +++ b/src/core.py @@ -93,6 +93,15 @@ def next_mode(self, ofs=1): self.set_mode((self.mode_index + ofs) % self.scale_notes.count('x')) self.dirty = self.dirty_lights = True + def toggle_sharps_flats(self, ofs=1): + if (self.use_sharps): + self.use_sharps = False + self.NOTES = NOTES_FLATS + else: + self.use_sharps = True + self.NOTES = NOTES_SHARPS + self.dirty = self.dirty_lights = True + def prev_scale(self, ofs=1): self.next_scale(-ofs) @@ -324,7 +333,7 @@ def get_note_index(self, x, y, transpose=True): y = self.board_h - y - 1 x += self.options.base_offset tr = self.tonic if transpose else 0 - return (row_offset * y + column_offset * x + tr) % len(NOTES) + return (row_offset * y + column_offset * x + tr) % len(self.NOTES) # ofs = (self.board_h - y) // 2 + BASE_OFFSET # step = 2 if WHOLETONE else 1 # tr = self.tonic if transpose else 0 @@ -335,7 +344,7 @@ def get_note_index(self, x, y, transpose=True): def get_note(self, x, y, transpose=True): """Get note name for x, y""" - return NOTES[self.get_note_index(x, y, transpose=transpose)] + return self.NOTES[self.get_note_index(x, y, transpose=transpose)] def get_color(self, x, y): """Get color for x, y""" @@ -478,13 +487,6 @@ def mouse_hover(self, x, y): def get_octave(self, x, y): """Get octave for x, y""" y = self.board_h - y - 1 - # if self.flipped: - # if self.tonic % 2 == 0: - # y -= 1 - # octave = int(x + 4 + self.position.x + y * 2.5) // 6 - # else: - if self.tonic % 2: - y -= 1 octave = int(x + 4 + self.position.x + y * 2.5) // 6 return octave @@ -1054,11 +1056,8 @@ def cb_midi_in(self, data, timestamp, force_channel=None): # self.midi_write(self.split_out, data, timestamp) # else: # self.midi_write(self.midi_out, data, timestamp) - elif note and note.location is not None: - col = note.location.x - row = note.location.y - split_chan = self.channel_from_split(col, row) - if split_chan: + elif note and note.split is not None: + if note.split: self.midi_write(self.split_out, data, timestamp) else: self.midi_write(self.midi_out, data, timestamp) @@ -1636,6 +1635,16 @@ def __init__(self): text='MOD>', manager=self.gui ) + self.btn_sharps_flats = pygame_gui.elements.UIButton( + relative_rect=pygame.Rect((bs.x * 16 + 2, y), (bs.x, bs.y)), + text='#/b', + manager=self.gui + ) + self.btn_quit = pygame_gui.elements.UIButton( + relative_rect=pygame.Rect((bs.x * 17 + 2, y), (bs.x, bs.y)), + text='QUIT', + manager=self.gui + ) # self.next_scale = pygame_gui.elements.UIButton( # relative_rect=pygame.Rect((bs.x * 11 + 2, y), (bs.x, bs.y)), # text='SCL>', @@ -1702,6 +1711,9 @@ def __init__(self): self.linn_out = None self.midi_out = None self.split_out = None + self.use_sharps = True + self.NOTES = NOTES_SHARPS + outnames = rtmidi2.get_out_ports() for i in range(len(outnames)): @@ -2024,7 +2036,7 @@ def mark(self, midinote, state, use_lights=False, only_row=None): y = 0 for row in rows: x = 0 - for x in range(len(row)): + for x in range(-1 * self.position.x, len(row)-self.position.x): #this band aids bug for 1 move right idx = self.get_note_index(x, y, transpose=False) # print(x, y, midinote%12, idx) if midinote % 12 == idx: @@ -2171,10 +2183,10 @@ def logic(self, dt): self.dirty = self.dirty_lights = True self.clear_marks(use_lights=False) elif ev.ui_element == self.btn_move_left: - self.move_board(-1) + self.move_board(1) self.clear_marks(use_lights=False) elif ev.ui_element == self.btn_move_right: - self.move_board(1) + self.move_board(-1) self.clear_marks(use_lights=False) # elif ev.ui_element == self.btn_mode: # # TODO: toggle mode @@ -2230,6 +2242,10 @@ def logic(self, dt): self.next_mode() elif ev.ui_element == self.btn_prev_mode: self.prev_mode() + elif ev.ui_element == self.btn_sharps_flats: + self.toggle_sharps_flats() + elif ev.ui_element == self.btn_quit: + self.quit() # elif ev.type == pygame_gui.UI_HORIZONTAL_SLIDER_MOVED: # if ev.ui_element == self.slider_velocity: # global self.options.velocity_curve @@ -2317,9 +2333,10 @@ def analyze(self, chord_notes): r = '' for i, note in enumerate(chord_notes): if note: - notes.append(NOTES[i % 12]) + n = mp.degree_to_note(i) + notes.append(n) if notes: - r = mp.alg.detect(mp.chord(','.join(notes))) + r = mp.alg.detect(mp.chord(notes)) # try: # r = r[0:self.chord.index(' sort')] # except ValueError: