fix: web midi
This commit is contained in:
parent
372bdf8be7
commit
eca92cf5b5
6 changed files with 249 additions and 230 deletions
|
|
@ -12,7 +12,19 @@ export function repl({
|
||||||
transpiler,
|
transpiler,
|
||||||
onToggle,
|
onToggle,
|
||||||
}) {
|
}) {
|
||||||
const scheduler = new Cyclist({ interval, onTrigger: defaultOutput, onError: onSchedulerError, getTime, onToggle });
|
const scheduler = new Cyclist({
|
||||||
|
interval,
|
||||||
|
onTrigger: (hap, deadline, duration) => {
|
||||||
|
if (!hap.context.onTrigger) {
|
||||||
|
return defaultOutput(hap, deadline, duration);
|
||||||
|
}
|
||||||
|
// call signature of output / onTrigger is different...
|
||||||
|
return hap.context.onTrigger(getTime() + deadline, hap);
|
||||||
|
},
|
||||||
|
onError: onSchedulerError,
|
||||||
|
getTime,
|
||||||
|
onToggle,
|
||||||
|
});
|
||||||
const evaluate = async (code, autostart = true) => {
|
const evaluate = async (code, autostart = true) => {
|
||||||
if (!code) {
|
if (!code) {
|
||||||
throw new Error('no code to evaluate');
|
throw new Error('no code to evaluate');
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as _WebMidi from 'webmidi';
|
import * as _WebMidi from 'webmidi';
|
||||||
import { Pattern, isPattern, isNote } from '@strudel.cycles/core';
|
import { Pattern, isPattern, isNote, getPlayableNoteValue } from '@strudel.cycles/core';
|
||||||
import { getAudioContext } from '@strudel.cycles/webaudio';
|
import { getAudioContext } from '@strudel.cycles/webaudio';
|
||||||
|
|
||||||
// if you use WebMidi from outside of this package, make sure to import that instance:
|
// if you use WebMidi from outside of this package, make sure to import that instance:
|
||||||
|
|
@ -41,7 +41,7 @@ Pattern.prototype.midi = function (output, channel = 1) {
|
||||||
return this._withHap((hap) => {
|
return this._withHap((hap) => {
|
||||||
// const onTrigger = (time: number, hap: any) => {
|
// const onTrigger = (time: number, hap: any) => {
|
||||||
const onTrigger = (time, hap) => {
|
const onTrigger = (time, hap) => {
|
||||||
let note = hap.value;
|
let note = getPlayableNoteValue(hap);
|
||||||
const velocity = hap.context?.velocity ?? 0.9;
|
const velocity = hap.context?.velocity ?? 0.9;
|
||||||
if (!isNote(note)) {
|
if (!isNote(note)) {
|
||||||
throw new Error('not a note: ' + note);
|
throw new Error('not a note: ' + note);
|
||||||
|
|
@ -75,7 +75,7 @@ Pattern.prototype.midi = function (output, channel = 1) {
|
||||||
device.playNote(note, channel, {
|
device.playNote(note, channel, {
|
||||||
time,
|
time,
|
||||||
duration: hap.duration.valueOf() * 1000 - 5,
|
duration: hap.duration.valueOf() * 1000 - 5,
|
||||||
velocity,
|
velocity, // TODO: "OutputChannel.js:942 The 'velocity' option is deprecated. Use 'attack' instead."?
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return hap.setContext({ ...hap.context, onTrigger });
|
return hap.setContext({ ...hap.context, onTrigger });
|
||||||
|
|
|
||||||
16
packages/react/dist/index.cjs.js
vendored
16
packages/react/dist/index.cjs.js
vendored
File diff suppressed because one or more lines are too long
436
packages/react/dist/index.es.js
vendored
436
packages/react/dist/index.es.js
vendored
File diff suppressed because it is too large
Load diff
|
|
@ -33,8 +33,9 @@ currently broken / buggy:
|
||||||
- [ ] repl log section => remove?
|
- [ ] repl log section => remove?
|
||||||
- [ ] hideHeader flag
|
- [ ] hideHeader flag
|
||||||
- [ ] pending flag
|
- [ ] pending flag
|
||||||
- [ ] web midi
|
- [x] web midi, TODO: test
|
||||||
- [ ] draw / pianoroll
|
- [ ] draw / pianoroll
|
||||||
|
- [ ] repl url hash does not work
|
||||||
- [x] pause does stop
|
- [x] pause does stop
|
||||||
- [ ] pause then play logs "TOO LATE" and drops some events
|
- [ ] pause then play logs "TOO LATE" and drops some events
|
||||||
- [x] random button triggers start
|
- [x] random button triggers start
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ function App() {
|
||||||
// getTime: () => Tone.getTransport().seconds,
|
// getTime: () => Tone.getTransport().seconds,
|
||||||
});
|
});
|
||||||
|
|
||||||
/* useWebMidi({
|
useWebMidi({
|
||||||
ready: useCallback(
|
ready: useCallback(
|
||||||
({ outputs }) => {
|
({ outputs }) => {
|
||||||
pushLog(`WebMidi ready! Just add .midi(${outputs.map((o) => `'${o.name}'`).join(' | ')}) to the pattern. `);
|
pushLog(`WebMidi ready! Just add .midi(${outputs.map((o) => `'${o.name}'`).join(' | ')}) to the pattern. `);
|
||||||
|
|
@ -169,7 +169,7 @@ function App() {
|
||||||
},
|
},
|
||||||
[pushLog],
|
[pushLog],
|
||||||
),
|
),
|
||||||
}); */
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen flex flex-col">
|
<div className="min-h-screen flex flex-col">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue