/// <summary> /// Analyzes the specified sets of songs. /// </summary> /// <param name="songs">Array of songs.</param> /// <param name="profile">Key-finding profile to be used.</param> public Analyzer Analyze(Song[][] songs, KeyFindingProfile profile = KeyFindingProfile.Simple) { return(this .ReadSongs(songs) .AnalyzeNoteGroups() .AnalyzeHarmonicities(profile)); //.AnalyzeStructures(); }
public float GetHarmonicity(KeyFindingProfile profile = KeyFindingProfile.Simple, Key keySignature = Key.CMajor) { return(HarmonicityAnalyzer.Instance .AnalyzeAverage( this.Notes .Select(note => note.Pitch) .ToArray(), profile )); }
/// <summary> /// Runs the analyzer. /// </summary> public static void RunAnalyzer(KeyFindingProfile profile = KeyFindingProfile.Simple) { var analyzer = Analyzer.Instance .Analyze(new[] { _songs[0].Values.ToArray(), _songs[1].Values.ToArray() }, profile); Harmonicities = analyzer.Harmonicities; }
/// <summary> /// Gets the major harmonicity between two pitches. /// </summary> /// <param name="pitch1">The first pitch.</param> /// <param name="pitch2">The second pitch.</param> /// <param name="profile">The key-finding profile to be used.</param> /// <returns>The major harmonicity between the two pitches.</returns> private float GetMajorHarmonicity(Pitch pitch1, Pitch pitch2, Key key, KeyFindingProfile profile = KeyFindingProfile.Simple) { return ( ProfileDictionary.Weights[profile][0, Math.Abs(pitch1.MidiPitch - pitch2.MidiPitch) % 12] + ( (this.Analyze(pitch1, key, profile) + this.Analyze(pitch2, key, profile)) / 2 ) ); }
private Analyzer AnalyzeHarmonicities(KeyFindingProfile profile = KeyFindingProfile.Simple) { this._harmonicities = new double[this._noteGroups.Length][, ]; for (var i = 0; i < this._noteGroups.Length; i++) { var songList = this._noteGroups[i]; this._harmonicities[i] = new double[songList.Length, 2]; for (var j = 0; j < songList.Length; j++) { var song = songList[j]; var min = float.MaxValue; var max = float.MinValue; var i1 = i; var j1 = j; if ((int)this._songLists[i1][j1].KeySignature == -1) { var thisSong = this._songLists[i1][j1]; thisSong.KeySignature = KeySignatureAnalyzer.Instance.Analyze(this._songLists[i1][j1]); } foreach (var harmonicity in song .Select(noteGroup => noteGroup.GetHarmonicity( profile, this._songLists[i1][j1].KeySignature ))) { if (harmonicity > max) { max = harmonicity; } if (harmonicity < min) { min = harmonicity; } } this._harmonicities[i][j, 0] = min; this._harmonicities[i][j, 1] = max; } } return(this); }
/// <summary> /// Analyzes the harmonicity between two or more pitches. /// </summary> /// <param name="pitches">The pitches.</param> /// <param name="profile">The key-finding profile to be used.</param> /// <returns>Array of harmonicities between pitches.</returns> private IEnumerable <float> AnalyzeIntervals(IEnumerable <Pitch> pitches, KeyFindingProfile profile = KeyFindingProfile.Simple, Key keySignature = Key.CMajor) { var pitchList = new List <Pitch>(pitches); pitchList.Sort((pitch, pitch1) => pitch.Key - pitch1.Key); var pitchArray = pitchList.ToArray(); if (pitches.Count() < 2) { return new[] { this.Analyze(pitches.ElementAt(0), keySignature, profile) } } ; return(pitchArray .Select((t, i) => ( this.GetMajorHarmonicity(t, pitchArray[(i + 1) % pitchArray.Length], keySignature, profile) + this.GetMinorHarmonicity(t, pitchArray[(i + 1) % pitchArray.Length], keySignature, profile) ) / 2 ).ToArray()); }
public Key Analyze(Song song, KeyFindingProfile profile = KeyFindingProfile.Simple) { var keys = Enum.GetValues(typeof(Key)); var coefficients = new Dictionary <Key, float>(); var points = keys .Cast <Key>() .ToDictionary(key => key, key => new PointF[12]); float[] highestCoefficient = { 0F }; var mostLikelyKey = Key.CMajor; foreach (var key in keys.Cast <Key>()) { for (var i = 0; i < 12; i++) { points[key][i] = new PointF(ProfileDictionary.Weights[profile][this.IsMinorKey(key) ? 1 : 0, i], 0); } foreach (var note in song.GetAllNotes()) { points[key][note.Pitch.MidiPitch % 12].Y++; } coefficients.Add(key, this.GetCorrelationCoefficient(points[key])); } foreach (var coefficient in coefficients .Where(coefficient => coefficient.Value > highestCoefficient[0])) { highestCoefficient[0] = coefficient.Value; mostLikelyKey = coefficient.Key; } return(mostLikelyKey); }
/// <summary> /// Analyzes the harmonicity of the specified pitch. /// </summary> /// <param name="pitch">The pitch.</param> /// <param name="key">The key to where the <paramref name="pitch"/> will be analyzed.</param> /// <param name="profile">The key-finding profile to be used.</param> /// <returns>A value corresponding to the harmonicity of the <paramref name="pitch"/> to the <paramref name="key"/>.</returns> public float Analyze(Pitch pitch, Key key = Key.CMajor, KeyFindingProfile profile = KeyFindingProfile.Simple) { return(ProfileDictionary.Weights[profile][this.IsMinorKey(key) ? 1 : 0, (int)pitch.Key]); }
/// <summary> /// Analyzes the average harmonicity of two or more pitches. /// </summary> /// <param name="pitches">The pitches.</param> /// <param name="profile">The key-finding profile to be used.</param> /// <returns>Average harmonicity of the pitches.</returns> /// <seealso cref="AnalyzeIntervals"/> public float AnalyzeAverage(Pitch[] pitches, KeyFindingProfile profile = KeyFindingProfile.Simple, Key keySignature = Key.CMajor) { return(this.AnalyzeIntervals(pitches, profile, keySignature).Average()); }