0
# Music Theory Core
1
2
Essential music theory functions for working with notes, intervals, chords, scales, keys, progressions, and rhythmic values. These modules provide the theoretical foundation for all musical operations in mingus.
3
4
## Capabilities
5
6
### Note Operations
7
8
Basic note operations for converting between different note representations, validating note names, and performing note transformations.
9
10
```python { .api }
11
def int_to_note(note_int: int, accidentals: str = "#") -> str:
12
"""
13
Convert integers (0-11) to note names.
14
15
Parameters:
16
- note_int: Integer from 0-11 representing chromatic pitch class
17
- accidentals: Use "#" for sharps or "b" for flats
18
19
Returns:
20
Note name as string (e.g., "C", "F#", "Bb")
21
"""
22
23
def note_to_int(note: str) -> int:
24
"""
25
Convert note names to integers (0-11).
26
27
Parameters:
28
- note: Note name (e.g., "C", "F#", "Bb")
29
30
Returns:
31
Integer from 0-11 representing chromatic pitch class
32
"""
33
34
def is_valid_note(note: str) -> bool:
35
"""
36
Return True if note is in recognized format.
37
38
Parameters:
39
- note: Note name to validate
40
41
Returns:
42
True if note is valid, False otherwise
43
"""
44
45
def augment(note: str) -> str:
46
"""
47
Augment a note (add sharp or remove flat).
48
49
Parameters:
50
- note: Note name to augment
51
52
Returns:
53
Augmented note name
54
"""
55
56
def diminish(note: str) -> str:
57
"""
58
Diminish a note (add flat or remove sharp).
59
60
Parameters:
61
- note: Note name to diminish
62
63
Returns:
64
Diminished note name
65
"""
66
67
def is_enharmonic(note1: str, note2: str) -> bool:
68
"""
69
Test if two notes are enharmonically equivalent.
70
71
Parameters:
72
- note1, note2: Note names to compare
73
74
Returns:
75
True if notes are enharmonically equivalent
76
"""
77
78
def reduce_accidentals(note: str) -> str:
79
"""
80
Reduce extra accidentals to proper notes.
81
82
Parameters:
83
- note: Note with possible redundant accidentals
84
85
Returns:
86
Note with reduced accidentals
87
"""
88
89
def remove_redundant_accidentals(note: str) -> str:
90
"""
91
Remove redundant sharps/flats from note.
92
93
Parameters:
94
- note: Note name to clean
95
96
Returns:
97
Note name with redundant accidentals removed
98
"""
99
100
# Constants
101
fifths: List[str] = ["F", "C", "G", "D", "A", "E", "B"]
102
"""Circle of fifths progression."""
103
```
104
105
### Key Signatures and Keys
106
107
Functions for working with musical keys, key signatures, and key relationships.
108
109
```python { .api }
110
def is_valid_key(key: str) -> bool:
111
"""
112
Return True if key is recognized.
113
114
Parameters:
115
- key: Key name (e.g., "C", "Am", "F#", "Bbm")
116
117
Returns:
118
True if key is valid
119
"""
120
121
def get_key_signature(key: str = "C") -> int:
122
"""
123
Return key signature as integer (number of sharps/flats).
124
125
Parameters:
126
- key: Key name
127
128
Returns:
129
Integer representing key signature (positive for sharps, negative for flats)
130
"""
131
132
def get_notes(key: str = "C") -> List[str]:
133
"""
134
Return ordered list of notes in key.
135
136
Parameters:
137
- key: Key name
138
139
Returns:
140
List of note names in the key
141
"""
142
143
def relative_major(key: str) -> str:
144
"""
145
Return relative major of minor key.
146
147
Parameters:
148
- key: Minor key name
149
150
Returns:
151
Relative major key name
152
"""
153
154
def relative_minor(key: str) -> str:
155
"""
156
Return relative minor of major key.
157
158
Parameters:
159
- key: Major key name
160
161
Returns:
162
Relative minor key name
163
"""
164
165
class Key:
166
"""Key object with properties for key analysis."""
167
168
def __init__(self, key: str = "C"):
169
"""
170
Create Key object.
171
172
Parameters:
173
- key: Key name (e.g., "C", "Am", "F#")
174
"""
175
176
@property
177
def key(self) -> str:
178
"""Key name."""
179
180
@property
181
def mode(self) -> str:
182
"""Mode (major or minor)."""
183
184
@property
185
def signature(self) -> int:
186
"""Key signature as integer."""
187
```
188
189
### Interval Analysis
190
191
Functions for creating and analyzing musical intervals between notes.
192
193
```python { .api }
194
def measure(note1: str, note2: str) -> int:
195
"""
196
Return half steps between notes.
197
198
Parameters:
199
- note1, note2: Note names
200
201
Returns:
202
Number of half steps between notes
203
"""
204
205
def determine(note1: str, note2: str, shorthand: bool = False) -> str:
206
"""
207
Name interval between notes.
208
209
Parameters:
210
- note1, note2: Note names
211
- shorthand: Return shorthand notation if True
212
213
Returns:
214
Interval name (e.g., "major third", "perfect fifth")
215
"""
216
217
def from_shorthand(note: str, interval: str, up: bool = True) -> str:
218
"""
219
Return note at shorthand interval.
220
221
Parameters:
222
- note: Starting note
223
- interval: Interval shorthand (e.g., "3", "5", "b7", "M7")
224
- up: Direction (True for up, False for down)
225
226
Returns:
227
Resulting note name
228
"""
229
230
def invert(interval: str) -> str:
231
"""
232
Invert interval.
233
234
Parameters:
235
- interval: Interval name
236
237
Returns:
238
Inverted interval name
239
"""
240
241
# Chromatic interval functions
242
def minor_second(note: str) -> str:
243
"""Return minor second above note."""
244
245
def major_second(note: str) -> str:
246
"""Return major second above note."""
247
248
def minor_third(note: str) -> str:
249
"""Return minor third above note."""
250
251
def major_third(note: str) -> str:
252
"""Return major third above note."""
253
254
def perfect_fourth(note: str) -> str:
255
"""Return perfect fourth above note."""
256
257
def perfect_fifth(note: str) -> str:
258
"""Return perfect fifth above note."""
259
260
def minor_sixth(note: str) -> str:
261
"""Return minor sixth above note."""
262
263
def major_sixth(note: str) -> str:
264
"""Return major sixth above note."""
265
266
def minor_seventh(note: str) -> str:
267
"""Return minor seventh above note."""
268
269
def major_seventh(note: str) -> str:
270
"""Return major seventh above note."""
271
272
def is_consonant(note1: str, note2: str, include_fourths: bool = True) -> bool:
273
"""
274
Test consonance between two notes.
275
276
Parameters:
277
- note1, note2: Note names
278
- include_fourths: Include perfect fourths as consonant
279
280
Returns:
281
True if interval is consonant
282
"""
283
284
def is_dissonant(note1: str, note2: str, include_fourths: bool = False) -> bool:
285
"""
286
Test dissonance between two notes.
287
288
Parameters:
289
- note1, note2: Note names
290
- include_fourths: Include perfect fourths as dissonant
291
292
Returns:
293
True if interval is dissonant
294
"""
295
```
296
297
### Chord Construction and Analysis
298
299
Comprehensive chord construction including triads, seventh chords, extended chords, and chord analysis functions.
300
301
```python { .api }
302
# Triad construction
303
def major_triad(note: str) -> List[str]:
304
"""
305
Return major triad.
306
307
Parameters:
308
- note: Root note
309
310
Returns:
311
List of notes in major triad
312
"""
313
314
def minor_triad(note: str) -> List[str]:
315
"""Return minor triad."""
316
317
def diminished_triad(note: str) -> List[str]:
318
"""Return diminished triad."""
319
320
def augmented_triad(note: str) -> List[str]:
321
"""Return augmented triad."""
322
323
def suspended_fourth_triad(note: str) -> List[str]:
324
"""Return sus4 triad."""
325
326
def suspended_second_triad(note: str) -> List[str]:
327
"""Return sus2 triad."""
328
329
# Seventh chord construction
330
def major_seventh(note: str) -> List[str]:
331
"""Return major seventh chord."""
332
333
def minor_seventh(note: str) -> List[str]:
334
"""Return minor seventh chord."""
335
336
def dominant_seventh(note: str) -> List[str]:
337
"""Return dominant seventh chord."""
338
339
def half_diminished_seventh(note: str) -> List[str]:
340
"""Return half-diminished seventh chord."""
341
342
def diminished_seventh(note: str) -> List[str]:
343
"""Return diminished seventh chord."""
344
345
def minor_major_seventh(note: str) -> List[str]:
346
"""Return minor-major seventh chord."""
347
348
# Extended chords
349
def major_sixth(note: str) -> List[str]:
350
"""Return major sixth chord."""
351
352
def minor_sixth(note: str) -> List[str]:
353
"""Return minor sixth chord."""
354
355
def major_ninth(note: str) -> List[str]:
356
"""Return major ninth chord."""
357
358
def minor_ninth(note: str) -> List[str]:
359
"""Return minor ninth chord."""
360
361
def dominant_ninth(note: str) -> List[str]:
362
"""Return dominant ninth chord."""
363
364
def dominant_flat_ninth(note: str) -> List[str]:
365
"""Return dominant flat ninth chord."""
366
367
def dominant_sharp_ninth(note: str) -> List[str]:
368
"""Return dominant sharp ninth chord."""
369
370
def eleventh(note: str) -> List[str]:
371
"""Return eleventh chord."""
372
373
def minor_eleventh(note: str) -> List[str]:
374
"""Return minor eleventh chord."""
375
376
def major_thirteenth(note: str) -> List[str]:
377
"""Return major thirteenth chord."""
378
379
def minor_thirteenth(note: str) -> List[str]:
380
"""Return minor thirteenth chord."""
381
382
def dominant_thirteenth(note: str) -> List[str]:
383
"""Return dominant thirteenth chord."""
384
385
def hendrix_chord(note: str) -> List[str]:
386
"""Return Hendrix chord (7#9)."""
387
388
def sixth_ninth(note: str) -> List[str]:
389
"""Return sixth/ninth chord."""
390
391
# Augmented chords
392
def augmented_major_seventh(note: str) -> List[str]:
393
"""Return augmented major seventh chord."""
394
395
def augmented_minor_seventh(note: str) -> List[str]:
396
"""Return augmented minor seventh chord."""
397
398
# Suspended chords
399
def suspended_triad(note: str) -> List[str]:
400
"""Return suspended triad (alias for sus4)."""
401
402
def suspended_second_triad(note: str) -> List[str]:
403
"""Return suspended second triad."""
404
405
def suspended_seventh(note: str) -> List[str]:
406
"""Return suspended seventh chord."""
407
408
def suspended_fourth_ninth(note: str) -> List[str]:
409
"""Return suspended fourth flat ninth chord."""
410
411
# Altered chords
412
def dominant_flat_five(note: str) -> List[str]:
413
"""Return dominant flat five chord."""
414
415
def lydian_dominant_seventh(note: str) -> List[str]:
416
"""Return lydian dominant seventh chord."""
417
418
# Chord analysis and manipulation
419
def determine(chord: List[str], shorthand: bool = False, no_inversions: bool = False, no_polychords: bool = False) -> str:
420
"""
421
Analyze chord and return name.
422
423
Parameters:
424
- chord: List of note names
425
- shorthand: Return shorthand notation
426
- no_inversions: Don't consider inversions
427
- no_polychords: Don't consider polychords
428
429
Returns:
430
Chord name or description
431
"""
432
433
def from_shorthand(shorthand_string: str, slash: str = None) -> List[str]:
434
"""
435
Create chord from shorthand notation.
436
437
Parameters:
438
- shorthand_string: Chord shorthand (e.g., "CM7", "Am", "F#dim7")
439
- slash: Slash chord bass note
440
441
Returns:
442
List of notes in chord
443
"""
444
445
def invert(chord: List[str]) -> List[str]:
446
"""
447
Invert chord.
448
449
Parameters:
450
- chord: List of note names
451
452
Returns:
453
Inverted chord
454
"""
455
456
def first_inversion(chord: List[str]) -> List[str]:
457
"""Return first inversion of chord."""
458
459
def second_inversion(chord: List[str]) -> List[str]:
460
"""Return second inversion of chord."""
461
462
def third_inversion(chord: List[str]) -> List[str]:
463
"""Return third inversion of chord."""
464
465
# Functional harmony (named functions)
466
def tonic(key: str) -> List[str]:
467
"""Return tonic chord in key."""
468
469
def tonic7(key: str) -> List[str]:
470
"""Return tonic seventh chord in key."""
471
472
def supertonic(key: str) -> List[str]:
473
"""Return supertonic chord in key."""
474
475
def supertonic7(key: str) -> List[str]:
476
"""Return supertonic seventh chord in key."""
477
478
def mediant(key: str) -> List[str]:
479
"""Return mediant chord in key."""
480
481
def mediant7(key: str) -> List[str]:
482
"""Return mediant seventh chord in key."""
483
484
def subdominant(key: str) -> List[str]:
485
"""Return subdominant chord in key."""
486
487
def subdominant7(key: str) -> List[str]:
488
"""Return subdominant seventh chord in key."""
489
490
def dominant(key: str) -> List[str]:
491
"""Return dominant chord in key."""
492
493
def dominant7(key: str) -> List[str]:
494
"""Return dominant seventh chord in key."""
495
496
def submediant(key: str) -> List[str]:
497
"""Return submediant chord in key."""
498
499
def submediant7(key: str) -> List[str]:
500
"""Return submediant seventh chord in key."""
501
502
def subtonic(key: str) -> List[str]:
503
"""Return subtonic chord in key."""
504
505
def subtonic7(key: str) -> List[str]:
506
"""Return subtonic seventh chord in key."""
507
508
# Roman numeral analysis (aliases)
509
def I(key: str) -> List[str]:
510
"""Return tonic chord in key."""
511
512
def I7(key: str) -> List[str]:
513
"""Return tonic seventh chord in key."""
514
515
def ii(key: str) -> List[str]:
516
"""Return supertonic chord in key."""
517
518
def II(key: str) -> List[str]:
519
"""Return supertonic chord in key."""
520
521
def ii7(key: str) -> List[str]:
522
"""Return supertonic seventh chord in key."""
523
524
def II7(key: str) -> List[str]:
525
"""Return supertonic seventh chord in key."""
526
527
def iii(key: str) -> List[str]:
528
"""Return mediant chord in key."""
529
530
def III(key: str) -> List[str]:
531
"""Return mediant chord in key."""
532
533
def iii7(key: str) -> List[str]:
534
"""Return mediant seventh chord in key."""
535
536
def III7(key: str) -> List[str]:
537
"""Return mediant seventh chord in key."""
538
539
def IV(key: str) -> List[str]:
540
"""Return subdominant chord in key."""
541
542
def IV7(key: str) -> List[str]:
543
"""Return subdominant seventh chord in key."""
544
545
def V(key: str) -> List[str]:
546
"""Return dominant chord in key."""
547
548
def V7(key: str) -> List[str]:
549
"""Return dominant seventh chord in key."""
550
551
def vi(key: str) -> List[str]:
552
"""Return submediant chord in key."""
553
554
def VI(key: str) -> List[str]:
555
"""Return submediant chord in key."""
556
557
def vi7(key: str) -> List[str]:
558
"""Return submediant seventh chord in key."""
559
560
def VI7(key: str) -> List[str]:
561
"""Return submediant seventh chord in key."""
562
563
def vii(key: str) -> List[str]:
564
"""Return subtonic chord in key."""
565
566
def VII(key: str) -> List[str]:
567
"""Return subtonic chord in key."""
568
569
def vii7(key: str) -> List[str]:
570
"""Return subtonic seventh chord in key."""
571
572
def VII7(key: str) -> List[str]:
573
"""Return subtonic seventh chord in key."""
574
```
575
576
### Scale Construction
577
578
Scale classes for constructing and analyzing various musical scales and modes.
579
580
```python { .api }
581
class Diatonic:
582
"""Generic diatonic scale."""
583
584
def __init__(self, note: str, semitones: List[int], octaves: int = 1):
585
"""
586
Create diatonic scale.
587
588
Parameters:
589
- note: Root note
590
- semitones: List of semitone intervals
591
- octaves: Number of octaves
592
"""
593
594
def ascending(self) -> List[str]:
595
"""Return ascending notes."""
596
597
def descending(self) -> List[str]:
598
"""Return descending notes."""
599
600
def degree(self, degree_number: int, direction: str = "a") -> str:
601
"""
602
Return scale degree.
603
604
Parameters:
605
- degree_number: Scale degree (1-8)
606
- direction: "a" for ascending, "d" for descending
607
608
Returns:
609
Note at scale degree
610
"""
611
612
@property
613
def name(self) -> str:
614
"""Scale name."""
615
616
@property
617
def tonic(self) -> str:
618
"""Tonic note."""
619
620
class Major(Diatonic):
621
"""Major scale (Ionian mode)."""
622
623
def __init__(self, note: str, octaves: int = 1):
624
"""Create major scale."""
625
626
class NaturalMinor(Diatonic):
627
"""Natural minor scale (Aeolian mode)."""
628
629
def __init__(self, note: str, octaves: int = 1):
630
"""Create natural minor scale."""
631
632
class HarmonicMinor(Diatonic):
633
"""Harmonic minor scale."""
634
635
def __init__(self, note: str, octaves: int = 1):
636
"""Create harmonic minor scale."""
637
638
class MelodicMinor(Diatonic):
639
"""Melodic minor scale."""
640
641
def __init__(self, note: str, octaves: int = 1):
642
"""Create melodic minor scale."""
643
644
class HarmonicMajor(Diatonic):
645
"""Harmonic major scale."""
646
647
def __init__(self, note: str, octaves: int = 1):
648
"""Create harmonic major scale."""
649
650
class Bachian(Diatonic):
651
"""Bachian scale."""
652
653
def __init__(self, note: str, octaves: int = 1):
654
"""Create Bachian scale."""
655
656
class MinorNeapolitan(Diatonic):
657
"""Minor Neapolitan scale."""
658
659
def __init__(self, note: str, octaves: int = 1):
660
"""Create minor Neapolitan scale."""
661
662
# Modal scales
663
class Dorian(Diatonic):
664
"""Dorian mode."""
665
666
def __init__(self, note: str, octaves: int = 1):
667
"""Create Dorian scale."""
668
669
class Phrygian(Diatonic):
670
"""Phrygian mode."""
671
672
def __init__(self, note: str, octaves: int = 1):
673
"""Create Phrygian scale."""
674
675
class Lydian(Diatonic):
676
"""Lydian mode."""
677
678
def __init__(self, note: str, octaves: int = 1):
679
"""Create Lydian scale."""
680
681
class Mixolydian(Diatonic):
682
"""Mixolydian mode."""
683
684
def __init__(self, note: str, octaves: int = 1):
685
"""Create Mixolydian scale."""
686
687
class Locrian(Diatonic):
688
"""Locrian mode."""
689
690
def __init__(self, note: str, octaves: int = 1):
691
"""Create Locrian scale."""
692
693
# Other scales
694
class Chromatic(Diatonic):
695
"""Chromatic scale."""
696
697
def __init__(self, key: str, octaves: int = 1):
698
"""Create chromatic scale."""
699
700
class WholeTone(Diatonic):
701
"""Whole tone scale."""
702
703
def __init__(self, note: str, octaves: int = 1):
704
"""Create whole tone scale."""
705
706
class Octatonic(Diatonic):
707
"""Octatonic (diminished) scale."""
708
709
def __init__(self, note: str, octaves: int = 1):
710
"""Create octatonic scale."""
711
712
def determine(notes: List[str]) -> List[str]:
713
"""
714
Determine scales containing given notes.
715
716
Parameters:
717
- notes: List of note names
718
719
Returns:
720
List of possible scale names
721
"""
722
```
723
724
### Chord Progressions
725
726
Functions for working with chord progressions and harmonic analysis.
727
728
```python { .api }
729
def to_chords(progression: List[str], key: str = "C") -> List[List[str]]:
730
"""
731
Convert progression to chords.
732
733
Parameters:
734
- progression: List of Roman numerals or chord functions
735
- key: Key for progression
736
737
Returns:
738
List of chord note lists
739
"""
740
741
def determine(chord: List[str], key: str, shorthand: bool = False) -> str:
742
"""
743
Determine chord function in key.
744
745
Parameters:
746
- chord: List of note names
747
- key: Key for analysis
748
- shorthand: Return shorthand notation
749
750
Returns:
751
Chord function (e.g., "I", "V7", "vi")
752
"""
753
754
def substitute(progression: List[str], substitute_index: int, depth: int = 0) -> List[str]:
755
"""
756
Generate chord substitutions for progression.
757
758
Parameters:
759
- progression: List of chord functions
760
- substitute_index: Index to substitute
761
- depth: Substitution depth
762
763
Returns:
764
List of possible substitution progressions
765
"""
766
767
def substitute_harmonic(progression: List[str], substitute_index: int, ignore_suffix: bool = False) -> List[str]:
768
"""
769
Perform simple harmonic substitutions.
770
771
Parameters:
772
- progression: List of chord functions
773
- substitute_index: Index to substitute
774
- ignore_suffix: Ignore chord suffixes if True
775
776
Returns:
777
List of possible harmonic substitutions
778
"""
779
780
def substitute_minor_for_major(progression: List[str], substitute_index: int, ignore_suffix: bool = False) -> List[str]:
781
"""
782
Substitute minor chords for major equivalents.
783
784
Parameters:
785
- progression: List of chord functions
786
- substitute_index: Index to substitute
787
- ignore_suffix: Ignore chord suffixes if True
788
789
Returns:
790
List of minor chord substitutions
791
"""
792
793
def substitute_major_for_minor(progression: List[str], substitute_index: int, ignore_suffix: bool = False) -> List[str]:
794
"""
795
Substitute major chords for minor equivalents.
796
797
Parameters:
798
- progression: List of chord functions
799
- substitute_index: Index to substitute
800
- ignore_suffix: Ignore chord suffixes if True
801
802
Returns:
803
List of major chord substitutions
804
"""
805
806
def substitute_diminished_for_diminished(progression: List[str], substitute_index: int, ignore_suffix: bool = False) -> List[str]:
807
"""
808
Substitute diminished chord for another diminished chord.
809
810
Parameters:
811
- progression: List of chord functions
812
- substitute_index: Index to substitute
813
- ignore_suffix: Ignore chord suffixes if True
814
815
Returns:
816
List of diminished chord substitutions
817
"""
818
819
def substitute_diminished_for_dominant(progression: List[str], substitute_index: int, ignore_suffix: bool = False) -> List[str]:
820
"""
821
Substitute diminished chords for dominant seventh chords.
822
823
Parameters:
824
- progression: List of chord functions
825
- substitute_index: Index to substitute
826
- ignore_suffix: Ignore chord suffixes if True
827
828
Returns:
829
List of diminished-to-dominant substitutions
830
"""
831
832
def parse_string(progression: str) -> Tuple[str, int, str]:
833
"""
834
Parse progression string into components.
835
836
Parameters:
837
- progression: Roman numeral progression string
838
839
Returns:
840
Tuple of (roman numeral, accidentals, suffix)
841
"""
842
843
def tuple_to_string(prog_tuple: Tuple[str, int, str]) -> str:
844
"""
845
Convert parsed tuple back to string.
846
847
Parameters:
848
- prog_tuple: Tuple from parse_string
849
850
Returns:
851
Reconstructed progression string
852
"""
853
854
def interval_diff(progression1: str, progression2: str, interval: int) -> int:
855
"""
856
Calculate interval difference between progressions.
857
858
Parameters:
859
- progression1: First roman numeral
860
- progression2: Second roman numeral
861
- interval: Target interval in semitones
862
863
Returns:
864
Number of accidentals needed for adjustment
865
"""
866
867
def skip(roman_numeral: str, skip_count: int = 1) -> str:
868
"""
869
Skip to next roman numeral.
870
871
Parameters:
872
- roman_numeral: Starting roman numeral
873
- skip_count: Number of steps to skip
874
875
Returns:
876
Next roman numeral in sequence
877
"""
878
879
# Constants
880
numerals: List[str] = ["I", "II", "III", "IV", "V", "VI", "VII"]
881
"""Roman numeral progression sequence."""
882
883
numeral_intervals: List[int] = [0, 2, 4, 5, 7, 9, 11]
884
"""Half-step intervals for each roman numeral."""
885
```
886
887
### Rhythmic Values
888
889
Constants and functions for working with note values and durations.
890
891
```python { .api }
892
# Note value constants
893
whole: int = 1
894
half: int = 2
895
quarter: int = 4
896
eighth: int = 8
897
sixteenth: int = 16
898
thirty_second: int = 32
899
sixty_fourth: int = 64
900
901
def add(value1: int, value2: int) -> int:
902
"""
903
Add note values.
904
905
Parameters:
906
- value1, value2: Note values to add
907
908
Returns:
909
Combined note value
910
"""
911
912
def subtract(value1: int, value2: int) -> int:
913
"""
914
Subtract note values.
915
916
Parameters:
917
- value1, value2: Note values
918
919
Returns:
920
Difference in note values
921
"""
922
923
def dots(value: int, nr: int = 1) -> float:
924
"""
925
Add dots to note value.
926
927
Parameters:
928
- value: Base note value
929
- nr: Number of dots
930
931
Returns:
932
Dotted note value
933
"""
934
935
def triplet(value: int) -> float:
936
"""
937
Create triplet value.
938
939
Parameters:
940
- value: Base note value
941
942
Returns:
943
Triplet note value
944
"""
945
946
def determine(value: float) -> str:
947
"""
948
Analyze note value.
949
950
Parameters:
951
- value: Note value to analyze
952
953
Returns:
954
Description of note value
955
"""
956
```
957
958
### Time Signatures
959
960
Functions for working with time signatures and meters.
961
962
```python { .api }
963
def is_valid(meter: Tuple[int, int]) -> bool:
964
"""
965
Test if meter tuple is valid.
966
967
Parameters:
968
- meter: Time signature tuple (numerator, denominator)
969
970
Returns:
971
True if meter is valid
972
"""
973
974
def is_compound(meter: Tuple[int, int]) -> bool:
975
"""
976
Test if meter is compound.
977
978
Parameters:
979
- meter: Time signature tuple
980
981
Returns:
982
True if meter is compound
983
"""
984
985
def is_simple(meter: Tuple[int, int]) -> bool:
986
"""
987
Test if meter is simple.
988
989
Parameters:
990
- meter: Time signature tuple
991
992
Returns:
993
True if meter is simple
994
"""
995
996
# Common time signatures
997
common_time: Tuple[int, int] = (4, 4)
998
cut_time: Tuple[int, int] = (2, 2)
999
```