music-theory-verification
Use when implementing or debugging music theory calculations - provides verification methods for intervals, note naming, scale construction, and chord voicings to catch common mathematical errors
安装与使用
请根据来源仓库和你的 AI 工具说明安装此技能。先阅读技能文件和依赖要求,再添加到工作流。
查看来源 ↗使用指南技能说明
Music Theory Verification
Overview
Music theory code involves modular arithmetic (mod 12) and interval calculations. Small errors produce completely wrong notes that may not be obvious until heard.
Core principle: Verify calculations against known musical facts before trusting code.
When to Use
- Debugging incorrect note display
- Verifying new scale/chord implementations
- Troubleshooting Nashville number display
- Checking fretboard/keyboard generation
- Validating transposition logic
The Chromatic Scale
Index: 0 1 2 3 4 5 6 7 8 9 10 11
Sharp: C C# D D# E F F# G G# A A# B
Flat: C Db D Eb E F Gb G Ab A Bb B
Interval Math
Note Value Calculation
// Adding interval to root
noteValue = (rootValue + interval) % 12;
// Example: G major 3rd
// G = 7, major 3rd = 4
// (7 + 4) % 12 = 11 = B ✓
Fret Note Calculation
// Note at fret position
noteValue = (openStringValue + fretNumber) % 12;
// Example: 3rd fret on A string (A = 9)
// (9 + 3) % 12 = 0 = C ✓
Common Errors
// WRONG: Forgetting modulo
noteValue = rootValue + interval; // Can exceed 11!
// WRONG: Wrong modulo base
noteValue = (root + interval) % 11; // Should be 12
// WRONG: Negative intervals without handling
noteValue = (root - interval) % 12; // Can be negative!
// CORRECT: Handle negative
noteValue = ((root - interval) % 12 + 12) % 12;
Quick Verification Tests
Major Scale Test
Starting from C (0), major scale intervals [0,2,4,5,7,9,11] should produce:
C(0) D(2) E(4) F(5) G(7) A(9) B(11)
Starting from G (7):
G(7) A(9) B(11) C(0) D(2) E(4) F#(6)
Minor Scale Test
Starting from A (9), natural minor [0,2,3,5,7,8,10]:
A(9) B(11) C(0) D(2) E(4) F(5) G(7)
Chord Test
C Major chord [0,4,7] from C(0):
C(0) E(4) G(7) ✓
G7 chord [0,4,7,10] from G(7):
G(7) B(11) D(2) F(5) ✓
Nashville Number Verification
Nashville numbers represent scale degrees 1-7.
Calculation
// Find position of note in current scale
nashvilleNumber = scaleIntervals.indexOf(
(noteValue - rootValue + 12) % 12
) + 1; // +1 because Nashville is 1-indexed
// If not in scale, nashvilleNumber = 0 or null
Test Cases
C Major scale, notes C-D-E-F-G-A-B:
C → 1 (root)
D → 2
E → 3
F → 4
G → 5
A → 6
B → 7
C# → null (not in scale)
Mode Derivation Verification
Each mode starts on a different scale degree of the parent scale.
From C Major (Ionian)
Ionian (I): C D E F G A B [0,2,4,5,7,9,11]
Dorian (II): D E F G A B C [0,2,3,5,7,9,10]
Phrygian (III): E F G A B C D [0,1,3,5,7,8,10]
Lydian (IV): F G A B C D E [0,2,4,6,7,9,11]
Mixolydian (V): G A B C D E F [0,2,4,5,7,9,10]
Aeolian (VI): A B C D E F G [0,2,3,5,7,8,10]
Locrian (VII): B C D E F G A [0,1,3,5,6,8,10]
Verify Mode Intervals
If implementing a mode, verify against this transformation:
// Mode intervals from parent major scale
function getModeIntervals(modeNumber: number): number[] {
const major = [0, 2, 4, 5, 7, 9, 11];
const startIndex = modeNumber - 1;
return major.map((_, i) => {
const sourceIndex = (startIndex + i) % 7;
const interval = (major[sourceIndex] - major[startIndex] + 12) % 12;
return interval;
}).sort((a, b) => a - b);
}
Fretboard Verification
Open String Notes (Standard Guitar Tuning E-A-D-G-B-E)
String 6 (low E): E = 4
String 5: A = 9
String 4: D = 2
String 3: G = 7
String 2: B = 11
String 1 (high E): E = 4
Fret Verification Points
Fret 5 on low E string: A (9) ✓
Fret 7 on A string: E (4) ✓
Fret 12 on any string: Same note as open (octave) ✓
Octave Calculation
// Standard MIDI octave calculation
// Middle C (C4) = MIDI 60
// C0 = 12, C1 = 24, ... C4 = 60
octave = Math.floor(midiNote / 12) - 1;
noteValue = midiNote % 12;
// For fretboard display
baseOctave = getStringBaseOctave(stringIndex);
octave = baseOctave + Math.floor((openNote + fret) / 12);
Piano Keyboard Verification
Key Position to Note
// White keys in octave: C D E F G A B (indices 0,2,4,5,7,9,11)
// Black keys: C# D# F# G# A# (indices 1,3,6,8,10)
function isBlackKey(noteValue: number): boolean {
return [1, 3, 6, 8, 10].includes(noteValue);
}
61-Key Keyboard (Standard)
- Starts at C2 (MIDI 36)
- Ends at C7 (MIDI 96)
- Middle C (C4) is key 25
Debugging Checklist
When notes display incorrectly:
- Verify root note value is correct (C=0, C#=1, etc.)
- Check interval array is correct for scale/chord
- Verify modulo 12 is applied consistently
- Check for off-by-one in array indexing
- Verify preferSharps is being respected
- Test with C root (simplest case) first
- Test with F# root (catches many edge cases)
- Play the notes - does it sound right?
Console Debugging Helpers
// Add to MusicTheoryService for debugging
debugNote(noteValue: number, preferSharps: boolean = true): string {
const sharps = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'];
const flats = ['C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B'];
return (preferSharps ? sharps : flats)[noteValue % 12];
}
debugScale(rootValue: number, intervals: number[]): void {
console.log('Scale notes:', intervals.map(i =>
this.debugNote((rootValue + i) % 12)
).join(' '));
}
debugChord(rootValue: number, intervals: number[]): void {
console.log('Chord notes:', intervals.map(i =>
this.debugNote((rootValue + i) % 12)
).join(' '));
}
Reference Tables
Circle of Fifths (Clockwise)
C(0) → G(7) → D(2) → A(9) → E(4) → B(11) →
F#(6) → C#(1) → G#(8) → D#(3) → A#(10) → F(5) → C
Interval Names to Semitones
| Name | Semitones | Example |
|---|---|---|
| m2 | 1 | C-Db |
| M2 | 2 | C-D |
| m3 | 3 | C-Eb |
| M3 | 4 | C-E |
| P4 | 5 | C-F |
| TT | 6 | C-F# |
| P5 | 7 | C-G |
| m6 | 8 | C-Ab |
| M6 | 9 | C-A |
| m7 | 10 | C-Bb |
| M7 | 11 | C-B |
| P8 | 12 | C-C' |
使用示例
查看来源仓库中的使用示例与配置说明。
查看来源 ↗来源历史
- 收录时间
- 2026-01-20
- 索引更新时间
- 2026-01-26
- Branch
- main
收录与同步日期属于本站记录。源码修改历史请查看来源仓库。
GitHub ↗chat Comments (0)
Sign in to join the discussion and leave a comment.
No comments yet. Be the first to share your thoughts!