コード例 #1
0
ファイル: Form1.cs プロジェクト: luungoc2005/ShazamExperiment
        private void button2_Click(object sender, EventArgs e)
        {
            if (RecordStream != null)
            {
                RecordStream.StopRecording();
                Stopwatch.Stop();

                if (RecordMemoryStream.Length > 0)
                {
                    RecordMemoryStream.Seek(0, SeekOrigin.Begin);
                    var stream = new RawSourceWaveStream(RecordMemoryStream, RecordStream.WaveFormat);

                    // find the song
                    textBox1.Text = $"Fingerprinting {RecordMemoryStream.Length} bytes, format: {RecordStream.WaveFormat.ToString()}... \r\n";
                    Application.DoEvents();
                    //var returnList = GetFingerprint(RecordMemoryStream, RecordStream.WaveFormat.BitsPerSample);

                    List <long> returnList;
                    using (var tempStream = new MemoryStream())
                    {
                        var buffer      = new byte[65536];
                        var shortBuffer = new short[32768];
                        var length      = 0;
                        while ((length = stream.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            Buffer.BlockCopy(buffer, 0, shortBuffer, 0, length);
                            for (int i = 0; i < length / 2; i += 2)
                            {
                                double outSample = shortBuffer[i] * 0.5 + shortBuffer[i + 1] * 0.5;
                                outSample = Math.Max(outSample, float.MinValue);
                                outSample = Math.Min(outSample, float.MaxValue);
                                tempStream.Write(BitConverter.GetBytes((float)outSample), 0, sizeof(float));
                                //writer.Write((float)outSample);
                                //System.Diagnostics.Debug.WriteLine(outSample);
                            }
                        }
                        returnList = GetFingerprint(tempStream);
                    }

                    textBox1.Text += "Searching... \r\n";
                    Application.DoEvents();
                    var foundList = new List <KeyValuePair <SongData, int> >();
                    var noMatches = new List <KeyValuePair <SongData, int> >();
                    var tempList  = new List <SongTimeData>();
                    foundList.Clear();
                    tempList.Clear();

                    int fingerprintPos = 0;
                    foreach (var fingerprint in returnList)
                    {
                        IEnumerable <SongTimeData> matchList;
                        if (songDb.TryGetValue(fingerprint, out matchList))
                        {
                            tempList.AddRange(matchList.Select(x =>
                            {
                                x.Position -= fingerprintPos;
                                return(x);
                            }));
                        }
                        fingerprintPos++;
                    }

                    textBox1.Text += $"Found {tempList.Count} matches...\r\n";
                    Application.DoEvents();
                    foreach (var item in tempList)
                    {
                        if (!foundList.Where(x => x.Key.FileName == item.SongData.FileName).Any())
                        {
                            var foundItem = tempList.Where(x => (x.SongData.FileName == item.SongData.FileName)).ToArray();
                            if (foundItem != null && foundItem.Any())
                            {
                                var minIndex = foundItem.Min(x => x.Position);
                                int score    = 0;
                                int matches  = foundItem.Length;
                                for (int i = 0; i < foundItem.Length; i++)
                                {
                                    score += Math.Abs(foundItem[i].Position - minIndex);
                                }
                                foundList.Add(new KeyValuePair <SongData, int>(item.SongData, score / matches));
                                noMatches.Add(new KeyValuePair <SongData, int>(item.SongData, matches));
                            }
                        }
                    }

                    SongData bestMatch  = null;
                    int      minScore   = int.MaxValue;
                    int      maxMatches = 0;
                    int      count      = 0;

                    foreach (var item in noMatches.OrderByDescending(x => x.Value))
                    {
                        var score = foundList.Where(x => (item.Key.FileName == x.Key.FileName)).FirstOrDefault();
                        if ((item.Value >= 2))
                        {
                            if (count < 20)
                            {
                                textBox1.Text += $"{count}: Match {item.Key.TrackName} {item.Value} times - Score: {score.Value}\r\n";
                            }
                            count++;

                            if (item.Value > maxMatches || ((item.Value == maxMatches) && score.Value < minScore))
                            {
                                bestMatch  = item.Key;
                                minScore   = score.Value;
                                maxMatches = item.Value;
                            }
                        }
                    }
                    if (bestMatch != null)
                    {
                        textBox1.Text += $"\r\nBest match: {bestMatch.TrackName}";
                    }
                }
            }
        }