2016-11-20 55 views
0

我正在嘗試使用libsndfile庫來讀取/寫入音頻文件之間的信息。爲什麼我的數組在C中返回錯誤的值?

我已經成功地讀取原始文件,寫它的一個副本「水印」的價值觀。

所有我想現在要做的就是打印任何索引,其中值不爲0

然而,當我把我的printBuffer()函數,它的返回全0即使在調試模式下時,我可以看到緩衝區中的值不是零/更改每次迭代。我正在調用緩衝區數組不正確嗎?

我還是新的C,所以如果您有任何建議,他們將不勝感激。

謝謝。

代碼:

#define _CRT_SECURE_NO_DEPRECATE  
#include <stdio.h> 
#include <stdlib.h> 
#include <sndfile.h> 
#include <time.h> 

#define MAX_CHANNEL 2 
#define BUF_SIZE 1024 

int numItems(int frames, int channels); 
void printInfo(int frames, int channels, int sampleRate); 
void watermark(double *buffer, int count, int channels); 
void watermark2(double *buffer, int count); 
void readFile(int fileNumber); 
void printBuffer(double *buffer, size_t count); 

int main(void) 
{ 

    int chosenFile, answer; 

    printf("Please select the file you want to read\n"); 
    printf("1. File1\n"); 
    printf("2. File2\n"); 
    printf("3. File3\n"); 
    printf("4. File4\n"); 
    printf("5. File5\n"); 
    scanf("%d", &chosenFile); 

    processFile(chosenFile); 
    /* 
    Put boolean here to check whether to process the original file or the new one 
    */ 
    printf("Would you like to read the new file?\n"); 
    printf("1. Yes\n"); 
    printf("2. No\n"); 
    scanf("%d", &answer); 

    if (answer == 1) 
    { 
     readFile(chosenFile); 
    } 

} 

int processFile(int fileNumber) 
{ 
    /*READING FILE*/ 

    static double buffer[BUF_SIZE]; 
    SF_INFO info; 
    SNDFILE *infile,*outfile; 
    int readCount, i; 


    /* 
    Put boolean here to check whether it should read the original files, or the new output files 

    */ 
    char *Files[] = { "File1.wav", "File2.wav", "File3.wav" 
     , "File4.wav", "DFile5.wav" }; 

    char *Files2[] = { "File1Output.wav", "File2Output.wav", "File3Output.wav" 
     , "File4Output.wav", "File5Output.wav" }; 

    char *inputFile = Files[fileNumber - 1]; 

    if (!(infile = sf_open(inputFile, SFM_READ, &info))) 
    { 
     printf("Not able to open input file %s.\n", inputFile); 
     puts(sf_strerror(NULL)); 
     return 1; 
    }; 


    printf("You have opened: %s\n", Files[fileNumber - 1]); 
    printInfo(info.frames, info.channels, info.samplerate); 
    int num = numItems(info.frames, info.channels); 
    printf("Buffer(frames*channels): %d \n", num); 


    /*WRITING FILE*/  
    char *outputFile = Files2[fileNumber - 1]; 
    printf("Your file has been saved in the following location: %s\n", outputFile); 


    if (!(outfile = sf_open(outputFile, SFM_WRITE, &info))) 
    { 
     printf("Not able to open output file %s.\n", outputFile); 
     puts(sf_strerror(NULL)); 
     return 1; 
    }; 

    /* 
    Actual buffer size is numItems, somehow can't declare buffer as buffer[numItems] 
    BUF_SIZE is set to 1024, which means that it reads the data in chunks of 1024 frames 
    it will keep writing in 1024 chuncks until all numItems have been written (numItems/BUF_SIZE) 
    Needs to be on a while loop otherwise it will only write the first 1024 frames of the file 
    */ 


    while ((readCount = sf_read_double(infile, buffer, BUF_SIZE))) 
    { 

     watermark(buffer, readCount, info.channels); 
     sf_write_double(outfile, buffer, readCount); 
    }; 


    for (i = 0; i < sizeof(buffer)/sizeof *buffer; i++) 
    { 
     printBuffer(buffer, sizeof(buffer)/sizeof *buffer); 
    } 


    /* 
    Can only close SF_open once both reading/writing has been done 
    if you close infile after the read, it's not able to copy the audio 
    data from infile to write into outfile 
    */ 
    sf_close(infile); 
    sf_close(outfile); 


    return; 
} 

void readFile(int fileNumber) 
{ 
    SF_INFO info; 
    SNDFILE *infile; 

    char *Files[] = { "File1Output.wav", "File2Output.wav", "File3Output.wav" 
     , "File4Output.wav", "File5Output.wav" }; 

    char *inputFile = Files[fileNumber - 1]; 

    infile = sf_open(inputFile, SFM_READ, &info); 

    printf("You have opened: %s\n", Files[fileNumber - 1]); 
    printInfo(info.frames, info.channels, info.samplerate); 

    sf_close(infile); 

    return; 


} 

