Added music21 and csound examples
This commit is contained in:
101
example.musicxml
Normal file
101
example.musicxml
Normal file
@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 4.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
|
||||
<score-partwise version="4.0">
|
||||
<movement-title>Music21 Fragment</movement-title>
|
||||
<identification>
|
||||
<creator type="composer">Music21</creator>
|
||||
<encoding>
|
||||
<encoding-date>2023-06-27</encoding-date>
|
||||
<software>music21 v.9.1.0</software>
|
||||
</encoding>
|
||||
</identification>
|
||||
<defaults>
|
||||
<scaling>
|
||||
<millimeters>7</millimeters>
|
||||
<tenths>40</tenths>
|
||||
</scaling>
|
||||
</defaults>
|
||||
<part-list>
|
||||
<score-part id="P0c4c819b93d5335473e23baff277bd9f">
|
||||
<part-name />
|
||||
</score-part>
|
||||
</part-list>
|
||||
<!--=========================== Part 1 ===========================-->
|
||||
<part id="P0c4c819b93d5335473e23baff277bd9f">
|
||||
<!--========================= Measure 1 ==========================-->
|
||||
<measure implicit="no" number="1">
|
||||
<attributes>
|
||||
<divisions>10080</divisions>
|
||||
<time>
|
||||
<beats>4</beats>
|
||||
<beat-type>4</beat-type>
|
||||
</time>
|
||||
<clef>
|
||||
<sign>G</sign>
|
||||
<line>2</line>
|
||||
</clef>
|
||||
</attributes>
|
||||
<note>
|
||||
<pitch>
|
||||
<step>D</step>
|
||||
<alter>0</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>10080</duration>
|
||||
<type>quarter</type>
|
||||
</note>
|
||||
<note>
|
||||
<pitch>
|
||||
<step>E</step>
|
||||
<alter>0</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>10080</duration>
|
||||
<type>quarter</type>
|
||||
</note>
|
||||
<note>
|
||||
<rest />
|
||||
<duration>10080</duration>
|
||||
<type>quarter</type>
|
||||
</note>
|
||||
<note>
|
||||
<pitch>
|
||||
<step>D</step>
|
||||
<alter>0</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>5040</duration>
|
||||
<type>eighth</type>
|
||||
</note>
|
||||
<note>
|
||||
<chord />
|
||||
<pitch>
|
||||
<step>E</step>
|
||||
<alter>0</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>5040</duration>
|
||||
<type>eighth</type>
|
||||
<accidental>natural</accidental>
|
||||
</note>
|
||||
<note>
|
||||
<chord />
|
||||
<pitch>
|
||||
<step>G</step>
|
||||
<alter>0</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>5040</duration>
|
||||
<type>eighth</type>
|
||||
</note>
|
||||
<note print-object="no" print-spacing="yes">
|
||||
<rest />
|
||||
<duration>5040</duration>
|
||||
<type>eighth</type>
|
||||
</note>
|
||||
<barline location="right">
|
||||
<bar-style>light-heavy</bar-style>
|
||||
</barline>
|
||||
</measure>
|
||||
</part>
|
||||
</score-partwise>
|
||||
36
examples/csound/play_with_csound.py
Normal file
36
examples/csound/play_with_csound.py
Normal file
@ -0,0 +1,36 @@
|
||||
try:
|
||||
import ctcsound
|
||||
except (ImportError,TypeError):
|
||||
csound_imported = false
|
||||
|
||||
from ziffers import *
|
||||
|
||||
if(csound_imported):
|
||||
|
||||
# Parse ziffers notation
|
||||
parsed = zparse("w 0 1 q 0 1 2 3 r e 5 3 9 2 q r 0")
|
||||
|
||||
# Convert to csound score
|
||||
score = to_csound_score(parsed, 180, 1500, "Meep")
|
||||
|
||||
# Outputs: i {instrument} {start time} {duration} {amplitude} {pitch}
|
||||
print(score)
|
||||
|
||||
orc = """
|
||||
instr Meep
|
||||
out(linen(oscili(p4,p5),0.1,p3,0.1))
|
||||
endin
|
||||
"""
|
||||
|
||||
c = ctcsound.Csound()
|
||||
c.setOption("-odac") # Using SetOption() to configure Csound
|
||||
|
||||
c.compileOrc(orc)
|
||||
|
||||
c.readScore(score)
|
||||
|
||||
c.start()
|
||||
c.perform()
|
||||
c.stop()
|
||||
else:
|
||||
print("Csound not found! First download from https://csound.com/ and add to PATH or PYENV (Windows path: C:\Program Files\Csound6_x64\bin). Then install ctcsound with 'pip install ctcsound'.")
|
||||
20
examples/music21/create_midi_file.py
Normal file
20
examples/music21/create_midi_file.py
Normal file
@ -0,0 +1,20 @@
|
||||
from music21 import *
|
||||
from ziffers import *
|
||||
|
||||
|
||||
# Create melody string
|
||||
melody = "q 0 2 4 r e 1 4 3 2 s 0 1 2 6 e 2 8 2 1 h 0"
|
||||
#bass_line = "(q 0 2 4 6 e 1 4 3 2 s 0 1 2 6 e 2 8 2 1 h 0)-7"
|
||||
|
||||
# Parse ziffers notation to melody from string
|
||||
parsed = zparse(melody)
|
||||
#parsed_bass = zparse(bass_line)
|
||||
|
||||
# Convert to music21 object
|
||||
s2 = to_music21(parsed, time="4/4")
|
||||
|
||||
# Merge melody and bass line
|
||||
#s2.append(to_music21(parsed_bass, time="4/4"))
|
||||
|
||||
# Write to midi file under examples/music21/midi folder
|
||||
s2.write('midi', fp='examples/music21/output/ziffers_example.mid')
|
||||
9
examples/music21/create_musicxml.py
Normal file
9
examples/music21/create_musicxml.py
Normal file
@ -0,0 +1,9 @@
|
||||
from music21 import *
|
||||
from ziffers import *
|
||||
|
||||
# Parse ziiffers object to music21 object
|
||||
parsed = zparse("q 1 024 5 235 h 02345678{12} 0", key='C', scale='Zyditonic')
|
||||
s2 = to_music21(parsed,time="4/4")
|
||||
|
||||
# Save to MusicXML file
|
||||
s2.write('musicxml', fp='examples/music21/output/ziffers_example.xml')
|
||||
9
examples/music21/create_png.py
Normal file
9
examples/music21/create_png.py
Normal file
@ -0,0 +1,9 @@
|
||||
from music21 import *
|
||||
from ziffers import *
|
||||
|
||||
# Parse ziiffers object to music21 object
|
||||
parsed = zparse('1 2 qr e 124')
|
||||
s2 = to_music21(parsed,time="4/4")
|
||||
|
||||
# Save object as png file
|
||||
s2.write("musicxml.png", fp="examples/music21/output/example.png")
|
||||
@ -1,8 +0,0 @@
|
||||
from music21 import *
|
||||
from sardine import *
|
||||
from ziffers import *
|
||||
|
||||
|
||||
s = to_music21('(i v vi vii^dim)@(q0 e2 s1 012)',time="4/4")
|
||||
|
||||
s.show('midi')
|
||||
@ -1,9 +0,0 @@
|
||||
from music21 import *
|
||||
from sardine import *
|
||||
from ziffers import *
|
||||
|
||||
parsed = zparse('1 2 qr e 124')
|
||||
s2 = to_music21(parsed,time="4/4")
|
||||
|
||||
s2.show()
|
||||
s2.show('midi')
|
||||
BIN
examples/music21/output/example-1.png
Normal file
BIN
examples/music21/output/example-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
99
examples/music21/output/example.musicxml
Normal file
99
examples/music21/output/example.musicxml
Normal file
@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 4.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
|
||||
<score-partwise version="4.0">
|
||||
<identification>
|
||||
<encoding>
|
||||
<encoding-date>2023-06-27</encoding-date>
|
||||
<software>music21 v.9.1.0</software>
|
||||
</encoding>
|
||||
</identification>
|
||||
<defaults>
|
||||
<scaling>
|
||||
<millimeters>7</millimeters>
|
||||
<tenths>40</tenths>
|
||||
</scaling>
|
||||
</defaults>
|
||||
<part-list>
|
||||
<score-part id="P2a5e2bdd0bc8bab63f324063ff62ac90">
|
||||
<part-name />
|
||||
</score-part>
|
||||
</part-list>
|
||||
<!--=========================== Part 1 ===========================-->
|
||||
<part id="P2a5e2bdd0bc8bab63f324063ff62ac90">
|
||||
<!--========================= Measure 1 ==========================-->
|
||||
<measure implicit="no" number="1">
|
||||
<attributes>
|
||||
<divisions>10080</divisions>
|
||||
<time>
|
||||
<beats>4</beats>
|
||||
<beat-type>4</beat-type>
|
||||
</time>
|
||||
<clef>
|
||||
<sign>G</sign>
|
||||
<line>2</line>
|
||||
</clef>
|
||||
</attributes>
|
||||
<note>
|
||||
<pitch>
|
||||
<step>D</step>
|
||||
<alter>0</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>10080</duration>
|
||||
<type>quarter</type>
|
||||
</note>
|
||||
<note>
|
||||
<pitch>
|
||||
<step>E</step>
|
||||
<alter>0</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>10080</duration>
|
||||
<type>quarter</type>
|
||||
</note>
|
||||
<note>
|
||||
<rest />
|
||||
<duration>10080</duration>
|
||||
<type>quarter</type>
|
||||
</note>
|
||||
<note>
|
||||
<pitch>
|
||||
<step>D</step>
|
||||
<alter>0</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>5040</duration>
|
||||
<type>eighth</type>
|
||||
</note>
|
||||
<note>
|
||||
<chord />
|
||||
<pitch>
|
||||
<step>E</step>
|
||||
<alter>0</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>5040</duration>
|
||||
<type>eighth</type>
|
||||
<accidental>natural</accidental>
|
||||
</note>
|
||||
<note>
|
||||
<chord />
|
||||
<pitch>
|
||||
<step>G</step>
|
||||
<alter>0</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>5040</duration>
|
||||
<type>eighth</type>
|
||||
</note>
|
||||
<note print-object="no" print-spacing="yes">
|
||||
<rest />
|
||||
<duration>5040</duration>
|
||||
<type>eighth</type>
|
||||
</note>
|
||||
<barline location="right">
|
||||
<bar-style>light-heavy</bar-style>
|
||||
</barline>
|
||||
</measure>
|
||||
</part>
|
||||
</score-partwise>
|
||||
BIN
examples/music21/output/ziffers_example.mid
Normal file
BIN
examples/music21/output/ziffers_example.mid
Normal file
Binary file not shown.
228
examples/music21/output/ziffers_example.xml
Normal file
228
examples/music21/output/ziffers_example.xml
Normal file
@ -0,0 +1,228 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 4.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
|
||||
<score-partwise version="4.0">
|
||||
<movement-title>Music21 Fragment</movement-title>
|
||||
<identification>
|
||||
<creator type="composer">Music21</creator>
|
||||
<encoding>
|
||||
<encoding-date>2023-06-27</encoding-date>
|
||||
<software>music21 v.9.1.0</software>
|
||||
</encoding>
|
||||
</identification>
|
||||
<defaults>
|
||||
<scaling>
|
||||
<millimeters>7</millimeters>
|
||||
<tenths>40</tenths>
|
||||
</scaling>
|
||||
</defaults>
|
||||
<part-list>
|
||||
<score-part id="P381d8734c7dfe8b1fbfca186c059f010">
|
||||
<part-name />
|
||||
</score-part>
|
||||
</part-list>
|
||||
<!--=========================== Part 1 ===========================-->
|
||||
<part id="P381d8734c7dfe8b1fbfca186c059f010">
|
||||
<!--========================= Measure 1 ==========================-->
|
||||
<measure implicit="no" number="1">
|
||||
<attributes>
|
||||
<divisions>10080</divisions>
|
||||
<time>
|
||||
<beats>4</beats>
|
||||
<beat-type>4</beat-type>
|
||||
</time>
|
||||
<clef>
|
||||
<sign>G</sign>
|
||||
<line>2</line>
|
||||
</clef>
|
||||
</attributes>
|
||||
<note>
|
||||
<pitch>
|
||||
<step>C</step>
|
||||
<alter>1</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>10080</duration>
|
||||
<type>quarter</type>
|
||||
<accidental>sharp</accidental>
|
||||
</note>
|
||||
<note>
|
||||
<pitch>
|
||||
<step>C</step>
|
||||
<alter>0</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>10080</duration>
|
||||
<type>quarter</type>
|
||||
<accidental>natural</accidental>
|
||||
</note>
|
||||
<note>
|
||||
<chord />
|
||||
<pitch>
|
||||
<step>F</step>
|
||||
<alter>0</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>10080</duration>
|
||||
<type>quarter</type>
|
||||
</note>
|
||||
<note>
|
||||
<chord />
|
||||
<pitch>
|
||||
<step>A</step>
|
||||
<alter>0</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>10080</duration>
|
||||
<type>quarter</type>
|
||||
</note>
|
||||
<note>
|
||||
<pitch>
|
||||
<step>C</step>
|
||||
<alter>0</alter>
|
||||
<octave>5</octave>
|
||||
</pitch>
|
||||
<duration>10080</duration>
|
||||
<type>quarter</type>
|
||||
</note>
|
||||
<note>
|
||||
<pitch>
|
||||
<step>F</step>
|
||||
<alter>0</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>10080</duration>
|
||||
<type>quarter</type>
|
||||
</note>
|
||||
<note>
|
||||
<chord />
|
||||
<pitch>
|
||||
<step>G</step>
|
||||
<alter>0</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>10080</duration>
|
||||
<type>quarter</type>
|
||||
</note>
|
||||
<note>
|
||||
<chord />
|
||||
<pitch>
|
||||
<step>C</step>
|
||||
<alter>0</alter>
|
||||
<octave>5</octave>
|
||||
</pitch>
|
||||
<duration>10080</duration>
|
||||
<type>quarter</type>
|
||||
<accidental>natural</accidental>
|
||||
</note>
|
||||
</measure>
|
||||
<!--========================= Measure 2 ==========================-->
|
||||
<measure implicit="no" number="2">
|
||||
<note>
|
||||
<pitch>
|
||||
<step>C</step>
|
||||
<alter>0</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>20160</duration>
|
||||
<type>half</type>
|
||||
<accidental>natural</accidental>
|
||||
</note>
|
||||
<note>
|
||||
<chord />
|
||||
<pitch>
|
||||
<step>F</step>
|
||||
<alter>0</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>20160</duration>
|
||||
<type>half</type>
|
||||
<accidental>natural</accidental>
|
||||
</note>
|
||||
<note>
|
||||
<chord />
|
||||
<pitch>
|
||||
<step>G</step>
|
||||
<alter>0</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>20160</duration>
|
||||
<type>half</type>
|
||||
<accidental>natural</accidental>
|
||||
</note>
|
||||
<note>
|
||||
<chord />
|
||||
<pitch>
|
||||
<step>A</step>
|
||||
<alter>0</alter>
|
||||
<octave>4</octave>
|
||||
</pitch>
|
||||
<duration>20160</duration>
|
||||
<type>half</type>
|
||||
<accidental>natural</accidental>
|
||||
</note>
|
||||
<note>
|
||||
<chord />
|
||||
<pitch>
|
||||
<step>C</step>
|
||||
<alter>0</alter>
|
||||
<octave>5</octave>
|
||||
</pitch>
|
||||
<duration>20160</duration>
|
||||
<type>half</type>
|
||||
<accidental>natural</accidental>
|
||||
</note>
|
||||
<note>
|
||||
<chord />
|
||||
<pitch>
|
||||
<step>D</step>
|
||||
<alter>-1</alter>
|
||||
<octave>5</octave>
|
||||
</pitch>
|
||||
<duration>20160</duration>
|
||||
<type>half</type>
|
||||
<accidental>flat</accidental>
|
||||
</note>
|
||||
<note>
|
||||
<chord />
|
||||
<pitch>
|
||||
<step>F</step>
|
||||
<alter>0</alter>
|
||||
<octave>5</octave>
|
||||
</pitch>
|
||||
<duration>20160</duration>
|
||||
<type>half</type>
|
||||
<accidental>natural</accidental>
|
||||
</note>
|
||||
<note>
|
||||
<chord />
|
||||
<pitch>
|
||||
<step>G</step>
|
||||
<alter>0</alter>
|
||||
<octave>5</octave>
|
||||
</pitch>
|
||||
<duration>20160</duration>
|
||||
<type>half</type>
|
||||
<accidental>natural</accidental>
|
||||
</note>
|
||||
<note>
|
||||
<chord />
|
||||
<pitch>
|
||||
<step>F</step>
|
||||
<alter>0</alter>
|
||||
<octave>6</octave>
|
||||
</pitch>
|
||||
<duration>20160</duration>
|
||||
<type>half</type>
|
||||
<accidental>natural</accidental>
|
||||
</note>
|
||||
<note print-object="no" print-spacing="yes">
|
||||
<rest />
|
||||
<duration>20160</duration>
|
||||
<type>half</type>
|
||||
</note>
|
||||
<barline location="right">
|
||||
<bar-style>light-heavy</bar-style>
|
||||
</barline>
|
||||
</measure>
|
||||
</part>
|
||||
</score-partwise>
|
||||
9
examples/music21/show_in_musescore.py
Normal file
9
examples/music21/show_in_musescore.py
Normal file
@ -0,0 +1,9 @@
|
||||
from music21 import *
|
||||
from ziffers import *
|
||||
|
||||
# Parse Ziffers string to music21 object
|
||||
s = to_music21('(i v vi vii^dim)@(q0 e 2 1 q 012)', scale="Lydian", time="4/4")
|
||||
|
||||
# See https://web.mit.edu/music21/doc/installing/installAdditional.html
|
||||
# Attempt to open / show the midi in MuseScore
|
||||
s.show()
|
||||
@ -153,9 +153,17 @@ class Ziffers(Sequence):
|
||||
def pairs(self) -> list[tuple]:
|
||||
"""Return list of pitches and durations"""
|
||||
return [
|
||||
(val.get_pitch_class(), val.get_duration())
|
||||
[val.get_pitch_class(), val.get_duration()]
|
||||
for val in self.evaluated_values
|
||||
if isinstance(val, Pitch)
|
||||
if isinstance(val, Pitch) or isinstance(val, Chord) or isinstance(val, Rest)
|
||||
]
|
||||
|
||||
def freq_pairs(self) -> list[tuple]:
|
||||
"""Return list of pitches in freq and durations"""
|
||||
return [
|
||||
[val.get_freq(), val.get_duration()]
|
||||
for val in self.evaluated_values
|
||||
if isinstance(val, Pitch) or isinstance(val, Chord) or isinstance(val, Rest)
|
||||
]
|
||||
|
||||
def octaves(self) -> list[int]:
|
||||
@ -194,4 +202,4 @@ class Ziffers(Sequence):
|
||||
return all_items
|
||||
if len(all_items) == 1:
|
||||
return all_items[0]
|
||||
return None
|
||||
return None
|
||||
@ -7,12 +7,67 @@ try:
|
||||
except ImportError:
|
||||
music21_imported: bool = False
|
||||
|
||||
try:
|
||||
import ctcsound
|
||||
csound_imported: bool = True
|
||||
except (ImportError, TypeError) as Error:
|
||||
csound_imported: bool = False
|
||||
|
||||
def freq_to_pch(freq: float) -> str:
|
||||
"Format frequency to Csound PCH format"
|
||||
return f"{freq:.2f}"
|
||||
|
||||
# Csound score example: i1 0 1 0.5 8.00
|
||||
# 1. The first number is the instrument number. In this case it is instrument 1.
|
||||
# 2. The second number is the start time in seconds. In this case it is 0 seconds.
|
||||
# 3. The third number is the duration in seconds. In this case it is 1 second.
|
||||
# 4. The fourth number is the amplitude. In this case it is 0.5.
|
||||
# 5. The fifth number is the frequency. In this case it is 8 Hz.
|
||||
|
||||
def freqs_and_durations_to_csound_score(pairs: list[list[float|list[float], float|list[float]]], bpm: int=80, amp: float=0.5, instr: (int|str)=1) -> str:
|
||||
"""Tranforms list of lists containing frequencies and note lengths to csound score format.
|
||||
Note lengths are transformed in seconds with the bpm.
|
||||
Start time in seconds is calculated and summed from the note lengths.
|
||||
If frequency is None, then it is a rest.
|
||||
If frequency is a list, then it is a chord.
|
||||
|
||||
Example input: [[261.6255653005986, 0.5], [None, 0.25], [440.0, 0.125], [[261.6255653005986, 329.62755691286986, 391.9954359817492], [0.25, 0.125, 0.25]]]"""
|
||||
score = ""
|
||||
instr = f'"{instr}"' if isinstance(instr, str) else instr
|
||||
start_time = 0
|
||||
for pair in pairs:
|
||||
if isinstance(pair[0], list):
|
||||
for freq, dur in zip(pair[0], pair[1]):
|
||||
score += f"i {instr} {start_time} {dur * 4 * 60 / bpm} {amp} {freq_to_pch(freq)}\n"
|
||||
start_time += max(pair[1]) * 4 * 60 / bpm
|
||||
else:
|
||||
if pair[0] is None:
|
||||
score += f"i {instr} {start_time} {pair[1] * 4 * 60 / bpm} {amp} 0\n"
|
||||
else:
|
||||
score += f"i {instr} {start_time} {pair[1] * 4 * 60 / bpm} {amp} {freq_to_pch(pair[0])}\n"
|
||||
start_time += pair[1] * 4 * 60 / bpm
|
||||
return score
|
||||
|
||||
def to_csound_score(expression: str | Ziffers, bpm: int=80, amp: float=0.5, instr: (int|str)=1) -> str:
|
||||
""" Transform Ziffers object to Csound score """
|
||||
if not csound_imported:
|
||||
raise ImportError("Install Csound library")
|
||||
|
||||
if isinstance(expression, Ziffers):
|
||||
score = freqs_and_durations_to_csound_score(expression.freq_pairs(),bpm,amp,instr)
|
||||
else:
|
||||
parsed = zparse(expression)
|
||||
score = freqs_and_durations_to_csound_score(parsed.freq_pairs(),bpm,amp,instr)
|
||||
|
||||
return score
|
||||
|
||||
def to_music21(expression: str | Ziffers, **options):
|
||||
"""Helper for passing options to the parser"""
|
||||
|
||||
if not music21_imported:
|
||||
raise ImportError("Install Music21 library")
|
||||
|
||||
# Register the ZiffersMusic21 converter
|
||||
converter.registerSubconverter(ZiffersMusic21)
|
||||
|
||||
if isinstance(expression, Ziffers):
|
||||
|
||||
Reference in New Issue
Block a user