作为研究项目的一部分,我想通过生成它的光谱图来分析声音文件。
我已经能够在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生成频谱图。
非常感谢任何帮助。
答案 0 :(得分:3)
很抱歉,我没有Mathworks放置spectrogram
的任何-toolbox,但这里有一些我放在公共领域的代码,可以帮我完成工作。
它比spectrogram
更实际,但具有后者的许多功能,因为我将演示使用Matlab附带的handel
音频剪辑('Hallelujah!')。
我不会假设您熟悉git或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')
上面的代码
handel
音频剪辑(这是来自George Frideric Handel的 Messiah 的9秒剪辑),arf.stft()
和提示:在您运行上面的代码或仅load
行后,您可以使用soundsc(handel.y, handel.Fs)
收听原始剪辑。
在谱图中,你可以清楚地看到前两个长哈利路亚,然后是两个较短的哈利路亚,然后是最后一个长的哈利路亚。时间按照你的意愿沿着y轴运行。
该代码演示了如何指定块长度(此处为1000个样本,或≈⅛秒)和重叠量(块长度的90%,因此900个重叠样本)。注意:
chunk size - 1
之间。如果您只是玩大块长度,您将感受到STFT让您调整的主旋钮。通常,一个选择在块大小的25%或50%之间重叠,以获得相当平滑的频谱图,而不会产生大量的计算开销。
N.B。您可以通过将额外参数传递给arf.stft
,特别是arf.stft( ..., 'nfft', 2^nextpow2(samplesPerChunk * 8))
来增加频率维度的平滑度。这明确设置要创建的频率仓的数量(最终,评估此大小的FFT)。默认值相当于2^nextpow2(samplesPerChunk)
,因此将其乘以8将对每个块的频谱进行上采样8倍。