Android 使用 JTransform 库可视化 PCM 数据
Posted
技术标签:
【中文标题】Android 使用 JTransform 库可视化 PCM 数据【英文标题】:Android visualize PCM data with JTransform library 【发布时间】:2018-05-28 07:41:40 【问题描述】:我正在尝试显示一些 PCM 数据的一些可视化效果。 目标是显示如下内容:
我搜索并发现 JTransform 是正确的库。但是,我找不到如何使用这个库的好指南。如何将我的 PCM 数据转换为可用于绘制条形的频段/频率数据?
非常感谢。
【问题讨论】:
你有没有得到这样的工作示例?我正在尝试做同样的事情。 【参考方案1】:PCM 音频是模拟音频曲线的数字化简化......这个时域信号可以输入离散傅里叶变换 api 调用,将数据转换为其等效频域......虚数和欧拉公式是您的朋友
最简单的部分是调用fft,它更多地涉及解析它的输出...... 从您的 PCM 中填充至少 1024 个(确保其为 2 的幂)点的缓冲区,然后将其输入到一些 fft api 调用中……这将返回给您它的频域等效项……将文档钉在任何一个上您使用的离散傅里叶变换 api 调用 ... 奈奎斯特极限的查找概念 ... 频率仓的主要概念 ... 随时掌握每个缓冲区的样本数和 PCM 音频的采样率
请注意,当您增加输入傅里叶变换的音频样本数量(音频曲线上的 PCM 点)时,从该调用返回的频率分辨率越精细,但是如果您的音频是一些动态信号,例如音乐(相反静态音调)这会降低时间特异性
这是我在 golang 中编写的一个函数,它是对 DFT 调用的包装器,我将 PCM 原始音频缓冲区归一化为浮点数,从 -1 到 +1 进行离散傅立叶变换(fft ) 调用然后使用从 DFT 返回的复数数组计算每个频率区间的幅度......通过观看视频(一次图像)合成音频的项目的一部分,然后它可以收听该音频以合成输出图像。 .. 实现了输出照片在很大程度上与输入照片匹配的目标......输入图像 -> 音频 -> 输出图像
func discrete_time_fourier_transform(aperiodic_audio_wave []float64, flow_data_spec *Flow_Spec) ([]discrete_fft, float64, float64, []float64)
min_freq := flow_data_spec.min_freq
max_freq := flow_data_spec.max_freq
// https://www.youtube.com/watch?v=mkGsMWi_j4Q
// Discrete Fourier Transform - Simple Step by Step
var complex_fft []complex128
complex_fft = fft.FFTReal(aperiodic_audio_wave) // input time domain ... output frequency domain of equally spaced freqs
number_of_samples := float64(len(complex_fft))
nyquist_limit_index := int(number_of_samples / 2)
all_dft := make([]discrete_fft, 0) // 20171008
/*
0th term of complex_fft is sum of all other terms
often called the bias shift
*/
var curr_real, curr_imag, curr_mag, curr_theta, max_magnitude, min_magnitude float64
max_magnitude = -999.0
min_magnitude = 999.0
min_magnitude = 999.0
all_magnitudes := make([]float64, 0)
curr_freq := 0.0
incr_freq := flow_data_spec.sample_rate / number_of_samples
for index, curr_complex := range complex_fft // we really only use half this range + 1
// if index <= nyquist_limit_index
if index <= nyquist_limit_index && curr_freq >= min_freq && curr_freq < max_freq
curr_real = real(curr_complex) // pluck out real portion of imaginary number
curr_imag = imag(curr_complex) // ditto for im
curr_mag = 2.0 * math.Sqrt(curr_real*curr_real+curr_imag*curr_imag) / number_of_samples
curr_theta = math.Atan2(curr_imag, curr_real)
curr_dftt := discrete_fft
real: 2.0 * curr_real,
imaginary: 2.0 * curr_imag,
magnitude: curr_mag,
theta: curr_theta,
if curr_dftt.magnitude > max_magnitude
max_magnitude = curr_dftt.magnitude
if curr_dftt.magnitude < min_magnitude
min_magnitude = curr_dftt.magnitude
// ... now stow it
all_dft = append(all_dft, curr_dftt)
all_magnitudes = append(all_magnitudes, curr_mag)
curr_freq += incr_freq
return all_dft, max_magnitude, min_magnitude, all_magnitudes
现在您有一个数组 all_magnitudes,其中数组的每个元素都是该频率区间的幅度...每个频率区间均按上述 var incr_freq 定义的频率增量均匀间隔...使用 min 和 max_magnitude 标准化幅度...它已准备好输入 X、Y 图,为您提供频谱图可视化
我建议打开一些书籍...观看我在上面提到的视频...我探索傅里叶变换奇迹的旅程一直在进行,因为我是一名 EE 本科生,其中充满了令人惊讶的应用程序及其理论仍然是一个非常活跃的研究领域
【讨论】:
以上是关于Android 使用 JTransform 库可视化 PCM 数据的主要内容,如果未能解决你的问题,请参考以下文章