use velocity in tone + midi + defaultSynth

This commit is contained in:
Felix Roos 2022-03-06 14:39:33 +01:00
parent fbc629c6da
commit 58e8e311a3
3 changed files with 19 additions and 16 deletions

View File

@ -32,12 +32,12 @@ Pattern.prototype.midi = function (output: string, channel = 1) {
}')` }')`
); );
} }
return this.fmap((value: any) => ({ return this._withEvent((event: any) => {
...value, const onTrigger = (time: number, event: any) => {
onTrigger: (time: number, event: any) => { let note = event.value;
value = value.value || value; const velocity = event.context?.velocity ?? 0.9;
if (!isNote(value)) { if (!isNote(note)) {
throw new Error('not a note: ' + value); throw new Error('not a note: ' + note);
} }
if (!WebMidi.enabled) { if (!WebMidi.enabled) {
throw new Error(`🎹 WebMidi is not enabled. Supported Browsers: https://caniuse.com/?search=webmidi`); throw new Error(`🎹 WebMidi is not enabled. Supported Browsers: https://caniuse.com/?search=webmidi`);
@ -58,14 +58,14 @@ Pattern.prototype.midi = function (output: string, channel = 1) {
time = time * 1000 + timingOffset; time = time * 1000 + timingOffset;
// const inMs = '+' + (time - Tone.context.currentTime) * 1000; // const inMs = '+' + (time - Tone.context.currentTime) * 1000;
// await enableWebMidi() // await enableWebMidi()
device.playNote(value, channel, { device.playNote(note, channel, {
time, time,
duration: event.duration * 1000 - 5, duration: event.duration * 1000 - 5,
// velocity: velocity ?? 0.5, velocity,
velocity: 0.9,
}); });
}, };
})); return event.setContext({ ...event.context, onTrigger });
});
}; };
export function useWebMidi(props?: any) { export function useWebMidi(props?: any) {

View File

@ -32,9 +32,11 @@ Pattern.prototype.tone = function (instrument) {
return this._withEvent((event) => { return this._withEvent((event) => {
const onTrigger = (time, event) => { const onTrigger = (time, event) => {
let note = event.value; let note = event.value;
let velocity = event.context?.velocity ?? 0.75;
switch (instrument.constructor.name) { switch (instrument.constructor.name) {
case 'PluckSynth': case 'PluckSynth':
// note = getPlayableNoteValue(event); // note = getPlayableNoteValue(event);
// velocity?
instrument.triggerAttack(note, time); instrument.triggerAttack(note, time);
break; break;
case 'NoiseSynth': case 'NoiseSynth':
@ -43,23 +45,24 @@ Pattern.prototype.tone = function (instrument) {
case 'Piano': case 'Piano':
// note = getPlayableNoteValue(event); // note = getPlayableNoteValue(event);
instrument.keyDown({ note, time, velocity: 0.5 }); instrument.keyDown({ note, time, velocity: 0.5 });
instrument.keyUp({ note, time: time + event.duration }); instrument.keyUp({ note, time: time + event.duration, velocity });
break; break;
case 'Sampler': case 'Sampler':
// note = getPlayableNoteValue(event); // note = getPlayableNoteValue(event);
instrument.triggerAttackRelease(note, event.duration, time); instrument.triggerAttackRelease(note, event.duration, time, velocity);
break; break;
case 'Players': case 'Players':
if (!instrument.has(event.value)) { if (!instrument.has(event.value)) {
throw new Error(`name "${event.value}" not defined for players`); throw new Error(`name "${event.value}" not defined for players`);
} }
const player = instrument.player(event.value); const player = instrument.player(event.value);
// velocity ?
player.start(time); player.start(time);
player.stop(time + event.duration); player.stop(time + event.duration);
break; break;
default: default:
// note = getPlayableNoteValue(event); // note = getPlayableNoteValue(event);
instrument.triggerAttackRelease(note, event.duration, time); instrument.triggerAttackRelease(note, event.duration, time, velocity);
} }
}; };
return event.setContext({ ...event.context, instrument, onTrigger }); return event.setContext({ ...event.context, instrument, onTrigger });

View File

@ -61,14 +61,14 @@ function useRepl({ tune, defaultSynth, autolink = true, onEvent, onDraw }: any)
(time, event) => { (time, event) => {
try { try {
onEvent?.(event); onEvent?.(event);
const { onTrigger } = event.context; const { onTrigger, velocity } = event.context;
if (!onTrigger) { if (!onTrigger) {
const note = event.value; const note = event.value;
if (!isNote(note)) { if (!isNote(note)) {
throw new Error('not a note: ' + note); throw new Error('not a note: ' + note);
} }
if (defaultSynth) { if (defaultSynth) {
defaultSynth.triggerAttackRelease(note, event.duration, time); defaultSynth.triggerAttackRelease(note, event.duration, time, velocity);
} else { } else {
throw new Error('no defaultSynth passed to useRepl.'); throw new Error('no defaultSynth passed to useRepl.');
} }