I'm writing a small program that use SDL and KissFFT that should open a wave file, play the file and find the magnitude and dB for each channel of the current sample buffer so I would visually display Left and Right channels on screen.
So far I have opened and played the file and wrote a small function that will input current sample buffer and calculate the magnitude and dB of the provided buffer.
I'm very new at signal processing and FFT but the basic concept should be to get the buffer, allocate the arrays IN/OUT. Fill the IN array with samples and calculate the FFT and store the output in OUT.
But from what I understand the OUT is an array of frequencies ( a lot of them ). So I would now like to find the magnitude and dB for left and right channel based on those.
This is my code for now
void audio_callback(void *userdata, Uint8 *stream, int len)
{
if (audio_len ==0)
return;
SDL_memset(stream, 0, len);
len = ( len > audio_len ? audio_len : len );
SDL_memcpy (stream, ptr_audio_buffer, len);
calc_loudness(ptr_audio_buffer, len); // 8192/2 = 4096 samples
ptr_audio_buffer += len;
audio_len -= len;
}
void calc_loudness(uint8_t *buff, int len)
{
int nfft = len;
double magnitude = 0;
kiss_fft_cfg cfg;
kiss_fft_cpx *cx_in = new kiss_fft_cpx[len];
kiss_fft_cpx *cx_out = new kiss_fft_cpx[len];
int16_t val = NULL;
cfg = kiss_fft_alloc(nfft, 0, 0, 0);
for (int i = 0;i<len;i+=2) // 4096 samples
{
decode_signed16(&buff[i], &val);
cx_in[i].r = (float)val / 32768.0; // I have to do this because values get wild. Why?
cx_in[i].i = 0.0;
}
kiss_fft(cfg, cx_in, cx_out);
int position = len/2-1; // last sample
magnitude = sqrt(pow(cx_out[position].r, 2) + pow(cx_out[position].i, 2));
double dB = 10 * log10(pow(cx_out[position].r, 2) + pow(cx_out[position].i, 2));
printf("magnitude: %9.4f \t dB: %9.4f\n", magnitude,dB);
// ...
// free memory.
}
At this point I have this arbitrary values that kind of look correct when displayed with fill_rect. But this only gets me one value. And I'm pretty sure I messed up a lot of things here.
How can I separate these values to 2 channels? (should I calculate fft for each channel separately?).