Read and Play Audio in MATLAB

Jan. 14, 2023

在MATLAB中,用户可以使用audioinfo函数获得声音文件的信息;使用audioread函数从声音文件中读取数据,并使用sound函数播放声音。

首先从网易云音乐上下载一个.mp3后缀的音乐文件wanfeng.mp3,使用audioinfo函数获取它的信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>> ainfo = audioinfo("wanfeng.mp3")
ainfo = 
  struct with fields:
             Filename: 'C:\Users\Tsing\Desktop\huogai\wanfeng.mp3'
    CompressionMethod: 'MP3'
          NumChannels: 2
           SampleRate: 44100
         TotalSamples: 8940671
             Duration: 2.027363000000000e+02
                Title: '晚风'
              Comment: '163 key(Don't modify):L64FU3W4YxX3ZFTmbZ+8/TXi60+/SzPUjSUNMVsdX+PCpKIeyShrk7/BY+Ejb4FReuzVIcMZEWPOwz7R5ei11Xe5RDH7CarLfBCg+8YNV9Z/HUD72WuOV3NvBBMQ2OZkRN4nBuaSaUyXYOFv7hsT0I/yQH7HFJ0cJfvdDsajVXALOAGYeynjLxfYXRcU5Qkvc18sYp4tEL8sFhj9RgnQXdhGCZsOmTkTlTQqqMEb4dQXsWsG4yvo5Yb8l+T1fXIRD+8+Ix3gkB+Tyx6/g0u0Tik6KPG9q4HYOXIAVsOLfr4weEnJb+yLc9jycjdk1BpLqFgpRgJu/GiX+aZow7NOPjW1EVpNsillUe/zSDUXIGUihOH0IqOoNoLKFurGmMb6qUmlwKTHTRfq1/CuumOzZy2y4JGnwu9hU+xhFCQx5V12ApklDkRfCe8duVvL8pIL0Phxvj7usONl3wOt9Yc+AaeHZyc3hzG4lVVapoXl/U0mFPBdiXsvIx29y+CcMvuLyTkBHXiQjMaaBA21XHYUkA=='
               Artist: '7copy'
              BitRate: 320

其中:

  • CompressionMethod字段,表示该声音文件采用MP3(Moving Picture Experts Group Audio Layer III,动态影像专家压缩标准音频层面3)音频压缩技术;

  • NumChannels字段,表示这是一个左右双通道的音频文件;

  • SampleRate字段,表示音频信号采样率,单位是Hz;

  • Duration字段,表示音频时长;

  • TotalSamples字段,表示音频文件总的采样点数,等于SampleRate字段和Duration字段的乘积,即:

    1
    2
    3
    
    >> ainfo.SampleRate*ainfo.Duration-ainfo.TotalSamples
    ans =
      -0.169999999925494
    
  • BitRate表示音频压缩文件的千比特率(kbit/s),只对MP3文件(.mp3文件)和MPEG-4 Audio(.m4a.mp4)文件有效;

接下来使用audioread函数将音频文件中的数据读取到MATLAB工作空间中:

1
[data, fs] = audioread("wanfeng.mp3");
1
2
3
4
>> whos
  Name            Size                Bytes  Class     Attributes
  data      8940144x2             143042304  double              
  fs              1x1                     8  double              

其中:

  • data是一个两通道的音频数据矩阵:

    image-20230114190256022

    此时我们并没有指定audioread函数的dataType属性,因此data的数据类型是默认的double,并且数据矩阵中的元素是标准化后的值,从[-1, 1]取值。若设置audioread函数的dataType属性为'native'

    1
    
    [data, fs] = audioread("wanfeng.mp3", 'native');
    
    1
    2
    3
    4
    
    >> whos
      Name            Size               Bytes  Class     Attributes
      data      8940144x2             71521152  single              
      fs              1x1                    8  double              
    

    此时的data变量就是single类型,由上图可以看到,data变量中的元素仍然从[-1,1]取值。但是对于其他类型的音频文件并不总是这样的取值范围。

  • fs,表示采样率,值为44100,单位是Hz;

    注:44100Hz,即44.1kHz是一个常用的音频采样率,其他常用的采样率还有:

    image-20230114193835323

    sound: Sample rate - MathWorks

得到音频数据data和采样率fs后,就可以使用sound函数播放声音:

1
sound(data, fs)

注:这里采用与音频文件一致的采样率播放,除此之外还可以使用不同的采样率播放,已达到放慢音频播放或者加快音频播放的效果。

仅仅只播放一个声道的音频也是可以的:

1
sound(data(:,1), fs) % left channel
1
sound(data(:,2), fs) % right channel

如果想要终止声音,需要在命令行窗口中输入命令:

1
>> clear sound

并且,还可以绘制一下两个通道的音频波形(Read and Write Audio Files: Plot Audio Data - MathWorks):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
clc, clear, close all

ainfo = audioinfo("wanfeng.mp3");

[data, fs] = audioread("wanfeng.mp3", 'native');

t = 0:1/fs:floor(ainfo.Duration);
t = t(1:end-1);

data = data(1:numel(t),:);

figure
hold(gca, "on")
box(gca, "on")
grid(gca, "on")
plot(t, data(:,1), DisplayName="left-channel")
plot(t,  data(:,2), DisplayName="right-channel")
legend()
xlim([t(1), t(end)])
xlabel('Time')
ylabel('Audio Signal')

image-20230114193236012