@@ -1804,50 +1804,71 @@ const TEMPERAMENT = {
18041804 "equal31" : {
18051805 // Equal 31EDO Temperament: 31 Equal Divisions of the Octave
18061806 "perfect 1" : Math . pow ( 2 , 0 / 31 ) ,
1807- "minor 2" : Math . pow ( 2 , 3 / 31 ) ,
1807+ "diminished 2" : Math . pow ( 2 , 1 / 31 ) ,
18081808 "augmented 1" : Math . pow ( 2 , 2 / 31 ) ,
1809+ "minor 2" : Math . pow ( 2 , 3 / 31 ) ,
1810+ "mid 2" : Math . pow ( 2 , 4 / 31 ) ,
18091811 "major 2" : Math . pow ( 2 , 5 / 31 ) ,
1810- "augmented 2" : Math . pow ( 2 , 6 / 31 ) ,
1812+ "up-major 2" : Math . pow ( 2 , 6 / 31 ) ,
1813+ "down-minor 3" : Math . pow ( 2 , 7 / 31 ) ,
18111814 "minor 3" : Math . pow ( 2 , 8 / 31 ) ,
1815+ "mid 3" : Math . pow ( 2 , 9 / 31 ) ,
18121816 "major 3" : Math . pow ( 2 , 10 / 31 ) ,
1813- "augmented 3" : Math . pow ( 2 , 11 / 31 ) ,
1814- "diminished 4" : Math . pow ( 2 , 12 / 31 ) ,
1817+ "up-major 3" : Math . pow ( 2 , 11 / 31 ) ,
1818+ "down 4" : Math . pow ( 2 , 12 / 31 ) ,
18151819 "perfect 4" : Math . pow ( 2 , 13 / 31 ) ,
1816- "augmented 4" : Math . pow ( 2 , 15 / 31 ) ,
1817- "diminished 5" : Math . pow ( 2 , 16 / 31 ) ,
1820+ "up 4" : Math . pow ( 2 , 14 / 31 ) ,
1821+ "down-diminished 5" : Math . pow ( 2 , 15 / 31 ) ,
1822+ "up-augmented 4" : Math . pow ( 2 , 16 / 31 ) ,
1823+ "down 5" : Math . pow ( 2 , 17 / 31 ) ,
18181824 "perfect 5" : Math . pow ( 2 , 18 / 31 ) ,
1819- "augmented 5" : Math . pow ( 2 , 19 / 31 ) ,
1825+ "up 5" : Math . pow ( 2 , 19 / 31 ) ,
1826+ "down-minor 6" : Math . pow ( 2 , 20 / 31 ) ,
18201827 "minor 6" : Math . pow ( 2 , 21 / 31 ) ,
1828+ "mid 6" : Math . pow ( 2 , 22 / 31 ) ,
18211829 "major 6" : Math . pow ( 2 , 23 / 31 ) ,
1822- "augmented 6" : Math . pow ( 2 , 24 / 31 ) ,
1830+ "up-major 6" : Math . pow ( 2 , 24 / 31 ) ,
1831+ "down-minor 7" : Math . pow ( 2 , 25 / 31 ) ,
18231832 "minor 7" : Math . pow ( 2 , 26 / 31 ) ,
1833+ "mid 7" : Math . pow ( 2 , 27 / 31 ) ,
18241834 "major 7" : Math . pow ( 2 , 28 / 31 ) ,
1825- "augmented 7" : Math . pow ( 2 , 29 / 31 ) ,
1826- "diminished 8" : Math . pow ( 2 , 30 / 31 ) ,
1835+ "up-major 7" : Math . pow ( 2 , 29 / 31 ) ,
1836+ "down 8" : Math . pow ( 2 , 30 / 31 ) ,
18271837 "perfect 8" : Math . pow ( 2 , 31 / 31 ) ,
1828- "pitchNumber" : 21 ,
1838+ "octave" : Math . pow ( 2 , 31 / 31 ) ,
1839+ "pitchNumber" : 31 ,
18291840 "interval" : [
18301841 "perfect 1" ,
1842+ "diminished 2" ,
18311843 "augmented 1" ,
18321844 "minor 2" ,
1845+ "mid 2" ,
18331846 "major 2" ,
1834- "augmented 2" ,
1847+ "up-major 2" ,
1848+ "down-minor 3" ,
18351849 "minor 3" ,
1850+ "mid 3" ,
18361851 "major 3" ,
1837- "augmented 3" ,
1838- "diminished 4" ,
1852+ "up-major 3" ,
1853+ "down 4" ,
18391854 "perfect 4" ,
1840- "augmented 4" ,
1841- "diminished 5" ,
1855+ "up 4" ,
1856+ "down-diminished 5" ,
1857+ "up-augmented 4" ,
1858+ "down 5" ,
18421859 "perfect 5" ,
1843- "augmented 5" ,
1860+ "up 5" ,
1861+ "down-minor 6" ,
18441862 "minor 6" ,
1863+ "mid 6" ,
18451864 "major 6" ,
1846- "augmented 6" ,
1865+ "up-major 6" ,
1866+ "down-minor 7" ,
18471867 "minor 7" ,
1868+ "mid 7" ,
18481869 "major 7" ,
1849- "augmented 7" ,
1850- "diminished 8" ,
1870+ "up-major 7" ,
1871+ "down 8" ,
18511872 "perfect 8"
18521873 ]
18531874 } ,
@@ -3585,7 +3606,6 @@ const getNoteFromInterval = (pitch, interval) => {
35853606 const number = pitchToNumber ( note1 , octave1 , "C major" ) ;
35863607 const pitches = [ "C" , "D" , "E" , "F" , "G" , "A" , "B" ] ;
35873608 const priorAttrs = [ DOUBLEFLAT , FLAT , "" , SHARP , DOUBLESHARP ] ;
3588- // let majorintervalNote;
35893609
35903610 /**
35913611 * Find the note that corresponds to a major interval.
@@ -3609,7 +3629,7 @@ const getNoteFromInterval = (pitch, interval) => {
36093629 let note = numberToPitch ( number + halfSteps ) ;
36103630 const num = interval . split ( " " ) ;
36113631 const pitchIndex = pitches . indexOf ( pitch1 ) ;
3612- let index = pitchIndex + Number ( num [ 1 ] ) - 1 ;
3632+ let index = pitchIndex + Number ( num [ num . length - 1 ] ) - 1 ;
36133633 let octave = octave1 ;
36143634 if ( index > 6 ) {
36153635 index = index - 7 ;
@@ -3643,15 +3663,15 @@ const getNoteFromInterval = (pitch, interval) => {
36433663 let majorNote ;
36443664 let accidental ;
36453665 let index1 ;
3646-
3666+
36473667 if (
36483668 interval === "minor 2" ||
36493669 interval === "minor 3" ||
36503670 interval === "minor 6" ||
36513671 interval === "minor 7"
36523672 ) {
36533673 //Major intervals lowered by a half step become minor.
3654- majorNote = findMajorInterval ( "major " + num [ 1 ] ) ;
3674+ majorNote = findMajorInterval ( "major " + num [ num . length - 1 ] ) ;
36553675 accidental = majorNote [ 0 ] . substring ( 1 , majorNote [ 0 ] . length ) ;
36563676 index1 = priorAttrs . indexOf ( accidental ) ;
36573677 if ( index1 === 0 ) {
@@ -3660,14 +3680,23 @@ const getNoteFromInterval = (pitch, interval) => {
36603680 accidental = priorAttrs [ index1 - 1 ] ;
36613681 }
36623682 }
3663-
3664- if (
3665- interval === "diminished 4" ||
3666- interval === "diminished 5" ||
3667- interval === "diminished 8"
3683+
3684+ // Diminished intervals for perfect intervals (lowered by half step)
3685+ else if (
3686+ interval === "down 4" ||
3687+ interval === "down 5" ||
3688+ interval === "down 8"
36683689 ) {
3669- //Perfect intervals lowered by a half step are called diminished.
3670- majorNote = findMajorInterval ( "perfect " + num [ 1 ] ) ;
3690+ // Mapping to the corresponding perfect interval
3691+ if ( interval === "down 4" ) {
3692+ majorNote = findMajorInterval ( "perfect 4" ) ;
3693+ } else if ( interval === "down 5" ) {
3694+ majorNote = findMajorInterval ( "perfect 5" ) ;
3695+ } else if ( interval === "down 8" ) {
3696+ majorNote = findMajorInterval ( "perfect 8" ) ;
3697+ }
3698+
3699+ // Lowering by one half step
36713700 accidental = majorNote [ 0 ] . substring ( 1 , majorNote [ 0 ] . length ) ;
36723701 index1 = priorAttrs . indexOf ( accidental ) ;
36733702 if ( index1 === 0 ) {
@@ -3676,15 +3705,71 @@ const getNoteFromInterval = (pitch, interval) => {
36763705 accidental = priorAttrs [ index1 - 1 ] ;
36773706 }
36783707 }
3679-
3680- if (
3681- interval === "augmented 2" ||
3682- interval === "augmented 3" ||
3683- interval === "augmented 6" ||
3684- interval === "augmented 7"
3708+
3709+ // Special case: doubly diminished 5th (very diminished)
3710+ else if ( interval === "down-diminished 5" ) {
3711+ majorNote = findMajorInterval ( "perfect 5" ) ;
3712+ accidental = majorNote [ 0 ] . substring ( 1 , majorNote [ 0 ] . length ) ;
3713+ index1 = priorAttrs . indexOf ( accidental ) ;
3714+
3715+ // Lowering by Two half steps for "very diminished"
3716+ if ( index1 <= 1 ) {
3717+ // If already at flat or double flat, add another flat
3718+ accidental = priorAttrs [ 0 ] + FLAT ;
3719+ } else {
3720+ // Go down two accidentals in the array
3721+ accidental = priorAttrs [ index1 - 2 ] ;
3722+ }
3723+ }
3724+
3725+ // Special case: diminished 2nd (from unison)
3726+ else if ( interval === "diminished 2" ) {
3727+ majorNote = findMajorInterval ( "perfect 1" ) ;
3728+ accidental = majorNote [ 0 ] . substring ( 1 , majorNote [ 0 ] . length ) ;
3729+ index1 = priorAttrs . indexOf ( accidental ) ;
3730+ if ( index1 === 0 ) {
3731+ accidental = priorAttrs [ index1 ] + FLAT ;
3732+ } else {
3733+ accidental = priorAttrs [ index1 - 1 ] ;
3734+ }
3735+ }
3736+
3737+ // Handle standard diminished intervals not covered by microtonal cases
3738+ else if ( interval . startsWith ( "diminished " ) ) {
3739+ const intervalNum = interval . split ( " " ) [ 1 ] ;
3740+ let baseInterval ;
3741+ if ( [ "4" , "5" , "8" ] . includes ( intervalNum ) ) { // Perfect-based
3742+ baseInterval = "perfect " + intervalNum ;
3743+ } else { // Major-based
3744+ baseInterval = "major " + intervalNum ;
3745+ }
3746+
3747+ majorNote = findMajorInterval ( baseInterval ) ;
3748+ accidental = majorNote [ 0 ] . substring ( 1 , majorNote [ 0 ] . length ) ;
3749+ index1 = priorAttrs . indexOf ( accidental ) ;
3750+
3751+ // Lower by one half-step from the base interval
3752+ if ( index1 === 0 ) {
3753+ accidental = priorAttrs [ index1 ] + FLAT ;
3754+ } else {
3755+ accidental = priorAttrs [ index1 - 1 ] ;
3756+ }
3757+ }
3758+
3759+ // Augmented intervals for perfect intervals (raised by half step)
3760+ else if (
3761+ interval === "up 4" ||
3762+ interval === "up 5" ||
3763+ interval === "up-augmented 4"
36853764 ) {
3686- //Major intervals raised by a half step are called augmented.
3687- majorNote = findMajorInterval ( "major " + num [ 1 ] ) ;
3765+ // Mapping to the corresponding perfect interval
3766+ if ( interval === "up 4" || interval === "up-augmented 4" ) {
3767+ majorNote = findMajorInterval ( "perfect 4" ) ;
3768+ } else if ( interval === "up 5" ) {
3769+ majorNote = findMajorInterval ( "perfect 5" ) ;
3770+ }
3771+
3772+ // Raise by one half step
36883773 accidental = majorNote [ 0 ] . substring ( 1 , majorNote [ 0 ] . length ) ;
36893774 index1 = priorAttrs . indexOf ( accidental ) ;
36903775 if ( index1 === 4 ) {
@@ -3693,15 +3778,37 @@ const getNoteFromInterval = (pitch, interval) => {
36933778 accidental = priorAttrs [ index1 + 1 ] ;
36943779 }
36953780 }
3696-
3697- if (
3698- interval === "augmented 1" ||
3781+
3782+ // Special case: augmented unison
3783+ else if ( interval === "augmented 1" ) {
3784+ majorNote = findMajorInterval ( "perfect 1" ) ;
3785+ accidental = majorNote [ 0 ] . substring ( 1 , majorNote [ 0 ] . length ) ;
3786+ index1 = priorAttrs . indexOf ( accidental ) ;
3787+ if ( index1 === 4 ) {
3788+ accidental = priorAttrs [ index1 ] + SHARP ;
3789+ } else {
3790+ accidental = priorAttrs [ index1 + 1 ] ;
3791+ }
3792+ }
3793+
3794+ // Standard augmented intervals
3795+ else if (
3796+ interval === "augmented 2" ||
3797+ interval === "augmented 3" ||
36993798 interval === "augmented 4" ||
37003799 interval === "augmented 5" ||
3800+ interval === "augmented 6" ||
3801+ interval === "augmented 7" ||
37013802 interval === "augmented 8"
37023803 ) {
3703- //Perfect intervals raised by a half step are called augmented.
3704- majorNote = findMajorInterval ( "perfect " + num [ 1 ] ) ;
3804+ const intervalNum = interval . split ( " " ) [ 1 ] ;
3805+ if ( [ "1" , "4" , "5" , "8" ] . includes ( intervalNum ) ) {
3806+ // Perfect-based augmented intervals
3807+ majorNote = findMajorInterval ( "perfect " + intervalNum ) ;
3808+ } else {
3809+ // Major-based augmented intervals
3810+ majorNote = findMajorInterval ( "major " + intervalNum ) ;
3811+ }
37053812 accidental = majorNote [ 0 ] . substring ( 1 , majorNote [ 0 ] . length ) ;
37063813 index1 = priorAttrs . indexOf ( accidental ) ;
37073814 if ( index1 === 4 ) {
@@ -3710,7 +3817,63 @@ const getNoteFromInterval = (pitch, interval) => {
37103817 accidental = priorAttrs [ index1 + 1 ] ;
37113818 }
37123819 }
3713-
3820+
3821+ // Handle "up-major" intervals (raised major)
3822+ else if (
3823+ interval === "up-major 2" ||
3824+ interval === "up-major 3" ||
3825+ interval === "up-major 6" ||
3826+ interval === "up-major 7"
3827+ ) {
3828+ let intervalNum ;
3829+ intervalNum = interval . split ( " " ) [ 1 ] ;
3830+ majorNote = findMajorInterval ( "major " + intervalNum ) ;
3831+ accidental = majorNote [ 0 ] . substring ( 1 , majorNote [ 0 ] . length ) ;
3832+ index1 = priorAttrs . indexOf ( accidental ) ;
3833+ if ( index1 === 4 ) {
3834+ accidental = priorAttrs [ index1 ] + SHARP ;
3835+ } else {
3836+ accidental = priorAttrs [ index1 + 1 ] ;
3837+ }
3838+ }
3839+
3840+ // Handle "down-minor" intervals (lowered minor - like diminished)
3841+ else if (
3842+ interval === "down-minor 3" ||
3843+ interval === "down-minor 6" ||
3844+ interval === "down-minor 7"
3845+ ) {
3846+ const intervalNum = interval . split ( " " ) [ 1 ] ;
3847+ majorNote = findMajorInterval ( "major " + intervalNum ) ;
3848+ accidental = majorNote [ 0 ] . substring ( 1 , majorNote [ 0 ] . length ) ;
3849+ index1 = priorAttrs . indexOf ( accidental ) ;
3850+
3851+ // Lower by an additional half step (total of two half steps below major)
3852+ if ( index1 <= 1 ) {
3853+ accidental = priorAttrs [ 0 ] + FLAT ;
3854+ } else {
3855+ accidental = priorAttrs [ index1 - 2 ] ; // Go down two accidentals
3856+ }
3857+ }
3858+
3859+ // Handle neutral/mid intervals (between major and minor)
3860+ else if (
3861+ interval === "mid 2" ||
3862+ interval === "mid 3" ||
3863+ interval === "mid 6" ||
3864+ interval === "mid 7"
3865+ ) {
3866+ const intervalNum = interval . split ( " " ) [ 1 ] ;
3867+ majorNote = findMajorInterval ( "major " + intervalNum ) ;
3868+ accidental = majorNote [ 0 ] . substring ( 1 , majorNote [ 0 ] . length ) ;
3869+ index1 = priorAttrs . indexOf ( accidental ) ;
3870+ if ( index1 === 0 ) {
3871+ accidental = priorAttrs [ index1 ] + FLAT ;
3872+ } else {
3873+ accidental = priorAttrs [ index1 - 1 ] ;
3874+ }
3875+ }
3876+
37143877 return [ majorNote [ 0 ] . substring ( 0 , 1 ) + accidental + "" , majorNote [ 1 ] ] ;
37153878 } ;
37163879
0 commit comments