ref: 397265f5791291defa76487c2388e1898e2e433c
dir: /main/flite_plan9.c/
/*************************************************************************/
/* */
/* Language Technologies Institute */
/* Carnegie Mellon University */
/* Copyright (c) 2001 */
/* All Rights Reserved. */
/* */
/* Permission is hereby granted, free of charge, to use and distribute */
/* this software and its documentation without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of this work, and to */
/* permit persons to whom this work is furnished to do so, subject to */
/* the following conditions: */
/* 1. The code must retain the above copyright notice, this list of */
/* conditions and the following disclaimer. */
/* 2. Any modifications must be clearly marked as such. */
/* 3. Original authors' names are not deleted. */
/* 4. The authors' names are not used to endorse or promote products */
/* derived from this software without specific prior written */
/* permission. */
/* */
/* CARNEGIE MELLON UNIVERSITY AND THE CONTRIBUTORS TO THIS WORK */
/* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
/* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
/* SHALL CARNEGIE MELLON UNIVERSITY NOR THE CONTRIBUTORS BE LIABLE */
/* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
/* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
/* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
/* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
/* THIS SOFTWARE. */
/* */
/*************************************************************************/
/* Author: Sigrid */
/* Date: June 2021 */
/*************************************************************************/
/* */
/* Simple top level program for Plan 9 */
/* */
/*************************************************************************/
#include <flite.h>
#include <bio.h>
#include "flite_version.h"
#pragma lib "../lang/cmu_us_awb/libcmu_us_awb.$M.a"
#pragma lib "../lang/cmu_us_rms/libcmu_us_rms.$M.a"
#pragma lib "../lang/cmu_us_slt/libcmu_us_slt.$M.a"
#pragma lib "../lang/cmulex/libcmulex.$M.a"
#pragma lib "../lang/usenglish/libusenglish.$M.a"
#pragma lib "../src/audio/libaudio.$M.a"
#pragma lib "../src/cg/libcg.$M.a"
#pragma lib "../src/hrg/libhrg.$M.a"
#pragma lib "../src/lexicon/liblexicon.$M.a"
#pragma lib "../src/regex/libregex.$M.a"
#pragma lib "../src/speech/libspeech.$M.a"
#pragma lib "../src/stats/libstats.$M.a"
#pragma lib "../src/synth/libsynth.$M.a"
#pragma lib "../src/utils/libutils.$M.a"
#pragma lib "../src/wavesynth/libwavesynth.$M.a"
void *
flite_set_lang_list(void)
{
return nil;
}
cst_voice *register_cmu_us_awb(const char *voxdir);
cst_voice *register_cmu_us_rms(const char *voxdir);
cst_voice *register_cmu_us_slt(const char *voxdir);
cst_val *
flite_set_voice_list(const char *voxdir)
{
flite_voice_list = cons_val(voice_val(register_cmu_us_slt(voxdir)), flite_voice_list);
flite_voice_list = cons_val(voice_val(register_cmu_us_awb(voxdir)), flite_voice_list);
flite_voice_list = cons_val(voice_val(register_cmu_us_rms(voxdir)), flite_voice_list);
flite_voice_list = val_reverse(flite_voice_list);
return flite_voice_list;
}
static void
usage(void)
{
cst_voice *voice;
const cst_val *v;
fprint(2, "usage: flite [-v VOICE] [>/dev/audio]\n");
fprint(2, "voices:");
for(v = flite_voice_list; v; v = val_cdr(v)){
voice = val_voice(val_car(v));
fprint(2, " %s", voice->name);
}
fprint(2, "\n");
fprint(2, " Carnegie Mellon University, Copyright (c) 1999-2021, all rights reserved\n");
fprint(2, " version: %s-%s-%s %s (http://cmuflite.org)\n",
FLITE_PROJECT_PREFIX,
FLITE_PROJECT_VERSION,
FLITE_PROJECT_STATE,
FLITE_PROJECT_DATE);
exits("usage");
}
static int
runconv(cst_wave *w)
{
char fmt[16];
int p[2];
sprintf(fmt, "s%dr%dc%d", 16, cst_wave_sample_rate(w), cst_wave_num_channels(w));
pipe(p);
if(rfork(RFPROC|RFNOTEG|RFFDG|RFCENVG) == 0){
dup(p[1], 0);
close(p[0]);
close(p[1]);
execl("/bin/audio/pcmconv", "pcmconv", "-i", fmt, nil);
fprint(2, "%r\n");
exits("pcmconv");
}
close(p[1]);
return p[0];
}
static int fd = -1;
static int
audiochunk(const cst_wave *w, int start, int size, int last, cst_audio_streaming_info *a)
{
USED(last, a);
if(fd < 0)
fd = runconv(w);
if(size > 0)
write(fd, cst_wave_samples(w)+start, 2*size);
if(last)
return CST_AUDIO_STREAM_STOP;
return CST_AUDIO_STREAM_CONT;
}
void
main(int argc, char **argv)
{
cst_audio_streaming_info *a;
char *s, *v;
cst_voice *voice;
Biobuf in;
if(Binit(&in, 0, OREAD|OCEXEC) != 0)
sysfatal("bio: %r");
flite_init();
flite_set_lang_list();
quotefmtinstall();
flite_set_voice_list(nil);
v = nil;
ARGBEGIN{
case 'v':
v = EARGF(usage());
break;
default:
usage();
}ARGEND
if((voice = flite_voice_select(v)) == nil)
sysfatal("invalid voice %q", v);
feat_copy_into(new_features(), voice->features);
a = new_audio_streaming_info();
a->asc = audiochunk;
a->min_buffsize = 4096;
feat_set(voice->features, "streaming_info", audio_streaming_info_val(a));
for(;;){
if((s = Brdstr(&in, '\n', 1)) == nil)
break;
flite_text_to_speech(s, voice, "stream");
}
close(fd);
waitpid();
exits(nil);
}