123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- import {Fraction} from "../../Common/DataObjects/Fraction";
- import {VerticalSourceStaffEntryContainer} from "./VerticalSourceStaffEntryContainer";
- import {Staff} from "./Staff";
- import {AbstractNotationInstruction} from "./Instructions/AbstractNotationInstruction";
- import {VoiceEntry} from "./VoiceEntry";
- import {Note} from "./Note";
- import {StaffEntryLink} from "./StaffEntryLink";
- import {ChordSymbolContainer} from "./ChordSymbolContainer";
- import {ClefInstruction} from "./Instructions/ClefInstruction";
- import {KeyInstruction} from "./Instructions/KeyInstruction";
- import {RhythmInstruction} from "./Instructions/RhythmInstruction";
- /**
- * A [[SourceStaffEntry]] is a container spanning all the [[VoiceEntry]]s at one timestamp for one [[StaffLine]].
- */
- export class SourceStaffEntry {
- constructor(verticalContainerParent: VerticalSourceStaffEntryContainer, parentStaff: Staff) {
- this.verticalContainerParent = verticalContainerParent;
- this.parentStaff = parentStaff;
- }
- private parentStaff: Staff;
- private verticalContainerParent: VerticalSourceStaffEntryContainer;
- private voiceEntries: VoiceEntry[] = [];
- private staffEntryLink: StaffEntryLink;
- private instructions: AbstractNotationInstruction[] = [];
- private chordSymbolContainers: ChordSymbolContainer[] = [];
- public get ParentStaff(): Staff {
- return this.parentStaff;
- }
- public get VerticalContainerParent(): VerticalSourceStaffEntryContainer {
- return this.verticalContainerParent;
- }
- public get Timestamp(): Fraction {
- if (this.VerticalContainerParent) {
- return this.VerticalContainerParent.Timestamp;
- }
- return undefined;
- }
- public get AbsoluteTimestamp(): Fraction {
- if (this.VerticalContainerParent) {
- return Fraction.plus(this.VerticalContainerParent.ParentMeasure.AbsoluteTimestamp, this.VerticalContainerParent.Timestamp);
- }
- return undefined;
- }
- public get VoiceEntries(): VoiceEntry[] {
- return this.voiceEntries;
- }
- public set VoiceEntries(value: VoiceEntry[]) {
- this.voiceEntries = value;
- }
- public get Link(): StaffEntryLink {
- return this.staffEntryLink;
- }
- public set Link(value: StaffEntryLink) {
- this.staffEntryLink = value;
- }
- public get Instructions(): AbstractNotationInstruction[] {
- return this.instructions;
- }
- public set Instructions(value: AbstractNotationInstruction[]) {
- this.instructions = value;
- }
- public get ChordContainers(): ChordSymbolContainer[] {
- return this.chordSymbolContainers;
- }
- public set ChordContainers(value: ChordSymbolContainer[]) {
- this.chordSymbolContainers = value;
- }
- // public removeAllInstructionsOfType(type: AbstractNotationInstruction): number {
- // let i: number = 0;
- // let ret: number = 0;
- // while (i < this.instructions.length) {
- // let instruction: AbstractNotationInstruction = this.instructions[i];
- // if (instruction instanceof type) {
- // this.instructions.splice(i, 1);
- // ret++;
- // } else {
- // i++;
- // }
- // }
- // return ret;
- // }
- //
- // public removeFirstInstructionOfType(type: AbstractNotationInstruction): boolean {
- // for (let i: number = 0; i < this.instructions.length; i++) {
- // if (this.instructions[i] instanceof type) {
- // this.instructions.splice(i, 1);
- // return true;
- // }
- // }
- // return false;
- // }
- public removeAllInstructionsOfTypeClefInstruction(): number {
- let i: number = 0;
- let ret: number = 0;
- while (i < this.instructions.length) {
- if (this.instructions[i] instanceof ClefInstruction) {
- this.instructions.splice(i, 1);
- ret++;
- } else {
- i++;
- }
- }
- return ret;
- }
- /**
- * Similar to RemoveAllInstructionsOfType but faster,
- * because it stops searching when the first instruction of the given type is found.
- * @returns {boolean}
- */
- public removeFirstInstructionOfTypeClefInstruction(): boolean {
- for (let i: number = 0; i < this.instructions.length; i++) {
- if (this.instructions[i] instanceof ClefInstruction) {
- this.instructions.splice(i, 1);
- return true;
- }
- }
- return false;
- }
- public removeAllInstructionsOfTypeKeyInstruction(): number {
- let i: number = 0;
- let ret: number = 0;
- while (i < this.instructions.length) {
- if (this.instructions[i] instanceof KeyInstruction) {
- this.instructions.splice(i, 1);
- ret++;
- } else {
- i++;
- }
- }
- return ret;
- }
- /**
- * Similar to RemoveAllInstructionsOfType but faster,
- * because it stops searching when the first instruction of the given type is found.
- * @returns {boolean}
- */
- public removeFirstInstructionOfTypeKeyInstruction(): boolean {
- for (let i: number = 0; i < this.instructions.length; i++) {
- if (this.instructions[i] instanceof KeyInstruction) {
- this.instructions.splice(i, 1);
- return true;
- }
- }
- return false;
- }
- public removeAllInstructionsOfTypeRhythmInstruction(): number {
- let i: number = 0;
- let ret: number = 0;
- while (i < this.instructions.length) {
- if (this.instructions[i] instanceof RhythmInstruction) {
- this.instructions.splice(i, 1);
- ret++;
- } else {
- i++;
- }
- }
- return ret;
- }
- public removeFirstInstructionOfTypeRhythmInstruction(): boolean {
- for (let i: number = 0; i < this.instructions.length; i++) {
- if (this.instructions[i] instanceof RhythmInstruction) {
- this.instructions.splice(i, 1);
- return true;
- }
- }
- return false;
- }
- /**
- * Calculate the [[SourceStaffEntry]]'s minimum NoteLength.
- * @returns {Fraction}
- */
- public calculateMinNoteLength(): Fraction {
- let duration: Fraction = new Fraction(Number.MAX_VALUE, 1);
- for (let idx: number = 0, len: number = this.VoiceEntries.length; idx < len; ++idx) {
- const voiceEntry: VoiceEntry = this.VoiceEntries[idx];
- for (let idx2: number = 0, len2: number = voiceEntry.Notes.length; idx2 < len2; ++idx2) {
- const note: Note = voiceEntry.Notes[idx2];
- if (note.Length.lt(duration)) {
- duration = note.Length;
- }
- }
- }
- return duration;
- }
- public calculateMaxNoteLength(): Fraction {
- let duration: Fraction = new Fraction(0, 1);
- for (let idx: number = 0, len: number = this.VoiceEntries.length; idx < len; ++idx) {
- const voiceEntry: VoiceEntry = this.VoiceEntries[idx];
- for (let idx2: number = 0, len2: number = voiceEntry.Notes.length; idx2 < len2; ++idx2) {
- const note: Note = voiceEntry.Notes[idx2];
- if (note.NoteTie) {
- // only add notes from this and after this sse!!
- const tieRestDuration: Fraction = Fraction.createFromFraction(note.Length);
- let addFollowingNotes: boolean = false;
- for (const n of note.NoteTie.Notes) {
- if (n === note) {
- addFollowingNotes = true;
- continue;
- }
- if (addFollowingNotes) {
- tieRestDuration.Add(n.Length);
- }
- }
- if (duration.lt(tieRestDuration)) {
- duration = tieRestDuration;
- }
- } else if (duration.lt(note.Length)) {
- duration = note.Length;
- }
- }
- }
- return duration;
- }
- public hasNotes(): boolean {
- for (let idx: number = 0, len: number = this.VoiceEntries.length; idx < len; ++idx) {
- const voiceEntry: VoiceEntry = this.VoiceEntries[idx];
- if (voiceEntry.Notes.length > 0) {
- return true;
- }
- }
- return false;
- }
- public hasTie(): boolean {
- for (let idx: number = 0, len: number = this.VoiceEntries.length; idx < len; ++idx) {
- const voiceEntry: VoiceEntry = this.VoiceEntries[idx];
- if (voiceEntry.hasTie()) {
- return true;
- }
- }
- return false;
- }
- public findLinkedNotes(linkedNotes: Note[]): void {
- for (let idx: number = 0, len: number = this.voiceEntries.length; idx < len; ++idx) {
- const voiceEntry: VoiceEntry = this.voiceEntries[idx];
- for (let idx2: number = 0, len2: number = voiceEntry.Notes.length; idx2 < len2; ++idx2) {
- const note: Note = voiceEntry.Notes[idx2];
- if (note.ParentStaffEntry === this) {
- linkedNotes.push(note);
- }
- }
- }
- }
- }
|