static int save_dataset_comments (const dataset *dset) { int i, j; cst_voice *v; cst_wave *w, *fullw = NULL; flite_init(); v = register_cmu_us_kal(); j = 0; for (i=0; i<N_COMMENTS; i++) { if (dset->comments[i] != NULL) { if (j == 0) { fullw = flite_text_to_wave(dset->comments[i], v); } else { w = flite_text_to_wave(dset->comments[i], v); concat_wave(fullw, w); delete_wave(w); } j++; } } cst_wave_save_riff(fullw, "gretl_flite.wav"); delete_wave(fullw); return 0; }
int flowm_say_text(TCHAR *text) { char *s; int ns; cst_voice *v; if (previous_wave) { delete_wave(previous_wave); previous_wave = NULL; } s = cst_wstr2cstr(text); /* text to synthesize */ v = VoxDefs[flowm_selected_voice].v; /* voice to synthesize with */ feat_remove(v->features,"print_info_relation"); if (flowm_selected_relation == 1) feat_set_string(v->features, "print_info_relation", "Word"); if (flowm_selected_relation == 2) feat_set_string(v->features, "print_info_relation", "Segment"); /* Do the synthesis */ previous_wave = flite_text_to_wave(s,v); ns = cst_wave_num_samples(previous_wave); cst_free(s); audio_flush(fl_ad); audio_close(fl_ad); fl_ad = NULL; return ns; }
int main(int argc, char **argv) { cst_wave *nw, *all; cst_val *files; const cst_val *w; cst_val *wavelist; cst_features *args; int i,j; float ntime; int stime; const char *nwfile; args = new_features(); files = cst_args(argv,argc, "usage: combine_waves OPTIONS\n" "Combine waves into single waveform\n" "-o <string> Output waveform\n" "-f <int> Input sample rate (for raw input)\n" "-itype <string> Input type, raw or headered\n" "-wavelist <string> File containing times and wave filenames\n", args); wavelist = get_wavelist(get_param_string(args,"-wavelist","-")); if (wavelist == 0) return -1; all = new_wave(); for (w = wavelist; w; w = val_cdr(w)) { ntime = decode_time(val_string(val_car(w))); nwfile = val_string(val_car(val_cdr(w))); nw = new_wave(); if (cst_wave_load_riff(nw,nwfile) != CST_OK_FORMAT) { fprintf(stderr, "combine_waves: can't read file or wrong format \"%s\"\n", nwfile); continue; } stime = ntime * nw->sample_rate; cst_wave_resize(all,stime+nw->num_samples,1); for (i=0,j=stime; i<nw->num_samples; i++,j++) { /* this will cause overflows */ all->samples[j] += nw->samples[i]; } delete_wave(nw); } cst_wave_save_riff(all,get_param_string(args,"-o","-")); return 0; }
void test_resize(void) { cst_wave *w = new_wave(); cst_wave_resize(w, 200, 2); TEST_CHECK(w->num_samples == 200); TEST_CHECK(w->num_channels = 2); TEST_CHECK(cst_wave_resize(NULL, 200, 2) < 0); delete_wave(w); }
void test_create(void) { cst_wave *w = NULL; w = new_wave(); TEST_CHECK(w != NULL); TEST_CHECK(w->num_samples == 0); TEST_CHECK(w->type == NULL); delete_wave(w); }
void test_copy(void) { cst_voice *v = NULL; cst_wave *w1, *w2; common_init(); v = mimic_voice_select(A_VOICE); w1 = mimic_text_to_wave("Hello", v); w2 = copy_wave(w1); TEST_CHECK(w1 != w2); TEST_CHECK(w1->num_samples == w2->num_samples); TEST_CHECK(w1->sample_rate == w2->sample_rate); TEST_CHECK(w1->num_channels == w2->num_channels); TEST_CHECK(w1->samples != w2->samples); TEST_CHECK(w1->samples[0] == w2->samples[0]); TEST_CHECK(w1->samples[10] == w2->samples[10]); TEST_CHECK(w1->samples[20] == w2->samples[20]); delete_wave(w1); delete_wave(w2); }
void test_rescale(void) { int i; cst_wave *w = new_wave(); cst_wave_resize(w, 10, 2); for (i = 0; i < 10; i++) w->samples[i] = 10 + i; cst_wave_rescale(w, 65536 * 2); //scale x2 for (i = 0; i < 10; i++) TEST_CHECK(w->samples[i] == (10 + i) * 2); delete_wave(w); }
void test_concat(void) { int original_len; cst_wave *w1, *w2; cst_voice *v; common_init(); v = mimic_voice_select(A_VOICE); w1 = mimic_text_to_wave("Hello", v); w2 = mimic_text_to_wave("There", v); original_len = w1->num_samples; concat_wave(w1, w2); TEST_CHECK(w1->num_samples == w2->num_samples + original_len); delete_wave(w1); delete_wave(w2); w1 = mimic_text_to_wave("Hello", v); w2 = mimic_text_to_wave("There", v); w2->sample_rate *= 2; // create sample rate mismatch concat_wave(w1, w2); TEST_CHECK(w1->num_samples != w2->num_samples + original_len); delete_wave(w1); delete_wave(w2); w1 = mimic_text_to_wave("Hello", v); w2 = mimic_text_to_wave("There", v); w2->num_channels *= 2; // create channel number mismatch concat_wave(w1, w2); TEST_CHECK(w1->num_samples != w2->num_samples + original_len); delete_wave(w1); delete_wave(w2); }
void next_tweet(struct sockaddr_in* server, int chan) { char buffer[BUFSIZE+1]; memset(buffer, BUFSIZE, 0); receive_tweet(buffer, server); printf("%s\n", buffer); if (si.w[chan]) delete_wave(si.w[chan]); si.w[chan] = flite_text_to_wave(buffer, voice); si.done[chan] = 0; si.pos[chan] = 0; si.cur_delay[chan] = 0.; si.rate_delay[chan] = 44100. / (double)si.w[chan]->sample_rate; /* play some tweets faster, some slower */ si.rate_delay[chan] *= (.75 + .5 * (double)(rand() % 256) / 255.); }
void flowm_terminate() { #ifdef DOTTS int i; for (i=0; VoxDefs[i].name; i++) { (VoxDefs[i].urv)(VoxDefs[i].v); /* unregister voice */ } #endif if (previous_wave) { delete_wave(previous_wave); previous_wave = NULL; } return; }
float flite_ssml_to_speech(const char *filename, cst_voice *voice, const char *outtype) { cst_tokenstream *ts; int fp; cst_wave *w; float d; if ((ts = ts_open(filename, get_param_string(voice->features,"text_whitespace",NULL), get_param_string(voice->features,"text_singlecharsymbols",NULL), get_param_string(voice->features,"text_prepunctuation",NULL), get_param_string(voice->features,"text_postpunctuation",NULL))) == NULL) { cst_errmsg("failed to open file \"%s\" for ssml reading\n", filename); return 1; } fp = get_param_int(voice->features,"file_start_position",0); if (fp > 0) ts_set_stream_pos(ts,fp); /* If its a file to write to, create and save an empty wave file */ /* as we are going to incrementally append to it */ if (!cst_streq(outtype,"play") && !cst_streq(outtype,"none") && !cst_streq(outtype,"stream")) { w = new_wave(); cst_wave_resize(w,0,1); cst_wave_set_sample_rate(w,16000); cst_wave_save_riff(w,outtype); /* an empty wave */ delete_wave(w); } d = flite_ssml_to_speech_ts(ts,voice,outtype); ts_close(ts); return d; }
void at_exit() { Pa_Terminate(); int i; if (si.w != NULL) { for (i = 0; i < si.channel_count; ++i) delete_wave(si.w[i]); free(si.w); si.w = NULL; } if (voice) { delete_voice(voice); voice = NULL; } if (sock >= 0) close(sock); }
int flowm_say_file(TCHAR *tfilename) { int rc = 0; char *filename; cst_voice *v; if (previous_wave) { /* This is really tidy up from Play -- but might say space */ delete_wave(previous_wave); previous_wave = NULL; } if (fl_ad) { MessageBoxW(0,L"audio fd still open",L"SayFile",0); audio_close(fl_ad); fl_ad = NULL; } v = VoxDefs[flowm_selected_voice].v; /* Where we want to start from */ feat_set_int(v->features, "file_start_position", flowm_file_pos); /* Only do print_info in play mode */ feat_remove(v->features,"print_info_relation"); filename = cst_wstr2cstr(tfilename); rc = flite_file_to_speech(filename, v, "stream"); cst_free(filename); audio_flush(fl_ad); audio_close(fl_ad); fl_ad = NULL; return rc; }
float flite_file_to_speech(const char *filename, cst_voice *voice, const char *outtype) { cst_utterance *utt; cst_tokenstream *ts; const char *token; cst_item *t; cst_relation *tokrel; float d, durs = 0; int num_tokens; cst_breakfunc breakfunc = default_utt_break; if ((ts = ts_open(filename, get_param_string(voice->features,"text_whitespace",NULL), get_param_string(voice->features,"text_singlecharsymbols",NULL), get_param_string(voice->features,"text_prepunctuation",NULL), get_param_string(voice->features,"text_postpunctuation",NULL))) == NULL) { cst_errmsg("failed to open file \"%s\" for reading\n", filename); return 1; } if (feat_present(voice->features,"utt_break")) breakfunc = val_breakfunc(feat_val(voice->features,"utt_break")); /* If its a file to write to delete it as we're going to */ /* incrementally append to it */ if (!cst_streq(outtype,"play") && !cst_streq(outtype,"none")) { cst_wave *w; w = new_wave(); cst_wave_resize(w,0,1); cst_wave_set_sample_rate(w,16000); cst_wave_save_riff(w,outtype); /* an empty wave */ delete_wave(w); } num_tokens = 0; utt = new_utterance(); tokrel = utt_relation_create(utt, "Token"); while (!ts_eof(ts) || num_tokens > 0) { token = ts_get(ts); if ((strlen(token) == 0) || (num_tokens > 500) || /* need an upper bound */ (relation_head(tokrel) && breakfunc(ts,token,tokrel))) { /* An end of utt */ d = flite_tokens_to_speech(utt,voice,outtype); utt = NULL; if (d < 0) goto out; durs += d; if (ts_eof(ts)) goto out; utt = new_utterance(); tokrel = utt_relation_create(utt, "Token"); num_tokens = 0; } num_tokens++; t = relation_append(tokrel, NULL); item_set_string(t,"name",token); item_set_string(t,"whitespace",ts->whitespace); item_set_string(t,"prepunctuation",ts->prepunctuation); item_set_string(t,"punc",ts->postpunctuation); item_set_int(t,"file_pos",ts->file_pos); item_set_int(t,"line_number",ts->line_number); } out: delete_utterance(utt); ts_close(ts); return durs; }
int main(int argc, char **argv) { cst_wave *w; int port; char *server; char *encoding; int i,iw; port = CST_AUDIO_DEFAULT_PORT; server = CST_AUDIO_DEFAULT_SERVER; encoding = CST_AUDIO_DEFAULT_ENCODING; if (argc == 1) { play_client_main_usage(); return 1; } if ((cst_streq("-h",argv[1])) || (cst_streq("-help",argv[1])) || (cst_streq("--help",argv[1]))) { play_client_main_usage(); return 1; } iw = 1; if (cst_streq("-s",argv[iw])) { if (argc < iw+1) { fprintf(stderr,"ERROR: no servername given\n"); play_client_main_usage(); return 1; } server = argv[iw+1]; iw+=2; } if (cst_streq("-p",argv[iw])) { if (argc < iw+1) { fprintf(stderr,"ERROR: no port given\n"); play_client_main_usage(); return 1; } port = atoi(argv[iw+1]); iw+=2; } if (cst_streq("-e",argv[iw])) { if (argc < iw+1) { fprintf(stderr,"ERROR: no encoding given\n"); play_client_main_usage(); return 1; } encoding = argv[iw+1]; iw+=2; } for (i=iw; i<argc; i++) { w = new_wave(); if (cst_wave_load_riff(w,argv[i]) != CST_OK_FORMAT) { fprintf(stderr, "play_wave: can't read file or wrong format \"%s\"\n", argv[i]); continue; } play_wave_client(w,server,port,encoding); delete_wave(w); } return 0; }
float flite_file_to_speech(const char *filename, cst_voice *voice, const char *outtype) { cst_utterance *utt; cst_tokenstream *ts; const char *token; cst_item *t; cst_relation *tokrel; float durs = 0; int num_tokens; cst_wave *w; cst_breakfunc breakfunc = default_utt_break; cst_uttfunc utt_user_callback = 0; int fp; if ((ts = ts_open(filename, get_param_string(voice->features,"text_whitespace",NULL), get_param_string(voice->features,"text_singlecharsymbols",NULL), get_param_string(voice->features,"text_prepunctuation",NULL), get_param_string(voice->features,"text_postpunctuation",NULL))) == NULL) { cst_errmsg("failed to open file \"%s\" for reading\n", filename); return 1; } fp = get_param_int(voice->features,"file_start_position",0); if (fp > 0) ts_set_stream_pos(ts,fp); if (feat_present(voice->features,"utt_break")) breakfunc = val_breakfunc(feat_val(voice->features,"utt_break")); if (feat_present(voice->features,"utt_user_callback")) utt_user_callback = val_uttfunc(feat_val(voice->features,"utt_user_callback")); /* If its a file to write to, create and save an empty wave file */ /* as we are going to incrementally append to it */ if (!cst_streq(outtype,"play") && !cst_streq(outtype,"none") && !cst_streq(outtype,"stream")) { w = new_wave(); cst_wave_resize(w,0,1); cst_wave_set_sample_rate(w,16000); cst_wave_save_riff(w,outtype); /* an empty wave */ delete_wave(w); } num_tokens = 0; utt = new_utterance(); tokrel = utt_relation_create(utt, "Token"); while (!ts_eof(ts) || num_tokens > 0) { token = ts_get(ts); if ((cst_strlen(token) == 0) || (num_tokens > 500) || /* need an upper bound */ (relation_head(tokrel) && breakfunc(ts,token,tokrel))) { /* An end of utt, so synthesize it */ if (utt_user_callback) utt = (utt_user_callback)(utt); if (utt) { utt = flite_do_synth(utt,voice,utt_synth_tokens); durs += flite_process_output(utt,outtype,TRUE); delete_utterance(utt); utt = NULL; } else break; if (ts_eof(ts)) break; utt = new_utterance(); tokrel = utt_relation_create(utt, "Token"); num_tokens = 0; } num_tokens++; t = relation_append(tokrel, NULL); item_set_string(t,"name",token); item_set_string(t,"whitespace",ts->whitespace); item_set_string(t,"prepunctuation",ts->prepunctuation); item_set_string(t,"punc",ts->postpunctuation); /* Mark it at the beginning of the token */ item_set_int(t,"file_pos", ts->file_pos-(1+ /* as we are already on the next char */ cst_strlen(token)+ cst_strlen(ts->prepunctuation)+ cst_strlen(ts->postpunctuation))); item_set_int(t,"line_number",ts->line_number); } delete_utterance(utt); ts_close(ts); return durs; }
/*-------------------------------------------------------------------- * flite_synth : synthesize current text-buffer *--------------------------------------------------------------------*/ void flite_synth(t_flite *x) { cst_wave *wave; int i,vecsize; t_garray *a; t_float *vec; # ifdef FLITE_DEBUG post("flite: got message 'synth'"); # endif // -- sanity checks if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) { pd_error(x,"flite: no such array '%s'", x->x_arrayname->s_name); return; } if (!x->textbuf) { pd_error(x,"flite: attempt to synthesize empty text-buffer!"); return; } # ifdef FLITE_DEBUG post("flite: flite_text_to_wave()"); # endif wave = flite_text_to_wave(x->textbuf,voice); if (!wave) { pd_error(x,"flite: synthesis failed for text '%s'", x->textbuf); return; } // -- resample # ifdef FLITE_DEBUG post("flite: cst_wave_resample()"); # endif cst_wave_resample(wave,sys_getsr()); // -- resize & write to our array # ifdef FLITE_DEBUG post("flite: garray_resize(%d)", wave->num_samples); # endif garray_resize(a, wave->num_samples); if (!garray_getfloatarray(a, &vecsize, &vec)) pd_error(x,"flite: bad template for write to array '%s'", x->x_arrayname->s_name); # ifdef FLITE_DEBUG post("flite: ->write to garray loop<-"); # endif for (i = 0; i < wave->num_samples; i++) { *vec++ = wave->samples[i]/32767.0; } // -- outlet synth-done-bang outlet_bang(x->x_obj.ob_outlet); // -- cleanup delete_wave(wave); // -- redraw garray_redraw(a); }
void test_delete(void) { delete_wave(NULL); }
void *_flite_speak(void *nothing) { AudioTrack track; cst_wave *wav; unsigned int pos; char *buf; int bytes; int ret; log_msg(OTTS_LOG_DEBUG, "flite: speaking thread starting.......\n"); set_speaking_thread_parameters(); while (1) { sem_wait(flite_semaphore); log_msg(OTTS_LOG_INFO, "Semaphore on\n"); flite_stopped = 0; flite_speaking = 1; if (opentts_audio_set_volume(module_audio_id, flite_volume) < 0) { log_msg(OTTS_LOG_ERR, "Can't set volume. audio not initialized?\n"); continue; } /* TODO: free(buf) */ buf = (char *)g_malloc((FliteMaxChunkLength + 1) * sizeof(char)); pos = 0; module_report_event_begin(); while (1) { if (flite_stopped) { log_msg(OTTS_LOG_INFO, "Stop in child, terminating"); flite_speaking = 0; module_report_event_stop(); break; } bytes = module_get_message_part(*flite_message, buf, &pos, FliteMaxChunkLength, FliteDelimiters); if (bytes < 0) { log_msg(OTTS_LOG_DEBUG, "End of message"); flite_speaking = 0; module_report_event_end(); break; } buf[bytes] = 0; log_msg(OTTS_LOG_DEBUG, "Returned %d bytes from get_part\n", bytes); log_msg(OTTS_LOG_NOTICE, "Text to synthesize is '%s'\n", buf); if (flite_pause_requested && (current_index_mark != -1)) { log_msg(OTTS_LOG_INFO, "Pause requested in parent, position %d\n", current_index_mark); flite_pause_requested = 0; flite_position = current_index_mark; break; } if (bytes > 0) { log_msg(OTTS_LOG_DEBUG, "Speaking in child..."); log_msg(OTTS_LOG_NOTICE, "Trying to synthesize text"); wav = flite_text_to_wave(buf, flite_voice); if (wav == NULL) { log_msg(OTTS_LOG_NOTICE, "Stop in child, terminating"); flite_speaking = 0; module_report_event_stop(); break; } track.num_samples = wav->num_samples; track.num_channels = wav->num_channels; track.sample_rate = wav->sample_rate; track.bits = 16; track.samples = wav->samples; flite_strip_silence(&track); log_msg(OTTS_LOG_INFO, "Got %d samples", track.num_samples); if (track.samples != NULL) { if (flite_stopped) { log_msg(OTTS_LOG_NOTICE, "Stop in child, terminating"); flite_speaking = 0; module_report_event_stop(); delete_wave(wav); break; } log_msg(OTTS_LOG_INFO, "Playing part of the message"); switch (module_audio_id->format) { case SPD_AUDIO_LE: ret = opentts_audio_play (module_audio_id, track, SPD_AUDIO_LE); break; case SPD_AUDIO_BE: ret = opentts_audio_play (module_audio_id, track, SPD_AUDIO_BE); break; } if (ret < 0) log_msg(OTTS_LOG_WARN, "ERROR: spd_audio failed to play the track"); if (flite_stopped) { log_msg(OTTS_LOG_NOTICE, "Stop in child, terminating (s)"); flite_speaking = 0; module_report_event_stop(); delete_wave(wav); break; } } delete_wave(wav); } else if (bytes == -1) { log_msg(OTTS_LOG_INFO, "End of data in speaking thread"); flite_speaking = 0; module_report_event_end(); break; } else { flite_speaking = 0; module_report_event_end(); break; } if (flite_stopped) { log_msg(OTTS_LOG_NOTICE, "Stop in child, terminating"); flite_speaking = 0; module_report_event_stop(); break; } } flite_stopped = 0; g_free(buf); } flite_speaking = 0; log_msg(OTTS_LOG_NOTICE, "flite: speaking thread ended.......\n"); pthread_exit(NULL); }