midiharmony 26.1.27__py3-none-any.whl → 26.1.30__py3-none-any.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.
midiharmony/README.md CHANGED
@@ -13,17 +13,138 @@
13
13
 
14
14
  ## Install
15
15
 
16
+ ### Standard processing on CPU (default)
17
+
16
18
  ```sh
17
19
  !pip install -U midiharmony
18
20
  ```
19
21
 
22
+ ### Accelerated processing on GPU
23
+
24
+ ```sh
25
+ !pip install -U midiharmony[gpu]
26
+ ```
27
+
20
28
  ***
21
29
 
22
- ## Basic use example
30
+ ## Basic use examples
31
+ *Using midiharmony is easy and requires just two lines of code :)*
32
+
33
+ ### Analyze a single MIDI
23
34
 
24
35
  ```python
25
36
  import midiharmony
37
+
38
+ midi_harmony_dict = midiharmony.analyze_midi('Come To My Window.mid')
39
+
40
+ # This code will return a single dictionary with harmony stats
41
+ {'midi_path': 'Come To My Window.mid',
42
+ 'midi_name': 'Come To My Window',
43
+ 'total_chords_count': 2287,
44
+ 'bad_chords_count': 11,
45
+ 'grouped_chords_count': 1861,
46
+ 'total_quads_count': 1861,
47
+ 'unique_quads_count': 644,
48
+ 'harmonic_quads_count': 470,
49
+ 'harmony_ratio': 0.7298136645962733
50
+ }
26
51
  ```
27
52
 
53
+ ### Analyze MIDI folder(s)
54
+
55
+ ```python
56
+ import midiharmony
57
+
58
+ midi_harmony_dicts_list = midiharmony.analyze_midi_folders(['./midi_folder_1',
59
+ './midi_folder_2',
60
+ './midi_folder_3'
61
+ ])
62
+
63
+ # This code will return a list of dictionaries with harmony stats
64
+ # for all processed MIDIs from all specified folders
65
+ [
66
+ {'midi_path': 'midi_folder_1/Bach Violin 2.mid',
67
+ 'midi_name': 'Bach Violin 2',
68
+ 'total_chords_count': 1089,
69
+ 'bad_chords_count': 71,
70
+ 'grouped_chords_count': 1045,
71
+ 'total_quads_count': 1045,
72
+ 'unique_quads_count': 974,
73
+ 'harmonic_quads_count': 867,
74
+ 'harmony_ratio': 0.8901437371663244},
75
+ {'midi_path': 'midi_folder_2/Camping at Aylm.mid',
76
+ 'midi_name': 'Camping at Aylm',
77
+ 'total_chords_count': 417,
78
+ 'bad_chords_count': 7,
79
+ 'grouped_chords_count': 383,
80
+ 'total_quads_count': 383,
81
+ 'unique_quads_count': 369,
82
+ 'harmonic_quads_count': 326,
83
+ 'harmony_ratio': 0.8834688346883469},
84
+ {'midi_path': 'midi_folder_3/Come To My Window.mid',
85
+ 'midi_name': 'Come To My Window',
86
+ 'total_chords_count': 2287,
87
+ 'bad_chords_count': 11,
88
+ 'grouped_chords_count': 1861,
89
+ 'total_quads_count': 1861,
90
+ 'unique_quads_count': 644,
91
+ 'harmonic_quads_count': 470,
92
+ 'harmony_ratio': 0.7298136645962733}
93
+ ]
94
+ ```
95
+
96
+ ***
97
+
98
+ ## NOTES
99
+
100
+ * Most important value in each returned midi_harmony_dictionary is the "harmony_ratio"
101
+ * High harmony_ratio (>=0.75) indicates good harmony
102
+ * Exceptional harmony is indicated by harmony_ratio >= 0.9
103
+
104
+ ***
105
+
106
+ ## midiharmony API reference list
107
+
108
+ ```midiharmony.find_quads_fast_cupy```
109
+ *Count matching 4‑chord rows between two arrays using a GPU‑accelerated FNV‑1a hash.*
110
+
111
+ ```midiharmony.find_quads_fast_numpy```
112
+ *Count matching 4‑chord rows between two arrays using NumPy on CPU.*
113
+
114
+ ```midiharmony.get_trg_array```
115
+ *Load and cache the target harmonic‑quad array in NumPy or CuPy form.*
116
+
117
+ ```midiharmony.process_midi```
118
+ *Extract chords, grouped chords, and unique 4‑chord quads from a MIDI file.*
119
+
120
+ ```midiharmony.analyze_processed_midi```
121
+ *Compare extracted quads against the target database and compute harmony metrics.*
122
+
123
+ ```midiharmony.analyze_midi```
124
+ *Run the full pipeline: process a MIDI file and evaluate its harmonic quality.*
125
+
126
+ ```midiharmony.analyze_midi_folders```
127
+ *Batch‑analyze all MIDI files in one or more folders and return harmony reports.*
128
+
129
+ ```midiharmony.helpers.get_package_data```
130
+ *Return a sorted list of packaged `.npz` data files with their resolved paths.*
131
+
132
+ ```midiharmony.helpers.get_normalized_midi_md5_hash```
133
+ *Compute original and normalized MD5 hashes for any MIDI file.*
134
+
135
+ ```midiharmony.helpers.normalize_midi_file```
136
+ *Normalize a MIDI file and write the normalized version to disk.*
137
+
138
+ ```midiharmony.helpers.is_installed```
139
+ *Check whether a Debian package is installed using `dpkg-query`.*
140
+
141
+ ```midiharmony.helpers._run_apt_get```
142
+ *Internal helper to run `apt-get` commands with consistent flags and timeout.*
143
+
144
+ ```midiharmony.helpers.install_apt_package```
145
+ *Idempotently install an apt package with retries, optional sudo, and optional python‑apt.*
146
+
147
+ ***
148
+
28
149
  ### Project Los Angeles
