Fix occasionally current speak not stopped when changing voice or rate (#144)

* Fix occasionally current speak not stopped when changing voice or rate

* Inherit tts rate when changing tts engine
This commit is contained in:
Huang Xin
2025-01-11 18:11:14 +01:00
committed by GitHub
parent 87bc842525
commit 463ea39467
4 changed files with 37 additions and 33 deletions
@@ -97,16 +97,16 @@ const TTSControl = () => {
if (!ttsController) return;
if (isPlaying) {
ttsController.pause();
await ttsController.pause();
setIsPlaying(false);
setIsPaused(true);
} else if (isPaused) {
// start for forward/backward/setvoice-paused
// set rate don't pause the tts
if (ttsController.state === 'paused') {
ttsController.resume();
await ttsController.resume();
} else {
ttsController.start();
await ttsController.start();
}
setIsPlaying(true);
setIsPaused(false);
@@ -130,7 +130,7 @@ const TTSControl = () => {
const handleStop = async () => {
const ttsController = ttsControllerRef.current;
if (ttsController) {
ttsController.stop();
await ttsController.stop();
ttsControllerRef.current = null;
setIsPlaying(false);
setShowPanel(false);
@@ -143,11 +143,11 @@ const TTSControl = () => {
const ttsController = ttsControllerRef.current;
if (ttsController) {
if (ttsController.state === 'playing') {
ttsController.pause();
ttsController.setRate(rate);
ttsController.start();
await ttsController.pause();
await ttsController.setRate(rate);
await ttsController.start();
} else {
ttsController.setRate(rate);
await ttsController.setRate(rate);
}
}
};
@@ -156,11 +156,11 @@ const TTSControl = () => {
const ttsController = ttsControllerRef.current;
if (ttsController) {
if (ttsController.state === 'playing') {
ttsController.pause();
ttsController.setVoice(voice);
ttsController.start();
await ttsController.pause();
await ttsController.setVoice(voice);
await ttsController.start();
} else {
ttsController.setVoice(voice);
await ttsController.setVoice(voice);
}
}
};
@@ -57,7 +57,7 @@ export class EdgeTTSClient implements TTSClient {
voiceId = this.#voice.id;
}
this.stopInternal();
await this.stopInternal();
// Preloading for longer ssml
if (marks.length > 1) {
@@ -117,7 +117,7 @@ export class EdgeTTSClient implements TTSClient {
break;
}
this.stopInternal();
await this.stopInternal();
}
}
@@ -136,10 +136,10 @@ export class EdgeTTSClient implements TTSClient {
}
async stop() {
this.stopInternal();
await this.stopInternal();
}
private stopInternal() {
private async stopInternal() {
this.#isPlaying = false;
this.#pausedAt = 0;
this.#startedAt = 0;
@@ -153,7 +153,7 @@ export class EdgeTTSClient implements TTSClient {
this.#sourceNode = null;
}
if (this.#audioContext) {
this.#audioContext.close();
await this.#audioContext.close();
this.#audioContext = null;
}
this.#audioBuffer = null;
@@ -16,6 +16,7 @@ export class TTSController extends EventTarget {
view: FoliateView;
#nossmlCnt: number = 0;
ttsRate: number = 1.0;
ttsClient: TTSClient;
ttsWebClient: TTSClient;
ttsEdgeClient: TTSClient;
@@ -61,7 +62,7 @@ export class TTSController extends EventTarget {
// FIXME: in case we are at the end of the book, need a better way to handle this
if (this.#nossmlCnt < 10 && this.state === 'playing') {
await this.view.next(1);
this.forward();
await this.forward();
}
return;
} else {
@@ -78,7 +79,7 @@ export class TTSController extends EventTarget {
}
if (lastCode === 'end' && this.state === 'playing') {
this.forward();
await this.forward();
}
}
@@ -103,26 +104,26 @@ export class TTSController extends EventTarget {
return this.#speak(resumeOrStart);
}
pause() {
async pause() {
this.state = 'paused';
this.ttsClient.pause().catch((e) => this.error(e));
await this.ttsClient.pause().catch((e) => this.error(e));
}
resume() {
async resume() {
this.state = 'playing';
this.ttsClient.resume().catch((e) => this.error(e));
await this.ttsClient.resume().catch((e) => this.error(e));
}
stop() {
async stop() {
this.state = 'stopped';
this.ttsClient.stop().catch((e) => this.error(e));
await this.ttsClient.stop().catch((e) => this.error(e));
}
// goto previous sentence
async backward() {
this.initViewTTS();
await this.initViewTTS();
if (this.state === 'playing') {
this.stop();
await this.stop();
this.#speak(this.view.tts?.prev());
} else {
this.state = 'backward-paused';
@@ -134,7 +135,7 @@ export class TTSController extends EventTarget {
async forward() {
await this.initViewTTS();
if (this.state === 'playing') {
this.stop();
await this.stop();
this.#speak(this.view.tts?.next());
} else {
this.state = 'forward-paused';
@@ -143,7 +144,8 @@ export class TTSController extends EventTarget {
}
async setRate(rate: number) {
this.ttsClient.setRate(rate);
this.ttsRate = rate;
await this.ttsClient.setRate(this.ttsRate);
}
async getVoices(lang: string) {
@@ -154,14 +156,16 @@ export class TTSController extends EventTarget {
async setVoice(voiceId: string) {
this.state = 'setvoice-paused';
this.ttsClient.stop();
await this.ttsClient.stop();
const useEdgeTTS = !!this.ttsEdgeVoices.find(
(voice) => (voiceId === '' || voice.id === voiceId) && !voice.disabled,
);
if (useEdgeTTS) {
this.ttsClient = this.ttsEdgeClient;
await this.ttsClient.setRate(this.ttsRate);
} else {
this.ttsClient = this.ttsWebClient;
await this.ttsClient.setRate(this.ttsRate);
}
await this.ttsClient.setVoice(voiceId);
}
@@ -175,8 +179,8 @@ export class TTSController extends EventTarget {
this.state = 'stopped';
}
kill() {
async kill() {
this.state = 'stopped';
this.ttsClient.stop();
await this.ttsClient.stop();
}
}