head_music 7.0.4 → 8.0.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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/Gemfile +1 -1
  4. data/lib/head_music/{diatonic_interval → analysis/diatonic_interval}/category.rb +1 -1
  5. data/lib/head_music/{diatonic_interval → analysis/diatonic_interval}/naming.rb +6 -6
  6. data/lib/head_music/{diatonic_interval → analysis/diatonic_interval}/parser.rb +4 -4
  7. data/lib/head_music/{diatonic_interval → analysis/diatonic_interval}/semitones.rb +4 -4
  8. data/lib/head_music/{diatonic_interval → analysis/diatonic_interval}/size.rb +1 -1
  9. data/lib/head_music/{diatonic_interval.rb → analysis/diatonic_interval.rb} +19 -16
  10. data/lib/head_music/{harmonic_interval.rb → analysis/harmonic_interval.rb} +5 -2
  11. data/lib/head_music/{melodic_interval.rb → analysis/melodic_interval.rb} +6 -3
  12. data/lib/head_music/{motion.rb → analysis/motion.rb} +6 -3
  13. data/lib/head_music/content/bar.rb +2 -2
  14. data/lib/head_music/content/composition.rb +3 -3
  15. data/lib/head_music/content/note.rb +1 -1
  16. data/lib/head_music/content/placement.rb +1 -1
  17. data/lib/head_music/content/position.rb +1 -1
  18. data/lib/head_music/content/rhythmic_value.rb +3 -3
  19. data/lib/head_music/{staff.rb → content/staff.rb} +6 -3
  20. data/lib/head_music/content/voice.rb +2 -2
  21. data/lib/head_music/{instrument.rb → instruments/instrument.rb} +10 -7
  22. data/lib/head_music/{data → instruments}/instrument_families.yml +49 -0
  23. data/lib/head_music/{instrument_family.rb → instruments/instrument_family.rb} +5 -2
  24. data/lib/head_music/{data → instruments}/instruments.yml +116 -0
  25. data/lib/head_music/{instrument → instruments}/staff.rb +5 -2
  26. data/lib/head_music/{instrument → instruments}/staff_scheme.rb +7 -2
  27. data/lib/head_music/{instrument → instruments}/variant.rb +6 -3
  28. data/lib/head_music/locales/en.yml +22 -0
  29. data/lib/head_music/locales/es.yml +22 -22
  30. data/lib/head_music/{alteration.rb → rudiment/alteration.rb} +9 -6
  31. data/lib/head_music/{chromatic_interval.rb → rudiment/chromatic_interval.rb} +7 -4
  32. data/lib/head_music/{circle.rb → rudiment/circle.rb} +9 -6
  33. data/lib/head_music/{clef.rb → rudiment/clef.rb} +7 -4
  34. data/lib/head_music/{consonance.rb → rudiment/consonance.rb} +4 -1
  35. data/lib/head_music/{interval_cycle.rb → rudiment/interval_cycle.rb} +12 -9
  36. data/lib/head_music/{key_signature → rudiment/key_signature}/enharmonic_equivalence.rb +4 -4
  37. data/lib/head_music/{key_signature.rb → rudiment/key_signature.rb} +10 -7
  38. data/lib/head_music/{letter_name.rb → rudiment/letter_name.rb} +9 -6
  39. data/lib/head_music/{meter.rb → rudiment/meter.rb} +6 -3
  40. data/lib/head_music/{musical_symbol.rb → rudiment/musical_symbol.rb} +4 -1
  41. data/lib/head_music/{pitch → rudiment/pitch}/enharmonic_equivalence.rb +4 -4
  42. data/lib/head_music/{pitch → rudiment/pitch}/octave_equivalence.rb +2 -2
  43. data/lib/head_music/{pitch.rb → rudiment/pitch.rb} +30 -27
  44. data/lib/head_music/{pitch_class.rb → rudiment/pitch_class.rb} +14 -11
  45. data/lib/head_music/{pitch_class_set.rb → rudiment/pitch_class_set.rb} +5 -2
  46. data/lib/head_music/{pitch_set.rb → rudiment/pitch_set.rb} +14 -11
  47. data/lib/head_music/{quality.rb → rudiment/quality.rb} +4 -1
  48. data/lib/head_music/{reference_pitch.rb → rudiment/reference_pitch.rb} +5 -2
  49. data/lib/head_music/{register.rb → rudiment/register.rb} +6 -3
  50. data/lib/head_music/rudiment/rhythm.rb +6 -0
  51. data/lib/head_music/{rhythmic_unit.rb → rudiment/rhythmic_unit.rb} +5 -2
  52. data/lib/head_music/{scale.rb → rudiment/scale.rb} +12 -9
  53. data/lib/head_music/{scale_degree.rb → rudiment/scale_degree.rb} +8 -5
  54. data/lib/head_music/{scale_type.rb → rudiment/scale_type.rb} +4 -1
  55. data/lib/head_music/{solmization.rb → rudiment/solmization.rb} +4 -1
  56. data/lib/head_music/{sonority.rb → rudiment/sonority.rb} +7 -4
  57. data/lib/head_music/{spelling.rb → rudiment/spelling.rb} +20 -17
  58. data/lib/head_music/{tuning.rb → rudiment/tuning.rb} +6 -3
  59. data/lib/head_music/style/annotation.rb +6 -6
  60. data/lib/head_music/style/guidelines/consonant_climax.rb +4 -4
  61. data/lib/head_music/style/guidelines/diatonic.rb +1 -1
  62. data/lib/head_music/style/guidelines/step_out_of_unison.rb +1 -1
  63. data/lib/head_music/version.rb +1 -1
  64. data/lib/head_music.rb +50 -46
  65. metadata +51 -51
  66. data/lib/head_music/rhythm.rb +0 -3
  67. /data/lib/head_music/{data → rudiment}/clefs.yml +0 -0
  68. /data/lib/head_music/{solmizations.yml → rudiment/solmizations.yml} +0 -0
