有人說: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哈哈~