“有关Web MIDI的教程? 在2016年? 你开玩笑的对吧?”

没有! 这不是你的想法! 对于我们自1990年代以来一直使用网络的用户来说,“ Web MIDI”一词通常会引起倒叙,直到网站上您在签署网站管理员的留言簿时自动播放低俗版的《最终倒计时》。 但是,在2016年,Web MIDI(尤其是Web MIDI API)具有更大的潜力。

乐器数字接口的MIDI标准。 该协议允许电子乐器,计算机和其他设备相互通信。 它通过从一台设备向另一台设备发送小消息来工作,例如说“刚刚按下了注释12”或“不再按下注释62”,但是是以数字的形式表示的。

Web MIDI API使用此协议,并允许您使用支持MIDI的乐器(例如键盘),将其连接到计算机,并将信息从键盘发送到浏览器。

目前, Chrome和Opera中仅支持 Web MIDI API,但是您可以通过访问此Bug来跟踪其在Firefox中的进度。

那么,为什么我们要将键盘连接到Web浏览器呢? 好吧,没有多少音乐家像音乐演奏家那样了解QWERTY键盘。 另外,支持MIDI的音乐设备种类繁多。 通过将支持MIDI的输入设备连接到我们的浏览器,以及使用Web Audio API,我们可以在网络上创建乐器。

想弹钢琴吗? 只需连接键盘,然后访问使用这些技术复制钢琴声音的网页即可。 想要不同的声音? 只需访问其他站点。

希望您可以看到此API的好处,但是它实际上如何工作?

访问MIDI设备

首先,我们要检查我们的浏览器是否支持Web MIDI API。 我们通过查看是否存在navigator.requestMIDIAccess方法来完成此操作。 仅在支持API的浏览器中实现此方法。

if (navigator.requestMIDIAccess) {console.log('Browser supports MIDI!');
}

现在我们知道该方法存在,让我们调用它以请求访问浏览器附带的任何MIDI输入。

if (navigator.requestMIDIAccess) {navigator.requestMIDIAccess().then(success, failure);
}

navigator.requestMIDIAccess()返回一个promise,这意味着它将根据请求MIDI访问的结果调用成功函数或失败函数。 在这里,我们给了它接下来要创建的两个函数的名称。

function success (midi) {console.log('Got midi!', midi);
}function failure () {console.error('No access to your midi devices.')
}

如您所见,我们的成功函数采用MIDIAc​​cess对象形式的MIDI参数。 MIDIAc​​cess对象是接收Midi数据的关键。 对象本身为您连接的任何MIDI设备提供了接口。 输入代表您已连接到计算机的任何MIDI设备。 我连接了一个MIDI键盘,因此,如果要登录midi.inputs.size ,它将输出“ 1”。

为了从我们的设备获取输入数据,我们首先创建一个变量,然后像这样给它分配midi.inputs.values()

var inputs = midi.inputs.values();

需要注意的重要一点是,分配给inputs的值是一个迭代器 。 迭代器是一个对象,它知道如何一次访问其属性,同时跟踪迭代序列中的当前位置。 它提供了next()方法,使您可以获取序列中的下一项。 它也有一个done属性,让我们知道是否已遍历对象的所有属性。 这意味着我们可以为这样的循环编写奇特的代码:

for (var input = inputs.next();input && !input.done;input = inputs.next()) {// each time there is a midi message call the onMIDIMessage functioninput.value.onmidimessage = onMIDIMessage;
}

这个for循环的意思是:

  1. 创建一个名为input的变量,并为其分配下一个输入。 因为我们还没有迭代任何输入,所以这将返回我们的第一个输入。
  2. 如果我们有一个输入并且输入迭代器的完成值不等于true,则继续循环。
  3. input设置为迭代器对象中的下一个输入。

您还将注意到,在此for循环内,我们为输入的onmidimessage侦听器分配了一个函数。 每当从该输入所代表的设备接收到MIDI事件时,都会调用此函数。 让我们创建一个函数:

function onMIDIMessage (message) {console.log(message.data);
}

解码MIDI数据

我们感兴趣的MIDI消息部分是数据。 发送了什么类型的MIDI事件? 按下键盘上的哪个键?

如果按照本教程进行操作,将会看到,当您按下键盘上的某个键时,浏览器会将类似[144, 61, 95]到控制台。 当您将手指移开按键时,浏览器将再次记录稍微不同的内容,例如[128, 61, 0]

这样的数组可以分解。 第一个元素是MIDI事件的类型。 MIDI消息可以包含相当少量的事件,并且每个事件都有一个相应的数目。 在我们的示例中,144映射到noteOn消息,表示已按下某个键,而128则是noteOff消息,告诉我们不再按下该键。 有关可能的MIDI事件类型的完整列表,请查看MIDI规范中的消息列表。

数组中的第二个值表示按下了键盘上的哪个键。 键盘上的每个音符都有一个从0到127的数字。在上面的示例中,我按下了键61,通过使用此查找表,我们可以看到它是C#。

数组中的第三个也是最后一个值表示速度,基本上是按键的速度。 这可以用来模拟弹奏钢琴时的琴键,既可以轻柔地弹奏琴键,也可以快速而硬地敲击琴键。

现在我们知道正在按下或释放哪个键号,让我们将其变成有用的东西。 让我们将Web MIDI API与Web Audio API挂钩。 如果您不熟悉Web Audio API,请查看我有关该主题的系列教程 。

创建网络工具

让我们将浏览器变成一个小型合成器。 我们将要创建一个振荡器,该振荡器生成所按下音符的频率,因此我们需要将MIDI音符编号转换为其相关频率。 幸运的是,我们的好朋友Wikipedia为我们提供了一些算法来做到这一点。 这是JavaScript形式的样子:

function midiNoteToFrequency (note) {return Math.pow(2, ((note - 69) / 12)) * 440;
}

给它一个音符,然后返回频率。 让我们在onMIDIMessage函数中使用它。

function onMIDIMessage (message) {var frequency = midiNoteToFrequency(message.data[1]);
}

接下来,如果MIDI消息是noteOn消息,则我们要播放此频率的音符。

if (message.data[0] === 144 && message.data[2] > 0) {playNote(frequency);
}

您可能会很容易理解if语句的第一部分。 我们正在检查消息类型为144,即noteOn消息。

但是第二部分呢? 好吧,某些MIDI设备将发送零速度的noteOn消息,而不是发送noteOff消息,因此我们正在检查消息的速度是否大于零。

现在我们已经覆盖了noteOn ,我们将为noteOff编写类似的noteOffNoteOff的消息值是128,因此我们不仅需要检查该值,还要检查它的速度是否为零,以覆盖我刚才提到的情况。

if (message.data[0] === 128 || message.data[2] === 0) {stopNote(frequency);
}

我们现在要做的就是填写startNotestopNote函数。 这是Web Audio API的工作,因此可悲地超出了本教程的范围,但是如果您知道该API,则下面的完整代码应该是不言而喻的。

如果没有,请查看有关Web Audio API的系列文章 ,其中包括如何构建合成器 。 该教程中的代码与我在这里所做的相似,因此将是应用您在这里学到的知识的理想之地。

var context = new AudioContext(),oscillators = {};if (navigator.requestMIDIAccess) {navigator.requestMIDIAccess().then(success, failure);
}function success (midi) {var inputs = midi.inputs.values();// inputs is an Iteratorfor (var input = inputs.next(); input && !input.done; input = inputs.next()) {// each time there is a midi message call the onMIDIMessage functioninput.value.onmidimessage = onMIDIMessage;}
}function failure () {console.error('No access to your midi devices.')
}function onMIDIMessage (message) {var frequency = midiNoteToFrequency(message.data[1]);if (message.data[0] === 144 && message.data[2] > 0) {playNote(frequency);}if (message.data[0] === 128 || message.data[2] === 0) {stopNote(frequency);}
}function midiNoteToFrequency (note) {return Math.pow(2, ((note - 69) / 12)) * 440;
}function playNote (frequency) {oscillators[frequency] = context.createOscillator();oscillators[frequency].frequency.value = frequency;oscillators[frequency].connect(context.destination);oscillators[frequency].start(context.currentTime);
}function stopNote (frequency) {oscillators[frequency].stop(context.currentTime);oscillators[frequency].disconnect();
}

接下来是什么?

请记住, noteOnnoteOff只是我们可用的两种消息类型,而MIDI键盘只是许多类型的MIDI设备之一。 您甚至不必使用MIDI来制作音乐作品。 您使用MIDI小号玩HTML5游戏吗? 听起来就像我的事。

翻译自: https://code.tutsplus.com/tutorials/introduction-to-web-midi--cms-25220

