comparison examples/basic_FFT_phase_vocoder/render.cpp @ 373:3bed6b09223c prerelease

Updated NE10 library to the latest version; needs a corresponding update to the /usr/include/ne10 header files on the SD image. Updated examples to compile against new version, and reordered D-Box channels to account for new PRU-based DAC channel reordering.
author andrewm
date Thu, 09 Jun 2016 20:03:09 +0100
parents db2fe4e1b88e
children 24c3a0663d54
comparison
equal deleted inserted replaced
372:db2fe4e1b88e 373:3bed6b09223c
78 }; 78 };
79 79
80 float gDryWet = 1; // mix between the unprocessed and processed sound 80 float gDryWet = 1; // mix between the unprocessed and processed sound
81 float gPlaybackLive = 0.5f; // mix between the file playback and the live audio input 81 float gPlaybackLive = 0.5f; // mix between the file playback and the live audio input
82 float gGain = 1; // overall gain 82 float gGain = 1; // overall gain
83 float *gInputAudio = NULL;
83 Midi midi; 84 Midi midi;
85
86
84 void midiCallback(MidiChannelMessage message, void* arg){ 87 void midiCallback(MidiChannelMessage message, void* arg){
85 if(message.getType() == kmmNoteOn){ 88 if(message.getType() == kmmNoteOn){
86 if(message.getDataByte(1) > 0){ 89 if(message.getDataByte(1) > 0){
87 int note = message.getDataByte(0); 90 int note = message.getDataByte(0);
88 float frequency = powf(2, (note-69)/12.f)*440; 91 float frequency = powf(2, (note-69)/12.f)*440;
131 gOutputBufferWritePointer += gHopSize; 134 gOutputBufferWritePointer += gHopSize;
132 135
133 timeDomainIn = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t)); 136 timeDomainIn = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t));
134 timeDomainOut = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t)); 137 timeDomainOut = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t));
135 frequencyDomain = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t)); 138 frequencyDomain = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t));
136 cfg = ne10_fft_alloc_c2c_float32 (gFFTSize); 139 cfg = ne10_fft_alloc_c2c_float32_neon (gFFTSize);
137 140
138 memset(timeDomainOut, 0, gFFTSize * sizeof (ne10_fft_cpx_float32_t)); 141 memset(timeDomainOut, 0, gFFTSize * sizeof (ne10_fft_cpx_float32_t));
139 memset(gOutputBuffer, 0, BUFFER_SIZE * sizeof(float)); 142 memset(gOutputBuffer, 0, BUFFER_SIZE * sizeof(float));
143
144 // Allocate buffer to mirror and modify the input
145 gInputAudio = (float *)malloc(context->audioFrames * context->audioChannels * sizeof(float));
146 if(gInputAudio == 0)
147 return false;
140 148
141 // Allocate the window buffer based on the FFT size 149 // Allocate the window buffer based on the FFT size
142 gWindowBuffer = (float *)malloc(gFFTSize * sizeof(float)); 150 gWindowBuffer = (float *)malloc(gFFTSize * sizeof(float));
143 if(gWindowBuffer == 0) 151 if(gWindowBuffer == 0)
144 return false; 152 return false;
175 if(pointer >= BUFFER_SIZE) 183 if(pointer >= BUFFER_SIZE)
176 pointer = 0; 184 pointer = 0;
177 } 185 }
178 186
179 // Run the FFT 187 // Run the FFT
180 ne10_fft_c2c_1d_float32_neon (frequencyDomain, timeDomainIn, cfg->twiddles, cfg->factors, gFFTSize, 0); 188 ne10_fft_c2c_1d_float32_neon (frequencyDomain, timeDomainIn, cfg, 0);
181 189
182 switch (gEffect){ 190 switch (gEffect){
183 case kRobot : 191 case kRobot :
184 // Robotise the output 192 // Robotise the output
185 for(int n = 0; n < gFFTSize; n++) { 193 for(int n = 0; n < gFFTSize; n++) {
200 //bypass 208 //bypass
201 break; 209 break;
202 } 210 }
203 211
204 // Run the inverse FFT 212 // Run the inverse FFT
205 ne10_fft_c2c_1d_float32_neon (timeDomainOut, frequencyDomain, cfg->twiddles, cfg->factors, gFFTSize, 1); 213 ne10_fft_c2c_1d_float32_neon (timeDomainOut, frequencyDomain, cfg, 1);
206 // Overlap-and-add timeDomainOut into the output buffer 214 // Overlap-and-add timeDomainOut into the output buffer
207 pointer = outWritePointer; 215 pointer = outWritePointer;
208 for(int n = 0; n < gFFTSize; n++) { 216 for(int n = 0; n < gFFTSize; n++) {
209 outBuffer[pointer] += (timeDomainOut[n].r) * gFFTScaleFactor; 217 outBuffer[pointer] += (timeDomainOut[n].r) * gFFTScaleFactor;
210 if(isnan(outBuffer[pointer])) 218 if(isnan(outBuffer[pointer]))
224 // Input and output are given from the audio hardware and the other 232 // Input and output are given from the audio hardware and the other
225 // ADCs and DACs (if available). If only audio is available, numMatrixFrames 233 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
226 // will be 0. 234 // will be 0.
227 void render(BelaContext* context, void* userData) 235 void render(BelaContext* context, void* userData)
228 { 236 {
229 float* audioIn = context->audioIn;
230 float* audioOut = context->audioOut; 237 float* audioOut = context->audioOut;
231 int numAudioFrames = context->audioFrames; 238 int numAudioFrames = context->audioFrames;
232 int numAudioChannels = context->audioChannels; 239 int numAudioChannels = context->audioChannels;
233 // ------ this code internal to the demo; leave as is ---------------- 240 // ------ this code internal to the demo; leave as is ----------------
234 241
235 // Prep the "input" to be the sound file played in a loop 242 // Prep the "input" to be the sound file played in a loop
236 for(int n = 0; n < numAudioFrames; n++) { 243 for(int n = 0; n < numAudioFrames; n++) {
237 if(gReadPtr < gSampleData.sampleLen) 244 if(gReadPtr < gSampleData.sampleLen)
238 audioIn[2*n] = audioIn[2*n+1] = gSampleData.samples[gReadPtr]*(1-gPlaybackLive) + 245 gInputAudio[2*n] = gInputAudio[2*n+1] = gSampleData.samples[gReadPtr]*(1-gPlaybackLive) +
239 gPlaybackLive*0.5f*(audioRead(context,n,0)+audioRead(context,n,1)); 246 gPlaybackLive*0.5f*(audioRead(context,n,0)+audioRead(context,n,1));
240 else 247 else
241 audioIn[2*n] = audioIn[2*n+1] = 0; 248 gInputAudio[2*n] = gInputAudio[2*n+1] = 0;
242 if(++gReadPtr >= gSampleData.sampleLen) 249 if(++gReadPtr >= gSampleData.sampleLen)
243 gReadPtr = 0; 250 gReadPtr = 0;
244 } 251 }
245 // ------------------------------------------------------------------- 252 // -------------------------------------------------------------------
246 253
247 for(int n = 0; n < numAudioFrames; n++) { 254 for(int n = 0; n < numAudioFrames; n++) {
248 gInputBuffer[gInputBufferPointer] = ((audioIn[n*numAudioChannels] + audioIn[n*numAudioChannels+1]) * 0.5); 255 gInputBuffer[gInputBufferPointer] = ((gInputAudio[n*numAudioChannels] + gInputAudio[n*numAudioChannels+1]) * 0.5);
249 256
250 // Copy output buffer to output 257 // Copy output buffer to output
251 for(int channel = 0; channel < numAudioChannels; channel++){ 258 for(int channel = 0; channel < numAudioChannels; channel++){
252 audioOut[n * numAudioChannels + channel] = gOutputBuffer[gOutputBufferReadPointer] * gGain * gDryWet + (1 - gDryWet) * audioIn[n * numAudioChannels + channel]; 259 audioOut[n * numAudioChannels + channel] = gOutputBuffer[gOutputBufferReadPointer] * gGain * gDryWet + (1 - gDryWet) * gInputAudio[n * numAudioChannels + channel];
253 } 260 }
254 261
255 // Clear the output sample in the buffer so it is ready for the next overlap-add 262 // Clear the output sample in the buffer so it is ready for the next overlap-add
256 gOutputBuffer[gOutputBufferReadPointer] = 0; 263 gOutputBuffer[gOutputBufferReadPointer] = 0;
257 gOutputBufferReadPointer++; 264 gOutputBufferReadPointer++;
285 { 292 {
286 NE10_FREE(timeDomainIn); 293 NE10_FREE(timeDomainIn);
287 NE10_FREE(timeDomainOut); 294 NE10_FREE(timeDomainOut);
288 NE10_FREE(frequencyDomain); 295 NE10_FREE(frequencyDomain);
289 NE10_FREE(cfg); 296 NE10_FREE(cfg);
297 free(gInputAudio);
290 free(gWindowBuffer); 298 free(gWindowBuffer);
291 } 299 }