Add embedded-oriented integer version of DFT.
This commit is contained in:
parent
7148254c41
commit
2e26b747fd
7
Makefile
7
Makefile
|
@ -5,7 +5,8 @@ SOUND:=sound.o sound_alsa.o sound_pulse.o sound_null.o
|
||||||
OUTS := OutputVoronoi.o DisplayArray.o OutputLinear.o DisplayPie.o DisplayNetwork.o DisplayUSB2812.o DisplayDMX.o
|
OUTS := OutputVoronoi.o DisplayArray.o OutputLinear.o DisplayPie.o DisplayNetwork.o DisplayUSB2812.o DisplayDMX.o
|
||||||
|
|
||||||
WINGCC:=i586-mingw32msvc-gcc
|
WINGCC:=i586-mingw32msvc-gcc
|
||||||
WINGCCFLAGS:= -lwinmm -lgdi32 -lws2_32 -O2 -ffast-math -g
|
WINGCCFLAGS:= -O2 -ffast-math -Wl,--relax -Wl,--gc-sections -ffunction-sections -fdata-sections -s
|
||||||
|
WINLDFLAGS:=-lwinmm -lgdi32 -lws2_32
|
||||||
|
|
||||||
RAWDRAWLIBS:=-lX11 -lm -lpthread -lXinerama -lXext
|
RAWDRAWLIBS:=-lX11 -lm -lpthread -lXinerama -lXext
|
||||||
LDLIBS:=-lpthread -lasound -lm -lpulse-simple -lpulse
|
LDLIBS:=-lpthread -lasound -lm -lpulse-simple -lpulse
|
||||||
|
@ -16,8 +17,8 @@ colorchord : os_generic.o main.o dft.o decompose.o filter.o color.o sort.o note
|
||||||
gcc -o $@ $^ $(CFLAGS) $(LDLIBS) $(EXTRALIBS) $(RAWDRAWLIBS)
|
gcc -o $@ $^ $(CFLAGS) $(LDLIBS) $(EXTRALIBS) $(RAWDRAWLIBS)
|
||||||
|
|
||||||
colorchord.exe : os_generic.c main.c dft.c decompose.c filter.c color.c sort.c notefinder.c util.c outdrivers.c DrawFunctions.c parameters.c chash.c WinDriver.c sound.c sound_null.c sound_win.c OutputVoronoi.c DisplayArray.c OutputLinear.c DisplayPie.c DisplayNetwork.c
|
colorchord.exe : os_generic.c main.c dft.c decompose.c filter.c color.c sort.c notefinder.c util.c outdrivers.c DrawFunctions.c parameters.c chash.c WinDriver.c sound.c sound_null.c sound_win.c OutputVoronoi.c DisplayArray.c OutputLinear.c DisplayPie.c DisplayNetwork.c
|
||||||
$(WINGCC) -o $@ $^ $(WINGCCFLAGS)
|
$(WINGCC) $(WINGCCFLAGS) -o $@ $^ $(WINLDFLAGS)
|
||||||
|
|
||||||
|
|
||||||
clean :
|
clean :
|
||||||
rm -rf *.o *~ colorchord
|
rm -rf *.o *~ colorchord colorchord.exe
|
||||||
|
|
10
WinDriver.c
10
WinDriver.c
|
@ -5,6 +5,7 @@
|
||||||
#include "DrawFunctions.h"
|
#include "DrawFunctions.h"
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <malloc.h> //for alloca
|
#include <malloc.h> //for alloca
|
||||||
|
|
||||||
static HINSTANCE lhInstance;
|
static HINSTANCE lhInstance;
|
||||||
|
@ -193,6 +194,8 @@ void CNFGSetup( const char * name_of_window, int width, int height )
|
||||||
InternalHandleResize();
|
InternalHandleResize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowsTerm();
|
||||||
|
|
||||||
void CNFGHandleInput()
|
void CNFGHandleInput()
|
||||||
{
|
{
|
||||||
int ldown = 0;
|
int ldown = 0;
|
||||||
|
@ -204,6 +207,13 @@ void CNFGHandleInput()
|
||||||
|
|
||||||
switch( msg.message )
|
switch( msg.message )
|
||||||
{
|
{
|
||||||
|
case WM_QUIT:
|
||||||
|
case WM_DESTROY:
|
||||||
|
case WM_CLOSE:
|
||||||
|
printf( "Close\n" );
|
||||||
|
WindowsTerm();
|
||||||
|
TerminateProcess( 0, 0 );
|
||||||
|
break;
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
HandleMotion( (msg.lParam & 0xFFFF), (msg.lParam>>16) & 0xFFFF, ( (msg.wParam & 0x01)?1:0) | ((msg.wParam & 0x02)?2:0) | ((msg.wParam & 0x10)?4:0) );
|
HandleMotion( (msg.lParam & 0xFFFF), (msg.lParam>>16) & 0xFFFF, ( (msg.wParam & 0x01)?1:0) | ((msg.wParam & 0x02)?2:0) | ((msg.wParam & 0x10)?4:0) );
|
||||||
break;
|
break;
|
||||||
|
|
BIN
colorchord.exe
BIN
colorchord.exe
Binary file not shown.
255
dft.c
255
dft.c
|
@ -1,7 +1,10 @@
|
||||||
|
|
||||||
#include "dft.h"
|
#include "dft.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
void DoDFT( float * outbins, float * frequencies, int bins, float * databuffer, int place_in_data_buffer, int size_of_data_buffer, float q )
|
void DoDFT( float * outbins, float * frequencies, int bins, float * databuffer, int place_in_data_buffer, int size_of_data_buffer, float q )
|
||||||
{
|
{
|
||||||
|
@ -41,6 +44,8 @@ void DoDFTQuick( float * outbins, float * frequencies, int bins, const float * d
|
||||||
|
|
||||||
for( i = 0; i < bins; i++ )
|
for( i = 0; i < bins; i++ )
|
||||||
{
|
{
|
||||||
|
int flirts = 0;
|
||||||
|
|
||||||
float freq = frequencies[i];
|
float freq = frequencies[i];
|
||||||
float phi = 0;
|
float phi = 0;
|
||||||
int ftq = freq * q;
|
int ftq = freq * q;
|
||||||
|
@ -66,6 +71,7 @@ void DoDFTQuick( float * outbins, float * frequencies, int bins, const float * d
|
||||||
binqtyc += cv;
|
binqtyc += cv;
|
||||||
|
|
||||||
phi += advance;
|
phi += advance;
|
||||||
|
flirts++;
|
||||||
}
|
}
|
||||||
|
|
||||||
float amp = sqrtf( binqtys * binqtys + binqtyc * binqtyc );
|
float amp = sqrtf( binqtys * binqtys + binqtyc * binqtyc );
|
||||||
|
@ -73,3 +79,250 @@ void DoDFTQuick( float * outbins, float * frequencies, int bins, const float * d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////DFT Progressive is for embedded systems, primarily.
|
||||||
|
|
||||||
|
|
||||||
|
static float * gbinqtys;
|
||||||
|
static float * gbinqtyc;
|
||||||
|
static float * phis;
|
||||||
|
static float * gfrequencies;
|
||||||
|
static float * goutbins;
|
||||||
|
static float * lastbins;
|
||||||
|
static float * advances;
|
||||||
|
|
||||||
|
static int gbins;
|
||||||
|
static float gq;
|
||||||
|
static float gspeedup;
|
||||||
|
|
||||||
|
#define PROGIIR .005
|
||||||
|
|
||||||
|
void HandleProgressive( float sample )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for( i = 0; i < gbins; i++ )
|
||||||
|
{
|
||||||
|
float thiss = sinf( phis[i] ) * sample;
|
||||||
|
float thisc = cosf( phis[i] ) * sample;
|
||||||
|
|
||||||
|
float s = gbinqtys[i] = gbinqtys[i] * (1.-PROGIIR) + thiss * PROGIIR;
|
||||||
|
float c = gbinqtyc[i] = gbinqtyc[i] * (1.-PROGIIR) + thisc * PROGIIR;
|
||||||
|
|
||||||
|
phis[i] += advances[i];
|
||||||
|
if( phis[i] > 6.283 ) phis[i]-=6.283;
|
||||||
|
|
||||||
|
goutbins[i] = sqrtf( s * s + c * c );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DoDFTProgressive( float * outbins, float * frequencies, int bins, const float * databuffer, int place_in_data_buffer, int size_of_data_buffer, float q, float speedup )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
static int last_place;
|
||||||
|
|
||||||
|
if( gbins != bins )
|
||||||
|
{
|
||||||
|
if( gbinqtys ) free( gbinqtys );
|
||||||
|
if( gbinqtyc ) free( gbinqtyc );
|
||||||
|
if( phis ) free( phis );
|
||||||
|
if( lastbins ) free( lastbins );
|
||||||
|
if( advances ) free( advances );
|
||||||
|
|
||||||
|
gbinqtys = malloc( sizeof(float)*bins );
|
||||||
|
gbinqtyc = malloc( sizeof(float)*bins );
|
||||||
|
phis = malloc( sizeof(float)*bins );
|
||||||
|
lastbins = malloc( sizeof(float)*bins );
|
||||||
|
advances = malloc( sizeof(float)*bins );
|
||||||
|
|
||||||
|
memset( gbinqtys, 0, sizeof(float)*bins );
|
||||||
|
memset( gbinqtyc, 0, sizeof(float)*bins );
|
||||||
|
memset( phis, 0, sizeof(float)*bins );
|
||||||
|
memset( lastbins, 0, sizeof(float)*bins );
|
||||||
|
|
||||||
|
}
|
||||||
|
memcpy( outbins, lastbins, sizeof(float)*bins );
|
||||||
|
|
||||||
|
for( i = 0; i < bins; i++ )
|
||||||
|
{
|
||||||
|
float freq = frequencies[i];
|
||||||
|
advances[i] = 3.14159*2.0/freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
gbins = bins;
|
||||||
|
gfrequencies = frequencies;
|
||||||
|
goutbins = outbins;
|
||||||
|
gspeedup = speedup;
|
||||||
|
gq = q;
|
||||||
|
|
||||||
|
place_in_data_buffer = (place_in_data_buffer+1)%size_of_data_buffer;
|
||||||
|
|
||||||
|
int didrun = 0;
|
||||||
|
for( i = last_place; i != place_in_data_buffer; i = (i+1)%size_of_data_buffer )
|
||||||
|
{
|
||||||
|
float fin = ((float)((int)(databuffer[i] * 127))) / 127.0; //simulate 8-bit input (it looks FINE!)
|
||||||
|
HandleProgressive( fin );
|
||||||
|
didrun = 1;
|
||||||
|
}
|
||||||
|
last_place = place_in_data_buffer;
|
||||||
|
|
||||||
|
if( didrun )
|
||||||
|
{
|
||||||
|
memcpy( lastbins, outbins, sizeof(float)*bins );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for( i = 0; i < bins; i++ )
|
||||||
|
{
|
||||||
|
printf( "%0.2f ", outbins[i]*100 );
|
||||||
|
}
|
||||||
|
printf( "\n" );*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////INTEGER DFT
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define PROGIIR .005
|
||||||
|
|
||||||
|
//NOTES to self:
|
||||||
|
//
|
||||||
|
// Let's say we want to try this on an AVR.
|
||||||
|
// 24 bins, 5 octaves = 120 bins.
|
||||||
|
// 20 MHz clock / 4.8k sps = 4096 IPS = 34 clocks per bin = :(
|
||||||
|
// We can do two at the same time, this frees us up some
|
||||||
|
|
||||||
|
static uint8_t donefirstrun;
|
||||||
|
static int8_t sintable[512]; //Actually [sin][cos] pairs.
|
||||||
|
|
||||||
|
|
||||||
|
//LDD instruction on AVR can read with constant offset. We can set Y to be the place in the buffer, and read with offset.
|
||||||
|
static uint16_t * datspace; //(advances,places,isses,icses)
|
||||||
|
|
||||||
|
//
|
||||||
|
void HandleProgressiveInt( int8_t sample1, int8_t sample2 )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint16_t startpl = 0;
|
||||||
|
int16_t ts, tc;
|
||||||
|
int16_t tmp1;
|
||||||
|
int8_t s1, c1;
|
||||||
|
uint16_t ipl, localipl, adv;
|
||||||
|
|
||||||
|
|
||||||
|
//startpl maps to 'Y'
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
//Estimated 68 minimum instructions... So for two pairs each... just under 5ksps, theoretical.
|
||||||
|
//Running overall at ~2kHz.
|
||||||
|
for( i = 0; i < gbins; i++ ) //Loop, fixed size = 3 + 2 cycles 5
|
||||||
|
{
|
||||||
|
//12 cycles MIN
|
||||||
|
adv = datspace[startpl++]; //Read, indirect from RAM (and increment) 2+2 cycles 4
|
||||||
|
ipl = datspace[startpl++]; //Read, indirect from RAM (and increment) 2+2 cycles 4
|
||||||
|
|
||||||
|
//13 cycles MIN
|
||||||
|
ipl += adv; //Advance, 16bit += 16bit, 1 + 1 cycles 2
|
||||||
|
localipl = (ipl>>8)<<1; //Select upper 8 bits 1 cycles 1
|
||||||
|
|
||||||
|
// need to load Z with 'sintable' and add localipl 2
|
||||||
|
s1 = sintable[localipl++]; //Read s1 component out of table. 2+2 cycles 2
|
||||||
|
c1 = sintable[localipl++]; //Read c1 component out of table. 2 cycles 2
|
||||||
|
|
||||||
|
ts = (s1 * sample1); // 8 x 8 multiply signed + copy R1 out. zero MSB ts 2
|
||||||
|
tc = (c1 * sample1); // 8 x 8 multiply signed + copy R1 out. zero MSB tc 2
|
||||||
|
|
||||||
|
|
||||||
|
//15 cycles MIN
|
||||||
|
ipl += adv; //Advance, 16bit += 16bit, 1 + 1 cycles 2
|
||||||
|
localipl = (ipl>>8)<<1; //Select upper 8 bits 1 cycles 1
|
||||||
|
|
||||||
|
// need to load Z with 'sintable' and add localipl 2
|
||||||
|
s1 = sintable[localipl++]; //Read s1 component out of table. 2 cycles 2
|
||||||
|
c1 = sintable[localipl++]; //Read c1 component out of table. 2 cycles 2
|
||||||
|
|
||||||
|
ts += (s1 * sample2); // 8 x 8 multiply signed + add R1 out. 3
|
||||||
|
tc += (c1 * sample2); // 8 x 8 multiply signed + add R1 out. 3
|
||||||
|
|
||||||
|
|
||||||
|
//Add TS and TC to the datspace stuff. (24 instructions)
|
||||||
|
tmp1 = datspace[startpl]; //Read out, sin component. 4
|
||||||
|
tmp1 -= tmp1>>6; //Subtract from the MSB (with carry) 2
|
||||||
|
tmp1 += ts>>6; //Add MSBs with carry 2
|
||||||
|
|
||||||
|
datspace[startpl++] = tmp1; //Store values back 4
|
||||||
|
|
||||||
|
tmp1 = datspace[startpl]; //Read out, sin component. 4
|
||||||
|
tmp1 -= tmp1>>6; //Subtract from the MSB (with carry) 2
|
||||||
|
tmp1 += tc>>6; //Add MSBs with carry 2
|
||||||
|
|
||||||
|
datspace[startpl++] = tmp1; //Store values back 4
|
||||||
|
|
||||||
|
datspace[startpl-3] = ipl; //Store values back 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DoDFTProgressiveInteger( float * outbins, float * frequencies, int bins, const float * databuffer, int place_in_data_buffer, int size_of_data_buffer, float q, float speedup )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
static int last_place;
|
||||||
|
|
||||||
|
if( !donefirstrun )
|
||||||
|
{
|
||||||
|
donefirstrun = 1;
|
||||||
|
for( i = 0; i < 256; i++ )
|
||||||
|
{
|
||||||
|
sintable[i*2+0] = (int8_t)((sinf( i / 256.0 * 6.283 ) * 127.0));
|
||||||
|
sintable[i*2+1] = (int8_t)((cosf( i / 256.0 * 6.283 ) * 127.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( gbins != bins )
|
||||||
|
{
|
||||||
|
gbins = bins;
|
||||||
|
if( datspace ) free( datspace );
|
||||||
|
datspace = malloc( bins * 2 * 4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for( i = 0; i < bins; i++ )
|
||||||
|
{
|
||||||
|
float freq = frequencies[i];
|
||||||
|
datspace[i*4] = 65536.0/freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for( i = last_place; i != ( place_in_data_buffer&0xffffe ); i = (i+2)%size_of_data_buffer )
|
||||||
|
{
|
||||||
|
int8_t ifr1 = (int8_t)( ((databuffer[i+0]) ) * 127 );
|
||||||
|
int8_t ifr2 = (int8_t)( ((databuffer[i+1]) ) * 127 );
|
||||||
|
// printf( "%d %d\n", i, place_in_data_buffer&0xffffe );
|
||||||
|
HandleProgressiveInt( ifr1, ifr2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
last_place = place_in_data_buffer&0xfffe;
|
||||||
|
|
||||||
|
//Extract bins.
|
||||||
|
for( i = 0; i < bins; i++ )
|
||||||
|
{
|
||||||
|
int16_t isps = datspace[i*4+2];
|
||||||
|
int16_t ispc = datspace[i*4+3];
|
||||||
|
int16_t mux = ( (isps/256) * (isps/256)) + ((ispc/256) * (ispc/256));
|
||||||
|
// printf( "%d (%d %d)\n", mux, isps, ispc );
|
||||||
|
outbins[i] = sqrt( mux )/100.0;
|
||||||
|
}
|
||||||
|
// printf( "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
7
dft.h
7
dft.h
|
@ -12,5 +12,12 @@ void DoDFT( float * outbins, float * frequencies, int bins, float * databuffer,
|
||||||
//Speedup = target number of data points
|
//Speedup = target number of data points
|
||||||
void DoDFTQuick( float * outbins, float * frequencies, int bins, const float * databuffer, int place_in_data_buffer, int size_of_data_buffer, float q, float speedup );
|
void DoDFTQuick( float * outbins, float * frequencies, int bins, const float * databuffer, int place_in_data_buffer, int size_of_data_buffer, float q, float speedup );
|
||||||
|
|
||||||
|
//An unusual tool to do a "progressive" DFT, using data from previous rounds.
|
||||||
|
void DoDFTProgressive( float * outbins, float * frequencies, int bins, const float * databuffer, int place_in_data_buffer, int size_of_data_buffer, float q, float speedup );
|
||||||
|
|
||||||
|
//A progressive DFT that's done using only low-bit integer math.
|
||||||
|
void DoDFTProgressiveInteger( float * outbins, float * frequencies, int bins, const float * databuffer, int place_in_data_buffer, int size_of_data_buffer, float q, float speedup );
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
5
integerprog.conf
Normal file
5
integerprog.conf
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
do_progressive_dft = 1
|
||||||
|
samplerate = 8000
|
||||||
|
buffer = 128
|
||||||
|
|
||||||
|
|
9
main.c
9
main.c
|
@ -14,8 +14,15 @@
|
||||||
#include "outdrivers.h"
|
#include "outdrivers.h"
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
|
|
||||||
|
struct SoundDriver * sd;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
void WindowsTerm()
|
||||||
|
{
|
||||||
|
CloseSound( sd );
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int lastfps;
|
int lastfps;
|
||||||
|
@ -244,7 +251,7 @@ int main(int argc, char ** argv)
|
||||||
|
|
||||||
|
|
||||||
//Initialize Sound
|
//Initialize Sound
|
||||||
struct SoundDriver * sd = InitSound( sound_source, &SoundCB );
|
sd = InitSound( sound_source, &SoundCB );
|
||||||
|
|
||||||
if( !sd )
|
if( !sd )
|
||||||
{
|
{
|
||||||
|
|
17
notefinder.c
17
notefinder.c
|
@ -25,6 +25,7 @@ struct NoteFinder * CreateNoteFinder( int spsRec )
|
||||||
ret->decompose_iterations = 1000;
|
ret->decompose_iterations = 1000;
|
||||||
ret->dft_speedup = 300;
|
ret->dft_speedup = 300;
|
||||||
ret->dft_q = 16;
|
ret->dft_q = 16;
|
||||||
|
ret->do_progressive_dft = 0;
|
||||||
ret->default_sigma = 1.4;
|
ret->default_sigma = 1.4;
|
||||||
ret->note_jumpability = 2.5;
|
ret->note_jumpability = 2.5;
|
||||||
ret->note_combine_distance = 0.5;
|
ret->note_combine_distance = 0.5;
|
||||||
|
@ -58,6 +59,7 @@ struct NoteFinder * CreateNoteFinder( int spsRec )
|
||||||
RegisterValue( "note_minimum_new_distribution_value", PAFLOAT, &ret->note_minimum_new_distribution_value, sizeof( ret->note_minimum_new_distribution_value ) );
|
RegisterValue( "note_minimum_new_distribution_value", PAFLOAT, &ret->note_minimum_new_distribution_value, sizeof( ret->note_minimum_new_distribution_value ) );
|
||||||
RegisterValue( "note_out_chop", PAFLOAT, &ret->note_out_chop, sizeof( ret->note_out_chop ) );
|
RegisterValue( "note_out_chop", PAFLOAT, &ret->note_out_chop, sizeof( ret->note_out_chop ) );
|
||||||
RegisterValue( "dft_iir", PAFLOAT, &ret->dft_iir, sizeof( ret->dft_iir ) );
|
RegisterValue( "dft_iir", PAFLOAT, &ret->dft_iir, sizeof( ret->dft_iir ) );
|
||||||
|
RegisterValue( "do_progressive_dft", PAINT, &ret->do_progressive_dft, sizeof( ret->do_progressive_dft ) );
|
||||||
|
|
||||||
AddCallback( "freqbins", ChangeNFParameters, ret );
|
AddCallback( "freqbins", ChangeNFParameters, ret );
|
||||||
AddCallback( "octaves", ChangeNFParameters, ret );
|
AddCallback( "octaves", ChangeNFParameters, ret );
|
||||||
|
@ -175,7 +177,20 @@ void RunNoteFinder( struct NoteFinder * nf, const float * audio_stream, int head
|
||||||
//This DFT function does not wavelet or anything.
|
//This DFT function does not wavelet or anything.
|
||||||
nf->StartTime = OGGetAbsoluteTime();
|
nf->StartTime = OGGetAbsoluteTime();
|
||||||
|
|
||||||
DoDFTQuick( dftbins, nf->frequencies, freqs, audio_stream, head, buffersize, nf->dft_q, nf->dft_speedup );
|
switch( nf->do_progressive_dft )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
DoDFTQuick( dftbins, nf->frequencies, freqs, audio_stream, head, buffersize, nf->dft_q, nf->dft_speedup );
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
DoDFTProgressive( dftbins, nf->frequencies, freqs, audio_stream, head, buffersize, nf->dft_q, nf->dft_speedup );
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
DoDFTProgressiveInteger( dftbins, nf->frequencies, freqs, audio_stream, head, buffersize, nf->dft_q, nf->dft_speedup );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf( stderr, "Error: No DFT Seleced\n" );
|
||||||
|
}
|
||||||
nf->DFTTime = OGGetAbsoluteTime();
|
nf->DFTTime = OGGetAbsoluteTime();
|
||||||
|
|
||||||
for( i = 0; i < freqs; i++ )
|
for( i = 0; i < freqs; i++ )
|
||||||
|
|
|
@ -16,6 +16,7 @@ struct NoteFinder
|
||||||
int filter_iter;// = 1;
|
int filter_iter;// = 1;
|
||||||
int decompose_iterations;// = 1000;
|
int decompose_iterations;// = 1000;
|
||||||
float amplify; // =1 (amplify input across the board)
|
float amplify; // =1 (amplify input across the board)
|
||||||
|
int do_progressive_dft; //= 1
|
||||||
|
|
||||||
//at 300, there is still some minimal aliasing at higher frequencies. Increase this for less low-end distortion
|
//at 300, there is still some minimal aliasing at higher frequencies. Increase this for less low-end distortion
|
||||||
//NOTE: This /should/ get fixed, as we /should/ be decimating the input data intelligently with lower octaves.
|
//NOTE: This /should/ get fixed, as we /should/ be decimating the input data intelligently with lower octaves.
|
||||||
|
|
47
sound_win.c
47
sound_win.c
|
@ -1,5 +1,3 @@
|
||||||
//XXX THIS DRIVER IS INCOMPLETE XXX
|
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
|
@ -12,7 +10,7 @@
|
||||||
#pragma comment(lib,"winmm.lib")
|
#pragma comment(lib,"winmm.lib")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define BUFFS 3
|
#define BUFFS 2
|
||||||
|
|
||||||
struct SoundDriverWin
|
struct SoundDriverWin
|
||||||
{
|
{
|
||||||
|
@ -27,9 +25,7 @@ struct SoundDriverWin
|
||||||
|
|
||||||
int buffer;
|
int buffer;
|
||||||
int isEnding;
|
int isEnding;
|
||||||
int Cbuff;
|
|
||||||
int GOBUFF;
|
int GOBUFF;
|
||||||
int OLDBUFF;
|
|
||||||
|
|
||||||
int recording;
|
int recording;
|
||||||
|
|
||||||
|
@ -42,6 +38,7 @@ static struct SoundDriverWin * w;
|
||||||
void CloseSoundWin( struct SoundDriverWin * r )
|
void CloseSoundWin( struct SoundDriverWin * r )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if( r )
|
if( r )
|
||||||
{
|
{
|
||||||
waveInStop(r->hMyWave);
|
waveInStop(r->hMyWave);
|
||||||
|
@ -65,6 +62,7 @@ int SoundStateWin( struct SoundDriverWin * soundobject )
|
||||||
void CALLBACK HANDLEMIC(HWAVEIN hwi,UINT umsg, DWORD dwi, DWORD hdr, DWORD dwparm)
|
void CALLBACK HANDLEMIC(HWAVEIN hwi,UINT umsg, DWORD dwi, DWORD hdr, DWORD dwparm)
|
||||||
{
|
{
|
||||||
int ctr;
|
int ctr;
|
||||||
|
int ob;
|
||||||
long cValue;
|
long cValue;
|
||||||
unsigned int maxWave=0;
|
unsigned int maxWave=0;
|
||||||
|
|
||||||
|
@ -80,18 +78,20 @@ void CALLBACK HANDLEMIC(HWAVEIN hwi,UINT umsg, DWORD dwi, DWORD hdr, DWORD dwpar
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MM_WIM_DATA:
|
case MM_WIM_DATA:
|
||||||
w->OLDBUFF=w->GOBUFF;
|
// printf( "Mic Data.\n");
|
||||||
w->GOBUFF=w->Cbuff;
|
ob = (w->GOBUFF+(BUFFS))%BUFFS;
|
||||||
w->Cbuff = (w->Cbuff+1)%3;
|
// waveInPrepareHeader(w->hMyWave,&(w->WavBuff[w->Cbuff]),sizeof(WAVEHDR));
|
||||||
waveInPrepareHeader(w->hMyWave,&(w->WavBuff[w->Cbuff]),sizeof(WAVEHDR));
|
|
||||||
waveInAddBuffer(w->hMyWave,&(w->WavBuff[w->Cbuff]),sizeof(WAVEHDR));
|
|
||||||
|
|
||||||
for (ctr=0;ctr<w->buffer * w->channelsRec;ctr++) {
|
for (ctr=0;ctr<w->buffer * w->channelsRec;ctr++) {
|
||||||
float cv = (uint16_t)(((uint8_t)w->WavBuff[w->GOBUFF].lpData[ctr*2+1])*256+((uint8_t)w->WavBuff[w->GOBUFF].lpData[ctr*2])+32768)-32768;
|
float cv = (uint16_t)(((uint8_t)w->WavBuff[ob].lpData[ctr*2+1])*256+((uint8_t)w->WavBuff[ob].lpData[ctr*2])+32768)-32768;
|
||||||
cv /= 32768;
|
cv /= 32768;
|
||||||
|
// if( ctr < 3 ) cv = -1;
|
||||||
|
// buffer[(w->buffer * w->channelsRec)-ctr-1] = cv;
|
||||||
buffer[ctr] = cv;
|
buffer[ctr] = cv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
waveInAddBuffer(w->hMyWave,&(w->WavBuff[w->GOBUFF]),sizeof(WAVEHDR));
|
||||||
|
w->GOBUFF = ( w->GOBUFF + 1 ) % BUFFS;
|
||||||
|
|
||||||
int playbacksamples; //Unused
|
int playbacksamples; //Unused
|
||||||
w->callback( 0, buffer, w->buffer, &playbacksamples, (struct SoundDriver*)w );
|
w->callback( 0, buffer, w->buffer, &playbacksamples, (struct SoundDriver*)w );
|
||||||
|
@ -113,23 +113,34 @@ static struct SoundDriverWin * InitWinSound( struct SoundDriverWin * r )
|
||||||
|
|
||||||
w = r;
|
w = r;
|
||||||
|
|
||||||
|
|
||||||
|
printf( "WFMT: %d %d %d\n", r->channelsRec, r->spsRec,
|
||||||
|
r->spsRec * r->channelsRec );
|
||||||
|
|
||||||
wfmt.wFormatTag = WAVE_FORMAT_PCM;
|
wfmt.wFormatTag = WAVE_FORMAT_PCM;
|
||||||
wfmt.nChannels = r->channelsRec;
|
wfmt.nChannels = r->channelsRec;
|
||||||
wfmt.nSamplesPerSec = r->spsRec;
|
wfmt.nSamplesPerSec = r->spsRec;
|
||||||
wfmt.nBlockAlign = 1;
|
wfmt.nAvgBytesPerSec = r->spsRec * r->channelsRec;
|
||||||
|
wfmt.nBlockAlign = r->channelsRec * 2;
|
||||||
wfmt.wBitsPerSample = 16;
|
wfmt.wBitsPerSample = 16;
|
||||||
wfmt.nAvgBytesPerSec = 0;
|
wfmt.cbSize = 0;
|
||||||
|
|
||||||
long dwdevice;
|
long dwdevice;
|
||||||
dwdevice = GetParameterI( "wininput", WAVE_MAPPER );
|
dwdevice = GetParameterI( "wininput", WAVE_MAPPER );
|
||||||
|
|
||||||
int p = waveInOpen(&r->hMyWave, dwdevice, &wfmt,(DWORD)(void*)(HANDLEMIC) , 0, CALLBACK_FUNCTION);
|
printf( "Wave Devs: %d; WAVE_MAPPER: %d; Selected Input: %d\n", waveInGetNumDevs(), WAVE_MAPPER, dwdevice );
|
||||||
|
|
||||||
printf( "WIO: %d\n", p );
|
printf( "waveInOpen: %p, %p\n", &r->hMyWave, &wfmt );
|
||||||
|
|
||||||
|
int p = waveInOpen(&r->hMyWave, dwdevice, &wfmt,(DWORD)(void*)(&HANDLEMIC) , 0, CALLBACK_FUNCTION);
|
||||||
|
|
||||||
|
printf( "WIO: %d\n", p ); //On real windows, returns 11
|
||||||
|
|
||||||
for ( i=0;i<BUFFS;i++)
|
for ( i=0;i<BUFFS;i++)
|
||||||
{
|
{
|
||||||
|
memset( &(r->WavBuff[i]), 0, sizeof(r->WavBuff[i]) );
|
||||||
(r->WavBuff[i]).dwBufferLength = r->buffer*2*r->channelsRec;
|
(r->WavBuff[i]).dwBufferLength = r->buffer*2*r->channelsRec;
|
||||||
|
(r->WavBuff[i]).dwLoops = 1;
|
||||||
(r->WavBuff[i]).lpData=(char*) malloc(r->buffer*r->channelsRec*2);
|
(r->WavBuff[i]).lpData=(char*) malloc(r->buffer*r->channelsRec*2);
|
||||||
waveInPrepareHeader(r->hMyWave,&(r->WavBuff[i]),sizeof(WAVEHDR));
|
waveInPrepareHeader(r->hMyWave,&(r->WavBuff[i]),sizeof(WAVEHDR));
|
||||||
waveInAddBuffer(r->hMyWave,&(r->WavBuff[i]),sizeof(WAVEHDR));
|
waveInAddBuffer(r->hMyWave,&(r->WavBuff[i]),sizeof(WAVEHDR));
|
||||||
|
@ -137,7 +148,7 @@ static struct SoundDriverWin * InitWinSound( struct SoundDriverWin * r )
|
||||||
|
|
||||||
p = waveInStart(r->hMyWave);
|
p = waveInStart(r->hMyWave);
|
||||||
|
|
||||||
printf( "WIS: %d\n", p );
|
printf( "WIS: %d\n", p ); //On real windows returns 5.
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -154,14 +165,12 @@ void * InitSoundWin( SoundCBType cb )
|
||||||
|
|
||||||
r->spsRec = GetParameterI( "samplerate", 44100 );
|
r->spsRec = GetParameterI( "samplerate", 44100 );
|
||||||
r->channelsRec = GetParameterI( "channels", 2 );
|
r->channelsRec = GetParameterI( "channels", 2 );
|
||||||
r->buffer = GetParameterI( "buffer", 1024 );
|
r->buffer = GetParameterI( "buffer", 384 );
|
||||||
r->recording = 0;
|
r->recording = 0;
|
||||||
r->isEnding = 0;
|
r->isEnding = 0;
|
||||||
printf( "Buffer: %d\n", r->buffer );
|
printf( "Buffer: %d\n", r->buffer );
|
||||||
|
|
||||||
r->Cbuff=0;
|
|
||||||
r->GOBUFF=0;
|
r->GOBUFF=0;
|
||||||
r->OLDBUFF=0;
|
|
||||||
|
|
||||||
return InitWinSound(r);
|
return InitWinSound(r);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue