maialib 1.10.2__cp311-cp311-win_amd64.whl
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.
- maialib/__init__.py +4 -0
- maialib/maiacore/Release/__init__.pyi +3 -0
- maialib/maiacore/Release/maiacore.cp311-win_amd64.pyd +0 -0
- maialib/maiacore/Release/maiacore.pyi +1414 -0
- maialib/maiacore/__init__.py +4 -0
- maialib/maiacore/__init__.pyi +24 -0
- maialib/maiapy/__init__.py +3 -0
- maialib/maiapy/__init__.pyi +3 -0
- maialib/maiapy/other.py +148 -0
- maialib/maiapy/other.pyi +79 -0
- maialib/maiapy/plots.py +806 -0
- maialib/maiapy/plots.pyi +103 -0
- maialib/maiapy/sethares_dissonance.py +481 -0
- maialib/maiapy/sethares_dissonance.pyi +128 -0
- maialib/setup.py +61 -0
- maialib/xml-scores-examples/Bach_Cello_Suite_1.mxl +0 -0
- maialib/xml-scores-examples/Beethoven_Symphony_5_mov_1.xml +170525 -0
- maialib/xml-scores-examples/Chopin_Fantasie_Impromptu.mxl +0 -0
- maialib/xml-scores-examples/Dvorak_Symphony_9_mov_4.mxl +0 -0
- maialib/xml-scores-examples/Mahler_Symphony_8_Finale.mxl +0 -0
- maialib/xml-scores-examples/Mozart_Requiem_Introitus.mxl +0 -0
- maialib/xml-scores-examples/Strauss_Also_Sprach_Zarathustra.mxl +0 -0
- maialib-1.10.2.dist-info/METADATA +822 -0
- maialib-1.10.2.dist-info/RECORD +27 -0
- maialib-1.10.2.dist-info/WHEEL +5 -0
- maialib-1.10.2.dist-info/licenses/LICENSE.txt +674 -0
- maialib-1.10.2.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,822 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: maialib
|
|
3
|
+
Version: 1.10.2
|
|
4
|
+
Summary: A C++/Python library to manipulate sheet music data
|
|
5
|
+
Home-page: https://github.com/nyckmaia/maialib
|
|
6
|
+
Author: Nycholas Maia
|
|
7
|
+
Author-email: nyckmaia@gmail.com
|
|
8
|
+
License: GNU General Public License v3 or later (GPLv3+)
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/nyckmaia/maialib/issues
|
|
10
|
+
Keywords: music,score,sheet music,analysis
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: C++
|
|
14
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Intended Audience :: Science/Research
|
|
17
|
+
Classifier: Natural Language :: English
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
19
|
+
Requires-Python: >=3.8.0
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE.txt
|
|
22
|
+
Requires-Dist: pandas>=2.0.0
|
|
23
|
+
Requires-Dist: plotly
|
|
24
|
+
Requires-Dist: kaleido
|
|
25
|
+
Requires-Dist: nbformat
|
|
26
|
+
Dynamic: author
|
|
27
|
+
Dynamic: author-email
|
|
28
|
+
Dynamic: classifier
|
|
29
|
+
Dynamic: description
|
|
30
|
+
Dynamic: description-content-type
|
|
31
|
+
Dynamic: home-page
|
|
32
|
+
Dynamic: keywords
|
|
33
|
+
Dynamic: license
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
Dynamic: project-url
|
|
36
|
+
Dynamic: requires-dist
|
|
37
|
+
Dynamic: requires-python
|
|
38
|
+
Dynamic: summary
|
|
39
|
+
|
|
40
|
+
# 🎵 Maialib - Music Analysis Library for Everyone
|
|
41
|
+
|
|
42
|
+

