head_music 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
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