diff options
author | Devine Lu Linvega <[email protected]> | 2018-11-16 20:13:01 +1200 |
---|---|---|
committer | Devine Lu Linvega <[email protected]> | 2018-11-16 20:13:01 +1200 |
commit | 934c8074c1d6154bfb81ad25c64336b0c54cbc57 (patch) | |
tree | 34c0fa4f973b52f630063b586d0c6fb917bb679c | |
parent | ac96842164dd13fb90c5775de46bd318e0af23f7 (diff) | |
download | Orca-934c8074c1d6154bfb81ad25c64336b0c54cbc57.tar.gz Orca-934c8074c1d6154bfb81ad25c64336b0c54cbc57.zip |
Completed midi implementation
-rw-r--r-- | README.md | 9 | ||||
-rw-r--r-- | desktop/core/lib/_midi.js | 12 | ||||
-rw-r--r-- | desktop/sources/scripts/midi.js | 73 | ||||
-rw-r--r-- | desktop/sources/scripts/terminal.js | 2 |
4 files changed, 56 insertions, 40 deletions
@@ -75,15 +75,6 @@ function frequencyFromNoteNumber(note) { The idea is to build a synth/mini sequencer, here's some tasks I need to tackle before then. -- [ ] Add `:MID[CD]` -- [ ] custom synth functions, like `:SYN[ADSR](C)` -- [ ] sub programs scope -- [ ] Implement midi -- [ ] Finish midi channel implementation -- [ ] Convert notes to midi values -- [ ] Implement a block comment syntax -- [ ] Fix M - ## Extras - This application supports the [Ecosystem Theme](https://github.com/hundredrabbits/Themes). diff --git a/desktop/core/lib/_midi.js b/desktop/core/lib/_midi.js index 17f23f9..bea63c7 100644 --- a/desktop/core/lib/_midi.js +++ b/desktop/core/lib/_midi.js @@ -11,7 +11,6 @@ function FnMidi (pico, x, y, passive) { this.ports = [{ x: 1, y: 0, input: true }, { x: 2, y: 0, input: true }, { x: 3, y: 0, input: true }, { x: 0, y: 0, bang: true }] this.haste = function () { - pico.lock(this.x, this.y - 1) pico.lock(this.x + 1, this.y) pico.lock(this.x + 2, this.y) pico.lock(this.x + 3, this.y) @@ -20,27 +19,26 @@ function FnMidi (pico, x, y, passive) { this.run = function () { if (!this.bang()) { return } + const notes = ['C', 'c', 'D', 'd', 'E', 'F', 'f', 'G', 'g', 'A', 'a', 'b'] + const channelGlyph = pico.glyphAt(this.x + 1, this.y) const octaveGlyph = pico.glyphAt(this.x + 2, this.y) const noteGlyph = pico.glyphAt(this.x + 3, this.y) if (channelGlyph === '.' || octaveGlyph === '.' || noteGlyph === '.') { return } + if (notes.indexOf(noteGlyph) < 0) { return } const channelValue = pico.allowed.indexOf(channelGlyph) const octaveValue = pico.allowed.indexOf(octaveGlyph) const noteValue = pico.allowed.indexOf(noteGlyph) const channel = clamp(channelValue, 0, 15) - const octave = clamp(octaveValue, 3, 8) - const note = this.convert(noteValue) + const octave = clamp(octaveValue, 2, 9) + const note = notes.indexOf(noteGlyph) terminal.midi.send(channel, octave, note, 127) } - this.convert = function (ch) { - return 64 - } - function clamp (v, min, max) { return v < min ? min : v > max ? max : v } } diff --git a/desktop/sources/scripts/midi.js b/desktop/sources/scripts/midi.js index d846613..232e3bb 100644 --- a/desktop/sources/scripts/midi.js +++ b/desktop/sources/scripts/midi.js @@ -16,14 +16,60 @@ function Midi (terminal) { this.run = function () { if (this.stack.length < 1) { return } - let html = '' + let text = '' for (const id in this.stack) { const note = this.stack[id] - html += `Ch${note[0]}:${note[1]}+${note[2]}(${note[3]}) ` + text += `${note[0]}+${note[1]}|${note[2]}.${note[3]} ` + this.play(note) } - terminal.log(`${html}`) + + terminal.log(text) + } + + this.send = function (channel, octave, note, velocity) { + this.stack.push([channel, octave, note, velocity]) + } + + this.play = function (note) { + const channel = this.makeChannel(note[0]) + const value = this.makeValue(note[1], note[2]) + const velocity = note[3] + + this.playNote(channel, value, velocity) + } + + this.playNote = function (channel, value, velocity) { + // TODO: Fix length to terminal bpm + const length = window.performance.now() + 100.0 + + terminal.midi.outputs[0].send([channel[0], value, velocity]) + terminal.midi.outputs[0].send([channel[1], value, velocity], length) + } + + // + + this.makeChannel = function (id) { + if (id === 0) { return [0x90, 0x80] } // ch1 + if (id === 1) { return [0x91, 0x81] } // ch2 + if (id === 2) { return [0x92, 0x82] } // ch3 + if (id === 3) { return [0x93, 0x83] } // ch4 + if (id === 4) { return [0x94, 0x84] } // ch5 + if (id === 5) { return [0x95, 0x85] } // ch6 + if (id === 6) { return [0x96, 0x86] } // ch7 + if (id === 7) { return [0x97, 0x87] } // ch8 + if (id === 8) { return [0x98, 0x88] } // ch9 + if (id === 9) { return [0x99, 0x89] } // ch10 } + this.makeValue = function (octave, note) { + const offset = 24 + const value = offset + (octave * 12) + note + console.log(octave, note, value) + return value // 60 = C3 + } + + // Setup + this.midiSetup = function () { if (!navigator.requestMIDIAccess) { return } @@ -42,26 +88,7 @@ function Midi (terminal) { console.warn('No Midi', err) } - this.send = function (channel, octave, note, velocity) { - this.stack.push([channel, octave, note, velocity]) - } - - this.play = function () { - this.ch1() - this.ch3() - } - - this.ch1 = function () { - terminal.midi.outputs[0].send([0x90, 60, 127]) - terminal.midi.outputs[0].send([0x80, 60, 127], window.performance.now() + 250.0) - } - - this.ch3 = function () { - terminal.midi.outputs[0].send([0x92, 60, 127]) - terminal.midi.outputs[0].send([0x82, 60, 127], window.performance.now() + 250.0) - } - - this.vu = function () { + this.toString = function () { if (this.stack.length === 0) { return '------' } if (this.stack.length === 1) { return '|-----' } if (this.stack.length === 2) { return '||----' } diff --git a/desktop/sources/scripts/terminal.js b/desktop/sources/scripts/terminal.js index 4bd226a..7f35616 100644 --- a/desktop/sources/scripts/terminal.js +++ b/desktop/sources/scripts/terminal.js @@ -160,7 +160,7 @@ function Terminal (pico) { this.write(`${this.cursor.inspect()}`.substr(0, col), col * 0, 0) this.write(`${this.cursor._mode()}`, col * 1, 0) this.write(`${this.bpm}`, col * 2, 0) - this.write(this.midi.vu(), col * 3, 0) + this.write(`${this.midi}`, col * 3, 0) } this.write = function (text, offsetX, offsetY) { |