annotate projects/audio_in_FFT/render.cpp @ 269:ac8eb07afcf5

Oxygen text added to each render.cpp file for the default projects. Text includes project explanation from Wiki, edited in places. Empty project added as a default project. Doxyfile updated. Each of the project locations added to INPUT configuration option. Consider just watching the whole project file so all new projects are automatically pulled through.
author Robert Jack <robert.h.jack@gmail.com>
date Tue, 17 May 2016 15:40:16 +0100
parents 3c3a1357657d
children
rev   line source
robert@269 1 /*
robert@269 2 ____ _____ _ _
robert@269 3 | __ )| ____| | / \
robert@269 4 | _ \| _| | | / _ \
robert@269 5 | |_) | |___| |___ / ___ \
robert@269 6 |____/|_____|_____/_/ \_\.io
robert@269 7
robert@269 8 */
robert@269 9
victor@4 10 /*
victor@4 11 * render.cpp
victor@4 12 *
victor@4 13 * Created on: Oct 24, 2014
victor@4 14 * Author: parallels
victor@4 15 */
victor@4 16
robert@269 17 /**
robert@269 18 \example 4_audio_FFT
robert@269 19
robert@269 20 Fast Fourier Transform
robert@269 21 ----------------------
robert@269 22
robert@269 23 This sketch performs an FFT (Fast Fourier Transform) on incoming audio. It uses
robert@269 24 the NE10 library, included at the top of the file (line 11).
robert@269 25
robert@269 26 Read the documentation on the NE10 library [here](http://projectne10.github.io/Ne10/doc/annotated.html).
robert@269 27
robert@269 28 The variables `timeDomainIn`, `timeDomainOut` and `frequencyDomain` are
robert@269 29 variables of the struct `ne10_fft_cpx_float32_t` [http://projectne10.github.io/Ne10/doc/structne10__fft__cpx__float32__t.html](http://projectne10.github.io/Ne10/doc/structne10__fft__cpx__float32__t.html).
robert@269 30 These are declared at the top of the file (line 21), and memory is allocated
robert@269 31 for them in `setup()` (line 41).
robert@269 32
robert@269 33 In `render()` a `for` loop performs the FFT which is performed on each sample,
robert@269 34 and the resulting output is placed on each channel.
robert@269 35
robert@269 36 */
robert@269 37
robert@269 38
robert@269 39
robert@269 40
robert@269 41
victor@4 42
andrewm@56 43 #include <BeagleRT.h>
victor@4 44 #include <rtdk.h>
victor@4 45 #include <NE10.h> // neon library
victor@4 46 #include <cmath>
victor@4 47
andrewm@5 48 int gFFTSize;
andrewm@5 49 float gFFTScaleFactor = 0;
victor@4 50
victor@4 51 int gReadPointer = 0;
victor@4 52 int gWritePointer = 0;
victor@4 53
victor@4 54 // FFT vars
andrewm@5 55 ne10_fft_cpx_float32_t* timeDomainIn;
andrewm@5 56 ne10_fft_cpx_float32_t* timeDomainOut;
victor@4 57 ne10_fft_cpx_float32_t* frequencyDomain;
victor@4 58 ne10_fft_cfg_float32_t cfg;
victor@4 59
andrewm@56 60 // setup() is called once before the audio rendering starts.
victor@4 61 // Use it to perform any initialisation and allocation which is dependent
victor@4 62 // on the period size or sample rate.
victor@4 63 //
victor@4 64 // userData holds an opaque pointer to a data structure that was passed
victor@4 65 // in from the call to initAudio().
victor@4 66 //
victor@4 67 // Return true on success; returning false halts the program.
victor@4 68
andrewm@56 69 bool setup(BeagleRTContext *context, void *userData)
victor@4 70 {
victor@4 71 // Retrieve a parameter passed in from the initAudio() call
andrewm@5 72 gFFTSize = *(int *)userData;
andrewm@5 73 gFFTScaleFactor = 1.0f / (float)gFFTSize;
victor@4 74
andrewm@5 75 timeDomainIn = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t));
andrewm@5 76 timeDomainOut = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t));
andrewm@5 77 frequencyDomain = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t));
andrewm@5 78 cfg = ne10_fft_alloc_c2c_float32 (gFFTSize);
victor@4 79
andrewm@5 80 memset(timeDomainOut, 0, gFFTSize * sizeof (ne10_fft_cpx_float32_t));
victor@4 81
victor@4 82 return true;
victor@4 83 }
victor@4 84
victor@4 85 // render() is called regularly at the highest priority by the audio engine.
victor@4 86 // Input and output are given from the audio hardware and the other
victor@4 87 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
victor@4 88 // will be 0.
victor@4 89
andrewm@52 90 void render(BeagleRTContext *context, void *userData)
victor@4 91 {
andrewm@52 92 for(unsigned int n = 0; n < context->audioFrames; n++) {
andrewm@52 93 timeDomainIn[gReadPointer].r = (ne10_float32_t) ((context->audioIn[n*context->audioChannels] +
andrewm@52 94 context->audioIn[n*context->audioChannels+1]) * 0.5);
andrewm@5 95 timeDomainIn[gReadPointer].i = 0;
victor@4 96
andrewm@5 97 if(++gReadPointer >= gFFTSize)
andrewm@5 98 {
andrewm@5 99 //FFT
andrewm@5 100 ne10_fft_c2c_1d_float32_neon (frequencyDomain, timeDomainIn, cfg->twiddles, cfg->factors, gFFTSize, 0);
victor@4 101
andrewm@5 102 //Do frequency domain stuff
victor@4 103
andrewm@5 104 //IFFT
andrewm@5 105 ne10_fft_c2c_1d_float32_neon (timeDomainOut, frequencyDomain, cfg->twiddles, cfg->factors, gFFTSize, 1);
victor@4 106
andrewm@5 107 gReadPointer = 0;
andrewm@5 108 gWritePointer = 0;
andrewm@5 109 }
victor@4 110
andrewm@56 111 for(unsigned int channel = 0; channel < context->audioChannels; channel++)
andrewm@52 112 context->audioOut[n * context->audioChannels + channel] = (float) timeDomainOut[gWritePointer].r * gFFTScaleFactor;
andrewm@5 113 gWritePointer++;
victor@4 114 }
victor@4 115 }
victor@4 116
andrewm@56 117 // cleanup() is called once at the end, after the audio has stopped.
andrewm@56 118 // Release any resources that were allocated in setup().
victor@4 119
andrewm@56 120 void cleanup(BeagleRTContext *context, void *userData)
victor@4 121 {
andrewm@5 122 NE10_FREE(timeDomainIn);
andrewm@5 123 NE10_FREE(timeDomainOut);
victor@4 124 NE10_FREE(frequencyDomain);
victor@4 125 NE10_FREE(cfg);
victor@4 126 }