annotate projects/audio_in_FFT/render.cpp @ 4:f34c63568523

_new FFT example [still noisy]
author Victor Zappi <victor.zappi@qmul.ac.uk>
date Thu, 06 Nov 2014 19:02:48 +0000
parents
children 09f03ac40fcc
rev   line source
victor@4 1 /*
victor@4 2 * render.cpp
victor@4 3 *
victor@4 4 * Created on: Oct 24, 2014
victor@4 5 * Author: parallels
victor@4 6 */
victor@4 7
victor@4 8
victor@4 9 #include "../../include/render.h"
victor@4 10 #include <rtdk.h>
victor@4 11 #include <NE10.h> // neon library
victor@4 12 #include <cmath>
victor@4 13
victor@4 14 int gFftSize;
victor@4 15 int gNumChannels;
victor@4 16
victor@4 17 int gReadPointer = 0;
victor@4 18 int gWritePointer = 0;
victor@4 19
victor@4 20 // FFT vars
victor@4 21 ne10_fft_cpx_float32_t* timeDomain;
victor@4 22 ne10_fft_cpx_float32_t* frequencyDomain;
victor@4 23 ne10_fft_cfg_float32_t cfg;
victor@4 24
victor@4 25 // initialise_render() is called once before the audio rendering starts.
victor@4 26 // Use it to perform any initialisation and allocation which is dependent
victor@4 27 // on the period size or sample rate.
victor@4 28 //
victor@4 29 // userData holds an opaque pointer to a data structure that was passed
victor@4 30 // in from the call to initAudio().
victor@4 31 //
victor@4 32 // Return true on success; returning false halts the program.
victor@4 33
victor@4 34 bool initialise_render(int numChannels, int numMatrixFramesPerPeriod,
victor@4 35 int numAudioFramesPerPeriod, float matrixSampleRate,
victor@4 36 float audioSampleRate, void *userData)
victor@4 37 {
victor@4 38 // Retrieve a parameter passed in from the initAudio() call
victor@4 39 gFftSize = *(int *)userData;
victor@4 40 gNumChannels = numChannels;
victor@4 41
victor@4 42 //memset(outSamples, gFftSize, 0.0); // set all to 0
victor@4 43
victor@4 44 timeDomain = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFftSize * sizeof (ne10_fft_cpx_float32_t));
victor@4 45 frequencyDomain = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFftSize * sizeof (ne10_fft_cpx_float32_t));
victor@4 46 cfg = ne10_fft_alloc_c2c_float32 (gFftSize);
victor@4 47
victor@4 48 return true;
victor@4 49 }
victor@4 50
victor@4 51 // render() is called regularly at the highest priority by the audio engine.
victor@4 52 // Input and output are given from the audio hardware and the other
victor@4 53 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
victor@4 54 // will be 0.
victor@4 55
victor@4 56 void render(int numMatrixFrames, int numAudioFrames, float *audioIn, float *audioOut,
victor@4 57 uint16_t *matrixIn, uint16_t *matrixOut)
victor@4 58 {
victor@4 59 for(int n = 0; n < numAudioFrames; n++) {
victor@4 60 timeDomain[gReadPointer].r = (ne10_float32_t) ((audioIn[n*gNumChannels] + audioIn[n*gNumChannels+1])/2);
victor@4 61 timeDomain[gReadPointer].i = 0;
victor@4 62 gReadPointer++;
victor@4 63 }
victor@4 64
victor@4 65 if(gReadPointer>=gFftSize)
victor@4 66 {
victor@4 67 //FFT
victor@4 68 ne10_fft_c2c_1d_float32_neon (frequencyDomain, timeDomain, cfg->twiddles, cfg->factors, gFftSize, 0);
victor@4 69
victor@4 70 //Do frequency domain stuff
victor@4 71
victor@4 72 //IFFT
victor@4 73 ne10_fft_c2c_1d_float32_neon (timeDomain, frequencyDomain, cfg->twiddles, cfg->factors, gFftSize, 1);
victor@4 74
victor@4 75 gReadPointer = 0;
victor@4 76 gWritePointer = 0;
victor@4 77 }
victor@4 78
victor@4 79 for(int n = 0; n < numAudioFrames; n++) {
victor@4 80 for(int channel = 0; channel < gNumChannels; channel++)
victor@4 81 audioOut[n * gNumChannels + channel] = (float) timeDomain[gWritePointer++].r/gFftSize;
victor@4 82 }
victor@4 83 }
victor@4 84
victor@4 85 // cleanup_render() is called once at the end, after the audio has stopped.
victor@4 86 // Release any resources that were allocated in initialise_render().
victor@4 87
victor@4 88 void cleanup_render()
victor@4 89 {
victor@4 90 NE10_FREE(timeDomain);
victor@4 91 NE10_FREE(frequencyDomain);
victor@4 92 NE10_FREE(cfg);
victor@4 93 }