1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
//
// Copyright 2019-2020 Hans W. Uhlig, Richard I. Christopher. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

use super::{Note, Octave, PitchClass, Steps};
use crate::types::interval::PerfectQuality::{Augmented, Diminished};
use crate::types::{Interval, Matrix, Tone};
use std::ops;

/// A4 [Pitch](musictheory::types::Pitch) [Tuning](musictheory::types::Tuning).
pub enum Tuning {
    A4_432Hz = 0,
    A4_434Hz = 1,
    A4_436Hz = 2,
    A4_438Hz = 3,
    A4_440Hz = 4,
    A4_442Hz = 5,
    A4_444Hz = 6,
    A4_446Hz = 7,
}

///
/// [Pitch](musictheory::types::Pitch) is the unique Combination of
/// [PitchClass](musictheory::types::PitchClass) and [Octave](musictheory::types::Octave).
///
/// Midi Note Table
/// * X - [PitchClass](musictheory::types::PitchClass)
/// * Y - [Octave](musictheory::types::Octave)
/// * C - Midi Note Id
///
/// |    | Cn   | Cs   | Dn   | Ds   | En   | Fn   | Fs   | Gn   | Gs   | An   | As   | Bn   |
/// |----|------|------|------|------|------|------|------|------|------|------|------|------|
/// | -1 | 0    | 1    | 2    | 3    | 4    | 5    | 6    | 7    | 8    | 9    | 10   | 11   |
/// |  0 | 12   | 13   | 14   | 15   | 16   | 17   | 18   | 19   | 20   | 21   | 22   | 23   |
/// |  1 | 24   | 25   | 26   | 27   | 28   | 29   | 30   | 31   | 32   | 33   | 34   | 35   |
/// |  2 | 36   | 37   | 38   | 39   | 40   | 41   | 42   | 43   | 44   | 45   | 46   | 47   |
/// |  3 | 48   | 49   | 50   | 51   | 52   | 53   | 54   | 55   | 56   | 57   | 58   | 59   |
/// |  4 | 60   | 61   | 62   | 63   | 64   | 65   | 66   | 67   | 68   | 69   | 70   | 71   |
/// |  5 | 72   | 73   | 74   | 75   | 76   | 77   | 78   | 79   | 80   | 81   | 82   | 83   |
/// |  6 | 84   | 85   | 86   | 87   | 88   | 89   | 90   | 91   | 92   | 93   | 94   | 95   |
/// |  7 | 96   | 97   | 98   | 99   | 100  | 101  | 102  | 103  | 104  | 105  | 106  | 107  |
/// |  8 | 108  | 109  | 110  | 111  | 112  | 113  | 114  | 115  | 116  | 117  | 118  | 119  |
/// |  9 | 120  | 122  | 123  | 124  | 125  | 126  | 127  | 128! | 129! | 130! | 131! | 132! |
/// | 10 | 133! | 134! | 135! | 136! | 137! | 138! | 139! | 140! | 141! | 142! | 143! | 144! |
///
/// Note: Pitches marked with a ! are not translatable to Midi
///
#[derive(Copy, Clone, Debug, Hash, PartialEq)]
pub struct Pitch(u8);

impl Pitch {
    /// Not for External Use
    pub(crate) const fn from_index(index: u8) -> Pitch {
        Pitch(index)
    }
    /// Not for External Use
    pub(crate) const fn to_index(&self) -> u8 {
        self.0
    }
    /// Get Natural Note for this Pitch
    pub fn note(&self) -> Note {
        Matrix::natural(&self.pitch_class(), &self.pitch_class().group())
            .unwrap()
    }
    /// Get Natural Tone for this Pitch
    pub fn tone(&self) -> Tone {
        Tone::from_parts(self.octave(), self.note())
    }
    /// Get [Notes](musictheory::types::Pitch) for this [Pitch](musictheory::types::Pitch).
    pub fn names(&self) -> &'static [Note] {
        self.pitch_class().names()
    }
    /// Get [PitchClass](musictheory::types::PitchClass) of this [Pitch](musictheory::types::Pitch)
    pub fn pitch_class(&self) -> PitchClass {
        PitchClass::from_index(self.0 % 12)
    }
    /// Get [Octave](musictheory::types::Octave) of this [Pitch](musictheory::types::Pitch)
    pub fn octave(&self) -> Octave {
        Octave::from_index(self.0 / 12).unwrap()
    }
    /// Get the semitone steps between two [Pitches](musictheory::types::Pitch).
    pub fn distance(&self, other: &Pitch) -> Steps {
        let l = self.to_index() as u16;
        let r = other.to_index() as u16;
        Steps::from(if r > l { r - l } else { l - r })
    }
    /// Get Frequency of [Pitch](musictheory::types::Pitch).
    pub fn frequency(&self, tuning: Tuning) -> f32 {
        FREQUENCIES[self.0 as usize][tuning as usize]
    }
}

