Algorithm 如何可视化音频数据?
我想要一些像这样的东西。不需要两种不同的颜色Algorithm 如何可视化音频数据?,algorithm,language-agnostic,math,graphics,audio,Algorithm,Language Agnostic,Math,Graphics,Audio,我想要一些像这样的东西。不需要两种不同的颜色 (来源:) 我已经有了两个int数组中立体声wav的音频数据(一个采样/毫秒),左声道和右声道各一个。我做了几次尝试,但看起来没有这么清晰,我的尝试变得尖利或紧凑 有什么好的建议吗?我在c#工作,但psuedocode还可以 假设我们有 函数绘制线(颜色,x1,y1,x2,y2) 两个int数组,数据长度为L的右[]和左[] 数据值介于32767和-32768之间 如果你做了任何其他的假设,就把它们写在你的答案里 for(i = 0; i &l
(来源:) 我已经有了两个int数组中立体声wav的音频数据(一个采样/毫秒),左声道和右声道各一个。我做了几次尝试,但看起来没有这么清晰,我的尝试变得尖利或紧凑 有什么好的建议吗?我在c#工作,但psuedocode还可以 假设我们有
- 函数绘制线(颜色,x1,y1,x2,y2)
- 两个int数组,数据长度为L的右[]和左[]
- 数据值介于32767和-32768之间
for(i = 0; i < L - 1; i++) {
// What magic goes here?
}
for(i=0;i
这就是我申请时的结果。(只有一个频道)您可能需要研究这方面的语言。我对它没有太多经验,但它主要用于统计分析/可视化场景。如果他们没有一些平滑函数来消除你提到的极端情况,我会感到惊讶
而且,将数据导入其中应该不会有问题。您不仅可以读取平面文本文件,而且它的设计也便于使用C进行扩展,因此可能还存在某种C#接口。每个像素可能有一个以上的样本。对于映射到单个像素的每组采样,可以从采样组中的最小值到最大值绘制(垂直)线段。如果放大到每像素1个采样或更少,这将不再起作用,“好”的解决方案是显示sinc插值。 因为DrawLine无法绘制单个像素,所以当最小值和最大值相同时,会出现一个小问题。在这种情况下,您可以在所需位置复制单个像素图像,如下代码所示:
double samplesPerPixel = (double)L / _width;
double firstSample = 0;
int endSample = firstSample + L - 1;
for (short pixel = 0; pixel < _width; pixel++)
{
int lastSample = __min(endSample, (int)(firstSample + samplesPerPixel));
double Y = _data[channel][(int)firstSample];
double minY = Y;
double maxY = Y;
for (int sample = (int)firstSample + 1; sample <= lastSample; sample++)
{
Y = _data[channel][sample];
minY = __min(Y, minY);
maxY = __max(Y, maxY);
}
x = pixel + _offsetx;
y1 = Value2Pixel(minY);
y2 = Value2Pixel(maxY);
if (y1 == y2)
{
g->DrawImageUnscaled(bm, x, y1);
}
else
{
g->DrawLine(pen, x, y1, x, y2);
}
firstSample += samplesPerPixel;
}
double samplesperpoixel=(double)L/\u宽度;
双第一样本=0;
int endSample=firstSample+L-1;
用于(短像素=0;像素<_宽度;像素++)
{
int lastSample=u min(endSample,(int)(firstSample+samplesPerPixel));
双Y=_数据[channel][(int)firstSample];
双minY=Y;
双maxY=Y;
对于(int-sample=(int)firstSample+1;样本DrawImageUnscaled(bm,x,y1);
}
其他的
{
g->DrawLine(画笔,x,y1,x,y2);
}
firstSample+=每像素采样数;
}
请注意,Value2Pixel将采样值缩放为像素值(在y方向)。Audacity是开源的,因此您可以查看代码。我假设如下……func getHeight(v){return abs(v)*32767/viewArea.height/2);samplesPerPixelColumn=samples.len/viewArea.width;对于I=1到viewArea.width{avgV=Avg(示例[i-i+samplesPerPixelColumn]);colHeight=getHeight(avgV);如果avgV>=0绘制线(黑色,i,viewArea.height/2,i,(viewArea.height/2)+colHeight)其他绘制线(黑色,i,viewArea.height/2,i,(viewArea.height/2)-colHeight);你可能需要在那里做一些舍入/范围处理,但这应该是要点。你为什么不把它放在一个答案中。我想给你一些可能立即有用的东西,但如果有一部分被否决了,就不会被否决。更多想法:不是垂直线,而是在上一个图形点和下一个图形点之间画对角线……Also、 如果足够放大,每个示例将有多个像素。我怀疑调用外部应用程序绘制位图是否可行。我正在每秒更新位图多次。