musa-dsl 0.30.2 → 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.
- checksums.yaml +4 -4
- data/.gitignore +5 -1
- data/.version +6 -0
- data/.yardopts +7 -0
- data/Gemfile +0 -1
- 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 +544 -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 +215 -1
- data/lib/musa-dsl/generative/generative-grammar.rb +387 -0
- data/lib/musa-dsl/generative/markov.rb +135 -3
- data/lib/musa-dsl/generative/rules.rb +312 -4
- data/lib/musa-dsl/generative/variatio.rb +286 -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 +113 -2
- data/lib/musa-dsl/midi/midi-voices.rb +275 -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 +353 -2
- data/lib/musa-dsl/music/equally-tempered-12-tone-scale-system.rb +70 -206
- data/lib/musa-dsl/music/scale_kinds/bebop/bebop_dominant_scale_kind.rb +110 -0
- data/lib/musa-dsl/music/scale_kinds/bebop/bebop_major_scale_kind.rb +110 -0
- data/lib/musa-dsl/music/scale_kinds/bebop/bebop_minor_scale_kind.rb +110 -0
- data/lib/musa-dsl/music/scale_kinds/blues/blues_major_scale_kind.rb +100 -0
- data/lib/musa-dsl/music/scale_kinds/blues/blues_scale_kind.rb +99 -0
- data/lib/musa-dsl/music/scale_kinds/chromatic_scale_kind.rb +79 -0
- data/lib/musa-dsl/music/scale_kinds/ethnic/double_harmonic_scale_kind.rb +102 -0
- data/lib/musa-dsl/music/scale_kinds/ethnic/hungarian_minor_scale_kind.rb +102 -0
- data/lib/musa-dsl/music/scale_kinds/ethnic/neapolitan_major_scale_kind.rb +102 -0
- data/lib/musa-dsl/music/scale_kinds/ethnic/neapolitan_minor_scale_kind.rb +101 -0
- data/lib/musa-dsl/music/scale_kinds/ethnic/phrygian_dominant_scale_kind.rb +103 -0
- data/lib/musa-dsl/music/scale_kinds/harmonic_major/harmonic_major_scale_kind.rb +104 -0
- data/lib/musa-dsl/music/scale_kinds/major_scale_kind.rb +110 -0
- data/lib/musa-dsl/music/scale_kinds/melodic_minor/altered_scale_kind.rb +106 -0
- data/lib/musa-dsl/music/scale_kinds/melodic_minor/dorian_b2_scale_kind.rb +104 -0
- data/lib/musa-dsl/music/scale_kinds/melodic_minor/locrian_sharp2_scale_kind.rb +103 -0
- data/lib/musa-dsl/music/scale_kinds/melodic_minor/lydian_augmented_scale_kind.rb +103 -0
- data/lib/musa-dsl/music/scale_kinds/melodic_minor/lydian_dominant_scale_kind.rb +106 -0
- data/lib/musa-dsl/music/scale_kinds/melodic_minor/melodic_minor_scale_kind.rb +104 -0
- data/lib/musa-dsl/music/scale_kinds/melodic_minor/mixolydian_b6_scale_kind.rb +103 -0
- data/lib/musa-dsl/music/scale_kinds/minor_harmonic_scale_kind.rb +125 -0
- data/lib/musa-dsl/music/scale_kinds/minor_natural_scale_kind.rb +123 -0
- data/lib/musa-dsl/music/scale_kinds/modes/dorian_scale_kind.rb +111 -0
- data/lib/musa-dsl/music/scale_kinds/modes/locrian_scale_kind.rb +114 -0
- data/lib/musa-dsl/music/scale_kinds/modes/lydian_scale_kind.rb +111 -0
- data/lib/musa-dsl/music/scale_kinds/modes/mixolydian_scale_kind.rb +111 -0
- data/lib/musa-dsl/music/scale_kinds/modes/phrygian_scale_kind.rb +111 -0
- data/lib/musa-dsl/music/scale_kinds/pentatonic/pentatonic_major_scale_kind.rb +93 -0
- data/lib/musa-dsl/music/scale_kinds/pentatonic/pentatonic_minor_scale_kind.rb +99 -0
- data/lib/musa-dsl/music/scale_kinds/symmetric/diminished_hw_scale_kind.rb +110 -0
- data/lib/musa-dsl/music/scale_kinds/symmetric/diminished_wh_scale_kind.rb +110 -0
- data/lib/musa-dsl/music/scale_kinds/symmetric/whole_tone_scale_kind.rb +99 -0
- data/lib/musa-dsl/music/scale_systems/equally_tempered_12_tone_scale_system.rb +80 -0
- data/lib/musa-dsl/music/scale_systems/twelve_semitones_scale_system.rb +60 -0
- data/lib/musa-dsl/music/scales.rb +1384 -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 +54 -0
- data/lib/musa-dsl/series/hash-or-array-serie-splitter.rb +64 -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 +57 -7
- data/lib/musa-dsl/series/queue-serie.rb +78 -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 +2 -1
- data/lib/musa-dsl.rb +132 -25
- data/musa-dsl.gemspec +25 -18
- metadata +158 -16
|
@@ -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
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Musa
|
|
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
|
|
25
|
+
class TwelveSemitonesScaleSystem < ScaleSystem
|
|
26
|
+
class << self
|
|
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 }
|
|
28
|
+
|
|
29
|
+
# System identifier.
|
|
30
|
+
# @return [Symbol] :et12
|
|
31
|
+
def id
|
|
32
|
+
:et12
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Number of distinct notes per octave.
|
|
36
|
+
# @return [Integer] 12
|
|
37
|
+
def notes_in_octave
|
|
38
|
+
12
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Size of smallest pitch division.
|
|
42
|
+
# @return [Integer] 1 (semitone)
|
|
43
|
+
def part_of_tone_size
|
|
44
|
+
1
|
|
45
|
+
end
|
|
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)
|
|
54
|
+
def intervals
|
|
55
|
+
@@intervals
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|