IoT-Labs/Coursework-Demo/buffer.h

142 lines
3.5 KiB
C
Raw Permalink Normal View History

2020-11-30 11:06:20 +00:00
#ifndef _BUFFER_GUARD
#define _BUFFER_GUARD
#include "util.h"
#include "math.h"
typedef struct Buffer {
float* items;
int length;
Stats stats;
} Buffer;
Buffer
getBuffer(int size) // retrieve new buffer with malloc-ed memory space
{
float* memSpace = (float*) malloc(size * sizeof(float));
Buffer buffer = {memSpace, size, };
return buffer;
}
void
freeBuffer(Buffer buffer) // little abstraction function to act as buffer destructor
{
free(buffer.items);
}
void
swapBufferMemory(Buffer *first, Buffer *second) // swap memspaces between buffers
{
float* firstItems = first->items; // swap input buffer and output buffer item pointers
first->items = second->items;
second->items = firstItems;
int firstLength = first->length; // swap lengths to iterate correctly
first->length = second->length;
second->length = firstLength;
}
void // perform aggregation into groupSize (4 in the spec)
aggregateBuffer(Buffer bufferIn, Buffer bufferOut, int groupSize)
{
int requiredGroups = ceil((float)bufferIn.length/groupSize); // number of groups
int finalGroupSize = bufferIn.length % groupSize; // work out length of final group if bufferIn not of length that divides nicely
if(requiredGroups > bufferOut.length) // error check
{
putFloat((float)bufferIn.length/groupSize); printf(" length out buffer required, %i provided\n", bufferOut.length);
return;
}
int g; // for group number
float *inputPtr = bufferIn.items; // cursor for full buffer
float *outputPtr = bufferOut.items; // cursor for output buffer
for(g = 0; g < requiredGroups; g++)
{
int length = groupSize; // length of this group's size
if(g == requiredGroups - 1 && finalGroupSize != 0) length = finalGroupSize; // shorten if necessary
*outputPtr = calculateMean(inputPtr, length); // SET OUTPUT VALUE
inputPtr += length; // increment both cursors
outputPtr++;
}
}
void
calculateBufferEMA(Buffer inBuffer, Buffer outBuffer, float smooth)
{
if(smooth < 0 || smooth > 1) // VALIDATE SMOOTH VALUE
{
printf("Smoothing value of %f not valid, between 0 and 1 required", smooth);
return NULL;
}
if(inBuffer.length > outBuffer.length) // OUTPUT BUFFER LONG ENOUGH
{
printf("Out buffer not big enough to hold items");
return NULL;
}
int i;
float *inputPtr = inBuffer.items; // cursor for full buffer
float *outputPtr = outBuffer.items; // cursor for output buffer
float emaLast;
for(i = 0; i < inBuffer.length; i++)
{
if(i == 0)
{
*outputPtr = *inputPtr; //first ema is first value
}
else
{
*outputPtr = calculateEMA(*inputPtr, emaLast, smooth);
}
emaLast = *outputPtr; // keep this ema for next round
inputPtr++;
outputPtr++;
}
}
void
clearBuffer(Buffer buffer)
{
int length = buffer.length;
if(length > 0)
{
int i;
float *bufferPtr = buffer.items;
for(i = 0; i < length; i++)
{
*bufferPtr = 0.0;
bufferPtr++;
}
}
}
void
printBuffer(Buffer buffer)
{
putchar('[');
int length = buffer.length;
if(length > 0)
{
int i;
float *ptr = buffer.items;
for(i = 0; i < length; i++)
{
if(i > 0) printf(", ");
putFloat(*ptr);
ptr++;
}
}
putchar(']');
}
#endif