예제 #1
0
 /// <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();
 }
예제 #2
0
 public float GetHarmonicity(KeyFindingProfile profile = KeyFindingProfile.Simple, Key keySignature = Key.CMajor)
 {
     return(HarmonicityAnalyzer.Instance
            .AnalyzeAverage(
                this.Notes
                .Select(note => note.Pitch)
                .ToArray(),
                profile
                ));
 }
예제 #3
0
        /// <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
             )
         );
 }
예제 #5
0
        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());
        }
예제 #7
0
        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());
 }