head_music 0.5.3 → 0.5.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 326a9d839392519ee341ca47ec34eb63ea461bd1
4
- data.tar.gz: 95dbb21634187c2ba6764829ce37e16759347d39
3
+ metadata.gz: 26fa77af760e9919b585bfb9db2e53d30b382ecf
4
+ data.tar.gz: 244d2c9e9d85800cfc0f897773e17d4a1410c885
5
5
  SHA512:
6
- metadata.gz: d7b40960fcf36045cfd9d512e27d41024fc2a1a37c10cbcffa1c89c125ac2fd3fba06108b457f6ae99c612bc956c23763636999239c05250c0842314be75fb11
7
- data.tar.gz: 6a7971653dad527be88f1321e9e3cab80b4855e8a460a82f885fd17d96a78fe1bb98e0b3fd21bfe2b6f49529bda891fadce86979dcf9669da5657ad82c51d5eb
6
+ metadata.gz: 89befc698de10095285b790246b6102bcd6d1ca94c3cf50ea19ee39c9f60e00de277c954172a652e7af1209d3660d33e8d002111aa1c4a426e3be82a574d683e
7
+ data.tar.gz: 71e3d3c4ed45c6b7407d077fb500227d1a372518190bd3cc3400d8bcdb49aea803c2d11b8815c4568b44ef2e5b5a2cc0022e1bef9eabee0eedb7c6ab5d23ec22
@@ -0,0 +1,54 @@
1
+ class HeadMusic::Clef
2
+ CLEFS = [
3
+ { pitch: 'G4', line: 2, names: ['treble', 'G-clef'], modern: true },
4
+ { pitch: 'G4', line: 1, names: ['French', 'French violin'] },
5
+ { pitch: 'G3', line: 2, names: ['tenor'], modern: true },
6
+
7
+ { pitch: 'F3', line: 3, names: ['baritone'] },
8
+ { pitch: 'F3', line: 4, names: ['bass', 'F-clef'], modern: true },
9
+ { pitch: 'F3', line: 5, names: ['sub-bass'] },
10
+
11
+ { pitch: 'C4', line: 1, names: ['soprano'] },
12
+ { pitch: 'C4', line: 2, names: ['mezzo-soprano'] },
13
+ { pitch: 'C4', line: 3, names: ['alto', 'viola', 'counter-tenor', 'countertenor'], modern: true },
14
+ { pitch: 'C4', line: 4, names: ['tenor'], modern: true },
15
+ { pitch: 'C4', line: 5, names: ['baritone'] },
16
+
17
+ { pitch: nil, line: 3, names: ['neutral', 'percussion'] }
18
+ ]
19
+
20
+ def self.get(name)
21
+ name = name.to_s
22
+ @clefs ||= {}
23
+ @clefs[name.to_s.to_sym] = new(name)
24
+ end
25
+
26
+ attr_reader :name, :pitch, :line
27
+
28
+ def initialize(name)
29
+ @name = name.to_s
30
+ clef_data = CLEFS.detect { |clef| clef[:names].include?(name) }
31
+ @pitch = HeadMusic::Pitch.get(clef_data[:pitch])
32
+ @line = clef_data[:line]
33
+ end
34
+
35
+ def clef_type
36
+ "#{pitch.letter_name}-clef"
37
+ end
38
+
39
+ def line_pitch(line_number)
40
+ @line_pitches ||= {}
41
+ @line_pitches[line_number] ||= begin
42
+ steps = (line_number - line) * 2
43
+ pitch.natural_steps(steps)
44
+ end
45
+ end
46
+
47
+ def space_pitch(space_number)
48
+ @space_pitches ||= {}
49
+ @space_pitches[space_number] ||= begin
50
+ steps = (space_number - line) * 2 + 1
51
+ pitch.natural_steps(steps)
52
+ end
53
+ end
54
+ end
@@ -33,7 +33,7 @@ class HeadMusic::FunctionalInterval
33
33
  quality_name, degree_name = words[0..-2].join(' '), words.last
34
34
  lower_pitch = HeadMusic::Pitch.get('C4')
35
35
  steps = NUMBER_NAMES.index(degree_name)
36
- higher_letter = lower_pitch.letter.steps(steps)
36
+ higher_letter = lower_pitch.letter_name.steps(steps)
37
37
  semitones = degree_quality_semitones.dig(degree_name.to_sym, quality_name.to_sym)
