comparison examples/04-Audio/filter-FIR/render.cpp @ 464:8fcfbfb32aa0 prerelease

Examples reorder with subdirectories. Added header to each project. Moved Doxygen to bottom of render.cpp.
author Robert Jack <robert.h.jack@gmail.com>
date Mon, 20 Jun 2016 16:20:38 +0100
parents
children b935f890e512
comparison
equal deleted inserted replaced
463:c47709e8b5c9 464:8fcfbfb32aa0
1 /*
2 ____ _____ _ _
3 | __ )| ____| | / \
4 | _ \| _| | | / _ \
5 | |_) | |___| |___ / ___ \
6 |____/|_____|_____/_/ \_\
7
8 The platform for ultra-low latency audio and sensor processing
9
10 http://bela.io
11
12 A project of the Augmented Instruments Laboratory within the
13 Centre for Digital Music at Queen Mary University of London.
14 http://www.eecs.qmul.ac.uk/~andrewm
15
16 (c) 2016 Augmented Instruments Laboratory: Andrew McPherson,
17 Astrid Bin, Liam Donovan, Christian Heinrichs, Robert Jack,
18 Giulio Moro, Laurel Pardue, Victor Zappi. All rights reserved.
19
20 The Bela software is distributed under the GNU Lesser General Public License
21 (LGPL 3.0), available here: https://www.gnu.org/licenses/lgpl-3.0.txt
22 */
23
24
25 #define ENABLE_NE10_FIR_FLOAT_NEON // Define needed for Ne10 library
26
27 #include <Bela.h>
28 #include <cmath>
29 #include <ne10/NE10.h> // neon library
30 #include "SampleData.h"
31 #include "FIRfilter.h"
32
33 SampleData gSampleData; // User defined structure to get complex data from main
34 int gReadPtr; // Position of last read sample from file
35
36 // filter vars
37 ne10_fir_instance_f32_t gFIRfilter;
38 ne10_float32_t *gFIRfilterIn;
39 ne10_float32_t *gFIRfilterOut;
40 ne10_uint32_t blockSize;
41 ne10_float32_t *gFIRfilterState;
42
43 void initialise_filter(BelaContext *context);
44
45 // Task for handling the update of the frequencies using the matrix
46 AuxiliaryTask gTriggerSamplesTask;
47
48 bool initialise_trigger();
49 void trigger_samples();
50
51 bool setup(BelaContext *context, void *userData)
52 {
53
54 // Retrieve a parameter passed in from the initAudio() call
55 gSampleData = *(SampleData *)userData;
56
57 gReadPtr = -1;
58
59 initialise_filter(context);
60
61 // Initialise auxiliary tasks
62 if(!initialise_trigger())
63 return false;
64
65 return true;
66 }
67
68 void render(BelaContext *context, void *userData)
69 {
70 for(unsigned int n = 0; n < context->audioFrames; n++) {
71 float in = 0;
72
73 // If triggered...
74 if(gReadPtr != -1)
75 in += gSampleData.samples[gReadPtr++]; // ...read each sample...
76
77 if(gReadPtr >= gSampleData.sampleLen)
78 gReadPtr = -1;
79
80 gFIRfilterIn[n] = in;
81 }
82
83 ne10_fir_float_neon(&gFIRfilter, gFIRfilterIn, gFIRfilterOut, blockSize);
84
85 for(unsigned int n = 0; n < context->audioFrames; n++) {
86 for(unsigned int channel = 0; channel < context->audioChannels; channel++)
87 context->audioOut[n * context->audioChannels + channel] = gFIRfilterOut[n]; // ...and put it in both left and right channel
88 }
89
90
91 // Request that the lower-priority task run at next opportunity
92 Bela_scheduleAuxiliaryTask(gTriggerSamplesTask);
93 }
94
95 // Initialise NE10 data structures to define FIR filter
96
97 void initialise_filter(BelaContext *context)
98 {
99 blockSize = context->audioFrames;
100 gFIRfilterState = (ne10_float32_t *) NE10_MALLOC ((FILTER_TAP_NUM+blockSize-1) * sizeof (ne10_float32_t));
101 gFIRfilterIn = (ne10_float32_t *) NE10_MALLOC (blockSize * sizeof (ne10_float32_t));
102 gFIRfilterOut = (ne10_float32_t *) NE10_MALLOC (blockSize * sizeof (ne10_float32_t));
103 ne10_fir_init_float(&gFIRfilter, FILTER_TAP_NUM, filterTaps, gFIRfilterState, blockSize);
104 }
105
106
107 // Initialise the auxiliary task
108 // and print info
109
110 bool initialise_trigger()
111 {
112 if((gTriggerSamplesTask = Bela_createAuxiliaryTask(&trigger_samples, 50, "bela-trigger-samples")) == 0)
113 return false;
114
115 rt_printf("Press 'a' to trigger sample, 's' to stop\n");
116 rt_printf("Press 'q' to quit\n");
117
118 return true;
119 }
120
121 // This is a lower-priority call to periodically read keyboard input
122 // and trigger samples. By placing it at a lower priority,
123 // it has minimal effect on the audio performance but it will take longer to
124 // complete if the system is under heavy audio load.
125
126 void trigger_samples()
127 {
128 // This is not a real-time task!
129 // Cos getchar is a system call, not handled by Xenomai.
130 // This task will be automatically down graded.
131
132 char keyStroke = '.';
133
134 keyStroke = getchar();
135 while(getchar()!='\n'); // to read the first stroke
136
137 switch (keyStroke)
138 {
139 case 'a':
140 gReadPtr = 0;
141 break;
142 case 's':
143 gReadPtr = -1;
144 break;
145 case 'q':
146 gShouldStop = true;
147 break;
148 default:
149 break;
150 }
151 }
152
153
154 void cleanup(BelaContext *context, void *userData)
155 {
156 delete[] gSampleData.samples;
157
158 NE10_FREE(gFIRfilterState);
159 NE10_FREE(gFIRfilterIn);
160 NE10_FREE(gFIRfilterOut);
161 }
162
163 /* ------------ Project Explantation ------------ */
164
165 /**
166 \example 04-filter-FIR
167
168 Finite Impulse Response Filter
169 ------------------------------
170
171 This is an example of a finite impulse response filter implementation.
172 */