Coverage Report

Created: 2026-08-13 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/espeak-ng/src/libespeak-ng/wavegen.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2005 to 2013 by Jonathan Duddington
3
 * email: jonsd@users.sourceforge.net
4
 * Copyright (C) 2015-2016 Reece H. Dunn
5
 *
6
 * This program is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, see: <http://www.gnu.org/licenses/>.
18
 */
19
20
// this version keeps wavemult window as a constant fraction
21
// of the cycle length - but that spreads out the HF peaks too much
22
23
#include "config.h"
24
25
#include <math.h>
26
#include <stdbool.h>
27
#include <stdint.h>
28
#include <stdio.h>
29
#include <stdlib.h>
30
#include <string.h>
31
32
#include <espeak-ng/espeak_ng.h>
33
#include <espeak-ng/speak_lib.h>
34
35
#include "wavegen.h"
36
#include "common.h"                   // for espeak_rand
37
#include "synthesize.h"               // for WGEN_DATA, RESONATOR, frame_t
38
#include "mbrola.h"                  // for MbrolaFill, MbrolaReset, mbrola...
39
40
#if USE_KLATT
41
#include "klatt.h"
42
#endif
43
44
#if USE_LIBSONIC
45
#include "sonic.h"
46
#endif
47
48
#include "sintab.h"
49
#include "speech.h"
50
51
static void SetSynth(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t *v);
52
53
static voice_t *wvoice = NULL;
54
55
static int option_harmonic1 = 10;
56
static int flutter_amp = 64;
57
58
static int general_amplitude = 60;
59
static int consonant_amp = 26;
60
61
int embedded_value[N_EMBEDDED_VALUES];
62
63
static int PHASE_INC_FACTOR;
64
int samplerate = 0; // this is set by Wavegeninit()
65
66
static wavegen_peaks_t peaks[N_PEAKS];
67
static int peak_harmonic[N_PEAKS];
68
static int peak_height[N_PEAKS];
69
70
int echo_head;
71
int echo_tail;
72
int echo_amp = 0;
73
short echo_buf[N_ECHO_BUF];
74
static int echo_length = 0; // period (in sample\) to ensure completion of echo at the end of speech, set in WavegenSetEcho()
75
76
static int voicing;
77
static RESONATOR rbreath[N_PEAKS];
78
79
35.4G
#define N_LOWHARM  30
80
81.0M
#define MAX_HARMONIC 400 // 400 * 50Hz = 20 kHz, more than enough
81
static int harm_inc[N_LOWHARM]; // only for these harmonics do we interpolate amplitude between steps
82
static int *harmspect;
83
static int hswitch = 0;
84
static int hspect[2][MAX_HARMONIC]; // 2 copies, we interpolate between then
85
86
static int nsamples = 0; // number to do
87
static int modulation_type = 0;
88
static int glottal_flag = 0;
89
static int glottal_reduce = 0;
90
91
static WGEN_DATA wdata;
92
93
static int amp_ix;
94
static int amp_inc;
95
static unsigned char *amplitude_env = NULL;
96
97
static int samplecount = 0; // number done
98
static int samplecount_start = 0; // count at start of this segment
99
static int end_wave = 0; // continue to end of wave cycle
100
static int wavephase;
101
static int phaseinc;
102
static int cycle_samples; // number of samples in a cycle at current pitch
103
static int cbytes;
104
static int hf_factor;
105
106
static double minus_pi_t;
107
static double two_pi_t;
108
109
unsigned char *out_ptr;
110
unsigned char *out_end;
111
112
espeak_ng_OUTPUT_HOOKS* output_hooks = NULL;
113
static int const_f0 = 0;
114
115
// the queue of operations passed to wavegen from sythesize
116
intptr_t wcmdq[N_WCMDQ][4];
117
int wcmdq_head = 0;
118
int wcmdq_tail = 0;
119
120
// pitch,speed,
121
const int embedded_default[N_EMBEDDED_VALUES]    = { 0,     50, espeakRATE_NORMAL, 100, 50,  0,  0, 0, espeakRATE_NORMAL, 0, 0, 0, 0, 0, 0 };
122
static const int embedded_max[N_EMBEDDED_VALUES] = { 0, 0x7fff, 2000, 300, 99, 99, 99, 0, 2000, 0, 0, 0, 0, 4, 0 };
123
124
#if USE_LIBSONIC
125
static sonicStream sonicSpeedupStream = NULL;
126
static double sonicSpeed = 1.0;
127
#endif
128
129
// 1st index=roughness
130
// 2nd index=modulation_type
131
// value: bits 0-3  amplitude (16ths), bits 4-7 every n cycles
132
23.2M
#define N_ROUGHNESS 8
133
static const unsigned char modulation_tab[N_ROUGHNESS][8] = {
134
  { 0, 0x00, 0x00, 0x00, 0, 0x46, 0xf2, 0x29 },
135
  { 0, 0x2f, 0x00, 0x2f, 0, 0x45, 0xf2, 0x29 },
136
  { 0, 0x2f, 0x00, 0x2e, 0, 0x45, 0xf2, 0x28 },
137
  { 0, 0x2e, 0x00, 0x2d, 0, 0x34, 0xf2, 0x28 },
138
  { 0, 0x2d, 0x2d, 0x2c, 0, 0x34, 0xf2, 0x28 },
139
  { 0, 0x2b, 0x2b, 0x2b, 0, 0x34, 0xf2, 0x28 },
140
  { 0, 0x2a, 0x2a, 0x2a, 0, 0x34, 0xf2, 0x28 },
141
  { 0, 0x29, 0x29, 0x29, 0, 0x34, 0xf2, 0x28 },
142
};
143
144
// Flutter table, to add natural variations to the pitch
145
78.2M
#define N_FLUTTER  0x170
146
static int Flutter_inc;
147
static const unsigned char Flutter_tab[N_FLUTTER] = {
148
  0x80, 0x9b, 0xb5, 0xcb, 0xdc, 0xe8, 0xed, 0xec,
149
  0xe6, 0xdc, 0xce, 0xbf, 0xb0, 0xa3, 0x98, 0x90,
150
  0x8c, 0x8b, 0x8c, 0x8f, 0x92, 0x94, 0x95, 0x92,
151
  0x8c, 0x83, 0x78, 0x69, 0x59, 0x49, 0x3c, 0x31,
152
  0x2a, 0x29, 0x2d, 0x36, 0x44, 0x56, 0x69, 0x7d,
153
  0x8f, 0x9f, 0xaa, 0xb1, 0xb2, 0xad, 0xa4, 0x96,
154
  0x87, 0x78, 0x69, 0x5c, 0x53, 0x4f, 0x4f, 0x55,
155
  0x5e, 0x6b, 0x7a, 0x88, 0x96, 0xa2, 0xab, 0xb0,
156
157
  0xb1, 0xae, 0xa8, 0xa0, 0x98, 0x91, 0x8b, 0x88,
158
  0x89, 0x8d, 0x94, 0x9d, 0xa8, 0xb2, 0xbb, 0xc0,
159
  0xc1, 0xbd, 0xb4, 0xa5, 0x92, 0x7c, 0x63, 0x4a,
160
  0x32, 0x1e, 0x0e, 0x05, 0x02, 0x05, 0x0f, 0x1e,
161
  0x30, 0x44, 0x59, 0x6d, 0x7f, 0x8c, 0x96, 0x9c,
162
  0x9f, 0x9f, 0x9d, 0x9b, 0x99, 0x99, 0x9c, 0xa1,
163
  0xa9, 0xb3, 0xbf, 0xca, 0xd5, 0xdc, 0xe0, 0xde,
164
  0xd8, 0xcc, 0xbb, 0xa6, 0x8f, 0x77, 0x60, 0x4b,
165
166
  0x3a, 0x2e, 0x28, 0x29, 0x2f, 0x3a, 0x48, 0x59,
167
  0x6a, 0x7a, 0x86, 0x90, 0x94, 0x95, 0x91, 0x89,
168
  0x80, 0x75, 0x6b, 0x62, 0x5c, 0x5a, 0x5c, 0x61,
169
  0x69, 0x74, 0x80, 0x8a, 0x94, 0x9a, 0x9e, 0x9d,
170
  0x98, 0x90, 0x86, 0x7c, 0x71, 0x68, 0x62, 0x60,
171
  0x63, 0x6b, 0x78, 0x88, 0x9b, 0xaf, 0xc2, 0xd2,
172
  0xdf, 0xe6, 0xe7, 0xe2, 0xd7, 0xc6, 0xb2, 0x9c,
173
  0x84, 0x6f, 0x5b, 0x4b, 0x40, 0x39, 0x37, 0x38,
174
175
  0x3d, 0x43, 0x4a, 0x50, 0x54, 0x56, 0x55, 0x52,
176
  0x4d, 0x48, 0x42, 0x3f, 0x3e, 0x41, 0x49, 0x56,
177
  0x67, 0x7c, 0x93, 0xab, 0xc3, 0xd9, 0xea, 0xf6,
178
  0xfc, 0xfb, 0xf4, 0xe7, 0xd5, 0xc0, 0xaa, 0x94,
179
  0x80, 0x71, 0x64, 0x5d, 0x5a, 0x5c, 0x61, 0x68,
180
  0x70, 0x77, 0x7d, 0x7f, 0x7f, 0x7b, 0x74, 0x6b,
181
  0x61, 0x57, 0x4e, 0x48, 0x46, 0x48, 0x4e, 0x59,
182
  0x66, 0x75, 0x84, 0x93, 0x9f, 0xa7, 0xab, 0xaa,
183
184
  0xa4, 0x99, 0x8b, 0x7b, 0x6a, 0x5b, 0x4e, 0x46,
185
  0x43, 0x45, 0x4d, 0x5a, 0x6b, 0x7f, 0x92, 0xa6,
186
  0xb8, 0xc5, 0xcf, 0xd3, 0xd2, 0xcd, 0xc4, 0xb9,
187
  0xad, 0xa1, 0x96, 0x8e, 0x89, 0x87, 0x87, 0x8a,
188
  0x8d, 0x91, 0x92, 0x91, 0x8c, 0x84, 0x78, 0x68,
189
  0x55, 0x41, 0x2e, 0x1c, 0x0e, 0x05, 0x01, 0x05,
190
  0x0f, 0x1f, 0x34, 0x4d, 0x68, 0x81, 0x9a, 0xb0,
191
  0xc1, 0xcd, 0xd3, 0xd3, 0xd0, 0xc8, 0xbf, 0xb5,
192
193
  0xab, 0xa4, 0x9f, 0x9c, 0x9d, 0xa0, 0xa5, 0xaa,
194
  0xae, 0xb1, 0xb0, 0xab, 0xa3, 0x96, 0x87, 0x76,
195
  0x63, 0x51, 0x42, 0x36, 0x2f, 0x2d, 0x31, 0x3a,
196
  0x48, 0x59, 0x6b, 0x7e, 0x8e, 0x9c, 0xa6, 0xaa,
197
  0xa9, 0xa3, 0x98, 0x8a, 0x7b, 0x6c, 0x5d, 0x52,
198
  0x4a, 0x48, 0x4a, 0x50, 0x5a, 0x67, 0x75, 0x82
199
};
200
201
// waveform shape table for HF peaks, formants 6,7,8
202
1
#define N_WAVEMULT 128
203
static int wavemult_offset = 0;
204
static int wavemult_max = 0;
205
206
// the presets are for 22050 Hz sample rate.
207
// A different rate will need to recalculate the presets in WavegenInit()
208
static unsigned char wavemult[N_WAVEMULT] = {
209
    0,   0,   0,   2,   3,   5,   8,  11,  14,  18,  22,  27,  32,  37,  43,  49,
210
   55,  62,  69,  76,  83,  90,  98, 105, 113, 121, 128, 136, 144, 152, 159, 166,
211
  174, 181, 188, 194, 201, 207, 213, 218, 224, 228, 233, 237, 240, 244, 246, 249,
212
  251, 252, 253, 253, 253, 253, 252, 251, 249, 246, 244, 240, 237, 233, 228, 224,
213
  218, 213, 207, 201, 194, 188, 181, 174, 166, 159, 152, 144, 136, 128, 121, 113,
214
  105,  98,  90,  83,  76,  69,  62,  55,  49,  43,  37,  32,  27,  22,  18,  14,
215
   11,   8,   5,   3,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
216
    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
217
};
218
219
// set from y = pow(2,x) * 128,  x=-1 to 1
220
3.28M
#define MAX_PITCH_VALUE  101
221
static const unsigned char pitch_adjust_tab[MAX_PITCH_VALUE+1] = {
222
   64,  65,  66,  67,  68,  69,  70,  71,
223
   72,  73,  74,  75,  76,  77,  78,  79,
224
   80,  81,  82,  83,  84,  86,  87,  88,
225
   89,  91,  92,  93,  94,  96,  97,  98,
226
  100, 101, 103, 104, 105, 107, 108, 110,
227
  111, 113, 115, 116, 118, 119, 121, 123,
228
  124, 126, 128, 130, 132, 133, 135, 137,
229
  139, 141, 143, 145, 147, 149, 151, 153,
230
  155, 158, 160, 162, 164, 167, 169, 171,
231
  174, 176, 179, 181, 184, 186, 189, 191,
232
  194, 197, 199, 202, 205, 208, 211, 214,
233
  217, 220, 223, 226, 229, 232, 236, 239,
234
  242, 246, 249, 252, 254, 255
235
};
236
237
void WcmdqStop(void)
238
0
{
239
0
  wcmdq_head = 0;
240
0
  wcmdq_tail = 0;
241
242
#if USE_LIBSONIC
243
  if (sonicSpeedupStream != NULL) {
244
    sonicDestroyStream(sonicSpeedupStream);
245
    sonicSpeedupStream = NULL;
246
  }
247
#endif
248
249
#if USE_MBROLA
250
  if (mbrola_name[0] != 0)
251
    MbrolaReset();
252
#endif
253
0
}
254
255
int WcmdqFree(void)
256
39.5M
{
257
39.5M
  int i;
258
39.5M
  i = wcmdq_head - wcmdq_tail;
259
39.5M
  if (i <= 0) i += N_WCMDQ;
260
39.5M
  return i;
261
39.5M
}
262
263
int WcmdqUsed(void)
264
28.9M
{
265
28.9M
  return N_WCMDQ - WcmdqFree();
266
28.9M
}
267
268
void WcmdqInc(void)
269
22.4M
{
270
22.4M
  wcmdq_tail++;
271
22.4M
  if (wcmdq_tail >= N_WCMDQ) wcmdq_tail = 0;
272
22.4M
}
273
274
static void WcmdqIncHead(void)
275
22.4M
{
276
22.4M
  MAKE_MEM_UNDEFINED(&wcmdq[wcmdq_head], sizeof(wcmdq[wcmdq_head]));
277
22.4M
  wcmdq_head++;
278
22.4M
  if (wcmdq_head >= N_WCMDQ) wcmdq_head = 0;
279
22.4M
}
280
281
#define PEAKSHAPEW 256
282
283
static const unsigned char pk_shape1[PEAKSHAPEW+1] = {
284
  255, 254, 254, 254, 254, 254, 253, 253, 252, 251, 251, 250, 249, 248, 247, 246,
285
  245, 244, 242, 241, 239, 238, 236, 234, 233, 231, 229, 227, 225, 223, 220, 218,
286
  216, 213, 211, 209, 207, 205, 203, 201, 199, 197, 195, 193, 191, 189, 187, 185,
287
  183, 180, 178, 176, 173, 171, 169, 166, 164, 161, 159, 156, 154, 151, 148, 146,
288
  143, 140, 138, 135, 132, 129, 126, 123, 120, 118, 115, 112, 108, 105, 102,  99,
289
   96,  95,  93,  91,  90,  88,  86,  85,  83,  82,  80,  79,  77,  76,  74,  73,
290
   72,  70,  69,  68,  67,  66,  64,  63,  62,  61,  60,  59,  58,  57,  56,  55,
291
   55,  54,  53,  52,  52,  51,  50,  50,  49,  48,  48,  47,  47,  46,  46,  46,
292
   45,  45,  45,  44,  44,  44,  44,  44,  44,  44,  43,  43,  43,  43,  44,  43,
293
   42,  42,  41,  40,  40,  39,  38,  38,  37,  36,  36,  35,  35,  34,  33,  33,
294
   32,  32,  31,  30,  30,  29,  29,  28,  28,  27,  26,  26,  25,  25,  24,  24,
295
   23,  23,  22,  22,  21,  21,  20,  20,  19,  19,  18,  18,  18,  17,  17,  16,
296
   16,  15,  15,  15,  14,  14,  13,  13,  13,  12,  12,  11,  11,  11,  10,  10,
297
   10,   9,   9,   9,   8,   8,   8,   7,   7,   7,   7,   6,   6,   6,   5,   5,
298
    5,   5,   4,   4,   4,   4,   4,   3,   3,   3,   3,   2,   2,   2,   2,   2,
299
    2,   1,   1,   1,   1,   1,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,
300
    0
301
};
302
303
static const unsigned char pk_shape2[PEAKSHAPEW+1] = {
304
  255, 254, 254, 254, 254, 254, 254, 254, 254, 254, 253, 253, 253, 253, 252, 252,
305
  252, 251, 251, 251, 250, 250, 249, 249, 248, 248, 247, 247, 246, 245, 245, 244,
306
  243, 243, 242, 241, 239, 237, 235, 233, 231, 229, 227, 225, 223, 221, 218, 216,
307
  213, 211, 208, 205, 203, 200, 197, 194, 191, 187, 184, 181, 178, 174, 171, 167,
308
  163, 160, 156, 152, 148, 144, 140, 136, 132, 127, 123, 119, 114, 110, 105, 100,
309
   96,  94,  91,  88,  86,  83,  81,  78,  76,  74,  71,  69,  66,  64,  62,  60,
310
   57,  55,  53,  51,  49,  47,  44,  42,  40,  38,  36,  34,  32,  30,  29,  27,
311
   25,  23,  21,  19,  18,  16,  14,  12,  11,   9,   7,   6,   4,   3,   1,   0,
312
    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
313
    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
314
    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
315
    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
316
    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
317
    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
318
    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
319
    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
320
    0
321
};
322
323
static const unsigned char *pk_shape;
324
325
void WavegenInit(int rate, int wavemult_fact)
326
1
{
327
1
  int ix;
328
1
  double x;
329
330
1
  if (wavemult_fact == 0)
331
1
    wavemult_fact = 60; // default
332
333
1
  wvoice = NULL;
334
1
  samplerate = rate;
335
1
  PHASE_INC_FACTOR = 0x8000000 / samplerate; // assumes pitch is Hz*32
336
1
  Flutter_inc = (64 * samplerate)/rate;
337
1
  samplecount = 0;
338
1
  nsamples = 0;
339
1
  wavephase = 0x7fffffff;
340
341
1
  wdata.amplitude = 32;
342
1
  wdata.amplitude_fmt = 100;
343
344
16
  for (ix = 0; ix < N_EMBEDDED_VALUES; ix++)
345
15
    embedded_value[ix] = embedded_default[ix];
346
347
  // set up window to generate a spread of harmonics from a
348
  // single peak for HF peaks
349
1
  wavemult_max = (samplerate * wavemult_fact)/(256 * 50);
350
1
  if (wavemult_max > N_WAVEMULT) wavemult_max = N_WAVEMULT;
351
352
1
  wavemult_offset = wavemult_max/2;
353
354
1
  if (samplerate != 22050) {
355
    // wavemult table has preset values for 22050 Hz, we only need to
356
    // recalculate them if we have a different sample rate
357
0
    for (ix = 0; ix < wavemult_max; ix++) {
358
0
      x = 127*(1.0 - cos((M_PI*2)*ix/wavemult_max));
359
0
      wavemult[ix] = (int)x;
360
0
    }
361
0
  }
362
363
1
  pk_shape = pk_shape2;
364
365
1
#if USE_KLATT
366
1
  KlattInit();
367
1
#endif
368
1
}
369
370
void WavegenFini(void)
371
0
{
372
0
#if USE_KLATT
373
0
  KlattFini();
374
0
#endif
375
0
}
376
377
int GetAmplitude(void)
378
12.7k
{
379
12.7k
  int amp;
380
381
  // normal, none, reduced, moderate, strong
382
12.7k
  static const unsigned char amp_emphasis[5] = { 16, 16, 10, 16, 22 };
383
384
12.7k
  amp = (embedded_value[EMBED_A])*55/100;
385
12.7k
  general_amplitude = amp * amp_emphasis[embedded_value[EMBED_F]] / 16;
386
12.7k
  return general_amplitude;
387
12.7k
}
388
389
static void WavegenSetEcho(void)
390
10.7k
{
391
10.7k
  if (wvoice == NULL)
392
0
    return;
393
394
10.7k
  int delay;
395
10.7k
  int amp;
396
397
10.7k
  voicing = wvoice->voicing;
398
10.7k
  delay = wvoice->echo_delay;
399
10.7k
  amp = wvoice->echo_amp;
400
401
10.7k
  if (delay >= N_ECHO_BUF)
402
0
    delay = N_ECHO_BUF-1;
403
10.7k
  if (amp > 100)
404
0
    amp = 100;
405
406
10.7k
  memset(echo_buf, 0, sizeof(echo_buf));
407
10.7k
  echo_tail = 0;
408
409
10.7k
  if (embedded_value[EMBED_H] > 0) {
410
    // set echo from an embedded command in the text
411
1.71k
    amp = embedded_value[EMBED_H];
412
1.71k
    delay = 130;
413
1.71k
  }
414
415
10.7k
  if (delay == 0)
416
9.03k
    amp = 0;
417
418
10.7k
  echo_head = (delay * samplerate)/1000;
419
10.7k
  echo_length = echo_head; // ensure completion of echo at the end of speech. Use 1 delay period?
420
10.7k
  if (amp == 0)
421
9.03k
    echo_length = 0;
422
10.7k
  if (amp > 20)
423
1.55k
    echo_length = echo_head * 2; // perhaps allow 2 echo periods if the echo is loud.
424
425
  // echo_amp units are 1/256ths of the amplitude of the original sound.
426
10.7k
  echo_amp = amp;
427
  // compensate (partially) for increase in amplitude due to echo
428
10.7k
  general_amplitude = GetAmplitude();
429
10.7k
  general_amplitude = ((general_amplitude * (500-amp))/500);
430
10.7k
}
431
432
int PeaksToHarmspect(wavegen_peaks_t *peaks, int pitch, int *htab, int control)
433
81.0M
{
434
81.0M
  if (wvoice == NULL)
435
0
    return 1;
436
437
  // Calculate the amplitude of each  harmonics from the formants
438
  // Only for formants 0 to 5
439
440
  // control 0=initial call, 1=every 64 cycles
441
442
  // pitch and freqs are Hz<<16
443
444
81.0M
  int f;
445
81.0M
  wavegen_peaks_t *p;
446
81.0M
  int fp;  // centre freq of peak
447
81.0M
  int fhi; // high freq of peak
448
81.0M
  int h;   // harmonic number
449
81.0M
  int pk;
450
81.0M
  int hmax;
451
81.0M
  int hmax_samplerate; // highest harmonic allowed for the samplerate
452
81.0M
  int x;
453
81.0M
  int h1;
454
455
  // initialise as much of *out as we will need
456
81.0M
  hmax = (peaks[wvoice->n_harmonic_peaks].freq + peaks[wvoice->n_harmonic_peaks].right)/pitch;
457
81.0M
  if (hmax >= MAX_HARMONIC)
458
0
    hmax = MAX_HARMONIC-1;
459
460
  // restrict highest harmonic to half the samplerate
461
81.0M
  hmax_samplerate = (((samplerate * 19)/40) << 16)/pitch; // only 95% of Nyquist freq
462
463
81.0M
  if (hmax > hmax_samplerate)
464
0
    hmax = hmax_samplerate;
465
466
3.82G
  for (h = 0; h <= hmax; h++)
467
3.74G
    htab[h] = 0;
468
469
567M
  for (pk = 0; pk <= wvoice->n_harmonic_peaks; pk++) {
470
486M
    p = &peaks[pk];
471
486M
    if ((p->height == 0) || (fp = p->freq) == 0)
472
4.03M
      continue;
473
474
482M
    fhi = p->freq + p->right;
475
482M
    h = ((p->freq - p->left) / pitch) + 1;
476
482M
    if (h <= 0) h = 1;
477
478
2.94G
    for (f = pitch*h; f < fp; f += pitch)
479
2.46G
      htab[h++] += pk_shape[(fp-f)/(p->left>>8)] * p->height;
480
3.51G
    for (; f < fhi; f += pitch)
481
3.03G
      htab[h++] += pk_shape[(f-fp)/(p->right>>8)] * p->height;
482
482M
  }
483
484
81.0M
  int y;
485
81.0M
  int h2;
486
  // increase bass
487
81.0M
  y = peaks[1].height * 10; // addition as a multiple of 1/256s
488
81.0M
  h2 = (1000<<16)/pitch; // decrease until 1000Hz
489
81.0M
  if (h2 > 0) {
490
81.0M
    x = y/h2;
491
81.0M
    h = 1;
492
891M
    while (y > 0) {
493
810M
      htab[h++] += y;
494
810M
      y -= x;
495
810M
    }
496
81.0M
  }
497
498
  // find the nearest harmonic for HF peaks where we don't use shape
499
324M
  for (; pk < N_PEAKS; pk++) {
500
243M
    x = peaks[pk].height >> 14;
501
243M
    peak_height[pk] = (x * x * 5)/2;
502
503
    // find the nearest harmonic for HF peaks where we don't use shape
504
243M
    if (control == 0) {
505
      // set this initially, but make changes only at the quiet point
506
4.14M
      peak_harmonic[pk] = peaks[pk].freq / pitch;
507
4.14M
    }
508
    // only use harmonics up to half the samplerate
509
243M
    if (peak_harmonic[pk] >= hmax_samplerate)
510
22.5k
      peak_height[pk] = 0;
511
243M
  }
512
513
  // convert from the square-rooted values
514
81.0M
  f = 0;
515
3.82G
  for (h = 0; h <= hmax; h++, f += pitch) {
516
3.74G
    x = htab[h] >> 15;
517
3.74G
    htab[h] = (x * x) >> 8;
518
519
3.74G
    int ix;
520
3.74G
    if ((ix = (f >> 19)) < N_TONE_ADJUST)
521
3.74G
      htab[h] = (htab[h] * wvoice->tone_adjust[ix]) >> 13; // index tone_adjust with Hz/8
522
3.74G
  }
523
524
  // adjust the amplitude of the first harmonic, affects tonal quality
525
81.0M
  h1 = htab[1] * option_harmonic1;
526
81.0M
  htab[1] = h1/8;
527
528
  // calc intermediate increments of LF harmonics
529
81.0M
  if (control & 1) {
530
2.38G
    for (h = 1; h < N_LOWHARM; h++)
531
2.30G
      harm_inc[h] = (htab[h] - harmspect[h]) >> 3;
532
79.6M
  }
533
534
81.0M
  return hmax; // highest harmonic number
535
81.0M
}
536
537
static void AdvanceParameters(void)
538
78.2M
{
539
  // Called every 64 samples to increment the formant freq, height, and widths
540
78.2M
  if (wvoice == NULL)
541
0
    return;
542
543
78.2M
  int x = 0;
544
78.2M
  int ix;
545
78.2M
  static int Flutter_ix = 0;
546
547
  // advance the pitch
548
78.2M
  wdata.pitch_ix += wdata.pitch_inc;
549
78.2M
  if ((ix = wdata.pitch_ix>>8) > 127) ix = 127;
550
78.2M
  if (wdata.pitch_env) x = wdata.pitch_env[ix] * wdata.pitch_range;
551
78.2M
  wdata.pitch = (x>>8) + wdata.pitch_base;
552
  
553
  
554
555
78.2M
  amp_ix += amp_inc;
556
557
  /* add pitch flutter */
558
78.2M
  if (Flutter_ix >= (N_FLUTTER*64))
559
212k
    Flutter_ix = 0;
560
78.2M
  x = ((int)(Flutter_tab[Flutter_ix >> 6])-0x80) * flutter_amp;
561
78.2M
  Flutter_ix += Flutter_inc;
562
78.2M
  wdata.pitch += x;
563
  
564
78.2M
  if(const_f0)
565
0
    wdata.pitch = (const_f0<<12);
566
567
78.2M
  if (wdata.pitch < 102400)
568
0
    wdata.pitch = 102400; // min pitch, 25 Hz  (25 << 12)
569
570
78.2M
  if (samplecount == samplecount_start)
571
9.66M
    return;
572
573
480M
  for (ix = 0; ix <= wvoice->n_harmonic_peaks; ix++) {
574
411M
    peaks[ix].freq1 += peaks[ix].freq_inc;
575
411M
    peaks[ix].freq = (int)peaks[ix].freq1;
576
411M
    peaks[ix].height1 += peaks[ix].height_inc;
577
411M
    if ((peaks[ix].height = (int)peaks[ix].height1) < 0)
578
1.67M
      peaks[ix].height = 0;
579
411M
    peaks[ix].left1 += peaks[ix].left_inc;
580
411M
    peaks[ix].left = (int)peaks[ix].left1;
581
411M
    if (ix < 3) {
582
205M
      peaks[ix].right1 += peaks[ix].right_inc;
583
205M
      peaks[ix].right = (int)peaks[ix].right1;
584
205M
    } else
585
205M
      peaks[ix].right = peaks[ix].left;
586
411M
  }
587
205M
  for (; ix < 8; ix++) {
588
    // formants 6,7,8 don't have a width parameter
589
137M
    if (ix < 7) {
590
68.6M
      peaks[ix].freq1 += peaks[ix].freq_inc;
591
68.6M
      peaks[ix].freq = (int)peaks[ix].freq1;
592
68.6M
    }
593
137M
    peaks[ix].height1 += peaks[ix].height_inc;
594
137M
    if ((peaks[ix].height = (int)peaks[ix].height1) < 0)
595
565k
      peaks[ix].height = 0;
596
137M
  }
597
68.6M
}
598
599
static double resonator(RESONATOR *r, double input)
600
39.1M
{
601
39.1M
  double x;
602
603
39.1M
  x = r->a * input + r->b * r->x1 + r->c * r->x2;
604
39.1M
  r->x2 = r->x1;
605
39.1M
  r->x1 = x;
606
607
39.1M
  return x;
608
39.1M
}
609
610
static void setresonator(RESONATOR *rp, int freq, int bwidth, int init)
611
697k
{
612
  // freq    Frequency of resonator in Hz
613
  // bwidth  Bandwidth of resonator in Hz
614
  // init    Initialize internal data
615
616
697k
  double x;
617
697k
  double arg;
618
619
697k
  if (init) {
620
83.4k
    rp->x1 = 0;
621
83.4k
    rp->x2 = 0;
622
83.4k
  }
623
624
697k
  arg = minus_pi_t * bwidth;
625
697k
  x = exp(arg);
626
627
697k
  rp->c = -(x * x);
628
629
697k
  arg = two_pi_t * freq;
630
697k
  rp->b = x * cos(arg) * 2.0;
631
632
697k
  rp->a = 1.0 - rp->b - rp->c;
633
697k
}
634
635
void InitBreath(void)
636
9.27k
{
637
9.27k
  int ix;
638
639
9.27k
  minus_pi_t = -M_PI / samplerate;
640
9.27k
  two_pi_t = -2.0 * minus_pi_t;
641
642
92.7k
  for (ix = 0; ix < N_PEAKS; ix++)
643
83.4k
    setresonator(&rbreath[ix], 2000, 200, 1);
644
9.27k
}
645
646
static void SetBreath(void)
647
79.6M
{
648
79.6M
  int pk;
649
650
79.6M
  if (wvoice == NULL || wvoice->breath[0] == 0)
651
79.5M
    return;
652
653
921k
  for (pk = 1; pk < N_PEAKS; pk++) {
654
819k
    if (wvoice->breath[pk] != 0) {
655
      // breath[0] indicates that some breath formants are needed
656
      // set the freq from the current synthesis formant and the width from the voice data
657
614k
      setresonator(&rbreath[pk], peaks[pk].freq >> 16, wvoice->breathw[pk], 0);
658
614k
    }
659
819k
  }
660
102k
}
661
662
static int ApplyBreath(void)
663
6.52M
{
664
6.52M
  if (wvoice == NULL)
665
0
    return 0;
666
667
6.52M
  int value = 0;
668
6.52M
  int noise;
669
6.52M
  int ix;
670
671
  // use two random numbers, for alternate formants
672
6.52M
  noise = espeak_rand(-0x2000, 0x1fff);
673
674
58.7M
  for (ix = 1; ix < N_PEAKS; ix++) {
675
52.2M
    int amp;
676
52.2M
    if ((amp = wvoice->breath[ix]) != 0) {
677
39.1M
      amp *= (peaks[ix].height >> 14);
678
39.1M
      value += (int)resonator(&rbreath[ix], noise) * amp;
679
39.1M
    }
680
52.2M
  }
681
6.52M
  return value;
682
6.52M
}
683
684
static int Wavegen(int length, int modulation, bool resume, frame_t *fr1, frame_t *fr2, voice_t *wvoice)
685
14.8M
{
686
14.8M
  if (resume == false)
687
11.0M
    SetSynth(length, modulation, fr1, fr2, wvoice);
688
689
14.8M
  if (wvoice == NULL)
690
0
    return 0;
691
692
14.8M
  unsigned short waveph;
693
14.8M
  unsigned short theta;
694
14.8M
  int total;
695
14.8M
  int h;
696
14.8M
  int ix;
697
14.8M
  int z, z1, z2;
698
14.8M
  int echo;
699
14.8M
  int ov;
700
14.8M
  static int maxh, maxh2;
701
14.8M
  int pk;
702
14.8M
  signed char c;
703
14.8M
  int sample;
704
14.8M
  int amp;
705
14.8M
  int modn_amp = 1, modn_period;
706
14.8M
  static int agc = 256;
707
14.8M
  static int h_switch_sign = 0;
708
14.8M
  static int cycle_count = 0;
709
14.8M
  static int amplitude2 = 0; // adjusted for pitch
710
711
  // continue until the output buffer is full, or
712
  // the required number of samples have been produced
713
714
5.06G
  for (;;) {
715
5.06G
    if ((end_wave == 0) && (samplecount == nsamples))
716
9.66M
      return 0;
717
718
5.05G
    if ((samplecount & 0x3f) == 0) {
719
      // every 64 samples, adjust the parameters
720
79.6M
      if (samplecount == 0) {
721
1.38M
        hswitch = 0;
722
1.38M
        harmspect = hspect[0];
723
1.38M
        maxh2 = PeaksToHarmspect(peaks, wdata.pitch<<4, hspect[0], 0);
724
725
        // adjust amplitude to compensate for fewer harmonics at higher pitch
726
1.38M
        amplitude2 = (wdata.amplitude * (wdata.pitch >> 8) * wdata.amplitude_fmt)/(10000 << 3);
727
728
        // switch sign of harmonics above about 900Hz, to reduce max peak amplitude
729
1.38M
        h_switch_sign = 890 / (wdata.pitch >> 12);
730
1.38M
      } else
731
78.2M
        AdvanceParameters();
732
733
      // pitch is Hz<<12
734
79.6M
      phaseinc = (wdata.pitch>>7) * PHASE_INC_FACTOR;
735
79.6M
      cycle_samples = samplerate/(wdata.pitch >> 12); // sr/(pitch*2)
736
79.6M
      hf_factor = wdata.pitch >> 11;
737
738
79.6M
      maxh = maxh2;
739
79.6M
      harmspect = hspect[hswitch];
740
79.6M
      hswitch ^= 1;
741
79.6M
      maxh2 = PeaksToHarmspect(peaks, wdata.pitch<<4, hspect[hswitch], 1);
742
743
79.6M
      SetBreath();
744
4.97G
    } else if ((samplecount & 0x07) == 0) {
745
16.5G
      for (h = 1; h < N_LOWHARM && h <= maxh2 && h <= maxh; h++)
746
15.9G
        harmspect[h] += harm_inc[h];
747
748
      // bring automatic gain control back towards unity
749
552M
      if (agc < 256) agc++;
750
552M
    }
751
752
5.05G
    samplecount++;
753
754
5.05G
    if (wavephase > 0) {
755
2.52G
      wavephase += phaseinc;
756
2.52G
      if (wavephase < 0) {
757
        // sign has changed, reached a quiet point in the waveform
758
24.6M
        cbytes = wavemult_offset - (cycle_samples)/2;
759
24.6M
        if (samplecount > nsamples)
760
1.38M
          return 0;
761
762
23.2M
        cycle_count++;
763
764
93.0M
        for (pk = wvoice->n_harmonic_peaks+1; pk < N_PEAKS; pk++) {
765
          // find the nearest harmonic for HF peaks where we don't use shape
766
69.8M
          peak_harmonic[pk] = ((peaks[pk].freq / (wdata.pitch*8)) + 1) / 2;
767
69.8M
        }
768
769
        // adjust amplitude to compensate for fewer harmonics at higher pitch
770
23.2M
        amplitude2 = (wdata.amplitude * (wdata.pitch >> 8) * wdata.amplitude_fmt)/(10000 << 3);
771
772
23.2M
        if (glottal_flag > 0) {
773
9.21k
          if (glottal_flag == 3) {
774
2.74k
            if ((nsamples-samplecount) < (cycle_samples*2)) {
775
              // Vowel before glottal-stop.
776
              // This is the start of the penultimate cycle, reduce its amplitude
777
1.34k
              glottal_flag = 2;
778
1.34k
              amplitude2 = (amplitude2 *  glottal_reduce)/256;
779
1.34k
            }
780
6.47k
          } else if (glottal_flag == 4) {
781
            // Vowel following a glottal-stop.
782
            // This is the start of the second cycle, reduce its amplitude
783
2.13k
            glottal_flag = 2;
784
2.13k
            amplitude2 = (amplitude2 * glottal_reduce)/256;
785
2.13k
          } else
786
4.33k
            glottal_flag--;
787
9.21k
        }
788
789
23.2M
        if (amplitude_env != NULL) {
790
          // amplitude envelope is only used for creaky voice effect on certain vowels/tones
791
60.8k
          if ((ix = amp_ix>>8) > 127) ix = 127;
792
60.8k
          amp = amplitude_env[ix];
793
60.8k
          amplitude2 = (amplitude2 * amp)/128;
794
60.8k
        }
795
796
        // introduce roughness into the sound by reducing the amplitude of
797
23.2M
        modn_period = 0;
798
23.2M
        if (voice->roughness < N_ROUGHNESS) {
799
23.2M
          modn_period = modulation_tab[voice->roughness][modulation_type];
800
23.2M
          modn_amp = modn_period & 0xf;
801
23.2M
          modn_period = modn_period >> 4;
802
23.2M
        }
803
804
23.2M
        if (modn_period != 0) {
805
6.93M
          if (modn_period == 0xf) {
806
            // just once */
807
11.8k
            amplitude2 = (amplitude2 * modn_amp)/16;
808
11.8k
            modulation_type = 0;
809
6.92M
          } else {
810
            // reduce amplitude every [modn_period} cycles
811
6.92M
            if ((cycle_count % modn_period) == 0)
812
3.35M
              amplitude2 = (amplitude2 * modn_amp)/16;
813
6.92M
          }
814
6.93M
        }
815
23.2M
      }
816
2.52G
    } else
817
2.52G
      wavephase += phaseinc;
818
5.04G
    waveph = (unsigned short)(wavephase >> 16);
819
5.04G
    total = 0;
820
821
    // apply HF peaks, formants 6,7,8
822
    // add a single harmonic and then spread this my multiplying by a
823
    // window.  This is to reduce the processing power needed to add the
824
    // higher frequence harmonics.
825
5.04G
    cbytes++;
826
5.04G
    if (cbytes >= 0 && cbytes < wavemult_max) {
827
9.63G
      for (pk = wvoice->n_harmonic_peaks+1; pk < N_PEAKS; pk++) {
828
7.22G
        theta = peak_harmonic[pk] * waveph;
829
7.22G
        total += (long)sin_tab[theta >> 5] * peak_height[pk];
830
7.22G
      }
831
832
      // spread the peaks by multiplying by a window
833
2.40G
      total = (long)(total / hf_factor) * wavemult[cbytes];
834
2.40G
    }
835
836
    // apply main peaks, formants 0 to 5
837
5.04G
    theta = waveph;
838
839
47.5G
    for (h = 1; h <= h_switch_sign; h++) {
840
42.4G
      total += ((int)sin_tab[theta >> 5] * harmspect[h]);
841
42.4G
      theta += waveph;
842
42.4G
    }
843
190G
    while (h <= maxh) {
844
185G
      total -= ((int)sin_tab[theta >> 5] * harmspect[h]);
845
185G
      theta += waveph;
846
185G
      h++;
847
185G
    }
848
849
5.04G
    if (voicing != 64)
850
2.71M
      total = (total >> 6) * voicing;
851
852
5.04G
    if (wvoice->breath[0])
853
6.52M
      total +=  ApplyBreath();
854
855
    // mix with sampled wave if required
856
5.04G
    z2 = 0;
857
5.04G
    if (wdata.mix_wavefile_ix < wdata.n_mix_wavefile) {
858
434M
      if (wdata.mix_wave_scale == 0) {
859
        // a 16 bit sample
860
0
        c = wdata.mix_wavefile[wdata.mix_wavefile_ix+wdata.mix_wavefile_offset+1];
861
0
        sample = wdata.mix_wavefile[wdata.mix_wavefile_ix+wdata.mix_wavefile_offset] + (c * 256);
862
0
        wdata.mix_wavefile_ix += 2;
863
434M
      } else {
864
        // a 8 bit sample, scaled
865
434M
        sample = (signed char)wdata.mix_wavefile[wdata.mix_wavefile_offset+wdata.mix_wavefile_ix++] * wdata.mix_wave_scale;
866
434M
      }
867
434M
      z2 = (sample * wdata.amplitude_v) >> 10;
868
434M
      z2 = (z2 * wdata.mix_wave_amp)/32;
869
870
434M
      if ((wdata.mix_wavefile_ix + wdata.mix_wavefile_offset) >= wdata.mix_wavefile_max)  // reached the end of available WAV data
871
77.6k
        wdata.mix_wavefile_offset -= (wdata.mix_wavefile_max*3)/4;
872
434M
    }
873
874
5.04G
    z1 = z2 + (((total>>8) * amplitude2) >> 13);
875
876
5.04G
    echo = (echo_buf[echo_tail++] * echo_amp);
877
5.04G
    z1 += echo >> 8;
878
5.04G
    if (echo_tail >= N_ECHO_BUF)
879
915k
      echo_tail = 0;
880
881
5.04G
    z = (z1 * agc) >> 8;
882
883
    // check for overflow, 16bit signed samples
884
5.04G
    if (z >= 32768) {
885
171k
      ov = 8388608/z1 - 1;      // 8388608 is 2^23, i.e. max value * 256
886
171k
      if (ov < agc) agc = ov;    // set agc to number of 1/256ths to multiply the sample by
887
171k
      z = (z1 * agc) >> 8;      // reduce sample by agc value to prevent overflow
888
5.04G
    } else if (z <= -32768) {
889
71.9k
      ov = -8388608/z1 - 1;
890
71.9k
      if (ov < agc) agc = ov;
891
71.9k
      z = (z1 * agc) >> 8;
892
71.9k
    }
893
5.04G
    *out_ptr++ = z;
894
5.04G
    *out_ptr++ = z >> 8;
895
5.04G
    if(output_hooks && output_hooks->outputVoiced) output_hooks->outputVoiced(z);
896
897
5.04G
    echo_buf[echo_head++] = z;
898
5.04G
    if (echo_head >= N_ECHO_BUF)
899
915k
      echo_head = 0;
900
901
5.04G
    if (out_ptr + 2 > out_end)
902
3.80M
      return 1;
903
5.04G
  }
904
14.8M
}
905
906
static int PlaySilence(int length, bool resume)
907
2.89M
{
908
2.89M
  static int n_samples;
909
910
2.89M
  nsamples = 0;
911
2.89M
  samplecount = 0;
912
2.89M
  wavephase = 0x7fffffff;
913
914
2.89M
  if (length == 0)
915
437k
    return 0;
916
917
2.45M
  if (resume == false)
918
1.76M
    n_samples = length;
919
920
2.45M
  int value = 0;
921
951M
  while (n_samples-- > 0) {
922
949M
    value = (echo_buf[echo_tail++] * echo_amp) >> 8;
923
924
949M
    if (echo_tail >= N_ECHO_BUF)
925
171k
      echo_tail = 0;
926
927
949M
    *out_ptr++ = value;
928
949M
    *out_ptr++ = value >> 8;
929
949M
    if(output_hooks && output_hooks->outputSilence) output_hooks->outputSilence(value);
930
931
949M
    echo_buf[echo_head++] = value;
932
949M
    if (echo_head >= N_ECHO_BUF)
933
171k
      echo_head = 0;
934
935
949M
    if (out_ptr + 2 > out_end)
936
699k
      return 1;
937
949M
  }
938
1.75M
  return 0;
939
2.45M
}
940
941
static int PlayWave(int length, bool resume, unsigned char *data, int scale, int amp)
942
1.93M
{
943
1.93M
  static int n_samples;
944
1.93M
  static int ix = 0;
945
1.93M
  int value;
946
1.93M
  signed char c;
947
948
1.93M
  if (resume == false) {
949
1.21M
    n_samples = length;
950
1.21M
    ix = 0;
951
1.21M
  }
952
953
1.93M
  nsamples = 0;
954
1.93M
  samplecount = 0;
955
956
963M
  while (n_samples-- > 0) {
957
962M
    if (scale == 0) {
958
      // 16 bits data
959
0
      c = data[ix+1];
960
0
      value = data[ix] + (c * 256);
961
0
      ix += 2;
962
962M
    } else {
963
      // 8 bit data, shift by the specified scale factor
964
962M
      value = (signed char)data[ix++] * scale;
965
962M
    }
966
962M
    value *= (consonant_amp * general_amplitude); // reduce strength of consonant
967
962M
    value = value >> 10;
968
962M
    value = (value * amp)/32;
969
970
962M
    value += ((echo_buf[echo_tail++] * echo_amp) >> 8);
971
972
962M
    if (value > 32767)
973
0
      value = 32767;
974
962M
    else if (value < -32768)
975
3
      value = -32768;
976
977
962M
    if (echo_tail >= N_ECHO_BUF)
978
174k
      echo_tail = 0;
979
980
962M
    out_ptr[0] = value;
981
962M
    out_ptr[1] = value >> 8;
982
962M
    if(output_hooks && output_hooks->outputUnvoiced) output_hooks->outputUnvoiced(value);
983
962M
    out_ptr += 2;
984
985
962M
    echo_buf[echo_head++] = (value*3)/4;
986
962M
    if (echo_head >= N_ECHO_BUF)
987
174k
      echo_head = 0;
988
989
962M
    if (out_ptr + 2 > out_end)
990
721k
      return 1;
991
962M
  }
992
1.21M
  return 0;
993
1.93M
}
994
995
static int SetWithRange0(int value, int max)
996
31.4k
{
997
31.4k
  if (value < 0)
998
857
    return 0;
999
30.5k
  if (value > max)
1000
3.34k
    return max;
1001
27.2k
  return value;
1002
30.5k
}
1003
1004
static void SetPitchFormants(void)
1005
10.6k
{
1006
10.6k
  if (wvoice == NULL)
1007
0
    return;
1008
1009
10.6k
  int ix;
1010
10.6k
  int factor = 256;
1011
10.6k
  int pitch_value;
1012
1013
  // adjust formants to give better results for a different voice pitch
1014
10.6k
  if ((pitch_value = embedded_value[EMBED_P]) > MAX_PITCH_VALUE)
1015
199
    pitch_value = MAX_PITCH_VALUE;
1016
1017
10.6k
  if (pitch_value > 50) {
1018
    // only adjust if the pitch is higher than normal
1019
199
    factor = 256 + (25 * (pitch_value - 50))/50;
1020
199
  }
1021
1022
74.4k
  for (ix = 0; ix <= 5; ix++)
1023
63.8k
    wvoice->freq[ix] = (wvoice->freq2[ix] * factor)/256;
1024
1025
10.6k
  factor = embedded_value[EMBED_T]*3;
1026
10.6k
  wvoice->height[0] = (wvoice->height2[0] * (256 - factor*2))/256;
1027
10.6k
  wvoice->height[1] = (wvoice->height2[1] * (256 - factor))/256;
1028
10.6k
}
1029
1030
void SetEmbedded(int control, int value)
1031
31.4k
{
1032
  // there was an embedded command in the text at this point
1033
31.4k
  int sign = 0;
1034
31.4k
  int command;
1035
1036
31.4k
  command = control & 0x1f;
1037
31.4k
  if ((control & 0x60) == 0x60)
1038
4.75k
    sign = -1;
1039
26.6k
  else if ((control & 0x60) == 0x40)
1040
2.58k
    sign = 1;
1041
1042
31.4k
  if (command < N_EMBEDDED_VALUES) {
1043
31.4k
    if (sign == 0)
1044
24.0k
      embedded_value[command] = value;
1045
7.33k
    else
1046
7.33k
      embedded_value[command] += (value * sign);
1047
31.4k
    embedded_value[command] = SetWithRange0(embedded_value[command], embedded_max[command]);
1048
31.4k
  }
1049
1050
31.4k
  switch (command)
1051
31.4k
  {
1052
605
  case EMBED_T:
1053
605
    WavegenSetEcho(); // and drop through to case P
1054
1.36k
  case EMBED_P:
1055
1.36k
    SetPitchFormants();
1056
1.36k
    break;
1057
432
  case EMBED_A: // amplitude
1058
432
    general_amplitude = GetAmplitude();
1059
432
    break;
1060
1.52k
  case EMBED_F: // emphasis
1061
1.52k
    general_amplitude = GetAmplitude();
1062
1.52k
    break;
1063
882
  case EMBED_H:
1064
882
    WavegenSetEcho();
1065
882
    break;
1066
31.4k
  }
1067
31.4k
}
1068
1069
void WavegenSetVoice(voice_t *v)
1070
9.27k
{
1071
9.27k
  static voice_t v2;
1072
1073
9.27k
  memcpy(&v2, v, sizeof(v2));
1074
9.27k
  wvoice = &v2;
1075
1076
9.27k
  if (v->peak_shape == 0)
1077
9.27k
    pk_shape = pk_shape1;
1078
0
  else
1079
0
    pk_shape = pk_shape2;
1080
1081
9.27k
  consonant_amp = (v->consonant_amp * 26) /100;
1082
9.27k
  if (samplerate <= 11000) {
1083
0
    consonant_amp = consonant_amp*2; // emphasize consonants at low sample rates
1084
0
    option_harmonic1 = 6;
1085
0
  }
1086
9.27k
  WavegenSetEcho();
1087
9.27k
  SetPitchFormants();
1088
9.27k
  MarkerEvent(espeakEVENT_SAMPLERATE, 0, wvoice->samplerate, 0, out_ptr);
1089
9.27k
}
1090
1091
static void SetAmplitude(int length, unsigned char *amp_env, int value)
1092
3.16M
{
1093
3.16M
  if (wvoice == NULL)
1094
0
    return;
1095
1096
3.16M
  amp_ix = 0;
1097
3.16M
  if (length == 0)
1098
285k
    amp_inc = 0;
1099
2.87M
  else
1100
2.87M
    amp_inc = (256 * ENV_LEN * STEPSIZE)/length;
1101
1102
3.16M
  wdata.amplitude = (value * general_amplitude)/16;
1103
3.16M
  wdata.amplitude_v = (wdata.amplitude * wvoice->consonant_ampv * 15)/100; // for wave mixed with voiced sounds
1104
1105
3.16M
  amplitude_env = amp_env;
1106
3.16M
}
1107
1108
void SetPitch2(voice_t *voice, int pitch1, int pitch2, int *pitch_base, int *pitch_range)
1109
3.16M
{
1110
3.16M
  int base;
1111
3.16M
  int range;
1112
3.16M
  int pitch_value;
1113
1114
3.16M
  if (pitch1 > pitch2) {
1115
11.8k
    int x;
1116
11.8k
    x = pitch1; // swap values
1117
11.8k
    pitch1 = pitch2;
1118
11.8k
    pitch2 = x;
1119
11.8k
  }
1120
1121
3.16M
  if ((pitch_value = embedded_value[EMBED_P]) > MAX_PITCH_VALUE)
1122
101k
    pitch_value = MAX_PITCH_VALUE;
1123
3.16M
  pitch_value -= embedded_value[EMBED_T]; // adjust tone for announcing punctuation
1124
3.16M
  if (pitch_value < 0)
1125
24.7k
    pitch_value = 0;
1126
1127
3.16M
  base = (voice->pitch_base * pitch_adjust_tab[pitch_value])/128;
1128
3.16M
  range =  (voice->pitch_range * embedded_value[EMBED_R])/50;
1129
1130
  // compensate for change in pitch when the range is narrowed or widened
1131
3.16M
  base -= (range - voice->pitch_range)*18;
1132
1133
3.16M
  *pitch_base = base + (pitch1 * range)/2;
1134
3.16M
  *pitch_range = base + (pitch2 * range)/2 - *pitch_base;
1135
3.16M
}
1136
1137
static void SetPitch(int length, unsigned char *env, int pitch1, int pitch2)
1138
3.16M
{
1139
3.16M
  if (wvoice == NULL)
1140
0
    return;
1141
1142
  // length in samples
1143
1144
3.16M
  if ((wdata.pitch_env = env) == NULL)
1145
0
    wdata.pitch_env = env_fall; // default
1146
1147
3.16M
  wdata.pitch_ix = 0;
1148
3.16M
  if (length == 0)
1149
2.39k
    wdata.pitch_inc = 0;
1150
3.16M
  else
1151
3.16M
    wdata.pitch_inc = (256 * ENV_LEN * STEPSIZE)/length;
1152
1153
3.16M
  SetPitch2(wvoice, pitch1, pitch2, &wdata.pitch_base, &wdata.pitch_range);
1154
  // set initial pitch
1155
3.16M
  wdata.pitch = ((wdata.pitch_env[0] * wdata.pitch_range) >>8) + wdata.pitch_base; // Hz << 12
1156
1157
3.16M
  flutter_amp = wvoice->flutter;
1158
3.16M
}
1159
1160
static void SetSynth(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t *v)
1161
11.0M
{
1162
11.0M
  if (wvoice == NULL || v == NULL)
1163
0
    return;
1164
1165
11.0M
  int ix;
1166
11.0M
  double next;
1167
11.0M
  int length2;
1168
11.0M
  int length4;
1169
11.0M
  int qix;
1170
11.0M
  static const int glottal_reduce_tab1[4] = { 0x30, 0x30, 0x40, 0x50 }; // vowel before [?], amp * 1/256
1171
11.0M
  static const int glottal_reduce_tab2[4] = { 0x90, 0xa0, 0xb0, 0xc0 }; // vowel after [?], amp * 1/256
1172
1173
11.0M
  end_wave = 1;
1174
1175
  // any additional information in the param1 ?
1176
11.0M
  modulation_type = modn & 0xff;
1177
1178
11.0M
  glottal_flag = 0;
1179
11.0M
  if (modn & 0x400) {
1180
1.46k
    glottal_flag = 3; // before a glottal stop
1181
1.46k
    glottal_reduce = glottal_reduce_tab1[(modn >> 8) & 3];
1182
1.46k
  }
1183
11.0M
  if (modn & 0x800) {
1184
2.13k
    glottal_flag = 4; // after a glottal stop
1185
2.13k
    glottal_reduce = glottal_reduce_tab2[(modn >> 8) & 3];
1186
2.13k
  }
1187
1188
16.2M
  for (qix = wcmdq_head+1;; qix++) {
1189
16.2M
    if (qix >= N_WCMDQ) qix = 0;
1190
16.2M
    if (qix == wcmdq_tail) break;
1191
1192
16.2M
    int cmd = wcmdq[qix][0];
1193
16.2M
    if (cmd == WCMD_SPECT) {
1194
9.66M
      end_wave = 0; // next wave generation is from another spectrum
1195
9.66M
      break;
1196
9.66M
    }
1197
6.56M
    if ((cmd == WCMD_WAVE) || (cmd == WCMD_PAUSE))
1198
1.38M
      break; // next is not from spectrum, so continue until end of wave cycle
1199
6.56M
  }
1200
1201
  // round the length to a multiple of the stepsize
1202
11.0M
  length2 = (length + STEPSIZE/2) & ~0x3f;
1203
11.0M
  if (length2 == 0)
1204
118k
    length2 = STEPSIZE;
1205
1206
  // add this length to any left over from the previous synth
1207
11.0M
  samplecount_start = samplecount;
1208
11.0M
  nsamples += length2;
1209
1210
11.0M
  length4 = length2/4;
1211
1212
11.0M
  peaks[7].freq = (7800  * v->freq[7] + v->freqadd[7]*256) << 8;
1213
11.0M
  peaks[8].freq = (9000  * v->freq[8] + v->freqadd[8]*256) << 8;
1214
1215
99.4M
  for (ix = 0; ix < 8; ix++) {
1216
88.3M
    if (ix < 7) {
1217
77.3M
      peaks[ix].freq1 = (fr1->ffreq[ix] * v->freq[ix] + v->freqadd[ix]*256) << 8;
1218
77.3M
      peaks[ix].freq = (int)peaks[ix].freq1;
1219
77.3M
      next = (fr2->ffreq[ix] * v->freq[ix] + v->freqadd[ix]*256) << 8;
1220
77.3M
      peaks[ix].freq_inc =  ((next - peaks[ix].freq1) * (STEPSIZE/4)) / length4; // lower headroom for fixed point math
1221
77.3M
    }
1222
1223
88.3M
    peaks[ix].height1 = (fr1->fheight[ix] * v->height[ix]) << 6;
1224
88.3M
    peaks[ix].height = (int)peaks[ix].height1;
1225
88.3M
    next = (fr2->fheight[ix] * v->height[ix]) << 6;
1226
88.3M
    peaks[ix].height_inc =  ((next - peaks[ix].height1) * STEPSIZE) / length2;
1227
1228
88.3M
    if ((ix <= 5) && (ix <= wvoice->n_harmonic_peaks)) {
1229
66.2M
      peaks[ix].left1 = (fr1->fwidth[ix] * v->width[ix]) << 10;
1230
66.2M
      peaks[ix].left = (int)peaks[ix].left1;
1231
66.2M
      next = (fr2->fwidth[ix] * v->width[ix]) << 10;
1232
66.2M
      peaks[ix].left_inc =  ((next - peaks[ix].left1) * STEPSIZE) / length2;
1233
1234
66.2M
      if (ix < 3) {
1235
33.1M
        peaks[ix].right1 = (fr1->fright[ix] * v->width[ix]) << 10;
1236
33.1M
        peaks[ix].right = (int)peaks[ix].right1;
1237
33.1M
        next = (fr2->fright[ix] * v->width[ix]) << 10;
1238
33.1M
        peaks[ix].right_inc = ((next - peaks[ix].right1) * STEPSIZE) / length2;
1239
33.1M
      } else
1240
33.1M
        peaks[ix].right = peaks[ix].left;
1241
66.2M
    }
1242
88.3M
  }
1243
11.0M
}
1244
1245
void Write4Bytes(FILE *f, int value)
1246
0
{
1247
  // Write 4 bytes to a file, least significant first
1248
0
  int ix;
1249
1250
0
  for (ix = 0; ix < 4; ix++) {
1251
0
    fputc(value & 0xff, f);
1252
0
    value = value >> 8;
1253
0
  }
1254
0
}
1255
1256
static int WavegenFill2(void)
1257
5.29M
{
1258
  // Pick up next wavegen commands from the queue
1259
  // return: 0  output buffer has been filled
1260
  // return: 1  input command queue is now empty
1261
5.29M
  intptr_t *q;
1262
5.29M
  int length;
1263
5.29M
  int result;
1264
5.29M
  int marker_type;
1265
5.29M
  static bool resume = false;
1266
5.29M
  static int echo_complete = 0;
1267
1268
5.29M
  if (wdata.pitch < 102400)
1269
1
    wdata.pitch = 102400; // min pitch, 25 Hz  (25 << 12)
1270
1271
32.9M
  while (out_ptr < out_end) {
1272
27.6M
    if (WcmdqUsed() <= 0) {
1273
75.8k
      if (echo_complete > 0) {
1274
        // continue to play silence until echo is completed
1275
9.13k
        resume = PlaySilence(echo_complete, resume);
1276
9.13k
        if (resume == true)
1277
9.00k
          return 0; // not yet finished
1278
9.13k
      }
1279
66.8k
      return 1; // queue empty, close sound channel
1280
75.8k
    }
1281
1282
27.6M
    result = 0;
1283
27.6M
    q = wcmdq[wcmdq_head];
1284
27.6M
    length = q[1];
1285
1286
27.6M
    switch (q[0] & 0xff)
1287
27.6M
    {
1288
3.16M
    case WCMD_PITCH:
1289
3.16M
      SetPitch(length, (unsigned char *)q[2], q[3] >> 16, q[3] & 0xffff);
1290
3.16M
      break;
1291
0
    case WCMD_PHONEME_ALIGNMENT:
1292
0
    {
1293
0
      char* data = (char*)q[1];
1294
0
      output_hooks->outputPhoSymbol(data,q[2]);
1295
0
      free(data);
1296
0
    }
1297
0
      break;
1298
2.88M
    case WCMD_PAUSE:
1299
2.88M
      if (resume == false)
1300
2.18M
        echo_complete -= length;
1301
2.88M
      wdata.n_mix_wavefile = 0;
1302
2.88M
      wdata.amplitude_fmt = 100;
1303
2.88M
#if USE_KLATT
1304
2.88M
      KlattReset(1);
1305
2.88M
#endif
1306
2.88M
      result = PlaySilence(length, resume);
1307
2.88M
      break;
1308
1.93M
    case WCMD_WAVE:
1309
1.93M
      echo_complete = echo_length;
1310
1.93M
      wdata.n_mix_wavefile = 0;
1311
1.93M
#if USE_KLATT
1312
1.93M
      KlattReset(1);
1313
1.93M
#endif
1314
1.93M
      result = PlayWave(length, resume, (unsigned char *)q[2], q[3] & 0xff, q[3] >> 8);
1315
1.93M
      break;
1316
622k
    case WCMD_WAVE2:
1317
      // wave file to be played at the same time as synthesis
1318
622k
      wdata.mix_wave_amp = q[3] >> 8;
1319
622k
      wdata.mix_wave_scale = q[3] & 0xff;
1320
622k
      wdata.n_mix_wavefile = (length & 0xffff);
1321
622k
      wdata.mix_wavefile_max = (length >> 16) & 0xffff;
1322
622k
      if (wdata.mix_wave_scale == 0) {
1323
0
        wdata.n_mix_wavefile *= 2;
1324
0
        wdata.mix_wavefile_max *= 2;
1325
0
      }
1326
622k
      wdata.mix_wavefile_ix = 0;
1327
622k
      wdata.mix_wavefile_offset = 0;
1328
622k
      wdata.mix_wavefile = (unsigned char *)q[2];
1329
622k
      break;
1330
882k
    case WCMD_SPECT2: // as WCMD_SPECT but stop any concurrent wave file
1331
882k
      wdata.n_mix_wavefile = 0; // ... and drop through to WCMD_SPECT case
1332
14.8M
    case WCMD_SPECT:
1333
14.8M
      echo_complete = echo_length;
1334
14.8M
      result = Wavegen(length & 0xffff, q[1] >> 16, resume, (frame_t *)q[2], (frame_t *)q[3], wvoice);
1335
14.8M
      break;
1336
0
#if USE_KLATT
1337
0
    case WCMD_KLATT2: // as WCMD_SPECT but stop any concurrent wave file
1338
0
      wdata.n_mix_wavefile = 0; // ... and drop through to WCMD_SPECT case
1339
0
    case WCMD_KLATT:
1340
0
      echo_complete = echo_length;
1341
0
      result = Wavegen_Klatt(length & 0xffff, resume, (frame_t *)q[2], (frame_t *)q[3], &wdata, wvoice);
1342
0
      break;
1343
0
#endif
1344
642k
    case WCMD_MARKER:
1345
642k
      marker_type = q[0] >> 8;
1346
642k
      MarkerEvent(marker_type, q[1], * (int *) & q[2], * ((int *) & q[2] + 1), out_ptr);
1347
642k
      break;
1348
3.16M
    case WCMD_AMPLITUDE:
1349
3.16M
      SetAmplitude(length, (unsigned char *)q[2], q[3]);
1350
3.16M
      break;
1351
9.27k
    case WCMD_VOICE:
1352
9.27k
      WavegenSetVoice((voice_t *)q[2]);
1353
9.27k
      free((voice_t *)q[2]);
1354
9.27k
      break;
1355
23.6k
    case WCMD_EMBEDDED:
1356
23.6k
      SetEmbedded(q[1], q[2]);
1357
23.6k
      break;
1358
#if USE_MBROLA
1359
    case WCMD_MBROLA_DATA:
1360
      if (wvoice != NULL)
1361
        result = MbrolaFill(length, resume, (general_amplitude * wvoice->voicing)/64);
1362
      break;
1363
#endif
1364
320k
    case WCMD_FMT_AMPLITUDE:
1365
320k
      if ((wdata.amplitude_fmt = q[1]) == 0)
1366
160k
        wdata.amplitude_fmt = 100; // percentage, but value=0 means 100%
1367
320k
      break;
1368
#if USE_LIBSONIC
1369
    case WCMD_SONIC_SPEED:
1370
      sonicSpeed = (double)q[1] / 1024;
1371
      if (sonicSpeedupStream && (sonicSpeed <= 1.0)) {
1372
        sonicFlushStream(sonicSpeedupStream);
1373
        int length = (out_end - out_ptr);
1374
        length = sonicReadShortFromStream(sonicSpeedupStream, (short*)out_ptr, length/2);
1375
#ifdef ARCH_BIG
1376
        {
1377
          unsigned i;
1378
          for (i = 0; i < length/2; i++) {
1379
            unsigned short v = ((unsigned short *) out_ptr)[i];
1380
            out_ptr[i*2] = v & 0xff;
1381
            out_ptr[i*2+1] = v >> 8;
1382
          }
1383
        }
1384
#endif
1385
        out_ptr += length * 2;
1386
      }
1387
      break;
1388
#endif
1389
27.6M
    }
1390
1391
27.6M
    if (result == 0) {
1392
22.4M
      WcmdqIncHead();
1393
22.4M
      resume = false;
1394
22.4M
    } else
1395
5.21M
      resume = true;
1396
27.6M
  }
1397
1398
5.21M
  return 0;
1399
5.29M
}
1400
1401
#if USE_LIBSONIC
1402
// Speed up the audio samples with libsonic.
1403
static int SpeedUp(short *outbuf, int length_in, int length_out, int end_of_text)
1404
{
1405
#ifdef ARCH_BIG
1406
  unsigned i;
1407
#endif
1408
1409
  if (length_in > 0) {
1410
    if (sonicSpeedupStream == NULL)
1411
      sonicSpeedupStream = sonicCreateStream(22050, 1);
1412
    if (sonicGetSpeed(sonicSpeedupStream) != sonicSpeed)
1413
      sonicSetSpeed(sonicSpeedupStream, sonicSpeed);
1414
1415
#ifdef ARCH_BIG
1416
    for (i = 0; i < length_in; i++) {
1417
      unsigned short v = ((unsigned char*) outbuf)[i*2] | (((unsigned char *)outbuf)[i*2+1] << 8);
1418
      ((unsigned short *) outbuf)[i] = v;
1419
    }
1420
#endif
1421
    sonicWriteShortToStream(sonicSpeedupStream, outbuf, length_in);
1422
  }
1423
1424
  if (sonicSpeedupStream == NULL)
1425
    return 0;
1426
1427
  if (end_of_text)
1428
    sonicFlushStream(sonicSpeedupStream);
1429
1430
  int ret = sonicReadShortFromStream(sonicSpeedupStream, outbuf, length_out);
1431
#ifdef ARCH_BIG
1432
  for (i = 0; i < length_out; i++) {
1433
    unsigned short v = ((unsigned short *) outbuf)[i];
1434
    ((unsigned char *)outbuf)[i*2] = v & 0xff;
1435
    ((unsigned char *)outbuf)[i*2+1] = v >> 8;
1436
  }
1437
#endif
1438
  return ret;
1439
}
1440
#endif
1441
1442
// Call WavegenFill2, and then speed up the output samples.
1443
int WavegenFill(void)
1444
5.29M
{
1445
5.29M
  int finished;
1446
#if USE_LIBSONIC
1447
  unsigned char *p_start;
1448
1449
  p_start = out_ptr;
1450
#endif
1451
1452
5.29M
  finished = WavegenFill2();
1453
1454
#if USE_LIBSONIC
1455
  if (sonicSpeed > 1.0) {
1456
    int length;
1457
    int max_length;
1458
1459
    max_length = (out_end - p_start);
1460
    length =  2*SpeedUp((short *)p_start, (out_ptr-p_start)/2, max_length/2, finished);
1461
    out_ptr = p_start + length;
1462
1463
    if (length >= max_length)
1464
      finished = 0; // there may be more data to flush
1465
  }
1466
#endif
1467
5.29M
  return finished;
1468
5.29M
}
1469
1470
#pragma GCC visibility push(default)
1471
1472
ESPEAK_NG_API espeak_ng_STATUS
1473
espeak_ng_SetOutputHooks(espeak_ng_OUTPUT_HOOKS* hooks)
1474
0
{
1475
0
  output_hooks = hooks;
1476
0
  return 0;
1477
0
}
1478
1479
ESPEAK_NG_API espeak_ng_STATUS
1480
espeak_ng_SetConstF0(int f0)
1481
0
{
1482
0
  const_f0 = f0;
1483
0
  return ENS_OK;
1484
0
}
1485
1486
#pragma GCC visibility pop