matlab卡农,又用Mathematica写了一段卡农

2023-11-10

你能在这里听到它

用数学软件演奏音乐早已不是什么新鲜事,很早就有人用Matlab弹奏卡农或是最炫民族风,最近我知道还有人用无理数生成一段音乐,很有趣。而我选择用Mathematica弹奏卡农是因为卡农这种谱曲方式很奇妙,体现在程序上也会是简洁而优美的。可能有人还不了解卡农是什么,卡农不是指某一首曲子,而是一种谱曲方式,它把几段相同的旋律在不同的时刻依次展开,交错的旋律又能相互配合,形成一首完整的卡农。这用Mathematica演奏的卡农就是大家最耳熟的“帕赫贝尔的卡农”,你可以在它的乐谱中一窥其中的奇妙。

87d9f2f8e684

我们关注的重点是,这首卡农有三个声部(在乐谱上对应着前三排)和一个背景旋律,但实际上三个声部演奏的旋律是相同的,所以我们只需要输入一个声部的谱子,然后让三个声部在不同的时间进入就可以了。

手动输入乐谱——失败

起初我在网上找到的是巴赫的手稿,当我把一个声部的旋律都输入进去后,最终的效果并不是很理想,我想这个谱子更适合音乐会弹奏,需要乐手控制不同声部的音量与节奏,但这在Mathematica上很难实现。

87d9f2f8e684

从Matlab到Mathematica

后来我在网上发现了一个用Matlab弹卡农的程序,听过之后,感觉他的谱子更适合用软件演奏。就决定把Matlab代码翻译到Mathematica上。首先我们分析一下Matlab的代码

Matlab代码

Matlab中的代码一共分三部分

1. 告诉电脑如何弹奏音符

2. 输入一个声部的旋律

3. 组合三个声部

1.告诉电脑如何弹奏音符

我们需要告诉电脑

i.音符名称(do,re,mi,fa...)

ii.音符持续的时间(音符时值t)

iii.音调(频率f)

所以我们输入的应该是如下格式的信息:

音符名称=sin(2πft)

看看这在Matlab中是如何做到的% 1/4 notes

do0f = mod4.*cos(2*pi*ScaleTable(21)*f0*t4);

re0f = mod4.*cos(2*pi*ScaleTable(22)*f0*t4);

mi0f = mod4.*cos(2*pi*ScaleTable(23)*f0*t4);

% 1/8 notes

fa0e = mod8.*cos(2*pi*ScaleTable(1)*f0*t8);

so0e = mod8.*cos(2*pi*ScaleTable(2)*f0*t8);

la0e = mod8.*cos(2*pi*ScaleTable(3)*f0*t8);

% 1/16 notes

fa0s = mod16.*cos(2*pi*ScaleTable(1)*f0*t16);

so0s = mod16.*cos(2*pi*ScaleTable(2)*f0*t16);

la0s = mod16.*cos(2*pi*ScaleTable(3)*f0*t16);

初看感觉很复杂,但其实它的形式和上面的公式是相同的

i.do0f,re0f,mi0f...代表音符名称

ii.ScaleTable(\space)*f0代表频率f,不同音符的ScaleTable()不同

iii.t4,t8,t16代表持续时间$t$,更具体的,t4=0.5s,t8=0.25s,t16=0.125s

但我们还发现他多出一个mod函数,这其实是一个修正函数(modify),乘上他之后可以让波形变得更柔和,有渐入渐出的效果。

87d9f2f8e684

未经mod修正过的波形

87d9f2f8e684

经mod修正过的波形

mod后面的数字代表对应音符的持续时间。比如mod4要和t4相乘。

2. 输入一个声部的音符

这一步就很好理解了,这首卡农背景旋律(Base Melody)由大提琴演奏,主旋律(Long Melody )由三把小提琴演奏,我们分别命名cello和violin% Base Melody

cello = [do1f do1f so0f so0f la0f la0f mi0f mi0f... fa0f fa0f do0f do0f fa0f fa0f so0f so0f];......

