Inspired by this talk by Jean-Philippe Côté I saw at Web Unleashed in Toronto last month, I thought I should dust off the old midi cable.

上个月我在多伦多的Web Unleashed上看到的让-菲利普·科特( Jean-PhilippeCôté)的演讲启发了我,我认为我应该清除旧的Midi电缆。

MIDI? (MIDI?)

MIDI is a protocol that various music and lighting devices use to talk to each other. Believe it or not v1.0 of the spec from 1983 is still the one in use, remaining largely unchanged. In a world where we don't know if we're using JavaScript, ECMAScript7, ES2016 or ES.Next, this is... interesting development. Or lack of. Looks like it just works. It's all about sending messages between devices. I admit the content of the messages in not the frieldliest, but it seems to be doing the job.

MIDI是各种音乐和照明设备用来互相交谈的协议。 信不信由你自1983年以来的规范v1.0仍在使用中,基本上保持不变。 在一个我们不知道是否使用JavaScript,ECMAScript7,ES2016或ES的世界中,接下来,这是一个有趣的发展。 还是缺乏。 看起来就可以了。 这都是关于在设备之间发送消息。 我承认消息的内容不是最友好的,但似乎可以完成工作。

And now - there's WebMIDI! Supported in Chrome and Opera proper (no flags) and via a polyfill everywhere else.

现在-有WebMIDI! 在Chrome和Opera专有版本(无标志)中以及通过其他所有位置的polyfill支持。

So let's see how to use it...

让我们来看看如何使用它...

演示地址

离地(Off the ground)

You need:

你需要:

  • Device with MIDI out, any old keyboard or pad of some sorts
    带有MIDI的设备,任何旧式键盘或某种打击垫
  • MIDI to USB cable (under $10 on Amazon), unless your device speaks midi over USB or your computer has a MIDI (send me photo!)
    MIDI到USB电缆(在亚马逊上不到10美元),除非您的设备通过USB讲话MIDI或您的计算机有MIDI(向我发送照片!)

navigator.requestMIDIAccess() is where it all starts. It returns a promise, which resolves with MIDIAccess object that has a map of MIDI inputs (you can have more than one)

navigator.requestMIDIAccess()是所有内容的起点。 它返回一个MIDIAccess ,并使用MIDIAccess对象进行解析, MIDIAccess对象具有MIDI输入映射(您可以有多个)

Here's how I get the first (and only, in my case) input suffering through modern APIs with their promises and their iterators and buh-humbah-grumble-grubmle:

这是我通过现代API获得的第一个(也是唯一一个)输入痛苦的方式,这些API带有它们的promise和它们的迭代器以及buh-humbah-grumble-grubmle:

navigator
.requestMIDIAccess()
.then(
midi =>
FIRST = midi.inputs.values().next().value
);

Now if you inspect FIRST you'll see it has a curious property - onmidimessage.

现在,如果您检查FIRST ,就会发现它具有奇特的属性onmidimessage

As you can expect, you signup for those events and start exploring them.

如您所料,您可以注册这些活动并开始进行探索。

听... (Listen...)

  FIRST.addEventListener(
'midimessage',
msg => console.log(msg.data)
)

The data seems to be the most promising piece of the msg event object.

data似乎是msg事件对象中最有希望的部分。

Here's what happens when I play C as soft as I can:

当我尽力演奏C时,会发生以下情况:

[144, 48, 33]
[128, 48, 64]

The two events seem to be "start" (144) and "stop" (128), the note is 48 and 33 is the velocity. 64... no idea and too lazy to look up specs.

这两个事件似乎是“开始”(144)和“停止”(128),音符是48,速度是33。 64 ...不知道,而且懒得查找规格。

Isn't that the beauty of web programming? I dunno what I'm doing (did not RTFM) but I can already build stuff just by trying things out and happily hacking.

这不是Web编程的美吗? 我不知道自己在做什么(不是RTFM),但是我已经可以通过尝试并愉快地进行黑客攻击来构建东西。

Then I play the same C as loud as I can:

然后,我尽可能大声地播放相同的C:

[144, 48, 122]
[128, 48, 64]

yup, 144 is start, 48 is C and 122 is the velocity (how hard I hit)

是的,144是开始,48是C,122是速度(我打的力度)

Playing soft and loud D seems to coincide with the hypothesis.

演奏柔和而响亮的D似乎与假设相吻合。

[144, 50, 70]
[128, 50, 64]
[144, 50, 120]
[128, 50, 64]

谢谢!(Thanks!)

Thanks for watching and reading, now let's hack on some music stuff!

感谢您的收看和阅读,现在让我们破解一些音乐!

快速更新-尝试过电子鼓,像魅力一样 (Quick update - tried with electronic drums, works like a charm)

