MATLAB演奏《左手指月》

网上找的一份《左手指月》的谱子,需要了解一些基础的音乐知识,看懂谱子就可以写程序了。
在这里插入图片描述
主函数

%% 《左手指月》——(香蜜沉沉烬如霜)
%% 清空
clear;clc;

%% 采样频率
Fs = 8192;

%% keynote_type:当前基调
F = 'F';
keynote_type = [F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,...
    F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,...
    F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,...
    F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,...
    F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,...
    F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,...
    F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,...
    F,F,F,F,F,F,F,F,F,F,F,F,F];

%% tone:取哪个音节
% 写法:1  2  3  4   5  6  7
% 读法:Do Re Mi Fa Sol La Si
tone = [6,3,3,5,6,6,7,6,5,3,5,3,0,2,3,4,5,6,5,6,1,...
    7,6,7,6,1,2,2,3,2,6,1,7,1,6,1,...
    2,0,1,2,4,3,0,6,3,3,5,6,6,7,6,5,3,5,3,0,...
    2,3,4,5,6,5,6,1,7,1,7,6,7,6,1,2,2,3,2,6,...
    1,7,1,6,1,2,0,1,2,4,3,6,3,3,5,6,6,7,6,5,...
    3,5,3,0,2,3,4,5,6,5,6,1,7,6,7,6,1,2,2,3,2,6,...
    1,7,1,6,1,2,0,1,2,4,3,0,1,0,1,4,3,2,1,...
    3,2,4,1,0,1,4,3,2,1,3,3,7];

%% rythm:节拍数(音的长短)
%    全音符      “5---”     全休符     “0000”     1
%   二分音符      “5-”     二分休止符   “00”      1/2
%   四分音符(?)    “5”     四分休止符    “0”      1/4
% 八分音符(?或?)  “5_”    八分休止符    “0_”      1/8
% 十六分音符(?)  “5__”   十六分休止符  “0__”     1/16
% 附点音符(?):延长前面音符时值的一半  5? = 5 + 5_ 
% 延音线(~):连接起来的若干个音要唱成一个音,时值为这些音的总和 5~5=5+5
% 连音符(~3~):将音符的时值自由均分 555~3~=55=5_  5_5_5_~3~=5_5_=5
a = 1;       b = 1/2;     c = 1/4;    d = 1/8;     e = 1/16;    f = 1/32;
c1 = 1/6;    c2 = 2/6;   c3 = 3/4;    d3 = 3/8;    d4 = 1/12;   d5 = 5/12;
e3 = 3/16;   e5 = 5/16;
rythm = [b,b,c3,c,a,c,c,c,c, c3,c,b,a, b,b,b,b,c3,c,b,b,...
    c3,c,b,b,b, c3,c,c,c,c, c3,c,b,b,b,...
    b,c3,c,b,b, c3,a, b,b,c3,c,a,c,c,c,c, c3,c,b,a,...
    b,b,c3,c,c3,c,b,b, c,c,c,c,b,b,b, c3,c,c,c,c,...
    c3,c,b,b,b, b,c3,c,b,b, a, b,b,c3,c,a,c,c,c,c,...
    c3,c,b,a, b,b,b,b,c3,c,b,b, c3,c,b,b,b, c3,c,c,c,c,...
    c3,c,b,b,b, b,c3,c,b,b, c3,a, a,c3,c,b,b,b,b,...
    b,b,c3, a,c3,c,b,b,b,b, b,b,c3];

%% keynote_change:升降调8度
% 中音:不带点的基本符号
% 高音:基本符号上面加一个点    倍高音:基本符号上面加两个点
% 低音:基本符号下面加一个点    倍低音:基本符号下面加两个点
% 1代表中音,2代表高音
keynote_change = [0.25,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0,...
    0.5,0.5,0.5,0.5,1, 1,1,1,1,0.5, 1,0.5,1,0.5,1,...
    1,1,1,1,1, 1,1, 0.5,1,1,1,1,1,1,1,1, 1,1,1,1,...
    1,1,1,1,1,1,1,2, 1,2,1,1,1,1,2, 2,2,2,2,1,...
    2,1,2,1,2, 2,1,2,2,2, 2, 0.5,1,1,1,1,1,1,1,1,...
    1,1,1,1, 1,1,1,1,1,1,1,2, 1,1,1,1,2, 2,2,2,2,1,...
    2,1,2,1,2, 2,1,2,2,2, 2,1, 1,1,1,1,1,1,1,...
    1,1,1, 1,1,1,1,1,1,1, 1,1,1];

%% up_down:音节升降
% 临时变音记号有:“?”升号---升高半音,“?”降号---降低半音,
%                “?”还原号---将小节内“?”或“?”过的音回到原来的位置
% 0代表正常,1代表升号
up_down = [0,0,0,0,0,0,0,0,0, 0,0,0,0, 0,0,0,0,0,0,0,0,...
    0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,...
    0,0,0,0,0, 0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,...
    0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,...
    0,0,0,0,0, 0,0,0,0,0, 0, 0,0,0,0,0,0,0,0,0,...
    0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,...
    0,0,0,0,0, 0,0,0,0,0, 0,0, 0,0,0,0,0,0,0,...
    0,0,0, 0,0,0,0,0,0,0, 0,0,0];

%% 调用get_wave
y = [];
len = length(tone);
for i = 1:1:len
    y = [y, get_wave(tone(i), rythm(i), keynote_change(i), keynote_type(i), up_down(i))];
end
sound(y, Fs);

get_wave函数

function y = get_wave(tone, rythm, keynote_change, keynote_type, up_down)
% get_wave: 
% tone: 取哪个音节;  rythm: 节拍数;  up_down:音节升降
% keynote_change:升降调8度;  keynote_type:当前基调

    Fs = 8192;  %采样频率
    keynote_B = 493; %开始的节奏降E
    keynote_Ab = 415; %中间变为降A
    keynote_Fd = 739; %开始的节奏降E
    
    rythm = 1.25 * rythm;
    tones_normal = [1, 3, 5, 6, 8, 10, 12]; % 1-7 到 C D E F G A B映射

    if nargin == 5  %有改变基调&可能有升降调&可能有音节升降
        if keynote_type == 'A'
            keynote = keynote_Ab;
        elseif keynote_type == 'B'
            keynote = keynote_B;
        elseif keynote_type == 'F'
            keynote = keynote_Fd;
        end
        keynote = keynote * keynote_change;
    end
    
    if tone == 0    % 停顿
        tone = 13;
    else
        tone = tones_normal(tone);
    end
    
    freqs = [1, 1.059, 1.122, 1.189, 1.260, 1.335, 1.414, 1.498, 1.587, 1.682, 1.782, 1.888, 0] .* keynote.*(1.059^up_down);
    x = linspace(0, 2*pi*rythm, floor(Fs*rythm));
    y = sin(freqs(tone) * x) .* (1 - x/(2*pi*rythm));
end
  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值