Class: Musa::Chords::ChordDefinition

Inherits:
Object
  • Object
show all
Defined in:
lib/musa-dsl/music/chord-definition.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, offsets:, **features) ⇒ ChordDefinition

Returns a new instance of ChordDefinition.



47
48
49
50
51
52
# File 'lib/musa-dsl/music/chord-definition.rb', line 47

def initialize(name, offsets:, **features)
  @name = name
  @features = features.clone.freeze
  @pitch_offsets = offsets.clone.freeze
  @pitch_names = offsets.collect { |k, v| [v, k] }.to_h
end

Instance Attribute Details

#featuresObject (readonly)

Returns the value of attribute features.



54
55
56
# File 'lib/musa-dsl/music/chord-definition.rb', line 54

def features
  @features
end

#nameObject (readonly)

Returns the value of attribute name.



54
55
56
# File 'lib/musa-dsl/music/chord-definition.rb', line 54

def name
  @name
end

#pitch_namesObject (readonly)

Returns the value of attribute pitch_names.



54
55
56
# File 'lib/musa-dsl/music/chord-definition.rb', line 54

def pitch_names
  @pitch_names
end

#pitch_offsetsObject (readonly)

Returns the value of attribute pitch_offsets.



54
55
56
# File 'lib/musa-dsl/music/chord-definition.rb', line 54

def pitch_offsets
  @pitch_offsets
end

Class Method Details

.[](name) ⇒ Object



4
5
6
# File 'lib/musa-dsl/music/chord-definition.rb', line 4

def self.[](name)
  @definitions[name]
end

.feature_key_of(feature_value) ⇒ Object



39
40
41
# File 'lib/musa-dsl/music/chord-definition.rb', line 39

def self.feature_key_of(feature_value)
  @features_by_value[feature_value]
end

.feature_valuesObject



43
44
45
# File 'lib/musa-dsl/music/chord-definition.rb', line 43

def self.feature_values
  @features_by_value.keys
end

.features_from(values = nil, hash = nil) ⇒ Object



24
25
26
27
28
29
30
31
32
# File 'lib/musa-dsl/music/chord-definition.rb', line 24

def self.features_from(values = nil, hash = nil)
  values ||= []
  hash ||= {}

  features = hash.dup
  values.each { |v| features[@features_by_value[v]] = v }

  features
end

.find_by_features(*values, **hash) ⇒ Object



34
35
36
37
# File 'lib/musa-dsl/music/chord-definition.rb', line 34

def self.find_by_features(*values, **hash)
  features = features_from(values, hash)
  @definitions.values.select { |d| features <= d.features }
end

.find_by_pitches(pitches) ⇒ Object



20
21
22
# File 'lib/musa-dsl/music/chord-definition.rb', line 20

def self.find_by_pitches(pitches)
  @definitions.values.find { |d| d.matches(pitches) }
end

.register(name, offsets:, **features) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
# File 'lib/musa-dsl/music/chord-definition.rb', line 8

def self.register(name, offsets:, **features)
  definition = ChordDefinition.new(name, offsets: offsets, **features).freeze

  @definitions ||= {}
  @definitions[definition.name] = definition

  @features_by_value ||= {}
  definition.features.each { |k, v| @features_by_value[v] = k }

  self
end

Instance Method Details

#inspectObject Also known as: to_s



90
91
92
# File 'lib/musa-dsl/music/chord-definition.rb', line 90

def inspect
  "<ChordDefinition: name = #{@name} features = #{@features} pitch_offsets = #{@pitch_offsets}>"
end

#matches(pitches) ⇒ Object



82
83
84
85
86
87
88
# File 'lib/musa-dsl/music/chord-definition.rb', line 82

def matches(pitches)
  reduced_pitches = octave_reduce(pitches).uniq

  !!reduced_pitches.find do |candidate_root_pitch|
    reduced_pitches.sort == octave_reduce(pitches(candidate_root_pitch)).uniq.sort
  end
end

#named_pitches(elements_or_pitches, &block) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/musa-dsl/music/chord-definition.rb', line 60

def named_pitches(elements_or_pitches, &block)
  pitches = elements_or_pitches.collect do |element_or_pitch|
    [if block_given?
       yield element_or_pitch
     else
       element_or_pitch
     end,
     element_or_pitch]
  end.to_h

  root_pitch = pitches.keys.find do |candidate_root_pitch|
    candidate_pitches = pitches.keys.collect { |p| p - candidate_root_pitch }
    octave_reduce(candidate_pitches).uniq == octave_reduce(@pitch_offsets.values).uniq
  end

  # TODO: OJO: problema con las notas duplicadas, con la identificación de inversiones y con las notas a distancias de más de una octava

  pitches.collect do |pitch, element|
    [@pitch_names[pitch - root_pitch], [element]]
  end.to_h
end

#pitches(root_pitch) ⇒ Object



56
57
58
# File 'lib/musa-dsl/music/chord-definition.rb', line 56

def pitches(root_pitch)
  @pitch_offsets.values.collect { |offset| root_pitch + offset }
end