Some refactoring
This commit is contained in:
@ -213,6 +213,7 @@ class Chord(Event):
|
|||||||
|
|
||||||
pitch_classes: list[Pitch] = field(default=None)
|
pitch_classes: list[Pitch] = field(default=None)
|
||||||
notes: list[int] = field(default=None)
|
notes: list[int] = field(default=None)
|
||||||
|
freqs: list[float] = field(default=None, init=False)
|
||||||
|
|
||||||
def set_notes(self, notes: list[int]):
|
def set_notes(self, notes: list[int]):
|
||||||
"""Set notes to the class"""
|
"""Set notes to the class"""
|
||||||
@ -221,11 +222,16 @@ class Chord(Event):
|
|||||||
def update_notes(self, options):
|
def update_notes(self, options):
|
||||||
"""Update notes"""
|
"""Update notes"""
|
||||||
notes = []
|
notes = []
|
||||||
|
freqs = []
|
||||||
|
|
||||||
for pitch in self.pitch_classes:
|
for pitch in self.pitch_classes:
|
||||||
pitch.update_options(options)
|
pitch.update_options(options)
|
||||||
pitch.update_note()
|
pitch.update_note()
|
||||||
notes.append(pitch.note)
|
notes.append(pitch.note)
|
||||||
|
freqs.append(pitch.freq)
|
||||||
|
|
||||||
self.notes = notes
|
self.notes = notes
|
||||||
|
self.freqs = freqs
|
||||||
|
|
||||||
|
|
||||||
@dataclass(kw_only=True)
|
@dataclass(kw_only=True)
|
||||||
@ -373,7 +379,7 @@ class Sequence(Meta):
|
|||||||
|
|
||||||
def _loop_items(items, options):
|
def _loop_items(items, options):
|
||||||
for item in items:
|
for item in items:
|
||||||
yield from _resolve_item(item, options)
|
yield from _resolve_item(item, options)
|
||||||
|
|
||||||
def _update_options(current: Item, options: dict) -> dict:
|
def _update_options(current: Item, options: dict) -> dict:
|
||||||
"""Update options based on current item"""
|
"""Update options based on current item"""
|
||||||
@ -481,6 +487,7 @@ class Ziffers(Sequence):
|
|||||||
"""Main class for holding options and the current state"""
|
"""Main class for holding options and the current state"""
|
||||||
|
|
||||||
options: dict = field(default_factory=DEFAULT_OPTIONS)
|
options: dict = field(default_factory=DEFAULT_OPTIONS)
|
||||||
|
start_options: dict = None
|
||||||
loop_i: int = 0
|
loop_i: int = 0
|
||||||
iterator = None
|
iterator = None
|
||||||
current: Item = field(default=None)
|
current: Item = field(default=None)
|
||||||
@ -505,12 +512,13 @@ class Ziffers(Sequence):
|
|||||||
else:
|
else:
|
||||||
self.options = DEFAULT_OPTIONS
|
self.options = DEFAULT_OPTIONS
|
||||||
|
|
||||||
|
self.start_options = self.options.copy()
|
||||||
self.evaluated_values = list(self.evaluate_tree(self.options))
|
self.evaluated_values = list(self.evaluate_tree(self.options))
|
||||||
self.iterator = iter(self.evaluated_values)
|
self.iterator = iter(self.evaluated_values)
|
||||||
|
|
||||||
def re_eval(self, options=None):
|
def re_eval(self, options=None):
|
||||||
"""Re-evaluate the iterator"""
|
"""Re-evaluate the iterator"""
|
||||||
self.options.update(DEFAULT_OPTIONS)
|
self.options = self.start_options.copy()
|
||||||
if options:
|
if options:
|
||||||
self.options.update(options)
|
self.options.update(options)
|
||||||
self.evaluated_values = list(self.evaluate_tree(self.options))
|
self.evaluated_values = list(self.evaluate_tree(self.options))
|
||||||
@ -628,11 +636,13 @@ class Subdivision(Sequence):
|
|||||||
has_children: bool = field(default=False, init=False)
|
has_children: bool = field(default=False, init=False)
|
||||||
|
|
||||||
def evaluate(self, options):
|
def evaluate(self, options):
|
||||||
|
"""Evaluate tree and then calculate lengths using subdivision"""
|
||||||
self.evaluated_values = list(self.evaluate_tree(options.copy()))
|
self.evaluated_values = list(self.evaluate_tree(options.copy()))
|
||||||
self.evaluated_values = list(self.evaluate_subdivisions(options))
|
self.evaluated_values = list(self.evaluate_subdivisions(options))
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def evaluate_subdivisions(self, options):
|
def evaluate_subdivisions(self, options):
|
||||||
|
"""Calculate new durations by dividing with the number of items in the sequence"""
|
||||||
self.subdiv_length = len(self.evaluated_values)
|
self.subdiv_length = len(self.evaluated_values)
|
||||||
self.local_options = options.copy()
|
self.local_options = options.copy()
|
||||||
self.local_options["duration"] = options["duration"] / self.subdiv_length
|
self.local_options["duration"] = options["duration"] / self.subdiv_length
|
||||||
@ -785,6 +795,7 @@ class Euclid(Item):
|
|||||||
evaluated_values: list = field(default=None)
|
evaluated_values: list = field(default=None)
|
||||||
|
|
||||||
def evaluate(self, options):
|
def evaluate(self, options):
|
||||||
|
"""Evaluate values using euclidean spread"""
|
||||||
onset_values = [
|
onset_values = [
|
||||||
val for val in self.onset.values if not isinstance(val, Whitespace)
|
val for val in self.onset.values if not isinstance(val, Whitespace)
|
||||||
]
|
]
|
||||||
|
|||||||
@ -58,13 +58,13 @@ def string_rewrite(axiom: str, rules: dict):
|
|||||||
def euclidian_rhythm(pulses: int, length: int, rotate: int = 0):
|
def euclidian_rhythm(pulses: int, length: int, rotate: int = 0):
|
||||||
"""Calculate Euclidean rhythms. Original algorithm by Thomas Morrill."""
|
"""Calculate Euclidean rhythms. Original algorithm by Thomas Morrill."""
|
||||||
|
|
||||||
def _starts_descent(list, index):
|
def _starts_descent(arr, index):
|
||||||
length = len(list)
|
length = len(arr)
|
||||||
next_index = (index + 1) % length
|
next_index = (index + 1) % length
|
||||||
return list[index] > list[next_index]
|
return arr[index] > arr[next_index]
|
||||||
|
|
||||||
def rotation(l, n):
|
def rotation(arr, idx):
|
||||||
return l[-n:] + l[:-n]
|
return arr[-idx:] + arr[:-idx]
|
||||||
|
|
||||||
if pulses >= length:
|
if pulses >= length:
|
||||||
return [True]
|
return [True]
|
||||||
|
|||||||
@ -1,40 +1,44 @@
|
|||||||
"""Collection of converters"""
|
"""Collection of converters"""
|
||||||
from music21 import converter, note, stream, meter, chord
|
from music21 import converter, note, stream, meter, chord, environment
|
||||||
from ziffers import zparse, Ziffers, Pitch, Rest, Chord
|
from ziffers import zparse, Ziffers, Pitch, Rest, Chord
|
||||||
|
|
||||||
def to_music21(strData: str|Ziffers, **options):
|
|
||||||
|
def to_music21(expression: str | Ziffers, **options):
|
||||||
"""Helper for passing options to the parser"""
|
"""Helper for passing options to the parser"""
|
||||||
converter.registerSubconverter(ZiffersMusic21)
|
converter.registerSubconverter(ZiffersMusic21)
|
||||||
|
|
||||||
if isinstance(strData,Ziffers):
|
if isinstance(expression, Ziffers):
|
||||||
if options:
|
if options:
|
||||||
options["preparsed"] = strData
|
options["preparsed"] = expression
|
||||||
else:
|
else:
|
||||||
options = {"preparsed": strData}
|
options = {"preparsed": expression}
|
||||||
options = {"ziffers": options}
|
options = {"ziffers": options}
|
||||||
return converter.parse("PREPARSED", format="ziffers", keywords=options)
|
return converter.parse("PREPARSED", format="ziffers", keywords=options)
|
||||||
|
|
||||||
if options:
|
if options:
|
||||||
options = {"ziffers": options}
|
options = {"ziffers": options}
|
||||||
return converter.parse(strData, format="ziffers", keywords=options)
|
return converter.parse(expression, format="ziffers", keywords=options)
|
||||||
else:
|
|
||||||
test = converter.parse(strData, format="ziffers")
|
test = converter.parse(expression, format="ziffers")
|
||||||
return test
|
return test
|
||||||
|
|
||||||
|
|
||||||
def set_musescore_path(path: str):
|
def set_musescore_path(path: str):
|
||||||
"""Helper for setting the Musescore path"""
|
"""Helper for setting the Musescore path"""
|
||||||
us = environment.UserSettings()
|
settings = environment.UserSettings()
|
||||||
# Default windows path:
|
# Default windows path:
|
||||||
# 'C:\\Program Files\\MuseScore 3\\bin\\MuseScore3.exe'
|
# 'C:\\Program Files\\MuseScore 3\\bin\\MuseScore3.exe'
|
||||||
us['musicxmlPath'] = path
|
settings["musicxmlPath"] = path
|
||||||
us['musescoreDirectPNGPath'] = path
|
settings["musescoreDirectPNGPath"] = path
|
||||||
|
|
||||||
|
|
||||||
class ZiffersMusic21(converter.subConverters.SubConverter):
|
class ZiffersMusic21(converter.subConverters.SubConverter):
|
||||||
"""Ziffers converter to Music21"""
|
"""Ziffers converter to Music21"""
|
||||||
|
|
||||||
registerFormats = ("ziffers",)
|
registerFormats = ("ziffers",)
|
||||||
registerInputExtensions = ("zf",)
|
registerInputExtensions = ("zf",)
|
||||||
|
|
||||||
def parseData(self, strData, number=None):
|
def parseData(self, dataString, number=None):
|
||||||
"""Parses Ziffers string to Music21 object"""
|
"""Parses Ziffers string to Music21 object"""
|
||||||
# Look for options in keywords object
|
# Look for options in keywords object
|
||||||
keywords = self.keywords["keywords"]
|
keywords = self.keywords["keywords"]
|
||||||
@ -43,25 +47,25 @@ class ZiffersMusic21(converter.subConverters.SubConverter):
|
|||||||
if "preparsed" in options:
|
if "preparsed" in options:
|
||||||
parsed = options["preparsed"]
|
parsed = options["preparsed"]
|
||||||
else:
|
else:
|
||||||
parsed = zparse(strData, **options)
|
parsed = zparse(dataString, **options)
|
||||||
else:
|
else:
|
||||||
parsed = zparse(strData)
|
parsed = zparse(dataString)
|
||||||
|
|
||||||
s = stream.Part()
|
note_stream = stream.Part()
|
||||||
if "time" in options:
|
if "time" in options:
|
||||||
m = meter.TimeSignature(options["time"]) # Common time
|
m_item = meter.TimeSignature(options["time"]) # Common time
|
||||||
else:
|
else:
|
||||||
m = meter.TimeSignature("c") # Common time
|
m_item = meter.TimeSignature("c") # Common time
|
||||||
|
|
||||||
s.insert(0, m)
|
note_stream.insert(0, m_item)
|
||||||
for item in parsed:
|
for item in parsed:
|
||||||
if isinstance(item,Pitch):
|
if isinstance(item, Pitch):
|
||||||
m_item = note.Note(item.note)
|
m_item = note.Note(item.note)
|
||||||
m_item.duration.quarterLength = item.duration * 4
|
m_item.duration.quarterLength = item.duration * 4
|
||||||
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.notes)
|
m_item = chord.Chord(item.notes)
|
||||||
m_item.duration.quarterLength = item.duration * 4
|
m_item.duration.quarterLength = item.duration * 4
|
||||||
s.append(m_item)
|
note_stream.append(m_item)
|
||||||
self.stream = s.makeMeasures()
|
self.stream = note_stream.makeMeasures()
|
||||||
|
|||||||
Reference in New Issue
Block a user