Scale Tuning

2003/3/23 Takuichi Hirano

周波数を求める関数（平均律）

[Input]
オクターブ
音 (c,c#,d,d#,e,f,f#,g,g#,a,a#,b)

ABCToNumOfHalfTone[ABC_] := 
          Which[
ABC == "C"  ||  ABC == "c", 
            0, 
ABC == "C#"  ||  ABC == "c#", 
            1, 
ABC == "D"  ||  ABC == "d", 
            2, 
ABC == "D#"  ||  ABC == "d#", 
            3, 
ABC == "E"  ||  ABC == "e", 
            4, 
ABC == "F"  ||  ABC == "f", 
            5, 
ABC == "F#"  ||  ABC == "f#", 
            6, 
ABC == "G"  ||  ABC == "g", 
            7, 
ABC == "G#"  ||  ABC == "g#", 
            8, 
ABC == "A"  ||  ABC == "a", 
            9, 
ABC == "A#"  ||  ABC == "a#", 
            10, 
ABC == "B"  ||  ABC == "b", 
            11];

FreqTemperament[Octave_, ABC_]:=Module[{r = (2^(1/12))},
  
ABCNum = 
              ABCToNumOfHalfTone[
                ABC]; 
(440*(r^((Octave - 4)*12)))*
                (r^(ABCNum - 9))  // N
];
FreqTemperament[OctABCList_List] := 
        Map[(FreqTemperament[#[[1]], #[[2]]] &), 
          OctABCList];

周波数を求める関数（純正律）

基準周波数は平均律で決める。
基準音から２オクターブ分までサポート

[Input]
基準音のオクターブと音名
と
オクターブ
音 (c,c#,d,d#,e,f,f#,g,g#,a,a#,b)

FreqJustIntonation[OctaveStd_, ABCStd_, Octave_, ABC_]:=Module[{r = (2^(1/12))},
  
ABCStdNum = 
              ABCToNumOfHalfTone[ABCStd]; 
ABCNum = 
              ABCToNumOfHalfTone[
                ABC]; 
 (*JustIntFracList = {1, (16/15), 
                    (9/8), (13/11), (5/4), (4/3), (7/5), (3/2), (8/5), (5/3), (16/9), 
                    (15/8)};*) 
JustIntFracList = {1, 
                (16/15), (9/8), (6/5), (5/4), (4/3), (45/32), (3/2), (8/5), (5/3), 
                (16/9), (15/8)}; 
DiffHalfTone = ((12*
                        Octave + ABCNum) - (12*OctaveStd + 
                      ABCStdNum)); 
(27.5*(2^OctaveStd)*(r^(ABCStdNum - 9)))*
                JustIntFracList[[Mod[DiffHalfTone, 12] + 
                      1]]*(2^Quotient)[DiffHalfTone, 12]  // N
];
FreqJustIntonation[OctaveStd_, ABCStd_, 
          OctABCList_List] := 
        Map[(FreqJustIntonation[OctaveStd, 
                ABCStd, #[[1]], #[[2]]] &), 
          OctABCList];

Difference Between Temperament and Just Intonation

\(\(ABCList = {{4, "a"}, {4, "b"}, {5, "c"}, {5, "d"}, {5, "e"}, {5, "f"}, {5, "g"}};\)\)

FreqTemperament[ABCList]

FreqJustIntonation[4, "a", ABCList]

g1 = 
        ListPlot[
          FreqTemperament[
            ABCList], 
PlotStyle -> {AbsolutePointSize[
                8], AbsoluteThickness[2], 
              RGBColor[1, 0, 1]}, 
PlotJoined -> 
            True, 
DisplayFunction -> 
            Identity];
g2 = 
        ListPlot[
          FreqTemperament[
            ABCList], 
PlotStyle -> {AbsolutePointSize[
                8], AbsoluteThickness[2], 
              RGBColor[1, 0, 1]}, 
PlotJoined -> 
            False, 
DisplayFunction -> 
            Identity];
g3 = 
        ListPlot[
          FreqJustIntonation[4, "a", 
            ABCList], 
PlotStyle -> {AbsolutePointSize[
                8], AbsoluteThickness[2], 
              RGBColor[0, 1, 1]}, 
PlotJoined -> 
            True, 
DisplayFunction -> 
            Identity];
g4 = 
        ListPlot[
          FreqJustIntonation[4, "a", 
            ABCList], 
PlotStyle -> {AbsolutePointSize[
                8], AbsoluteThickness[2], 
              RGBColor[0, 1, 1]}, 
PlotJoined -> 
            False, 
DisplayFunction -> 
            Identity];
Show[{g1, g2, g3, 
        g4}, 
PlotRange -> {{1, 7}, {440, 
            880}}, 
Frame -> 
        True, 
Axes -> 
        None, 
DisplayFunction -> $DisplayFunction]

Scale Tuning Data for MIDI
Roland SC-88VL Manual p. 86, p. 80

DecNumberToHexString1[n_] := 
        Module[{}, 
Which[
n == 
              10, "a", 
n == 
              11, "b", 
n == 
              12, "c", 
n == 
              13, "d", 
n == 
              14, "e", 
n == 
              15, "f", 
True, 
            ToString[
              n]
]
];
CentToMIDIScaleTuningData[p_] := 
        Module[{}, 
hex = 
            IntegerDigits[p + 64, 16]; 
"x"  <>  
            DecNumberToHexString1[hex[[1]]]  <>  
            DecNumberToHexString1[
              hex[[2]]]
];
CentToMIDIScaleTuningData[lis_List] := 
        Map[CentToMIDIScaleTuningData, lis];

\(\(CDEList = {{4, "c"}, {4, "c#"}, {4, "d"}, {4, "d#"}, {4, "e"}, {4, "f"}, {4, "f#"}, {4, "g"}, {4, "g#"}, {4, "a"}, {4, "a#"}, {4, "b"}};\)\)
Scale[0] = FreqTemperament[CDEList];
Scale[1] = 
        FreqJustIntonation[4, "c", CDEList];

    
PitchScale[0] = 1200*Log[2, Scale[0]];
PitchScale[1] = 1200*Log[2, Scale[1]];

    
Print["**** \:5e73\:5747\:5f8b\:304b\:3089\:306e\:305a\:308c\:306e\
\:30d4\:30c3\:30c1(\:30bb\:30f3\:30c8\:5024) ****"];
Print["Ratio: ", Scale[1]/Scale[0]];
Print["Pitch (Cent): ", 
        Round[1200*Log[2, Scale[1]/Scale[0]]]];
\(\(Print["MIDI Scale Tuning: ", 
StringJoin[
Drop[
Flatten[
Map[\(({#, ","} &)\), 
                CentToMIDIScaleTuningData[
                  Round[1200*
                      Log[2, Scale[1]/
                          Scale[0]]]]
]
]
, \(-1\)
]
]
];\)\)