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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +1 -1
  3. data/.github/workflows/release.yml +1 -1
  4. data/CLAUDE.md +134 -0
  5. data/Gemfile.lock +25 -25
  6. data/Rakefile +2 -2
  7. data/TODO.md +41 -150
  8. data/bin/check_instrument_consistency.rb +86 -0
  9. data/check_instrument_consistency.rb +0 -0
  10. data/head_music.gemspec +1 -1
  11. data/lib/head_music/analysis/diatonic_interval/naming.rb +1 -1
  12. data/lib/head_music/analysis/diatonic_interval.rb +28 -7
  13. data/lib/head_music/instruments/instrument_families.yml +10 -9
  14. data/lib/head_music/instruments/instruments.yml +350 -368
  15. data/lib/head_music/locales/en.yml +92 -0
  16. data/lib/head_music/rudiment/rhythmic_unit.rb +93 -26
  17. data/lib/head_music/rudiment/scale_degree.rb +8 -3
  18. data/lib/head_music/rudiment/tuning/just_intonation.rb +85 -0
  19. data/lib/head_music/rudiment/tuning/meantone.rb +87 -0
  20. data/lib/head_music/rudiment/tuning/pythagorean.rb +91 -0
  21. data/lib/head_music/rudiment/tuning.rb +17 -3
  22. data/lib/head_music/style/annotation.rb +4 -4
  23. data/lib/head_music/style/guidelines/notes_same_length.rb +16 -16
  24. data/lib/head_music/version.rb +1 -1
  25. data/lib/head_music.rb +3 -0
  26. data/user_stories/backlog/band-score-order.md +38 -0
  27. data/user_stories/backlog/chamber-ensemble-score-order.md +33 -0
  28. data/user_stories/backlog/consonance-dissonance-classification.md +57 -0
  29. data/user_stories/backlog/dyad-analysis.md +65 -0
  30. data/user_stories/backlog/orchestral-score-order.md +43 -0
  31. data/user_stories/backlog/pitch-class-set-analysis.md +39 -0
  32. data/user_stories/backlog/pitch-set-classification.md +62 -0
  33. data/user_stories/backlog/sonority-identification.md +47 -0
  34. 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.2.1
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-06-21 00:00:00.000000000 Z
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: '1.2'
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: '1.2'
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