38
38
  higher_pitch = HeadMusic::Pitch.from_number_and_letter(lower_pitch + semitones, higher_letter)
39
39
  new(lower_pitch, higher_pitch)
@@ -70,7 +70,7 @@ class HeadMusic::FunctionalInterval
70
70
  end
71
71
 
72
72
  def simple_number
73
- @simple_number ||= @lower_pitch.letter.steps_to(@higher_pitch.letter) + 1
73
+ @simple_number ||= @lower_pitch.letter_name.steps_to(@higher_pitch.letter_name) + 1
74
74
  end
75
75
 
76
76
  def simple_semitones
@@ -1,7 +1,5 @@
1
1
  class HeadMusic::LetterName
2
- # Defines the natural relationship between the natural letter-named notes
3
-
4
- NAMES = ('A'..'G').to_a
2
+ NAMES = %w[C D E F G A B]
5
3
 
6
4
  NATURAL_PITCH_CLASS_NUMBERS = {
7
5
  'C' => 0,
@@ -23,18 +21,18 @@ class HeadMusic::LetterName
23
21
  singleton_class.send(:alias_method, :[], :get)
24
22
 
25
23
  def self.from_name(name)
26
- @letters ||= {}
24
+ @letter_names ||= {}
27
25
  name = name.to_s.first.upcase
28
- @letters[name] ||= new(name) if NAMES.include?(name)
26
+ @letter_names[name] ||= new(name) if NAMES.include?(name)
29
27
  end
30
28
 
31
29
  def self.from_pitch_class(pitch_class)
32
- @letters ||= {}
30
+ @letter_names ||= {}
33
31
  return nil if pitch_class.to_s == pitch_class
34
32
  pitch_class = pitch_class.to_i % 12
35
33
  name = NAMES.detect { |name| pitch_class == NATURAL_PITCH_CLASS_NUMBERS[name] }
36
34
  name ||= HeadMusic::PitchClass::PREFERRED_SPELLINGS[pitch_class].first
37
- @letters[name] ||= new(name) if NAMES.include?(name)
35
+ @letter_names[name] ||= new(name) if NAMES.include?(name)
38
36
  end
39
37
 
40
38
  attr_reader :name
@@ -60,7 +58,7 @@ class HeadMusic::LetterName
60
58
  end
61
59
 
62
60
  def steps(num)
63
- cycle[num]
61
+ HeadMusic::LetterName.get(cycle[num % NAMES.length])
64
62
  end
65
63
 
66
64
  def steps_to(other, direction = :ascending)
@@ -0,0 +1,14 @@
1
+ class HeadMusic::Note
2
+ attr_reader :pitch, :rhythmic_value
3
+
4
+ delegate :ticks, to: :rhythmic_value
5
+
6
+ def initialize(pitch, rhythmic_unit, rhythmic_value_modifiers = {})
7
+ @pitch = HeadMusic::Pitch.get(pitch)
8
+ @rhythmic_value = HeadMusic::RhythmicValue.new(rhythmic_unit, rhythmic_value_modifiers)
9
+ end
10
+
11
+ def duration
12
+ rhythmic_value.total_value
13
+ end
14
+ end
@@ -4,7 +4,7 @@ class HeadMusic::Pitch
4
4
  attr_reader :spelling
5
5
  attr_reader :octave
6
6
 
7
- delegate :letter, :letter_cycle, to: :spelling
7
+ delegate :letter_name, :letter_name_cycle, to: :spelling
8
8
  delegate :accidental, :sharp?, :flat?, to: :spelling
9
9
  delegate :pitch_class, to: :spelling
10
10
  delegate :semitones, to: :accidental, prefix: true, allow_nil: true
@@ -28,14 +28,14 @@ class HeadMusic::Pitch
28
28
  fetch_or_create(spelling, octave)
29
29
  end
30
30
 
31
- def self.from_number_and_letter(number, letter)
32
- letter = HeadMusic::LetterName.get(letter)
33
- natural_letter_pitch = get(HeadMusic::LetterName.get(letter).pitch_class)
31
+ def self.from_number_and_letter(number, letter_name)
32
+ letter_name = HeadMusic::LetterName.get(letter_name)
33
+ natural_letter_pitch = get(HeadMusic::LetterName.get(letter_name).pitch_class)
34
34
  natural_letter_pitch += 12 while (number - natural_letter_pitch.to_i).to_i >= 11
35
35
  natural_letter_pitch = get(natural_letter_pitch)
36
36
  accidental_interval = natural_letter_pitch.smallest_interval_to(HeadMusic::PitchClass.get(number))
37
37
  accidental = HeadMusic::Accidental.for_interval(accidental_interval)
38
- spelling = HeadMusic::Spelling.fetch_or_create(letter, accidental)
38
+ spelling = HeadMusic::Spelling.fetch_or_create(letter_name, accidental)
39
39
  fetch_or_create(spelling, natural_letter_pitch.octave)
40
40
  end
41
41
 
@@ -57,7 +57,7 @@ class HeadMusic::Pitch
57
57
  end
58
58
 
59
59
  def midi_note_number
60
- (octave + 1) * 12 + letter.pitch_class.to_i + accidental_semitones.to_i
60
+ (octave + 1) * 12 + letter_name.pitch_class.to_i + accidental_semitones.to_i
61
61
  end
62
62
 
63
63
  alias_method :midi, :midi_note_number
@@ -71,6 +71,10 @@ class HeadMusic::Pitch
71
71
  midi_note_number
72
72
  end
73
73
 
74
+ def natural
75
+ HeadMusic::Pitch.get(self.to_s.gsub(/[#b]/, ''))
76
+ end
77
+
74
78
  def enharmonic?(other)
75
79
  self.midi_note_number == other.midi_note_number
76
80
  end
@@ -101,5 +105,17 @@ class HeadMusic::Pitch
101
105
  HeadMusic::Scale.get(self, scale_type_name)
102
106
  end
103
107
 
108
+ def natural_steps(num_steps)
109
+ target_letter_name = self.letter_name.steps(num_steps)
110
+ direction = num_steps >= 0 ? 1 : -1
111
+ octaves_delta = (num_steps.abs / 7) * direction
112
+ if num_steps < 0 && target_letter_name.position > letter_name.position
113
+ octaves_delta -= 1
114
+ elsif num_steps > 0 && target_letter_name.position < letter_name.position
115
+ octaves_delta += 1
116
+ end
117
+ HeadMusic::Pitch.get([target_letter_name, octave + octaves_delta].join)
118
+ end
119
+
104
120
  private_class_method :new
105
121
  end
@@ -0,0 +1,59 @@
1
+ class HeadMusic::RhythmicUnit
2
+ MULTIPLES = ['whole', 'double whole', 'longa', 'maxima']
3
+ DIVISIONS = ['whole', 'half', 'quarter', 'eighth', 'sixteenth', 'thirty-second', 'sixty-fourth', 'hundred twenty-eighth', 'two hundred fifty-sixth']
4
+
5
+ BRITISH_MULTIPLE_NAMES = %w[semibreve breve longa maxima]
6
+ BRITISH_DIVISION_NAMES = %w[semibreve minim crotchet quaver semiquaver demisemiquaver hemidemisemiquaver semihemidemisemiquaver demisemihemidemisemiquaver]
7
+
8
+ def self.get(name)
9
+ @rhythmic_units ||= {}
10
+ @rhythmic_units[name.to_s] ||= new(name.to_s)
11
+ end
12
+ singleton_class.send(:alias_method, :[], :get)
13
+
14
+ attr_reader :name, :numerator, :denominator
15
+ delegate :to_s, to: :name
16
+
17
+ def initialize(canonical_name)
18
+ @name ||= canonical_name
19
+ @numerator ||= MULTIPLES.include?(name) ? 2**MULTIPLES.index(name) : 1
20
+ @denominator ||= DIVISIONS.include?(name) ? 2**DIVISIONS.index(name) : 1
21
+ end
22
+
23
+ def relative_value
24
+ @numerator.to_f / @denominator
25
+ end
26
+
27
+ def notehead
28
+ case relative_value
29
+ when 8
30
+ :maxima
31
+ when 4
32
+ :longa
33
+ when 2
34
+ :breve
35
+ when 0.5, 1
36
+ :open
37
+ else
38
+ :closed
39
+ end
40
+ end
41
+
42
+ def flags
43
+ DIVISIONS.include?(name) ? [DIVISIONS.index(name) - 2, 0].max : 0
44
+ end
45
+
46
+ def has_stem?
47
+ relative_value < 1
48
+ end
49
+
50
+ def british_name
51
+ if MULTIPLES.include?(name)
52
+ BRITISH_MULTIPLE_NAMES[MULTIPLES.index(name)]
53
+ elsif DIVISIONS.include?(name)
54
+ BRITISH_DIVISION_NAMES[DIVISIONS.index(name)]
55
+ end
56
+ end
57
+
58
+ private_class_method :new
59
+ end
@@ -1,63 +1,60 @@
1
1
  class HeadMusic::RhythmicValue
2
- MULTIPLES = ['whole', 'double whole', 'longa', 'maxima']
3
- DIVISIONS = ['whole', 'half', 'quarter', 'eighth', 'sixteenth', 'thirty-second', 'sixty-fourth', 'hundred twenty-eighth note', 'two hundred fifty-sixth note']
2
+ PPQN = PULSES_PER_QUARTER_NOTE = 960
4
3
 
5
- BRITISH_MULTIPLE_NAMES = %w[semibreve breve longa maxima]
6
- BRITISH_DIVISION_NAMES = %w[semibreve minim crotchet quaver semiquaver demisemiquaver hemidemisemiquaver semihemidemisemiquaver demisemihemidemisemiquaver]
4
+ attr_reader :unit, :dots, :tied_value
7
5
 
8
- def self.get(name)
9
- @rhythmic_values ||= {}
10
- @rhythmic_values[name.to_s] ||= new(name.to_s)
11
- end
12
- singleton_class.send(:alias_method, :[], :get)
6
+ delegate :name, to: :unit, prefix: true
13
7
 
14
- attr_reader :name
15
- delegate :to_s, to: :name
16
- delegate :to_i, to: :relative_value
8
+ def initialize(unit, dots: nil, tied_value: nil)
9
+ @unit = HeadMusic::RhythmicUnit.get(unit)
10
+ @dots = [0, 1, 2, 3].include?(dots) ? dots : 0
11
+ @tied_value = tied_value
12
+ end
17
13
 
18
- def initialize(canonical_name)
19
- @name ||= canonical_name
14
+ def unit_value
15
+ unit.relative_value
20
16
  end
21
17
 
22
18
  def relative_value
23
- @relative_value ||=
24
- if MULTIPLES.include?(name)
25
- 1.0 * 2**MULTIPLES.index(name)
26
- elsif DIVISIONS.include?(name)
27
- 1.0 / 2**DIVISIONS.index(name)
28
- end
19
+ unit_value * multiplier
29
20
  end
30
21
 
31
- def per_whole
32
- @per_whole ||=
33
- if MULTIPLES.include?(name)
34
- 1.0 / 2**MULTIPLES.index(name)
35
- elsif DIVISIONS.include?(name)
36
- 1.0 * 2**DIVISIONS.index(name)
37
- end
22
+ def total_value
23
+ relative_value + (tied_value ? tied_value.total_value : 0)
38
24
  end
39
25
 
40
- def note_head
41
- return :breve if relative_value == 2
42
- return :open if relative_value >= 0.5
43
- :closed
26
+ def multiplier
27
+ (0..dots).reduce(0) { |sum, i| sum += (1.0/2)**i }
44
28
  end
45
29
 
46
- def flags
47
- DIVISIONS.include?(name) ? [DIVISIONS.index(name) - 2, 0].max : 0
30
+ def ticks
31
+ PPQN * 4 * total_value
48
32
  end
49
33
 
50
- def has_stem?
51
- relative_value < 1
34
+ def per_whole
35
+ 1.0 / relative_value
52
36
  end
53
37
 
54
- def british_name
55
- if MULTIPLES.include?(name)
56
- BRITISH_MULTIPLE_NAMES[MULTIPLES.index(name)]
57
- elsif DIVISIONS.include?(name)
58
- BRITISH_DIVISION_NAMES[DIVISIONS.index(name)]
38
+ def name_modifier_prefix
39
+ case dots
40
+ when 1
41
+ 'dotted'
42
+ when 2
43
+ 'double-dotted'
44
+ when 3
45
+ 'triple-dotted'
59
46
  end
60
47
  end
61
48
 
62
- private_class_method :new
49
+ def single_value_name
50
+ [name_modifier_prefix, unit_name].reject(&:nil?).join(' ')
51
+ end
52
+
53
+ def name
54
+ if tied_value
55
+ [single_value_name, tied_value.name].reject(&:nil?).join(' tied to ')
56
+ else
57
+ single_value_name
58
+ end
59
+ end
63
60
  end
@@ -19,7 +19,7 @@ class HeadMusic::Scale
19
19
  @pitches ||= {}
20
20
  @pitches[direction] ||= {}
21
21
  @pitches[direction][octaves] ||= begin
22
- letter_cycle = root_pitch.letter_cycle
22
+ letter_name_cycle = root_pitch.letter_name_cycle
23
23
  semitones_from_root = 0
24
24
  [root_pitch].tap do |pitches|
25
25
  if [:ascending, :both].include?(direction)
@@ -50,8 +50,8 @@ class HeadMusic::Scale
50
50
  pitches(direction: direction, octaves: octaves).map(&:name)
51
51
  end
52
52
 
53
- def letter_cycle
54
- @letter_cycle ||= root_pitch.letter_cycle
53
+ def letter_name_cycle
54
+ @letter_name_cycle ||= root_pitch.letter_name_cycle
55
55
  end
56
56
 
57
57
  def root_pitch_number
@@ -77,9 +77,9 @@ class HeadMusic::Scale
77
77
  def letter_for_step(step, semitones_from_root, direction)
78
78
  pitch_class_number = (root_pitch.pitch_class.to_i + semitones_from_root) % 12
79
79
  if scale_type.intervals.length == 7
80
- direction == :ascending ? letter_cycle[step % 7] : letter_cycle[-step % 7]
80
+ direction == :ascending ? letter_name_cycle[step % 7] : letter_name_cycle[-step % 7]
81
81
  elsif scale_type.intervals.length < 7 && parent_scale_pitches
82
- parent_scale_pitch_for(semitones_from_root).letter
82
+ parent_scale_pitch_for(semitones_from_root).letter_name
83
83
  elsif root_pitch.flat?
84
84
  HeadMusic::PitchClass::FLAT_SPELLINGS[pitch_class_number]
85
85
  else
@@ -89,7 +89,7 @@ class HeadMusic::Scale
89
89
 
90
90
  def pitch_for_step(step, semitones_from_root, direction)
91
91
  pitch_number = root_pitch_number + semitones_from_root
92
- letter = letter_for_step(step, semitones_from_root, direction)
93
- HeadMusic::Pitch.from_number_and_letter(pitch_number, letter)
92
+ letter_name = letter_for_step(step, semitones_from_root, direction)
93
+ HeadMusic::Pitch.from_number_and_letter(pitch_number, letter_name)
94
94
  end
95
95
  end
@@ -1,14 +1,13 @@
1
- # A Spelling is a pitch class with a letter name and possibly an accidental
2
1
  class HeadMusic::Spelling
3
2
  MATCHER = /^\s*([A-G])([b#]*)(\-?\d+)?\s*$/
4
3
 
5
4
  attr_reader :pitch_class
6
- attr_reader :letter
5
+ attr_reader :letter_name
7
6
  attr_reader :accidental
8
7
 
9
8
  delegate :number, to: :pitch_class, prefix: true
10
9
  delegate :to_i, to: :pitch_class_number
11
- delegate :cycle, to: :letter, prefix: true
10
+ delegate :cycle, to: :letter_name, prefix: true
12
11
  delegate :enharmonic?, to: :pitch_class
13
12
 
14
13
  def self.get(identifier)
@@ -23,43 +22,43 @@ class HeadMusic::Spelling
23
22
  def self.from_name(name)
24
23
  if match(name)
25
24
  letter_name, accidental_string, _octave = match(name).captures
26
- letter = HeadMusic::LetterName.get(letter_name)
27
- return nil unless letter
25
+ letter_name = HeadMusic::LetterName.get(letter_name)
26
+ return nil unless letter_name
28
27
  accidental = HeadMusic::Accidental.get(accidental_string)
29
- fetch_or_create(letter, accidental)
28
+ fetch_or_create(letter_name, accidental)
30
29
  end
31
30
  end
32
31
 
33
32
  def self.from_number(number)
34
33
  return nil unless number == number.to_i
35
34
  pitch_class_number = number.to_i % 12
36
- letter = HeadMusic::LetterName.from_pitch_class(pitch_class_number)
37
- from_number_and_letter(number, letter)
35
+ letter_name = HeadMusic::LetterName.from_pitch_class(pitch_class_number)
36
+ from_number_and_letter(number, letter_name)
38
37
  end
39
38
 
40
- def self.from_number_and_letter(number, letter)
41
- letter = HeadMusic::LetterName.get(letter)
42
- natural_letter_pitch_class = HeadMusic::LetterName.get(letter).pitch_class
43
- accidental_interval = letter.pitch_class.smallest_interval_to(HeadMusic::PitchClass.get(number))
39
+ def self.from_number_and_letter(number, letter_name)
40
+ letter_name = HeadMusic::LetterName.get(letter_name)
41
+ natural_letter_pitch_class = HeadMusic::LetterName.get(letter_name).pitch_class
42
+ accidental_interval = letter_name.pitch_class.smallest_interval_to(HeadMusic::PitchClass.get(number))
44
43
  accidental = HeadMusic::Accidental.for_interval(accidental_interval)
45
- fetch_or_create(letter, accidental)
44
+ fetch_or_create(letter_name, accidental)
46
45
  end
47
46
 
48
- def self.fetch_or_create(letter, accidental)
47
+ def self.fetch_or_create(letter_name, accidental)
49
48
  @spellings ||= {}
50
- key = [letter, accidental].join
51
- @spellings[key] ||= new(letter, accidental)
49
+ key = [letter_name, accidental].join
50
+ @spellings[key] ||= new(letter_name, accidental)
52
51
  end
53
52
 
54
- def initialize(letter, accidental = nil)
55
- @letter = HeadMusic::LetterName.get(letter.to_s)
53
+ def initialize(letter_name, accidental = nil)
54
+ @letter_name = HeadMusic::LetterName.get(letter_name.to_s)
56
55
  @accidental = HeadMusic::Accidental.get(accidental.to_s)
57
56
  accidental_semitones = @accidental ? @accidental.semitones : 0
58
- @pitch_class = HeadMusic::PitchClass.get(letter.pitch_class + accidental_semitones)
57
+ @pitch_class = HeadMusic::PitchClass.get(letter_name.pitch_class + accidental_semitones)
59
58
  end
60
59
 
61
60
  def name
62
- [letter, accidental].join
61
+ [letter_name, accidental].join
63
62
  end
64
63
 
65
64
  def to_s
@@ -1,3 +1,3 @@
1
1
  module HeadMusic
2
- VERSION = "0.5.3"
2
+ VERSION = "0.5.4"
3
3
  end
data/lib/head_music.rb CHANGED
@@ -6,16 +6,19 @@ require 'humanize'
6
6
 
7
7
  require 'head_music/accidental'
8
8
  require 'head_music/circle'
9
+ require 'head_music/clef'
9
10
  require 'head_music/consonance'
10
11
  require 'head_music/functional_interval'
11
12
  require 'head_music/interval'
12
13
  require 'head_music/key_signature'
13
14
  require 'head_music/letter_name'
14
15
  require 'head_music/meter'
16
+ require 'head_music/note'
15
17
  require 'head_music/octave'
16
18
  require 'head_music/pitch_class'
17
19
  require 'head_music/pitch'
18
20
  require 'head_music/quality'
21
+ require 'head_music/rhythmic_unit'
19
22
  require 'head_music/rhythmic_value'
20
23
  require 'head_music/scale'
21
24
  require 'head_music/scale_type'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: head_music
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob Head
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-02-23 00:00:00.000000000 Z
11
+ date: 2017-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -116,16 +116,19 @@ files:
116
116
  - lib/head_music.rb
117
117
  - lib/head_music/accidental.rb
118
118
  - lib/head_music/circle.rb
119
+ - lib/head_music/clef.rb
119
120
  - lib/head_music/consonance.rb
120
121
  - lib/head_music/functional_interval.rb
121
122
  - lib/head_music/interval.rb
122
123
  - lib/head_music/key_signature.rb
123
124
  - lib/head_music/letter_name.rb
124
125
  - lib/head_music/meter.rb
126
+ - lib/head_music/note.rb
125
127
  - lib/head_music/octave.rb
126
128
  - lib/head_music/pitch.rb
127
129
  - lib/head_music/pitch_class.rb
128
130
  - lib/head_music/quality.rb
131
+ - lib/head_music/rhythmic_unit.rb
129
132
  - lib/head_music/rhythmic_value.rb
130
133
  - lib/head_music/scale.rb
131
134
  - lib/head_music/scale_type.rb