123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- import {Fraction} from "../../Common/DataObjects/fraction";
- import {Voice} from "./Voice";
- import {SourceStaffEntry} from "./SourceStaffEntry";
- import {Note} from "./Note";
- import {Pitch} from "../../Common/DataObjects/pitch";
- import {LyricsEntry} from "./Lyrics/LyricsEntry";
- import {TechnicalInstruction} from "./Instructions/TechnicalInstruction";
- import {OrnamentContainer} from "./OrnamentContainer";
- import {KeyInstruction} from "./Instructions/KeyInstruction";
- import {OrnamentEnum} from "./OrnamentContainer";
- import {AccidentalEnum} from "../../Common/DataObjects/pitch";
- export class VoiceEntry {
- constructor(timestamp: Fraction, parentVoice: Voice, parentSourceStaffEntry: SourceStaffEntry) {
- this.timestamp = timestamp;
- this.parentVoice = parentVoice;
- this.parentSourceStaffEntry = parentSourceStaffEntry;
- }
- public graceVoiceEntriesBefore: VoiceEntry[];
- public graceVoiceEntriesAfter: VoiceEntry[];
- private parentVoice: Voice;
- private parentSourceStaffEntry: SourceStaffEntry;
- private timestamp: Fraction;
- private notes: Note[] = [];
- private articulations: ArticulationEnum[] = [];
- private technicalInstructions: TechnicalInstruction[] = [];
- private lyricsEntries: { [n: number]: LyricsEntry; } = {};
- private arpeggiosNotesIndices: number[] = [];
- private ornamentContainer: OrnamentContainer;
- public get ParentSourceStaffEntry(): SourceStaffEntry {
- return this.parentSourceStaffEntry;
- }
- public get ParentVoice(): Voice {
- return this.parentVoice;
- }
- public get Timestamp(): Fraction {
- return this.timestamp;
- }
- public set Timestamp(value: Fraction) {
- this.timestamp = value;
- }
- public get Notes(): Note[] {
- return this.notes;
- }
- public get Articulations(): ArticulationEnum[] {
- return this.articulations;
- }
- public get TechnicalInstructions(): TechnicalInstruction[] {
- return this.technicalInstructions;
- }
- public get LyricsEntries(): { [n: number]: LyricsEntry; } {
- return this.lyricsEntries;
- }
- public set LyricsEntries(value: { [n: number]: LyricsEntry; }) {
- this.lyricsEntries = value;
- }
- public get ArpeggiosNotesIndices(): number[] {
- return this.arpeggiosNotesIndices;
- }
- public set ArpeggiosNotesIndices(value: number[]) {
- this.arpeggiosNotesIndices = value;
- }
- public get OrnamentContainer(): OrnamentContainer {
- return this.ornamentContainer;
- }
- public set OrnamentContainer(value: OrnamentContainer) {
- this.ornamentContainer = value;
- }
- public static isSupportedArticulation(articulation: ArticulationEnum): boolean {
- switch (articulation) {
- case ArticulationEnum.accent:
- case ArticulationEnum.strongaccent:
- case ArticulationEnum.invertedstrongaccent:
- case ArticulationEnum.staccato:
- case ArticulationEnum.staccatissimo:
- case ArticulationEnum.spiccato:
- case ArticulationEnum.tenuto:
- case ArticulationEnum.fermata:
- case ArticulationEnum.invertedfermata:
- case ArticulationEnum.breathmark:
- case ArticulationEnum.caesura:
- case ArticulationEnum.lefthandpizzicato:
- case ArticulationEnum.naturalharmonic:
- case ArticulationEnum.snappizzicato:
- case ArticulationEnum.upbow:
- case ArticulationEnum.downbow:
- return true;
- default:
- return false;
- }
- }
- public hasTie(): boolean {
- for (let idx: number = 0, len: number = this.Notes.length; idx < len; ++idx) {
- let note: Note = this.Notes[idx];
- if (note.NoteTie !== undefined) { return true; }
- }
- return false;
- }
- public hasSlur(): boolean {
- for (let idx: number = 0, len: number = this.Notes.length; idx < len; ++idx) {
- let note: Note = this.Notes[idx];
- if (note.NoteSlurs.length > 0) { return true; }
- }
- return false;
- }
- public isStaccato(): boolean {
- for (let idx: number = 0, len: number = this.Articulations.length; idx < len; ++idx) {
- let articulation: ArticulationEnum = this.Articulations[idx];
- if (articulation === ArticulationEnum.staccato) { return true; }
- }
- return false;
- }
- public isAccent(): boolean {
- for (let idx: number = 0, len: number = this.Articulations.length; idx < len; ++idx) {
- let articulation: ArticulationEnum = this.Articulations[idx];
- if (articulation === ArticulationEnum.accent || articulation === ArticulationEnum.strongaccent) {
- return true;
- }
- }
- return false;
- }
- public getVerseNumberForLyricEntry(lyricsEntry: LyricsEntry): number {
- let lyricsEntries: { [n: number]: LyricsEntry; } = this.lyricsEntries;
- for (let key in lyricsEntries) {
- if (lyricsEntries.hasOwnProperty(key)) { // FIXME check has own property
- if (lyricsEntry === this.lyricsEntries[key]) {
- return +key;
- }
- }
- }
- return 1;
- }
- //public createVoiceEntriesForOrnament(activeKey: KeyInstruction): VoiceEntry[] {
- // return this.createVoiceEntriesForOrnament(this, activeKey);
- //}
- public createVoiceEntriesForOrnament(voiceEntryWithOrnament: VoiceEntry, activeKey: KeyInstruction): VoiceEntry[] {
- if (voiceEntryWithOrnament === undefined) {
- voiceEntryWithOrnament = this;
- }
- let voiceEntries: VoiceEntry[] = [];
- if (voiceEntryWithOrnament.ornamentContainer === undefined) {
- return;
- }
- let baseNote: Note = this.notes[0];
- let baselength: Fraction = baseNote.calculateNoteLengthWithoutTie();
- let baseVoice: Voice = voiceEntryWithOrnament.ParentVoice;
- let baseTimestamp: Fraction = voiceEntryWithOrnament.Timestamp;
- let currentTimestamp: Fraction = Fraction.createFromFraction(baseTimestamp);
- //let length: Fraction;
- switch (voiceEntryWithOrnament.ornamentContainer.GetOrnament) {
- case OrnamentEnum.Trill: {
- let length: Fraction = new Fraction(baselength.Numerator, baselength.Denominator * 8);
- let higherPitch: Pitch = baseNote.Pitch.getTransposedPitch(1);
- let alteration: AccidentalEnum = activeKey.getAlterationForPitch(higherPitch);
- if (voiceEntryWithOrnament.OrnamentContainer.AccidentalAbove !== AccidentalEnum.NONE) {
- alteration = <AccidentalEnum><number>voiceEntryWithOrnament.ornamentContainer.AccidentalAbove;
- }
- for (let i: number = 0; i < 8; i++) {
- currentTimestamp = Fraction.plus(baseTimestamp, new Fraction(i * length.Numerator, length.Denominator));
- if ((i % 2) === 0) {
- this.createBaseVoiceEntry(currentTimestamp, length, baseVoice, baseNote, voiceEntries);
- } else {
- this.createAlteratedVoiceEntry(currentTimestamp, length, baseVoice, higherPitch, alteration, voiceEntries);
- }
- }
- }
- break;
- case OrnamentEnum.Turn: {
- let length: Fraction = new Fraction(baselength.Numerator, baselength.Denominator * 4);
- let lowerPitch: Pitch = baseNote.Pitch.getTransposedPitch(-1);
- let lowerAlteration: AccidentalEnum = activeKey.getAlterationForPitch(lowerPitch);
- let higherPitch: Pitch = baseNote.Pitch.getTransposedPitch(1);
- let higherAlteration: AccidentalEnum = activeKey.getAlterationForPitch(higherPitch);
- this.createAlteratedVoiceEntry(
- currentTimestamp, length, baseVoice, higherPitch, higherAlteration, voiceEntries
- );
- currentTimestamp.push(length);
- this.createBaseVoiceEntry(currentTimestamp, length, baseVoice, baseNote, voiceEntries);
- currentTimestamp.push(length);
- this.createAlteratedVoiceEntry(
- currentTimestamp, length, baseVoice, lowerPitch, lowerAlteration, voiceEntries
- );
- currentTimestamp.push(length);
- this.createBaseVoiceEntry(currentTimestamp, length, baseVoice, baseNote, voiceEntries);
- }
- break;
- case OrnamentEnum.InvertedTurn: {
- let length: Fraction = new Fraction(baselength.Numerator, baselength.Denominator * 4);
- let lowerPitch: Pitch = baseNote.Pitch.getTransposedPitch(-1);
- let lowerAlteration: AccidentalEnum = activeKey.getAlterationForPitch(lowerPitch);
- let higherPitch: Pitch = baseNote.Pitch.getTransposedPitch(1);
- let higherAlteration: AccidentalEnum = activeKey.getAlterationForPitch(higherPitch);
- this.createAlteratedVoiceEntry(
- currentTimestamp, length, baseVoice, lowerPitch, lowerAlteration, voiceEntries
- );
- currentTimestamp.push(length);
- this.createBaseVoiceEntry(currentTimestamp, length, baseVoice, baseNote, voiceEntries);
- currentTimestamp.push(length);
- this.createAlteratedVoiceEntry(
- currentTimestamp, length, baseVoice, higherPitch, higherAlteration, voiceEntries
- );
- currentTimestamp.push(length);
- this.createBaseVoiceEntry(currentTimestamp, length, baseVoice, baseNote, voiceEntries);
- }
- break;
- case OrnamentEnum.DelayedTurn: {
- let length: Fraction = new Fraction(baselength.Numerator, baselength.Denominator * 2);
- let lowerPitch: Pitch = baseNote.Pitch.getTransposedPitch(-1);
- let lowerAlteration: AccidentalEnum = activeKey.getAlterationForPitch(lowerPitch);
- let higherPitch: Pitch = baseNote.Pitch.getTransposedPitch(1);
- let higherAlteration: AccidentalEnum = activeKey.getAlterationForPitch(higherPitch);
- this.createBaseVoiceEntry(currentTimestamp, length, baseVoice, baseNote, voiceEntries);
- currentTimestamp = Fraction.plus(baseTimestamp, length);
- length.Denominator = baselength.Denominator * 8;
- this.createAlteratedVoiceEntry(currentTimestamp, length, baseVoice, higherPitch, higherAlteration, voiceEntries);
- currentTimestamp.push(length);
- this.createBaseVoiceEntry(currentTimestamp, length, baseVoice, baseNote, voiceEntries);
- currentTimestamp.push(length);
- this.createAlteratedVoiceEntry(currentTimestamp, length, baseVoice, lowerPitch, lowerAlteration, voiceEntries);
- currentTimestamp.push(length);
- this.createBaseVoiceEntry(currentTimestamp, length, baseVoice, baseNote, voiceEntries);
- }
- break;
- case OrnamentEnum.DelayedInvertedTurn: {
- let length: Fraction = new Fraction(baselength.Numerator, baselength.Denominator * 2);
- let lowerPitch: Pitch = baseNote.Pitch.getTransposedPitch(-1);
- let lowerAlteration: AccidentalEnum = activeKey.getAlterationForPitch(lowerPitch);
- let higherPitch: Pitch = baseNote.Pitch.getTransposedPitch(1);
- let higherAlteration: AccidentalEnum = activeKey.getAlterationForPitch(higherPitch);
- this.createBaseVoiceEntry(currentTimestamp, length, baseVoice, baseNote, voiceEntries);
- currentTimestamp = Fraction.plus(baseTimestamp, length);
- length.Denominator = baselength.Denominator * 8;
- this.createAlteratedVoiceEntry(currentTimestamp, length, baseVoice, lowerPitch, lowerAlteration, voiceEntries);
- currentTimestamp.push(length);
- this.createBaseVoiceEntry(currentTimestamp, length, baseVoice, baseNote, voiceEntries);
- currentTimestamp.push(length);
- this.createAlteratedVoiceEntry(currentTimestamp, length, baseVoice, higherPitch, higherAlteration, voiceEntries);
- currentTimestamp.push(length);
- this.createBaseVoiceEntry(currentTimestamp, length, baseVoice, baseNote, voiceEntries);
- }
- break;
- case OrnamentEnum.Mordent: {
- let length: Fraction = new Fraction(baselength.Numerator, baselength.Denominator * 4);
- let higherPitch: Pitch = baseNote.Pitch.getTransposedPitch(1);
- let alteration: AccidentalEnum = activeKey.getAlterationForPitch(higherPitch);
- this.createBaseVoiceEntry(currentTimestamp, length, baseVoice, baseNote, voiceEntries);
- currentTimestamp.push(length);
- this.createAlteratedVoiceEntry(currentTimestamp, length, baseVoice, higherPitch, alteration, voiceEntries);
- length.Denominator = baselength.Denominator * 2;
- currentTimestamp = Fraction.plus(baseTimestamp, length);
- this.createBaseVoiceEntry(currentTimestamp, length, baseVoice, baseNote, voiceEntries);
- }
- break;
- case OrnamentEnum.InvertedMordent: {
- let length: Fraction = new Fraction(baselength.Numerator, baselength.Denominator * 4);
- let lowerPitch: Pitch = baseNote.Pitch.getTransposedPitch(-1);
- let alteration: AccidentalEnum = activeKey.getAlterationForPitch(lowerPitch);
- this.createBaseVoiceEntry(currentTimestamp, length, baseVoice, baseNote, voiceEntries);
- currentTimestamp.push(length);
- this.createAlteratedVoiceEntry(currentTimestamp, length, baseVoice, lowerPitch, alteration, voiceEntries);
- length.Denominator = baselength.Denominator * 2;
- currentTimestamp = Fraction.plus(baseTimestamp, length);
- this.createBaseVoiceEntry(currentTimestamp, length, baseVoice, baseNote, voiceEntries);
- }
- break;
- default:
- throw new RangeError();
- }
- return voiceEntries;
- }
- private createBaseVoiceEntry(
- currentTimestamp: Fraction, length: Fraction, baseVoice: Voice, baseNote: Note, voiceEntries: VoiceEntry[]
- ): void {
- let voiceEntry: VoiceEntry = new VoiceEntry(currentTimestamp, baseVoice, baseNote.ParentStaffEntry);
- let pitch: Pitch = new Pitch(baseNote.Pitch.FundamentalNote, baseNote.Pitch.Octave, baseNote.Pitch.Accidental);
- let note: Note = new Note(voiceEntry, undefined, length, pitch);
- voiceEntry.Notes.push(note);
- voiceEntries.push(voiceEntry);
- }
- private createAlteratedVoiceEntry(
- currentTimestamp: Fraction, length: Fraction, baseVoice: Voice, higherPitch: Pitch,
- alteration: AccidentalEnum, voiceEntries: VoiceEntry[]
- ): void {
- let voiceEntry: VoiceEntry = new VoiceEntry(currentTimestamp, baseVoice, undefined);
- let pitch: Pitch = new Pitch(higherPitch.FundamentalNote, higherPitch.Octave, alteration);
- let note: Note = new Note(voiceEntry, undefined, length, pitch);
- voiceEntry.Notes.push(note);
- voiceEntries.push(voiceEntry);
- }
- }
- export enum ArticulationEnum {
- accent,
- strongaccent,
- invertedstrongaccent,
- staccato,
- staccatissimo,
- spiccato,
- tenuto,
- fermata,
- invertedfermata,
- breathmark,
- caesura,
- lefthandpizzicato,
- naturalharmonic,
- snappizzicato,
- upbow,
- downbow,
- scoop,
- plop,
- doit,
- falloff,
- stress,
- unstress,
- detachedlegato,
- otherarticulation
- }
|