2017-08-08 70 views
2

我一直在用c編程音頻文件。我發現這個代碼應該讀取一個音頻文件,然後編寫一個包含幾個信息的csv文件來分析音頻波,以防萬一是一個簡單的聲音:我對音色的振幅感興趣,在音色的聲音和它的高度和延伸。將編碼的音頻文件轉換爲帶有信號值的文本

  main() { 
      // Create a 20 ms audio buffer (assuming Fs = 44.1 kHz) 
      int16_t buf[N] = {0}; // buffer 
      int n;    // buffer index 

      // Open WAV file with FFmpeg and read raw samples via the pipe. 
      FILE *pipein; 
      pipein = popen("ffmpeg -i whistle.wav -f s16le -ac 1 -", "r"); 
      fread(buf, 2, N, pipein); 
      pclose(pipein); 

      // Print the sample values in the buffer to a CSV file 
      FILE *csvfile; 
      csvfile = fopen("samples.csv", "w"); 
      for (n=0 ; n<N ; ++n) fprintf(csvfile, "%d\n", buf[n]); 
      fclose(csvfile); 

     } 

有人可以解釋我詳細如何讀取音頻文件,以便我可以從中提取我需要的信息?參考此代碼,有人可以解釋我在第8行管道的含義

pipein = popen("ffmpeg -i whistle.wav -f s16le -ac 1 -", "r"); 

p.s.我已經知道如何讀取包含大量有用信息的音頻文件的標題,但我也想分析整個音頻文件,並通過示例進行分析。

回答

3

我剛剛編譯然後跑到你的代碼...輸出文件samples.csv是簽署16位整數的垂直列代表每個輸入音頻曲線的樣本......在:因人而異

-20724 
-19681 
-18556 
-17359 
-16096 
-14766 
-13383 
-11940 
-10460 
-8928 
-7371 
-5778 
-4165 
-2536 
-897 
749 
2385 
4019 
5633 
7224 
8793 
10318 
11811 
13251 
14644 
15977 
17247 

...因此而原始音頻是在變量buf您可以添加到您上面的代碼爲您解答

- 音頻是一個曲線,當曲線不能搖晃它的沉默。在計算音量時,理解比特深度的意義...我建議你在文本編輯器中打開輸出文件來觀察每個值...知道你有一個16位的深度告訴你可能的整數值的數量......在一個空白的盯着read up on PCM raw audio ...第一個近似值你的代碼以下更改會告訴你的音量

int min_value = 9999; 
int max_value = -9999; 

for (n=0 ; n < N ; ++n) { 

    if (buf[n] < min_value) min_value = buf[n]; 
    if (buf[n] > max_value) max_value = buf[n]; 

    fprintf(csvfile, "%d\n", buf[n]); 
} 

fclose(csvfile); 

printf("min_value %d\n", min_value); 
printf("max_value %d\n", max_value); 

知道你的音頻的比特深度,可以說,其16位的,那麼你有2^16個可能的不同的整數...比如從0至(65536 - 1)表示你原始音頻的曲線......也就是說,如果你的數據是無符號的......如果它的帶符號整數(如WAV文件頭中定義的那樣)然後移動該範圍使其零中心......然後範圍將從-32768到(+32768 - 1)或從-32768到+32767 ...因此,如果您的音頻buf[n]值遍歷整個possi ble範圍從最小值到最大值,那麼您的音頻樣本可以說是全音量......現在我們可以解釋上述測量值:min_value和max_value ...如果min_value大約在-16384,並且if max_value約爲+16384,那麼音量約爲最大值的一半,因爲它只消耗整數值範圍的一半

因此可以計算範圍從0到1(最小音量到最大音量)的音量(通過簡單化)使用此公式

num_possible_ints = 2^bit_depth // == 65536 for bit depth of 16 bits 
volume = 1 - (num_possible_ints - (max_value - min_value))/num_possible_ints 

爲什麼這是過於簡單化了?因爲如果不預先處理音頻緩衝區[通過丟棄極少激增到最大值或最小值的外圍音頻樣本,如果需要的話],這種方法很容易給出太高的音量測量結果

有更好的音量測量但保持在介意其容易感知的偏差...... lookup Root Mean Square to calculate volume with better accuracy ... to quote :

RMS均通過信號,波形和線性零線(未0分貝,但軸)之間的區域移動的區域。由於波形在中心線上方(+)和下方( - )兩者之間擺動,擺動的極性必須被忽略。幸運的是,在數學中,任何乘以自身(平方)的東西都會產生積極的結果。然後可以對信號進行平均(在時間軸/窗口ED提及或其積分時間內的算術平均值),因爲正半部和負半部不會相互抵消 - 最終與平方相反執行 - 平方根。

RMS只是意味着均方根或信號平方的算術平均值的平方根。

實際上,它意味着高幅度,尖峯,瞬態內容的信號可以具有與較低幅度但較胖的波形相同的RMS值 - 因爲它們都具有相同的能量含量。如果你通過揚聲器放置它們,它們都應該產生相同的聲能輸出。

典型的spikey波形是類似於鼓瞬態的波形,而較胖的波形將是正弦波或者甚至是方波(就像你可以得到的那樣),其中需要低得多的峯值電平以具有相同的功率1.4Vp的波與1.0Vp的方波具有相同的RMS電平)。

...這應該讓你開始

PSpopen is doing a stream read from the input file

相關問題