从音频中绘制波形的算法

时间:2014-10-30 21:17:53

标签: c++ algorithm audio ffmpeg

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

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

白噪声:

White Noise

算法

  

您需要做的就是将每个样本从-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;
}

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

audacity

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

7 个答案:

答案 0 :(得分:6)

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

int x = x0 + sample_number * (xn - x0) / number_of_samples;

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

编辑:再考虑一下这个问题,你可能想用内线代替min而不是min。

答案 1 :(得分:5)

每个人的解释 我是一个dj应用程序的开发人员,正在寻找类似的答案。 所以我将解释你在任何软件中可能看到的音乐波形,包括大胆。

有三种类型的波形用于在任何音乐软件中显示。 即样本,平均值和RMS。

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

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

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

希望这有助于某人澄清有关音频波形的概念。

答案 2 :(得分:3)

BBC R&amp; D有一个很好的节目audiowaveform可以做你想要的,你可以咨询他们的来源。

答案 3 :(得分:3)

我认为你指的是这里描述的波形。

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

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

希望这会有所帮助。

答案 4 :(得分:2)

showwavespic

ffmpeg可以使用showwavespic过滤器绘制波形。

enter image description here

ffmpeg -i input -filter_complex "showwavespic=split_channels=1" output.png

有关选项,请参阅showwavespic filter documentation

showwaves

您还可以使用showwaves滤镜制作实时波形的视频。

ffmpeg -i input -filter_complex \
"showwaves=s=600x240:mode=line:split_channels=1,format=yuv420p[v]"  \
-map "[v]" -map 0:a -movflags +faststart output.mp4

有关选项,请参阅showwaves filter documentation

答案 5 :(得分:1)

底部图表只包含较长的时间跨度,因此如果您增加了numSamples,您将获得更严格的图表。但是,在白噪声的情况下,您将看不到正常声音/音乐中的峰值和低谷。

因此,如果您可以增加样本量,或者至少增加样本周期(x轴),您将开始模拟底部图表。使用其中两个来获得立体声效果。

答案 6 :(得分:1)

第二个波形可能是简单曲折图的列近似。

每列都是从前一个样本幅度到当前样本幅度的一条线。

因此,将所有样本读取到画布或纹理作为预测试点作为点,然后,一旦完成,您可以做两种情况,制作条形而不是点,向上绘制到最后一个样本或向上到此样本取决于哪个更高,只要你在两个之间划一条线。这确保了波形很小,下一个样本之间的能量很低,而高能量则很高。

您可以对其进行别名并测量多个样本,它只取决于您运行的硬件,如果您想要读取1000d样本并对波形进行巨大的二维数组表示,然后将其向下混合为较小的可显示图像或者如果您只想运行512个样本并快速更新。在程序中使用2d画布时,应该可以快速制作超过512个样本的详细波形。

...另一个选项与另一个答案中的灰色波形相同,将绝对值绘制为从+当前样本到当前样本的行。

它有助于平均多个样本,即每4个样本或每4个样本中最多得到一个不那么不稳定的图形,它是一个快速混叠的孩子。