如何以对数方式绘制数据
How to plot data logarithmically
我已经对音频信号进行了 FFT,并希望像这样在对数刻度上绘制结果
http://abletonuniverse.altervista.org/wp-content/uploads/2013/04/Spectrum.jpg
但出于某种原因,我无法弄清楚如何缩放数据以适应该对数曲线(从 0 开始,以奈奎斯特频率结束,即采样率/块大小)。
目前我有这个
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 个分贝点。忽略绘图点的 y 分量。
我的数据没有正确缩放,因为我的第一个 bin (~43 hz) 是 log10(43)= 1.633,图表的末尾是 log10(22050) = 4.3,所以我的 space第一个垃圾箱占据了 window 的三分之一以上。重要的是我不只是把我的第一个垃圾桶放在 window 的最左边,最左边必须是 0。
有人知道将数据缩放到如图所示的整齐对数 bin 中的正确方法吗?他们有三个整齐的容器,代表 10 的数量级,它很方便地在 22050 处结束。
供参考,这是我现在拥有的,您可以看到光谱左侧的长直线。该行的第一个扭结点是 43 赫兹,即我的第一个垃圾箱。我还没有建立网格,但是当我弄清楚缩放比例时就会出现。
0Hz 频率不能显示在对数标度频率轴上。您引用的图表上显示的左侧对应于 10Hz。您可以映射频率坐标,使选定的最小频率(例如 minFrequencyToDisplay=10Hz
)绘制在值 x=0
处,最后一个 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的网格线
我已经对音频信号进行了 FFT,并希望像这样在对数刻度上绘制结果
http://abletonuniverse.altervista.org/wp-content/uploads/2013/04/Spectrum.jpg
但出于某种原因,我无法弄清楚如何缩放数据以适应该对数曲线(从 0 开始,以奈奎斯特频率结束,即采样率/块大小)。
目前我有这个
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 个分贝点。忽略绘图点的 y 分量。
我的数据没有正确缩放,因为我的第一个 bin (~43 hz) 是 log10(43)= 1.633,图表的末尾是 log10(22050) = 4.3,所以我的 space第一个垃圾箱占据了 window 的三分之一以上。重要的是我不只是把我的第一个垃圾桶放在 window 的最左边,最左边必须是 0。
有人知道将数据缩放到如图所示的整齐对数 bin 中的正确方法吗?他们有三个整齐的容器,代表 10 的数量级,它很方便地在 22050 处结束。
供参考,这是我现在拥有的,您可以看到光谱左侧的长直线。该行的第一个扭结点是 43 赫兹,即我的第一个垃圾箱。我还没有建立网格,但是当我弄清楚缩放比例时就会出现。
0Hz 频率不能显示在对数标度频率轴上。您引用的图表上显示的左侧对应于 10Hz。您可以映射频率坐标,使选定的最小频率(例如 minFrequencyToDisplay=10Hz
)绘制在值 x=0
处,最后一个 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的网格线