ContinuousDynamicExpression.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import {PlacementEnum, AbstractExpression} from "../AbstractExpression";
  2. import {MultiExpression} from "../MultiExpression";
  3. import {Fraction} from "../../../../Common/DataObjects/Fraction";
  4. import {SourceMeasure} from "../../SourceMeasure";
  5. export class ContinuousDynamicExpression extends AbstractExpression {
  6. constructor(dynamicType: ContDynamicEnum, placement: PlacementEnum, staffNumber: number, measure: SourceMeasure,
  7. label: string = "") {
  8. super(placement);
  9. super.parentMeasure = measure;
  10. this.dynamicType = dynamicType;
  11. this.label = label;
  12. this.staffNumber = staffNumber;
  13. this.startVolume = -1;
  14. this.endVolume = -1;
  15. if (label !== "") {
  16. this.setType();
  17. }
  18. }
  19. private static listContinuousDynamicIncreasing: string[] = ["crescendo", "cresc", "cresc.", "cres."];
  20. private static listContinuousDynamicDecreasing: string[] = ["decrescendo", "decresc", "decr.", "diminuendo", "dim.", "dim"];
  21. // private static listContinuousDynamicGeneral: string[] = ["subito","al niente","piu","meno"];
  22. private dynamicType: ContDynamicEnum;
  23. private startMultiExpression: MultiExpression;
  24. private endMultiExpression: MultiExpression;
  25. private startVolume: number;
  26. private endVolume: number;
  27. private staffNumber: number;
  28. private label: string;
  29. public get DynamicType(): ContDynamicEnum {
  30. return this.dynamicType;
  31. }
  32. public set DynamicType(value: ContDynamicEnum) {
  33. this.dynamicType = value;
  34. }
  35. public get StartMultiExpression(): MultiExpression {
  36. return this.startMultiExpression;
  37. }
  38. public set StartMultiExpression(value: MultiExpression) {
  39. this.startMultiExpression = value;
  40. }
  41. public get EndMultiExpression(): MultiExpression {
  42. return this.endMultiExpression;
  43. }
  44. public set EndMultiExpression(value: MultiExpression) {
  45. this.endMultiExpression = value;
  46. }
  47. public get Placement(): PlacementEnum {
  48. return this.placement;
  49. }
  50. public set Placement(value: PlacementEnum) {
  51. this.placement = value;
  52. }
  53. public get StartVolume(): number {
  54. return this.startVolume;
  55. }
  56. public set StartVolume(value: number) {
  57. this.startVolume = value;
  58. }
  59. public get EndVolume(): number {
  60. return this.endVolume;
  61. }
  62. public set EndVolume(value: number) {
  63. this.endVolume = value;
  64. }
  65. public get StaffNumber(): number {
  66. return this.staffNumber;
  67. }
  68. public set StaffNumber(value: number) {
  69. this.staffNumber = value;
  70. }
  71. public get Label(): string {
  72. return this.label;
  73. }
  74. public set Label(value: string) {
  75. this.label = value;
  76. this.setType();
  77. }
  78. public static isInputStringContinuousDynamic(inputString: string): boolean {
  79. if (inputString === undefined) { return false; }
  80. return (
  81. ContinuousDynamicExpression.isStringInStringList(ContinuousDynamicExpression.listContinuousDynamicIncreasing, inputString)
  82. || ContinuousDynamicExpression.isStringInStringList(ContinuousDynamicExpression.listContinuousDynamicDecreasing, inputString)
  83. );
  84. }
  85. public getInterpolatedDynamic(currentAbsoluteTimestamp: Fraction): number {
  86. const continuousAbsoluteStartTimestamp: Fraction = this.StartMultiExpression.AbsoluteTimestamp;
  87. let continuousAbsoluteEndTimestamp: Fraction;
  88. if (this.EndMultiExpression !== undefined) {
  89. continuousAbsoluteEndTimestamp = this.EndMultiExpression.AbsoluteTimestamp;
  90. } else {
  91. continuousAbsoluteEndTimestamp = Fraction.plus(
  92. this.startMultiExpression.SourceMeasureParent.AbsoluteTimestamp, this.startMultiExpression.SourceMeasureParent.Duration
  93. );
  94. }
  95. if (currentAbsoluteTimestamp.lt(continuousAbsoluteStartTimestamp)) { return -1; }
  96. if (continuousAbsoluteEndTimestamp.lt(currentAbsoluteTimestamp)) { return -2; }
  97. const interpolationRatio: number =
  98. Fraction.minus(currentAbsoluteTimestamp, continuousAbsoluteStartTimestamp).RealValue
  99. / Fraction.minus(continuousAbsoluteEndTimestamp, continuousAbsoluteStartTimestamp).RealValue;
  100. const interpolatedVolume: number = Math.max(0.0, Math.min(99.9, this.startVolume + (this.endVolume - this.startVolume) * interpolationRatio));
  101. return interpolatedVolume;
  102. }
  103. public isWedge(): boolean {
  104. return this.label === undefined;
  105. }
  106. private setType(): void {
  107. if (ContinuousDynamicExpression.isStringInStringList(ContinuousDynamicExpression.listContinuousDynamicIncreasing, this.label)) {
  108. this.dynamicType = ContDynamicEnum.crescendo;
  109. } else if (ContinuousDynamicExpression.isStringInStringList(ContinuousDynamicExpression.listContinuousDynamicDecreasing, this.label)) {
  110. this.dynamicType = ContDynamicEnum.diminuendo;
  111. }
  112. }
  113. }
  114. export enum ContDynamicEnum {
  115. crescendo = 0,
  116. /** Diminuendo/Decrescendo. These terms are apparently sometimes synonyms, and a falling wedge is given in MusicXML as type="diminuendo". */
  117. diminuendo = 1
  118. }