Matlab - 用正确的缩放创建psd

时间:2015-04-05 10:39:40

标签: matlab audio

我想分析一个audiodata(.wav,pcm,32k作为采样率)并用轴Sxx(瓦特/赫兹不是db)和f(赫兹)创建它的psd。

所以我首先要读出audiodata:

[x,fs]=audioread('test.wav');

在此之后我遇到了一些问题,因为我真的不知道如何继续,而且Matlab总是告诉我psd功能在将来不会得到支持,而且我应该使用pwelch ..(也试图构建autocorr,然后使用傅里叶来到Sxx,但它并没有很好地工作)

那么有人能告诉我如何从矢量x到具有以瓦/赫兹为单位的psd值的矢量并在之后绘制它吗?

非常感谢各种帮助! :)

Update1 :是的,我确实阅读了pwelch的文档,但我担心我的英语太糟糕了,无法理解它。 所以,如果我使用psd文档:

nfft = 2^nextpow2(length(x));
Pxx = abs(fft(x,nfft)).^2/length(x)/fs;
Hpsd = dspdata.psd(Pxx(1:length(Pxx)/2),'fs',fs);  
plot(Hpsd) 

我能够在db中获得具有正确频率峰值的情节。 (我不知道dspdata.psd是如何工作的)

我试过了:

[Pyy,f]=pwelch(x,fs)
plot(Pyy)

这给了我一个非db-scale但是峰值频率错误

更新2 : 首先,非常感谢您的详细解答!目前我正在使用我的matlabskills以及我的英语语言,但所有具体的技术术语都给我带来了困难。 在明确频率为1khz的wav数据上使用pwelch的例子时,该图显示了圆形峰值约为0.14,它是否仍然可以是一个特殊的x轴?

如果我这样试试:

[y,fs]=audioread('test.wav');
N=length(y);
bin_vals=0:N-1;
fax_Hz= bin_vals*fs/N;
N_2=ceil(N/2);
Y=fft(y);
pyy=Y.*conj(Y);
plot(fax_Hz(1:N_2),pyy(1:N_2))

结果似乎正确(这样正确吗?),但我仍然需要一些时间来搜索以W / Hz显示y轴的正确方法,因为我不知道音频信号是如何创建的。

更新3 http://s000.tinyupload.com/index.php?file_id=33803229773204653857 该wav文件的主频应为1khz,持续时间为3秒,采样频率为44100Hz。 (如果我绘制从audioread收到的数据,振荡似乎是合理的)

[y,fs]=audioread('1khz.wav');
[pyy,f]=pwelch(y,fs);
plot(f,pyy)

我在x轴上得到0.14的峰值。

如果我使用

[y,fs]=audioread('1khz.wav');
[pyy,f]=pwelch(y,[],[],[],fs);
plot(f,pyy)

相反,峰值是1000.这是对的吗?我怎么能解释y轴上的差异缩放? (pwelch vs. abs的平方) 我还想问一下是否可以在matlab中获得平坦的awd? (因为你只有有限的元素,我不知道到达那里)

再次感谢您的详细支持!

更新4 @ A.Donda 所以我有一个新问题,我认为可能需要更详细一些。所以我的计划基本上是做以下事情:

  1. 读取和Audiodata([y,fs])并生成具有特定SNR的白噪声([n,fs])
  2. 生成滤波器H,其形成与PSD(n)类似的PSD(y)
  3. 生成逆滤波器G = H ^( - 1),它会恢复H的效果。
  4. 我的问题是,使用pwelch时,得到的pyy矢量长度小于y的矢量长度。由于我的滤波器由P = sqrt(pnn / pyy)决定,我不能将fft(y)* H乘以因此得不到任何结果。 你对这个问题有什么帮助吗? 或者有没有办法从PSD(​​韦尔奇估计)回到正常信号(如pwelch的反函数)?

1 个答案:

答案 0 :(得分:0)

psd文档中的示例中,您自己计算psd估计值,然后将其放入dspdata.psd容器并绘制它。这里dspdata.psd数据的作用基本上是计算频率轴并将其提供给plot命令,仅此而已。你得到了一个谱密度估计图,但这是你自己使用fft计算的一个,这是你能得到的最简单和最差的psd估计,即所谓的周期图。

您对pwelch的使用几乎是正确的,您只是忘记在图中使用频率轴信息。

[Pyy,f]=pwelch(x,fs)
plot(f,Pyy)

应该以正确的频率给你峰值。

您对pwelch的使用几乎是正确的,但您必须将采样频率作为第5个参数,然后在图中使用频率轴信息。

[Pyy,f]=pwelch(y,[],[],[],fs);
plot(f,Pyy)

应该以正确的频率给你峰值。

pwelch给出的是信号在Hz范围内的频谱密度。因此,正确的轴标签将是

xlabel('frequency (Hz)')
ylabel('psd (1/Hz)')

您提供的信号pwelch是一个没有物理尺寸的纯数字序列。通过指定采样率,时间轴获得物理单位s,因此得到的频率以Hz为单位,密度为1 / Hz。但是你的时间序列值仍然没有物理尺寸,因此密度与W之类的东西无关。你的音频信号是通过校准的A / D转换器获得的吗?如果是,您应该能够将数据与物理维度和单位联系起来,但这是一个非常重要的步骤。

就个人而言,我真的建议你提高自己的英语水平,因为使用软件,尤其是编程界面,如果没有正确理解文档是一种灾难。