andrewm@0: /* andrewm@0: * render.cpp andrewm@0: * andrewm@0: * Created on: Oct 24, 2014 andrewm@0: * Author: parallels andrewm@0: */ andrewm@0: andrewm@0: andrewm@0: #include "../../include/render.h" andrewm@0: #include "../../include/Utilities.h" andrewm@0: #include andrewm@0: #include andrewm@0: andrewm@0: float gPhase; andrewm@0: float gInverseSampleRate; andrewm@13: int gMatrixFramesPerAudioFrame; andrewm@0: andrewm@0: // These settings are carried over from main.cpp andrewm@0: // Setting global variables is an alternative approach andrewm@0: // to passing a structure to userData in initialise_render() andrewm@0: andrewm@0: extern int gSensorInputFrequency; andrewm@0: extern int gSensorInputAmplitude; andrewm@0: andrewm@0: // initialise_render() is called once before the audio rendering starts. andrewm@0: // Use it to perform any initialisation and allocation which is dependent andrewm@0: // on the period size or sample rate. andrewm@0: // andrewm@0: // userData holds an opaque pointer to a data structure that was passed andrewm@0: // in from the call to initAudio(). andrewm@0: // andrewm@0: // Return true on success; returning false halts the program. andrewm@0: andrewm@12: bool initialise_render(int numMatrixChannels, int numAudioChannels, andrewm@12: int numMatrixFramesPerPeriod, andrewm@12: int numAudioFramesPerPeriod, andrewm@12: float matrixSampleRate, float audioSampleRate, andrewm@12: void *userData) andrewm@0: { andrewm@13: if(numMatrixFramesPerPeriod == 0 || numMatrixFramesPerPeriod > numAudioFramesPerPeriod) { andrewm@13: rt_printf("Error: this example needs the matrix enabled, with 4 or 8 channels\n"); andrewm@0: return false; andrewm@0: } andrewm@0: andrewm@13: gMatrixFramesPerAudioFrame = numAudioFramesPerPeriod / numMatrixFramesPerPeriod; andrewm@0: gInverseSampleRate = 1.0 / audioSampleRate; andrewm@0: gPhase = 0.0; andrewm@0: andrewm@0: return true; andrewm@0: } andrewm@0: andrewm@0: // render() is called regularly at the highest priority by the audio engine. andrewm@0: // Input and output are given from the audio hardware and the other andrewm@0: // ADCs and DACs (if available). If only audio is available, numMatrixFrames andrewm@0: // will be 0. andrewm@0: andrewm@0: void render(int numMatrixFrames, int numAudioFrames, float *audioIn, float *audioOut, andrewm@0: uint16_t *matrixIn, uint16_t *matrixOut) andrewm@0: { andrewm@0: float frequency = 0; andrewm@0: float amplitude = 0; andrewm@0: andrewm@0: // There are twice as many audio frames as matrix frames since audio sample rate andrewm@0: // is twice as high andrewm@0: andrewm@0: for(int n = 0; n < numAudioFrames; n++) { andrewm@13: if(!(n % gMatrixFramesPerAudioFrame)) { andrewm@0: // Even audio samples: update frequency and amplitude from the matrix andrewm@13: frequency = map(analogRead(gSensorInputFrequency, n/gMatrixFramesPerAudioFrame), 0, MATRIX_MAX, 100, 1000); andrewm@13: amplitude = (float)analogRead(gSensorInputAmplitude, n/gMatrixFramesPerAudioFrame) / MATRIX_MAX; andrewm@0: } andrewm@0: andrewm@0: float out = amplitude * sinf(gPhase); andrewm@0: andrewm@13: for(int channel = 0; channel < gNumAudioChannels; channel++) andrewm@13: audioOut[n * gNumAudioChannels + channel] = out; andrewm@0: andrewm@0: gPhase += 2.0 * M_PI * frequency * gInverseSampleRate; andrewm@0: if(gPhase > 2.0 * M_PI) andrewm@0: gPhase -= 2.0 * M_PI; andrewm@0: } andrewm@0: } andrewm@0: andrewm@0: // cleanup_render() is called once at the end, after the audio has stopped. andrewm@0: // Release any resources that were allocated in initialise_render(). andrewm@0: andrewm@0: void cleanup_render() andrewm@0: { andrewm@0: andrewm@0: }