@@ -8,7 +8,7 @@ web tool [Parangonda](https://sildater.github.io/parangonada/)
88
99
1010Installation
11- ==========
11+ -------
1212
1313The easiest way to install the package is via ` pip ` from the [ PyPI (Python
1414Package Index)] ( https://pypi.org/project/parangonar/> ) :
@@ -18,14 +18,19 @@ pip install parangonar
1818This 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
3136import 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
4449sdm = pa.AutomaticNoteMatcher()
4550pred_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
6999import parangonar as pa
70100import partitura as pt
@@ -78,36 +108,12 @@ sna = score.note_array()
78108
79109# match the notes in the note arrays
80110sdm = 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
113119import 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
154199import parangonar as pa
155200import partitura as pt
@@ -164,10 +209,104 @@ sna_match = score_match.note_array()
164209# show or save plot of note alignment
165210pa.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+
171310License
172311=======
173312
0 commit comments