2017-01-09 5 views
1

Ich arbeite an einem kleinen Tool, das Daten aus einer WAV-Datei liest. Dieses Tool extrahiert zunächst den Header, gefolgt von der Trennung der Audiodaten in den linken und rechten Kanal. Audiodateien sind nur Dateien mit einer Abtastfrequenz von 44100 Hz, 16 Bit PCM und Dual-Channel.c - Schreiben von Daten in WAV-Datei

Nach der Manipulation der Daten möchte ich die Daten in eine Ausgabedatei zurückschreiben und 100 Nullen auf jedem Kanal anhängen. Hier tritt das Problem auf: Zuerst wird nur die Hälfte der gewünschten Samples an jeden Kanal angehängt. Zweitens sind die erste Hälfte der angehängten "Nullen" zufällige Daten.

Sehen Sie meinen Code unten

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

#define BUFFSIZE 1024 
#define NUM_ZEROS 100 

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

typedef struct header_file 
{ 
    char chunk_id[4]; 
    int chunk_size; 
    char format[4]; 
    char subchunk1_id[4]; 
    int subchunk1_size; 
    short int audio_format; 
    short int num_channels; 
    int sample_rate; 
    int byte_rate; 
    short int block_align; 
    short int bits_per_sample; 
    char subchunk2_id[4]; 
    int subchunk2_size; 
} header; 

typedef struct header_file* header_p; 


int main(int argc, char** argv){ 

    if(argc != 3){ 
     printf("Wrong number of input arguments. Aborting.\n"); 
     return -1; 
    } 

    char *inputFile = argv[1]; 
    char *outputFile = argv[2]; 

    FILE * infile = fopen(inputFile, "r+"); 
    FILE * outfile = fopen(outputFile, "w+"); 

    int count = 0;          // For counting number of frames in wave file. 
    short int buff16[2*BUFFSIZE];      // short int used for 16 bit as input data format is 16 bit PCM audio 
    short int buffLeft[BUFFSIZE], buffRight[BUFFSIZE]; 
    header_p meta = (header_p)malloc(sizeof(header)); // header_p points to a header struct that contains the wave file metadata fields 
    int nb, cnt;          // variable storing number of bytes returned 

    printf("Buffers initialized.\n"); 

    if (infile) 
    { 
     fread(meta, 1, sizeof(header), infile); 
     meta->subchunk2_size = meta->subchunk2_size + 2 * NUM_ZEROS; 
     fwrite(meta,1, sizeof(*meta), outfile); 


     while (!feof(infile)) 
     { 
      nb = fread(buff16,1,BUFFSIZE,infile);  // Reading data in chunks of BUFSIZE 
      count++;         // Incrementing Number of frames 

      for(cnt = 0; cnt < nb/2; cnt++){ 
       buffLeft[cnt] = buff16[2*cnt]; 
       buffRight[cnt] = buff16[2*cnt+1]; 
      } 

      /* 
      * TODO: INSERT SIGNAL PROCESSING PART 
      */ 

      for(cnt = 0; cnt < nb/2; cnt++){ 
       buff16[2*cnt] = buffLeft[cnt]; 
       buff16[2*cnt+1] = buffRight[cnt]; 
      } 

      fwrite(buff16,1,nb,outfile); 
     } 

     for(cnt = 0; cnt < 2*NUM_ZEROS; cnt++){ 
      buff16[cnt] = 0; 
     } 
     fwrite(buff16,1, 2*NUM_ZEROS,outfile); 

     printf("Number of frames in the input wave file are %d.\n", count); 
    } 

    fclose(infile); 
    fclose(outfile); 

    return 0; 
} 

jemand eine Idee Hat, was ich falsch gemacht habe?

Antwort

0

Sie haben

#define NUM_ZEROS 100 

und

fwrite(buff16,1, 2*NUM_ZEROS,outfile); 

Ziel:

Ich möchte die Daten in eine Ausgabedatei schreiben zurück und 100 Nullen auf jedem Kanal anhängen.

Ich denke, es sollte 100 Proben für jeden Kanal sein. Da Sie 16bit PCM haben, ist jedes Beispiel 2 Bytes. So ein Kanal benötigt 200 Bytes (Nullen) geschrieben werden. Stereo bedeutet 400 Bytes.

Ihr fwrite speichert nur 2 * NUM_ZEROS so 200 Bytes - dies ist die Antwort auf einen Teil über fehlende Proben.

Zusätzlich erklären Sie

short int buff16 [2 * BUFFSIZE];

während Sie nur die Hälfte davon lesen und die Hälfte der Hälfte (nb/2) für die Verarbeitung verwenden. Dann schreibe den vollen Puffer (eigentlich die Hälfte von deklariert) mit der oberen Hälfte voller zufälligen Müll aus dem Speicher.

0

Sind Sie sicher, dass nur ein Teil der hinzugefügten Nullen Müll ist?

Sie verwirren die Datengröße für fread und fwrite

Ihre Puffer sind short int:

short int buff16[2*BUFFSIZE]; // BUFFSIZE*2*sizeof(short) bytes 

Sie lesen nur 1/4 der Größe:

nb = fread(buff16,1,BUFFSIZE,infile); // BUFFSIZE bytes 

Dieses liest BUFSIZEBytes wie Sie nur eine Größe von 1 pro Element angeben. Anstelle von BUFFSIZE*2 Shorts lesen Sie nur BUFFSIZE Bytes. Der Rückgabewert ist die Anzahl der Leseelemente, d. H. Wieder Bytes. In Ihrem Puffer reicht diese Datenmenge nur für nb/2 Elemente, aber Sie greifen auf buff16[0] .. buff16[nb-1] wo die zweite Hälfte davon nicht aus der Datei gelesen wurde. Zum Glück schreiben Sie auch nicht die zweite Hälfte in die neue Datei zurück, da der gleiche Fehler mit der Länge auch dort vorhanden ist. Und schließlich ist das gleiche Problem vorhanden, wenn Sie die Nullwerte an die Datei anhängen.

tl; dr

Ihre Größe Parameter ändern für fread und fwrite-sizeof(short int).