首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >用JTransform库可视化PCM数据

用JTransform库可视化PCM数据
EN

Stack Overflow用户
提问于 2018-05-28 15:41:41
回答 1查看 602关注 0票数 1

我正在尝试展示一些PCM数据的可视化效果。目标是显示类似以下内容的内容:

我搜索了一下,发现JTransform是正确的库。但是,我找不到一个好的指南来指导如何使用这个库。如何将PCM数据转换为可用于绘制条形图的频带/频率数据?

非常感谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-29 02:18:10

PCM音频是模拟音频曲线的数字化简化。这个时域信号可以被馈送到离散傅立叶变换api调用中,以将数据转换为其频域等效信号...虚数和欧拉公式是你的朋友

最简单的部分是调用fft,它更复杂的是解析它的输出...用你的PCM中的至少1024点(确保它是2的幂)填充一个缓冲区,然后把它输入到一些fft api调用中……这将返回给你它的频域等价物。无论你使用哪种离散傅立叶变换api调用,都可以锁定文档...查找奈奎斯特极限的概念。掌握频点的概念……保持每个缓冲区的采样数量和PCM音频的采样速率

请注意,随着输入到傅立叶变换的音频样本(音频曲线上的PCM点)数量的增加,从该呼叫返回的频率分辨率越高,但是,如果您的音频是音乐之类的动态信号(而不是静态音调),这会降低时间特异性

这是我用golang编写的一个函数,它是对DFT调用的包装,我给它提供了一个PCM原始音频缓冲区,它被归一化为从-1到+1的浮点数,其中它进行离散傅立叶变换(fft)调用,然后使用从DFT返回的复数组来计算每个频率域的幅值。项目的一部分,它通过观看视频(一次一个图像)来合成音频,然后它可以收听音频来合成输出图像……实现了输出照片与输入照片基本匹配的目标......输入图像->音频->输出图像

代码语言:javascript
复制
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,其中数组的每个元素都是该频率段的大小……每个频率单元由由上述变量incr_freq定义的频率增量均匀地间隔。使用min和max_magnitude来归一化大小...它准备好输入到X,Y图中,为您提供谱图可视化

我建议打开一些书..。观看我在上面的评论中提到的视频…我一直在探索傅里叶变换的奇妙之处,因为我是一名EE本科生,它充满了令人惊讶的应用,它的理论仍然是一个非常活跃的研究领域

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50561419

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档