前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MATLAB版晴天

MATLAB版晴天

作者头像
喜欢ctrl的cxk
发布2019-11-08 11:38:30
8110
发布2019-11-08 11:38:30
举报
文章被收录于专栏:Don的成长史

写在前面:

今天上数学模型实验课要用到MATLAB,我记得之前在知乎上收藏过一个很有趣的回答—— MATLAB能做什么?

答主分享了一个帖子:Matlab如何演奏周杰伦的“晴天”

握草!瞬间就觉得MATLAB真的太强辣! tql! 我一定要好好学习MATLAB!

原帖摘取:

听完这个音乐之后,会有一个很直观的感觉就是,音色跟印象中有比较大的出入。其根本原因在于,在脚本中对do,re,mi等声音定义为纯音,也就是以某个固定频率进行简谐运动所产生的声波。而先前所听过由乐器演奏的音乐,是由复合音组成,也就是不同的纯音混合在一起所形成的复合音。

1. 目标音乐的简谱

首先需要搜索目标音乐的简谱。以“晴天”为例,在“找歌谱”网上能够找到相应的简谱。

对此需要对音乐的基础知识稍作补习,不过相信先用一首自己熟悉的歌曲拿来联系,应该很容易就能上手。

2. 对音符的定义

在这个过程中,需要对节拍稍作注意,最常见的像四分之一拍,八分之一拍,以及十六分之一拍。

以四分之一拍的do为例:

代码语言:javascript
复制
do1f= mod4.*cos(2*pi*ScaleTable(5)*f0*t4);

其中涉及节拍,音调以及频率。mod4,ScaleTable及t4的定义,可参见帖子最后的源码。

分享几点我在编程过程中绕的弯路:

像图中所示的这种情况,最初我也是分别做三个音符数据输出,但是整体听下来的效果比较奇怪,也因为我在乐理基础上的欠缺。

最终,我处理的方式是,这三个音符作为9/16拍的mi输出,这样听起来的效果会相对连续些,不知道从音乐方面来看,这么处理的方式是否正确。

类似的情况,这幅图中的do,可作为3/8拍的do输出。

那么针对这些情况,需要在节拍以及时间间隔定义上,额外再定义9/16拍,3/8拍等情况的数据。

3. 乐谱的定义

在最基本的音符定义完之后,就可以着手通过音符来定义乐谱了。根据简谱依次用所定义的音符定义一个声音矩阵:

代码语言:javascript
复制
violin = [mi1e fa1e so1e mi1f fa1e so1e ti1e];

如果出现有和弦的情况,以同样的方式定义和弦的曲子,并与violin的声音矩阵做加法处理。

之后通过sound函数就能够听到整首歌的效果:

代码语言:javascript
复制
sound(s,fs);

同时,如果你想保存这首歌的话,可以通过audiowrite函数来实现:

代码语言:javascript
复制
audiowrite('Qingtian.wav',violin,fs)

另外,如果已经有一个音频文件想通过Matlab处理,可以通过audioread函数来读取该音频文件:

代码语言:javascript
复制
audioread('Qingtian.wav')

以上就是实现Matlab演奏歌曲的整个过程,接下来附上晴天的源代码,如果你有兴趣想用该代码实现别的歌曲的演奏,只需要将violin矩阵中的乐谱矩阵稍作修改,就能实现你所需的效果。

代码语言:javascript
复制
fs = 44100;
dt = 1/fs;
T16 = 0.2;
t16 = [0:dt:T16];
[temp k] = size(t16);
t2_5 = linspace(0,10*T16,10*k);
t2_25 = linspace(0,9*T16,9*k);
t2 = linspace(0,8*T16,8*k);
t4_5 = linspace(0,6*T16,6*k);
t4 = linspace(0,4*T16,4*k);
t6 = linspace(0,3*T16,3*k);
t8 = linspace(0,2*T16,2*k);
t12 = linspace(0,1.5*T16,1.5*k);
[temp i] = size(t4);
[temp j] = size(t8);

mod2_5 = sin(pi*t2_5/t2_5(end));
mod2_25 = sin(pi*t2_25/t2_25(end));
mod4 = sin(pi*t4/t4(end));
mod4_5 = sin(pi*t4_5/t4_5(end));
mod6 = sin(pi*t6/t6(end));
mod8 = sin(pi*t8/t8(end));
mod12 = sin(pi*t12/t12(end));
mod16 = sin(pi*t16/t16(end));
f0 = 2*146.8;
ScaleTable = [2/3 3/4 5/6 15/16 ...
1 9/8 5/4 4/3 3/2 5/3 9/5 15/8 ...
2 9/4 5/2 8/3 3 10/3 15/4 4 ...
1/2 9/16 5/8];

% 1/4 notes
do0f = mod4.*cos(2*pi*ScaleTable(21)*f0*t4);
re0f = mod4.*cos(2*pi*ScaleTable(22)*f0*t4);
mi0f = mod4.*cos(2*pi*ScaleTable(23)*f0*t4);
fa0f = mod4.*cos(2*pi*ScaleTable(1)*f0*t4);
so0f = mod4.*cos(2*pi*ScaleTable(2)*f0*t4);
la0f = mod4.*cos(2*pi*ScaleTable(3)*f0*t4);
ti0f = mod4.*cos(2*pi*ScaleTable(4)*f0*t4);
do1f = mod4.*cos(2*pi*ScaleTable(5)*f0*t4);
re1f = mod4.*cos(2*pi*ScaleTable(6)*f0*t4);
mi1f = mod4.*cos(2*pi*ScaleTable(7)*f0*t4);
fa1f = mod4.*cos(2*pi*ScaleTable(8)*f0*t4);
so1f = mod4.*cos(2*pi*ScaleTable(9)*f0*t4);
la1f = mod4.*cos(2*pi*ScaleTable(10)*f0*t4);
tb1f = mod4.*cos(2*pi*ScaleTable(11)*f0*t4);
ti1f = mod4.*cos(2*pi*ScaleTable(12)*f0*t4);
do2f = mod4.*cos(2*pi*ScaleTable(13)*f0*t4);
re2f = mod4.*cos(2*pi*ScaleTable(14)*f0*t4);
mi2f = mod4.*cos(2*pi*ScaleTable(15)*f0*t4);
fa2f = mod4.*cos(2*pi*ScaleTable(16)*f0*t4);
so2f = mod4.*cos(2*pi*ScaleTable(17)*f0*t4);
la2f = mod4.*cos(2*pi*ScaleTable(18)*f0*t4);
ti2f = mod4.*cos(2*pi*ScaleTable(19)*f0*t4);
do3f = mod4.*cos(2*pi*ScaleTable(20)*f0*t4);
blkf = zeros(1,i);

% 1/8 notes
do0e = mod8.*cos(2*pi*ScaleTable(21)*f0*t8);
fa0e = mod8.*cos(2*pi*ScaleTable(1)*f0*t8);
so0e = mod8.*cos(2*pi*ScaleTable(2)*f0*t8);
la0e = mod8.*cos(2*pi*ScaleTable(3)*f0*t8);
ti0e = mod8.*cos(2*pi*ScaleTable(4)*f0*t8);
do1e = mod8.*cos(2*pi*ScaleTable(5)*f0*t8);
do1_2_5 = mod2_5.*cos(2*pi*ScaleTable(5)*f0*t2_5);
do1_6 = mod6.*cos(2*pi*ScaleTable(5)*f0*t6);
re1e = mod8.*cos(2*pi*ScaleTable(6)*f0*t8);
re1_2_5 = mod2_5.*cos(2*pi*ScaleTable(6)*f0*t2_5);
re1_4_5 = mod4_5.*cos(2*pi*ScaleTable(6)*f0*t4_5);
mi1e = mod8.*cos(2*pi*ScaleTable(7)*f0*t8);
mi1_2_25 = mod2_25.*cos(2*pi*ScaleTable(7)*f0*t2_25);
mi1_2_5 = mod2_5.*cos(2*pi*ScaleTable(7)*f0*t2_5);
fa1e = mod8.*cos(2*pi*ScaleTable(8)*f0*t8);
so1e = mod8.*cos(2*pi*ScaleTable(9)*f0*t8);
la1e = mod8.*cos(2*pi*ScaleTable(10)*f0*t8);
la1_6 = mod6.*cos(2*pi*ScaleTable(10)*f0*t6);
tb1e = mod8.*cos(2*pi*ScaleTable(11)*f0*t8);
ti1e = mod8.*cos(2*pi*ScaleTable(12)*f0*t8);
do2e = mod8.*cos(2*pi*ScaleTable(13)*f0*t8);
do2_4_5 = mod4_5.*cos(2*pi*ScaleTable(13)*f0*t4_5);
do2_2_5 = mod2_5.*cos(2*pi*ScaleTable(13)*f0*t2_5);
re2e = mod8.*cos(2*pi*ScaleTable(14)*f0*t8);
mi2e = mod8.*cos(2*pi*ScaleTable(15)*f0*t8);
fa2e = mod8.*cos(2*pi*ScaleTable(16)*f0*t8);
so2e = mod8.*cos(2*pi*ScaleTable(17)*f0*t8);
la2e = mod8.*cos(2*pi*ScaleTable(18)*f0*t8);
ti2e = mod8.*cos(2*pi*ScaleTable(19)*f0*t8);
do3e = mod8.*cos(2*pi*ScaleTable(20)*f0*t8);
blke = zeros(1,j);

