| andrewm@0 | 1 /* | 
| andrewm@0 | 2  * render.cpp | 
| andrewm@0 | 3  * | 
| andrewm@0 | 4  *  Created on: Oct 24, 2014 | 
| andrewm@0 | 5  *      Author: parallels | 
| andrewm@0 | 6  */ | 
| andrewm@0 | 7 | 
| andrewm@0 | 8 | 
| andrewm@52 | 9 #include "../../include/BeagleRT.h" | 
| andrewm@0 | 10 #include "../../include/Utilities.h" | 
| andrewm@0 | 11 #include <rtdk.h> | 
| andrewm@0 | 12 #include <cmath> | 
| andrewm@0 | 13 | 
| andrewm@0 | 14 // Set range for analog outputs designed for driving LEDs | 
| andrewm@52 | 15 const float kMinimumAmplitude = (1.5 / 5.0); | 
| andrewm@52 | 16 const float kAmplitudeRange = 1.0 - kMinimumAmplitude; | 
| andrewm@0 | 17 | 
| andrewm@0 | 18 float gFrequency; | 
| andrewm@0 | 19 float gPhase; | 
| andrewm@0 | 20 float gInverseSampleRate; | 
| andrewm@0 | 21 | 
| andrewm@0 | 22 // initialise_render() is called once before the audio rendering starts. | 
| andrewm@0 | 23 // Use it to perform any initialisation and allocation which is dependent | 
| andrewm@0 | 24 // on the period size or sample rate. | 
| andrewm@0 | 25 // | 
| andrewm@0 | 26 // userData holds an opaque pointer to a data structure that was passed | 
| andrewm@0 | 27 // in from the call to initAudio(). | 
| andrewm@0 | 28 // | 
| andrewm@0 | 29 // Return true on success; returning false halts the program. | 
| andrewm@0 | 30 | 
| andrewm@52 | 31 bool initialise_render(BeagleRTContext *context, void *userData) | 
| andrewm@0 | 32 { | 
| andrewm@0 | 33 	// Retrieve a parameter passed in from the initAudio() call | 
| andrewm@0 | 34 	gFrequency = *(float *)userData; | 
| andrewm@0 | 35 | 
| andrewm@52 | 36 	if(context->analogFrames == 0) { | 
| andrewm@12 | 37 		rt_printf("Error: this example needs the matrix enabled\n"); | 
| andrewm@0 | 38 		return false; | 
| andrewm@0 | 39 	} | 
| andrewm@0 | 40 | 
| andrewm@52 | 41 	gInverseSampleRate = 1.0 / context->analogSampleRate; | 
| andrewm@0 | 42 	gPhase = 0.0; | 
| andrewm@0 | 43 | 
| andrewm@0 | 44 	return true; | 
| andrewm@0 | 45 } | 
| andrewm@0 | 46 | 
| andrewm@0 | 47 // render() is called regularly at the highest priority by the audio engine. | 
| andrewm@0 | 48 // Input and output are given from the audio hardware and the other | 
| andrewm@0 | 49 // ADCs and DACs (if available). If only audio is available, numMatrixFrames | 
| andrewm@0 | 50 // will be 0. | 
| andrewm@0 | 51 | 
| andrewm@52 | 52 void render(BeagleRTContext *context, void *userData) | 
| andrewm@0 | 53 { | 
| andrewm@52 | 54 	for(int n = 0; n < context->analogFrames; n++) { | 
| andrewm@0 | 55 		// Set LED to different phase for each matrix channel | 
| andrewm@0 | 56 		float relativePhase = 0.0; | 
| andrewm@52 | 57 		for(int channel = 0; channel < context->analogChannels; channel++) { | 
| andrewm@0 | 58 			float out = kMinimumAmplitude + kAmplitudeRange * 0.5f * (1.0f + sinf(gPhase + relativePhase)); | 
| andrewm@0 | 59 | 
| andrewm@52 | 60 			analogWriteFrame(context, n, channel, out); | 
| andrewm@0 | 61 | 
| andrewm@0 | 62 			// Advance by pi/4 (1/8 of a full rotation) for each channel | 
| andrewm@0 | 63 			relativePhase += M_PI * 0.25; | 
| andrewm@0 | 64 		} | 
| andrewm@0 | 65 | 
| andrewm@0 | 66 		gPhase += 2.0 * M_PI * gFrequency * gInverseSampleRate; | 
| andrewm@0 | 67 		if(gPhase > 2.0 * M_PI) | 
| andrewm@0 | 68 			gPhase -= 2.0 * M_PI; | 
| andrewm@0 | 69 	} | 
| andrewm@0 | 70 } | 
| andrewm@0 | 71 | 
| andrewm@0 | 72 // cleanup_render() is called once at the end, after the audio has stopped. | 
| andrewm@0 | 73 // Release any resources that were allocated in initialise_render(). | 
| andrewm@0 | 74 | 
| andrewm@52 | 75 void cleanup_render(BeagleRTContext *context, void *userData) | 
| andrewm@0 | 76 { | 
| andrewm@0 | 77 | 
| andrewm@0 | 78 } |