/*
 *
 * First assignment for ECS732 RTDSP, to implement a 2-way audio crossover
 * using the BeagleBone Black.
 *
 * Andrew McPherson and Victor Zappi
 * Queen Mary, University of London
 */

#include "../../include/render.h"
#include <cmath>
#include <rtdk.h>

/* TASK: declare any global variables you need here */

// initialise_render() is called once before the audio rendering starts.
// Use it to perform any initialisation and allocation which is dependent
// on the period size or sample rate.
//
// userData holds an opaque pointer to a data structure that was passed
// in from the call to initAudio().
//
// Return true on success; returning false halts the program.
int gNumDigitalFrames=0;
bool initialise_render(int numAnalogChannels, int numDigitalChannels, int numAudioChannels,
					   int numAnalogFramesPerPeriod,
					   int numAudioFramesPerPeriod,
					   float analogSampleRate, float audioSampleRate,
					   void *userData)
{
	gNumAnalogChannels=numAnalogChannels;
	return true;
}

// render() is called regularly at the highest priority by the audio engine.
// Input and output are given from the audio hardware and the other
// ADCs and DACs (if available). If only audio is available, numAnalogFrames
// will be 0.

long int gCountFrames=0;
void render(int numAnalogFrames, int numDigitalFrames, int numAudioFrames, float *audioIn, float *audioOut,
			float *analogIn, float *analogOut, uint32_t *digital)
/*
 * Hey, expect buffer underruns to happen here, as we are doing lots of printfs
 * */
{
	gNumDigitalFrames=numDigitalFrames;
	if(gCountFrames==0){ //this will be executed only on the first call to render(), but the bits will go through this cycle for every subsequent buffer
						// that is, P8_29 will pulse at the beginning of each buffer
	}
	for(int i=1; i<gNumDigitalFrames; i++)
		digitalWriteAll(i, GPIO_LOW); //write all channels on the given frame. Initialize them to zero
	digitalWrite(0, 4, GPIO_HIGH); // set pin 0 HIGH from the current frame to the end of the buffer
	for(int n=0; n<numAnalogFrames; n++) {
		for(int c=0; c<gNumAnalogChannels; c++)
			AnalogWriteFrame(c,n,0); //set channel c on frame n to 0, equivalent to analogOut[n*numAnalogChannels+c]=0;
	}
	AnalogWrite(0,3,0.2); //set channel 0 to 0.2 from frame 3 onwards ...
	AnalogWrite(1,3,0.7); //set channel 1 to 0.7 from frame 3 onwards ...
	AnalogWrite(2,6,0.5); //set channel 2 to 0.5 from frame 6 onwards ...
	for(int n=0; n<numAudioFrames; n++){
		printf("Digital frame %d: 0x%08x;\n",n,digital[n]);
	}
	for(int n=0; n<numAnalogFrames; n++){
		printf("Analog out frame %d :",n);
		for(int c=0; c<gNumAnalogChannels; c++)
			printf("%.1f ",analogOut[n*gNumAnalogChannels + c]);
		printf("\n");
	}
}
// cleanup_render() is called once at the end, after the audio has stopped.
// Release any resources that were allocated in initialise_render().

void cleanup_render()
{
	/* TASK:
	 * If you allocate any memory, be sure to release it here.
	 * You may or may not need anything in this function, depending
	 * on your implementation.
	 */
}
