musa-dsl 0.40.0 → 0.41.0

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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/Gemfile +0 -1
  4. data/docs/subsystems/music.md +326 -15
  5. data/lib/musa-dsl/generative/darwin.rb +36 -1
  6. data/lib/musa-dsl/generative/generative-grammar.rb +28 -0
  7. data/lib/musa-dsl/generative/markov.rb +2 -0
  8. data/lib/musa-dsl/generative/rules.rb +54 -0
  9. data/lib/musa-dsl/generative/variatio.rb +69 -0
  10. data/lib/musa-dsl/midi/midi-recorder.rb +4 -0
  11. data/lib/musa-dsl/midi/midi-voices.rb +10 -0
  12. data/lib/musa-dsl/music/chords.rb +54 -9
  13. data/lib/musa-dsl/music/equally-tempered-12-tone-scale-system.rb +70 -521
  14. data/lib/musa-dsl/music/scale_kinds/bebop/bebop_dominant_scale_kind.rb +110 -0
  15. data/lib/musa-dsl/music/scale_kinds/bebop/bebop_major_scale_kind.rb +110 -0
  16. data/lib/musa-dsl/music/scale_kinds/bebop/bebop_minor_scale_kind.rb +110 -0
  17. data/lib/musa-dsl/music/scale_kinds/blues/blues_major_scale_kind.rb +100 -0
  18. data/lib/musa-dsl/music/scale_kinds/blues/blues_scale_kind.rb +99 -0
  19. data/lib/musa-dsl/music/scale_kinds/chromatic_scale_kind.rb +79 -0
  20. data/lib/musa-dsl/music/scale_kinds/ethnic/double_harmonic_scale_kind.rb +102 -0
  21. data/lib/musa-dsl/music/scale_kinds/ethnic/hungarian_minor_scale_kind.rb +102 -0
  22. data/lib/musa-dsl/music/scale_kinds/ethnic/neapolitan_major_scale_kind.rb +102 -0
  23. data/lib/musa-dsl/music/scale_kinds/ethnic/neapolitan_minor_scale_kind.rb +101 -0
  24. data/lib/musa-dsl/music/scale_kinds/ethnic/phrygian_dominant_scale_kind.rb +103 -0
  25. data/lib/musa-dsl/music/scale_kinds/harmonic_major/harmonic_major_scale_kind.rb +104 -0
  26. data/lib/musa-dsl/music/scale_kinds/major_scale_kind.rb +110 -0
  27. data/lib/musa-dsl/music/scale_kinds/melodic_minor/altered_scale_kind.rb +106 -0
  28. data/lib/musa-dsl/music/scale_kinds/melodic_minor/dorian_b2_scale_kind.rb +104 -0
  29. data/lib/musa-dsl/music/scale_kinds/melodic_minor/locrian_sharp2_scale_kind.rb +103 -0
  30. data/lib/musa-dsl/music/scale_kinds/melodic_minor/lydian_augmented_scale_kind.rb +103 -0
  31. data/lib/musa-dsl/music/scale_kinds/melodic_minor/lydian_dominant_scale_kind.rb +106 -0
  32. data/lib/musa-dsl/music/scale_kinds/melodic_minor/melodic_minor_scale_kind.rb +104 -0
  33. data/lib/musa-dsl/music/scale_kinds/melodic_minor/mixolydian_b6_scale_kind.rb +103 -0
  34. data/lib/musa-dsl/music/scale_kinds/minor_harmonic_scale_kind.rb +125 -0
  35. data/lib/musa-dsl/music/scale_kinds/minor_natural_scale_kind.rb +123 -0
  36. data/lib/musa-dsl/music/scale_kinds/modes/dorian_scale_kind.rb +111 -0
  37. data/lib/musa-dsl/music/scale_kinds/modes/locrian_scale_kind.rb +114 -0
  38. data/lib/musa-dsl/music/scale_kinds/modes/lydian_scale_kind.rb +111 -0
  39. data/lib/musa-dsl/music/scale_kinds/modes/mixolydian_scale_kind.rb +111 -0
  40. data/lib/musa-dsl/music/scale_kinds/modes/phrygian_scale_kind.rb +111 -0
  41. data/lib/musa-dsl/music/scale_kinds/pentatonic/pentatonic_major_scale_kind.rb +93 -0
  42. data/lib/musa-dsl/music/scale_kinds/pentatonic/pentatonic_minor_scale_kind.rb +99 -0
  43. data/lib/musa-dsl/music/scale_kinds/symmetric/diminished_hw_scale_kind.rb +110 -0
  44. data/lib/musa-dsl/music/scale_kinds/symmetric/diminished_wh_scale_kind.rb +110 -0
  45. data/lib/musa-dsl/music/scale_kinds/symmetric/whole_tone_scale_kind.rb +99 -0
  46. data/lib/musa-dsl/music/scale_systems/equally_tempered_12_tone_scale_system.rb +80 -0
  47. data/lib/musa-dsl/music/scale_systems/twelve_semitones_scale_system.rb +60 -0
  48. data/lib/musa-dsl/music/scales.rb +427 -0
  49. data/lib/musa-dsl/series/buffer-serie.rb +6 -0
  50. data/lib/musa-dsl/series/hash-or-array-serie-splitter.rb +23 -0
  51. data/lib/musa-dsl/series/quantizer-serie.rb +12 -0
  52. data/lib/musa-dsl/series/queue-serie.rb +13 -0
  53. data/lib/musa-dsl/version.rb +2 -1
  54. data/musa-dsl.gemspec +20 -15
  55. metadata +85 -22
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Musa
4
+ module Scales
5
+ # Phrygian mode (third mode of major scale).
6
+ #
7
+ # PhrygianScaleKind defines the Phrygian mode, a minor mode with a characteristic
8
+ # lowered second degree. It's built on the third degree of the major scale
9
+ # and has a dark, exotic, Spanish/Middle Eastern quality.
10
+ #
11
+ # ## Pitch Structure
12
+ #
13
+ # 7 diatonic degrees plus extended harmony (8th-13th):
14
+ #
15
+ # **Scale Degrees** (Roman numerals, lowercase for minor):
16
+ #
17
+ # - **i** (tonic): Root (0 semitones)
18
+ # - **ii** (supertonic): **Minor second** (1 semitone) ← CHARACTERISTIC
19
+ # - **iii** (mediant): Minor third (3 semitones)
20
+ # - **iv** (subdominant): Perfect fourth (5 semitones)
21
+ # - **v** (dominant): Perfect fifth (7 semitones)
22
+ # - **vi** (submediant): Minor sixth (8 semitones)
23
+ # - **vii** (subtonic): Minor seventh (10 semitones)
24
+ #
25
+ # ## Key Difference from Natural Minor
26
+ #
27
+ # The **ii** degree is lowered from 2 semitones (major second) to
28
+ # 1 semitone (minor second), creating:
29
+ #
30
+ # - A dark, exotic quality
31
+ # - The characteristic "Phrygian color"
32
+ # - Strong association with Spanish/Flamenco music
33
+ #
34
+ # ## Musical Character
35
+ #
36
+ # The Phrygian mode:
37
+ #
38
+ # - Maintains minor quality (minor third)
39
+ # - Has a lowered 2nd that creates tension
40
+ # - Common in flamenco, metal, and Middle Eastern music
41
+ # - The half-step from ii to i creates strong resolution
42
+ #
43
+ # ## Usage
44
+ #
45
+ # e_phrygian = Scales[:et12][440.0][:phrygian][64]
46
+ # e_phrygian.tonic # E (64)
47
+ # e_phrygian.ii # F (65) - minor second (characteristic)
48
+ #
49
+ # @see ScaleKind Abstract base class
50
+ # @see MinorNaturalScaleKind Natural minor (with major 2nd)
51
+ # @see DorianScaleKind Dorian mode
52
+ class PhrygianScaleKind < ScaleKind
53
+ @base_metadata = {
54
+ family: :greek_modes,
55
+ brightness: -2,
56
+ character: [:dark, :spanish, :exotic],
57
+ parent: { scale: :major, degree: 3 }
58
+ }.freeze
59
+
60
+ class << self
61
+ @@pitches =
62
+ [{ functions: %i[i _1 tonic first],
63
+ pitch: 0 },
64
+ { functions: %i[ii _2 supertonic second],
65
+ pitch: 1 },
66
+ { functions: %i[iii _3 mediant third],
67
+ pitch: 3 },
68
+ { functions: %i[iv _4 subdominant fourth],
69
+ pitch: 5 },
70
+ { functions: %i[v _5 dominant fifth],
71
+ pitch: 7 },
72
+ { functions: %i[vi _6 submediant sixth],
73
+ pitch: 8 },
74
+ { functions: %i[vii _7 subtonic seventh],
75
+ pitch: 10 },
76
+ { functions: %i[viii _8 eighth],
77
+ pitch: 12 },
78
+ { functions: %i[ix _9 ninth],
79
+ pitch: 12 + 1 },
80
+ { functions: %i[x _10 tenth],
81
+ pitch: 12 + 3 },
82
+ { functions: %i[xi _11 eleventh],
83
+ pitch: 12 + 5 },
84
+ { functions: %i[xii _12 twelfth],
85
+ pitch: 12 + 7 },
86
+ { functions: %i[xiii _13 thirteenth],
87
+ pitch: 12 + 8 }].freeze
88
+
89
+ # Pitch structure.
90
+ # @return [Array<Hash>] pitch definitions with functions and offsets
91
+ def pitches
92
+ @@pitches
93
+ end
94
+
95
+ # Number of diatonic degrees.
96
+ # @return [Integer] 7
97
+ def grades
98
+ 7
99
+ end
100
+
101
+ # Scale kind identifier.
102
+ # @return [Symbol] :phrygian
103
+ def id
104
+ :phrygian
105
+ end
106
+ end
107
+
108
+ EquallyTempered12ToneScaleSystem.register PhrygianScaleKind
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Musa
4
+ module Scales
5
+ # Major pentatonic scale kind.
6
+ #
7
+ # PentatonicMajorScaleKind defines the major pentatonic scale, a five-note
8
+ # scale derived from the major scale by omitting the 4th and 7th degrees.
9
+ # It has a bright, open sound and is extremely common in folk, rock, and blues.
10
+ #
11
+ # ## Pitch Structure
12
+ #
13
+ # 5 diatonic degrees plus extended (6th-10th):
14
+ #
15
+ # **Scale Degrees** (Roman numerals, uppercase for major):
16
+ #
17
+ # - **I** (tonic): Root (0 semitones)
18
+ # - **II** (supertonic): Major second (2 semitones)
19
+ # - **III** (mediant): Major third (4 semitones)
20
+ # - **V** (dominant): Perfect fifth (7 semitones)
21
+ # - **VI** (submediant): Major sixth (9 semitones)
22
+ #
23
+ # ## Relationship to Major Scale
24
+ #
25
+ # Major pentatonic = Major scale minus 4th and 7th degrees.
26
+ # This removes all semitone intervals, creating a scale with no dissonance.
27
+ #
28
+ # ## Musical Character
29
+ #
30
+ # The major pentatonic:
31
+ #
32
+ # - Has a bright, happy, open quality
33
+ # - No semitones = no tension or dissonance
34
+ # - Universal across cultures (found in music worldwide)
35
+ # - Common in folk, country, rock, pop, and blues
36
+ #
37
+ # ## Usage
38
+ #
39
+ # c_pent = Scales[:et12][440.0][:pentatonic_major][60]
40
+ # c_pent.tonic # C (60)
41
+ # c_pent.dominant # G (67)
42
+ #
43
+ # @see ScaleKind Abstract base class
44
+ # @see MajorScaleKind Major scale
45
+ # @see PentatonicMinorScaleKind Minor pentatonic
46
+ class PentatonicMajorScaleKind < ScaleKind
47
+ @base_metadata = {
48
+ family: :pentatonic,
49
+ brightness: 1,
50
+ character: [:bright, :simple, :folk],
51
+ parent: nil
52
+ }.freeze
53
+
54
+ class << self
55
+ @@pitches =
56
+ [{ functions: %i[I _1 tonic first],
57
+ pitch: 0 },
58
+ { functions: %i[II _2 supertonic second],
59
+ pitch: 2 },
60
+ { functions: %i[III _3 mediant third],
61
+ pitch: 4 },
62
+ { functions: %i[V _4 dominant fourth],
63
+ pitch: 7 },
64
+ { functions: %i[VI _5 submediant fifth],
65
+ pitch: 9 },
66
+ { functions: %i[VIII _6 sixth],
67
+ pitch: 12 },
68
+ { functions: %i[IX _7 seventh],
69
+ pitch: 12 + 2 },
70
+ { functions: %i[X _8 eighth],
71
+ pitch: 12 + 4 },
72
+ { functions: %i[XII _9 ninth],
73
+ pitch: 12 + 7 },
74
+ { functions: %i[XIII _10 tenth],
75
+ pitch: 12 + 9 }].freeze
76
+
77
+ def pitches
78
+ @@pitches
79
+ end
80
+
81
+ def grades
82
+ 5
83
+ end
84
+
85
+ def id
86
+ :pentatonic_major
87
+ end
88
+ end
89
+
90
+ EquallyTempered12ToneScaleSystem.register PentatonicMajorScaleKind
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Musa
4
+ module Scales
5
+ # Minor pentatonic scale kind.
6
+ #
7
+ # PentatonicMinorScaleKind defines the minor pentatonic scale, a five-note
8
+ # scale derived from the natural minor scale by omitting the 2nd and 6th degrees.
9
+ # It's the foundation of blues and rock improvisation.
10
+ #
11
+ # ## Pitch Structure
12
+ #
13
+ # 5 diatonic degrees plus extended (6th-10th):
14
+ #
15
+ # **Scale Degrees** (Roman numerals, lowercase for minor):
16
+ #
17
+ # - **i** (tonic): Root (0 semitones)
18
+ # - **iii** (mediant): Minor third (3 semitones)
19
+ # - **iv** (subdominant): Perfect fourth (5 semitones)
20
+ # - **v** (dominant): Perfect fifth (7 semitones)
21
+ # - **vii** (subtonic): Minor seventh (10 semitones)
22
+ #
23
+ # ## Relationship to Natural Minor
24
+ #
25
+ # Minor pentatonic = Natural minor minus 2nd and 6th degrees.
26
+ # This removes all semitone intervals, creating a scale with no dissonance.
27
+ #
28
+ # ## Relative Major Pentatonic
29
+ #
30
+ # A minor pentatonic shares the same notes as C major pentatonic.
31
+ # They are relative scales.
32
+ #
33
+ # ## Musical Character
34
+ #
35
+ # The minor pentatonic:
36
+ #
37
+ # - Has a bluesy, soulful quality
38
+ # - Foundation of blues and rock guitar solos
39
+ # - Works over both minor and dominant 7th chords
40
+ # - Easy to improvise with (no "wrong" notes)
41
+ #
42
+ # ## Usage
43
+ #
44
+ # a_pent = Scales[:et12][440.0][:pentatonic_minor][69]
45
+ # a_pent.tonic # A (69)
46
+ # a_pent.dominant # E (76)
47
+ #
48
+ # @see ScaleKind Abstract base class
49
+ # @see MinorNaturalScaleKind Natural minor scale
50
+ # @see PentatonicMajorScaleKind Major pentatonic
51
+ # @see BluesScaleKind Blues scale (pentatonic + blue note)
52
+ class PentatonicMinorScaleKind < ScaleKind
53
+ @base_metadata = {
54
+ family: :pentatonic,
55
+ brightness: -1,
56
+ character: [:bluesy, :simple, :rock],
57
+ parent: nil
58
+ }.freeze
59
+
60
+ class << self
61
+ @@pitches =
62
+ [{ functions: %i[i _1 tonic first],
63
+ pitch: 0 },
64
+ { functions: %i[iii _2 mediant second],
65
+ pitch: 3 },
66
+ { functions: %i[iv _3 subdominant third],
67
+ pitch: 5 },
68
+ { functions: %i[v _4 dominant fourth],
69
+ pitch: 7 },
70
+ { functions: %i[vii _5 subtonic fifth],
71
+ pitch: 10 },
72
+ { functions: %i[viii _6 sixth],
73
+ pitch: 12 },
74
+ { functions: %i[x _7 seventh],
75
+ pitch: 12 + 3 },
76
+ { functions: %i[xi _8 eighth],
77
+ pitch: 12 + 5 },
78
+ { functions: %i[xii _9 ninth],
79
+ pitch: 12 + 7 },
80
+ { functions: %i[xiv _10 tenth],
81
+ pitch: 12 + 10 }].freeze
82
+
83
+ def pitches
84
+ @@pitches
85
+ end
86
+
87
+ def grades
88
+ 5
89
+ end
90
+
91
+ def id
92
+ :pentatonic_minor
93
+ end
94
+ end
95
+
96
+ EquallyTempered12ToneScaleSystem.register PentatonicMinorScaleKind
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Musa
4
+ module Scales
5
+ # Diminished half-whole scale kind.
6
+ #
7
+ # DiminishedHWScaleKind defines the half-whole diminished scale (also called
8
+ # octatonic scale), an eight-note symmetric scale alternating half steps and
9
+ # whole steps. It's commonly used over diminished 7th chords.
10
+ #
11
+ # ## Pitch Structure
12
+ #
13
+ # 8 degrees plus extended:
14
+ #
15
+ # **Scale Degrees** (pattern: H-W-H-W-H-W-H-W):
16
+ #
17
+ # - **i** (_1): Root (0 semitones)
18
+ # - **ii** (_2): Minor second (1 semitone)
19
+ # - **iii** (_3): Minor third (3 semitones)
20
+ # - **iv** (_4): Major third (4 semitones)
21
+ # - **v** (_5): Diminished fifth (6 semitones)
22
+ # - **vi** (_6): Perfect fifth (7 semitones)
23
+ # - **vii** (_7): Major sixth (9 semitones)
24
+ # - **viii** (_8): Minor seventh (10 semitones)
25
+ #
26
+ # ## Symmetric Properties
27
+ #
28
+ # - Only 3 distinct diminished scales exist
29
+ # - Repeats every minor third (3 semitones)
30
+ # - Contains 4 minor thirds, 4 major thirds, 2 tritones
31
+ # - Every diminished 7th chord is contained within
32
+ #
33
+ # ## Musical Character
34
+ #
35
+ # The half-whole diminished scale:
36
+ #
37
+ # - Tense, dark, unstable quality
38
+ # - Used over diminished 7th chords
39
+ # - Common in jazz, film scores, classical
40
+ # - Creates strong chromatic tension
41
+ #
42
+ # ## Usage
43
+ #
44
+ # c_dim = Scales[:et12][440.0][:diminished_hw][60]
45
+ # c_dim[0].pitch # C (60)
46
+ # c_dim[1].pitch # Db (61)
47
+ #
48
+ # @see ScaleKind Abstract base class
49
+ # @see DiminishedWHScaleKind Whole-half diminished (dominant diminished)
50
+ # @see WholeToneScaleKind Whole tone scale
51
+ class DiminishedHWScaleKind < ScaleKind
52
+ @base_metadata = {
53
+ family: :symmetric,
54
+ brightness: nil,
55
+ character: [:diminished, :tense, :jazz],
56
+ parent: nil
57
+ }.freeze
58
+
59
+ class << self
60
+ @@pitches =
61
+ [{ functions: %i[i _1 tonic first],
62
+ pitch: 0 },
63
+ { functions: %i[ii _2 second],
64
+ pitch: 1 },
65
+ { functions: %i[iii _3 third],
66
+ pitch: 3 },
67
+ { functions: %i[iv _4 fourth],
68
+ pitch: 4 },
69
+ { functions: %i[v _5 fifth],
70
+ pitch: 6 },
71
+ { functions: %i[vi _6 sixth],
72
+ pitch: 7 },
73
+ { functions: %i[vii _7 seventh],
74
+ pitch: 9 },
75
+ { functions: %i[viii _8 eighth],
76
+ pitch: 10 },
77
+ { functions: %i[ix _9 ninth],
78
+ pitch: 12 },
79
+ { functions: %i[x _10 tenth],
80
+ pitch: 12 + 1 },
81
+ { functions: %i[xi _11 eleventh],
82
+ pitch: 12 + 3 },
83
+ { functions: %i[xii _12 twelfth],
84
+ pitch: 12 + 4 },
85
+ { functions: %i[xiii _13 thirteenth],
86
+ pitch: 12 + 6 },
87
+ { functions: %i[xiv _14 fourteenth],
88
+ pitch: 12 + 7 },
89
+ { functions: %i[xv _15 fifteenth],
90
+ pitch: 12 + 9 },
91
+ { functions: %i[xvi _16 sixteenth],
92
+ pitch: 12 + 10 }].freeze
93
+
94
+ def pitches
95
+ @@pitches
96
+ end
97
+
98
+ def grades
99
+ 8
100
+ end
101
+
102
+ def id
103
+ :diminished_hw
104
+ end
105
+ end
106
+
107
+ EquallyTempered12ToneScaleSystem.register DiminishedHWScaleKind
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Musa
4
+ module Scales
5
+ # Diminished whole-half scale kind.
6
+ #
7
+ # DiminishedWHScaleKind defines the whole-half diminished scale (also called
8
+ # dominant diminished), an eight-note symmetric scale alternating whole steps
9
+ # and half steps. It's commonly used over dominant 7th chords with altered tensions.
10
+ #
11
+ # ## Pitch Structure
12
+ #
13
+ # 8 degrees plus extended:
14
+ #
15
+ # **Scale Degrees** (pattern: W-H-W-H-W-H-W-H):
16
+ #
17
+ # - **I** (_1): Root (0 semitones)
18
+ # - **II** (_2): Major second (2 semitones)
19
+ # - **III** (_3): Minor third (3 semitones)
20
+ # - **IV** (_4): Perfect fourth (5 semitones)
21
+ # - **V** (_5): Diminished fifth (6 semitones)
22
+ # - **VI** (_6): Augmented fifth (8 semitones)
23
+ # - **VII** (_7): Major sixth (9 semitones)
24
+ # - **VIII** (_8): Major seventh (11 semitones)
25
+ #
26
+ # ## Symmetric Properties
27
+ #
28
+ # - Only 3 distinct diminished scales exist
29
+ # - Repeats every minor third (3 semitones)
30
+ # - Same notes as half-whole, but different starting point
31
+ # - Contains natural 9, #9, #11, 13 over dominant chord
32
+ #
33
+ # ## Musical Character
34
+ #
35
+ # The whole-half diminished scale:
36
+ #
37
+ # - Used over dominant 7th chords (hence "dominant diminished")
38
+ # - Provides b9, #9, #11, and natural 13 tensions
39
+ # - Common in bebop and modern jazz
40
+ # - Creates sophisticated altered dominant sound
41
+ #
42
+ # ## Usage
43
+ #
44
+ # g_dom_dim = Scales[:et12][440.0][:diminished_wh][67]
45
+ # g_dom_dim[0].pitch # G (67)
46
+ # g_dom_dim[1].pitch # A (69)
47
+ #
48
+ # @see ScaleKind Abstract base class
49
+ # @see DiminishedHWScaleKind Half-whole diminished
50
+ # @see AlteredScaleKind Altered scale (another dominant scale)
51
+ class DiminishedWHScaleKind < ScaleKind
52
+ @base_metadata = {
53
+ family: :symmetric,
54
+ brightness: nil,
55
+ character: [:diminished, :dominant, :jazz],
56
+ parent: nil
57
+ }.freeze
58
+
59
+ class << self
60
+ @@pitches =
61
+ [{ functions: %i[I _1 tonic first],
62
+ pitch: 0 },
63
+ { functions: %i[II _2 second],
64
+ pitch: 2 },
65
+ { functions: %i[III _3 third],
66
+ pitch: 3 },
67
+ { functions: %i[IV _4 fourth],
68
+ pitch: 5 },
69
+ { functions: %i[V _5 fifth],
70
+ pitch: 6 },
71
+ { functions: %i[VI _6 sixth],
72
+ pitch: 8 },
73
+ { functions: %i[VII _7 seventh],
74
+ pitch: 9 },
75
+ { functions: %i[VIII _8 eighth],
76
+ pitch: 11 },
77
+ { functions: %i[IX _9 ninth],
78
+ pitch: 12 },
79
+ { functions: %i[X _10 tenth],
80
+ pitch: 12 + 2 },
81
+ { functions: %i[XI _11 eleventh],
82
+ pitch: 12 + 3 },
83
+ { functions: %i[XII _12 twelfth],
84
+ pitch: 12 + 5 },
85
+ { functions: %i[XIII _13 thirteenth],
86
+ pitch: 12 + 6 },
87
+ { functions: %i[XIV _14 fourteenth],
88
+ pitch: 12 + 8 },
89
+ { functions: %i[XV _15 fifteenth],
90
+ pitch: 12 + 9 },
91
+ { functions: %i[XVI _16 sixteenth],
92
+ pitch: 12 + 11 }].freeze
93
+
94
+ def pitches
95
+ @@pitches
96
+ end
97
+
98
+ def grades
99
+ 8
100
+ end
101
+
102
+ def id
103
+ :diminished_wh
104
+ end
105
+ end
106
+
107
+ EquallyTempered12ToneScaleSystem.register DiminishedWHScaleKind
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Musa
4
+ module Scales
5
+ # Whole tone scale kind.
6
+ #
7
+ # WholeToneScaleKind defines the whole tone scale, a six-note symmetric
8
+ # scale where every interval is a whole step (major second). It has a
9
+ # dreamy, ambiguous quality with no clear tonal center.
10
+ #
11
+ # ## Pitch Structure
12
+ #
13
+ # 6 degrees plus extended:
14
+ #
15
+ # **Scale Degrees**:
16
+ #
17
+ # - **I** (_1): Root (0 semitones)
18
+ # - **II** (_2): Major second (2 semitones)
19
+ # - **III** (_3): Major third (4 semitones)
20
+ # - **IV#** (_4): Augmented fourth (6 semitones)
21
+ # - **V#** (_5): Augmented fifth (8 semitones)
22
+ # - **VII** (_6): Minor seventh (10 semitones)
23
+ #
24
+ # ## Symmetric Properties
25
+ #
26
+ # - Only 2 distinct whole tone scales exist (C and C#)
27
+ # - Every note can function as the root
28
+ # - Divides the octave into 6 equal parts
29
+ # - No perfect fifths = no strong harmonic function
30
+ #
31
+ # ## Musical Character
32
+ #
33
+ # The whole tone scale:
34
+ #
35
+ # - Dreamy, floating, ambiguous quality
36
+ # - No leading tones or tendency tones
37
+ # - Associated with impressionism (Debussy)
38
+ # - Used over augmented and dominant 7#5 chords
39
+ #
40
+ # ## Usage
41
+ #
42
+ # c_whole = Scales[:et12][440.0][:whole_tone][60]
43
+ # c_whole[0].pitch # C (60)
44
+ # c_whole[3].pitch # F# (66)
45
+ #
46
+ # @see ScaleKind Abstract base class
47
+ # @see DiminishedHWScaleKind Diminished scale (another symmetric scale)
48
+ class WholeToneScaleKind < ScaleKind
49
+ @base_metadata = {
50
+ family: :symmetric,
51
+ brightness: nil,
52
+ character: [:floating, :impressionist, :ambiguous],
53
+ parent: nil
54
+ }.freeze
55
+
56
+ class << self
57
+ @@pitches =
58
+ [{ functions: %i[I _1 tonic first],
59
+ pitch: 0 },
60
+ { functions: %i[II _2 second],
61
+ pitch: 2 },
62
+ { functions: %i[III _3 third],
63
+ pitch: 4 },
64
+ { functions: %i[IV _4 fourth],
65
+ pitch: 6 },
66
+ { functions: %i[V _5 fifth],
67
+ pitch: 8 },
68
+ { functions: %i[VI _6 sixth],
69
+ pitch: 10 },
70
+ { functions: %i[VII _7 seventh],
71
+ pitch: 12 },
72
+ { functions: %i[VIII _8 eighth],
73
+ pitch: 12 + 2 },
74
+ { functions: %i[IX _9 ninth],
75
+ pitch: 12 + 4 },
76
+ { functions: %i[X _10 tenth],
77
+ pitch: 12 + 6 },
78
+ { functions: %i[XI _11 eleventh],
79
+ pitch: 12 + 8 },
80
+ { functions: %i[XII _12 twelfth],
81
+ pitch: 12 + 10 }].freeze
82
+
83
+ def pitches
84
+ @@pitches
85
+ end
86
+
87
+ def grades
88
+ 6
89
+ end
90
+
91
+ def id
92
+ :whole_tone
93
+ end
94
+ end
95
+
96
+ EquallyTempered12ToneScaleSystem.register WholeToneScaleKind
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'twelve_semitones_scale_system'
4
+
5
+ module Musa
6
+ module Scales
7
+ # Equal temperament 12-tone scale system.
8
+ #
9
+ # EquallyTempered12ToneScaleSystem implements the standard equal temperament
10
+ # tuning where each semitone has exactly the same frequency ratio: 2^(1/12).
11
+ # This is the most common tuning system in modern Western music.
12
+ #
13
+ # ## Frequency Calculation
14
+ #
15
+ # Uses the equal temperament formula based on A440 concert pitch:
16
+ #
17
+ # frequency = a_frequency × 2^((pitch - 69) / 12)
18
+ #
19
+ # Where:
20
+ #
21
+ # - **a_frequency**: Reference A frequency (typically 440 Hz)
22
+ # - **pitch**: MIDI pitch number (69 = A4)
23
+ #
24
+ # ## Historical Pitch Standards
25
+ #
26
+ # Different A frequencies represent different historical standards:
27
+ #
28
+ # - **440 Hz**: Modern concert pitch (ISO 16)
29
+ # - **442 Hz**: Used by some orchestras (brighter sound)
30
+ # - **415 Hz**: Baroque pitch (approximately A=415)
31
+ # - **432 Hz**: Alternative tuning (some claim harmonic benefits)
32
+ #
33
+ # ## Registration
34
+ #
35
+ # This system is registered as the default scale system, accessible via:
36
+ #
37
+ # Scales[:et12] # By ID
38
+ # Scales.default_system # As default
39
+ #
40
+ # ## Usage
41
+ #
42
+ # # Get system with standard A440 tuning
43
+ # system = Scales[:et12][440.0]
44
+ #
45
+ # # Get system with baroque tuning
46
+ # baroque = Scales[:et12][415.0]
47
+ #
48
+ # # Access scale kinds
49
+ # c_major = system[:major][60]
50
+ # a_minor = system[:minor][69]
51
+ #
52
+ # @see TwelveSemitonesScaleSystem Abstract base class
53
+ # @see ScaleSystem#frequency_of_pitch Abstract method implemented here
54
+ class EquallyTempered12ToneScaleSystem < TwelveSemitonesScaleSystem
55
+ class << self
56
+ # Calculates frequency for a pitch using equal temperament.
57
+ #
58
+ # Implements the equal temperament tuning formula where each semitone
59
+ # has a frequency ratio of 2^(1/12) ≈ 1.059463.
60
+ #
61
+ # @param pitch [Integer] MIDI pitch number
62
+ # @param _root_pitch [Integer] unused (required by interface)
63
+ # @param a_frequency [Numeric] reference A4 frequency in Hz
64
+ # @return [Float] frequency in Hz
65
+ #
66
+ # @example Standard A440 tuning
67
+ # frequency_of_pitch(69, nil, 440.0) # => 440.0 (A4)
68
+ # frequency_of_pitch(60, nil, 440.0) # => 261.63 (C4, middle C)
69
+ #
70
+ # @example Baroque tuning
71
+ # frequency_of_pitch(69, nil, 415.0) # => 415.0 (A4)
72
+ def frequency_of_pitch(pitch, _root_pitch, a_frequency)
73
+ (a_frequency * Rational(2)**Rational(pitch - 69, 12)).to_f
74
+ end
75
+ end
76
+
77
+ Scales.register EquallyTempered12ToneScaleSystem, default: true
78
+ end
79
+ end
80
+ end