| | 1 | | namespace MusicTheory.Theory.Harmony; |
| | 2 | |
|
| | 3 | | public enum Voice { Soprano, Alto, Tenor, Bass } |
| | 4 | |
|
| | 5 | | public readonly record struct VoiceRange(int MinMidi, int MaxMidi, int WarnMinMidi, int WarnMaxMidi) |
| | 6 | | { |
| | 7 | | public bool InHardRange(int midi) => midi >= MinMidi && midi <= MaxMidi; |
| | 8 | | public bool InWarnRange(int midi) => midi >= WarnMinMidi && midi <= WarnMaxMidi; |
| | 9 | | } |
| | 10 | |
|
| | 11 | | public static class VoiceRanges |
| | 12 | | { |
| | 13 | | // 目安: (Sop C4-A5),(Alt G3-D5),(Ten C3-A4),(Bs F2-D4) とし ±長三度(±4semitones)を警告許容 |
| 1544 | 14 | | private static (int min,int max) Base(string name) => name switch |
| 1544 | 15 | | { |
| 415 | 16 | | "S" => (60, 81), // C4..A5 |
| 387 | 17 | | "A" => (55, 74), // G3..D5 |
| 373 | 18 | | "T" => (48, 69), // C3..A4 |
| 369 | 19 | | "B" => (41, 62), // F2..D4 |
| 0 | 20 | | _ => (60,81) |
| 1544 | 21 | | }; |
| | 22 | | private static VoiceRange Make((int min,int max) b) |
| 1544 | 23 | | => new(b.min, b.max, b.min-4, b.max+4); |
| | 24 | |
|
| 415 | 25 | | public static VoiceRange Soprano => Make(Base("S")); |
| 387 | 26 | | public static VoiceRange Alto => Make(Base("A")); |
| 373 | 27 | | public static VoiceRange Tenor => Make(Base("T")); |
| 369 | 28 | | public static VoiceRange Bass => Make(Base("B")); |
| | 29 | |
|
| 1522 | 30 | | public static VoiceRange ForVoice(Voice v) => v switch |
| 1522 | 31 | | { |
| 405 | 32 | | Voice.Soprano => Soprano, |
| 383 | 33 | | Voice.Alto => Alto, |
| 369 | 34 | | Voice.Tenor => Tenor, |
| 365 | 35 | | Voice.Bass => Bass, |
| 0 | 36 | | _ => Soprano |
| 1522 | 37 | | }; |
| | 38 | | } |