public override bool TryParse(Scanner scanner, out TempoCommandletNode commandlet) { scanner.SkipOptional(':', true); commandlet = new TempoCommandletNode(); var match = scanner.Match(@"((\d+)\s*=\s*)?(\d+)"); if (!match.Success) { this.Report(LogLevel.Error, scanner.LastReadRange, Messages.Error_InvalidTempoSignature); commandlet = null; return(false); } if (match.Groups[1].Success) { var noteValueNumber = int.Parse(match.Groups[2].Value); BaseNoteValue noteValue; if (!BaseNoteValues.TryParse(noteValueNumber, out noteValue)) { this.Report(LogLevel.Error, scanner.LastReadRange, Messages.Error_IrrationalNoteValueInTempoSignatureNotSupported); commandlet = null; return(false); } commandlet.NoteValue = new LiteralNode <BaseNoteValue>(noteValue, new TextRange(scanner.LastReadRange, match.Groups[2], scanner.Source)); } var beats = int.Parse(match.Groups[3].Value); if (beats == 0) { this.Report(LogLevel.Error, scanner.LastReadRange, Messages.Error_TempoSignatureSpeedTooLow); commandlet = null; return(false); } if (beats > 10000) { this.Report(LogLevel.Error, scanner.LastReadRange, Messages.Error_TempoSignatureSpeedTooFast); commandlet = null; return(false); } commandlet.Beats = new LiteralNode <int>(beats, new TextRange(scanner.LastReadRange, match.Groups[3], scanner.Source)); return(true); }
public bool ToDocumentElement(TablatureContext context, ILogger logger, VoicePart voicePart, out RhythmSegmentVoice voice) { voice = new RhythmSegmentVoice(voicePart) { Range = this.Range }; context.CurrentVoice = voice; foreach (var beat in this.Beats) { Beat documentBeat; if (!beat.ToDocumentElement(context, logger, voice, out documentBeat)) { return(false); } voice.Beats.Add(documentBeat); } // try to fill voice with rests if insufficient notes fed var duration = this.GetDuration(); if (duration < this.ExpectedDuration) { BaseNoteValue[] factors; if (!BaseNoteValues.TryFactorize(this.ExpectedDuration - duration, out factors)) { logger.Report(LogLevel.Error, this.Range, Messages.Error_InconsistentVoiceDurationCannotBeFilledWithRest); return(false); } logger.Report(LogLevel.Suggestion, this.Range, Messages.Suggestion_InconsistentVoiceDuration); foreach (var factor in factors) { var beat = new Beat() { NoteValue = new NoteValue(factor), IsRest = true, Notes = new BeatNote[0] }; context.CurrentVoice.IsTerminatedWithRest = true; voice.Beats.Add(beat); } } return(true); }
public override bool TryParse(Scanner scanner, out TimeSignatureCommandletNode commandlet) { commandlet = new TimeSignatureCommandletNode(); scanner.SkipOptional(':', true); var match = scanner.Match(@"(\d+)\s*\/\s*(\d+)"); if (!match.Success) { this.Report(LogLevel.Error, scanner.LastReadRange, Messages.Error_InvalidTimeSignature); commandlet = null; return(false); } var beats = int.Parse(match.Groups[1].Value); if (beats > 32) { this.Report(LogLevel.Error, scanner.LastReadRange, Messages.Error_UnsupportedBeatsInTimeSignature); commandlet = null; return(false); } commandlet.Beats = new LiteralNode <int>(beats, new TextRange(scanner.LastReadRange, match.Groups[1], scanner.Source)); var noteValueNumber = int.Parse(match.Groups[2].Value); if (noteValueNumber > 32) { this.Report(LogLevel.Error, scanner.LastReadRange, Messages.Error_UnsupportedNoteValueInTimeSignature); commandlet = null; return(false); } BaseNoteValue noteValue; if (!BaseNoteValues.TryParse(noteValueNumber, out noteValue)) { this.Report(LogLevel.Error, scanner.LastReadRange, Messages.Error_IrrationalNoteValueInTimeSignatureNotSupported); commandlet = null; return(false); } commandlet.NoteValue = new LiteralNode <BaseNoteValue>(noteValue, new TextRange(scanner.LastReadRange, match.Groups[2], scanner.Source)); return(true); }
public static bool TryReadBaseNoteValue(Scanner scanner, ILogger logger, out LiteralNode <BaseNoteValue> baseNoteValueNode) { int reciprocal; if (!scanner.TryReadInteger(out reciprocal)) { logger.Report(LogLevel.Error, scanner.LastReadRange, Messages.Error_NoteValueExpected); baseNoteValueNode = null; return(false); } BaseNoteValue baseNoteValue; if (!BaseNoteValues.TryParse(reciprocal, out baseNoteValue)) { logger.Report(LogLevel.Error, scanner.LastReadRange, Messages.Error_InvalidReciprocalNoteValue); baseNoteValueNode = null; return(false); } baseNoteValueNode = new LiteralNode <BaseNoteValue>(baseNoteValue, scanner.LastReadRange); return(true); }