Pitch_Test.ts 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import { Pitch, NoteEnum, AccidentalEnum } from "../../../src/Common/DataObjects/Pitch";
  2. describe("Pitch Unit Tests:", () => {
  3. describe("transpose Pitch", () => {
  4. const pitch: Pitch = new Pitch(NoteEnum.A, 1, AccidentalEnum.NONE);
  5. const transposedFundamentalAndOctave: {halftone: number, overflow: number } =
  6. Pitch.CalculateTransposedHalfTone(pitch, 12);
  7. const higherTransposedFundamentalAndOctave: {halftone: number, overflow: number } =
  8. Pitch.CalculateTransposedHalfTone(pitch, 26);
  9. it("should be 1 octave higher and same fundamental", (done: Mocha.Done) => {
  10. chai.expect(transposedFundamentalAndOctave.overflow).to.equal(1);
  11. chai.expect(transposedFundamentalAndOctave.halftone).to.equal(pitch.FundamentalNote);
  12. chai.expect(higherTransposedFundamentalAndOctave.overflow).to.equal(2);
  13. chai.expect(higherTransposedFundamentalAndOctave.halftone).to.equal(pitch.FundamentalNote + 2);
  14. done();
  15. });
  16. });
  17. describe("calculate Frequency from Pitch", () => {
  18. const pitch1: Pitch = new Pitch(NoteEnum.A, 1, AccidentalEnum.NONE);
  19. const pitch2: Pitch = new Pitch(NoteEnum.B, 1, AccidentalEnum.DOUBLEFLAT);
  20. const pitch3: Pitch = new Pitch(NoteEnum.G, 1, AccidentalEnum.DOUBLESHARP);
  21. const frequency1: number = Pitch.calcFrequency(Pitch.calcFractionalKey(pitch1.Frequency));
  22. const frequency2: number = Pitch.calcFrequency(Pitch.calcFractionalKey(pitch2.Frequency));
  23. const frequency3: number = Pitch.calcFrequency(Pitch.calcFractionalKey(pitch3.Frequency));
  24. it("should be 440Hz", (done: Mocha.Done) => {
  25. chai.expect(pitch1.Frequency).to.equal(440);
  26. chai.expect(pitch2.Frequency).to.equal(440);
  27. chai.expect(pitch3.Frequency).to.equal(440);
  28. chai.expect(frequency1).to.equal(440);
  29. chai.expect(frequency2).to.equal(440);
  30. chai.expect(frequency3).to.equal(440);
  31. done();
  32. });
  33. });
  34. describe("calculate fractional key", () => {
  35. // the values are validated against the C# output. TODO: ask mauz about the shift
  36. const pitch1: Pitch = new Pitch(NoteEnum.C, 6, AccidentalEnum.SHARP); // C#6 -> 109
  37. const pitch2: Pitch = new Pitch(NoteEnum.B, 1, AccidentalEnum.NONE); // B1 -> 59
  38. const pitch3: Pitch = new Pitch(NoteEnum.F, 4, AccidentalEnum.DOUBLEFLAT); // Fbb4 -> 87
  39. const pitch4: Pitch = new Pitch(NoteEnum.E, -1, AccidentalEnum.DOUBLESHARP); // E##-1 -> 30
  40. const pitch5: Pitch = new Pitch(NoteEnum.A, 1, AccidentalEnum.NONE); // A1 -> 57
  41. const key1: number = Pitch.calcFractionalKey(pitch1.Frequency);
  42. const key2: number = Pitch.calcFractionalKey(pitch2.Frequency);
  43. const key3: number = Pitch.calcFractionalKey(pitch3.Frequency);
  44. const key4: number = Pitch.calcFractionalKey(pitch4.Frequency);
  45. const key5: number = Pitch.calcFractionalKey(pitch5.Frequency);
  46. it("pitch key should equal midi key", (done: Mocha.Done) => {
  47. chai.expect(Math.round(key1)).to.equal(109);
  48. chai.expect(Math.round(key2)).to.equal(59);
  49. chai.expect(Math.round(key3)).to.equal(87);
  50. chai.expect(Math.round(key4)).to.equal(30);
  51. chai.expect(Math.round(key5)).to.equal(57);
  52. done();
  53. });
  54. });
  55. describe("calculate Pitch from Frequency", () => {
  56. const octave: number = 1;
  57. const accidentals: number[] = [AccidentalEnum.DOUBLEFLAT,
  58. AccidentalEnum.FLAT,
  59. AccidentalEnum.NONE,
  60. AccidentalEnum.SHARP,
  61. AccidentalEnum.DOUBLESHARP,
  62. ];
  63. let pitch: Pitch;
  64. let calcedPitch: Pitch;
  65. for (let i: number = 0; i < Pitch.pitchEnumValues.length; i++) {
  66. for (let j: number = 0; j < accidentals.length; j++) {
  67. pitch = new Pitch(Pitch.pitchEnumValues[i], octave, accidentals[j]);
  68. calcedPitch = Pitch.fromFrequency(pitch.Frequency);
  69. it( "calcedPitch equals original, " +
  70. `note: ${pitch.FundamentalNote}, octave: ${pitch.Octave}, accidental; ${pitch.Accidental}`,
  71. (done: Mocha.Done) => {
  72. // compare the frequencies here -> only AccidentalEnum None and Sharp will lead to same note, octave and accidental
  73. chai.expect(pitch.Frequency).to.equal(calcedPitch.Frequency);
  74. done();
  75. });
  76. }
  77. }
  78. });
  79. describe("get Pitch from fractional key", () => {
  80. const octave: number = 5;
  81. const accidentals: number[] = [AccidentalEnum.DOUBLEFLAT,
  82. AccidentalEnum.FLAT,
  83. AccidentalEnum.NONE,
  84. AccidentalEnum.SHARP,
  85. AccidentalEnum.DOUBLESHARP,
  86. ];
  87. let pitch: Pitch;
  88. let calcedPitch: Pitch;
  89. for (let i: number = 0; i < Pitch.pitchEnumValues.length; i++) {
  90. for (let j: number = 0; j < accidentals.length; j++) {
  91. pitch = new Pitch(Pitch.pitchEnumValues[i], octave, accidentals[j]);
  92. const halftone: number = pitch.getHalfTone();
  93. calcedPitch = Pitch.fromHalftone(halftone);
  94. it( "calcedPitch equals original, " +
  95. `note: ${pitch.FundamentalNote}, octave: ${pitch.Octave}, accidental; ${pitch.Accidental}`,
  96. (done: Mocha.Done) => {
  97. chai.expect(pitch.getHalfTone()).to.equal(calcedPitch.getHalfTone());
  98. done();
  99. });
  100. }
  101. }
  102. });
  103. // TODO: test ceiling and floor (needed for the music sheet transpose)
  104. // TODO: test getTransposedPitch (or delete it -> seems to be a less powerful implementation of CalculateTransposedHalfTone)
  105. // TODO: test DoEnharmonicEnchange (needed for the midi reader)
  106. });