用 Lua 控制 MIDI 合成器来播放自定义格式乐谱

说明: 本文是根据 七周七语言(卷2) 中的一个 Lua 示例项目略加修改而来.

目录

项目介绍

这个项目通过 Lua 调用一个用 C++ 实现的 MIDI 接口库 RtMidi 来控制一个 MIDI合成器 播放自定义格式的乐谱, 来演示 LuaC 之间的代码交互.

首先用 C++ 作为宿主程序, 把 Lua 解释器嵌入其中, 接着用 C++ 封装了一个可供 Lua 脚本调用的 C++ 函数 midi_send, 这个函数通过调用 RtMidi 库中的 APIMIDI合成器 发送控制命令来播放音乐, 而音乐的来源则是我们用 Lua 自定义格式的乐谱, 由 Lua 将其解析转换为 MIDI 合成器 能够识别的格式.

环境准备

这个项目是跨平台的, 可以同时支持 Windows/macOS/Linux 平台, 本文只提供 macOS 上的实现, 其他两个平台也很简单, 其中 Lua 部分的代码不需要改变.

需要安装以下环境

  • 包管理器 brew;
  • 编译工具 XCodegcc;
  • C sound 项目的源码跟 RtMidi;
  • LuaCMake;
  • macOS 下的 MIDI合成器: SimpleSynth

我的环境上只缺 C sound 项目, RtMidi 以及 SimpleSynth, 前两个用 brew 安装, 命令如下:

  • 添加 C sound 项目的源代码
