Fixed some bugs

This commit is contained in:
2023-02-26 21:41:30 +02:00
parent 78295da323
commit da020cc3a2
3 changed files with 98 additions and 40 deletions

View File

@ -125,3 +125,21 @@ def test_measure_durations(pattern: str, expected: list):
) )
def test_measure_octaves(pattern: str, expected: list): def test_measure_octaves(pattern: str, expected: list):
assert collect(zparse(pattern),len(expected)*2,"octave") == expected*2 assert collect(zparse(pattern),len(expected)*2,"octave") == expected*2
@pytest.mark.parametrize(
"pattern,expected",
[
("e r qr r q r", [0.125, 0.25, 0.125, 0.25])
]
)
def test_rest(pattern: str, expected: list):
assert collect(zparse(pattern),len(expected)*2,"duration") == expected*2
@pytest.mark.parametrize(
"pattern,expected",
[
("-3..9 1..9", [55, 57, 59, 60, 62, 64, 65, 67, 69, 71, 72, 74, 76, 62, 64, 65, 67, 69, 71, 72, 74, 76])
]
)
def test_ranges(pattern: str, expected: list):
assert collect(zparse(pattern),len(expected)*2,"note") == expected*2

View File

@ -136,14 +136,16 @@ class Event(Item):
class Rest(Event): class Rest(Event):
"""Class for rests""" """Class for rests"""
@dataclass
@dataclass
class Measure(Item): class Measure(Item):
""" Class for measures/bars. Used to reset default options. """ """Class for measures/bars. Used to reset default options."""
text: str = field(default="|", init=False) text: str = field(default="|", init=False)
def reset_options(self, options: dict): def reset_options(self, options: dict):
"""Reset options when measure changes""" """Reset options when measure changes"""
next_measure = options.get("measure", 0)+1 next_measure = options.get("measure", 0) + 1
start_options = options["start_options"].copy() start_options = options["start_options"].copy()
options.clear() options.clear()
options.update(start_options) options.update(start_options)
@ -151,6 +153,7 @@ class Measure(Item):
options["start_options"] = start_options.copy() options["start_options"] = start_options.copy()
self.measure = next_measure self.measure = next_measure
@dataclass(kw_only=True) @dataclass(kw_only=True)
class Pitch(Event): class Pitch(Event):
"""Class for pitch in time""" """Class for pitch in time"""
@ -170,6 +173,30 @@ class Pitch(Event):
self.text = str(self.pitch_class) self.text = str(self.pitch_class)
self.update_note() self.update_note()
def get_note(self):
"""Getter for note"""
return self.note
def get_freq(self):
"""Getter for freq"""
return self.freq
def get_octave(self):
"""Getter for octave"""
return self.octave
def get_beat(self):
"""Getter for beat"""
return self.beat
def get_pitch_class(self):
"""Getter for pitche"""
return self.pitch_class
def get_duration(self):
"""Getter for duration"""
return self.duration
def update_note(self, force: bool = False): def update_note(self, force: bool = False):
"""Update note if Key, Scale and Pitch-class are present""" """Update note if Key, Scale and Pitch-class are present"""
if ( if (
@ -227,7 +254,6 @@ class Pitch(Event):
return self.pitch_class return self.pitch_class
@dataclass(kw_only=True) @dataclass(kw_only=True)
class RandomPitch(Event): class RandomPitch(Event):
"""Class for random pitch""" """Class for random pitch"""
@ -257,13 +283,13 @@ class Chord(Event):
"""Class for chords""" """Class for chords"""
pitch_classes: list[Pitch] = field(default=None) pitch_classes: list[Pitch] = field(default=None)
note: list[int] = field(default=None) notes: list[int] = field(default=None)
inversions: int = field(default=None) inversions: int = field(default=None)
pitch_class: list[int] = field(default=None, init=False) pitches: list[int] = field(default=None, init=False)
freq: list[float] = field(default=None, init=False) freqs: list[float] = field(default=None, init=False)
octave: list[int] = field(default=None, init=False) octaves: list[int] = field(default=None, init=False)
duration: list[float] = field(default=None, init=False) durations: list[float] = field(default=None, init=False)
beat: list[float] = field(default=None, init=False) beats: list[float] = field(default=None, init=False)
def __post_init__(self): def __post_init__(self):
if self.inversions is not None: if self.inversions is not None:
@ -271,7 +297,31 @@ class Chord(Event):
def set_notes(self, notes: list[int]): def set_notes(self, notes: list[int]):
"""Set notes to the class""" """Set notes to the class"""
self.note = notes self.notes = notes
def get_note(self):
"""Getter for notes"""
return self.notes
def get_freq(self):
"""Getter for freqs"""
return self.freqs
def get_octave(self):
"""Getter for octaves"""
return self.octaves
def get_beat(self):
"""Getter for beats"""
return self.beats
def get_pitch_class(self):
"""Getter for pitches"""
return self.pitches
def get_duration(self):
"""Getter for durations"""
return self.durations
def invert(self, value: int): def invert(self, value: int):
"""Chord inversion""" """Chord inversion"""
@ -307,12 +357,12 @@ class Chord(Event):
durations.append(pitch.duration) durations.append(pitch.duration)
beats.append(pitch.beat) beats.append(pitch.beat)
self.pitch = pitches self.pitches = pitches
self.note = notes self.notes = notes
self.freq = freqs self.freqs = freqs
self.octave = octaves self.octaves = octaves
self.duration = durations self.durations = durations
self.beat = beats self.beats = beats
@dataclass(kw_only=True) @dataclass(kw_only=True)
@ -596,7 +646,7 @@ class Sequence(Meta):
chord = Chord( chord = Chord(
text=pitch_text, text=pitch_text,
pitch_classes=pitch_classes, pitch_classes=pitch_classes,
note=chord_notes, notes=chord_notes,
kwargs=options, kwargs=options,
inversions=current.inversions, inversions=current.inversions,
) )
@ -718,7 +768,7 @@ class Ziffers(Sequence):
def pitch_classes(self) -> list[int]: def pitch_classes(self) -> list[int]:
"""Return list of pitch classes as ints""" """Return list of pitch classes as ints"""
return [ return [
val.pitch_class val.get_pitch_class()
for val in self.evaluated_values for val in self.evaluated_values
if isinstance(val, (Pitch, Chord)) if isinstance(val, (Pitch, Chord))
] ]
@ -726,29 +776,21 @@ class Ziffers(Sequence):
def notes(self) -> list[int]: def notes(self) -> list[int]:
"""Return list of midi notes""" """Return list of midi notes"""
return [ return [
val.note val.get_note() for val in self.evaluated_values if isinstance(val, (Pitch, Chord))
for val in self.evaluated_values
if isinstance(val, (Pitch, Chord))
] ]
def durations(self) -> list[float]: def durations(self) -> list[float]:
"""Return list of pitch durations as floats""" """Return list of pitch durations as floats"""
return [ return [val.get_duration() for val in self.evaluated_values if isinstance(val, Event)]
val.duration
for val in self.evaluated_values
if isinstance(val, Event)
]
def beats(self) -> list[float]: def beats(self) -> list[float]:
"""Return list of pitch durations as floats""" """Return list of pitch durations as floats"""
return [ return [val.get_beat() for val in self.evaluated_values if isinstance(val, Event)]
val.beat for val in self.evaluated_values if isinstance(val, Event)
]
def pairs(self) -> list[tuple]: def pairs(self) -> list[tuple]:
"""Return list of pitches and durations""" """Return list of pitches and durations"""
return [ return [
(val.pitch_class, val.duration) (val.get_pitch_class(), val.get_duration())
for val in self.evaluated_values for val in self.evaluated_values
if isinstance(val, Pitch) if isinstance(val, Pitch)
] ]
@ -756,7 +798,7 @@ class Ziffers(Sequence):
def octaves(self) -> list[int]: def octaves(self) -> list[int]:
"""Return list of octaves""" """Return list of octaves"""
return [ return [
val.octave val.get_octave()
for val in self.evaluated_values for val in self.evaluated_values
if isinstance(val, (Pitch, Chord)) if isinstance(val, (Pitch, Chord))
] ]
@ -764,9 +806,7 @@ class Ziffers(Sequence):
def freqs(self) -> list[int]: def freqs(self) -> list[int]:
"""Return list of octaves""" """Return list of octaves"""
return [ return [
val.freq val.get_freq() for val in self.evaluated_values if isinstance(val, (Pitch, Chord))
for val in self.evaluated_values
if isinstance(val, (Pitch, Chord))
] ]
@ -888,12 +928,12 @@ class Range(Item):
merged_options["octave"] += options["octave"] merged_options["octave"] += options["octave"]
if self.start < self.end: if self.start < self.end:
for i in range(self.start, self.end + 1): for i in range(self.start, self.end + 1):
yield Pitch(pitch_class=i, local_options=merged_options) yield Pitch(pitch_class=i, kwargs=merged_options)
elif self.start > self.end: elif self.start > self.end:
for i in reversed(range(self.end, self.start + 1)): for i in reversed(range(self.end, self.start + 1)):
yield Pitch(pitch_class=i, local_options=merged_options) yield Pitch(pitch_class=i, kwargs=merged_options)
else: else:
yield Pitch(pitch_class=self.start, local_options=merged_options) yield Pitch(pitch_class=self.start, kwargs=merged_options)
@dataclass(kw_only=True) @dataclass(kw_only=True)

View File

@ -65,7 +65,7 @@ class ZiffersMusic21(converter.subConverters.SubConverter):
elif isinstance(item, Rest): elif isinstance(item, Rest):
m_item = note.Rest(item.duration * 4) m_item = note.Rest(item.duration * 4)
elif isinstance(item, Chord): elif isinstance(item, Chord):
m_item = chord.Chord(item.note) m_item = chord.Chord(item.notes)
m_item.duration.quarterLength = item.duration * 4 m_item.duration.quarterLength = item.durations * 4
note_stream.append(m_item) note_stream.append(m_item)
self.stream = note_stream.makeMeasures() self.stream = note_stream.makeMeasures()