MATLAB 编写简易电子琴

2023-11-01 07:00
文章标签 matlab 编写 简易 电子琴

本文主要是介绍MATLAB 编写简易电子琴,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 声音模型
  • 音色
  • 简易电子琴

用MATLAB遍了一个小程序,可以弹奏一些简单的曲子。演示视频:
Bilbili视频:MATLAB 编写简易电子琴
一个电子琴基本的要求应当是能按键盘命令发出特定音高和音色的声音。键盘命令我用的是input 函数,缺点是每按一个键要回车使得弹奏很难连续,但目前没想到合适的替代方法;而声音的音高和音色则分别基频和泛频决定

声音模型

声音本质是机械振动产生的波通过介质传播至人耳,这一振动可由函数 x ( t ) x(t) x(t)表示,离散化后即为向量 x n x_n xn以及采样率 f s f_s fs,且满足 x n = x ( t n ) , t n = n / f s x_n=x(t_n), t_n=n/f_s xn=x(tn),tn=n/fs.
而MATLAB 中可用sound(x,fs)函数发出一段声音,如下面的代码运行后将发出一段白噪声:

 x=normrnd(0,1,1,10000);fs=5000;sound(x,fs)

琴弦则近似以如下方式振动(数学物理方法等教材有介绍):
x ( t ) = ∑ n = 1 N A n s i n ( 2 π f n t + ϕ n ) x(t)=\sum_{n=1}^{N}A_nsin(2\pi f_nt+\phi_n) x(t)=n=1NAnsin(2πfnt+ϕn)
其中基频 f 1 f_1 f1 决定声音的音高, f n , n > 1 f_n, n>1 fn,n>1决定音色。基频与音阶的部分对应表如下(没有加升降音):
E4 329.63
F4 349.23
G4 392
A4 440
B4 493.88
C5 523.25
D5 587.33
E5 659.25
F5 698.46
G5 783.99
A5 880
B5 987.77
C6 1046.5
D6 1174.66
E6 1318.51
F6 1396.91
G6 1567.98
A6 1760
B6 1975.53

于是,在MATLAB中发出A4音的代码如下:

fs=5000;
t=0:1/fs:1;
f=440;
x=sin(2*pi*f*t);
sound(x,fs)

音色

除基频 f 1 f_1 f1外,还有由高阶模式振动产生的倍频,各本征频频的振幅 A n A_n An以及相位 ϕ n \phi_n ϕn确定了声音的音色,简单起见,假定 ϕ 0 = 0 \phi_0=0 ϕ0=0。并加入一个衰减:
x ( t ) = e − t 2 / 2 t 0 2 ∑ n = 1 N A n s i n ( 2 π f n t ) x(t)=e^{-t^2/2t_0^2}\sum_{n=1}^{N}A_nsin(2\pi f_nt) x(t)=et2/2t02n=1NAnsin(2πfnt)
从网上找到一段任意音高的钢琴音,傅里叶变换后频谱如下:
记录下前八个本征频率对应的振幅 A n A_n An如下:
645.4
183.7
30
20
20
20
20
56

简易电子琴

编写函数piano(f,amp),其中f 为基频,amp为最低的数个本征频率对应的振幅,其中f通过查找键盘输入的音阶对应的频率得到。再循环运行此函数即可
代码如下:

Amp=xlsread('Amp.xlsx');
Amp=1/max(Amp)*Amp;
n=length(Amp);f=xlsread('frequency.xlsx','B:B');
%To input "exit" to exit
IN=0;
or=1;
while 1IN=input('','s');switch INcase 's'or=1;case 'a'or=0;case 'd'or=2;case '1'piano(f(or*7+1),Amp);case '2'piano(f(or*7+2),Amp);case '3'piano(f(or*7+3),Amp);case '4'piano(f(or*7+4),Amp);case '5'piano(f(or*7+5),Amp);case '6'piano(f(or*7+6),Amp);case '7'piano(f(or*7+7),Amp); case 'exit'breakotherwisedisp('Again');end
endfunction p=piano(f,amp)
fs=32000;
t=0:1/fs:1;
x=0*t;
n=length(amp);
for i=1:nx=x+amp(i)*sin(2*pi*f*i*t); 
end
x=x.*exp(-1/(2*0.3^2)*t.^2);
sound(x,fs)
p=1;
end

