如何在x轴上以频率生成matlab中wav文件的谱图

时间:2016-07-13 19:02:50

标签: android matlab audio spectrogram

作为研究项目的一部分,我想通过生成它的光谱图来分析声音文件。

我已经能够在matlab中成功生成波形文件的光谱图,其中y轴为频率,x轴为时间。但是,我想生成频谱图,其频率在x轴上,时间在y轴上。怎么办呢?

我搜索了堆栈,但没有找到任何可接受的答案。

我的代码生成频谱图,其频率在y轴上,时间在x轴上(Matlab代码):

[song, fs] = wavread('filename.wav');
windowSize = 256;
windowOverlap = [];
freqRange = 0:300;
spectrogram(song, windowSize, windowOverlap, freqRange, fs, 'yaxis');

我更改了参数' yaxis'在函数谱图中,对于xaxis'现在频率在x轴上,时间在y轴上。但是,我得到的光谱图与可靠光源产生的光谱图不同。

以下是我生成的频谱图 - spectrogram

从可靠来源生成的频谱图(我没有代码)。

reliable_spectrogram

此外,两种色谱图的配色方案都不同。我的录音长度为50秒,而标签上显示的时间为9秒。我该如何解决这些问题?

我的最终任务是能够在Android设备上生成频谱图(可能使用android中的GraphView库)。所以我必须编写代码来用Java生成频谱图。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:3)

前言

很抱歉,我没有Mathworks放置spectrogram的任何-toolbox,但这里有一些我放在公共领域的代码,可以帮我完成工作。

它比spectrogram更实际,但具有后者的许多功能,因为我将演示使用Matlab附带的handel音频剪辑('Hallelujah!')。

设置

我不会假设您熟悉git或Matlab名称空间。

  1. 在Matlab路径的某处创建一个名为+arf的目录(例如,~/Documents/MATLAB甚至是您当前的代码目录。)
  2. 下载stft.m并将其放入+arf/
  3. 同时将partition.m下载到+arf/
  4. 这会在其中创建arf namespace,其中arf.stftarf.partition函数(后者由arf.stft使用)。

    代码

    clearvars
    
    % Load data: this is an audio clip built into Matlab.
    handel = load('handel');
    % To hear this audio clip, run the following:
    % >> soundsc(handel.y, handel.Fs)
    
    % STFT parameters.
    % 1000 samples is roughly 1/8th of a second. A reasonable chunk size.
    samplesPerChunk = 1000;
    % Overlap a lot between chunks to see a smooth STFT.
    overlapSamples = round(samplesPerChunk * 0.9);
    
    % Generate STFT
    [stftArr, fVec, tVec] = arf.stft(handel.y, ...
                                     samplesPerChunk, ...
                                     'noverlap', overlapSamples, ...
                                     'fs', handel.Fs);
    
    % Plot results
    figure('color', 'white');
    imagesc(fVec / 1e3, tVec, 20 * log10(abs(stftArr)).');
    axis xy
    colorbar
    xlabel('frequency (KHz)')
    ylabel('time (s)')
    caxis(max(caxis) - [40 0])
    title('`handel` spectrogram via STFT, top 40 dB')
    

    上面的代码

    1. 加载打包到Matlab中的handel音频剪辑(这是来自George Frideric Handel的 Messiah 的9秒剪辑),
    2. 定义了STFT的一些参数,
    3. 使用arf.stft()
    4. 评估STFT
    5. 绘制STFT。
    6. 提示:在您运行上面的代码或仅load行后,您可以使用soundsc(handel.y, handel.Fs)收听原始剪辑。

      结果

      STFT of handel Hallelujah clip

      在谱图中,你可以清楚地看到前两个长哈利路亚,然后是两个较短的哈利路亚,然后是最后一个长的哈利路亚。时间按照你的意愿沿着y轴运行。

      该代码演示了如何指定块长度(此处为1000个样本,或≈⅛秒)和重叠量(块长度的90%,因此900个重叠样本)。注意:

      • 较大的块长度会导致时间分辨率降低(但频率分辨率更高)。
      • 重叠越少,STFT随着时间的推移出现越多的锯齿状和不太平滑(以及您支付的计算/内存开销越少)。重叠量必须介于0(块之间没有重叠)和chunk size - 1之间。

      如果您只是玩大块长度,您将感受到STFT让您调整的主旋钮。通常,一个选择在块大小的25%或50%之间重叠,以获得相当平滑的频谱图,而不会产生大量的计算开销。

      N.B。您可以通过将额外参数传递给arf.stft,特别是arf.stft( ..., 'nfft', 2^nextpow2(samplesPerChunk * 8))来增加频率维度的平滑度。这明确设置要创建的频率仓的数量(最终,评估此大小的FFT)。默认值相当于2^nextpow2(samplesPerChunk),因此将其乘以8将对每个块的频谱进行上采样8倍。