% 1/16 notes
fa0s = mod16.*cos(2*pi*ScaleTable(1)*f0*t16);
so0s = mod16.*cos(2*pi*ScaleTable(2)*f0*t16);
la0s = mod16.*cos(2*pi*ScaleTable(3)*f0*t16);
ti0s = mod16.*cos(2*pi*ScaleTable(4)*f0*t16);
do1s = mod16.*cos(2*pi*ScaleTable(5)*f0*t16);
do1_12 = mod12.*cos(2*pi*ScaleTable(5)*f0*t12);
re1s = mod16.*cos(2*pi*ScaleTable(6)*f0*t16);
mi1s = mod16.*cos(2*pi*ScaleTable(7)*f0*t16);
fa1s = mod16.*cos(2*pi*ScaleTable(8)*f0*t16);
so1s = mod16.*cos(2*pi*ScaleTable(9)*f0*t16);
la1s = mod16.*cos(2*pi*ScaleTable(10)*f0*t16);
tb1s = mod16.*cos(2*pi*ScaleTable(11)*f0*t16);
ti1s = mod16.*cos(2*pi*ScaleTable(12)*f0*t16);
do2s = mod16.*cos(2*pi*ScaleTable(13)*f0*t16);
re2s = mod16.*cos(2*pi*ScaleTable(14)*f0*t16);
mi2s = mod16.*cos(2*pi*ScaleTable(15)*f0*t16);
fa2s = mod16.*cos(2*pi*ScaleTable(16)*f0*t16);
so2s = mod16.*cos(2*pi*ScaleTable(17)*f0*t16);
la2s = mod16.*cos(2*pi*ScaleTable(18)*f0*t16);
ti2s = mod16.*cos(2*pi*ScaleTable(19)*f0*t16);
do3s = mod16.*cos(2*pi*ScaleTable(20)*f0*t16);
blks = zeros(1,k);

violin = [blke so1e so1e do1e do1f re1e mi1e...
blke so1e so1e do1e do1e re1s mi1s re1e so0e...
blke so1e so1e do1e do1f re1e mi1e...
blke mi1f re1s mi1s fa1s mi1s re1s fa1s mi1e do1e...
so0e do1e so1e mi1e fa1e mi1e re1e do1s re1s...
mi1e mi1e mi1e mi1e re1s mi1s re1e do1f...
so0e do1e re1e mi1e fa1e mi1e re1e do1s re1s...
mi1e mi1e mi1e mi1e re1s mi1s re1e do1_12 blke ti1s...
do1s do1s do1s do1s ti1s do1e do1e do1s do1s do1s ti1s do1e...
do1e do1s do1s do1s ti1s do1e do1e do1s do1s do1s so1s so1e so1s...
blks so1s so1s so1s so1s so1e so1s so1s so1s so1s so1s so1s fa1s mi1s...
mi1_2_25 blkf do1s do1s do1s do1s...
la0e ti0e do1e so1e fa1e mi1e do1e do1_6...
blkf do1s do1s do1s do1s mi1e do1e...
la0e ti0e do1e so1e fa1e mi1e do1e...
re1_2_5 blkf blkf...
mi1e re1e fa1e mi1f do1e so1e ti1e...
do2e ti1e so1e do1f do1e la1e la1e...
blke la1e so1e so1f so1e fa1e mi1e...
re1e mi1e fa1e mi1_2_5...
mi1e fa1e so1e mi1f fa1e so1e ti1e...
re2e ti1e do2e do2_4_5 blke do2e...
do2e so1e so1e la1e so1e fa1e re1e mi1e...
fa1e so1e la1e do1e la1_6 ti1s ti1f...
mi1e re1e fa1e mi1f do1e so1e ti1e...
do2e ti1e so1e do1f do1e la1e la1e...
blke la1e so1e so1f so1e fa1e mi1e...
re1e mi1e fa1e mi1_2_5...
mi1e fa1e so1e mi1f fa1e so1e ti1e...
re2e ti1e do2e do2_4_5 blke do2e...
do2e so1e so1e la1e so1e fa1e la0e ti0e...
do1e re1e mi1e re1_4_5 mi1e do1_2_5];

s = violin;
s = s/max(s);

sound(s,fs);
audiowrite('Qingtian.wav',violin,fs)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/03/05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写在前面:
  • 原帖摘取:
    • 1. 目标音乐的简谱
    • 2. 对音符的定义
      • 3. 乐谱的定义
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档