29
150
  ### Tegridy Code 2026
@@ -62,8 +62,6 @@ print('=' * 70)
62
62
 
63
63
  import os, copy, time
64
64
 
65
- from typing import List, Optional, Union, Tuple, Dict, Any
66
-
67
65
  import tqdm
68
66
 
69
67
  ###################################################################################
@@ -157,8 +155,25 @@ def find_quads_fast_numpy(src_array: np.ndarray, trg_array: np.ndarray) -> int:
157
155
  _trg_cache_np = None
158
156
  _trg_cache_cp = None
159
157
 
160
- def get_trg_array(use_gpu=False, verbose=True):
158
+ def get_trg_array(use_gpu: bool = False, verbose: bool = True):
161
159
 
160
+ """
161
+ Load and cache the target harmonic‑chord array in either NumPy (CPU) or CuPy (GPU) form.
162
+
163
+ Parameters
164
+ ----------
165
+ use_gpu : bool, optional
166
+ If True, return a cached CuPy array; otherwise return a cached NumPy array.
167
+ Falls back to NumPy automatically if CuPy is unavailable.
168
+ verbose : bool, optional
169
+ If True, print diagnostic messages when loading arrays for the first time.
170
+
171
+ Returns
172
+ -------
173
+ numpy.ndarray or cupy.ndarray
174
+ The cached target array, loaded once and reused across calls.
175
+ """
176
+
162
177
  global _trg_cache_np, _trg_cache_cp
163
178
 
164
179
  if not use_gpu:
@@ -191,9 +206,44 @@ def get_trg_array(use_gpu=False, verbose=True):
191
206
 
192
207
  ###################################################################################
193
208
 
194
- def process_midi(midi_file_path,
195
- verbose=True
196
- ):
209
+ def process_midi(midi_file_path: str, verbose: bool = True):
210
+
211
+ """
212
+ Analyze a MIDI file and extract harmonic information, chord statistics,
213
+ and unique 4‑chord progression quads.
214
+
215
+ Parameters
216
+ ----------
217
+ midi_file_path : str
218
+ Path to the MIDI file to process.
219
+ verbose : bool, optional
220
+ If True, print progress messages and execution timing.
221
+
222
+ Returns
223
+ -------
224
+ dict
225
+ A dictionary containing:
226
+
227
+ - 'midi_path' : str
228
+ Original file path.
229
+ - 'midi_name' : str
230
+ File name without extension.
231
+ - 'total_chords_count' : int
232
+ Number of chordified events.
233
+ - 'bad_chords_count' : int
234
+ Number of chords that required correction.
235
+ - 'grouped_chords_count' : int
236
+ Length of the grouped chord sequence.
237
+ - 'total_quads_count' : int
238
+ Total number of extracted 4‑chord windows.
239
+ - 'unique_quads_count' : int
240
+ Number of unique 4‑chord quads.
241
+ - 'quads' : list[tuple[int]]
242
+ Unique 4‑chord progressions discovered.
243
+
244
+ Returns an empty dictionary if the MIDI contains no events,
245
+ only drums, or an exception occurs.
246
+ """
197
247
 
