@@ -2046,6 +2046,89 @@ describe("pitchToFrequency", () => {
20462046 } ) ;
20472047} ) ;
20482048
2049+ describe ( "pitchToFrequency cents edge cases" , ( ) => {
2050+ global . TWELTHROOT2 = 1.0594630943592953 ;
2051+ global . TWELVEHUNDRETHROOT2 = Number ( "1.0005777895065549" ) ;
2052+ global . A0 = 27.5 ;
2053+
2054+ it ( "12-EDO regression: cents formula matches standard 12-EDO" , ( ) => {
2055+ // When temperament is 12-EDO and cents is 0, result must equal standard 12-EDO frequency
2056+ const result0 = pitchToFrequency ( "A" , 4 , 0 , "C" ) ;
2057+ expect ( result0 ) . toBe ( A0 * Math . pow ( TWELTHROOT2 , 48 ) ) ;
2058+
2059+ // With cents and 12-EDO, uses 1200-EDO formula
2060+ const result50 = pitchToFrequency ( "A" , 4 , 50 , "C" ) ;
2061+ expect ( result50 ) . toBe ( A0 * Math . pow ( TWELVEHUNDRETHROOT2 , 48 * 100 + 50 ) ) ;
2062+ } ) ;
2063+
2064+ it ( "19-EDO cents: explicit formula matches implementation" , ( ) => {
2065+ // A4 in 19-EDO = pitchNumber 76 (4 * 19)
2066+ // freq = A0 * 2^(1/(19*100))^(76*100 + cents)
2067+ const result0 = pitchToFrequency ( "A" , 4 , 0 , "C" , "equal19" ) ;
2068+ const expected0 = A0 * Math . pow ( 2 , 1 / ( 19 * 100 ) ) ** ( 76 * 100 ) ;
2069+ expect ( result0 ) . toBeCloseTo ( expected0 , 4 ) ;
2070+
2071+ const result50 = pitchToFrequency ( "A" , 4 , 50 , "C" , "equal19" ) ;
2072+ const expected50 = A0 * Math . pow ( 2 , 1 / ( 19 * 100 ) ) ** ( 76 * 100 + 50 ) ;
2073+ expect ( result50 ) . toBeCloseTo ( expected50 , 4 ) ;
2074+ } ) ;
2075+
2076+ it ( "31-EDO cents: explicit formula matches implementation" , ( ) => {
2077+ // A4 in 31-EDO = pitchNumber 124 (4 * 31)
2078+ const result0 = pitchToFrequency ( "A" , 4 , 0 , "C" , "equal31" ) ;
2079+ const expected0 = A0 * Math . pow ( 2 , 1 / ( 31 * 100 ) ) ** ( 124 * 100 ) ;
2080+ expect ( result0 ) . toBeCloseTo ( expected0 , 4 ) ;
2081+
2082+ const result100 = pitchToFrequency ( "A" , 4 , 100 , "C" , "equal31" ) ;
2083+ const expected100 = A0 * Math . pow ( 2 , 1 / ( 31 * 100 ) ) ** ( 124 * 100 + 100 ) ;
2084+ expect ( result100 ) . toBeCloseTo ( expected100 , 4 ) ;
2085+ } ) ;
2086+
2087+ it ( "handles large positive cents in 12-EDO" , ( ) => {
2088+ // 1199 cents ~ almost one octave above
2089+ const result = pitchToFrequency ( "A" , 4 , 1199 , "C" ) ;
2090+ const expected = A0 * Math . pow ( TWELVEHUNDRETHROOT2 , 48 * 100 + 1199 ) ;
2091+ expect ( result ) . toBeCloseTo ( expected , 4 ) ;
2092+ } ) ;
2093+
2094+ it ( "handles large negative cents in 12-EDO" , ( ) => {
2095+ // -100 cents = one semitone flat
2096+ const result = pitchToFrequency ( "A" , 4 , - 100 , "C" ) ;
2097+ const expected = A0 * Math . pow ( TWELVEHUNDRETHROOT2 , 48 * 100 - 100 ) ;
2098+ expect ( result ) . toBeCloseTo ( expected , 4 ) ;
2099+ } ) ;
2100+
2101+ it ( "handles cents at different octaves with temperament" , ( ) => {
2102+ // C5 in 19-EDO: pitchNumber = 5*19 + 0(C) - 9(A offset) = 86
2103+ const result = pitchToFrequency ( "C" , 5 , 30 , "C" , "equal19" ) ;
2104+ const expected = A0 * Math . pow ( 2 , 1 / ( 19 * 100 ) ) ** ( 86 * 100 + 30 ) ;
2105+ expect ( result ) . toBeCloseTo ( expected , 4 ) ;
2106+ } ) ;
2107+
2108+ it ( "12-EDO regression: cents with unequal temperaments" , ( ) => {
2109+ // Default equal temperament with cents should match 12-EDO cents formula
2110+ const result = pitchToFrequency ( "A" , 4 , 75 , "C" ) ;
2111+ const expected = A0 * Math . pow ( TWELVEHUNDRETHROOT2 , 48 * 100 + 75 ) ;
2112+ expect ( result ) . toBeCloseTo ( expected , 4 ) ;
2113+ } ) ;
2114+ } ) ;
2115+
2116+ describe ( "frequencyToPitch cents with 12-EDO regression" , ( ) => {
2117+ it ( "returns 0 cents for exact 12-EDO pitches" , ( ) => {
2118+ expect ( frequencyToPitch ( 440 ) [ 2 ] ) . toBe ( 0 ) ;
2119+ expect ( frequencyToPitch ( 261.63 ) [ 2 ] ) . toBe ( 0 ) ;
2120+ expect ( frequencyToPitch ( 523.25 ) [ 2 ] ) . toBe ( 0 ) ;
2121+ } ) ;
2122+
2123+ it ( "detects small cents deviation in 12-EDO" , ( ) => {
2124+ // 441 Hz = 440 * 2^(1/1200) ≈ A4 + 1 cent
2125+ const freq = 440 * Math . pow ( 2 , 1 / 1200 ) ;
2126+ const result = frequencyToPitch ( freq ) ;
2127+ expect ( result [ 2 ] ) . toBeGreaterThan ( 0 ) ;
2128+ expect ( result [ 2 ] ) . toBeLessThan ( 2 ) ;
2129+ } ) ;
2130+ } ) ;
2131+
20492132describe ( "noteToFrequency" , ( ) => {
20502133 global . TWELTHROOT2 = 1.0594630943592953 ;
20512134 global . TWELVEHUNDRETHROOT2 = Number ( "1.0005777895065549" ) ;
0 commit comments