/// <summary> /// Converts the string representation of a relative semitones list into its scale definition equivalent. /// </summary> /// <param paramname="s">The <see cref="string"/> represention of the semitone relative distances.</param> /// <returns>The <see cref="ScaleDefinition"/>.</returns> /// <exception cref="System.FormatException">Throw if the format is incorrect,</exception> public static ScaleDefinition Parse(string s) { var relativeSemitones = RelativeSemitoneList.Parse(s); var result = new ScaleDefinition(relativeSemitones); return(result); }
public Symmetry(IReadOnlyCollection <Semitone> relativesIntervals) { var list = relativesIntervals.ToList(); var count = list.Count; if (count % 2 != 0) { return; // Ensure count divides by 2 } bool CheckIntervals(int candidateBlockSize) { if (count % candidateBlockSize != 0) { return(false); // Ensure count divides by blocksize } var blockCount = count / candidateBlockSize; for (var i = 0; i < candidateBlockSize; i++) { var interval = list[i]; for (var j = 1; j < blockCount; j++) { var index = i + j * candidateBlockSize; if (list[index] != interval) { return(false); } } } return(true); } var blockSize = Enumerable.Range(1, count / 2).FirstOrDefault(CheckIntervals); if (blockSize <= 0) { return; } // Intervals are symmetric Block = new RelativeSemitoneList(relativesIntervals.Take(blockSize)); BlockCount = count / blockSize; }