198
248
  midi_name = os.path.splitext(os.path.basename(midi_file_path))[0]
199
249
 
@@ -351,9 +401,37 @@ def process_midi(midi_file_path,
351
401
  ###################################################################################
352
402
 
353
403
  def analyze_processed_midi(processed_midi_dict,
354
- keep_quads=False,
355
- verbose=False
404
+ keep_quads: bool = False,
405
+ verbose: bool = False
356
406
  ):
407
+
408
+ """
409
+ Evaluate harmonic quality of a processed MIDI file by comparing its
410
+ extracted chord‑quad sequences against the target quad database.
411
+
412
+ Parameters
413
+ ----------
414
+ processed_midi_dict : dict
415
+ Output dictionary from `process_midi`, containing extracted chord
416
+ information and a 'quads' list of 4‑chord progressions.
417
+ keep_quads : bool, optional
418
+ If True, preserve the original 'quads' list in the returned dictionary.
419
+ If False, omit it to reduce memory usage.
420
+ verbose : bool, optional
421
+ If True, print progress messages and timing information.
422
+
423
+ Returns
424
+ -------
425
+ dict
426
+ A dictionary containing the original processed‑MIDI metadata plus:
427
+
428
+ - 'harmonic_quads_count' : int
429
+ Number of quads that match entries in the target quad database.
430
+ - 'harmony_ratio' : float
431
+ Fraction of matching quads relative to total quads.
432
+
433
+ If `keep_quads` is False, the 'quads' key is removed.
434
+ """
357
435
 
358
436
  if verbose:
359
437
 
@@ -418,9 +496,26 @@ def analyze_processed_midi(processed_midi_dict,
418
496
 
419
497
  ###################################################################################
420
498
 
421
- def analyze_midi(midi_file_path,
422
- verbose=True
423
- ):
499
+ def analyze_midi(midi_file_path: str, verbose: bool = True):
500
+
501
+ """
502
+ End‑to‑end MIDI harmony analysis pipeline combining chord extraction
503
+ and harmonic‑quad evaluation.
504
+
505
+ Parameters
506
+ ----------
507
+ midi_file_path : str
508
+ Path to the MIDI file to analyze.
509
+ verbose : bool, optional
510
+ If True, print progress messages and total execution time.
511
+
512
+ Returns
513
+ -------
514
+ dict
515
+ The harmony‑analysis dictionary produced by `analyze_processed_midi`.
516
+ Returns an empty dictionary if processing fails or the MIDI contains
517
+ no analyzable harmonic content.
518
+ """
424
519
 
425
520
  processed_midi_dict = {}
426
521
  harmony_dict = {}
@@ -450,12 +545,35 @@ def analyze_midi(midi_file_path,
450
545
 
451
546
  ###################################################################################
452
547
 
453
- def analyze_midi_folder(midi_folders_paths_list,
454
- midi_files_extensions=['.mid', '.midi', '.kar'],
455
- show_progress_bar=True,
456
- verbose=False
457
- ):
548
+ def analyze_midi_folders(midi_folders_paths_list,
549
+ midi_files_extensions=['.mid', '.midi', '.kar'],
550
+ show_progress_bar: bool = True,
551
+ verbose: bool = False
552
+ ):
458
553
 
554
+ """
555
+ Batch‑analyze all MIDI files inside one or more folders, producing
556
+ harmony‑analysis dictionaries for each valid file.
557
+
558
+ Parameters
559
+ ----------
560
+ midi_folders_paths_list : list[str]
561
+ List of folder paths to search for MIDI files.
562
+ midi_files_extensions : list[str], optional
563
+ File extensions to include when scanning folders.
564
+ show_progress_bar : bool, optional
565
+ If True, display a tqdm progress bar while processing files.
566
+ verbose : bool, optional
567
+ If True, print diagnostic information and timing details.
568
+
569
+ Returns
570
+ -------
571
+ list[dict]
572
+ A list of harmony‑analysis dictionaries, one per successfully
573
+ processed MIDI file. Files that fail processing or contain no
574
+ analyzable harmonic content are skipped.
575
+ """
576
+
459
577
  if verbose:
460
578
  start_time = time.time()
461
579
 
@@ -0,0 +1,194 @@
1
+ Metadata-Version: 2.4
2
+ Name: midiharmony
3
+ Version: 26.1.30
4
+ Summary: Fast, data‑driven harmony analysis for any MIDI file
5
+ Author-email: Alex Lev <alexlev61@proton.me>
6
+ Maintainer-email: Alex Lev <alexlev61@proton.me>
7
+ License-Expression: Apache-2.0
8
+ Project-URL: Homepage, https://github.com/asigalov61/midiharmony
9
+ Project-URL: SoundCloud, https://soundcloud.com/aleksandr-sigalov-61/
10
+ Project-URL: Documentation, https://github.com/asigalov61/midiharmony
11
+ Project-URL: Issues, https://github.com/asigalov61/midiharmony/issues
12
+ Project-URL: Discussions, https://github.com/asigalov61/midiharmony/discussions
13
+ Project-URL: Dataset, https://huggingface.co/datasets/projectlosangeles/Discover-MIDI-Dataset
14
+ Keywords: MIDI,MIDI harmony,harmony,symbolic music,music,music harmony,harmony analysis,harmonic analysis,music information retrieval,MIR,music discovery,music search,music quality,music metadata,music recommendation,research,musicology,music analysis
15
+ Classifier: Development Status :: 5 - Production/Stable
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Intended Audience :: Science/Research
18
+ Classifier: Intended Audience :: Education
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3 :: Only
22
+ Classifier: Programming Language :: Python :: 3.8
23
+ Classifier: Programming Language :: Python :: 3.9
24
+ Classifier: Programming Language :: Python :: 3.10
25
+ Classifier: Programming Language :: Python :: 3.11
26
+ Classifier: Programming Language :: Python :: 3.12
27
+ Classifier: Topic :: Multimedia :: Sound/Audio
28
+ Classifier: Topic :: Multimedia :: Sound/Audio :: MIDI
29
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
30
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
31
+ Classifier: Environment :: Console
32
+ Classifier: Natural Language :: English
33
+ Classifier: Typing :: Typed
34
+ Requires-Python: >=3.8
35
+ Description-Content-Type: text/markdown
36
+ License-File: LICENSE
37
+ Requires-Dist: tqdm
38
+ Requires-Dist: matplotlib
39
+ Requires-Dist: numpy==1.26.4
40
+ Provides-Extra: gpu
41
+ Requires-Dist: cupy-cuda12x; extra == "gpu"
42
+ Requires-Dist: numpy==1.26.4; extra == "gpu"
43
+ Dynamic: license-file
44
+
45
+ # midiharmony
46
+ ## Fast, data‑driven harmony analysis for any MIDI file
47
+
48
+ <img width="1024" height="1024" alt="midiharmony" src="https://github.com/user-attachments/assets/586cf022-ce06-4cea-bfdc-ffcf9b0365d1" />
49
+
50
+ ***
51
+
52
+ ## Abstract
53
+
54
+ *midiharmony provides fast, stand‑alone harmony analysis for MIDI files by comparing their chord and note relationships against a high‑quality database of extracted chord quads. This approach enables reliable detection of strong harmonic structure, musically coherent progressions, and potential inconsistencies, making it a practical tool for music‑AI pipelines, composition analysis, and large‑scale MIDI processing.*
55
+
56
+ ***
57
+
58
+ ## Install
59
+
60
+ ### Standard processing on CPU (default)
61
+
62
+ ```sh
63
+ !pip install -U midiharmony
64
+ ```
65
+
66
+ ### Accelerated processing on GPU
67
+
68
+ ```sh
69
+ !pip install -U midiharmony[gpu]
70
+ ```
71
+
72
+ ***
73
+
74
+ ## Basic use examples
75
+ *Using midiharmony is easy and requires just two lines of code :)*
76
+
77
+ ### Analyze a single MIDI
78
+
79
+ ```python
80
+ import midiharmony
81
+
82
+ midi_harmony_dict = midiharmony.analyze_midi('Come To My Window.mid')
83
+
84
+ # This code will return a single dictionary with harmony stats
85
+ {'midi_path': 'Come To My Window.mid',
86
+ 'midi_name': 'Come To My Window',
87
+ 'total_chords_count': 2287,
88
+ 'bad_chords_count': 11,
89
+ 'grouped_chords_count': 1861,
90
+ 'total_quads_count': 1861,
91
+ 'unique_quads_count': 644,
92
+ 'harmonic_quads_count': 470,
93
+ 'harmony_ratio': 0.7298136645962733
94
+ }
95
+ ```
96
+
97
+ ### Analyze MIDI folder(s)
98
+
99
+ ```python
100
+ import midiharmony
101
+
102
+ midi_harmony_dicts_list = midiharmony.analyze_midi_folders(['./midi_folder_1',
103
+ './midi_folder_2',
104
+ './midi_folder_3'
105
+ ])
106
+
107
+ # This code will return a list of dictionaries with harmony stats
108
+ # for all processed MIDIs from all specified folders
109
+ [
110
+ {'midi_path': 'midi_folder_1/Bach Violin 2.mid',
111
+ 'midi_name': 'Bach Violin 2',
112
+ 'total_chords_count': 1089,
113
+ 'bad_chords_count': 71,
114
+ 'grouped_chords_count': 1045,
115
+ 'total_quads_count': 1045,
116
+ 'unique_quads_count': 974,
117
+ 'harmonic_quads_count': 867,
118
+ 'harmony_ratio': 0.8901437371663244},
119
+ {'midi_path': 'midi_folder_2/Camping at Aylm.mid',
120
+ 'midi_name': 'Camping at Aylm',
121
+ 'total_chords_count': 417,
122
+ 'bad_chords_count': 7,
123
+ 'grouped_chords_count': 383,
124
+ 'total_quads_count': 383,
125
+ 'unique_quads_count': 369,
126
+ 'harmonic_quads_count': 326,
127
+ 'harmony_ratio': 0.8834688346883469},
128
+ {'midi_path': 'midi_folder_3/Come To My Window.mid',
129
+ 'midi_name': 'Come To My Window',
130
+ 'total_chords_count': 2287,
131
+ 'bad_chords_count': 11,
132
+ 'grouped_chords_count': 1861,
133
+ 'total_quads_count': 1861,
134
+ 'unique_quads_count': 644,
135
+ 'harmonic_quads_count': 470,
136
+ 'harmony_ratio': 0.7298136645962733}
137
+ ]
138
+ ```
139
+
140
+ ***
141
+
142
+ ## NOTES
143
+
144
+ * Most important value in each returned midi_harmony_dictionary is the "harmony_ratio"
145
+ * High harmony_ratio (>=0.75) indicates good harmony
146
+ * Exceptional harmony is indicated by harmony_ratio >= 0.9
147
+
148
+ ***
149
+
150
+ ## midiharmony API reference list
151
+
152
+ ```midiharmony.find_quads_fast_cupy```
153
+ *Count matching 4‑chord rows between two arrays using a GPU‑accelerated FNV‑1a hash.*
154
+
155
+ ```midiharmony.find_quads_fast_numpy```
156
+ *Count matching 4‑chord rows between two arrays using NumPy on CPU.*
157
+
158
+ ```midiharmony.get_trg_array```
159
+ *Load and cache the target harmonic‑quad array in NumPy or CuPy form.*
160
+
161
+ ```midiharmony.process_midi```
162
+ *Extract chords, grouped chords, and unique 4‑chord quads from a MIDI file.*
163
+
164
+ ```midiharmony.analyze_processed_midi```
165
+ *Compare extracted quads against the target database and compute harmony metrics.*
166
+
167
+ ```midiharmony.analyze_midi```
168
+ *Run the full pipeline: process a MIDI file and evaluate its harmonic quality.*
169
+
170
+ ```midiharmony.analyze_midi_folders```
171
+ *Batch‑analyze all MIDI files in one or more folders and return harmony reports.*
172
+
173
+ ```midiharmony.helpers.get_package_data```
174
+ *Return a sorted list of packaged `.npz` data files with their resolved paths.*
175
+
176
+ ```midiharmony.helpers.get_normalized_midi_md5_hash```
177
+ *Compute original and normalized MD5 hashes for any MIDI file.*
178
+
179
+ ```midiharmony.helpers.normalize_midi_file```
180
+ *Normalize a MIDI file and write the normalized version to disk.*
181
+
182
+ ```midiharmony.helpers.is_installed```
183
+ *Check whether a Debian package is installed using `dpkg-query`.*
184
+
185
+ ```midiharmony.helpers._run_apt_get```
186
+ *Internal helper to run `apt-get` commands with consistent flags and timeout.*
187
+
188
+ ```midiharmony.helpers.install_apt_package```
189
+ *Idempotently install an apt package with retries, optional sudo, and optional python‑apt.*
190
+
191
+ ***
192
+
193
+ ### Project Los Angeles
194
+ ### Tegridy Code 2026
@@ -1,10 +1,10 @@
1
1
  midiharmony/MIDI.py,sha256=kANk5j1-EMnW0cWlrKQca5A-KM7oy0BtE5eYUKPuG-k,69614
2
- midiharmony/README.md,sha256=-DMhg4O9Dt9l5qj67R7RIO274sC_raxh1b-CVq2ySpE,823
2
+ midiharmony/README.md,sha256=PzIQOOQvwNK41JqEvTviD0e0EatpNPdDe_nw-ooOEL0,4686
3
3
  midiharmony/TMIDIX.py,sha256=KhSxEMs8tB0PXOHcBRbYqa63kgDBxAsvyFa9oAO2bu0,548390
4
4
  midiharmony/__init__.py,sha256=7gSewe5Li5yGW1RHy3H5fupLaL2NmXNgkpFpzSqMx2E,50
5
5
  midiharmony/helpers.py,sha256=xc6RWrNz_T2HXWJlzRDDgvKb-zexNJKpmRrAIZ9Obtc,8886
6
6
  midiharmony/midi_to_colab_audio.py,sha256=dP-YMJVrCN_orOs3iYAmlRMwlHOzme3irahnLubJohw,145302
7
- midiharmony/midiharmony.py,sha256=FDqsIvAVdG4iLW-GtXe45aPzyRC3_W6BLx_m-aCxBz8,16657
7
+ midiharmony/midiharmony.py,sha256=uYthvc-DFq43Mo3HJsoD0YxLRDse5ACaMYjG5tkHhWo,20872
8
8
  midiharmony/artwork/Project-Los-Angeles.png,sha256=6SBoK-YgXOo7mluLjS_MH0KZljkhd5-9N0s3sMbax4E,989875
9
9
  midiharmony/artwork/README.md,sha256=_7QXLfyPNFWzs96MnoPecTJNWigEfSr3uWRnG6uZjk4,159
10
10
  midiharmony/artwork/Tegridy-Code-2026.png,sha256=gzDtGxeTNFvQPKzP6isxXtYIdMN7RbkTlcE6xywc_S8,594966
@@ -13,8 +13,8 @@ midiharmony/artwork/midiharmony.png,sha256=7TwKQScUh8D8-ZKEnlOO8gFSSnmXICYC3XvHN
13
13
  midiharmony/data/README.md,sha256=vpxZ5ZERJeO9HkmEI91DqtvTKnFhxfwnrVI18prYEtg,694
14
14
  midiharmony/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
15
  midiharmony/data/all_harmonic_chords_quads.npz,sha256=-oxuq8KbyAS1CfEo-Ud1Dr6WQgAJfEMMPthaPlGRODk,37146464
16
- midiharmony-26.1.27.dist-info/licenses/LICENSE,sha256=Uar9eD8GksWLFWX8YWqJDo8uIstPH1at58jnS_FEDZw,11364
17
- midiharmony-26.1.27.dist-info/METADATA,sha256=JMWeYHqfikTr5xVX-cVRrDwD43gII9P-Py-jjwamSsA,3024
18
- midiharmony-26.1.27.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
19
- midiharmony-26.1.27.dist-info/top_level.txt,sha256=5SwvhlIS9lrTsXPh_XuuIkfxNmPMbPqOk0CVQz9eMog,12
20
- midiharmony-26.1.27.dist-info/RECORD,,
16
+ midiharmony-26.1.30.dist-info/licenses/LICENSE,sha256=Uar9eD8GksWLFWX8YWqJDo8uIstPH1at58jnS_FEDZw,11364
17
+ midiharmony-26.1.30.dist-info/METADATA,sha256=f_g76NHjkO5HIxkH5_kUx1sjiUuhXjxz5az5r-hvh3U,7062
18
+ midiharmony-26.1.30.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
19
+ midiharmony-26.1.30.dist-info/top_level.txt,sha256=5SwvhlIS9lrTsXPh_XuuIkfxNmPMbPqOk0CVQz9eMog,12
20
+ midiharmony-26.1.30.dist-info/RECORD,,
@@ -1,72 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: midiharmony
3
- Version: 26.1.27
4
- Summary: Fast, data‑driven harmony analysis for any MIDI file
5
- Author-email: Alex Lev <alexlev61@proton.me>
6
- Maintainer-email: Alex Lev <alexlev61@proton.me>
7
- License-Expression: Apache-2.0
8
- Project-URL: Homepage, https://github.com/asigalov61/midiharmony
9
- Project-URL: SoundCloud, https://soundcloud.com/aleksandr-sigalov-61/
10
- Project-URL: Documentation, https://github.com/asigalov61/midiharmony
11
- Project-URL: Issues, https://github.com/asigalov61/midiharmony/issues
12
- Project-URL: Discussions, https://github.com/asigalov61/midiharmony/discussions
13
- Project-URL: Dataset, https://huggingface.co/datasets/projectlosangeles/Discover-MIDI-Dataset
14
- Keywords: MIDI,MIDI harmony,harmony,symbolic music,music,music harmony,harmony analysis,harmonic analysis,music information retrieval,MIR,music discovery,music search,music quality,music metadata,music recommendation,research,musicology,music analysis
15
- Classifier: Development Status :: 5 - Production/Stable
16
- Classifier: Intended Audience :: Developers
17
- Classifier: Intended Audience :: Science/Research
18
- Classifier: Intended Audience :: Education
19
- Classifier: Operating System :: OS Independent
20
- Classifier: Programming Language :: Python :: 3
21
- Classifier: Programming Language :: Python :: 3 :: Only
22
- Classifier: Programming Language :: Python :: 3.8
23
- Classifier: Programming Language :: Python :: 3.9
24
- Classifier: Programming Language :: Python :: 3.10
25
- Classifier: Programming Language :: Python :: 3.11
26
- Classifier: Programming Language :: Python :: 3.12
27
- Classifier: Topic :: Multimedia :: Sound/Audio
28
- Classifier: Topic :: Multimedia :: Sound/Audio :: MIDI
29
- Classifier: Topic :: Scientific/Engineering :: Information Analysis
30
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
31
- Classifier: Environment :: Console
32
- Classifier: Natural Language :: English
33
- Classifier: Typing :: Typed
34
- Requires-Python: >=3.8
35
- Description-Content-Type: text/markdown
36
- License-File: LICENSE
37
- Requires-Dist: tqdm
38
- Requires-Dist: matplotlib
39
- Requires-Dist: midirenderer
40
- Requires-Dist: cupy-cuda12x
41
- Requires-Dist: numpy==1.26.4
42
- Dynamic: license-file
43
-
44
- # midiharmony
45
- ## Fast, data‑driven harmony analysis for any MIDI file
46
-
47
- <img width="1024" height="1024" alt="midiharmony" src="https://github.com/user-attachments/assets/586cf022-ce06-4cea-bfdc-ffcf9b0365d1" />
48
-
49
- ***
50
-
51
- ## Abstract
52
-
53
- *midiharmony provides fast, stand‑alone harmony analysis for MIDI files by comparing their chord and note relationships against a high‑quality database of extracted chord quads. This approach enables reliable detection of strong harmonic structure, musically coherent progressions, and potential inconsistencies, making it a practical tool for music‑AI pipelines, composition analysis, and large‑scale MIDI processing.*
54
-
55
- ***
56
-
57
- ## Install
58
-
59
- ```sh
60
- !pip install -U midiharmony
61
- ```
62
-
63
- ***
64
-
65
- ## Basic use example
66
-
67
- ```python
68
- import midiharmony
69
- ```
70
-
71
- ### Project Los Angeles
72
- ### Tegridy Code 2026