Skip to content

Commit 8a6fae7

Browse files
authored
Merge pull request #5 from sildater/develop
Release 1.0.0
2 parents ec64157 + 8bfb718 commit 8a6fae7

File tree

14 files changed

+2733
-177
lines changed

14 files changed

+2733
-177
lines changed

README.md

Lines changed: 181 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ web tool [Parangonda](https://sildater.github.io/parangonada/)
88

99

1010
Installation
11-
==========
11+
-------
1212

1313
The easiest way to install the package is via `pip` from the [PyPI (Python
1414
Package Index)](https://pypi.org/project/parangonar/>):
@@ -18,14 +18,19 @@ pip install parangonar
1818
This will install the latest release of the package and will install all dependencies automatically.
1919

2020

21-
Quickstart
21+
Getting Started
2222
==========
2323

24-
The following code loads the contents of a a previously aligned performance
25-
and score alignment file (encoded in the [match file format](https://arxiv.org/abs/2206.01104)).
24+
The following code snippets load the contents of a a previously aligned performance
25+
and score alignment file (encoded in the [match file format](https://cpjku.github.io/matchfile/)).
26+
27+
A new alignment is computed using different note matchers and the predicted alignment are compared to the ground truth:
28+
29+
For an interactive version of these snippets, check the `getting_started.ipynb` notebook.
2630

27-
A new alignment is computed using a hierarchical DTW-based note matcher and the resulting
28-
alignment are compared to the ground truth:
31+
32+
1 - Automatic Note Matching: `AutomaticNoteMatcher` and `DualDTWNoteMatcher`
33+
-----
2934

3035
```python
3136
import parangonar as pa
@@ -37,10 +42,10 @@ perf_match, groundtruth_alignment, score_match = pt.load_match(
3742
)
3843

3944
# compute note arrays from the loaded score and performance
40-
pna_match = perf_match.note_array()
41-
sna_match = score_match.note_array()
45+
pna_match = perf_match[0].note_array()
46+
sna_match = score_match[0].note_array()
4247

43-
# match the notes in the note arrays
48+
# match the notes in the note arrays --------------------- DualDTWNoteMatcher
4449
sdm = pa.AutomaticNoteMatcher()
4550
pred_alignment = sdm(sna_match,
4651
pna_match,
@@ -58,13 +63,38 @@ for alignment_type in types:
5863
'Recall ',format(recall, '.3f'),
5964
'F-Score ',format(f_score, '.3f'))
6065
print('------------------')
61-
```
6266

6367

64-
Aligning MusicXML Scores and MIDI Performances
65-
==========
6668

6769

70+
# this matcher requires grace note info
71+
sna_match = score_match[0].note_array(include_grace_notes=True)
72+
73+
# match the notes in the note arrays --------------------- DualDTWNoteMatcher
74+
sdm = pa.DualDTWNoteMatcher()
75+
pred_alignment = sdm(sna_match,
76+
pna_match,
77+
process_ornaments=False,
78+
score_part=score_match[0]) # if a score part is passed, ornaments can be handled seperately
79+
80+
# compute f-score and print the results
81+
print('------------------')
82+
types = ['match','insertion', 'deletion']
83+
for alignment_type in types:
84+
precision, recall, f_score = pa.fscore_alignments(pred_alignment,
85+
groundtruth_alignment,
86+
alignment_type)
87+
print('Evaluate ',alignment_type)
88+
print('Precision: ',format(precision, '.3f'),
89+
'Recall ',format(recall, '.3f'),
90+
'F-Score ',format(f_score, '.3f'))
91+
print('------------------')
92+
93+
```
94+
95+
Aligning MusicXML Scores and MIDI Performances
96+
-----
97+
6898
```python
6999
import parangonar as pa
70100
import partitura as pt
@@ -78,36 +108,12 @@ sna = score.note_array()
78108

79109
# match the notes in the note arrays
80110
sdm = pa.AutomaticNoteMatcher()
81-
pred_alignment = sdm(sna_match, pna_match)
82-
```
83-
84-
File I/O for note alignments
85-
==========
86-
87-
```python
88-
import partitura as pt
89-
import parangonar as pa
90-
91-
# load note alignments of the asap dataset:
92-
# https://github.com/CPJKU/asap-dataset/tree/note_alignments
93-
alignment = pt.io.importparangonada.load_alignment_from_ASAP(filename= 'path/to/note_alignment.tsv')
111+
pred_alignment = sdm(sna, pna)
94112

95-
# export a note alignment for visualization with parangonada:
96-
# https://sildater.github.io/parangonada/
97-
pa.match.save_parangonada_csv(alignment,
98-
performance_data,
99-
score_data,
100-
outdir="path/to/dir")
101-
102-
# import a corrected note alignment from parangonada:
103-
# https://sildater.github.io/parangonada/
104-
alignment = pt.io.importparangonada.load_parangonada_alignment(filename= 'path/to/note_alignment.csv')
105113
```
106114

107-
108-
109-
Anchor Point Alignment Example
110-
==========
115+
2 - Anchor Point Alignment: `AnchorPointNoteMatcher`
116+
----
111117

112118
```python
113119
import parangonar as pa
@@ -148,8 +154,47 @@ for alignment_type in types:
148154
print('------------------')
149155
```
150156

151-
Visualize Alignment
152-
==========
157+
158+
3 - Online / Realtime Alignment: `OnlineTransformerMatcher` and `OnlinePureTransformerMatcher`
159+
----
160+
161+
```python
162+
import parangonar as pa
163+
import partitura as pt
164+
165+
perf_match, groundtruth_alignment, score_match = pt.load_match(
166+
filename= pa.EXAMPLE,
167+
create_score=True
168+
)
169+
170+
# compute note arrays from the loaded score and performance
171+
pna_match = perf_match[0].note_array()
172+
# this matcher requires grace note info
173+
sna_match = score_match[0].note_array(include_grace_notes=True)
174+
175+
# set up the matcher using the score information: OnlineTransformerMatcher / OnlinePureTransformerMatcher
176+
matcher = pa.OnlinePureTransformerMatcher(sna_match)
177+
178+
# the "offline" method loops over all notes in the performance and calls the "online" method for each one.
179+
pred_alignment = matcher.offline(pna_match)
180+
181+
# compute f-score and print the results
182+
print('------------------')
183+
types = ['match','insertion', 'deletion']
184+
for alignment_type in types:
185+
precision, recall, f_score = pa.fscore_alignments(pred_alignment,
186+
groundtruth_alignment,
187+
alignment_type)
188+
print('Evaluate ',alignment_type)
189+
print('Precision: ',format(precision, '.3f'),
190+
'Recall ',format(recall, '.3f'),
191+
'F-Score ',format(f_score, '.3f'))
192+
print('------------------')
193+
```
194+
195+
4 - Visualize Alignment
196+
----
197+
153198
```python
154199
import parangonar as pa
155200
import partitura as pt
@@ -164,10 +209,104 @@ sna_match = score_match.note_array()
164209
# show or save plot of note alignment
165210
pa.plot_alignment(pna_match,
166211
sna_match,
167-
alignment,
212+
alignment,s
168213
save_file = False)
214+
215+
# or plot the performance and score as piano rolls given a reference:
216+
# we can encode errors if given ground truth
217+
# Blue lines indicate correct matches, red lines incorrect ones.
218+
pa.plot_alignment_comparison(pna_match, sna_match,
219+
pred_alignment, groundtruth_alignment)
220+
```
221+
222+
5 - File I/O for note alignments
223+
----
224+
225+
Most I/O functions are handled by partitura.
226+
For [Parangonada](https://sildater.github.io/parangonada/):
227+
- pt.io.importparangonada.load_parangonada_alignment
228+
- pt.io.importparangonada.load_parangonada_csv
229+
- pt.io.exportparangonada.save_parangonada_alignment
230+
- pt.io.exportparangonada.save_parangonada_csv
231+
232+
For [(n)ASAP alignments](https://github.com/CPJKU/asap-dataset)
233+
- pt.io.importparangonada.load_alignment_from_ASAP
234+
- pt.io.exportparangonada.save_alignment_for_ASAP
235+
236+
For [match files](https://cpjku.github.io/matchfile/)
237+
- pt.io.importmatch.load_match
238+
- pt.io.exportmatch.save_match
239+
240+
and a basic interface for saving parangonada-ready csv files is also available:
241+
242+
----
243+
244+
```python
245+
import partitura as pt
246+
import parangonar as pa
247+
248+
# export a note alignment for visualization with parangonada:
249+
# https://sildater.github.io/parangonada/
250+
pa.match.save_parangonada_csv(alignment,
251+
performance_data,
252+
score_data,
253+
outdir="path/to/dir")
254+
255+
256+
# import a corrected note alignment from parangonada:
257+
# https://sildater.github.io/parangonada/
258+
alignment = pt.io.importparangonada.load_parangonada_alignment(filename= 'path/to/note_alignment.csv')
259+
260+
# load note alignments of the asap dataset:
261+
# https://github.com/CPJKU/asap-dataset/tree/note_alignments
262+
alignment = pt.io.importparangonada.load_alignment_from_ASAP(filename= 'path/to/note_alignment.tsv')
169263
```
170264

265+
266+
6 - Aligned Data
267+
----
268+
269+
These note-aligned datasets are publically available:
270+
- [Vienna 4x22](https://github.com/CPJKU/vienna4x22)
271+
- [(n)ASAP note alignments](https://github.com/CPJKU/asap-dataset)
272+
- [Batik Dataset](https://github.com/huispaty/batik_plays_mozart)
273+
274+
Publications
275+
=====
276+
277+
Two publications are associated with models available in **Parangonar**.
278+
The anchor point-enhanced `AnchorPointNoteMatcher` and the automatic `AutomaticNoteMatcher` are this described in:
279+
280+
```
281+
@article{nasap-dataset,
282+
title = {Automatic Note-Level Score-to-Performance Alignments in the ASAP Dataset},
283+
author = {Peter, Silvan David and Cancino-Chacón, Carlos Eduardo and Foscarin, Francesco and McLeod, Andrew Philip and Henkel, Florian and Karystinaios, Emmanouil and Widmer, Gerhard},
284+
doi = {10.5334/tismir.149},
285+
journal = {Transactions of the International Society for Music Information Retrieval {(TISMIR)}},
286+
year = {2023}
287+
}
288+
```
289+
290+
and the former is used in the creation of the [note-aligned (n)ASAP Dataset](https://github.com/CPJKU/asap-dataset).
291+
292+
293+
The improved automatic `DualDTWNoteMatcher` and the online / realtime `OnlineTransformerMatcher` / `OnlinePureTransformerMatcher` are described in:
294+
295+
296+
```
297+
@inproceedings{peter-2023,
298+
title={Online Symbolic Music Alignment with Offline Reinforcement Learning},
299+
author={Peter, Silvan David},
300+
booktitle={International Society for Music Information Retrieval Conference {(ISMIR)}},
301+
year={2023}
302+
}
303+
```
304+
305+
Acknowledgments
306+
=======
307+
308+
This work is supported by the European Research Council (ERC) under the EU’s Horizon 2020 research & innovation programme, grant agreement No. 10101937 (”Wither Music?”).
309+
171310
License
172311
=======
173312

0 commit comments

Comments
 (0)