Compare commits
15 commits
Author | SHA1 | Date | |
---|---|---|---|
26bcc970fa | |||
dfd7faf8b2 | |||
cd9094e8cb | |||
35a4abfb50 | |||
42a8235ddf | |||
cd1c1f93d0 | |||
fe5ce57e9a | |||
3de5d62a05 | |||
2539f021dc | |||
ab11048f10 | |||
80d6b40a7d | |||
0a172502fe | |||
10041b66b4 | |||
ad6a7418f3 | |||
2c8a022aca |
|
@ -27,6 +27,7 @@ struct HIDAPIOutDriver
|
|||
int is_rgby;
|
||||
int bank_size[4];
|
||||
int bank_id[4];
|
||||
int do_write_method;
|
||||
};
|
||||
|
||||
|
||||
|
@ -49,13 +50,74 @@ static void * LEDOutThread( void * v )
|
|||
}
|
||||
printf( "\n" );
|
||||
*/
|
||||
int r = hid_send_feature_report( led->devh, led->last_leds, total_bytes );
|
||||
if( r < 0 )
|
||||
if( led->do_write_method )
|
||||
{
|
||||
led->did_init = 0;
|
||||
printf( "Fault sending LEDs.\n" );
|
||||
static int rk;
|
||||
|
||||
int panel = 0;
|
||||
for( panel = 0; panel < 9; panel++ )
|
||||
{
|
||||
uint8_t hidbuf[66];
|
||||
memset( hidbuf, 0x00, 65 );
|
||||
hidbuf[0] = panel;
|
||||
int i;
|
||||
int tled = panel;
|
||||
|
||||
if( led->do_write_method == 2 )
|
||||
{
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
int wled = i * 3;
|
||||
tled = panel * 16 + i;
|
||||
hidbuf[wled+2] = OutLEDs[tled*3+1];
|
||||
hidbuf[wled+3] = OutLEDs[tled*3+0];
|
||||
hidbuf[wled+4] = OutLEDs[tled*3+2];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
int wled = i * 3;
|
||||
hidbuf[wled+2] = OutLEDs[tled*3+1];
|
||||
hidbuf[wled+3] = OutLEDs[tled*3+0];
|
||||
hidbuf[wled+4] = OutLEDs[tled*3+2];
|
||||
}
|
||||
}
|
||||
|
||||
rk += 0x80;
|
||||
hidbuf[0] = 0;
|
||||
hidbuf[1] = panel;
|
||||
|
||||
int r;
|
||||
#if 0
|
||||
for( i = 0; i < 64; i++ )
|
||||
{
|
||||
printf( "%02x ", hidbuf[i] );
|
||||
}
|
||||
printf( "\n" ); fflush( stdout );
|
||||
#endif
|
||||
// printf( "." ); fflush( stdout );
|
||||
r = hid_write( led->devh, hidbuf, 64 );
|
||||
//usleep(1000);
|
||||
if( r < 0 )
|
||||
{
|
||||
led->did_init = 0;
|
||||
printf( "Fault sending LEDs.\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int r = hid_send_feature_report( led->devh, led->last_leds, total_bytes );
|
||||
if( r < 0 )
|
||||
{
|
||||
led->did_init = 0;
|
||||
printf( "Fault sending LEDs.\n" );
|
||||
}
|
||||
}
|
||||
led->readyFlag = 0;
|
||||
printf( "." ); fflush( stdout );
|
||||
}
|
||||
OGUSleep(100);
|
||||
}
|
||||
|
@ -72,8 +134,17 @@ static void LEDUpdate(void * id, struct NoteFinder*nf)
|
|||
{
|
||||
led->did_init = 1;
|
||||
hid_init();
|
||||
|
||||
led->devh = hid_open( 0xabcd, 0xf104, 0 );
|
||||
|
||||
if( led->do_write_method )
|
||||
{
|
||||
//Impulse
|
||||
led->devh = hid_open( 0x0483, 0x5750, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
//My dingus.
|
||||
led->devh = hid_open( 0xabcd, 0xf104, 0 );
|
||||
}
|
||||
|
||||
if( !led->devh )
|
||||
{
|
||||
|
@ -217,6 +288,7 @@ static void LEDParams(void * id )
|
|||
led->bank_id[1] = 0; RegisterValue( "bank2_id", PAINT, &led->bank_id[1], sizeof( led->bank_id[1] ) );
|
||||
led->bank_id[2] = 0; RegisterValue( "bank3_id", PAINT, &led->bank_id[2], sizeof( led->bank_id[2] ) );
|
||||
led->bank_id[3] = 0; RegisterValue( "bank4_id", PAINT, &led->bank_id[3], sizeof( led->bank_id[3] ) );
|
||||
led->do_write_method = 0; RegisterValue( "do_write_method", PAINT, &led->do_write_method, sizeof( led->do_write_method ) );
|
||||
|
||||
led->did_init = 0;
|
||||
}
|
||||
|
|
BIN
colorchord2/colorchord.exe
Normal file → Executable file
BIN
colorchord2/colorchord.exe
Normal file → Executable file
Binary file not shown.
37
colorchord2/impulse.conf
Normal file
37
colorchord2/impulse.conf
Normal file
|
@ -0,0 +1,37 @@
|
|||
|
||||
This is a vornoi thing:
|
||||
outdrivers = DisplayArray, OutputCells, DisplayHIDAPI
|
||||
lightx = 12
|
||||
lighty = 12
|
||||
leds = 144
|
||||
fromsides = 0
|
||||
shape_cutoff = 0.00
|
||||
satamp = 5.000
|
||||
amppow = 2.510
|
||||
distpow = 1.500
|
||||
|
||||
light_siding = 1.9
|
||||
|
||||
samplerate = 11025
|
||||
buffer = 64
|
||||
|
||||
#sourcename = default
|
||||
sourcename = alsa_output.pci-0000_00_1f.3.analog-stereo.monitor
|
||||
#default
|
||||
do_write_method = 2
|
||||
|
||||
amplify = 2.5
|
||||
note_attach_amp_iir = 0.9000
|
||||
note_attach_amp_iir2 = 0.550
|
||||
note_attach_freq_iir = 0.9000
|
||||
dft_iir = .6
|
||||
dft_q = 20.0000
|
||||
dft_speedup = 1000.0000
|
||||
note_jumpability = 1.0000
|
||||
|
||||
#skittlequantity = 24
|
||||
timebased = 1
|
||||
snakey=0
|
||||
qtyamp = 160
|
||||
|
||||
|
|
@ -18,6 +18,11 @@ Unfortunately the I2S Out (WS2812 in) pin is the same as RX1 (pin 25), which mea
|
|||
|
||||
The audio data is taken from TOUT, but must be kept between 0 and 1V.
|
||||
|
||||
An option that has been thurroughly tested is for use with the 2019 MAGFest Swadge. https://github.com/cnlohr/swadge2019
|
||||
|
||||
Audio portion:
|
||||
![Audio portion of schematic](https://raw.githubusercontent.com/cnlohr/swadge2019/master/hardware/swadge2019_schematic_audio.png)
|
||||
|
||||
## Notes
|
||||
|
||||
./makeconf.inc has a few variables that Make uses for building and flashing the firmware.
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
#define HPABUFFSIZE 512
|
||||
|
||||
#define CCEMBEDDED
|
||||
#define NUM_LIN_LEDS 541
|
||||
#define NUM_LIN_LEDS 16
|
||||
#define DFREQ 16000
|
||||
|
||||
#define LUXETRON 0
|
||||
#define memcpy ets_memcpy
|
||||
#define memset ets_memset
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ Extra copyright info:
|
|||
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#include <ccconfig.h>
|
||||
#include "slc_register.h"
|
||||
#include "esp82xxutil.h"
|
||||
#include <c_types.h>
|
||||
|
@ -45,9 +45,8 @@ Extra copyright info:
|
|||
//Creates an I2S SR of 93,750 Hz, or 3 MHz Bitclock (.333us/sample)
|
||||
// 12000000L/(div*bestbck*2)
|
||||
//It is likely you could speed this up a little.
|
||||
#define LUXETRON
|
||||
|
||||
#ifdef LUXETRON
|
||||
#if LUXETRON == 1
|
||||
#define INVERT
|
||||
#define WS_I2S_BCK 14
|
||||
#define WS_I2S_DIV 5
|
||||
|
@ -456,10 +455,10 @@ static const uint16_t bitpatterns[16] = {
|
|||
#elif defined(WS2812_FOUR_SAMPLE)
|
||||
#ifdef INVERT
|
||||
static const uint16_t bitpatterns[16] = {
|
||||
~0b1000100010001000, ~0b1000100010001100, ~0b1000100011001000, ~0b1000100011001100,
|
||||
~0b1000110010001000, ~0b1000110010001100, ~0b1000110011001000, ~0b1000110011001100,
|
||||
~0b1100100010001000, ~0b1100100010001100, ~0b1100100011001000, ~0b1100100011001100,
|
||||
~0b1100110010001000, ~0b1100110010001100, ~0b1100111011001000, ~0b1100110011001100,
|
||||
0b0111011101110111, 0b0111011101110011, 0b0111011100110111, 0b0111011100110011,
|
||||
0b0111001101110111, 0b0111001101110011, 0b0111001100110111, 0b0111001100110011,
|
||||
0b0011011101110111, 0b0011011101110011, 0b0011011100110111, 0b0011011100110011,
|
||||
0b0011001101110111, 0b0011001101110011, 0b0011000100110111, 0b0011001100110011,
|
||||
};
|
||||
#else
|
||||
//Tricky, send out WS2812 bits with coded pulses, one nibble, then the other.
|
||||
|
|
|
@ -87,10 +87,10 @@ int main()
|
|||
|
||||
|
||||
|
||||
uint16_t Sdatspace32A[FIXBINS*2]; //(advances,places)
|
||||
uint16_t Sdatspace32A[FIXBINS*2]; //(advances,places) full revolution is 256. 8bits integer part 8bit fractional
|
||||
int32_t Sdatspace32B[FIXBINS*2]; //(isses,icses)
|
||||
|
||||
//This is updated every time the DFT hits the octavecount, or 1/32 updates.
|
||||
//This is updated every time the DFT hits the octavecount, or 1 out of (1<<OCTAVES) times which is (1<<(OCTAVES-1)) samples
|
||||
int32_t Sdatspace32BOut[FIXBINS*2]; //(isses,icses)
|
||||
|
||||
//Sdo_this_octave is a scheduling state for the running SIN/COS states for
|
||||
|
@ -107,6 +107,9 @@ static uint8_t Swhichoctaveplace;
|
|||
uint16_t embeddedbins[FIXBINS];
|
||||
|
||||
//From: http://stackoverflow.com/questions/1100090/looking-for-an-efficient-integer-square-root-algorithm-for-arm-thumb2
|
||||
// for sqrt approx but also suggestion for quick norm approximation that would work in this DFT
|
||||
|
||||
#if APPROXNORM != 1
|
||||
/**
|
||||
* \brief Fast Square root algorithm, with rounding
|
||||
*
|
||||
|
@ -157,6 +160,7 @@ static uint16_t SquareRootRounded(uint32_t a_nInput)
|
|||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
void UpdateOutputBins32()
|
||||
{
|
||||
|
@ -164,26 +168,38 @@ void UpdateOutputBins32()
|
|||
int32_t * ipt = &Sdatspace32BOut[0];
|
||||
for( i = 0; i < FIXBINS; i++ )
|
||||
{
|
||||
int16_t isps = *(ipt++)>>16;
|
||||
int16_t ispc = *(ipt++)>>16;
|
||||
|
||||
int32_t isps = *(ipt++); //keep 32 bits
|
||||
int32_t ispc = *(ipt++);
|
||||
// take absolute values
|
||||
isps = isps<0? -isps : isps;
|
||||
ispc = ispc<0? -ispc : ispc;
|
||||
int octave = i / FIXBPERO;
|
||||
|
||||
//If we are running DFT32 on regular ColorChord, then we will need to
|
||||
//also update goutbins[]... But if we're on embedded systems, we only
|
||||
//update embeddedbins32.
|
||||
#ifndef CCEMBEDDED
|
||||
uint32_t mux = ( (isps) * (isps)) + ((ispc) * (ispc));
|
||||
goutbins[i] = sqrtf( (float)mux );
|
||||
//reasonable (but arbitrary amplification)
|
||||
// convert 32 bit precision isps and ispc to floating point
|
||||
float mux = ( (float)isps * (float)isps) + ((float)ispc * (float)ispc);
|
||||
goutbins[i] = sqrtf(mux)/65536.0; // scale by 2^16
|
||||
//reasonable (but arbitrary attenuation)
|
||||
goutbins[i] /= (78<<DFTIIR)*(1<<octave);
|
||||
#endif
|
||||
|
||||
uint32_t rmux = ( (isps) * (isps)) + ((ispc) * (ispc));
|
||||
#if APPROXNORM == 1
|
||||
// using full 32 bit precision for isps and ispc
|
||||
uint32_t rmux = isps>ispc? isps + (ispc>>1) : ispc + (isps>>1);
|
||||
rmux = rmux>>16; // keep most significant 16 bits
|
||||
#else
|
||||
// use the most significant 16 bits of isps and ispc when squaring
|
||||
// since isps and ispc are non-negative right bit shifing is well defined
|
||||
uint32_t rmux = ( (isps>>16) * (isps>>16)) + ((ispc>16) * (ispc>>16));
|
||||
rmux = SquareRootRounded( rmux );
|
||||
#endif
|
||||
|
||||
//bump up all outputs here, so when we nerf it by bit shifting by
|
||||
//ctave we don't lose a lot of detail.
|
||||
rmux = SquareRootRounded( rmux ) << 1;
|
||||
//octave we don't lose a lot of detail.
|
||||
rmux = rmux << 1;
|
||||
|
||||
embeddedbins32[i] = rmux >> octave;
|
||||
}
|
||||
|
@ -194,16 +210,24 @@ static void HandleInt( int16_t sample )
|
|||
int i;
|
||||
uint16_t adv;
|
||||
uint8_t localipl;
|
||||
int16_t filteredsample;
|
||||
|
||||
uint8_t oct = Sdo_this_octave[Swhichoctaveplace];
|
||||
Swhichoctaveplace ++;
|
||||
Swhichoctaveplace &= BINCYCLE-1;
|
||||
|
||||
for( i = 0; i < OCTAVES;i++ )
|
||||
{
|
||||
Saccum_octavebins[i] += sample;
|
||||
}
|
||||
|
||||
if( oct > 128 )
|
||||
{
|
||||
//Special: This is when we can update everything.
|
||||
//This gets run one out of every 1/(1<<OCTAVES) times.
|
||||
//This gets run once out of every (1<<OCTAVES) times.
|
||||
// which is half as many samples
|
||||
//It handles updating part of the DFT.
|
||||
//It should happen at the very first call to HandleInit
|
||||
int32_t * bins = &Sdatspace32B[0];
|
||||
int32_t * binsOut = &Sdatspace32BOut[0];
|
||||
|
||||
|
@ -221,16 +245,11 @@ static void HandleInt( int16_t sample )
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
for( i = 0; i < OCTAVES;i++ )
|
||||
{
|
||||
Saccum_octavebins[i] += sample;
|
||||
}
|
||||
|
||||
// process a filtered sample for one of the octaves
|
||||
uint16_t * dsA = &Sdatspace32A[oct*FIXBPERO*2];
|
||||
int32_t * dsB = &Sdatspace32B[oct*FIXBPERO*2];
|
||||
|
||||
sample = Saccum_octavebins[oct]>>(OCTAVES-oct);
|
||||
filteredsample = Saccum_octavebins[oct]>>(OCTAVES-oct);
|
||||
Saccum_octavebins[oct] = 0;
|
||||
|
||||
for( i = 0; i < FIXBPERO; i++ )
|
||||
|
@ -239,10 +258,10 @@ static void HandleInt( int16_t sample )
|
|||
localipl = *(dsA) >> 8;
|
||||
*(dsA++) += adv;
|
||||
|
||||
*(dsB++) += (Ssinonlytable[localipl] * sample);
|
||||
*(dsB++) += (Ssinonlytable[localipl] * filteredsample);
|
||||
//Get the cosine (1/4 wavelength out-of-phase with sin)
|
||||
localipl += 64;
|
||||
*(dsB++) += (Ssinonlytable[localipl] * sample);
|
||||
*(dsB++) += (Ssinonlytable[localipl] * filteredsample);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,11 +271,12 @@ int SetupDFTProgressive32()
|
|||
int j;
|
||||
|
||||
Sdonefirstrun = 1;
|
||||
|
||||
for( i = 0; i < BINCYCLE; i++ )
|
||||
Sdo_this_octave[0] = 0xff;
|
||||
for( i = 0; i < BINCYCLE-1; i++ )
|
||||
{
|
||||
// Sdo_this_octave =
|
||||
// 4 3 4 2 4 3 4 ...
|
||||
// 255 4 3 4 2 4 3 4 1 4 3 4 2 4 3 4 0 4 3 4 2 4 3 4 1 4 3 4 2 4 3 4 is case for 5 octaves.
|
||||
// Initial state is special one, then at step i do octave = Sdo_this_octave with averaged samples from last update of that octave
|
||||
//search for "first" zero
|
||||
|
||||
for( j = 0; j <= OCTAVES; j++ )
|
||||
|
@ -271,7 +291,7 @@ int SetupDFTProgressive32()
|
|||
#endif
|
||||
return -1;
|
||||
}
|
||||
Sdo_this_octave[i] = OCTAVES-j-1;
|
||||
Sdo_this_octave[i+1] = OCTAVES-j-1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -280,10 +300,12 @@ int SetupDFTProgressive32()
|
|||
|
||||
void UpdateBins32( const uint16_t * frequencies )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < FIXBINS; i++ )
|
||||
int i;
|
||||
int imod = 0;
|
||||
for( i = 0; i < FIXBINS; i++, imod++ )
|
||||
{
|
||||
uint16_t freq = frequencies[i%FIXBPERO];
|
||||
if (imod >= FIXBPERO) imod=0;
|
||||
uint16_t freq = frequencies[imod];
|
||||
Sdatspace32A[i*2] = freq;// / oneoveroctave;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,13 @@
|
|||
//made here should be backported there as well.
|
||||
|
||||
//You can # define these to be other things elsewhere.
|
||||
|
||||
// Will used simple approximation of norm rather than
|
||||
// sum squares and approx sqrt
|
||||
#ifndef APPROXNORM
|
||||
#define APPROXNORM 1
|
||||
#endif
|
||||
|
||||
#ifndef OCTAVES
|
||||
#define OCTAVES 5
|
||||
#endif
|
||||
|
|
|
@ -61,17 +61,17 @@ void UpdateLinearLEDs()
|
|||
{
|
||||
if( note_peak_freqs[ sorted_note_map[j] ] > nff )
|
||||
{
|
||||
break;
|
||||
break; // so j is correct place to insert
|
||||
}
|
||||
}
|
||||
for( k = sorted_map_count; k > j; k-- )
|
||||
for( k = sorted_map_count; k > j; k-- ) // make room
|
||||
{
|
||||
sorted_note_map[k] = sorted_note_map[k-1];
|
||||
}
|
||||
sorted_note_map[j] = i;
|
||||
sorted_note_map[j] = i; // insert in correct place
|
||||
#else
|
||||
sorted_note_map[sorted_map_count] = i; // insert at end
|
||||
#endif
|
||||
sorted_note_map[sorted_map_count] = i;
|
||||
sorted_map_count++;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue