add getPlayableNoteValue helper

This commit is contained in:
Felix Roos 2022-02-28 23:32:22 +01:00
parent 1242b1738a
commit ffe258a9fb
3 changed files with 20 additions and 14 deletions

View File

@ -16,9 +16,10 @@ import {
NoiseSynth,
PluckSynth,
Sampler,
getDestination
getDestination,
} from 'tone';
import { Piano } from '@tonejs/piano';
import { getPlayableNoteValue } from '../../util.mjs';
// what about
// https://www.charlie-roberts.com/gibberish/playground/
@ -30,13 +31,15 @@ Pattern.prototype.tone = function (instrument) {
// instrument.toDestination();
return this._withEvent((event) => {
const onTrigger = (time, event) => {
const note = getPlayableNoteValue(event);
// TODO: test if all tonejs instruments can handle freqs
if (instrument.constructor.name === 'PluckSynth') {
instrument.triggerAttack(event.value, time);
instrument.triggerAttack(note, time);
} else if (instrument.constructor.name === 'NoiseSynth') {
instrument.triggerAttackRelease(event.duration, time); // noise has no value
} else if (instrument.constructor.name === 'Piano') {
instrument.keyDown({ note: event.value, time, velocity: 0.5 });
instrument.keyUp({ note: event.value, time: time + event.duration });
instrument.keyDown({ note, time, velocity: 0.5 });
instrument.keyUp({ note, time: time + event.duration });
} else {
instrument.triggerAttackRelease(event.value, event.duration, time);
}

View File

@ -1,6 +1,5 @@
import { useCallback, useState, useMemo } from 'react';
import { isNote } from 'tone';
import { fromMidi } from '../../util.mjs';
import { getPlayableNoteValue } from '../../util.mjs';
import { evaluate } from './evaluate';
import type { Pattern } from './types';
import useCycle from './useCycle';
@ -64,15 +63,8 @@ function useRepl({ tune, defaultSynth, autolink = true, onEvent, onDraw }: any)
onEvent?.(event);
const { onTrigger } = event.context;
if (!onTrigger) {
let note = event.value;
// if value is number => interpret as midi number...
// TODO: what if value is meant as frequency? => check context
if (typeof event.value === 'number') {
note = fromMidi(event.value);
} else if (!isNote(note)) {
throw new Error('not a note: ' + note);
}
if (defaultSynth) {
const note = getPlayableNoteValue(event);
defaultSynth.triggerAttackRelease(note, event.duration, time);
} else {
throw new Error('no defaultSynth passed to useRepl.');

View File

@ -28,3 +28,14 @@ export const fromMidi = (n) => {
// modulo that works with negative numbers e.g. mod(-1, 3) = 2
// const mod = (n: number, m: number): number => (n < 0 ? mod(n + m, m) : n % m);
export const mod = (n, m) => (n < 0 ? mod(n + m, m) : n % m);
export const getPlayableNoteValue = (event) => {
let { value: note, context } = event;
// if value is number => interpret as midi number as long as its not marked as frequency
if (typeof note === 'number' && context.type !== 'frequency') {
note = fromMidi(event.value);
} else if (typeof note === 'string' && !isNote(note)) {
throw new Error('not a note: ' + note);
}
return note;
};