allow cascading files to be loaded, fix the filter. Improve stability of output linear. Change a bunch of IIR settings.
This commit is contained in:
parent
f3d950c129
commit
a377262c80
|
@ -19,6 +19,7 @@ struct DPODriver
|
|||
{
|
||||
int xn;
|
||||
int yn;
|
||||
int rot90;
|
||||
int zigzag;
|
||||
};
|
||||
|
||||
|
@ -29,8 +30,8 @@ static void DPOUpdate(void * id, struct NoteFinder*nf)
|
|||
struct DPODriver * d = (struct DPODriver*)id;
|
||||
|
||||
|
||||
float cw = ((float)screenx) / d->xn;
|
||||
float ch = ((float)screeny) / d->yn;
|
||||
float cw = ((float)(d->rot90?screeny:screenx)) / d->xn;
|
||||
float ch = ((float)(d->rot90?screenx:screeny)) / d->yn;
|
||||
|
||||
for( y = 0; y < d->yn; y++ )
|
||||
for( x = 0; x < d->xn; x++ )
|
||||
|
@ -54,7 +55,11 @@ static void DPOUpdate(void * id, struct NoteFinder*nf)
|
|||
CNFGColor( OutLEDs[index*3+0] | (OutLEDs[index*3+1] <<8)|(OutLEDs[index*3+2] <<16) );
|
||||
float dx = (x) * cw;
|
||||
float dy = (y) * ch;
|
||||
CNFGTackRectangle( dx, dy, dx+cw+.5, dy+ch+.5 );
|
||||
|
||||
if( d->rot90 )
|
||||
CNFGTackRectangle( dy, dx, dy+ch+.5, dx+cw+.5 );
|
||||
else
|
||||
CNFGTackRectangle( dx, dy, dx+cw+.5, dy+ch+.5 );
|
||||
}
|
||||
CNFGColor( 0xffffff );
|
||||
}
|
||||
|
@ -66,6 +71,7 @@ static void DPOParams(void * id )
|
|||
d->xn = 16; RegisterValue( "lightx", PINT, &d->xn, sizeof( d->xn ) );
|
||||
d->yn = 9; RegisterValue( "lighty", PINT, &d->yn, sizeof( d->yn ) );
|
||||
d->zigzag = 0; RegisterValue( "zigzag", PINT, &d->zigzag, sizeof( d->zigzag ) );
|
||||
d->rot90 = 0; RegisterValue( "rot90", PINT, &d->rot90, sizeof( d->rot90 ) );
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
//XXX This needs to be re-worked to only output LEDs so DisplayArray can take it.
|
||||
//XXX CONSIDER DUMPING
|
||||
|
||||
#include "outdrivers.h"
|
||||
#include "notefinder.h"
|
||||
#include <stdio.h>
|
||||
|
@ -11,7 +14,7 @@
|
|||
//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
|
||||
#define MAX_LEDS_PER_NOTE 1024
|
||||
|
||||
extern short screenx, screeny;
|
||||
|
||||
|
@ -116,7 +119,7 @@ static void DPOUpdate(void * id, struct NoteFinder*nf)
|
|||
}
|
||||
}
|
||||
|
||||
float cw = ((float)screenx) / d->xn;
|
||||
/* float cw = ((float)screenx) / d->xn;
|
||||
float ch = ((float)screeny) / d->yn;
|
||||
|
||||
for( i = 0; i < d->note_peaks; i++ )
|
||||
|
@ -134,7 +137,24 @@ static void DPOUpdate(void * id, struct NoteFinder*nf)
|
|||
|
||||
CNFGDrawBox( x, y, x+cw, y+ch );
|
||||
}
|
||||
}*/
|
||||
|
||||
int led = 0;
|
||||
for( i = 0; i < d->note_peaks; i++ )
|
||||
{
|
||||
struct LINote * l = &d->notes[i];
|
||||
int j;
|
||||
float sat = nf->note_amplitudes_out[i] * d->satamp;
|
||||
if( sat > 1 ) sat = 1;
|
||||
uint32_t color = CCtoHEX( nf->note_positions[i] / 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++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void DPOParams(void * id )
|
||||
|
|
7
Makefile
7
Makefile
|
@ -2,13 +2,16 @@ all : colorchord
|
|||
|
||||
RAWDRAW:=DrawFunctions.o XDriver.o
|
||||
SOUND:=sound.o sound_alsa.o sound_pulse.o sound_null.o
|
||||
OUTS:=LEDOUTDriver.o DisplayOUTDriver.o DisplayShapeDriver.o parameters.o chash.o
|
||||
OUTS := OutputVoronoi.o DisplayArray.o OutputLinear.o DisplayPie.o
|
||||
|
||||
#LEDOUTDriver.o DisplayOUTDriver.o
|
||||
|
||||
RAWDRAWLIBS:=-lX11 -lm -lpthread -lXinerama -lXext
|
||||
LDLIBS:=-lpthread -lasound -lm -lpulse-simple -lpulse
|
||||
CFLAGS:=-g -Os -flto -Wall -ffast-math
|
||||
EXTRALIBS:=-lusb-1.0
|
||||
|
||||
colorchord : os_generic.o main.o dft.o decompose.o filter.o color.o sort.o notefinder.o util.o outdrivers.o $(RAWDRAW) $(SOUND) $(OUTS)
|
||||
colorchord : os_generic.o main.o dft.o decompose.o filter.o color.o sort.o notefinder.o util.o outdrivers.o $(RAWDRAW) $(SOUND) $(OUTS) parameters.o chash.o
|
||||
gcc -o $@ $^ $(CFLAGS) $(LDLIBS) $(EXTRALIBS) $(RAWDRAWLIBS)
|
||||
|
||||
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
|
||||
#define MAX_LEDS_PER_NOTE 512
|
||||
|
||||
extern short screenx, screeny;
|
||||
|
||||
struct LINote
|
||||
{
|
||||
float x, y; //In screen space.
|
||||
|
@ -64,8 +62,8 @@ static void DPOUpdate(void * id, struct NoteFinder*nf)
|
|||
{
|
||||
float angle = nf->note_positions[i] / nf->freqbins * 6.28318;
|
||||
// float angle = nf->enduring_note_id[i];
|
||||
float cx = screenx/2;
|
||||
float cy = screeny/2;
|
||||
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;
|
||||
|
@ -79,8 +77,8 @@ static void DPOUpdate(void * id, struct NoteFinder*nf)
|
|||
else
|
||||
{
|
||||
srand( nf->enduring_note_id[i] );
|
||||
l->x = rand()%screenx;
|
||||
l->y = rand()%screenx;
|
||||
l->x = rand()%d->xn;
|
||||
l->y = rand()%d->yn;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,17 +90,13 @@ static void DPOUpdate(void * id, struct NoteFinder*nf)
|
|||
|
||||
|
||||
|
||||
float cw = ((float)screenx) / d->xn;
|
||||
float ch = ((float)screeny) / d->yn;
|
||||
|
||||
int x, y;
|
||||
int led = 0;
|
||||
for( y = 0; y < d->yn; y++ )
|
||||
for( x = 0; x < d->xn; x++ )
|
||||
{
|
||||
float lx = (x+.5) * cw;
|
||||
float ly = (y+.5) * ch;
|
||||
float kx = (x) * cw;
|
||||
float ky = (y) * ch;
|
||||
float lx = (x+.5);
|
||||
float ly = (y+.5);
|
||||
|
||||
int bestmatch = -1;
|
||||
float bestmatchval = 0;
|
||||
|
@ -126,18 +120,18 @@ static void DPOUpdate(void * id, struct NoteFinder*nf)
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t color = 0;
|
||||
if( bestmatch != -1 )
|
||||
{
|
||||
float sat = nf->note_amplitudes_out[bestmatch] * d->satamp;
|
||||
if( sat > 1.0 ) sat = 1.0;
|
||||
CNFGColor ( CCtoHEX( nf->note_positions[bestmatch] / nf->freqbins, 1.0, sat ) );
|
||||
color = CCtoHEX( nf->note_positions[bestmatch] / nf->freqbins, 1.0, sat );
|
||||
}
|
||||
else
|
||||
{
|
||||
CNFGColor ( 0 );
|
||||
}
|
||||
CNFGTackRectangle( kx, ky, kx+cw, ky+ch );
|
||||
|
||||
OutLEDs[led*3+0] = color & 0xff;
|
||||
OutLEDs[led*3+1] = ( color >> 8 ) & 0xff;
|
||||
OutLEDs[led*3+2] = ( color >> 16 ) & 0xff;
|
||||
led++;
|
||||
}
|
||||
CNFGColor ( 0xffffff );
|
||||
}
|
||||
|
@ -145,20 +139,22 @@ static void DPOUpdate(void * id, struct NoteFinder*nf)
|
|||
static void DPOParams(void * id )
|
||||
{
|
||||
struct DPODriver * d = (struct DPODriver*)id;
|
||||
d->xn = 160; RegisterValue( "lightx", PINT, &d->xn, sizeof( d->xn ) ); printf( "XN: %d\n", d->xn );
|
||||
|
||||
//XXX WRONG
|
||||
d->xn = 160; RegisterValue( "lightx", PINT, &d->xn, sizeof( d->xn ) );
|
||||
d->yn = 90; RegisterValue( "lighty", PINT, &d->yn, sizeof( d->yn ) );
|
||||
d->cutoff = .01; RegisterValue( "shape_cutoff", PFLOAT, &d->cutoff, sizeof( d->cutoff ) );
|
||||
d->cutoff = .01; RegisterValue( "Voronoi_cutoff", PFLOAT, &d->cutoff, sizeof( d->cutoff ) );
|
||||
d->satamp = 5; RegisterValue( "satamp", PFLOAT, &d->satamp, sizeof( d->satamp ) );
|
||||
|
||||
d->amppow = 2.51; RegisterValue( "amppow", PFLOAT, &d->amppow, sizeof( d->amppow ) );
|
||||
d->distpow = 1.5; RegisterValue( "distpow", PFLOAT, &d->distpow, sizeof( d->distpow ) );
|
||||
|
||||
d->from_sides = 1.5;RegisterValue( "fromsides", PINT, &d->from_sides, sizeof( d->from_sides ) );
|
||||
d->from_sides = 1; RegisterValue( "fromsides", PINT, &d->from_sides, sizeof( d->from_sides ) );
|
||||
|
||||
d->note_peaks = 0;
|
||||
}
|
||||
|
||||
static struct DriverInstances * DisplayShapeDriver(const char * parameters)
|
||||
static struct DriverInstances * OutputVoronoi(const char * parameters)
|
||||
{
|
||||
struct DriverInstances * ret = malloc( sizeof( struct DriverInstances ) );
|
||||
struct DPODriver * d = ret->id = malloc( sizeof( struct DPODriver ) );
|
||||
|
@ -169,6 +165,6 @@ static struct DriverInstances * DisplayShapeDriver(const char * parameters)
|
|||
return ret;
|
||||
}
|
||||
|
||||
REGISTER_OUT_DRIVER(DisplayShapeDriver);
|
||||
REGISTER_OUT_DRIVER(OutputVoronoi);
|
||||
|
||||
|
||||
|
|
5
TODO
5
TODO
|
@ -1,8 +1,11 @@
|
|||
Still to do:
|
||||
|
||||
Try this:
|
||||
* Separate "LED Selection" from "output" algorithms.
|
||||
* Separate "LED Selection" from "output" algorithms. << Do this by allowing arbitrary Lights Drivers
|
||||
|
||||
* For light finding, pick lights off the peaks to get number of lights to use.
|
||||
* For light shifting (for 1d-looping light systems) shift the centers of the notes, then vernoi between the notes.
|
||||
|
||||
Brenden:
|
||||
* Consider running DFT on all channels and mixing results
|
||||
|
||||
|
|
|
@ -251,7 +251,7 @@ void CNFGTackRectangle( short x1, short y1, short x2, short y2 )
|
|||
|
||||
void CNFGTackPoly( RDPoint * points, int verts )
|
||||
{
|
||||
XFillPolygon(CNFGDisplay, CNFGPixmap, CNFGGC, (XPoint *)points, 3, Convex, CoordModeOrigin );
|
||||
XFillPolygon(CNFGDisplay, CNFGPixmap, CNFGGC, (XPoint *)points, verts, Convex, CoordModeOrigin );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
45
default.conf
45
default.conf
|
@ -7,22 +7,9 @@
|
|||
#Whether to limit the control loop to ~60ish FPS.
|
||||
cpu_autolimit = 1
|
||||
|
||||
#What display output driver should be used?
|
||||
displayname = DisplayShapeDriver
|
||||
|
||||
|
||||
#Display Shape Driver parameters
|
||||
fromsides = 1
|
||||
lightx = 80
|
||||
lighty = 45
|
||||
shape_cutoff = 0.01
|
||||
satamp = 5.000
|
||||
amppow = 2.510
|
||||
distpow = 1.500
|
||||
|
||||
#General GUI properties.
|
||||
title = PA Test
|
||||
set_screenx = 640
|
||||
set_screenx = 720
|
||||
set_screeny = 480
|
||||
|
||||
#Sound properties.
|
||||
|
@ -41,7 +28,7 @@ sourcename = alsa_output.pci-0000_00_1b.0.analog-stereo.monitor
|
|||
##################################
|
||||
|
||||
# How much to amplify the incoming signal.
|
||||
amplify = 2.0
|
||||
amplify = 2.5
|
||||
|
||||
# What is the base note? I.e. the lowest note.
|
||||
# Note that it won't have very much impact until an octave up though!
|
||||
|
@ -52,29 +39,43 @@ base_hz = 55.0000
|
|||
# default_sigma = 1.4000
|
||||
|
||||
# DFT properties for the DFT up top.
|
||||
dft_iir = 0.7000
|
||||
dft_q = 10.0000
|
||||
dft_speedup = 300.0000
|
||||
dft_iir = 0.0
|
||||
dft_q = 20.0000
|
||||
dft_speedup = 1000.0000
|
||||
octaves = 5
|
||||
|
||||
filter_iter = 1
|
||||
filter_strength = 0.5000
|
||||
filter_iter = 2
|
||||
filter_strength = .5
|
||||
|
||||
# How many bins per octave to use?
|
||||
freqbins = 24
|
||||
|
||||
# For the final note information... How much to slack everything?
|
||||
note_attach_amp_iir = 0.3000
|
||||
note_attach_amp_iir2 = 0.2000
|
||||
note_attach_amp_iir2 = 0.200
|
||||
note_attach_freq_iir = 0.4000
|
||||
|
||||
#How many bins a note can jump from frame to frame to be considered a slide.
|
||||
#this is used to prevent notes from popping in and out a lot.
|
||||
note_combine_distance = 0.5000
|
||||
note_jumpability = 2.5000
|
||||
note_jumpability = 1.8000
|
||||
note_minimum_new_distribution_value = 0.0200
|
||||
note_out_chop = 0.1000
|
||||
|
||||
|
||||
#=======================================================================
|
||||
#Outputs
|
||||
|
||||
|
||||
This is a vornoi thing:
|
||||
outdrivers = DisplayArray, OutputVoronoi
|
||||
lightx = 72
|
||||
lighty = 48
|
||||
fromsides = 1
|
||||
shape_cutoff = 0.03
|
||||
satamp = 5.000
|
||||
amppow = 2.510
|
||||
distpow = 1.500
|
||||
|
||||
|
||||
|
||||
|
|
11
filter.c
11
filter.c
|
@ -2,7 +2,7 @@
|
|||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*
|
||||
void FilterFoldedBinsIIRTWOPASS( float * folded, int bins, float iir )
|
||||
{
|
||||
int i;
|
||||
|
@ -33,8 +33,7 @@ void FilterFoldedBinsIIRTWOPASS( float * folded, int bins, float iir )
|
|||
{
|
||||
folded[i] = v * iir + folded[i] * inv;
|
||||
}
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
void FilterFoldedBinsBlob( float * folded, int bins, float strength, int iter )
|
||||
|
@ -47,8 +46,10 @@ void FilterFoldedBinsBlob( float * folded, int bins, float strength, int iter )
|
|||
memcpy( tmp, folded, sizeof( tmp ) );
|
||||
for( i = 0; i < bins; i++ )
|
||||
{
|
||||
float left = tmp[(i-1+bins)%bins];
|
||||
float right = tmp[(i-1+bins)%bins];
|
||||
// float left = tmp[(i-1+bins)%bins];
|
||||
// float right = tmp[(i-1+bins)%bins];
|
||||
float right = tmp[(i+bins+1)%bins];
|
||||
float left = tmp[(i+bins-1)%bins];
|
||||
folded[i] = folded[i] * (1.-strength) + (left + right) * strength * 0.5;
|
||||
}
|
||||
}
|
||||
|
|
2
filter.h
2
filter.h
|
@ -3,7 +3,7 @@
|
|||
|
||||
|
||||
//Perform a two-pass filter on the data, circularly. Once right, then left.
|
||||
void FilterFoldedBinsIIRTWOPASS( float * folded, int bins, float strength );
|
||||
//void FilterFoldedBinsIIRTWOPASS( float * folded, int bins, float strength );
|
||||
|
||||
void FilterFoldedBinsBlob( float * folded, int bins, float strength, int iter );
|
||||
|
||||
|
|
72
main.c
72
main.c
|
@ -17,6 +17,8 @@
|
|||
short screenx, screeny;
|
||||
int gargc;
|
||||
char ** gargv;
|
||||
struct DriverInstances * outdriver[MAX_OUT_DRIVERS];
|
||||
|
||||
|
||||
int set_screenx = 640; REGISTER_PARAM( set_screenx, PINT );
|
||||
int set_screeny = 480; REGISTER_PARAM( set_screeny, PINT );
|
||||
|
@ -68,7 +70,7 @@ void SoundCB( float * out, float * in, int samplesr, int * samplesp, struct Soun
|
|||
//Load the samples into a ring buffer. Split the channels from interleved to one per buffer.
|
||||
*samplesp = 0;
|
||||
|
||||
int process_channels = (MAX_CHANNELS < channelin)?MAX_CHANNELS:channelin;
|
||||
// int process_channels = (MAX_CHANNELS < channelin)?MAX_CHANNELS:channelin;
|
||||
|
||||
int i;
|
||||
int j;
|
||||
|
@ -77,13 +79,13 @@ void SoundCB( float * out, float * in, int samplesr, int * samplesp, struct Soun
|
|||
if( sample_channel < 0 )
|
||||
{
|
||||
float fo = 0;
|
||||
for( j = 0; j < process_channels; j++ )
|
||||
for( j = 0; j < channelin; j++ )
|
||||
{
|
||||
float f = in[i*channelin+j];
|
||||
if( f < -1 || f > 1 ) continue;
|
||||
fo += f;
|
||||
}
|
||||
fo /= process_channels;
|
||||
fo /= channelin;
|
||||
sound[soundhead] = fo;
|
||||
soundhead = (soundhead+1)%SOUNDCBSIZE;
|
||||
|
||||
|
@ -144,9 +146,11 @@ void LoadFile( const char * filename )
|
|||
int main(int argc, char ** argv)
|
||||
{
|
||||
// const char * OutDriver = "name=LEDOutDriver;leds=512;light_siding=1.9";
|
||||
const char * InitialFile = "default.conf";
|
||||
const char * InitialFile = 0;
|
||||
const char * InitialFileDefault = "default.conf";
|
||||
int i;
|
||||
double LastFileTime;
|
||||
double LastFileTimeInit = 0;
|
||||
double LastFileTimeDefault = 0;
|
||||
|
||||
gargc = argc;
|
||||
gargv = argv;
|
||||
|
@ -156,8 +160,15 @@ int main(int argc, char ** argv)
|
|||
InitialFile = argv[1];
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
LastFileTime = OGGetFileTime( InitialFile );
|
||||
LastFileTimeDefault = OGGetFileTime( InitialFileDefault );
|
||||
LoadFile( InitialFileDefault );
|
||||
}
|
||||
|
||||
if( InitialFile )
|
||||
{
|
||||
LastFileTimeInit = OGGetFileTime( InitialFile );
|
||||
LoadFile( InitialFile );
|
||||
}
|
||||
|
||||
|
@ -171,7 +182,35 @@ int main(int argc, char ** argv)
|
|||
CNFGBGColor = 0x800000;
|
||||
CNFGDialogColor = 0x444444;
|
||||
CNFGSetup( "ColorChord Test", set_screenx, set_screeny );
|
||||
struct DriverInstances * outdriver = SetupOutDriver( );
|
||||
|
||||
|
||||
char * OutDriverNames = strdup( GetParameterS( "outdrivers", "null" ) );
|
||||
char * ThisDriver = OutDriverNames;
|
||||
char * TDStart;
|
||||
for( i = 0; i < MAX_OUT_DRIVERS; i++ )
|
||||
{
|
||||
while( *ThisDriver == ' ' || *ThisDriver == '\t' ) ThisDriver++;
|
||||
if( !*ThisDriver ) break;
|
||||
|
||||
TDStart = ThisDriver;
|
||||
|
||||
while( *ThisDriver != 0 && *ThisDriver != ',' )
|
||||
{
|
||||
if( *ThisDriver == '\t' || *ThisDriver == ' ' ) *ThisDriver = 0;
|
||||
ThisDriver++;
|
||||
}
|
||||
|
||||
if( *ThisDriver )
|
||||
{
|
||||
*ThisDriver = 0;
|
||||
ThisDriver++;
|
||||
}
|
||||
|
||||
printf( "Loading: %s\n", TDStart );
|
||||
outdriver[i] = SetupOutDriver( TDStart );
|
||||
}
|
||||
free(OutDriverNames);
|
||||
|
||||
|
||||
//Initialize Sound
|
||||
struct SoundDriver * sd = InitSound( sound_source, &SoundCB );
|
||||
|
@ -198,8 +237,10 @@ int main(int argc, char ** argv)
|
|||
//Done all ColorChord work.
|
||||
|
||||
VisTimeStart = OGGetAbsoluteTime();
|
||||
if( outdriver )
|
||||
outdriver->Func( outdriver->id, nf );
|
||||
for( i = 0; i < MAX_OUT_DRIVERS; i++ )
|
||||
if( outdriver[i] )
|
||||
outdriver[i]->Func( outdriver[i]->id, nf );
|
||||
|
||||
VisTimeEnd = OGGetAbsoluteTime();
|
||||
|
||||
//Handle outputs.
|
||||
|
@ -331,10 +372,17 @@ int main(int argc, char ** argv)
|
|||
OGUSleep( (int)( SecToWait * 1000000 ) );
|
||||
}
|
||||
|
||||
if( OGGetFileTime( InitialFile ) != LastFileTime )
|
||||
if( OGGetFileTime( InitialFileDefault ) != LastFileTimeDefault ||
|
||||
(InitialFile && LastFileTimeInit != OGGetFileTime( InitialFile ) ) )
|
||||
{
|
||||
LastFileTime = OGGetFileTime( InitialFile );
|
||||
LoadFile( InitialFile );
|
||||
LastFileTimeDefault = OGGetFileTime( InitialFileDefault );
|
||||
LoadFile( InitialFileDefault );
|
||||
|
||||
if( InitialFile )
|
||||
{
|
||||
LastFileTimeInit = OGGetFileTime( InitialFile );
|
||||
LoadFile( InitialFile );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -206,6 +206,7 @@ void RunNoteFinder( struct NoteFinder * nf, const float * audio_stream, int head
|
|||
nf->folded_bins[i] = amp;
|
||||
}
|
||||
|
||||
//This is here to reduce the number of false-positive hits. It helps remove peaks that are meaningless.
|
||||
FilterFoldedBinsBlob( nf->folded_bins, freqbins, nf->filter_strength, nf->filter_iter );
|
||||
|
||||
nf->FilterTime = OGGetAbsoluteTime();
|
||||
|
@ -328,7 +329,7 @@ void RunNoteFinder( struct NoteFinder * nf, const float * audio_stream, int head
|
|||
|
||||
nf->note_amplitudes2[i] = nf->note_amplitudes2[i] * (1.-nf->note_attach_amp_iir2) + nf->note_amplitudes[i] * nf->note_attach_amp_iir2;
|
||||
|
||||
if( nf->note_amplitudes[i] < nf->note_min_amplitude )
|
||||
if( nf->note_amplitudes2[i] < nf->note_min_amplitude )
|
||||
{
|
||||
nf->note_amplitudes[i] = 0;
|
||||
nf->note_amplitudes2[i] = 0;
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
unsigned char OutLEDs[MAX_LEDS*3];
|
||||
int UsedLEDs;
|
||||
|
||||
struct OutDriverListElem ODList[MAX_OUT_DRIVERS];
|
||||
const char OutDriverParameters[MAX_OUT_DRIVER_STRING];
|
||||
|
||||
|
@ -28,13 +32,12 @@ struct DriverInstances * null( )
|
|||
REGISTER_OUT_DRIVER(null);
|
||||
|
||||
|
||||
struct DriverInstances * SetupOutDriver( )
|
||||
struct DriverInstances * SetupOutDriver( const char * drivername )
|
||||
{
|
||||
int i;
|
||||
const char * p = GetParameterS( "displayname", "null" );
|
||||
for( i = 0; i < MAX_OUT_DRIVERS; i++ )
|
||||
{
|
||||
if( ODList[i].Name && strcmp( p, ODList[i].Name ) == 0 )
|
||||
if( ODList[i].Name && strcmp( drivername, ODList[i].Name ) == 0 )
|
||||
{
|
||||
printf( "Found: %s %p\n", ODList[i].Name, ODList[i].Init );
|
||||
return ODList[i].Init( );
|
||||
|
|
|
@ -5,6 +5,12 @@
|
|||
|
||||
struct NoteFinder;
|
||||
|
||||
#define MAX_LEDS 32678
|
||||
|
||||
|
||||
extern unsigned char OutLEDs[MAX_LEDS*3];
|
||||
extern int UsedLEDs;
|
||||
|
||||
|
||||
#define MAX_OUT_DRIVERS 64
|
||||
#define MAX_OUT_DRIVER_STRING 1024
|
||||
|
|
76
parameters.c
76
parameters.c
|
@ -26,10 +26,10 @@ float GetParameterF( const char * name, float defa )
|
|||
{
|
||||
switch( p->t )
|
||||
{
|
||||
case PFLOAT: return *((float*)p->ptr);
|
||||
case PINT: return *((int*)p->ptr);
|
||||
case PFLOAT: return *((float*)p->lp->ptr);
|
||||
case PINT: return *((int*)p->lp->ptr);
|
||||
case PSTRING:
|
||||
case PBUFFER: if( p->ptr ) return atof( p->ptr );
|
||||
case PBUFFER: if( p->lp->ptr ) return atof( p->lp->ptr );
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
@ -46,10 +46,10 @@ int GetParameterI( const char * name, int defa )
|
|||
{
|
||||
switch( p->t )
|
||||
{
|
||||
case PFLOAT: return *((float*)p->ptr);
|
||||
case PINT: return *((int*)p->ptr);
|
||||
case PFLOAT: return *((float*)p->lp->ptr);
|
||||
case PINT: return *((int*)p->lp->ptr);
|
||||
case PSTRING:
|
||||
case PBUFFER: if( p->ptr ) return atoi( p->ptr );
|
||||
case PBUFFER: if( p->lp->ptr ) return atoi( p->lp->ptr );
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
@ -67,10 +67,10 @@ const char * GetParameterS( const char * name, const char * defa )
|
|||
{
|
||||
switch( p->t )
|
||||
{
|
||||
case PFLOAT: snprintf( returnbuffer, sizeof( returnbuffer ), "%0.4f", *((float*)p->ptr) ); return returnbuffer;
|
||||
case PINT: snprintf( returnbuffer, sizeof( returnbuffer ), "%d", *((int*)p->ptr) ); return returnbuffer;
|
||||
case PFLOAT: snprintf( returnbuffer, sizeof( returnbuffer ), "%0.4f", *((float*)p->lp->ptr) ); return returnbuffer;
|
||||
case PINT: snprintf( returnbuffer, sizeof( returnbuffer ), "%d", *((int*)p->lp->ptr) ); return returnbuffer;
|
||||
case PSTRING:
|
||||
case PBUFFER: return p->ptr;
|
||||
case PBUFFER: return p->lp->ptr;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
@ -83,22 +83,41 @@ const char * GetParameterS( const char * name, const char * defa )
|
|||
|
||||
static int SetParameter( struct Param * p, const char * str )
|
||||
{
|
||||
struct LinkedParameter * lp;
|
||||
lp = p->lp;
|
||||
|
||||
switch( p->t )
|
||||
{
|
||||
case PFLOAT:
|
||||
*((float*)p->ptr) = atof( str );
|
||||
while( lp )
|
||||
{
|
||||
*((float*)lp->ptr) = atof( str );
|
||||
lp = lp->lp;
|
||||
}
|
||||
break;
|
||||
case PINT:
|
||||
*((int*)p->ptr) = atoi( str );
|
||||
while( lp )
|
||||
{
|
||||
*((int*)lp->ptr) = atoi( str );
|
||||
lp = lp->lp;
|
||||
}
|
||||
break;
|
||||
case PBUFFER:
|
||||
strncpy( (char*)p->ptr, str, p->size );
|
||||
if( p->size > 0 )
|
||||
((char*)p->ptr)[p->size-1]= '\0';
|
||||
while( lp )
|
||||
{
|
||||
strncpy( (char*)lp->ptr, str, p->size );
|
||||
if( p->size > 0 )
|
||||
((char*)lp->ptr)[p->size-1]= '\0';
|
||||
lp = lp->lp;
|
||||
}
|
||||
break;
|
||||
case PSTRING:
|
||||
free( p->ptr );
|
||||
p->ptr = strdup( str );
|
||||
while( lp )
|
||||
{
|
||||
free( lp->ptr );
|
||||
lp->ptr = strdup( str );
|
||||
lp = lp->lp;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
|
@ -129,8 +148,8 @@ void RegisterValue( const char * name, enum ParamType t, void * ptr, int size )
|
|||
{
|
||||
fprintf( stderr, "Warning: Orphan parameter %s was not a PSTRING.\n", name );
|
||||
}
|
||||
char * orig = p->ptr;
|
||||
p->ptr = ptr;
|
||||
char * orig = p->lp->ptr;
|
||||
p->lp->ptr = ptr;
|
||||
p->t = t;
|
||||
p->size = size;
|
||||
p->orphan = 0;
|
||||
|
@ -143,7 +162,18 @@ void RegisterValue( const char * name, enum ParamType t, void * ptr, int size )
|
|||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "Warning: Parameter %s re-registered. Cannot re-register.\n", name );
|
||||
struct LinkedParameter * lp = p->lp;
|
||||
if( size != p->size )
|
||||
{
|
||||
fprintf( stderr, "Size mismatch: Parameter %s.\n", name );
|
||||
}
|
||||
else
|
||||
{
|
||||
p->lp = malloc( sizeof( struct LinkedParameter ) );
|
||||
p->lp->lp = lp;
|
||||
p->lp->ptr = ptr;
|
||||
memcpy( p->lp->ptr, p->lp->lp->ptr, size );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -151,7 +181,9 @@ void RegisterValue( const char * name, enum ParamType t, void * ptr, int size )
|
|||
struct Param ** n = (struct Param**)HashTableInsert( parameters, name, 1 );
|
||||
*n = malloc( sizeof( struct Param ) );
|
||||
(*n)->t = t;
|
||||
(*n)->ptr = ptr;
|
||||
(*n)->lp = malloc( sizeof( struct LinkedParameter ) );
|
||||
(*n)->lp->lp = 0;
|
||||
(*n)->lp->ptr = ptr;
|
||||
(*n)->orphan = 0;
|
||||
(*n)->size = size;
|
||||
(*n)->callback = 0;
|
||||
|
@ -215,7 +247,9 @@ void SetParametersFromString( const char * string )
|
|||
*n = malloc( sizeof ( struct Param ) );
|
||||
(*n)->orphan = 1;
|
||||
(*n)->t = PSTRING;
|
||||
(*n)->ptr = strdup( value );
|
||||
(*n)->lp = malloc( sizeof( struct LinkedParameter ) );
|
||||
(*n)->lp->lp = 0;
|
||||
(*n)->lp->ptr = strdup( value );
|
||||
(*n)->size = strlen( value ) + 1;
|
||||
(*n)->callback = 0;
|
||||
}
|
||||
|
|
|
@ -22,13 +22,19 @@ struct ParamCallback
|
|||
struct ParamCallback * next;
|
||||
};
|
||||
|
||||
struct LinkedParameter
|
||||
{
|
||||
void * ptr;
|
||||
struct LinkedParameter * lp;
|
||||
};
|
||||
|
||||
struct Param
|
||||
{
|
||||
char orphan; //If this is set, then this is something that was received from a string, but has no claimed interface.
|
||||
//It will be claimed when RegisterValue is called. NOTE: When orphan is set, it must be a malloc'd string.
|
||||
enum ParamType t;
|
||||
void * ptr;
|
||||
int size;
|
||||
struct LinkedParameter * lp;
|
||||
|
||||
struct ParamCallback * callback;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue