昨天有人问我怎么用Matlab读取WAV或MP3等音频信号,然后提取音频,并作傅里叶变换,找到音频的振频和谐波。然后,他给了我一段m文件代码,说是会报错,让我改一下看看。然后,我就一顿操作,使用audioread函数读取,稍微修改了两行代码,就帮他解决了问题。
今天,把这个过程及最后的代码发出来,供各位参考。虽然,我也不知道到底啥意思,反正就是解决那些报错信息就可以了。
原版m文件
接下来,先把他给的m文件代码发出来:
clc;
clear all;
[x,FS,NBITS]=wavread('1.WAV');
N=length(x)
if mod(N,2)==0;N=N;else x(N)=[];N=N-1;end;
tx=(0:N-1)/FS;
subplot(3,2,1);plot(tx,x);
xf=fft(x);
fx=(0:N/2)*FS/N;
subplot(3,2,2);plot(fx,abs(xf(1:N/2+1)));
运行后,报错信息如下:
未定义函数或变量 'wavread'。
出错 dai (line 3)
[x,FS,NBITS]=wavread('1.WAV');
问题判断:不存在wavread这个函数,估计是用法问题。经过一番查询,觉得可以使用audioread这个函数,我们先看看这个函数的功能吧:
>> help audioread
audioread Read audio files
[Y, FS]=audioread(FILENAME) reads an audio file specified by the
string FILE, returning the sampled data in Y and the sample rate
FS, in Hertz.
[Y, FS]=audioread(FILENAME, [START END]) returns only samples START
through END from each channel in the file.
[Y, FS]=audioread(FILENAME, DATATYPE) specifies the data type format of
Y used to represent samples read from the file.
If DATATYPE='double', Y contains double-precision normalized samples.
If DATATYPE='native', Y contains samples in the native data type
found in the file. Interpretation of DATATYPE is case-insensitive and
partial matching is supported.
If omitted, DATATYPE='double'.
[Y, FS]=audioread(FILENAME, [START END], DATATYPE);
Output Data Ranges
Y is returned as an m-by-n matrix, where m is the number of audio
samples read and n is the number of audio channels in the file.
If you do not specify DATATYPE, or dataType is 'double',
then Y is of type double, and matrix elements are normalized values
between -1.0 and 1.0.
If DATATYPE is 'native', then Y may be one of several MATLAB
data types, depending on the file format and the BitsPerSample
of the input file:
File Format BitsPerSample Data Type of Y Data Range of Y
----------------------------------------------------------------------
WAVE (.wav) 8 uint8 0 <= Y <= 255
16 int16 -32768 <= Y <= 32767
24 int32 -2^32 <= Y <= 2^32-1
32 int32 -2^32 <= Y <= 2^32-1
32 single -1.0 <= Y <= +1.0
----------------------------------------------------------------------
FLAC (.flac) 8 uint8 0 <= Y <= 255
16 int16 -32768 <= Y <= 32767
24 int32 -2^32 <= Y <= 2^32-1
----------------------------------------------------------------------
MP3 (.mp3) N/A single -1.0 <= Y <= +1.0
MPEG-4(.m4a,.mp4)
OGG (.ogg)
----------------------------------------------------------------------
Call audioinfo to learn the BitsPerSample of the file.
Note that where Y is single or double and the BitsPerSample is
32 or 64, values in Y might exceed +1.0 or -1.0.
我们发现,读取后的音频会有两个参数:一个Y,是一个矩阵,一般是一个两列多行矩阵,甚至多行多列矩阵的采样数据;FS是这个音频的采样率,即一秒钟的音频所包含的数据组数。
因此,我们把对方发来的m文件,作一部分修改,得到如下结果:
clc;
clear all;
[Y,FS]=audioread('1.WAV');
N=length(Y)
if mod(N,2)==0;N=N;else Y(N)=[];N=N-1;end;
tx=(0:N-1)/FS;
subplot(3,2,1);
plot(tx,Y);
xf=fft(Y);
fx=(0:N/2)*FS/N;
subplot(3,2,2);
plot(fx,abs(xf(1:N/2+1)));
运行后,得到如下图形:
对方,觉得振频那部分,即右边处理的不是太好。经过观察,我发现需要调整下振频部分的横坐标范围就可以了。顺便,我重新调整了图片放置的位置,通过修改subplot这个函数可以实现。最后,修改后的代码如下:
clc;
clear all;
[Y,FS]=audioread('1.WAV');
N=length(Y)
if mod(N,2)==0;N=N;else Y(N)=[];N=N-1;end;
tx=(0:N-1)/FS;
subplot(2,1,1);
plot(tx,Y);
xf=fft(Y);
fx=(0:N/2)*FS/N;
subplot(2,1,2);
plot(fx,abs(xf(1:N/2+1)));
axis([100 300,-inf,inf])
其运行结果如下:
好了,到此完美的解决了对方的问题。这里说一下,axis,即最后一行,是修改plot画图结果的坐标范围:其中,100 300表示横坐标范围为100到300,-inf inf表示纵坐标范围不做处理。
当然,也可以读取mp3文件,比如我这里再处理一个mp3文件,如下结果:
开头,我们说Y是一个两列矩阵,其实我们也可以通过如下代码分别展开这两列,来绘图,结果跟文中的m文件结果是一致的。算了,最后这部分可以忽略。其实plot自己会识别多列数组的,它会自动在一个图中绘制结果。
a=Y(:,1);
b=Y(:,2);
plot(tx,a,tx,b)
plot(tx,Y)
原创文章,作者:古哥,转载需经过作者授权同意,并附上原文链接:https://iymark.com/articles/626.html
评论列表(1条)
对啦,这里为什么Y是两列数据呢,你可以理解为双声道,左右两个声道,所以会出现两组数据。