Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
474fd80a95 | ||
|
|
bf5ee88610 |
@@ -2,5 +2,5 @@ apiVersion: v2
|
|||||||
name: ai-spel-frontend
|
name: ai-spel-frontend
|
||||||
description: Static web frontend for the Swedish life simulator
|
description: Static web frontend for the Swedish life simulator
|
||||||
type: application
|
type: application
|
||||||
version: 0.1.42
|
version: 0.1.43
|
||||||
appVersion: "0.1.42"
|
appVersion: "0.1.43"
|
||||||
@@ -117,17 +117,19 @@ test('recognition watchdog closes a session that never ends and permits retry',
|
|||||||
assert.equal(h.recognitions.length, 2);
|
assert.equal(h.recognitions.length, 2);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('TTS selects Swedish fallback, applies rate, and cancellation invalidates callbacks', () => {
|
test('TTS uses the system default voice unless a named Swedish voice is selected', () => {
|
||||||
const h = makeHarness();
|
const h = makeHarness();
|
||||||
h.controller.update({mode: 'game-voice', rate: 1.4});
|
h.controller.update({mode: 'game-voice', rate: 1.4});
|
||||||
assert.equal(h.controller.speak('Hej.'), true);
|
assert.equal(h.controller.speak('Hej.'), true);
|
||||||
const first = h.utterances[0];
|
const first = h.utterances[0];
|
||||||
assert.equal(first.lang, 'sv-SE');
|
assert.equal(first.lang, 'sv-SE');
|
||||||
assert.equal(first.rate, 1.4);
|
assert.equal(first.rate, 1.4);
|
||||||
assert.equal(first.voice.name, 'Svensk');
|
assert.equal(first.voice, null);
|
||||||
h.controller.cancelSpeech();
|
h.controller.cancelSpeech();
|
||||||
first.onend();
|
first.onend();
|
||||||
assert.equal(h.controller.getState(), 'IDLE');
|
assert.equal(h.controller.getState(), 'IDLE');
|
||||||
|
assert.equal(h.controller.speak('Namngiven röst.', {voiceName: 'Svensk'}), true);
|
||||||
|
assert.equal(h.utterances.at(-1).voice.name, 'Svensk');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('a player gesture restores the iOS speech primer after cancelling a queued reply', () => {
|
test('a player gesture restores the iOS speech primer after cancelling a queued reply', () => {
|
||||||
|
|||||||
@@ -233,9 +233,14 @@
|
|||||||
utterance.pitch = isNarrator ? 1 : Math.min(2, Math.max(0, Number(voiceOptions.pitch ?? profile.pitch ?? identityProfile.pitch) || 1));
|
utterance.pitch = isNarrator ? 1 : Math.min(2, Math.max(0, Number(voiceOptions.pitch ?? profile.pitch ?? identityProfile.pitch) || 1));
|
||||||
const requestedName = voiceOptions.voiceName || profile.voiceName || settings.voiceName;
|
const requestedName = voiceOptions.voiceName || profile.voiceName || settings.voiceName;
|
||||||
const voices = availableVoices();
|
const voices = availableVoices();
|
||||||
utterance.voice = voices.find(voice => voice.name === requestedName)
|
// An empty selection means the operating system should choose its
|
||||||
|
// default voice for the requested language. Forcing the first voice
|
||||||
|
// returned by WebKit can select a voice that is listed but cannot speak.
|
||||||
|
utterance.voice = requestedName
|
||||||
|
? voices.find(voice => voice.name === requestedName)
|
||||||
|| voices.find(voice => /^sv(-|$)/i.test(voice.lang))
|
|| voices.find(voice => /^sv(-|$)/i.test(voice.lang))
|
||||||
|| null;
|
|| null
|
||||||
|
: null;
|
||||||
utterance.onstart = () => {
|
utterance.onstart = () => {
|
||||||
if (token !== generation) return;
|
if (token !== generation) return;
|
||||||
if (speechStartTimer !== null) win.clearTimeout(speechStartTimer);
|
if (speechStartTimer !== null) win.clearTimeout(speechStartTimer);
|
||||||
|
|||||||
Reference in New Issue
Block a user