Commit 7201e77d authored by Gargaj's avatar Gargaj
Browse files

rejig the fft code so that the buffer is always fresh

parent bb8c6281
......@@ -12,59 +12,62 @@ namespace FFT
kiss_fftr_cfg fftcfg;
mal_context context;
mal_device captureDevice;
float lastFFT[ FFT_SIZE ];
float sampleBuf[ FFT_SIZE * 2 ];
int sampleCursor = 0;
void OnLog( mal_context* pContext, mal_device* pDevice, const char* message )
{
printf( "[FFT] [mal:%p:%p]\n %s", pContext, pDevice, message );
}
void OnReceiveFrames( mal_device* pDevice, mal_uint32 frameCount, const void* pSamples )
{
frameCount = frameCount < FFT_SIZE * 2 ? frameCount : FFT_SIZE * 2;
// Just rotate the buffer; copy existing, append new
const mal_int16 * samples = (const mal_int16 *)pSamples;
float * p = sampleBuf;
for ( int i = 0; i < FFT_SIZE * 2 - frameCount; i++ )
{
*( p++ ) = sampleBuf[ i + frameCount ];
}
for ( int i = 0; i < frameCount; i++ )
{
sampleBuf[ sampleCursor++ ] = ( samples[ 0 ] + samples[ 1 ] ) / 65535.0f; // int16 max * 2 -> -1..1
samples += 2;
if ( sampleCursor == FFT_SIZE * 2 )
{
kiss_fft_cpx out[ FFT_SIZE + 1 ];
kiss_fftr( fftcfg, sampleBuf, out );
for ( int i = 0; i < FFT_SIZE; i++ )
{
static const float scaling = 1.0f / (float)FFT_SIZE;
lastFFT[ i ] = 2.0 * sqrtf( out[ i ].r*out[ i ].r + out[ i ].i*out[ i ].i ) * scaling;
}
sampleCursor = 0;
}
*( p++ ) = ( samples[ i * 2 ] + samples[ i * 2 + 1 ] ) / 65535.0f; // int16 max * 2 -> -1..1
}
}
bool Open()
{
memset( lastFFT, 0, sizeof( float ) * FFT_SIZE );
memset( sampleBuf, 0, sizeof( float ) * FFT_SIZE * 2 );
fftcfg = kiss_fftr_alloc( FFT_SIZE * 2, false, NULL, NULL );
if ( mal_context_init( NULL, 0, NULL, &context ) != MAL_SUCCESS )
const mal_context_config context_config = mal_context_config_init( OnLog );
mal_result result = mal_context_init( NULL, 0, &context_config, &context );
if ( result != MAL_SUCCESS )
{
printf( "[FFT] Failed to initialize context." );
printf( "[FFT] Failed to initialize context: %d", result );
return false;
}
mal_device_config config = mal_device_config_init( mal_format_s16, 2, 44100, OnReceiveFrames, NULL );
printf( "[FFT] MAL context initialized, backend is '%s'\n", mal_get_backend_name( context.backend ) );
const mal_device_config config = mal_device_config_init( mal_format_s16, 2, 44100, OnReceiveFrames, NULL );
if ( mal_device_init( &context, mal_device_type_capture, NULL, &config, NULL, &captureDevice ) != MAL_SUCCESS )
result = mal_device_init( &context, mal_device_type_capture, NULL, &config, NULL, &captureDevice );
if ( result != MAL_SUCCESS )
{
mal_context_uninit( &context );
printf( "[FFT] Failed to initialize capture device.\n" );
printf( "[FFT] Failed to initialize capture device: %d\n", result );
return false;
}
if ( mal_device_start( &captureDevice ) != MAL_SUCCESS )
result = mal_device_start( &captureDevice );
if ( result != MAL_SUCCESS )
{
mal_device_uninit( &captureDevice );
mal_context_uninit( &context );
printf( "[FFT] Failed to start capture device.\n" );
printf( "[FFT] Failed to start capture device: %d\n", result );
return false;
}
......@@ -72,7 +75,15 @@ namespace FFT
}
bool GetFFT( float * samples )
{
memcpy( samples, lastFFT, sizeof( float )*FFT_SIZE );
kiss_fft_cpx out[ FFT_SIZE + 1 ];
kiss_fftr( fftcfg, sampleBuf, out );
for ( int i = 0; i < FFT_SIZE; i++ )
{
static const float scaling = 1.0f / (float)FFT_SIZE;
samples[ i ] = 2.0 * sqrtf( out[ i ].r * out[ i ].r + out[ i ].i * out[ i ].i ) * scaling;
}
return true;
}
void Close()
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment