soundkit 1.0.0__tar.gz

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.
soundkit-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Quabynah Davis
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,538 @@
1
+ Metadata-Version: 2.4
2
+ Name: soundkit
3
+ Version: 1.0.0
4
+ Summary: A comprehensive Python framework for musical note processing, MIDI manipulation and music theory operations
5
+ Author-email: Quabynah Davis <exceldavisville@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/davisdeveloper/soundkit
8
+ Project-URL: Bug Tracker, https://github.com/davisdeveloper/soundkit/issues
9
+ Project-URL: Documentation, https://github.com/davisdeveloper/soundkit#readme
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Education
13
+ Classifier: Intended Audience :: Other Audience
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.7
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Topic :: Multimedia :: Sound/Audio
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Classifier: Topic :: Education
25
+ Requires-Python: >=3.7
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Dynamic: license-file
29
+
30
+ # SoundKit
31
+
32
+ **A Comprehensive Python Framework for Musical Note Processing, MIDI Manipulation and Music Theory Operations**
33
+
34
+ SoundKit is a powerful Python framework designed for musicians, developers, and audio engineers working with musical notes, MIDI data, and music theory. It provides intuitive APIs for note conversion, chord generation, scale creation, and comprehensive music theory operations.
35
+
36
+ ## Features
37
+
38
+ - 🎵 **Note Conversion**: Convert between note names, MIDI numbers, and frequencies
39
+ - 🎹 **Chord Generation**: Create chords with various types and inversions
40
+ - 🎼 **Scale Generation**: Generate musical scales with multiple octaves
41
+ - 🔍 **Validation**: Comprehensive input validation and error handling
42
+ - 📊 **Utilities**: Advanced conversion tools and music theory utilities
43
+ - 🎯 **Music Theory**: Built-in music theory operations and constants
44
+
45
+ ## Installation
46
+
47
+ ```bash
48
+ pip install soundkit
49
+ ```
50
+
51
+ ## Quick Start
52
+
53
+ ```python
54
+ import soundkit as sk
55
+
56
+ # Basic note conversion
57
+ print(sk.notes.midiKey("C4")) # 60
58
+ print(sk.notes.midiFreq("A4")) # 440.0
59
+
60
+ # Create chords
61
+ c_major = sk.chords.get_chord_notes("C", "maj", 4)
62
+ print(c_major) # [60, 64, 67]
63
+
64
+ # Generate scales
65
+ c_major_scale = sk.scales.get_scale_notes("C", "major", 4, 2)
66
+ print(c_major_scale) # [60, 62, 64, 65, 67, 69, 71, 72, 74, 76, 77, 79, 81, 83]
67
+ ```
68
+
69
+ ## Core Modules
70
+
71
+ ### Notes Module
72
+
73
+ The `notes` module handles all note-related conversions and operations.
74
+
75
+ #### Basic Note Conversion
76
+
77
+ ```python
78
+ import soundkit as sk
79
+
80
+ # Convert note name to MIDI number
81
+ midi_number = sk.notes.midiKey("C4") # 60
82
+ midi_number = sk.notes.midiKey("A4") # 69
83
+ midi_number = sk.notes.midiKey("Gb3") # 54
84
+
85
+ # Convert note name to frequency
86
+ frequency = sk.notes.midiFreq("A4") # 440.0
87
+ frequency = sk.notes.midiFreq("C4") # 261.63
88
+ frequency = sk.notes.midiFreq("C4", round_digits=4) # 261.6256
89
+
90
+ # Convert frequency to MIDI number
91
+ midi_number = sk.notes.freqToMidi(440.0) # 69
92
+ midi_number = sk.notes.freqToMidi(261.63) # 60
93
+
94
+ # Convert MIDI number to note name
95
+ note_name = sk.notes.midiToNoteName(60) # "C4"
96
+ note_name = sk.notes.midiToNoteName(69) # "A4"
97
+ note_name = sk.notes.midiToNoteName(60, use_sharps=False) # "C4" (no effect for C)
98
+ ```
99
+
100
+ #### Supported Note Formats
101
+
102
+ SoundKit supports various note naming conventions:
103
+
104
+ ```python
105
+ # Sharp notes
106
+ sk.notes.midiKey("C#4") # 61
107
+ sk.notes.midiKey("D#4") # 63
108
+ sk.notes.midiKey("F#4") # 66
109
+
110
+ # Flat notes
111
+ sk.notes.midiKey("Db4") # 61
112
+ sk.notes.midiKey("Eb4") # 63
113
+ sk.notes.midiKey("Gb4") # 66
114
+
115
+ # Mixed notation
116
+ sk.notes.midiKey("C4") # 60
117
+ sk.notes.midiKey("C#4") # 61
118
+ sk.notes.midiKey("Db4") # 61 (same as C#4)
119
+ ```
120
+
121
+ #### Batch Processing
122
+
123
+ ```python
124
+ import soundkit as sk
125
+
126
+ # Process multiple notes at once
127
+ notes = ["C4", "E4", "G4", "A4", "B4"]
128
+
129
+ # Convert to MIDI numbers
130
+ midi_numbers = sk.notes.notes_to_midi(notes)
131
+ print(midi_numbers) # [60, 64, 67, 69, 71]
132
+
133
+ # Convert to frequencies
134
+ frequencies = sk.notes.notes_to_frequencies(notes)
135
+ print(frequencies) # [261.63, 329.63, 392.0, 440.0, 493.88]
136
+
137
+ # With custom concert pitch
138
+ frequencies = sk.notes.notes_to_frequencies(notes, concert_pitch=442.0)
139
+ ```
140
+
141
+ #### Validation
142
+
143
+ ```python
144
+ import soundkit as sk
145
+
146
+ # Check if note is valid
147
+ is_valid = sk.notes.is_valid_midi_range("C4") # True
148
+ is_valid = sk.notes.is_valid_midi_range("C11") # False
149
+
150
+ # Handle invalid notes gracefully
151
+ try:
152
+ sk.notes.midiKey("H4") # Invalid note
153
+ except sk.InvalidNoteError as e:
154
+ print(f"Error: {e}")
155
+
156
+ try:
157
+ sk.notes.midiKey("C11") # Invalid octave
158
+ except sk.InvalidOctaveError as e:
159
+ print(f"Error: {e}")
160
+ ```
161
+
162
+ ### Chords Module
163
+
164
+ The `chords` module provides chord generation and manipulation.
165
+
166
+ #### Basic Chord Generation
167
+
168
+ ```python
169
+ import soundkit as sk
170
+
171
+ # Generate chord notes
172
+ c_major = sk.chords.get_chord_notes("C", "maj", 4)
173
+ print(c_major) # [60, 64, 67]
174
+
175
+ d_minor = sk.chords.get_chord_notes("D", "min", 4)
176
+ print(d_minor) # [62, 65, 69]
177
+
178
+ g_seventh = sk.chords.get_chord_notes("G", "7", 4)
179
+ print(g_seventh) # [67, 71, 74, 77]
180
+ ```
181
+
182
+ #### Available Chord Types
183
+
184
+ ```python
185
+ import soundkit as sk
186
+
187
+ # Get all available chord types
188
+ chord_types = sk.chords.get_chord_names()
189
+ print(chord_types)
190
+ # ['maj', 'major', 'min', 'minor', 'dim', 'diminished', 'aug', 'augmented',
191
+ # '7', 'dominant7', 'maj7', 'major7', 'min7', 'minor7', 'dim7', 'diminished7',
192
+ # 'half_dim7', 'm7b5', 'sus2', 'sus4', '9', 'maj9']
193
+ ```
194
+
195
+ #### Chord Inversions
196
+
197
+ ```python
198
+ import soundkit as sk
199
+
200
+ # Root position
201
+ c_major_root = sk.chords.get_chord_notes("C", "maj", 4, inversion=0)
202
+ print(c_major_root) # [60, 64, 67]
203
+
204
+ # First inversion
205
+ c_major_first = sk.chords.get_chord_notes("C", "maj", 4, inversion=1)
206
+ print(c_major_first) # [64, 67, 72]
207
+
208
+ # Second inversion
209
+ c_major_second = sk.chords.get_chord_notes("C", "maj", 4, inversion=2)
210
+ print(c_major_second) # [67, 72, 76]
211
+ ```
212
+
213
+ #### Chord Frequencies
214
+
215
+ ```python
216
+ import soundkit as sk
217
+
218
+ # Get chord frequencies
219
+ c_major_freq = sk.chords.get_chord_frequencies("C", "maj", 4)
220
+ print(c_major_freq) # [261.63, 329.63, 392.0]
221
+
222
+ # With custom rounding
223
+ c_major_freq = sk.chords.get_chord_frequencies("C", "maj", 4, round_digits=4)
224
+ print(c_major_freq) # [261.6256, 329.6276, 392.0]
225
+
226
+ # With inversion
227
+ c_major_first_freq = sk.chords.get_chord_frequencies("C", "maj", 4, inversion=1)
228
+ ```
229
+
230
+ ### Scales Module
231
+
232
+ The `scales` module provides scale generation and music theory operations.
233
+
234
+ #### Basic Scale Generation
235
+
236
+ ```python
237
+ import soundkit as sk
238
+
239
+ # Generate scale notes
240
+ c_major = sk.scales.get_scale_notes("C", "major", 4)
241
+ print(c_major) # [60, 62, 64, 65, 67, 69, 71]
242
+
243
+ a_minor = sk.scales.get_scale_notes("A", "minor", 4)
244
+ print(a_minor) # [69, 71, 72, 74, 76, 77, 79]
245
+
246
+ # Multiple octaves
247
+ c_major_2octaves = sk.scales.get_scale_notes("C", "major", 4, 2)
248
+ print(c_major_2octaves) # [60, 62, 64, 65, 67, 69, 71, 72, 74, 76, 77, 79, 81, 83]
249
+ ```
250
+
251
+ #### Available Scale Types
252
+
253
+ ```python
254
+ import soundkit as sk
255
+
256
+ # Get all available scale types
257
+ scale_types = sk.scales.get_scale_names()
258
+ print(scale_types)
259
+ # ['major', 'minor', 'natural_minor', 'harmonic_minor', 'melodic_minor',
260
+ # 'pentatonic_major', 'pentatonic_minor', 'blues', 'dorian', 'phrygian',
261
+ # 'lydian', 'mixolydian', 'locrian', 'whole_tone']
262
+ ```
263
+
264
+ #### Scale Frequencies
265
+
266
+ ```python
267
+ import soundkit as sk
268
+
269
+ # Get scale frequencies
270
+ c_major_freq = sk.scales.get_scale_frequencies("C", "major", 4)
271
+ print(c_major_freq) # [261.63, 293.66, 329.63, 349.23, 392.0, 440.0, 493.88]
272
+
273
+ # Multiple octaves with custom rounding
274
+ c_major_2oct_freq = sk.scales.get_scale_frequencies("C", "major", 4, 2, round_digits=1)
275
+ ```
276
+
277
+ #### Modes and Special Scales
278
+
279
+ ```python
280
+ import soundkit as sk
281
+
282
+ # Modes
283
+ d_dorian = sk.scales.get_scale_notes("D", "dorian", 4)
284
+ print(d_dorian) # [62, 64, 65, 67, 69, 71, 72]
285
+
286
+ # Pentatonic scales
287
+ c_pentatonic_major = sk.scales.get_scale_notes("C", "pentatonic_major", 4)
288
+ print(c_pentatonic_major) # [60, 62, 64, 67, 69]
289
+
290
+ a_pentatonic_minor = sk.scales.get_scale_notes("A", "pentatonic_minor", 4)
291
+ print(a_pentatonic_minor) # [69, 72, 74, 76, 79]
292
+
293
+ # Blues scale
294
+ c_blues = sk.scales.get_scale_notes("C", "blues", 4)
295
+ print(c_blues) # [60, 63, 65, 66, 67, 70]
296
+ ```
297
+
298
+ ### Utils Module
299
+
300
+ The `utils` module provides validation and conversion utilities.
301
+
302
+ #### Validators
303
+
304
+ ```python
305
+ import soundkit as sk
306
+
307
+ # Note validation
308
+ is_valid = sk.validators.validate_note_name("C4") # True
309
+ is_valid = sk.validators.validate_note_name("H4") # False
310
+ is_valid = sk.validators.validate_note_name("C#4") # True
311
+ is_valid = sk.validators.validate_note_name("Db4") # True
312
+
313
+ # MIDI range validation
314
+ is_valid = sk.validators.validate_midi_range(60) # True
315
+ is_valid = sk.validators.validate_midi_range(128) # False
316
+
317
+ # Frequency validation
318
+ is_valid = sk.validators.validate_frequency(440.0) # True
319
+ is_valid = sk.validators.validate_frequency(-10.0) # False
320
+
321
+ # Octave validation
322
+ is_valid = sk.validators.validate_octave(4) # True
323
+ is_valid = sk.validators.validate_octave(11) # False
324
+
325
+ # Note normalization
326
+ normalized = sk.validators.normalize_note_name("c#4") # "C#4"
327
+ normalized = sk.validators.normalize_note_name("db4") # "DB4"
328
+ normalized = sk.validators.normalize_note_name("C ♯4") # "C#4"
329
+ ```
330
+
331
+ #### Converters
332
+
333
+ ```python
334
+ import soundkit as sk
335
+
336
+ # Frequency to cents
337
+ cents = sk.converters.frequency_to_cents(440, 444) # ~15.67
338
+ cents = sk.converters.frequency_to_cents(440, 880) # 1200.0
339
+
340
+ # Cents to ratio
341
+ ratio = sk.converters.cents_to_ratio(100) # ~1.05946
342
+ ratio = sk.converters.cents_to_ratio(1200) # 2.0
343
+
344
+ # Ratio conversions
345
+ ratio = sk.converters.semitones_to_ratio(12) # 2.0
346
+ semitones = sk.converters.ratio_to_semitones(2.0) # 12.0
347
+
348
+ # Frequency normalization
349
+ normalized = sk.converters.normalize_frequency(441.0) # ~440.0
350
+ normalized = sk.converters.normalize_frequency(445.0, reference=442.0)
351
+ ```
352
+
353
+ ### Constants
354
+
355
+ SoundKit provides useful musical constants:
356
+
357
+ ```python
358
+ import soundkit as sk
359
+
360
+ # Standard concert pitch
361
+ print(sk.CONCERT_PITCH) # 440.0
362
+
363
+ # MIDI range
364
+ print(sk.MIDI_RANGE) # (0, 127)
365
+
366
+ # Reference frequencies
367
+ print(sk.REFERENCE_FREQUENCIES["A4"]) # 440.0
368
+ print(sk.REFERENCE_FREQUENCIES["C4"]) # 261.63
369
+
370
+ # Use constants in your calculations
371
+ custom_freq = sk.notes.midiFreq("A4", concert_pitch=442.0)
372
+ ```
373
+
374
+ ## Error Handling
375
+
376
+ SoundKit provides comprehensive error handling with custom exceptions:
377
+
378
+ ```python
379
+ import soundkit as sk
380
+
381
+ try:
382
+ # Invalid note name
383
+ sk.notes.midiKey("H4")
384
+ except sk.InvalidNoteError as e:
385
+ print(f"Invalid note: {e}")
386
+
387
+ try:
388
+ # Invalid octave
389
+ sk.notes.midiKey("C11")
390
+ except sk.InvalidOctaveError as e:
391
+ print(f"Invalid octave: {e}")
392
+
393
+ try:
394
+ # Invalid frequency
395
+ sk.notes.freqToMidi(-100)
396
+ except sk.InvalidFrequencyError as e:
397
+ print(f"Invalid frequency: {e}")
398
+
399
+ try:
400
+ # Invalid chord type
401
+ sk.chords.get_chord_notes("C", "invalid_type", 4)
402
+ except sk.InvalidChordError as e:
403
+ print(f"Invalid chord: {e}")
404
+
405
+ try:
406
+ # Invalid scale type
407
+ sk.scales.get_scale_notes("C", "invalid_scale", 4)
408
+ except sk.InvalidScaleError as e:
409
+ print(f"Invalid scale: {e}")
410
+ ```
411
+
412
+ ## Advanced Examples
413
+
414
+ ### Music Theory Application
415
+
416
+ ```python
417
+ import soundkit as sk
418
+
419
+ def analyze_progression(progression):
420
+ """Analyze a chord progression"""
421
+ for chord in progression:
422
+ root, quality = chord
423
+ notes = sk.chords.get_chord_notes(root, quality, 4)
424
+ frequencies = sk.chords.get_chord_frequencies(root, quality, 4)
425
+ print(f"{root}{quality}: {notes} -> {frequencies}Hz")
426
+
427
+ # Analyze a II-V-I progression
428
+ progression = [("D", "min7"), ("G", "7"), ("C", "maj7")]
429
+ analyze_progression(progression)
430
+ ```
431
+
432
+ ### Scale Visualization
433
+
434
+ ```python
435
+ import soundkit as sk
436
+
437
+ def print_scale_intervals(root_note, scale_type, octave=4):
438
+ """Print scale with note names and frequencies"""
439
+ midi_notes = sk.scales.get_scale_notes(root_note, scale_type, octave)
440
+
441
+ print(f"{root_note} {scale_type} scale:")
442
+ for midi in midi_notes:
443
+ note_name = sk.notes.midiToNoteName(midi)
444
+ frequency = sk.notes.midiFreq(note_name)
445
+ print(f" {note_name}: {frequency}Hz")
446
+
447
+ print_scale_intervals("C", "major")
448
+ print_scale_intervals("A", "harmonic_minor")
449
+ ```
450
+
451
+ ### Tuning Analysis
452
+
453
+ ```python
454
+ import soundkit as sk
455
+
456
+ def compare_tunings(note_name, reference_pitches):
457
+ """Compare frequencies across different tuning standards"""
458
+ print(f"Note: {note_name}")
459
+ for name, pitch in reference_pitches.items():
460
+ freq = sk.notes.midiFreq(note_name, concert_pitch=pitch)
461
+ print(f" {name} (A4={pitch}Hz): {freq}Hz")
462
+
463
+ tunings = {
464
+ "Modern Standard": 440.0,
465
+ "Baroque": 415.0,
466
+ "Classical": 430.0,
467
+ "Modern High": 442.0
468
+ }
469
+
470
+ compare_tunings("A4", tunings)
471
+ ```
472
+
473
+ ## API Reference
474
+
475
+ ### Notes Module
476
+
477
+ - `midiKey(note_name: str) -> int`: Convert note name to MIDI number
478
+ - `midiFreq(note_name: str, round_digits: int = 2, concert_pitch: float = 440.0) -> float`: Convert note name to frequency
479
+ - `freqToMidi(frequency: float, concert_pitch: float = 440.0) -> int`: Convert frequency to MIDI number
480
+ - `midiToNoteName(midi_number: int, use_sharps: bool = True) -> str`: Convert MIDI number to note name
481
+ - `is_valid_midi_range(note_name: str) -> bool`: Check if note is within MIDI range
482
+ - `notes_to_midi(note_list: List[str]) -> List[Union[int, str]]`: Convert list of notes to MIDI numbers
483
+ - `notes_to_frequencies(note_list: List[str], round_digits: int = 2, concert_pitch: float = 440.0) -> List[Union[float, str]]`: Convert list of notes to frequencies
484
+
485
+ ### Chords Module
486
+
487
+ - `get_chord_notes(chord_root: str, chord_type: str = 'maj', octave: int = 4, inversion: int = 0) -> List[int]`: Get MIDI notes for a chord
488
+ - `get_chord_frequencies(chord_root: str, chord_type: str = 'maj', octave: int = 4, round_digits: int = 2, inversion: int = 0) -> List[float]`: Get frequencies for a chord
489
+ - `get_chord_names() -> List[str]`: Get available chord types
490
+
491
+ ### Scales Module
492
+
493
+ - `get_scale_notes(scale_root: str, scale_type: str = 'major', octave: int = 4, num_octaves: int = 1) -> List[int]`: Get MIDI notes for a scale
494
+ - `get_scale_frequencies(scale_root: str, scale_type: str = 'major', octave: int = 4, num_octaves: int = 1, round_digits: int = 2) -> List[float]`: Get frequencies for a scale
495
+ - `get_scale_names() -> List[str]`: Get available scale types
496
+
497
+ ### Utils Module
498
+
499
+ #### Validators
500
+
501
+ - `validate_note_name(note_name: str) -> bool`: Validate note name format
502
+ - `validate_midi_range(midi_number: int) -> bool`: Validate MIDI number range
503
+ - `validate_frequency(frequency: float) -> bool`: Validate frequency value
504
+ - `validate_octave(octave: int) -> bool`: Validate octave range
505
+ - `normalize_note_name(note_name: str) -> str`: Normalize note name format
506
+
507
+ #### Converters
508
+
509
+ - `frequency_to_cents(freq1: float, freq2: float) -> float`: Convert frequency ratio to cents
510
+ - `cents_to_ratio(cents: float) -> float`: Convert cents to frequency ratio
511
+ - `ratio_to_cents(ratio: float) -> float`: Convert frequency ratio to cents
512
+ - `semitones_to_ratio(semitones: float) -> float`: Convert semitones to frequency ratio
513
+ - `ratio_to_semitones(ratio: float) -> float`: Convert frequency ratio to semitones
514
+ - `normalize_frequency(frequency: float, reference: float = 440.0) -> float`: Normalize frequency to nearest reference
515
+
516
+ ## Contributing
517
+
518
+ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
519
+
520
+ ## License
521
+
522
+ SoundKit is released under the MIT License. See [LICENSE](LICENSE) for details.
523
+
524
+ ## Support
525
+
526
+ For bug reports, feature requests, or questions:
527
+
528
+ - Create an issue on [GitHub](https://github.com/yourusername/soundkit/issues)
529
+
530
+ - Email: <exceldavisville@gmail.com>
531
+
532
+ ## Version History
533
+
534
+ - **1.0.0**: Initial release with core note, chord, and scale functionality
535
+
536
+ ---
537
+
538
+ SoundKit is developed and maintained by Quabynah Davis.