예제 #1
0
    static ShazamResult CaptureAndTag()
    {
        var analysis = new Analysis();
        var finder   = new LandmarkFinder(analysis);

        using (var capture = new WasapiCapture()) {
            var captureBuf = new BufferedWaveProvider(capture.WaveFormat)
            {
                ReadFully = false
            };

            capture.DataAvailable += (s, e) => {
                captureBuf.AddSamples(e.Buffer, 0, e.BytesRecorded);
            };

            capture.StartRecording();

            using (var resampler = new MediaFoundationResampler(captureBuf, new WaveFormat(Analysis.SAMPLE_RATE, 16, 1))) {
                var sampleProvider = resampler.ToSampleProvider();
                var retryMs        = 3000;
                var tagId          = Guid.NewGuid().ToString();

                while (true)
                {
                    while (captureBuf.BufferedDuration.TotalSeconds < 1)
                    {
                        Thread.Sleep(100);
                    }

                    analysis.ReadChunk(sampleProvider);

                    if (analysis.StripeCount > 2 * LandmarkFinder.RADIUS_TIME)
                    {
                        finder.Find(analysis.StripeCount - LandmarkFinder.RADIUS_TIME - 1);
                    }

                    if (analysis.ProcessedMs >= retryMs)
                    {
                        //new Painter(analysis, finder).Paint("c:/temp/spectro.png");
                        //new Synthback(analysis, finder).Synth("c:/temp/synthback.raw");

                        var sigBytes = Sig.Write(Analysis.SAMPLE_RATE, analysis.ProcessedSamples, finder);
                        var result   = ShazamApi.SendRequest(tagId, analysis.ProcessedMs, sigBytes).GetAwaiter().GetResult();
                        if (result.Success)
                        {
                            return(result);
                        }

                        retryMs = result.RetryMs;
                        if (retryMs == 0)
                        {
                            return(result);
                        }
                    }
                }
            }
        }
    }
예제 #2
0
    public static byte[] Write(int sampleRate, int sampleCount, LandmarkFinder finder)
    {
        using (var mem = new MemoryStream())
            using (var writer = new BinaryWriter(mem)) {
                writer.Write(0xCAFE2580); // Dialling "2580" on your phone and holding it up to the music, https://www.shazam.com/company
                writer.Write(-1);
                writer.Write(-1);
                writer.Write(0x94119C00);
                writer.Write(0);
                writer.Write(0);
                writer.Write(0);
                writer.Write(GetSampleRateCode(sampleRate) << 27);
                writer.Write(0);
                writer.Write(0);
                writer.Write(sampleCount);
                writer.Write(0x007C0000);
                writer.Write(0x40000000);
                writer.Write(-1);

                var bandData = GetBandData(finder);
                for (var i = 0; i < bandData.Length; i++)
                {
                    writer.Write(0x60030040 + i);
                    writer.Write(bandData[i].Length);
                    writer.Write(bandData[i]);
                }

                var totalLen   = (int)mem.Length;
                var contentLen = totalLen - 48;

                foreach (var i in new[] { 2, 13 })
                {
                    mem.Position = i * 4;
                    writer.Write(contentLen);
                }

                var crc = Force.Crc32.Crc32Algorithm.Compute(mem.GetBuffer(), 8, totalLen - 8);
                mem.Position = 4;
                writer.Write(crc);

                return(mem.ToArray());
            }
    }
예제 #3
0
 public Synthback(Analysis analysis, LandmarkFinder finder)
 {
     Analysis = analysis;
     Finder   = finder;
 }
예제 #4
0
 public Painter(Analysis analysis, LandmarkFinder finder)
 {
     Analysis = analysis;
     Finder   = finder;
 }
예제 #5
0
    // Alternative (legacy?) format used in ShazamCore10.dll
    // Works with any sample rate
    public static byte[] Write2(int sampleRate, int sampleCount, LandmarkFinder finder)
    {
        using (var mem = new MemoryStream())
            using (var writer = new BinaryWriter(mem)) {
                writer.Write(-1);
                writer.Write(0x789ABC05);
                writer.Write(0xFFFFFFFF);
                writer.Write(0x30000002);
                writer.Write(0x10);
                writer.Write(-1);
                writer.Write(-1);
                writer.Write(0);
                writer.Write(0);
                writer.Write(0x40000000);
                writer.Write(-1);
                writer.Write(0);
                writer.Write(0);
                writer.Write(0);
                writer.Write(0);
                writer.Write(0x50000001);
                writer.Write(0x18);
                writer.Write(0);
                writer.Write(0);
                writer.Write(0);
                writer.Write(0xDEADBEEF);
                writer.Write(Convert.ToInt32(sampleCount * 8000L / sampleRate));
                writer.Write(0);
                writer.Write(0x31100000);
                writer.Write(0x0f);
                writer.Write(0x42700000);

                var bandData = GetBandData(finder);
                for (var i = 0; i < bandData.Length; i++)
                {
                    writer.Write(0);
                    writer.Write(0x60030040 + i);
                    writer.Write(bandData[i].Length);
                    writer.Write(0);
                    writer.Write(0);
                    writer.Write(0);
                    writer.Write(bandData[i]);
                }

                var totalLen   = (int)mem.Length;
                var contentLen = totalLen - 32;

                foreach (var i in new[] { 0, 5, 10 })
                {
                    mem.Position = i * 4;
                    writer.Write(contentLen);
                }

                mem.Position = 6 * 4;
                writer.Write(contentLen ^ 0x789ABC13);

                var buffer   = mem.GetBuffer();
                var checksum = (uint)0;
                for (var i = 0; i < totalLen / 4; i++)
                {
                    checksum += BitConverter.ToUInt32(buffer, 4 * i);
                }

                mem.Position = 7 * 4;
                writer.Write(checksum);

                return(mem.ToArray());
            }
    }
예제 #6
0
 static byte[][] GetBandData(LandmarkFinder finder)
 {
     return(finder.EnumerateBandedLandmarks().Select(GetBandData).ToArray());
 }