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、 如果足够放大,每个示例将有多个像素。我怀疑调用外部应用程序绘制位图是否可行。我正在每秒更新位图多次。