Reputation: 41
I am processing a dataset of 17 hours of audio .wav (16-bit PCM, 192khz), to simulate a "real-time" processing that will be embedded in an ESP32, Arduino DUE or in a RASP, depending on the results.
How am I handling with that now?
First I cut the 17 hours file in a 1 minute samples, after I created a program in C that turns this file into a .CSV (jumping the entire head of .wav and taking only the date field).
PS: I chose CSV to have the data in a better disposition in order to perform tests in Scilab to validate the algorithms.
With this generated .CSV file I run it in a second program, that opens this file and fills a circular buffer with 130ms (24900 values), when the buffer is full, the code begins to calculate the RMS (Root Mean Square) in moving window with 10ms overlap, window size is 30ms . When I get a value greater than 1000 it is considered an event.
Below you can see an illustration of the problem:
Here is shown the Window with 50 ms before and after an event which I mean:
PS: Inicio, Fim and Janela means respectively, Start, End, Window.
My question is:
How should I save these 50ms before and after the event, since the event can occur anywhere in the buffer? And what should I do if the event lasts for more than one window?
Some data to help the understanding:
130ms = 24900 values from my .csv file
50ms = 9600 values
30ms = 5700 values
10ms = 1920 values
I've searched for several sources, but most of the DSP bibliographies and Data Structures treat these topics superficially, just illustrating what a circular buffer is and not how to deal with it in a useful way.
Here is my code sketch, which seems to be taking a wrong approach to the problem, but I really have no idea how to proceed, in this case I created a data-set from 1 to 100 to ease of the debug:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
// Define the size of window 50ms
#define window_size 3 // 30ms
#define buffer_size 13 // 130ms = 50ms + 30ms + 50ms
int main()
{
//define variables.
int buffer[buffer_size]={0}; // create the buffer with 150ms;
int write = 0;
int i = 0, j = 0;
int read = 0;
int read1 =0;
int write1 = 0;
int counter_elements = 0;
int number_lines = 0;
int save_line = 0;
char c;
char str[1024]; // array to hold characters in a conversion of char to int.
int inicio = 0, fim = 0;
//RMS
int soma_quadrado = 0;
int rms = 0;
int pre_amostragem[5] = {0};
//Define variaveis referentes a leitura do arquivo e manipulacoes do mesmo.
FILE * fp;
FILE * LOG;
FILE * log_rms_final;
// Open the file and verify is NULL.
if((fp = fopen("generator.txt","r")) == NULL)
{ // Define o nome do csv para abrir
printf("Error! Can't open the file.\n");
exit(1);
}
// store rms values
LOG = fopen("RMSValues.csv", "a");
// store the 50ms after and before a event.
log_rms_final = fopen("Log_RMS.csv","a");
int lines = 0;
while(!feof(fp))
{
fgets(str,1024,fp); //reads 1024 characters and store in str.
buffer[write] = atoi(str);
write = (write + 1) % buffer_size; // circular
counter_elements++; // sum
c = fgetc(fp);
if(c == '\n')
{
lines++;
}
printf("%d\n", lines);
//if buffer is full
if(counter_elements == buffer_size)
{
// window
read1 = read;
for(i = 0; i < window_size; i++)
{
//square and sum.
soma_quadrado += buffer[read1]*buffer[read1];
read1 = (read1 + 1) % buffer_size;
}
// RMS
rms = sqrt(soma_quadrado/window_size);
fprintf(LOG, "\n %d", rms); // store
if(rms > 1000)
{
printf("rms: %d\n",rms);
// store the 50ms befor a event and the window.
write1 = write;
for(j = 0 ; j < 5; j++)
{
write1 = (write1 + (buffer_size - 1)) % buffer_size;
pre_amostragem[j] = buffer[write1];
}
fprintf(log_rms_final,"%s","\n");
for(j = 4; j >= 0; j--)
{
fprintf(log_rms_final,"%d - pre \n",pre_amostragem[j]);
}
fprintf(log_rms_final,"%s","\n");
/*
for(j = 0; j < window_size; j++)
{
fprintf(log_rms_final,"%d - janela\n",buffer[read1]);
read1 = (read1 + 1) % buffer_size;
}
*/
fprintf(log_rms_final,"%s","\n");
//store the 50ms after a event.
/*
fseek(log_rms_final,save_line - 3,save_line);
for(j = 0; j < 5; j++){
fgets(str,1024,fp);
fprintf(log_rms_final,"%d - pós \n",atoi(str));
}
*/
}
soma_quadrado = 0;
rms = 0;
read = (read + 1) % buffer_size;
counter_elements = counter_elements - 2;
}
soma_quadrado = 0;
rms = 0;
}
fclose(fp);
fclose(LOG);
fclose(log_rms_final);
return 0;
}
some comments are in Portuguese but they aren't relevant for the understanding of the problem.
Upvotes: 2
Views: 293
Reputation: 8614
I am giving you an algorithm for the solution here.
As mentioned below in the comments, this solution will work for a window size > 50 ms also. You need to select the size of the final buffer accordingly.
Upvotes: 2