annotate projects/filter_FIR/render.cpp @ 56:3c3a1357657d newapi

Further API update to name three primary functions setup(), render() and cleanup(). Changed include paths so now can #include <BeagleRT.h>. Removed stale pru_rtaudio.bin file as this is now done as pru_rtaudio_bin.h. Updated examples to new API and fixed minor compiler warnings along the way. Network example needs further attention to compile.
author andrewm
date Wed, 15 Jul 2015 12:10:51 +0100
parents a6d223473ea2
children 5433c83ce04e
rev   line source
victor@2 1 /*
victor@2 2 * render.cpp
victor@2 3 *
victor@2 4 * Created on: Oct 24, 2014
victor@2 5 * Author: Andrew McPherson and Victor Zappi
victor@2 6 */
victor@2 7
victor@2 8
andrewm@56 9 #include <BeagleRT.h>
victor@2 10 #include <cmath>
victor@2 11 #include <NE10.h> // neon library
victor@2 12 #include "SampleData.h"
victor@2 13 #include "FIRfilter.h"
victor@2 14
victor@2 15 SampleData gSampleData; // User defined structure to get complex data from main
victor@2 16 int gReadPtr; // Position of last read sample from file
victor@2 17
victor@2 18 // filter vars
victor@2 19 ne10_fir_instance_f32_t gFIRfilter;
victor@2 20 ne10_float32_t *gFIRfilterIn;
victor@2 21 ne10_float32_t *gFIRfilterOut;
victor@2 22 ne10_uint32_t blockSize;
victor@2 23 ne10_float32_t *gFIRfilterState;
victor@2 24
andrewm@52 25 void initialise_filter(BeagleRTContext *context);
victor@2 26
victor@2 27 // Task for handling the update of the frequencies using the matrix
victor@2 28 AuxiliaryTask gTriggerSamplesTask;
victor@2 29
victor@2 30 bool initialise_trigger();
victor@2 31 void trigger_samples();
victor@2 32
andrewm@56 33 // setup() is called once before the audio rendering starts.
victor@2 34 // Use it to perform any initialisation and allocation which is dependent
victor@2 35 // on the period size or sample rate.
victor@2 36 //
victor@2 37 // userData holds an opaque pointer to a data structure that was passed
victor@2 38 // in from the call to initAudio().
victor@2 39 //
victor@2 40 // Return true on success; returning false halts the program.
victor@2 41
andrewm@56 42 bool setup(BeagleRTContext *context, void *userData)
victor@2 43 {
victor@2 44
victor@2 45 // Retrieve a parameter passed in from the initAudio() call
victor@2 46 gSampleData = *(SampleData *)userData;
victor@2 47
victor@2 48 gReadPtr = -1;
victor@2 49
andrewm@52 50 initialise_filter(context);
victor@2 51
victor@2 52 // Initialise auxiliary tasks
victor@2 53 if(!initialise_trigger())
victor@2 54 return false;
victor@2 55
victor@2 56 return true;
victor@2 57 }
victor@2 58
victor@2 59 // render() is called regularly at the highest priority by the audio engine.
victor@2 60 // Input and output are given from the audio hardware and the other
victor@2 61 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
victor@2 62 // will be 0.
victor@2 63
andrewm@52 64 void render(BeagleRTContext *context, void *userData)
victor@2 65 {
andrewm@52 66 for(unsigned int n = 0; n < context->audioFrames; n++) {
victor@2 67 float in = 0;
victor@2 68
victor@2 69 // If triggered...
victor@2 70 if(gReadPtr != -1)
victor@2 71 in += gSampleData.samples[gReadPtr++]; // ...read each sample...
victor@2 72
victor@2 73 if(gReadPtr >= gSampleData.sampleLen)
victor@2 74 gReadPtr = -1;
victor@2 75
victor@2 76 gFIRfilterIn[n] = in;
victor@2 77 }
victor@2 78
victor@2 79 ne10_fir_float_neon(&gFIRfilter, gFIRfilterIn, gFIRfilterOut, blockSize);
victor@2 80
andrewm@52 81 for(unsigned int n = 0; n < context->audioFrames; n++) {
andrewm@52 82 for(unsigned int channel = 0; channel < context->audioChannels; channel++)
andrewm@52 83 context->audioOut[n * context->audioChannels + channel] = gFIRfilterOut[n]; // ...and put it in both left and right channel
victor@2 84 }
victor@2 85
victor@2 86
victor@2 87 // Request that the lower-priority task run at next opportunity
andrewm@52 88 BeagleRT_scheduleAuxiliaryTask(gTriggerSamplesTask);
victor@2 89 }
victor@2 90
victor@2 91 // Initialise NE10 data structures to define FIR filter
victor@2 92
andrewm@52 93 void initialise_filter(BeagleRTContext *context)
victor@2 94 {
andrewm@52 95 blockSize = context->audioFrames;
victor@2 96 gFIRfilterState = (ne10_float32_t *) NE10_MALLOC ((FILTER_TAP_NUM+blockSize-1) * sizeof (ne10_float32_t));
victor@2 97 gFIRfilterIn = (ne10_float32_t *) NE10_MALLOC (blockSize * sizeof (ne10_float32_t));
victor@2 98 gFIRfilterOut = (ne10_float32_t *) NE10_MALLOC (blockSize * sizeof (ne10_float32_t));
victor@2 99 ne10_fir_init_float(&gFIRfilter, FILTER_TAP_NUM, filterTaps, gFIRfilterState, blockSize);
victor@2 100 }
victor@2 101
victor@2 102
victor@2 103 // Initialise the auxiliary task
victor@2 104 // and print info
victor@2 105
victor@2 106 bool initialise_trigger()
victor@2 107 {
andrewm@52 108 if((gTriggerSamplesTask = BeagleRT_createAuxiliaryTask(&trigger_samples, 50, "beaglert-trigger-samples")) == 0)
victor@2 109 return false;
victor@2 110
victor@2 111 rt_printf("Press 'a' to trigger sample, 's' to stop\n");
victor@2 112 rt_printf("Press 'q' to quit\n");
victor@2 113
victor@2 114 return true;
victor@2 115 }
victor@2 116
victor@2 117 // This is a lower-priority call to periodically read keyboard input
victor@2 118 // and trigger samples. By placing it at a lower priority,
victor@2 119 // it has minimal effect on the audio performance but it will take longer to
victor@2 120 // complete if the system is under heavy audio load.
victor@2 121
victor@2 122 void trigger_samples()
victor@2 123 {
victor@2 124 // This is not a real-time task!
victor@2 125 // Cos getchar is a system call, not handled by Xenomai.
victor@2 126 // This task will be automatically down graded.
victor@2 127
victor@2 128 char keyStroke = '.';
victor@2 129
victor@2 130 keyStroke = getchar();
victor@2 131 while(getchar()!='\n'); // to read the first stroke
victor@2 132
victor@2 133 switch (keyStroke)
victor@2 134 {
victor@2 135 case 'a':
victor@2 136 gReadPtr = 0;
victor@2 137 break;
victor@2 138 case 's':
victor@2 139 gReadPtr = -1;
victor@2 140 break;
victor@2 141 case 'q':
victor@2 142 gShouldStop = true;
victor@2 143 break;
victor@2 144 default:
victor@2 145 break;
victor@2 146 }
victor@2 147 }
victor@2 148
victor@2 149
victor@2 150
andrewm@56 151 // cleanup() is called once at the end, after the audio has stopped.
andrewm@56 152 // Release any resources that were allocated in setup().
victor@2 153
andrewm@56 154 void cleanup(BeagleRTContext *context, void *userData)
victor@2 155 {
victor@2 156 delete[] gSampleData.samples;
victor@2 157
victor@2 158 NE10_FREE(gFIRfilterState);
victor@2 159 NE10_FREE(gFIRfilterIn);
victor@2 160 NE10_FREE(gFIRfilterOut);
victor@2 161 }