ru_tts

Форк
0
/
speechrate_control.c 
203 строки · 5.5 Кб
1
/* speechrate_control.c -- Apply speechrate parameters to a sound script
2
 *
3
 * Copyright (C) 1990, 1991 Speech Research Laboratory, Minsk
4
 * Copyright (C) 2005 Igor Poretsky <poretsky@mlbox.ru>
5
 * Copyright (C) 2021 Boris Lobanov <lobbormef@gmail.com>
6
 * Copyright (C) 2021 Alexander Ivanov <ivalex01@gmail.com>
7
 *
8
 * SPDX-License-Identifier: MIT
9
 */
10

11
#include <stdint.h>
12
#include <stdlib.h>
13
#include <string.h>
14

15
#include "soundscript.h"
16
#include "timing.h"
17
#include "transcription.h"
18

19

20
/* Local static data */
21

22
/* Bottom duration threshold for all voice sounds */
23
static const uint8_t bottom[] =
24
  {
25
    30, 31, 32, 31, 30, 30,
26
    31, 32, 31, 30, 15, 15,
27
    15, 15, 15, 15, 15, 15,
28
    15, 15, 15, 15, 15, 15,
29
    15, 15, 15, 15, 15, 15,
30
    15, 15, 15, 15, 15, 15,
31
    15, 15, 15, 15, 15, 15,
32
    15, 15, 15, 15, 15, 15,
33
    15, 15, 30, 30, 30, 30,
34
    30, 15, 15, 15, 15, 15,
35
    30, 30, 30, 30, 30, 15,
36
    15, 15, 15, 15, 30, 30,
37
    30, 30, 30, 15, 15, 15,
38
    15, 15, 30, 30, 30, 30,
39
    30, 15, 15, 15, 15, 15,
40
    30, 30, 30, 30, 30, 10,
41
    11, 12, 11, 10, 10, 11,
42
    12, 11, 10, 15, 15, 15,
43
    15, 15, 15, 15, 15, 15,
44
    15, 15, 15, 15, 15, 15,
45
    15, 15, 20, 30, 35, 20,
46
    40, 20, 35, 49, 30, 45,
47
    20, 40, 50, 40, 50, 60,
48
    50, 0, 20, 25, 10, 35,
49
    35, 20, 20, 30, 20, 35,
50
    40, 0, 20, 25, 0, 20,
51
    25, 20, 20, 30, 20, 20,
52
    30, 50, 50, 40, 40, 35,
53
    35, 50, 40, 40, 50, 30,
54
    30, 30, 30, 40, 50, 60,
55
    60, 80, 70, 70, 90, 50,
56
    60, 50, 50, 5, 0, 255,
57
    255, 0, 255, 255, 255, 255,
58
    255, 255, 255
59
  };
60

61
/* Top duration threshold for all voice sounds */
62
static const uint8_t top[] =
63
  {
64
    75, 78, 80, 78, 75, 55,
65
    58, 60, 58, 55, 30, 30,
66
    30, 30, 30, 25, 25, 25,
67
    25, 25, 30, 30, 30, 30,
68
    30, 25, 25, 25, 25, 25,
69
    30, 30, 30, 30, 30, 25,
70
    25, 25, 25, 25, 30, 30,
71
    30, 30, 30, 25, 25, 25,
72
    25, 25, 60, 60, 60, 60,
73
    60, 25, 25, 25, 25, 25,
74
    50, 50, 50, 50, 50, 25,
75
    25, 25, 25, 25, 50, 50,
76
    50, 50, 50, 25, 25, 25,
77
    25, 25, 50, 50, 50, 50,
78
    50, 25, 25, 25, 25, 25,
79
    60, 60, 60, 60, 60, 50,
80
    50, 50, 50, 50, 50, 50,
81
    50, 50, 50, 30, 30, 35,
82
    30, 35, 30, 30, 30, 30,
83
    30, 35, 30, 30, 30, 30,
84
    35, 30, 40, 80, 90, 45,
85
    110, 50, 90, 100, 50, 110,
86
    40, 100, 110, 100, 100,
87
    110, 100, 20, 30, 30, 23,
88
    80, 40, 30, 30, 50, 35,
89
    50, 60, 19, 30, 30, 19,
90
    30, 30, 30, 30, 50, 30,
91
    30, 50, 110, 100, 80, 100,
92
    80, 70, 130, 120, 110, 130,
93
    90, 90, 80, 80, 90, 100,
94
    150, 150, 160, 170, 170,
95
    210, 130, 150, 130, 130,
96
    50, 0, 20, 30, 25, 25,
97
    40, 50, 15, 255, 55, 255
98
  };
