Implement more systematic logging in webapp
This commit is contained in:
@@ -23,6 +23,7 @@ export class DeviceContext {
|
|||||||
} else {
|
} else {
|
||||||
if (this.input != null && this.output != null) return
|
if (this.input != null && this.output != null) return
|
||||||
this.device = null
|
this.device = null
|
||||||
|
toast.info('Device disconnected')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -30,13 +31,20 @@ export class DeviceContext {
|
|||||||
async initialize() {
|
async initialize() {
|
||||||
try {
|
try {
|
||||||
const midi = await navigator.requestMIDIAccess({ sysex: true })
|
const midi = await navigator.requestMIDIAccess({ sysex: true })
|
||||||
console.log(Array.from(midi.inputs.values()), Array.from(midi.outputs.values()))
|
const inputs = Array.from(midi.inputs.values())
|
||||||
|
const outputs = Array.from(midi.outputs.values())
|
||||||
|
console.log(
|
||||||
|
'MIDI inputs:',
|
||||||
|
Array.from(midi.inputs.values()),
|
||||||
|
'outputs:',
|
||||||
|
Array.from(midi.outputs.values()),
|
||||||
|
)
|
||||||
|
|
||||||
this.input = midi.inputs.values().find(isInkclip) ?? null
|
this.input = inputs.find(isInkclip) ?? null
|
||||||
this.output = midi.outputs.values().find(isInkclip) ?? null
|
this.output = outputs.find(isInkclip) ?? null
|
||||||
|
|
||||||
midi.addEventListener('statechange', e => {
|
midi.addEventListener('statechange', e => {
|
||||||
console.log(e.port)
|
console.log(`MIDI port statechange:`, e.port)
|
||||||
if (!e.port || !isInkclip(e.port)) return
|
if (!e.port || !isInkclip(e.port)) return
|
||||||
if (e.port?.state === 'connected') {
|
if (e.port?.state === 'connected') {
|
||||||
if (e.port.type === 'input' && !this.input) this.input = e.port as MIDIInput
|
if (e.port.type === 'input' && !this.input) this.input = e.port as MIDIInput
|
||||||
@@ -47,7 +55,7 @@ export class DeviceContext {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
toast.error('Failed to acquire MIDI access. Please grant access manually in your browser.')
|
toast.error(`Failed to acquire MIDI access: ${e}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ export class Device {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
private send(req: Request) {
|
private send(req: Request) {
|
||||||
|
console.log('Sending request:', req)
|
||||||
const encResult = encode7in8(p.serialize(requestSchema, req))
|
const encResult = encode7in8(p.serialize(requestSchema, req))
|
||||||
const len = 1 + MAGIC_NUMBER.length + encResult.byteLength + 1
|
const len = 1 + MAGIC_NUMBER.length + encResult.byteLength + 1
|
||||||
|
|
||||||
@@ -66,8 +67,14 @@ export class Device {
|
|||||||
private recv({ timeout, filter }: RecvOptions): Promise<Response> {
|
private recv({ timeout, filter }: RecvOptions): Promise<Response> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const callback = (e: MIDIMessageEvent) => {
|
const callback = (e: MIDIMessageEvent) => {
|
||||||
if (!e.data) return
|
if (!e.data) {
|
||||||
if (e.data.length < 2 || e.data[0] !== 0xf0 || e.data[e.data.length - 1] !== 0xf7) return
|
console.warn('Received MIDIMessageEvent with no data:', e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (e.data.length < 2 || e.data[0] !== 0xf0 || e.data[e.data.length - 1] !== 0xf7) {
|
||||||
|
console.warn('Received non-SysEx message:', e.data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const sysexPayload = e.data.slice(1, -1)
|
const sysexPayload = e.data.slice(1, -1)
|
||||||
if (sysexPayload.length < MAGIC_NUMBER.length) return
|
if (sysexPayload.length < MAGIC_NUMBER.length) return
|
||||||
@@ -77,8 +84,14 @@ export class Device {
|
|||||||
const payload = decode7in8InPlace(sysexPayload.slice(MAGIC_NUMBER.length))
|
const payload = decode7in8InPlace(sysexPayload.slice(MAGIC_NUMBER.length))
|
||||||
try {
|
try {
|
||||||
const decResult = p.deserialize(responseSchema, payload)
|
const decResult = p.deserialize(responseSchema, payload)
|
||||||
if (!filter || filter(decResult.value)) resolve(decResult.value)
|
if (!filter || filter(decResult.value)) {
|
||||||
|
console.log('Received response:', decResult.value)
|
||||||
|
resolve(decResult.value)
|
||||||
|
} else {
|
||||||
|
console.log('Filtered response:', decResult.value)
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
console.warn('Cannot decode received payload:', payload, e)
|
||||||
reject(e)
|
reject(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ async function updateSerial() {
|
|||||||
try {
|
try {
|
||||||
const response = await deviceCtx.device.request({ type: 'GetIdentification' })
|
const response = await deviceCtx.device.request({ type: 'GetIdentification' })
|
||||||
assert(response.type === 'GetIdentification')
|
assert(response.type === 'GetIdentification')
|
||||||
console.log(response)
|
|
||||||
serial = response.value.serial
|
serial = response.value.serial
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
|
|||||||
@@ -55,9 +55,7 @@ export function makeAltText(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function drawQuantizedData(ctx: CanvasRenderingContext2D, data: Uint8Array) {
|
export function drawQuantizedData(ctx: CanvasRenderingContext2D, data: Uint8Array) {
|
||||||
console.log('attempting drawQuantizedData')
|
|
||||||
const imageData = ctx.createImageData(DEVICE_WIDTH, DEVICE_HEIGHT)
|
const imageData = ctx.createImageData(DEVICE_WIDTH, DEVICE_HEIGHT)
|
||||||
console.log('finished creating')
|
|
||||||
|
|
||||||
for (let y = 0; y < DEVICE_HEIGHT; y++) {
|
for (let y = 0; y < DEVICE_HEIGHT; y++) {
|
||||||
for (let x = 0; x < DEVICE_WIDTH; x++) {
|
for (let x = 0; x < DEVICE_WIDTH; x++) {
|
||||||
@@ -72,8 +70,6 @@ export function drawQuantizedData(ctx: CanvasRenderingContext2D, data: Uint8Arra
|
|||||||
imageData.data[bitmapIx + 3] = 0xff
|
imageData.data[bitmapIx + 3] = 0xff
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log('finished writing')
|
|
||||||
|
|
||||||
ctx.putImageData(imageData, 0, 0)
|
ctx.putImageData(imageData, 0, 0)
|
||||||
console.log('finished putting')
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,17 +39,21 @@ async function connectAndWrite() {
|
|||||||
inProgress = true
|
inProgress = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (let i = 0; i < buffer.byteLength; i += 500) {
|
const start = Date.now()
|
||||||
|
for (let i = 0; i < buffer.byteLength; i += 834) {
|
||||||
await deviceCtx.device.request({
|
await deviceCtx.device.request({
|
||||||
type: 'SetPattern',
|
type: 'SetPattern',
|
||||||
value: {
|
value: {
|
||||||
from: i,
|
from: i,
|
||||||
chroma: { type: 'Black' },
|
chroma: { type: 'Black' },
|
||||||
pattern: buffer.slice(i, i + 500),
|
pattern: buffer.slice(i, i + 834),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
const written = Date.now()
|
||||||
await deviceCtx.device.request({ type: 'UpdateDisplay' })
|
await deviceCtx.device.request({ type: 'UpdateDisplay' })
|
||||||
|
const finish = Date.now()
|
||||||
|
console.log('Time (ms): write', written - start, 'update', finish - written, 'total', finish - start)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
toast.error(`Error writing to device: ${e}`)
|
toast.error(`Error writing to device: ${e}`)
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user