AccidentalCalculator.ts 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import {IGraphicalSymbolFactory} from "../Interfaces/IGraphicalSymbolFactory";
  2. import {AccidentalEnum} from "../../Common/DataObjects/Pitch";
  3. import {KeyInstruction} from "../VoiceData/Instructions/KeyInstruction";
  4. import {GraphicalNote} from "./GraphicalNote";
  5. import {Pitch} from "../../Common/DataObjects/Pitch";
  6. import {NoteEnum} from "../../Common/DataObjects/Pitch";
  7. import Dictionary from "typescript-collections/dist/lib/Dictionary";
  8. /**
  9. * Compute the accidentals for notes according to the current key instruction
  10. */
  11. export class AccidentalCalculator {
  12. private symbolFactory: IGraphicalSymbolFactory;
  13. private keySignatureNoteAlterationsDict: Dictionary<number, AccidentalEnum> = new Dictionary<number, AccidentalEnum>();
  14. private currentAlterationsComparedToKeyInstructionList: number[] = [];
  15. private currentInMeasureNoteAlterationsDict: Dictionary<number, AccidentalEnum> = new Dictionary<number, AccidentalEnum>();
  16. private activeKeyInstruction: KeyInstruction;
  17. constructor(symbolFactory: IGraphicalSymbolFactory) {
  18. this.symbolFactory = symbolFactory;
  19. }
  20. public get ActiveKeyInstruction(): KeyInstruction {
  21. return this.activeKeyInstruction;
  22. }
  23. public set ActiveKeyInstruction(value: KeyInstruction) {
  24. this.activeKeyInstruction = value;
  25. this.reactOnKeyInstructionChange();
  26. }
  27. /**
  28. * This method is called after each Measure
  29. */
  30. public doCalculationsAtEndOfMeasure(): void {
  31. this.currentInMeasureNoteAlterationsDict.clear();
  32. for (const key of this.keySignatureNoteAlterationsDict.keys()) {
  33. this.currentInMeasureNoteAlterationsDict.setValue(key, this.keySignatureNoteAlterationsDict.getValue(key));
  34. }
  35. }
  36. public checkAccidental(graphicalNote: GraphicalNote, pitch: Pitch, grace: boolean, graceScalingFactor: number): void {
  37. if (pitch === undefined) {
  38. return;
  39. }
  40. const pitchKey: number = <number>pitch.FundamentalNote + pitch.Octave * 12;
  41. /*let pitchKeyGivenInMeasureDict: boolean = this.currentInMeasureNoteAlterationsDict.containsKey(pitchKey);
  42. if (
  43. (pitchKeyGivenInMeasureDict && this.currentInMeasureNoteAlterationsDict.getValue(pitchKey) !== pitch.Accidental)
  44. || (!pitchKeyGivenInMeasureDict && pitch.Accidental !== AccidentalEnum.NONE)
  45. ) {
  46. if (this.currentAlterationsComparedToKeyInstructionList.indexOf(pitchKey) === -1) {
  47. this.currentAlterationsComparedToKeyInstructionList.push(pitchKey);
  48. }
  49. this.currentInMeasureNoteAlterationsDict.setValue(pitchKey, pitch.Accidental);
  50. this.symbolFactory.addGraphicalAccidental(graphicalNote, pitch, grace, graceScalingFactor);
  51. } else if (
  52. this.currentAlterationsComparedToKeyInstructionList.indexOf(pitchKey) !== -1
  53. && ((pitchKeyGivenInMeasureDict && this.currentInMeasureNoteAlterationsDict.getValue(pitchKey) !== pitch.Accidental)
  54. || (!pitchKeyGivenInMeasureDict && pitch.Accidental === AccidentalEnum.NONE))
  55. ) {
  56. this.currentAlterationsComparedToKeyInstructionList.splice(this.currentAlterationsComparedToKeyInstructionList.indexOf(pitchKey), 1);
  57. this.currentInMeasureNoteAlterationsDict.setValue(pitchKey, pitch.Accidental);
  58. this.symbolFactory.addGraphicalAccidental(graphicalNote, pitch, grace, graceScalingFactor);
  59. }*/
  60. const isInCurrentAlterationsToKeyList: boolean = this.currentAlterationsComparedToKeyInstructionList.indexOf(pitchKey) >= 0;
  61. if (this.currentInMeasureNoteAlterationsDict.containsKey(pitchKey)) {
  62. if (isInCurrentAlterationsToKeyList) {
  63. this.currentAlterationsComparedToKeyInstructionList.splice(this.currentAlterationsComparedToKeyInstructionList.indexOf(pitchKey), 1);
  64. }
  65. if (this.currentInMeasureNoteAlterationsDict.getValue(pitchKey) !== pitch.Accidental) {
  66. if (this.keySignatureNoteAlterationsDict.containsKey(pitchKey) &&
  67. this.keySignatureNoteAlterationsDict.getValue(pitchKey) !== pitch.Accidental) {
  68. this.currentAlterationsComparedToKeyInstructionList.push(pitchKey);
  69. this.currentInMeasureNoteAlterationsDict.setValue(pitchKey, pitch.Accidental);
  70. } else {
  71. this.currentInMeasureNoteAlterationsDict.remove(pitchKey);
  72. }
  73. this.symbolFactory.addGraphicalAccidental(graphicalNote, pitch, grace, graceScalingFactor);
  74. }
  75. } else {
  76. if (pitch.Accidental !== AccidentalEnum.NONE) {
  77. if (!isInCurrentAlterationsToKeyList) {
  78. this.currentAlterationsComparedToKeyInstructionList.push(pitchKey);
  79. }
  80. this.currentInMeasureNoteAlterationsDict.setValue(pitchKey, pitch.Accidental);
  81. this.symbolFactory.addGraphicalAccidental(graphicalNote, pitch, grace, graceScalingFactor);
  82. } else {
  83. if (isInCurrentAlterationsToKeyList) {
  84. this.currentAlterationsComparedToKeyInstructionList.splice(this.currentAlterationsComparedToKeyInstructionList.indexOf(pitchKey), 1);
  85. this.symbolFactory.addGraphicalAccidental(graphicalNote, pitch, grace, graceScalingFactor);
  86. }
  87. }
  88. }
  89. }
  90. private reactOnKeyInstructionChange(): void {
  91. const noteEnums: NoteEnum[] = KeyInstruction.getNoteEnumList(this.activeKeyInstruction);
  92. let keyAccidentalType: AccidentalEnum;
  93. if (this.activeKeyInstruction.Key > 0) {
  94. keyAccidentalType = AccidentalEnum.SHARP;
  95. } else {
  96. keyAccidentalType = AccidentalEnum.FLAT;
  97. }
  98. this.keySignatureNoteAlterationsDict.clear();
  99. this.currentAlterationsComparedToKeyInstructionList.length = 0;
  100. for (let octave: number = -9; octave < 9; octave++) {
  101. for (let i: number = 0; i < noteEnums.length; i++) {
  102. this.keySignatureNoteAlterationsDict.setValue(<number>noteEnums[i] + octave * 12, keyAccidentalType);
  103. }
  104. }
  105. this.doCalculationsAtEndOfMeasure();
  106. }
  107. }