99

100
/* Sound duration forming elements */
101
static const uint8_t elements[][6] =
102
  {
103
    { 20, 20, 0, 0, 0, 0 },
104
    { 50, 25, 25, 0, 0, 0 },
105
    { 10, 2, 1, 0, 0, 0 },
106
    { 20, 10, 0, 0, 0, 0 },
107
    { 60, 30, 0, 0, 0, 0 },
108
    { 30, 15, 0, 0, 0, 0 },
109
    { 50, 40, 20, 0, 0, 0 },
110
    { 20, 12, 6, 0, 0, 0 },
111
    { 0, 8, 12, 40, 0, 0 }
112
  };
113

114

115
/* Global functions */
116

117
/*
118
 * Initial timing setup for specified speech rate and relative
119
 * interclause gap duration expressed as a percentage
120
 * of the default value.
121
 */
122
void timing_setup(timing_t *timing, int speech_rate, int gap_factor)
123
{
124
  int i;
125

126
  if (speech_rate < 20)
127
    timing->rate_factor = 20;
128
  else if (speech_rate > 500)
129
    timing->rate_factor = 500;
130
  else timing->rate_factor = speech_rate;
131
  timing->gap_factor = (uint8_t) ((gap_factor << 2) / 5);
132
  for (i = 0; i < CLAUSE_SEPARATORS; i++)
133
    timing->gaplen[i] = top[i + 191];
134
}
135

136
/*
137
 * Adjust gap duration for specified separator
138
 * applying a percentage factor.
139
 */
140
void adjust_gaplen(timing_t *timing, char separator, int gap_factor)
141
{
142
  char *s = memchr(punctuations, separator, CLAUSE_SEPARATORS);
143
  if (s)
144
    {
145
      int i = s - punctuations;
146
      int gaplen = top[i + 191] * gap_factor / 100;
147
      if (gaplen < 0)
148
        timing->gaplen[i] = 0;
149
      else if (gaplen > 150)
150
        timing->gaplen[i] = 150;
151
      else timing->gaplen[i] = (uint8_t) gaplen;
152
    }
153
}
154

155
/*
156
 * Apply speechrate parameters to the soundscript
157
 * according to specified timing data.
158
 */
159
void apply_speechrate(soundscript_t *script, timing_t *timing, time_plan_ptr_t draft)
160
{
161
  uint16_t i;
162
  uint8_t n = 1;
163

164
  for (i = 0; i < script->length; i++)
165
    {
166
      uint8_t j = script->sounds[i].id;
167
      if (j < 189)
168
        {
169
          if ((draft[1][n] != 4) || (script->sounds[i].stage != 3))
170
            {
171
              uint32_t s = 0;
172
              uint8_t k;
173
              for (k = 0; k < TIME_PLAN_ROWS; k++)
174
                s += elements[k][draft[k][n]];
175
              s *= top[j] - bottom[j];
176
              s *= 120;
177
              s += (((uint32_t) bottom[j]) << 14) + 2048;
178
              s >>= 12;
179
              if ((draft[1][n] == 5) && (script->sounds[i].stage == 2))
180
                s += s >> 1;
181
              script->sounds[i].duration = (uint16_t)(s * 100 / timing->rate_factor);
182
            }
183
          else script->sounds[i].duration = 0;
184
          if (script->sounds[i].stage >= script->sounds[i + 1].stage)
185
            if (draft[1][n++] == 5)
186
              {
187
                while ((++i) < script->length)
188
                  {
189
                    script->sounds[i].duration = 0;
190
                    if (script->sounds[i].stage >= script->sounds[i + 1].stage)
191
                      break;
192
                  }
193
                n++;
194
              }
195
        }
196
      else
197
        {
198
          int k = j - 191;
199
          uint8_t gaplen = ((k >= 0) && (k < CLAUSE_SEPARATORS)) ? timing->gaplen[k] : top[j];
200
          script->sounds[i].duration = (uint16_t)((unsigned int)timing->gap_factor * gaplen * 100 / timing->rate_factor);
201
        }
202
    }
203
}
204

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

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

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

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