head_music 0.24.0 → 0.24.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -8,6 +8,7 @@ class HeadMusic::ScaleDegree
8
8
  NAME_FOR_DIATONIC_DEGREE = [nil, 'tonic', 'supertonic', 'mediant', 'subdominant', 'dominant', 'submediant'].freeze
9
9
 
10
10
  attr_reader :key_signature, :spelling
11
+
11
12
  delegate :scale, to: :key_signature
12
13
  delegate :scale_type, to: :scale
13
14
 
@@ -28,7 +28,7 @@ class HeadMusic::ScaleType
28
28
  vii: [:locrian],
29
29
  }.freeze
30
30
 
31
- CHROMATIC = [H, H, H, H, H, H, H, H, H, H, H, H].freeze
31
+ CHROMATIC = ([H] * 12)
32
32
 
33
33
  MINOR_PENTATONIC = [3, 2, 2, 3, 2].freeze
34
34
 
@@ -6,22 +6,37 @@ require 'head_music/musical_symbol'
6
6
  class HeadMusic::Sign
7
7
  include Comparable
8
8
 
9
- attr_reader :identifier, :cents, :musical_symbol
9
+ attr_reader :identifier, :cents, :musical_symbols
10
10
 
11
11
  delegate :ascii, :unicode, :html_entity, to: :musical_symbol
12
12
 
