public Melody12Tone(MelodyBase melodyBase, TwelveToneSet toneset, int key = 0, int tempo = 60) { this.melodyBase = melodyBase; this.toneset = toneset; this.key = key; this.tempo = tempo; }
public TwelveToneSet(Random rand, int ntones, TwelveToneSet scale) { Debug.Assert(ntones <= scale.Count); tone12 pos = 0; // Find the first tone the scale while (!scale[pos]) { pos++; } // Randomly move it forward int times = rand.Next(scale.Count); pos = scale.Next(pos, times); tones = 0; tones &= (short)(1 << pos); for (int i = 1; i < ntones; i++) { pos = scale.Next(pos, 2); tones &= (short)(1 << pos); } Debug.Assert(ntones == this.Count); }
public bool IsSimilar(TwelveToneSet other) { if (other.Count != this.Count) { return(false); } if (this.Equals(other)) { return(true); } TwelveToneSet copy = new TwelveToneSet(this); for (int i = 1; i < TWELVE; i++) { copy = copy.ShiftRight(1); if (copy.Equals(other)) { return(true); } } return(false); }
public bool CoveredBy(TwelveToneSet other) { for (int i = 0; i < TWELVE; i++) { if (this[i] && !other[i]) { return(false); } } return(true); }
/// <summary> /// Distance based on the number of common underlying Scales /// </summary> public int DistanceScales(TwelveToneSet other) { int count = 0; TwelveToneSet copy = new TwelveToneSet(majorScale); for (int i = 0; i < TWELVE; i++) { if (this.CoveredBy(copy) && other.CoveredBy(copy)) { count++; } copy.ShiftRight(1); } int ret = Math.Min(CountMajorScales(), other.CountMajorScales()) - count; return(ret); }
public bool CoveredByAnySimilar(TwelveToneSet other) { if (this.CoveredBy(other)) { return(true); } TwelveToneSet copy = new TwelveToneSet(this); for (int i = 1; i < TWELVE; i++) { copy = copy.ShiftRight(1); if (copy.CoveredBy(other)) { return(true); } } return(false); }
int CountMajorScales() { int count = 0; TwelveToneSet copy = new TwelveToneSet(majorScale); if (this.CoveredBy(copy)) { count++; } for (int i = 1; i < TWELVE; i++) { copy.ShiftRight(1); if (this.CoveredBy(copy)) { count++; } } return(count); }
/// <summary> /// Produces a list containing all similar scales. /// For example, if given only major scale (or similarly only minor scale) /// it will return: ionian(major), dorian, phrygian, lydian, mixolydian, aeolian and locrian scale. /// </summary> private static List <TwelveToneSet> CalculateAllScales(List <TwelveToneSet> scales) { if (scales == null) { return(null); } // Assert each scale is rooted, no two scales are similar for (int i = 0; i < scales.Count; i++) { Debug.Assert(scales[i].IsRooted); for (int j = i + 1; j < scales.Count; j++) { Debug.Assert(!scales[i].IsSimilar(scales[j])); } } List <TwelveToneSet> allScales = new List <TwelveToneSet>(); foreach (var scale in scales) { TwelveToneSet currScale = scale; do { // Shift to next inversion e.g. ionian to dorian do { currScale = currScale.ShiftRight(1); } while (!currScale.IsRooted); allScales.Add(currScale); } while (currScale != scale); } return(allScales); }
public TwelveToneSet ShiftInScale(int count, TwelveToneSet scale) { if (count == 0) { return(this); } Debug.Assert(scale.Count >= Count); short set = 0; // Transpose in scale notes first TwelveToneSet intersect = Intersection(this, scale); Dictionary <int, int> mapping = new Dictionary <int, int>(); foreach (var x in intersect) { mapping[x] = scale.NextInScale(x, count); set = BitOn(set, mapping[x]); } // If each in-scale note was transposed by the same amount, do it for the rest TwelveToneSet rest = Minus(this, scale); var nesto = mapping.Select(kpv => new tone12(kpv.Value - kpv.Key)); if (nesto.Distinct().Count() == 1) { tone12 offset = mapping.First().Value - mapping.First().Key; rest = Minus(this, scale); foreach (var x in rest) { mapping[x] = (x + offset); set = BitOn(set, x + offset); } TwelveToneSet ttsInScale = new TwelveToneSet(set); Debug.Assert(ttsInScale.Count == this.Count); return(ttsInScale); } // If the choice is between in-scale and out-scale, choose in scale rest = Minus(this, scale); foreach (var x in rest) { var list = mapping.Select(kpv => x + (kpv.Value - kpv.Key)).Distinct().ToList(); if (list.Count == 2) { if (scale[list.First()] ^ scale[list.Last()]) { tone12 tone = scale[list.First()] ? list.First() : list.Last(); mapping[x] = tone; set = BitOn(set, tone); } } } TwelveToneSet tts = new TwelveToneSet(set); Debug.Assert(tts.Count == this.Count); return(tts); }
public int TotalDistance(TwelveToneSet other) { return(DistanceScales(other) + DistanceCommonTones(other)); }
/// <summary> /// Distance based on common tones between the two chords /// </summary> /// <param name="other">The other TwelveToneSet</param> /// <returns>Greater count minus the number of common tones</returns> public int DistanceCommonTones(TwelveToneSet other) { TwelveToneSet common = TwelveToneSet.Intersection(this, other); return(Math.Max(this.Count, other.Count) - common.Count); }
static TwelveToneSet Negative(TwelveToneSet set) { return(new TwelveToneSet((short)(chromatic.tones - set.tones))); }
static TwelveToneSet Intersection(TwelveToneSet set1, TwelveToneSet set2) { return(new TwelveToneSet((short)(set1.tones & set2.tones))); }
static TwelveToneSet Union(TwelveToneSet set1, TwelveToneSet set2) { return(new TwelveToneSet((short)(set1.tones | set2.tones))); }
public bool Equals(TwelveToneSet other) => tones == other.tones;
static TwelveToneSet Minus(TwelveToneSet set1, TwelveToneSet set2) { return(new TwelveToneSet((short)(set1.tones & (Negative(set2).tones)))); }
public MelodyPartDtoC(int offset, TwelveToneSet scale, MelodyPartList node) //todo: scale should be 3rd arg : base(offset, node) { Debug.Assert(node.IsDiatonic); this.scale = scale; }
public TwelveToneSet(TwelveToneSet other) { this.tones = other.tones; }