Air:midi admin$ brew tap kunstmusik/csound
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 2 taps (homebrew/core and homebrew/cask).
==> New Formulae
azure-storage-cpp i386-elf-binutils maven@3.5 node@10 shellz um
fluxctl i386-elf-gcc mesa ruby@2.4 sourcedocs
==> Updated Formulae
bdw-gc ✔ dartsim hebcal mitie sec
c-ares ✔
......
==> Deleted Formulae
corebird kibana@4.4 maven@3.0 maven@3.1 nethack4 ruby@2.2 taylor tcptrack
Error: Failed to import: /usr/local/Homebrew/Library/Taps/benswift/homebrew-extempore/extempore-llvm341.rb
extempore-llvm341: undefined method `sha1' for #<Class:0x000000011189d728> ==> Tapping kunstmusik/csound
Cloning into '/usr/local/Homebrew/Library/Taps/kunstmusik/homebrew-csound'...
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 7 (delta 0), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (7/7), done.
Tapped 3 formulae (34 files, 28.1KB).
Air:midi admin$
  • 安装 RtMidi
Air:midi admin$ brew install rtmidi
==> Downloading https://homebrew.bintray.com/bottles/rtmidi-3.0.0.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring rtmidi-3.0.0.high_sierra.bottle.tar.gz

用 Lua 控制 MIDI 合成器来播放自定义格式乐谱的更多相关文章

  1. 自定义css样式结合js控制audio做音乐播放器

    最近工作需求需要播放预览一些音乐资源,所以自己写了个控制audio的音乐播放器. 实现的原理主要是通过js调整audio的对象属性及对象方法来进行控制: 1.通过play().pause()来控制音乐 ...

  2. H5多媒体(用面向对象的方法控制视频、音频播放、暂停、延时暂停)

    视频,音频播放器会是我们在工作中用到的一些h5新标签,它自带一些属性,比如暂停播放,快进快退,但是,我们经常不用原生的样式或者方法,我们需要自定义这些按钮来达到我们需要的样式,也需要我们自定义来实现一 ...

  3. 重新想象 Windows 8.1 Store Apps (90) - 通信的新特性: 通过 HttpBaseProtocolFilter 实现 http 请求的缓存控制,以及 cookie 读写; 自定义 HttpFilter; 其他

    [源码下载] 重新想象 Windows 8.1 Store Apps (90) - 通信的新特性: 通过 HttpBaseProtocolFilter 实现 http 请求的缓存控制,以及 cooki ...

  4. HTML5 - 使用JavaScript控制<audio>音频的播放

    有时我们需要使用js来控制播放器实现音乐的播放,暂停.或者使用js播放一些音效.   1,通过JavaScript控制页面上的播放器 比如把页面上添加一个<audio>用来播放背景音乐(由 ...

  5. 想控制GIF图片动画播放吗?试试gifffer.js

    在线演示:http://www.gbtags.com/gb/demoviewer/3578/c6bec39a-61ae-4017-8e23-e0bc1eeb740f/example|index.htm ...

  6. MmSystem播放Wav格式声音

    //MmSystem播放Wav格式声音 //MmSystem 支持 *.wav声音格式 snd ->SoundRecorderuses MmSystem; //引用MmSystem//播放系统声 ...

  7. 多浏览器播放wav格式的音频文件

    html5的audio标签只在火狐下支持wav格式的音频播放,无法兼容IE和google , 使用audioplayer.js 基本上能支持大部分浏览器播放wav音频文件,经测试IE.火狐.googl ...

  8. opencv实例三:播放AVI格式视频

    一.不带滚动条的视频读取播放. 1.原理介绍:视频的本质是一些静态的图像的集合,opencv可以不断读取视屏中的图片,显示,就可以实时的视频流进行处理了. 2.代码如下: /************* ...

  9. amr格式转mp3和直接播放amr格式的文件-sunziren

    原创文章,转载请注明出处! 前言: amr作为一种高压缩比的音频格式,受到很多客户的青睐.本文主要涉及两部分的内容,一是amr如何转为mp3格式,二是如何直接播放amr格式的文件. 1. 如何使用Ja ...

随机推荐

  1. Win10 1803 Spring Creators update Consumer edition的版本记录

    安装时可选择的版本列表 安装完之后的版本: 3. 时间线更新 4. Focus assistant

  2. Java 死锁

    什么是死锁? 当一个线程永远地持有一个锁,并且其他线程都尝试去获得这个锁时,那么它们将永远被阻塞,当线程A持有锁1想获取锁2,当线程B持有锁2想获取锁1 这种情况下就会产生2个线程一直在阻塞等待其他线 ...

  3. python之字典操作

    字典操作代码如下: #数据字典操作汇总 person = {'name': 'Mike', 'age': 25} print("初始的数据字典:", person) #访问字典值 ...

  4. Lodop在页面获取打印机列表 选择打印机预览

    利用GET_PRINTER_COUNT,获取打印机个数,然后用GET_PRINTER_NAME(intPrinterIndex);循环获取打印机名称,添加到list列表里,可以让用户在页面就选择打印机 ...

  5. BZOJ5361[Lydsy1805月赛]对称数——主席树+随机化

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=5361 好神的一道题啊! 容易看出来是要用维护权值的数据结构,因此树链剖分首先pass掉. ...

  6. Fire Net ZOJ - 1002

    题意: 一个n * n 的棋盘 上面有些障碍物  放棋子 棋子不能在同一行 同一列 但可以在同一行或同一列隔着障碍物放 这题与poj1321  的思想差不多 对于一个位置 有两种状态放还是不放 参数i ...

  7. 在 Ali Kubernetes 系统中,我们这样实践混沌工程

    在传统的软件测试中,我们通常通过一个给定的条件来判断系统的反馈,通过断言来判断是否符合预期,测试条件和结果通常比较明确和固定.而混沌工程,是通过注入一些“不确定”因素,象放进了一群淘气的猴子,在系统资 ...

  8. 【BZOJ4712】洪水(动态dp)

    [BZOJ4712]洪水(动态dp) 题面 BZOJ 然而是权限题QwQ,所以粘过来算了. Description 小A走到一个山脚下,准备给自己造一个小屋.这时候,小A的朋友(op,又叫管理员)打开 ...

  9. sql server 小技巧(2) 删除sql server中重复的数据

    with list_numbers as ( select Name, AuthorOrTime, Url, Price, EstimatePrice, Size, Category, ROW_NUM ...

  10. python常见面试题(三)

    问题1 到底什么是Python?你可以在回答中与其他技术进行对比(也鼓励这样做). 答案 下面是一些关键点: Python是一种解释型语言.这就是说,与C语言和C的衍生语言不同,Python代码在运行 ...