/// <summary> /// Reduces the specified musical time spans to the common denominator. /// </summary> /// <param name="fraction1">First time span.</param> /// <param name="fraction2">Second time span.</param> /// <param name="numerator1">Numerator of the reduced first time span.</param> /// <param name="numerator2">Numerator of the reduced second time span.</param> /// <param name="denominator">Common denominator of reduced time spans.</param> private static void ReduceToCommonDenominator(MusicalTimeSpan fraction1, MusicalTimeSpan fraction2, out long numerator1, out long numerator2, out long denominator) { denominator = MathUtilities.LeastCommonMultiple(fraction1.Denominator, fraction2.Denominator); numerator1 = fraction1.Numerator * denominator / fraction1.Denominator; numerator2 = fraction2.Numerator * denominator / fraction2.Denominator; }
internal static ParsingResult TryParse(string input, out MusicalTimeSpan timeSpan) { timeSpan = null; if (string.IsNullOrWhiteSpace(input)) { return(ParsingResult.EmptyInputString); } var match = ParsingUtilities.Match(input, Patterns); if (match == null) { return(ParsingResult.NotMatched); } // Fraction long numerator; if (!ParsingUtilities.ParseLong(match, NumeratorGroupName, 1, out numerator)) { return(new ParsingResult(NumeratorIsOutOfRange)); } long denominator; if (!ParsingUtilities.ParseLong(match, DenominatorGroupName, 1, out denominator)) { return(new ParsingResult(DenominatorIsOutOfRange)); } var fractionMnemonicGroup = match.Groups[FractionMnemonicGroupName]; if (fractionMnemonicGroup.Success) { var fractionDefinition = Fractions[fractionMnemonicGroup.Value]; numerator = fractionDefinition.Item1; denominator = fractionDefinition.Item2; } // Tuplet int tupletNotesCount; if (!ParsingUtilities.ParseInt(match, TupletNotesCountGroupName, 1, out tupletNotesCount)) { return(new ParsingResult(TupletNotesCountIsOutOfRange)); } int tupletSpaceSize; if (!ParsingUtilities.ParseInt(match, TupletSpaceSizeGroupName, 1, out tupletSpaceSize)) { return(new ParsingResult(TupletSpaceSizeIsOutOfRange)); } var tupletMnemonicGroup = match.Groups[TupletMnemonicGroupName]; if (tupletMnemonicGroup.Success) { var tupletDefinition = Tuplets[tupletMnemonicGroup.Value]; tupletNotesCount = tupletDefinition.Item1; tupletSpaceSize = tupletDefinition.Item2; } // Dots var dotsGroup = match.Groups[DotsGroupName]; var dots = dotsGroup.Success ? dotsGroup.Value.Length : 0; // timeSpan = new MusicalTimeSpan(numerator, denominator).Dotted(dots).Tuplet(tupletNotesCount, tupletSpaceSize); return(ParsingResult.Parsed); }
/// <summary> /// Converts the string representation of a whole note's fraction to its <see cref="MusicalTimeSpan"/> /// equivalent. A return value indicates whether the conversion succeeded. /// </summary> /// <param name="input">A string containing a time span to convert.</param> /// <param name="timeSpan">When this method returns, contains the <see cref="MusicalTimeSpan"/> /// equivalent of the time span contained in <paramref name="input"/>, if the conversion succeeded, or /// null if the conversion failed. The conversion fails if the <paramref name="input"/> is null or /// <see cref="String.Empty"/>, is not of the correct format. This parameter is passed uninitialized; /// any value originally supplied in result will be overwritten.</param> /// <returns>true if <paramref name="input"/> was converted successfully; otherwise, false.</returns> public static bool TryParse(string input, out MusicalTimeSpan timeSpan) { return(MusicalTimeSpanParser.TryParse(input, out timeSpan).Status == ParsingStatus.Parsed); }