Problem with file reading . WAV

Asked

Viewed 239 times

5

Hi, I’m trying to read a file. 5s wav filled with "silence" to test the code in C. I was able to read the header but while trying to extract the date field where it contains the content itself ( which I believe should be zero) generates some numbers. as shown below.

Code:

#include <stdio.h>
#include <stdlib.h>

char buff[10000];
int main(){

    int i;
    FILE * fp;
    FILE *flog;

    if ((fp = fopen("Silencio2.wav", "rb")) == NULL){
        printf("Fail!");
        exit(1);
    }


    fseek(fp, 44, 0); // Lê apartir do campo DATA como segue na documentação.
    fread(buff,sizeof(int),1024,fp);
    flog = fopen("Silencio2.txt","w"); // Cria um log para jogar no matlab e gerar o gráfico

    // Imprime em hexadecimal para visualizar melhor e salva em decimal no log.
    for(i = 0; i < 5000 ; i++){
     printf("%i == %hhx \n",i,buff[i]);
     fprintf(flog,"%d\n",buff[i]);
     buff[i] = 0;
    }
    fclose(flog);
    return 0;
}

Header Reading Image . Wav:

Saída do Header, pelo meu programa.

As we can notice the program correctly reads the header bringing the coherent information, RIFF, WAVE, FMT, 1 channel, 16bits, 16khz and the beginning of the date (40~44).

Font I am using to read the file . wav: http://soundfile.sapp.org/doc/WaveFormat/

Features of file . wav:

Bitrate: 16 bits PCM;
Canais: 1;
SampleRate: 16khz.
Tempo: 5s;
Gerado pelo Audacity com a função de gerar silencio.

After saving this log in txt I am pasting the same in Matlab and reading the original file in it, in order to print the comparative graph between the 2 to validate my data, however I am getting the following output:

1st Graphic Processing of Matlab with the readaudio function(); 2º Graphic out of my code log;

Comparação MATLAB x Meu Código

Script Matlab:

[Sile2,Fs] = audioread('Silencio2.wav');
title('Gerado pelo MATLAB');
subplot(2, 1, 2);
plot(CodeSile2);
title('Meu código');
subplot(2, 1, 1);
plot(Sile2);

The question that remains is: Are my results consistent? Because beyond the divergence of magnitude of the signal there is a noise, that I can not explain why. The signal was generated through a silent generator.

PS: Yes I know libsnd but how I want to embed this code in stm32/esp32, the less libraries use better.

1 answer

3


There are some errors going on in your code...

Ok you jumped directly to the Byte which contains the audio file data here:

fseek(fp, 44, 0);

On the next line read 1024 bytes:

fread(buff,sizeof(int),1024,fp);

Right after inside your while you’re trying to walk up to the byte 5000 ? as if you only read in buffer 1024 ? Surely he read them correctly 1024 first positions within its while and after that started picking up dirt, this is the main problem of your code.

Either you read the total size of bytes of your audio and store in the buffer or walk accessing piece by piece within the loop, detail the current size of the buff does not have the capacity to store everything, you defined it as being buff[10000]; if you want to play the 5 entire seconds inside your buffer would need to 80000:

Samplerate: 16 khz. Time: 5s;

16000*5 = 80000

Of course the second option is the smartest, reading bytes by pieces is the most sensible and efficient alternative, you should think of something working like this:

fseek(fp, 44, 0); // Lê apartir do campo DATA como segue na documentação.



//enquanto tiver dados para ler
do{

// a cada iteração captura 1024 bytes
byte_read=fread(buff,sizeof(int),1024,fp);

 //ler os 1024 bytes do buffer acima
 for(i = 0; i < 1024 ; i++){
     printf("%i == %hhx \n",i,buff[i]);
     fprintf(flog,"%d\n",buff[i]);
     buff[i] = 0;
  }

//enquanto tiver dados para ler
}while(byte_read > 0)

Another thing, to compare your data .txt with the value of Matlab you will need to convert the value you are saving in decimal to float point (this responds on the divergence of signal magnitude), the Matlab represents the waveform of an audio file decoded in float point, the values float between -1 e 1, the audio that is decoding in C is 16 bits, by default if represented in decimals will float between -32768 e 32767, then to convert its values to match the values of Matlab vc you must convert to float point using the equation seuNumDecimal/32768.0

  • 1

    Thank you very much, I hadn’t really realized this detail by making the adjustment in Tlab and picking the right sample size worked super well! Hug. PS: Exactly I will read by parts as indicated, I was trying to understand first if the code was functional in this way.

  • what good @Gabriellavoura is always good to help :-)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.