made progress... getting very close to an embedded colorchord

This commit is contained in:
cnlohr 2015-04-04 02:23:53 -04:00
parent 5e9023c6a0
commit 36a3777522
7 changed files with 152 additions and 50 deletions

View file

@ -32,7 +32,7 @@
//must decrease. Increasing this value makes responses slower. Lower values are //must decrease. Increasing this value makes responses slower. Lower values are
//more responsive. //more responsive.
#ifndef DFTIIR #ifndef DFTIIR
#define DFTIIR 4 #define DFTIIR 6
#endif #endif
//Everything the integer one buys, except it only calculates 2 octaves worth of notes per audio frame. //Everything the integer one buys, except it only calculates 2 octaves worth of notes per audio frame.

View file

@ -101,6 +101,11 @@ void Init()
void HandleFrameInfo() void HandleFrameInfo()
{ {
int i, j, k; int i, j, k;
uint8_t hitnotes[MAXNOTES];
for( i = 0; i < MAXNOTES; i++ )
{
hitnotes[i] = 0;
}
#ifdef USE_32DFT #ifdef USE_32DFT
uint16_t * strens; uint16_t * strens;
@ -275,10 +280,11 @@ void HandleFrameInfo()
if( marked_note != -1 ) if( marked_note != -1 )
{ {
if( note_peak_amps[marked_note] <= this ) hitnotes[marked_note] = 1;
note_peak_amps[marked_note] = this; // if( note_peak_amps[marked_note] <= this )
if( note_peak_amps2[marked_note] <= this ) note_peak_amps[marked_note] = note_peak_amps[marked_note] - (note_peak_amps[marked_note]>>AMP_1_NERFING_BITS) + (this>>AMP_1_NERFING_BITS);
note_peak_amps2[marked_note] = this; // if( note_peak_amps2[marked_note] <= this )
note_peak_amps2[marked_note] = note_peak_amps2[marked_note] - (note_peak_amps2[marked_note]>>AMP_2_NERFING_BITS) + (this>>AMP_2_NERFING_BITS);
} }
} }
} }
@ -327,7 +333,7 @@ void HandleFrameInfo()
for( i = 0; i < MAXNOTES; i++ ) for( i = 0; i < MAXNOTES; i++ )
{ {
if( note_peak_freqs[i] == 255 ) continue; if( note_peak_freqs[i] == 255 || hitnotes[i] ) continue;
note_peak_amps[i] -= note_peak_amps[i]>>AMP_1_NERFING_BITS; note_peak_amps[i] -= note_peak_amps[i]>>AMP_1_NERFING_BITS;
note_peak_amps2[i] -= note_peak_amps2[i]>>AMP_2_NERFING_BITS; note_peak_amps2[i] -= note_peak_amps2[i]>>AMP_2_NERFING_BITS;

View file

@ -17,7 +17,7 @@
//Notes are the individually identifiable notes we receive from the sound. //Notes are the individually identifiable notes we receive from the sound.
//We track up to this many at one time. Just because a note may appear to //We track up to this many at one time. Just because a note may appear to
//vaporize in one frame doesn't mean it is annihilated immediately. //vaporize in one frame doesn't mean it is annihilated immediately.
#define MAXNOTES 10 #define MAXNOTES 12
//Determines bit shifts for where notes lie. We represent notes with an uint8_t //Determines bit shifts for where notes lie. We represent notes with an uint8_t
//We have to define all of the possible locations on the note line in this. //We have to define all of the possible locations on the note line in this.
@ -25,19 +25,22 @@
#define SEMIBITSPERBIN 3 #define SEMIBITSPERBIN 3
#define NOTERANGE ((1<<SEMIBITSPERBIN)*FIXBPERO) #define NOTERANGE ((1<<SEMIBITSPERBIN)*FIXBPERO)
//This is the amplitude, coming from folded_bins. If the value is below this
//it is considered a non-note.
#define MIN_AMP_FOR_NOTE 64
//If there is detected note this far away from an established note, we will //If there is detected note this far away from an established note, we will
//then consider this new note the same one as last time, and move the established //then consider this new note the same one as last time, and move the established
//note. This is also used when combining notes. It is this distance times two. //note. This is also used when combining notes. It is this distance times two.
#define MAX_JUMP_DISTANCE 7 #define MAX_JUMP_DISTANCE 5
#define MINIMUM_AMP_FOR_NOTE_TO_DISAPPEAR 32
#define AMP_1_NERFING_BITS 5 #define AMP_1_NERFING_BITS 5
#define AMP_2_NERFING_BITS 3 #define AMP_2_NERFING_BITS 3
//This is the amplitude, coming from folded_bins. If the value is below this
//it is considered a non-note.
#define MIN_AMP_FOR_NOTE 64
#define MINIMUM_AMP_FOR_NOTE_TO_DISAPPEAR (1<<(AMP_1_NERFING_BITS))
#ifdef USE_32DFT #ifdef USE_32DFT
#include "DFT32.h" #include "DFT32.h"

View file

@ -3,7 +3,7 @@
//uint8_t ledArray[NUM_LIN_LEDS]; //Points to which notes correspond to these LEDs //uint8_t ledArray[NUM_LIN_LEDS]; //Points to which notes correspond to these LEDs
uint8_t ledOut[NUM_LIN_LEDS*3]; uint8_t ledOut[NUM_LIN_LEDS*3];
void UpdateLinear() void UpdateLinearLEDs()
{ {
//Source material: //Source material:
/* /*
@ -19,46 +19,85 @@ void UpdateLinear()
uint8_t i; uint8_t i;
uint16_t j; uint16_t j;
uint32_t total_size_all_notes = 0; uint32_t total_size_all_notes = 0;
uint16_t porpamps[MAXNOTES]; //LEDs for each corresponding note. int32_t porpamps[MAXNOTES]; //LEDs for each corresponding note.
uint8_t sorted_note_map[MAXNOTES]; //mapping from which note into the array of notes from the rest of the system.
uint16_t local_peak_amps[MAXNOTES];
uint16_t local_peak_amps2[MAXNOTES];
uint8_t local_note_freq[MAXNOTES];
uint8_t sorted_map_count = 0;
for( i = 0; i < MAXNOTES; i++ ) for( i = 0; i < MAXNOTES; i++ )
{ {
porpamps[i] = 0; uint16_t ist = note_peak_amps[i];
if( note_peak_freqs[i] == 255 ) continue; if( note_peak_freqs[i] == 255 || ist <= NERF_NOTE_SIZE_VALUE )
total_size_all_notes += note_peak_amps[i]; {
local_peak_amps[i] = 0;
continue;
}
for( j = 0; j < sorted_map_count; j++ )
{
//TODO SORT ME
}
sorted_map_count++;
} }
uint32_t porportional = (total_size_for_all_notes << 8) / NUM_LIN_LEDS; for( i = 0; i < MAXNOTES; i++ )
{
uint16_t ist = note_peak_amps[i];
porpamps[i] = 0;
if( note_peak_freqs[i] == 255 || ist <= NERF_NOTE_SIZE_VALUE )
{
local_peak_amps[i] = 0;
continue;
}
local_peak_amps[i] = ist - NERF_NOTE_SIZE_VALUE;
total_size_all_notes += local_peak_amps[i];
}
if( total_size_all_notes == 0 )
{
for( j = 0; j < NUM_LIN_LEDS * 3; j++ )
{
ledOut[j] = 0;
}
return;
}
uint32_t porportional = (uint32_t)(NUM_LIN_LEDS<<8)/((uint32_t)total_size_all_notes);
uint16_t total_accounted_leds = 0; uint16_t total_accounted_leds = 0;
for( i = 0; i < MAXNOTES; i++ ) for( i = 0; i < MAXNOTES; i++ )
{ {
if( note_peak_freqs[i] == 255 ) continue; if( note_peak_freqs[i] == 255 ) continue;
porpamps[i] = (note_peak_amps[i] * porportional) >> 8; porpamps[i] = (local_peak_amps[i] * porportional) >> 8;
total_accounted_leds += porpamps[i]; total_accounted_leds += porpamps[i];
} }
uint16_t total_unaccounted_leds = NUM_LIN_LEDS - total_accounted_leds; int16_t total_unaccounted_leds = NUM_LIN_LEDS - total_accounted_leds;
for( i = 0; i < MAXNOTES, total_unaccounted_leds; i++ ) for( i = 0; i < MAXNOTES && total_unaccounted_leds; i++ )
{ {
if( note_peak_freqs[i] == 255 ) continue; if( note_peak_freqs[i] == 255 ) continue;
porpamps[i]++; porpamps[i]++; total_unaccounted_leds--;
} }
//Now, we use porpamps to march through the LEDs, coloring them. //Now, we use porpamps to march through the LEDs, coloring them.
j = 0; j = 0;
for( i = 0; i < MAXNOTES; i++ ) for( i = 0; i < MAXNOTES; i++ )
{ {
while( porpamps[i] ) while( porpamps[i] > 0 )
{ {
uint16_t amp = note_peak_amps2[i]; uint16_t amp = ((uint32_t)note_peak_amps2[i] * NOTE_FINAL_AMP) >> 8;
if( amp > 255 ) amp = 255; if( amp > 255 ) amp = 255;
uint32_t color = ECCtoHEX( note_peak_freqs[i], 255, amp ); uint32_t color = ECCtoHEX( note_peak_freqs[i], 255, amp );
ledOut[i*3+0] = ( color >> 0 ) & 0xff; ledOut[j*3+0] = ( color >> 0 ) & 0xff;
ledOut[i*3+1] = ( color >> 8 ) & 0xff; ledOut[j*3+1] = ( color >> 8 ) & 0xff;
ledOut[i*3+2] = ( color >>16 ) & 0xff; ledOut[j*3+2] = ( color >>16 ) & 0xff;
j++; j++;
porpamps[i]--; porpamps[i]--;
} }
@ -69,43 +108,46 @@ void UpdateLinear()
uint32_t ECCtoHEX( uint8_t note, uint8_t sat, uint8_t val ) uint32_t ECCtoHEX( uint8_t note, uint8_t sat, uint8_t val )
{ {
uint16_t hue = 0; uint16_t hue = 0;
uint8_t third = 65535/3; uint16_t third = 65535/3;
uint16_t scalednote = note uint16_t scalednote = note;
uint16_t renote = ((uint32_t)note * 65535) / NOTERANGE; uint32_t renote = ((uint32_t)note * 65536) / NOTERANGE;
//Note is expected to be a vale from 0..(NOTERANGE-1) //Note is expected to be a vale from 0..(NOTERANGE-1)
//renote goes from 0 to the next one under 65536. //renote goes from 0 to the next one under 65536.
if( renote < third ) if( renote < third )
{ {
//Yellow to Red. //Yellow to Red.
hue = (third - renote) >> 1; hue = (third - renote) >> 1;
} }
else if( note < (third>>1) ) else if( renote < (third<<1) )
{ {
//Red to Blue //Red to Blue
hue = (third-renote); hue = (third-renote);
} }
else else
{ {
hue = (((65535-renote) * third) >> 1) + (third>>1); //hue = ((((65535-renote)>>8) * (uint32_t)(third>>8)) >> 1) + (third<<1);
hue = (uint16_t)(((uint32_t)(65536-renote)<<16) / (third<<1)) + (third>>1); // ((((65535-renote)>>8) * (uint32_t)(third>>8)) >> 1) + (third<<1);
} }
hue >>= 8; hue >>= 8;
// printf( "%d;", hue );
return EHSVtoHEX( hue, sat, val ); return EHSVtoHEX( hue, sat, val );
} }
uint32_t EHSVtoHEX( uint8_t hue, uint8_t sat, uint8_t val ) uint32_t EHSVtoHEX( uint8_t hue, uint8_t sat, uint8_t val )
{ {
#define SIXTH1 43 #define SIXTH1 43
#define SIXTH2 85 #define SIXTH2 85
#define SIXTH3 128 #define SIXTH3 128
#define SIXTH4 171 #define SIXTH4 171
#define SIXTH5 213 #define SIXTH5 213
uint16_t or = 0, og = 0, ob = 0; uint16_t or = 0, og = 0, ob = 0;
hue += SIXTH2; //Off by 60 degrees. hue -= SIXTH1; //Off by 60 degrees.
//TODO: There are colors that overlap here, consider //TODO: There are colors that overlap here, consider
//tweaking this to make the best use of the colorspace. //tweaking this to make the best use of the colorspace.
@ -155,15 +197,17 @@ uint32_t EHSVtoHEX( uint8_t hue, uint8_t sat, uint8_t val )
//OR..OB == 0..65025 //OR..OB == 0..65025
or = or * rs + 255 * (256-rs); or = or * rs + 255 * (256-rs);
or = or * rs + 255 * (256-rs); og = og * rs + 255 * (256-rs);
or = or * rs + 255 * (256-rs); ob = ob * rs + 255 * (256-rs);
//printf( "__%d %d %d =-> %d\n", or, og, ob, rs );
or >>= 8; or >>= 8;
og >>= 8; og >>= 8;
ob >>= 8; ob >>= 8;
return or | (og<<8) | (ob<<16);
}
return or | (og<<8) | ((uint32_t)ob<<16);
}
/*
uint32_t HSVtoHEX( float hue, float sat, float value ) uint32_t HSVtoHEX( float hue, float sat, float value )
{ {
@ -233,4 +277,4 @@ uint32_t HSVtoHEX( float hue, float sat, float value )
return (ob<<16) | (og<<8) | ora; return (ob<<16) | (og<<8) | ora;
} }
*/

View file

@ -3,13 +3,20 @@
#include "embeddednf.h" #include "embeddednf.h"
//Controls brightness
#define NOTE_FINAL_AMP 255 //Number from 0...255
//Controls, basically, the minimum size of the splotches.
#define NERF_NOTE_SIZE_VALUE 10
#define NUM_LIN_LEDS 296 #define NUM_LIN_LEDS 296
#define LIN_WRAPAROUND 0 //Whether the output lights wrap around. (TODO) #define LIN_WRAPAROUND 0 //Whether the output lights wrap around. (TODO)
extern uint8_t ledArray[]; extern uint8_t ledArray[];
extern uint8_t ledOut[]; //[NUM_LIN_LEDS*3] extern uint8_t ledOut[]; //[NUM_LIN_LEDS*3]
void UpdateLinear(); void UpdateLinearLEDs();
uint32_t ECCtoHEX( uint8_t note, uint8_t sat, uint8_t val ); uint32_t ECCtoHEX( uint8_t note, uint8_t sat, uint8_t val );
uint32_t EHSVtoHEX( uint8_t hue, uint8_t sat, uint8_t val ); //hue = 0..255 // TODO: TEST ME!!! uint32_t EHSVtoHEX( uint8_t hue, uint8_t sat, uint8_t val ); //hue = 0..255 // TODO: TEST ME!!!

View file

@ -3,11 +3,11 @@ all : embeddedcc
CFLAGS:=-Ofast -DCCEMBEDDED -I.. -flto -m32 -DDFREQ=11025 CFLAGS:=-Ofast -DCCEMBEDDED -I.. -flto -m32 -DDFREQ=11025
LDFLAGS:=-ffunction-sections -Wl,--gc-sections -fno-asynchronous-unwind-tables -Wl,--strip-all LDFLAGS:=-ffunction-sections -Wl,--gc-sections -fno-asynchronous-unwind-tables -Wl,--strip-all
embeddedcc : ../embeddednf.c ../DFT32.c embeddedcc.c embeddedcc : ../embeddednf.c ../DFT32.c embeddedcc.c ../embeddedout.c
gcc -o $@ $^ $(CFLAGS) $(LDFLAGS) gcc -o $@ $^ $(CFLAGS) $(LDFLAGS)
runembedded : embeddedcc runembedded : embeddedcc
parec --format=u8 --rate=11025 --channels=1 --device=alsa_output.pci-0000_00_1b.0.analog-stereo.monitor | ./embeddedcc parec --format=u8 --rate=11025 --channels=1 --device=alsa_output.pci-0000_00_1b.0.analog-stereo.monitor --latency=128 | ./embeddedcc
clean : clean :
rm -rf embeddedcc *~ rm -rf embeddedcc *~

View file

@ -3,14 +3,57 @@
// It is intended as a minimal scaffolding for testing Embedded ColorChord. // It is intended as a minimal scaffolding for testing Embedded ColorChord.
// //
#include <stdio.h>
#include "embeddednf.h" #include "embeddednf.h"
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <stdio.h>
#include "embeddedout.h"
struct sockaddr_in servaddr;
int sock;
#define expected_lights 296
void NewFrame()
{
int i;
char buffer[3000];
HandleFrameInfo();
UpdateLinearLEDs();
buffer[0] = 0;
buffer[1] = 0;
buffer[2] = 0;
for( i = 0; i < expected_lights * 3; i++ )
{
buffer[i+3] = ledOut[i];
}
int r = send(sock,buffer,expected_lights*3+3,0);
}
int main() int main()
{ {
int wf = 0; int wf = 0;
int ci; int ci;
sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
printf( "%d\n", sock );
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("192.168.0.245");
servaddr.sin_port=htons(7777);
connect( sock, (struct sockaddr *)&servaddr, sizeof(servaddr) );
Init(); Init();
while( ( ci = getchar() ) != EOF ) while( ( ci = getchar() ) != EOF )
{ {
int cs = ci - 0x80; int cs = ci - 0x80;
@ -19,11 +62,10 @@ int main()
#else #else
Push8BitIntegerSkippy( (int8_t)cs ); Push8BitIntegerSkippy( (int8_t)cs );
#endif #endif
//printf( "%d ", cs ); fflush( stdout );
wf++; wf++;
if( wf == 64 ) if( wf == 64 )
{ {
HandleFrameInfo(); NewFrame();
wf = 0; wf = 0;
} }
} }