public float[][] CreateSpectrogram(AudioSamples audioSamples, int overlap, int 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); 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 FingerprintSignature CreateFingerprint(AudioSamples audioSamples, SpectrogramConfig configuration) { absEnergy = new double[(Frequencies.Length - 1) * 4]; // number of frequencies bands (33) lowpassFilters = new LowpassFilters(Frequencies.Length - 1); // 33 bands try { int width = (audioSamples.Samples.Length - configuration.WdftSize) / configuration.Overlap; // WdftSize=2048 / Overlap=64 if (width < 1) { return(null); } // reserve memory for 32 bit fingerprint hashes byte[] hashes = new byte[width * sizeof(uint)]; byte[] reliabilities = new byte[width * 32]; // elke subfinger (32 bits) heeft voor elke bit een waarde tussen 0 en 31 voor relibility (dus 5 bits), we ronden dit af naar 1 byte FingerprintSignature fingerprintSignature = new FingerprintSignature(null, 0, hashes, (long)(width * 11.6)); fingerprintSignature.Reliabilities = reliabilities; // Calculate a hamming windows float[] hammingWindow = new float[configuration.WdftSize]; for (int i = 0; i < hammingWindow.Length; i++) { // Hamming (watch it peak is at beginning not as in real hamming in the middle) hammingWindow[i] = 0.54f + 0.46f * (float)System.Math.Cos((6.283f * (float)i / hammingWindow.Length)); //hammingWindow[i] = 0.54f - (0.46f * (float)System.Math.Cos(((6.283f * (float)i) / (hammingWindow.Length - 1)))); // real hamming window } //for int[] frequenciesRange = Frequencies; // 34 freqencies float[] samples = new float[configuration.WdftSize]; for (int i = 0; i < width; i++) { if (((samples.Length - 1) + (i * configuration.Overlap)) >= audioSamples.Samples.Length) { // we hebben niet voldoende data meer! // dus we stoppen nu en nemen het "laaste" stukje niet mee! break; } for (int j = 0; j < samples.Length; j++) { samples[j] = audioSamples.Samples[j + (i * configuration.Overlap)] * hammingWindow[j]; } // for j float[] complexSignal = fftService.FFTForward(samples, 0, configuration.WdftSize); byte[] reliability; uint subFingerprint = CalculateSubFingerprint(complexSignal, frequenciesRange, 5512, out reliability); Buffer.BlockCopy(BitConverter.GetBytes(subFingerprint), 0, hashes, i * sizeof(uint), sizeof(uint)); Buffer.BlockCopy(reliability, 0, reliabilities, i * reliability.Length, reliability.Length); // sequencenumber = i; // timestamp = (i / audioSamples.Samples.Length) * configuration.SampleRate } //for return(fingerprintSignature); } finally { absEnergy = null; lowpassFilters = null; } }