summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/index.js68
-rw-r--r--client/lib/midi.js36
2 files changed, 65 insertions, 39 deletions
diff --git a/client/index.js b/client/index.js
index fef9b0c..81cb34c 100644
--- a/client/index.js
+++ b/client/index.js
@@ -15,7 +15,7 @@ import {
import {
requestAudioContext, norm, dataURItoBlob,
get_bounds, get_diff_bounds,
- transpose,
+ transpose, ftom,
} from './lib/util'
import {
update_value_on_change,
@@ -54,7 +54,7 @@ data.load().then(lists => {
transpose(lists.gun_violence_by_month.lines).forEach((row, i) => {
const name = lists.gun_violence_by_month.h[i]
if (name === 'Date') return
- console.log(name, row)
+ // console.log(name, row)
datasets[name] = {
name,
h: [name],
@@ -74,7 +74,7 @@ data.load().then(lists => {
return (parseInt(y) - parseInt(min_y)) * 12 + parseInt(m)
})
max_i = (parseInt(max_y) - parseInt(min_y)) * 12 + parseInt(12)
- console.log('max i', max_i)
+ // console.log('max i', max_i)
datasets["Mass Shootings"].data = lines
datasets["Mass Shootings"].lines = [lines.map(row => row[mass_fields.total_victims])]
requestAudioContext(ready)
@@ -82,8 +82,6 @@ data.load().then(lists => {
/* play function for mass shooting data w/ custom timing */
-let mass_rest = 0
-
// export const note_values = [
// [8, '8 measures', 8 * 512],
// [4, '4 measures', 4 * 512],
@@ -107,62 +105,77 @@ function play_mass_shootings(i, bounds, diff, note_time, channel="all", exportin
const x = i % rows[0].length
const n = rows[y][x]
const total = dataset.dates.length
+ let pedal_note
let notes = [], midi_notes = [], cases = [], timings
- console.log(i, mass_i, dataset.dates[mass_i], channel, exporting)
+ // console.log(i, mass_i, dataset.dates[mass_i], channel, exporting)
while (i >= dataset.dates[mass_i] && mass_i < total) {
notes.push(dataset.lines[0][mass_i])
cases.push(dataset.data[mass_i][mass_fields.date] + ' ' + dataset.data[mass_i][mass_fields.case] +
", " + dataset.data[mass_i][mass_fields.fatalities] + ' dead, ' + dataset.data[mass_i][mass_fields.injured] + ' injured')
- console.log('push case', dataset.data[mass_i][mass_fields.date] + ' ' + dataset.data[mass_i][mass_fields.case])
+ // console.log('push case', dataset.data[mass_i][mass_fields.date] + ' ' + dataset.data[mass_i][mass_fields.case])
mass_i += 1
}
switch (notes.length) {
default:
case 0:
- mass_rest += 1
break
case 1:
- midi_notes.push(play_note( norm(notes[0], min, max) * nx.multiply.value, 128, channel, exporting, mass_rest, 0))
+ midi_notes.push(play_note( norm(notes[0], min, max) * nx.multiply.value, 128, channel, exporting, 0))
timings = [128]
break
case 2:
- midi_notes.push(play_note( norm(notes[0], min, max) * nx.multiply.value, 64, channel, exporting, mass_rest, 0))
- midi_notes.push(play_note( norm(notes[1], min, max) * nx.multiply.value, 64, channel, exporting, 0, 64))
+ midi_notes.push(play_note( norm(notes[0], min, max) * nx.multiply.value, 64, channel, exporting, 0))
+ midi_notes.push(play_note( norm(notes[1], min, max) * nx.multiply.value, 64, channel, exporting, 64))
timings = [64, 64]
break
case 3:
- midi_notes.push(play_note( norm(notes[0], min, max) * nx.multiply.value, 43, channel, exporting, mass_rest, 0))
- midi_notes.push(play_note( norm(notes[1], min, max) * nx.multiply.value, 43, channel, exporting, 0, 43))
- midi_notes.push(play_note( norm(notes[2], min, max) * nx.multiply.value, 42, channel, exporting, 0, 85))
+ midi_notes.push(play_note( norm(notes[0], min, max) * nx.multiply.value, 43, channel, exporting, 0))
+ midi_notes.push(play_note( norm(notes[1], min, max) * nx.multiply.value, 43, channel, exporting, 43))
+ midi_notes.push(play_note( norm(notes[2], min, max) * nx.multiply.value, 42, channel, exporting, 85))
timings = [43, 43 ,42]
break
case 4:
- midi_notes.push(play_note( norm(notes[0], min, max) * nx.multiply.value, 32, channel, exporting, mass_rest, 0))
- midi_notes.push(play_note( norm(notes[1], min, max) * nx.multiply.value, 32, channel, exporting, 0, 32))
- midi_notes.push(play_note( norm(notes[2], min, max) * nx.multiply.value, 32, channel, exporting, 0, 64))
- midi_notes.push(play_note( norm(notes[3], min, max) * nx.multiply.value, 32, channel, exporting, 0, 96))
+ midi_notes.push(play_note( norm(notes[0], min, max) * nx.multiply.value, 32, channel, exporting, 0))
+ midi_notes.push(play_note( norm(notes[1], min, max) * nx.multiply.value, 32, channel, exporting, 32))
+ midi_notes.push(play_note( norm(notes[2], min, max) * nx.multiply.value, 32, channel, exporting, 64))
+ midi_notes.push(play_note( norm(notes[3], min, max) * nx.multiply.value, 32, channel, exporting, 96))
timings = [32, 32, 32, 32]
break
}
- if (cases.length) {
- document.querySelector('#cases').innerHTML = cases.join('<br>')
+ const pedal_freq = scales.current().index(nx.pedal_tone.value, nx.octave.value)
+ pedal_note = get_midi_note_for_frequency(pedal_freq)
+ if (!exporting) {
+ kalimba.play(pedal_freq, -12)
+ if (cases.length) {
+ document.querySelector('#cases').innerHTML = cases.join('<br>')
+ }
}
if (total <= mass_i) {
- mass_rest = 0
mass_i = 0
i = 0
} else {
i += 1
}
- const pedal_freq = scales.current().index(nx.pedal_tone.value, nx.octave.value)
- kalimba.play(pedal_freq, -12)
if (notes.length) {
- mass_rest = 0
- return [i, midi_notes, timings, mass_rest]
+ return [i, midi_notes, timings, pedal_note]
+ }
+ return [i, [], [], pedal_note]
+}
+
+function get_midi_note_for_frequency(freq){
+ let midi_note = ftom(freq)
+ let cents = midi_note % 1
+ if (cents > 0.5) {
+ midi_note += 1
+ cents -= 1
}
- mass_rest += 128
- return [i, [], [], 0]
+ cents *= 2
+ midi_note = Math.floor(midi_note)
+ if (midi_note > 127) return 0
+ const note = Tone.Frequency(Math.floor(midi_note), "midi").toNote()
+console.log(freq, midi_note, note)
+ return note
}
/* play next note according to sonification */
@@ -197,7 +210,6 @@ function pick_dataset(key){
console.log('pick dataset:', key, datasets[key])
i = 0
mass_i = 0
- mass_rest = 0
dataset = datasets[key]
bounds = get_bounds(dataset)
diff = get_diff_bounds(bounds.rows)
diff --git a/client/lib/midi.js b/client/lib/midi.js
index 449abc0..b22f2fe 100644
--- a/client/lib/midi.js
+++ b/client/lib/midi.js
@@ -55,7 +55,7 @@ export function midi_init() {
/* play a single note */
-export function play_note(index, duration, channel="all", exporting=false, rest=0, defer=0){
+export function play_note(index, duration, channel="all", exporting=false, defer=0){
// console.log(index)
const scale = scales.current()
const freq = scale.index(index + Math.round(nx.offset.value), nx.octave.value)
@@ -70,10 +70,10 @@ export function play_note(index, duration, channel="all", exporting=false, rest=
if ((midiDevice || exporting) && midi_note > 127) return 0
const note = Tone.Frequency(Math.floor(midi_note), "midi").toNote()
const defer_time = 30000 / Tone.Transport.bpm.value * defer / 128
- console.log(defer, defer_time)
if (exporting) {
return note
}
+ console.log('defer', defer, defer_time)
if (midiDevice) {
duration = duration || 60000 / Tone.Transport.bpm.value
if (! exporting) {
@@ -147,32 +147,46 @@ export function export_pattern_as_midi(datasetName, bounds, diff, tempo, timingI
const { rows } = bounds
// let count = behavior === 'sequence' ? rows[0].length * rows.length : rows.length
max_i = max_i || rows[0].length
- let notes, timings, wait
+ let notes, timings
let note_time
// let timing = note_values[timingIndex][2]
+ let pedal_note, next_i
+ let wait = 0
let midi_track = new MidiWriter.Track()
- let next_i
midi_track.setTempo(tempo)
+ let pedal_track = new MidiWriter.Track()
+ pedal_track.setTempo(tempo)
for (let i = 0, len = max_i; i < len; i++) {
- [next_i, notes, timings, wait] = play_fn(i, bounds, diff, note_time, "all", true)
+ [next_i, notes, timings, pedal_note] = play_fn(i, bounds, diff, note_time, "all", true)
// if (timing.length) {
// note_time = timing[i % timing.length]
// } else {
// note_time = timing
// }
// midi_track.addEvent(new MidiWriter.NoteEvent({ pitch: notes, duration: 't' + note_time }))
- // console.log(i, notes, timings, wait)
+ // console.log(i, notes, timings)
+ if (!notes.length) wait += 128
for (let j = 0; j < notes.length; j++) {
- console.log(i, j, notes[j], timings[j], wait)
- midi_track.addEvent(new MidiWriter.NoteEvent({
+ console.log(i, j, notes[j], timings[j], wait, pedal_note)
+ let e = {
pitch: notes[j],
duration: 't' + timings[j],
- wait,
- }))
+ velocity: 50,
+ }
+ if (wait) {
+ e.wait = 't' + wait
+ }
+ midi_track.addEvent(new MidiWriter.NoteEvent(e))
wait = 0
}
+ pedal_track.addEvent(new MidiWriter.NoteEvent({
+ pitch: pedal_note,
+ duration: 't128',
+ velocity: 25,
+ }))
}
- const writer = new MidiWriter.Writer([midi_track])
+ let tracks = [midi_track, pedal_track]
+ const writer = new MidiWriter.Writer(tracks)
const blob = dataURItoBlob(writer.dataUri())
saveAs(blob, 'Recording - ' + datasetName + '.mid')
}