|
|
43
|
+
[](https://badge.fury.io/py/maialib)
|
|
44
|
+
[](https://pypi.org/project/maialib/)
|
|
45
|
+
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
46
|
+
[](https://pepy.tech/project/maialib)
|
|
47
|
+
|
|
48
|
+
**Analyze and create musical scores using Python - designed for musicians, researchers, and composers.**
|
|
49
|
+
|
|
50
|
+
Whether you're a music student analyzing Bach chorales, a composer generating algorithmic pieces, or a researcher studying harmonic patterns across centuries of music, Maialib makes working with musical scores as easy as a few lines of code.
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
import maialib as ml
|
|
54
|
+
|
|
55
|
+
# Create a middle C note
|
|
56
|
+
note = ml.Note("C#4")
|
|
57
|
+
|
|
58
|
+
# Print information about this note
|
|
59
|
+
print("Note Information:")
|
|
60
|
+
print(f" Pitch: {note.getPitch()}")
|
|
61
|
+
print(f" Pitch class: {note.getPitchClass()}")
|
|
62
|
+
print(f" Pitch Step: {note.getPitchStep()}")
|
|
63
|
+
print(f" Octave: {note.getOctave()}")
|
|
64
|
+
print(f" Alter symbol: {note.getAlterSymbol()}" )
|
|
65
|
+
print(f" Type (long name): {note.getLongType()}")
|
|
66
|
+
print(f" Duration (unit: quarter notes): {note.getQuarterDuration()}")
|
|
67
|
+
print(f" MIDI number: {note.getMidiNumber()}")
|
|
68
|
+
print(f" Frequency: {note.getFrequency():.2f} Hz")
|
|
69
|
+
print(f" Is note on: {note.isNoteOn()}")
|
|
70
|
+
print(f" Is note off: {note.isNoteOff()}")
|
|
71
|
+
print(f" Enharmonic Notes: {note.getEnharmonicNotes()}")
|
|
72
|
+
print(f" Harmonic Spectrum (first 3 partials): {note.getHarmonicSpectrum(numPartials=3, partialsDecayExpRate=0.5)}")
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Output**
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
Note Information:
|
|
79
|
+
Pitch: C#4
|
|
80
|
+
Pitch class: C#
|
|
81
|
+
Pitch Step: C
|
|
82
|
+
Octave: 4
|
|
83
|
+
Alter symbol: #
|
|
84
|
+
Type (long name): quarter
|
|
85
|
+
Duration (unit: quarter notes): 1.0
|
|
86
|
+
MIDI number: 61
|
|
87
|
+
Frequency: 277.18 Hz
|
|
88
|
+
Is note on: True
|
|
89
|
+
Is note off: False
|
|
90
|
+
Ehnarmonic Notes: [<Note Db4>, <Note Bx3>]
|
|
91
|
+
Harmonic Spectrum (first 3 partials): ([277.1826171875, 554.365234375, 831.5478515625], [1.0, 0.5, 0.25])
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**No music software required. No complex APIs. Just simple, powerful Python.**
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## 📑 Table of Contents
|
|
99
|
+
|
|
100
|
+
- [Why Maialib?](#-why-maialib)
|
|
101
|
+
- [Installation](#-installation)
|
|
102
|
+
- [Quick Start](#-quick-start)
|
|
103
|
+
- [Examples Gallery](#-examples-gallery)
|
|
104
|
+
- [What Can You Analyze?](#-what-can-you-analyze)
|
|
105
|
+
- [Documentation](#-documentation)
|
|
106
|
+
- [Included Example Scores](#-included-example-scores)
|
|
107
|
+
- [FAQ](#-faq)
|
|
108
|
+
- [Community & Support](#-community--support)
|
|
109
|
+
- [Contributing](#-contributing)
|
|
110
|
+
- [Citation](#-citation)
|
|
111
|
+
- [License](#%EF%B8%8F-license)
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## ✨ Why Maialib?
|
|
116
|
+
|
|
117
|
+
### Built for Musicians Who Code (or Want to Learn)
|
|
118
|
+
|
|
119
|
+
- **🎹 Musician-Friendly**: Designed with music theory terminology, not just technical jargon
|
|
120
|
+
- **⚡ Lightning Fast**: C++17 core engine with Python interface - get professional performance without complexity
|
|
121
|
+
- **📊 Data Science Ready**: Export to pandas DataFrames for statistical analysis
|
|
122
|
+
- **🎨 Visualization Built-in**: Generate piano rolls, pitch envelopes, and dissonance curves
|
|
123
|
+
- **📝 MusicXML Native**: Read and write standard notation files from MuseScore, Finale, Sibelius
|
|
124
|
+
- **🔬 Research-Grade**: Used in musicology research and composition studies
|
|
125
|
+
- **🎓 Academic Foundation**: Developed as part of doctoral research at UNICAMP (State University of Campinas)
|
|
126
|
+
|
|
127
|
+
### Perfect For:
|
|
128
|
+
|
|
129
|
+
✅ **Music Students** - Analyze scores for theory assignments and research projects <br/>
|
|
130
|
+
✅ **Composers** - Generate algorithmic compositions and explore musical patterns<br/>
|
|
131
|
+
✅ **Musicologists** - Perform computational analysis on large musical corpora<br/>
|
|
132
|
+
✅ **Music Teachers** - Create customized teaching examples and exercises<br/>
|
|
133
|
+
✅ **Arrangers** - Batch transpose scores for different instruments<br/>
|
|
134
|
+
✅ **Performers** - Extract sections and practice specific passages<br/>
|
|
135
|
+
✅ **Researchers** - Conduct quantitative musicology studies
|
|
136
|
+
|
|
137
|
+
### Key Features
|
|
138
|
+
|
|
139
|
+
- **Full MusicXML Support**: Read and write `.xml`, `.mxl`, and `.musicxml` files
|
|
140
|
+
- **High Performance**: C++17 core engine for fast computation on large musical corpora
|
|
141
|
+
- **Built-in Visualizations**: Piano rolls, pitch envelopes, chord analysis, and dissonance curves
|
|
142
|
+
- **Advanced Chord Analysis**: Identify qualities, analyze complexity, and calculate harmonic density
|
|
143
|
+
- **Dissonance Models**: Psychoacoustic dissonance calculation using the Sethares model
|
|
144
|
+
- **DataFrame Export**: Seamless integration with pandas for statistical analysis
|
|
145
|
+
- **Beginner-Friendly**: Simple API designed for musicians without extensive programming experience
|
|
146
|
+
- **Comprehensive Documentation**: Interactive tutorials, examples, and complete API reference
|
|
147
|
+
- **Cross-Platform**: Works on Windows, Linux, and macOS with Python 3.8-3.14
|
|
148
|
+
|
|
149
|
+
### Academic Background
|
|
150
|
+
|
|
151
|
+
Maialib was developed as part of the doctoral thesis:
|
|
152
|
+
|
|
153
|
+
**"maialib: A programming library for computer-aided music analysis and composition with applications on models of dissonance"**
|
|
154
|
+
|
|
155
|
+
- **Author**: Nycholas Maia
|
|
156
|
+
- **Institution**: UNICAMP (Universidade Estadual de Campinas)
|
|
157
|
+
- **Defense Date**: November 25, 2022
|
|
158
|
+
- **Research Focus**: Computational musicology, dissonance models, and algorithmic composition
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## 🔧 Installation
|
|
163
|
+
|
|
164
|
+
### Prerequisites
|
|
165
|
+
|
|
166
|
+
- **Python 3.8 or newer** ([Download here](https://www.python.org/downloads/))
|
|
167
|
+
- Basic command line familiarity (we'll guide you!)
|
|
168
|
+
|
|
169
|
+
### Install in 30 Seconds
|
|
170
|
+
|
|
171
|
+
Open your terminal (or Command Prompt on Windows) and run:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
pip install maialib
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**Upgrading from an older version?**
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
pip install maialib --upgrade
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Verify Installation
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
import maialib as ml
|
|
187
|
+
print(ml.__version__)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
If you see a version number, you're ready to go! 🎉
|
|
191
|
+
|
|
192
|
+
<details>
|
|
193
|
+
<summary>🛠️ Troubleshooting Installation Issues</summary>
|
|
194
|
+
|
|
195
|
+
**"pip: command not found"**
|
|
196
|
+
|
|
197
|
+
- Make sure Python is in your system PATH
|
|
198
|
+
- Try `python -m pip install maialib` or `python3 -m pip install maialib`
|
|
199
|
+
|
|
200
|
+
**"ModuleNotFoundError: No module named 'maialib'"**
|
|
201
|
+
|
|
202
|
+
- Verify installation with `pip list | grep maialib`
|
|
203
|
+
- Make sure you're using the same Python environment
|
|
204
|
+
|
|
205
|
+
**Still having issues?**
|
|
206
|
+
|
|
207
|
+
- [Check our Installation Guide](https://github.com/nyckmaia/maialib/wiki/Installation)
|
|
208
|
+
- [Ask in GitHub Discussions](https://github.com/nyckmaia/maialib/discussions)
|
|
209
|
+
|
|
210
|
+
</details>
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## 🚀 Quick Start
|
|
215
|
+
|
|
216
|
+
### Your First Musical Analysis in 5 Minutes
|
|
217
|
+
|
|
218
|
+
Maialib includes example scores so you can start immediately - no need to find files!
|
|
219
|
+
|
|
220
|
+
```python
|
|
221
|
+
import maialib as ml
|
|
222
|
+
|
|
223
|
+
# Load one of the included Bach examples
|
|
224
|
+
sampleScore = ml.SampleScore.Bach_Cello_Suite_1
|
|
225
|
+
sampleScorePath = ml.getSampleScorePath(sampleScore)
|
|
226
|
+
score = ml.Score(sampleScorePath)
|
|
227
|
+
|
|
228
|
+
# Get basic score information
|
|
229
|
+
print(f"Title: {score.getTitle()}")
|
|
230
|
+
print(f"Composer: {score.getComposerName()}")
|
|
231
|
+
print(f"Number of measures: {score.getNumMeasures()}")
|
|
232
|
+
print(f"Number of notes: {score.getNumNotes()}")
|
|
233
|
+
|
|
234
|
+
# Extract all notes as a pandas DataFrame
|
|
235
|
+
df = score.toDataFrame()
|
|
236
|
+
print("\nFirst 5 notes:")
|
|
237
|
+
print(df.head())
|
|
238
|
+
|
|
239
|
+
# Count notes by pitch class
|
|
240
|
+
pitch_distribution = df['Note'].value_counts()
|
|
241
|
+
print("\nPitch class distribution:")
|
|
242
|
+
print(pitch_distribution)
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**Output:**
|
|
246
|
+
|
|
247
|
+
```
|
|
248
|
+
Title: Cello Suite No. 1
|
|
249
|
+
Composer: Johann Sebastian Bach
|
|
250
|
+
Number of measures: 220
|
|
251
|
+
Number of notes: 2293
|
|
252
|
+
|
|
253
|
+
First 5 notes:
|
|
254
|
+
Part Measure Note
|
|
255
|
+
0 <Part Violoncello> <Measure 0> <Note G2>
|
|
256
|
+
1 <Part Violoncello> <Measure 0> <Note D3>
|
|
257
|
+
2 <Part Violoncello> <Measure 0> <Note B3>
|
|
258
|
+
3 <Part Violoncello> <Measure 0> <Note A3>
|
|
259
|
+
4 <Part Violoncello> <Measure 0> <Note B3>
|
|
260
|
+
|
|
261
|
+
Pitch class distribution:
|
|
262
|
+
Note
|
|
263
|
+
<Note A3> 241
|
|
264
|
+
<Note G3> 184
|
|
265
|
+
<Note F#3> 169
|
|
266
|
+
<Note D3> 156
|
|
267
|
+
<Note B3> 154
|
|
268
|
+
...
|
|
269
|
+
<Note Eb2> 1
|
|
270
|
+
<Note Bb2> 1
|
|
271
|
+
<Note Ab3> 1
|
|
272
|
+
<Note Eb4> 1
|
|
273
|
+
<Note D4> 1
|
|
274
|
+
Name: count, Length: 99, dtype: int64
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Visualize Your Score
|
|
278
|
+
|
|
279
|
+
```python
|
|
280
|
+
# Load one of the included Bach examples
|
|
281
|
+
sampleScore = ml.SampleScore.Bach_Cello_Suite_1
|
|
282
|
+
sampleScorePath = ml.getSampleScorePath(sampleScore)
|
|
283
|
+
score = ml.Score(sampleScorePath)
|
|
284
|
+
|
|
285
|
+
# Generate a piano roll visualization
|
|
286
|
+
fig1, df1 = ml.plotPianoRoll(score, measureStart=1, measureEnd=16)
|
|
287
|
+
fig1.show()
|
|
288
|
+
|
|
289
|
+
# Plot pitch envelope over time
|
|
290
|
+
fig2, df2 = ml.plotScorePitchEnvelope(score, measureStart=1, measureEnd=16)
|
|
291
|
+
fig2.show()
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## 💡 Examples Gallery
|
|
297
|
+
|
|
298
|
+
### Example 1: Get all music chords as a table
|
|
299
|
+
|
|
300
|
+
```python
|
|
301
|
+
import maialib as ml
|
|
302
|
+
|
|
303
|
+
# Load one of the included Chopin examples
|
|
304
|
+
sampleScore = ml.SampleScore.Chopin_Fantasie_Impromptu
|
|
305
|
+
sampleScorePath = ml.getSampleScorePath(sampleScore)
|
|
306
|
+
score = ml.Score(sampleScorePath)
|
|
307
|
+
|
|
308
|
+
# Extract chord data as a pandas DataFrame
|
|
309
|
+
chords = score.getChordsDataFrame()
|
|
310
|
+
print(chords)
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**Output**
|
|
314
|
+
|
|
315
|
+
```
|
|
316
|
+
measure floatMeasure key chord \
|
|
317
|
+
0 1 1.000000 <Key E> <Chord [G#2, G#3]>
|
|
318
|
+
1 2 2.000000 <Key E> <Chord [G#2, G#3]>
|
|
319
|
+
2 3 3.000000 <Key E> <Chord [C#2, C#3]>
|
|
320
|
+
3 3 3.083333 <Key E> <Chord [G#3]>
|
|
321
|
+
4 3 3.166667 <Key E> <Chord [G#3]>
|
|
322
|
+
... ... ... ... ...
|
|
323
|
+
1746 101 101.812500 <Key E> <Chord [G#1, G#2, C#4]>
|
|
324
|
+
1747 101 101.875000 <Key E> <Chord [G#1, G#2, G#4]>
|
|
325
|
+
1748 101 101.937500 <Key E> <Chord [G#1, G#2, F#3]>
|
|
326
|
+
1749 102 102.000000 <Key E> <Chord [C#2, G#2, F#3, G#3, B#3, D#4]>
|
|
327
|
+
1750 103 103.000000 <Key E> <Chord [C#2, G#2, E#3, G#3, C#4]>
|
|
328
|
+
|
|
329
|
+
isHomophonic
|
|
330
|
+
0 True
|
|
331
|
+
1 True
|
|
332
|
+
2 True
|
|
333
|
+
3 True
|
|
334
|
+
4 False
|
|
335
|
+
... ...
|
|
336
|
+
1746 False
|
|
337
|
+
1747 False
|
|
338
|
+
1748 False
|
|
339
|
+
1749 True
|
|
340
|
+
1750 True
|
|
341
|
+
|
|
342
|
+
[1751 rows x 5 columns]
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Example 2: Analyze Melodic Intervals
|
|
346
|
+
|
|
347
|
+
```python
|
|
348
|
+
# Load Beethoven's Symphony No. 5 score
|
|
349
|
+
score = ml.Score(ml.getSampleScorePath(ml.SampleScore.Beethoven_Symphony_5th))
|
|
350
|
+
|
|
351
|
+
# Analyze melodic intervals in the first measure of the first violin part
|
|
352
|
+
firstMeasure = score.getPart('Violins 1').getMeasure(0) # First violin part
|
|
353
|
+
firstMeasureNumNotes = firstMeasure.getNumNotes()
|
|
354
|
+
|
|
355
|
+
# Collect notes in the first measure
|
|
356
|
+
notes = []
|
|
357
|
+
for i in range(firstMeasureNumNotes):
|
|
358
|
+
note = firstMeasure.getNote(i)
|
|
359
|
+
notes.append(note)
|
|
360
|
+
|
|
361
|
+
# Calculate and print melodic intervals
|
|
362
|
+
print("Melodic intervals in opening:")
|
|
363
|
+
for i in range(firstMeasureNumNotes - 1):
|
|
364
|
+
if notes[i].isNoteOff() or notes[i+1].isNoteOff():
|
|
365
|
+
continue
|
|
366
|
+
interval = ml.Interval(notes[i], notes[i+1])
|
|
367
|
+
print(f"{notes[i].getPitch()} → {notes[i+1].getPitch()}: {interval.getName()} ({interval.getNumSemitones()} semitones)")
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
**Output**
|
|
371
|
+
|
|
372
|
+
```
|
|
373
|
+
Melodic intervals in opening:
|
|
374
|
+
G4 → G4: P1 (0 semitones)
|
|
375
|
+
G4 → G4: P1 (0 semitones)
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### Example 3: Find Melodic Patterns
|
|
379
|
+
|
|
380
|
+
```python
|
|
381
|
+
# Load your Beethoven 5th Symphony score (or any other sheet music)
|
|
382
|
+
score = ml.Score('Beethoven_5th_symphony.xml')
|
|
383
|
+
|
|
384
|
+
# Define a pattern to search for (e.g., descending scale fragment)
|
|
385
|
+
pattern = [
|
|
386
|
+
ml.Note("G4"),
|
|
387
|
+
ml.Note("F4"),
|
|
388
|
+
ml.Note("E4"),
|
|
389
|
+
ml.Note("D4")
|
|
390
|
+
]
|
|
391
|
+
|
|
392
|
+
# Find all occurrences
|
|
393
|
+
df_patterns = score.findMelodyPatternDataFrame(
|
|
394
|
+
melodyPattern=pattern,
|
|
395
|
+
totalIntervalsSimilarityThreshold=0.8,
|
|
396
|
+
totalRhythmSimilarityThreshold=0.5
|
|
397
|
+
)
|
|
398
|
+
|
|
399
|
+
print(f"Found {len(df_patterns)} occurrences of the pattern")
|
|
400
|
+
print(df_patterns[['partName', 'measureId', 'transposeInterval', 'totalSimilarity']])
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
**Output**
|
|
404
|
+
|
|
405
|
+
```
|
|
406
|
+
Found 6 occurrences of the pattern
|
|
407
|
+
partName measureId transposeInterval totalSimilarity
|
|
408
|
+
0 Violins 1 406 m3 asc 1.0
|
|
409
|
+
1 Violins 1 409 m7 asc 1.0
|
|
410
|
+
2 Violins 2 406 m3 asc 1.0
|
|
411
|
+
3 Violins 2 409 m7 asc 1.0
|
|
412
|
+
4 Violas 166 M2 desc 1.0
|
|
413
|
+
5 Violas 460 M6 desc 1.0
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Example 4: Statistical Harmonic Analysis
|
|
417
|
+
|
|
418
|
+
```python
|
|
419
|
+
import pandas as pd
|
|
420
|
+
import maialib as ml
|
|
421
|
+
|
|
422
|
+
score = ml.Score('Beethoven_Symphony_5.xml')
|
|
423
|
+
|
|
424
|
+
chords = score.getChords()
|
|
425
|
+
|
|
426
|
+
# Analyze chord quality distribution
|
|
427
|
+
chord_qualities = []
|
|
428
|
+
for _, _, _, chord, _ in chords:
|
|
429
|
+
if chord.isMajorChord():
|
|
430
|
+
chord_qualities.append('Major')
|
|
431
|
+
elif chord.isMinorChord():
|
|
432
|
+
chord_qualities.append('Minor')
|
|
433
|
+
elif chord.isDiminishedChord():
|
|
434
|
+
chord_qualities.append('Diminished')
|
|
435
|
+
elif chord.isAugmentedChord():
|
|
436
|
+
chord_qualities.append('Augmented')
|
|
437
|
+
else:
|
|
438
|
+
chord_qualities.append('Other')
|
|
439
|
+
|
|
440
|
+
# Create distribution
|
|
441
|
+
df = pd.DataFrame({'Quality': chord_qualities})
|
|
442
|
+
distribution = df['Quality'].value_counts(normalize=True) * 100
|
|
443
|
+
|
|
444
|
+
print("Chord quality distribution:")
|
|
445
|
+
print(distribution)
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
**Output**
|
|
449
|
+
|
|
450
|
+
```
|
|
451
|
+
Chord quality distribution:
|
|
452
|
+
Quality
|
|
453
|
+
Other 40.218878
|
|
454
|
+
Major 30.711354
|
|
455
|
+
Minor 22.229822
|
|
456
|
+
Diminished 6.703146
|
|
457
|
+
Augmented 0.136799
|
|
458
|
+
Name: proportion, dtype: float64
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
### Example 5: Dissonance Analysis
|
|
462
|
+
|
|
463
|
+
```python
|
|
464
|
+
# Calculate psychoacoustic dissonance using Sethares model
|
|
465
|
+
score = ml.Score('my_score.xml')
|
|
466
|
+
chords = score.getChords()
|
|
467
|
+
|
|
468
|
+
dissonance_values = []
|
|
469
|
+
for _, _, _, chord, _ in chords:
|
|
470
|
+
# Calculate Sethares dissonance value
|
|
471
|
+
chordDissonance = chord.getSetharesDissonance(numPartialsPerNote=6)
|
|
472
|
+
dissonance_values.append(chordDissonance)
|
|
473
|
+
|
|
474
|
+
print(dissonance_values)
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
**Output**
|
|
478
|
+
|
|
479
|
+
```
|
|
480
|
+
[1.1458631753921509, 1.1458631753921509, 1.1458631753921509, 1.233114242553711, 0.9513687491416931,...]
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
---
|
|
484
|
+
|
|
485
|
+
## 🎹 What Can You Analyze?
|
|
486
|
+
|
|
487
|
+
Maialib provides comprehensive tools for musical analysis:
|
|
488
|
+
|
|
489
|
+
### 🎼 Score Analysis
|
|
490
|
+
|
|
491
|
+
- Load MusicXML files (`.xml`, `.mxl`, `.musicxml`)
|
|
492
|
+
- Extract parts, measures, notes, and chords
|
|
493
|
+
- Access key signatures, time signatures, and tempo markings
|
|
494
|
+
- Export to pandas DataFrames for data science workflows
|
|
495
|
+
|
|
496
|
+
### 🎵 Melodic Analysis
|
|
497
|
+
|
|
498
|
+
- Find melodic patterns and motifs
|
|
499
|
+
- Calculate intervallic contours
|
|
500
|
+
- Analyze pitch distributions and ranges
|
|
501
|
+
- Compute melodic similarity metrics
|
|
502
|
+
|
|
503
|
+
### 🎶 Harmonic Analysis
|
|
504
|
+
|
|
505
|
+
- Extract vertical chord structures
|
|
506
|
+
- Identify chord qualities (major, minor, diminished, augmented)
|
|
507
|
+
- Analyze harmonic complexity and density
|
|
508
|
+
- Calculate psychoacoustic dissonance (Sethares model)
|
|
509
|
+
- Track chord progressions
|
|
510
|
+
|
|
511
|
+
### 🎹 Rhythmic Analysis
|
|
512
|
+
|
|
513
|
+
- Extract rhythmic patterns
|
|
514
|
+
- Analyze duration distributions
|
|
515
|
+
- Calculate rhythmic similarity
|
|
516
|
+
- Study metric structures
|
|
517
|
+
|
|
518
|
+
### 🎨 Visualization
|
|
519
|
+
|
|
520
|
+
- Piano rolls with customizable colors
|
|
521
|
+
- Pitch envelope graphs
|
|
522
|
+
- Chord analysis heatmaps
|
|
523
|
+
- Dissonance curves
|
|
524
|
+
- Statistical distribution plots
|
|
525
|
+
|
|
526
|
+
### ⚙️ Score Manipulation
|
|
527
|
+
|
|
528
|
+
- Transpose to any key
|
|
529
|
+
- Extract specific sections
|
|
530
|
+
- Modify notes, chords, and measures
|
|
531
|
+
- Export modified scores to MusicXML
|
|
532
|
+
|
|
533
|
+
### 📊 Statistical Tools
|
|
534
|
+
|
|
535
|
+
- Convert scores to DataFrames
|
|
536
|
+
- Aggregate data across multiple scores
|
|
537
|
+
- Perform corpus-wide analysis
|
|
538
|
+
- Export data for R, MATLAB, or other tools
|
|
539
|
+
|
|
540
|
+
---
|
|
541
|
+
|
|
542
|
+
## 📚 Documentation
|
|
543
|
+
|
|
544
|
+
### For Musicians & Researchers
|
|
545
|
+
|
|
546
|
+
**🎓 Interactive Tutorials** - Learn by doing with Jupyter notebooks:
|
|
547
|
+
|
|
548
|
+
- [Create Notes and Chords](https://github.com/nyckmaia/maialib/blob/main/python-tutorial/create_notes_chords.ipynb) - Build musical objects from scratch
|
|
549
|
+
- [Create a Score](https://github.com/nyckmaia/maialib/blob/main/python-tutorial/create_score.ipynb) - Generate scores programmatically
|
|
550
|
+
- [Using DataFrames](https://github.com/nyckmaia/maialib/blob/main/python-tutorial/dataframe.ipynb) - Export and analyze with pandas
|
|
551
|
+
- [Get Chords](https://github.com/nyckmaia/maialib/blob/main/python-tutorial/get_chords.ipynb) - Extract harmonic structures
|
|
552
|
+
- [Intervals](https://github.com/nyckmaia/maialib/blob/main/python-tutorial/intervals.ipynb) - Work with melodic and harmonic intervals
|
|
553
|
+
- [Plotting Functions](https://github.com/nyckmaia/maialib/blob/main/python-tutorial/plots.ipynb) - Visualize your analysis
|
|
554
|
+
|
|
555
|
+
**📖 Full Tutorial Collection**: [Browse all tutorials](https://github.com/nyckmaia/maialib/tree/main/python-tutorial)
|
|
556
|
+
|
|
557
|
+
**🌐 API Reference**: [Complete documentation](https://maialib.com/)
|
|
558
|
+
|
|
559
|
+
### For Developers
|
|
560
|
+
|
|
561
|
+
**🛠️ Build from Source**: See [BUILDING.md](BUILDING.md) for C++ compilation instructions
|
|
562
|
+
|
|
563
|
+
**💻 C++ API Documentation**: [Developer docs](https://maialib.com/)
|
|
564
|
+
|
|
565
|
+
**🤝 Contributing**: See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines
|
|
566
|
+
|
|
567
|
+
---
|
|
568
|
+
|
|
569
|
+
## 🎼 Included Example Scores
|
|
570
|
+
|
|
571
|
+
Maialib includes 7 classical works so you can start exploring immediately:
|
|
572
|
+
|
|
573
|
+
- **Bach** - Cello Suite No. 1 (`Bach_Cello_Suite_1.mxl`)
|
|
574
|
+
- **Bach** - Prelude No. 1 in C Major, BWV 846 (`Bach_Prelude_1_BWV_846.xml`)
|
|
575
|
+
- **Beethoven** - String Quartet Op. 133 (`Beethoven_quartet_133.xml`)
|
|
576
|
+
- **Beethoven** - Symphony No. 5, Movement 1 (`Beethoven_Symphony_5_mov_1.xml`)
|
|
577
|
+
- **Chopin** - Fantaisie-Impromptu Op. 66 (`Chopin_Fantasie_Impromptu.mxl`)
|
|
578
|
+
- **Dvořák** - Symphony No. 9 "New World", Movement 4 (`Dvorak_Symphony_9_mov_4.xml`)
|
|
579
|
+
- **Mahler** - Symphony No. 1 "Titan", Movement 1 (`Mahler_Symphony_1_mov_1.mxl`)
|
|
580
|
+
- **Mozart** - Requiem, Introitus (`Mozart_Requiem_Introitus.mxl`)
|
|
581
|
+
- **Strauss** - The Blue Danube Waltz (`Strauss_Blue_Danube.mxl`)
|
|
582
|
+
|
|
583
|
+
**Try them now:**
|
|
584
|
+
|
|
585
|
+
```python
|
|
586
|
+
import maialib as ml
|
|
587
|
+
sampleScorePath = ml.getSampleScorePath(ml.SampleScore.Beethoven_Symphony_5th)
|
|
588
|
+
score = ml.Score(sampleScorePath)
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
---
|
|
592
|
+
|
|
593
|
+
## ❓ FAQ
|
|
594
|
+
|
|
595
|
+
### What is MusicXML?
|
|
596
|
+
|
|
597
|
+
MusicXML is the standard file format for sheet music, like `.docx` for documents or `.pdf` for portable documents. It contains all musical information: notes, rhythms, dynamics, articulations, and layout. Most notation software (MuseScore, Finale, Sibelius) can export to MusicXML.
|
|
598
|
+
|
|
599
|
+
### Where can I find MusicXML files?
|
|
600
|
+
|
|
601
|
+
Many sources offer free MusicXML downloads:
|
|
602
|
+
|
|
603
|
+
- [MuseScore.com](https://musescore.com) - Largest free sheet music library
|
|
604
|
+
- [IMSLP](https://imslp.org) - Public domain classical music
|
|
605
|
+
- [MusicXML.com](https://www.musicxml.com/music-in-musicxml/) - Sample files
|
|
606
|
+
- Export from your own notation software
|
|
607
|
+
|
|
608
|
+
### What if I don't have a MusicXML file?
|
|
609
|
+
|
|
610
|
+
You have several options:
|
|
611
|
+
|
|
612
|
+
1. **Convert from MIDI**: Import MIDI files into MuseScore (free) and export as MusicXML
|
|
613
|
+
2. **Scan PDF scores**: Use OMR (Optical Music Recognition) software:
|
|
614
|
+
- [MuseScore Import](https://musescore.com/import) - Experimental, free
|
|
615
|
+
- [ACE Studio PDF to MusicXML](https://acestudio.ai/pdf-to-musicxml/) - Free converter
|
|
616
|
+
- [Sibelius PhotoScore](https://www.avid.com/photoscore-and-notateme-lite) - Professional option
|
|
617
|
+
3. **Use included examples**: Maialib comes with 7 classical works ready to analyze!
|
|
618
|
+
|
|
619
|
+
### Do I need programming experience?
|
|
620
|
+
|
|
621
|
+
**Beginner-friendly:** If you've never programmed before, start with our [interactive tutorials](https://github.com/nyckmaia/maialib/tree/main/python-tutorial). Basic Python knowledge helps, but you can learn as you go. Most common tasks require just 3-5 lines of code.
|
|
622
|
+
|
|
623
|
+
**Intermediate users:** If you know Python basics, you'll be productive immediately.
|
|
624
|
+
|
|
625
|
+
**Advanced users:** Full C++ source code available for custom extensions.
|
|
626
|
+
|
|
627
|
+
### Can I use Maialib for commercial projects?
|
|
628
|
+
|
|
629
|
+
Yes! Maialib is licensed under GPL-3.0, which allows commercial use. However:
|
|
630
|
+
|
|
631
|
+
- ✅ You can use Maialib in commercial research, analysis, or composition
|
|
632
|
+
- ✅ You can sell music created or analyzed with Maialib
|
|
633
|
+
- ⚠️ If you distribute software that uses Maialib, you must also license it under GPL-3.0
|
|
634
|
+
- 📖 See [license details](#%EF%B8%8F-license) below
|
|
635
|
+
|
|
636
|
+
### How do I cite Maialib in my research?
|
|
637
|
+
|
|
638
|
+
```bibtex
|
|
639
|
+
@software{maialib2024,
|
|
640
|
+
author = {Maia, Nycholas},
|
|
641
|
+
title = {Maialib: Music Analysis Library},
|
|
642
|
+
year = {2024},
|
|
643
|
+
url = {https://github.com/nyckmaia/maialib},
|
|
644
|
+
version = {1.0}
|
|
645
|
+
}
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
Text citation: "Analysis performed using Maialib (Maia, 2024), a Python library for computational musicology."
|
|
649
|
+
|
|
650
|
+
### Does Maialib work with MIDI files?
|
|
651
|
+
|
|
652
|
+
Not directly. Maialib is designed for MusicXML, which contains more musical information than MIDI (articulations, dynamics, score layout). However, you can:
|
|
653
|
+
|
|
654
|
+
1. Convert MIDI → MusicXML using MuseScore
|
|
655
|
+
2. Load the MusicXML file into Maialib
|
|
656
|
+
3. Export back to MIDI if needed
|
|
657
|
+
|
|
658
|
+
### How is this different from notation software like MuseScore or Finale?
|
|
659
|
+
|
|
660
|
+
**Notation Software** (MuseScore, Finale, Sibelius):
|
|
661
|
+
|
|
662
|
+
- Visual editing of scores
|
|
663
|
+
- Playback and engraving
|
|
664
|
+
- Manual analysis
|
|
665
|
+
|
|
666
|
+
**Maialib**:
|
|
667
|
+
|
|
668
|
+
- Programmatic analysis at scale
|
|
669
|
+
- Statistical and computational musicology
|
|
670
|
+
- Batch processing hundreds of scores
|
|
671
|
+
- Algorithmic composition
|
|
672
|
+
- Integration with data science tools
|
|
673
|
+
|
|
674
|
+
**Use both together!** Edit scores in MuseScore, analyze them with Maialib.
|
|
675
|
+
|
|
676
|
+
### What Python version do I need?
|
|
677
|
+
|
|
678
|
+
Maialib supports **Python 3.8 through 3.14**. Check your version:
|
|
679
|
+
|
|
680
|
+
```bash
|
|
681
|
+
python --version
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
### Can I contribute to Maialib?
|
|
685
|
+
|
|
686
|
+
Absolutely! We welcome:
|
|
687
|
+
|
|
688
|
+
- 🐛 Bug reports and fixes
|
|
689
|
+
- ✨ Feature requests and implementations
|
|
690
|
+
- 📚 Documentation improvements
|
|
691
|
+
- 🌍 Translation help
|
|
692
|
+
- 🎵 Example scores and tutorials
|
|
693
|
+
|
|
694
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) to get started.
|
|
695
|
+
|
|
696
|
+
### Is there a community?
|
|
697
|
+
|
|
698
|
+
Yes! Connect with other Maialib users:
|
|
699
|
+
|
|
700
|
+
- 💬 [GitHub Discussions](https://github.com/nyckmaia/maialib/discussions) - Ask questions, share projects
|
|
701
|
+
- 🐛 [Issue Tracker](https://github.com/nyckmaia/maialib/issues) - Report bugs, request features
|
|
702
|
+
- 📧 [Email maintainer](mailto:nyckmaia@gmail.com) - Direct contact
|
|
703
|
+
|
|
704
|
+
---
|
|
705
|
+
|
|
706
|
+
## 🤝 Community & Support
|
|
707
|
+
|
|
708
|
+
### Get Help
|
|
709
|
+
|
|
710
|
+
- 💬 **[GitHub Discussions](https://github.com/nyckmaia/maialib/discussions)** - Ask questions, share your projects
|
|
711
|
+
- 🐛 **[Issue Tracker](https://github.com/nyckmaia/maialib/issues)** - Report bugs or request features
|
|
712
|
+
- 📖 **[Documentation](https://maialib.com)** - Complete API reference
|
|
713
|
+
- 📧 **[Email](mailto:nyckmaia@gmail.com)** - Contact the maintainer
|
|
714
|
+
|
|
715
|
+
### Share Your Work
|
|
716
|
+
|
|
717
|
+
Built something cool with Maialib? We'd love to hear about it!
|
|
718
|
+
|
|
719
|
+
- Share in [GitHub Discussions](https://github.com/nyckmaia/maialib/discussions/categories/show-and-tell)
|
|
720
|
+
- Tag `#maialib` on social media
|
|
721
|
+
- Submit your project to our showcase
|
|
722
|
+
|
|
723
|
+
---
|
|
724
|
+
|
|
725
|
+
## 🌟 Contributing
|
|
726
|
+
|
|
727
|
+
We welcome contributions from musicians, programmers, and researchers!
|
|
728
|
+
|
|
729
|
+
**Ways to contribute:**
|
|
730
|
+
|
|
731
|
+
- 🐛 Report bugs or suggest features in [Issues](https://github.com/nyckmaia/maialib/issues)
|
|
732
|
+
- 📝 Improve documentation or tutorials
|
|
733
|
+
- 🎵 Share example scores or analysis notebooks
|
|
734
|
+
- 💻 Submit code improvements via Pull Requests
|
|
735
|
+
|
|
736
|
+
**Getting started:**
|
|
737
|
+
|
|
738
|
+
1. Fork the repository
|
|
739
|
+
2. Make your improvements
|
|
740
|
+
3. Submit a Pull Request
|
|
741
|
+
|
|
742
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.
|
|
743
|
+
|
|
744
|
+
---
|
|
745
|
+
|
|
746
|
+
## 📖 Citation
|
|
747
|
+
|
|
748
|
+
If you use Maialib in your research, please cite:
|
|
749
|
+
|
|
750
|
+
```bibtex
|
|
751
|
+
@software{maialib2022,
|
|
752
|
+
author = {Maia, Nycholas},
|
|
753
|
+
title = {Maialib: Music Analysis Library for Computational Musicology},
|
|
754
|
+
year = {2022},
|
|
755
|
+
publisher = {GitHub},
|
|
756
|
+
url = {https://github.com/nyckmaia/maialib},
|
|
757
|
+
version = {1.10.0}
|
|
758
|
+
}
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
**Text format:**
|
|
762
|
+
|
|
763
|
+
> Maia, N. (2022). _Maialib: Music Analysis Library for Computational Musicology_ (Version 1.10.0) [Computer software]. https://github.com/nyckmaia/maialib
|
|
764
|
+
|
|
765
|
+
---
|
|
766
|
+
|
|
767
|
+
## ⚖️ License
|
|
768
|
+
|
|
769
|
+
Maialib is licensed under the **[GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.html)**.
|
|
770
|
+
|
|
771
|
+
**What this means in plain language:**
|
|
772
|
+
|
|
773
|
+
✅ **You CAN:**
|
|
774
|
+
|
|
775
|
+
- Use Maialib for personal projects, research, and commercial work
|
|
776
|
+
- Modify the source code
|
|
777
|
+
- Distribute modified versions
|
|
778
|
+
- Use it in academic publications
|
|
779
|
+
|
|
780
|
+
⚠️ **You MUST:**
|
|
781
|
+
|
|
782
|
+
- Keep the same GPL-3.0 license if you distribute modified versions
|
|
783
|
+
- Provide source code if you distribute software that includes Maialib
|
|
784
|
+
- Give credit to the original authors
|
|
785
|
+
|
|
786
|
+
📚 **For academic use:** Simply cite Maialib in your publications (see [Citation](#-citation))
|
|
787
|
+
|
|
788
|
+
🎵 **For creative work:** Music you create or analyze with Maialib is yours - the license only applies to the software itself.
|
|
789
|
+
|
|
790
|
+
**Questions about licensing?** [Contact us](mailto:nyckmaia@gmail.com)
|
|
791
|
+
|
|
792
|
+
---
|
|
793
|
+
|
|
794
|
+
## 📖 Glossary
|
|
795
|
+
|
|
796
|
+
<details>
|
|
797
|
+
<summary>Click to expand - Terms for non-programmers</summary>
|
|
798
|
+
|
|
799
|
+
- **API**: Application Programming Interface - the set of functions and commands available in Maialib
|
|
800
|
+
- **DataFrame**: A table-like data structure (like Excel spreadsheets) used for organizing and analyzing data
|
|
801
|
+
- **MusicXML**: Standard file format for musical notation, readable by most music software
|
|
802
|
+
- **MIDI**: Musical Instrument Digital Interface - a simpler music format focusing on performance data
|
|
803
|
+
- **Python Package**: Pre-built software you install with one command (`pip install`)
|
|
804
|
+
- **pip**: Python's package installer - the tool used to install Maialib
|
|
805
|
+
- **Transpose**: Shift all notes up or down by a specific interval
|
|
806
|
+
- **Chord Quality**: The type of chord (major, minor, diminished, augmented, etc.)
|
|
807
|
+
- **Pitch Class**: The note name without octave (C, D, E, etc.)
|
|
808
|
+
- **Harmonic Analysis**: Studying chords and their relationships in music
|
|
809
|
+
- **Melodic Contour**: The shape of a melody (ascending, descending, etc.)
|
|
810
|
+
- **Dissonance**: Musical tension or roughness between simultaneous notes
|
|
811
|
+
|
|
812
|
+
</details>
|
|
813
|
+
|
|
814
|
+
---
|
|
815
|
+
|
|
816
|
+
<div align="center">
|
|
817
|
+
|
|
818
|
+
**Made with ❤️ for musicians and researchers**
|
|
819
|
+
|
|
820
|
+
[⭐ Star us on GitHub](https://github.com/nyckmaia/maialib) | [🐛 Report Issues](https://github.com/nyckmaia/maialib/issues) | [💬 Join Discussions](https://github.com/nyckmaia/maialib/discussions)
|
|
821
|
+
|
|
822
|
+
</div>
|