【matlab】从让matlab唱歌开始

大家坐好,我要编故事了。

这两天又看了《我不是药神》(这是豆瓣介绍)这部电影,虽然已经知道故事是如何发展的,不过情节又一次拨动了我的心弦。好多情节翻来覆去在脑袋里出现:老阿婆求情,印度兄弟义无反顾的支持,机场送儿子走,入狱时众人相送。脑袋里总是出现一个声音:不该啊~ 看完电影,意犹未尽,于是找到了主题曲《只要平凡》,一直循环播放。

今天早上突发奇想,想看看matlab能和这个mp3文件擦出什么样的火花,于是就开始了今天这个“让matlab唱歌”的实验之旅。

1、尝试搜索,看看matlab能否处理音频文件

搜到了这样一个帮助说明文档:
【matlab】从让matlab唱歌开始_第1张图片
貌似这个audioread靠谱,上手试一试他给的例子:读取、播放音频文件。
【matlab】从让matlab唱歌开始_第2张图片
上面例子里通过load handel.mat 文件,载入了两个变量:

  • Fs采样率,这里的值是8192,表示一秒钟有8192个采样点。
  • y 是一个矩阵,里面存放着用数字表示的音频样本,为 double 类型,矩阵元素是介于 −-1.0 和 1.0 之间的归一化值。

用plot 命令把y画出来看一看:
【matlab】从让matlab唱歌开始_第3张图片
可以用 audiowrite 将音频数据文件写入文件,用 audioread 读取音频文件。但是最重要的是:可以用sound 函数播放读入的音频数据。

% matlab脚本
clear,clc
load handel.mat     % 加载handel.mat中的数据
plot(y)             % 把音频采样值y画出来看看
max(y)              %看看y的最大值
min(y)              %看看y的最小值

filename = 'handel.wav';  
audiowrite(filename,y,Fs);  % 将音频采样信号写入文件 handel.wav
clear y,Fs;                 % 这是为了下面重新读入音频数据,暂时清除工作空间载入的两个变量。

[y,Fs] = audioread('handel.wav'); % 读取 handel.wav,还是获得音频数据y,采样率Fs
sound(y,Fs);                      % 播放音频文件,到这句,你就可以听见matlab在播放这首曲子。

一个无关紧要知识点:这里的handel.mat中的“Handel”指的是:乔治·弗里德里希·亨德尔。

2、让matlab唱我喜欢的这首《只要平凡》

嗯,我是从网上下载的这个mp3文件,想让matlab唱这首歌给我听
【matlab】从让matlab唱歌开始_第4张图片
先看一下这个文件的信息,使用audioinfo这个函数:

clear all
filename = 'D:\myMatlab\只要平凡.mp3'
info = audioinfo(filename)

【matlab】从让matlab唱歌开始_第5张图片

看到这个文件的文件名, 压缩格式,音频声道数量(NumChannels),采样率(SampleRate),采样点数(TotalSamples),时长(Duration),音频文件的BitRate千位/秒 (kbit/s) 数。

这首歌,时长246.1秒,每秒128Kbits,所以文件大小差不多有:246.1*128/8/1024=3.8M。(嗯,差不多,差不多)
【matlab】从让matlab唱歌开始_第6张图片
当我们读入这个文件的时候,我们要用到的是采样率和通道数。

[data,Fs] = audioread(filename);

其中 Fs 为 44100,data是一个 10852464 * 2 的矩阵,二维double类型的矩阵,应该表示两个声道。试着用sound播放一下这首歌,

% 千万不要尝试不带Fs参数运行sound,没有Fs参数,将会按照默认的采样率 8192 播放音频。
% 想这首歌,如果原始采样率是44100,不带Fs参数时,相当于将歌曲放慢了 44100/8192=5.4倍,
% 听起来像动物低吼,很难听~
% sound(data)

sound(data,Fs) ; %这样就直接开始播放文件,要想停止,可以在命令行中执行下面的命令。
% clear sound %停止播放
% 如果你在一个脚本中执行了多个sound命令,感觉他好像会启动多个线程,一起播放声音。一个clear将会终止所有的播放。

3、让matlab唱do re mi

嗯,上面我们看到,sound函数有两个参数就可以播放声音,第一个参数是一个矩阵,第二个参数是描述矩阵的参数。如果我们可以构造这个矩阵,就可以用sound让matlab唱出声音。

先搜索一下,do,re,mi 三个音的频率是多少:
【matlab】从让matlab唱歌开始_第7张图片
分别是 261.63Hz,293.66Hz,329.63Hz。我们构造时间长度为一秒的do,每秒8192个采样点:

Fs = 8192;
t=0:1/(Fs-1):1; % 因为是从0s到1s,除去两个点,还要8190个点。

y1 =sin(2*pi*261.63*t);  % 中央C,do,频率261.63Hz,时间从0到1秒,一共8192个采样点。
sound(y1,Fs);            % 对你可以听到do了。 

重复上面的步骤,构造re和mi,

Fs = 8192;
t=0:1/(Fs-1):1; % 因为是从0s到1s,除去两个点,还要8190个点。

y1 =sin(2*pi*261.63*t);  % 中央C,do,频率261.63Hz,时间从0到1秒,一共8192个采样点。
y2 =sin(2*pi*293.66*t); % re
y3 =sin(2*pi*329.63*t); % mi

y = [y1,y2,y3];         % 三个音拼在一起,do re mi
sound(y,Fs)

这就让matlab唱出了do re mi,不过在两个音之间,会听到’哒’一声。看看这一声是怎么来的。这篇讨论中,高人解释了一下为什么会有’哒‘一声。我理解是:在y1和y2相接的时候,由于两个音有变化,所以产生了更多其他频率的分量,这个分量的声音就是’哒‘那一声。
【matlab】从让matlab唱歌开始_第8张图片
如果这样,是不是就可以将乐谱写成矩阵,然后播放这个矩阵,就可以听见matlab了!对吧!

嗯,可能还有几个问题:
1、如何将乐谱变成一个数组?
2、如何消除两个音之间’哒‘这一声?
3、如何表现出不同乐器的音色?(多个泛音)

你可能感兴趣的:(matlab)