Web MIDI简介相关推荐

  1. web安全简介_Web安全:HTTP简介

    web安全简介 by Alex Nadalin 通过亚历克斯·纳达林 Web安全:HTTP简介 (Web Security: an introduction to HTTP) This is part ...

  2. Tim Berners-Lee重新分散的新Web SOLID简介

    by Arnav Bansal 通过Arnav Bansal Tim Berners-Lee重新分散的新Web SOLID简介 (An introduction to SOLID, Tim Berne ...

  3. 《jQuery与JavaScript入门经典》——第 1 章 动态Web编程简介 1.1理解Web服务器浏览器范式...

    本节书摘来自异步社区<jQuery与JavaScript入门经典>一书中的第1章,第1.1节,作者:[美]Brad Dayley著,更多章节内容可以访问云栖社区"异步社区&quo ...

  4. web API简介(二):客户端储存之document.cookie API

    概述 前篇:web API简介(一):API,Ajax和Fetch 客户端储存从某一方面来说和动态网站差不多.动态网站是用服务端来储存数据,而客户端储存是用客户端来储存数据.document.cook ...

  5. 第一章 Web MVC简介 —— 跟开涛学SpringMVC

    第一章 Web MVC简介 -- 跟开涛学SpringMVC Web MVC简介 1.1.Web开发中的请求-响应模型: 在Web世界里,具体步骤如下: 1.  Web浏览器(如IE)发起请求,如访问 ...

  6. J2EE基础之Web服务简介

    J2EE基础之Web服务简介 1.什么是Web服务? 在人们的日常生活中,经常会查询网页上某城市的天气信息,这些信息都是动态的.实时的,它是专业的气象站提供的一种服务.例如,在网上购物时,通常采用网上 ...

  7. JavaScript(五)—— Web APIs 简介/JavaScript 必须掌握的 DOM 操作 (丰富案例 + 思维导图)

    本篇为 JavaScript 系列笔记第五篇,将陆续更新后续内容.参考:黑马程序员JavaScript核心教程,前端基础教程 系列笔记: JavaScript(一)-- 初识JavaScript / ...

  8. amazeui学习笔记二(进阶开发2)--Web组件简介Web Component

    amazeui学习笔记二(进阶开发2)--Web组件简介Web Component 一.总结 1.amaze ui:amaze ui是一个web 组件, 由模板(hbs).样式(LESS).交互(JS ...

  9. Web MIDI API W3C

    Musical Instrument Digital Interface (MIDI) protocol是乐器(instruments),控制器(controllers)和电脑(computers)之 ...

最新文章

  1. oracle负载均衡方案,Oracle负载均衡配置代码
  2. 使用键值flyweight的Boost.Flyweight示例
  3. Expert Shell Scripting
  4. 骚操作!昨晚停网,我写了一段Python代码破解了隔壁小姐姐的wifi密码...
  5. 简单实用的js调试logger组件
  6. 电子设计竞赛电源题(4)-Buck与Boost电路
  7. Android清空Fragment回退栈
  8. unity的inputField文本框赋值问题
  9. PHP上传大文件 分割文件上传
  10. 传统认知PK网络认知 刚子扯谈烤串认知
  11. 自己动手修理单击变双击的鼠标
  12. 基于微信小程序的医疗监督反馈小程序的设计与实现-计算机毕业设计源码+LW文档
  13. WSJ Merkel Top On Forbes' Most Powerful Women List For 4th Year
  14. 一个nginx小白的vue项目部署的成功!
  15. 全能在线APP一款开源的多功能在线学习考试智慧软件系统
  16. jeb 内存溢出解决方案
  17. 悲惨程序生涯 狗血得你无法相信
  18. 100集华为HCIE安全培训视频教材整理 | 智能策略
  19. 求解非约束优化问题的拟牛顿方法(BFGS、DFP)
  20. 【正版软件】威力导演16 LE版 附激活码

热门文章

  1. Windows10 Clion 无法打开文件cudart.lib
  2. 云笔记Leanote,超级好用的一款开源云笔记
  3. Linux指令用之记之-sell算数运算
  4. 电脑使用越来越慢,如何解决
  5. 河北职高计算机专业高考分数线,河北职高对口本科大学录取分数线
  6. ib中文文学课如何学习重点?
  7. 【软考】总结--任性的一个人的朝圣
  8. python 游戏开发_Python游戏开发入门
  9. 模仿淘宝web扫码登录
  10. C语言 使用数组索引与指针索引 在循环中对编译器优化的影响及耗时分析