从音频中绘制波形的算法

yay*_*yuj 8 c++ algorithm audio ffmpeg

我正在尝试从原始音频文件中绘制波形.我使用FFmpeg对音频文件进行了解复用/解码,我有以下信息:样本缓冲区,样本缓冲区的大小,音频文件的持续时间(以秒为单位),采样率(44100,48000等),样本大小,样本format(uint8,int16,int32,float,double)和原始音频数据本身.

在互联网上挖掘我发现了这个算法(更多这里):

白噪声:

白噪声

算法

您需要做的就是将每个样本从-amplitude随机化为幅度.在大多数情况下,我们不关心通道的数量,因此我们只使用新的随机数填充每个样本.

Random rnd = new Random();
short randomValue = 0;

for (int i = 0; i < numSamples; i++)
{
    randomValue = Convert.ToInt16(rnd.Next(-amplitude, amplitude));
    data.shortArray[i] = randomValue;
}
Run Code Online (Sandbox Code Playgroud)

这真的很好,但我不想这样画,但这样:

大胆

是否有任何算法或想法如何使用我所拥有的信息绘制?

Mar*_*som 6

首先,您需要确定每个样本最终会在屏幕上的哪个位置.

int x = x0 + sample_number * (xn - x0) / number_of_samples;
Run Code Online (Sandbox Code Playgroud)

现在,对于具有相同的所有样本x,分别确定正值和负值的最小值和最大值.绘制一条垂直线,一条从负最大值到正最大值的暗线,然后是从负顶部到正面最小值的一条亮线.

编辑:考虑一下这个,你可能想要使用平均而不是内线的min.


Dil*_*eet 6

每个人的说明我是dj应用程序的开发人员,正在寻找类似的答案。因此,我将解释所有在包括audacity在内的任何软件中可能看到的音乐波形。

在任何音乐软件中都可以使用3种波形显示。即样本,平均值和均方根值。

1)样本是图形中显示的实际音乐点,可以是原始音频数据的数组(在以大胆缩放波形时看到的点)。

2)平均:最常用,假设您要在屏幕上显示3分钟的歌曲,因此屏幕上的单个点必须显示至少100ms(大约)具有很多原始音频点的歌曲,因此要显示,我们需要计算所有歌曲的平均值在该100ms持续时间内的点数,以此类推,在剩下的音轨中依此类推(胆大的深蓝色大波形)。

3)RMS:类似于平均值,但此处取平均值,而不是平均值,而是取特定持续时间的均方根(蓝色内部的小浅蓝色波形是大胆的rms波形)。

现在如何计算波形。

1)当您使用任何技术解码一首歌曲时,采样都是原始数据,您会获得原始采样/点。现在基于点的格式,将它们转换为-1到1的范围,例如,如果格式为16位,则将所有点除以32768(16位数字的最大范围),然后绘制点。

2)对于平均波形-首先将所有将负值转换为正值的点相加,然后乘以2,然后取平均值。

//samples is the array and nb_samples is the length of array
float sum = 0;
for(int i = 0 ; i < nb_samples ; i++){
    if(samples[i] < 0)
        sum += -samples[i];
    else
        sum += samples[i];
}
float average_point = (sum * 2) / nb_samples; //average after multiplying by 2
//now draw this point
Run Code Online (Sandbox Code Playgroud)

3)RMS:其简单取均方根-因此,首先对每个样本求平方,然后取总和,然后计算均值,再取均方根。我将在节目中展示

//samples is the array and nb_samples is the length of array
float squaredsum = 0;
for(int i = 0 ; i < nb_samples ; i++){
    squaredsum += samples[i] * samples[i]; // square and sum
}
float mean = squaredsum / nb_samples; // calculated mean
float rms_point = Math.sqrt(mean); //now calculate square root in last
//now draw this point
Run Code Online (Sandbox Code Playgroud)

请注意,这里的样本是点的数组,用于计算特定歌曲持续时间的点/像素。例如,如果您想以60像素绘制1分钟的歌曲数据,则样本数组将是1秒内所有点的数组,即以1像素显示的音频点数。

希望这将有助于有人阐明有关音频波形的概念。

  • 在自己做了一些研究和实验之后,我发现计算每个点的最大值和最小值(原始文件中的样本窗口)并向上绘制最大值,向下绘制最小值(我也计划将算法作为答案发布)看起来最接近我尝试过的所有音频软件(Reaper、Audacity、Reason、Live)。当遵循“平均方法”时,波形会显着缩小,我必须再次将其放大,才能获得不错的结果,这看起来与最小/最大方法或我在常见 DAW 中看到的结果有很大不同。 (2认同)

use*_*265 5

我认为您指的是此处描述的波形。

http://manual.audacityteam.org/o/man/audacity_waveform.html

我还没有阅读整页。但是每个垂直条代表一个波形样本窗口。深蓝色是该窗口中的最大正值和最小负值(我认为)。浅蓝色是均方根的RMS。 http://www.mathwords.com/r/root_mean_square.htm。(基本上,您将每个窗口内的值平方,取平均值,然后平方根。

希望这可以帮助。