用 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. python数据相关性分析 (计算相关系数)

    #-*- coding: utf-8 -*- #餐饮销量数据相关性分析 计算相关系数 from __future__ import print_function import pandas as pd ...

  2. Layui_1.0.9_分页实例_Java

    一.实体 package com.ebd.application.modules.taskManage.pojo; import com.ebd.application.common.Base.Bas ...

  3. [代码]--python爬虫联系--爬取成语

    闲来无事,玩了个成语接龙,于是就想用python爬取下成语网站上的成语,直接上代码: #coding=utf-8 import requests from bs4 import BeautifulSo ...

  4. Django model 中的字段解释

    Django 通过 models 实现数据库的创建.修改.删除等操作,本文为模型中一般常用的类型的清单,便于查询和使用: AutoField:一个自动递增的整型字段,添加记录时它会自动增长.你通常不需 ...

  5. Vue模板 script部分

    <script> export default { name: "Home", data() { return {}; }, methods: { // 组件的方法 } ...

  6. NodeJs加载站点的所有页面不存在则404

    演示 链接:https://pan.baidu.com/s/1TZ351m3wUWZpq46qGbejjg 密码:ijj5 代码: var http = require("http" ...

  7. BZOJ5334 [TJOI2018] 数学计算 【线段树分治】

    题目分析: 大概是考场上的签到题.首先mod不是质数,所以不能求逆元.注意到有加入操作和删除操作.一个很典型的想法就是线段树分治.建立时间线段树然后只更改有影响的节点,最后把所有标记下传.时间复杂度是 ...

  8. 自学Python3.2-函数分类(内置函数)

    自学Python之路-Python基础+模块+面向对象自学Python之路-Python网络编程自学Python之路-Python并发编程+数据库+前端自学Python之路-django 自学Pyth ...

  9. 【BZOJ4738/UOJ#276】汽水(点分治,分数规划)

    [BZOJ4738/UOJ#276]汽水(点分治,分数规划) 题面 BZOJ UOJ 题解 今天考试的题目,虽然说是写完了,但是感觉还是半懂不懂的来着. 代码基本照着\(Anson\)爷的码的,orz ...

  10. qrcode模块简单使用

    函数式自动生成二维码 import qrcode img = qrcode.make("hello world!") img.get_image().show() img.save ...