navigator.requestMIDIAccess().then(midi => I = midi.inputs);
I.values().next().value.onmidimessage = msg => console.log(msg.data)

Here's a slow closing of the hi-hat:

这是踩-的缓慢关闭:

[185, 4, 4]
[185, 4, 8]
[185, 4, 12]
[185, 4, 16]
[185, 4, 21]
[185, 4, 26]
[185, 4, 30]
[185, 4, 35]
[185, 4, 42]
[185, 4, 49]
[185, 4, 55]
[185, 4, 59]
[185, 4, 63]
[185, 4, 68]
[185, 4, 73]
[185, 4, 79]
[185, 4, 83]
[185, 4, 90]

Closed hi-hat hit

踩hi闭合

[185, 4, 90]
[153, 22, 89]
[137, 22, 64]

And slightly open

并稍微打开

[185, 4, 81]
[153, 26, 65]
[137, 26, 64]

Snare proper:

适当的军鼓

[153, 38, 98]
[137, 38, 64]

Snare rim:

小军圈:

[153, 37, 35]
[137, 37, 64]

Rim shot (both skin/mesh and rim)

轮辋射击(皮肤/网眼和边缘)

[153, 40, 127]
[137, 40, 64]

另一个快速更新:控制表面消失的香蕉 (Another quick update: control surface gone bananas)

A control surface is a big mouse replacement when you work with music software and there are a lot of channels (tracks, e.g. guitar, bass, lead vocals, backing vocals...). So instead of reaching with the mouse to various virtual knobs why not work with real knobs and even twist more than one at a time. And guess what - control surfaces also use MIDI.

当您使用音乐软件并且有很多通道(音轨,例如吉他,贝斯,主唱,背景音乐...)时,控制面板是鼠标的替代品。 因此,与其用鼠标触及各种虚拟旋钮,不如不使用真实旋钮甚至一次扭曲多个旋钮。 猜猜是什么-控制界面也使用MIDI。

So after logging a few MIDI messaged to the console, it was obvious that messages starting with 144 (like note ON for keyboards) are for touch controls. The second bit is which touch control (there are about a hundred on this device) and then a value between 0 (off), 127 (on) and sometimes values in between to mean blinking.

因此,在记录了一些发送到控制台的MIDI消息后,很明显,以144开头的消息(例如键盘的音符为ON)是用于触摸控件的。 第二位是哪个触摸控制(此设备上大约有一百个),然后是介于0(关闭),127(开启)之间的值,有时介于两者之间的值表示闪烁。

As for the faders, this control surface has 9 with numbers 224 to 232 and values 0 to 127.

至于推子,此控制表面有9个,编号为224至232,值为0至127。

So all that's left is to write two random functions to control random knobs and faders with a setTimeout and make the thing dance and blink and go crazy.

因此,剩下的就是编写两个随机函数,用setTimeout控制随机的旋钮和推子,使事情起舞,眨眼,发疯。

Unlike the previous examples where I used MIDI input, this here is the midi output. In other words the browser sends a MIDI message to the device and the device reacts. For some reason I couldn't make this output work with the keyboard, but here it totally worked.

与之前使用MIDI输入的示例不同,这里是midi输出。 换句话说,浏览器向设备发送MIDI消息,然后设备做出React。 由于某种原因,我无法使此输出与键盘一起工作,但是在这里它完全可以工作。

navigator.requestMIDIAccess().then(midi => O = midi.outputs);
// thanks stackoverflow
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// random touch (on/off lights)
function rando144() {
return [144, getRandomInt(0, 100), getRandomInt(120, 127)];
}
var a = setInterval(() => O.values().next().value.send(rando144()), 100)
// random fader
function rando() {
var channel = getRandomInt(224, 232);
var value = getRandomInt(0, 127);
return [channel, 0, value];
}
var b = setInterval(() => O.values().next().value.send(rando()), 200)

And the video result:

和视频结果:

演示地址

Tell your friends about this post on Facebook and Twitter

在Facebook和Twitter上告诉您的朋友有关此帖子的信息

翻译自: https://www.phpied.com/hello-webmidi/

