ru_tts-for-nvda

Форк
0
99 строк · 2.7 Кб
1
// Copyright (C) 2021 - 2023 Александр Линьков <kvark128@yandex.ru>
2
// Этот файл распространяется под лицензией MIT
3

4
#include <stdlib.h>
5

6
#include <sonic.h>
7
#include <ru_tts.h>
8
#include "ru_tts_nvda.h"
9

10
#define SUCCESS 0
11
#define FAILURE 1
12

13
#define WAVE_SIZE 4096
14
#define SAMPLE_RATE 10000
15
#define NUM_CHANNELS 1
16

17
int writeToConsumer(const TTS_t *tts, const int minSamples) {
18
	int numSamples = sonicSamplesAvailable(tts->stream);
19
	while (numSamples >= minSamples) {
20
		int n = sonicReadShortFromStream(tts->stream, tts->buffer, WAVE_SIZE);
21
		if (tts->consumer(tts->buffer, n, NULL)) {
22
			// Пользователь прервал синтез. Необходимо сбросить внутренние буферы sonic
23
			sonicFlushStream(tts->stream);
24
			while (sonicReadShortFromStream(tts->stream, tts->buffer, WAVE_SIZE));
25
			return FAILURE;
26
		}
27
		numSamples -= n;
28
	}
29
	return SUCCESS;
30
}
31

32
int audio_callback(void *buffer, size_t size, void *user_data) {
33
	signed char *samples = (signed char*) buffer;
34
	TTS_t *tts = (TTS_t*) user_data;
35
	for (size_t i = 0; i < size; i++) {
36
		// Sonic не поддерживает аудиоданные в форме signed char. Преобразуем signed char в unsigned char
37
		samples[i] ^= 0x80;
38
	}
39
	if (sonicWriteUnsignedCharToStream(tts->stream, buffer, size) == 0) {
40
		return FAILURE;
41
	}
42
	return writeToConsumer(tts, WAVE_SIZE);
43
}
44

45
RUTTS_EXPORT TTS_t* tts_create(ru_tts_callback wave_consumer) {
46
	if (wave_consumer == NULL) {
47
		return NULL;
48
	}
49
	sonicStream stream = sonicCreateStream(SAMPLE_RATE, NUM_CHANNELS);
50
	if (stream == NULL) {
51
		return NULL;
52
	}
53
	// Буфер для short-сэмплов
54
	void *buffer = malloc(WAVE_SIZE * sizeof(short));
55
	if (buffer == NULL) {
56
		sonicDestroyStream(stream);
57
		return NULL;
58
	}
59
	TTS_t *tts = malloc(sizeof(TTS_t));
60
	if (tts == NULL) {
61
		sonicDestroyStream(stream);
62
		free(buffer);
63
		return NULL;
64
	}
65
	tts->stream = stream;
66
	tts->buffer = buffer;
67
	tts->consumer = wave_consumer;
68
	return tts;
69
}
70

71
RUTTS_EXPORT void tts_destroy(TTS_t *tts) {
72
	if (tts == NULL) {
73
		return;
74
	}
75
	if (tts->stream != NULL) {
76
		sonicDestroyStream(tts->stream);
77
		tts->stream = NULL;
78
	}
79
	if (tts->buffer != NULL) {
80
		free(tts->buffer);
81
		tts->buffer = NULL;
82
	}
83
	tts->consumer = NULL;
84
	free(tts);
85
}
86

87
RUTTS_EXPORT void tts_speak(const TTS_t *tts, const ru_tts_conf_t *config, const char *text) {
88
	ru_tts_transfer(config, text, tts->buffer, WAVE_SIZE, audio_callback, (void*)tts);
89
	sonicFlushStream(tts->stream);
90
	writeToConsumer(tts, 1);
91
}
92

93
RUTTS_EXPORT void tts_setVolume(const TTS_t *tts, float volume) {
94
	sonicSetVolume(tts->stream, volume);
95
}
96

97
RUTTS_EXPORT void tts_setSpeed(const TTS_t *tts, float speed) {
98
	sonicSetSpeed(tts->stream, speed);
99
}
100

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.