2
* brass - Braille and speech server
4
* Copyright (C) 2001 by Roger Butenuth, All rights reserved.
5
* Copyright 2002 by Michael Gorse.
7
* This is free software, placed under the terms of the
8
* GNU General Public License, as published by the Free Software
9
* Foundation. Please see the file COPYING for details.
11
* $Id: fs.c,v 1.15 2004/02/20 23:47:44 mgorse Exp $
20
#include <signal.h> /* tmp. for dbg. */
26
#include "flite_version.h"
28
#include "synthesizer.h"
33
static int s_close(synth_t *s);
34
static int s_synth(synth_t *s, unsigned char *buffer);
35
static int s_flush(synth_t *s);
36
static int s_clear(synth_t *s);
38
static int s_index_set(struct synth_struct *s);
39
static int s_index_wait(struct synth_struct *s, int id, int timeout);
41
static int s_get_param(struct synth_struct *s, synth_par_t par, int *value);
42
static int s_set_param(struct synth_struct *s, synth_par_t par, int value);
44
typedef struct synth_state {
49
static synth_state_t private_state[2];
51
static synth_t state[] = {
54
&languages[LANG_BRITISH_ENGLISH],
61
NULL, /* s_index_set, */
62
NULL, /* s_index_wait, */
67
&languages[LANG_GERMAN],
68
"FLite/German", /* not supported */
74
NULL, /* s_index_set, */
75
NULL, /* s_index_wait, */
82
static int current_language = -1;
83
static int ref_count = 0;
84
static FILE *debug_fp = NULL;
86
typedef enum { NONE, SPEECH, TONE } ac_type;
94
#if 0 /* tbd - figure out what these variables are supposed to be used for */
95
/*static int sync_mark_no = 0;*/ /* currently used number */
96
/*static struct timeval mark;*/ /* time the mark has been set */
99
/* server-specific variables */
100
static cst_voice *v = NULL;
101
static pthread_t wave_thread;
102
static int wave_thread_active;
103
static pthread_mutex_t wave_mutex;
104
static AUDIO_COMMAND *ac;
106
static int ac_head, ac_tail;
107
static int ac_synthpos; /* largest index to play + 1 */
108
static pthread_t text_thread;
109
static int text_thread_active;
110
static pthread_mutex_t text_mutex;
112
static int text_size;
113
static int text_head, text_tail;
114
static int text_synthpos; /* pointer to beyond last piece to be played */
115
cst_audiodev *audiodev = NULL; /* Sound device */
116
static int pas; /* play after synthesizing? */
117
static pthread_attr_t ta; /* for creating threads */
118
static float time_left = 0;
119
static int s_count = 0;
121
extern cst_voice *REGISTER_VOX(const char *voxdir);
122
extern int cst_alloc_out;
126
* ----------------------------------------------------------------------
127
* Called before library is loaded.
128
* ----------------------------------------------------------------------
136
* ----------------------------------------------------------------------
137
* Called before library is unloaded.
138
* ----------------------------------------------------------------------
146
* ----------------------------------------------------------------------
147
* General open function for german and english synthesizer.
148
* Second open increments refcount.
149
* Return 0 on success, 1 on error.
150
* ----------------------------------------------------------------------
153
/* This code seems to cause lingering processes in the event of a crash */
154
void segfault(int sig)
156
extern char *sockname;
157
es_log(1, "Got a seg fault -- exiting");
158
printf("Got a seg fault -- exiting.\n");
164
synth_t *synth_open(void *context, lookup_string_t lookup)
167
char *language = (*lookup)(context, "language");
171
if (language == NULL) {
172
language = "english";
174
if (ref_count == 0) {
178
signal(SIGSEGV, segfault);
181
v = REGISTER_VOX(NULL);
182
pthread_attr_init(&ta);
183
pthread_attr_setdetachstate(&ta, PTHREAD_CREATE_DETACHED);
184
text_thread_active = 0;
186
text = (char *)malloc(text_size);
187
text_head = text_tail = text_synthpos = 0;
188
wave_thread_active = 0;
190
ac = (AUDIO_COMMAND *)malloc(ac_size * sizeof(AUDIO_COMMAND));
191
ac_head = ac_tail = ac_synthpos = 0;
192
if (!ac || !text) return NULL;
193
pthread_mutex_init(&wave_mutex, NULL);
198
if (!strcasecmp(language, "english")) {
201
} else if (!strcasecmp(language, "german")) {
209
if (s != NULL && !s->state->initialized) {
210
s->state->param[S_SPEED] = 1000;
211
s->state->param[S_PITCH] = 1000;
212
s->state->param[S_VOLUME] = 1000;
213
s->state->initialized = 1;
221
* ----------------------------------------------------------------------
222
* General close. Decrement refcount, do real close when count reaches
224
* ----------------------------------------------------------------------
226
static int s_close(synth_t *s)
229
if (ref_count == 0) {
230
/* Wait for any speech to be spoken */
231
while (text_thread_active || wave_thread_active) usleep(50000);
232
if (text) free(text);
243
* ----------------------------------------------------------------------
244
* Verify that the synthesizer is set to the correct language.
245
* Switch if necessary.
246
* ----------------------------------------------------------------------
248
static void verify_language(struct synth_struct *s)
252
if (s->lang->lang == LANG_BRITISH_ENGLISH
253
&& current_language != LANG_BRITISH_ENGLISH) {
255
} else if (s->lang->lang == LANG_GERMAN &&
256
current_language != LANG_GERMAN) {
264
static void cst_wave_free(cst_wave *w)
266
es_log(2, "cst_wave_free: %p", w);
269
cst_free(w->samples);
274
static void ac_destroy(AUDIO_COMMAND *ac)
278
case SPEECH: case TONE: cst_wave_free(ac->data); break;
284
static void close_audiodev()
288
audio_close(audiodev);
293
static void play_unlock(void *canceled)
295
es_log(2, "play: unlocking wave mutex");
296
pthread_mutex_unlock(&wave_mutex);
297
es_log(2, "play: unlocked wave mutex");
300
#define PLAY_UNLOCK \
302
pthread_cleanup_pop(0);
305
es_log(2, "play: locking wave mutex"); \
306
pthread_cleanup_push(play_unlock, NULL); \
307
pthread_mutex_lock(&wave_mutex); \
308
es_log(2, "play: got wave mutex"); \
309
pthread_testcancel();
311
static void * play(void *s)
316
int *sparam = ((synth_t *)s)->state->param;
318
//pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
319
es_log(2, "play: init: ac_head=%d ac_tail=%d", ac_head, ac_tail);
320
while (ac_head < ac_synthpos)
325
if (ac[ac_head].type == NONE)
327
pas = (ac_synthpos > 0? 1: 0);
330
wptr = ac[ac_head].data;
331
audiodev = audio_open(wptr->sample_rate, wptr->num_channels, CST_AUDIO_LINEAR16);
333
if (!audiodev || (long)audiodev->platform_data == -1)
337
es_log(2, "Audio device is busy; trying again");
340
pthread_testcancel();
343
terror("audio_open");
346
es_log(2, "play: ac_head=%d type=%d", ac_head, ac[ac_head].type);
347
if (ac[ac_head].type == NONE)
349
/* There will be more data, but it isn't ready yet. */
350
es_log(2, "ac[%d] is inactive, setting pas", ac_head);
357
wptr = ac[ac_head].data;
358
if (ac[ac_head].type == SPEECH)
360
skip = 1500000 / sparam[S_SPEED];
361
playlen = wptr->num_samples - (skip * 2);
362
if (playlen > 0 && playlen < 500) playlen += (skip * 2) / 3;
367
playlen = wptr->num_samples;
369
if (playlen < 0) playlen = 0;
370
es_log(2, "play: wave=%p, samples=%p, num_samples=%d skip=%d playlen=%d", wptr, wptr->samples, wptr->num_samples, skip, playlen);
371
time_left += (float)playlen / wptr->sample_rate;
374
if (sparam[S_VOLUME] != 1000)
375
cst_wave_rescale(wptr, (sparam[S_VOLUME] << 16) / 1000);
376
pthread_testcancel();
377
audio_write(audiodev, wptr->samples + skip, playlen * 2);
378
pthread_testcancel();
380
es_log(2, "play: syncing");
381
audio_flush(audiodev);
382
pthread_testcancel();
383
time_left -= (float)playlen / wptr->sample_rate;
385
ac_destroy(&ac[ac_head]);
387
if (++ac_head > (ac_size >> 1))
389
es_log(1, "play: compacting wave pointers");
390
memmove(ac, ac + ac_head, (ac_tail - ac_head) * sizeof(AUDIO_COMMAND));
392
ac_synthpos -= ac_head;
397
es_log(2, "play: loop over: ac_head=%d, ac_tail=%d", ac_head, ac_tail);
399
if (ac_head == ac_tail)
401
ac_head = ac_tail = wave_thread_active = 0;
403
else pas = 1; /* there is more data -- need to re-enter */
405
es_log(2, "play: exiting");
409
/* This kludge works around the race condition where a synthesize thread is
410
started, then speech is silenced, then more speech is added, with the first
411
thread never having been created. We want to avoid having two synthesize
412
threads running in this situation. A better solution would be to use
413
thread conditions, but I have been unable to get them to work so far. If
414
you can help, then send me an email. */
419
} SYNTHESIZE_INITIALIZER;
421
void *make_initializer(void *s, int s_count)
423
SYNTHESIZE_INITIALIZER *ptr;
425
ptr = (SYNTHESIZE_INITIALIZER *)malloc(sizeof(SYNTHESIZE_INITIALIZER));
426
if (!ptr) return NULL;
428
ptr->s_count = s_count;
432
static void * synthesize(void *initializer)
434
cst_wave *wptr = NULL;
435
int wml = 0; /* wave mutex locked */
439
int just_entered = 1;
441
if (!initializer) return NULL;
442
s = ((SYNTHESIZE_INITIALIZER *)initializer)->s;
443
s_count_enter = ((SYNTHESIZE_INITIALIZER *)initializer)->s_count;
445
if (s_count != s_count_enter) return NULL;
446
es_log(2, "synthesize: entering");
447
while (text[text_head])
449
es_log(2, "synthesize: %d %d", text_head, text_tail);
450
switch ((command = text[text_head++]))
453
wptr = flite_text_to_wave(text + text_head, v);
458
if (sscanf(text + text_head, "%d %d %d", &freq, &dur, &vol) != 3)
460
es_log(1, "unable to scan tone: %s", text + text_head);
463
wptr = generate_tone(freq, dur, vol);
467
/* snafu - I'm getting the hell out of here */
468
es_log(1, "synthesize: internal error: unknown command: %x", text[text_head - 1]);
471
if (time_left > 3 && !just_entered)
473
es_log(1, "time_left=%f -- going to sleep\n", time_left);
474
usleep(time_left * 750000);
477
if (s_count != s_count_enter)
479
es_log(2, "synthesize: canceling");
483
es_log(2, "synthesize: %p %p\n", wptr, wptr->samples);
484
es_log(1, "text=%s", text + text_head);
485
while (text[text_head]) text_head++;
486
text_head++; /* This is not a bug. */
487
pthread_mutex_lock(&text_mutex);
488
if (wave_thread_active)
491
es_log(2, "synthesize: locking wave mutex");
492
pthread_mutex_lock(&wave_mutex);
493
es_log(2, "synthesize: got wave mutex");
495
/* Compact buffer if it seems like a good thing to do */
496
if (text_head > (text_size >> 1))
498
es_log(1, "synthesizer: compacting buffer");
499
memcpy(text, text + text_head, text_tail - text_head + 1);
500
text_tail -= text_head;
501
if (text_synthpos != -1) text_synthpos -= text_head;
504
if (ac_size == ac_tail + 1)
506
es_log(1, "synthesize: allocating more wave memory");
508
ac = (AUDIO_COMMAND *)realloc(ac, ac_size * sizeof(AUDIO_COMMAND));
511
fprintf(stderr, "Out of memory, ac_size=%d\n", ac_size);
515
ac[ac_tail].type = command;
516
ac[ac_tail++].data = wptr;
517
if (text_head == text_tail) ac_synthpos = ac_tail;
518
es_log(2, "synthesize: after adding: %d %d", ac_head, ac_tail);
521
es_log(2, "synthesize: unlocking wave mutex");
522
pthread_mutex_unlock(&wave_mutex);
523
es_log(2, "synthesize: unlocked wave mutex");
528
es_log(2, "synthesize: pas set, creating play thread");
529
es_log(2, "synthesize: locking wave mutex");
530
pthread_mutex_lock(&wave_mutex);
531
es_log(2, "synthesize: got wave mutex");
532
wave_thread_active = 1;
533
pthread_create(&wave_thread, &ta, play, (void *)s);
534
pthread_mutex_unlock(&wave_mutex);
535
es_log(2, "synthesize: unlocked wave mutex");
538
pthread_mutex_unlock(&text_mutex);
540
pthread_mutex_lock(&text_mutex);
541
text_head = text_tail = text_thread_active = 0;
542
pthread_mutex_unlock(&text_mutex);
543
es_log(2, "synthesize: dying: %d %d", ac_head, ac_tail);
548
* ----------------------------------------------------------------------
549
* Copy Text to server. Text is not spoken until a flush command
551
* ----------------------------------------------------------------------
553
static void add_command(struct synth_struct *s, int id, unsigned char *buffer)
557
assert(s->state->initialized);
558
len = strlen(buffer);
559
if (text_thread_active) pthread_mutex_lock(&text_mutex);
560
if (text_tail + len + 3 >= text_size)
563
text = (char *)realloc(text, text_size);
566
fprintf(stderr, "Out of memory: text_size=%d\n", text_size);
570
text[text_tail++] = (char)id;
571
strcpy(text + text_tail, buffer);
572
text_tail += len + 1;
573
/* The below line is important. An extra \0 indicates to the synthesize
574
thread that there is no more data. */
575
text[text_tail] = '\0';
576
if (!text_thread_active)
578
pthread_mutex_init(&text_mutex, NULL);
579
es_log(2, "s_synth: creating new text thread");
580
text_thread_active = 1;
581
ac_synthpos = 0xffff;
582
pthread_create(&text_thread, &ta, synthesize, make_initializer(s, s_count));
584
else pthread_mutex_unlock(&text_mutex);
588
static int s_synth(struct synth_struct *s, unsigned char *buffer)
590
add_command(s, 1, buffer);
594
void add_tone_command(struct synth_struct *s, int freq, int dur, int vol)
598
sprintf(buf, "%d %d %d", freq, dur, vol);
599
add_command(s, 2, buf);
603
* ----------------------------------------------------------------------
604
* Flush synthesizer. This triggers the synthesizer and starts
606
* ----------------------------------------------------------------------
608
static int s_flush(synth_t *s)
612
if (text_tail == 0 && ac_tail == 0) return 0;
613
text_synthpos = text_tail;
614
if (!wave_thread_active)
616
es_log(2, "s_flush: locking wave mutex");
617
pthread_mutex_lock(&wave_mutex);
618
es_log(2, "s_flush: got wave mutex");
619
wave_thread_active = 1;
620
es_log(2, "es_flush: creating play thread");
621
result = pthread_create(&wave_thread, &ta, play, s);
622
pthread_mutex_unlock(&wave_mutex);
623
es_log(2, "s_flush: unlocked wave mutex");
631
* ----------------------------------------------------------------------
632
* Remove anything in the synthesizer speech queue.
633
* ----------------------------------------------------------------------
635
static int s_clear(synth_t *s)
639
es_log(2, "s_clear: text=%d %d, wave=%d %d", text_head, text_tail, ac_head, ac_tail);
640
es_log(2, "s_clear: locking wave mutex");
641
pthread_mutex_lock(&wave_mutex);
642
es_log(2, "s_clear: got wave mutex");
643
if (text_thread_active)
645
es_log(2, "canceling text thread: %d %d", text_head, text_tail);
648
if (wave_thread_active)
650
es_log(2, "canceling wave thread: %d %d", ac_head, ac_tail);
651
pthread_cancel(wave_thread);
653
pthread_mutex_unlock(&wave_mutex);
656
audio_drain(audiodev);
660
/* Free any wave data */
661
//es_log("s_clear: freeing wave data: %d", ac_tail);
662
for (i = 0; i < ac_tail; i++)
664
if (ac[i].type != NONE) ac_destroy(&ac[i]);
667
//es_log(2, "mem=%d", cst_alloc_out);
669
text_head = text_tail = text_synthpos = 0;
670
ac_head = ac_tail = ac_synthpos = 0;
671
text_thread_active = wave_thread_active = 0;
680
* ----------------------------------------------------------------------
682
* ----------------------------------------------------------------------
684
static int s_index_set(struct synth_struct *s)
690
* ----------------------------------------------------------------------
692
* ----------------------------------------------------------------------
694
static int s_index_wait(struct synth_struct *s, int id, int timeout)
703
* ----------------------------------------------------------------------
704
* Get a synthesizer parameter.
705
* ----------------------------------------------------------------------
707
static int s_get_param(struct synth_struct *s, synth_par_t par, int *value)
709
if (par >= 0 && par < S_MAX) {
710
*value = s->state->param[par];
718
* ----------------------------------------------------------------------
719
* Set a parameter of the synthesizer.
720
* ----------------------------------------------------------------------
722
static int s_set_param(struct synth_struct *s, synth_par_t par, int value)
727
case S_SPEED: /* default: 1 */
728
es_log(2, "Setting duration_stretch to %4.3f", (float)1000 / value);
729
feat_set_float(v->features, "duration_stretch", (float)1000 / value);
731
case S_PITCH: /* default: 100 */
732
es_log(2, "Setting pitch to %3.3f", exp((float)value / 1000) * 100 / exp(1));
733
feat_set_float(v->features, "int_f0_target_mean", exp((float)value / 1000) * 100 / exp(1));
736
case S_VOLUME: /* default: 92, range: 0-100 */
742
s->state->param[par] = value;
748
lang_descr_t languages[LANGUAGES] = {
749
{ LANG_BRITISH_ENGLISH, "British English" },
750
{ LANG_GERMAN, "German" },
751
{ LANG_DUMMY, "no language" }
769
lang_t *language_open(void *context, lookup_string_t lookup)
771
lang.synth = synth_open(context, lookup);