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
|
@@ -1,12 +1,145 @@
|
|
|
1
1
|
require 'set'
|
|
2
2
|
|
|
3
3
|
module Musa
|
|
4
|
+
# Chord construction and manipulation framework.
|
|
5
|
+
#
|
|
6
|
+
# The Chords module provides a comprehensive system for defining, creating, and
|
|
7
|
+
# manipulating musical chords. It supports standard chord types (triads, sevenths,
|
|
8
|
+
# ninths, etc.) with various qualities (major, minor, diminished, augmented, dominant).
|
|
9
|
+
#
|
|
10
|
+
# ## Architecture
|
|
11
|
+
#
|
|
12
|
+
# - **ChordDefinition**: Template defining chord structure (intervals and features)
|
|
13
|
+
# - **Chord**: Actual chord instance with specific root and scale context
|
|
14
|
+
#
|
|
15
|
+
# ## Basic Usage
|
|
16
|
+
#
|
|
17
|
+
# # Create chord from scale note
|
|
18
|
+
# scale = Scales::Scales.default_system.default_tuning.major[60]
|
|
19
|
+
# chord = scale.tonic.chord # C major triad
|
|
20
|
+
# chord = scale.tonic.chord :triad # Explicitly specify size
|
|
21
|
+
#
|
|
22
|
+
# ## Features
|
|
23
|
+
#
|
|
24
|
+
# Chords are defined by features:
|
|
25
|
+
#
|
|
26
|
+
# - **quality**: :major, :minor, :diminished, :augmented, :dominant
|
|
27
|
+
# - **size**: :triad, :seventh, :ninth, :eleventh, :thirteenth
|
|
28
|
+
#
|
|
29
|
+
# # Registered chord definitions.
|
|
30
|
+
#
|
|
31
|
+
# ## Triads
|
|
32
|
+
#
|
|
33
|
+
# Basic three-note chords:
|
|
34
|
+
#
|
|
35
|
+
# - **:maj** - Major triad (1-3-5): root, major third, perfect fifth
|
|
36
|
+
# - **:min** - Minor triad (1-♭3-5): root, minor third, perfect fifth
|
|
37
|
+
# - **:dim** - Diminished triad (1-♭3-♭5): root, minor third, diminished fifth
|
|
38
|
+
# - **:aug** - Augmented triad (1-3-♯5): root, major third, augmented fifth
|
|
39
|
+
#
|
|
40
|
+
# ## Seventh Chords
|
|
41
|
+
#
|
|
42
|
+
# Four-note chords with added seventh:
|
|
43
|
+
#
|
|
44
|
+
# - **:maj7** - Major seventh (1-3-5-7): major triad + major seventh
|
|
45
|
+
# - **:min7** - Minor seventh (1-♭3-5-♭7): minor triad + minor seventh
|
|
46
|
+
# - **:dom7** - Dominant seventh (1-3-5-♭7): major triad + minor seventh
|
|
47
|
+
#
|
|
48
|
+
# ## Extended Chords
|
|
49
|
+
#
|
|
50
|
+
# Chords with ninths, elevenths, and thirteenths:
|
|
51
|
+
#
|
|
52
|
+
# - **:maj9, :min9, :dom9** - Ninth chords
|
|
53
|
+
# - **:maj11, :min11** - Eleventh chords
|
|
54
|
+
# - **:maj13, :min13** - Thirteenth chords
|
|
55
|
+
#
|
|
56
|
+
# @see ChordDefinition Chord template/definition
|
|
57
|
+
# @see Chord Instantiated chord
|
|
4
58
|
module Chords
|
|
59
|
+
# Chord template defining structure and features.
|
|
60
|
+
#
|
|
61
|
+
# ChordDefinition is a template that specifies the intervals and characteristics
|
|
62
|
+
# of a chord type. It's defined once and used to create many chord instances.
|
|
63
|
+
#
|
|
64
|
+
# ## Components
|
|
65
|
+
#
|
|
66
|
+
# - **Name**: Unique identifier (:maj, :min, :dom7, etc.)
|
|
67
|
+
# - **Offsets**: Semitone intervals from root ({ root: 0, third: 4, fifth: 7 })
|
|
68
|
+
# - **Features**: Characteristics (quality: :major, size: :triad)
|
|
69
|
+
#
|
|
70
|
+
# ## Registration
|
|
71
|
+
#
|
|
72
|
+
# Chord definitions are registered globally:
|
|
73
|
+
#
|
|
74
|
+
# ChordDefinition.register :maj,
|
|
75
|
+
# quality: :major,
|
|
76
|
+
# size: :triad,
|
|
77
|
+
# offsets: { root: 0, third: 4, fifth: 7 }
|
|
78
|
+
#
|
|
79
|
+
# ## Finding Definitions
|
|
80
|
+
#
|
|
81
|
+
# **By name**:
|
|
82
|
+
#
|
|
83
|
+
# ChordDefinition[:maj] # => <ChordDefinition :maj>
|
|
84
|
+
#
|
|
85
|
+
# **By features**:
|
|
86
|
+
#
|
|
87
|
+
# ChordDefinition.find_by_features(quality: :major, size: :triad)
|
|
88
|
+
# # => [<ChordDefinition :maj>]
|
|
89
|
+
#
|
|
90
|
+
# **By pitches**:
|
|
91
|
+
#
|
|
92
|
+
# ChordDefinition.find_by_pitches([60, 64, 67]) # C E G
|
|
93
|
+
# # => <ChordDefinition :maj>
|
|
94
|
+
#
|
|
95
|
+
# @example Defining a major triad
|
|
96
|
+
# ChordDefinition.register :maj,
|
|
97
|
+
# quality: :major,
|
|
98
|
+
# size: :triad,
|
|
99
|
+
# offsets: { root: 0, third: 4, fifth: 7 }
|
|
100
|
+
#
|
|
101
|
+
# @example Defining a dominant seventh
|
|
102
|
+
# ChordDefinition.register :dom7,
|
|
103
|
+
# quality: :dominant,
|
|
104
|
+
# size: :seventh,
|
|
105
|
+
# offsets: { root: 0, third: 4, fifth: 7, seventh: 10 }
|
|
106
|
+
#
|
|
107
|
+
# @see Chord Instantiated chord using this definition
|
|
108
|
+
# @see chord-definitions.rb Standard chord definitions
|
|
5
109
|
class ChordDefinition
|
|
110
|
+
# Retrieves a registered chord definition by name.
|
|
111
|
+
#
|
|
112
|
+
# @param name [Symbol] chord definition name
|
|
113
|
+
# @return [ChordDefinition, nil] definition or nil if not found
|
|
114
|
+
#
|
|
115
|
+
# @example
|
|
116
|
+
# ChordDefinition[:maj] # => <ChordDefinition :maj>
|
|
117
|
+
# ChordDefinition[:min7] # => <ChordDefinition :min7>
|
|
6
118
|
def self.[](name)
|
|
7
119
|
@definitions[name]
|
|
8
120
|
end
|
|
9
121
|
|
|
122
|
+
# Registers a new chord definition.
|
|
123
|
+
#
|
|
124
|
+
# Creates and registers a chord definition with specified intervals and features.
|
|
125
|
+
# The definition becomes available globally for chord creation.
|
|
126
|
+
#
|
|
127
|
+
# @param name [Symbol] unique chord identifier
|
|
128
|
+
# @param offsets [Hash{Symbol => Integer}] semitone intervals from root
|
|
129
|
+
# @param features [Hash] chord characteristics (quality, size, etc.)
|
|
130
|
+
# @return [self]
|
|
131
|
+
#
|
|
132
|
+
# @example Major triad
|
|
133
|
+
# ChordDefinition.register :maj,
|
|
134
|
+
# quality: :major,
|
|
135
|
+
# size: :triad,
|
|
136
|
+
# offsets: { root: 0, third: 4, fifth: 7 }
|
|
137
|
+
#
|
|
138
|
+
# @example Minor seventh
|
|
139
|
+
# ChordDefinition.register :min7,
|
|
140
|
+
# quality: :minor,
|
|
141
|
+
# size: :seventh,
|
|
142
|
+
# offsets: { root: 0, third: 3, fifth: 7, seventh: 11 }
|
|
10
143
|
def self.register(name, offsets:, **features)
|
|
11
144
|
definition = ChordDefinition.new(name, offsets: offsets, **features)
|
|
12
145
|
|
|
@@ -22,10 +155,28 @@ module Musa
|
|
|
22
155
|
self
|
|
23
156
|
end
|
|
24
157
|
|
|
158
|
+
# Finds chord definition matching a set of pitches.
|
|
159
|
+
#
|
|
160
|
+
# Identifies chord by comparing pitch intervals, accounting for octave reduction.
|
|
161
|
+
#
|
|
162
|
+
# @param pitches [Array<Integer>] MIDI pitch numbers
|
|
163
|
+
# @return [ChordDefinition, nil] matching definition or nil
|
|
164
|
+
#
|
|
165
|
+
# @example
|
|
166
|
+
# ChordDefinition.find_by_pitches([60, 64, 67]) # => :maj
|
|
25
167
|
def self.find_by_pitches(pitches)
|
|
26
168
|
@definitions.values.find { |d| d.matches(pitches) }
|
|
27
169
|
end
|
|
28
170
|
|
|
171
|
+
# Converts feature values to feature hash.
|
|
172
|
+
#
|
|
173
|
+
# @param values [Array<Symbol>] feature values
|
|
174
|
+
# @param hash [Hash] feature key-value pairs
|
|
175
|
+
# @return [Hash] combined features
|
|
176
|
+
#
|
|
177
|
+
# @example
|
|
178
|
+
# features_from([:major, :triad])
|
|
179
|
+
# # => { quality: :major, size: :triad }
|
|
29
180
|
def self.features_from(values = nil, hash = nil)
|
|
30
181
|
values ||= []
|
|
31
182
|
hash ||= {}
|
|
@@ -36,23 +187,49 @@ module Musa
|
|
|
36
187
|
features
|
|
37
188
|
end
|
|
38
189
|
|
|
190
|
+
# Finds definitions matching specified features.
|
|
191
|
+
#
|
|
192
|
+
# @param values [Array<Symbol>] feature values
|
|
193
|
+
# @param hash [Hash] feature key-value pairs
|
|
194
|
+
# @return [Array<ChordDefinition>] matching definitions
|
|
195
|
+
#
|
|
196
|
+
# @example
|
|
197
|
+
# find_by_features(quality: :major, size: :triad)
|
|
198
|
+
# # => [<ChordDefinition :maj>]
|
|
39
199
|
def self.find_by_features(*values, **hash)
|
|
40
200
|
features = features_from(values, hash)
|
|
41
201
|
@definitions.values.select { |d| features <= d.features }
|
|
42
202
|
end
|
|
43
203
|
|
|
204
|
+
# Returns feature key for a feature value.
|
|
205
|
+
#
|
|
206
|
+
# @param feature_value [Symbol] feature value
|
|
207
|
+
# @return [Symbol] feature key
|
|
44
208
|
def self.feature_key_of(feature_value)
|
|
45
209
|
@features_by_value[feature_value]
|
|
46
210
|
end
|
|
47
211
|
|
|
212
|
+
# Returns all registered feature values.
|
|
213
|
+
#
|
|
214
|
+
# @return [Array<Symbol>] feature values
|
|
48
215
|
def self.feature_values
|
|
49
216
|
@features_by_value.keys
|
|
50
217
|
end
|
|
51
218
|
|
|
219
|
+
# Returns all registered feature keys.
|
|
220
|
+
#
|
|
221
|
+
# @return [Set<Symbol>] feature keys
|
|
52
222
|
def self.feature_keys
|
|
53
223
|
@feature_keys
|
|
54
224
|
end
|
|
55
225
|
|
|
226
|
+
# Creates a chord definition.
|
|
227
|
+
#
|
|
228
|
+
# @param name [Symbol] chord name
|
|
229
|
+
# @param offsets [Hash{Symbol => Integer}] semitone offsets
|
|
230
|
+
# @param features [Hash] chord features
|
|
231
|
+
#
|
|
232
|
+
# @api private
|
|
56
233
|
def initialize(name, offsets:, **features)
|
|
57
234
|
@name = name.freeze
|
|
58
235
|
@features = features.transform_values(&:dup).transform_values(&:freeze).freeze
|
|
@@ -61,16 +238,52 @@ module Musa
|
|
|
61
238
|
freeze
|
|
62
239
|
end
|
|
63
240
|
|
|
64
|
-
|
|
241
|
+
# Chord name.
|
|
242
|
+
# @return [Symbol]
|
|
243
|
+
attr_reader :name
|
|
65
244
|
|
|
245
|
+
# Chord features (quality, size, etc.).
|
|
246
|
+
# @return [Hash{Symbol => Symbol}]
|
|
247
|
+
attr_reader :features
|
|
248
|
+
|
|
249
|
+
# Semitone offsets by position name.
|
|
250
|
+
# @return [Hash{Symbol => Integer}]
|
|
251
|
+
attr_reader :pitch_offsets
|
|
252
|
+
|
|
253
|
+
# Position names by semitone offset.
|
|
254
|
+
# @return [Hash{Integer => Symbol}]
|
|
255
|
+
attr_reader :pitch_names
|
|
256
|
+
|
|
257
|
+
# Calculates chord pitches from root pitch.
|
|
258
|
+
#
|
|
259
|
+
# @param root_pitch [Integer] MIDI root pitch
|
|
260
|
+
# @return [Array<Integer>] chord pitches
|
|
261
|
+
#
|
|
262
|
+
# @example
|
|
263
|
+
# chord_def.pitches(60) # => [60, 64, 67] for C major
|
|
66
264
|
def pitches(root_pitch)
|
|
67
265
|
@pitch_offsets.values.collect { |offset| root_pitch + offset }
|
|
68
266
|
end
|
|
69
267
|
|
|
268
|
+
# Checks if chord fits within a scale.
|
|
269
|
+
#
|
|
270
|
+
# @param scale [Scale] scale to check against
|
|
271
|
+
# @param chord_root_pitch [Integer] chord root pitch
|
|
272
|
+
# @return [Boolean] true if all chord notes are in scale
|
|
273
|
+
#
|
|
274
|
+
# @example
|
|
275
|
+
# maj_def.in_scale?(c_major, chord_root_pitch: 60) # => true
|
|
70
276
|
def in_scale?(scale, chord_root_pitch:)
|
|
71
277
|
!pitches(chord_root_pitch).find { |chord_pitch| scale.note_of_pitch(chord_pitch).nil? }
|
|
72
278
|
end
|
|
73
279
|
|
|
280
|
+
# Maps elements to named chord positions.
|
|
281
|
+
#
|
|
282
|
+
# @param elements_or_pitches [Array] elements to map
|
|
283
|
+
# @yield [element] block to extract pitch from element
|
|
284
|
+
# @return [Hash{Symbol => Array}] position names to elements
|
|
285
|
+
#
|
|
286
|
+
# @api private
|
|
74
287
|
def named_pitches(elements_or_pitches, &block)
|
|
75
288
|
pitches = elements_or_pitches.collect do |element_or_pitch|
|
|
76
289
|
[if block_given?
|
|
@@ -93,6 +306,16 @@ module Musa
|
|
|
93
306
|
end.to_h
|
|
94
307
|
end
|
|
95
308
|
|
|
309
|
+
# Checks if pitches match this chord definition.
|
|
310
|
+
#
|
|
311
|
+
# Compares octave-reduced pitch sets to determine if they form this chord.
|
|
312
|
+
#
|
|
313
|
+
# @param pitches [Array<Integer>] MIDI pitches to check
|
|
314
|
+
# @return [Boolean] true if pitches match this chord
|
|
315
|
+
#
|
|
316
|
+
# @example
|
|
317
|
+
# maj_def.matches([60, 64, 67]) # => true (C major)
|
|
318
|
+
# maj_def.matches([60, 63, 67]) # => false (C minor)
|
|
96
319
|
def matches(pitches)
|
|
97
320
|
reduced_pitches = octave_reduce(pitches).uniq
|
|
98
321
|
|
|
@@ -101,6 +324,9 @@ module Musa
|
|
|
101
324
|
end
|
|
102
325
|
end
|
|
103
326
|
|
|
327
|
+
# Returns string representation.
|
|
328
|
+
#
|
|
329
|
+
# @return [String]
|
|
104
330
|
def inspect
|
|
105
331
|
"<ChordDefinition: name = #{@name} features = #{@features} pitch_offsets = #{@pitch_offsets}>"
|
|
106
332
|
end
|
|
@@ -109,6 +335,12 @@ module Musa
|
|
|
109
335
|
|
|
110
336
|
private
|
|
111
337
|
|
|
338
|
+
# Reduces pitches to within one octave (0-11).
|
|
339
|
+
#
|
|
340
|
+
# @param pitches [Array<Integer>] MIDI pitches
|
|
341
|
+
# @return [Array<Integer>] octave-reduced pitches
|
|
342
|
+
#
|
|
343
|
+
# @api private
|
|
112
344
|
def octave_reduce(pitches)
|
|
113
345
|
pitches.collect { |p| p % 12 }
|
|
114
346
|
end
|
|
@@ -2,22 +2,49 @@ require_relative 'chord-definition'
|
|
|
2
2
|
|
|
3
3
|
# TODO trasladar los acordes de https://en.wikipedia.org/wiki/Chord_notation
|
|
4
4
|
|
|
5
|
+
# TRIADS
|
|
6
|
+
# Major triad: C-E-G (0-4-7 semitones)
|
|
5
7
|
Musa::Chords::ChordDefinition.register :maj, quality: :major, size: :triad, offsets: { root: 0, third: 4, fifth: 7 }
|
|
8
|
+
|
|
9
|
+
# Minor triad: C-Eb-G (0-3-7 semitones)
|
|
6
10
|
Musa::Chords::ChordDefinition.register :min, quality: :minor, size: :triad, offsets: { root: 0, third: 3, fifth: 7 }
|
|
7
|
-
|
|
11
|
+
|
|
12
|
+
# Diminished triad: C-Eb-Gb (0-3-6 semitones)
|
|
13
|
+
Musa::Chords::ChordDefinition.register :dim, quality: :diminished, size: :triad, offsets: { root: 0, third: 3, fifth: 6 }
|
|
14
|
+
|
|
15
|
+
# Augmented triad: C-E-G# (0-4-8 semitones)
|
|
8
16
|
Musa::Chords::ChordDefinition.register :aug, quality: :augmented, size: :triad, offsets: { root: 0, third: 4, fifth: 8 }
|
|
9
17
|
|
|
18
|
+
# SEVENTH CHORDS
|
|
19
|
+
# Major seventh: C-E-G-B (0-4-7-11 semitones)
|
|
10
20
|
Musa::Chords::ChordDefinition.register :maj7, quality: :major, size: :seventh, offsets: { root: 0, third: 4, fifth: 7, seventh: 11 }
|
|
11
|
-
Musa::Chords::ChordDefinition.register :min7, quality: :minor, size: :seventh, offsets: { root: 0, third: 3, fifth: 7, seventh: 11 }
|
|
12
21
|
|
|
22
|
+
# Minor seventh: C-Eb-G-Bb (0-3-7-10 semitones)
|
|
23
|
+
Musa::Chords::ChordDefinition.register :min7, quality: :minor, size: :seventh, offsets: { root: 0, third: 3, fifth: 7, seventh: 10 }
|
|
24
|
+
|
|
25
|
+
# Dominant seventh: C-E-G-Bb (0-4-7-10 semitones)
|
|
13
26
|
Musa::Chords::ChordDefinition.register :dom7, quality: :dominant, size: :seventh, offsets: { root: 0, third: 4, fifth: 7, seventh: 10 }
|
|
14
27
|
|
|
28
|
+
# NINTH CHORDS
|
|
29
|
+
# Major ninth: C-E-G-B-D (0-4-7-11-14 semitones)
|
|
15
30
|
Musa::Chords::ChordDefinition.register :maj9, quality: :major, size: :ninth, offsets: { root: 0, third: 4, fifth: 7, seventh: 11, ninth: 14 }
|
|
16
|
-
|
|
31
|
+
|
|
32
|
+
# Minor ninth: C-Eb-G-Bb-D (0-3-7-10-14 semitones) - NOTE: Changed seventh from 11 to 10
|
|
33
|
+
Musa::Chords::ChordDefinition.register :min9, quality: :minor, size: :ninth, offsets: { root: 0, third: 3, fifth: 7, seventh: 10, ninth: 14 }
|
|
34
|
+
|
|
35
|
+
# Dominant ninth: C-E-G-Bb-D (0-4-7-10-14 semitones)
|
|
17
36
|
Musa::Chords::ChordDefinition.register :dom9, quality: :dominant, size: :ninth, offsets: { root: 0, third: 4, fifth: 7, seventh: 10, ninth: 14 }
|
|
18
37
|
|
|
38
|
+
# ELEVENTH CHORDS
|
|
39
|
+
# Major eleventh: C-E-G-B-D-F (0-4-7-11-14-17 semitones)
|
|
19
40
|
Musa::Chords::ChordDefinition.register :maj11, quality: :major, size: :eleventh, offsets: { root: 0, third: 4, fifth: 7, seventh: 11, ninth: 14, eleventh: 17 }
|
|
20
|
-
Musa::Chords::ChordDefinition.register :min11, quality: :minor, size: :eleventh, offsets: { root: 0, third: 3, fifth: 7, seventh: 11, ninth: 14, eleventh: 17 }
|
|
21
41
|
|
|
22
|
-
|
|
23
|
-
Musa::Chords::ChordDefinition.register :
|
|
42
|
+
# Minor eleventh: C-Eb-G-Bb-D-F (0-3-7-10-14-17 semitones) - NOTE: Changed seventh from 11 to 10
|
|
43
|
+
Musa::Chords::ChordDefinition.register :min11, quality: :minor, size: :eleventh, offsets: { root: 0, third: 3, fifth: 7, seventh: 10, ninth: 14, eleventh: 17 }
|
|
44
|
+
|
|
45
|
+
# THIRTEENTH CHORDS
|
|
46
|
+
# Major thirteenth: C-E-G-B-D-F-A (0-4-7-11-14-17-21 semitones)
|
|
47
|
+
Musa::Chords::ChordDefinition.register :maj13, quality: :major, size: :thirteenth, offsets: { root: 0, third: 4, fifth: 7, seventh: 11, ninth: 14, eleventh: 17, thirteenth: 21 }
|
|
48
|
+
|
|
49
|
+
# Minor thirteenth: C-Eb-G-Bb-D-F-A (0-3-7-10-14-17-21 semitones) - NOTE: Changed seventh from 11 to 10
|
|
50
|
+
Musa::Chords::ChordDefinition.register :min13, quality: :minor, size: :thirteenth, offsets: { root: 0, third: 3, fifth: 7, seventh: 10, ninth: 14, eleventh: 17, thirteenth: 21 }
|