Skip to content

Commit d1e6792

Browse files
Merge pull request #40 from pymatchmaker/develop
release v0.2.1
2 parents d5c58d7 + e72d9b0 commit d1e6792

37 files changed

Lines changed: 12426 additions & 672 deletions

.github/workflows/pypi_publish.yml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: pypi
1+
name: Publish to PyPI
22

33
on:
44
release:
@@ -11,7 +11,7 @@ jobs:
1111
strategy:
1212
matrix:
1313
os: [ubuntu-latest, macos-latest]
14-
14+
1515
steps:
1616
- uses: actions/checkout@v3
1717

@@ -35,9 +35,9 @@ jobs:
3535
CIBW_BUILD_VERBOSITY: 1
3636

3737
- name: Upload artifact
38-
uses: actions/upload-artifact@v3
38+
uses: actions/upload-artifact@v4
3939
with:
40-
name: wheels
40+
name: wheels-${{ matrix.os }}
4141
path: ./wheelhouse/*.whl
4242

4343
publish:
@@ -47,12 +47,13 @@ jobs:
4747
id-token: write
4848
steps:
4949
- name: Download artifacts
50-
uses: actions/download-artifact@v3
50+
uses: actions/download-artifact@v4
5151
with:
52-
name: wheels
52+
pattern: wheels-*
5353
path: dist
54+
merge-multiple: true
5455

55-
- name: Publish to TestPyPI
56+
- name: Publish to PyPI
5657
uses: pypa/gh-action-pypi-publish@release/v1
5758
with:
5859
password: ${{ secrets.PYPI_API_TOKEN }}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Publish to TestPyPI
2+
3+
on:
4+
push:
5+
tags: ['v*.*.*rc*']
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
build_wheels:
11+
name: Build wheels on ${{ matrix.os }}
12+
runs-on: ${{ matrix.os }}
13+
strategy:
14+
matrix:
15+
os: [ubuntu-latest, macos-latest]
16+
17+
steps:
18+
- uses: actions/checkout@v3
19+
20+
- name: Set up Python
21+
uses: actions/setup-python@v4
22+
with:
23+
python-version: "3.12"
24+
25+
- name: Install cibuildwheel
26+
run: python -m pip install cibuildwheel
27+
28+
- name: Build wheels
29+
run: python -m cibuildwheel
30+
env:
31+
CIBW_BUILD: "cp39-* cp310-* cp311-* cp312-*"
32+
CIBW_ARCHS: "x86_64"
33+
CIBW_ARCHS_MACOS: "x86_64 arm64"
34+
CIBW_BEFORE_BUILD: |
35+
pip install --upgrade pip
36+
pip install "numpy>=1.26.3,<2.0" "cython>=3.0.8,<4.0"
37+
CIBW_BUILD_VERBOSITY: 1
38+
39+
- name: Upload artifact
40+
uses: actions/upload-artifact@v4
41+
with:
42+
name: wheels-${{ matrix.os }}
43+
path: ./wheelhouse/*.whl
44+
45+
publish:
46+
needs: build_wheels
47+
runs-on: ubuntu-latest
48+
permissions:
49+
id-token: write
50+
steps:
51+
- name: Download artifacts
52+
uses: actions/download-artifact@v4
53+
with:
54+
pattern: wheels-*
55+
path: dist
56+
merge-multiple: true
57+
58+
- name: Publish to TestPyPI
59+
uses: pypa/gh-action-pypi-publish@release/v1
60+
with:
61+
repository-url: https://test.pypi.org/legacy/
62+
password: ${{ secrets.TEST_PYPI_API_TOKEN }}

.github/workflows/unittest.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Python Unittest
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- develop
7+
8+
jobs:
9+
test:
10+
strategy:
11+
fail-fast: false
12+
matrix:
13+
platform: [ubuntu-latest, macos-latest]
14+
python-version: ["3.9", "3.10", "3.11", "3.12"]
15+
16+
runs-on: ${{ matrix.platform }}
17+
steps:
18+
- uses: actions/checkout@v3
19+
20+
- name: Set up Python ${{ matrix.python-version }}
21+
uses: actions/setup-python@v4
22+
with:
23+
python-version: ${{ matrix.python-version }}
24+
25+
- name: Install system dependencies (Ubuntu)
26+
if: matrix.platform == 'ubuntu-latest'
27+
run: |
28+
sudo apt-get update
29+
sudo apt-get install -y portaudio19-dev python3-pyaudio fluidsynth
30+
31+
- name: Install system dependencies (macOS)
32+
if: matrix.platform == 'macos-latest'
33+
run: |
34+
brew install portaudio fluidsynth
35+
36+
- name: Install dependencies
37+
run: |
38+
python -m pip install --upgrade pip
39+
pip install --upgrade setuptools
40+
pip install -e .
41+
42+
- name: Run tests
43+
run: |
44+
python -m unittest discover tests

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,10 @@ dev/*
187187
examples/example_live_audio_oltw.py
188188

189189
.ruff_cache/
190+
results/
191+
matchmaker/mtchmkr_alt.py
192+
score_audio_Bach-fugue_bwv_858.wav
193+
.gitignore
194+
score_audio_mozart_k265_var1.wav
195+
performance_audio*/
196+
score_audio*/

