public float[][] CreateSpectrogram(AudioSamples audioSamples, int overlap, int wdftSize) { float[] window = new DefaultSpectrogramConfig().Window.GetWindow(wdftSize); float[] samples = audioSamples.Samples; int width = (samples.Length - wdftSize) / overlap; float[][] frames = new float[width][]; for (int i = 0; i < width; i++) { float[] complexSignal = fftService.FFTForward(samples, i * overlap, wdftSize, window); float[] band = new float[(wdftSize / 2) + 1]; for (int j = 0; j < (wdftSize / 2) + 1; j++) { double re = complexSignal[2 * j]; double img = complexSignal[(2 * j) + 1]; re /= (float)wdftSize / 2; img /= (float)wdftSize / 2; band[j] = (float)((re * re) + (img * img)); } frames[i] = band; } return frames; }
public void SubFingerprintsAreBuiltCorrectlyFromAudioSamplesForTrack() { const int TenSeconds = 10; var samples = new AudioSamples { Samples = TestUtilities.GenerateRandomFloatArray(SampleRate * TenSeconds) }; const int ThreeFingerprints = 3; var rawFingerprints = GetGenericFingerprints(ThreeFingerprints); fingerprintService.Setup(service => service.CreateFingerprints(samples, It.IsAny<DefaultFingerprintConfiguration>())).Returns(rawFingerprints); lshAlgorithm.Setup(service => service.Hash(It.IsAny<Fingerprint>(), NumberOfHashTables, NumberOfHashKeysPerTable, It.IsAny<IEnumerable<string>>())).Returns(new HashedFingerprint(GenericSignature(), GenericHashBuckets(), 0, 0, Enumerable.Empty<string>())); var hashDatas = fingerprintCommandBuilder.BuildFingerprintCommand() .From(samples) .UsingServices(audioService.Object) .Hash() .Result; Assert.AreEqual(ThreeFingerprints, hashDatas.Count); byte[] genericSignature = GenericSignature(); long[] genericHashBuckets = GenericHashBuckets(); foreach (var hashData in hashDatas) { CollectionAssert.AreEqual(genericSignature, hashData.SubFingerprint); CollectionAssert.AreEqual(genericHashBuckets, hashData.HashBins); } }
public void SubFingerprintsAreBuiltCorrectlyFromFileForTrack() { const int TenSeconds = 10; var samples = new AudioSamples { Samples = TestUtilities.GenerateRandomFloatArray(SampleRate * TenSeconds) }; const int ThreeFingerprints = 3; var rawFingerprints = GetGenericFingerprints(ThreeFingerprints); const string PathToAudioFile = "path-to-audio-file"; audioService.Setup(service => service.ReadMonoSamplesFromFile(PathToAudioFile, SampleRate)).Returns(samples); fingerprintService.Setup( service => service.CreateFingerprints(samples, It.IsAny<DefaultFingerprintConfiguration>())).Returns( rawFingerprints); lshAlgorithm.Setup(service => service.Hash(It.IsAny<Fingerprint>(), NumberOfHashTables, NumberOfHashKeysPerTable)).Returns(new HashedFingerprint(GenericSignature, GenericHashBuckets, 0, 0.928)); var hashDatas = fingerprintCommandBuilder.BuildFingerprintCommand() .From(PathToAudioFile) .UsingServices(audioService.Object) .Hash() .Result; Assert.AreEqual(ThreeFingerprints, hashDatas.Count); foreach (var hashData in hashDatas) { Assert.AreSame(GenericSignature, hashData.SubFingerprint); } }
private AudioSamples Copy(AudioSamples chunk) { float[] withCached = new float[tailLength + chunk.Samples.Length]; Buffer.BlockCopy(tailBuffer, 0, withCached, 0, sizeof(float) * tailLength); Buffer.BlockCopy(chunk.Samples, 0, withCached, sizeof(float) * tailLength, sizeof(float) * chunk.Samples.Length); return(new AudioSamples(withCached, chunk.Origin, chunk.SampleRate, relativeTo)); }
private void NormalizeAudioIfNecessary(AudioSamples samples, FingerprintConfiguration configuration) { if (configuration.NormalizeSignal) { audioSamplesNormalizer.NormalizeInPlace(samples.Samples); } }
private void Cache(AudioSamples chunk) { int nextStride = Stride.NextStride; tailLength = tailBuffer.Length - nextStride; relativeTo = chunk.RelativeTo.AddSeconds((double)(chunk.Samples.Length - tailLength) / chunk.SampleRate); Buffer.BlockCopy(chunk.Samples, sizeof(float) * (chunk.Samples.Length - tailLength), tailBuffer, 0, sizeof(float) * tailLength); }
private void Cache(AudioSamples chunk) { int nextStride = Stride.NextStride; left = chunk.Samples.Length - nextStride; relativeTo = chunk.RelativeTo.AddSeconds((double)(nextStride) / chunk.SampleRate); Buffer.BlockCopy(chunk.Samples, sizeof(float) * (nextStride), buffer, 0, sizeof(float) * left); }
public List<SpectralImage> CreateLogSpectrogram(AudioSamples audioSamples, SpectrogramConfig configuration) { int width = (audioSamples.Samples.Length - configuration.WdftSize) / configuration.Overlap; if (width < 1) { return new List<SpectralImage>(); } float[][] frames = new float[width][]; int[] logFrequenciesIndexes = logUtility.GenerateLogFrequenciesRanges(audioSamples.SampleRate, configuration); float[] window = configuration.Window.GetWindow(configuration.WdftSize); Parallel.For(0, width, i => { float[] complexSignal = fftService.FFTForward(audioSamples.Samples, i * configuration.Overlap, configuration.WdftSize, window); frames[i] = ExtractLogBins(complexSignal, logFrequenciesIndexes, configuration.LogBins, configuration.WdftSize); }); return CutLogarithmizedSpectrum(frames, audioSamples.SampleRate, configuration); }
public void FingerprintsAreBuiltCorrectlyFromFile() { const string PathToAudioFile = "path-to-audio-file"; const int TenSeconds = 10; var samples = new AudioSamples { Samples = TestUtilities.GenerateRandomFloatArray(SampleRate * TenSeconds) }; const int ThreeFingerprints = 3; var rawFingerprints = GetGenericFingerprints(ThreeFingerprints); audioService.Setup(service => service.ReadMonoSamplesFromFile(PathToAudioFile, SampleRate)).Returns(samples); fingerprintService.Setup(service => service.CreateFingerprints(samples, It.IsAny<DefaultFingerprintConfiguration>())).Returns(rawFingerprints); var fingerprints = ((FingerprintCommand)fingerprintCommandBuilder.BuildFingerprintCommand() .From(PathToAudioFile) .UsingServices(audioService.Object)) .Fingerprint() .Result; Assert.AreEqual(ThreeFingerprints, fingerprints.Count); Assert.AreSame(rawFingerprints, fingerprints); }
public AudioSamples Aggregate(AudioSamples chunk) { if (chunk.Samples.Length < MinSize) { throw new ArgumentException($"{nameof(chunk)} cannot be less than {MinSize}"); } inc++; if (inc == 0) { Cache(chunk); return(chunk); } var cached = Copy(chunk); Cache(chunk); return(cached); }
public void SubFingerprintsAreBuiltCorrectlyFromFileForTrackStartingAtSpecificSecond() { const string PathToAudioFile = "path-to-audio-file"; const int StartSecond = 10; const int SecondsToProcess = 20; AudioSamples samples = new AudioSamples { Samples = TestUtilities.GenerateRandomFloatArray(SampleRate * 10) }; const int ThreeFingerprints = 3; var rawFingerprints = GetGenericFingerprints(ThreeFingerprints); audioService.Setup(service => service.ReadMonoSamplesFromFile(PathToAudioFile, SampleRate, SecondsToProcess, StartSecond)).Returns(samples); fingerprintService.Setup(service => service.CreateFingerprints(samples, It.IsAny<DefaultFingerprintConfiguration>())).Returns(rawFingerprints); byte[] genericSignature = GenericSignature(); lshAlgorithm.Setup(service => service.Hash(It.IsAny<Fingerprint>(), NumberOfHashTables, NumberOfHashKeysPerTable, It.IsAny<IEnumerable<string>>())).Returns( new HashedFingerprint(genericSignature, GenericHashBuckets(), 0, 0, Enumerable.Empty<string>())); var hashDatas = fingerprintCommandBuilder.BuildFingerprintCommand() .From(PathToAudioFile, SecondsToProcess, StartSecond) .UsingServices(audioService.Object) .Hash() .Result; Assert.AreEqual(ThreeFingerprints, hashDatas.Count); foreach (var hashData in hashDatas) { CollectionAssert.AreEqual(genericSignature, hashData.SubFingerprint); } audioService.Verify(service => service.ReadMonoSamplesFromFile(PathToAudioFile, SampleRate, SecondsToProcess, StartSecond)); }
public List<Fingerprint> CreateFingerprints(AudioSamples samples, FingerprintConfiguration configuration) { NormalizeAudioIfNecessary(samples, configuration); var spectrum = spectrumService.CreateLogSpectrogram(samples, configuration.SpectrogramConfig); return CreateFingerprintsFromLogSpectrum(spectrum, configuration); }
public IWithFingerprintConfiguration From(AudioSamples audioSamples) { createFingerprintsMethod = () => fingerprintService.CreateFingerprints(audioSamples, FingerprintConfiguration); return this; }
public IWithQueryAndFingerprintConfiguration From(AudioSamples audioSamples) { fingerprintingMethodFromSelector = () => fingerprintCommandBuilder.BuildFingerprintCommand().From(audioSamples); return this; }
private void SetupFftService(DefaultSpectrogramConfig configuration, AudioSamples samples) { logUtility.Setup(utility => utility.GenerateLogFrequenciesRanges(SampleRate, configuration)) .Returns(new[] { 118, 125, 133, 141, 149, 158, 167, 177, 187, 198, 210, 223, 236, 250, 264, 280, 297, 314, 333, 352, 373, 395, 419, 443, 470, 497, 527, 558, 591, 626, 663, 702, 744, }); fftService.Setup(service => service.FFTForward(samples.Samples, It.IsAny<int>(), configuration.WdftSize, It.IsAny<float[]>())) .Returns(TestUtilities.GenerateRandomFloatArray(2048)); }