comparison projects/audio_in_FFT/render.cpp @ 5:09f03ac40fcc

API improvements and cleanups. Now all common audio command-line options can be parsed automatically.
author andrewm
date Sat, 08 Nov 2014 16:16:55 +0100
parents f34c63568523
children 06f93bef7dd2
comparison
equal deleted inserted replaced
4:f34c63568523 5:09f03ac40fcc
9 #include "../../include/render.h" 9 #include "../../include/render.h"
10 #include <rtdk.h> 10 #include <rtdk.h>
11 #include <NE10.h> // neon library 11 #include <NE10.h> // neon library
12 #include <cmath> 12 #include <cmath>
13 13
14 int gFftSize; 14 int gFFTSize;
15 float gFFTScaleFactor = 0;
15 int gNumChannels; 16 int gNumChannels;
16 17
17 int gReadPointer = 0; 18 int gReadPointer = 0;
18 int gWritePointer = 0; 19 int gWritePointer = 0;
19 20
20 // FFT vars 21 // FFT vars
21 ne10_fft_cpx_float32_t* timeDomain; 22 ne10_fft_cpx_float32_t* timeDomainIn;
23 ne10_fft_cpx_float32_t* timeDomainOut;
22 ne10_fft_cpx_float32_t* frequencyDomain; 24 ne10_fft_cpx_float32_t* frequencyDomain;
23 ne10_fft_cfg_float32_t cfg; 25 ne10_fft_cfg_float32_t cfg;
24 26
25 // initialise_render() is called once before the audio rendering starts. 27 // initialise_render() is called once before the audio rendering starts.
26 // Use it to perform any initialisation and allocation which is dependent 28 // Use it to perform any initialisation and allocation which is dependent
34 bool initialise_render(int numChannels, int numMatrixFramesPerPeriod, 36 bool initialise_render(int numChannels, int numMatrixFramesPerPeriod,
35 int numAudioFramesPerPeriod, float matrixSampleRate, 37 int numAudioFramesPerPeriod, float matrixSampleRate,
36 float audioSampleRate, void *userData) 38 float audioSampleRate, void *userData)
37 { 39 {
38 // Retrieve a parameter passed in from the initAudio() call 40 // Retrieve a parameter passed in from the initAudio() call
39 gFftSize = *(int *)userData; 41 gFFTSize = *(int *)userData;
42 gFFTScaleFactor = 1.0f / (float)gFFTSize;
40 gNumChannels = numChannels; 43 gNumChannels = numChannels;
41 44
42 //memset(outSamples, gFftSize, 0.0); // set all to 0 45 timeDomainIn = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t));
46 timeDomainOut = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t));
47 frequencyDomain = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t));
48 cfg = ne10_fft_alloc_c2c_float32 (gFFTSize);
43 49
44 timeDomain = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFftSize * sizeof (ne10_fft_cpx_float32_t)); 50 memset(timeDomainOut, 0, gFFTSize * sizeof (ne10_fft_cpx_float32_t));
45 frequencyDomain = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFftSize * sizeof (ne10_fft_cpx_float32_t));
46 cfg = ne10_fft_alloc_c2c_float32 (gFftSize);
47 51
48 return true; 52 return true;
49 } 53 }
50 54
51 // render() is called regularly at the highest priority by the audio engine. 55 // render() is called regularly at the highest priority by the audio engine.
55 59
56 void render(int numMatrixFrames, int numAudioFrames, float *audioIn, float *audioOut, 60 void render(int numMatrixFrames, int numAudioFrames, float *audioIn, float *audioOut,
57 uint16_t *matrixIn, uint16_t *matrixOut) 61 uint16_t *matrixIn, uint16_t *matrixOut)
58 { 62 {
59 for(int n = 0; n < numAudioFrames; n++) { 63 for(int n = 0; n < numAudioFrames; n++) {
60 timeDomain[gReadPointer].r = (ne10_float32_t) ((audioIn[n*gNumChannels] + audioIn[n*gNumChannels+1])/2); 64 timeDomainIn[gReadPointer].r = (ne10_float32_t) ((audioIn[n*gNumChannels] + audioIn[n*gNumChannels+1]) * 0.5);
61 timeDomain[gReadPointer].i = 0; 65 timeDomainIn[gReadPointer].i = 0;
62 gReadPointer++;
63 }
64 66
65 if(gReadPointer>=gFftSize) 67 if(++gReadPointer >= gFFTSize)
66 { 68 {
67 //FFT 69 //FFT
68 ne10_fft_c2c_1d_float32_neon (frequencyDomain, timeDomain, cfg->twiddles, cfg->factors, gFftSize, 0); 70 ne10_fft_c2c_1d_float32_neon (frequencyDomain, timeDomainIn, cfg->twiddles, cfg->factors, gFFTSize, 0);
69 71
70 //Do frequency domain stuff 72 //Do frequency domain stuff
71 73
72 //IFFT 74 //IFFT
73 ne10_fft_c2c_1d_float32_neon (timeDomain, frequencyDomain, cfg->twiddles, cfg->factors, gFftSize, 1); 75 ne10_fft_c2c_1d_float32_neon (timeDomainOut, frequencyDomain, cfg->twiddles, cfg->factors, gFFTSize, 1);
74 76
75 gReadPointer = 0; 77 gReadPointer = 0;
76 gWritePointer = 0; 78 gWritePointer = 0;
77 } 79 }
78 80
79 for(int n = 0; n < numAudioFrames; n++) {
80 for(int channel = 0; channel < gNumChannels; channel++) 81 for(int channel = 0; channel < gNumChannels; channel++)
81 audioOut[n * gNumChannels + channel] = (float) timeDomain[gWritePointer++].r/gFftSize; 82 audioOut[n * gNumChannels + channel] = (float) timeDomainOut[gWritePointer].r * gFFTScaleFactor;
83 gWritePointer++;
82 } 84 }
83 } 85 }
84 86
85 // cleanup_render() is called once at the end, after the audio has stopped. 87 // cleanup_render() is called once at the end, after the audio has stopped.
86 // Release any resources that were allocated in initialise_render(). 88 // Release any resources that were allocated in initialise_render().
87 89
88 void cleanup_render() 90 void cleanup_render()
89 { 91 {
90 NE10_FREE(timeDomain); 92 NE10_FREE(timeDomainIn);
93 NE10_FREE(timeDomainOut);
91 NE10_FREE(frequencyDomain); 94 NE10_FREE(frequencyDomain);
92 NE10_FREE(cfg); 95 NE10_FREE(cfg);
93 } 96 }