% Long Melody

violin = [mi2f mi2f re2f re2f do2f do2f ti1f ti1f... la1f la1f so1f so1f la1f la1f ti1f ti1f ......

3.组合三个声部

正如我前面说的,我们只需要在不同的时间点加入相应的旋律,就像下面这样(blkblock代表空白音符)% violin1

v1 = [blkblock violin blkblock blkblock];

% violin2

v2 = [blkblock blkblock violin blkblock];

% violin3

v3 = [blkblock blkblock blkblock violin];

% Combination

s = c1+v1+v2+v3;

sound(s,fs);

这样就得到了一段能在Matlab上演奏卡农的代码,接下来就要把它翻译到Mathematica上。

翻译到Mathematica

我们当然要借助Mathematica来翻译,思路跟Matlab上的思路一样

1.建立音符名称和声音的关联(Association)

最终的关联应该像下面这样。我给这个关联起名叫“asswecan”,意思是用这个关联我们能做到「音符名称到声音的转换」,记住这个名字,我们之后会用到。

87d9f2f8e684

那么要如何生成这个关联呢?首先我们需要生成声音,这里用到Play函数:

87d9f2f8e684

一个频率为440Hz的“中音A”的波形

根据Matlab代码中的音符信息「ScaleTable(),f0,t4,t8,t16」改变Play函数中的参数来发出不同的音调,替换的关系是这样的:

87d9f2f8e684

有了这个思路,就可以用StringReplace函数进行替换了。

2.输入一个声部的旋律

Matlab中的旋律代码有许多多余的字符,需要我们处理一下

i.输入Matlab代码中的旋律cellonoteinfo =

"do1f do1f so0f so0f la0f%% la0f mi0f mi0f...fa0f%% fa0f do0f do0f fa0f \n

fa0f so0f so0f";

这里面有很多我们不希望得到的 ... %% 空格回车这样的字符,需要把他们去掉。

ii.定义去掉无用字符的函数infotonote[info_] :=

StringPartition[StringJoin@StringCases[info, _?LetterQ | _?DigitQ],4];

iii.得到适用于Mathematica的旋律In[1]:= cellonote = infotonote[cellonoteinfo]

Out[1]:= {"do1f", "do1f", "so0f", "so0f", "la0f", "la0f", "mi0f", "mi0f", \

"fa0f", "fa0f", "do0f", "do0f", "fa0f", "fa0f", "so0f", "so0f"}

这样我们就得到了旋律中的音符名称列表

3.用声音替换旋律中的音符名称

还记得那个"asswecan"吗?它可以把音符名称替换成声音。用“asswecan”关联完成对几段旋律的转换,并规定好他们开始弹奏的时间,比如vio1末尾的8就代表第一把小提琴在第8秒才开始弹奏。cello = Sound[Flatten@Table[Replace[cellonote, notetosoundass, 1], 23], {0}];

vio1 = Sound[Replace[violinnote, notetosoundass, 1], {8}];

vio2 = Sound[Replace[violinnote, notetosoundass, 1], {16}];

vio3 = Sound[Replace[violinnote, notetosoundass, 1], {24}];

4.最后把他们组合起来

87d9f2f8e684

As we can see, 我们完成了!

你可以在B站听到这段旋律

你也可以前往Wolfram社区下载Matlab及Mathematica代码文件

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

matlab卡农,又用Mathematica写了一段卡农 的相关文章

  • [OpenGL]第一章 OpenGL概述

    第一章 OpenGL概述 1 1 什么是OpenGL OpenGLwikipedia是一种应用程序编程接口 API 它是一种可以对图形硬件设备特性进行访问的软件库 一个用来渲染图像的OpenGL程序需要执行的主要操作如下 从OpenGL的几
  • windows下安装虚拟机+ Ubuntu的详细过程

    windows下安装虚拟机 Ubuntu的详细过程 Ubuntu在VMware中无法全屏 界面太小问题的解决方法
  • 第18讲支架

    弄了个直射光源 晃了下方向 有效果 支架无非就是复制过来的 从技术上说不难 从艺术上确实牛逼
  • springmvc 使用JSR-303进行数据校验

    项目中 通常使用较多的是前端的校验 比如页面中js校验以及form表单使用bootstrap校验 然而对于安全要求较高点建议在服务端进行校验 服务端校验 控制层controller 校验页面请求的参数的合法性 在服务端控制层controll
  • php+中defined,phpdefined()函数的用法总结

    The define function defines a constant define 函数的作用是 定义一个常量 Constants are much like variables except for the following d
  • AMS磁编码器:AS5048与AS5047区别,伺服电机闭环系统位置反馈

    本文只简介 AMS的磁编码器 其他厂商磁编IC见另一篇 https blog csdn net Mark md article details 100181701 新增补了一篇 详细介绍了GMR磁编码器原理 同类对比优劣 安装方式 设计注意
  • Excel中万能的查询函数——VLOOKUP(使用方法+实操)

    Vlookup函数 基础用法并不难 尤其遇到需要查询匹配的问题 简直不要太好用 但想要掌握全部用法还是需要时间的 对vlookup用法做了超强汇总表 检索 vlookup函数用法大全https link zhihu com target h
  • java中定时任务 schedule 分布式下没有锁住 时间不同步 执行滞后 相对时间 系统时间 spring springboot

    java util Timer计时器可以进行 管理任务延迟执行 如1000ms后执行任务 及周期性执行 如每500ms执行一次该任务 但是 Timer存在一些缺陷 应考虑使用ScheduledThreadPoolExecutor代替 Tim
  • 每一个C++开发者都应该知道的线上工具

    要想代码写得丝滑 怎么可以不熟练各种开发工具呢 锤子用的好 烦恼会减少 这里推荐几个C 开发中用于编译 构建 调试和性能分析的线上工具 最初的资料来源于Lightning Talk Online Tools Every C Develope
  • docker 安装完全分布式Hadoop集群

    一 搭建原因 鉴于本人机器性能较低 在机器上运行多个Linux虚拟机比较吃力 如果再在其上运行分布式计算环境 想必更加吃力 我想这也是很多同学的普遍问题 通过百度 我了解到了docker技术 网上有很多docker搭建Hadoop的教程 总
  • 微信小程序登陆账号验证隐私协议验证页面及代码

    微信小程序登陆页 页面主要是需要校验账号手机号 验证勾选同意使用协议和隐私政策 效果如下 1 账号密码部分页面代码
  • 移动Web开发入门(一) -- 像素、媒体查询、em、rem

    文章目录 一 移动Web开发 二 基本概念 分辨率 物理像素 CSS像素 物理像素和CSS像素的关系 设备像素比 dpr 获取dpr PPI DPI 视口 viewport 设置 Viewport 获取视口宽度 三 媒体查询 媒体类型 媒体
  • Java中Logger类应用

    类 Logger java lang Object java util logging LoggerLogger 对象用来记录特定系统或应用程序组件的日志消息 一般使用圆点分隔的层次名称空间来命名 Logger Logger 名称可以是任意
  • 最小费用最大流问题与算法实现(Bellman-Ford、SPFA、Dijkstra)

    摘要 今日 对最小费用最大流问题进行了一个简单的研究 并针对网上的一些已有算法进行了查找和研究 博客和资料很多 但是留下的算法很多运行失败 出错 或者意义不明 这里 个人对其中的Bellman Ford SPFA 改进的Dijkstra三种
  • CompletableFuture线程池执行多个任务进行链式、组合等助理使用

    2 1 CompletableFuture简介 使用线程池执行任务没法直接对多个任务进行链式 组合等处理 或者说实现起来比较麻烦需要借助并发工具类才能完成 CompletableFuture实现了对任务编排的能力 借助这项能力 可以轻松地组
  • Pycharm 出现报错:Failed building wheel for XXX

    报错原因 是因为Python解释器的版本太高 与Pycharm版本不符 解决办法 安装一个比pycharm低一个版本的python解释器 比如pycharm3 10 那Python就3 9或以下版本 如果答案 您满意 请采纳意见和点赞关注
  • 【操作系统原理】01-操作系统概览

    一 What Why 操作系统是管理计算机硬件和软件资源的计算机程序 管理配置内存 决定资源供需顺序 控制输入输出设备等 操作系统提供让用户和系统交互的操作界面 从手机到超级计算机 操作系统可简单也可复杂 操作系统的种类是多种多样的 不局限
  • SVN服务器搭建和使用(一)

    Subversion是优秀的版本控制工具 其具体的的优点和详细介绍 这里就不再多说 首先来下载和搭建SVN服务器 现在Subversion已经迁移到apache网站上了 下载地址 http subversion apache org pac
  • C#复制构造函数学习

    通过从另一个对象复制变量或将一个对象的数据复制到另一个对象来创建对象的构造函数称为复制构造函数 复制构造函数是一个参数化构造函数 包含相同类类型的参数 它的主要用途是将新实例初始化为现有实例的值 using System namespace

随机推荐

  • 电脑提示MSVCP140.dll文件丢失的解决方法

    打开软件或者游戏出现运行出现报错 提示 由于找不到 MSVCP140 dll 无法继续执行代码 重新安装程序可能会解决此问题 这一般是什么原因导致了这个问题 我们要如何解决 下面小编分享一下由于找不到MSVCP140 dll无法继续执行代码
  • linux卸载zookeeper_Zookeeper学习

    zookeeper 是一个分布式协调服务的开源框架 主要用来解决分布式集群中应用系统的一致性问题 本质上是一个分布式的小文件存储系统 提供基于类似文件系统的目录树方式的数据存储 并且可以对树中的节点进行有效管理 从而用来维护和监控你存储的数
  • nosql 之认识篇

    使用sql server n年后 发现mysql这个开源数据库也很好用 于是投身到这个行列中 最近开发个sns类型的网站 随着用户的增多 感觉数据库所承受的压力成为了整个网站继续发展的瓶颈 为了更好的解决此问题 发现twitter face
  • CRNN+CTC实现不定长验证码识别(keras模型-训练篇)

    目录 前言 运行环境 生成数据集 构建网络模型 初步训练模型 测试模型 进一步训练模型 结语 前言 本文为CRNN CTC实现不定长验证码识别 keras模型 示例篇 的续篇 示例篇中使用的字符仅为数字 本文将训练集拓展到包含数字字母在内的
  • SharedPreferences存储

    目录 1 获得SharedPreferences对象 1 1 使用getSharedPreferences 方法获取 1 2 使用getPreferences 方法获取 2 向SharedPreferences文件中存储数据 3 读取Sha
  • 封装一个底部导航

    html部分
  • GPT-3.5-turbo小白连接教程

    前言 最近在看Chat几批题的相关内容 尝试了在自己电脑上调用一下OpenAI的api 下面以调用几批题 3 5 turbo为例进行讲解 本次分享分为三大模块 第一个模块先对连接成功后的AI聊天机器人的功能进行简要了解 第二个模块讲一下国内
  • mysql workbench怎么设置为中文?(仅菜单项汉化)附带main_menu文件

    找到Mysql Workbench安装目录 若全部默认则地址如下 C Program Files MySQL MySQL Workbench 8 0 CE data 里面有main menu xml文件 用汉化后的文件替换软件重启即可 链接
  • 性能测试ftp服务器,测试ftp服务器的性能

    测试ftp服务器的性能 内容精选 换一换 云耀云服务器适用于对CPU 内存 硬盘空间和带宽无特殊要求 服务一般只需要部署在一台或少量的服务器上 一次投入成本少 后期维护成本低的场景 例如网站开发 Web应用 推荐使用云耀云服务器 主要提供均
  • 退出屏保前玩一把游戏吧!webBrowser中网页如何调用.NET方法

    本文主要以 HackerScreenSaver 新功能的开发经历介绍 webBrowser中网页如何调用 NET方法的过程 1 背景 之前开源了一款名为 HackerScreenSaver 的 Windows 屏保程序 该程序具有模拟黑客炫
  • 大专应届生内心独白:室友都有依靠,孤单的只有我自己

    前言 室友都有大腿抱 孤单的只有自己 作为大专生 我们大三下学期没有课程 主要是写论文 找工作 可我一点也不着急 因为我还没做好毕业的准备 也很迷茫 室友A准备回老家考公务员 室友B的父母已经给他找好了工作 室友C去亲戚公司了 而我 却只能
  • 一个关于POP3协议超时的问题

    前段时间在做一个email项目时 一个测试人员报了一个BUG 就是当email客户端在连接hotmail 的POP3服务器之后大概4 5分钟就会自动把客户端断掉 为这个问题我查了一下POP协议规范 协议中有这么一段话 POP3服务器可以拥有
  • 老司机才懂的测试问题定位方法!

    在软件开发过程中 项目测试是至关重要的一环 然而 测试过程中常常会遇到各种问题 本文将介绍一些常见的项目测试问题 并探讨如何有效地定位这些问题 1 问题一 功能不符合预期 定位方式 检查需求文档和设计文档 确保理解功能的正确性和预期行为 仔
  • MSF使用教程

    MSF使用教程 1 简介 Metasploit是一款开源安全漏洞检测工具 附带数百个已知的软件漏洞 并保持频繁更新 被安全社区冠以 可以黑掉整个宇宙 之名的强大渗透测试框架 2 MSF模块介绍 1 辅助模块 auxiliary 负责执行信息
  • 字符集编码(GBK,BIG5,UNICODE)与C++的string/wstring

    GBK BIG5等字符集编码范围的具体说明 一 预备知识 1 字符 字符是抽象的最小文本单位 它没有固定的形状 可能是一个字形 而且没有值 A 是一个字符 德国 法国和许多其他欧洲国家通用货币的标志 也是一个字符 中 国 这是两个汉字字符
  • 以太坊2.0主网即将上线 一轮前所未有的超级牛市来了

    8月4日 以太坊2 0第0阶段信标链的最终版测试网Medalla上线 多个客户端同时运行测试 至少有16384个验证者参与了本次测试 在测试过程中 虽然出现了Nimbus 和 Lodestar 节点因无法处理测试网的负载量而卡住 导致Med
  • logback配置两套日志路径

    日志推送工作根据公司日志管理规范及国家攻防演练需要 请协助对所有应用重要场景的日志进行收集 需求如下 1 涉及场景 用户登录场景 密码修改场景 密码找回场景 注册场景 2 日志字段需求及格式 filebeat对接日志格式 登录 修改 注册
  • 消息队列MQ-面试题

    一个用消息队列 的人 不知道为啥用 MQ 这就有点尴尬 1 什么是消息队列 可以看作是一个存放消息的容器 当我们需要使用消息的时候可以取出消息供自己使用 消息队列是分布式系统中重要的组件 使用消息队列主要是为了通过异步处理提高系统性能和削峰
  • vue3 中应用 element plus,pinia 实现简易购物车

    使用pinia 进行全局的状态管理 降低组件之间的耦合性 一 项目需要的资源 1 element plus官方地址 https element plus gitee io zh CN guide quickstart html 2 pini
  • matlab卡农,又用Mathematica写了一段卡农

    你能在这里听到它 用数学软件演奏音乐早已不是什么新鲜事 很早就有人用Matlab弹奏卡农或是最炫民族风 最近我知道还有人用无理数生成一段音乐 很有趣 而我选择用Mathematica弹奏卡农是因为卡农这种谱曲方式很奇妙 体现在程序上也会是简