int numItems(int frames, int channels) 
{ 
    int numItems = frames * channels; 
    return numItems; 
} 
void printInfo(int frames, int channels, int sampleRate) 
{ 
    printf("Number of Frames = %d\n", frames); 
    printf("Number of Channels = %d\n", channels); 
    printf("Sample Rate = %d\n", sampleRate); 
} 

void watermark(double *buffer, int count, int channels) 
{  
    double value[MAX_CHANNEL] = { 0.0, 0.0 }; 
    int i, j; 

    if (channels > 1) 
    { 
     /* 
     Sets j to be the first channel and while i is less than 1024/5, i += channels 
     buffer[3] value is multiplied by 0, and set to 0 
     this mutes that particular index value or frame 
     this keeps going until i>=1024/5 and then the next channel is chosen where j = 2 
     buffer[4] value is multiplied by 0 and set to 0 
     this keeps going until i>=1024/5 where it calls back to the while loop in processFile 
     */ 

     for (j = 0; j < channels; j++) 
     { 
      for (i = j; i < count/5; i += channels) 
      { 
       buffer[i] *= value[j]; 
      } 
     } 
    } 
    else 
    { 
     /* 
     If audio file has 1 channel, buffer[i] is set to 0 for all values < 1024/5 frames 
     and it goes back to normal until the next 1024 frames where the first 1024/5 frames. 
     */ 
     for (i = 0; i < count/5; i++) 
     { 
      buffer[i] *= value[0]; 
     } 
    } 

    return; 
} 

void printBuffer(double *buffer, size_t count) 
{ 
    int i; 

    for (i = 0; i < count; i++) 
    { 
     if (i != 0) 
      printf("%d\n", buffer[i]); 
    } 
} 

/* 
- *DONE* - Need to create function that will read the newly outputted file 
- Find where the watermarks have been left on the audio 
- Compare buffer[] values between original file and new outputted file 
*/ 
+0

也許你打算寫'if(buffer [i]!= 0)'?你現在的狀況只是跳過第一次迭代。另外,你應該在'printf()'函數中使用'%lf'來打印double值。 –

+1

@HonzaDejdar:您必須使用'%lf'來讀取'scanf()'等中的double值。自C99以來,您可能會(可能不需要)使用'%lf'格式化'double'值。可選的原因是'float'值被默認的升級規則自動提升爲'double',這些規則適用於可變參數函數,如'printf',所以'printf'永遠不會傳遞'float',因此'%f '作爲'double'的原始傳統格式(並且,由於默認的促銷規則,'浮動')。 –

+0

@JonathanLeffler感謝您的文章,我不知道這一點。然而,業主使用'%d',我認爲這是錯誤的:) –

回答

0
while ((readCount = sf_read_double(infile, buffer, BUF_SIZE))) 
{ 

    watermark(buffer, readCount, info.channels); 
    sf_write_double(outfile, buffer, readCount); 
}; 

在這裏,你一次又一次地使用緩衝區中讀取一些數據,水印,並將其out.Only寫一旦你完成,你打印的最後剩餘的數據出來

for (i = 0; i < sizeof(buffer)/sizeof *buffer; i++) 
{ 
    printBuffer(buffer, sizeof(buffer)/sizeof *buffer); 
} 

所以,用

#define MAX_CHANNEL 2 
#define BUF_SIZE 1024 
:緩衝區

和具有16位44100立體聲的波形文件,如果您有像音樂一樣的普通音頻或幾乎沒有噪音的高質量錄音,您將只能看到最後5.8ms的聲音數據,可能幾乎是靜音。

此外:根據上次讀取的塊,您會看到文件的尾部,然後看到尾部之前的某個部分,就像您看到的最後3.2ms,然後是之前的2.6ms,未被覆蓋在上次閱讀電話中。

/編輯:好的,可能是我拿到的數字錯誤,數據類型是雙等,但在概念上的錯誤是一樣的。

/編輯2:看着喬納森·萊弗勒的評論,我看到有更多的錯誤... - 我建議開啓所有的編譯器警告,並試圖瞭解(和修復)他們。

+0

謝謝你。我甚至沒有考慮到音頻文件末尾的沉默。我在while循環中加入了'for循環',但是這需要更多的調整,所以我不需要遍歷所有的數據,而只需要一小部分。非常感謝你。 – user3604802

+0

請接受幫助你的答案。這是堆棧溢出的工作原理 –

相關問題