Rezo
Well-known member
I have a need to do some analysis on a PCM data stream from a WAV file, to create a 3-band waveform of an audio track.
I'm reading the data directly from the SD card, and looping though samples.
I am not playing the audio back during this analysis, and when I do, I'm not using the Audio lib at all, but rather directly feeding data to SAI and loading samples though the SAI interrupt.
I need to use the biquad filter to create three bandpass filters to extract Low (20-200Hz) Mid (200-2000Hz) and High (2000-20000Hz) of each track.
Is there a way to run the data though the biquad filter and read the output at the same time?
Below is an example of how I create a single band waveform with amplitude and rms view. I've noted where I want to add the three bandpass filters
If this can be done using the audio library, I'd highly appreciate some guidance here.
If not, then can this be done with CMSIS-DSP lib?
I'm reading the data directly from the SD card, and looping though samples.
I am not playing the audio back during this analysis, and when I do, I'm not using the Audio lib at all, but rather directly feeding data to SAI and loading samples though the SAI interrupt.
I need to use the biquad filter to create three bandpass filters to extract Low (20-200Hz) Mid (200-2000Hz) and High (2000-20000Hz) of each track.
Is there a way to run the data though the biquad filter and read the output at the same time?
Below is an example of how I create a single band waveform with amplitude and rms view. I've noted where I want to add the three bandpass filters
Code:
void createWaveform(ExFile file) {
// Skip WAV header (44 bytes)
file.seekSet(44);
uint32_t numSamplesProcessed = 0;
// Loop through PCM data
while (file.available()) {
int32_t maxAmplitude = 0;
int64_t sumSquares = 0;
for (uint16_t i = 0; i < NUM_SAMPLES; i++) {
int16_t leftChannel, rightChannel;
if (file.read(&leftChannel, sizeof(int16_t)) != sizeof(int16_t)) break;
if (file.read(&rightChannel, sizeof(int16_t)) != sizeof(int16_t)) break;
int32_t combinedSample = (leftChannel + rightChannel) / 2;
int32_t amplitude = abs(combinedSample); // Ensure amplitude is positive
if (amplitude > maxAmplitude) {
maxAmplitude = amplitude;
}
sumSquares += (int64_t)amplitude * amplitude;
}
//EXTRACT THREE BANDS HERE
// Calculate RMS
int32_t rms = sqrt(sumSquares / NUM_SAMPLES);
// Scale amplitude and RMS to 8 bits each (0-WAVEFORM_HEIGHT/2-1)
uint8_t scaledAmplitude = map(maxAmplitude,0, INT16_MAX, 0, WAVEFORM_HEIGHT/2-1);
uint8_t scaledRMS = map(rms,0, INT16_MAX, 0, WAVEFORM_HEIGHT/2-1);
// Combine amplitude and RMS into a uint16_t value
uint16_t combinedValue = (scaledAmplitude << 8) | scaledRMS;
if (numSamplesProcessed < WFORMDYNAMIC_SIZE) {
WFORMDYNAMIC[numSamplesProcessed] = combinedValue;
numSamplesProcessed++;
}
}
Serial.printf("Number of samples proccessed: %d \n", numSamplesProcessed);
//Skip back to end of WAV header/start of PCM data
file.seekSet(44);
}
If this can be done using the audio library, I'd highly appreciate some guidance here.
If not, then can this be done with CMSIS-DSP lib?