public override void Draw(RenderWindow window) { if (!isFirstFrame) { waitForEnter(); } else { isFirstFrame = false; } double[] samples = new double[BufferSize]; for (int i = 0; i < rendersTillStop; i++) { if (offset + BufferSize < SampleCount) { for (int counter = 0; counter < BufferSize; counter++) //one line of spectogram { samples[counter] = Samples[offset + counter]; //4k samples } offset += (int)BufferSize; //filter out high frequencies and downsample audio data var cutOffData = AudioProcessor.DownSample(samples, downSampleCoef, SampleRate); //1k samples for (int index = 0; index < BufferSize / downSampleCoef; index++) { //data[index * 2] = cutOffData[index] * hammingWindow[index]; //apply hamming window bins[index * 2] = cutOffData[index] * this.window[index]; //apply hamming window bins[index * 2 + 1] = 0d; //set 0s for Img complex values } FastFourierTransformation.FFT(bins); //apply fft //1024 = WIDTH 700=HEIGHT Render(bins, new Vector2f(100 + i * (1024 / rendersTillStop), 700), (int)BufferSize / (2 * downSampleCoef)); window.Draw(VA); } else { //Draw last frame and then close window window.Draw(instructionsText); window.Display(); waitForEnter(); window.Close(); return; } } window.Draw(instructionsText); }
public override void Update() { int offset = (int)(Song.PlayingOffset.AsSeconds() * SampleRate); timeText.DisplayedString = Song.PlayingOffset.AsSeconds().ToString(); double[] samples = new double[BufferSize]; //allocate array taht will be used at downsampling Task t1 = Task.Factory.StartNew(() => SetImaginary()); if (offset + BufferSize < SampleCount) { if (ChannelCount == 2) { for (uint i = 0; i < BufferSize; i++) { samples[i] = Samples[(i + offset) * 2]; } } else { for (uint i = 0; i < BufferSize; i++) { samples[i] = Samples[(i + offset)]; } } } //Filter out frequencies and then downsamples var cutOffData = AudioProcessor.DownSample(samples, downSampleCoef, SampleRate); t1.Wait(); //t1 is working with bin array //enter complex values to the bin array for (int i = 0; i < BufferSize / downSampleCoef; i++) { bin[i * 2] = cutOffData[i] * window[i]; } FastFourierTransformation.FFT(bin); for (uint i = 0; i < BufferSize / (2 * downSampleCoef); i++) { VA[i] = new Vertex(new Vector2f((float)(i * 0.5 * downSampleCoef + 100), (float)(200 - AudioRecognitionLibrary.Tools.Arithmetics.GetComplexAbs(bin[2 * i], bin[2 * i + 1]) / 100000))); //100000 is to scale visualisation so it fits the window } }
/// <summary> /// Creates fingerprint of given audio and returns it together with number of valid notes. (needed to compute recognition accuracy). <br></br> /// </summary> /// <param name="audio">Audio whos fingerprint we want.</param> /// <returns>Tuple where Item1 is fingerprint, Item2 is total number of notes. <br></br>fingerprint: [hash; (absolute anchor times)]<br></br>Note: Address is the hash.</returns> public Tuple <Dictionary <uint, List <uint> >, int> GetAudioFingerprint(IAudioFormat audio) { short[] monoData = AudioProcessor.ConvertToMono(audio); double[] data = Array.ConvertAll(monoData, item => (double)item); //compute downsample coeficient for resampling to Parameters.TargetSamplingRate int downsampleCoef = (int)audio.SampleRate / Parameters.TargetSamplingRate; double[] downsampledData = AudioProcessor.DownSample(data, downsampleCoef, audio.SampleRate); int bufferSize = Parameters.WindowSize / downsampleCoef; //default: 4096/4 = 1024 var timeFrequencyPoints = CreateTimeFrequencyPoints(bufferSize, downsampledData); //[hash;(AbsAnchorTimes)] Dictionary <uint, List <uint> > fingerprint = CreateRecordAddresses(timeFrequencyPoints); return(new Tuple <Dictionary <uint, List <uint> >, int> (fingerprint, timeFrequencyPoints.Count)); }