commit
02738a0694
4 changed files with 53 additions and 9 deletions
|
|
@ -935,18 +935,18 @@ export function makeComposable(func) {
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
|
|
||||||
const patternify2 = (f) => (pata, patb, pat) =>
|
export const patternify2 = (f) => (pata, patb, pat) =>
|
||||||
pata
|
pata
|
||||||
.fmap((a) => (b) => f.call(pat, a, b))
|
.fmap((a) => (b) => f.call(pat, a, b))
|
||||||
.appLeft(patb)
|
.appLeft(patb)
|
||||||
.innerJoin();
|
.innerJoin();
|
||||||
const patternify3 = (f) => (pata, patb, patc, pat) =>
|
export const patternify3 = (f) => (pata, patb, patc, pat) =>
|
||||||
pata
|
pata
|
||||||
.fmap((a) => (b) => (c) => f.call(pat, a, b, c))
|
.fmap((a) => (b) => (c) => f.call(pat, a, b, c))
|
||||||
.appLeft(patb)
|
.appLeft(patb)
|
||||||
.appLeft(patc)
|
.appLeft(patc)
|
||||||
.innerJoin();
|
.innerJoin();
|
||||||
const patternify4 = (f) => (pata, patb, patc, patd, pat) =>
|
export const patternify4 = (f) => (pata, patb, patc, patd, pat) =>
|
||||||
pata
|
pata
|
||||||
.fmap((a) => (b) => (c) => (d) => f.call(pat, a, b, c, d))
|
.fmap((a) => (b) => (c) => (d) => f.call(pat, a, b, c, d))
|
||||||
.appLeft(patb)
|
.appLeft(patb)
|
||||||
|
|
|
||||||
33
packages/core/speak.mjs
Normal file
33
packages/core/speak.mjs
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
import { Pattern, patternify2 } from './index.mjs';
|
||||||
|
|
||||||
|
const synth = window?.speechSynthesis;
|
||||||
|
let allVoices = synth?.getVoices();
|
||||||
|
// console.log('voices', allVoices);
|
||||||
|
|
||||||
|
function speak(words, lang, voice) {
|
||||||
|
synth.cancel();
|
||||||
|
const utterance = new SpeechSynthesisUtterance(words);
|
||||||
|
utterance.lang = lang;
|
||||||
|
allVoices = synth.getVoices();
|
||||||
|
const voices = allVoices.filter((v) => v.lang.includes(lang));
|
||||||
|
if (typeof voice === 'number') {
|
||||||
|
utterance.voice = voices[voice % voices.length];
|
||||||
|
} else if (typeof voice === 'string') {
|
||||||
|
utterance.voice = voices.find((voice) => voice.name === voice);
|
||||||
|
}
|
||||||
|
// console.log(utterance.voice?.name, utterance.voice?.lang);
|
||||||
|
speechSynthesis.speak(utterance);
|
||||||
|
}
|
||||||
|
|
||||||
|
Pattern.prototype._speak = function (lang, voice) {
|
||||||
|
return this._withEvent((event) => {
|
||||||
|
const onTrigger = (time, event) => {
|
||||||
|
speak(event.value, lang, voice);
|
||||||
|
};
|
||||||
|
return event.setContext({ ...event.context, onTrigger });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Pattern.prototype.speak = function (lang, voice) {
|
||||||
|
return patternify2(Pattern.prototype._speak)(reify(lang), reify(voice), this);
|
||||||
|
};
|
||||||
|
|
@ -26,17 +26,28 @@ import '@strudel.cycles/tonal/tonal.mjs';
|
||||||
import '@strudel.cycles/xen/xen.mjs';
|
import '@strudel.cycles/xen/xen.mjs';
|
||||||
import '@strudel.cycles/xen/tune.mjs';
|
import '@strudel.cycles/xen/tune.mjs';
|
||||||
import '@strudel.cycles/core/euclid.mjs';
|
import '@strudel.cycles/core/euclid.mjs';
|
||||||
|
import '@strudel.cycles/core/speak.mjs';
|
||||||
import '@strudel.cycles/tone/pianoroll.mjs';
|
import '@strudel.cycles/tone/pianoroll.mjs';
|
||||||
import '@strudel.cycles/tone/draw.mjs';
|
import '@strudel.cycles/tone/draw.mjs';
|
||||||
import '@strudel.cycles/osc/osc.mjs';
|
import '@strudel.cycles/osc/osc.mjs';
|
||||||
import controls from '@strudel.cycles/core/controls.mjs';
|
import controls from '@strudel.cycles/core/controls.mjs';
|
||||||
|
|
||||||
extend(Tone, strudel, strudel.Pattern.prototype.bootstrap(), controls, toneHelpers, voicingHelpers, drawHelpers, uiHelpers, {
|
extend(
|
||||||
gist,
|
|
||||||
euclid,
|
|
||||||
mini,
|
|
||||||
Tone,
|
Tone,
|
||||||
});
|
strudel,
|
||||||
|
strudel.Pattern.prototype.bootstrap(),
|
||||||
|
controls,
|
||||||
|
toneHelpers,
|
||||||
|
voicingHelpers,
|
||||||
|
drawHelpers,
|
||||||
|
uiHelpers,
|
||||||
|
{
|
||||||
|
gist,
|
||||||
|
euclid,
|
||||||
|
mini,
|
||||||
|
Tone,
|
||||||
|
},
|
||||||
|
);
|
||||||
// eval stuff end
|
// eval stuff end
|
||||||
|
|
||||||
const codeParam = window.location.href.split('#')[1];
|
const codeParam = window.location.href.split('#')[1];
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import cx from '../cx';
|
||||||
|
|
||||||
// eval stuff start
|
// eval stuff start
|
||||||
import { extend } from '@strudel.cycles/eval';
|
import { extend } from '@strudel.cycles/eval';
|
||||||
import * as strudel from '@strudel.cycles/core/strudel.mjs';
|
import * as strudel from '@strudel.cycles/core';
|
||||||
import gist from '@strudel.cycles/core/gist.js';
|
import gist from '@strudel.cycles/core/gist.js';
|
||||||
import { mini } from '@strudel.cycles/mini/mini.mjs';
|
import { mini } from '@strudel.cycles/mini/mini.mjs';
|
||||||
import { Tone } from '@strudel.cycles/tone';
|
import { Tone } from '@strudel.cycles/tone';
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue