head_music 0.18.0 → 0.19.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.
- checksums.yaml +4 -4
- data/lib/head_music/chord.rb +2 -2
- data/lib/head_music/{bar.rb → content/bar.rb} +0 -0
- data/lib/head_music/{composition.rb → content/composition.rb} +5 -1
- data/lib/head_music/{note.rb → content/note.rb} +0 -0
- data/lib/head_music/{placement.rb → content/placement.rb} +6 -6
- data/lib/head_music/{position.rb → content/position.rb} +1 -1
- data/lib/head_music/{rhythmic_value.rb → content/rhythmic_value.rb} +4 -0
- data/lib/head_music/{voice.rb → content/voice.rb} +5 -3
- data/lib/head_music/key_signature.rb +1 -1
- data/lib/head_music/scale.rb +2 -2
- data/lib/head_music/style/annotation.rb +3 -4
- data/lib/head_music/style/annotations/always_move.rb +3 -3
- data/lib/head_music/style/annotations/direction_changes.rb +2 -3
- data/lib/head_music/style/annotations/end_on_tonic.rb +1 -1
- data/lib/head_music/style/annotations/mostly_conjunct.rb +3 -3
- data/lib/head_music/style/annotations/singable_range.rb +1 -1
- data/lib/head_music/version.rb +1 -1
- data/lib/head_music.rb +9 -8
- metadata +9 -10
- data/lib/head_music/language.rb +0 -61
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17a6cfc4f189a661c7f095056b429e32ce17468a
|
4
|
+
data.tar.gz: d3a3cc4b18e87fa0f7af9ba584b5f28946329784
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2e9b674c4bde48f3ce71ef0768b60461f3af1ebfcfc501ab9500af24b9b61cbc071f176a43d064fba5e5d9e83f0bc53ee80ffd8d34551ea2bd2777926437f1dc
|
7
|
+
data.tar.gz: 04fb64922f6c47d6df0f0cb637ad68b188fffe448dbefe02992aa85169c6ae8993b83383bdf59118391e94c3651ea76ddb7c52c9dd7b93d266d9a0aa8a9d28f0
|
data/lib/head_music/chord.rb
CHANGED
@@ -34,8 +34,8 @@ class HeadMusic::Chord
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def intervals
|
37
|
-
pitches.
|
38
|
-
HeadMusic::FunctionalInterval.new(
|
37
|
+
pitches.each_cons(2).map do |pitch_pair|
|
38
|
+
HeadMusic::FunctionalInterval.new(*pitch_pair)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
File without changes
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# A composition is
|
3
|
+
# A composition is musical content.
|
4
4
|
class HeadMusic::Composition
|
5
5
|
attr_reader :name, :key_signature, :meter, :voices
|
6
6
|
|
@@ -56,6 +56,10 @@ class HeadMusic::Composition
|
|
56
56
|
voices.reject(&:cantus_firmus?).first
|
57
57
|
end
|
58
58
|
|
59
|
+
def to_s
|
60
|
+
"#{name} — #{voices.count} voice(s)"
|
61
|
+
end
|
62
|
+
|
59
63
|
private
|
60
64
|
|
61
65
|
def ensure_attributes(name, key_signature, meter)
|
File without changes
|
@@ -29,25 +29,25 @@ class HeadMusic::Placement
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def during?(other_placement)
|
32
|
-
starts_during?(other_placement) || ends_during?(other_placement) ||
|
32
|
+
starts_during?(other_placement) || ends_during?(other_placement) || wraps?(other_placement)
|
33
33
|
end
|
34
34
|
|
35
35
|
def to_s
|
36
|
-
"#{pitch ? pitch : 'rest'} at #{position}"
|
36
|
+
"#{rhythmic_value} #{pitch ? pitch : 'rest'} at #{position}"
|
37
37
|
end
|
38
38
|
|
39
39
|
private
|
40
40
|
|
41
41
|
def starts_during?(other_placement)
|
42
|
-
|
42
|
+
position >= other_placement.position && position < other_placement.next_position
|
43
43
|
end
|
44
44
|
|
45
45
|
def ends_during?(other_placement)
|
46
|
-
|
46
|
+
next_position > other_placement.position && next_position <= other_placement.next_position
|
47
47
|
end
|
48
48
|
|
49
|
-
def
|
50
|
-
|
49
|
+
def wraps?(other_placement)
|
50
|
+
position <= other_placement.position && next_position >= other_placement.next_position
|
51
51
|
end
|
52
52
|
|
53
53
|
def ensure_attributes(voice, position, rhythmic_value, pitch)
|
@@ -95,7 +95,7 @@ end
|
|
95
95
|
|
96
96
|
# In Logic Pro X, the 'beat' is determined by the denominator, even if compound.
|
97
97
|
# Logic then divides the beat into 'divisions' that are a sixteenth in length.
|
98
|
-
# Each division is then divided into 240 ticks (960 PPQN / 4 sixteenths-per-quarter)
|
98
|
+
# Each division is then divided into 240 ticks (960 PPQN / 4 sixteenths-per-quarter = 240 ticks per sixteenth note)
|
99
99
|
|
100
100
|
# Tempo specifies the beat unit, usually the traditional beat unit in the case of compound meters,
|
101
101
|
# so 6/8 would specify [dotted-quarter] = 132 (or whatever).
|
@@ -59,9 +59,7 @@ class HeadMusic::Voice
|
|
59
59
|
|
60
60
|
def melodic_intervals
|
61
61
|
@melodic_intervals ||=
|
62
|
-
notes.map
|
63
|
-
HeadMusic::MelodicInterval.new(notes[i - 1], note) if i.positive?
|
64
|
-
end.compact
|
62
|
+
notes.each_cons(2).map { |note_pair| HeadMusic::MelodicInterval.new(*note_pair) }
|
65
63
|
end
|
66
64
|
|
67
65
|
def leaps
|
@@ -102,6 +100,10 @@ class HeadMusic::Voice
|
|
102
100
|
placements.last.position.bar_number
|
103
101
|
end
|
104
102
|
|
103
|
+
def to_s
|
104
|
+
"#{role}: #{pitches.first(10).map(&:to_s)}"
|
105
|
+
end
|
106
|
+
|
105
107
|
private
|
106
108
|
|
107
109
|
def insert_into_placements(placement)
|
data/lib/head_music/scale.rb
CHANGED
@@ -61,9 +61,9 @@ class HeadMusic::Scale
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def octave_scale_pitches(direction, semitones_from_root)
|
64
|
-
direction_intervals(direction).map.with_index do |semitones, i|
|
64
|
+
direction_intervals(direction).map.with_index(1) do |semitones, i|
|
65
65
|
semitones_from_root += semitones * direction_sign(direction)
|
66
|
-
pitch_for_step(i
|
66
|
+
pitch_for_step(i, semitones_from_root, direction)
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
@@ -101,10 +101,9 @@ class HeadMusic::Style::Annotation
|
|
101
101
|
end
|
102
102
|
|
103
103
|
def motions
|
104
|
-
downbeat_harmonic_intervals.map
|
105
|
-
|
106
|
-
|
107
|
-
end.compact
|
104
|
+
downbeat_harmonic_intervals.each_cons(2).map do |harmonic_interval_pair|
|
105
|
+
HeadMusic::Motion.new(*harmonic_interval_pair)
|
106
|
+
end
|
108
107
|
end
|
109
108
|
|
110
109
|
def downbeat_harmonic_intervals
|
@@ -8,8 +8,8 @@ class HeadMusic::Style::Annotations::AlwaysMove < HeadMusic::Style::Annotation
|
|
8
8
|
MESSAGE = 'Always move to a different note.'
|
9
9
|
|
10
10
|
def marks
|
11
|
-
melodic_intervals.
|
12
|
-
|
13
|
-
|
11
|
+
melodic_intervals.
|
12
|
+
select { |interval| interval.perfect? && interval.unison? }.
|
13
|
+
map { |interval| HeadMusic::Style::Mark.for_all(interval.notes) }
|
14
14
|
end
|
15
15
|
end
|
@@ -23,9 +23,8 @@ class HeadMusic::Style::Annotations::DirectionChanges < HeadMusic::Style::Annota
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def melodic_intervals_changing_direction
|
26
|
-
melodic_intervals.
|
27
|
-
|
28
|
-
interval.direction != previous_direction
|
26
|
+
melodic_intervals.each_cons(2).reject do |interval_pair|
|
27
|
+
interval_pair[0].direction == interval_pair[1].direction
|
29
28
|
end
|
30
29
|
end
|
31
30
|
end
|
@@ -8,7 +8,7 @@ class HeadMusic::Style::Annotations::EndOnTonic < HeadMusic::Style::Annotation
|
|
8
8
|
MESSAGE = 'End on the first scale degree.'
|
9
9
|
|
10
10
|
def marks
|
11
|
-
HeadMusic::Style::Mark.for(notes.last) if
|
11
|
+
HeadMusic::Style::Mark.for(notes.last) if notes.any? && !ends_on_tonic?
|
12
12
|
end
|
13
13
|
|
14
14
|
private
|
@@ -18,9 +18,9 @@ class HeadMusic::Style::Annotations::MostlyConjunct < HeadMusic::Style::Annotati
|
|
18
18
|
private
|
19
19
|
|
20
20
|
def marks_for_skips_and_leaps
|
21
|
-
melodic_intervals.
|
22
|
-
|
23
|
-
|
21
|
+
melodic_intervals.
|
22
|
+
reject(&:step?).
|
23
|
+
map { |interval| HeadMusic::Style::Mark.for_all(interval.notes, fitness: HeadMusic::SMALL_PENALTY_FACTOR) }
|
24
24
|
end
|
25
25
|
|
26
26
|
def conjunct_ratio
|
data/lib/head_music/version.rb
CHANGED
data/lib/head_music.rb
CHANGED
@@ -20,11 +20,9 @@ require 'head_music/utilities/hash_key'
|
|
20
20
|
require 'head_music/named_rudiment'
|
21
21
|
|
22
22
|
# rudiments
|
23
|
-
require 'head_music/bar'
|
24
23
|
require 'head_music/chord'
|
25
24
|
require 'head_music/circle'
|
26
25
|
require 'head_music/clef'
|
27
|
-
require 'head_music/composition'
|
28
26
|
require 'head_music/consonance'
|
29
27
|
require 'head_music/functional_interval'
|
30
28
|
require 'head_music/grand_staff'
|
@@ -32,28 +30,31 @@ require 'head_music/harmonic_interval'
|
|
32
30
|
require 'head_music/instrument'
|
33
31
|
require 'head_music/interval'
|
34
32
|
require 'head_music/key_signature'
|
35
|
-
require 'head_music/language'
|
36
33
|
require 'head_music/letter_name'
|
37
34
|
require 'head_music/melodic_interval'
|
38
35
|
require 'head_music/meter'
|
39
36
|
require 'head_music/motion'
|
40
|
-
require 'head_music/note'
|
41
37
|
require 'head_music/octave'
|
42
38
|
require 'head_music/pitch'
|
43
39
|
require 'head_music/pitch_class'
|
44
|
-
require 'head_music/placement'
|
45
|
-
require 'head_music/position'
|
46
40
|
require 'head_music/quality'
|
47
41
|
require 'head_music/rhythm'
|
48
42
|
require 'head_music/rhythmic_unit'
|
49
|
-
require 'head_music/rhythmic_value'
|
50
43
|
require 'head_music/scale'
|
51
44
|
require 'head_music/scale_degree'
|
52
45
|
require 'head_music/scale_type'
|
53
46
|
require 'head_music/sign'
|
54
47
|
require 'head_music/spelling'
|
55
48
|
require 'head_music/staff'
|
56
|
-
|
49
|
+
|
50
|
+
# content
|
51
|
+
require 'head_music/content/bar'
|
52
|
+
require 'head_music/content/composition'
|
53
|
+
require 'head_music/content/note'
|
54
|
+
require 'head_music/content/placement'
|
55
|
+
require 'head_music/content/position'
|
56
|
+
require 'head_music/content/rhythmic_value'
|
57
|
+
require 'head_music/content/voice'
|
57
58
|
|
58
59
|
# analysis
|
59
60
|
require 'head_music/style/analysis'
|
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.
|
4
|
+
version: 0.19.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: 2018-
|
11
|
+
date: 2018-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -116,34 +116,34 @@ files:
|
|
116
116
|
- circle.yml
|
117
117
|
- head_music.gemspec
|
118
118
|
- lib/head_music.rb
|
119
|
-
- lib/head_music/bar.rb
|
120
119
|
- lib/head_music/chord.rb
|
121
120
|
- lib/head_music/circle.rb
|
122
121
|
- lib/head_music/clef.rb
|
123
|
-
- lib/head_music/composition.rb
|
124
122
|
- lib/head_music/consonance.rb
|
123
|
+
- lib/head_music/content/bar.rb
|
124
|
+
- lib/head_music/content/composition.rb
|
125
|
+
- lib/head_music/content/note.rb
|
126
|
+
- lib/head_music/content/placement.rb
|
127
|
+
- lib/head_music/content/position.rb
|
128
|
+
- lib/head_music/content/rhythmic_value.rb
|
129
|
+
- lib/head_music/content/voice.rb
|
125
130
|
- lib/head_music/functional_interval.rb
|
126
131
|
- lib/head_music/grand_staff.rb
|
127
132
|
- lib/head_music/harmonic_interval.rb
|
128
133
|
- lib/head_music/instrument.rb
|
129
134
|
- lib/head_music/interval.rb
|
130
135
|
- lib/head_music/key_signature.rb
|
131
|
-
- lib/head_music/language.rb
|
132
136
|
- lib/head_music/letter_name.rb
|
133
137
|
- lib/head_music/melodic_interval.rb
|
134
138
|
- lib/head_music/meter.rb
|
135
139
|
- lib/head_music/motion.rb
|
136
140
|
- lib/head_music/named_rudiment.rb
|
137
|
-
- lib/head_music/note.rb
|
138
141
|
- lib/head_music/octave.rb
|
139
142
|
- lib/head_music/pitch.rb
|
140
143
|
- lib/head_music/pitch_class.rb
|
141
|
-
- lib/head_music/placement.rb
|
142
|
-
- lib/head_music/position.rb
|
143
144
|
- lib/head_music/quality.rb
|
144
145
|
- lib/head_music/rhythm.rb
|
145
146
|
- lib/head_music/rhythmic_unit.rb
|
146
|
-
- lib/head_music/rhythmic_value.rb
|
147
147
|
- lib/head_music/scale.rb
|
148
148
|
- lib/head_music/scale_degree.rb
|
149
149
|
- lib/head_music/scale_type.rb
|
@@ -192,7 +192,6 @@ files:
|
|
192
192
|
- lib/head_music/style/rulesets/modern_cantus_firmus.rb
|
193
193
|
- lib/head_music/utilities/hash_key.rb
|
194
194
|
- lib/head_music/version.rb
|
195
|
-
- lib/head_music/voice.rb
|
196
195
|
homepage: https://github.com/roberthead/head_music
|
197
196
|
licenses:
|
198
197
|
- MIT
|
data/lib/head_music/language.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# A language.
|
4
|
-
class HeadMusic::Language
|
5
|
-
include Comparable
|
6
|
-
include HeadMusic::NamedRudiment
|
7
|
-
|
8
|
-
LANGUAGES = [
|
9
|
-
{ name: 'American English', short_name: 'English', abbreviation: 'en-US' },
|
10
|
-
{ name: 'British English', abbreviation: 'en-GB' },
|
11
|
-
{ name: 'French', native_name: 'Français', abbreviation: 'fr' },
|
12
|
-
{ name: 'German', native_name: 'Deutsche', abbreviation: 'de' },
|
13
|
-
{ name: 'Italian', native_name: 'Italiano', abbreviation: 'it' },
|
14
|
-
{ name: 'Spanish', native_name: 'Español', abbreviation: 'es' },
|
15
|
-
{ name: 'Russian', native_name: 'русский', abbreviation: 'ru' },
|
16
|
-
].freeze
|
17
|
-
|
18
|
-
LANGUAGES.
|
19
|
-
map { |language| ::HeadMusic::Utilities::HashKey.for(language[:name]) }.
|
20
|
-
each { |language_key| define_singleton_method(language_key) { HeadMusic::Language.get(language_key) } }
|
21
|
-
|
22
|
-
LANGUAGES.
|
23
|
-
map { |language| ::HeadMusic::Utilities::HashKey.for(language[:native_name]) }.
|
24
|
-
reject(&:nil?).
|
25
|
-
each { |language_key| define_singleton_method(language_key) { HeadMusic::Language.get(language_key) } }
|
26
|
-
|
27
|
-
LANGUAGES.
|
28
|
-
map { |language| ::HeadMusic::Utilities::HashKey.for(language[:short_name]) }.
|
29
|
-
reject(&:nil?).
|
30
|
-
each { |language_key| define_singleton_method(language_key) { HeadMusic::Language.get(language_key) } }
|
31
|
-
|
32
|
-
def self.default
|
33
|
-
english
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.get(name)
|
37
|
-
get_by_name(name) || default
|
38
|
-
end
|
39
|
-
|
40
|
-
attr_accessor :name, :native_name, :short_name
|
41
|
-
|
42
|
-
def initialize(identifier)
|
43
|
-
identifier_key = HeadMusic::Utilities::HashKey.for(identifier)
|
44
|
-
language_data = LANGUAGES.detect do |data|
|
45
|
-
%i[name native_name short_name].
|
46
|
-
map { |key| HeadMusic::Utilities::HashKey.for(data[key]) }.
|
47
|
-
include?(identifier_key)
|
48
|
-
end
|
49
|
-
@name = language_data[:name]
|
50
|
-
@native_name = language_data[:native_name]
|
51
|
-
@short_name = language_data[:short_name]
|
52
|
-
end
|
53
|
-
|
54
|
-
def <=>(other)
|
55
|
-
name.to_s <=> other.to_s
|
56
|
-
end
|
57
|
-
|
58
|
-
def inspect
|
59
|
-
[name, native_name, short_name].reject(&:nil?).join(' / ')
|
60
|
-
end
|
61
|
-
end
|