Added basic music21 converter
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@ -165,6 +165,7 @@ cython_debug/
|
||||
# VSCode
|
||||
.vscode
|
||||
|
||||
# Debugging file
|
||||
# Debugging files
|
||||
debug.py
|
||||
test.py
|
||||
|
||||
|
||||
10
test.py
10
test.py
@ -1,4 +1,8 @@
|
||||
from ziffers import *
|
||||
# a = z1("q e 1 ^ ^ 2 _ 3 4 <3> 3")
|
||||
a = z1("1 2")
|
||||
print(a.take(3))
|
||||
from music21 import *
|
||||
|
||||
z = z('e (1 2 3)+(4 2 1)*2')
|
||||
s = to_music21(z,octave=-2,time="3/4")
|
||||
|
||||
s.show()
|
||||
s.show('midi')
|
||||
|
||||
@ -4,3 +4,4 @@ from .classes import *
|
||||
from .common import *
|
||||
from .defaults import *
|
||||
from .scale import *
|
||||
from .converters import *
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
""" 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
|
||||
import operator
|
||||
import random
|
||||
@ -31,6 +31,9 @@ class Meta:
|
||||
if getattr(self, key) is None:
|
||||
setattr(self, key, value)
|
||||
|
||||
def dict(self):
|
||||
return {k: str(v) for k, v in asdict(self).items()}
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Item(Meta):
|
||||
|
||||
61
ziffers/converters.py
Normal file
61
ziffers/converters.py
Normal 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()
|
||||
Reference in New Issue
Block a user