Note.ts 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. import {VoiceEntry, StemDirectionType} from "./VoiceEntry";
  2. import {SourceStaffEntry} from "./SourceStaffEntry";
  3. import {Fraction} from "../../Common/DataObjects/Fraction";
  4. import {Pitch} from "../../Common/DataObjects/Pitch";
  5. import {Beam} from "./Beam";
  6. import {Tuplet} from "./Tuplet";
  7. import {Tie} from "./Tie";
  8. import {Staff} from "./Staff";
  9. import {Slur} from "./Expressions/ContinuousExpressions/Slur";
  10. import {NoteState} from "../Graphical/DrawingEnums";
  11. import {Notehead} from "./Notehead";
  12. import {Arpeggio} from "./Arpeggio";
  13. /**
  14. * Represents a single pitch with a duration (length)
  15. */
  16. export class Note {
  17. constructor(voiceEntry: VoiceEntry, parentStaffEntry: SourceStaffEntry, length: Fraction, pitch: Pitch) {
  18. this.voiceEntry = voiceEntry;
  19. this.parentStaffEntry = parentStaffEntry;
  20. this.length = length;
  21. this.pitch = pitch;
  22. if (pitch !== undefined) {
  23. this.halfTone = pitch.getHalfTone();
  24. } else {
  25. this.halfTone = 0;
  26. }
  27. }
  28. /**
  29. * The transposed (!!!) HalfTone of this note.
  30. */
  31. public halfTone: number;
  32. public state: NoteState;
  33. private voiceEntry: VoiceEntry;
  34. private parentStaffEntry: SourceStaffEntry;
  35. private length: Fraction;
  36. /** The length/duration given in the <type> tag. different from length for tuplets/tremolos. */
  37. private typeLength: Fraction;
  38. /** The amount of notes the tuplet of this note (if there is one) replaces. */
  39. private normalNotes: number;
  40. /**
  41. * The untransposed (!!!) source data.
  42. */
  43. private pitch: Pitch;
  44. private beam: Beam;
  45. private tuplet: Tuplet;
  46. private tie: Tie;
  47. private slurs: Slur[] = [];
  48. private playbackInstrumentId: string = undefined;
  49. private notehead: Notehead = undefined;
  50. /** States whether the note should be displayed. False if xmlNode.attribute("print-object").value = "no". */
  51. private printObject: boolean = true;
  52. /** The Arpeggio this note is part of. */
  53. private arpeggio: Arpeggio;
  54. /** States whether this is a cue note (Stichnote) (smaller size). */
  55. private isCueNote: boolean;
  56. /** The stem direction asked for in XML. Not necessarily final or wanted stem direction. */
  57. private stemDirectionXml: StemDirectionType;
  58. /** The number of tremolo strokes this note has (16th tremolo = 2 strokes).
  59. * Could be a Tremolo object in future when there is more data like tremolo between two notes.
  60. */
  61. private tremoloStrokes: number;
  62. /** Color of the stem given in the XML Stem tag. RGB Hexadecimal, like #00FF00.
  63. * This is not used for rendering, which takes VoiceEntry.StemColor.
  64. * It is merely given in the note's stem element in XML and stored here for reference.
  65. * So, to read or change the stem color of a note, modify note.ParentVoiceEntry.StemColor.
  66. */
  67. private stemColorXml: string;
  68. /** Color of the notehead given in the XML Notehead tag. RGB Hexadecimal, like #00FF00.
  69. * This should not be changed, instead noteheadColor is used and modifiable for Rendering.
  70. * Needs to be stored here and not in Note.Notehead,
  71. * because Note.Notehead is undefined for normal Noteheads to save space and time.
  72. */
  73. private noteheadColorXml: string;
  74. /** Color of the notehead currently set. RGB Hexadecimal, like #00FF00.
  75. * Needs to be stored here and not in Note.Notehead,
  76. * because Note.Notehead is undefined for normal Noteheads to save space and time.
  77. */
  78. private noteheadColor: string;
  79. public get ParentVoiceEntry(): VoiceEntry {
  80. return this.voiceEntry;
  81. }
  82. public set ParentVoiceEntry(value: VoiceEntry) {
  83. this.voiceEntry = value;
  84. }
  85. public get ParentStaffEntry(): SourceStaffEntry {
  86. return this.parentStaffEntry;
  87. }
  88. public get ParentStaff(): Staff {
  89. return this.parentStaffEntry.ParentStaff;
  90. }
  91. public get Length(): Fraction {
  92. return this.length;
  93. }
  94. public set Length(value: Fraction) {
  95. this.length = value;
  96. }
  97. public get TypeLength(): Fraction {
  98. return this.typeLength;
  99. }
  100. public set TypeLength(value: Fraction) {
  101. this.typeLength = value;
  102. }
  103. public get NormalNotes(): number {
  104. return this.normalNotes;
  105. }
  106. public set NormalNotes(value: number) {
  107. this.normalNotes = value;
  108. }
  109. public get Pitch(): Pitch {
  110. return this.pitch;
  111. }
  112. public get NoteBeam(): Beam {
  113. return this.beam;
  114. }
  115. public set NoteBeam(value: Beam) {
  116. this.beam = value;
  117. }
  118. public set Notehead(value: Notehead) {
  119. this.notehead = value;
  120. }
  121. public get Notehead(): Notehead {
  122. return this.notehead;
  123. }
  124. public get NoteTuplet(): Tuplet {
  125. return this.tuplet;
  126. }
  127. public set NoteTuplet(value: Tuplet) {
  128. this.tuplet = value;
  129. }
  130. public get NoteTie(): Tie {
  131. return this.tie;
  132. }
  133. public set NoteTie(value: Tie) {
  134. this.tie = value;
  135. }
  136. public get NoteSlurs(): Slur[] {
  137. return this.slurs;
  138. }
  139. public set NoteSlurs(value: Slur[]) {
  140. this.slurs = value;
  141. }
  142. public get PlaybackInstrumentId(): string {
  143. return this.playbackInstrumentId;
  144. }
  145. public set PlaybackInstrumentId(value: string) {
  146. this.playbackInstrumentId = value;
  147. }
  148. public get PrintObject(): boolean {
  149. return this.printObject;
  150. }
  151. public set PrintObject(value: boolean) {
  152. this.printObject = value;
  153. }
  154. public get Arpeggio(): Arpeggio {
  155. return this.arpeggio;
  156. }
  157. public set Arpeggio(value: Arpeggio) {
  158. this.arpeggio = value;
  159. }
  160. public get IsCueNote(): boolean {
  161. return this.isCueNote;
  162. }
  163. public set IsCueNote(value: boolean) {
  164. this.isCueNote = value;
  165. }
  166. public get StemDirectionXml(): StemDirectionType {
  167. return this.stemDirectionXml;
  168. }
  169. public set StemDirectionXml(value: StemDirectionType) {
  170. this.stemDirectionXml = value;
  171. }
  172. public get TremoloStrokes(): number {
  173. return this.tremoloStrokes;
  174. }
  175. public set TremoloStrokes(value: number) {
  176. this.tremoloStrokes = value;
  177. }
  178. public get StemColorXml(): string {
  179. return this.stemColorXml;
  180. }
  181. public set StemColorXml(value: string) {
  182. this.stemColorXml = value;
  183. }
  184. public get NoteheadColorXml(): string {
  185. return this.noteheadColorXml;
  186. }
  187. public set NoteheadColorXml(value: string) {
  188. this.noteheadColorXml = value;
  189. }
  190. public get NoteheadColor(): string {
  191. return this.noteheadColor;
  192. }
  193. public set NoteheadColor(value: string) {
  194. this.noteheadColor = value;
  195. }
  196. public isRest(): boolean {
  197. return this.Pitch === undefined;
  198. }
  199. public ToString(): string {
  200. if (this.pitch !== undefined) {
  201. return this.Pitch.ToString() + ", length: " + this.length.toString();
  202. } else {
  203. return "rest note, length: " + this.length.toString();
  204. }
  205. }
  206. public getAbsoluteTimestamp(): Fraction {
  207. return Fraction.plus(
  208. this.voiceEntry.Timestamp,
  209. this.parentStaffEntry.VerticalContainerParent.ParentMeasure.AbsoluteTimestamp
  210. );
  211. }
  212. public checkForDoubleSlur(slur: Slur): boolean {
  213. for (let idx: number = 0, len: number = this.slurs.length; idx < len; ++idx) {
  214. const noteSlur: Slur = this.slurs[idx];
  215. if (
  216. noteSlur.StartNote !== undefined &&
  217. noteSlur.EndNote !== undefined &&
  218. slur.StartNote !== undefined &&
  219. slur.StartNote === noteSlur.StartNote &&
  220. noteSlur.EndNote === this
  221. ) { return true; }
  222. }
  223. return false;
  224. }
  225. }
  226. export enum Appearance {
  227. Normal,
  228. Grace,
  229. Cue
  230. }