我正在编写一个应用程序,需要获取音频文件的原始波形数据,以便我可以在应用程序(C#/ .NET)中呈现它。我正在使用ffmpeg卸载此任务,但看起来ffmpeg只能output the waveform data as a png or as a stream to gnuplot。
我已经看过其他库来做这件事(NAudio / CSCore),但是他们需要windows / microsoft media foundation,因为这个应用程序将作为web应用程序部署到azure我不能使用它们。
我的策略是从png本身读取波形数据,但这看起来很糟糕而且在顶部。理想的输出是阵列中固定采样的一系列峰值,其中数组中的每个值都是峰值(范围从1-100或其他东西,例如this)。
答案 0 :(得分:2)
Sabona budi,
写了关于手动获取波形的方法,然后给你看一个例子,我发现this code
可以做你想要的(或者至少,你可以从中学到一些东西)。
1)使用FFmpeg获取样本数组
尝试此处显示的示例代码:http://blog.wudilabs.org/entry/c3d357ed/?lang=en-US
尝试使用它,尝试使用手动等建议进行调整...在显示的代码中,只需将string path
更改为指向您自己的文件路径。修改proc.StartInfo.Arguments
部分,将最后一部分替换为:
proc.StartInfo.Arguments = "-i \"" + path + "\" -vn -ac 1 -filter:a aresample=myNum -map 0:a -c:a pcm_s16le -f data -";
myNum
部分中aresample=myNum
的计算方式为:
44100 * total Seconds = X.
myNum = X / WaveForm Width.
最后使用ProcessBuffer
函数和这个逻辑:
static void ProcessBuffer(byte[] buffer, int length)
{
float val; //amplitude value of a sample
int index = 0; //position within sample bytes
int slicePos = 0; //horizontal (X-axis) position for pixels of next slice
while (index < length)
{
val = BitConverter.ToInt16(buffer, index);
index += sizeof(short);
// use number in va to do something...
// eg: Draw a line on canvas for part of waveform's pixels
// eg: myBitmap.SetPixel(slicePos, val, Color.Green);
slicePos++;
}
}
如果您想手动without FFmpeg。你可以试试......
2)将音频解码为PCM
您可以将音频文件(mp3)加载到您的应用程序中,然后首先将其解码为PCM(即:原始数字音频)。然后只读取PCM编号以生成波形。不要直接从压缩数学字节中读取数字,如MP3。
这些PCM数据值(关于音频幅度)进入字节数组。如果您的声音是16位,那么您通过将每个样本读取为short
(即一次获得两个连续字节的值)来提取PCM值16 bits == 2 bytes length
)。
基本上,当一个字节数组中有16位音频PCM时,每两个字节代表一个音频样本的幅度值。此值会在每个切片处变为高度(响度)。切片是波形中 time 的1像素垂直线。
现在采样率表示每秒采样数。通常44100个样本(44.1 khz )。您可以看到使用44,000个像素来表示一秒钟的声音是不可行的,因此divide
所需的波形width
总计为multiply
。取结果&amp; while
乘以2(覆盖两个字节),这就是你在形成波形时跳跃 - 和 - 采样幅度的方式。在left
循环中执行此操作。
答案 1 :(得分:0)
您可以使用this tutorial中描述的功能将从音频文件解码的原始数据作为double
值数组。