@@ -1,11 +1,14 @@
1
+ # A module for music rudiments
2
+ module HeadMusic::Rudiment; end
3
+
1
4
  # A scale contains ordered pitches starting at a tonal center.
2
- class HeadMusic::Scale
5
+ class HeadMusic::Rudiment::Scale
3
6
  SCALE_REGEX = /^[A-G][#b]?\s+\w+$/
4
7
 
5
8
  def self.get(root_pitch, scale_type = nil)
6
9
  root_pitch, scale_type = root_pitch.split(/\s+/) if root_pitch.is_a?(String) && scale_type =~ SCALE_REGEX
7
- root_pitch = HeadMusic::Pitch.get(root_pitch)
8
- scale_type = HeadMusic::ScaleType.get(scale_type || :major)
10
+ root_pitch = HeadMusic::Rudiment::Pitch.get(root_pitch)
11
+ scale_type = HeadMusic::Rudiment::ScaleType.get(scale_type || :major)
9
12
  @scales ||= {}
10
13
  hash_key = HeadMusic::Utilities::HashKey.for(
11
14
  [root_pitch, scale_type].join(" ").gsub(/#|♯/, "sharp").gsub(/(\w)[b♭]/, '\\1flat')
@@ -18,8 +21,8 @@ class HeadMusic::Scale
18
21
  attr_reader :root_pitch, :scale_type
19
22
 
20
23
  def initialize(root_pitch, scale_type)
21
- @root_pitch = HeadMusic::Pitch.get(root_pitch)
22
- @scale_type = HeadMusic::ScaleType.get(scale_type)
24
+ @root_pitch = HeadMusic::Rudiment::Pitch.get(root_pitch)
25
+ @scale_type = HeadMusic::Rudiment::ScaleType.get(scale_type)
23
26
  end
24
27
 
25
28
  def pitches(direction: :ascending, octaves: 1)
@@ -80,7 +83,7 @@ class HeadMusic::Scale
80
83
  end
81
84
 
82
85
  def parent_scale_pitches
83
- HeadMusic::Scale.get(root_pitch, scale_type.parent_name).pitches if scale_type.parent
86
+ HeadMusic::Rudiment::Scale.get(root_pitch, scale_type.parent_name).pitches if scale_type.parent
84
87
  end
85
88
 
86
89
  def parent_scale_pitch_for(semitones_from_root)
@@ -92,7 +95,7 @@ class HeadMusic::Scale
92
95
  def pitch_for_step(step, semitones_from_root, direction)
93
96
  pitch_number = root_pitch_number + semitones_from_root
94
97
  letter_name = letter_for_step(step, semitones_from_root, direction)
95
- HeadMusic::Pitch.from_number_and_letter(pitch_number, letter_name)
98
+ HeadMusic::Rudiment::Pitch.from_number_and_letter(pitch_number, letter_name)
96
99
  end
97
100
 
98
101
  def letter_for_step(step, semitones_from_root, direction)
@@ -117,11 +120,11 @@ class HeadMusic::Scale
117
120
  def flat_letter_for_step(semitones_from_root)
118
121
  return unless root_pitch.flat?
119
122
 
120
- HeadMusic::PitchClass::FLAT_SPELLINGS[pitch_class_number(semitones_from_root)]
123
+ HeadMusic::Rudiment::PitchClass::FLAT_SPELLINGS[pitch_class_number(semitones_from_root)]
121
124
  end
122
125
 
123
126
  def sharp_letter_for_step(semitones_from_root)
124
- HeadMusic::PitchClass::SHARP_SPELLINGS[pitch_class_number(semitones_from_root)]
127
+ HeadMusic::Rudiment::PitchClass::SHARP_SPELLINGS[pitch_class_number(semitones_from_root)]
125
128
  end
126
129
 
127
130
  def pitch_class_number(semitones_from_root)
@@ -1,6 +1,9 @@
1
+ # A module for music rudiments
2
+ module HeadMusic::Rudiment; end
3
+
1
4
  # A scale degree is a number indicating the ordinality of the spelling in the key.
2
5
  # TODO: Rewrite to accept a tonal_center and a scale type.
3
- class HeadMusic::ScaleDegree
6
+ class HeadMusic::Rudiment::ScaleDegree
4
7
  include Comparable
5
8
 
6
9
  NAME_FOR_DIATONIC_DEGREE = [nil, "tonic", "supertonic", "mediant", "subdominant", "dominant", "submediant"].freeze
@@ -12,7 +15,7 @@ class HeadMusic::ScaleDegree
12
15
 
13
16
  def initialize(key_signature, spelling)
14
17
  @key_signature = key_signature
15
- @spelling = HeadMusic::Spelling.get(spelling)
18
+ @spelling = HeadMusic::Rudiment::Spelling.get(spelling)
16
19
  end
17
20
 
18
21
  def degree
@@ -23,7 +26,7 @@ class HeadMusic::ScaleDegree
23
26
  spelling_alteration_semitones = spelling.alteration&.semitones || 0
24
27
  usual_sign_semitones = scale_degree_usual_spelling.alteration&.semitones || 0
25
28
  delta = spelling_alteration_semitones - usual_sign_semitones
26
- HeadMusic::Alteration.by(:semitones, delta) if delta != 0
29
+ HeadMusic::Rudiment::Alteration.by(:semitones, delta) if delta != 0
27
30
  end
28
31
 
29
32
  def alteration_semitones
@@ -35,7 +38,7 @@ class HeadMusic::ScaleDegree
35
38
  end
36
39
 
37
40
  def <=>(other)
38
- if other.is_a?(HeadMusic::ScaleDegree)
41
+ if other.is_a?(HeadMusic::Rudiment::ScaleDegree)
39
42
  [degree, alteration_semitones] <=> [other.degree, other.alteration_semitones]
40
43
  else
41
44
  # TODO: Improve this
@@ -53,6 +56,6 @@ class HeadMusic::ScaleDegree
53
56
  private
54
57
 
55
58
  def scale_degree_usual_spelling
56
- HeadMusic::Spelling.get(scale.spellings[degree - 1])
59
+ HeadMusic::Rudiment::Spelling.get(scale.spellings[degree - 1])
57
60
  end
58
61
  end
@@ -1,5 +1,8 @@
1
+ # A module for music rudiments
2
+ module HeadMusic::Rudiment; end
3
+
1
4
  # A ScaleType represents a particular scale pattern, such as major, lydian, or minor pentatonic.
2
- class HeadMusic::ScaleType
5
+ class HeadMusic::Rudiment::ScaleType
3
6
  H = 1 # whole step
4
7
  W = 2 # half step
5
8
 
@@ -1,6 +1,9 @@
1
+ # A module for music rudiments
2
+ module HeadMusic::Rudiment; end
3
+
1
4
  # A scale degree is a number indicating the ordinality of the spelling in the key signature.
2
5
  # TODO: Rewrite to accept a tonal_center and a scale type.
3
- class HeadMusic::Solmization
6
+ class HeadMusic::Rudiment::Solmization
4
7
  include HeadMusic::Named
5
8
 
6
9
  DEFAULT_SOLMIZATION = "solfège"
@@ -1,7 +1,10 @@
1
+ # A module for music rudiments
2
+ module HeadMusic::Rudiment; end
3
+
1
4
  # A Sonority describes a set of pitch class intervalic relationships.
2
5
  # For example, a minor triad, or a major-minor seventh chord.
3
6
  # The Sonority class is a factory for returning one of its subclasses.
4
- class HeadMusic::Sonority
7
+ class HeadMusic::Rudiment::Sonority
5
8
  SONORITIES = {
6
9
  major_triad: %w[M3 P5],
7
10
  minor_triad: %w[m3 P5],
@@ -110,12 +113,12 @@ class HeadMusic::Sonority
110
113
  return nil unless identifier
111
114
 
112
115
  @diatonic_intervals_above_bass_pitch ||=
113
- SONORITIES[identifier].map { |shorthand| HeadMusic::DiatonicInterval.get(shorthand) }
116
+ SONORITIES[identifier].map { |shorthand| HeadMusic::Analysis::DiatonicInterval.get(shorthand) }
114
117
  end
115
118
 
116
119
  def ==(other)
117
- other = HeadMusic::PitchSet.new(other) if other.is_a?(Array)
118
- other = self.class.new(other) if other.is_a?(HeadMusic::PitchSet)
120
+ other = HeadMusic::Rudiment::PitchSet.new(other) if other.is_a?(Array)
121
+ other = self.class.new(other) if other.is_a?(HeadMusic::Rudiment::PitchSet)
119
122
  identifier == other.identifier
120
123
  end
121
124
  end
@@ -1,8 +1,11 @@
1
+ # A module for music rudiments
2
+ module HeadMusic::Rudiment; end
3
+
1
4
  # Represents the spelling of a pitch, such as C# or Db.
2
5
  # Composite of a LetterName and an optional Alteration.
3
6
  # Does not include the octave. See Pitch for that.
4
- class HeadMusic::Spelling
5
- MATCHER = /^\s*([A-G])(#{HeadMusic::Alteration.matcher}?)(-?\d+)?\s*$/i
7
+ class HeadMusic::Rudiment::Spelling
8
+ MATCHER = /^\s*([A-G])(#{HeadMusic::Rudiment::Alteration.matcher}?)(-?\d+)?\s*$/i
6
9
 
7
10
  attr_reader :pitch_class, :letter_name, :alteration
8
11
 
@@ -13,7 +16,7 @@ class HeadMusic::Spelling
13
16
  delegate :sharp?, :flat?, :double_sharp?, :double_flat?, to: :alteration, allow_nil: true
14
17
 
15
18
  def self.get(identifier)
16
- return identifier if identifier.is_a?(HeadMusic::Spelling)
19
+ return identifier if identifier.is_a?(HeadMusic::Rudiment::Spelling)
17
20
 
18
21
  from_name(identifier) || from_number(identifier)
19
22
  end
@@ -26,10 +29,10 @@ class HeadMusic::Spelling
26
29
  return nil unless matching_string(name)
27
30
 
28
31
  letter_name, sign_string, _octave = matching_string(name).captures
29
- letter_name = HeadMusic::LetterName.get(letter_name)
32
+ letter_name = HeadMusic::Rudiment::LetterName.get(letter_name)
30
33
  return nil unless letter_name
31
34
 
32
- alteration = HeadMusic::Alteration.get(sign_string)
35
+ alteration = HeadMusic::Rudiment::Alteration.get(sign_string)
33
36
  fetch_or_create(letter_name, alteration)
34
37
  end
35
38
 
@@ -37,15 +40,15 @@ class HeadMusic::Spelling
37
40
  return nil unless number == number.to_i
38
41
 
39
42
  pitch_class_number = number.to_i % 12
40
- letter_name = HeadMusic::LetterName.from_pitch_class(pitch_class_number)
43
+ letter_name = HeadMusic::Rudiment::LetterName.from_pitch_class(pitch_class_number)
41
44
  from_number_and_letter(number, letter_name)
42
45
  end
43
46
 
44
47
  def self.from_number_and_letter(number, letter_name)
45
- letter_name = HeadMusic::LetterName.get(letter_name)
48
+ letter_name = HeadMusic::Rudiment::LetterName.get(letter_name)
46
49
  natural_letter_pitch_class = letter_name.pitch_class
47
- alteration_interval = natural_letter_pitch_class.smallest_interval_to(HeadMusic::PitchClass.get(number))
48
- alteration = HeadMusic::Alteration.by(:semitones, alteration_interval) if alteration_interval != 0
50
+ alteration_interval = natural_letter_pitch_class.smallest_interval_to(HeadMusic::Rudiment::PitchClass.get(number))
51
+ alteration = HeadMusic::Rudiment::Alteration.by(:semitones, alteration_interval) if alteration_interval != 0
49
52
  fetch_or_create(letter_name, alteration)
50
53
  end
51
54
 
@@ -56,10 +59,10 @@ class HeadMusic::Spelling
56
59
  end
57
60
 
58
61
  def initialize(letter_name, alteration = nil)
59
- @letter_name = HeadMusic::LetterName.get(letter_name.to_s)
60
- @alteration = HeadMusic::Alteration.get(alteration)
62
+ @letter_name = HeadMusic::Rudiment::LetterName.get(letter_name.to_s)
63
+ @alteration = HeadMusic::Rudiment::Alteration.get(alteration)
61
64
  alteration_semitones = @alteration ? @alteration.semitones : 0
62
- @pitch_class = HeadMusic::PitchClass.get(letter_name.pitch_class + alteration_semitones)
65
+ @pitch_class = HeadMusic::Rudiment::PitchClass.get(letter_name.pitch_class + alteration_semitones)
63
66
  end
64
67
 
65
68
  def name
@@ -71,12 +74,12 @@ class HeadMusic::Spelling
71
74
  end
72
75
 
73
76
  def ==(other)
74
- other = HeadMusic::Spelling.get(other)
77
+ other = HeadMusic::Rudiment::Spelling.get(other)
75
78
  to_s == other.to_s
76
79
  end
77
80
 
78
81
  def scale(scale_type_name = nil)
79
- HeadMusic::Scale.get(self, scale_type_name)
82
+ HeadMusic::Rudiment::Scale.get(self, scale_type_name)
80
83
  end
81
84
 
82
85
  def natural?
@@ -94,7 +97,7 @@ class HeadMusic::Spelling
94
97
  # Enharmonic equivalence occurs when two spellings refer to the same pitch class, such as D# and Eb.
95
98
  class EnharmonicEquivalence
96
99
  def self.get(spelling)
97
- spelling = HeadMusic::Spelling.get(spelling)
100
+ spelling = HeadMusic::Rudiment::Spelling.get(spelling)
98
101
  @enharmonic_equivalences ||= {}
99
102
  @enharmonic_equivalences[spelling.to_s] ||= new(spelling)
100
103
  end
@@ -102,11 +105,11 @@ class HeadMusic::Spelling
102
105
  attr_reader :spelling
103
106
 
104
107
  def initialize(spelling)
105
- @spelling = HeadMusic::Spelling.get(spelling)
108
+ @spelling = HeadMusic::Rudiment::Spelling.get(spelling)
106
109
  end
107
110
 
108
111
  def enharmonic_equivalent?(other)
109
- other = HeadMusic::Spelling.get(other)
112
+ other = HeadMusic::Rudiment::Spelling.get(other)
110
113
  spelling != other && spelling.pitch_class_number == other.pitch_class_number
111
114
  end
112
115
 
@@ -1,16 +1,19 @@
1
+ # A module for music rudiments
2
+ module HeadMusic::Rudiment; end
3
+
1
4
  # A tuning has a reference pitch and frequency and provides frequencies for all pitches
2
5
  # The base class assumes equal temperament tuning. By default, A4 = 440.0 Hz
3
- class HeadMusic::Tuning
6
+ class HeadMusic::Rudiment::Tuning
4
7
  attr_accessor :reference_pitch
5
8
 
6
9
  delegate :pitch, :frequency, to: :reference_pitch, prefix: true
7
10
 
8
11
  def initialize(reference_pitch: :a440)
9
- @reference_pitch = HeadMusic::ReferencePitch.get(reference_pitch)
12
+ @reference_pitch = HeadMusic::Rudiment::ReferencePitch.get(reference_pitch)
10
13
  end
11
14
 
12
15
  def frequency_for(pitch)
13
- pitch = HeadMusic::Pitch.get(pitch)
16
+ pitch = HeadMusic::Rudiment::Pitch.get(pitch)
14
17
  reference_pitch_frequency * (2**(1.0 / 12))**(pitch - reference_pitch.pitch).semitones
15
18
  end
16
19
  end
@@ -82,8 +82,8 @@ class HeadMusic::Style::Annotation
82
82
 
83
83
  def diatonic_interval_from_tonic(note)
84
84
  tonic_to_use = tonic_pitch
85
- tonic_to_use -= HeadMusic::ChromaticInterval.get(:perfect_octave) while tonic_to_use > note.pitch
86
- HeadMusic::DiatonicInterval.new(tonic_to_use, note.pitch)
85
+ tonic_to_use -= HeadMusic::Rudiment::ChromaticInterval.get(:perfect_octave) while tonic_to_use > note.pitch
86
+ HeadMusic::Analysis::DiatonicInterval.new(tonic_to_use, note.pitch)
87
87
  end
88
88
 
89
89
  def bass_voice?
@@ -96,21 +96,21 @@ class HeadMusic::Style::Annotation
96
96
 
97
97
  def motions
98
98
  downbeat_harmonic_intervals.each_cons(2).map do |harmonic_interval_pair|
99
- HeadMusic::Motion.new(*harmonic_interval_pair)
99
+ HeadMusic::Analysis::Motion.new(*harmonic_interval_pair)
100
100
  end
101
101
  end
102
102
 
103
103
  def downbeat_harmonic_intervals
104
104
  @downbeat_harmonic_intervals ||=
105
105
  cantus_firmus.notes
106
- .map { |note| HeadMusic::HarmonicInterval.new(note.voice, voice, note.position) }
106
+ .map { |note| HeadMusic::Analysis::HarmonicInterval.new(note.voice, voice, note.position) }
107
107
  .reject { |interval| interval.notes.length < 2 }
108
108
  end
109
109
 
110
110
  def harmonic_intervals
111
111
  @harmonic_intervals ||=
112
112
  positions
113
- .map { |position| HeadMusic::HarmonicInterval.new(cantus_firmus, voice, position) }
113
+ .map { |position| HeadMusic::Analysis::HarmonicInterval.new(cantus_firmus, voice, position) }
114
114
  .reject { |harmonic_interval| harmonic_interval.notes.length < 2 }
115
115
  end
116
116
 
@@ -128,6 +128,6 @@ class HeadMusic::Style::Annotation
128
128
  end
129
129
 
130
130
  def tonic_pitch
131
- @tonic_pitch ||= HeadMusic::Pitch.get(tonic_spelling)
131
+ @tonic_pitch ||= HeadMusic::Rudiment::Pitch.get(tonic_spelling)
132
132
  end
133
133
  end
@@ -36,12 +36,12 @@ class HeadMusic::Style::Guidelines::ConsonantClimax < HeadMusic::Style::Annotati
36
36
 
37
37
  def diatonic_interval_to_highest_pitch
38
38
  @diatonic_interval_to_highest_pitch ||=
39
- HeadMusic::DiatonicInterval.new(tonic_pitch, highest_pitch)
39
+ HeadMusic::Analysis::DiatonicInterval.new(tonic_pitch, highest_pitch)
40
40
  end
41
41
 
42
42
  def diatonic_interval_to_lowest_pitch
43
43
  @diatonic_interval_to_lowest_pitch ||=
44
- HeadMusic::DiatonicInterval.new(tonic_pitch, lowest_pitch)
44
+ HeadMusic::Analysis::DiatonicInterval.new(tonic_pitch, lowest_pitch)
45
45
  end
46
46
 
47
47
  def highest_pitch_appears_once?
@@ -73,11 +73,11 @@ class HeadMusic::Style::Guidelines::ConsonantClimax < HeadMusic::Style::Annotati
73
73
  end
74
74
 
75
75
  def step_between_highest_notes?
76
- HeadMusic::MelodicInterval.new(highest_notes.first, notes_between_highest_notes.first).step?
76
+ HeadMusic::Analysis::MelodicInterval.new(highest_notes.first, notes_between_highest_notes.first).step?
77
77
  end
78
78
 
79
79
  def step_between_lowest_notes?
80
- HeadMusic::MelodicInterval.new(lowest_notes.first, notes_between_lowest_notes.first).step?
80
+ HeadMusic::Analysis::MelodicInterval.new(lowest_notes.first, notes_between_lowest_notes.first).step?
81
81
  end
82
82
 
83
83
  def single_note_between_highest_notes?
@@ -15,7 +15,7 @@ class HeadMusic::Style::Guidelines::Diatonic < HeadMusic::Style::Annotation
15
15
  notes_not_in_key.reject do |note|
16
16
  penultimate_note &&
17
17
  note == penultimate_note &&
18
- HeadMusic::ScaleDegree.new(key_signature, note.pitch.spelling).alteration == "#"
18
+ HeadMusic::Rudiment::ScaleDegree.new(key_signature, note.pitch.spelling).alteration == "#"
19
19
  end
20
20
  end
21
21
 
@@ -22,7 +22,7 @@ class HeadMusic::Style::Guidelines::StepOutOfUnison < HeadMusic::Style::Annotati
22
22
  perfect_unisons.map do |unison|
23
23
  note1 = voice.note_at(unison.position)
24
24
  note2 = voice.note_following(unison.position)
25
- HeadMusic::MelodicInterval.new(note1, note2) if note1 && note2
25
+ HeadMusic::Analysis::MelodicInterval.new(note1, note2) if note1 && note2
26
26
  end.compact
27
27
  end
28
28
 
@@ -1,3 +1,3 @@
1
1
  module HeadMusic
2
- VERSION = "7.0.4"
2
+ VERSION = "8.0.0"
3
3
  end
data/lib/head_music.rb CHANGED
@@ -32,50 +32,42 @@ require "head_music/utilities/hash_key"
32
32
  require "head_music/named"
33
33
 
34
34
  # rudiments
35
- require "head_music/alteration"
36
- require "head_music/chromatic_interval"
37
- require "head_music/circle"
38
- require "head_music/clef"
39
- require "head_music/consonance"
40
- require "head_music/diatonic_interval"
41
- require "head_music/diatonic_interval/category"
42
- require "head_music/diatonic_interval/naming"
43
- require "head_music/diatonic_interval/parser"
44
- require "head_music/diatonic_interval/semitones"
45
- require "head_music/diatonic_interval/size"
46
- require "head_music/harmonic_interval"
47
- require "head_music/instrument_family"
48
- require "head_music/instrument"
49
- require "head_music/instrument/staff_scheme"
50
- require "head_music/instrument/staff"
51
- require "head_music/instrument/variant"
52
- require "head_music/interval_cycle"
53
- require "head_music/key_signature"
54
- require "head_music/key_signature/enharmonic_equivalence"
55
- require "head_music/letter_name"
56
- require "head_music/melodic_interval"
57
- require "head_music/meter"
58
- require "head_music/motion"
59
- require "head_music/musical_symbol"
60
- require "head_music/pitch"
61
- require "head_music/pitch/enharmonic_equivalence"
62
- require "head_music/pitch/octave_equivalence"
63
- require "head_music/pitch_class"
64
- require "head_music/pitch_class_set"
65
- require "head_music/pitch_set"
66
- require "head_music/quality"
67
- require "head_music/reference_pitch"
68
- require "head_music/register"
69
- require "head_music/rhythm"
70
- require "head_music/rhythmic_unit"
71
- require "head_music/scale"
72
- require "head_music/scale_degree"
73
- require "head_music/scale_type"
74
- require "head_music/solmization"
75
- require "head_music/sonority"
76
- require "head_music/spelling"
77
- require "head_music/staff"
78
- require "head_music/tuning"
35
+ require "head_music/rudiment/alteration"
36
+ require "head_music/rudiment/chromatic_interval"
37
+ require "head_music/rudiment/circle"
38
+ require "head_music/rudiment/clef"
39
+ require "head_music/rudiment/consonance"
40
+ require "head_music/rudiment/interval_cycle"
41
+ require "head_music/rudiment/key_signature"
42
+ require "head_music/rudiment/key_signature/enharmonic_equivalence"
43
+ require "head_music/rudiment/letter_name"
44
+ require "head_music/rudiment/meter"
45
+ require "head_music/rudiment/musical_symbol"
46
+ require "head_music/rudiment/pitch"
47
+ require "head_music/rudiment/pitch/enharmonic_equivalence"
48
+ require "head_music/rudiment/pitch/octave_equivalence"
49
+ require "head_music/rudiment/pitch_class"
50
+ require "head_music/rudiment/pitch_class_set"
51
+ require "head_music/rudiment/pitch_set"
52
+ require "head_music/rudiment/quality"
53
+ require "head_music/rudiment/reference_pitch"
54
+ require "head_music/rudiment/register"
55
+ require "head_music/rudiment/rhythm"
56
+ require "head_music/rudiment/rhythmic_unit"
57
+ require "head_music/rudiment/scale"
58
+ require "head_music/rudiment/scale_degree"
59
+ require "head_music/rudiment/scale_type"
60
+ require "head_music/rudiment/solmization"
61
+ require "head_music/rudiment/sonority"
62
+ require "head_music/rudiment/spelling"
63
+ require "head_music/rudiment/tuning"
64
+
65
+ # instruments
66
+ require "head_music/instruments/instrument_family"
67
+ require "head_music/instruments/instrument"
68
+ require "head_music/instruments/staff_scheme"
69
+ require "head_music/instruments/staff"
70
+ require "head_music/instruments/variant"
79
71
 
80
72
  # content
81
73
  require "head_music/content/bar"
@@ -84,14 +76,26 @@ require "head_music/content/note"
84
76
  require "head_music/content/placement"
85
77
  require "head_music/content/position"
86
78
  require "head_music/content/rhythmic_value"
79
+ require "head_music/content/staff"
87
80
  require "head_music/content/voice"
88
81
 
89
82
  # analysis
83
+ require "head_music/analysis/diatonic_interval"
84
+ require "head_music/analysis/diatonic_interval/category"
85
+ require "head_music/analysis/diatonic_interval/naming"
86
+ require "head_music/analysis/diatonic_interval/parser"
87
+ require "head_music/analysis/diatonic_interval/semitones"
88
+ require "head_music/analysis/diatonic_interval/size"
89
+ require "head_music/analysis/harmonic_interval"
90
+ require "head_music/analysis/melodic_interval"
91
+ require "head_music/analysis/motion"
92
+
93
+ # style analysis
90
94
  require "head_music/style/analysis"
91
95
  require "head_music/style/annotation"
92
96
  require "head_music/style/mark"
93
97
 
94
- # guidelines
98
+ # style guidelines
95
99
  require "head_music/style/guidelines/always_move"
96
100
  require "head_music/style/guidelines/approach_perfection_contrarily"
97
101
  require "head_music/style/guidelines/at_least_eight_notes"
@@ -126,7 +130,7 @@ require "head_music/style/guidelines/step_to_final_note"
126
130
  require "head_music/style/guidelines/step_up_to_final_note"
127
131
  require "head_music/style/guidelines/up_to_fourteen_notes"
128
132
 
129
- # guides
133
+ # style guides
130
134
  require "head_music/style/guides/fux_cantus_firmus"
131
135
  require "head_music/style/guides/modern_cantus_firmus"
132
136
  require "head_music/style/guides/first_species_melody"
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: 7.0.4
4
+ version: 8.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob Head
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-02-23 00:00:00.000000000 Z
11
+ date: 2025-05-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -120,37 +120,30 @@ files:
120
120
  - bin/setup
121
121
  - head_music.gemspec
122
122
  - lib/head_music.rb
123
- - lib/head_music/alteration.rb
124
- - lib/head_music/chromatic_interval.rb
125
- - lib/head_music/circle.rb
126
- - lib/head_music/clef.rb
127
- - lib/head_music/consonance.rb
123
+ - lib/head_music/analysis/diatonic_interval.rb
124
+ - lib/head_music/analysis/diatonic_interval/category.rb
125
+ - lib/head_music/analysis/diatonic_interval/naming.rb
126
+ - lib/head_music/analysis/diatonic_interval/parser.rb
127
+ - lib/head_music/analysis/diatonic_interval/semitones.rb
128
+ - lib/head_music/analysis/diatonic_interval/size.rb
129
+ - lib/head_music/analysis/harmonic_interval.rb
130
+ - lib/head_music/analysis/melodic_interval.rb
131
+ - lib/head_music/analysis/motion.rb
128
132
  - lib/head_music/content/bar.rb
129
133
  - lib/head_music/content/composition.rb
130
134
  - lib/head_music/content/note.rb
131
135
  - lib/head_music/content/placement.rb
132
136
  - lib/head_music/content/position.rb
133
137
  - lib/head_music/content/rhythmic_value.rb
138
+ - lib/head_music/content/staff.rb
134
139
  - lib/head_music/content/voice.rb
135
- - lib/head_music/data/clefs.yml
136
- - lib/head_music/data/instrument_families.yml
137
- - lib/head_music/data/instruments.yml
138
- - lib/head_music/diatonic_interval.rb
139
- - lib/head_music/diatonic_interval/category.rb
140
- - lib/head_music/diatonic_interval/naming.rb
141
- - lib/head_music/diatonic_interval/parser.rb
142
- - lib/head_music/diatonic_interval/semitones.rb
143
- - lib/head_music/diatonic_interval/size.rb
144
- - lib/head_music/harmonic_interval.rb
145
- - lib/head_music/instrument.rb
146
- - lib/head_music/instrument/staff.rb
147
- - lib/head_music/instrument/staff_scheme.rb
148
- - lib/head_music/instrument/variant.rb
149
- - lib/head_music/instrument_family.rb
150
- - lib/head_music/interval_cycle.rb
151
- - lib/head_music/key_signature.rb
152
- - lib/head_music/key_signature/enharmonic_equivalence.rb
153
- - lib/head_music/letter_name.rb
140
+ - lib/head_music/instruments/instrument.rb
141
+ - lib/head_music/instruments/instrument_families.yml
142
+ - lib/head_music/instruments/instrument_family.rb
143
+ - lib/head_music/instruments/instruments.yml
144
+ - lib/head_music/instruments/staff.rb
145
+ - lib/head_music/instruments/staff_scheme.rb
146
+ - lib/head_music/instruments/variant.rb
154
147
  - lib/head_music/locales/de.yml
155
148
  - lib/head_music/locales/en.yml
156
149
  - lib/head_music/locales/en_GB.yml
@@ -158,30 +151,38 @@ files:
158
151
  - lib/head_music/locales/fr.yml
159
152
  - lib/head_music/locales/it.yml
160
153
  - lib/head_music/locales/ru.yml
161
- - lib/head_music/melodic_interval.rb
162
- - lib/head_music/meter.rb
163
- - lib/head_music/motion.rb
164
- - lib/head_music/musical_symbol.rb
165
154
  - lib/head_music/named.rb
166
- - lib/head_music/pitch.rb
167
- - lib/head_music/pitch/enharmonic_equivalence.rb
168
- - lib/head_music/pitch/octave_equivalence.rb
169
- - lib/head_music/pitch_class.rb
170
- - lib/head_music/pitch_class_set.rb
171
- - lib/head_music/pitch_set.rb
172
- - lib/head_music/quality.rb
173
- - lib/head_music/reference_pitch.rb
174
- - lib/head_music/register.rb
175
- - lib/head_music/rhythm.rb
176
- - lib/head_music/rhythmic_unit.rb
177
- - lib/head_music/scale.rb
178
- - lib/head_music/scale_degree.rb
179
- - lib/head_music/scale_type.rb
180
- - lib/head_music/solmization.rb
181
- - lib/head_music/solmizations.yml
182
- - lib/head_music/sonority.rb
183
- - lib/head_music/spelling.rb
184
- - lib/head_music/staff.rb
155
+ - lib/head_music/rudiment/alteration.rb
156
+ - lib/head_music/rudiment/chromatic_interval.rb
157
+ - lib/head_music/rudiment/circle.rb
158
+ - lib/head_music/rudiment/clef.rb
159
+ - lib/head_music/rudiment/clefs.yml
160
+ - lib/head_music/rudiment/consonance.rb
161
+ - lib/head_music/rudiment/interval_cycle.rb
162
+ - lib/head_music/rudiment/key_signature.rb
163
+ - lib/head_music/rudiment/key_signature/enharmonic_equivalence.rb
164
+ - lib/head_music/rudiment/letter_name.rb
165
+ - lib/head_music/rudiment/meter.rb
166
+ - lib/head_music/rudiment/musical_symbol.rb
167
+ - lib/head_music/rudiment/pitch.rb
168
+ - lib/head_music/rudiment/pitch/enharmonic_equivalence.rb
169
+ - lib/head_music/rudiment/pitch/octave_equivalence.rb
170
+ - lib/head_music/rudiment/pitch_class.rb
171
+ - lib/head_music/rudiment/pitch_class_set.rb
172
+ - lib/head_music/rudiment/pitch_set.rb
173
+ - lib/head_music/rudiment/quality.rb
174
+ - lib/head_music/rudiment/reference_pitch.rb
175
+ - lib/head_music/rudiment/register.rb
176
+ - lib/head_music/rudiment/rhythm.rb
177
+ - lib/head_music/rudiment/rhythmic_unit.rb
178
+ - lib/head_music/rudiment/scale.rb
179
+ - lib/head_music/rudiment/scale_degree.rb
180
+ - lib/head_music/rudiment/scale_type.rb
181
+ - lib/head_music/rudiment/solmization.rb
182
+ - lib/head_music/rudiment/solmizations.yml
183
+ - lib/head_music/rudiment/sonority.rb
184
+ - lib/head_music/rudiment/spelling.rb
185
+ - lib/head_music/rudiment/tuning.rb
185
186
  - lib/head_music/style/analysis.rb
186
187
  - lib/head_music/style/annotation.rb
187
188
  - lib/head_music/style/guidelines/always_move.rb
@@ -222,7 +223,6 @@ files:
222
223
  - lib/head_music/style/guides/fux_cantus_firmus.rb
223
224
  - lib/head_music/style/guides/modern_cantus_firmus.rb
224
225
  - lib/head_music/style/mark.rb
225
- - lib/head_music/tuning.rb
226
226
  - lib/head_music/utilities/hash_key.rb
227
227
  - lib/head_music/version.rb
228
228
  homepage: https://github.com/roberthead/head_music
@@ -244,7 +244,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
244
244
  - !ruby/object:Gem::Version
245
245
  version: '0'
246
246
  requirements: []
247
- rubygems_version: 3.4.10
247
+ rubygems_version: 3.5.6
248
248
  signing_key:
249
249
  specification_version: 4
250
250
  summary: The rudiments of western music theory.