protected bool FillRhythmSegmentVoices(TablatureContext context, ILogger logger, RhythmSegmentBase rhythmSegment) { var duration = this.GetDuration(); if (this.TrebleVoice != null) { this.TrebleVoice.ExpectedDuration = duration; RhythmSegmentVoice trebleVoice; if (!this.TrebleVoice.ToDocumentElement(context, logger, VoicePart.Treble, out trebleVoice)) { return(false); } rhythmSegment.TrebleVoice = trebleVoice; } if (this.BassVoice != null) { this.BassVoice.ExpectedDuration = duration; RhythmSegmentVoice bassVoice; if (!this.BassVoice.ToDocumentElement(context, logger, VoicePart.Bass, out bassVoice)) { return(false); } rhythmSegment.BassVoice = bassVoice; } return(true); }
internal override bool Apply(TablatureContext context, ILogger logger) { Alternation alternation; if (!this.ToDocumentElement(context, logger, out alternation)) { return(false); } if (context.DocumentState.AlternationTextExplicity != Explicity.NotSpecified && alternation.Explicity != context.DocumentState.AlternationTextExplicity) { logger.Report(LogLevel.Warning, this.Range.To.AsRange(), Messages.Warning_InconsistentAlternationTextExplicity); } using (var state = context.AlterDocumentState()) { foreach (var index in alternation.Indices) { state.DefinedAlternationIndices.Add(index); } state.CurrentAlternation = alternation; state.AlternationTextType = alternation.TextType; state.AlternationTextExplicity = alternation.Explicity; } return(true); }
internal override bool Apply(TablatureContext context, ILogger logger) { Bar bar; if (!this.ToDocumentElement(context, logger, null, out bar)) { return(false); } if (bar.Rhythm != null && bar.Lyrics != null) { var beats = bar.Rhythm.Segments.Sum(s => s.FirstVoice.Beats?.Count ?? 0); if (beats < bar.Lyrics.Segments.Count) { logger.Report(LogLevel.Suggestion, bar.Lyrics.Range, Messages.Suggestion_LyricsTooLong); } } context.AddBar(bar); // check if this bar terminates an alternative ending, must be done AFTER adding this bar to context if ((bar.CloseLine == CloseBarLine.End || bar.CloseLine == CloseBarLine.EndRepeat) && context.DocumentState.CurrentAlternation != null) { using (var state = context.AlterDocumentState()) { state.CurrentAlternation = null; } } return(true); }
public bool ToDocumentElement(TablatureContext context, ILogger logger, VoicePart voicePart, out BeatNote element) { var documentState = context.DocumentState; if (this.Fret != null && this.Fret.Value + documentState.MinimumCapoFret < (documentState.CapoFretOffsets?[this.String.Value - 1] ?? 0)) { logger.Report(LogLevel.Warning, this.Fret.Range, Messages.Warning_FretUnderCapo, this.String.Value, this.Fret.Value); } element = new BeatNote { Range = this.Range, PreConnection = this.PreConnection?.Value ?? PreNoteConnection.None, PostConnection = this.PostConnection?.Value ?? PostNoteConnection.None, IsTied = this.Tie != null, TiePosition = this.TiePosition?.Value, String = this.String.Value - 1, Fret = this.Fret?.Value ?? BeatNote.UnspecifiedFret, EffectTechnique = this.EffectTechnique?.Value ?? NoteEffectTechnique.None, EffectTechniqueParameter = this.EffectTechniqueParameter?.Value, Accent = this.Accent?.Value ?? NoteAccent.Normal }; if (!this.Validate(context, logger, voicePart, element)) { return(false); } return(true); }
public bool ToDocumentElement(TablatureContext context, ILogger logger, out ChordDefinition element) { if (context.DocumentState.DefinedChords.Any( c => c.Name.Equals(this.Name.Value, StringComparison.InvariantCulture))) { logger.Report(LogLevel.Warning, this.Range, Messages.Warning_ChordAlreadyDefined); element = null; return(false); } ChordFingering chordFingering; if (!this.Fingering.ToDocumentElement(context, logger, out chordFingering)) { element = null; return(false); } element = new ChordDefinition { Range = this.Range, DisplayName = this.GetDisplayName(), Name = this.Name.Value, Fingering = chordFingering }; return(true); }
public bool ToDocumentElement(TablatureContext context, ILogger logger, out Rhythm rhythm) { rhythm = new Rhythm { Range = this.Range }; var duration = PreciseDuration.Zero; foreach (var segment in this.Segments) { RhythmSegment rhythmSegment; if (!segment.ToDocumentElement(context, logger, out rhythmSegment)) { return(false); } rhythm.Segments.Add(rhythmSegment); duration += segment.GetDuration(); } // duration could be 0 if rhythm is not defined (only chord defined), rhythm will be determined by the rhythm instruction if (duration > 0 && duration == context.DocumentState.TimeSignature.Time.GetDuration()) { logger.Report(LogLevel.Warning, this.Range, Messages.Warning_BeatsNotMatchingTimeSignature); rhythm.NotMatchingTime = true; } return(true); }
public override bool CheckIntegrity(TablatureContext context, ILogger logger) { if (context.Bars.Count > 0) { var firstBar = context.Bars[0]; if (firstBar.OpenLine == null) { logger.Report(LogLevel.Hint, firstBar.Range.Value.From.AsRange(), Messages.Hint_FirstOpenBarLineMissing); } for (var i = 1; i < context.Bars.Count - 1; ++i) { if (context.Bars[i].CloseLine == null && context.Bars[i + 1].OpenLine == null) { logger.Report(LogLevel.Warning, context.Bars[i].Range.Value.To.AsRange(), Messages.Warning_BarLineMissing); } } var lastBar = context.Bars[context.Bars.Count - 1]; if (lastBar.CloseLine == null) { logger.Report(LogLevel.Hint, lastBar.Range.Value.To.AsRange(), Messages.Hint_LastCloseBarLineMissing); } } return(true); }
public override bool CheckIntegrity(TablatureContext context, ILogger logger) { var lastIndex = 0; var missingIndices = new List <int>(); foreach (var index in context.DocumentState.DefinedAlternationIndices.OrderBy(i => i)) { if (index != lastIndex + 1) { missingIndices.Add(index); } lastIndex = index; } if (missingIndices.Count == 0) { return(true); } var alternationTextType = context.DocumentState.AlternationTextType ?? AlternationTextType.Arabic; logger.Report(LogLevel.Error, null, Messages.Error_MissingAlternationTexts, string.Join(", ", missingIndices.Select(i => AlternationText.GetAlternationText(alternationTextType, i)))); return(false); }
internal override bool Apply(TablatureContext context, ILogger logger) { if (context.DocumentState.BarAppeared) { logger.Report(LogLevel.Error, this.Range, Messages.Error_TuningInstructionAfterBarAppeared); return(false); } if (context.DocumentState.TuningSignature != null) { logger.Report(LogLevel.Warning, this.Range, Messages.Warning_RedefiningTuningInstruction); return(false); } TuningSignature tuning; if (!this.ToDocumentElement(context, logger, out tuning)) { return(false); } using (var state = context.AlterDocumentState()) { state.TuningSignature = tuning; } return(true); }
private bool ValidatePostConnection(TablatureContext context, ILogger logger, VoicePart voicePart, BeatNote element) { if (this.PostConnection == null || this.PostConnection.Value == PostNoteConnection.None) { return(true); } if (this.PostConnection.Value == PostNoteConnection.SlideOutToHigher || this.PostConnection.Value == PostNoteConnection.SlideOutToLower) { if (this.Fret == null) { logger.Report(LogLevel.Error, this.PreConnection.Range, Messages.Error_FretMissingForSlideOutNote); return(false); } if (this.PostConnection.Value == PostNoteConnection.SlideOutToLower && this.Fret.Value <= context.DocumentState.GetCapoFretOffset(this.String.Value - 1)) { logger.Report(LogLevel.Warning, this.Fret.Range, Messages.Warning_FretTooLowForSlideOutNote); element.PostConnection = PostNoteConnection.None; } } return(true); }
public bool ToDocumentElement(TablatureContext context, ILogger logger, out TimeSignature element) { if ((context.DocumentState.RhythmTemplate != null || context.DocumentState.BarAppeared) && context.DocumentState.TimeSignature == null) { logger.Report(LogLevel.Error, this.Range, Messages.Error_TimeInstructionAfterBarAppearedOrRhythmInstruction); element = null; return(false); } if (context.DocumentState.TimeSignature != null && this.ValueEquals(context.DocumentState.TimeSignature)) { logger.Report(LogLevel.Suggestion, this.Range, Messages.Suggestion_UselessTimeInstruction); element = null; return(false); } element = new TimeSignature { Range = this.Range, Time = new Time(this.Beats.Value, this.NoteValue.Value) }; return(true); }
public bool ToDocumentElement(TablatureContext context, ILogger logger, out RhythmTemplateSegment rhythmSegment) { rhythmSegment = new RhythmTemplateSegment { Range = this.Range }; return(this.FillRhythmSegmentVoices(context, logger, rhythmSegment)); }
public bool ToDocumentElement(TablatureContext context, ILogger logger, out LyricsSegment lyricsSegment) { lyricsSegment = new LyricsSegment { Text = this.Text.Value, Range = this.Range }; return(true); }
public BarArranger(TablatureContext context, DocumentBar bar) { _context = context; _bar = bar; _previousBeats = new Dictionary <VoicePart, Beat> { { VoicePart.Bass, null }, { VoicePart.Treble, null } }; }
public bool ToDocumentElement(TablatureContext context, ILogger logger, out TuningSignature element) { element = new TuningSignature { Range = this.Range, Tuning = new Tuning(this.Name?.Value, this.StringTunings.Select(t => t.ToPitch()).ToArray()) }; 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); }
internal override bool Apply(TablatureContext context, ILogger logger) { var templateBarNodes = this.TemplateBars.Bars; var instanceBarNodes = this.InstanceBars.Bars; if (instanceBarNodes.Count < templateBarNodes.Count) { logger.Report(LogLevel.Warning, this.InstanceBars.Range, Messages.Warning_PatternInstanceBarsLessThanTemplateBars); } var templateBars = new List <Bar>(); foreach (var barNode in templateBarNodes) { if (barNode.Lyrics != null) { logger.Report(LogLevel.Warning, barNode.Lyrics.Range, Messages.Warning_TemplateBarCannotContainLyrics); } Bar bar; if (!barNode.ToDocumentElement(context, logger, null, out bar)) { return(false); } templateBars.Add(bar); } var templateIndex = 0; foreach (var barNode in instanceBarNodes) { var templateBar = templateBars[templateIndex]; Bar instanceBar; if (this.ApplyTemplateBar(templateBar, barNode, out instanceBar, context, logger)) { context.AddBar(instanceBar); } ++templateIndex; if (templateIndex == templateBarNodes.Count) { templateIndex = 0; } } return(true); }
internal override bool Apply(TablatureContext context, ILogger logger) { KeySignature key; if (!this.ToDocumentElement(context, logger, out key)) { return(false); } using (var state = context.AlterDocumentState()) state.KeySignature = key; return(true); }
internal override bool Apply(TablatureContext context, ILogger logger) { Capo capo; if (!this.ToDocumentElement(context, logger, out capo)) return false; using (var state = context.AlterDocumentState()) { state.Capos.Add(capo); state.CapoFretOffsets = capo.OffsetFrets(state.CapoFretOffsets); } return true; }
public override bool CheckIntegrity(TablatureContext context, ILogger logger) { foreach (var capo in context.DocumentState .Capos .Where(capo => capo.CapoInfo.AffectedStrings .All(n => capo.CapoInfo.Position < context.DocumentState.CapoFretOffsets[n - 1])) ) { logger.Report(LogLevel.Suggestion, capo.Range, Messages.Suggestion_UselessCapoInstruction); } return(true); }
public bool ValidateColumn(TablatureContext context, ILogger logger, BarColumn column) { if (column.VoiceBeats.Count == 2 && column.VoiceBeats.All(b => b.StrumTechnique != StrumTechnique.None)) { if (column.VoiceBeats[0].StrumTechnique != column.VoiceBeats[1].StrumTechnique) { logger.Report(LogLevel.Warning, column.VoiceBeats[1].Range, Messages.Warning_ConflictedStrumTechniques); column.VoiceBeats[1].StrumTechnique = StrumTechnique.None; } } return(true); }
public bool ToDocumentElement(TablatureContext context, ILogger logger, RhythmSegmentVoice ownerVoice, out Beat beat) { beat = new Beat() { Range = this.Range, StrumTechnique = this.StrumTechnique?.Value ?? (StrumTechniqueEnum?)this.ChordStrumTechnique?.Value ?? StrumTechniqueEnum.None, Accent = this.Accent?.Value ?? Core.MusicTheory.BeatAccent.Normal, HoldAndPause = this.HoldAndPause?.Value ?? Core.MusicTheory.HoldAndPause.None, Ornament = this.Ornament?.Value ?? Core.MusicTheory.Ornament.None, NoteRepetition = this.NoteRepetition?.Value ?? Core.MusicTheory.NoteRepetition.None, EffectTechniqueParameter = this.OrnamentParameter?.Value ?? default(double), IsRest = this.Rest != null, IsTied = this.Tie != null, TiePosition = this.TiePosition?.Value, PreConnection = this.PreConnection?.Value ?? PreBeatConnection.None, PostConnection = this.PostConnection?.Value ?? PostBeatConnection.None, NoteValue = this.NoteValue.ToNoteValue(), VoicePart = ownerVoice.Part, IsForceBeamStart = this.ForceBeamStart != null, IsForceBeamEnd = this.ForceBeamEnd != null }; if (!this.Validate(context, logger, beat)) { return(false); } var notes = new List <BeatNote>(); foreach (var note in this.Notes) { BeatNote documentNote; if (!note.ToDocumentElement(context, logger, ownerVoice.Part, out documentNote)) { return(false); } documentNote.OwnerBeat = beat; notes.Add(documentNote); ownerVoice.LastNoteOnStrings[documentNote.String] = documentNote; } beat.Notes = notes.ToArray(); ownerVoice.IsTerminatedWithRest = beat.IsRest; return(true); }
private bool RetrievePreConnectedNote(TablatureContext context, ILogger logger, BeatNote element) { var lastNote = context.GetLastNoteOnString(this.String.Value - 1); if (lastNote == null) { logger.Report(LogLevel.Error, this.PreConnection.Range, Messages.Error_ConnectionPredecessorNotExisted); return(false); } element.PreConnectedNote = lastNote; return(true); }
internal override bool Apply(TablatureContext context, ILogger logger) { TempoSignature tempo; if (!this.ToDocumentElement(context, logger, out tempo)) { return(false); } using (var state = context.AlterDocumentState()) { state.TempoSignature = tempo; } return(true); }
internal override bool Apply(TablatureContext context, ILogger logger) { ChordDefinition definition; if (!this.ToDocumentElement(context, logger, out definition)) { return(false); } using (var state = context.AlterDocumentState()) { state.DefinedChords.Add(definition); } return(true); }
public bool ToDocumentElement(TablatureContext context, ILogger logger, out TempoSignature element) { if (this.ValueEquals(context.DocumentState.TempoSignature)) { logger.Report(LogLevel.Suggestion, this.Range, Messages.Suggestion_UselessTempoInstruction); element = null; return(false); } element = new TempoSignature { Range = this.Range, Tempo = new Tempo(this.Beats.Value, this.NoteValue?.Value ?? BaseNoteValue.Quater) }; return(true); }
internal override bool Apply(TablatureContext context, ILogger logger) { Section section; if (!this.ToDocumentElement(context, logger, out section)) { return(false); } using (var state = context.AlterDocumentState()) { state.DefinedSections.Add(section); state.CurrentSection = section; } return(true); }
public bool ToDocumentElement(TablatureContext context, ILogger logger, out Section element) { if (context.DocumentState.DefinedSections.Any(this.ValueEquals)) { logger.Report(LogLevel.Warning, this.Range, Messages.Warning_DuplicatedSectionName, this.SectionName.Value); element = null; return(false); } element = new Section { Name = this.SectionName.Value, Range = this.Range }; return(true); }
private bool Validate(TablatureContext context, ILogger logger, VoicePart voicePart, BeatNote element) { if (!this.ValidateTie(context, logger, element)) { return(false); } if (!this.ValidatePreConnection(context, logger, voicePart, element)) { return(false); } if (!this.ValidatePostConnection(context, logger, voicePart, element)) { return(false); } return(true); }
public bool ToDocumentElement(TablatureContext context, ILogger logger, out KeySignature element) { var noteName = this.Key.ToNoteName(); if (context.DocumentState.KeySignature != null && context.DocumentState.KeySignature.Key == noteName) { logger.Report(LogLevel.Suggestion, this.Range, Messages.Suggestion_RedundantKeySignature); element = null; return(false); } element = new KeySignature { Range = this.Range, Key = noteName }; return(true); }