impl From<u8> for Pitch {
    fn from(index: u8) -> Pitch {
        Pitch(index)
    }
}

impl ops::Add<Interval> for Pitch {
    type Output = Option<Self>;
    fn add(self, interval: Interval) -> Self::Output {
        if interval == Interval::First(Diminished) {
            self - Steps::from(1)
        } else {
            self + interval.steps()
        }
    }
}

impl ops::Add<Steps> for Pitch {
    type Output = Option<Self>;
    fn add(self, steps: Steps) -> Self::Output {
        let new_pitch_index = self.to_index() as i32 + steps.value() as i32;
        if 0 <= new_pitch_index && new_pitch_index < 144 {
            Some(Pitch::from_index(new_pitch_index as u8))
        } else {
            None
        }
    }
}

impl std::ops::Sub<Interval> for Pitch {
    type Output = Option<Self>;
    fn sub(self, interval: Interval) -> Self::Output {
        if interval == Interval::First(Diminished) {
            self + Steps::from(1)
        } else {
            self - interval.steps()
        }
    }
}

impl std::ops::Sub<Steps> for Pitch {
    type Output = Option<Self>;
    fn sub(self, steps: Steps) -> Self::Output {
        let new_pitch_index = self.to_index() as i32 - steps.value() as i32;
        if 0 <= new_pitch_index && new_pitch_index < 144 {
            Some(Pitch::from_index(new_pitch_index as u8))
        } else {
            None
        }
    }
}

#[test]
fn test_addition() {
    use crate::types::{
        Accidental, Interval, MajorQuality, Note, Octave, PerfectQuality, Tone,
    };
    fn test(pitch: Pitch, steps: Steps, expect: Option<Pitch>) {
        let result = pitch + steps;
        assert_eq!(
            result, expect,
            "{:?} + {} = {:?} Expected: {:?}",
            pitch, steps, result, expect
        );
    }
    test(
        Pitch::from_index(69),
        Steps::from(13),
        Some(Pitch::from_index(82)),
    );
    test(
        Pitch::from_index(69),
        Steps::from(0),
        Some(Pitch::from_index(69)),
    );
    test(Pitch::from_index(140), Steps::from(10), None);
}

#[cfg(test)]
mod tests {
    use super::{Interval, Pitch};

    #[test]
    fn test_subtraction() {
        use crate::types::{Accidental, Interval, Note, Octave, Steps, Tone};
        fn test(pitch: Pitch, steps: Steps, expect: Option<Pitch>) {
            let result = pitch - steps;
            assert_eq!(
                result, expect,
                "{:?} - {} = {:?} Expected: {:?}",
                pitch, steps, result, expect
            );
        }
        test(
            Pitch::from_index(69),
            Steps::from(0),
            Some(Pitch::from_index(69)),
        );
        test(
            Pitch::from_index(69),
            Steps::from(20),
            Some(Pitch::from_index(49)),
        );
        test(Pitch::from_index(29), Steps::from(30), None);
    }
}

