我正在尝试从原始音频文件中绘制波形。我使用FFmpeg对音频文件进行了解复用/解码,我有以下信息:样本缓冲区,样本缓冲区的大小,音频文件的持续时间(以秒为单位),采样率(44100,48000等),样本大小,样本format(uint8,int16,int32,float,double)和原始音频数据本身。
在互联网上挖掘我发现了这个算法(更多here):
白噪声:
算法
您需要做的就是将每个样本从-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;
}
这真的很好,但我不想这样画,但这样:
我是否有任何算法或想法可以使用我所拥有的信息进行绘制?
答案 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)
ffmpeg
可以使用showwavespic
过滤器绘制波形。
ffmpeg -i input -filter_complex "showwavespic=split_channels=1" output.png
有关选项,请参阅showwavespic
filter documentation。
您还可以使用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个样本中最多得到一个不那么不稳定的图形,它是一个快速混叠的孩子。