Mercurial > hg > beaglert
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); |