Merge pull request #67 from tidalcycles/speak

Speech output
This commit is contained in:
Felix Roos 2022-04-14 00:09:17 +02:00 committed by GitHub
commit 02738a0694
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 9 deletions

View File

@ -935,18 +935,18 @@ export function makeComposable(func) {
return func;
}
const patternify2 = (f) => (pata, patb, pat) =>
export const patternify2 = (f) => (pata, patb, pat) =>
pata
.fmap((a) => (b) => f.call(pat, a, b))
.appLeft(patb)
.innerJoin();
const patternify3 = (f) => (pata, patb, patc, pat) =>
export const patternify3 = (f) => (pata, patb, patc, pat) =>
pata
.fmap((a) => (b) => (c) => f.call(pat, a, b, c))
.appLeft(patb)
.appLeft(patc)
.innerJoin();
const patternify4 = (f) => (pata, patb, patc, patd, pat) =>
export const patternify4 = (f) => (pata, patb, patc, patd, pat) =>
pata
.fmap((a) => (b) => (c) => (d) => f.call(pat, a, b, c, d))
.appLeft(patb)

33
packages/core/speak.mjs Normal file
View 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);
};

View File

@ -26,17 +26,28 @@ import '@strudel.cycles/tonal/tonal.mjs';
import '@strudel.cycles/xen/xen.mjs';
import '@strudel.cycles/xen/tune.mjs';
import '@strudel.cycles/core/euclid.mjs';
import '@strudel.cycles/core/speak.mjs';
import '@strudel.cycles/tone/pianoroll.mjs';
import '@strudel.cycles/tone/draw.mjs';
import '@strudel.cycles/osc/osc.mjs';
import controls from '@strudel.cycles/core/controls.mjs';
extend(Tone, strudel, strudel.Pattern.prototype.bootstrap(), controls, toneHelpers, voicingHelpers, drawHelpers, uiHelpers, {
gist,
euclid,
mini,
extend(
Tone,
});
strudel,
strudel.Pattern.prototype.bootstrap(),
controls,
toneHelpers,
voicingHelpers,
drawHelpers,
uiHelpers,
{
gist,
euclid,
mini,
Tone,
},
);
// eval stuff end
const codeParam = window.location.href.split('#')[1];

View File

@ -6,7 +6,7 @@ import cx from '../cx';
// eval stuff start
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 { mini } from '@strudel.cycles/mini/mini.mjs';
import { Tone } from '@strudel.cycles/tone';