有人说:MATLAB除了生孩子,其他的都会。
那能用它来创造音乐吗?
答案是 可以的
首先我们要知道我们所听到的DO RE MI,是怎么产生的?之间的不同是什么?
音乐作为“波”的一种,自然可以用正弦波的叠加来模拟,不同的频率可以发出不同频率的音符,所以我们只要用MATLAB生成一系列的正弦函数,再加上MATLAB自带的**sound()**函数即可。
音乐主要由音调和节拍组成,所以音乐函数需要两个输入,即音调(tone)和节拍(rythm)
现给出函数模块:
Fs为采样频率,一般默认8192Hz,也就是一秒钟采样次数;
linspace(a,b,c)函数用于均匀产生b个a到c之间数组;
freqs的数组为不同音色对应的频率,简单起见只列出常用的;
注意:播放频率应该与采样频率保持一致!!!
function y = gen_wave( tone, rythm )
%UNTITLED2 音乐函数 对应music2
% 音调 拍
Fs = 8192;
freqs = [523, 587, 659, 698, 783, 880, 988];
x = linspace(0, 2 * pi * rythm, floor(Fs * rythm));
y = sin(freqs(tone) * x);
end
新建主函数执行如下代码即可发出DO音。
Fs = 8192;
y=[];
y = gen_wave(1,1);
sound(y,Fs);
执行完成后用**plot()**函数可以画出声音图像,如下图
可以看见非常的密集,局部放大之后是:
首先可以看出放大之后,值是不连续的,然后声音一直是不变的,这和我们实际上是不太相符的,钢琴的音应该是刚按下的时候最大,后面随着时间变化,声音逐渐衰退,所以我们在y的后面乘上一个函数,使之衰减,代码如下:
function y = gen_wave( tone, rythm )
% 音调 拍
Fs = 8192;
freqs = [523, 587, 659, 698, 783, 880, 988];
x = linspace(0, 2 * pi * rythm, floor(Fs * rythm));
y = sin(freqs(tone) * x) .*(1- x/(rythm * 2 *pi));
end
重新运行DO音,并画出图像得:
放大局部
可以看出这个是振荡衰减的,当然也可以乘上一个指数衰减的函数,这样的得到的声音会更加真实。
接着我们可以找一首完整音乐的乐谱,比如《小星星》
根据简谱我们可以生成这首歌曲的音乐代表数组,代码如下:
Fs = 8192;
y=[];
music = [1,1,5,5,6,6,5,...
4,4,3,3,2,2,1,...
5,5,4,4,3,3,2,...
5,5,4,4,3,3,2,...
1,1,5,5,6,6,5,...
4,4,3,3,2,2,1];
music_length = length(music(:));
y1 = gen_wave(1,1);
y2 = gen_wave(2,1);
y3 = gen_wave(3,1);
y4 = gen_wave(4,1);
y5 = gen_wave(5,1);
y6 = gen_wave(6,1);
y7 = gen_wave(7,1);
for i = 1:1:music_length
if music(i) == 1
y=[y,y1];
elseif music(i) == 2
y=[y,y2];
elseif music(i) == 3
y=[y,y3];
elseif music(i) == 4
y=[y,y4];
elseif music(i) == 5
y=[y,y5];
elseif music(i) == 6
y=[y,y6];
elseif music(i) == 7
y=[y,y7];
end
end
sound(y, Fs);
通过遍历音乐数组,执行子程序,我们可以生成其音阶数组,再用sound()播放即可。
如果感觉有用的话,点个赞吧,O(∩_∩)O哈哈~