2017-01-09 137 views
1

我正在研究從wav文件讀取數據的小工具。該工具首先提取標題,然後將音頻數據分離爲左右聲道。音頻文件只是採樣頻率爲44100Hz,16Bit PCM和雙聲道的文件。c - 將數據寫入wav文件

操作數據後,我想將數據寫回輸出文件並在每個通道上追加100個零。這裏會出現這樣的問題:首先,每個通道只追加一半所需樣品。其次,附加「零」的前半部分是隨機數據。

見我下面

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

碼某人是否有一個想法,我做錯了什麼?

回答

0

你有

#define NUM_ZEROS 100 

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

目的:

我希望將數據寫回一個輸出文件,並在每個通道上追加100個零 。

我認爲它應該是100個樣本在每個通道。 由於你有16位PCM,每個採樣是2個字節。 所以一個通道需要寫入200個字節(零)。立體聲意味着400字節。

你的fwrite只保存2 * NUM_ZEROS所以200字節 - 這是部分關於丟失樣本的答案。

另外聲明

短整型buff16 [2 * BUFFSIZE];

同時只讀取其中的一半,並使用半數(nb/2)的一半進行處理。比完整的緩衝區(實際上是聲明的一半)和上半部分充滿隨機垃圾的內存。

0

你確定只有一部分添加的零是垃圾嗎?

你陷入困境的fread數據大小和fwrite

你的緩衝區short int

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

您僅讀取尺寸的1/4:

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

這讀取BUFSIZEbytes,因爲您只能爲每個元素指定大小1。 而不是BUFFSIZE*2短褲,你只能讀取BUFFSIZE字節。 返回值是讀取元素的數量,即字節數。 在您的緩衝區中,該數據量僅對nb/2元素足夠,但訪問buff16[0] .. buff16[nb-1]其中後半部分未從文件中讀取。 幸運的是,您也不會將後半部分寫入新文件,因爲 同樣的長度錯誤也出現在那裏。 最後,在將零值附加到文件時存在同樣的問題。

TL;博士

更改尺寸參數freadfwritesizeof(short int)