123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- import {SourceMeasure} from "../../VoiceData/SourceMeasure";
- import {RepetitionInstruction, RepetitionInstructionEnum, AlignmentType} from "../../VoiceData/Instructions/RepetitionInstruction";
- import {RepetitionInstructionComparer} from "../../VoiceData/Instructions/RepetitionInstruction";
- import {ArgumentOutOfRangeException} from "../../Exceptions";
- import {MusicSheet} from "../../MusicSheet";
- export class RepetitionCalculator {
- private musicSheet: MusicSheet;
- private repetitionInstructions: RepetitionInstruction[] = [];
- private currentMeasure: SourceMeasure;
- private currentMeasureIndex: number;
- /**
- * Is called when all repetition symbols have been read from xml.
- * Creates the repetition instructions and adds them to the corresponding measure.
- * Creates the logical repetition objects for iteration and playback.
- * @param musicSheet
- * @param repetitionInstructions
- */
- public calculateRepetitions(musicSheet: MusicSheet, repetitionInstructions: RepetitionInstruction[]): void {
- this.musicSheet = <MusicSheet>musicSheet;
- this.repetitionInstructions = repetitionInstructions;
- const sourceMeasures: SourceMeasure[] = this.musicSheet.SourceMeasures;
- for (let idx: number = 0, len: number = this.repetitionInstructions.length; idx < len; ++idx) {
- const instruction: RepetitionInstruction = this.repetitionInstructions[idx];
- this.currentMeasureIndex = instruction.measureIndex;
- this.currentMeasure = sourceMeasures[this.currentMeasureIndex];
- this.handleRepetitionInstructions(instruction);
- }
- // if there are more than one instruction at measure begin or end,
- // sort them according to the nesting of the repetitions:
- for (let idx: number = 0, len: number = this.musicSheet.SourceMeasures.length; idx < len; ++idx) {
- const measure: SourceMeasure = this.musicSheet.SourceMeasures[idx];
- if (measure.FirstRepetitionInstructions.length > 1) {
- measure.FirstRepetitionInstructions.sort(RepetitionInstructionComparer.Compare);
- }
- if (measure.LastRepetitionInstructions.length > 1) {
- measure.LastRepetitionInstructions.sort(RepetitionInstructionComparer.Compare);
- }
- }
- }
- private handleRepetitionInstructions(currentRepetitionInstruction: RepetitionInstruction): boolean {
- switch (currentRepetitionInstruction.type) {
- case RepetitionInstructionEnum.StartLine:
- this.currentMeasure.FirstRepetitionInstructions.push(currentRepetitionInstruction);
- break;
- case RepetitionInstructionEnum.BackJumpLine:
- this.currentMeasure.LastRepetitionInstructions.push(currentRepetitionInstruction);
- break;
- case RepetitionInstructionEnum.Ending:
- // set ending start or end
- if (currentRepetitionInstruction.alignment === AlignmentType.Begin) { // ending start
- this.currentMeasure.FirstRepetitionInstructions.push(currentRepetitionInstruction);
- } else { // ending end
- for (let idx: number = 0, len: number = currentRepetitionInstruction.endingIndices.length; idx < len; ++idx) {
- this.currentMeasure.LastRepetitionInstructions.push(currentRepetitionInstruction);
- }
- }
- break;
- case RepetitionInstructionEnum.Segno:
- this.currentMeasure.FirstRepetitionInstructions.push(currentRepetitionInstruction);
- break;
- case RepetitionInstructionEnum.Fine:
- this.currentMeasure.LastRepetitionInstructions.push(currentRepetitionInstruction);
- break;
- case RepetitionInstructionEnum.ToCoda:
- this.currentMeasure.LastRepetitionInstructions.push(currentRepetitionInstruction);
- break;
- case RepetitionInstructionEnum.Coda:
- this.currentMeasure.LastRepetitionInstructions.push(currentRepetitionInstruction);
- break;
- case RepetitionInstructionEnum.DaCapo:
- this.currentMeasure.LastRepetitionInstructions.push(currentRepetitionInstruction);
- break;
- case RepetitionInstructionEnum.DalSegno:
- this.currentMeasure.LastRepetitionInstructions.push(currentRepetitionInstruction);
- break;
- case RepetitionInstructionEnum.DalSegnoAlFine:
- this.currentMeasure.LastRepetitionInstructions.push(currentRepetitionInstruction);
- break;
- case RepetitionInstructionEnum.DaCapoAlFine:
- this.currentMeasure.LastRepetitionInstructions.push(currentRepetitionInstruction);
- break;
- case RepetitionInstructionEnum.DalSegnoAlCoda:
- this.currentMeasure.LastRepetitionInstructions.push(currentRepetitionInstruction);
- break;
- case RepetitionInstructionEnum.DaCapoAlCoda:
- this.currentMeasure.LastRepetitionInstructions.push(currentRepetitionInstruction);
- break;
- case RepetitionInstructionEnum.None:
- break;
- default:
- throw new ArgumentOutOfRangeException("currentRepetitionInstruction");
- }
- return true;
- }
- }
|