musa-dsl 0.30.2 → 0.40.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.
- checksums.yaml +4 -4
- data/.gitignore +3 -1
- data/.version +6 -0
- data/.yardopts +7 -0
- data/README.md +227 -6
- data/docs/README.md +83 -0
- data/docs/api-reference.md +86 -0
- data/docs/getting-started/quick-start.md +93 -0
- data/docs/getting-started/tutorial.md +58 -0
- data/docs/subsystems/core-extensions.md +316 -0
- data/docs/subsystems/datasets.md +465 -0
- data/docs/subsystems/generative.md +290 -0
- data/docs/subsystems/matrix.md +63 -0
- data/docs/subsystems/midi.md +123 -0
- data/docs/subsystems/music.md +233 -0
- data/docs/subsystems/musicxml-builder.md +264 -0
- data/docs/subsystems/neumas.md +71 -0
- data/docs/subsystems/repl.md +135 -0
- data/docs/subsystems/sequencer.md +98 -0
- data/docs/subsystems/series.md +302 -0
- data/docs/subsystems/transcription.md +152 -0
- data/docs/subsystems/transport.md +177 -0
- data/lib/musa-dsl/core-ext/array-explode-ranges.rb +68 -0
- data/lib/musa-dsl/core-ext/arrayfy.rb +110 -0
- data/lib/musa-dsl/core-ext/attribute-builder.rb +91 -30
- data/lib/musa-dsl/core-ext/deep-copy.rb +125 -2
- data/lib/musa-dsl/core-ext/dynamic-proxy.rb +78 -0
- data/lib/musa-dsl/core-ext/extension.rb +53 -0
- data/lib/musa-dsl/core-ext/hashify.rb +162 -1
- data/lib/musa-dsl/core-ext/inspect-nice.rb +154 -0
- data/lib/musa-dsl/core-ext/smart-proc-binder.rb +117 -0
- data/lib/musa-dsl/core-ext/with.rb +114 -0
- data/lib/musa-dsl/datasets/dataset.rb +109 -0
- data/lib/musa-dsl/datasets/delta-d.rb +78 -0
- data/lib/musa-dsl/datasets/e.rb +186 -2
- data/lib/musa-dsl/datasets/gdv.rb +279 -2
- data/lib/musa-dsl/datasets/gdvd.rb +201 -0
- data/lib/musa-dsl/datasets/helper.rb +75 -0
- data/lib/musa-dsl/datasets/p.rb +177 -2
- data/lib/musa-dsl/datasets/packed-v.rb +91 -0
- data/lib/musa-dsl/datasets/pdv.rb +136 -1
- data/lib/musa-dsl/datasets/ps.rb +134 -4
- data/lib/musa-dsl/datasets/score/queriable.rb +143 -1
- data/lib/musa-dsl/datasets/score/render.rb +105 -1
- data/lib/musa-dsl/datasets/score/to-mxml/process-pdv.rb +138 -1
- data/lib/musa-dsl/datasets/score/to-mxml/process-ps.rb +111 -0
- data/lib/musa-dsl/datasets/score/to-mxml/process-time.rb +200 -1
- data/lib/musa-dsl/datasets/score/to-mxml/to-mxml.rb +145 -1
- data/lib/musa-dsl/datasets/score.rb +279 -0
- data/lib/musa-dsl/datasets/v.rb +88 -0
- data/lib/musa-dsl/generative/darwin.rb +180 -1
- data/lib/musa-dsl/generative/generative-grammar.rb +359 -0
- data/lib/musa-dsl/generative/markov.rb +133 -3
- data/lib/musa-dsl/generative/rules.rb +258 -4
- data/lib/musa-dsl/generative/variatio.rb +217 -2
- data/lib/musa-dsl/logger/logger.rb +267 -2
- data/lib/musa-dsl/matrix/matrix.rb +256 -10
- data/lib/musa-dsl/midi/midi-recorder.rb +108 -1
- data/lib/musa-dsl/midi/midi-voices.rb +265 -4
- data/lib/musa-dsl/music/chord-definition.rb +233 -1
- data/lib/musa-dsl/music/chord-definitions.rb +33 -6
- data/lib/musa-dsl/music/chords.rb +308 -2
- data/lib/musa-dsl/music/equally-tempered-12-tone-scale-system.rb +315 -0
- data/lib/musa-dsl/music/scales.rb +957 -40
- data/lib/musa-dsl/musicxml/builder/attributes.rb +483 -3
- data/lib/musa-dsl/musicxml/builder/backup-forward.rb +166 -1
- data/lib/musa-dsl/musicxml/builder/direction.rb +243 -0
- data/lib/musa-dsl/musicxml/builder/helper.rb +240 -0
- data/lib/musa-dsl/musicxml/builder/measure.rb +284 -0
- data/lib/musa-dsl/musicxml/builder/note-complexities.rb +324 -8
- data/lib/musa-dsl/musicxml/builder/note.rb +285 -0
- data/lib/musa-dsl/musicxml/builder/part-group.rb +108 -1
- data/lib/musa-dsl/musicxml/builder/part.rb +139 -0
- data/lib/musa-dsl/musicxml/builder/pitched-note.rb +124 -0
- data/lib/musa-dsl/musicxml/builder/rest.rb +93 -0
- data/lib/musa-dsl/musicxml/builder/score-partwise.rb +276 -0
- data/lib/musa-dsl/musicxml/builder/typed-text.rb +62 -1
- data/lib/musa-dsl/musicxml/builder/unpitched-note.rb +83 -0
- data/lib/musa-dsl/neumalang/neumalang.rb +675 -0
- data/lib/musa-dsl/neumas/array-to-neumas.rb +149 -0
- data/lib/musa-dsl/neumas/neuma-decoder.rb +253 -0
- data/lib/musa-dsl/neumas/neuma-gdv-decoder.rb +142 -2
- data/lib/musa-dsl/neumas/neuma-gdvd-decoder.rb +82 -0
- data/lib/musa-dsl/neumas/neumas.rb +67 -0
- data/lib/musa-dsl/neumas/string-to-neumas.rb +233 -1
- data/lib/musa-dsl/repl/repl.rb +550 -0
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-every.rb +118 -2
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-move.rb +149 -2
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +296 -0
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-timed.rb +88 -2
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play.rb +161 -0
- data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +263 -0
- data/lib/musa-dsl/sequencer/base-sequencer-tick-based.rb +173 -1
- data/lib/musa-dsl/sequencer/base-sequencer-tickless-based.rb +177 -0
- data/lib/musa-dsl/sequencer/base-sequencer.rb +710 -10
- data/lib/musa-dsl/sequencer/sequencer-dsl.rb +210 -0
- data/lib/musa-dsl/sequencer/timeslots.rb +79 -0
- data/lib/musa-dsl/series/array-to-serie.rb +37 -1
- data/lib/musa-dsl/series/base-series.rb +843 -5
- data/lib/musa-dsl/series/buffer-serie.rb +48 -0
- data/lib/musa-dsl/series/hash-or-array-serie-splitter.rb +41 -0
- data/lib/musa-dsl/series/main-serie-constructors.rb +398 -2
- data/lib/musa-dsl/series/main-serie-operations.rb +538 -16
- data/lib/musa-dsl/series/proxy-serie.rb +67 -0
- data/lib/musa-dsl/series/quantizer-serie.rb +45 -7
- data/lib/musa-dsl/series/queue-serie.rb +65 -0
- data/lib/musa-dsl/series/series-composer.rb +701 -0
- data/lib/musa-dsl/series/timed-serie.rb +473 -28
- data/lib/musa-dsl/transcription/from-gdv-to-midi.rb +404 -1
- data/lib/musa-dsl/transcription/from-gdv-to-musicxml.rb +118 -0
- data/lib/musa-dsl/transcription/from-gdv.rb +84 -1
- data/lib/musa-dsl/transcription/transcription.rb +265 -0
- data/lib/musa-dsl/transport/clock.rb +125 -0
- data/lib/musa-dsl/transport/dummy-clock.rb +89 -2
- data/lib/musa-dsl/transport/external-tick-clock.rb +91 -0
- data/lib/musa-dsl/transport/input-midi-clock.rb +133 -1
- data/lib/musa-dsl/transport/timer-clock.rb +183 -1
- data/lib/musa-dsl/transport/timer.rb +83 -0
- data/lib/musa-dsl/transport/transport.rb +318 -0
- data/lib/musa-dsl/version.rb +1 -1
- data/lib/musa-dsl.rb +132 -25
- data/musa-dsl.gemspec +12 -10
- metadata +87 -8
|
@@ -2,30 +2,126 @@ require_relative 'scales'
|
|
|
2
2
|
|
|
3
3
|
module Musa
|
|
4
4
|
module Scales
|
|
5
|
+
# Base class for 12-semitone scale systems.
|
|
6
|
+
#
|
|
7
|
+
# TwelveSemitonesScaleSystem provides the foundation for any scale system
|
|
8
|
+
# using 12 semitones per octave. It defines intervals and structure but
|
|
9
|
+
# doesn't specify tuning (frequency calculation).
|
|
10
|
+
#
|
|
11
|
+
# Concrete subclasses must implement frequency calculation:
|
|
12
|
+
#
|
|
13
|
+
# - {EquallyTempered12ToneScaleSystem}: Equal temperament (12-TET)
|
|
14
|
+
# - Other temperaments could be added (e.g., meantone, just intonation)
|
|
15
|
+
#
|
|
16
|
+
# ## Intervals
|
|
17
|
+
#
|
|
18
|
+
# Defines standard interval names using semitone distances:
|
|
19
|
+
#
|
|
20
|
+
# { P0: 0, m2: 1, M2: 2, m3: 3, M3: 4, P4: 5, TT: 6,
|
|
21
|
+
# P5: 7, m6: 8, M6: 9, m7: 10, M7: 11, P8: 12 }
|
|
22
|
+
#
|
|
23
|
+
# @abstract Subclasses must implement {frequency_of_pitch}
|
|
24
|
+
# @see EquallyTempered12ToneScaleSystem Concrete equal temperament implementation
|
|
5
25
|
class TwelveSemitonesScaleSystem < ScaleSystem
|
|
6
26
|
class << self
|
|
7
27
|
@@intervals = { P0: 0, m2: 1, M2: 2, m3: 3, M3: 4, P4: 5, TT: 6, P5: 7, m6: 8, M6: 9, m7: 10, M7: 11, P8: 12 }
|
|
8
28
|
|
|
29
|
+
# System identifier.
|
|
30
|
+
# @return [Symbol] :et12
|
|
9
31
|
def id
|
|
10
32
|
:et12
|
|
11
33
|
end
|
|
12
34
|
|
|
35
|
+
# Number of distinct notes per octave.
|
|
36
|
+
# @return [Integer] 12
|
|
13
37
|
def notes_in_octave
|
|
14
38
|
12
|
|
15
39
|
end
|
|
16
40
|
|
|
41
|
+
# Size of smallest pitch division.
|
|
42
|
+
# @return [Integer] 1 (semitone)
|
|
17
43
|
def part_of_tone_size
|
|
18
44
|
1
|
|
19
45
|
end
|
|
20
46
|
|
|
47
|
+
# Interval definitions.
|
|
48
|
+
#
|
|
49
|
+
# @return [Hash{Symbol => Integer}] interval name to semitones mapping
|
|
50
|
+
#
|
|
51
|
+
# @example
|
|
52
|
+
# intervals[:P5] # => 7 (perfect fifth)
|
|
53
|
+
# intervals[:M3] # => 4 (major third)
|
|
21
54
|
def intervals
|
|
22
55
|
@@intervals
|
|
23
56
|
end
|
|
24
57
|
end
|
|
25
58
|
end
|
|
26
59
|
|
|
60
|
+
# Equal temperament 12-tone scale system.
|
|
61
|
+
#
|
|
62
|
+
# EquallyTempered12ToneScaleSystem implements the standard equal temperament
|
|
63
|
+
# tuning where each semitone has exactly the same frequency ratio: 2^(1/12).
|
|
64
|
+
# This is the most common tuning system in modern Western music.
|
|
65
|
+
#
|
|
66
|
+
# ## Frequency Calculation
|
|
67
|
+
#
|
|
68
|
+
# Uses the equal temperament formula based on A440 concert pitch:
|
|
69
|
+
#
|
|
70
|
+
# frequency = a_frequency × 2^((pitch - 69) / 12)
|
|
71
|
+
#
|
|
72
|
+
# Where:
|
|
73
|
+
#
|
|
74
|
+
# - **a_frequency**: Reference A frequency (typically 440 Hz)
|
|
75
|
+
# - **pitch**: MIDI pitch number (69 = A4)
|
|
76
|
+
#
|
|
77
|
+
# ## Historical Pitch Standards
|
|
78
|
+
#
|
|
79
|
+
# Different A frequencies represent different historical standards:
|
|
80
|
+
#
|
|
81
|
+
# - **440 Hz**: Modern concert pitch (ISO 16)
|
|
82
|
+
# - **442 Hz**: Used by some orchestras (brighter sound)
|
|
83
|
+
# - **415 Hz**: Baroque pitch (approximately A=415)
|
|
84
|
+
# - **432 Hz**: Alternative tuning (some claim harmonic benefits)
|
|
85
|
+
#
|
|
86
|
+
# ## Registration
|
|
87
|
+
#
|
|
88
|
+
# This system is registered as the default scale system, accessible via:
|
|
89
|
+
#
|
|
90
|
+
# Scales[:et12] # By ID
|
|
91
|
+
# Scales.default_system # As default
|
|
92
|
+
#
|
|
93
|
+
# ## Usage
|
|
94
|
+
#
|
|
95
|
+
# # Get system with standard A440 tuning
|
|
96
|
+
# system = Scales[:et12][440.0]
|
|
97
|
+
#
|
|
98
|
+
# # Get system with baroque tuning
|
|
99
|
+
# baroque = Scales[:et12][415.0]
|
|
100
|
+
#
|
|
101
|
+
# # Access scale kinds
|
|
102
|
+
# c_major = system[:major][60]
|
|
103
|
+
# a_minor = system[:minor][69]
|
|
104
|
+
#
|
|
105
|
+
# @see TwelveSemitonesScaleSystem Abstract base class
|
|
106
|
+
# @see ScaleSystem#frequency_of_pitch Abstract method implemented here
|
|
27
107
|
class EquallyTempered12ToneScaleSystem < TwelveSemitonesScaleSystem
|
|
28
108
|
class << self
|
|
109
|
+
# Calculates frequency for a pitch using equal temperament.
|
|
110
|
+
#
|
|
111
|
+
# Implements the equal temperament tuning formula where each semitone
|
|
112
|
+
# has a frequency ratio of 2^(1/12) ≈ 1.059463.
|
|
113
|
+
#
|
|
114
|
+
# @param pitch [Integer] MIDI pitch number
|
|
115
|
+
# @param _root_pitch [Integer] unused (required by interface)
|
|
116
|
+
# @param a_frequency [Numeric] reference A4 frequency in Hz
|
|
117
|
+
# @return [Float] frequency in Hz
|
|
118
|
+
#
|
|
119
|
+
# @example Standard A440 tuning
|
|
120
|
+
# frequency_of_pitch(69, nil, 440.0) # => 440.0 (A4)
|
|
121
|
+
# frequency_of_pitch(60, nil, 440.0) # => 261.63 (C4, middle C)
|
|
122
|
+
#
|
|
123
|
+
# @example Baroque tuning
|
|
124
|
+
# frequency_of_pitch(69, nil, 415.0) # => 415.0 (A4)
|
|
29
125
|
def frequency_of_pitch(pitch, _root_pitch, a_frequency)
|
|
30
126
|
(a_frequency * Rational(2)**Rational(pitch - 69, 12)).to_f
|
|
31
127
|
end
|
|
@@ -35,6 +131,35 @@ module Musa
|
|
|
35
131
|
end
|
|
36
132
|
|
|
37
133
|
|
|
134
|
+
# Chromatic scale kind (all 12 semitones).
|
|
135
|
+
#
|
|
136
|
+
# ChromaticScaleKind defines the chromatic scale containing all 12 semitones
|
|
137
|
+
# of the octave. It's used as a fallback for chromatic (non-diatonic) notes
|
|
138
|
+
# and for atonal or twelve-tone compositions.
|
|
139
|
+
#
|
|
140
|
+
# ## Pitch Structure
|
|
141
|
+
#
|
|
142
|
+
# Contains 12 pitch classes, one for each semitone:
|
|
143
|
+
#
|
|
144
|
+
# - Degrees: _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12
|
|
145
|
+
# - Pitches: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 (semitones from root)
|
|
146
|
+
#
|
|
147
|
+
# ## Special Properties
|
|
148
|
+
#
|
|
149
|
+
# - **chromatic?**: Returns true (only scale kind with this property)
|
|
150
|
+
# - Used automatically when accessing non-diatonic notes in diatonic scales
|
|
151
|
+
#
|
|
152
|
+
# ## Usage
|
|
153
|
+
#
|
|
154
|
+
# chromatic = Scales[:et12][440.0][:chromatic][60]
|
|
155
|
+
# chromatic._1 # C
|
|
156
|
+
# chromatic._2 # C#/Db
|
|
157
|
+
# chromatic._3 # D
|
|
158
|
+
# # ... all 12 semitones
|
|
159
|
+
#
|
|
160
|
+
# @see ScaleKind Abstract base class
|
|
161
|
+
# @see MajorScaleKind Major scale (7 notes)
|
|
162
|
+
# @see MinorNaturalScaleKind Minor scale (7 notes)
|
|
38
163
|
class ChromaticScaleKind < ScaleKind
|
|
39
164
|
class << self
|
|
40
165
|
@@pitches =
|
|
@@ -51,14 +176,20 @@ module Musa
|
|
|
51
176
|
{ functions: [:_11], pitch: 10 },
|
|
52
177
|
{ functions: [:_12], pitch: 11 }].freeze
|
|
53
178
|
|
|
179
|
+
# Pitch structure.
|
|
180
|
+
# @return [Array<Hash>] pitch definitions with functions and offsets
|
|
54
181
|
def pitches
|
|
55
182
|
@@pitches
|
|
56
183
|
end
|
|
57
184
|
|
|
185
|
+
# Scale kind identifier.
|
|
186
|
+
# @return [Symbol] :chromatic
|
|
58
187
|
def id
|
|
59
188
|
:chromatic
|
|
60
189
|
end
|
|
61
190
|
|
|
191
|
+
# Indicates if this is a chromatic scale.
|
|
192
|
+
# @return [Boolean] true
|
|
62
193
|
def chromatic?
|
|
63
194
|
true
|
|
64
195
|
end
|
|
@@ -67,6 +198,52 @@ module Musa
|
|
|
67
198
|
EquallyTempered12ToneScaleSystem.register ChromaticScaleKind
|
|
68
199
|
end
|
|
69
200
|
|
|
201
|
+
# Major scale kind (Ionian mode).
|
|
202
|
+
#
|
|
203
|
+
# MajorScaleKind defines the major scale, the fundamental scale of Western
|
|
204
|
+
# tonal music. It follows the pattern: W-W-H-W-W-W-H (whole-half steps)
|
|
205
|
+
# or intervals: M2-M2-m2-M2-M2-M2-m2 from the root.
|
|
206
|
+
#
|
|
207
|
+
# ## Pitch Structure
|
|
208
|
+
#
|
|
209
|
+
# 7 diatonic degrees plus extended harmony (8th-13th):
|
|
210
|
+
#
|
|
211
|
+
# **Scale Degrees** (Roman numerals, uppercase for major):
|
|
212
|
+
#
|
|
213
|
+
# - **I** (tonic): Root (0 semitones)
|
|
214
|
+
# - **II** (supertonic): Major second (2 semitones)
|
|
215
|
+
# - **III** (mediant): Major third (4 semitones)
|
|
216
|
+
# - **IV** (subdominant): Perfect fourth (5 semitones)
|
|
217
|
+
# - **V** (dominant): Perfect fifth (7 semitones)
|
|
218
|
+
# - **VI** (submediant): Major sixth (9 semitones, relative minor)
|
|
219
|
+
# - **VII** (leading): Major seventh (11 semitones)
|
|
220
|
+
#
|
|
221
|
+
# **Extended degrees** (for extended harmony):
|
|
222
|
+
#
|
|
223
|
+
# - VIII-XIII: Compound intervals (8th, 9th, 10th, 11th, 12th, 13th)
|
|
224
|
+
#
|
|
225
|
+
# ## Function Aliases
|
|
226
|
+
#
|
|
227
|
+
# Each degree has multiple function names:
|
|
228
|
+
#
|
|
229
|
+
# - **Numeric**: _1, _2, _3, _4, _5, _6, _7 (ordinal)
|
|
230
|
+
# - **Roman**: I, II, III, IV, V, VI, VII (harmonic analysis)
|
|
231
|
+
# - **Function**: tonic, supertonic, mediant, subdominant, dominant,
|
|
232
|
+
# submediant, leading
|
|
233
|
+
# - **Ordinal**: first, second, third, fourth, fifth, sixth, seventh
|
|
234
|
+
# - **Special**: relative/relative_minor for VI (relative minor root)
|
|
235
|
+
#
|
|
236
|
+
# ## Usage
|
|
237
|
+
#
|
|
238
|
+
# c_major = Scales[:et12][440.0][:major][60]
|
|
239
|
+
# c_major.tonic # C (60)
|
|
240
|
+
# c_major.dominant # G (67)
|
|
241
|
+
# c_major.VI # A (69) - relative minor root
|
|
242
|
+
# c_major.relative_minor.scale(:minor) # A minor scale
|
|
243
|
+
#
|
|
244
|
+
# @see ScaleKind Abstract base class
|
|
245
|
+
# @see MinorNaturalScaleKind Natural minor scale
|
|
246
|
+
# @see ChromaticScaleKind Chromatic scale
|
|
70
247
|
class MajorScaleKind < ScaleKind
|
|
71
248
|
class << self
|
|
72
249
|
@@pitches =
|
|
@@ -97,14 +274,20 @@ module Musa
|
|
|
97
274
|
{ functions: %i[XIII _13 thirteenth],
|
|
98
275
|
pitch: 12 + 9 }].freeze
|
|
99
276
|
|
|
277
|
+
# Pitch structure.
|
|
278
|
+
# @return [Array<Hash>] pitch definitions with functions and offsets
|
|
100
279
|
def pitches
|
|
101
280
|
@@pitches
|
|
102
281
|
end
|
|
103
282
|
|
|
283
|
+
# Number of diatonic degrees.
|
|
284
|
+
# @return [Integer] 7
|
|
104
285
|
def grades
|
|
105
286
|
7
|
|
106
287
|
end
|
|
107
288
|
|
|
289
|
+
# Scale kind identifier.
|
|
290
|
+
# @return [Symbol] :major
|
|
108
291
|
def id
|
|
109
292
|
:major
|
|
110
293
|
end
|
|
@@ -113,6 +296,65 @@ module Musa
|
|
|
113
296
|
EquallyTempered12ToneScaleSystem.register MajorScaleKind
|
|
114
297
|
end
|
|
115
298
|
|
|
299
|
+
# Natural minor scale kind (Aeolian mode).
|
|
300
|
+
#
|
|
301
|
+
# MinorNaturalScaleKind defines the natural minor scale, parallel to the
|
|
302
|
+
# major scale but with a darker, melancholic character. It follows the
|
|
303
|
+
# pattern: W-H-W-W-H-W-W or intervals: M2-m2-M2-M2-m2-M2-M2 from the root.
|
|
304
|
+
#
|
|
305
|
+
# ## Pitch Structure
|
|
306
|
+
#
|
|
307
|
+
# 7 diatonic degrees plus extended harmony (8th-13th):
|
|
308
|
+
#
|
|
309
|
+
# **Scale Degrees** (Roman numerals, lowercase for minor):
|
|
310
|
+
#
|
|
311
|
+
# - **i** (tonic): Root (0 semitones)
|
|
312
|
+
# - **ii** (supertonic): Major second (2 semitones)
|
|
313
|
+
# - **iii** (mediant): Minor third (3 semitones, relative major)
|
|
314
|
+
# - **iv** (subdominant): Perfect fourth (5 semitones)
|
|
315
|
+
# - **v** (dominant): Perfect fifth (7 semitones)
|
|
316
|
+
# - **vi** (submediant): Minor sixth (8 semitones)
|
|
317
|
+
# - **vii** (subtonic): Minor seventh (10 semitones, NOT leading tone)
|
|
318
|
+
#
|
|
319
|
+
# **Extended degrees**: viii-xiii (compound intervals)
|
|
320
|
+
#
|
|
321
|
+
# ## Differences from Major
|
|
322
|
+
#
|
|
323
|
+
# Compared to major scale (same tonic):
|
|
324
|
+
#
|
|
325
|
+
# - **iii**: Flatted third (minor third instead of major)
|
|
326
|
+
# - **vi**: Flatted sixth (minor sixth instead of major)
|
|
327
|
+
# - **vii**: Flatted seventh (minor seventh instead of major)
|
|
328
|
+
#
|
|
329
|
+
# ## Relative Major
|
|
330
|
+
#
|
|
331
|
+
# The **iii** degree is the root of the relative major scale (shares same
|
|
332
|
+
# notes but different tonic). For example:
|
|
333
|
+
#
|
|
334
|
+
# - A minor (natural) relative major: C major
|
|
335
|
+
# - C major relative minor: A minor
|
|
336
|
+
#
|
|
337
|
+
# ## Function Aliases
|
|
338
|
+
#
|
|
339
|
+
# Similar to major but with lowercase Roman numerals:
|
|
340
|
+
#
|
|
341
|
+
# - **Numeric**: _1, _2, _3, _4, _5, _6, _7
|
|
342
|
+
# - **Roman**: i, ii, iii, iv, v, vi, vii
|
|
343
|
+
# - **Function**: tonic, supertonic, mediant, subdominant, dominant, submediant
|
|
344
|
+
# - **Ordinal**: first, second, third, fourth, fifth, sixth, seventh
|
|
345
|
+
# - **Special**: relative/relative_major for iii
|
|
346
|
+
#
|
|
347
|
+
# ## Usage
|
|
348
|
+
#
|
|
349
|
+
# a_minor = Scales[:et12][440.0][:minor][69]
|
|
350
|
+
# a_minor.tonic # A (69)
|
|
351
|
+
# a_minor.dominant # E (76)
|
|
352
|
+
# a_minor.iii # C (72) - relative major root
|
|
353
|
+
# a_minor.relative_major.scale(:major) # C major scale
|
|
354
|
+
#
|
|
355
|
+
# @see ScaleKind Abstract base class
|
|
356
|
+
# @see MajorScaleKind Major scale
|
|
357
|
+
# @see MinorHarmonicScaleKind Harmonic minor (with raised 7th)
|
|
116
358
|
class MinorNaturalScaleKind < ScaleKind
|
|
117
359
|
class << self
|
|
118
360
|
@@pitches =
|
|
@@ -143,14 +385,20 @@ module Musa
|
|
|
143
385
|
{ functions: %i[xiii _13 thirteenth],
|
|
144
386
|
pitch: 12 + 8 }].freeze
|
|
145
387
|
|
|
388
|
+
# Pitch structure.
|
|
389
|
+
# @return [Array<Hash>] pitch definitions with functions and offsets
|
|
146
390
|
def pitches
|
|
147
391
|
@@pitches
|
|
148
392
|
end
|
|
149
393
|
|
|
394
|
+
# Number of diatonic degrees.
|
|
395
|
+
# @return [Integer] 7
|
|
150
396
|
def grades
|
|
151
397
|
7
|
|
152
398
|
end
|
|
153
399
|
|
|
400
|
+
# Scale kind identifier.
|
|
401
|
+
# @return [Symbol] :minor
|
|
154
402
|
def id
|
|
155
403
|
:minor
|
|
156
404
|
end
|
|
@@ -159,6 +407,67 @@ module Musa
|
|
|
159
407
|
EquallyTempered12ToneScaleSystem.register MinorNaturalScaleKind
|
|
160
408
|
end
|
|
161
409
|
|
|
410
|
+
# Harmonic minor scale kind.
|
|
411
|
+
#
|
|
412
|
+
# MinorHarmonicScaleKind defines the harmonic minor scale, a variation of
|
|
413
|
+
# the natural minor with a raised seventh degree. This creates a leading
|
|
414
|
+
# tone (major seventh) that resolves strongly to the tonic, giving the
|
|
415
|
+
# scale a more directed, dramatic character.
|
|
416
|
+
#
|
|
417
|
+
# ## Pitch Structure
|
|
418
|
+
#
|
|
419
|
+
# 7 diatonic degrees plus extended harmony (8th-13th):
|
|
420
|
+
#
|
|
421
|
+
# **Scale Degrees** (Roman numerals, lowercase for minor):
|
|
422
|
+
#
|
|
423
|
+
# - **i** (tonic): Root (0 semitones)
|
|
424
|
+
# - **ii** (supertonic): Major second (2 semitones)
|
|
425
|
+
# - **iii** (mediant): Minor third (3 semitones, relative major)
|
|
426
|
+
# - **iv** (subdominant): Perfect fourth (5 semitones)
|
|
427
|
+
# - **v** (dominant): Perfect fifth (7 semitones)
|
|
428
|
+
# - **vi** (submediant): Minor sixth (8 semitones)
|
|
429
|
+
# - **vii** (leading): **Major seventh** (11 semitones) ← RAISED from natural minor
|
|
430
|
+
#
|
|
431
|
+
# **Extended degrees**: viii-xiii (compound intervals)
|
|
432
|
+
#
|
|
433
|
+
# ## Key Difference from Natural Minor
|
|
434
|
+
#
|
|
435
|
+
# The **vii** degree is raised from 10 semitones (minor seventh) to
|
|
436
|
+
# 11 semitones (major seventh), creating:
|
|
437
|
+
#
|
|
438
|
+
# - A **leading tone** that resolves strongly upward to the tonic
|
|
439
|
+
# - An **augmented second** interval between vi and vii (3 semitones)
|
|
440
|
+
# - A **dominant seventh chord** (v7) with strong resolution to i
|
|
441
|
+
#
|
|
442
|
+
# ## Musical Character
|
|
443
|
+
#
|
|
444
|
+
# The harmonic minor scale:
|
|
445
|
+
#
|
|
446
|
+
# - Maintains minor quality (minor third)
|
|
447
|
+
# - Provides strong dominant-to-tonic resolution
|
|
448
|
+
# - Creates exotic sound due to augmented second (vi-vii)
|
|
449
|
+
# - Common in classical, jazz, and Middle Eastern music
|
|
450
|
+
#
|
|
451
|
+
# ## Function Aliases
|
|
452
|
+
#
|
|
453
|
+
# Same as natural minor:
|
|
454
|
+
#
|
|
455
|
+
# - **Numeric**: _1, _2, _3, _4, _5, _6, _7
|
|
456
|
+
# - **Roman**: i, ii, iii, iv, v, vi, vii
|
|
457
|
+
# - **Function**: tonic, supertonic, mediant, subdominant, dominant,
|
|
458
|
+
# submediant, leading
|
|
459
|
+
# - **Special**: relative/relative_major for iii
|
|
460
|
+
#
|
|
461
|
+
# ## Usage
|
|
462
|
+
#
|
|
463
|
+
# a_harmonic_minor = Scales[:et12][440.0][:minor_harmonic][69]
|
|
464
|
+
# a_harmonic_minor.vii # G# (80) - raised 7th, not G (79)
|
|
465
|
+
# a_harmonic_minor.vi # F (77)
|
|
466
|
+
# # Augmented second: F to G# = 3 semitones
|
|
467
|
+
#
|
|
468
|
+
# @see ScaleKind Abstract base class
|
|
469
|
+
# @see MinorNaturalScaleKind Natural minor (with minor 7th)
|
|
470
|
+
# @see MajorScaleKind Major scale
|
|
162
471
|
class MinorHarmonicScaleKind < ScaleKind
|
|
163
472
|
class << self
|
|
164
473
|
@@pitches =
|
|
@@ -189,14 +498,20 @@ module Musa
|
|
|
189
498
|
{ functions: %i[xiii _13],
|
|
190
499
|
pitch: 12 + 8 }].freeze
|
|
191
500
|
|
|
501
|
+
# Pitch structure.
|
|
502
|
+
# @return [Array<Hash>] pitch definitions with functions and offsets
|
|
192
503
|
def pitches
|
|
193
504
|
@@pitches
|
|
194
505
|
end
|
|
195
506
|
|
|
507
|
+
# Number of diatonic degrees.
|
|
508
|
+
# @return [Integer] 7
|
|
196
509
|
def grades
|
|
197
510
|
7
|
|
198
511
|
end
|
|
199
512
|
|
|
513
|
+
# Scale kind identifier.
|
|
514
|
+
# @return [Symbol] :minor_harmonic
|
|
200
515
|
def id
|
|
201
516
|
:minor_harmonic
|
|
202
517
|
end
|