我第一次使用音频文件在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。我已经知道如何读取音频文件的标题,其中包含许多有用的信息,但我也想分析整个音频文件,逐个样本。
答案 0 :(得分:4)
我刚刚编译然后运行你的代码...输出文件samples.csv是一个带符号16位整数的垂直列,代表输入音频曲线的每个样本......如:YMMV
-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]
值从最小值到最大值遍历整个可能的范围,那么您的音频样本范围可以说是全音量...现在我们处于一个位置解释上述测量:min_value和max_value ...如果min_value在-16384附近,如果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平均信号所取代的区域,即波形与线性零线之间的区域(不是0dB,而是轴)。
当波形在中心线上方(+)和下方( - )摆动时,必须忽略摆动的极性。幸运的是,在数学中,任何乘以其自身(平方)的东西都会变成正数。然后可以对信号进行平均(在时间线/窗口ED提及的算术平均值或其积分时间),因为正和负半部现在相互抵消 - 并且最终执行平方反转 - 平方根。
RMS只表示均方根或信号平方算术平均值的平方根。
实际上,这意味着高振幅,spikey,瞬态内容的信号可以具有与较低振幅但较胖的波形相同的RMS值 - 因为它们都具有相同的能量含量。如果你把它们放在扬声器中,它们都应该产生相同的声能输出。
典型的spikey波形就像鼓瞬态,而较胖的波形可能是正弦波甚至是方波(尽可能胖),其中需要更低的峰值才能获得相同的功率(正弦波) 1.4Vp具有与1.0Vp的方波相同的RMS水平。
......这应该让你开始