基于MATLAB的电子琴设计

概述

乐器仿真是跨软件工程和音乐理论双领域的交叉学科研究方向,长期以来,受到专业知识的限制,音乐专业人士不能采用软件工程及数学方法对乐器声学原理进行深入的剖析,而软件工程人员对音乐知识了解相对较少,因此涉及音乐的软件工程研究一直相对薄弱。实际上,在现代信号处理、模式识别的技术支撑下,可以揭示音乐背后的数学秘密,提高人类对音乐的理解。软件工程技术在音乐领域的应用,将给人类带来全新的听觉感受,符合国家近期提出的文化强国理念,在人文、科技领域都具有研究意义。

先上个动图给大家看看效果:GUI显示电子琴琴键,黑白键代表不同的音符,点击对应琴键显示音符的时域波形图,并显示音符对应的频率信息,左下角可以调整节拍,即每个音符的持续时间,动图不能播放声音,真实运行其实是有声音的,真正实现了电子琴的效果。

在这里插入图片描述

这里贴出部分源代码:
在这里插入图片描述

将鼠标点击位置转为音符表:

% 作用: 把鼠标点击的位置转换为在音符表里的对应下标
% x, y: 鼠标点击坐标

function [row, col] = getPositionInTable(x, y)
    col = floor((x - 1) ./ 17 + 1);
    row = 2;                                                % row = 2 为白键音符所在行。白键排布有规律, 17像素一个白键。
    if y < 67                                               % 67是白键和黑键的交界处,如果鼠标点击的范围可能是黑键
        for left = -5 : 17 : 352                            % 黑键的排布规律
            right = left + 10;
            if left > x                                     % 如果x在两个黑键之间,直接跳出。使用上面算好的白键位置即可。
                break
            end
            if left <= x && x <= right                      % 如果落在某个黑键范围内
                preAmount = floor((left + 5) ./ 17 + 1);    % 算出是第几个黑键
                r = mod(preAmount, 7);                      %1 5 8 12 15个黑键其实是不存在的
                if r ~= 1 && r ~= 5                         % 如果黑键位置除以7的余数不是1也不是5,表示确实在黑键上
                    row = 1;                                % raw = 1 为黑键所在行
                    col = preAmount;                        % 列为算出的黑键位置
                end
                break                                       % 如果确实是不存在的黑键,直接跳出,还是使用上面算好的白键位置。
            end
        end
    end
end

将音符表转为音频信号


function music = noteText2Music(allNotes, noteTexts)
    % 用于把音符文本转换为音频信号。
    % -------------------------------
    % noteText样例:
    % { 'E41', 'C41', '01', 'AB41'}
    % -------------------------------
    global fs;
    global t;
    scaleTable = {'B', 'AB', 'A', 'GA', 'G', 'FG', ...
        'F', 'E', 'DE', 'D', 'CD', 'C'};            % 音阶表
    scaleNum = 0;
    music = [];
    [~, amount] = size(noteTexts);                  % 获取音符数量
    for i = 1 : amount
        noteText = noteTexts{i};
        if strcmp(noteText(1),'0') == 1             % 音符文本的第一个字符是0表示为休止符
            noteLength = str2double(noteText(2)); 
            switch noteLength
                case 1
                    note = zeros(1, 22051);    % 01 = 休止 1/2case 2
                    note = zeros(1, 11026);    % 02 = 休止 1/4case 3
                    note = zeros(1, 5513);     % 03 = 休止 1/4 秒
            end
        else
            scale = noteText(1:end-2);                  % 如果不是休止符则第一个字符到倒数第三个字符为音阶
            degree = str2double(noteText(end-1:end-1));	% 倒数第二个字符为音度
            noteLength = str2double(noteText(end:end)); % 最后一个字符为音符长度,含义与休止符最后一个字符相同
            equMartix = strcmpi(scaleTable, scale);     % 下面一个For循环用于查找音阶在音阶表中的位置
            for scaleNum = 1 : 12
                if equMartix(scaleNum) == 1
                    break
                end
            end
            note = [];
            note(1,:) = allNotes{noteLength}(scaleNum, degree,:); % note 为查表获得的音频信号
        end
    
        if isempty(music)       % 将所有的音频信号连接起来。
            music = note;
        else
            music = [music(:,:) note];
        end
    end
    music = music/max(music);   % 归一化
end


  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值