objective-c - 如何以对数方式绘制数据

标签 objective-c audio graphics fft

我已经对音频信号进行了 FFT,并希望将结果绘制在对数刻度上,如下所示

http://abletonuniverse.altervista.org/wp-content/uploads/2013/04/Spectrum.jpg

但由于某种原因,我无法弄清楚如何缩放数据以适应该对数曲线(从 0 开始,以奈奎斯特频率结束,即采样率/ block 大小)。

目前这就是我所拥有的

CGContextMoveToPoint(context, 0, rect.size.height);

// Skip the DC Offset (index 0)
for (int i = 1; i < _bins; i++) {
    // Get frequency from bin
    float binFreq = i * 44100.0 / (_bins * 2);

    // Map to rect coordinate space
    float x = log10f(binFreq) * rect.size.width / log10f(44100.0 / 2);
    float y = _freqArray[i] * rect.size.height / -130.0;

    // Draw line
    CGContextAddLineToPoint(context, x, y);
}

我的数据在 _freqArray 中为 0 到 ~-130 之间的 512 个 dB 点。忽略绘制点的 y 分量。

我的数据未正确缩放,因为我的第一个 bin (~43 hz) 是 log10(43)= 1.633,而图表的末尾是 log10(22050) = 4.3,因此我的第一个 bin 之间的空间占用了 window 的三分之一。重要的是,我不只是将第一个垃圾箱放在窗口的最左侧,最左侧必须为 0。

有人知道将数据缩放到如图所示的整齐对数箱的正确方法吗?它们有三个整齐的 bin,代表 10 的数量级,并且很方便地以 22050 结束。

作为引用,这就是我现在拥有的,您可以看到光谱左侧的长直线。该行中的第一个拐点是 43 Hz,即我的第一个 bin。我还没有建立一个网格,但是当我弄清楚缩放比例时就会出现。 enter image description here

最佳答案

0Hz 频率无法显示在对数刻度频率轴上。您引用的图表中显示的左侧对应于 10Hz。您可以映射频率坐标,以便在值 x=0 处绘制所选的最小频率(例如 minFrequencyToDisplay=10Hz),并在值处绘制最后一个 bin x=rect.size.width-1,如下所示:

// Map to rect coordinate space
float logMinFreq = log10f(minFrequencyToDisplay);
float x = (log10f(binFreq)-logMinFreq ) * (rect.size.width-1) /
          (log10f(44100.0 / 2)-logMinFreq );

使用相同的公式可以得到100Hz、1kHz和10kHz的网格线。

关于objective-c - 如何以对数方式绘制数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31142335/

相关文章:

iphone - CGBitmapContextCreate 的内存使用率非常高

r - 使用 ggplot2 绘制 pca biplot

ios - 需要帮助设置自定义单元格

android - 如何使 SpeechRecognizer 的蜂鸣声静音?

c# - 使用DirectSound设置不同的音频输出

javascript - 在 Android 上的音频元素中播放 blob

php - 寻找用于交互式网络对象演示的 PHP/Flash 图形库

java - 在 Java 中缩放像素数组

iphone - 解析 XML 内部 XML 标签 Objective-C

ios - NSURLSession 和多线程