你好,WebMIDI相关推荐

  1. cmd怎么实现Java你好_java环境配置以及如何在cmd窗口运行java代码

    对于初学java的人来说,电脑的环境配置也许会让你头疼,但只要你认真一些学习,相信对你来说都是OK的啦~ 首先回到桌面,选择我的电脑,单击右键属性,进入高级系统设置,点击环境变量设置.用户变量选择Te ...

  2. HarmonyOS开发工具DevEcoStudio 的下载以及运行(包含下载开发工具,sdk,模拟机,以及运行第一个应用你好,世界)

    开发工具下载 首先打开HarmonyOS 官网 地址链接 向下滑动一下就能看到开发工具DevEcoStudio 了,点击下载 下载之后是一个压缩包(我这里下载的windos版本的) 解压之后有一个.e ...

  3. JAVA求是否为闰年,for-while循环,输出你好

    第一次写Java程序有点小紧张,如果我没猜错的话,你现在应该在3楼的某个教室里慌的不行吧? 哈哈哈 疯狂建议写成三个类,打上注释 直接上代码 package com.classOne;//自己定义的p ...

  4. 小程序json字符串转 json对象 { name :你好} 转成 { name :你好}

    解决后端接口返回 var obj ="{ name :"你好"}" 类似这样的数据,对象或者数组外面包了一层引号, 把这种数据转成 var obj = { na ...

  5. 用数据分析《你好,李焕英》“斐妈”爆红的真相

    作者 | 俊欣 来源 | 数据分析与篮球 头图 | 下载于视觉中国 <你好,李焕英>成为了春节档最热门最火爆的电影之一.截止目前,根据猫眼电影专业版的数据显示,该影片的票房已经突破了43亿 ...

  6. 面试者被公司粗暴对待,进门讲了三句话被赶出:包括一句你好

    对于职场上的人而言,找工作是一件比较扎心的事情,特别是在面试环节,内心是最为忐忑的.但是在面试过程中,一些面试者往往处于弱势的一方,用人单位是强势的一方.因此面试者有时候会受到一些不平等的对待,比如下 ...

  7. 《Arduino实战》——第1章 你好Arduino

    本节书摘来异步社区<Arduino实战>一书中的第1章,作者:[美]Martin Evans ,Joshua Noble ,Jordan Hochenbaum,更多章节内容可以访问云栖社区 ...

  8. [转载] 杜拉拉升职记——30 我保证以后一直对你好

    来源:李可. 杜拉拉升职记(第三版). 西安: 陕西师范大学出版社, 2010, 5. 30 我保证以后一直对你好 拉拉一到上海就按预约好的时间去找几位总监开会,等她回到自己的位置上已经过了下班时间. ...

  9. eclipse java代码某一行需要修改注释_看看这些Java代码开发规范吧!你好,我好,大家好!...

    作为一名开发人员,当你接手他人的项目时,且当你阅读他人的代码时,是有没有遇到脑袋充血,感觉Java要把你"送走"的感觉呢?我们在用Java开发技术进行开发前,一定要牢牢恪守Java ...

最新文章

  1. rdd与mysql表 join_6、JdbcRDD读取mysql的数据
  2. mongodb 3.2配置内存缓存大小为MB/MongoDB 3.x内存限制配置
  3. Linux下glibc内存管理
  4. OC字符串转C语言字符串
  5. php常用linux命令httpd,Linux常用的100个命令
  6. 《C专家编程》一1.6 它很棒,但它符合标准吗
  7. IntelliJ IDEA 内存优化最佳实践
  8. 计算机文化基础第二次答案,中国石油大学2020年秋计算机文化基础第二次在线作业答案...
  9. 2021 年百度之星·程序设计大赛 - 复赛 1002 Add or Multiply 1(第2类斯特林数)
  10. Vue开发环境搭建 VsCode
  11. PowerBI Report Server借助Wap与ADFS实现集成一
  12. Web视频上添加文字
  13. Stata:回归结果中不报告行业虚拟变量的系数
  14. 有人问你后端面试考哪些?把这篇扔给他!
  15. PPT2016;插入视频,无法实现自动播放
  16. ipad的文件连接云服务器,ipad原来可以这样用(八):文件共享——也说说云端技术...
  17. https://api-hmugo-web.itheima.net 不在以下 request 合法域名列表中,请参考文档:https://developers.weixin.qq.com/minip
  18. 华硕主板M2N-电源跳线怎么接
  19. 导热材料在电子产品散热系统中的重要性
  20. Aprioriall算法

热门文章

  1. ardupilot 如何快速下载代码
  2. 寒冬中疯狂开店的海底捞,如何突破堂食困境
  3. 欧姆龙CP1H标准程序,一共控制五个伺本体四个+一个轴扩展包含轴点动
  4. UG NX二次开发(C#)-建模-获取圆柱面信息(轴向、半径、深度)
  5. 机房收费系统——UML类图
  6. JZOJ4870. 【NOIP2016提高A组集训第9场11.7】涂色游戏
  7. MySQL union 和 union all的区别
  8. Google粘土动画纯Javascript代码实现
  9. C/C++ 模拟键盘操作(三)模拟鼠标输入
  10. Redis作为单线程 为什么我用它还是出现了超卖的情况?