/// Frequency Chart
#[rustfmt::skip]
// @formatter:off
const FREQUENCIES: [[f32; 8]; 144] = [
    [    8.025,     8.065,     8.100,     8.140,     8.175,     8.215,     8.250,     8.285], //   0 - Cn[-1]
    [    8.505,     8.545,     8.585,     8.625,     8.660,     8.700,     8.740,     8.780], //   1 - Cs[-1]
    [    9.010,     9.050,     9.095,     9.135,     9.175,     9.220,     9.260,     9.300], //   2 - Dn[-1]
    [    9.545,     9.590,     9.635,     9.680,     9.725,     9.765,     9.810,     9.855], //   3 - Ds[-1]
    [   10.115,    10.160,    10.205,    10.255,    10.300,    10.350,    10.395,    10.440], //   4 - En[-1]
    [   10.715,    10.765,    10.815,    10.865,    10.915,    10.965,    11.015,    11.060], //   5 - Fn[-1]
    [   11.350,    11.405,    11.455,    11.510,    11.560,    11.615,    11.665,    11.720], //   6 - Fs[-1]
    [   12.025,    12.085,    12.140,    12.195,    12.250,    12.305,    12.360,    12.415], //   7 - Gn[-1]
    [   12.740,    12.800,    12.860,    12.920,    12.980,    13.035,    13.095,    13.155], //   8 - Gs[-1]
    [   13.500,    13.560,    13.625,    13.690,    13.750,    13.810,    13.875,    13.940], //   9 - An[-1]
    [   14.305,    14.370,    14.435,    14.500,    14.570,    14.635,    14.700,    14.765], //  10 - As[-1]
    [   15.155,    15.225,    15.295,    15.365,    15.435,    15.505,    15.575,    15.645], //  11 - Bn[-1]
    [   16.050,    16.130,    16.200,    16.280,    16.350,    16.430,    16.500,    16.570], //  12 - Cn[0]
    [   17.010,    17.090,    17.170,    17.250,    17.320,    17.400,    17.480,    17.560], //  13 - Cs[0]
    [   18.020,    18.100,    18.190,    18.270,    18.350,    18.440,    18.520,    18.600], //  14 - Dn[0]
    [   19.090,    19.180,    19.270,    19.360,    19.450,    19.530,    19.620,    19.710], //  15 - Ds[0]
    [   20.230,    20.320,    20.410,    20.510,    20.600,    20.700,    20.790,    20.880], //  16 - En[0]
    [   21.430,    21.530,    21.630,    21.730,    21.830,    21.930,    22.030,    22.120], //  17 - Fn[0]
    [   22.700,    22.810,    22.910,    23.020,    23.120,    23.230,    23.330,    23.440], //  18 - Fs[0]
    [   24.050,    24.170,    24.280,    24.390,    24.500,    24.610,    24.720,    24.830], //  19 - Gn[0]
    [   25.480,    25.600,    25.720,    25.840,    25.960,    26.070,    26.190,    26.310], //  20 - Gs[0]
    [   27.000,    27.120,    27.250,    27.380,    27.500,    27.620,    27.750,    27.880], //  21 - An[0]
    [   28.610,    28.740,    28.870,    29.000,    29.140,    29.270,    29.400,    29.530], //  22 - As[0]
    [   30.310,    30.450,    30.590,    30.730,    30.870,    31.010,    31.150,    31.290], //  23 - Bn[0]
    [   32.110,    32.260,    32.410,    32.550,    32.700,    32.850,    33.000,    33.150], //  24 - Cn[1]
    [   34.020,    34.180,    34.330,    34.490,    34.650,    34.810,    34.960,    35.120], //  25 - Cs[1]
    [   36.040,    36.210,    36.370,    36.540,    36.710,    36.870,    37.040,    37.210], //  26 - Dn[1]
    [   38.180,    38.360,    38.540,    38.710,    38.890,    39.070,    39.240,    39.420], //  27 - Ds[1]
    [   40.450,    40.640,    40.830,    41.020,    41.200,    41.390,    41.580,    41.770], //  28 - En[1]
    [   42.860,    43.060,    43.260,    43.460,    43.650,    43.850,    44.050,    44.250], //  29 - Fn[1]
    [   45.410,    45.620,    45.830,    46.040,    46.250,    46.460,    46.670,    46.880], //  30 - Fs[1]
    [   48.110,    48.330,    48.550,    48.780,    49.000,    49.220,    49.440,    49.670], //  31 - Gn[1]
    [   50.970,    51.210,    51.440,    51.680,    51.910,    52.150,    52.390,    52.620], //  32 - Gs[1]
    [   54.000,    54.250,    54.500,    54.750,    55.000,    55.250,    55.500,    55.750], //  33 - An[1]
    [   57.210,    57.480,    57.740,    58.010,    58.270,    58.540,    58.800,    59.070], //  34 - As[1]
    [   60.610,    60.890,    61.170,    61.450,    61.740,    62.020,    62.300,    62.580], //  35 - Bn[1]
    [   64.220,    64.510,    64.810,    65.110,    65.410,    65.700,    66.000,    66.300], //  36 - Cn[2]
    [   68.040,    68.350,    68.670,    68.980,    69.300,    69.610,    69.930,    70.240], //  37 - Cs[2]
    [   72.080,    72.420,    72.750,    73.080,    73.420,    73.750,    74.080,    74.420], //  38 - Dn[2]
    [   76.370,    76.720,    77.070,    77.430,    77.780,    78.140,    78.490,    78.840], //  39 - Ds[2]
    [   80.910,    81.280,    81.660,    82.030,    82.410,    82.780,    83.160,    83.530], //  40 - En[2]
    [   85.720,    86.120,    86.510,    86.910,    87.310,    87.700,    88.100,    88.500], //  41 - Fn[2]
    [   90.820,    91.240,    91.660,    92.080,    92.500,    92.920,    93.340,    93.760], //  42 - Fs[2]
    [   96.220,    96.660,    97.110,    97.550,    98.000,    98.440,    98.890,    99.340], //  43 - Gn[2]
    [  101.940,   102.410,   102.880,   103.350,   103.830,   104.300,   104.770,   105.240], //  44 - Gs[2]
    [  108.000,   108.500,   109.000,   109.500,   110.000,   110.500,   111.000,   111.500], //  45 - An[2]
    [  114.420,   114.950,   115.480,   116.010,   116.540,   117.070,   117.600,   118.130], //  46 - As[2]
    [  121.230,   121.790,   122.350,   122.910,   123.470,   124.030,   124.590,   125.150], //  47 - Bn[2]
    [  128.430,   129.030,   129.620,   130.220,   130.810,   131.410,   132.000,   132.600], //  48 - Cn[3]
    [  136.070,   136.700,   137.330,   137.960,   138.590,   139.220,   139.850,   140.480], //  49 - Cs[3]
    [  144.160,   144.830,   145.500,   146.160,   146.830,   147.500,   148.170,   148.830], //  50 - Dn[3]
    [  152.740,   153.440,   154.150,   154.860,   155.560,   156.270,   156.980,   157.680], //  51 - Ds[3]
    [  161.820,   162.570,   163.320,   164.060,   164.810,   165.560,   166.310,   167.060], //  52 - En[3]
    [  171.440,   172.230,   173.030,   173.820,   174.610,   175.410,   176.200,   177.000], //  53 - Fn[3]
    [  181.630,   182.470,   183.320,   184.160,   185.000,   185.840,   186.680,   187.520], //  54 - Fs[3]
    [  192.430,   193.320,   194.220,   195.110,   196.000,   196.890,   197.780,   198.670], //  55 - Gn[3]
    [  203.880,   204.820,   205.760,   206.710,   207.650,   208.600,   209.540,   210.480], //  56 - Gs[3]
    [  216.000,   217.000,   218.000,   219.000,   220.000,   221.000,   222.000,   223.000], //  57 - An[3]
    [  228.840,   229.900,   230.960,   232.020,   233.080,   234.140,   235.200,   236.260], //  58 - As[3]
    [  242.450,   243.570,   244.700,   245.820,   246.940,   248.060,   249.190,   250.310], //  59 - Bn[3]
    [  256.870,   258.060,   259.250,   260.440,   261.630,   262.810,   264.000,   265.190], //  60 - Cn[4]
    [  272.140,   273.400,   274.660,   275.920,   277.180,   278.440,   279.700,   280.960], //  61 - Cs[4]
    [  288.330,   289.660,   290.990,   292.330,   293.660,   295.000,   296.330,   297.670], //  62 - Dn[4]
    [  305.470,   306.880,   308.300,   309.710,   311.130,   312.540,   313.960,   315.370], //  63 - Ds[4]
    [  323.630,   325.130,   326.630,   328.130,   329.630,   331.130,   332.620,   334.120], //  64 - En[4]
    [  342.880,   344.470,   346.050,   347.640,   349.230,   350.820,   352.400,   353.990], //  65 - Fn[4]
    [  363.270,   364.950,   366.630,   368.310,   369.990,   371.680,   373.360,   375.040], //  66 - Fs[4]
    [  384.870,   386.650,   388.430,   390.210,   392.000,   393.780,   395.560,   397.340], //  67 - Gn[4]
    [  407.750,   409.640,   411.530,   413.420,   415.300,   417.190,   419.080,   420.970], //  68 - Gs[4]
    [  432.000,   434.000,   436.000,   438.000,   440.000,   442.000,   444.000,   446.000], //  69 - An[4] - Tuning
    [  457.690,   459.810,   461.930,   464.040,   466.160,   468.280,   470.400,   472.520], //  70 - As[4]
    [  484.900,   487.150,   489.390,   491.640,   493.880,   496.130,   498.370,   500.620], //  71 - Bn[4]
    [  513.740,   516.120,   518.490,   520.870,   523.250,   525.630,   528.010,   530.390], //  72 - Cn[5]
    [  544.290,   546.810,   549.330,   551.850,   554.370,   556.880,   559.400,   561.920], //  73 - Cs[5]
    [  576.650,   579.320,   581.990,   584.660,   587.330,   590.000,   592.670,   595.340], //  74 - Dn[5]
    [  610.940,   613.770,   616.600,   619.430,   622.250,   625.080,   627.910,   630.740], //  75 - Ds[5]
    [  647.270,   650.270,   653.260,   656.260,   659.250,   662.250,   665.250,   668.240], //  76 - En[5]
    [  685.760,   688.930,   692.110,   695.280,   698.460,   701.630,   704.810,   707.980], //  77 - Fn[5]
    [  726.530,   729.900,   733.260,   736.630,   739.990,   743.350,   746.720,   750.080], //  78 - Fs[5]
    [  769.740,   773.300,   776.860,   780.430,   783.990,   787.550,   791.120,   794.680], //  79 - Gn[5]
    [  815.510,   819.280,   823.060,   826.830,   830.610,   834.380,   838.160,   841.940], //  80 - Gs[5]
    [  864.000,   868.000,   872.000,   876.000,   880.000,   884.000,   888.000,   892.000], //  81 - An[5]
    [  915.380,   919.610,   923.850,   928.090,   932.330,   936.570,   940.800,   945.040], //  82 - As[5]
    [  969.810,   974.300,   978.790,   983.280,   987.770,   992.260,   996.750,  1001.240], //  83 - Bn[5]
    [ 1027.470,  1032.230,  1036.990,  1041.740,  1046.500,  1051.260,  1056.020,  1060.770], //  84 - Cn[6]
    [ 1088.570,  1093.610,  1098.650,  1103.690,  1108.730,  1113.770,  1118.810,  1123.850], //  85 - Cs[6]
    [ 1153.300,  1158.640,  1163.980,  1169.320,  1174.660,  1180.000,  1185.340,  1190.680], //  86 - Dn[6]
    [ 1221.880,  1227.540,  1233.190,  1238.850,  1244.510,  1250.160,  1255.820,  1261.480], //  87 - Ds[6]
    [ 1294.540,  1300.530,  1306.520,  1312.520,  1318.510,  1324.500,  1330.500,  1336.490], //  88 - En[6]
    [ 1371.510,  1377.860,  1384.210,  1390.560,  1396.910,  1403.260,  1409.610,  1415.960], //  89 - Fn[6]
    [ 1453.070,  1459.800,  1466.520,  1473.250,  1479.980,  1486.700,  1493.430,  1500.160], //  90 - Fs[6]
    [ 1539.470,  1546.600,  1553.730,  1560.850,  1567.980,  1575.110,  1582.240,  1589.360], //  91 - Gn[6]
    [ 1631.010,  1638.570,  1646.120,  1653.670,  1661.220,  1668.770,  1676.320,  1683.870], //  92 - Gs[6]
    [ 1728.000,  1736.000,  1744.000,  1752.000,  1760.000,  1768.000,  1776.000,  1784.000], //  93 - An[6]
    [ 1830.750,  1839.230,  1847.700,  1856.180,  1864.660,  1873.130,  1881.610,  1890.080], //  94 - As[6]
    [ 1939.610,  1948.590,  1957.570,  1966.550,  1975.530,  1984.510,  1993.490,  2002.470], //  95 - Bn[6]
    [ 2054.950,  2064.460,  2073.980,  2083.490,  2093.000,  2102.520,  2112.030,  2121.540], //  96 - Cn[7]
    [ 2177.140,  2187.220,  2197.300,  2207.380,  2217.460,  2227.540,  2237.620,  2247.700], //  97 - Cs[7]
    [ 2306.600,  2317.280,  2327.960,  2338.640,  2349.320,  2360.000,  2370.670,  2381.350], //  98 - Dn[7]
    [ 2443.760,  2455.070,  2466.390,  2477.700,  2489.020,  2500.330,  2511.640,  2522.960], //  99 - Ds[7]
    [ 2589.070,  2601.060,  2613.050,  2625.030,  2637.020,  2649.010,  2660.990,  2672.980], // 100 - En[7]
    [ 2743.030,  2755.730,  2768.430,  2781.130,  2793.830,  2806.520,  2819.220,  2831.920], // 101 - Fn[7]
    [ 2906.140,  2919.590,  2933.050,  2946.500,  2959.960,  2973.410,  2986.860,  3000.320], // 102 - Fs[7]
    [ 3078.950,  3093.200,  3107.450,  3121.710,  3135.960,  3150.220,  3164.470,  3178.730], // 103 - Gn[7]
    [ 3262.030,  3277.130,  3292.230,  3307.340,  3322.440,  3337.540,  3352.640,  3367.740], // 104 - Gs[7]
    [ 3456.000,  3472.000,  3488.000,  3504.000,  3520.000,  3536.000,  3552.000,  3568.000], // 105 - An[7]
    [ 3661.500,  3678.460,  3695.410,  3712.360,  3729.310,  3746.260,  3763.210,  3780.160], // 106 - As[7]
    [ 3879.230,  3897.190,  3915.150,  3933.110,  3951.070,  3969.030,  3986.990,  4004.950], // 107 - Bn[7]
    [ 4109.900,  4128.930,  4147.950,  4166.980,  4186.010,  4205.030,  4224.060,  4243.090], // 108 - Cn[8]
    [ 4354.290,  4374.440,  4394.600,  4414.760,  4434.920,  4455.080,  4475.240,  4495.400], // 109 - Cs[8]
    [ 4613.210,  4634.560,  4655.920,  4677.280,  4698.630,  4719.990,  4741.350,  4762.710], // 110 - Dn[8]
    [ 4887.520,  4910.150,  4932.780,  4955.400,  4978.030,  5000.660,  5023.290,  5045.910], // 111 - Ds[8]
    [ 5178.150,  5202.120,  5226.090,  5250.070,  5274.040,  5298.010,  5321.990,  5345.960], // 112 - En[8]
    [ 5486.060,  5511.460,  5536.850,  5562.250,  5587.650,  5613.050,  5638.450,  5663.850], // 113 - Fn[8]
    [ 5812.280,  5839.180,  5866.090,  5893.000,  5919.910,  5946.820,  5973.730,  6000.640], // 114 - Fs[8]
    [ 6157.890,  6186.400,  6214.910,  6243.420,  6271.930,  6300.440,  6328.940,  6357.450], // 115 - Gn[8]
    [ 6524.060,  6554.260,  6584.470,  6614.670,  6644.880,  6675.080,  6705.280,  6735.490], // 116 - Gs[8]
    [ 6912.000,  6944.000,  6976.000,  7008.000,  7040.000,  7072.000,  7104.000,  7136.000], // 117 - An[8]
    [ 7323.010,  7356.910,  7390.810,  7424.720,  7458.620,  7492.520,  7526.430,  7560.330], // 118 - As[8]
    [ 7758.460,  7794.380,  7830.300,  7866.210,  7902.130,  7938.050,  7973.970,  8009.890], // 119 - Bn[8]
    [ 8219.800,  8257.860,  8295.900,  8333.960,  8372.020,  8410.060,  8448.120,  8486.180], // 120 - Cn[9]
    [ 8708.580,  8748.880,  8789.200,  8829.520,  8869.840,  8910.160,  8950.480,  8990.800], // 121 - Cs[9]
    [ 9226.420,  9269.120,  9311.840,  9354.560,  9397.260,  9439.980,  9482.700,  9525.420], // 122 - Dn[9]
    [ 9775.040,  9820.300,  9865.560,  9910.800,  9956.060, 10001.320, 10046.580, 10091.820], // 123 - Ds[9]
    [10356.300, 10404.240, 10452.180, 10500.140, 10548.080, 10596.020, 10643.980, 10691.920], // 124 - En[9]
    [10972.120, 11022.920, 11073.700, 11124.500, 11175.300, 11226.100, 11276.900, 11327.700], // 125 - Fn[9]
    [11624.560, 11678.360, 11732.180, 11786.000, 11839.820, 11893.640, 11947.460, 12001.280], // 126 - Fs[9]
    [12315.780, 12372.800, 12429.820, 12486.840, 12543.860, 12600.880, 12657.880, 12714.900], // 127 - Gn[9]
    [13048.120, 13108.520, 13168.940, 13229.340, 13289.760, 13350.160, 13410.560, 13470.980], // 128 - Gs[9]
    [13824.000, 13888.000, 13952.000, 14016.000, 14080.000, 14144.000, 14208.000, 14272.000], // 129 - An[9]
    [14646.020, 14713.820, 14781.620, 14849.440, 14917.240, 14985.040, 15052.860, 15120.660], // 130 - As[9]
    [15516.920, 15588.760, 15660.600, 15732.420, 15804.260, 15876.100, 15947.940, 16019.780], // 131 - Bn[9]
    [16439.600, 16515.720, 16591.800, 16667.920, 16744.040, 16820.120, 16896.240, 16972.360], // 132 - Cn[10]
    [17417.160, 17497.760, 17578.400, 17659.040, 17739.680, 17820.320, 17900.960, 17981.600], // 133 - Cs[10]
    [18452.840, 18538.240, 18623.680, 18709.120, 18794.520, 18879.960, 18965.400, 19050.840], // 134 - Dn[10]
    [19550.080, 19640.600, 19731.120, 19821.600, 19912.120, 20002.640, 20093.160, 20183.640], // 135 - Ds[10]
    [20712.600, 20808.480, 20904.360, 21000.280, 21096.160, 21192.040, 21287.960, 21383.840], // 136 - En[10]
    [21944.240, 22045.840, 22147.400, 22249.000, 22350.600, 22452.200, 22553.800, 22655.400], // 137 - Fn[10]
    [23249.120, 23356.720, 23464.360, 23572.000, 23679.640, 23787.280, 23894.920, 24002.560], // 138 - Fs[10]
    [24631.560, 24745.600, 24859.640, 24973.680, 25087.720, 25201.760, 25315.760, 25429.800], // 139 - Gn[10]
    [26096.240, 26217.040, 26337.880, 26458.680, 26579.520, 26700.320, 26821.120, 26941.960], // 140 - Gs[10]
    [27648.000, 27776.000, 27904.000, 28032.000, 28160.000, 28288.000, 28416.000, 28544.000], // 141 - An[10]
    [29292.040, 29427.640, 29563.240, 29698.880, 29834.480, 29970.080, 30105.720, 30241.320], // 142 - As[10]
    [31033.840, 31177.520, 31321.200, 31464.840, 31608.520, 31752.200, 31895.880, 32039.560], // 143 - Bn[10]
];
// @formatter:on