partitura 1.4.1__tar.gz → 1.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {partitura-1.4.1 → partitura-1.6.0}/PKG-INFO +13 -2
- {partitura-1.4.1 → partitura-1.6.0}/partitura/__init__.py +6 -1
- partitura-1.6.0/partitura/assets/score_example.mei +69 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/directions.py +1 -23
- {partitura-1.4.1 → partitura-1.6.0}/partitura/io/__init__.py +39 -9
- {partitura-1.4.1 → partitura-1.6.0}/partitura/io/exportaudio.py +79 -4
- partitura-1.6.0/partitura/io/exportkern.py +344 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/io/exportmatch.py +8 -3
- partitura-1.6.0/partitura/io/exportmei.py +645 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/io/exportmidi.py +41 -1
- {partitura-1.4.1 → partitura-1.6.0}/partitura/io/exportmusicxml.py +66 -10
- partitura-1.6.0/partitura/io/importdcml.py +353 -0
- partitura-1.6.0/partitura/io/importkern.py +913 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/io/importmatch.py +90 -88
- {partitura-1.4.1 → partitura-1.6.0}/partitura/io/importmei.py +48 -12
- {partitura-1.4.1 → partitura-1.6.0}/partitura/io/importmidi.py +183 -29
- {partitura-1.4.1 → partitura-1.6.0}/partitura/io/importmusic21.py +15 -9
- {partitura-1.4.1 → partitura-1.6.0}/partitura/io/importmusicxml.py +225 -12
- {partitura-1.4.1 → partitura-1.6.0}/partitura/io/importnakamura.py +1 -1
- {partitura-1.4.1 → partitura-1.6.0}/partitura/io/matchfile_utils.py +2 -1
- {partitura-1.4.1 → partitura-1.6.0}/partitura/io/matchlines_v1.py +8 -6
- {partitura-1.4.1 → partitura-1.6.0}/partitura/musicanalysis/key_identification.py +10 -67
- {partitura-1.4.1 → partitura-1.6.0}/partitura/musicanalysis/meter.py +14 -16
- {partitura-1.4.1 → partitura-1.6.0}/partitura/musicanalysis/note_array_to_score.py +1 -1
- {partitura-1.4.1 → partitura-1.6.0}/partitura/musicanalysis/note_features.py +138 -8
- {partitura-1.4.1 → partitura-1.6.0}/partitura/musicanalysis/performance_codec.py +36 -24
- {partitura-1.4.1 → partitura-1.6.0}/partitura/musicanalysis/performance_features.py +1 -1
- {partitura-1.4.1 → partitura-1.6.0}/partitura/performance.py +37 -7
- {partitura-1.4.1 → partitura-1.6.0}/partitura/score.py +1507 -308
- {partitura-1.4.1 → partitura-1.6.0}/partitura/utils/__init__.py +4 -0
- partitura-1.6.0/partitura/utils/fluidsynth.py +326 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/utils/generic.py +34 -2
- partitura-1.6.0/partitura/utils/globals.py +743 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/utils/misc.py +48 -1
- {partitura-1.4.1 → partitura-1.6.0}/partitura/utils/music.py +251 -313
- {partitura-1.4.1 → partitura-1.6.0}/partitura/utils/normalize.py +1 -3
- {partitura-1.4.1 → partitura-1.6.0}/partitura/utils/synth.py +18 -38
- {partitura-1.4.1 → partitura-1.6.0}/partitura.egg-info/PKG-INFO +13 -2
- {partitura-1.4.1 → partitura-1.6.0}/partitura.egg-info/SOURCES.txt +9 -1
- {partitura-1.4.1 → partitura-1.6.0}/setup.py +1 -1
- partitura-1.6.0/tests/test_clef.py +105 -0
- partitura-1.6.0/tests/test_cross_staff.py +34 -0
- partitura-1.6.0/tests/test_dcml_import.py +20 -0
- partitura-1.6.0/tests/test_fluidsynth.py +97 -0
- partitura-1.6.0/tests/test_kern.py +84 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_mei.py +45 -10
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_merge_parts.py +10 -1
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_metrical_position.py +2 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_midi_import.py +60 -2
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_note_array.py +3 -5
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_note_features.py +17 -1
- partitura-1.6.0/tests/test_performance.py +332 -0
- partitura-1.6.0/tests/test_performance_features.py +46 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_synth.py +1 -1
- partitura-1.6.0/tests/test_urlload.py +26 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_utils.py +111 -45
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_xml.py +64 -0
- partitura-1.4.1/partitura/assets/score_example.mei +0 -56
- partitura-1.4.1/partitura/io/exportmei.py +0 -2096
- partitura-1.4.1/partitura/io/importkern.py +0 -626
- partitura-1.4.1/tests/test_cross_staff_beaming.py +0 -20
- partitura-1.4.1/tests/test_kern.py +0 -48
- partitura-1.4.1/tests/test_performance.py +0 -140
- partitura-1.4.1/tests/test_performance_features.py +0 -42
- {partitura-1.4.1 → partitura-1.6.0}/LICENSE +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/README.md +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/assets/musicxml.xsd +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/assets/score_example.krn +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/assets/score_example.mid +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/assets/score_example.musicxml +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/display.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/io/exportparangonada.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/io/importparangonada.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/io/matchfile_base.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/io/matchlines_v0.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/io/musescore.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/musicanalysis/__init__.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/musicanalysis/pitch_spelling.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/musicanalysis/tonal_tension.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura/musicanalysis/voice_separation.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura.egg-info/dependency_links.txt +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura.egg-info/requires.txt +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/partitura.egg-info/top_level.txt +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/setup.cfg +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_deprecations.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_display.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_harmony.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_key_estimation.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_load_performance.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_load_score.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_m21_import.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_match_export.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_match_import.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_midi_export.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_musescore.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_nakamura.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_new_divs.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_octave_shift.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_parangonada.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_part_properties.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_partial_measures.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_performance_codec.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_pianoroll.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_pitch_spelling.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_quarter_adjust.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_rest_array.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_time_estimation.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_times.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_tonal_tension.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_transpose.py +0 -0
- {partitura-1.4.1 → partitura-1.6.0}/tests/test_voice_estimation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: partitura
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.6.0
|
|
4
4
|
Summary: A package for handling symbolic musical information
|
|
5
5
|
Home-page: https://github.com/CPJKU/partitura
|
|
6
6
|
Author: Maarten Grachten, Carlos Cancino-Chacón, Silvan Peter, Emmanouil Karystinaios, Francesco Foscarin, Thassilo Gadermaier, Patricia Hu
|
|
@@ -21,6 +21,17 @@ Requires-Dist: lxml
|
|
|
21
21
|
Requires-Dist: lark-parser
|
|
22
22
|
Requires-Dist: xmlschema
|
|
23
23
|
Requires-Dist: mido
|
|
24
|
+
Dynamic: author
|
|
25
|
+
Dynamic: author-email
|
|
26
|
+
Dynamic: classifier
|
|
27
|
+
Dynamic: description
|
|
28
|
+
Dynamic: description-content-type
|
|
29
|
+
Dynamic: home-page
|
|
30
|
+
Dynamic: keywords
|
|
31
|
+
Dynamic: license
|
|
32
|
+
Dynamic: requires-dist
|
|
33
|
+
Dynamic: requires-python
|
|
34
|
+
Dynamic: summary
|
|
24
35
|
|
|
25
36
|
|
|
26
37
|
[//]: # (<p align="center"> )
|
|
@@ -15,6 +15,7 @@ from .io.exportmusicxml import save_musicxml
|
|
|
15
15
|
from .io.importmei import load_mei
|
|
16
16
|
from .io.importkern import load_kern
|
|
17
17
|
from .io.importmusic21 import load_music21
|
|
18
|
+
from .io.importdcml import load_dcml
|
|
18
19
|
from .io.importmidi import load_score_midi, load_performance_midi, midi_to_notearray
|
|
19
20
|
from .io.exportmidi import save_score_midi, save_performance_midi
|
|
20
21
|
from .io.importmatch import load_match
|
|
@@ -22,7 +23,8 @@ from .io.exportmatch import save_match
|
|
|
22
23
|
from .io.importnakamura import load_nakamuramatch, load_nakamuracorresp
|
|
23
24
|
from .io.importparangonada import load_parangonada_csv
|
|
24
25
|
from .io.exportparangonada import save_parangonada_csv, save_csv_for_parangonada
|
|
25
|
-
from .io.exportaudio import save_wav
|
|
26
|
+
from .io.exportaudio import save_wav, save_wav_fluidsynth
|
|
27
|
+
from .io.exportmei import save_mei
|
|
26
28
|
from .display import render
|
|
27
29
|
from . import musicanalysis
|
|
28
30
|
from .musicanalysis import make_note_features, compute_note_array, full_note_array
|
|
@@ -56,9 +58,12 @@ __all__ = [
|
|
|
56
58
|
"save_performance_midi",
|
|
57
59
|
"load_match",
|
|
58
60
|
"save_match",
|
|
61
|
+
"load_dcml",
|
|
59
62
|
"load_nakamuramatch",
|
|
60
63
|
"load_nakamuracorresp",
|
|
61
64
|
"load_parangonada_csv",
|
|
62
65
|
"save_parangonada_csv",
|
|
66
|
+
"save_wav",
|
|
67
|
+
"save_wav_fluidsynth",
|
|
63
68
|
"render",
|
|
64
69
|
]
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<?xml-model href="https://music-encoding.org/schema/5.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
|
|
3
|
+
<?xml-model href="https://music-encoding.org/schema/5.0/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
|
|
4
|
+
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="5.0">
|
|
5
|
+
<meiHead xml:id="m21agkk">
|
|
6
|
+
<fileDesc xml:id="f1x9ud6p">
|
|
7
|
+
<titleStmt xml:id="t1pe4slb">
|
|
8
|
+
<title />
|
|
9
|
+
<respStmt />
|
|
10
|
+
</titleStmt>
|
|
11
|
+
<pubStmt xml:id="p1kxcrok">
|
|
12
|
+
<date isodate="2024-10-30" type="encoding-date">2024-10-30</date>
|
|
13
|
+
</pubStmt>
|
|
14
|
+
</fileDesc>
|
|
15
|
+
<encodingDesc xml:id="e1xr2zpp">
|
|
16
|
+
<appInfo xml:id="a1wyxc5n">
|
|
17
|
+
<application xml:id="a1t43ge2" isodate="2024-10-30T10:56:32" version="4.3.1-3b8cc17">
|
|
18
|
+
<name xml:id="n1cp60l4">Verovio</name>
|
|
19
|
+
<p xml:id="p13nndma">Transcoded from MusicXML</p>
|
|
20
|
+
</application>
|
|
21
|
+
</appInfo>
|
|
22
|
+
</encodingDesc>
|
|
23
|
+
</meiHead>
|
|
24
|
+
<music>
|
|
25
|
+
<body>
|
|
26
|
+
<mdiv xml:id="muo97v6">
|
|
27
|
+
<score xml:id="suneqlv">
|
|
28
|
+
<scoreDef xml:id="sz00r05">
|
|
29
|
+
<staffGrp xml:id="s1h35kps">
|
|
30
|
+
<staffGrp xml:id="P1" bar.thru="true">
|
|
31
|
+
<grpSym xml:id="g1eji31e" symbol="brace" />
|
|
32
|
+
<label xml:id="l8lirjj">Piano</label>
|
|
33
|
+
<instrDef xml:id="iggd40h" midi.channel="0" midi.instrnum="0" midi.volume="78.00%" />
|
|
34
|
+
<staffDef xml:id="sbpks8p" n="1" lines="5" ppq="1">
|
|
35
|
+
<clef xml:id="c1p7nrnw" shape="G" line="2" />
|
|
36
|
+
<keySig xml:id="ki5anqv" sig="0" />
|
|
37
|
+
<meterSig xml:id="m1vpw2w2" count="4" unit="4" />
|
|
38
|
+
</staffDef>
|
|
39
|
+
<staffDef xml:id="s1g416nz" n="2" lines="5" ppq="1">
|
|
40
|
+
<clef xml:id="cezkswz" shape="G" line="2" />
|
|
41
|
+
<keySig xml:id="kk41xfz" sig="0" />
|
|
42
|
+
<meterSig xml:id="m7alo7s" count="4" unit="4" />
|
|
43
|
+
</staffDef>
|
|
44
|
+
</staffGrp>
|
|
45
|
+
</staffGrp>
|
|
46
|
+
</scoreDef>
|
|
47
|
+
<section xml:id="suu4o7p">
|
|
48
|
+
<measure xml:id="m1e358qx" n="1">
|
|
49
|
+
<staff xml:id="s1ufvigy" n="1">
|
|
50
|
+
<layer xml:id="l1r7cvga" n="1">
|
|
51
|
+
<rest xml:id="ro1o7cb" dur.ppq="2" dur="2" />
|
|
52
|
+
<chord xml:id="c1c1r6b7" dur.ppq="2" dur="2" stem.dir="down">
|
|
53
|
+
<note xml:id="n6dpu2p" oct="5" pname="c" />
|
|
54
|
+
<note xml:id="njfgcwp" oct="5" pname="e" />
|
|
55
|
+
</chord>
|
|
56
|
+
</layer>
|
|
57
|
+
</staff>
|
|
58
|
+
<staff xml:id="s710zw2" n="2">
|
|
59
|
+
<layer xml:id="leffrs2" n="5">
|
|
60
|
+
<note xml:id="n1txt37q" dur.ppq="4" dur="1" oct="4" pname="a" />
|
|
61
|
+
</layer>
|
|
62
|
+
</staff>
|
|
63
|
+
</measure>
|
|
64
|
+
</section>
|
|
65
|
+
</score>
|
|
66
|
+
</mdiv>
|
|
67
|
+
</body>
|
|
68
|
+
</music>
|
|
69
|
+
</mei>
|
|
@@ -13,6 +13,7 @@ The functionality is provided by the function `parse_words`
|
|
|
13
13
|
|
|
14
14
|
import re
|
|
15
15
|
import warnings
|
|
16
|
+
from partitura.utils.globals import UNABBREVS
|
|
16
17
|
|
|
17
18
|
try:
|
|
18
19
|
from lark import Lark
|
|
@@ -51,29 +52,6 @@ def join_items(items):
|
|
|
51
52
|
)
|
|
52
53
|
|
|
53
54
|
|
|
54
|
-
UNABBREVS = [
|
|
55
|
-
(re.compile(r"(crescendo|cresc\.?)"), "crescendo"),
|
|
56
|
-
(re.compile(r"(smorzando|smorz\.?)"), "smorzando"),
|
|
57
|
-
(re.compile(r"(decrescendo|(decresc|decr|dimin|dim)\.?)"), "diminuendo"),
|
|
58
|
-
(re.compile(r"((acceler|accel|acc)\.?)"), "accelerando"),
|
|
59
|
-
(re.compile(r"(ritenente|riten\.?)"), "ritenuto"),
|
|
60
|
-
(re.compile(r"((ritard|rit)\.?)"), "ritardando"),
|
|
61
|
-
(re.compile(r"((rallent|rall)\.?)"), "rallentando"),
|
|
62
|
-
(re.compile(r"(dolciss\.?)"), "dolcissimo"),
|
|
63
|
-
(re.compile(r"((sosten|sost)\.?)"), "sostenuto"),
|
|
64
|
-
(re.compile(r"(delicatiss\.?)"), "delicatissimo"),
|
|
65
|
-
(re.compile(r"(leggieramente|leggiermente|leggiero|legg\.?)"), "leggiero"),
|
|
66
|
-
(re.compile(r"(leggierissimo|(leggieriss\.?))"), "leggierissimo"),
|
|
67
|
-
(re.compile(r"(scherz\.?)"), "scherzando"),
|
|
68
|
-
(re.compile(r"(tenute|ten\.?)"), "tenuto"),
|
|
69
|
-
(re.compile(r"(allegretto)"), "allegro"),
|
|
70
|
-
(re.compile(r"(espress\.?)"), "espressivo"),
|
|
71
|
-
(re.compile(r"(ligato)"), "legato"),
|
|
72
|
-
(re.compile(r"(ligatissimo)"), "legatissimo"),
|
|
73
|
-
(re.compile(r"((rinforz|rinf|rfz|rf)\.?)"), "rinforzando"),
|
|
74
|
-
]
|
|
75
|
-
|
|
76
|
-
|
|
77
55
|
def unabbreviate(s):
|
|
78
56
|
for p, v in UNABBREVS:
|
|
79
57
|
if p.match(s):
|
|
@@ -5,17 +5,21 @@ This module contains methods for importing and exporting symbolic music formats.
|
|
|
5
5
|
"""
|
|
6
6
|
from typing import Union
|
|
7
7
|
import os
|
|
8
|
-
|
|
8
|
+
import urllib.request
|
|
9
|
+
from urllib.parse import urlparse
|
|
10
|
+
import tempfile
|
|
9
11
|
from .importmusicxml import load_musicxml
|
|
10
12
|
from .importmidi import load_score_midi, load_performance_midi
|
|
11
13
|
from .musescore import load_via_musescore
|
|
12
14
|
from .importmatch import load_match
|
|
13
15
|
from .importmei import load_mei
|
|
14
16
|
from .importkern import load_kern
|
|
17
|
+
from .exportkern import save_kern
|
|
15
18
|
from .importparangonada import load_parangonada_csv
|
|
16
19
|
from .exportparangonada import save_parangonada_csv
|
|
17
20
|
from .importmusic21 import load_music21
|
|
18
|
-
|
|
21
|
+
from .exportmei import save_mei
|
|
22
|
+
from .importdcml import load_dcml
|
|
19
23
|
from partitura.utils.misc import (
|
|
20
24
|
deprecated_alias,
|
|
21
25
|
deprecated_parameter,
|
|
@@ -30,6 +34,14 @@ class NotSupportedFormatError(Exception):
|
|
|
30
34
|
pass
|
|
31
35
|
|
|
32
36
|
|
|
37
|
+
def is_url(input):
|
|
38
|
+
try:
|
|
39
|
+
result = urlparse(input)
|
|
40
|
+
return all([result.scheme, result.netloc])
|
|
41
|
+
except ValueError:
|
|
42
|
+
return False
|
|
43
|
+
|
|
44
|
+
|
|
33
45
|
@deprecated_alias(score_fn="filename")
|
|
34
46
|
@deprecated_parameter("ensure_list")
|
|
35
47
|
def load_score(filename: PathLike, force_note_ids="keep") -> Score:
|
|
@@ -55,11 +67,29 @@ def load_score(filename: PathLike, force_note_ids="keep") -> Score:
|
|
|
55
67
|
scr: :class:`partitura.score.Score`
|
|
56
68
|
A score instance.
|
|
57
69
|
"""
|
|
70
|
+
if is_url(filename):
|
|
71
|
+
url = filename
|
|
72
|
+
# Send a GET request to the URL
|
|
73
|
+
with urllib.request.urlopen(url) as response:
|
|
74
|
+
data = response.read()
|
|
75
|
+
|
|
76
|
+
# Extract the file extension from the URL
|
|
77
|
+
extension = os.path.splitext(url)[-1]
|
|
78
|
+
|
|
79
|
+
# Create a temporary file
|
|
80
|
+
temp_file = tempfile.NamedTemporaryFile(suffix=extension, delete=True)
|
|
81
|
+
|
|
82
|
+
# Write the content to the temporary file
|
|
83
|
+
with open(temp_file.name, "wb") as f:
|
|
84
|
+
f.write(data)
|
|
85
|
+
|
|
86
|
+
filename = temp_file.name
|
|
87
|
+
else:
|
|
88
|
+
extension = os.path.splitext(filename)[-1].lower()
|
|
58
89
|
|
|
59
|
-
extension = os.path.splitext(filename)[-1].lower()
|
|
60
90
|
if extension in (".mxl", ".xml", ".musicxml"):
|
|
61
91
|
# Load MusicXML
|
|
62
|
-
|
|
92
|
+
score = load_musicxml(
|
|
63
93
|
filename=filename,
|
|
64
94
|
force_note_ids=force_note_ids,
|
|
65
95
|
)
|
|
@@ -69,15 +99,15 @@ def load_score(filename: PathLike, force_note_ids="keep") -> Score:
|
|
|
69
99
|
assign_note_ids = False
|
|
70
100
|
else:
|
|
71
101
|
assign_note_ids = True
|
|
72
|
-
|
|
102
|
+
score = load_score_midi(
|
|
73
103
|
filename=filename,
|
|
74
104
|
assign_note_ids=assign_note_ids,
|
|
75
105
|
)
|
|
76
106
|
elif extension in [".mei"]:
|
|
77
107
|
# Load MEI
|
|
78
|
-
|
|
108
|
+
score = load_mei(filename=filename)
|
|
79
109
|
elif extension in [".kern", ".krn"]:
|
|
80
|
-
|
|
110
|
+
score = load_kern(
|
|
81
111
|
filename=filename,
|
|
82
112
|
force_note_ids=force_note_ids,
|
|
83
113
|
)
|
|
@@ -105,7 +135,7 @@ def load_score(filename: PathLike, force_note_ids="keep") -> Score:
|
|
|
105
135
|
".gp",
|
|
106
136
|
]:
|
|
107
137
|
# Load MuseScore
|
|
108
|
-
|
|
138
|
+
score = load_via_musescore(
|
|
109
139
|
filename=filename,
|
|
110
140
|
force_note_ids=force_note_ids,
|
|
111
141
|
)
|
|
@@ -115,11 +145,11 @@ def load_score(filename: PathLike, force_note_ids="keep") -> Score:
|
|
|
115
145
|
filename=filename,
|
|
116
146
|
create_score=True,
|
|
117
147
|
)
|
|
118
|
-
return score
|
|
119
148
|
else:
|
|
120
149
|
raise NotSupportedFormatError(
|
|
121
150
|
f"{extension} file extension is not supported. If this should be supported, consider editing partitura/io/__init__.py file"
|
|
122
151
|
)
|
|
152
|
+
return score
|
|
123
153
|
|
|
124
154
|
|
|
125
155
|
def load_score_as_part(filename: PathLike) -> Part:
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/python
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
"""
|
|
4
|
-
This module contains methods to synthesize Partitura object to wav
|
|
5
|
-
additive synthesis
|
|
4
|
+
This module contains methods to synthesize a Partitura ScoreLike object to wav.
|
|
6
5
|
"""
|
|
7
6
|
from typing import Union, Optional, Callable, Dict, Any
|
|
8
7
|
import numpy as np
|
|
@@ -13,10 +12,18 @@ from partitura.score import ScoreLike
|
|
|
13
12
|
from partitura.performance import PerformanceLike
|
|
14
13
|
|
|
15
14
|
from partitura.utils.synth import synthesize, SAMPLE_RATE, A4
|
|
15
|
+
from partitura.utils.fluidsynth import (
|
|
16
|
+
synthesize_fluidsynth,
|
|
17
|
+
DEFAULT_SOUNDFONT,
|
|
18
|
+
HAS_FLUIDSYNTH,
|
|
19
|
+
)
|
|
16
20
|
|
|
17
21
|
from partitura.utils.misc import PathLike
|
|
18
22
|
|
|
19
|
-
__all__ = [
|
|
23
|
+
__all__ = [
|
|
24
|
+
"save_wav",
|
|
25
|
+
"save_wav_fluidsynth",
|
|
26
|
+
]
|
|
20
27
|
|
|
21
28
|
|
|
22
29
|
def save_wav(
|
|
@@ -89,8 +96,76 @@ def save_wav(
|
|
|
89
96
|
bpm=bpm,
|
|
90
97
|
)
|
|
91
98
|
|
|
99
|
+
if out is not None:
|
|
100
|
+
# convert to 16bit integers (save as PCM 16 bit)
|
|
101
|
+
# (some DAWs cannot load audio files that are float64,
|
|
102
|
+
# e.g., Logic)
|
|
103
|
+
amplitude = np.iinfo(np.int16).max
|
|
104
|
+
if abs(audio_signal).max() <= 1:
|
|
105
|
+
# convert to 16bit integers (save as PCM 16 bit)
|
|
106
|
+
amplitude = np.iinfo(np.int16).max
|
|
107
|
+
audio_signal *= amplitude
|
|
108
|
+
wavfile.write(out, samplerate, audio_signal.astype(np.int16))
|
|
109
|
+
|
|
110
|
+
else:
|
|
111
|
+
return audio_signal
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def save_wav_fluidsynth(
|
|
115
|
+
input_data: Union[ScoreLike, PerformanceLike, np.ndarray],
|
|
116
|
+
out: Optional[PathLike] = None,
|
|
117
|
+
samplerate: int = SAMPLE_RATE,
|
|
118
|
+
soundfont: PathLike = DEFAULT_SOUNDFONT,
|
|
119
|
+
bpm: Union[float, np.ndarray, Callable] = 60,
|
|
120
|
+
) -> Optional[np.ndarray]:
|
|
121
|
+
"""
|
|
122
|
+
Export a score (a `Score`, `Part`, `PartGroup` or list of `Part` instances),
|
|
123
|
+
a performance (`Performance`, `PerformedPart` or list of `PerformedPart` instances)
|
|
124
|
+
as a WAV file using fluidsynth
|
|
125
|
+
|
|
126
|
+
Parameters
|
|
127
|
+
----------
|
|
128
|
+
input_data : ScoreLike, PerformanceLike or np.ndarray
|
|
129
|
+
A partitura object with note information.
|
|
130
|
+
out : PathLike or None
|
|
131
|
+
Path of the output Wave file. If None, the method outputs
|
|
132
|
+
the audio signal as an array (see `audio_signal` below).
|
|
133
|
+
samplerate: int
|
|
134
|
+
The sample rate of the audio file in Hz. The default is 44100Hz.
|
|
135
|
+
soundfont : PathLike
|
|
136
|
+
Path to the soundfont in SF2/SF3 format for fluidsynth.
|
|
137
|
+
bpm : float, np.ndarray, callable
|
|
138
|
+
The bpm to render the output (if the input is a score-like object).
|
|
139
|
+
See `partitura.utils.music.performance_notearray_from_score_notearray`
|
|
140
|
+
for more information on this parameter.
|
|
141
|
+
|
|
142
|
+
Returns
|
|
143
|
+
-------
|
|
144
|
+
audio_signal : np.ndarray
|
|
145
|
+
Audio signal as a 1D array. Only returned if `out` is None.
|
|
146
|
+
"""
|
|
147
|
+
|
|
148
|
+
if not HAS_FLUIDSYNTH:
|
|
149
|
+
raise ImportError("Fluidsynth is not installed!")
|
|
150
|
+
|
|
151
|
+
audio_signal = synthesize_fluidsynth(
|
|
152
|
+
note_info=input_data,
|
|
153
|
+
samplerate=samplerate,
|
|
154
|
+
soundfont=soundfont,
|
|
155
|
+
bpm=bpm,
|
|
156
|
+
)
|
|
157
|
+
|
|
92
158
|
if out is not None:
|
|
93
159
|
# Write audio signal
|
|
94
|
-
|
|
160
|
+
|
|
161
|
+
# convert to 16bit integers (save as PCM 16 bit)
|
|
162
|
+
# (some DAWs cannot load audio files that are float64,
|
|
163
|
+
# e.g., Logic)
|
|
164
|
+
amplitude = np.iinfo(np.int16).max
|
|
165
|
+
if abs(audio_signal).max() <= 1:
|
|
166
|
+
# convert to 16bit integers (save as PCM 16 bit)
|
|
167
|
+
amplitude = np.iinfo(np.int16).max
|
|
168
|
+
audio_signal *= amplitude
|
|
169
|
+
wavfile.write(out, samplerate, audio_signal.astype(np.int16))
|
|
95
170
|
else:
|
|
96
171
|
return audio_signal
|