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
					
				
					 15 changed files with 227 additions and 99 deletions
				
			
		| 
						 | 
				
			
			@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue