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); } } } } } }
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()); } }
public Synthback(Analysis analysis, LandmarkFinder finder) { Analysis = analysis; Finder = finder; }
public Painter(Analysis analysis, LandmarkFinder finder) { Analysis = analysis; Finder = finder; }
// 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()); } }
static byte[][] GetBandData(LandmarkFinder finder) { return(finder.EnumerateBandedLandmarks().Select(GetBandData).ToArray()); }