1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
import Tone from 'tone'
import WebMidi from 'webmidi'
import 'nexusui'
import keys from './lib/keys'
import kalimba from './lib/kalimba'
import scales from './lib/scales'
import { mod, browser, requestAudioContext, ftom, mtof, tap } from './lib/util'
import * as data from './data'
const nx = window.nx
let midi
WebMidi.enable(midi_ready)
function midi_ready(err) {
if (err) {
console.error('webmidi failed to initialize')
return
}
if (!WebMidi.outputs.length) {
console.error('no MIDI output found')
}
console.log(WebMidi.inputs)
console.log(WebMidi.outputs)
midi = WebMidi.outputs[0]
}
function play(index){
const freq = scales.current().index(index)
let midi_note = ftom(freq)
let cents = midi_note % 1
if (cents > 0.5) {
midi_note += 1
cents -= 1
}
cents *= 2
midi_note = Math.floor(midi_note)
// console.log(freq, midi_note, cents.foFixed(1))
if (midi) {
midi.playNote(Tone.Frequency(Math.floor(midi_note), "midi").toNote(), "all", { duration: 90000 / Tone.Transport.bpm.value })
// cents
midi.sendPitchBend(cents, "all")
} else {
kalimba.play(freq)
}
}
nx.onload = () => requestAudioContext(ready)
function ready () {
nx.widgets.scale.choices = scales.names()
nx.widgets.scale.init()
nx.widgets.scale.on('*', e => scales.pick(e.value))
// nx.widgets.shiftUp.on('*', tap(shiftUp))
nx.colorize('#f4d142')
Tone.Transport.bpm.value = 108
nx.widgets.tempo.min = 10
nx.widgets.tempo.max = 1000
nx.widgets.tempo.set({ value: 108 })
nx.widgets.tempo.on('*', () => Tone.Transport.bpm.value = nx.widgets.tempo.val.value )
Tone.Transport.start()
}
keys.listen(play)
|