Transpose
This commit is contained in:
@@ -1,26 +1,18 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from itertools import product
|
||||
from typing import NamedTuple
|
||||
|
||||
from generator.transposition import mod12
|
||||
from generator import harmony
|
||||
from generator.model import NATURAL, alteration
|
||||
|
||||
STANDARD_TUNING = ((6, 40), (5, 45), (4, 50), (3, 55), (2, 59), (1, 64))
|
||||
WRITTEN_GUITAR_OCTAVE_OFFSET = 12
|
||||
|
||||
class TabPosition(NamedTuple):
|
||||
string_number: int
|
||||
fret: int
|
||||
midi: int
|
||||
from generator.guitar import MAX_FRET, MIN_FRET, STANDARD_TUNING, TabPosition, WRITTEN_GUITAR_OCTAVE_OFFSET, within_fret_span
|
||||
|
||||
def chord_pitch_classes(symbol: str | dict) -> tuple[int, ...]:
|
||||
return harmony.pitch_classes(harmony.parse_symbol(symbol) if isinstance(symbol, str) else symbol)
|
||||
|
||||
def positions_for_string(string_number: int, open_midi: int, pitch_classes: tuple[int, ...]) -> list[TabPosition]:
|
||||
result: list[TabPosition] = []
|
||||
for fret in range(0, 13):
|
||||
for fret in range(MIN_FRET, MAX_FRET + 1):
|
||||
midi = open_midi + fret
|
||||
if mod12(midi) in pitch_classes:
|
||||
result.append(TabPosition(string_number, fret, midi))
|
||||
@@ -63,14 +55,13 @@ def find_playable_voicing(symbol: str | dict) -> list[TabPosition]:
|
||||
best: tuple[TabPosition, ...] | None = None
|
||||
best_score = 10**9
|
||||
for string_set in string_sets:
|
||||
options = [by_string[string_number][:8] for string_number in string_set]
|
||||
options = [by_string[string_number] for string_number in string_set]
|
||||
if any(not item for item in options):
|
||||
continue
|
||||
for candidate in product(*options):
|
||||
if bass_pc is not None and min(candidate, key=lambda p: p.midi).midi % 12 != bass_pc:
|
||||
continue
|
||||
fretted = [position.fret for position in candidate if position.fret > 0]
|
||||
if fretted and max(fretted) - min(fretted) > 4:
|
||||
if not within_fret_span(candidate):
|
||||
continue
|
||||
covered = {mod12(position.midi) for position in candidate}
|
||||
if not set(pitch_classes).issubset(covered):
|
||||
|
||||
Reference in New Issue
Block a user