Web MIDI简介
“有關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循環的意思是:
您還將注意到,在此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編寫類似的noteOff 。 NoteOff的消息值是128,因此我們不僅需要檢查該值,還要檢查它的速度是否為零,以覆蓋我剛才提到的情況。
if (message.data[0] === 128 || message.data[2] === 0) {stopNote(frequency); }我們現在要做的就是填寫startNote和stopNote函數。 這是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(); }接下來是什么?
請記住, noteOn和noteOff只是我們可用的兩種消息類型,而MIDI鍵盤只是許多類型的MIDI設備之一。 您甚至不必使用MIDI來制作音樂作品。 您使用MIDI小號玩HTML5游戲嗎? 聽起來就像我的事。
翻譯自: https://code.tutsplus.com/tutorials/introduction-to-web-midi--cms-25220
總結
以上是生活随笔為你收集整理的Web MIDI简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SDN开源,从你的全世界路过
- 下一篇: 水平垂直投影