AccidentalCalculator.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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. public doCalculationsAtEndOfMeasure(): void {
  28. this.currentInMeasureNoteAlterationsDict.clear();
  29. for (let key of this.keySignatureNoteAlterationsDict.keys()) {
  30. this.currentInMeasureNoteAlterationsDict.setValue(key, this.keySignatureNoteAlterationsDict.getValue(key));
  31. }
  32. }
  33. public checkAccidental(graphicalNote: GraphicalNote, pitch: Pitch, grace: boolean, graceScalingFactor: number): void {
  34. if (pitch === undefined) {
  35. return;
  36. }
  37. let pitchKey: number = <number>pitch.FundamentalNote + pitch.Octave * 12;
  38. /*let pitchKeyGivenInMeasureDict: boolean = this.currentInMeasureNoteAlterationsDict.containsKey(pitchKey);
  39. if (
  40. (pitchKeyGivenInMeasureDict && this.currentInMeasureNoteAlterationsDict.getValue(pitchKey) !== pitch.Accidental)
  41. || (!pitchKeyGivenInMeasureDict && pitch.Accidental !== AccidentalEnum.NONE)
  42. ) {
  43. if (this.currentAlterationsComparedToKeyInstructionList.indexOf(pitchKey) === -1) {
  44. this.currentAlterationsComparedToKeyInstructionList.push(pitchKey);
  45. }
  46. this.currentInMeasureNoteAlterationsDict.setValue(pitchKey, pitch.Accidental);
  47. this.symbolFactory.addGraphicalAccidental(graphicalNote, pitch, grace, graceScalingFactor);
  48. } else if (
  49. this.currentAlterationsComparedToKeyInstructionList.indexOf(pitchKey) !== -1
  50. && ((pitchKeyGivenInMeasureDict && this.currentInMeasureNoteAlterationsDict.getValue(pitchKey) !== pitch.Accidental)
  51. || (!pitchKeyGivenInMeasureDict && pitch.Accidental === AccidentalEnum.NONE))
  52. ) {
  53. this.currentAlterationsComparedToKeyInstructionList.splice(this.currentAlterationsComparedToKeyInstructionList.indexOf(pitchKey), 1);
  54. this.currentInMeasureNoteAlterationsDict.setValue(pitchKey, pitch.Accidental);
  55. this.symbolFactory.addGraphicalAccidental(graphicalNote, pitch, grace, graceScalingFactor);
  56. }*/
  57. let isInCurrentAlterationsToKeyList: boolean = this.currentAlterationsComparedToKeyInstructionList.indexOf(pitchKey) >= 0;
  58. if (this.currentInMeasureNoteAlterationsDict.containsKey(pitchKey)) {
  59. if (isInCurrentAlterationsToKeyList) {
  60. this.currentAlterationsComparedToKeyInstructionList.splice(this.currentAlterationsComparedToKeyInstructionList.indexOf(pitchKey), 1);
  61. }
  62. if (this.currentInMeasureNoteAlterationsDict.getValue(pitchKey) !== pitch.Accidental) {
  63. if (this.keySignatureNoteAlterationsDict.containsKey(pitchKey) &&
  64. this.keySignatureNoteAlterationsDict.getValue(pitchKey) !== pitch.Accidental) {
  65. this.currentAlterationsComparedToKeyInstructionList.push(pitchKey);
  66. this.currentInMeasureNoteAlterationsDict.setValue(pitchKey, pitch.Accidental);
  67. } else {
  68. this.currentInMeasureNoteAlterationsDict.remove(pitchKey);
  69. }
  70. this.symbolFactory.addGraphicalAccidental(graphicalNote, pitch, grace, graceScalingFactor);
  71. }
  72. } else {
  73. if (pitch.Accidental !== AccidentalEnum.NONE) {
  74. if (!isInCurrentAlterationsToKeyList) {
  75. this.currentAlterationsComparedToKeyInstructionList.push(pitchKey);
  76. }
  77. this.currentInMeasureNoteAlterationsDict.setValue(pitchKey, pitch.Accidental);
  78. this.symbolFactory.addGraphicalAccidental(graphicalNote, pitch, grace, graceScalingFactor);
  79. } else {
  80. if (isInCurrentAlterationsToKeyList) {
  81. this.currentAlterationsComparedToKeyInstructionList.splice(this.currentAlterationsComparedToKeyInstructionList.indexOf(pitchKey), 1);
  82. this.symbolFactory.addGraphicalAccidental(graphicalNote, pitch, grace, graceScalingFactor);
  83. }
  84. }
  85. }
  86. }
  87. private reactOnKeyInstructionChange(): void {
  88. let noteEnums: NoteEnum[] = KeyInstruction.getNoteEnumList(this.activeKeyInstruction);
  89. let keyAccidentalType: AccidentalEnum;
  90. if (this.activeKeyInstruction.Key > 0) {
  91. keyAccidentalType = AccidentalEnum.SHARP;
  92. } else {
  93. keyAccidentalType = AccidentalEnum.FLAT;
  94. }
  95. this.keySignatureNoteAlterationsDict.clear();
  96. this.currentAlterationsComparedToKeyInstructionList.length = 0;
  97. for (let octave: number = -9; octave < 9; octave++) {
  98. for (let i: number = 0; i < noteEnums.length; i++) {
  99. this.keySignatureNoteAlterationsDict.setValue(<number>noteEnums[i] + octave * 12, keyAccidentalType);
  100. }
  101. }
  102. this.doCalculationsAtEndOfMeasure();
  103. }
  104. }