Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Bug fixes and feature adds #8

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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`.

Expand All @@ -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:
Expand Down
5 changes: 4 additions & 1 deletion src/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
55 changes: 36 additions & 19 deletions src/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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
Expand All @@ -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"""
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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>',
Expand Down Expand Up @@ -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)):
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down