13
- SIGN_DATA = [
14
- { identifier: :sharp, ascii: '#', unicode: '♯', html_entity: '♯', cents: 100 },
15
- { identifier: :flat, ascii: 'b', unicode: '♭', html_entity: '♭', cents: -100 },
16
- { identifier: :natural, ascii: '', unicode: '', html_entity: '♮', cents: 0 },
17
- { identifier: :double_sharp, ascii: 'x', unicode: '𝄪', html_entity: '𝄪', cents: 200 },
18
- { identifier: :double_flat, ascii: 'bb', unicode: '𝄫', html_entity: '𝄫', cents: -200 },
13
+ SIGN_RECORDS = [
14
+ {
15
+ identifier: :sharp, cents: 100,
16
+ symbols: [{ ascii: '#', unicode: '', html_entity: '♯' }],
17
+ },
18
+ {
19
+ identifier: :flat, cents: -100,
20
+ symbols: [{ ascii: 'b', unicode: '♭', html_entity: '♭' }],
21
+ },
22
+ {
23
+ identifier: :natural, cents: 0,
24
+ symbols: [{ ascii: '', unicode: '♮', html_entity: '♮' }],
25
+ },
26
+ {
27
+ identifier: :double_sharp, cents: 200,
28
+ symbols: [{ ascii: 'x', unicode: '𝄪', html_entity: '𝄪' }],
29
+ },
30
+ {
31
+ identifier: :double_flat, cents: -200,
32
+ symbols: [{ ascii: 'bb', unicode: '𝄫', html_entity: '𝄫' }],
33
+ },
19
34
  ].freeze
20
35
 
21
- SIGN_IDENTIFIERS = SIGN_DATA.map { |attributes| attributes[:identifier] }.freeze
36
+ SIGN_IDENTIFIERS = SIGN_RECORDS.map { |attributes| attributes[:identifier] }.freeze
22
37
 
23
38
  def self.all
24
- SIGN_DATA.map { |attributes| new(attributes) }
39
+ SIGN_RECORDS.map { |attributes| new(attributes) }
25
40
  end
26
41
 
27
42
  def self.symbols
@@ -76,16 +91,26 @@ class HeadMusic::Sign
76
91
  cents <=> other.cents
77
92
  end
78
93
 
94
+ def musical_symbol
95
+ musical_symbols.first
96
+ end
97
+
79
98
  private
80
99
 
81
100
  def initialize(attributes)
82
101
  @identifier = attributes[:identifier]
83
102
  @cents = attributes[:cents]
84
- @musical_symbol = HeadMusic::MusicalSymbol.new(
85
- unicode: attributes[:unicode],
86
- ascii: attributes[:ascii],
87
- html_entity: attributes[:html_entity]
88
- )
103
+ initialize_musical_symbols(attributes[:symbols])
104
+ end
105
+
106
+ def initialize_musical_symbols(list)
107
+ @musical_symbols = (list || []).map do |record|
108
+ HeadMusic::MusicalSymbol.new(
109
+ unicode: record[:unicode],
110
+ ascii: record[:ascii],
111
+ html_entity: record[:html_entity]
112
+ )
113
+ end
89
114
  end
90
115
 
91
116
  private_class_method :new
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A scale degree is a number indicating the ordinality of the spelling in the key signature.
4
+ # TODO: Rewrite to accept a tonal_center and a scale type.
5
+ class HeadMusic::Solmization
6
+ include HeadMusic::Named
7
+
8
+ DEFAULT_SOLMIZATION = 'solfège'
9
+
10
+ RECORDS = YAML.load_file(File.expand_path('solmizations.yml', __dir__)).freeze
11
+
12
+ attr_reader :syllables
13
+
14
+ def self.get(identifier = nil)
15
+ get_by_name(identifier)
16
+ end
17
+
18
+ private_class_method :new
19
+
20
+ private
21
+
22
+ def initialize(name = nil)
23
+ name = nil if name.empty?
24
+ name ||= DEFAULT_SOLMIZATION
25
+ record = record_for_name(name)
26
+ if record
27
+ initialize_data_from_record(record)
28
+ else
29
+ self.name = name
30
+ end
31
+ end
32
+
33
+ def record_for_name(name)
34
+ key = HeadMusic::Utilities::HashKey.for(name)
35
+ RECORDS.detect do |record|
36
+ name_strings = record[:localized_names].map { |localized_name| localized_name[:name] }
37
+ name_keys = name_strings.map { |name_string| HeadMusic::Utilities::HashKey.for(name_string) }
38
+ name_keys.include?(key)
39
+ end
40
+ end
41
+
42
+ def initialize_data_from_record(record)
43
+ @syllables = record[:syllables]
44
+ initialize_localized_names(record[:localized_names])
45
+ end
46
+
47
+ def initialize_localized_names(list)
48
+ @localized_names = (list || []).map do |name_attributes|
49
+ HeadMusic::Named::LocalizedName.new(name_attributes.slice(:name, :locale_code, :abbreviation))
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,20 @@
1
+ ---
2
+ - :syllables:
3
+ - do
4
+ - re
5
+ - mi
6
+ - fa
7
+ - sol
8
+ - la
9
+ - ti
10
+ :localized_names:
11
+ - :name: solfège
12
+ - :name: solfège
13
+ :locale_code: en
14
+ - :name: solfège
15
+ :locale_code: fr
16
+ - :name: solfeggio
17
+ :locale_code: it
18
+ - :name: sol-fa
19
+ - :name: solfa
20
+ - :name: solfeo
@@ -4,7 +4,7 @@
4
4
  # Composite of a LetterName and an optional Sign.
5
5
  # Does not include the octave. See Pitch for that.
6
6
  class HeadMusic::Spelling
7
- MATCHER = /^\s*([A-G])(#{HeadMusic::Sign.matcher}?)(\-?\d+)?\s*$/i.freeze
7
+ MATCHER = /^\s*([A-G])(#{HeadMusic::Sign.matcher}?)(-?\d+)?\s*$/i.freeze
8
8
 
9
9
  attr_reader :pitch_class
10
10
  attr_reader :letter_name
@@ -6,6 +6,6 @@ module HeadMusic::Utilities; end
6
6
  # Util for converting an object to a consistent hash key
7
7
  module HeadMusic::Utilities::HashKey
8
8
  def self.for(identifier)
9
- identifier.to_s.downcase.gsub(/\W+/, '_').to_sym
9
+ I18n.transliterate(identifier.to_s).downcase.gsub(/\W+/, '_').to_sym
10
10
  end
11
11
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HeadMusic
4
- VERSION = '0.24.0'
4
+ VERSION = '0.24.5'
5
5
  end
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: head_music
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.24.0
4
+ version: 0.24.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob Head
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-28 00:00:00.000000000 Z
11
+ date: 2020-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '5.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '5.0'
27
27
  - !ruby/object:Gem::Dependency
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: i18n
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.8'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.8'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -131,6 +145,8 @@ files:
131
145
  - lib/head_music/content/position.rb
132
146
  - lib/head_music/content/rhythmic_value.rb
133
147
  - lib/head_music/content/voice.rb
148
+ - lib/head_music/data/clefs.yml
149
+ - lib/head_music/data/instruments.yml
134
150
  - lib/head_music/diatonic_interval.rb
135
151
  - lib/head_music/grand_staff.rb
136
152
  - lib/head_music/harmonic_interval.rb
@@ -138,6 +154,12 @@ files:
138
154
  - lib/head_music/interval_cycle.rb
139
155
  - lib/head_music/key_signature.rb
140
156
  - lib/head_music/letter_name.rb
157
+ - lib/head_music/locales/de.yml
158
+ - lib/head_music/locales/en.yml
159
+ - lib/head_music/locales/en_GB.yml
160
+ - lib/head_music/locales/es.yml
161
+ - lib/head_music/locales/fr.yml
162
+ - lib/head_music/locales/it.yml
141
163
  - lib/head_music/melodic_interval.rb
142
164
  - lib/head_music/meter.rb
143
165
  - lib/head_music/motion.rb
@@ -158,6 +180,8 @@ files:
158
180
  - lib/head_music/scale_degree.rb
159
181
  - lib/head_music/scale_type.rb
160
182
  - lib/head_music/sign.rb
183
+ - lib/head_music/solmization.rb
184
+ - lib/head_music/solmizations.yml
161
185
  - lib/head_music/sonority.rb
162
186
  - lib/head_music/spelling.rb
163
187
  - lib/head_music/staff.rb
@@ -216,7 +240,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
216
240
  requirements:
217
241
  - - ">="
218
242
  - !ruby/object:Gem::Version
219
- version: 2.4.0
243
+ version: '2.5'
220
244
  required_rubygems_version: !ruby/object:Gem::Requirement
221
245
  requirements:
222
246
  - - ">="