171 lines
3.9 KiB
C
171 lines
3.9 KiB
C
#include "outdrivers.h"
|
|
#include "notefinder.h"
|
|
#include <stdio.h>
|
|
#include "parameters.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "color.h"
|
|
#include <math.h>
|
|
#include "DrawFunctions.h"
|
|
|
|
//Uses: note_amplitudes2[note] for how many lights to use.
|
|
//Uses: note_amplitudes_out[note] for how bright it should be.
|
|
|
|
#define MAX_LEDS_PER_NOTE 512
|
|
|
|
struct LINote
|
|
{
|
|
float x, y; //In screen space.
|
|
float ledexp;
|
|
float lednrm; //How many LEDs should we have?
|
|
};
|
|
|
|
struct DPODriver
|
|
{
|
|
int xn;
|
|
int yn;
|
|
float cutoff;
|
|
float satamp;
|
|
float amppow; //For amplitudes
|
|
float distpow; //for distances
|
|
int note_peaks;
|
|
int from_sides;
|
|
|
|
struct LINote * notes;
|
|
};
|
|
|
|
static void DPOUpdate(void * id, struct NoteFinder*nf)
|
|
{
|
|
int i;
|
|
struct DPODriver * d = (struct DPODriver*)id;
|
|
|
|
int tleds = d->xn * d->yn;
|
|
|
|
if( d->note_peaks != nf->note_peaks )
|
|
{
|
|
d->note_peaks = nf->note_peaks;
|
|
if( d->notes ) free( d->notes );
|
|
d->notes = malloc( sizeof( struct LINote ) * nf->note_peaks );
|
|
memset( d->notes, 0, sizeof( struct LINote ) * nf->note_peaks );
|
|
}
|
|
|
|
|
|
float totalexp = 0;
|
|
|
|
for( i = 0; i < d->note_peaks; i++ )
|
|
{
|
|
struct LINote * l = &d->notes[i];
|
|
l->ledexp = pow( nf->note_amplitudes2[i], d->amppow ) - d->cutoff;
|
|
if( l->ledexp < 0 ) l->ledexp = 0;
|
|
totalexp += l->ledexp;
|
|
if( d->from_sides )
|
|
{
|
|
float angle = nf->note_positions[i] / nf->freqbins * 6.28318;
|
|
// float angle = nf->enduring_note_id[i];
|
|
float cx = d->xn/2.0;
|
|
float cy = d->yn/2.0;
|
|
float tx = sin( angle ) * cx + cx;
|
|
float ty = cos( angle ) * cy + cy;
|
|
l->x = l->x * .9 + tx * .1;
|
|
l->y = l->y * .9 + ty * .1;
|
|
if( nf->enduring_note_id[i] == 0 )
|
|
{
|
|
l->x = cx;
|
|
l->y = cy;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
srand( nf->enduring_note_id[i] );
|
|
l->x = rand()%d->xn;
|
|
l->y = rand()%d->yn;
|
|
}
|
|
}
|
|
|
|
for( i = 0; i < d->note_peaks; i++ )
|
|
{
|
|
struct LINote * l = &d->notes[i];
|
|
l->lednrm = l->ledexp * tleds / totalexp;
|
|
}
|
|
|
|
|
|
|
|
int x, y;
|
|
int led = 0;
|
|
for( y = 0; y < d->yn; y++ )
|
|
for( x = 0; x < d->xn; x++ )
|
|
{
|
|
float lx = (x+.5);
|
|
float ly = (y+.5);
|
|
|
|
int bestmatch = -1;
|
|
float bestmatchval = 0;
|
|
for( i = 0; i < d->note_peaks; i++ )
|
|
{
|
|
struct LINote * l = &d->notes[i];
|
|
float distsq = (lx-l->x)*(lx-l->x)+(ly-l->y)*(ly-l->y);
|
|
float dist;
|
|
if( d->distpow == 1.0 )
|
|
dist = distsq;
|
|
else if( d->distpow == 2.0 )
|
|
dist = sqrtf(distsq);
|
|
else
|
|
dist = powf(distsq,1.0);
|
|
|
|
float match = l->ledexp / dist;
|
|
if( match > bestmatchval )
|
|
{
|
|
bestmatch = i;
|
|
bestmatchval = match;
|
|
}
|
|
}
|
|
|
|
uint32_t color = 0;
|
|
if( bestmatch != -1 )
|
|
{
|
|
float sat = nf->note_amplitudes_out[bestmatch] * d->satamp;
|
|
if( sat > 1.0 ) sat = 1.0;
|
|
color = CCtoHEX( nf->note_positions[bestmatch] / nf->freqbins, 1.0, sat );
|
|
}
|
|
|
|
OutLEDs[led*3+0] = color & 0xff;
|
|
OutLEDs[led*3+1] = ( color >> 8 ) & 0xff;
|
|
OutLEDs[led*3+2] = ( color >> 16 ) & 0xff;
|
|
led++;
|
|
}
|
|
CNFGColor ( 0xffffff );
|
|
}
|
|
|
|
static void DPOParams(void * id )
|
|
{
|
|
struct DPODriver * d = (struct DPODriver*)id;
|
|
|
|
//XXX WRONG
|
|
d->xn = 160; RegisterValue( "lightx", PAINT, &d->xn, sizeof( d->xn ) );
|
|
d->yn = 90; RegisterValue( "lighty", PAINT, &d->yn, sizeof( d->yn ) );
|
|
d->cutoff = .01; RegisterValue( "Voronoi_cutoff", PAFLOAT, &d->cutoff, sizeof( d->cutoff ) );
|
|
d->satamp = 5; RegisterValue( "satamp", PAFLOAT, &d->satamp, sizeof( d->satamp ) );
|
|
|
|
d->amppow = 2.51; RegisterValue( "amppow", PAFLOAT, &d->amppow, sizeof( d->amppow ) );
|
|
d->distpow = 1.5; RegisterValue( "distpow", PAFLOAT, &d->distpow, sizeof( d->distpow ) );
|
|
|
|
d->from_sides = 1; RegisterValue( "fromsides", PAINT, &d->from_sides, sizeof( d->from_sides ) );
|
|
|
|
d->note_peaks = 0;
|
|
}
|
|
|
|
static struct DriverInstances * OutputVoronoi(const char * parameters)
|
|
{
|
|
struct DriverInstances * ret = malloc( sizeof( struct DriverInstances ) );
|
|
struct DPODriver * d = ret->id = malloc( sizeof( struct DPODriver ) );
|
|
memset( d, 0, sizeof( struct DPODriver ) );
|
|
ret->Func = DPOUpdate;
|
|
ret->Params = DPOParams;
|
|
DPOParams( d );
|
|
return ret;
|
|
}
|
|
|
|
REGISTER_OUT_DRIVER(OutputVoronoi);
|
|
|
|
|