Mercurial > hg > beaglert
comparison examples/audio_in_FFT/render.cpp @ 300:dbeed520b014 prerelease
Renamed projects to examples
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Fri, 27 May 2016 13:58:20 +0100 |
parents | projects/audio_in_FFT/render.cpp@3c3a1357657d |
children | e4392164b458 |
comparison
equal
deleted
inserted
replaced
297:a3d83ebdf49b | 300:dbeed520b014 |
---|---|
1 /* | |
2 * render.cpp | |
3 * | |
4 * Created on: Oct 24, 2014 | |
5 * Author: parallels | |
6 */ | |
7 | |
8 | |
9 #include <BeagleRT.h> | |
10 #include <rtdk.h> | |
11 #include <NE10.h> // neon library | |
12 #include <cmath> | |
13 | |
14 int gFFTSize; | |
15 float gFFTScaleFactor = 0; | |
16 | |
17 int gReadPointer = 0; | |
18 int gWritePointer = 0; | |
19 | |
20 // FFT vars | |
21 ne10_fft_cpx_float32_t* timeDomainIn; | |
22 ne10_fft_cpx_float32_t* timeDomainOut; | |
23 ne10_fft_cpx_float32_t* frequencyDomain; | |
24 ne10_fft_cfg_float32_t cfg; | |
25 | |
26 // setup() is called once before the audio rendering starts. | |
27 // Use it to perform any initialisation and allocation which is dependent | |
28 // on the period size or sample rate. | |
29 // | |
30 // userData holds an opaque pointer to a data structure that was passed | |
31 // in from the call to initAudio(). | |
32 // | |
33 // Return true on success; returning false halts the program. | |
34 | |
35 bool setup(BeagleRTContext *context, void *userData) | |
36 { | |
37 // Retrieve a parameter passed in from the initAudio() call | |
38 gFFTSize = *(int *)userData; | |
39 gFFTScaleFactor = 1.0f / (float)gFFTSize; | |
40 | |
41 timeDomainIn = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t)); | |
42 timeDomainOut = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t)); | |
43 frequencyDomain = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t)); | |
44 cfg = ne10_fft_alloc_c2c_float32 (gFFTSize); | |
45 | |
46 memset(timeDomainOut, 0, gFFTSize * sizeof (ne10_fft_cpx_float32_t)); | |
47 | |
48 return true; | |
49 } | |
50 | |
51 // render() is called regularly at the highest priority by the audio engine. | |
52 // Input and output are given from the audio hardware and the other | |
53 // ADCs and DACs (if available). If only audio is available, numMatrixFrames | |
54 // will be 0. | |
55 | |
56 void render(BeagleRTContext *context, void *userData) | |
57 { | |
58 for(unsigned int n = 0; n < context->audioFrames; n++) { | |
59 timeDomainIn[gReadPointer].r = (ne10_float32_t) ((context->audioIn[n*context->audioChannels] + | |
60 context->audioIn[n*context->audioChannels+1]) * 0.5); | |
61 timeDomainIn[gReadPointer].i = 0; | |
62 | |
63 if(++gReadPointer >= gFFTSize) | |
64 { | |
65 //FFT | |
66 ne10_fft_c2c_1d_float32_neon (frequencyDomain, timeDomainIn, cfg->twiddles, cfg->factors, gFFTSize, 0); | |
67 | |
68 //Do frequency domain stuff | |
69 | |
70 //IFFT | |
71 ne10_fft_c2c_1d_float32_neon (timeDomainOut, frequencyDomain, cfg->twiddles, cfg->factors, gFFTSize, 1); | |
72 | |
73 gReadPointer = 0; | |
74 gWritePointer = 0; | |
75 } | |
76 | |
77 for(unsigned int channel = 0; channel < context->audioChannels; channel++) | |
78 context->audioOut[n * context->audioChannels + channel] = (float) timeDomainOut[gWritePointer].r * gFFTScaleFactor; | |
79 gWritePointer++; | |
80 } | |
81 } | |
82 | |
83 // cleanup() is called once at the end, after the audio has stopped. | |
84 // Release any resources that were allocated in setup(). | |
85 | |
86 void cleanup(BeagleRTContext *context, void *userData) | |
87 { | |
88 NE10_FREE(timeDomainIn); | |
89 NE10_FREE(timeDomainOut); | |
90 NE10_FREE(frequencyDomain); | |
91 NE10_FREE(cfg); | |
92 } |