README.md

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -10,53 +10,69 @@ We aim to provide efficient reference implementations of score followers for use
1010

1111
The full documentation for matchmaker is available online at [readthedocs.org](https://pymatchmaker.readthedocs.io/).
1212

13-
1413
## Setup
1514

1615
### Prerequisites
1716

18-
- Available Python version: 3.9 (other versions will be supported soon!)
17+
- Available Python version: 3.12
1918
- [Fluidsynth](https://www.fluidsynth.org/)
2019
- [PortAudio](http://www.portaudio.com/)
2120

22-
First, install Fluidsynth, and then install the `pyfluidsynth` Python library. Note that `pyfluidsynth` only provides Python bindings for Fluidsynth; it does not install Fluidsynth itself. Be aware that there is also a `fluidsynth` Python library (without the `py-` prefix), but it is not compatible with `matchmaker`.
21+
First, install Fluidsynth, and then install the `pyfluidsynth` Python library. We recommend to install Fluidsynth using conda as well (see instructions below).
2322

24-
### Install from PyPI
25-
26-
```bash
27-
pip install pymatchmaker
28-
```
23+
Note that `pyfluidsynth` only provides Python bindings for Fluidsynth; it does not install Fluidsynth itself. Be aware that there is also a `fluidsynth` Python library (without the `py-` prefix), but it is not compatible with `matchmaker`. We recommend installing Fluidsynth using conda
2924

3025
### Install from source using conda
3126

32-
Please refer to the [requirements.txt](requirements.txt) file for the minimum required versions of the packages.
3327
Setting up the code as described here requires [conda](https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html). Follow the instructions for your OS.
3428

3529
To setup the experiments, use the following script.
3630

3731
```bash
3832
# Clone matchmaker
3933
git clone https://github.com/pymatchmaker/matchmaker.git
40-
cd matchmaker
4134

4235
# Create the conda environment
43-
conda create -n matchmaker python=3.9
36+
conda create -n matchmaker python=3.12
37+
4438
conda activate matchmaker
4539

46-
# Install matchmaker
47-
pip install -e .
40+
# Go to matchmaker directory
41+
cd ../matchmaker
4842

49-
# Install matchmaker with dev tools
50-
pip install -e .[dev]
43+
# Install matchmaker in editable mode
44+
pip install -e ."[dev]"
5145

52-
# Setup pre-commit
53-
pre-commit install
54-
```
46+
# Install GCC
47+
conda install -c conda-forge gcc=12.1.0
5548

56-
If you have a ImportError with 'Fluidsynth' by `pyfluidsynth` library on MacOS, please refer to the following [link](https://stackoverflow.com/a/75339618).
49+
# Install glib and fluidsynth
50+
conda install -c conda-forge glib fluidsynth
51+
```
5752

5853
Because of the dependency of `partitura`, which uses `MuseScore_General.sf3` (free soundfont provided by MuseScore) as the default soundfont, the soundfont will be installed automatically inside the `partitura` package. This might take a while for the first time.
5954

55+
### Known Setup Issues
56+
57+
#### Missing Visual C++ build tools (on Windows)
58+
59+
The solution seems to be to download vs_BuildTools.exe from <https://visualstudio.microsoft.com/visual-cpp-build-tools/> and then execute
60+
61+
```bash
62+
vs_buildtools.exe --norestart --passive --downloadThenInstall --includeRecommended --add Microsoft.VisualStudio.Workload.NativeDesktop --add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Workload.MSBuildTools
63+
```
64+
65+
#### Issues with Fluidsynth and pyfluidsynth on Windows
66+
67+
On Windows, pyfluidsynth expects fluidsynth.exe to be located in `C:\tools\bin` (other users have reported that it is expected in `C:\tools\fluidsynth\bin`). You can fix the issue by
68+
69+
1. Get the ZIP file for your Windows version from <https://github.com/FluidSynth/fluidsynth/releases/latest>
70+
2. Extract the contents to `C:\tools` (or wherever pyfluidsynth expects the executable to be).
71+
72+
#### Using Fluidsynth installed from Homebrew on MacOS
73+
74+
We recommend to install Fluidsynth from conda in a dedicated environemnt. If however, you want to use the system-wide Fluidsynth installed with homebrew, you might run into an `ImportError("Couldn't find the FluidSynth library.")` with `pyfluidsynth`. Please refer to the following [link](https://stackoverflow.com/a/75339618).
75+
6076
## Usage Examples
6177

6278
### Quickstart for live streaming
@@ -98,19 +114,33 @@ for current_position in mm.run():
98114
### Testing with Specific Input Device
99115

100116
To use a specific audio or MIDI device that is not the default device, you can pass the device name or index.
117+
By default, `input_type` is set to `“audio”`. If you are using a MIDI device, you can change the input type to `“midi”`.
101118

102119
```python
103120
from matchmaker import Matchmaker
104121

105122
mm = Matchmaker(
106123
score_file="path/to/score",
107-
input_type="audio",
108124
device_name_or_index="MacBookPro Microphone",
109125
)
110126
for current_position in mm.run():
111127
print(current_position)
112128
```
113129

130+
### Running Examples
131+
132+
The repository includes a ready-to-use example script that demonstrates the complete workflow:
133+
134+
```bash
135+
# Run with audio input (default)
136+
python run_examples.py
137+
138+
# Run with MIDI input
139+
python run_examples.py --midi
140+
```
141+
142+
This script runs a complete example with score following and evaluation, saving results to the `results/` directory.
143+
114144
### Testing with Different Methods or Features
115145

116146
For testing with Audio input, you can specify the alignment method as follows:
@@ -130,24 +160,6 @@ for current_position in mm.run():
130160
For options regarding the `method`, please refer to the [Alignment Methods](#alignment-methods) section.
131161
For options regarding the `feature_type`, please refer to the [Features](#features) section.
132162

133-
### Custom Example
134-
135-
If you want to use a different alignment method or custom method, you can do so by importing the specific class and passing the necessary parameters.
136-
In order to define a custom alignment class, you need to inherit from the Base `OnlineAlignment` class and implement the `run` method. Note that the returned value from the `OnlineAlignment` class should be the current frame number in the reference features, not in beats.
137-
138-
```python
139-
from matchmaker.dp import OnlineTimeWarpingDixon
140-
from matchmaker.io.audio import AudioStream
141-
from matchmaker.features import ChromagramProcessor
142-
143-
feature_processor = ChromagramProcessor()
144-
reference_features = feature_processor('path/to/score/audio.wav')
145-
146-
with AudioStream(processor=feature_processor) as stream:
147-
score_follower = OnlineTimeWarpingDixon(reference_features, stream.queue)
148-
for current_frame in score_follower.run():
149-
print(current_frame) # frame number in the reference features
150-
```
151163

152164
## Alignment Methods
153165

@@ -187,7 +199,17 @@ Initialization parameters for the `Matchmaker` class:
187199

188200
If you find Matchmaker useful, we would appreciate if you could cite us!
189201

202+
```bibtex
203+
@inproceedings{park_matchmaker_2025,
204+
title = {Matchmaker: {An} {Open}-{Source} {Library} for {Real}-{Time} {Piano} {Score} {Following} and {Systematic} {Evaluation}},
205+
booktitle = {Proceedings of the 26th {International} {Society} for {Music} {Information} {Retrieval} {Conference} ({ISMIR} 2025)},
206+
author = {Park, Jiyun and Cancino-Chacón, Carlos and Chiruthapudi, Suhit and Nam, Juhan},
207+
address = {Daejeon, South Korea}
208+
year = {2025}
209+
}
190210
```
211+
212+
```bibtex
191213
@inproceedings{matchmaker_lbd,
192214
title={{Matchmaker: A Python library for Real-time Music Alignment}},
193215
author={Park, Jiyun and Cancino-Chac\'{o}n, Carlos and Kwon, Taegyun and Nam, Juhan},
@@ -197,6 +219,8 @@ If you find Matchmaker useful, we would appreciate if you could cite us!
197219
}
198220
```
199221

222+
223+
200224
## Acknowledgments
201225

202226
This work has been supported by the Austrian Science Fund (FWF), grant agreement PAT 8820923 ("*Rach3: A Computational Approach to Study Piano Rehearsals*"). Additionally, this work was supported by the National Research Foundation of Korea (NRF) grant funded by the Korea government (MSIT) (No. NRF-2023R1A2C3007605).

matchmaker/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
import pkg_resources
1616

1717
__version__ = pkg_resources.get_distribution("pymatchmaker").version
18-
except Exception:
19-
__version__ = "0.0.1"
18+
except Exception: # pragma: no cover
19+
__version__ = "0.2.1"
2020

2121
EXAMPLE_SCORE = pkg_resources.resource_filename(
2222
"matchmaker",
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
0.716146 0.716146
2+
1.171875 1.171875
3+
1.613021 1.613021
4+
2.076042 2.076042
5+
2.504167 2.504167
6+
2.939063 2.939063
7+
3.418750 3.418750
8+
3.914583 3.914583
9+
4.369792 4.369792
10+
4.830208 4.830208
11+
5.292188 5.292188
12+
5.738542 5.738542
13+
6.197917 6.197917
14+
6.685417 6.685417
15+
7.192187 7.192187
16+
7.743750 7.743750
17+
8.254167 8.254167
18+
8.708334 8.708334
19+
9.176042 9.176042
20+
9.615625 9.615625
21+
10.059375 10.059375
22+
10.507812 10.507812
23+
10.972396 10.972396
24+
11.432812 11.432812
25+
11.884028 11.884028
26+
12.344791 12.344791
27+
12.823611 12.823611
28+
13.293750 13.293750
29+
13.774653 13.774653
30+
14.235416 14.235416
31+
14.790973 14.790973
32+
15.513542 15.513542
33+
16.236980 16.236980
34+
16.687500 16.687500
35+
17.133854 17.133854
36+
17.602604 17.602604
37+
18.025520 18.025520
38+
18.467709 18.467709
39+
18.956945 18.956945
40+
19.408333 19.408333
41+
19.870834 19.870834
42+
20.318750 20.318750
43+
20.796354 20.796354
44+
21.228125 21.228125
45+
21.692709 21.692709
46+
22.178646 22.178646
47+
22.714584 22.714584
48+
23.326042 23.326042

0 commit comments

Comments
 (0)