head_music 8.2.1 → 8.3.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/.github/workflows/ci.yml +1 -1
- data/.github/workflows/release.yml +1 -1
- data/CLAUDE.md +134 -0
- data/Gemfile.lock +25 -25
- data/Rakefile +2 -2
- data/TODO.md +41 -150
- data/bin/check_instrument_consistency.rb +86 -0
- data/check_instrument_consistency.rb +0 -0
- data/head_music.gemspec +1 -1
- data/lib/head_music/analysis/diatonic_interval/naming.rb +1 -1
- data/lib/head_music/analysis/diatonic_interval.rb +28 -7
- data/lib/head_music/instruments/instrument_families.yml +10 -9
- data/lib/head_music/instruments/instruments.yml +350 -368
- data/lib/head_music/locales/en.yml +92 -0
- data/lib/head_music/rudiment/rhythmic_unit.rb +93 -26
- data/lib/head_music/rudiment/scale_degree.rb +8 -3
- data/lib/head_music/rudiment/tuning/just_intonation.rb +85 -0
- data/lib/head_music/rudiment/tuning/meantone.rb +87 -0
- data/lib/head_music/rudiment/tuning/pythagorean.rb +91 -0
- data/lib/head_music/rudiment/tuning.rb +17 -3
- data/lib/head_music/style/annotation.rb +4 -4
- data/lib/head_music/style/guidelines/notes_same_length.rb +16 -16
- data/lib/head_music/version.rb +1 -1
- data/lib/head_music.rb +3 -0
- data/user_stories/backlog/band-score-order.md +38 -0
- data/user_stories/backlog/chamber-ensemble-score-order.md +33 -0
- data/user_stories/backlog/consonance-dissonance-classification.md +57 -0
- data/user_stories/backlog/dyad-analysis.md +65 -0
- data/user_stories/backlog/orchestral-score-order.md +43 -0
- data/user_stories/backlog/pitch-class-set-analysis.md +39 -0
- data/user_stories/backlog/pitch-set-classification.md +62 -0
- data/user_stories/backlog/sonority-identification.md +47 -0
- metadata +18 -4
data/lib/head_music.rb
CHANGED
@@ -56,6 +56,9 @@ require "head_music/rudiment/scale_type"
|
|
56
56
|
require "head_music/rudiment/solmization"
|
57
57
|
require "head_music/rudiment/spelling"
|
58
58
|
require "head_music/rudiment/tuning"
|
59
|
+
require "head_music/rudiment/tuning/just_intonation"
|
60
|
+
require "head_music/rudiment/tuning/pythagorean"
|
61
|
+
require "head_music/rudiment/tuning/meantone"
|
59
62
|
|
60
63
|
# instruments
|
61
64
|
require "head_music/instruments/instrument_family"
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Band Score Order
|
2
|
+
|
3
|
+
As a band director or arranger
|
4
|
+
|
5
|
+
I want to organize instruments in band score order
|
6
|
+
|
7
|
+
So that my scores follow standard concert band conventions
|
8
|
+
|
9
|
+
## Scenario: Display instruments in band order
|
10
|
+
|
11
|
+
Given I have a composition for concert band
|
12
|
+
|
13
|
+
When I request the score order for a band arrangement
|
14
|
+
|
15
|
+
Then the instruments should be ordered as follows:
|
16
|
+
- Flutes
|
17
|
+
- Oboes
|
18
|
+
- Bassoons
|
19
|
+
- Clarinets
|
20
|
+
- Saxophones
|
21
|
+
- Cornets
|
22
|
+
- Trumpets
|
23
|
+
- Horns
|
24
|
+
- Trombones
|
25
|
+
- Euphoniums
|
26
|
+
- Tubas
|
27
|
+
- Timpani
|
28
|
+
- Percussion
|
29
|
+
|
30
|
+
## Scenario: Recognize different percussion placement
|
31
|
+
|
32
|
+
Given I am working with both orchestral and band scores
|
33
|
+
|
34
|
+
When I compare the score orders
|
35
|
+
|
36
|
+
Then I should note that percussion placement differs:
|
37
|
+
- In orchestral scores: percussion appears after brass
|
38
|
+
- In band scores: percussion appears at the bottom
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Chamber Ensemble Score Order
|
2
|
+
|
3
|
+
As a chamber music composer
|
4
|
+
|
5
|
+
I want to organize instruments in standard chamber ensemble orders
|
6
|
+
|
7
|
+
So that my scores follow established conventions for small ensembles
|
8
|
+
|
9
|
+
## Scenario: Display brass quintet in standard order
|
10
|
+
|
11
|
+
Given I have a brass quintet composition
|
12
|
+
|
13
|
+
When I request the score order
|
14
|
+
|
15
|
+
Then the instruments should be ordered as follows:
|
16
|
+
- Trumpet I
|
17
|
+
- Trumpet II
|
18
|
+
- Horn
|
19
|
+
- Trombone
|
20
|
+
- Tuba
|
21
|
+
|
22
|
+
## Scenario: Display woodwind quintet in standard order
|
23
|
+
|
24
|
+
Given I have a woodwind quintet composition
|
25
|
+
|
26
|
+
When I request the score order
|
27
|
+
|
28
|
+
Then the instruments should be ordered as follows:
|
29
|
+
- Flute
|
30
|
+
- Oboe
|
31
|
+
- Clarinet
|
32
|
+
- Horn
|
33
|
+
- Bassoon
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# Consonance and Dissonance Classification
|
2
|
+
|
3
|
+
As a music theorist or counterpoint student
|
4
|
+
|
5
|
+
I want to classify intervals by their consonance and dissonance levels
|
6
|
+
|
7
|
+
So that I can apply proper voice leading rules
|
8
|
+
|
9
|
+
## Scenario: Classify open consonances
|
10
|
+
|
11
|
+
Given I have a perfect fifth or perfect octave
|
12
|
+
|
13
|
+
When I check the consonance classification
|
14
|
+
|
15
|
+
Then it should be identified as "open consonance"
|
16
|
+
|
17
|
+
## Scenario: Classify soft consonances
|
18
|
+
|
19
|
+
Given I have a third or sixth interval (major or minor)
|
20
|
+
|
21
|
+
When I check the consonance classification
|
22
|
+
|
23
|
+
Then it should be identified as "soft consonance"
|
24
|
+
|
25
|
+
## Scenario: Classify mild dissonances
|
26
|
+
|
27
|
+
Given I have a major second or minor seventh
|
28
|
+
|
29
|
+
When I check the consonance classification
|
30
|
+
|
31
|
+
Then it should be identified as "mild dissonance"
|
32
|
+
|
33
|
+
## Scenario: Classify sharp dissonances
|
34
|
+
|
35
|
+
Given I have a minor second or major seventh
|
36
|
+
|
37
|
+
When I check the consonance classification
|
38
|
+
|
39
|
+
Then it should be identified as "sharp dissonance"
|
40
|
+
|
41
|
+
## Scenario: Handle perfect fourth context
|
42
|
+
|
43
|
+
Given I have a perfect fourth interval
|
44
|
+
|
45
|
+
When I check the consonance classification
|
46
|
+
|
47
|
+
Then it should indicate context-dependent classification
|
48
|
+
|
49
|
+
And note it can be either consonant or dissonant
|
50
|
+
|
51
|
+
## Scenario: Classify tritone
|
52
|
+
|
53
|
+
Given I have a tritone interval
|
54
|
+
|
55
|
+
When I check the consonance classification
|
56
|
+
|
57
|
+
Then it should be identified as "neutral" or "restless"
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# Dyad Analysis
|
2
|
+
|
3
|
+
As a music analyst or counterpoint student
|
4
|
+
|
5
|
+
I want to analyze two-note combinations (dyads)
|
6
|
+
|
7
|
+
So that I can understand harmonic implications in two-part music
|
8
|
+
|
9
|
+
## Scenario: Identify interval in dyad
|
10
|
+
|
11
|
+
Given I have two pitches forming a dyad
|
12
|
+
|
13
|
+
When I access the interval property
|
14
|
+
|
15
|
+
Then I should receive the correct interval between the pitches
|
16
|
+
|
17
|
+
## Scenario: Find implied triads from thirds
|
18
|
+
|
19
|
+
Given I have a dyad that forms a third
|
20
|
+
|
21
|
+
When I request the implied triad
|
22
|
+
|
23
|
+
Then I should receive the most likely triad containing those pitches
|
24
|
+
|
25
|
+
And it should consider the musical context
|
26
|
+
|
27
|
+
## Scenario: List possible triads from fifth
|
28
|
+
|
29
|
+
Given I have a dyad forming a perfect fifth
|
30
|
+
|
31
|
+
When I request possible triads
|
32
|
+
|
33
|
+
Then I should receive both major and minor triad options
|
34
|
+
|
35
|
+
And each should contain the given pitches
|
36
|
+
|
37
|
+
## Scenario: List possible triads from third
|
38
|
+
|
39
|
+
Given I have a dyad forming a minor third
|
40
|
+
|
41
|
+
When I request possible triads
|
42
|
+
|
43
|
+
Then I should receive minor and diminished triad options
|
44
|
+
|
45
|
+
And for a major third I should receive major and augmented options
|
46
|
+
|
47
|
+
## Scenario: Find possible seventh chords
|
48
|
+
|
49
|
+
Given I have a dyad
|
50
|
+
|
51
|
+
When I request possible seventh chords
|
52
|
+
|
53
|
+
Then I should receive all seventh chords containing those pitches
|
54
|
+
|
55
|
+
And they should include appropriate inversions
|
56
|
+
|
57
|
+
## Scenario: Handle enharmonic possibilities
|
58
|
+
|
59
|
+
Given I have a dyad with enharmonic possibilities
|
60
|
+
|
61
|
+
When I request possible enharmonic chords
|
62
|
+
|
63
|
+
Then I should receive chords based on enharmonic respellings
|
64
|
+
|
65
|
+
And each should be correctly identified
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# Orchestral Score Order
|
2
|
+
|
3
|
+
As a composer or conductor
|
4
|
+
|
5
|
+
I want to organize instruments in orchestral score order
|
6
|
+
|
7
|
+
So that my scores follow standard orchestral conventions
|
8
|
+
|
9
|
+
## Scenario: Display instruments in orchestral order
|
10
|
+
|
11
|
+
Given I have a composition with multiple instruments
|
12
|
+
|
13
|
+
When I request the score order for an orchestral arrangement
|
14
|
+
|
15
|
+
Then the instruments should be ordered as follows:
|
16
|
+
- Woodwinds (flutes, oboes, clarinets, bassoons)
|
17
|
+
- Brass (horns, trumpets, trombones, tuba)
|
18
|
+
- Percussion (timpani, percussion)
|
19
|
+
- Harp and keyboards
|
20
|
+
- Soloists (instrumental or vocal)
|
21
|
+
- Voices
|
22
|
+
- Strings (violins I, violins II, viola, violoncellos, double bass)
|
23
|
+
|
24
|
+
## Scenario: Use standard orchestral abbreviations
|
25
|
+
|
26
|
+
Given I am creating an orchestral score
|
27
|
+
|
28
|
+
When I display instrument names
|
29
|
+
|
30
|
+
Then I should see standard abbreviations:
|
31
|
+
- Fl or Fls for Flutes
|
32
|
+
- Ob or Obs for Oboes
|
33
|
+
- Cl or Cls for Clarinets
|
34
|
+
- Bsn or Bsns for Bassoons
|
35
|
+
- Hn or Hns for Horns
|
36
|
+
- Tpt or Tpts for Trumpets
|
37
|
+
- Trb or Trbs for Trombones
|
38
|
+
- Timp for Timpani
|
39
|
+
- Perc for Percussion
|
40
|
+
- Vlns for Violins
|
41
|
+
- Vla for Viola
|
42
|
+
- Vcl for Violoncellos
|
43
|
+
- DB for Double Bass
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Pitch Class Set Analysis
|
2
|
+
|
3
|
+
As a music theorist studying atonal music
|
4
|
+
|
5
|
+
I want to analyze pitch class sets
|
6
|
+
|
7
|
+
So that I can identify set relationships and transformations
|
8
|
+
|
9
|
+
## Scenario: Find normal form
|
10
|
+
|
11
|
+
Given I have a pitch class set
|
12
|
+
|
13
|
+
When I request the normal form
|
14
|
+
|
15
|
+
Then I should receive the most compact rotation
|
16
|
+
|
17
|
+
And it should minimize the interval span
|
18
|
+
|
19
|
+
## Scenario: Find prime form
|
20
|
+
|
21
|
+
Given I have a pitch class set
|
22
|
+
|
23
|
+
When I request the prime form
|
24
|
+
|
25
|
+
Then I should receive the most compact form
|
26
|
+
|
27
|
+
And it should consider both the original and all inversions
|
28
|
+
|
29
|
+
And it should be the optimal normal form among all possibilities
|
30
|
+
|
31
|
+
## Scenario: Compare equivalent sets
|
32
|
+
|
33
|
+
Given I have two different pitch class sets
|
34
|
+
|
35
|
+
When I compare their prime forms
|
36
|
+
|
37
|
+
Then I can determine if they are equivalent
|
38
|
+
|
39
|
+
And identify the transformation relationship between them
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Pitch Set Classification
|
2
|
+
|
3
|
+
As a music theorist
|
4
|
+
|
5
|
+
I want to classify pitch sets by their size and properties
|
6
|
+
|
7
|
+
So that I can analyze and categorize harmonic structures
|
8
|
+
|
9
|
+
## Scenario: Identify empty set
|
10
|
+
|
11
|
+
Given I have no pitches
|
12
|
+
|
13
|
+
When I create a pitch set
|
14
|
+
|
15
|
+
Then it should be identified as an EmptySet
|
16
|
+
|
17
|
+
## Scenario: Identify monad
|
18
|
+
|
19
|
+
Given I have a single pitch
|
20
|
+
|
21
|
+
When I check the pitch set type
|
22
|
+
|
23
|
+
Then it should be identified as a Monad
|
24
|
+
|
25
|
+
And monad? should return true
|
26
|
+
|
27
|
+
## Scenario: Identify dyad
|
28
|
+
|
29
|
+
Given I have exactly two pitches
|
30
|
+
|
31
|
+
When I check the pitch set type
|
32
|
+
|
33
|
+
Then it should be identified as a Dyad
|
34
|
+
|
35
|
+
And dyad? should return true
|
36
|
+
|
37
|
+
## Scenario: Distinguish triads from trichords
|
38
|
+
|
39
|
+
Given I have three pitches
|
40
|
+
|
41
|
+
When I analyze the pitch set
|
42
|
+
|
43
|
+
Then trichord? should return true for any 3-pitch set
|
44
|
+
|
45
|
+
And triad? should return true only if they form stacked thirds
|
46
|
+
|
47
|
+
## Scenario: Identify larger pitch sets
|
48
|
+
|
49
|
+
Given I have a pitch set with N pitches
|
50
|
+
|
51
|
+
When I check the classification
|
52
|
+
|
53
|
+
Then it should be identified as:
|
54
|
+
- Tetrachord (4 pitches) with seventh_chord? check
|
55
|
+
- Pentachord (5 pitches)
|
56
|
+
- Hexachord (6 pitches)
|
57
|
+
- Heptachord (7 pitches)
|
58
|
+
- Octachord (8 pitches)
|
59
|
+
- Nonachord (9 pitches)
|
60
|
+
- Decachord (10 pitches)
|
61
|
+
- Undecachord (11 pitches)
|
62
|
+
- Dodecachord (12 pitches)
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# Sonority Identification
|
2
|
+
|
3
|
+
As a music theorist or composer
|
4
|
+
|
5
|
+
I want to identify and work with named sonorities
|
6
|
+
|
7
|
+
So that I can analyze and create harmonic structures
|
8
|
+
|
9
|
+
## Scenario: Get sonority by identifier
|
10
|
+
|
11
|
+
Given I need a specific sonority
|
12
|
+
|
13
|
+
When I call Sonority.get with an identifier like "major triad"
|
14
|
+
|
15
|
+
Then I should receive the corresponding sonority object
|
16
|
+
|
17
|
+
And it should contain the correct interval structure
|
18
|
+
|
19
|
+
## Scenario: Identify sonority from pitch set
|
20
|
+
|
21
|
+
Given I have a set of pitches
|
22
|
+
|
23
|
+
When I call Sonority.for with the pitch set
|
24
|
+
|
25
|
+
Then I should receive the identified sonority
|
26
|
+
|
27
|
+
And it should correctly name the harmonic structure
|
28
|
+
|
29
|
+
## Scenario: Generate pitch set from sonority
|
30
|
+
|
31
|
+
Given I have a sonority and a root pitch
|
32
|
+
|
33
|
+
When I call Sonority.pitch_set_for with root pitch and inversion
|
34
|
+
|
35
|
+
Then I should receive the correct pitches
|
36
|
+
|
37
|
+
And they should be in the specified inversion
|
38
|
+
|
39
|
+
## Scenario: Access sonority from pitch set
|
40
|
+
|
41
|
+
Given I have a PitchSet object
|
42
|
+
|
43
|
+
When I call the sonority method
|
44
|
+
|
45
|
+
Then I should receive the corresponding Sonority object
|
46
|
+
|
47
|
+
And it should correctly identify the harmonic content
|
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: 8.
|
4
|
+
version: 8.3.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: 2025-
|
11
|
+
date: 2025-07-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
89
|
+
version: '2.0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
96
|
+
version: '2.0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: bundler-audit
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -144,6 +144,7 @@ files:
|
|
144
144
|
- ".ruby-version"
|
145
145
|
- ".yardopts"
|
146
146
|
- CHANGELOG.md
|
147
|
+
- CLAUDE.md
|
147
148
|
- CODE_OF_CONDUCT.md
|
148
149
|
- CONTRIBUTING.md
|
149
150
|
- Gemfile
|
@@ -152,8 +153,10 @@ files:
|
|
152
153
|
- README.md
|
153
154
|
- Rakefile
|
154
155
|
- TODO.md
|
156
|
+
- bin/check_instrument_consistency.rb
|
155
157
|
- bin/console
|
156
158
|
- bin/setup
|
159
|
+
- check_instrument_consistency.rb
|
157
160
|
- head_music.gemspec
|
158
161
|
- lib/head_music.rb
|
159
162
|
- lib/head_music/analysis/circle.rb
|
@@ -219,6 +222,9 @@ files:
|
|
219
222
|
- lib/head_music/rudiment/solmizations.yml
|
220
223
|
- lib/head_music/rudiment/spelling.rb
|
221
224
|
- lib/head_music/rudiment/tuning.rb
|
225
|
+
- lib/head_music/rudiment/tuning/just_intonation.rb
|
226
|
+
- lib/head_music/rudiment/tuning/meantone.rb
|
227
|
+
- lib/head_music/rudiment/tuning/pythagorean.rb
|
222
228
|
- lib/head_music/style/analysis.rb
|
223
229
|
- lib/head_music/style/annotation.rb
|
224
230
|
- lib/head_music/style/guidelines/always_move.rb
|
@@ -262,6 +268,14 @@ files:
|
|
262
268
|
- lib/head_music/utilities/hash_key.rb
|
263
269
|
- lib/head_music/version.rb
|
264
270
|
- test_translations.rb
|
271
|
+
- user_stories/backlog/band-score-order.md
|
272
|
+
- user_stories/backlog/chamber-ensemble-score-order.md
|
273
|
+
- user_stories/backlog/consonance-dissonance-classification.md
|
274
|
+
- user_stories/backlog/dyad-analysis.md
|
275
|
+
- user_stories/backlog/orchestral-score-order.md
|
276
|
+
- user_stories/backlog/pitch-class-set-analysis.md
|
277
|
+
- user_stories/backlog/pitch-set-classification.md
|
278
|
+
- user_stories/backlog/sonority-identification.md
|
265
279
|
homepage: https://github.com/roberthead/head_music
|
266
280
|
licenses:
|
267
281
|
- MIT
|