Added basic music21 converter

This commit is contained in:
2023-02-13 17:28:42 +02:00
parent 7cc89d3333
commit e240c45693
5 changed files with 75 additions and 5 deletions

3
.gitignore vendored
View File

@ -165,6 +165,7 @@ cython_debug/
# VSCode # VSCode
.vscode .vscode
# Debugging file # Debugging files
debug.py debug.py
test.py

10
test.py
View File

@ -1,4 +1,8 @@
from ziffers import * from ziffers import *
# a = z1("q e 1 ^ ^ 2 _ 3 4 <3> 3") from music21 import *
a = z1("1 2")
print(a.take(3)) z = z('e (1 2 3)+(4 2 1)*2')
s = to_music21(z,octave=-2,time="3/4")
s.show()
s.show('midi')

View File

@ -4,3 +4,4 @@ from .classes import *
from .common import * from .common import *
from .defaults import * from .defaults import *
from .scale import * from .scale import *
from .converters import *

View File

@ -1,5 +1,5 @@
""" Ziffers classes for the parsed notation """ """ Ziffers classes for the parsed notation """
from dataclasses import dataclass, field, replace from dataclasses import dataclass, field, replace, asdict
from itertools import product, islice, cycle from itertools import product, islice, cycle
import operator import operator
import random import random
@ -31,6 +31,9 @@ class Meta:
if getattr(self, key) is None: if getattr(self, key) is None:
setattr(self, key, value) setattr(self, key, value)
def dict(self):
return {k: str(v) for k, v in asdict(self).items()}
@dataclass(kw_only=True) @dataclass(kw_only=True)
class Item(Meta): class Item(Meta):

61
ziffers/converters.py Normal file
View File

@ -0,0 +1,61 @@
"""Collection of converters"""
from music21 import converter, note, stream, meter
from ziffers import zparse, Ziffers
def to_music21(strData: str|Ziffers, **options):
"""Helper for passing options to the parser"""
converter.registerSubconverter(ZiffersMusic21)
if isinstance(strData,Ziffers):
if options:
options["preparsed"] = strData
else:
options = {"preparsed": strData}
options = {"ziffers": options}
return converter.parse("PREPARSED", format="ziffers", keywords=options)
if options:
options = {"ziffers": options}
return converter.parse(strData, format="ziffers", keywords=options)
else:
test = converter.parse(strData, format="ziffers")
return test
def set_musescore_path(path: str):
"""Helper for setting the Musescore path"""
us = environment.UserSettings()
# Default windows path:
# 'C:\\Program Files\\MuseScore 3\\bin\\MuseScore3.exe'
us['musicxmlPath'] = path
us['musescoreDirectPNGPath'] = path
class ZiffersMusic21(converter.subConverters.SubConverter):
"""Ziffers converter to Music21"""
registerFormats = ("ziffers",)
registerInputExtensions = ("zf",)
def parseData(self, strData, number=None):
"""Parses Ziffers string to Music21 object"""
# Look for options in keywords object
keywords = self.keywords["keywords"]
if "ziffers" in keywords:
options = keywords["ziffers"]
if "preparsed" in options:
parsed = options["preparsed"]
else:
parsed = zparse(strData, **options)
else:
parsed = zparse(strData)
s = stream.Part()
if "time" in options:
m = meter.TimeSignature(options["time"]) # Common time
else:
m = meter.TimeSignature("c") # Common time
s.insert(0, m)
for z in parsed:
m_note = note.Note(z.note)
m_note.duration.quarterLength = z.duration * 4
s.append(m_note)
self.stream = s.makeMeasures()