【问题标题】:Convert encoded audio file to text with signal values将编码的音频文件转换为带有信号值的文本
【发布时间】:2018-01-16 12:24:46
【问题描述】:

我第一次用 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");

附言我已经知道如何读取音频文件的标题,其中包含很多有用的信息,但我也想逐个样本地分析整个音频文件。

【问题讨论】:

    标签: c audio ffmpeg


    【解决方案1】:

    我刚刚编译然后运行您的代码...输出文件 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 仅表示均方根或信号平方的算术平均值的平方根。

    实际上,这意味着高幅度、尖峰、瞬态内容的信号可以具有与幅度较低但波形较宽的信号相同的 RMS 值 - 因为它们都具有相同的能量含量。如果将它们通过扬声器,它们应该会产生相同的声能输出。

    典型的尖峰波形是鼓瞬变之类的东西,而较粗的波形是正弦波甚至是方波(尽可能胖),其中需要低得多的峰值电平才能获得相同的功率(正弦波1.4Vp 的 RMS 电平与 1.0Vp 的方波相同)。

    ...这应该让你开始

    PS popen is doing a stream read from the input file

    【讨论】:

      猜你喜欢
      • 2014-04-29
      • 1970-01-01
      • 1970-01-01
      • 2018-12-19
      • 2021-10-05
      • 1970-01-01
      • 1970-01-01
      • 2020-12-08
      • 1970-01-01
      相关资源
      最近更新 更多