SAMPLING AUDIO - How to handle large data?

romitraj
Posts: 2
Joined: Fri Feb 14, 2020 12:35 pm

SAMPLING AUDIO - How to handle large data?

Postby romitraj » 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

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() {}
My problem I have is here

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
  }
}
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

mikemoy
Posts: 448
Joined: Fri Jan 12, 2018 9:10 pm

Re: SAMPLING AUDIO - How to handle large data?

Postby mikemoy » Sat Feb 15, 2020 7:09 am

You throw your samples into a ram variable array. Then you have a back end task that is reading those samples and saving it to SPIFF filesystem. Basically create 2 variable. The one to hold your samples, and one to store how many samples you have.

uint8_t samples[21000];
uint16_t sample_counter=0;

As you get a sample, save it to:

samples[sample_counter] = value;
if(++sample_counter >= 21000)
{
sample_counter=0;
}

Now in back end task, it will hold until sample_counter changes from 0. you determine at what level it needs to reach before it starts writing in chunks to the filesystem.

romitraj
Posts: 2
Joined: Fri Feb 14, 2020 12:35 pm

Re: SAMPLING AUDIO - How to handle large data?

Postby romitraj » Sat Feb 15, 2020 9:29 am

The problem is the my task handler is unable to write the data to the file. It crashes. So my sample buffer size is 1000, so that is basically being called 21 times a second and needs to write these 1000 lines to a file. But it is not able to do that keeps crashing.

mikemoy
Posts: 448
Joined: Fri Jan 12, 2018 9:10 pm

Re: SAMPLING AUDIO - How to handle large data?

Postby mikemoy » Sat Feb 15, 2020 5:40 pm

I have never needed to write to a file that quickly so I dont know if it can ,or there is something going on with your code.
But the point here is that you can slow down your writes while you are still saving the data to ram.

bobtidey
Posts: 30
Joined: Mon Jun 18, 2018 2:24 pm

Re: SAMPLING AUDIO - How to handle large data?

Postby bobtidey » Mon Feb 17, 2020 8:56 am

If you use an esp32 module with 4MByte PSRAM (e.g. WROVER) then you can store your whole capture in a buffer before writing out to file.

bobolink
Posts: 37
Joined: Mon Feb 26, 2018 4:17 pm

Re: SAMPLING AUDIO - How to handle large data?

Postby bobolink » Mon Feb 17, 2020 12:18 pm

For 60 sec. of 16 bit samples 4MB of PSRAM, as suggested above, would work but it has a slow write cycle. I don’t know if it would complete before the next interrupt.

ESP_Sprite
Posts: 3262
Joined: Thu Nov 26, 2015 4:08 am

Re: SAMPLING AUDIO - How to handle large data?

Postby ESP_Sprite » Tue Feb 18, 2020 8:35 am

I'd say that for 4 MByte, most sd-cards will get up to their rated write speed, which usually is way higher than needed for writing audio data.

Who is online

Users browsing this forum: barbiani and 44 guests