comparison projects/oscillator_bank/render.cpp @ 52:a6d223473ea2 newapi

Updated examples for new API. tank_wars not yet updated; audio_in_FFT and oscillator_bank not working properly yet.
author andrewm
date Sun, 31 May 2015 02:13:39 -0500
parents 643cbee74eda
children 3c3a1357657d
comparison
equal deleted inserted replaced
51:4f8db16f17b5 52:a6d223473ea2
4 * Created on: Oct 24, 2014 4 * Created on: Oct 24, 2014
5 * Author: parallels 5 * Author: parallels
6 */ 6 */
7 7
8 8
9 #include "../../include/RTAudio.h" 9 #include "../../include/BeagleRT.h"
10 #include "../../include/Utilities.h" 10 #include "../../include/Utilities.h"
11 #include <rtdk.h> 11 #include <rtdk.h>
12 #include <cstdlib> 12 #include <cstdlib>
13 #include <cmath> 13 #include <cmath>
14 #include <cstring> 14 #include <cstring>
56 // 56 //
57 // userData holds an opaque pointer to a data structure that was passed 57 // userData holds an opaque pointer to a data structure that was passed
58 // in from the call to initAudio(). 58 // in from the call to initAudio().
59 // 59 //
60 // Return true on success; returning false halts the program. 60 // Return true on success; returning false halts the program.
61 bool initialise_render(int numMatrixChannels, int numDigitalChannels, int numAudioChannels, 61 bool initialise_render(BeagleRTContext *context, void *userData)
62 int numMatrixFramesPerPeriod,
63 int numAudioFramesPerPeriod,
64 float matrixSampleRate, float audioSampleRate,
65 void *userData, RTAudioSettings* settings)
66 { 62 {
67 srandom(time(NULL)); 63 srandom(time(NULL));
68 64
69 if(numAudioChannels != 2) { 65 if(context->audioChannels != 2) {
70 rt_printf("Error: this example needs stereo audio enabled\n"); 66 rt_printf("Error: this example needs stereo audio enabled\n");
71 return false; 67 return false;
72 } 68 }
73 69
74 // Initialise the sine wavetable 70 // Initialise the sine wavetable
107 float increment = (kMaximumFrequency - kMinimumFrequency) / (float)gNumOscillators; 103 float increment = (kMaximumFrequency - kMinimumFrequency) / (float)gNumOscillators;
108 104
109 for(int n = 0; n < gNumOscillators; n++) { 105 for(int n = 0; n < gNumOscillators; n++) {
110 gPhases[n] = 0.0; 106 gPhases[n] = 0.0;
111 107
112 if(numMatrixFramesPerPeriod == 0) { 108 if(context->analogFrames == 0) {
113 // Random frequencies when used without matrix 109 // Random frequencies when used without matrix
114 gFrequencies[n] = kMinimumFrequency + (kMaximumFrequency - kMinimumFrequency) * ((float)random() / (float)RAND_MAX); 110 gFrequencies[n] = kMinimumFrequency + (kMaximumFrequency - kMinimumFrequency) * ((float)random() / (float)RAND_MAX);
115 } 111 }
116 else { 112 else {
117 // Constant spread of frequencies when used with matrix 113 // Constant spread of frequencies when used with matrix
118 gFrequencies[n] = freq; 114 gFrequencies[n] = freq;
119 freq += increment; 115 freq += increment;
120 } 116 }
121 117
122 // For efficiency, frequency is expressed in change in wavetable position per sample, not Hz or radians 118 // For efficiency, frequency is expressed in change in wavetable position per sample, not Hz or radians
123 gFrequencies[n] *= (float)gWavetableLength / audioSampleRate; 119 gFrequencies[n] *= (float)gWavetableLength / context->audioSampleRate;
124 gAmplitudes[n] = ((float)random() / (float)RAND_MAX) / (float)gNumOscillators; 120 gAmplitudes[n] = ((float)random() / (float)RAND_MAX) / (float)gNumOscillators;
125 gDFrequencies[n] = gDAmplitudes[n] = 0.0; 121 gDFrequencies[n] = gDAmplitudes[n] = 0.0;
126 } 122 }
127 123
128 increment = 0; 124 increment = 0;
133 // to avoid weird phase effects 129 // to avoid weird phase effects
134 float randScale = 0.99 + .02 * (float)random() / (float)RAND_MAX; 130 float randScale = 0.99 + .02 * (float)random() / (float)RAND_MAX;
135 float newFreq = freq * randScale; 131 float newFreq = freq * randScale;
136 132
137 // For efficiency, frequency is expressed in change in wavetable position per sample, not Hz or radians 133 // For efficiency, frequency is expressed in change in wavetable position per sample, not Hz or radians
138 gFrequencies[n] = newFreq * (float)gWavetableLength / audioSampleRate; 134 gFrequencies[n] = newFreq * (float)gWavetableLength / context->audioSampleRate;
139 135
140 freq += increment; 136 freq += increment;
141 } 137 }
142 138
143 // Initialise auxiliary tasks 139 // Initialise auxiliary tasks
144 if((gFrequencyUpdateTask = createAuxiliaryTask(&recalculate_frequencies, 90, "beaglert-update-frequencies")) == 0) 140 if((gFrequencyUpdateTask = BeagleRT_createAuxiliaryTask(&recalculate_frequencies, 85, "beaglert-update-frequencies")) == 0)
145 return false; 141 return false;
146 142
147 for(int n = 0; n < gNumOscillators; n++) 143 //for(int n = 0; n < gNumOscillators; n++)
148 rt_printf("%f\n", gFrequencies[n]); 144 // rt_printf("%f\n", gFrequencies[n]);
149 145
150 gAudioSampleRate = audioSampleRate; 146 gAudioSampleRate = context->audioSampleRate;
151 gSampleCount = 0; 147 gSampleCount = 0;
152 148
153 return true; 149 return true;
154 } 150 }
155 151
156 // render() is called regularly at the highest priority by the audio engine. 152 // render() is called regularly at the highest priority by the audio engine.
157 // Input and output are given from the audio hardware and the other 153 // Input and output are given from the audio hardware and the other
158 // ADCs and DACs (if available). If only audio is available, numMatrixFrames 154 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
159 // will be 0. 155 // will be 0.
160 156
161 void render(int numAnalogFrames, int numAudioFrames, int numDigitalFrames, float *audioIn, float *audioOut, 157 void render(BeagleRTContext *context, void *userData)
162 float *analogIn, float *analogOut, uint32_t *digital)
163 { 158 {
164 // Initialise buffer to 0 159 // Initialise buffer to 0
165 memset(audioOut, 0, 2 * numAudioFrames * sizeof(float)); 160 memset(context->audioOut, 0, 2 * context->audioFrames * sizeof(float));
166 161
167 // Render audio frames 162 // Render audio frames
168 oscillator_bank_neon(numAudioFrames, audioOut, 163 oscillator_bank_neon(context->audioFrames, context->audioOut,
169 gNumOscillators, gWavetableLength, 164 gNumOscillators, gWavetableLength,
170 gPhases, gFrequencies, gAmplitudes, 165 gPhases, gFrequencies, gAmplitudes,
171 gDFrequencies, gDAmplitudes, 166 gDFrequencies, gDAmplitudes,
172 gWavetable); 167 gWavetable);
173 168
174 if(numAnalogFrames != 0 && (gSampleCount += numAudioFrames) >= 128) { 169 if(context->analogFrames != 0 && (gSampleCount += context->audioFrames) >= 128) {
175 gSampleCount = 0; 170 gSampleCount = 0;
176 gNewMinFrequency = map(analogIn[0], 0, 1.0, 1000.0f, 8000.0f); 171 gNewMinFrequency = map(context->analogIn[0], 0, 1.0, 1000.0f, 8000.0f);
177 gNewMaxFrequency = map(analogIn[1], 0, 1.0, 1000.0f, 8000.0f); 172 gNewMaxFrequency = map(context->analogIn[1], 0, 1.0, 1000.0f, 8000.0f);
178 173
179 // Make sure max >= min 174 // Make sure max >= min
180 if(gNewMaxFrequency < gNewMinFrequency) { 175 if(gNewMaxFrequency < gNewMinFrequency) {
181 float temp = gNewMaxFrequency; 176 float temp = gNewMaxFrequency;
182 gNewMaxFrequency = gNewMinFrequency; 177 gNewMaxFrequency = gNewMinFrequency;
183 gNewMinFrequency = temp; 178 gNewMinFrequency = temp;
184 } 179 }
185 180
186 // Request that the lower-priority task run at next opportunity 181 // Request that the lower-priority task run at next opportunity
187 //scheduleAuxiliaryTask(gFrequencyUpdateTask); 182 //BeagleRT_scheduleAuxiliaryTask(gFrequencyUpdateTask);
188 } 183 }
189 } 184 }
190 185
191 // This is a lower-priority call to update the frequencies which will happen 186 // This is a lower-priority call to update the frequencies which will happen
192 // periodically when the matrix is enabled. By placing it at a lower priority, 187 // periodically when the matrix is enabled. By placing it at a lower priority,
213 208
214 209
215 // cleanup_render() is called once at the end, after the audio has stopped. 210 // cleanup_render() is called once at the end, after the audio has stopped.
216 // Release any resources that were allocated in initialise_render(). 211 // Release any resources that were allocated in initialise_render().
217 212
218 void cleanup_render() 213 void cleanup_render(BeagleRTContext *context, void *userData)
219 { 214 {
220 free(gWavetable); 215 free(gWavetable);
221 free(gPhases); 216 free(gPhases);
222 free(gFrequencies); 217 free(gFrequencies);
223 free(gAmplitudes); 218 free(gAmplitudes);