这一电子琴小程序是写着玩的,非常简陋,一个较大的问题就是弹奏很难连续。如果有改进建议欢迎留言

这篇关于MATLAB 编写简易电子琴的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/321297

相关文章

python实现简易SSL的项目实践

《python实现简易SSL的项目实践》本文主要介绍了python实现简易SSL的项目实践,包括CA.py、server.py和client.py三个模块,文中通过示例代码介绍的非常详细,对大家的学习... 目录运行环境运行前准备程序实现与流程说明运行截图代码CA.pyclient.pyserver.py参

使用PyQt实现简易文本编辑器

《使用PyQt实现简易文本编辑器》这篇文章主要为大家详细介绍了如何使用PyQt5框架构建一个简单的文本编辑器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录分析主窗口类 (MyWindow)菜单操作语法高亮 (SyntaxHighlighter)运行程序主要组件代码图示分析实现

5分钟获取deepseek api并搭建简易问答应用

《5分钟获取deepseekapi并搭建简易问答应用》本文主要介绍了5分钟获取deepseekapi并搭建简易问答应用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需... 目录1、获取api2、获取base_url和chat_model3、配置模型参数方法一:终端中临时将加

利用Python编写一个简单的聊天机器人

《利用Python编写一个简单的聊天机器人》这篇文章主要为大家详细介绍了如何利用Python编写一个简单的聊天机器人,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 使用 python 编写一个简单的聊天机器人可以从最基础的逻辑开始,然后逐步加入更复杂的功能。这里我们将先实现一个简单的

用Java打造简易计算器的实现步骤

《用Java打造简易计算器的实现步骤》:本文主要介绍如何设计和实现一个简单的Java命令行计算器程序,该程序能够执行基本的数学运算(加、减、乘、除),文中通过代码介绍的非常详细,需要的朋友可以参考... 目录目标:一、项目概述与功能规划二、代码实现步骤三、测试与优化四、总结与收获总结目标:简单计算器,设计

使用PyQt5编写一个简单的取色器

《使用PyQt5编写一个简单的取色器》:本文主要介绍PyQt5搭建的一个取色器,一共写了两款应用,一款使用快捷键捕获鼠标附近图像的RGB和16进制颜色编码,一款跟随鼠标刷新图像的RGB和16... 目录取色器1取色器2PyQt5搭建的一个取色器,一共写了两款应用,一款使用快捷键捕获鼠标附近图像的RGB和16

如何用Python绘制简易动态圣诞树

《如何用Python绘制简易动态圣诞树》这篇文章主要给大家介绍了关于如何用Python绘制简易动态圣诞树,文中讲解了如何通过编写代码来实现特定的效果,包括代码的编写技巧和效果的展示,需要的朋友可以参考... 目录代码:效果:总结 代码:import randomimport timefrom math

通过C#和RTSPClient实现简易音视频解码功能

《通过C#和RTSPClient实现简易音视频解码功能》在多媒体应用中,实时传输协议(RTSP)用于流媒体服务,特别是音视频监控系统,通过C#和RTSPClient库,可以轻松实现简易的音视... 目录前言正文关键特性解决方案实现步骤示例代码总结最后前言在多媒体应用中,实时传输协议(RTSP)用于流媒体服

使用Java编写一个文件批量重命名工具

《使用Java编写一个文件批量重命名工具》这篇文章主要为大家详细介绍了如何使用Java编写一个文件批量重命名工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录背景处理1. 文件夹检查与遍历2. 批量重命名3. 输出配置代码片段完整代码背景在开发移动应用时,UI设计通常会提供不

如何编写Linux PCIe设备驱动器 之二

如何编写Linux PCIe设备驱动器 之二 功能(capability)集功能(capability)APIs通过pci_bus_read_config完成功能存取功能APIs参数pos常量值PCI功能结构 PCI功能IDMSI功能电源功率管理功能 功能(capability)集 功能(capability)APIs int pcie_capability_read_wo