如何在 Matlab 中生成频率为 x 轴的 wav 文件的频谱图
How to generate the spectrogram of a wav file in Matlab with frequency on the x-axis
作为研究项目的一部分,我想通过生成频谱图来分析声音文件。
我已经能够在 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 轴上。但是,我得到的频谱图与从可靠来源生成的频谱图不同。
这是我生成的频谱图 -
可靠来源生成的频谱图(我没有代码)。
此外,两个频谱图中的配色方案不同。我的录音是 50 秒,而标签上显示的时间是 9 秒。我该如何解决这些问题?
我的最终任务是能够在 android 设备上生成频谱图(可能使用 android 中的 GraphView 库)。所以我必须编写代码来生成 Java.
中的频谱图
非常感谢任何帮助。
前言
抱歉,我没有 Mathworks 放入 spectrogram
的任何工具箱,但这是我放入 public 域中的一些代码,可以为我完成这项工作。
它比 spectrogram
更实用,但具有后者的许多功能,正如我将使用 Matlab 附带的 handel
音频剪辑('Hallelujah!')进行演示一样。
设置
我不会假定您熟悉 git 或 Matlab 命名空间。
- 在您的 Matlab 路径中的某处创建一个名为
+arf
的目录(例如,~/Documents/MATLAB
甚至您当前的代码目录)。
- 下载
stft.m
并放入+arf/
。
- 同时下载
partition.m
到 +arf/
。
这将创建一个 arf
namespace,其中包含 arf.stft
和 arf.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')
上面的代码
- 加载打包到 Matlab 中的
handel
音频剪辑(这是来自乔治·弗里德里克·汉德尔 弥赛亚 的九秒剪辑),
- 为STFT定义一些参数,
- 用
arf.stft()
和 评估 STFT
- 绘制 STFT。
提示:在你 运行 上面的代码之后,或者只是 load
行之后,你可以用 soundsc(handel.y, handel.Fs)
.
收听原始剪辑
结果
在频谱图中,可以清楚地看到前两首长的哈利路亚,然后是两首较短的,最后是最后一首长的。沿 y 轴的时间 运行s 如您所愿。
代码演示了如何指定块长度(此处为 1000 个样本,或 ≈⅛ 秒)和重叠量(块长度的 90%,因此有 900 个重叠样本)。注:
- 块长度越大,时间分辨率越低(但频率分辨率越高)。
- 重叠越少,STFT 随时间出现的锯齿状越多,平滑度越低(您支付的 computational/memory 开销就越少)。重叠量必须在 0(块之间没有重叠)和
chunk size - 1
. 之间
如果你只是玩弄块长度,你会感觉到 STFT 给你调整的主旋钮。通常,一个人会选择块大小的 25% 或 50% 之间的重叠,以获得相当平滑的频谱图,而无需大量的计算开销。
N.B。您可以通过将额外的参数传递给 arf.stft
,特别是 arf.stft( ..., 'nfft', 2^nextpow2(samplesPerChunk * 8))
来增加沿 频率 维度的平滑度。这明确设置了要创建的频率仓的数量(最终,评估了这个大小的 FFT)。默认值相当于 2^nextpow2(samplesPerChunk)
,因此将其乘以 8 会将每个块的频谱上采样八倍。
作为研究项目的一部分,我想通过生成频谱图来分析声音文件。
我已经能够在 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 轴上。但是,我得到的频谱图与从可靠来源生成的频谱图不同。
这是我生成的频谱图 -
可靠来源生成的频谱图(我没有代码)。
此外,两个频谱图中的配色方案不同。我的录音是 50 秒,而标签上显示的时间是 9 秒。我该如何解决这些问题?
我的最终任务是能够在 android 设备上生成频谱图(可能使用 android 中的 GraphView 库)。所以我必须编写代码来生成 Java.
中的频谱图非常感谢任何帮助。
前言
抱歉,我没有 Mathworks 放入 spectrogram
的任何工具箱,但这是我放入 public 域中的一些代码,可以为我完成这项工作。
它比 spectrogram
更实用,但具有后者的许多功能,正如我将使用 Matlab 附带的 handel
音频剪辑('Hallelujah!')进行演示一样。
设置
我不会假定您熟悉 git 或 Matlab 命名空间。
- 在您的 Matlab 路径中的某处创建一个名为
+arf
的目录(例如,~/Documents/MATLAB
甚至您当前的代码目录)。 - 下载
stft.m
并放入+arf/
。 - 同时下载
partition.m
到+arf/
。
这将创建一个 arf
namespace,其中包含 arf.stft
和 arf.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')
上面的代码
- 加载打包到 Matlab 中的
handel
音频剪辑(这是来自乔治·弗里德里克·汉德尔 弥赛亚 的九秒剪辑), - 为STFT定义一些参数,
- 用
arf.stft()
和 评估 STFT
- 绘制 STFT。
提示:在你 运行 上面的代码之后,或者只是 load
行之后,你可以用 soundsc(handel.y, handel.Fs)
.
结果
在频谱图中,可以清楚地看到前两首长的哈利路亚,然后是两首较短的,最后是最后一首长的。沿 y 轴的时间 运行s 如您所愿。
代码演示了如何指定块长度(此处为 1000 个样本,或 ≈⅛ 秒)和重叠量(块长度的 90%,因此有 900 个重叠样本)。注:
- 块长度越大,时间分辨率越低(但频率分辨率越高)。
- 重叠越少,STFT 随时间出现的锯齿状越多,平滑度越低(您支付的 computational/memory 开销就越少)。重叠量必须在 0(块之间没有重叠)和
chunk size - 1
. 之间
如果你只是玩弄块长度,你会感觉到 STFT 给你调整的主旋钮。通常,一个人会选择块大小的 25% 或 50% 之间的重叠,以获得相当平滑的频谱图,而无需大量的计算开销。
N.B。您可以通过将额外的参数传递给 arf.stft
,特别是 arf.stft( ..., 'nfft', 2^nextpow2(samplesPerChunk * 8))
来增加沿 频率 维度的平滑度。这明确设置了要创建的频率仓的数量(最终,评估了这个大小的 FFT)。默认值相当于 2^nextpow2(samplesPerChunk)
,因此将其乘以 8 会将每个块的频谱上采样八倍。