SAMPLING AUDIO - How to handle large data?
Posted: Fri Feb 14, 2020 12:47 pm
Hello,
I am building an audio sampler on ESP32. I have been following https://www.toptal.com/embedded/esp32-audio-sampling loosely. Instead of reading from the inbuilt ESP32 ADC, I am using a MCP3208. The problem I am having is figuring out how to deal with the 1000 samples I am sampling every few microseconds. Here is the relevant parts of my code
My problem I have is here
I would ideally like to write it directly to a file using the SPIFF filesystem but it crashes if I try to do that. Can someone please advice me, what can I do here? Is there a way I can store all these samples while I am sampling. I want to record for about 60 seconds at 21,000 samples a second. Which is 1.2 million samples. Should I hold these values and then write them to a file after sampling? Or should I be writing it to the file while sampling (not able to do it because it crashes)?
Thanks
I am building an audio sampler on ESP32. I have been following https://www.toptal.com/embedded/esp32-audio-sampling loosely. Instead of reading from the inbuilt ESP32 ADC, I am using a MCP3208. The problem I am having is figuring out how to deal with the 1000 samples I am sampling every few microseconds. Here is the relevant parts of my code
Code: Select all
#include <MCP3208.h>
#include <SPI.h>
#define ADC_SAMPLES_COUNT 1000
portMUX_TYPE DRAM_ATTR timerMux = portMUX_INITIALIZER_UNLOCKED;
TaskHandle_t complexHandlerTask;
hw_timer_t * adcTimer = NULL; // our timer
MCP3208 adc(5);
int16_t abuf[ADC_SAMPLES_COUNT];
int16_t abufPos = 0;
void complexHandler(void *param) {
while (true) {
// Sleep until the ISR gives us something to do, or for 1 second
uint32_t tcount = ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(1000));
//how do I deal with abuf array here
}
}
void IRAM_ATTR onTimer() {
portENTER_CRITICAL_ISR(&timerMux);
abuf[abufPos++] = adc.analogRead(0);
if (abufPos >= ADC_SAMPLES_COUNT) {
abufPos = 0;
// Notify adcTask that the buffer is full.
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
vTaskNotifyGiveFromISR(complexHandlerTask, &xHigherPriorityTaskWoken);
if (xHigherPriorityTaskWoken) {
portYIELD_FROM_ISR();
}
}
portEXIT_CRITICAL_ISR(&timerMux);
}
void setup() {
xTaskCreate(complexHandler, "Handler Task", 8192, NULL, 1, &complexHandlerTask);
adcTimer = timerBegin(3, 80, true); // 80 MHz / 80 = 1 MHz hardware clock for easy figuring
timerAttachInterrupt(adcTimer, &onTimer, true); // Attaches the handler function to the timer
timerAlarmWrite(adcTimer,50, true); // Interrupts when counter == 45, i.e. 22.222 times a second
timerAlarmEnable(adcTimer);
adc.begin();
Serial.begin(115200);
}
void loop() {}
Code: Select all
void complexHandler(void *param) {
while (true) {
// Sleep until the ISR gives us something to do, or for 1 second
uint32_t tcount = ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(1000));
//how do I deal with abuf array here
}
}
Thanks