mirror of
https://github.com/kennethreitz/pytheory.git
synced 2026-06-05 23:00:20 +00:00
Add Fretboard.keyboard() for piano/synth controllers
Fretboard.keyboard(keys=88, start="A0") — configurable key count: - 88 keys = full piano (A0-C8) - 61 keys = standard synth controller - 49/37/25 keys = compact MIDI controllers 25 instrument presets total. 368 tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -927,6 +927,32 @@ class Fretboard:
|
||||
Tone.from_string("E4", system="western"),
|
||||
])
|
||||
|
||||
@classmethod
|
||||
def keyboard(cls, keys=88, start="A0"):
|
||||
"""Piano or keyboard with the given number of keys.
|
||||
|
||||
Args:
|
||||
keys: Number of keys (default 88 for a full piano).
|
||||
Common sizes: 25, 37, 49, 61, 76, 88.
|
||||
start: The lowest note (default ``"A0"`` for standard piano).
|
||||
|
||||
A full 88-key piano spans A0 (27.5 Hz) to C8 (4186 Hz) —
|
||||
the widest range of any standard acoustic instrument.
|
||||
Smaller MIDI controllers typically start at C.
|
||||
|
||||
Examples::
|
||||
|
||||
Fretboard.keyboard() # 88-key piano
|
||||
Fretboard.keyboard(61, "C2") # 61-key controller
|
||||
Fretboard.keyboard(25, "C3") # 25-key mini controller
|
||||
"""
|
||||
from .tones import Tone
|
||||
start_tone = Tone.from_string(start, system="western")
|
||||
tones = []
|
||||
for i in range(keys - 1, -1, -1):
|
||||
tones.append(start_tone.add(i))
|
||||
return cls(tones=tones)
|
||||
|
||||
@classmethod
|
||||
def lute(cls):
|
||||
"""Renaissance lute in G tuning (6 courses).
|
||||
|
||||
+18
-1
@@ -1942,7 +1942,7 @@ def test_all_instruments_create():
|
||||
"violin", "viola", "cello", "double_bass",
|
||||
"banjo", "harp", "pedal_steel",
|
||||
"bouzouki", "oud", "sitar", "shamisen", "erhu",
|
||||
"charango", "pipa", "balalaika", "lute",
|
||||
"charango", "pipa", "balalaika", "lute", "keyboard",
|
||||
]
|
||||
for name in instruments:
|
||||
fb = getattr(Fretboard, name)()
|
||||
@@ -2002,6 +2002,23 @@ def test_fretboard_pipa():
|
||||
assert len(fb) == 4
|
||||
|
||||
|
||||
def test_keyboard_88():
|
||||
kb = Fretboard.keyboard()
|
||||
assert len(kb) == 88
|
||||
|
||||
|
||||
def test_keyboard_25():
|
||||
kb = Fretboard.keyboard(25, "C3")
|
||||
assert len(kb) == 25
|
||||
assert kb.tones[-1].name == "C"
|
||||
assert kb.tones[-1].octave == 3
|
||||
|
||||
|
||||
def test_keyboard_custom():
|
||||
kb = Fretboard.keyboard(61, "C2")
|
||||
assert len(kb) == 61
|
||||
|
||||
|
||||
# ── Ergonomic integration tests ─────────────────────────────────────────────
|
||||
|
||||
def test_ergonomic_workflow():
|
||||
|
||||
Reference in New Issue
Block a user